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
data/lib/net/dns/rr/a.rb CHANGED
@@ -1,7 +1,6 @@
1
1
  module Net
2
2
  module DNS
3
3
  class RR
4
-
5
4
  #
6
5
  # = IPv4 Address Record (A)
7
6
  #
@@ -23,13 +22,10 @@ module Net
23
22
  # without any embedded space (e.g. "10.2.0.52" or "192.0.5.6").
24
23
  #
25
24
  class A < RR
26
-
27
25
  # Gets the current IPv4 address for this record.
28
26
  #
29
27
  # Returns an instance of IPAddr.
30
- def address
31
- @address
32
- end
28
+ attr_reader :address
33
29
 
34
30
  # Assigns a new IPv4 address to this record, which can be in the
35
31
  # form of a <tt>String</tt> or an <tt>IPAddr</tt> object.
@@ -54,71 +50,65 @@ module Net
54
50
  address.to_s
55
51
  end
56
52
 
57
-
58
53
  private
59
54
 
60
- def subclass_new_from_hash(options)
61
- if options.has_key?(:address)
62
- @address = check_address(options[:address])
63
- elsif options.has_key?(:rdata)
64
- @address = check_address(options[:rdata])
65
- else
66
- raise ArgumentError, ":address or :rdata field is mandatory"
67
- end
55
+ def subclass_new_from_hash(options)
56
+ if options.key?(:address)
57
+ @address = check_address(options[:address])
58
+ elsif options.key?(:rdata)
59
+ @address = check_address(options[:rdata])
60
+ else
61
+ raise ArgumentError, ":address or :rdata field is mandatory"
68
62
  end
63
+ end
69
64
 
70
- def subclass_new_from_string(str)
71
- @address = check_address(str)
72
- end
65
+ def subclass_new_from_string(str)
66
+ @address = check_address(str)
67
+ end
73
68
 
74
- def subclass_new_from_binary(data, offset)
75
- a, b, c, d = data.unpack("@#{offset} CCCC")
76
- @address = IPAddr.new("#{a}.#{b}.#{c}.#{d}")
77
- offset + 4
78
- end
69
+ def subclass_new_from_binary(data, offset)
70
+ a, b, c, d = data.unpack("@#{offset} CCCC")
71
+ @address = IPAddr.new("#{a}.#{b}.#{c}.#{d}")
72
+ offset + 4
73
+ end
79
74
 
75
+ def set_type
76
+ @type = Net::DNS::RR::Types.new("A")
77
+ end
80
78
 
81
- def set_type
82
- @type = Net::DNS::RR::Types.new("A")
83
- end
79
+ def get_inspect
80
+ value
81
+ end
84
82
 
85
- def get_inspect
86
- value
83
+ def check_address(input)
84
+ address = case input
85
+ when IPAddr
86
+ input
87
+ # Address in numeric form
88
+ when Integer
89
+ IPAddr.new(input, Socket::AF_INET)
90
+ when String
91
+ IPAddr.new(input)
92
+ else
93
+ raise ArgumentError, "Invalid IP address `#{input}'"
87
94
  end
88
95
 
89
-
90
- def check_address(input)
91
- address = case input
92
- when IPAddr
93
- input
94
- when Integer # Address in numeric form
95
- tmp = [(input >> 24), (input >> 16) & 0xFF, (input >> 8) & 0xFF, input & 0xFF]
96
- tmp = tmp.collect { |x| x.to_s }.join(".")
97
- IPAddr.new(tmp)
98
- when String
99
- IPAddr.new(input)
100
- else
101
- raise ArgumentError, "Invalid IP address `#{input}'"
102
- end
103
-
104
- if !address.ipv4?
105
- raise(ArgumentError, "Must specify an IPv4 address")
106
- end
107
-
108
- address
96
+ unless address.ipv4?
97
+ raise(ArgumentError, "Must specify an IPv4 address")
109
98
  end
110
99
 
111
- def build_pack
112
- @address_pack = @address.hton
113
- @rdlength = @address_pack.size
114
- end
100
+ address
101
+ end
115
102
 
