elbping 0.0.9 → 0.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/elbping/resolver.rb +56 -27
  2. metadata +2 -2
@@ -1,43 +1,72 @@
1
1
 
2
- require 'net/dns'
3
- require 'ipaddress'
2
+ require 'resolv'
3
+
4
+ class TcpDNS < Resolv::DNS
5
+ # This is largely a copy-paste job from mri/source/lib/resolv.rb
6
+ def fetch_resource(name, typeclass)
7
+ lazy_initialize
8
+ request = make_tcp_requester
9
+ sends = {}
10
+ begin
11
+ @config.resolv(name) { |candidate, tout, nameserver, port|
12
+ msg = Message.new
13
+ msg.rd = 1
14
+ msg.add_question(candidate, typeclass)
15
+ unless sender = senders[[candidate, nameserver, port]]
16
+ sender = senders[[candidate, nameserver, port]] =
17
+ requester.sender(msg, candidate, nameserver, port)
18
+ end
19
+ reply, reply_name = requester.request(sender, tout)
20
+ case reply.rcode
21
+ when RCode::NoError
22
+ if reply.tc == 1 and not Requester::TCP === requester
23
+ requester.close
24
+ # Retry via TCP:
25
+ requester = make_tcp_requester(nameserver, port)
26
+ senders = {}
27
+ # This will use TCP for all remaining candidates (assuming the
28
+ # current candidate does not already respond successfully via
29
+ # TCP). This makes sense because we already know the full
30
+ # response will not fit in an untruncated UDP packet.
31
+ redo
32
+ else
33
+ yield(reply, reply_name)
34
+ end
35
+ return
36
+ when RCode::NXDomain
37
+ raise Config::NXDomain.new(reply_name.to_s)
38
+ else
39
+ raise Config::OtherResolvError.new(reply_name.to_s)
40
+ end
41
+ }
42
+ ensure
43
+ requester.close
44
+ end
45
+ end
46
+ end
4
47
 
5
48
  module ElbPing
6
49
  module Resolver
7
50
  def self.resolve_ns(nameserver)
8
- # Resolve nameserver IP (you can't just plug a hostname into Net::DNS::Resolve)
9
- # Return an empty list if can't look up nameserver address
10
- if IPAddress.valid? nameserver
11
- ns_addrs = [nameserver]
12
- else
13
- begin
14
- ns_addrs = Resolver(nameserver).answer.map { |rr| rr.address.to_s }
15
- rescue
16
- ns_addrs = []
17
- end
18
- end
51
+ # Leftover from a resolver lib that wouldn't resolve its own nameservers
52
+ return [nameserver]
19
53
  end
20
54
 
21
55
  # Resolve an ELB address to a list of node IPs. Should always return a list
22
56
  # as long as the server responded, even if it's empty.
23
- def self.find_elb_nodes(target, nameserver)
57
+ def self.find_elb_nodes(target, nameserver, timeout=5)
58
+ # `timeout` is in seconds
24
59
  ns_addrs = resolve_ns nameserver
25
60
 
26
61
  # Now resolve our ELB nodes
27
- resolver = Net::DNS::Resolver.new(
28
- :use_tcp => true,
29
- :nameservers => ns_addrs,
30
- :retry => 5)
31
- begin
32
- resp = resolver.query(target, Net::DNS::ANY)
33
- rescue ArgumentError
34
- # For some reason this is raised on timeout
35
- raise "Error querying DNS: Probably a timeout"
62
+ resp = nil
63
+ Timeout::timeout(timeout) do
64
+ TcpDNS.open :nameserver => ns_addrs, :search => '', :ndots => 1 do |dns|
65
+ # TODO: Exceptions
66
+ resp = dns.getresources target, Resolv::DNS::Resource::IN::A
67
+ end
36
68
  end
37
-
38
- nodes = []
39
- resp.each_address { |a| nodes += [a.to_s] }
40
- nodes
69
+ resp.map { |r| r.address.to_s }
41
70
  end
42
71
  end
43
72
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: elbping
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -95,7 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
95
  version: '0'
96
96
  requirements: []
97
97
  rubyforge_project:
98
- rubygems_version: 1.8.25
98
+ rubygems_version: 1.8.23
99
99
  signing_key:
100
100
  specification_version: 3
101
101
  summary: Small tool to 'ping' the nodes that make up an Amazon Elastic Load Balancer