Skip to content

Commit 52b4950

Browse files
committed
Land rapid7#5498, @hmoore-r7's patch for a number of Net::DNS/enum_dns issues
2 parents 093f339 + c800179 commit 52b4950

File tree

3 files changed

+133
-178
lines changed

3 files changed

+133
-178
lines changed

lib/net/dns/resolver.rb

Lines changed: 56 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ module DNS
8787
#
8888
class Resolver
8989

90+
class NextNameserver < RuntimeError
91+
end
92+
9093
# An hash with the defaults values of almost all the
9194
# configuration parameters of a resolver object. See
9295
# the description for each parameter to have an
@@ -109,7 +112,7 @@ class Resolver
109112
:ignore_truncated => false,
110113
:packet_size => 512,
111114
:tcp_timeout => TcpTimeout.new(120),
112-
:udp_timeout => UdpTimeout.new(0)}
115+
:udp_timeout => UdpTimeout.new(5)}
113116

114117
# Create a new resolver object.
115118
#
@@ -887,8 +890,11 @@ def query(name,type=Net::DNS::A,cls=Net::DNS::IN)
887890
end
888891

889892
@logger.debug "Query(#{name},#{Net::DNS::RR::Types.new(type)},#{Net::DNS::RR::Classes.new(cls)})"
890-
891-
send(name,type,cls)
893+
begin
894+
send(name,type,cls)
895+
rescue ::NoResponseError
896+
return
897+
end
892898

893899
end
894900

@@ -1011,13 +1017,13 @@ def axfr(name,cls=Net::DNS::IN)
10111017
packet_data = packet.data
10121018
packet_size = packet_data.size
10131019

1014-
if @raw
1015-
@logger.warn "AXFR query, switching to TCP over RAW socket"
1016-
method = :send_raw_tcp
1017-
else
1018-
@logger.warn "AXFR query, switching to TCP"
1019-
method = :send_tcp
1020-
end
1020+
if @raw
1021+
@logger.warn "AXFR query, switching to TCP over RAW socket"
1022+
method = :send_raw_tcp
1023+
else
1024+
@logger.warn "AXFR query, switching to TCP"
1025+
method = :send_tcp
1026+
end
10211027

10221028
answers = []
10231029
soa = 0
@@ -1026,7 +1032,7 @@ def axfr(name,cls=Net::DNS::IN)
10261032

10271033
begin
10281034
response = Net::DNS::Packet.parse(ans[0],ans[1])
1029-
if response.answer[0].type == "SOA"
1035+
if response && response.answer && response.answer[0] && response.answer[0].type == "SOA"
10301036
soa += 1
10311037
if soa >= 2
10321038
break
@@ -1167,50 +1173,54 @@ def send_tcp(packet,packet_data)
11671173
sockaddr = Socket.pack_sockaddr_in(@config[:port],ns.to_s)
11681174

11691175
@config[:tcp_timeout].timeout do
1170-
catch "next nameserver" do
1171-
socket.connect(sockaddr)
1172-
@logger.info "Contacting nameserver #{ns} port #{@config[:port]}"
1173-
socket.write(length+packet_data)
1174-
got_something = false
1175-
loop do
1176-
buffer = ""
1176+
socket.connect(sockaddr)
1177+
@logger.info "Contacting nameserver #{ns} port #{@config[:port]}"
1178+
socket.write(length+packet_data)
1179+
got_something = false
1180+
loop do
1181+
buffer = ""
1182+
begin
11771183
ans = socket.recv(Net::DNS::INT16SZ)
1178-
if ans.size == 0
1179-
if got_something
1180-
break #Proper exit from loop
1181-
else
1182-
@logger.warn "Connection reset to nameserver #{ns}, trying next."
1183-
throw "next nameserver"
1184-
end
1184+
rescue ::Errno::ECONNRESET
1185+
ans = ""
1186+
end
1187+
if ans.size == 0
1188+
if got_something
1189+
break #Proper exit from loop
1190+
else
1191+
@logger.warn "Connection reset to nameserver #{ns}, trying next."
1192+
raise NextNameserver
11851193
end
1186-
got_something = true
1187-
len = ans.unpack("n")[0]
1194+
end
1195+
got_something = true
1196+
len = ans.unpack("n")[0]
11881197

1189-
@logger.info "Receiving #{len} bytes..."
1198+
@logger.info "Receiving #{len} bytes..."
11901199

1191-
if len == 0
1192-
@logger.warn "Receiving 0 length packet from nameserver #{ns}, trying next."
1193-
throw "next nameserver"
1194-
end
1200+
if len == 0
1201+
@logger.warn "Receiving 0 length packet from nameserver #{ns}, trying next."
1202+
raise NextNameserver
1203+
end
11951204

1196-
while (buffer.size < len)
1197-
left = len - buffer.size
1198-
temp,from = socket.recvfrom(left)
1199-
buffer += temp
1200-
end
1205+
while (buffer.size < len)
1206+
left = len - buffer.size
1207+
temp,from = socket.recvfrom(left)
1208+
buffer += temp
1209+
end
12011210

1202-
unless buffer.size == len
1203-
@logger.warn "Malformed packet from nameserver #{ns}, trying next."
1204-
throw "next nameserver"
1205-
end
1206-
if block_given?
1207-
yield [buffer,["",@config[:port],ns.to_s,ns.to_s]]
1208-
else
1209-
return [buffer,["",@config[:port],ns.to_s,ns.to_s]]
1210-
end
1211+
unless buffer.size == len
1212+
@logger.warn "Malformed packet from nameserver #{ns}, trying next."
1213+
raise NextNameserver
1214+
end
1215+
if block_given?
1216+
yield [buffer,["",@config[:port],ns.to_s,ns.to_s]]
1217+
else
1218+
return [buffer,["",@config[:port],ns.to_s,ns.to_s]]
12111219
end
12121220
end
12131221
end
1222+
rescue NextNameserver
1223+
next
12141224
rescue Timeout::Error
12151225
@logger.warn "Nameserver #{ns} not responding within TCP timeout, trying next one"
12161226
next

0 commit comments

Comments
 (0)