net-dns 0.6.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/.gitignore +8 -6
  2. data/.travis.yml +14 -0
  3. data/CHANGELOG.md +79 -0
  4. data/Gemfile +4 -0
  5. data/Rakefile +56 -66
  6. data/demo/check_soa.rb +1 -1
  7. data/demo/threads.rb +1 -1
  8. data/lib/net/dns.rb +24 -22
  9. data/lib/net/dns/header.rb +77 -103
  10. data/lib/net/dns/{names/names.rb → names.rb} +19 -20
  11. data/lib/net/dns/packet.rb +231 -256
  12. data/lib/net/dns/question.rb +11 -40
  13. data/lib/net/dns/resolver.rb +248 -250
  14. data/lib/net/dns/resolver/socks.rb +6 -6
  15. data/lib/net/dns/resolver/timeouts.rb +1 -1
  16. data/lib/net/dns/rr.rb +112 -117
  17. data/lib/net/dns/rr/a.rb +98 -89
  18. data/lib/net/dns/rr/aaaa.rb +84 -68
  19. data/lib/net/dns/rr/classes.rb +91 -106
  20. data/lib/net/dns/rr/cname.rb +64 -45
  21. data/lib/net/dns/rr/hinfo.rb +90 -50
  22. data/lib/net/dns/rr/mr.rb +61 -44
  23. data/lib/net/dns/rr/mx.rb +73 -48
  24. data/lib/net/dns/rr/ns.rb +60 -46
  25. data/lib/net/dns/rr/null.rb +11 -12
  26. data/lib/net/dns/rr/ptr.rb +47 -34
  27. data/lib/net/dns/rr/soa.rb +5 -6
  28. data/lib/net/dns/rr/srv.rb +1 -4
  29. data/lib/net/dns/rr/txt.rb +14 -14
  30. data/lib/net/dns/rr/types.rb +13 -13
  31. data/lib/net/dns/version.rb +8 -14
  32. data/net-dns.gemspec +35 -0
  33. data/setup.rb +3 -2
  34. data/test/header_test.rb +18 -18
  35. data/test/names_test.rb +21 -0
  36. data/test/packet_test.rb +38 -31
  37. data/test/question_test.rb +23 -24
  38. data/test/resolver/timeouts_test.rb +13 -13
  39. data/test/resolver_test.rb +28 -20
  40. data/test/rr/a_test.rb +70 -23
  41. data/test/rr/aaaa_test.rb +109 -0
  42. data/test/rr/classes_test.rb +61 -49
  43. data/test/rr/cname_test.rb +97 -0
  44. data/test/rr/hinfo_test.rb +117 -0
  45. data/test/rr/mr_test.rb +105 -0
  46. data/test/rr/mx_test.rb +112 -0
  47. data/test/rr/ns_test.rb +34 -12
  48. data/test/rr/types_test.rb +4 -4
  49. data/test/rr_test.rb +1 -1
  50. metadata +77 -52
  51. data/AUTHORS.rdoc +0 -7
  52. data/CHANGELOG.rdoc +0 -46
  53. data/VERSION.yml +0 -5
@@ -1,87 +1,103 @@
1
- require 'ipaddr'
2
-
3
-
4
- module Net
5
- module DNS
6
-
7
- class RR
1
+ module Net
2
+ module DNS
3
+ class RR
8
4
 
9
5
  #
10
- # RR type AAAA
6
+ # = IPv6 Address Record (AAAA)
7
+ #
8
+ # Class for DNS IPv6 Address (AAAA) resource records.
11
9
  #
12
10
  class AAAA < RR
13
- attr_reader :address
14
11
 
15
- # Assign to the RR::AAAA object a new IPv6 address, which can be in the
16
- # form of a string or an IPAddr object
12
+ # Gets the current IPv6 address for this record.
13
+ #
14
+ # Returns an instance of IPAddr.
15
+ def address
16
+ @address
17
+ end
18
+
19
+ # Assigns a new IPv6 address to this record, which can be in the
20
+ # form of a <tt>String</tt> or an <tt>IPAddr</tt> object.
17
21
  #
18
- # a.address = "::1"
19
- # a.address = IPAddr.new("::1")
22
+ # Examples
20
23
  #
