net-dns 0.2.5 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
data/InstalledFiles CHANGED
@@ -1,22 +1 @@
1
- /usr/local/lib/site_ruby/1.8/net/dns/resolver.rb
2
- /usr/local/lib/site_ruby/1.8/net/dns/dns.rb
3
1
  /usr/local/lib/site_ruby/1.8/net/dns/rr.rb
4
- /usr/local/lib/site_ruby/1.8/net/dns/question.rb
5
- /usr/local/lib/site_ruby/1.8/net/dns/header.rb
6
- /usr/local/lib/site_ruby/1.8/net/dns/packet.rb
7
- /usr/local/lib/site_ruby/1.8/net/dns/names/names.rb
8
- /usr/local/lib/site_ruby/1.8/net/dns/resolver/timeouts.rb
9
- /usr/local/lib/site_ruby/1.8/net/dns/resolver/socks.rb
10
- /usr/local/lib/site_ruby/1.8/net/dns/rr/null.rb
11
- /usr/local/lib/site_ruby/1.8/net/dns/rr/types.rb
12
- /usr/local/lib/site_ruby/1.8/net/dns/rr/hinfo.rb
13
- /usr/local/lib/site_ruby/1.8/net/dns/rr/mr.rb
14
- /usr/local/lib/site_ruby/1.8/net/dns/rr/soa.rb
15
- /usr/local/lib/site_ruby/1.8/net/dns/rr/mx.rb
16
- /usr/local/lib/site_ruby/1.8/net/dns/rr/txt.rb
17
- /usr/local/lib/site_ruby/1.8/net/dns/rr/cname.rb
18
- /usr/local/lib/site_ruby/1.8/net/dns/rr/a.rb
19
- /usr/local/lib/site_ruby/1.8/net/dns/rr/aaaa.rb
20
- /usr/local/lib/site_ruby/1.8/net/dns/rr/ns.rb
21
- /usr/local/lib/site_ruby/1.8/net/dns/rr/classes.rb
22
- /usr/local/lib/site_ruby/1.8/net/dns/rr/ptr.rb
data/Rakefile CHANGED
@@ -6,7 +6,23 @@ require 'rake/gempackagetask'
6
6
 
7
7
  require 'rubygems'
8
8
 
9
- $VERSION = "0.2.5"
9
+ $VERSION = "0.3"
10
+
11
+ task :package => [:version, :clean]
12
+
13
+ desc "Library version"
14
+ task :version do
15
+ file = "lib/net/dns/dns.rb"
16
+ str = IO.readlines(file).to_s
17
+ offset = (str =~ /VERSION = "(.*)"/)
18
+ unless $1 == $VERSION
19
+ str.gsub!($1,$VERSION)
20
+ File.open(file,"w") do |out|
21
+ out << str
22
+ end
23
+ end
24
+ end
25
+
10
26
 
11
27
  desc "Run the tests"
12
28
  Rake::TestTask.new do |t|
data/lib/net/dns/dns.rb CHANGED
@@ -10,8 +10,8 @@ module Net # :nodoc:
10
10
  module DNS
11
11
 
12
12
  # Version of the library
13
- VERSION = 0.1
14
-
13
+ VERSION = "0.3"
14
+
15
15
  # Packet size in bytes
16
16
  PACKETSZ = 512
17
17
 
@@ -291,6 +291,13 @@ module Net # :nodoc:
291
291
  retval
292
292
  end
293
293
 
294
+
295
+ # Wrapper to Header#truncated?
296
+ #
297
+ def truncated?
298
+ @header.truncated?
299
+ end
300
+
294
301
  # Assing a Net::DNS::Header object to a Net::DNS::Packet
295
302
  # instance.
296
303
  #
@@ -15,7 +15,7 @@ require 'net/dns/resolver/timeouts'
15
15
  module Net # :nodoc:
16
16
  module DNS
17
17
 
18
-
18
+ include Logger::Severity
19
19
 
