irrc 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d0cea0cd7090c9cdc0050e02cc02368a03e48f12
4
- data.tar.gz: 022c5535b1e8acb15e3641fcff65959105ebd5c7
3
+ metadata.gz: 2153f20f9106d41a4879ffbc6ab3da228fb92c91
4
+ data.tar.gz: f79d595e7e9feba683de2e366dd08fdc93b9d119
5
5
  SHA512:
6
- metadata.gz: f3883807ba6822641f396177a1fb187f0d50c96595ac9b4b33c6d2693a789ac720cd7b324aa1b780ee76898760afd247cf93803a0a9d606c668e0bf826bb9f51
7
- data.tar.gz: 0e89f38a1c5b90241301ff54839949cc1778dc0194163659f8e60c23b457fe5e29cfbb25806ab41c707dffb9348eb07f29ef27a0230620445076e0d0460f728f
6
+ metadata.gz: 01730d20bad2b5b2509b1895fc237ebc299d372ba5a053f52cae32b74e31be9580aa3d84856424e946dd1debf0de1c45f7fb8636fff807258fe133f402ad9eb2
7
+ data.tar.gz: e45bce36c6a1449a6a4f866f6e258e76c264dd96fb6f1bc8eb4be9a1cd9e2badc9f409408fefadc39e8a185783eb6fb8b62415cc3c6f24104c0489923636912e
@@ -1,6 +1,14 @@
1
1
  language: ruby
2
+
2
3
  rvm:
3
- - 2.0.0
4
- - 2.1.0
5
- - 2.1.1
6
- - ruby-head
4
+ - 2.1.9
5
+ - 2.2.6
6
+ - 2.3.3
7
+ - ruby-head
8
+
9
+ before_install:
10
+ - gem update bundler
11
+
12
+ matrix:
13
+ allow_failures:
14
+ - rvm: ruby-head
data/Gemfile CHANGED
@@ -1,7 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- group :test do
4
- gem 'rspec'
5
- end
6
-
7
- gemspec
3
+ # Specify your gem's dependencies in junoser.gemspec
4
+ gemspec
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2014 Shintaro Kojima
3
+ Copyright (c) 2017 Shintaro Kojima
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -64,8 +64,8 @@ You can load irrc as a library and use it easily in your own code.
64
64
  require 'irrc'
65
65
 
66
66
  client = Irrc::Client.new
67
- client.query(:jpirr, 'AS-JPNIC', source: :jpirr) # queries JPIRR about AS-JPNIC with a SOURCE: filter
68
- client.query(:ripe, 'AS-RIPENCC', protocol: :ipv4) # queries RIPE Whoisd about AS-RIPENCC for IPv4 only
67
+ client.query :jpirr, 'AS-JPNIC', source: :jpirr # queries JPIRR about AS-JPNIC with a SOURCE: filter
68
+ client.query :ripe, 'AS-RIPENCC', protocol: :ipv4 # queries RIPE Whoisd about AS-RIPENCC for IPv4 only
69
69
  client.perform # returns the results in a Hash
