net-dns 0.8.0 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +6 -14
  2. data/.rspec +1 -0
  3. data/.travis.yml +9 -16
  4. data/CHANGELOG.md +37 -13
  5. data/LICENSE.txt +56 -0
  6. data/README.md +94 -77
  7. data/demo/check_soa.rb +27 -38
  8. data/demo/threads.rb +3 -7
  9. data/lib/net/dns/header.rb +86 -110
  10. data/lib/net/dns/names.rb +31 -31
  11. data/lib/net/dns/packet.rb +148 -158
  12. data/lib/net/dns/question.rb +41 -42
  13. data/lib/net/dns/resolver/socks.rb +47 -55
  14. data/lib/net/dns/resolver/timeouts.rb +19 -30
  15. data/lib/net/dns/resolver.rb +151 -176
  16. data/lib/net/dns/rr/a.rb +45 -55
  17. data/lib/net/dns/rr/aaaa.rb +39 -50
  18. data/lib/net/dns/rr/classes.rb +32 -37
  19. data/lib/net/dns/rr/cname.rb +31 -41
  20. data/lib/net/dns/rr/hinfo.rb +40 -56
  21. data/lib/net/dns/rr/mr.rb +31 -42
  22. data/lib/net/dns/rr/mx.rb +35 -47
  23. data/lib/net/dns/rr/ns.rb +31 -41
  24. data/lib/net/dns/rr/null.rb +10 -15
  25. data/lib/net/dns/rr/ptr.rb +16 -24
  26. data/lib/net/dns/rr/soa.rb +36 -35
  27. data/lib/net/dns/rr/srv.rb +18 -19
  28. data/lib/net/dns/rr/txt.rb +11 -16
  29. data/lib/net/dns/rr/types.rb +118 -109
  30. data/lib/net/dns/rr.rb +107 -117
  31. data/lib/net/dns/version.rb +5 -13
  32. data/lib/net/dns.rb +6 -11
  33. metadata +18 -83
  34. data/.gitignore +0 -8
  35. data/Gemfile +0 -4
  36. data/Rakefile +0 -71
  37. data/fixtures/resolv.conf +0 -4
  38. data/lib/net/dns/core_ext.rb +0 -52
  39. data/net-dns.gemspec +0 -35
  40. data/test/header_test.rb +0 -167
  41. data/test/names_test.rb +0 -21
  42. data/test/packet_test.rb +0 -49
  43. data/test/question_test.rb +0 -83
  44. data/test/resolver/timeouts_test.rb +0 -109
  45. data/test/resolver_test.rb +0 -117
  46. data/test/rr/a_test.rb +0 -113
  47. data/test/rr/aaaa_test.rb +0 -109
  48. data/test/rr/classes_test.rb +0 -85
  49. data/test/rr/cname_test.rb +0 -97
  50. data/test/rr/hinfo_test.rb +0 -117
  51. data/test/rr/mr_test.rb +0 -105
  52. data/test/rr/mx_test.rb +0 -112
  53. data/test/rr/ns_test.rb +0 -86
  54. data/test/rr/types_test.rb +0 -69
  55. data/test/rr_test.rb +0 -131
  56. data/test/test_helper.rb +0 -4
@@ -1,20 +1,19 @@
1
1
  module Net
2
- module DNS
3
-
2
+ module DNS
4
3
  #
5
4
  # =Name
6
5
  #
7
6
  # Net::DNS::Question - DNS packet question class
8
7
  #
9
8
  # =Synopsis
10
- #
9
+ #
11
10
  # require 'net/dns/question'
12
11
  #
13
12
  # =Description
14
13
  #
15
14
  # This class represent the Question portion of a DNS packet. The number
16
15
  # of question entries is stored in the +qdCount+ variable of an Header
17
- # object.
16
+ # object.
18
17
  #
19
18
  # A new object can be created passing the name of the query and the type
20
19
  # of answer desired, plus an optional argument containing the class:
@@ -26,13 +25,13 @@ module Net
26
25
  # packet, as when an answer is received.
27
26
  # To obtain the binary data from a question object you can use
28
27
  # the method Question#data:
29
- #
28
+ #
30
29
  # question.data
31
30
  # #=> "\006google\003com\000\000\001\000\001"
32
31
  #
33
32
  # A lot of methods were written to keep a compatibility layer with
34
33
  # the Perl version of the library, as long as methods name which are
35
- # more or less the same.
34
+ # more or less the same.
36
35
  #
37
36
  class Question
38
37
  include Names
@@ -40,18 +39,18 @@ module Net
40
39
  # Base error class.
41
40
  class Error < StandardError
42
41
  end
43
-
42
+
44
43
  # An error in the +name+ part of a Question entry
45
44
  class NameInvalid < Error
46
45
  end
47
-
46
+
48
47
  # +name+ part of a Question entry