20
20
  # =Name
21
21
  #
@@ -108,7 +108,6 @@ module Net # :nodoc:
108
108
  :packet_size => 512,
109
109
  :tcp_timeout => TcpTimeout.new(120),
110
110
  :udp_timeout => UdpTimeout.new(0)}
111
-
112
111
 
113
112
  # Create a new resolver object.
114
113
  #
@@ -208,7 +207,7 @@ module Net # :nodoc:
208
207
 
209
208
  # New logger facility
210
209
  @logger = Logger.new(@config[:log_file])
211
- @logger.level = Logger::WARN
210
+ @logger.level = $DEBUG ? Logger::DEBUG : Logger::WARN
212
211
 
213
212
  #------------------------------------------------------------
214
213
  # Resolver configuration will be set in order from:
@@ -774,10 +773,6 @@ module Net # :nodoc:
774
773
  #
775
774
  # Note that this will destroy the precedent logger.
776
775
  #
777
- # This is the only mode user will have to control their logger, such
778
- # as setting the level threshold, because no reader is set for this
779
- # instance variable.
780
- #
781
776
  def logger=(logger)
782
777
  if logger.kind_of? Logger
783
778
  @logger.close
@@ -787,6 +782,27 @@ module Net # :nodoc:
787
782
  end
788
783
  end
789
784
 
785
+ # Set the log level for the built-in logging facility.
786
+ #
787
+ # The log level can be one of the following:
788
+ #
789
+ # - +Net::DNS::DEBUG+
790
+ # - +Net::DNS::INFO+
791
+ # - +Net::DNS::WARN+
792
+ # - +Net::DNS::ERROR+
793
+ # - +Net::DNS::FATAL+
794
+ #
795
+ # Note that if the global variable $DEBUG is set (like when the
796
+ # -d switch is used at the command line) the logger level is
797
+ # automatically set at DEGUB.
798
+ #
799
+ # For further informations, see Logger documentation in the
800
+ # Ruby standard library.
801
+ #
802
+ def log_level=(level)
803
+ @logger.level = level
804
+ end
805
+
790
806
  # Performs a DNS query for the given name, applying the searchlist if
791
807
  # appropriate. The search algorithm is as follows:
792
808
  #
@@ -1040,37 +1056,60 @@ module Net # :nodoc:
1040
1056
  end
1041
1057
 
1042
1058
  def send_tcp(packet,packet_data)
1043
- # Generate new TCP socket or use persistent one
1044
- if @config[:persistent_tcp] and @@tcp_socket
1045
- socket = @@tcp_socket
1046
- @logger.info "Using persistent socket #{socket.inspect}"
1047
- else
1048
- socket = Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)
1049
- socket.bind(Socket.pack_sockaddr_in(@config[:source_port],@config[:source_address].to_s))
1050
- @@tcp_socket = socket if @config[:persistent_tcp]
1051
- end
1052
1059
 
1053
- ans = ""
1054
- response = ""
1060
+ ans = nil
1055
1061
  length = [packet_data.size].pack("n")
1056
1062
  @config[:nameservers].each do |ns|
1057
- @config[:tcp_timeout].timeout do
1063
+ begin
1064
+
1065
+ # Generate new TCP socket or use persistent one
1066
+ if @config[:persistent_tcp] and @@tcp_socket
1067
+ socket = @@tcp_socket
1068
+ @logger.info "Using persistent socket #{socket.inspect}"
1069
+ else
1070
+ socket = Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)
1071
+ socket.bind(Socket.pack_sockaddr_in(@config[:source_port],@config[:source_address].to_s))
1072
+ @@tcp_socket = socket if @config[:persistent_tcp]
1073
+ end
1074
+
1058
1075
  sockaddr = Socket.pack_sockaddr_in(@config[:port],ns.to_s)