70
70
  ```
71
71
 
@@ -99,7 +99,7 @@ AS-JPNIC: # queried object
99
99
 
100
100
  * Ruby >= 2.0.0
101
101
 
102
- Successfully tested with 2.0.0, 2.1.0, 2.1.1, 2.1.2.
102
+ Successfully tested with 2.1.9, 2.2.6, 2.3.3 and 2.4.0.
103
103
 
104
104
 
105
105
  ## Threading
@@ -146,34 +146,12 @@ client = Irrc::Client.new {|c| c.logger = Rails.logger }
146
146
 
147
147
  Here is a quick performance comparison with peval and irrpt.
148
148
 
149
- * Ordinary as-set
150
-
151
- | CLI command | user | system | cpu | total |
152
- | :------------------------------ | --------: | ---------: | ------: | ---------: |
153
- | peval -h jpirr.nic.ad.jp AS-OCN | 0.14s | 0.04s | 1% | 9.397 |
154
- | irrpt_eval AS-OCN | 0.35s | 0.06s | 5% | 8.021 |
155
- | **irrc -h jpirr AS-OCN** | **0.42s** | **0.09s** | **4%** | **10.639** |
156
-
157
- * Huge as-set
158
-
159
- Object caching may contribute to the query performance.
160
-
161
- | CLI command | user | system | cpu | total |
162
- | :---------------------------------------- | ----------: | ---------: | ------: | ----------: |
163
- | peval -h jpirr.nic.ad.jp AS-HURRICANE | 67.29s | 1.21s | 22% | 4:58.16 |
164
- | irrpt_eval AS-HURRICANE | 163.10s | 1.38s | 43% | 6:18.17 |
165
- | **irrc -h jpirr AS-HURRICANE** | **20.26s** | **1.84s** | **7%** | **4:54.37** |
166
-
167
- * Multiple as-set
168
-
169
- Multi-threading and object caching may contribute to the query performance.
170
-
171
- | CLI command | user | system | cpu | total |
172
- | :------------------------------------------------------------- | ----------: | ---------: | ------: | ----------: |
173
- | for i in AS-HURRICANE AS-GBLX; peval -h jpirr.nic.ad.jp $i | 76.47s | 1.08s | 20% | 6:15.80 |
174
- | irrpt_fetch | 174.21s | 1.29s | 44% | 6:38.50 |
175
- | irrc -h jpirr AS-HURRICANE AS-GBLX | 22.28s | 1.75s | 8% | 4:34.31 |
176
- | **irrc -h jpirr -t 2 AS-HURRICANE AS-GBLX** | **23.04s** | **1.81s** | **9%** | **4:09.27** |
149
+ | CLI command | user | system | cpu | total |
150
+ | :----------------------------------------------- | --------: | ---------: | ------: | ---------: |
151
+ | peval -h jpirr.nic.ad.jp 'afi ipv4, ipv6 AS-OCN' | 0.15s | 0.04s | 3% | 4.959 |
152
+ | irrpt_list_prefixes AS-OCN | 0.21s | 0.09s | 3% | 9.693 |
153
+ | **irrc -h jpirr AS-OCN** | **0.42s** | **0.12s** | **5%** | **9.622** |
154
+ | **irrc -h jpirr -t 4 AS-OCN** | **0.39s** | **0.13s** | **19%** | **2.754** |
177
155
 
178
156
 
179
157
  ## Contributing
@@ -192,4 +170,4 @@ For questions or feedbacks write to my twitter @codeout.
192
170
 
193
171
  ## Copyright and License
194
172
 
195
- Copyright (c) 2014 Shintaro Kojima. Code released under the [MIT license](LICENSE).
173
+ Copyright (c) 2017 Shintaro Kojima. Code released under the [MIT license](LICENSE).
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "foo"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'yaml'
5
+
6
+ require 'irrc'
7
+
8
+
9
+ options = Struct.new(:host, :source, :protocol, :threads, :debug).new(nil, [], [], 1, nil)
10
+
11
+ opts = OptionParser.new do |opts|
12
+ opts.banner = <<-EOS
13
+
14
+ Usage: #{opts.program_name} [options] object [object ...]
15
+
16
+ If no [-4|-6|--ipv4|--ipv6] option given, it tries both of ipv4 and ipv6.
17
+ EOS
18
+ opts.separator ''
19
+ opts.separator 'Options:'
20
+
21
+ opts.on '-h HOST', 'Specify FQDN of IRR / Whois server to send queries.',
22
+ 'IRR / Whois name is also acceptable. This switch is mandatory.' do |host|
23
+ options.host = host
24
+ end
25
+
26
+ opts.on '-s SOURCE', '--source', 'Specify an authoritative IRR / Whois source name.',
27
+ 'Multiply this option for multiple SOURCE.',
28
+ "eg) #{opts.program_name} -s jpirr -s radb AS-JPNIC" do |source|
29
+ options.source |= [source]
30
+ end
31
+
32
+ opts.on '-4', '--ipv4', 'Resolve IPv4 prefixes.' do
33
+ options.protocol |= [:ipv4]
34
+ end
35
+
36
+ opts.on '-6', '--ipv6', 'Resolve IPv6 prefixes.' do
37
+ options.protocol |= [:ipv6]
38
+ end
39
+
40
+ opts.on '-t NUMBER', '--threads', 'Number of threads to resolve prefixes per IRR / Whois server.' do |threads|
41
+ options.threads = threads
42
+ end
43
+
44
+ opts.on '-d', '--debug', 'Print raw queries, answers and additional informations.' do
45
+ options.debug = true
46
+ end
47
+
48
+ opts.on_tail '--help', 'Show this message' do
49
+ puts "irrc: Better IRR client to resolve as-set, route-set or aut-num object into prefixes", opts
50
+ exit
51
+ end
52
+
53
+ opts.on_tail '-v', '--version', 'Show version' do
54
+ puts Irrc::VERSION
55
+ exit
56
+ end
57
+ end
58
+ opts.parse!
59
+
60
+
61
+ if ARGV.empty?
62
+ $stderr.puts 'Missing Argument: object is required.', opts
63
+ abort
64
+ end
65
+
66
+ unless options.host
67
+ $stderr.puts 'Missing Argument: -h option is required.', opts
68
+ abort
69
+ end
70
+
71
+
72
+ options.protocol = [:ipv4, :ipv6] if options.protocol.empty?
73
+
74
+
75
+ begin
76
+ client = if options.debug
77
+ Irrc::Client.new(options.threads) {|c| c.logger = Irrc::Logging::Logger.new(STDERR) }
78
+ else
79
+ Irrc::Client.new(options.threads)
80
+ end
81
+
82
+ client.query options.host, ARGV, source: options.source, protocol: options.protocol
83
+ puts client.perform.to_yaml
84
+ rescue
85
+ $stderr.print "#{$!.class}: " unless $!.instance_of?(RuntimeError)
86
+ $stderr.puts $!.message
87
+
88
+ abort
89
+ end
@@ -8,16 +8,21 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Irrc::VERSION
9
9
  spec.authors = ['Shintaro Kojima']
10
10
  spec.email = ['goodies@codeout.net']
11
+
11
12
  spec.summary = 'IRR / Whois client to expand as-set and route-set into a list of origin ASs and prefixes'
12
13
  spec.description = 'irrc is a lightweight and flexible client of IRR / Whois Database to expand arbitrary as-set and route-set objects into a list of origin ASs and prefixes belonging to the ASs. It allows concurrent queries to IRR / Whois Databases for performance.'
13
14
  spec.homepage = 'https://github.com/codeout/irrc'
14
15
  spec.license = 'MIT'
15
16
 
16
- spec.files = `git ls-files -z`.split("\x0")
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ['lib']
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency 'net-telnet'
20
23
 
21
- spec.add_development_dependency 'bundler', '~> 1.6'
22
- spec.add_development_dependency 'rake'
24
+ spec.add_development_dependency 'bundler', '~> 1.9'
25
+ spec.add_development_dependency 'rake', '~> 10.0'
26
+ spec.add_development_dependency 'rspec'
27
+ spec.required_ruby_version = '>= 2.0.0'
23
28
  end
@@ -37,15 +37,14 @@ module Irrc
37
37
  #
38
38
  # Examples
39
39
  #
40
- # client.query(:jpirr, 'AS-JPNIC', source: :jpirr, protocol: :ipv4)
41
- # client.query(:jpirr, 'AS-JPNIC', source: [:jpirr, :radb])
40
+ # client.query :jpirr, 'AS-JPNIC', source: :jpirr, protocol: :ipv4
41
+ # client.query :jpirr, 'AS-JPNIC', source: [:jpirr, :radb]
42
42
  def query(host, objects, options={})
43
- raise ArgumentError, 'host required.' unless host
43
+ raise ArgumentError, 'host is required.' unless host
44
44
  fqdn = Irrc::Irr.host(host) || host
45
45
 
46
- queues[fqdn] ||= Queue.new
47
46
  Array(objects).map {|object|
48
- queues[fqdn] << Irrc::Query.new(object, options)
47
+ queue(fqdn) << Irrc::Query.new(object, options)
49
48
  }
50
49
  end
51
50
 
@@ -56,9 +55,10 @@ module Irrc
56
55
  done = []
57
56
 
58
57
  queues.each_with_object([]) {|(fqdn, queue), workers|
59
- @thread_limit.times.map {
58
+ @thread_limit.times.map.with_index {|i|
60
59
  workers << Thread.start {
61
- done.push *worker_class(fqdn).new(fqdn, queues[fqdn], &@block).run
60
+ Thread.current[:id] = i+1
61
+ done.push *worker_class(fqdn).new(fqdn, queue(fqdn), cache(fqdn), &@block).run(@thread_limit)
62
62
  }
63
63
  }
64
64
  }.each {|t| t.join }
@@ -90,7 +90,19 @@ module Irrc
90
90
  private
91
91
 
92
92
  def queues
93
- @_queues ||= {}
93
+ @queues ||= {}
94
+ end
95
+
96
+ def queue(fqdn)
97
+ queues[fqdn] ||= Queue.new
98
+ end
99
+
100
+ def caches
101
+ @caches ||= {}
102
+ end
103
+
104
+ def cache(fqdn)
105
+ caches[fqdn] ||= {}
94
106
  end
95
107
 
96
108
  def worker_class(fqdn)
@@ -11,8 +11,8 @@ module Irrc
11
11
  end
12
12
 
13
13
  def connect
14
- @connection ||= logger.info("Connecting to #{@host}") &&
15
- Net::Telnet.new('Host' => @host,
14
+ @connection ||= logger.info("Connecting to #{@fqdn}") &&
15
+ Net::Telnet.new('Host' => @fqdn,
16
16
  'Port' => 43,
17
17
  'Telnetmode' => false,
18
18
  'Prompt' => return_code)
@@ -20,7 +20,7 @@ module Irrc
20
20
 
21
21
  def close
22
22
  if established?
23
- logger.info "Closing a connection to #{@host}"
23
+ logger.info "Closing a connection to #{@fqdn}"
24
24
  @connection.close
25
25
  end
26
26
  end
@@ -28,12 +28,5 @@ module Irrc
28
28
  def established?
29
29
  @connection && !@connection.sock.closed?
30
30
  end
31
-
32
- def execute(command)
33
- return if command.nil? || command == ''
34
-
35
- logger.debug "Executing: #{command}"
36
- @connection.cmd(command).tap {|result| logger.debug "Returned: #{result}" }
37
- end
38
31
  end
39
32
  end
@@ -48,49 +48,43 @@ module Irrc
48
48
 
49
49
  # See http://www.irr.net/docs/list.html
50
50
  LIST = [
51
- ['ALTDB', 'whois.altdb.net', 'irrd'],
52
- ['AOLTW', 'whois.aoltw.net', 'irrd'],
53
- ['APNIC', 'whois.apnic.net', 'whoisd'],
54
- ['ARIN', 'rr.arin.net', 'whoisd'],
55
- # ['BCNET', 'whois.bc.net', nil],
56
- ['BELL', 'whois.in.bell.ca', 'irrd'],
57
- ['BBOI', 'irr.bboi.net', 'irrd'],
58
- ['CANARIE', 'whois.canarie.ca', 'whoisd'],
59
- ['D', 'whois.depository.net', 'whoisd'],
60
- # ['DERU', 'whois.deru.net', nil],
61
- # ['DIGITALREALM', 'rr.digitalrealm.net', nil],
62
- ['EASYNET', 'whois.noc.easynet.net', 'whoisd'],
63
- # ['EBIT', 'whois.ebit.ca', nil],
64
- ['EPOCH', 'whois.epoch.net', 'irrd'],
65
- ['GT', 'rr.gt.ca', 'irrd'],
66
- # ['GW', 'whois.gw.net', nil],
67
- ['HOST', 'rr.host.net', 'irrd'],
68
- ['JPIRR', 'jpirr.nic.ad.jp', 'irrd'],
69
- ['LEVEL3', 'rr.level3.net', 'whoisd'],
70
- # ['MTO', 'rr.mtotelecom.com', nil],
71
- ['NESTEGG', 'whois.nestegg.net', 'irrd'],
72
- ['NTTCOM', 'rr.ntt.net', 'irrd'],
73
- ['OPENFACE', 'whois.openface.ca', 'irrd'],
74
- ['OTTIX', 'whois.ottix.net', 'irrd'],
75
- ['PANIX', 'rrdb.access.net', 'irrd'],
76
- ['RADB', 'whois.radb.net', 'irrd'],
77
- ['REACH', 'rr.net.reach.com', 'irrd'],
78
- ['RGNET', 'whois.rg.net', 'irrd'],
79
- ['RIPE', 'whois.ripe.net', 'whoisd'],
80
- ['RISQ', 'rr.risq.net', 'irrd'],
81
- ['ROGERS', 'whois.rogerstelecom.net', 'irrd'],
82
- ['SAVVIS', 'rr.savvis.net', 'whoisd'],
83
- ['TC', 'bgp.net.br', 'irrd']
51
+ ['AFRINIC', 'whois.afrinic.net', 'whoisd'],
52
+ ['ALTDB', 'whois.altdb.net', 'irrd'],
53
+ ['AOLTW', 'whois.aoltw.net', 'irrd'],
54
+ ['APNIC', 'whois.apnic.net', 'whoisd'],
55
+ ['ARIN', 'rr.arin.net', 'whoisd'],
56
+ ['BELL', 'whois.in.bell.ca', 'irrd'],
57
+ ['BBOI', 'irr.bboi.net', 'irrd'],
58
+ ['CANARIE', 'whois.canarie.ca', 'whoisd'],
59
+ ['EASYNET', 'whois.noc.easynet.net', 'whoisd'],
60
+ ['EPOCH', 'whois.epoch.net', 'irrd'],
61
+ ['GT', 'rr.gt.ca', 'irrd'],
62
+ ['HOST', 'rr.host.net', 'irrd'],
63
+ ['JPIRR', 'jpirr.nic.ad.jp', 'irrd'],
64
+ ['LEVEL3', 'rr.level3.net', 'whoisd'],
65
+ ['NESTEGG', 'whois.nestegg.net', 'irrd'],
66
+ ['NTTCOM', 'rr.ntt.net', 'irrd'],
67
+ ['OPENFACE', 'whois.openface.ca', 'irrd'],
68
+ ['OTTIX', 'whois.ottix.net', 'irrd'],
69
+ ['PANIX', 'rrdb.access.net', 'irrd'],
70
+ ['RADB', 'whois.radb.net', 'irrd'],
71
+ ['REACH', 'rr.net.reach.com', 'irrd'],
72
+ ['RGNET', 'whois.rg.net', 'irrd'],
73
+ ['RIPE', 'whois.ripe.net', 'whoisd'],
74
+ ['RISQ', 'rr.risq.net', 'irrd'],
75
+ ['ROGERS', 'whois.rogerstelecom.net', 'irrd'],
76
+ ['SAVVIS', 'rr.savvis.net', 'whoisd'],
77
+ ['TC', 'whois.bgp.net.br', 'irrd']
84
78
  ]
85
79
  end
86
80
 
87
81
 
88
82
  def object
89
- @_object
83
+ @object
90
84
  end
91
85
 
92
86
  def object=(object)
93
- @_object = object
87
+ @object = object
94
88
  end
95
89
 
96
90
  # Public: Returns the object type to query.
@@ -98,7 +92,7 @@ module Irrc
98
92
  #
99
93
  # Returns: A String. ('as-set', 'route-set' or 'aut-num')
100
94
  def object_type
101
- case @_object
95
+ case @object
102
96
  when /^AS-[\w-]+$|:AS-[\w-]+$/i
103
97
  'as-set'
104
98
  when /^RS-[\w-]+$|:RS-[\w-]+$/i
@@ -20,8 +20,6 @@ module Irrc
20
20
  include Irrc::Runner
21
21
  include Irrc::Irrd::Api
22
22
 
23
- attr_reader :host, :queue
24
-
25
23
 
26
24
  private
27
25
 
@@ -35,54 +33,73 @@ module Irrc
35
33
 
36
34
  case query.object_type
37
35
  when 'as-set'
38
- resolve_aut_nums_from_as_set query
39
- resolve_prefixes_from_aut_nums query
36
+ expand_as_set query
40
37
  when 'route-set'
41
- resolve_prefixes_from_route_set query
38
+ expand_route_set query
42
39
  when 'aut-num'
43
- query.add_aut_num_result query.object
44
- resolve_prefixes_from_aut_nums query
40
+ expand_aut_num query
45
41
  end
42
+
43
+ query
46
44
  end
47
45
 
48
46
  def set_source(query)
49
47
  command = set_source_command(query.sources)
50
48
  if execute(command) =~ error_code
51
- raise "'#{command}' failed on '#{host}' (#{$1})."
49
+ raise "'#{command}' failed on '#{@fqdn}' (#{$1})."
52
50
  end
53
51
  end
54
52
 
55
- def resolve_aut_nums_from_as_set(query)
56
- command = expand_set_command(query.object)
57
- result = execute(command)
58
- query.add_aut_num_result parse_aut_nums_from_as_set(result)
59
- rescue
60
- raise "'#{command}' failed on '#{host}' (#{$!.message})."
53
+ # Public: Expand an as-set object into aut-nums
54
+ def expand_as_set(query)
55
+ result = cache(query.object, query.sources) {
56
+ begin
57
+ command = expand_set_command(query.object)
58
+ execute(command)
59
+ rescue
60
+ raise "'#{command}' failed on '#{@fqdn}' (#{$!.message})."
61
+ end
62
+ }
63
+
64
+ parse_aut_nums_from_as_set(result).each do |autnum|
65
+ child = query.fork(autnum)
66
+ query.add_aut_num_result autnum if child.aut_num?
67
+ end
61
68
  end
62
69
 
63
- def resolve_prefixes_from_route_set(query)
64
- command = expand_set_command(query.object)
65
- result = execute(command)
70
+ # Public: Expand a route-set into routes
71
+ def expand_route_set(query)
72
+ result = cache(query.object, query.sources) {
73
+ begin
74
+ command = expand_set_command(query.object)
75
+ execute(command)
76
+ rescue
77
+ raise "'#{command}' failed on '#{@fqdn}' (#{$!.message})."
78
+ end
79
+ }
80
+
66
81
  prefixes = classify_by_protocol(parse_prefixes_from_route_set(result))
67
82
 
68
83
  query.protocols.each do |protocol|
69
84
  query.add_prefix_result prefixes[protocol], nil, protocol
70
85
  end
71
- rescue
72
- raise "'#{command}' failed on '#{host}' (#{$!.message})."
73
86
  end
74
87
 
75
- def resolve_prefixes_from_aut_nums(query)
76
- unless query.protocols.empty?
77
- # ipv4 and ipv6 should have the same result so far
78
- (query.result[:ipv4] || query.result[:ipv6]).keys.each do |autnum|
79
- command = expand_aut_num_command(autnum)
80
- result = execute(command)
88
+ # Public: Expand an aut-num object into routes
89
+ def expand_aut_num(query)
90
+ return if query.protocols.empty?
81
91
 
82
- query.protocols.each do |protocol|
83
- query.add_prefix_result parse_prefixes_from_aut_num(result, protocol), autnum, protocol
84
- end
92
+ result = cache(query.object, query.sources) {
93
+ begin
94
+ command = expand_aut_num_command(query.object)
95
+ execute(command)
96
+ rescue
97
+ raise "'#{command}' failed on '#{@fqdn}' (#{$!.message})."
85
98
  end
99
+ }
100
+
101
+ query.protocols.each do |protocol|
102
+ query.add_prefix_result parse_prefixes_from_aut_num(result, protocol), query.object, protocol
86
103
  end
87
104
  end
88
105
  end