49
- attr_reader :qName
48
+ attr_reader :qName
50
49
  # +type+ part of a Question entry
51
- attr_reader :qType
50
+ attr_reader :qType
52
51
  # +class+ part of a Question entry
53
- attr_reader :qClass
54
-
52
+ attr_reader :qClass
53
+
55
54
  # Creates a new Net::DNS::Question object:
56
55
  #
57
56
  # question = Net::DNS::Question.new("example.com")
@@ -60,8 +59,8 @@ module Net
60
59
  # #=> "example.com MX IN"
61
60
  # question = Net::DNS::Question.new("example.com", Net::DNS::TXT, Net::DNS::HS)
62
61
  # #=> "example.com TXT HS"
63
-
64
- # If not specified, +type+ and +cls+ arguments defaults
62
+
63
+ # If not specified, +type+ and +cls+ arguments defaults
65
64
  # to Net::DNS::A and Net::DNS::IN respectively.
66
65
  #
67
66
  def initialize(name, type = Net::DNS::A, cls = Net::DNS::IN)
@@ -83,18 +82,18 @@ module Net
83
82
  o.send(:new_from_binary, arg.to_s)
84
83
  o
85
84
  end
86
-
85
+
87
86
  # Outputs binary data from a Question object
88
87
  #
89
88
  # question.data
90
89
  # #=> "\006google\003com\000\000\001\000\001"
91
90
  #
92
91
  def data
93
- [pack_name(@qName),@qType.to_i,@qClass.to_i].pack("a*nn")
92
+ [pack_name(@qName), @qType.to_i, @qClass.to_i].pack("a*nn")
94
93
  end
95
-
94
+
96
95
  # Return the binary data of the objects, plus an offset
97
- # and an Hash with references to compressed names. For use in
96
+ # and an Hash with references to compressed names. For use in
98
97
  # Net::DNS::Packet compressed packet creation.
99
98
  def comp_data
100
99
  arr = @qName.split(".")
@@ -103,20 +102,19 @@ module Net
103
102
  names = {}
104
103
  offset = Net::DNS::HFIXEDSZ
105
104
  arr.size.times do |i|
106
- x = i+1
105
+ x = i + 1
107
106
  elem = arr[-x]
108
107
  len = elem.size
109
- string = ((string.reverse)+([len,elem].pack("Ca*")).reverse).reverse
108
+ string = (string.reverse + [len, elem].pack("Ca*").reverse).reverse
110
109
  names[string] = offset
111
110
  offset += len
112
111
  end
113
112
  offset += 2 * Net::DNS::INT16SZ
114
113
  str += "\000"
115
- [[str,@qType.to_i,@qClass.to_i].pack("a*nn"),offset,names]
114
+ [[str, @qType.to_i, @qClass.to_i].pack("a*nn"), offset, names]
116
115
  end
117
-
118
-
119
- #
116
+
117
+ #
120
118
  # call-seq:
121
119
  # question.inspect -> string
122
120
  #
@@ -126,15 +124,15 @@ module Net
126
124
  # q.inspect # => "google.com. IN A "
127
125
  #
128
126
  def inspect
129
- if @qName.size > 29 then
130
- len = @qName.size + 1
127
+ len = if @qName.size > 29
128
+ @qName.size + 1
131
129
  else
132
- len = 29
130
+ 29
133
131
  end
134
132
  [@qName, @qClass.to_s, @qType.to_s].pack("A#{len} A8 A8")
135
133
  end
136
-
137
- #
134
+
135
+ #
138
136
  # call-seq:
139
137
  # question.to_s -> string
140
138
  #
@@ -145,44 +143,45 @@ module Net
145
143
  # q.inspect # => "google.com. IN A "
146
144
  #
147
145
  def to_s
148
- "#{self.inspect}"
146
+ inspect.to_s
149
147
  end
150
-
151
-
148
+
152
149
  private
153
-
150
+
154
151
  def build_qName(str)
155
152
  result = ""
156
153
  offset = 0
157
154
  loop do
158
- len = str.unpack("@#{offset} C")[0]
155
+ len = str.unpack1("@#{offset} C")
159
156
  break if len == 0
157
+
160
158
  offset += 1
161
- result += str[offset..offset+len-1]
159
+ result += str[offset..offset + len - 1]
162
160
  result += "."
163
161
  offset += len
164
162
  end
165
163
  result
166
164
  end
167
-
165
+
168
166
  def check_name(input)
169
167
  name = input.to_s.strip
170
- if name =~ /[^\w\.\-_]/
168
+ if name =~ /[^\w\.\-_\*]/
171
169
  raise NameInvalid, "Invalid Question Name `#{name}'"
172
170
  end
171
+
173
172
  name
174
173
  end
175
-
174
+
176
175
  def new_from_binary(data)