21
- def address=(addr)
22
- @address = check_address addr
24
+ # a.address = "192.168.0.1"
25
+ # a.address = IPAddr.new("10.0.0.1")
26
+ #
27
+ # Returns the new allocated instance of IPAddr.
28
+ def address=(string_or_ipaddr)
29
+ @address = check_address(string_or_ipaddr)
23
30
  build_pack
24
- end # address=
25
-
26
- private
27
-
28
- def check_address(addr)
29
- address = ""
30
- case addr
31
- when String
32
- address = IPAddr.new addr
33
- when IPAddr
34
- address = addr
35
- else
36
- raise ArgumentError, "Unknown address type: #{addr.inspect}"
37
- end
38
- raise ArgumentError, "Must specify an IPv6 address" unless address.ipv6?
39
- address
40
- rescue ArgumentError
41
- raise ArgumentError, "Invalid address #{addr.inspect}"
42
- end
43
-
44
- def build_pack
45
- @address_pack = @address.hton
46
- @rdlength = @address_pack.size
47
- end
48
-
49
- def get_data
50
- @address_pack
31
+ @address
51
32
  end
52
33
 
53
- def get_inspect
54
- "#@address"
55
- end
56
-
57
- def subclass_new_from_hash(args)
58
- if args.has_key? :address
59
- @address = check_address args[:address]
60
- else
61
- raise ArgumentError, ":address field is mandatory but missing"
62
- end
63
- end
64
-
65
- def subclass_new_from_string(str)
66
- @address = check_address(str)
67
- end
68
-
69
- def subclass_new_from_binary(data,offset)
70
- arr = data.unpack("@#{offset} n8")
71
- @address = IPAddr.new sprintf("%x:%x:%x:%x:%x:%x:%x:%x",*arr)
72
- return offset + 16
34
+ # Gets the standardized value for this record,
35
+ # represented by the value of <tt>address</tt>.
36
+ #
37
+ # Returns a String.
38
+ def value
39
+ address.to_s
73
40
  end
74
-
41
+
42
+
75
43
  private
76
-
44
+
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
+
63
+
77
64
  def set_type
78
65
  @type = Net::DNS::RR::Types.new("AAAA")
79
66
  end
80
-
67
+
68
+ def get_inspect
69
+ value
70
+ end
71
+
72
+
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
82
+
83
+ if !address.ipv6?
84
+ raise(ArgumentError, "Must specify an IPv6 address")
85
+ end
86
+
87
+ address
88
+ end
89
+
90
+ def build_pack
91
+ @address_pack = @address.hton
92
+ @rdlength = @address_pack.size
93
+ end
94
+
95
+ def get_data
96
+ @address_pack
97
+ end
98
+
81
99
  end
82
-
100
+
83
101
  end
84
102
  end
85
103
  end
86
-
87
-
@@ -1,148 +1,133 @@
1
- module Net # :nodoc:
2
- module DNS
3
-
1
+ module Net
2
+ module DNS
3
+
4
4
  class RR
5
-
5
+
6
6
  #
7
- # This is an auxiliary class to hadle RR class field in a DNS packet.
7
+ # = Net::DNS::Classes
8
+ #
9
+ # This is an auxiliary class to handle <tt>Net::DNS::RR</tt>
10
+ # class field in a DNS packet.
8
11
  #
9
12
  class Classes
