mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/resolv.rb (Resolv::DNS::Message::MessageDecoder#inspect):
implemented. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26231 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
1dc1bf28ab
commit
50b8893d56
3 changed files with 121 additions and 2 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
Sun Jan 3 01:29:18 2010 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* lib/resolv.rb (Resolv::DNS::Message::MessageDecoder#inspect):
|
||||||
|
implemented.
|
||||||
|
|
||||||
Sat Jan 2 15:57:54 2010 Tanaka Akira <akr@fsij.org>
|
Sat Jan 2 15:57:54 2010 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* lib/resolv.rb (Resolv::DNS#initialize): new option :nameserver_port.
|
* lib/resolv.rb (Resolv::DNS#initialize): new option :nameserver_port.
|
||||||
|
|
|
@ -1385,6 +1385,10 @@ class Resolv
|
||||||
yield self
|
yield self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def inspect
|
||||||
|
"\#<#{self.class}: #{@data[0, @index].inspect} #{@data[@index..-1].inspect}>"
|
||||||
|
end
|
||||||
|
|
||||||
def get_length16
|
def get_length16
|
||||||
len, = self.get_unpack('n')
|
len, = self.get_unpack('n')
|
||||||
save_limit = @limit
|
save_limit = @limit
|
||||||
|
@ -2097,8 +2101,11 @@ class Resolv
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize(address) # :nodoc:
|
def initialize(address) # :nodoc:
|
||||||
unless address.kind_of?(String) && address.length == 4
|
unless address.kind_of?(String)
|
||||||
raise ArgumentError.new('IPv4 address must be 4 bytes')
|
raise ArgumentError, 'IPv4 address must be a string'
|
||||||
|
end
|
||||||
|
unless address.length == 4
|
||||||
|
raise ArgumentError, "IPv4 address expects 4 bytes but #{address.length} bytes"
|
||||||
end
|
end
|
||||||
@address = address
|
@address = address
|
||||||
end
|
end
|
||||||
|
|
107
test/resolv/test_dns.rb
Normal file
107
test/resolv/test_dns.rb
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
require 'test/unit'
|
||||||
|
require 'resolv'
|
||||||
|
require 'socket'
|
||||||
|
|
||||||
|
class TestResolvDNS < Test::Unit::TestCase
|
||||||
|
def setup
|
||||||
|
@save_do_not_reverse_lookup = BasicSocket.do_not_reverse_lookup
|
||||||
|
BasicSocket.do_not_reverse_lookup = true
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
BasicSocket.do_not_reverse_lookup = @save_do_not_reverse_lookup
|
||||||
|
end
|
||||||
|
|
||||||
|
def with_udp(host, port)
|
||||||
|
u = UDPSocket.new
|
||||||
|
begin
|
||||||
|
u.bind(host, port)
|
||||||
|
yield u
|
||||||
|
ensure
|
||||||
|
u.close
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_query_ipv4_address
|
||||||
|
with_udp('127.0.0.1', 0) {|u|
|
||||||
|
_, server_port, _, server_address = u.addr
|
||||||
|
begin
|
||||||
|
th = Thread.new {
|
||||||
|
Resolv::DNS.open(:nameserver_port => [[server_address, server_port]]) {|dns|
|
||||||
|
dns.getresources("foo.example.org", Resolv::DNS::Resource::IN::A)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg, (af, client_port, _, client_address) = u.recvfrom(4096)
|
||||||
|
id, word2, qdcount, ancount, nscount, arcount = msg.unpack("nnnnnn")
|
||||||
|
qr = (word2 & 0x8000) >> 15
|
||||||
|
opcode = (word2 & 0x7800) >> 11
|
||||||
|
aa = (word2 & 0x0400) >> 10
|
||||||
|
tc = (word2 & 0x0200) >> 9
|
||||||
|
rd = (word2 & 0x0100) >> 8
|
||||||
|
ra = (word2 & 0x0080) >> 7
|
||||||
|
z = (word2 & 0x0070) >> 4
|
||||||
|
rcode = word2 & 0x000f
|
||||||
|
rest = msg[12..-1]
|
||||||
|
assert_equal(0, qr) # 0:query 1:response
|
||||||
|
assert_equal(0, opcode) # 0:QUERY 1:IQUERY 2:STATUS
|
||||||
|
assert_equal(0, aa) # Authoritative Answer
|
||||||
|
assert_equal(0, tc) # TrunCation
|
||||||
|
assert_equal(1, rd) # Recursion Desired
|
||||||
|
assert_equal(0, ra) # Recursion Available
|
||||||
|
assert_equal(0, z) # Reserved for future use
|
||||||
|
assert_equal(0, rcode) # 0:No-error 1:Format-error 2:Server-failure 3:Name-Error 4:Not-Implemented 5:Refused
|
||||||
|
assert_equal(1, qdcount) # number of entries in the question section.
|
||||||
|
assert_equal(0, ancount) # number of entries in the answer section.
|
||||||
|
assert_equal(0, nscount) # number of entries in the authority records section.
|
||||||
|
assert_equal(0, arcount) # number of entries in the additional records section.
|
||||||
|
name = [3, "foo", 7, "example", 3, "org", 0].pack("Ca*Ca*Ca*C")
|
||||||
|
assert_operator(rest, :start_with?, name)
|
||||||
|
rest = rest[name.length..-1]
|
||||||
|
assert_equal(4, rest.length)
|
||||||
|
qtype, qclass = rest.unpack("nn")
|
||||||
|
assert_equal(1, qtype) # A
|
||||||
|
assert_equal(1, qtype) # IN
|
||||||
|
id = id
|
||||||
|
qr = 1
|
||||||
|
opcode = opcode
|
||||||
|
aa = 0
|
||||||
|
tc = 0
|
||||||
|
rd = rd
|
||||||
|
ra = 1
|
||||||
|
z = 0
|
||||||
|
rcode = 0
|
||||||
|
qdcount = 0
|
||||||
|
ancount = 1
|
||||||
|
nscount = 0
|
||||||
|
arcount = 0
|
||||||
|
word2 = (qr << 15) |
|
||||||
|
(opcode << 11) |
|
||||||
|
(aa << 10) |
|
||||||
|
(tc << 9) |
|
||||||
|
(rd << 8) |
|
||||||
|
(ra << 7) |
|
||||||
|
(z << 4) |
|
||||||
|
rcode
|
||||||
|
msg = [id, word2, qdcount, ancount, nscount, arcount].pack("nnnnnn")
|
||||||
|
type = 1
|
||||||
|
klass = 1
|
||||||
|
ttl = 3600
|
||||||
|
rdlength = 4
|
||||||
|
rdata = [192,0,2,1].pack("CCCC") # 192.0.2.1 (TEST-NET address) RFC 3330
|
||||||
|
rr = [name, type, klass, ttl, rdlength, rdata].pack("a*nnNna*")
|
||||||
|
msg << rr
|
||||||
|
u.send(msg, 0, client_address, client_port)
|
||||||
|
result = th.value
|
||||||
|
assert_instance_of(Array, result)
|
||||||
|
assert_equal(1, result.length)
|
||||||
|
rr = result[0]
|
||||||
|
assert_instance_of(Resolv::DNS::Resource::IN::A, rr)
|
||||||
|
assert_instance_of(Resolv::IPv4, rr.address)
|
||||||
|
assert_equal("192.0.2.1", rr.address.to_s)
|
||||||
|
assert_equal(3600, rr.ttl)
|
||||||
|
ensure
|
||||||
|
th.join
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
Loading…
Add table
Add a link
Reference in a new issue