dnsruby 1.55 → 1.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +96 -0
- data/Rakefile +30 -29
- data/demo/axfr.rb +93 -93
- data/demo/check_soa.rb +99 -99
- data/demo/check_zone.rb +59 -59
- data/demo/digdlv.rb +43 -43
- data/demo/digroot.rb +34 -34
- data/demo/example_recurse.rb +14 -14
- data/demo/mresolv.rb +30 -30
- data/demo/mx.rb +31 -31
- data/demo/rubydig.rb +37 -37
- data/demo/to_resolve.txt +3088 -3088
- data/demo/trace_dns.rb +46 -46
- data/lib/dnsruby.rb +161 -526
- data/lib/dnsruby/DNS.rb +305 -0
- data/lib/{Dnsruby/Cache.rb → dnsruby/cache.rb} +152 -152
- data/lib/{Dnsruby → dnsruby}/code_mapper.rb +48 -52
- data/lib/dnsruby/code_mappers.rb +295 -0
- data/lib/{Dnsruby/Config.rb → dnsruby/config.rb} +454 -454
- data/lib/{Dnsruby → dnsruby}/dnssec.rb +91 -91
- data/lib/{Dnsruby/Hosts.rb → dnsruby/hosts.rb} +125 -125
- data/lib/{Dnsruby → dnsruby}/ipv4.rb +26 -26
- data/lib/{Dnsruby → dnsruby}/ipv6.rb +42 -42
- data/lib/{Dnsruby → dnsruby}/key_cache.rb +29 -29
- data/lib/dnsruby/message/decoder.rb +164 -0
- data/lib/dnsruby/message/encoder.rb +75 -0
- data/lib/dnsruby/message/header.rb +249 -0
- data/lib/dnsruby/message/message.rb +629 -0
- data/lib/dnsruby/message/question.rb +86 -0
- data/lib/dnsruby/message/section.rb +96 -0
- data/lib/{Dnsruby → dnsruby}/name.rb +141 -141
- data/lib/dnsruby/packet_sender.rb +661 -0
- data/lib/{Dnsruby/Recursor.rb → dnsruby/recursor.rb} +235 -233
- data/lib/dnsruby/resolv.rb +113 -0
- data/lib/dnsruby/resolver.rb +1192 -0
- data/lib/dnsruby/resource/A.rb +56 -0
- data/lib/dnsruby/resource/AAAA.rb +54 -0
- data/lib/{Dnsruby → dnsruby}/resource/AFSDB.rb +68 -68
- data/lib/{Dnsruby → dnsruby}/resource/CERT.rb +105 -105
- data/lib/{Dnsruby → dnsruby}/resource/DHCID.rb +54 -54
- data/lib/dnsruby/resource/DLV.rb +27 -0
- data/lib/{Dnsruby → dnsruby}/resource/DNSKEY.rb +372 -372
- data/lib/{Dnsruby → dnsruby}/resource/DS.rb +255 -255
- data/lib/{Dnsruby → dnsruby}/resource/HINFO.rb +71 -71
- data/lib/{Dnsruby → dnsruby}/resource/HIP.rb +29 -29
- data/lib/{Dnsruby → dnsruby}/resource/IN.rb +30 -30
- data/lib/{Dnsruby → dnsruby}/resource/IPSECKEY.rb +31 -31
- data/lib/{Dnsruby → dnsruby}/resource/ISDN.rb +62 -62
- data/lib/{Dnsruby → dnsruby}/resource/KX.rb +65 -65
- data/lib/{Dnsruby → dnsruby}/resource/LOC.rb +263 -263
- data/lib/{Dnsruby → dnsruby}/resource/MINFO.rb +69 -69
- data/lib/{Dnsruby → dnsruby}/resource/MX.rb +65 -65
- data/lib/{Dnsruby → dnsruby}/resource/NAPTR.rb +98 -98
- data/lib/{Dnsruby → dnsruby}/resource/NSAP.rb +171 -171
- data/lib/dnsruby/resource/NSEC.rb +275 -0
- data/lib/dnsruby/resource/NSEC3.rb +332 -0
- data/lib/dnsruby/resource/NSEC3PARAM.rb +135 -0
- data/lib/dnsruby/resource/OPT.rb +272 -0
- data/lib/{Dnsruby → dnsruby}/resource/PX.rb +70 -70
- data/lib/{Dnsruby → dnsruby}/resource/RP.rb +75 -75
- data/lib/dnsruby/resource/RR.rb +421 -0
- data/lib/dnsruby/resource/RRSIG.rb +275 -0
- data/lib/dnsruby/resource/RRSet.rb +190 -0
- data/lib/{Dnsruby → dnsruby}/resource/RT.rb +67 -67
- data/lib/{Dnsruby → dnsruby}/resource/SOA.rb +94 -94
- data/lib/dnsruby/resource/SPF.rb +29 -0
- data/lib/dnsruby/resource/SRV.rb +112 -0
- data/lib/{Dnsruby → dnsruby}/resource/SSHFP.rb +14 -14
- data/lib/dnsruby/resource/TKEY.rb +163 -0
- data/lib/dnsruby/resource/TSIG.rb +593 -0
- data/lib/{Dnsruby → dnsruby}/resource/TXT.rb +191 -191
- data/lib/dnsruby/resource/X25.rb +55 -0
- data/lib/{Dnsruby → dnsruby}/resource/domain_name.rb +25 -25
- data/lib/{Dnsruby → dnsruby}/resource/generic.rb +80 -80
- data/lib/dnsruby/resource/resource.rb +25 -0
- data/lib/{Dnsruby → dnsruby}/select_thread.rb +148 -148
- data/lib/{Dnsruby/SingleResolver.rb → dnsruby/single_resolver.rb} +60 -60
- data/lib/{Dnsruby → dnsruby}/single_verifier.rb +344 -344
- data/lib/dnsruby/the_log.rb +44 -0
- data/lib/dnsruby/update.rb +278 -0
- data/lib/dnsruby/validator_thread.rb +124 -0
- data/lib/dnsruby/version.rb +3 -0
- data/lib/{Dnsruby → dnsruby}/zone_reader.rb +93 -93
- data/lib/{Dnsruby → dnsruby}/zone_transfer.rb +377 -377
- data/test/spec_helper.rb +16 -0
- data/test/tc_axfr.rb +31 -34
- data/test/tc_cache.rb +32 -32
- data/test/tc_dlv.rb +28 -28
- data/test/tc_dns.rb +73 -76
- data/test/tc_dnskey.rb +31 -32
- data/test/tc_dnsruby.rb +50 -44
- data/test/tc_ds.rb +36 -36
- data/test/tc_escapedchars.rb +252 -255
- data/test/tc_hash.rb +17 -21
- data/test/tc_header.rb +48 -57
- data/test/tc_hip.rb +19 -22
- data/test/tc_ipseckey.rb +18 -21
- data/test/tc_keith.rb +300 -0
- data/test/tc_message.rb +87 -0
- data/test/tc_misc.rb +83 -87
- data/test/tc_name.rb +81 -84
- data/test/tc_naptr.rb +18 -21
- data/test/tc_nsec.rb +55 -55
- data/test/tc_nsec3.rb +23 -24
- data/test/tc_nsec3param.rb +20 -21
- data/test/tc_packet.rb +90 -93
- data/test/tc_packet_unique_push.rb +48 -51
- data/test/tc_question.rb +30 -33
- data/test/tc_queue.rb +16 -17
- data/test/tc_recur.rb +16 -17
- data/test/tc_res_config.rb +38 -41
- data/test/tc_res_env.rb +29 -32
- data/test/tc_res_file.rb +26 -29
- data/test/tc_res_opt.rb +62 -65
- data/test/tc_resolver.rb +287 -242
- data/test/tc_rr-opt.rb +70 -63
- data/test/tc_rr-txt.rb +68 -71
- data/test/tc_rr-unknown.rb +45 -48
- data/test/tc_rr.rb +76 -70
- data/test/tc_rrset.rb +21 -22
- data/test/tc_rrsig.rb +19 -20
- data/test/tc_single_resolver.rb +294 -297
- data/test/tc_soak.rb +199 -202
- data/test/tc_soak_base.rb +29 -34
- data/test/tc_sshfp.rb +20 -23
- data/test/tc_tcp.rb +32 -35
- data/test/tc_tkey.rb +41 -44
- data/test/tc_tsig.rb +81 -84
- data/test/tc_update.rb +108 -111
- data/test/tc_validator.rb +29 -29
- data/test/tc_verifier.rb +81 -82
- data/test/ts_dnsruby.rb +16 -15
- data/test/ts_offline.rb +62 -63
- data/test/ts_online.rb +115 -115
- metadata +155 -90
- data/README +0 -59
- data/lib/Dnsruby/DNS.rb +0 -305
- data/lib/Dnsruby/PacketSender.rb +0 -656
- data/lib/Dnsruby/Resolver.rb +0 -1189
- data/lib/Dnsruby/TheLog.rb +0 -44
- data/lib/Dnsruby/message.rb +0 -1230
- data/lib/Dnsruby/resource/A.rb +0 -56
- data/lib/Dnsruby/resource/AAAA.rb +0 -54
- data/lib/Dnsruby/resource/DLV.rb +0 -27
- data/lib/Dnsruby/resource/NSEC.rb +0 -298
- data/lib/Dnsruby/resource/NSEC3.rb +0 -340
- data/lib/Dnsruby/resource/NSEC3PARAM.rb +0 -135
- data/lib/Dnsruby/resource/OPT.rb +0 -213
- data/lib/Dnsruby/resource/RRSIG.rb +0 -275
- data/lib/Dnsruby/resource/SPF.rb +0 -29
- data/lib/Dnsruby/resource/SRV.rb +0 -112
- data/lib/Dnsruby/resource/TKEY.rb +0 -163
- data/lib/Dnsruby/resource/TSIG.rb +0 -593
- data/lib/Dnsruby/resource/X25.rb +0 -55
- data/lib/Dnsruby/resource/resource.rb +0 -678
- data/lib/Dnsruby/update.rb +0 -278
- data/lib/Dnsruby/validator_thread.rb +0 -124
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
#Copyright 2007 Nominet UK
|
|
3
|
-
#
|
|
4
|
-
#Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
#you may not use this file except in compliance with the License.
|
|
6
|
-
#You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
#Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
#distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
#See the License for the specific language governing permissions and
|
|
14
|
-
#limitations under the License.
|
|
15
|
-
|
|
1
|
+
# --
|
|
2
|
+
# Copyright 2007 Nominet UK
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
# ++
|
|
16
16
|
module Dnsruby
|
|
17
17
|
class RR
|
|
18
|
-
#Class to store generic RRs (RFC 3597)
|
|
18
|
+
# Class to store generic RRs (RFC 3597)
|
|
19
19
|
class Generic < RR # RFC 3597
|
|
20
|
-
#data for the generic resource record
|
|
20
|
+
# data for the generic resource record
|
|
21
21
|
attr_reader :data
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
def from_data(data) #:nodoc: all
|
|
24
24
|
@data = data[0]
|
|
25
25
|
end
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
def rdata_to_string #:nodoc: all
|
|
28
28
|
if (@data!=nil)
|
|
29
29
|
return "\\# " + @data.length.to_s + " " + @data.unpack("H*")[0]
|
|
30
30
|
end
|
|
31
31
|
return "#NO DATA"
|
|
32
32
|
end
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
def from_string(data) #:nodoc: all
|
|
35
35
|
@data = data
|
|
36
36
|
end
|
|
37
|
-
|
|
37
|
+
|
|
38
38
|
def encode_rdata(msg, canonical=false) #:nodoc: all
|
|
39
39
|
msg.put_bytes(data)
|
|
40
40
|
end
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
def self.decode_rdata(msg) #:nodoc: all
|
|
43
43
|
return self.new(msg.get_bytes)
|
|
44
44
|
end
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
def self.create(type_value, class_value) #:nodoc:
|
|
47
47
|
c = Class.new(Generic)
|
|
48
|
-
#
|
|
49
|
-
#
|
|
48
|
+
# c.type = type_value
|
|
49
|
+
# c.klass = class_value
|
|
50
50
|
c.const_set(:TypeValue, type_value)
|
|
51
51
|
c.const_set(:ClassValue, class_value)
|
|
52
52
|
Generic.const_set("Type#{type_value}_Class#{class_value}", c)
|
|
@@ -54,22 +54,22 @@ module Dnsruby
|
|
|
54
54
|
return c
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
#
|
|
60
|
-
|
|
61
|
-
#NS RR
|
|
62
|
-
#Nameserver resource record
|
|
57
|
+
|
|
58
|
+
# --
|
|
59
|
+
# Standard (class generic) RRs
|
|
60
|
+
# ++
|
|
61
|
+
# NS RR
|
|
62
|
+
# Nameserver resource record
|
|
63
63
|
class NS < DomainName
|
|
64
64
|
ClassValue = nil #:nodoc: all
|
|
65
65
|
TypeValue = Types::NS #:nodoc: all
|
|
66
|
-
|
|
66
|
+
|
|
67
67
|
alias nsdname domainname
|
|
68
68
|
alias nsdname= domainname=
|
|
69
69
|
end
|
|
70
|
-
|
|
71
|
-
#CNAME RR
|
|
72
|
-
#The canonical name for an alias
|
|
70
|
+
|
|
71
|
+
# CNAME RR
|
|
72
|
+
# The canonical name for an alias
|
|
73
73
|
class CNAME < DomainName
|
|
74
74
|
ClassValue = nil #:nodoc: all
|
|
75
75
|
TypeValue = Types::CNAME #:nodoc: all
|
|
@@ -77,48 +77,48 @@ module Dnsruby
|
|
|
77
77
|
alias cname domainname
|
|
78
78
|
alias cname= domainname=
|
|
79
79
|
end
|
|
80
|
-
|
|
81
|
-
#DNAME RR
|
|
80
|
+
|
|
81
|
+
# DNAME RR
|
|
82
82
|
class DNAME < DomainName
|
|
83
83
|
ClassValue = nil #:nodoc: all
|
|
84
84
|
TypeValue = Types::DNAME #:nodoc: all
|
|
85
|
-
|
|
85
|
+
|
|
86
86
|
alias dname domainname
|
|
87
87
|
alias dname= domainname=
|
|
88
88
|
end
|
|
89
|
-
|
|
90
|
-
#MB RR
|
|
89
|
+
|
|
90
|
+
# MB RR
|
|
91
91
|
class MB < DomainName
|
|
92
92
|
ClassValue = nil #:nodoc: all
|
|
93
93
|
TypeValue = Types::MB #:nodoc: all
|
|
94
94
|
alias madname domainname
|
|
95
95
|
alias madname= domainname=
|
|
96
96
|
end
|
|
97
|
-
|
|
98
|
-
#MG RR
|
|
97
|
+
|
|
98
|
+
# MG RR
|
|
99
99
|
class MG < DomainName
|
|
100
100
|
ClassValue = nil #:nodoc: all
|
|
101
101
|
TypeValue = Types::MG #:nodoc: all
|
|
102
102
|
alias mgmname domainname
|
|
103
103
|
alias mgmname= domainname=
|
|
104
104
|
end
|
|
105
|
-
|
|
106
|
-
#MR RR
|
|
105
|
+
|
|
106
|
+
# MR RR
|
|
107
107
|
class MR < DomainName
|
|
108
108
|
ClassValue = nil #:nodoc: all
|
|
109
109
|
TypeValue = Types::MR #:nodoc: all
|
|
110
110
|
alias newname domainname
|
|
111
111
|
alias newname= domainname=
|
|
112
112
|
end
|
|
113
|
-
|
|
114
|
-
#PTR RR
|
|
113
|
+
|
|
114
|
+
# PTR RR
|
|
115
115
|
class PTR < DomainName
|
|
116
116
|
ClassValue = nil #:nodoc: all
|
|
117
117
|
TypeValue = Types::PTR #:nodoc: all
|
|
118
118
|
end
|
|
119
|
-
|
|
120
|
-
#ANY RR
|
|
121
|
-
#
|
|
119
|
+
|
|
120
|
+
# ANY RR
|
|
121
|
+
# A Query type requesting any RR
|
|
122
122
|
class ANY < RR
|
|
123
123
|
ClassValue = nil #:nodoc: all
|
|
124
124
|
TypeValue = Types::ANY #:nodoc: all
|
|
@@ -131,35 +131,35 @@ module Dnsruby
|
|
|
131
131
|
def from_data(data)
|
|
132
132
|
end
|
|
133
133
|
end
|
|
134
|
-
end
|
|
134
|
+
end
|
|
135
135
|
end
|
|
136
|
-
require '
|
|
137
|
-
require '
|
|
138
|
-
require '
|
|
139
|
-
require '
|
|
140
|
-
require '
|
|
141
|
-
require '
|
|
142
|
-
require '
|
|
143
|
-
require '
|
|
144
|
-
require '
|
|
145
|
-
require '
|
|
146
|
-
require '
|
|
147
|
-
require '
|
|
148
|
-
require '
|
|
149
|
-
require '
|
|
150
|
-
require '
|
|
151
|
-
require '
|
|
152
|
-
require '
|
|
153
|
-
require '
|
|
154
|
-
require '
|
|
155
|
-
require '
|
|
156
|
-
require '
|
|
157
|
-
require '
|
|
158
|
-
require '
|
|
159
|
-
require '
|
|
160
|
-
require '
|
|
161
|
-
require '
|
|
162
|
-
require '
|
|
163
|
-
require '
|
|
164
|
-
require '
|
|
165
|
-
require '
|
|
136
|
+
require 'dnsruby/resource/HINFO'
|
|
137
|
+
require 'dnsruby/resource/MINFO'
|
|
138
|
+
require 'dnsruby/resource/ISDN'
|
|
139
|
+
require 'dnsruby/resource/MX'
|
|
140
|
+
require 'dnsruby/resource/NAPTR'
|
|
141
|
+
require 'dnsruby/resource/NSAP'
|
|
142
|
+
require 'dnsruby/resource/PX'
|
|
143
|
+
require 'dnsruby/resource/RP'
|
|
144
|
+
require 'dnsruby/resource/RT'
|
|
145
|
+
require 'dnsruby/resource/SOA'
|
|
146
|
+
require 'dnsruby/resource/TXT'
|
|
147
|
+
require 'dnsruby/resource/X25'
|
|
148
|
+
require 'dnsruby/resource/SPF'
|
|
149
|
+
require 'dnsruby/resource/CERT'
|
|
150
|
+
require 'dnsruby/resource/LOC'
|
|
151
|
+
require 'dnsruby/resource/OPT'
|
|
152
|
+
require 'dnsruby/resource/TSIG'
|
|
153
|
+
require 'dnsruby/resource/TKEY'
|
|
154
|
+
require 'dnsruby/resource/DNSKEY'
|
|
155
|
+
require 'dnsruby/resource/RRSIG'
|
|
156
|
+
require 'dnsruby/resource/NSEC'
|
|
157
|
+
require 'dnsruby/resource/DS'
|
|
158
|
+
require 'dnsruby/resource/NSEC3'
|
|
159
|
+
require 'dnsruby/resource/NSEC3PARAM'
|
|
160
|
+
require 'dnsruby/resource/DLV'
|
|
161
|
+
require 'dnsruby/resource/SSHFP'
|
|
162
|
+
require 'dnsruby/resource/IPSECKEY'
|
|
163
|
+
require 'dnsruby/resource/HIP'
|
|
164
|
+
require 'dnsruby/resource/KX'
|
|
165
|
+
require 'dnsruby/resource/DHCID'
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# --
|
|
2
|
+
# Copyright 2007 Nominet UK
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
# ++
|
|
16
|
+
module Dnsruby
|
|
17
|
+
ClassHash = {} #:nodoc: all
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
require 'dnsruby/resource/RRSet'
|
|
22
|
+
require 'dnsruby/resource/RR'
|
|
23
|
+
require 'dnsruby/resource/domain_name'
|
|
24
|
+
require 'dnsruby/resource/generic'
|
|
25
|
+
require 'dnsruby/resource/IN'
|
|
@@ -1,54 +1,54 @@
|
|
|
1
|
-
|
|
2
|
-
#Copyright 2007 Nominet UK
|
|
3
|
-
#
|
|
4
|
-
#Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
#you may not use this file except in compliance with the License.
|
|
6
|
-
#You may obtain a copy of the License at
|
|
7
|
-
#
|
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
#
|
|
10
|
-
#Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
#distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
#See the License for the specific language governing permissions and
|
|
14
|
-
#limitations under the License.
|
|
15
|
-
|
|
1
|
+
# --
|
|
2
|
+
# Copyright 2007 Nominet UK
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
# ++
|
|
16
16
|
require 'socket'
|
|
17
|
-
#require 'thread'
|
|
17
|
+
# require 'thread'
|
|
18
18
|
begin
|
|
19
19
|
require 'fastthread'
|
|
20
20
|
rescue LoadError
|
|
21
21
|
require 'thread'
|
|
22
22
|
end
|
|
23
23
|
require 'singleton'
|
|
24
|
-
require '
|
|
24
|
+
require 'dnsruby/validator_thread.rb'
|
|
25
25
|
module Dnsruby
|
|
26
26
|
Thread::abort_on_exception = true
|
|
27
27
|
class SelectThread #:nodoc: all
|
|
28
28
|
class SelectWakeup < RuntimeError; end
|
|
29
29
|
include Singleton
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
30
|
+
# This singleton class runs a continuous select loop which
|
|
31
|
+
# listens for responses on all of the in-use sockets.
|
|
32
|
+
# When a new query is sent, the thread is woken up, and
|
|
33
|
+
# the socket is added to the select loop (and the new timeout
|
|
34
|
+
# calculated).
|
|
35
|
+
# Note that a combination of the socket and the packet ID is
|
|
36
|
+
# sufficient to uniquely identify the query to the select thread.
|
|
37
37
|
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
38
|
+
# But how do we find the response queue for a particular query?
|
|
39
|
+
# Hash of client_id->[query, client_queue, socket]
|
|
40
|
+
# and socket->[client_id]
|
|
41
41
|
#
|
|
42
|
-
#
|
|
43
|
-
|
|
42
|
+
# @todo@ should we implement some of cancel function?
|
|
43
|
+
|
|
44
44
|
def initialize
|
|
45
45
|
@@mutex = Mutex.new
|
|
46
46
|
@@mutex.synchronize {
|
|
47
47
|
@@in_select=false
|
|
48
|
-
#
|
|
48
|
+
# @@notifier,@@notified=IO.pipe
|
|
49
49
|
@@sockets = [] # @@notified]
|
|
50
50
|
@@timeouts = Hash.new
|
|
51
|
-
#
|
|
51
|
+
# @@mutex.synchronize do
|
|
52
52
|
@@query_hash = Hash.new
|
|
53
53
|
@@socket_hash = Hash.new
|
|
54
54
|
@@observers = Hash.new
|
|
@@ -60,20 +60,20 @@ module Dnsruby
|
|
|
60
60
|
@@wakeup_sockets = get_socket_pair
|
|
61
61
|
@@sockets << @@wakeup_sockets[1]
|
|
62
62
|
|
|
63
|
-
#
|
|
63
|
+
# Suppress reverse lookups
|
|
64
64
|
BasicSocket.do_not_reverse_lookup = true
|
|
65
|
-
#
|
|
66
|
-
#
|
|
65
|
+
# end
|
|
66
|
+
# Now start the select thread
|
|
67
67
|
@@select_thread = Thread.new {
|
|
68
68
|
do_select
|
|
69
69
|
}
|
|
70
|
-
#
|
|
71
|
-
#
|
|
70
|
+
# # Start the validator thread
|
|
71
|
+
# @@validator = ValidatorThread.instance
|
|
72
72
|
}
|
|
73
73
|
end
|
|
74
|
-
|
|
74
|
+
|
|
75
75
|
def get_socket_pair
|
|
76
|
-
#
|
|
76
|
+
# Emulate socketpair on platforms which don't support it
|
|
77
77
|
srv = nil
|
|
78
78
|
begin
|
|
79
79
|
srv = TCPServer.new('localhost', 0)
|
|
@@ -94,8 +94,8 @@ module Dnsruby
|
|
|
94
94
|
attr_accessor :query_bytes, :query, :ignore_truncation, :client_queue,
|
|
95
95
|
:client_query_id, :socket, :dest_server, :dest_port, :endtime, :udp_packet_size,
|
|
96
96
|
:single_resolver
|
|
97
|
-
#
|
|
98
|
-
#
|
|
97
|
+
# new(query_bytes, query, ignore_truncation, client_queue, client_query_id,
|
|
98
|
+
# socket, dest_server, dest_port, endtime, , udp_packet_size, single_resolver)
|
|
99
99
|
def initialize(*args)
|
|
100
100
|
@query_bytes = args[0]
|
|
101
101
|
@query = args[1]
|
|
@@ -110,13 +110,13 @@ module Dnsruby
|
|
|
110
110
|
@single_resolver = args[10]
|
|
111
111
|
end
|
|
112
112
|
end
|
|
113
|
-
|
|
113
|
+
|
|
114
114
|
def add_to_select(query_settings)
|
|
115
|
-
#
|
|
115
|
+
# Add the query to sockets, and then wake the select thread up
|
|
116
116
|
@@mutex.synchronize {
|
|
117
117
|
check_select_thread_synchronized
|
|
118
|
-
#
|
|
119
|
-
#
|
|
118
|
+
# @TODO@ This assumes that all client_query_ids are unique!
|
|
119
|
+
# Would be a good idea at least to check this...
|
|
120
120
|
@@query_hash[query_settings.client_query_id]=query_settings
|
|
121
121
|
@@socket_hash[query_settings.socket]=[query_settings.client_query_id] # @todo@ If we use persistent sockets then we need to update this array
|
|
122
122
|
@@timeouts[query_settings.client_query_id]=query_settings.endtime
|
|
@@ -125,10 +125,10 @@ module Dnsruby
|
|
|
125
125
|
begin
|
|
126
126
|
@@wakeup_sockets[0].send("wakeup!", 0)
|
|
127
127
|
rescue Exception => e
|
|
128
|
-
#
|
|
128
|
+
# do nothing
|
|
129
129
|
end
|
|
130
130
|
end
|
|
131
|
-
|
|
131
|
+
|
|
132
132
|
def check_select_thread_synchronized
|
|
133
133
|
if (!@@select_thread.alive?)
|
|
134
134
|
Dnsruby.log.debug{"Restarting select thread"}
|
|
@@ -137,7 +137,7 @@ module Dnsruby
|
|
|
137
137
|
}
|
|
138
138
|
end
|
|
139
139
|
end
|
|
140
|
-
|
|
140
|
+
|
|
141
141
|
def select_thread_alive?
|
|
142
142
|
ret=true
|
|
143
143
|
@@mutex.synchronize{
|
|
@@ -145,7 +145,7 @@ module Dnsruby
|
|
|
145
145
|
}
|
|
146
146
|
return ret
|
|
147
147
|
end
|
|
148
|
-
|
|
148
|
+
|
|
149
149
|
def do_select
|
|
150
150
|
unused_loop_count = 0
|
|
151
151
|
last_tick_time = Time.now - 10
|
|
@@ -179,14 +179,14 @@ module Dnsruby
|
|
|
179
179
|
if (has_observer && (timeout > tick_time))
|
|
180
180
|
timeout = tick_time
|
|
181
181
|
end
|
|
182
|
-
#
|
|
182
|
+
# next if (timeout < 0)
|
|
183
183
|
begin
|
|
184
184
|
ready, write, errors = IO.select(sockets, nil, nil, timeout)
|
|
185
185
|
rescue SelectWakeup
|
|
186
|
-
#
|
|
186
|
+
# If SelectWakeup, then just restart this loop - the select call will be made with the new data
|
|
187
187
|
next
|
|
188
188
|
rescue IOError => e# Don't worry if the socket was closed already
|
|
189
|
-
#
|
|
189
|
+
# print "IO Error =: #{e}\n"
|
|
190
190
|
next
|
|
191
191
|
end
|
|
192
192
|
if ready && ready.include?(@@wakeup_sockets[1])
|
|
@@ -197,17 +197,17 @@ module Dnsruby
|
|
|
197
197
|
wakeup_msg = @@wakeup_sockets[1].recv_nonblock(20)
|
|
198
198
|
end
|
|
199
199
|
rescue
|
|
200
|
-
#
|
|
200
|
+
# do nothing
|
|
201
201
|
end
|
|
202
202
|
end
|
|
203
203
|
if (ready == nil)
|
|
204
|
-
#
|
|
204
|
+
# proces the timeouts
|
|
205
205
|
process_timeouts
|
|
206
206
|
unused_loop_count+=1
|
|
207
207
|
else
|
|
208
208
|
process_ready(ready)
|
|
209
209
|
unused_loop_count=0
|
|
210
|
-
#
|
|
210
|
+
# process_error(errors)
|
|
211
211
|
end
|
|
212
212
|
@@mutex.synchronize{
|
|
213
213
|
if (unused_loop_count > 10 && @@query_hash.empty? && @@observers.empty?)
|
|
@@ -215,22 +215,22 @@ module Dnsruby
|
|
|
215
215
|
return
|
|
216
216
|
end
|
|
217
217
|
}
|
|
218
|
-
#
|
|
218
|
+
# }
|
|
219
219
|
end
|
|
220
220
|
end
|
|
221
|
-
|
|
221
|
+
|
|
222
222
|
def process_error(errors)
|
|
223
223
|
Dnsruby.log.debug{"Error! #{errors.inspect}"}
|
|
224
|
-
#
|
|
224
|
+
# @todo@ Process errors [can we do this in single socket environment?]
|
|
225
225
|
end
|
|
226
|
-
|
|
227
|
-
#
|
|
228
|
-
#
|
|
226
|
+
|
|
227
|
+
# @@query_hash[query_settings.client_query_id]=query_settings
|
|
228
|
+
# @@socket_hash[query_settings.socket]=[query_settings.client_query_id] # @todo@ If we use persistent sockets then we need to update this array
|
|
229
229
|
def process_ready(ready)
|
|
230
230
|
ready.each do |socket|
|
|
231
231
|
query_settings = nil
|
|
232
232
|
@@mutex.synchronize{
|
|
233
|
-
#
|
|
233
|
+
# Can do this if we have a query per socket, but not otherwise...
|
|
234
234
|
c_q_id = @@socket_hash[socket][0] # @todo@ If we use persistent sockets then this won't work
|
|
235
235
|
query_settings = @@query_hash[c_q_id]
|
|
236
236
|
}
|
|
@@ -238,7 +238,7 @@ module Dnsruby
|
|
|
238
238
|
udp_packet_size = query_settings.udp_packet_size
|
|
239
239
|
msg, bytes = get_incoming_data(socket, udp_packet_size)
|
|
240
240
|
if (msg!=nil)
|
|
241
|
-
#
|
|
241
|
+
# Check that the IP we received from was the IP we sent to!
|
|
242
242
|
answerip = msg.answerip.downcase
|
|
243
243
|
answerfrom = msg.answerfrom.downcase
|
|
244
244
|
dest_server = query_settings.dest_server
|
|
@@ -247,7 +247,7 @@ module Dnsruby
|
|
|
247
247
|
begin
|
|
248
248
|
destserveripaddr = IPAddr.new(dest_server)
|
|
249
249
|
rescue ArgumentError
|
|
250
|
-
#
|
|
250
|
+
# Host name not IP address
|
|
251
251
|
end
|
|
252
252
|
if (dest_server && (dest_server != '0.0.0.0') &&
|
|
253
253
|
(answeripaddr != destserveripaddr) &&
|
|
@@ -260,22 +260,22 @@ module Dnsruby
|
|
|
260
260
|
ready.delete(socket)
|
|
261
261
|
end
|
|
262
262
|
end
|
|
263
|
-
|
|
263
|
+
|
|
264
264
|
def send_response_to_client(msg, bytes, socket)
|
|
265
|
-
#
|
|
266
|
-
#
|
|
265
|
+
# Figure out which client_ids we were expecting on this socket, then see if any header ids match up
|
|
266
|
+
# @TODO@ Can get rid of this, as we only have one query per socket.
|
|
267
267
|
client_ids=[]
|
|
268
268
|
@@mutex.synchronize{
|
|
269
269
|
client_ids = @@socket_hash[socket]
|
|
270
270
|
}
|
|
271
|
-
#
|
|
271
|
+
# get the queries associated with them
|
|
272
272
|
client_ids.each do |id|
|
|
273
273
|
query_header_id=nil
|
|
274
274
|
@@mutex.synchronize{
|
|
275
275
|
query_header_id = @@query_hash[id].query.header.id
|
|
276
276
|
}
|
|
277
277
|
if (query_header_id == msg.header.id)
|
|
278
|
-
#
|
|
278
|
+
# process the response
|
|
279
279
|
client_queue = nil
|
|
280
280
|
res = nil
|
|
281
281
|
query=nil
|
|
@@ -285,7 +285,7 @@ module Dnsruby
|
|
|
285
285
|
query = @@query_hash[id].query
|
|
286
286
|
}
|
|
287
287
|
tcp = (socket.class == TCPSocket)
|
|
288
|
-
#
|
|
288
|
+
# At this point, we should check if the response is OK
|
|
289
289
|
if (ret = res.check_response(msg, bytes, query, client_queue, id, tcp))
|
|
290
290
|
remove_id(id)
|
|
291
291
|
exception = msg.get_exception
|
|
@@ -294,19 +294,19 @@ module Dnsruby
|
|
|
294
294
|
end
|
|
295
295
|
Dnsruby.log.debug{"Pushing response to client queue"}
|
|
296
296
|
push_to_client(id, client_queue, msg, exception, query, res)
|
|
297
|
-
#
|
|
298
|
-
#
|
|
297
|
+
# client_queue.push([id, msg, exception])
|
|
298
|
+
# notify_queue_observers(client_queue, id)
|
|
299
299
|
else
|
|
300
|
-
#
|
|
300
|
+
# Sending query again - don't return response
|
|
301
301
|
end
|
|
302
302
|
return
|
|
303
303
|
end
|
|
304
304
|
end
|
|
305
|
-
#
|
|
305
|
+
# If not, then we have an error
|
|
306
306
|
Dnsruby.log.error{"Stray packet - " + msg.inspect + "\n from " + socket.inspect}
|
|
307
307
|
print("Stray packet - " + msg.question()[0].qname.to_s + " from " + msg.answerip.to_s + ", #{client_ids.length} client_ids\n")
|
|
308
308
|
end
|
|
309
|
-
|
|
309
|
+
|
|
310
310
|
def remove_id(id)
|
|
311
311
|
socket=nil
|
|
312
312
|
@@mutex.synchronize{
|
|
@@ -322,7 +322,7 @@ module Dnsruby
|
|
|
322
322
|
rescue IOError # Don't worry if the socket was closed already
|
|
323
323
|
end
|
|
324
324
|
end
|
|
325
|
-
|
|
325
|
+
|
|
326
326
|
def process_timeouts
|
|
327
327
|
time_now = Time.now
|
|
328
328
|
timeouts={}
|
|
@@ -335,11 +335,11 @@ module Dnsruby
|
|
|
335
335
|
end
|
|
336
336
|
end
|
|
337
337
|
end
|
|
338
|
-
|
|
338
|
+
|
|
339
339
|
def tcp_read(socket)
|
|
340
|
-
#
|
|
341
|
-
#
|
|
342
|
-
#
|
|
340
|
+
# Keep buffer for all TCP sockets, and return
|
|
341
|
+
# to select after reading available data. Once all data has been received,
|
|
342
|
+
# then process message.
|
|
343
343
|
buf=""
|
|
344
344
|
expected_length = 0
|
|
345
345
|
@@mutex.synchronize {
|
|
@@ -355,26 +355,26 @@ module Dnsruby
|
|
|
355
355
|
input, = socket.recv_nonblock(expected_length-buf.length)
|
|
356
356
|
if (input=="")
|
|
357
357
|
TheLog.info("Bad response from server - no bytes read - ignoring")
|
|
358
|
-
#
|
|
358
|
+
# @TODO@ Should we do anything about this?
|
|
359
359
|
return false
|
|
360
360
|
end
|
|
361
361
|
buf += input
|
|
362
362
|
rescue
|
|
363
|
-
#
|
|
363
|
+
# Oh well - better luck next time!
|
|
364
364
|
return false
|
|
365
365
|
end
|
|
366
366
|
end
|
|
367
|
-
#
|
|
367
|
+
# If data is complete, then return it.
|
|
368
368
|
if (buf.length == expected_length)
|
|
369
369
|
if (expected_length == 2)
|
|
370
|
-
#
|
|
370
|
+
# We just read the data_length field. Now we need to start reading that many bytes.
|
|
371
371
|
@@mutex.synchronize {
|
|
372
372
|
answersize = buf.unpack('n')[0]
|
|
373
373
|
@@tcp_buffers[socket] = ["", answersize]
|
|
374
374
|
}
|
|
375
375
|
return tcp_read(socket)
|
|
376
376
|
else
|
|
377
|
-
#
|
|
377
|
+
# We just read the data - now return it
|
|
378
378
|
@@mutex.synchronize {
|
|
379
379
|
@@tcp_buffers.delete(socket)
|
|
380
380
|
}
|
|
@@ -387,18 +387,18 @@ module Dnsruby
|
|
|
387
387
|
return false
|
|
388
388
|
end
|
|
389
389
|
end
|
|
390
|
-
|
|
390
|
+
|
|
391
391
|
def get_incoming_data(socket, packet_size)
|
|
392
392
|
answerfrom,answerip,answerport,answersize=nil
|
|
393
393
|
ans,buf = nil
|
|
394
394
|
begin
|
|
395
395
|
if (socket.class == TCPSocket)
|
|
396
|
-
#
|
|
397
|
-
#
|
|
398
|
-
#
|
|
399
|
-
#
|
|
400
|
-
#
|
|
401
|
-
#
|
|
396
|
+
# @todo@ Ruby Bug #9061 stops this working right
|
|
397
|
+
# We'd like to do a socket.recvfrom, but that raises an Exception
|
|
398
|
+
# on Windows for TCPSocket for Ruby 1.8.5 (and 1.8.6).
|
|
399
|
+
# So, we need to do something different for TCP than UDP. *sigh*
|
|
400
|
+
# @TODO@ This workaround will only work if there is exactly one socket per query
|
|
401
|
+
# - *not* ideal TCP use!
|
|
402
402
|
@@mutex.synchronize{
|
|
403
403
|
client_id = @@socket_hash[socket][0]
|
|
404
404
|
answerfrom = @@query_hash[client_id].dest_server
|
|
@@ -406,16 +406,16 @@ module Dnsruby
|
|
|
406
406
|
answerport = @@query_hash[client_id].dest_port
|
|
407
407
|
}
|
|
408
408
|
|
|
409
|
-
#
|
|
410
|
-
#
|
|
409
|
+
# Call TCP read here - that will take care of reading the 2 byte length,
|
|
410
|
+
# and then the full packet - without blocking select.
|
|
411
411
|
buf = tcp_read(socket)
|
|
412
412
|
if (!buf) # Wait for the buffer to comletely fill
|
|
413
|
-
#
|
|
413
|
+
# handle_recvfrom_failure(socket, "")
|
|
414
414
|
return
|
|
415
415
|
end
|
|
416
416
|
else
|
|
417
|
-
#
|
|
418
|
-
#
|
|
417
|
+
# @TODO@ Can we get recvfrom to stop issuing PTR queries when we already
|
|
418
|
+
# know both the FQDN and the IP address?
|
|
419
419
|
if (ret = socket.recvfrom(packet_size))
|
|
420
420
|
buf = ret[0]
|
|
421
421
|
answerport=ret[1][1]
|
|
@@ -423,7 +423,7 @@ module Dnsruby
|
|
|
423
423
|
answerip=ret[1][3]
|
|
424
424
|
answersize=(buf.length)
|
|
425
425
|
else
|
|
426
|
-
#
|
|
426
|
+
# recvfrom failed - why?
|
|
427
427
|
Dnsruby.log.error{"Error - recvfrom failed from #{socket}"}
|
|
428
428
|
handle_recvfrom_failure(socket, "")
|
|
429
429
|
return
|
|
@@ -435,7 +435,7 @@ module Dnsruby
|
|
|
435
435
|
return
|
|
436
436
|
end
|
|
437
437
|
Dnsruby.log.debug{";; answer from #{answerfrom} : #{answersize} bytes\n"}
|
|
438
|
-
|
|
438
|
+
|
|
439
439
|
begin
|
|
440
440
|
ans = Message.decode(buf)
|
|
441
441
|
rescue Exception => e
|
|
@@ -444,19 +444,19 @@ module Dnsruby
|
|
|
444
444
|
if (client_id == nil)
|
|
445
445
|
Dnsruby.log.error{"Decode error from #{answerip} but can't determine packet id"}
|
|
446
446
|
end
|
|
447
|
-
#
|
|
447
|
+
# We should check if the TC bit is set (if we can get that far)
|
|
448
448
|
if ((DecodeError === e) && (e.partial_message.header.tc))
|
|
449
449
|
Dnsruby.log.error{"Decode error (from {answerip})! Header shows truncation, so trying again over TCP"}
|
|
450
|
-
#
|
|
450
|
+
# If it is, then we should retry over TCP
|
|
451
451
|
sent = false
|
|
452
452
|
@@mutex.synchronize{
|
|
453
453
|
client_ids = @@socket_hash[socket]
|
|
454
|
-
#
|
|
454
|
+
# get the queries associated with them
|
|
455
455
|
client_ids.each do |id|
|
|
456
456
|
query_header_id=nil
|
|
457
457
|
query_header_id = @@query_hash[id].query.header.id
|
|
458
458
|
if (query_header_id == e.partial_message.header.id)
|
|
459
|
-
#
|
|
459
|
+
# process the response
|
|
460
460
|
client_queue = nil
|
|
461
461
|
res = nil
|
|
462
462
|
query=nil
|
|
@@ -464,7 +464,7 @@ module Dnsruby
|
|
|
464
464
|
res = @@query_hash[id].single_resolver
|
|
465
465
|
query = @@query_hash[id].query
|
|
466
466
|
|
|
467
|
-
#
|
|
467
|
+
# NOW RESEND OVER TCP!
|
|
468
468
|
Thread.new {
|
|
469
469
|
res.send_async(query, client_queue, id, true)
|
|
470
470
|
}
|
|
@@ -481,7 +481,7 @@ module Dnsruby
|
|
|
481
481
|
end
|
|
482
482
|
return
|
|
483
483
|
end
|
|
484
|
-
|
|
484
|
+
|
|
485
485
|
if (ans!= nil)
|
|
486
486
|
Dnsruby.log.debug{"#{ans}"}
|
|
487
487
|
ans.answerfrom=(answerfrom)
|
|
@@ -490,10 +490,10 @@ module Dnsruby
|
|
|
490
490
|
end
|
|
491
491
|
return ans, buf
|
|
492
492
|
end
|
|
493
|
-
|
|
493
|
+
|
|
494
494
|
def handle_recvfrom_failure(socket, exception)
|
|
495
|
-
#
|
|
496
|
-
#
|
|
495
|
+
# No way to notify the client about this error, unless there was only one connection on the socket
|
|
496
|
+
# Not a problem, as there only will ever be one connection on the socket (Kaminsky attack mitigation)
|
|
497
497
|
ids_for_socket = []
|
|
498
498
|
@@mutex.synchronize{
|
|
499
499
|
ids_for_socket = @@socket_hash[socket]
|
|
@@ -509,18 +509,18 @@ module Dnsruby
|
|
|
509
509
|
Dnsruby.log.fatal{"Recvfrom failed from #{socket}, no way to tell query id"}
|
|
510
510
|
end
|
|
511
511
|
end
|
|
512
|
-
|
|
512
|
+
|
|
513
513
|
def get_client_id_from_answerfrom(socket, answerip, answerport)
|
|
514
|
-
#
|
|
514
|
+
# @TODO@ Can get rid of this, as there is only one query per socket
|
|
515
515
|
client_id=nil
|
|
516
|
-
#
|
|
516
|
+
# Figure out client id from answerfrom
|
|
517
517
|
@@mutex.synchronize{
|
|
518
518
|
ids = @@socket_hash[socket]
|
|
519
519
|
ids.each do |id|
|
|
520
|
-
#
|
|
520
|
+
# Does this id speak to this dest_server?
|
|
521
521
|
query_settings = @@query_hash[id]
|
|
522
522
|
if (answerip == query_settings.dest_server && answerport == query_settings.dest_port)
|
|
523
|
-
#
|
|
523
|
+
# We have a match
|
|
524
524
|
client_id = id
|
|
525
525
|
break
|
|
526
526
|
end
|
|
@@ -528,24 +528,24 @@ module Dnsruby
|
|
|
528
528
|
}
|
|
529
529
|
return client_id
|
|
530
530
|
end
|
|
531
|
-
|
|
531
|
+
|
|
532
532
|
def send_exception_to_client(err, socket, client_id, msg=nil)
|
|
533
|
-
#
|
|
533
|
+
# find the client response queue
|
|
534
534
|
client_queue = nil
|
|
535
535
|
@@mutex.synchronize {
|
|
536
536
|
client_queue = @@query_hash[client_id].client_queue
|
|
537
537
|
}
|
|
538
538
|
remove_id(client_id)
|
|
539
|
-
#
|
|
539
|
+
# push_to_client(client_id, client_queue, msg, err)
|
|
540
540
|
client_queue.push([client_id, Resolver::EventType::ERROR, msg, err])
|
|
541
541
|
notify_queue_observers(client_queue, client_id)
|
|
542
542
|
end
|
|
543
|
-
|
|
543
|
+
|
|
544
544
|
def push_exception_to_select(client_id, client_queue, err, msg)
|
|
545
545
|
@@mutex.synchronize{
|
|
546
546
|
@@queued_exceptions.push([client_id, client_queue, err, msg])
|
|
547
547
|
}
|
|
548
|
-
#
|
|
548
|
+
# Make sure select loop is running!
|
|
549
549
|
if (@@select_thread && @@select_thread.alive?)
|
|
550
550
|
else
|
|
551
551
|
@@select_thread = Thread.new {
|
|
@@ -553,10 +553,10 @@ module Dnsruby
|
|
|
553
553
|
}
|
|
554
554
|
end
|
|
555
555
|
end
|
|
556
|
-
|
|
556
|
+
|
|
557
557
|
def push_response_to_select(client_id, client_queue, msg, query, res)
|
|
558
|
-
#
|
|
559
|
-
#
|
|
558
|
+
# This needs to queue the response TO THE SELECT THREAD, which then needs
|
|
559
|
+
# to send it out from its normal loop.
|
|
560
560
|
Dnsruby.log.debug{"Pushing response to client queue direct from resolver or validator"}
|
|
561
561
|
@@mutex.synchronize{
|
|
562
562
|
err = nil
|
|
@@ -565,7 +565,7 @@ module Dnsruby
|
|
|
565
565
|
end
|
|
566
566
|
@@queued_responses.push([client_id, client_queue, msg, err, query, res])
|
|
567
567
|
}
|
|
568
|
-
#
|
|
568
|
+
# Make sure select loop is running!
|
|
569
569
|
if (@@select_thread && @@select_thread.alive?)
|
|
570
570
|
else
|
|
571
571
|
@@select_thread = Thread.new {
|
|
@@ -573,15 +573,15 @@ module Dnsruby
|
|
|
573
573
|
}
|
|
574
574
|
end
|
|
575
575
|
end
|
|
576
|
-
|
|
576
|
+
|
|
577
577
|
def push_validation_response_to_select(client_id, client_queue, msg, err, query, res)
|
|
578
|
-
#
|
|
579
|
-
#
|
|
578
|
+
# This needs to queue the response TO THE SELECT THREAD, which then needs
|
|
579
|
+
# to send it out from its normal loop.
|
|
580
580
|
Dnsruby.log.debug{"Pushing response to client queue direct from resolver or validator"}
|
|
581
581
|
@@mutex.synchronize{
|
|
582
582
|
@@queued_validation_responses.push([client_id, client_queue, msg, err, query, res])
|
|
583
583
|
}
|
|
584
|
-
#
|
|
584
|
+
# Make sure select loop is running!
|
|
585
585
|
if (@@select_thread && @@select_thread.alive?)
|
|
586
586
|
else
|
|
587
587
|
@@select_thread = Thread.new {
|
|
@@ -596,15 +596,15 @@ module Dnsruby
|
|
|
596
596
|
exceptions = @@queued_exceptions
|
|
597
597
|
@@queued_exceptions = []
|
|
598
598
|
}
|
|
599
|
-
|
|
599
|
+
|
|
600
600
|
exceptions.each do |item|
|
|
601
601
|
client_id, client_queue, err, msg = item
|
|
602
|
-
#
|
|
602
|
+
# push_to_client(client_id, client_queue, msg, err)
|
|
603
603
|
client_queue.push([client_id, Resolver::EventType::ERROR, msg, err])
|
|
604
604
|
notify_queue_observers(client_queue, client_id)
|
|
605
605
|
end
|
|
606
606
|
end
|
|
607
|
-
|
|
607
|
+
|
|
608
608
|
def send_queued_responses
|
|
609
609
|
responses = []
|
|
610
610
|
@@mutex.synchronize{
|
|
@@ -614,13 +614,13 @@ module Dnsruby
|
|
|
614
614
|
|
|
615
615
|
responses.each do |item|
|
|
616
616
|
client_id, client_queue, msg, err, query, res = item
|
|
617
|
-
#
|
|
617
|
+
# push_to_client(client_id, client_queue, msg, err)
|
|
618
618
|
client_queue.push([client_id, Resolver::EventType::RECEIVED, msg, err])
|
|
619
619
|
notify_queue_observers(client_queue, client_id)
|
|
620
|
-
#
|
|
621
|
-
#
|
|
622
|
-
#
|
|
623
|
-
#
|
|
620
|
+
# Do we need to validate this? The response has come from the cache -
|
|
621
|
+
# validate it only if it has not been validated already
|
|
622
|
+
# So, if we need to validate it, send it to the validation thread
|
|
623
|
+
# Otherwise, send VALIDATED to the requester.
|
|
624
624
|
if (((msg.security_level == Message::SecurityLevel::UNCHECKED) ||
|
|
625
625
|
(msg.security_level == Message::SecurityLevel::INDETERMINATE)) &&
|
|
626
626
|
(ValidatorThread.requires_validation?(query, msg, err, res)))
|
|
@@ -643,28 +643,28 @@ module Dnsruby
|
|
|
643
643
|
|
|
644
644
|
responses.each do |item|
|
|
645
645
|
client_id, client_queue, msg, err, query, res = item
|
|
646
|
-
#
|
|
646
|
+
# push_to_client(client_id, client_queue, msg, err)
|
|
647
647
|
client_queue.push([client_id, Resolver::EventType::VALIDATED, msg, err])
|
|
648
648
|
notify_queue_observers(client_queue, client_id)
|
|
649
649
|
end
|
|
650
650
|
end
|
|
651
651
|
|
|
652
652
|
def push_to_client(client_id, client_queue, msg, err, query, res)
|
|
653
|
-
#
|
|
654
|
-
#
|
|
655
|
-
#
|
|
656
|
-
#
|
|
653
|
+
# @TODO@ Really need to let the client know that we have received a valid response!
|
|
654
|
+
# Can do that by calling notify_observers here, but with an identifier which
|
|
655
|
+
# defines the response to be a "Response received - validating. Please stop sending"
|
|
656
|
+
# type of response.
|
|
657
657
|
client_queue.push([client_id, Resolver::EventType::RECEIVED, msg, err])
|
|
658
658
|
notify_queue_observers(client_queue, client_id)
|
|
659
659
|
|
|
660
660
|
if (!err || (err.instance_of?(NXDomain)))
|
|
661
|
-
#
|
|
662
|
-
#
|
|
663
|
-
#
|
|
664
|
-
#
|
|
661
|
+
#
|
|
662
|
+
# This method now needs to push the response to the validator,
|
|
663
|
+
# which will then take responsibility for delivering it to the client.
|
|
664
|
+
# The validator will need access to the queue observers -
|
|
665
665
|
validator = ValidatorThread.new(client_id, client_queue, msg, err, query ,self, res)
|
|
666
666
|
validator.run
|
|
667
|
-
#
|
|
667
|
+
# @@validator.add_to_queue([client_id, client_queue, msg, err, query, self, res])
|
|
668
668
|
end
|
|
669
669
|
end
|
|
670
670
|
|
|
@@ -677,11 +677,11 @@ module Dnsruby
|
|
|
677
677
|
end
|
|
678
678
|
}
|
|
679
679
|
end
|
|
680
|
-
|
|
680
|
+
|
|
681
681
|
def remove_observer(client_queue, observer)
|
|
682
682
|
@@mutex.synchronize {
|
|
683
683
|
if (@@observers[client_queue]==observer)
|
|
684
|
-
#
|
|
684
|
+
# @@observers.delete(observer)
|
|
685
685
|
@@observers.delete(client_queue)
|
|
686
686
|
else
|
|
687
687
|
if (@@observers[client_queue] == nil)
|
|
@@ -696,7 +696,7 @@ module Dnsruby
|
|
|
696
696
|
end
|
|
697
697
|
|
|
698
698
|
def notify_queue_observers(client_queue, client_query_id)
|
|
699
|
-
#
|
|
699
|
+
# If any observers are known for this query queue then notify them
|
|
700
700
|
observer=nil
|
|
701
701
|
@@mutex.synchronize {
|
|
702
702
|
observer = @@observers[client_queue]
|
|
@@ -705,9 +705,9 @@ module Dnsruby
|
|
|
705
705
|
observer.handle_queue_event(client_queue, client_query_id)
|
|
706
706
|
end
|
|
707
707
|
end
|
|
708
|
-
|
|
708
|
+
|
|
709
709
|
def send_tick_to_observers
|
|
710
|
-
#
|
|
710
|
+
# If any observers are known then send them a tick
|
|
711
711
|
tick_observers=nil
|
|
712
712
|
@@mutex.synchronize {
|
|
713
713
|
tick_observers = @@tick_observers
|