1059
- socket.connect(sockaddr)
1060
- socket.write(length+packet_data)
1061
- ans = socket.recv(Net::DNS::INT16SZ)
1062
- len = ans.unpack("n")[0]
1063
- p len
1064
- next if len == 0
1065
- ans = socket.recv(len)
1066
- next if ans.size == 0
1067
- p ans.size
1076
+
1077
+ @config[:tcp_timeout].timeout do
1078
+ socket.connect(sockaddr)
1079
+ @logger.info "Contacting nameserver #{ns} port #{@config[:port]}"
1080
+ socket.write(length+packet_data)
1081
+ ans = socket.recv(Net::DNS::INT16SZ)
1082
+ len = ans.unpack("n")[0]
1083
+
1084
+ if len == 0
1085
+ @logger.warn "Receiving 0 lenght packet from nameserver #{ns}, trying next."
1086
+ next
1087
+ end
1088
+
1089
+ ans = socket.recv(len)
1090
+ unless ans.size == len
1091
+ @logger.warn "Malformed packet from nameserver #{ns}, trying next."
1092
+ next
1093
+ end
1094
+ end
1095
+
1068
1096
  ans = [ans,["",@config[:port],ns.to_s,ns.to_s]]
1069
1097
  @logger.info "Received #{ans[0].size} bytes from #{ans[1][2]+":"+ans[1][1].to_s}"
1098
+
1099
+ rescue TimeoutError
1100
+ @logger.warn "Nameserver #{ns} not responding within TCP timeout, trying next one"
1101
+ next
1102
+ ensure
1103
+ socket.close unless @config[:persistent_tcp]
1070
1104
  end
1071
- response = Net::DNS::Packet.parse(ans[0],ans[1])
1072
1105
  end
1073
- return response
1106
+
1107
+ if ans
1108
+ return Net::DNS::Packet.parse(ans[0],ans[1])
1109
+ else
1110
+ @logger.fatal "No response from nameservers list: aborting"
1111
+ raise NoResponseError
1112
+ end
1074
1113
  end
1075
1114
 
1076
1115
 
@@ -1090,6 +1129,7 @@ module Net # :nodoc:
1090
1129
  @config[:nameservers].each do |ns|
1091
1130
  begin
1092
1131
  @config[:udp_timeout].timeout do
1132
+ @logger.info "Contacting nameserver #{ns} port #{@config[:port]}"
1093
1133
  socket.send(packet_data,0,ns.to_s,@config[:port])
1094
1134
  ans = socket.recvfrom(@config[:packet_size])
1095
1135
  end
@@ -1102,7 +1142,12 @@ module Net # :nodoc:
1102
1142
  next
1103
1143
  end
1104
1144
  end
1105
- return Net::DNS::Packet.parse(ans[0],ans[1])
1145
+ if ans
1146
+ return Net::DNS::Packet.parse(ans[0],ans[1])
1147
+ else
1148
+ @logger.fatal "No response from nameservers list: aborting"
1149
+ raise NoResponseError
1150
+ end
1106
1151
  end
1107
1152
 
1108
1153
  def valid?(name)
@@ -1119,7 +1164,9 @@ end # module Net
1119
1164
 
1120
1165
  class ResolverArgumentError < ArgumentError # :nodoc:
1121
1166
  end
1122
-
1167
+ class NoResponseError < StandardError # :nodoc:
1168
+ end
1169
+
1123
1170
  module ExtendHash # :nodoc:
1124
1171
  # Returns an hash with all the
1125
1172
  # keys turned into downcase
data/lib/net/dns/rr.rb CHANGED
@@ -212,20 +212,36 @@ module Net # :nodoc:
212
212
  # #=> example.com. 7200 IN MX 10 mailhost.example.com.
213
213
  #
214
214
  def inspect
215
- # Organize data for pretty format
216
- if @name.size >= 24
217
- nlen = @name.size + 1
218
- tlen = @ttl.to_s.size+2
219
- else
220
- nlen = 24
221
- tlen = 8
222
- end
223
215
  data = get_inspect
