net-dns 0.8.0 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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