177
- str,type,cls = data.unpack("a#{data.size - 4}nn")
176
+ raise NameInvalid if data.size <= 4
177
+
178
+ str, type, cls = data.unpack("a#{data.size - 4}nn")
178
179
  @qName = build_qName(str)
179
180
  @qType = Net::DNS::RR::Types.new type
180
181
  @qClass = Net::DNS::RR::Classes.new cls
181
- rescue StandardError => e
182
+ rescue StandardError
182
183
  raise ArgumentError, "Invalid data: #{data.inspect}"
183
184
  end
184
-
185
185
  end
186
-
187
186
  end
188
187
  end
@@ -2,18 +2,16 @@ require 'socket'
2
2
  require 'ipaddr'
3
3
 
4
4
  class RawSocket # :nodoc:
5
-
6
5
  @@id_arr = []
7
-
8
- def initialize(src_addr,dest_addr)
9
-
6
+
7
+ def initialize(src_addr, dest_addr)
10
8
  # Define socket
11
9
  begin
12
10
  @socket = Socket.new PF_INET, SOCK_RAW, IPPROTO_RAW
13
11
  rescue SystemCallError => e
14
12
  raise SystemCallError, "You must be root to use raw sockets! #{e}"
15
13
  end
16
-
14
+
17
15
  @socket.setsockopt IPPROTO_IP, IP_HDRINCL, 1
18
16
 
19
17
  # Checks addresses
@@ -26,7 +24,7 @@ class RawSocket # :nodoc:
26
24
 
27
25
  # Set correct protocol version in the header
28
26
  @version = @dest_addr.ipv4? ? "0100" : "0110"
29
-
27
+
30
28
  # Total lenght: must be overridden by subclasses
31
29
  @tot_lenght = 20
32
30
 
@@ -38,49 +36,48 @@ class RawSocket # :nodoc:
38
36
  @id = 1234
39
37
 
40
38
  # Generate peer sockaddr
41
- @to = Socket.pack_sockaddr_in @dest_port, @dest_addr.to_s
39
+ @to = Socket.pack_sockaddr_in @dest_port, @dest_addr.to_s
42
40
  end
43
41
 
44
42
  def send(payload = '')
45
- packet = make_ip_header([[ @version+'0101', 'B8' ], # version, hlen
46
- [ 0, 'C' ], # tos
47
- [ @tot_lenght + payload.size, 'n' ], # total len
48
- [ @id, 'n' ], # id
49
- [ 0, 'n' ], # flags, offset
50
- [ 64, 'C' ], # ttl
51
- [ @protocol, 'C' ], # protocol
52
- [ 0, 'n' ], # checksum
53
- [ @src_addr.to_i, 'N' ], # source
54
- [ @dest_addr.to_i, 'N' ], # destination
55
- ])
43
+ packet = make_ip_header([
44
+ [@version + '0101', 'B8'], # version, hlen
45
+ [0, 'C'], # tos
46
+ [@tot_lenght + payload.size, 'n'], # total len
47
+ [@id, 'n'], # id
48
+ [0, 'n'], # flags, offset
49
+ [64, 'C'], # ttl
50
+ [@protocol, 'C'], # protocol
51
+ [0, 'n'], # checksum
52
+ [@src_addr.to_i, 'N'], # source
53
+ [@dest_addr.to_i, 'N'], # destination
54
+ ])
56
55
  packet << make_transport_header(payload.size)
57
56
  packet << [payload].pack("a*")
58
- @socket.send(packet,0,@to)
59
- end
57
+ @socket.send(packet, 0, @to)
58
+ end
60
59
 
61
60
  private
62
-
63
- def check_addr addr
61
+
62
+ def check_addr(addr)
64
63
  case addr
65
- when String
66
- IPAddr.new(addr)
67
- when IPAddr
68
- addr
69
- else
70
- raise ArgumentError, "Wrong address format: #{addr}"
71
- end
72
- end
73
-
74
- def check_port port
75
- if (1..65535).include? port and port.kind_of? Integer
76
- port
64
+ when String
65
+ IPAddr.new(addr)
66
+ when IPAddr
67
+ addr
77
68
  else
78
- raise ArgumentError, "Port #{port} not valid"
69
+ raise ArgumentError, "Wrong address format: #{addr}"
79
70
  end
80
71
  end
81
-
72
+
73
+ def check_port(port)
74
+ raise ArgumentError, "Port #{port} not valid" unless (1..65_535).cover?(port) && port.is_a?(Integer)
75
+
76
+ port
77
+ end
78
+
82
79
  def genID
83
- while (@@id_arr.include?(q = rand(65535)))
80
+ while @@id_arr.include?(q = rand(65_535))
84
81
  end
85
82
  @@id_arr.push(q)
86
83
  q
@@ -103,34 +100,31 @@ class RawSocket # :nodoc:
103
100
  data[-3] = checksum