224
216
  # Returns the preformatted string
225
- [@name, @ttl.to_s, @cls.to_s, @type.to_s,
226
- data].pack("A#{nlen} A#{tlen} A#{8-(nlen-24)-(tlen-8)} A8 A*")
217
+ if @name.size < 24
218
+ [@name, @ttl.to_s, @cls.to_s, @type.to_s,
219
+ data].pack("A24 A8 A8 A8 A*")
220
+ else
221
+ to_a.join(" ")
222
+ end
223
+ end
224
+
225
+ # Returns the RR in a string format.
226
+ #
227
+ # mx = Net::DNS::RR.new("example.com. 7200 MX 10 mailhost.example.com.")
228
+ # mx.to_s
229
+ # #=> "example.com. 7200 IN MX 10 mailhost.example.com."
230
+ #
231
+ def to_s
232
+ "#{self.inspect}"
227
233
  end
228
234
 
235
+ # Returns an array with all the fields for the RR record.
236
+ #
237
+ # mx = Net::DNS::RR.new("example.com. 7200 MX 10 mailhost.example.com.")
238
+ # mx.to_a
239
+ # #=> ["example.com.",7200,"IN","MX","10 mailhost.example.com."]
240
+ #
241
+ def to_a
242
+ [@name,@ttl,@cls.to_s,@type.to_s,get_inspect]
243
+ end
244
+
229
245
  # Type accessor
230
246
  def type
231
247
  @type.to_s
@@ -33,6 +33,8 @@ class Test_RR < Test::Unit::TestCase
33
33
  @a_binary = Net::DNS::RR.parse(@a_data)
34
34
  @mx_data = @mx.data
35
35
  @mx_binary = Net::DNS::RR.parse(@mx_data)
36
+
37
+ @array = [@name,@ttl,@cls,@type,@rdata]
36
38
 
37
39
  end
38
40
 
@@ -116,6 +118,9 @@ class Test_RR < Test::Unit::TestCase
116
118
 
117
119
  assert_equal(@a_data, @a_binary.data)
118
120
  assert_equal(@mx_data, @mx_binary.data)
121
+
122
+ assert_equal(@str, @a_hash.to_s)
123
+ assert_equal(@array, @a_hash.to_a)
119
124
  end
120
125
 
121
126
  def test_range
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: net-dns
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.2.5
7
- date: 2007-02-02 00:00:00 +00:00
6
+ version: "0.3"
7
+ date: 2007-02-04 00:00:00 +00:00
8
8
  summary: Pure Ruby DNS library
9
9
  require_paths:
10
10
  - lib
@@ -50,7 +50,6 @@ files:
50
50
  - lib/net/dns/dns.rb
51
51
  - lib/net/dns/rr.rb
52
52
  - lib/net/dns/question.rb
53
- - lib/net/dns/rr.rb~
54
53
  - lib/net/dns/header.rb
55
54
  - lib/net/dns/packet.rb
56
55
  - lib/net/dns/rr
@@ -58,7 +57,6 @@ files:
58
57
  - lib/net/dns/resolver/timeouts.rb
59
58
  - lib/net/dns/resolver/socks.rb
60
59
  - lib/net/dns/rr/null.rb
61
- - lib/net/dns/rr/ptr.rb~
62
60
  - lib/net/dns/rr/types.rb
63
61
  - lib/net/dns/rr/hinfo.rb
64
62
  - lib/net/dns/rr/mr.rb