116
- def get_data
117
- @address_pack
118
- end
103
+ def build_pack
104
+ @address_pack = @address.hton
105
+ @rdlength = @address_pack.size
106
+ end
119
107
 
108
+ def get_data
109
+ @address_pack
110
+ end
120
111
  end
121
-
122
112
  end
123
113
  end
124
114
  end
@@ -1,20 +1,16 @@
1
1
  module Net
2
2
  module DNS
3
3
  class RR
4
-
5
4
  #
6
5
  # = IPv6 Address Record (AAAA)
7
6
  #
8
7
  # Class for DNS IPv6 Address (AAAA) resource records.
9
8
  #
10
9
  class AAAA < RR
11
-
12
10
  # Gets the current IPv6 address for this record.
13
11
  #
14
12
  # Returns an instance of IPAddr.
15
- def address
16
- @address
17
- end
13
+ attr_reader :address
18
14
 
19
15
  # Assigns a new IPv6 address to this record, which can be in the
20
16
  # form of a <tt>String</tt> or an <tt>IPAddr</tt> object.
@@ -39,65 +35,58 @@ module Net
39
35
  address.to_s
40
36
  end
41
37
 
42
-
43
38
  private
44
39
 
45
- def subclass_new_from_hash(options)
46
- if options.has_key?(:address)
47
- @address = check_address(options[:address])
48
- else
49
- raise ArgumentError, ":address field is mandatory"
50
- end
51
- end
52
-
53
- def subclass_new_from_string(str)
54
- @address = check_address(str)
55
- end
56
-
57
- def subclass_new_from_binary(data, offset)
58
- tokens = data.unpack("@#{offset} n8")
59
- @address = IPAddr.new(sprintf("%x:%x:%x:%x:%x:%x:%x:%x", *tokens))
60
- offset + 16
61
- end
62
-
40
+ def subclass_new_from_hash(options)
41
+ raise ArgumentError, ":address field is mandatory" unless options.key?(:address)
63
42
 
64
- def set_type
65
- @type = Net::DNS::RR::Types.new("AAAA")
66
- end
43
+ @address = check_address(options[:address])
44
+ end
67
45
 
68
- def get_inspect
69
- value
70
- end
46
+ def subclass_new_from_string(str)
47
+ @address = check_address(str)
48
+ end
71
49
 
50
+ def subclass_new_from_binary(data, offset)
51
+ tokens = data.unpack("@#{offset} n8")
52
+ @address = IPAddr.new(format("%x:%x:%x:%x:%x:%x:%x:%x", *tokens))
53
+ offset + 16
54
+ end
72
55
 
73
- def check_address(input)
74
- address = case input
75
- when IPAddr
76
- input
77
- when String
78
- IPAddr.new(input)
79
- else
80
- raise ArgumentError, "Invalid IP address `#{input}'"
81
- end
56
+ def set_type
57
+ @type = Net::DNS::RR::Types.new("AAAA")
58
+ end
82
59
 
83
- if !address.ipv6?
84
- raise(ArgumentError, "Must specify an IPv6 address")
85
- end
60
+ def get_inspect
61
+ value
62
+ end
86
63
 
87
- address
64
+ def check_address(input)
65
+ address = case input
66
+ when IPAddr
67
+ input
68
+ when String
69
+ IPAddr.new(input)
70
+ else
71
+ raise ArgumentError, "Invalid IP address `#{input}'"
88
72
  end
89
73
 
90
- def build_pack
91
- @address_pack = @address.hton
92
- @rdlength = @address_pack.size
74
+ unless address.ipv6?
75
+ raise(ArgumentError, "Must specify an IPv6 address")
93
76
  end
94
77
 
95
- def get_data
96
- @address_pack
97
- end
78
+ address
79
+ end
98
80
 
99
- end
81
+ def build_pack
82
+ @address_pack = @address.hton
83
+ @rdlength = @address_pack.size
84
+ end
100
85
 
86
+ def get_data
87
+ @address_pack
88
+ end
89
+ end
101
90
  end
102
91
  end
103
92
  end
@@ -1,8 +1,6 @@
1
1
  module Net
2
2
  module DNS
3
-
4
3
  class RR
5
-
6
4
  #