10
-
11
- # An hash with the values of each RR class stored with the
12
- # respective id number
13
- Classes = {
13
+
14
+ # Hash with the values of each RR class stored with the
15
+ # respective id number.
16
+ CLASSES = {
14
17
  'IN' => 1, # RFC 1035
15
18
  'CH' => 3, # RFC 1035
16
19
  'HS' => 4, # RFC 1035
17
20
  'NONE' => 254, # RFC 2136
18
21
  'ANY' => 255, # RFC 1035
19
22
  }
20
-
21
- # The default value when class is nil in Resource Records
22
- @@default = Classes["IN"]
23
23
 
24
- # Be able to control the default class to assign when
25
- # cls argument is +nil+. Default to +IN+
26
- def self.default=(str)
27
- if Classes.has_key? str
28
- @@default = Classes[str]
29
- else
30
- raise ClassArgumentError, "Unknown class #{str}"
31
- end
32
- end
33
-
34
- # Checks whether +cls+ is a valid RR class.
35
- def self.valid?(cls)
36
- case cls
37
- when String
38
- return Classes.has_key?(cls)
39
- when Fixnum
40
- return Classes.invert.has_key?(cls)
41
- else
42
- raise ClassArgumentError, "Wrong cls class: #{cls.class}"
43
- end
44
- end
45
-
46
- # Returns the class in string format, as "IN" or "CH",
47
- # given the numeric value
48
- def self.to_str(cls)
49
- case cls
50
- when Fixnum
51
- if Classes.invert.has_key? cls
52
- return Classes.invert[cls]
53
- else
54
- raise ClassArgumentError, "Unknown class number #{cls}"
55
- end
56
- else
57
- raise ClassArgumentError, "Wrong cls class: #{cls.class}"
58
- end
59
- end
24
+ # The default value when class is nil in Resource Records
25
+ @@default = CLASSES["IN"]
60
26
 
61
- # Gives in output the keys from the +Classes+ hash
62
- # in a format suited for regexps
63
- def self.regexp
64
- Classes.keys.sort.join("|")
65
- end
66
27
 
67
28
  # Creates a new object representing an RR class. Performs some
68
29
  # checks on the argument validity too. Il +cls+ is +nil+, the
69
30
  # default value is +ANY+ or the one set with Classes.default=
70
31
  def initialize(cls)
71
32
  case cls
72
- when String
73
- # type in the form "A" or "NS"
74
- new_from_string(cls.upcase)
75
- when Fixnum
76
- # type in numeric form
77
- new_from_num(cls)
78
- when nil
79
- # default type, control with Classes.default=
80
- @str = Classes.invert[@@default]
81
- @num = @@default
82
- else
83
- raise ClassArgumentError, "Wrong cls class: #{cls.class}"
33
+ when String
34
+ initialize_from_str(cls)
35
+ when Fixnum
36
+ initialize_from_num(cls)
37
+ when nil
38
+ initialize_from_num(@@default)
84
39
  end
85
- end
86
40
 
87
- # Constructor for string data class,
88
- # *PRIVATE* method
89
- def new_from_string(cls)
90
- case cls
91
- when /^CLASS\\d+/
92
- # TODO!!!
93
- else
94
- # String with name of class
95
- if Classes.has_key? cls
96
- @str = cls
97
- @num = Classes[cls]
98
- else
99
- raise ClassesArgumentError, "Unknown cls #{cls}"
100
- end
41
+ if @str.nil? || @num.nil?
42
+ raise ArgumentError, "Unable to create a `Classes' from `#{cls}'"
101
43
  end
102
44
  end
103
45
 
104
- # Contructor for numeric data class
105
- # *PRIVATE* method
106
- def new_from_num(cls)
107
- if Classes.invert.has_key? cls
108
- @num = cls
109
- @str = Classes.invert[cls]
110
- else
111
- raise ClassesArgumentError, "Unkown cls number #{cls}"
112
- end
113
- end
114
-
115
- # Returns the class in number format
46
+ # Returns the class in number format
116
47
  # (default for normal use)
48
+ #
49
+ # FIXME: inspect must return a String.
50
+ #
117
51
  def inspect
118
52
  @num
119
53
  end
120
54
 
121
55
  # Returns the class in string format,
122
- # i.d. "IN" or "CH" or such a string.
56
+ # ex. "IN" or "CH" or such a string.
123
57
  def to_s
124
- @str
58
+ @str.to_s
125
59
  end
126
-
60
+
127
61
  # Returns the class in numeric format,
128
- # usable by the pack methods for data transfers
62
+ # usable by the pack methods for data transfers.
129
63
  def to_i
130
64
  @num.to_i
131
65
  end
132
66
 
133
67
 
134
- # Should be used only for testing purpouses
135
- def to_str
136
- @num.to_s
68
+
69
+ # Be able to control the default class to assign when
70
+ # cls argument is +nil+. Default to +IN+
71
+ def self.default=(str)
72
+ if CLASSES[str]
73
+ @@default = CLASSES[str]
74
+ else
75
+ raise ArgumentError, "Unknown class `#{str}'"
76
+ end
77
+ end
78
+
79
+ # Returns whether <tt>cls</tt> is a valid RR class.
80
+ #
81
+ # Net::DNS::RR::Classes.valid?("IN")
82
+ # # => true
83
+ # Net::DNS::RR::Classes.valid?(1)
84
+ # # => true
85
+ # Net::DNS::RR::Classes.valid?("Q")
86
+ # # => false
87
+ # Net::DNS::RR::Classes.valid?(256)
88
+ # # => false
89
+ # Net::DNS::RR::Classes.valid?(Hash.new)
90
+ # # => ArgumentError
91
+ #
92
+ # FIXME: valid? should never raise.
93
+ #
94
+ # ==== Raises
95
+ # ArgumentError:: if <tt>cls</tt> isn't either a String or a Fixnum
96
+ #
97
+ def self.valid?(cls)
98
+ 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}"
105
+ end
106
+ end
107
+
108
+ # Gives in output the keys from the +Classes+ hash
109
+ # in a format suited for regexps
110
+ def self.regexp
111
+ CLASSES.keys.sort.join("|")
112
+ end
113
+
114
+
115
+ private
116
+
117
+ # Initialize a new instance from a Class name.
118
+ def initialize_from_str(str)
119
+ key = str.to_s.upcase
120
+ @num, @str = CLASSES[key], key
137
121
  end
