net-dns 0.3 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +7 -0
- data/INSTALL +8 -0
- data/Rakefile +4 -4
- data/THANKS +24 -0
- data/gemspec +3 -4
- data/lib/net/dns/dns.rb +1 -1
- data/lib/net/dns/header.rb +117 -48
- data/lib/net/dns/packet.rb +14 -0
- data/lib/net/dns/resolver.rb +91 -60
- data/lib/net/dns/rr.rb +1 -2
- data/lib/net/dns/rr/srv.rb +57 -0
- data/test/net/dns/test_header.rb +7 -7
- metadata +16 -12
- data/InstalledFiles +0 -1
data/CHANGELOG
ADDED
data/INSTALL
CHANGED
data/Rakefile
CHANGED
@@ -6,7 +6,7 @@ require 'rake/gempackagetask'
|
|
6
6
|
|
7
7
|
require 'rubygems'
|
8
8
|
|
9
|
-
$VERSION = "0.
|
9
|
+
$VERSION = "0.4"
|
10
10
|
|
11
11
|
task :package => [:version, :clean]
|
12
12
|
|
@@ -33,7 +33,7 @@ end
|
|
33
33
|
|
34
34
|
desc "Install the library"
|
35
35
|
task :install do
|
36
|
-
sh
|
36
|
+
sh("sudo ruby setup.rb")
|
37
37
|
end
|
38
38
|
|
39
39
|
desc "Build documentation"
|
@@ -55,10 +55,10 @@ SPEC = Gem::Specification.new do |s|
|
|
55
55
|
s.summary = "Pure Ruby DNS library"
|
56
56
|
candidates = Dir.glob("**/*")
|
57
57
|
s.files = candidates.delete_if do |item|
|
58
|
-
item.include?("CVS") || item.include?("rdoc") || item.include?("pkg")
|
58
|
+
item.include?("CVS") || item.include?("rdoc") || item.include?("pkg") || item.include?(".svn")
|
59
59
|
end
|
60
60
|
s.has_rdoc = true
|
61
|
-
s.extra_rdoc_files = ["README"]
|
61
|
+
s.extra_rdoc_files = ["README","AUTHORS","INSTALL", "THANKS"]
|
62
62
|
s.description = <<EOF
|
63
63
|
A pure Ruby DNS library, similar to the Perl Net::DNS library
|
64
64
|
EOF
|
data/THANKS
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
Many thanks to these wonderful people:
|
2
|
+
|
3
|
+
- Paul Barry for his excellent article on May07 issue of LinuxJournal, for the kind words and for bug reports
|
4
|
+
- Dan Janowski (and his SRV RR)
|
5
|
+
- Joshua Abraham
|
6
|
+
- Ben April
|
7
|
+
- Gene Rogers
|
8
|
+
- Nicholas Veeser
|
9
|
+
- Gildas Cherruel
|
10
|
+
- Alex Dalitz
|
11
|
+
- Cory Wright
|
12
|
+
- Nicolas Pugnant
|
13
|
+
- Andrea Peltrin
|
14
|
+
- Giovanni Corriga
|
15
|
+
- Luca Russo
|
16
|
+
- Pierguido Lambri
|
17
|
+
- Andrea Pampuri
|
18
|
+
- _koo_
|
19
|
+
- Oyku Gencay
|
20
|
+
- Eric Liedtke
|
21
|
+
- Justin Mercier
|
22
|
+
- Daniel Berger
|
23
|
+
and all #ruby-lang people
|
24
|
+
|
data/gemspec
CHANGED
@@ -7,10 +7,9 @@ SPEC = Gem::Specification.new do |s|
|
|
7
7
|
s.homepage = "http://net-dns.rubyforge.org/"
|
8
8
|
s.platform = Gem::Platform::RUBY
|
9
9
|
s.summary = "Pure Ruby DNS library"
|
10
|
-
candidates = Dir.glob("{bin,docs,lib,tests}/**/*")
|
10
|
+
candidates = Dir.glob("{bin,demo,docs,lib,tests}/**/*")
|
11
11
|
s.files = candidates.delete_if do |item|
|
12
|
-
item.include?("CVS") || item.include?("rdoc")
|
12
|
+
item.include?("CVS") || item.include?("rdoc") || item.include?(".svn")
|
13
13
|
end
|
14
14
|
s.has_rdoc = true
|
15
|
-
s.extra_rdoc_files = ["README"]
|
16
|
-
end
|
15
|
+
s.extra_rdoc_files = ["README","AUTHORS","INSTALL", "THANKS"]
|
data/lib/net/dns/dns.rb
CHANGED
data/lib/net/dns/header.rb
CHANGED
@@ -71,7 +71,110 @@ module Net # :nodoc:
|
|
71
71
|
# it and/or modify it under the same terms as Ruby itself.
|
72
72
|
#
|
73
73
|
class Header
|
74
|
+
|
75
|
+
#
|
76
|
+
# =Name
|
77
|
+
#
|
78
|
+
# Net::DNS::Header::RCode - DNS Header RCode handling class
|
79
|
+
#
|
80
|
+
# =Synopsis
|
81
|
+
#
|
82
|
+
# It should be used internally by Net::DNS::Header class. However, it's still
|
83
|
+
# possible to instantiate it directly.
|
84
|
+
#
|
85
|
+
# require 'net/dns/header'
|
86
|
+
# rcode = Net::DNS::Header::RCode.new 0
|
87
|
+
#
|
88
|
+
# =Description
|
89
|
+
#
|
90
|
+
# The RCode class represents the RCode field in the Header portion of a
|
91
|
+
# DNS packet. This field (called Response Code) is used to get informations
|
92
|
+
# about the status of a DNS operation, such as a query or an update. These
|
93
|
+
# are the values in the original Mockapetris's standard (RFC1035):
|
94
|
+
#
|
95
|
+
# * 0 No error condition
|
96
|
+
# * 1 Format error - The name server was unable to interpret
|
97
|
+
# the query.
|
98
|
+
# * 2 Server failure - The name server was
|
99
|
+
# unable to process this query due to a
|
100
|
+
# problem with the name server.
|
101
|
+
# * 3 Name Error - Meaningful only for
|
102
|
+
# responses from an authoritative name
|
103
|
+
# server, this code signifies that the
|
104
|
+
# domain name referenced in the query does
|
105
|
+
# not exist.
|
106
|
+
# * 4 Not Implemented - The name server does
|
107
|
+
# not support the requested kind of query.
|
108
|
+
# * 5 Refused - The name server refuses to
|
109
|
+
# perform the specified operation for
|
110
|
+
# policy reasons. For example, a name
|
111
|
+
# server may not wish to provide the
|
112
|
+
# information to the particular requester,
|
113
|
+
# or a name server may not wish to perform
|
114
|
+
# a particular operation (e.g., zone
|
115
|
+
# transfer) for particular data.
|
116
|
+
# * 6-15 Reserved for future use.
|
117
|
+
#
|
118
|
+
# In the next DNS RFCs, codes 6-15 has been assigned to the following
|
119
|
+
# errors:
|
120
|
+
#
|
121
|
+
# * 6 YXDomain
|
122
|
+
# * 7 YXRRSet
|
123
|
+
# * 8 NXRRSet
|
124
|
+
# * 9 NotAuth
|
125
|
+
# * 10 NotZone
|
126
|
+
#
|
127
|
+
# More RCodes has to come for TSIGs and other operations.
|
128
|
+
#
|
129
|
+
class RCode
|
130
|
+
|
131
|
+
# Constant for +rcode+ Response Code No Error
|
132
|
+
NOERROR = 0
|
133
|
+
# Constant for +rcode+ Response Code Format Error
|
134
|
+
FORMAT = 1
|
135
|
+
# Constant for +rcode+ Response Code Server Format Error
|
136
|
+
SERVER = 2
|
137
|
+
# Constant for +rcode+ Response Code Name Error
|
138
|
+
NAME = 3
|
139
|
+
# Constant for +rcode+ Response Code Not Implemented Error
|
140
|
+
NOTIMPLEMENTED = 4
|
141
|
+
# Constant for +rcode+ Response Code Refused Error
|
142
|
+
REFUSED = 5
|
143
|
+
|
144
|
+
|
145
|
+
|
146
|
+
RCodeType = %w[NoError FormErr ServFail NXDomain NotImp
|
147
|
+
Refused YXDomain YXRRSet NXRRSet NotAuth NotZone]
|
148
|
+
|
149
|
+
RCodeErrorString = ["No errors",
|
150
|
+
"The name server was unable to interpret the query",
|
151
|
+
"The name server was unable to process this query due to problem with the name server",
|
152
|
+
"Domain name referenced in the query does not exists",
|
153
|
+
"The name server does not support the requested kind of query",
|
154
|
+
"The name server refuses to perform the specified operation for policy reasons",
|
155
|
+
"",
|
156
|
+
"",
|
157
|
+
"",
|
158
|
+
"",
|
159
|
+
""]
|
160
|
+
|
161
|
+
attr_reader :code, :type, :explanation
|
74
162
|
|
163
|
+
def initialize(code)
|
164
|
+
if (0..10).include? code
|
165
|
+
@code = code
|
166
|
+
@type = RCodeType[code]
|
167
|
+
@explanation = RCodeErrorString[code]
|
168
|
+
else
|
169
|
+
raise HeaderArgumentError, "RCode #{code} out of range"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def to_s
|
174
|
+
@code.to_s
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
75
178
|
# Constant for +opCode+ query
|
76
179
|
QUERY = 0
|
77
180
|
# Constant for +opCode+ iquery
|
@@ -81,27 +184,14 @@ module Net # :nodoc:
|
|
81
184
|
# Array with given strings
|
82
185
|
OPARR = %w[QUERY IQUERY STATUS]
|
83
186
|
|
84
|
-
# Constant for +rcode+ Response Code No Error
|
85
|
-
NOERROR = 0
|
86
|
-
# Constant for +rcode+ Response Code Format Error
|
87
|
-
FORMAT = 1
|
88
|
-
# Constant for +rcode+ Response Code Server Format Error
|
89
|
-
SERVER = 2
|
90
|
-
# Constant for +rcode+ Response Code Name Error
|
91
|
-
NAME = 3
|
92
|
-
# Constant for +rcode+ Response Code Not Implemented Error
|
93
|
-
NOTIMPLEMENTED = 4
|
94
|
-
# Constant for +rcode+ Response Code Refused Error
|
95
|
-
REFUSED = 5
|
96
|
-
# Array with given strings
|
97
|
-
CODEARR = %w[NOERROR FORMAT SERVER NAME NOTIMPLEMENTED REFUSED]
|
98
|
-
|
99
187
|
@@id_arr = []
|
100
188
|
|
101
189
|
# Reader for +id+ attribute
|
102
190
|
attr_reader :id
|
103
191
|
# Reader for the operational code
|
104
192
|
attr_reader :opCode
|
193
|
+
# Reader for the rCode instance
|
194
|
+
attr_reader :rCode
|
105
195
|
# Reader for question section entries number
|
106
196
|
attr_reader :qdCount
|
107
197
|
# Reader for answer section entries number
|
@@ -176,7 +266,6 @@ module Net # :nodoc:
|
|
176
266
|
end
|
177
267
|
end
|
178
268
|
|
179
|
-
|
180
269
|
# Inspect method, prints out all the options and relative values.
|
181
270
|
#
|
182
271
|
# p Net::DNS::Header.new
|
@@ -201,7 +290,7 @@ module Net # :nodoc:
|
|
201
290
|
";; ra = #@ra\t" +
|
202
291
|
"ad = #@ad\t" +
|
203
292
|
"cd = #@cd\t" +
|
204
|
-
"rcode = #{
|
293
|
+
"rcode = #{@rCode.type}\n" +
|
205
294
|
";; qdCount = #@qdCount\t"+
|
206
295
|
"anCount = #@anCount\t"+
|
207
296
|
"nsCount = #@nsCount\t"+
|
@@ -260,7 +349,7 @@ module Net # :nodoc:
|
|
260
349
|
arr = []
|
261
350
|
arr.push(@id)
|
262
351
|
arr.push((@qr<<7)|(@opCode<<3)|(@aa<<2)|(@tc<<1)|@rd)
|
263
|
-
arr.push((@ra<<7)|(@ad<<5)|(@cd<<4)|@rCode)
|
352
|
+
arr.push((@ra<<7)|(@ad<<5)|(@cd<<4)|@rCode.code)
|
264
353
|
arr.push(@qdCount)
|
265
354
|
arr.push(@anCount)
|
266
355
|
arr.push(@nsCount)
|
@@ -538,50 +627,30 @@ module Net # :nodoc:
|
|
538
627
|
# Returns an error array for the header response code, or
|
539
628
|
# +nil+ if no error is generated.
|
540
629
|
#
|
541
|
-
# error, cause = header.
|
630
|
+
# error, cause = header.rCode_str
|
542
631
|
# puts "Error #{error} cause by: #{cause}" if error
|
543
|
-
# #=> Error
|
632
|
+
# #=> Error ForErr caused by: The name server
|
544
633
|
# #=> was unable to interpret the query
|
545
634
|
#
|
546
635
|
def rCode_str
|
547
|
-
|
548
|
-
when NOERROR
|
549
|
-
return nil,nil
|
550
|
-
when FORMAT
|
551
|
-
return "Format Error", "The name server was unable to interpret the query"
|
552
|
-
when SERVER
|
553
|
-
return "Server Failure",
|
554
|
-
"The name server was unable to process this query due to problem with the name server"
|
555
|
-
when NAME
|
556
|
-
return "Name Error", "Domain name referenced in the query does not exists"
|
557
|
-
when NOTIMPLEMENTED
|
558
|
-
return "Not Implemented",
|
559
|
-
"The name server does not support the requested kind of query"
|
560
|
-
when REFUSED
|
561
|
-
return "Refused",
|
562
|
-
"The name server refuses to perform the specified operation for policy reasons"
|
563
|
-
end
|
636
|
+
return rCode.type, rCode.explanation
|
564
637
|
end
|
565
638
|
|
566
|
-
#
|
639
|
+
# Checks for errors in the DNS packet
|
567
640
|
#
|
568
|
-
#
|
641
|
+
# unless header.error?
|
569
642
|
# puts "No errors in DNS answer packet"
|
570
643
|
# end
|
571
644
|
#
|
572
|
-
def
|
573
|
-
@rCode
|
645
|
+
def error?
|
646
|
+
@rCode.code > 0
|
574
647
|
end
|
575
648
|
|
576
649
|
# Set the rCode value. This should only be done in DNS
|
577
650
|
# answer packets.
|
578
651
|
#
|
579
652
|
def rCode=(val)
|
580
|
-
|
581
|
-
@rCode = val
|
582
|
-
else
|
583
|
-
raise HeaderArgumentError, ":rCode must be one of #{CODEARR.join(" ")}"
|
584
|
-
end
|
653
|
+
@rCode = RCode.new(val)
|
585
654
|
end
|
586
655
|
|
587
656
|
# Sets the number of entries in a question section
|
@@ -629,7 +698,7 @@ module Net # :nodoc:
|
|
629
698
|
def new_from_scratch
|
630
699
|
@id = genID # generate ad unique id
|
631
700
|
@qr = @aa = @tc = @ra = @ad = @cd = 0
|
632
|
-
@rCode =
|
701
|
+
@rCode = RCode.new(0) # no error
|
633
702
|
@anCount = @nsCount = @arCount = 0
|
634
703
|
@rd = @qdCount = 1
|
635
704
|
@opCode = QUERY # standard query, default message
|
@@ -649,7 +718,7 @@ module Net # :nodoc:
|
|
649
718
|
@ra = (arr[2] >> 7) & 0x01
|
650
719
|
@ad = (arr[2] >> 5) & 0x01
|
651
720
|
@cd = (arr[2] >> 4) & 0x01
|
652
|
-
@rCode =
|
721
|
+
@rCode = RCode.new(arr[2] & 0xf)
|
653
722
|
@qdCount = arr[3]
|
654
723
|
@anCount = arr[4]
|
655
724
|
@nsCount = arr[5]
|
data/lib/net/dns/packet.rb
CHANGED
@@ -456,6 +456,20 @@ module Net # :nodoc:
|
|
456
456
|
yield elem.ptrdname
|
457
457
|
end
|
458
458
|
end
|
459
|
+
|
460
|
+
# Chacks whether a query has returned a NXDOMAIN error,
|
461
|
+
# meaning the domain name queried doesn't exists.
|
462
|
+
#
|
463
|
+
# %w[a.com google.com ibm.com d.com].each do |domain|
|
464
|
+
# response = Net::DNS::Resolver.new.send(domain)
|
465
|
+
# puts "#{domain} doesn't exist" if response.nxdomain?
|
466
|
+
# end
|
467
|
+
# #=> a.com doesn't exist
|
468
|
+
# #=> d.com doesn't exist
|
469
|
+
#
|
470
|
+
def nxdomain?
|
471
|
+
header.rCode == Net::DNS::Header::NAME
|
472
|
+
end
|
459
473
|
|
460
474
|
private
|
461
475
|
|
data/lib/net/dns/resolver.rb
CHANGED
@@ -11,6 +11,7 @@ require 'logger'
|
|
11
11
|
require 'net/dns/packet'
|
12
12
|
require 'net/dns/resolver/timeouts'
|
13
13
|
|
14
|
+
alias old_send send
|
14
15
|
|
15
16
|
module Net # :nodoc:
|
16
17
|
module DNS
|
@@ -104,7 +105,7 @@ module Net # :nodoc:
|
|
104
105
|
:defname => true,
|
105
106
|
:dns_search => true,
|
106
107
|
:use_tcp => false,
|
107
|
-
:
|
108
|
+
:ignore_truncated => false,
|
108
109
|
:packet_size => 512,
|
109
110
|
:tcp_timeout => TcpTimeout.new(120),
|
110
111
|
:udp_timeout => UdpTimeout.new(0)}
|
@@ -658,10 +659,10 @@ module Net # :nodoc:
|
|
658
659
|
end
|
659
660
|
alias usevc= use_tcp=
|
660
661
|
|
661
|
-
def
|
662
|
-
@config[:
|
662
|
+
def ignore_truncated?
|
663
|
+
@config[:ignore_truncated]
|
663
664
|
end
|
664
|
-
alias_method :
|
665
|
+
alias_method :ignore_truncated, :ignore_truncated?
|
665
666
|
|
666
667
|
def ignore_truncated=(bool)
|
667
668
|
case bool
|
@@ -890,7 +891,6 @@ module Net # :nodoc:
|
|
890
891
|
|
891
892
|
end
|
892
893
|
|
893
|
-
|
894
894
|
# Performs a DNS query for the given name. Neither the
|
895
895
|
# searchlist nor the default domain will be appended.
|
896
896
|
#
|
@@ -924,6 +924,8 @@ module Net # :nodoc:
|
|
924
924
|
raise ResolverError, "No nameservers specified!"
|
925
925
|
end
|
926
926
|
|
927
|
+
method = :send_udp
|
928
|
+
|
927
929
|
if argument.kind_of? Net::DNS::Packet
|
928
930
|
packet = argument
|
929
931
|
else
|
@@ -939,33 +941,87 @@ module Net # :nodoc:
|
|
939
941
|
if packet_size > @config[:packet_size] # Must use TCP, either plain or raw
|
940
942
|
if @raw # Use raw sockets?
|
941
943
|
@logger.info "Sending #{packet_size} bytes using TCP over RAW socket"
|
942
|
-
|
944
|
+
method = :send_raw_tcp
|
943
945
|
else
|
944
946
|
@logger.info "Sending #{packet_size} bytes using TCP"
|
945
|
-
|
947
|
+
method = :send_tcp
|
946
948
|
end
|
947
949
|
else # Packet size is inside the boundaries
|
948
950
|
if @raw # Use raw sockets?
|
949
951
|
@logger.info "Sending #{packet_size} bytes using UDP over RAW socket"
|
950
|
-
|
952
|
+
method = :send_raw_udp
|
951
953
|
elsif use_tcp? # User requested TCP
|
952
954
|
@logger.info "Sending #{packet_size} bytes using TCP"
|
953
|
-
|
955
|
+
method = :send_tcp
|
954
956
|
else # Finally use UDP
|
955
957
|
@logger.info "Sending #{packet_size} bytes using UDP"
|
956
|
-
ans = send_udp(packet,packet_data)
|
957
958
|
end
|
958
959
|
end
|
959
960
|
|
960
|
-
if
|
961
|
+
if type == Net::DNS::AXFR
|
962
|
+
if @raw
|
963
|
+
@logger.warn "AXFR query, switching to TCP over RAW socket"
|
964
|
+
method = :send_raw_tcp
|
965
|
+
else
|
966
|
+
@logger.warn "AXFR query, switching to TCP"
|
967
|
+
method = :send_tcp
|
968
|
+
end
|
969
|
+
end
|
970
|
+
|
971
|
+
ans = self.old_send(method,packet,packet_data)
|
972
|
+
|
973
|
+
unless ans
|
974
|
+
@logger.fatal "No response from nameservers list: aborting"
|
975
|
+
raise NoResponseError
|
976
|
+
end
|
977
|
+
|
978
|
+
@logger.info "Received #{ans[0].size} bytes from #{ans[1][2]+":"+ans[1][1].to_s}"
|
979
|
+
response = Net::DNS::Packet.parse(ans[0],ans[1])
|
980
|
+
|
981
|
+
if response.header.truncated? and not ignore_truncated?
|
961
982
|
@logger.warn "Packet truncated, retrying using TCP"
|
962
|
-
|
983
|
+
self.use_tcp = true
|
984
|
+
begin
|
985
|
+
return send(argument,type,cls)
|
986
|
+
ensure
|
987
|
+
self.use_tcp = false
|
988
|
+
end
|
963
989
|
end
|
964
990
|
|
965
|
-
|
991
|
+
return response
|
966
992
|
end
|
967
|
-
|
968
|
-
|
993
|
+
|
994
|
+
#
|
995
|
+
# Performs a zone transfer for the zone passed as a parameter.
|
996
|
+
#
|
997
|
+
# It is actually only a wrapper to a send with type set as Net::DNS::AXFR,
|
998
|
+
# since it is using the same infrastucture.
|
999
|
+
#
|
1000
|
+
def axfr(name,cls=Net::DNS::IN)
|
1001
|
+
@logger.info "Requested AXFR transfer, zone #{name} class #{cls}"
|
1002
|
+
send(name,Net::DNS::AXFR,cls)
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
#
|
1006
|
+
# Performs an MX query for the domain name passed as parameter.
|
1007
|
+
#
|
1008
|
+
# It actually uses the same methods a normal Resolver query would
|
1009
|
+
# use, but automatically sort the results based on preferences
|
1010
|
+
# and returns an ordered array.
|
1011
|
+
#
|
1012
|
+
# Example:
|
1013
|
+
#
|
1014
|
+
# res = Net::DNS::Resolver.new
|
1015
|
+
# res.mx("google.com")
|
1016
|
+
#
|
1017
|
+
def mx(name,cls=Net::DNS::IN)
|
1018
|
+
arr = []
|
1019
|
+
send(name, Net::DNS::MX, cls).answer.each do |entry|
|
1020
|
+
arr << entry if entry.type == 'MX'
|
1021
|
+
end
|
1022
|
+
return arr.sort_by {|a| a.preference}
|
1023
|
+
end
|
1024
|
+
|
969
1025
|
private
|
970
1026
|
|
971
1027
|
# Parse a configuration file specified as the argument.
|
@@ -1059,18 +1115,12 @@ module Net # :nodoc:
|
|
1059
1115
|
|
1060
1116
|
ans = nil
|
1061
1117
|
length = [packet_data.size].pack("n")
|
1118
|
+
|
1062
1119
|
@config[:nameservers].each do |ns|
|
1063
1120
|
begin
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
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
|
1121
|
+
buffer = ""
|
1122
|
+
socket = Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)
|
1123
|
+
socket.bind(Socket.pack_sockaddr_in(@config[:source_port],@config[:source_address].to_s))
|
1074
1124
|
|
1075
1125
|
sockaddr = Socket.pack_sockaddr_in(@config[:port],ns.to_s)
|
1076
1126
|
|
@@ -1080,50 +1130,39 @@ module Net # :nodoc:
|
|
1080
1130
|
socket.write(length+packet_data)
|
1081
1131
|
ans = socket.recv(Net::DNS::INT16SZ)
|
1082
1132
|
len = ans.unpack("n")[0]
|
1133
|
+
|
1134
|
+
@logger.info "Receiving #{len} bytes..."
|
1083
1135
|
|
1084
1136
|
if len == 0
|
1085
1137
|
@logger.warn "Receiving 0 lenght packet from nameserver #{ns}, trying next."
|
1086
1138
|
next
|
1087
1139
|
end
|
1140
|
+
|
1141
|
+
while (buffer.size < len)
|
1142
|
+
left = len - buffer.size
|
1143
|
+
temp,from = socket.recvfrom(left)
|
1144
|
+
buffer += temp
|
1145
|
+
end
|
1088
1146
|
|
1089
|
-
|
1090
|
-
unless ans.size == len
|
1147
|
+
unless buffer.size == len
|
1091
1148
|
@logger.warn "Malformed packet from nameserver #{ns}, trying next."
|
1092
1149
|
next
|
1093
1150
|
end
|
1094
1151
|
end
|
1095
|
-
|
1096
|
-
ans = [ans,["",@config[:port],ns.to_s,ns.to_s]]
|
1097
|
-
@logger.info "Received #{ans[0].size} bytes from #{ans[1][2]+":"+ans[1][1].to_s}"
|
1098
|
-
|
1152
|
+
return [buffer,["",@config[:port],ns.to_s,ns.to_s]]
|
1099
1153
|
rescue TimeoutError
|
1100
1154
|
@logger.warn "Nameserver #{ns} not responding within TCP timeout, trying next one"
|
1101
1155
|
next
|
1102
1156
|
ensure
|
1103
|
-
socket.close
|
1157
|
+
socket.close
|
1104
1158
|
end
|
1105
1159
|
end
|
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
|
1113
1160
|
end
|
1114
1161
|
|
1115
|
-
|
1116
1162
|
def send_udp(packet,packet_data)
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
@logger.info "Using persistent socket #{socket.inspect}"
|
1121
|
-
else
|
1122
|
-
socket = UDPSocket.new
|
1123
|
-
socket.bind(@config[:source_address].to_s,@config[:source_port])
|
1124
|
-
@@udp_socket = socket if @config[:persistent_udp]
|
1125
|
-
end
|
1126
|
-
|
1163
|
+
socket = UDPSocket.new
|
1164
|
+
socket.bind(@config[:source_address].to_s,@config[:source_port])
|
1165
|
+
|
1127
1166
|
ans = nil
|
1128
1167
|
response = ""
|
1129
1168
|
@config[:nameservers].each do |ns|
|
@@ -1133,21 +1172,13 @@ module Net # :nodoc:
|
|
1133
1172
|
socket.send(packet_data,0,ns.to_s,@config[:port])
|
1134
1173
|
ans = socket.recvfrom(@config[:packet_size])
|
1135
1174
|
end
|
1136
|
-
if ans
|
1137
|
-
@logger.info "Received #{ans[0].size} bytes from #{ans[1][2]+":"+ans[1][1].to_s}"
|
1138
|
-
break
|
1139
|
-
end
|
1175
|
+
break if ans
|
1140
1176
|
rescue TimeoutError
|
1141
1177
|
@logger.warn "Nameserver #{ns} not responding within UDP timeout, trying next one"
|
1142
1178
|
next
|
1143
1179
|
end
|
1144
1180
|
end
|
1145
|
-
|
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
|
1181
|
+
ans
|
1151
1182
|
end
|
1152
1183
|
|
1153
1184
|
def valid?(name)
|
data/lib/net/dns/rr.rb
CHANGED
@@ -0,0 +1,57 @@
|
|
1
|
+
##
|
2
|
+
#
|
3
|
+
# Net::DNS::RR::SRV
|
4
|
+
#
|
5
|
+
# $Id$
|
6
|
+
#
|
7
|
+
##
|
8
|
+
|
9
|
+
|
10
|
+
module Net
|
11
|
+
module DNS
|
12
|
+
class RR
|
13
|
+
|
14
|
+
#------------------------------------------------------------
|
15
|
+
# RR type SRV
|
16
|
+
#------------------------------------------------------------
|
17
|
+
class SRV < RR
|
18
|
+
|
19
|
+
attr_reader :priority, :weight, :port, :host
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def build_pack
|
24
|
+
str = ""
|
25
|
+
end
|
26
|
+
|
27
|
+
def set_type
|
28
|
+
@type = Net::DNS::RR::Types.new("SRV")
|
29
|
+
end
|
30
|
+
|
31
|
+
def subclass_new_from_binary(data,offset)
|
32
|
+
off_end = offset + @rdlength
|
33
|
+
@priority, @weight, @port = data.unpack("@#{offset} n n n")
|
34
|
+
offset+=6
|
35
|
+
|
36
|
+
@host=[]
|
37
|
+
while offset < off_end
|
38
|
+
len = data.unpack("@#{offset} C")[0]
|
39
|
+
offset += 1
|
40
|
+
str = data[offset..offset+len-1]
|
41
|
+
offset += len
|
42
|
+
@host << str
|
43
|
+
end
|
44
|
+
@host=@host.join(".")
|
45
|
+
offset
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
end # class SRV
|
50
|
+
end # class RR
|
51
|
+
|
52
|
+
|
53
|
+
end # module DNS
|
54
|
+
end # module Net
|
55
|
+
|
56
|
+
|
57
|
+
|
data/test/net/dns/test_header.rb
CHANGED
@@ -16,7 +16,7 @@ class Test_Header < Test::Unit::TestCase
|
|
16
16
|
:cd => 0,
|
17
17
|
:ad => 0,
|
18
18
|
:ra => 1,
|
19
|
-
:rCode => Header::FORMAT,
|
19
|
+
:rCode => Header::RCode::FORMAT,
|
20
20
|
:qdCount => 1,
|
21
21
|
:anCount => 2,
|
22
22
|
:nsCount => 3,
|
@@ -31,7 +31,7 @@ class Test_Header < Test::Unit::TestCase
|
|
31
31
|
@modified.rd = false
|
32
32
|
@modified.cd = false
|
33
33
|
@modified.ra = true
|
34
|
-
@modified.rCode = Header::FORMAT
|
34
|
+
@modified.rCode = Header::RCode::FORMAT
|
35
35
|
@modified.qdCount = 1
|
36
36
|
@modified.anCount = 2
|
37
37
|
@modified.nsCount = 3
|
@@ -54,7 +54,7 @@ class Test_Header < Test::Unit::TestCase
|
|
54
54
|
assert_equal(@default.checking?, true)
|
55
55
|
assert_equal(@default.verified?, false)
|
56
56
|
assert_equal(@default.r_available?, false)
|
57
|
-
assert_equal(@default.rCode, Header::NOERROR)
|
57
|
+
assert_equal(@default.rCode.code, Header::RCode::NOERROR)
|
58
58
|
assert_equal(@default.qdCount, 1)
|
59
59
|
assert_equal(@default.anCount, 0)
|
60
60
|
assert_equal(@default.nsCount, 0)
|
@@ -70,7 +70,7 @@ class Test_Header < Test::Unit::TestCase
|
|
70
70
|
assert_equal(@hash.checking?, true)
|
71
71
|
assert_equal(@hash.verified?, false)
|
72
72
|
assert_equal(@hash.r_available?, true)
|
73
|
-
assert_equal(@hash.rCode, Header::FORMAT)
|
73
|
+
assert_equal(@hash.rCode.code, Header::RCode::FORMAT)
|
74
74
|
assert_equal(@hash.qdCount, 1)
|
75
75
|
assert_equal(@hash.anCount, 2)
|
76
76
|
assert_equal(@hash.nsCount, 3)
|
@@ -86,7 +86,7 @@ class Test_Header < Test::Unit::TestCase
|
|
86
86
|
assert_equal(@modified.checking?, true)
|
87
87
|
assert_equal(@modified.verified?, false)
|
88
88
|
assert_equal(@modified.r_available?, true)
|
89
|
-
assert_equal(@modified.rCode, Header::FORMAT)
|
89
|
+
assert_equal(@modified.rCode.code, Header::RCode::FORMAT)
|
90
90
|
assert_equal(@modified.qdCount, 1)
|
91
91
|
assert_equal(@modified.anCount, 2)
|
92
92
|
assert_equal(@modified.nsCount, 3)
|
@@ -104,7 +104,7 @@ class Test_Header < Test::Unit::TestCase
|
|
104
104
|
assert_equal(@binary.checking?, true)
|
105
105
|
assert_equal(@binary.verified?, false)
|
106
106
|
assert_equal(@binary.r_available?, true)
|
107
|
-
assert_equal(@binary.rCode, Header::FORMAT)
|
107
|
+
assert_equal(@binary.rCode.code, Header::RCode::FORMAT)
|
108
108
|
assert_equal(@binary.qdCount, 1)
|
109
109
|
assert_equal(@binary.anCount, 2)
|
110
110
|
assert_equal(@binary.nsCount, 3)
|
@@ -150,7 +150,7 @@ class Test_Header < Test::Unit::TestCase
|
|
150
150
|
@default.ad=2
|
151
151
|
end
|
152
152
|
assert_raise(HeaderArgumentError) do
|
153
|
-
@default.rCode=
|
153
|
+
@default.rCode=46
|
154
154
|
end
|
155
155
|
assert_raise(HeaderWrongCount) do
|
156
156
|
@default.qdCount=100000
|
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.
|
7
|
-
date: 2007-
|
6
|
+
version: "0.4"
|
7
|
+
date: 2007-05-13 00:00:00 +01:00
|
8
8
|
summary: Pure Ruby DNS library
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -30,22 +30,22 @@ authors:
|
|
30
30
|
- Marco Ceresa
|
31
31
|
files:
|
32
32
|
- demo
|
33
|
+
- demo/check_soa.rb
|
34
|
+
- demo/threads.rb
|
33
35
|
- README
|
34
36
|
- setup.rb
|
35
|
-
-
|
37
|
+
- CHANGELOG
|
36
38
|
- gemspec
|
37
39
|
- Rakefile
|
38
40
|
- AUTHORS
|
39
41
|
- lib
|
40
|
-
- test
|
41
|
-
- THANKS
|
42
|
-
- INSTALL
|
43
|
-
- demo/check_soa.rb
|
44
|
-
- demo/threads.rb
|
45
42
|
- lib/net
|
46
43
|
- lib/net/dns
|
47
44
|
- lib/net/dns/names
|
45
|
+
- lib/net/dns/names/names.rb
|
48
46
|
- lib/net/dns/resolver
|
47
|
+
- lib/net/dns/resolver/timeouts.rb
|
48
|
+
- lib/net/dns/resolver/socks.rb
|
49
49
|
- lib/net/dns/resolver.rb
|
50
50
|
- lib/net/dns/dns.rb
|
51
51
|
- lib/net/dns/rr.rb
|
@@ -53,9 +53,6 @@ files:
|
|
53
53
|
- lib/net/dns/header.rb
|
54
54
|
- lib/net/dns/packet.rb
|
55
55
|
- lib/net/dns/rr
|
56
|
-
- lib/net/dns/names/names.rb
|
57
|
-
- lib/net/dns/resolver/timeouts.rb
|
58
|
-
- lib/net/dns/resolver/socks.rb
|
59
56
|
- lib/net/dns/rr/null.rb
|
60
57
|
- lib/net/dns/rr/types.rb
|
61
58
|
- lib/net/dns/rr/hinfo.rb
|
@@ -69,25 +66,32 @@ files:
|
|
69
66
|
- lib/net/dns/rr/ns.rb
|
70
67
|
- lib/net/dns/rr/classes.rb
|
71
68
|
- lib/net/dns/rr/ptr.rb
|
69
|
+
- lib/net/dns/rr/srv.rb
|
70
|
+
- test
|
72
71
|
- test/net
|
73
72
|
- test/net/dns
|
74
73
|
- test/net/dns/test_packet.rb
|
75
74
|
- test/net/dns/test_rr.rb
|
76
75
|
- test/net/dns/resolver
|
76
|
+
- test/net/dns/resolver/test_timeouts.rb
|
77
77
|
- test/net/dns/test_header.rb
|
78
78
|
- test/net/dns/test_question.rb
|
79
79
|
- test/net/dns/rr
|
80
|
-
- test/net/dns/resolver/test_timeouts.rb
|
81
80
|
- test/net/dns/rr/test_types.rb
|
82
81
|
- test/net/dns/rr/test_ns.rb
|
83
82
|
- test/net/dns/rr/test_a.rb
|
84
83
|
- test/net/dns/rr/test_classes.rb
|
84
|
+
- THANKS
|
85
|
+
- INSTALL
|
85
86
|
test_files: []
|
86
87
|
|
87
88
|
rdoc_options: []
|
88
89
|
|
89
90
|
extra_rdoc_files:
|
90
91
|
- README
|
92
|
+
- AUTHORS
|
93
|
+
- INSTALL
|
94
|
+
- THANKS
|
91
95
|
executables: []
|
92
96
|
|
93
97
|
extensions: []
|
data/InstalledFiles
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
/usr/local/lib/site_ruby/1.8/net/dns/rr.rb
|