7
5
  # = Net::DNS::Classes
8
6
  #
@@ -10,37 +8,35 @@ module Net
10
8
  # class field in a DNS packet.
11
9
  #
12
10
  class Classes
13
-
14
11
  # Hash with the values of each RR class stored with the
15
12
  # respective id number.
16
13
  CLASSES = {
17
- 'IN' => 1, # RFC 1035
18
- 'CH' => 3, # RFC 1035
19
- 'HS' => 4, # RFC 1035
20
- 'NONE' => 254, # RFC 2136
21
- 'ANY' => 255, # RFC 1035
22
- }
14
+ 'IN' => 1, # RFC 1035
15
+ 'CH' => 3, # RFC 1035
16
+ 'HS' => 4, # RFC 1035
17
+ 'NONE' => 254, # RFC 2136
18
+ 'ANY' => 255, # RFC 1035
19
+ }.freeze
23
20
 
24
21
  # The default value when class is nil in Resource Records
25
22
  @@default = CLASSES["IN"]
26
23
 
27
-
28
24
  # Creates a new object representing an RR class. Performs some
29
25
  # checks on the argument validity too. Il +cls+ is +nil+, the
30
26
  # default value is +ANY+ or the one set with Classes.default=
31
27
  def initialize(cls)
32
28
  case cls
33
- when String
34
- initialize_from_str(cls)
35
- when Fixnum
36
- initialize_from_num(cls)
37
- when nil
38
- initialize_from_num(@@default)
29
+ when String
30
+ initialize_from_str(cls)
31
+ when Integer
32
+ initialize_from_num(cls)
33
+ when nil
34
+ initialize_from_num(@@default)
39
35
  end
40
36
 
41
- if @str.nil? || @num.nil?
42
- raise ArgumentError, "Unable to create a `Classes' from `#{cls}'"
43
- end
37
+ return unless @str.nil? || @num.nil?
38
+
39
+ raise ArgumentError, "Unable to create a `Classes' from `#{cls}'"
44
40
  end
45
41
 
46
42
  # Returns the class in number format
@@ -64,16 +60,16 @@ module Net
64
60
  @num.to_i
65
61
  end
66
62
 
67
-
63
+ def self.default
64
+ @@default
65
+ end
68
66
 
69
67
  # Be able to control the default class to assign when
70
68
  # cls argument is +nil+. Default to +IN+
71
69
  def self.default=(str)
72
- if CLASSES[str]
73
- @@default = CLASSES[str]
74
- else
75
- raise ArgumentError, "Unknown class `#{str}'"
76
- end
70
+ raise ArgumentError, "Unknown class `#{str}'" unless CLASSES[str]
71
+
72
+ @@default = CLASSES[str]
77
73
  end
78
74
 
79
75
  # Returns whether <tt>cls</tt> is a valid RR class.
@@ -96,12 +92,12 @@ module Net
96
92
  #
97
93
  def self.valid?(cls)
98
94
  case cls
99
- when String
100
- CLASSES.has_key?(cls)
101
- when Fixnum
102
- CLASSES.invert.has_key?(cls)
103
- else
104
- raise ArgumentError, "Wrong cls class: #{cls.class}"
95
+ when String
96
+ CLASSES.key?(cls)
97
+ when Integer
98
+ CLASSES.invert.key?(cls)
99
+ else
100
+ raise ArgumentError, "Wrong cls class: #{cls.class}"
105
101
  end
106
102
  end
107
103
 
@@ -111,23 +107,22 @@ module Net
111
107
  CLASSES.keys.sort.join("|")
112
108
  end
113
109
 
114
-
115
- private
110
+ private
116
111
 
117
112
  # Initialize a new instance from a Class name.
118
113
  def initialize_from_str(str)
119
114
  key = str.to_s.upcase
120
- @num, @str = CLASSES[key], key
115
+ @num = CLASSES[key]
116
+ @str = key
121
117
  end
122
118
 
123
119
  # Initialize a new instance from the Class value.
124
120
  def initialize_from_num(num)
125
121
  key = num.to_i
126
- @num, @str = key, CLASSES.invert[key]
122
+ @num = key
123
+ @str = CLASSES.invert[key]
127
124
  end