138
122
 
139
- private :new_from_num, :new_from_string
123
+ # Initialize a new instance from the Class value.
124
+ def initialize_from_num(num)
125
+ key = num.to_i
126
+ @num, @str = key, CLASSES.invert[key]
127
+ end
140
128
 
141
- end # class Classes
142
-
143
- end # class RR
144
- end # module DNS
145
- end # module Net
129
+ end
146
130
 
147
- class ClassArgumentError < ArgumentError # :nodoc:
131
+ end
132
+ end
148
133
  end
@@ -1,63 +1,82 @@
1
- module Net
1
+ module Net # :nodoc:
2
2
  module DNS
3
-
4
3
  class RR
5
-
6
- #------------------------------------------------------------
7
- # RR type CNAME
8
- #------------------------------------------------------------
4
+
5
+ #
6
+ # = Canonical Name Record (CNAME)
7
+ #
8
+ # Class for DNS CNAME resource records.
9
+ #
10
+ # A CNAME record maps an alias or nickname to the real or Canonical name
11
+ # which may lie outside the current zone.
12
+ # Canonical means expected or real name.
13
+ #
9
14
  class CNAME < RR
10
- attr_reader :cname
11
15
 
12
- private
13
-
14
- def check_name(name)
15
- unless name =~ /(\w\.?)+\s*$/ and name =~ /[a-zA-Z]/
16
- raise ArgumentError, "Canonical Name not valid: #{name}"
17
- end
18
- name
16
+ # Gets the canonical name value.
17
+ #
18
+ # Returns a String.
19
+ def cname
20
+ @cname
19
21
  end
20
22
 
21
- def build_pack
22
- @cname_pack = pack_name(@cname)
23
- @rdlength = @cname_pack.size
23
+ # Gets the standardized value for this record,
24
+ # represented by the value of <tt>cname</tt>.
25
+ #
26
+ # Returns a String.
27
+ def value
28
+ cname.to_s
24
29
  end
25
30
 
26
- def get_data
27
- @cname_pack
28
- end
29
31
 
30
- def get_inspect
31
- "#@cname"
32
- end
32
+ private
33
33
 
34
- def subclass_new_from_hash(args)
35
- if args.has_key? :cname
36
- @cname = check_name args[:cname]
37
- else
38
- raise ArgumentError, ":cname field is mandatory but missing"
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
41
+
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
39
49
  end
40
- end
41
50
 
42
- def subclass_new_from_string(str)
43
- @cname = check_name(str)
44
- end
45
51
 
46
- def subclass_new_from_binary(data,offset)
47
- @cname,offset = dn_expand(data,offset)
48
- return offset
49
- end
50
-
51
- private
52
-
53
52
  def set_type
54
53
  @type = Net::DNS::RR::Types.new("CNAME")
55
54
  end
56
-
57
- end # class CNAME
58
-
59
- end # class RR
60
- end # module DNS
61
- end # module Net
62
55
 
56
+ def get_inspect
57
+ value
58
+ end
59
+
60
+
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
67
+ end
68
+
69
+ def build_pack
70
+ @cname_pack = pack_name(@cname)
71
+ @rdlength = @cname_pack.size
72
+ end
73
+
74
+ def get_data
75
+ @cname_pack
76
+ end
77
+
78
+ end
63
79
 
80
+ end
81
+ end
82
+ end