data/lib/net/dns/rr.rb~ DELETED
@@ -1,391 +0,0 @@
1
- #
2
- # $Id: RR.rb,v 1.19 2006/07/28 07:33:36 bluemonk Exp $
3
- #
4
-
5
- require 'net/dns/names/names'
6
- require 'net/dns/rr/types'
7
- require 'net/dns/rr/classes'
8
-
9
-
10
- files = %w[a ns mx cname txt soa ptr aaaa mr] # hinfo mb mg mr
11
- files.each do |file|
12
- require "net/dns/rr/#{file}"
13
- end
14
-
15
- module Net # :nodoc:
16
- module DNS
17
-
18
- # =Name
19
- #
20
- # Net::DNS::RR - DNS Resource Record class
21
- #
22
- # =Synopsis
23
- #
24
- # require 'net/dns/rr'
25
- #
26
- # =Description
27
- #
28
- # The Net::DNS::RR is the base class for DNS Resource
29
- # Record (RR) objects. A RR is a pack of data that represents
30
- # resources for a DNS zone. The form in which this data is
31
- # shows can be drawed as follow:
32
- #
33
- # "name ttl class type data"
34
- #
35
- # The +name+ is the name of the resource, like an canonical
36
- # name for an +A+ record (internet ip address). The +ttl+ is the
37
- # time to live, expressed in seconds. +type+ and +class+ are
38
- # respectively the type of resource (+A+ for ip addresses, +NS+
39
- # for nameservers, and so on) and the class, which is almost
40
- # always +IN+, the Internet class. At the end, +data+ is the
41
- # value associated to the name for that particular type of
42
- # resource record. An example:
43
- #
44
- # # A record for IP address
45
- # "www.example.com 86400 IN A 172.16.100.1"
46
- #
47
- # # NS record for name server
48
- # "www.example.com 86400 IN NS ns.example.com"
49
- #
50
- # A new RR object can be created in 2 ways: passing a string
51
- # such the ones above, or specifying each field as the pair
52
- # of an hash. See the Net::DNS::RR.new method for details.
53
- #
54
- # =Error classes
55
- #
56
- # Some error classes has been defined for the Net::DNS::RR class,
57
- # which are listed here to keep a light and browsable main documentation.
58
- # We have:
59
- #
60
- # * RRArgumentError: Generic argument error for class Net::DNS::RR
61
- # * RRDataError: Error in parsing binary data, maybe from a malformed packet
62
- #
63
- # =Copyright
64
- #
65
- # Copyright (c) 2006 Marco Ceresa
66
- #
67
- # All rights reserved. This program is free software; you may redistribute
68
- # it and/or modify it under the same terms as Ruby itself.
69
- #
70
- class RR
71
- include Net::DNS::Names
72
-
73
- # Regexp matching an RR string
74
- RR_REGEXP = Regexp.new("^\\s*(\\S+)\\s*(\\d+)?\\s+(" +
75
- Net::DNS::RR::Classes.regexp +
76
- "|CLASS\\d+)?\\s*(" +
77
- Net::DNS::RR::Types.regexp +
78
- "|TYPE\\d+)?\\s*(.*)$", Regexp::IGNORECASE)
79
-
80
- # Dimension of the sum of class, type, TTL and rdlength fields in a
81
- # RR portion of the packet, in bytes
82
- RRFIXEDSZ = 10
83
-
84
- # Name of the RR
85
- attr_reader :name
86
- # TTL time (in seconds) of the RR
87
- attr_reader :ttl
88
- # Data belonging to that appropriate class,
89
- # not to be used (use real accessors instead)
90
- attr_reader :rdata
91
-
92
- # Create a new instance of Net::DNS::RR class, or an instance of
93
- # any of the subclass of the appropriate type.
94
- #
95
- # Argument can be a string or an hash. With a sting, we can pass
96
- # a RR resource record in the canonical format:
97
- #
98
- # a = Net::DNS::RR.new("foo.example.com. 86400 A 10.1.2.3")
99
- # mx = Net::DNS::RR.new("example.com. 7200 MX 10 mailhost.example.com.")
100
- # cname = Net::DNS::RR.new("www.example.com 300 IN CNAME www1.example.com")
101
- # txt = Net::DNS::RR.new('baz.example.com 3600 HS TXT "text record"')
102
- #
103
- # Incidentally, +a+, +mx+, +cname+ and +txt+ objects will be instances of
104
- # respectively Net::DNS::RR::A, Net::DNS::RR::MX, Net::DNS::RR::CNAME and
105
- # Net::DNS::RR::TXT classes.
106
- #
107
- # The name is required; all other informations are optional.
108
- # If omitted, the +TTL+ defaults to 10800, +type+ default to +A+ and the RR class
109
- # defaults to +IN+. Omitting the optional fields is useful for creating the
110
- # empty RDATA sections required for certain dynamic update operations.
111
- # All names must be fully qualified. The trailing dot (.) is optional.
112
- #
113
- # The preferred method is however passing an hash with keys and values:
114
- #
115
- # rr = Net::DNS::RR.new(
116
- # :name => "foo.example.com",
117
- # :ttl => 86400,
118
- # :cls => "IN",
119
- # :type => "A",
120
- # :address => "10.1.2.3"
121
- # )
122
- #
123
- # rr = Net::DNS::RR.new(
124
- # :name => "foo.example.com",
125
- # :type => "A"
126
- # )
127
- #
128
- # Name and data are required; all the others fields are optionals like
129
- # we've seen before. The data field can be specified either with the
130
- # right name of the resource (:address in the example above) or with
131
- # the generic key :rdata. Consult documentation to find the exact name
132
- # for the resource in each subclass.
133
- #
134
- def initialize(arg)
135
- case arg
136
- when String
137
- instance = new_from_string(arg)
138
- when Hash
139
- instance = new_from_hash(arg)
140
- else
141
- raise RRArgumentError, "Invalid argument, must be a RR string or an hash of values"
142
- end
143
-
144
- if @type.to_s == "ANY"
145
- @cls = Net::DNS::RR::Classes.new("IN")
146
- end
147
-
148
- build_pack
149
- set_type
150
-
151
- instance
152
- end
153
-
154
- # Return a new RR object of the correct type (like Net::DNS::RR::A
155
- # if the type is A) from a binary string, usually obtained from
156
- # network stream.
157
- #
158
- # This method is used when parsing a binary packet by the Packet
159
- # class.
160
- #
161
- def RR.parse(data)
162
- o = allocate
163
- obj,offset = o.send(:new_from_binary, data, 0)
164
- return obj
165
- end
166
-
167
- # Same as RR.parse, but takes an entire packet binary data to
168
- # perform name expansion. Default when analizing a packet
169
- # just received from a network stream.
170
- #
171
- # Return an instance of appropriate class and the offset
172
- # pointing at the end of the data parsed.
173
- #
174
- def RR.parse_packet(data,offset)
175
- o = allocate
176
- o.send(:new_from_binary,data,offset)
177
- end
178
-
179
- # Return the RR object in binary data format, suitable
180
- # for using in network streams, with names compressed.
181
- # Must pass as arguments the offset inside the packet
182
- # and an hash of compressed names.
183
- #
184
- # This method is to be used in other classes and is
185
- # not intended for user space programs.
186
- #
187
- # TO FIX in one of the future releases
188
- #
189
- def comp_data(offset,compnames)
190
- type,cls = @type.to_i, @cls.to_i
191
- str,offset,names = dn_comp(@name,offset,compnames)
192
- str += [type,cls,@ttl,@rdlength].pack("n2 N n")
193
- offset += Net::DNS::RRFIXEDSZ
194
- return str,offset,names
195
- end
196
-
197
- # Return the RR object in binary data format, suitable
198
- # for using in network streams.
199
- #
200
- # raw_data = rr.data
201
- # puts "RR is #{raw_data.size} bytes long"
202
- #
203
- def data
204
- type,cls = @type.to_i, @cls.to_i
205
- str = pack_name(@name)
206
- return str + [type,cls,@ttl,@rdlength].pack("n2 N n") + get_data
207
- end
208
-
209
- # Canonical inspect method
210
- #
211
- # mx = Net::DNS::RR.new("example.com. 7200 MX 10 mailhost.example.com.")
212
- # #=> example.com. 7200 IN MX 10 mailhost.example.com.
213
- #
214
- def inspect
215
- # Organize data for pretty format
216
- if @name.size >= 24
217
- nlen = @name.size + 1
218
- tlen = @ttl.to_s.size+2
219
- else
220
- nlen = 24
221
- tlen = 8
222
- end
223
- data = get_inspect
224
- # Returns the preformatted string
225
- [@name, @ttl.to_s, @cls.to_s, @type.to_s,
226
- data].pack("A#{nlen} A#{tlen} A#{8-(nlen-24)-(tlen-8)} A8 A*")
227
- end
228
-
229
- # Type accessor
230
- def type
231
- @type.to_s
232
- end
233
-
234
- # Class accessor
235
- def cls
236
- @cls.to_s
237
- end
238
-
239
- private
240
-
241
- #---
242
- # New RR with argument in string form
243
- #---
244
- def new_from_string(rrstring)
245
-
246
- unless rrstring =~ RR_REGEXP
247
- raise RRArgumentError,
248
- "Format error for RR string (maybe CLASS and TYPE not valid?)"
249
- end
250
-
251
- # Name of RR - mandatory
252
- begin
253
- @name = $1.downcase
254
- rescue NoMethodError
255
- raise RRArgumentError, "Missing name field in RR string #{rrstring}"
256
- end
257
-
258
- # Time to live for RR, default 3 hours
259
- @ttl = $2 ? $2.to_i : 10800
260
-
261
- # RR class, default to IN
262
- @cls = Net::DNS::RR::Classes.new $3
263
-
264
- # RR type, default to A
265
- @type = Net::DNS::RR::Types.new $4
266
-
267
- # All the rest is data
268
- @rdata = $5 ? $5.strip : ""
269
-
270
- if self.class == Net::DNS::RR
271
- (eval "Net::DNS::RR::#@type").new(rrstring)
272
- else
273
- subclass_new_from_string(@rdata)
274
- self.class
275
- end
276
- end
277
-
278
- def new_from_hash(args)
279
-
280
- # Name field is mandatory
281
- unless args.has_key? :name
282
- raise RRArgumentError, "RR argument error: need at least RR name"
283
- end
284
-
285
- @name = args[:name].downcase
286
- @ttl = args[:ttl] ? args[:ttl].to_i : 10800 # Default 3 hours
287
- @type = Net::DNS::RR::Types.new args[:type]
288
- @cls = Net::DNS::RR::Classes.new args[:cls]
289
-
290
- @rdata = args[:rdata] ? args[:rdata].strip : ""
291
- @rdlength = args[:rdlength] || @rdata.size
292
-
293
- if self.class == Net::DNS::RR
294
- (eval "Net::DNS::RR::#@type").new(args)
295
- else
296
- hash = args - [:name,:ttl,:type,:cls]
297
- if hash.has_key? :rdata
298
- subclass_new_from_string(hash[:rdata])
299
- else
300
- subclass_new_from_hash(hash)
301
- end
302
- self.class
303
- end
304
- end # new_from_hash
305
-
306
- def new_from_binary(data,offset)
307
- if self.class == Net::DNS::RR
308
- temp = dn_expand(data,offset)[1]
309
- type = Net::DNS::RR::Types.new data.unpack("@#{temp} n")[0]
310
- (eval "Net::DNS::RR::#{type}").parse_packet(data,offset)
311
- else
312
- @name,offset = dn_expand(data,offset)
313
- rrtype,cls,@ttl,@rdlength = data.unpack("@#{offset} n2 N n")
314
- @type = Net::DNS::RR::Types.new rrtype
315
- @cls = Net::DNS::RR::Classes.new cls
316
- offset += RRFIXEDSZ
317
- offset = subclass_new_from_binary(data,offset)
318
- build_pack
319
- set_type
320
- return [self,offset]
321
- end
322
- # rescue StandardError => err
323
- # raise RRDataError, "Caught exception, maybe packet malformed: #{err}"
324
- end
325
-
326
- # Methods to be overridden by subclasses
327
- def subclass_new_from_array(arr)
328
- end
329
- def subclass_new_from_string(str)
330
- end
331
- def subclass_new_from_hash(hash)
332
- end
333
- def subclass_new_from_binary(data,offset)
334
- end
335
- def build_pack
336
- end
337
- def set_type
338
- end
339
- def get_inspect
340
- @rdata
341
- end
342
- def get_data
343
- @rdata
344
- end
345
-
346
- # NEW new method :)
347
- def self.new(*args)
348
- o = allocate
349
- obj = o.send(:initialize,*args)
350
- if self == Net::DNS::RR
351
- return obj
352
- else
353
- return o
354
- end
355
- end
356
-
357
- end # class RR
358
-
359
- end # module DNS
360
- end # module Net
361
-
362
- class RRArgumentError < ArgumentError # :nodoc:
363
- end
364
- class RRDataError < StandardError # :nodoc:
365
- end
366
-
367
- module ExtendHash # :nodoc:
368
-
369
- # Performs a sort of group difference
370
- # operation on hashes or arrays
371
- #
372
- # a = {:a=>1,:b=>2,:c=>3}
373
- # b = {:a=>1,:b=>2}
374
- # c = [:a,:c]
375
- # a-b #=> {:c=>3}
376
- # a-c #=> {:b=>2}
377
- #
378
- def -(oth)
379
- case oth
380
- when Hash
381
- delete_if {|k,v| oth.has_key? k}
382
- when Array
383
- delete_if {|k,v| oth.include? k}
384
- end
385
- end
386
- end
387
-
388
- class Hash # :nodoc:
389
- include ExtendHash
390
- end
391
-
@@ -1,71 +0,0 @@
1
- ##
2
- #
3
- # Net::DNS::RR::PTR
4
- #
5
- # $Id: PTR.rb,v 1.5 2006/07/28 07:33:36 bluemonk Exp $
6
- #
7
- ##
8
-
9
- module Net
10
- module DNS
11
- class RR
12
-
13
- #------------------------------------------------------------
14
- # RR type PTR
15
- #------------------------------------------------------------
16
- class PTR < RR
17
-
18
- # Getter for PTR resource
19
- def ptr
20
- @ptrdname.to_s
21
- end
22
- alias_method :ptrdname, :ptr
23
-
24
- private
25
-
26
- def check_ptr(str)
27
- IPAddr.new str
28
- rescue
29
- raise RRArgumentError, "PTR section not valid"
30
- end
31
-
32
- def build_pack
33
- @ptrdname_pack = pack_name(@ptrdname)
34
- @rdlength = @ptrdname_pack.size
35
- end
36
-
37
- def set_type
38
- @type = Net::DNS::RR::RRTypes.new("PTR")
39
- end
40
-
41
- def get_data
42
- @ptrdname_pack
43
- end
44
-
45
- def get_inspect
46
- "#@ptrdname"
47
- end
48
-
49
- def subclass_new_from_hash(args)
50
- if args.has_key? :ptrdname or args.has_key? :ptr
51
- @ptrdname = args[0][:ptrdname]
52
- else
53
- raise RRArgumentError, ":ptrdname or :ptr field is mandatory but missing"
54
- end
55
- end
56
-
57
- def subclass_new_from_string(str)
58
- @ptrdname = check_ptr(str)
59
- end
60
-
61
- def subclass_new_from_binary(data,offset)
62
- @ptrdname,offset = dn_expand(data,offset)
63
- return offset
64
- end
65
-
66
- end # class PTR
67
-
68
- end # class RR
69
- end # module DNS
70
- end # module Net
71
-