128
-
129
125
  end
130
-
131
126
  end
132
127
  end
133
128
  end
@@ -1,7 +1,6 @@
1
1
  module Net # :nodoc:
2
2
  module DNS
3
3
  class RR
4
-
5
4
  #
6
5
  # = Canonical Name Record (CNAME)
7
6
  #
@@ -12,13 +11,10 @@ module Net # :nodoc:
12
11
  # Canonical means expected or real name.
13
12
  #
14
13
  class CNAME < RR
15
-
16
14
  # Gets the canonical name value.
17
15
  #
18
16
  # Returns a String.
19
- def cname
20
- @cname
21
- end
17
+ attr_reader :cname
22
18
 
23
19
  # Gets the standardized value for this record,
24
20
  # represented by the value of <tt>cname</tt>.
@@ -28,55 +24,49 @@ module Net # :nodoc:
28
24
  cname.to_s
29
25
  end
30
26
 
31
-
32
27
  private
33
28
 
34
- def subclass_new_from_hash(options)
35
- if options.has_key?(:cname)
36
- @cname = check_name(options[:cname])
37
- else
38
- raise ArgumentError, ":cname field is mandatory"
39
- end
40
- end
29
+ def subclass_new_from_hash(options)
30
+ raise ArgumentError, ":cname field is mandatory" unless options.key?(:cname)
41
31
 
42
- def subclass_new_from_string(str)
43
- @cname = check_name(str)
44
- end
45
-
46
- def subclass_new_from_binary(data, offset)
47
- @cname, offset = dn_expand(data, offset)
48
- offset
49
- end
32
+ @cname = check_name(options[:cname])
33
+ end
50
34
 
35
+ def subclass_new_from_string(str)
36
+ @cname = check_name(str)
37
+ end
51
38
 
52
- def set_type
53
- @type = Net::DNS::RR::Types.new("CNAME")
54
- end
39
+ def subclass_new_from_binary(data, offset)
40
+ @cname, offset = dn_expand(data, offset)
41
+ offset
42
+ end
55
43
 
56
- def get_inspect
57
- value
58
- end
44
+ def set_type
45
+ @type = Net::DNS::RR::Types.new("CNAME")
46
+ end
59
47
 
48
+ def get_inspect
49
+ value
50
+ end
60
51
 
61
- def check_name(input)
62
- name = input.to_s
63
- unless name =~ /(\w\.?)+\s*$/ and name =~ /[a-zA-Z]/
64
- raise ArgumentError, "Invalid Canonical Name `#{name}'"
65
- end
66
- name
52
+ def check_name(input)
53
+ name = input.to_s
54
+ unless name =~ /(\w\.?)+\s*$/ && name =~ /[a-zA-Z]/
55
+ raise ArgumentError, "Invalid Canonical Name `#{name}'"
67
56
  end
68
57
 
69
- def build_pack
70
- @cname_pack = pack_name(@cname)
71
- @rdlength = @cname_pack.size
72
- end
58
+ name
59
+ end
73
60
 
74
- def get_data
75
- @cname_pack
76
- end
61
+ def build_pack
62
+ @cname_pack = pack_name(@cname)
63
+ @rdlength = @cname_pack.size
64
+ end
77
65
 
66
+ def get_data
67
+ @cname_pack
68
+ end
78
69
  end
79
-
80
70
  end
81
71
  end
82
72
  end
@@ -1,7 +1,6 @@
1
1
  module Net # :nodoc:
2
2
  module DNS
3
3
  class RR
4
-
5
4
  #
6
5
  # = System Information Record (HINFO)
7
6
  #
@@ -13,30 +12,24 @@ module Net # :nodoc:
13
12
  # Single space between CPU and OS parameters.
14
13
  #
15
14
  class HINFO < RR
16
-
17
15
  # Gets the CPU value.
18
16
  #
19
17
  # Returns a String.
20
- def cpu
21
- @cpu
22
- end
18
+ attr_reader :cpu
23
19
 
24
20
  # Gets the OS value.
25
21
  #
26
22
  # Returns a String.