104
101
  data.pack(template)
105
102
  end
106
-
103
+
107
104
  def make_transport_header
108
105
  ""
109
106
  end
110
-
111
107
  end
112
108
 
113
109
  class UdpRawSocket < RawSocket # :nodoc:
110
+ def initialize(src_addr, src_port, dest_addr, dest_port)
111
+ super(src_addr, dest_addr)
114
112
 
115
- def initialize(src_addr,src_port,dest_addr,dest_port)
116
-
117
- super(src_addr,dest_addr)
118
-
119
113
  # Check ports
120
114
  @src_port = check_port src_port
121
115
  @dest_port = check_port dest_port
122
-
116
+
123
117
  # Total lenght: must be overridden by subclasses
124
118
  @tot_lenght = 20 + 8 # 8 bytes => UDP Header
125
119
 
126
120
  # Protocol: must be overridden by subclasses
127
121
  @protocol = 17 # UDP protocol
128
122
 
129
- @to = Socket.pack_sockaddr_in @dest_port, @dest_addr.to_s
123
+ @to = Socket.pack_sockaddr_in @dest_port, @dest_addr.to_s
130
124
  end
131
125
 
132
126
  private
133
-
127
+
134
128
  def make_udp_header(parts)
135
129
  template = ''
136
130
  data = []
@@ -139,16 +133,14 @@ class UdpRawSocket < RawSocket # :nodoc:
139
133
  template << part[-1]
140
134
  end
141
135
  data.pack(template)
142
- end
143
-
136
+ end
137
+
144
138
  def make_transport_header(pay_size)
145
139
  make_udp_header([
146
- [ @src_port, 'n'], # source port
147
- [ @dest_port, 'n' ], # destination port
148
- [ 8 + pay_size, 'n' ], # len
149
- [ 0, 'n' ] # checksum (mandatory)
150
- ])
140
+ [@src_port, 'n'], # source port
141
+ [@dest_port, 'n'], # destination port
142
+ [8 + pay_size, 'n'], # len
143
+ [0, 'n'], # checksum (mandatory)
144
+ ])
151
145
  end
152
-
153
146
  end
154
-
@@ -3,28 +3,19 @@ require 'timeout'
3
3
  module Net # :nodoc:
4
4
  module DNS
5
5
  class Resolver
6
-
7
6
  class DnsTimeout
8
-
9
7
  attr_reader :seconds
10
8
 
11
-
12
9
  def initialize(seconds)
13
- if seconds.is_a? Numeric and seconds >= 0
14
- @seconds = seconds
15
- else
16
- raise ArgumentError, "Invalid value for tcp timeout"
17
- end
10
+ raise ArgumentError, "Invalid value for tcp timeout" unless seconds.is_a?(Numeric) && seconds >= 0
11
+
12
+ @seconds = seconds
18
13
  end
19
14
 
20
15
  # Returns a string representation of the timeout corresponding
21
16
  # to the number of <tt>@seconds</tt>.
22
17
  def to_s
23
- if @seconds == 0
24
- @output.to_s
25
- else
26
- @seconds.to_s
27
- end
18
+ @seconds == 0 ? @output.to_s : @seconds.to_s
28
19
  end
29
20
 
30
21
  def pretty_to_s
@@ -37,27 +28,26 @@ module Net # :nodoc:
37
28
  # If @seconds is 0 or nil, no timeout is set.
38
29
  def timeout(&block)
39
30
  raise LocalJumpError, "no block given" unless block_given?
31
+
40
32
  Timeout.timeout(@seconds, &block)
41
33
  end
42
34
 
43
-
44
35
  private
45
36
 
46
- def transform(secs)
47
- case secs
48
- when 0
49
- to_s
50
- when 1..59
51
- "#{secs} seconds"
52
- when 60..3559
53
- "#{secs / 60} minutes and #{secs % 60} seconds"
54
- else
55
- hours = secs / 3600
56
- secs -= (hours * 3600)
57
- "#{hours} hours, #{secs / 60} minutes and #{secs % 60} seconds"
58
- end
37
+ def transform(secs)
38
+ case secs
39
+ when 0
40
+ to_s
41
+ when 1..59
42
+ "#{secs} seconds"
43
+ when 60..3559
44
+ "#{secs / 60} minutes and #{secs % 60} seconds"
45
+ else
46
+ hours = secs / 3600
47
+ secs -= (hours * 3600)
48
+ "#{hours} hours, #{secs / 60} minutes and #{secs % 60} seconds"
59
49
  end
60
-
50
+ end
61
51
  end
62
52
 
63
53
  class TcpTimeout < DnsTimeout
@@ -73,7 +63,6 @@ module Net # :nodoc:
73
63
  super
74
64
  end
75
65
  end
76
-
77
66
  end
78
67
  end
79
- end
68
+ end