27
- def os
28
- @os
29
- end
23
+ attr_reader :os
30
24
 
31
25
  # Gets the standardized value for this record,
32
26
  # represented by the value of <tt>cpu</tt> and <tt>os</tt>.
33
27
  #
34
28
  # Returns a String.
35
29
  def value
36
- %Q{"#{cpu}" "#{os}"}
30
+ %Q("#{cpu}" "#{os}")
37
31
  end
38
32
 
39
-
40
33
  # Gets a list of all the attributes for this record.
41
34
  #
42
35
  # Returns an Array of values.
@@ -44,65 +37,56 @@ module Net # :nodoc:
44
37
  [nil, nil, cls.to_s, type.to_s, value]
45
38
  end
46
39
 
47
-
48
40
  private
49
41
 
50
- def subclass_new_from_hash(options)
51
- if options.has_key?(:cpu) && options.has_key?(:os)
52
- @cpu = options[:cpu]
53
- @os = options[:os]
54
- else
55
- raise ArgumentError, ":cpu and :os fields are mandatory"
56
- end
57
- end
42
+ def subclass_new_from_hash(options)
43
+ raise ArgumentError, ":cpu and :os fields are mandatory" unless options.key?(:cpu) && options.key?(:os)
58
44
 
59
- def subclass_new_from_string(str)
60
- @cpu, @os = check_hinfo(str)
61
- end
45
+ @cpu = options[:cpu]
46
+ @os = options[:os]
47
+ end
62
48
 
63
- def subclass_new_from_binary(data, offset)
64
- len = data.unpack("@#{offset} C").first
65
- offset += 1
66
- @cpu = data[offset..(offset + len)]
67
- offset += len
68
-
69
- len = data.unpack("@#{offset} C").first
70
- offset += 1
71
- @os = data[offset..(offset + len)]
72
- offset += len
73
- end
49
+ def subclass_new_from_string(str)
50
+ @cpu, @os = check_hinfo(str)
51
+ end
74
52
 
53
+ def subclass_new_from_binary(data, offset)
54
+ len = data.unpack1("@#{offset} C")
55
+ offset += 1
56
+ @cpu = data[offset..(offset + len)]
57
+ offset += len
75
58
 
76
- def set_type
77
- @type = Net::DNS::RR::Types.new("HINFO")
78
- end
59
+ len = data.unpack1("@#{offset} C")
60
+ offset += 1
61
+ @os = data[offset..(offset + len)]
62
+ offset += len
63
+ end
79
64
 
80
- def get_inspect
81
- value
82
- end
65
+ def set_type
66
+ @type = Net::DNS::RR::Types.new("HINFO")
67
+ end
83
68
 
69
+ def get_inspect
70
+ value
71
+ end
84
72
 
85
- def check_hinfo(input)
86
- if input.to_s.strip =~ /^(?:["']?(.*?)["']?)\s+(?:["']?(.*?)["']?)$/
87
- [$1, $2]
88
- else
89
- raise ArgumentError, "Invalid HINFO Section `#{input}'"
90
- end
91
- end
73
+ def check_hinfo(input)
74
+ raise ArgumentError, "Invalid HINFO Section `#{input}'" unless input.to_s.strip =~ /^(?:["']?(.*?)["']?)\s+(?:["']?(.*?)["']?)$/
92
75
 
93
- def build_pack
94
- @hinfo_pack = ""
95
- @hinfo_pack += [cpu.size].pack("C") + cpu
96
- @hinfo_pack += [os.size ].pack("C") + os
97
- @rdlength = @hinfo_pack.size
98
- end
76
+ [Regexp.last_match(1), Regexp.last_match(2)]
77
+ end
99
78
 
100
- def get_data
101
- @hinfo_pack
102
- end
79
+ def build_pack
80
+ @hinfo_pack = ""
81
+ @hinfo_pack += [cpu.size].pack("C") + cpu
82
+ @hinfo_pack += [os.size].pack("C") + os
83
+ @rdlength = @hinfo_pack.size
84
+ end
103
85
 
86
+ def get_data
87
+ @hinfo_pack
88
+ end
104
89
  end
105
-
106
90
  end
107
91
  end
108
92
  end