dnsruby 1.55 → 1.56.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +96 -0
  3. data/Rakefile +30 -29
  4. data/demo/axfr.rb +93 -93
  5. data/demo/check_soa.rb +99 -99
  6. data/demo/check_zone.rb +59 -59
  7. data/demo/digdlv.rb +43 -43
  8. data/demo/digroot.rb +34 -34
  9. data/demo/example_recurse.rb +14 -14
  10. data/demo/mresolv.rb +30 -30
  11. data/demo/mx.rb +31 -31
  12. data/demo/rubydig.rb +37 -37
  13. data/demo/to_resolve.txt +3088 -3088
  14. data/demo/trace_dns.rb +46 -46
  15. data/lib/dnsruby.rb +161 -526
  16. data/lib/dnsruby/DNS.rb +305 -0
  17. data/lib/{Dnsruby/Cache.rb → dnsruby/cache.rb} +152 -152
  18. data/lib/{Dnsruby → dnsruby}/code_mapper.rb +48 -52
  19. data/lib/dnsruby/code_mappers.rb +295 -0
  20. data/lib/{Dnsruby/Config.rb → dnsruby/config.rb} +454 -454
  21. data/lib/{Dnsruby → dnsruby}/dnssec.rb +91 -91
  22. data/lib/{Dnsruby/Hosts.rb → dnsruby/hosts.rb} +125 -125
  23. data/lib/{Dnsruby → dnsruby}/ipv4.rb +26 -26
  24. data/lib/{Dnsruby → dnsruby}/ipv6.rb +42 -42
  25. data/lib/{Dnsruby → dnsruby}/key_cache.rb +29 -29
  26. data/lib/dnsruby/message/decoder.rb +164 -0
  27. data/lib/dnsruby/message/encoder.rb +75 -0
  28. data/lib/dnsruby/message/header.rb +249 -0
  29. data/lib/dnsruby/message/message.rb +629 -0
  30. data/lib/dnsruby/message/question.rb +86 -0
  31. data/lib/dnsruby/message/section.rb +96 -0
  32. data/lib/{Dnsruby → dnsruby}/name.rb +141 -141
  33. data/lib/dnsruby/packet_sender.rb +661 -0
  34. data/lib/{Dnsruby/Recursor.rb → dnsruby/recursor.rb} +235 -233
  35. data/lib/dnsruby/resolv.rb +113 -0
  36. data/lib/dnsruby/resolver.rb +1192 -0
  37. data/lib/dnsruby/resource/A.rb +56 -0
  38. data/lib/dnsruby/resource/AAAA.rb +54 -0
  39. data/lib/{Dnsruby → dnsruby}/resource/AFSDB.rb +68 -68
  40. data/lib/{Dnsruby → dnsruby}/resource/CERT.rb +105 -105
  41. data/lib/{Dnsruby → dnsruby}/resource/DHCID.rb +54 -54
  42. data/lib/dnsruby/resource/DLV.rb +27 -0
  43. data/lib/{Dnsruby → dnsruby}/resource/DNSKEY.rb +372 -372
  44. data/lib/{Dnsruby → dnsruby}/resource/DS.rb +255 -255
  45. data/lib/{Dnsruby → dnsruby}/resource/HINFO.rb +71 -71
  46. data/lib/{Dnsruby → dnsruby}/resource/HIP.rb +29 -29
  47. data/lib/{Dnsruby → dnsruby}/resource/IN.rb +30 -30
  48. data/lib/{Dnsruby → dnsruby}/resource/IPSECKEY.rb +31 -31
  49. data/lib/{Dnsruby → dnsruby}/resource/ISDN.rb +62 -62
  50. data/lib/{Dnsruby → dnsruby}/resource/KX.rb +65 -65
  51. data/lib/{Dnsruby → dnsruby}/resource/LOC.rb +263 -263
  52. data/lib/{Dnsruby → dnsruby}/resource/MINFO.rb +69 -69
  53. data/lib/{Dnsruby → dnsruby}/resource/MX.rb +65 -65
  54. data/lib/{Dnsruby → dnsruby}/resource/NAPTR.rb +98 -98
  55. data/lib/{Dnsruby → dnsruby}/resource/NSAP.rb +171 -171
  56. data/lib/dnsruby/resource/NSEC.rb +275 -0
  57. data/lib/dnsruby/resource/NSEC3.rb +332 -0
  58. data/lib/dnsruby/resource/NSEC3PARAM.rb +135 -0
  59. data/lib/dnsruby/resource/OPT.rb +272 -0
  60. data/lib/{Dnsruby → dnsruby}/resource/PX.rb +70 -70
  61. data/lib/{Dnsruby → dnsruby}/resource/RP.rb +75 -75
  62. data/lib/dnsruby/resource/RR.rb +421 -0
  63. data/lib/dnsruby/resource/RRSIG.rb +275 -0
  64. data/lib/dnsruby/resource/RRSet.rb +190 -0
  65. data/lib/{Dnsruby → dnsruby}/resource/RT.rb +67 -67
  66. data/lib/{Dnsruby → dnsruby}/resource/SOA.rb +94 -94
  67. data/lib/dnsruby/resource/SPF.rb +29 -0
  68. data/lib/dnsruby/resource/SRV.rb +112 -0
  69. data/lib/{Dnsruby → dnsruby}/resource/SSHFP.rb +14 -14
  70. data/lib/dnsruby/resource/TKEY.rb +163 -0
  71. data/lib/dnsruby/resource/TSIG.rb +593 -0
  72. data/lib/{Dnsruby → dnsruby}/resource/TXT.rb +191 -191
  73. data/lib/dnsruby/resource/X25.rb +55 -0
  74. data/lib/{Dnsruby → dnsruby}/resource/domain_name.rb +25 -25
  75. data/lib/{Dnsruby → dnsruby}/resource/generic.rb +80 -80
  76. data/lib/dnsruby/resource/resource.rb +25 -0
  77. data/lib/{Dnsruby → dnsruby}/select_thread.rb +148 -148
  78. data/lib/{Dnsruby/SingleResolver.rb → dnsruby/single_resolver.rb} +60 -60
  79. data/lib/{Dnsruby → dnsruby}/single_verifier.rb +344 -344
  80. data/lib/dnsruby/the_log.rb +44 -0
  81. data/lib/dnsruby/update.rb +278 -0
  82. data/lib/dnsruby/validator_thread.rb +124 -0
  83. data/lib/dnsruby/version.rb +3 -0
  84. data/lib/{Dnsruby → dnsruby}/zone_reader.rb +93 -93
  85. data/lib/{Dnsruby → dnsruby}/zone_transfer.rb +377 -377
  86. data/test/spec_helper.rb +16 -0
  87. data/test/tc_axfr.rb +31 -34
  88. data/test/tc_cache.rb +32 -32
  89. data/test/tc_dlv.rb +28 -28
  90. data/test/tc_dns.rb +73 -76
  91. data/test/tc_dnskey.rb +31 -32
  92. data/test/tc_dnsruby.rb +50 -44
  93. data/test/tc_ds.rb +36 -36
  94. data/test/tc_escapedchars.rb +252 -255
  95. data/test/tc_hash.rb +17 -21
  96. data/test/tc_header.rb +48 -57
  97. data/test/tc_hip.rb +19 -22
  98. data/test/tc_ipseckey.rb +18 -21
  99. data/test/tc_keith.rb +300 -0
  100. data/test/tc_message.rb +87 -0
  101. data/test/tc_misc.rb +83 -87
  102. data/test/tc_name.rb +81 -84
  103. data/test/tc_naptr.rb +18 -21
  104. data/test/tc_nsec.rb +55 -55
  105. data/test/tc_nsec3.rb +23 -24
  106. data/test/tc_nsec3param.rb +20 -21
  107. data/test/tc_packet.rb +90 -93
  108. data/test/tc_packet_unique_push.rb +48 -51
  109. data/test/tc_question.rb +30 -33
  110. data/test/tc_queue.rb +16 -17
  111. data/test/tc_recur.rb +16 -17
  112. data/test/tc_res_config.rb +38 -41
  113. data/test/tc_res_env.rb +29 -32
  114. data/test/tc_res_file.rb +26 -29
  115. data/test/tc_res_opt.rb +62 -65
  116. data/test/tc_resolver.rb +287 -242
  117. data/test/tc_rr-opt.rb +70 -63
  118. data/test/tc_rr-txt.rb +68 -71
  119. data/test/tc_rr-unknown.rb +45 -48
  120. data/test/tc_rr.rb +76 -70
  121. data/test/tc_rrset.rb +21 -22
  122. data/test/tc_rrsig.rb +19 -20
  123. data/test/tc_single_resolver.rb +294 -297
  124. data/test/tc_soak.rb +199 -202
  125. data/test/tc_soak_base.rb +29 -34
  126. data/test/tc_sshfp.rb +20 -23
  127. data/test/tc_tcp.rb +32 -35
  128. data/test/tc_tkey.rb +41 -44
  129. data/test/tc_tsig.rb +81 -84
  130. data/test/tc_update.rb +108 -111
  131. data/test/tc_validator.rb +29 -29
  132. data/test/tc_verifier.rb +81 -82
  133. data/test/ts_dnsruby.rb +16 -15
  134. data/test/ts_offline.rb +62 -63
  135. data/test/ts_online.rb +115 -115
  136. metadata +155 -90
  137. data/README +0 -59
  138. data/lib/Dnsruby/DNS.rb +0 -305
  139. data/lib/Dnsruby/PacketSender.rb +0 -656
  140. data/lib/Dnsruby/Resolver.rb +0 -1189
  141. data/lib/Dnsruby/TheLog.rb +0 -44
  142. data/lib/Dnsruby/message.rb +0 -1230
  143. data/lib/Dnsruby/resource/A.rb +0 -56
  144. data/lib/Dnsruby/resource/AAAA.rb +0 -54
  145. data/lib/Dnsruby/resource/DLV.rb +0 -27
  146. data/lib/Dnsruby/resource/NSEC.rb +0 -298
  147. data/lib/Dnsruby/resource/NSEC3.rb +0 -340
  148. data/lib/Dnsruby/resource/NSEC3PARAM.rb +0 -135
  149. data/lib/Dnsruby/resource/OPT.rb +0 -213
  150. data/lib/Dnsruby/resource/RRSIG.rb +0 -275
  151. data/lib/Dnsruby/resource/SPF.rb +0 -29
  152. data/lib/Dnsruby/resource/SRV.rb +0 -112
  153. data/lib/Dnsruby/resource/TKEY.rb +0 -163
  154. data/lib/Dnsruby/resource/TSIG.rb +0 -593
  155. data/lib/Dnsruby/resource/X25.rb +0 -55
  156. data/lib/Dnsruby/resource/resource.rb +0 -678
  157. data/lib/Dnsruby/update.rb +0 -278
  158. data/lib/Dnsruby/validator_thread.rb +0 -124
data/README DELETED
@@ -1,59 +0,0 @@
1
- Dnsruby
2
- =======
3
-
4
- Dnsruby is a pure Ruby DNS client library which implements a
5
- stub resolver. It aims to comply with all DNS RFCs, including
6
- DNSSEC NSEC3 support.
7
-
8
- Dnsruby presents a new API for DNS. It is based on Ruby's core
9
- resolv.rb Resolv API, but has been much extended to provide a
10
- complete DNS implementation.
11
-
12
- Dnsruby runs a single I/O thread to handle all concurrent
13
- queries. It is therefore suitable for high volume DNS applications.
14
-
15
- The following is a (non-exhaustive) list of features :
16
-
17
- o Implemented RRs : A, AAAA, AFSDB, ANY, CERT, CNAME, DNAME,
18
- HINFO, ISDN, LOC, MB, MG, MINFO, MR, MX, NAPTR, NS, NSAP,
19
- OPT, PTR, PX, RP, RT, SOA, SPF, SRV, TKEY, TSIG, TXT, WKS,
20
- X25, DNSKEY, RRSIG, NSEC, NSEC3, NSEC3PARAM, DS, DLV
21
-
22
- o Generic RR types supported (RFC3597)
23
-
24
- o (Signed) Zone transfer (AXFR and IXFR) supported
25
-
26
- o (Signed) Dyamic updates supported
27
-
28
- o DNSSEC validation supported
29
-
30
- Dependencies
31
- ============
32
-
33
- Dnsruby can run with no dependencies. However, if you wish to
34
- use TSIG or DNSSEC then the OpenSSL library must be available.
35
- This is a part of the Ruby standard library, but appears not to
36
- be present on all Ruby platforms. If it is not available, then
37
- the test code will not run the tests which require it. Code which
38
- attempts to use the library (if it is not present) will raise an
39
- exception.
40
-
41
- Demo code
42
- =========
43
-
44
- The demo folder contains some example programs using Dnsruby.
45
- These examples include a basic dig tool (rubydig) and a tool to
46
- concurrently resolve many names, amongst others.
47
-
48
- Online tests
49
- ============
50
-
51
- Nominet operate a test server which the Dnsruby test code queries.
52
- If this server is not available then some of the online tests will
53
- not be run.
54
-
55
-
56
- Contact
57
- =======
58
-
59
- alex@caerkettontech.com
data/lib/Dnsruby/DNS.rb DELETED
@@ -1,305 +0,0 @@
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
- require 'Dnsruby/Hosts'
17
- require 'Dnsruby/Config'
18
- require "Dnsruby/Resolver"
19
- module Dnsruby
20
-
21
- #== Dnsruby::DNS class
22
- #Resolv::DNS performs DNS queries.
23
- #
24
- #=== class methods
25
- #* Dnsruby::DNS.new(config_info=nil)
26
- #
27
- # ((|config_info|)) should be nil, a string or a hash.
28
- # If nil is given, /etc/resolv.conf and platform specific information is used.
29
- # If a string is given, it should be a filename which format is same as /etc/resolv.conf.
30
- # If a hash is given, it may contains information for nameserver, search and ndots as follows.
31
- #
32
- # Dnsruby::DNS.new({:nameserver=>["210.251.121.21"], :search=>["ruby-lang.org"], :ndots=>1})
33
- #
34
- #* Dnsruby::DNS.open(config_info=nil)
35
- #* Dnsruby::Resolv::DNS.open(config_info=nil) {|dns| ...}
36
- #
37
- #=== methods
38
- #* Dnsruby::DNS#close
39
- #
40
- #* Dnsruby::DNS#getaddress(name)
41
- #* Dnsruby::DNS#getaddresses(name)
42
- #* Dnsruby::DNS#each_address(name) {|address| ...}
43
- # address lookup methods.
44
- #
45
- # ((|name|)) must be an instance of Dnsruby::Name or String. Resultant
46
- # address is represented as an instance of Dnsruby::IPv4 or Dnsruby::IPv6.
47
- #
48
- #* Dnsruby::DNS#getname(address)
49
- #* Dnsruby::DNS#getnames(address)
50
- #* Dnsruby::DNS#each_name(address) {|name| ...}
51
- # These methods lookup hostnames .
52
- #
53
- # ((|address|)) must be an instance of Dnsruby::IPv4, Dnsruby::IPv6 or String.
54
- # Resultant name is represented as an instance of Dnsruby::Name.
55
- #
56
- #* Dnsruby::DNS#getresource(name, type, class)
57
- #* Dnsruby::DNS#getresources(name, type, class)
58
- #* Dnsruby::DNS#each_resource(name, type, class) {|resource| ...}
59
- # These methods lookup DNS resources of ((|name|)).
60
- # ((|name|)) must be a instance of Dnsruby::Name or String.
61
- #
62
- # ((|type|)) must be a member of Dnsruby::Types
63
- # ((|class|)) must be a member of Dnsruby::Classes
64
- #
65
- # Resultant resource is represented as an instance of (a subclass of)
66
- # Dnsruby::RR.
67
- # (Dnsruby::RR::IN::A, etc.)
68
- #
69
- #The searchlist and other Config info is applied to the domain name if appropriate. All the nameservers
70
- #are tried (if there is no timely answer from the first).
71
- #
72
- #This class uses Resolver to perform the queries.
73
- #
74
- #Information taken from the following places :
75
- #* STD0013
76
- #* RFC 1035, etc.
77
- #* ftp://ftp.isi.edu/in-notes/iana/assignments/dns-parameters
78
- #* etc.
79
- class DNS
80
-
81
- attr_accessor :do_caching
82
-
83
- #Creates a new DNS resolver. See Resolv::DNS.new for argument details.
84
- #
85
- #Yields the created DNS resolver to the block, if given, otherwise returns it.
86
- def self.open(*args)
87
- dns = new(*args)
88
- return dns unless block_given?
89
- begin
90
- yield dns
91
- ensure
92
- dns.close
93
- end
94
- end
95
-
96
- #Closes the resolver
97
- def close
98
- @resolver.close
99
- end
100
-
101
-
102
- def to_s
103
- return "DNS : " + @config.to_s
104
- end
105
-
106
- #Creates a new DNS resolver
107
- #
108
- #+config_info+ can be:
109
- #
110
- #* nil:: Uses platform default (e.g. /etc/resolv.conf)
111
- #* String:: Path to a file using /etc/resolv.conf's format
112
- #* Hash:: Must contain :nameserver, :search and :ndots keys
113
- # example :
114
- #
115
- # Dnsruby::DNS.new({:nameserver => ['210.251.121.21'],
116
- # :search => ['ruby-lang.org'],
117
- # :ndots => 1})
118
- def initialize(config_info=nil)
119
- @do_caching = true
120
- @config = Config.new()
121
- @config.set_config_info(config_info)
122
- @resolver = Resolver.new(@config)
123
- # if (@resolver.single_resolvers.length == 0)
124
- # raise ArgumentError.new("Must pass at least one valid resolver address")
125
- # end
126
- end
127
-
128
- attr_reader :config
129
-
130
- #Gets the first IP address of +name+ from the DNS resolver
131
- #
132
- #+name+ can be a Dnsruby::Name or a String. Retrieved address will be a
133
- #Dnsruby::IPv4 or a Dnsruby::IPv6
134
- def getaddress(name)
135
- each_address(name) {|address| return address}
136
- raise ResolvError.new("DNS result has no information for #{name}")
137
- end
138
-
139
- #Gets all IP addresses of +name+ from the DNS resolver
140
- #
141
- #+name+ can be a Dnsruby::Name or a String. Retrieved address will be a
142
- #Dnsruby::IPv4 or a Dnsruby::IPv6
143
- def getaddresses(name)
144
- ret = []
145
- each_address(name) {|address| ret << address}
146
- return ret
147
- end
148
-
149
- #Iterates over all IP addresses of +name+ retrieved from the DNS resolver
150
- #
151
- #+name+ can be a Dnsruby::Name or a String. Retrieved address will be a
152
- #Dnsruby::IPv4 or a Dnsruby::IPv6
153
- def each_address(name)
154
- each_resource(name) {|resource| yield resource.address}
155
- end
156
-
157
- #Gets the first hostname for +address+ from the DNS resolver
158
- #
159
- #+address+ must be a Dnsruby::IPv4, Dnsruby::IPv6 or a String. Retrieved
160
- #name will be a Dnsruby::Name.
161
- def getname(address)
162
- each_name(address) {|name| return name}
163
- raise ResolvError.new("DNS result has no information for #{address}")
164
- end
165
-
166
- #Gets all hostnames for +address+ from the DNS resolver
167
- #
168
- #+address+ must be a Dnsruby::IPv4, Dnsruby::IPv6 or a String. Retrieved
169
- #name will be a Dnsruby::Name.
170
- def getnames(address)
171
- ret = []
172
- each_name(address) {|name| ret << name}
173
- return ret
174
- end
175
-
176
- #Iterates over all hostnames for +address+ retrieved from the DNS resolver
177
- #
178
- #+address+ must be a Dnsruby::IPv4, Dnsruby::IPv6 or a String. Retrieved
179
- #name will be a Dnsruby::Name.
180
- def each_name(address)
181
- case address
182
- when Name
183
- ptr = address
184
- when IPv4, IPv6
185
- ptr = address.to_name
186
- when IPv4::Regex
187
- ptr = IPv4.create(address).to_name
188
- when IPv6::Regex
189
- ptr = IPv6.create(address).to_name
190
- else
191
- raise ResolvError.new("cannot interpret as address: #{address}")
192
- end
193
- each_resource(ptr, Types.PTR, Classes.IN) {|resource| yield resource.domainname}
194
- end
195
-
196
- #Look up the first +type+, +klass+ resource for +name+
197
- #
198
- #+type+ defaults to Dnsruby::Types.A
199
- #+klass+ defaults to Dnsruby::Classes.IN
200
- #
201
- #Returned resource is represented as a Dnsruby::RR instance, e.g.
202
- #Dnsruby::RR::IN::A
203
- def getresource(name, type=Types.A, klass=Classes.IN)
204
- each_resource(name, type, klass) {|resource| return resource}
205
- raise ResolvError.new("DNS result has no information for #{name}")
206
- end
207
-
208
- #Look up all +type+, +klass+ resources for +name+
209
- #
210
- #+type+ defaults to Dnsruby::Types.A
211
- #+klass+ defaults to Dnsruby::Classes.IN
212
- #
213
- #Returned resource is represented as a Dnsruby::RR instance, e.g.
214
- #Dnsruby::RR::IN::A
215
- def getresources(name, type=Types.A, klass=Classes.IN)
216
- ret = []
217
- each_resource(name, type, klass) {|resource| ret << resource}
218
- return ret
219
- end
220
-
221
- #Iterates over all +type+, +klass+ resources for +name+
222
- #
223
- #+type+ defaults to Dnsruby::Types.A
224
- #+klass+ defaults to Dnsruby::Classes.IN
225
- #
226
- #Yielded resource is represented as a Dnsruby::RR instance, e.g.
227
- #Dnsruby::RR::IN::A
228
- def each_resource(name, type=Types.A, klass=Classes.IN, &proc)
229
- type = Types.new(type)
230
- klass = Classes.new(klass)
231
- reply, reply_name = send_query(name, type, klass)
232
- case reply.rcode.code
233
- when RCode::NOERROR
234
- extract_resources(reply, reply_name, type, klass, &proc)
235
- return
236
- # when RCode::NXDomain
237
- # Dnsruby.log.debug("RCode::NXDomain returned - raising error")
238
- # raise Config::NXDomain.new(reply_name.to_s)
239
- else
240
- Dnsruby.log.error{"Unexpected rcode : #{reply.rcode.string}"}
241
- raise Config::OtherResolvError.new(reply_name.to_s)
242
- end
243
- end
244
-
245
- def extract_resources(msg, name, type, klass) # :nodoc:
246
- if type == Types.ANY
247
- n0 = Name.create(name)
248
- msg.each_answer {|rec|
249
- yield rec if n0 == rec.name
250
- }
251
- end
252
- yielded = false
253
- n0 = Name.create(name)
254
- msg.each_answer {|rec|
255
- if n0 == rec.name
256
- case rec.type
257
- when type
258
- if (rec.klass == klass)
259
- yield rec
260
- yielded = true
261
- end
262
- when Types.CNAME
263
- n0 = rec.domainname
264
- end
265
- end
266
- }
267
- return if yielded
268
- msg.each_answer {|rec|
269
- if n0 == rec.name
270
- case rec.type
271
- when type
272
- if (rec.klass == klass)
273
- yield rec
274
- end
275
- end
276
- end
277
- }
278
- end
279
-
280
- def send_query(name, type=Types.A, klass=Classes.IN) # :nodoc:
281
- candidates = @config.generate_candidates(name)
282
- exception = nil
283
- candidates.each do |candidate|
284
- q = Queue.new
285
- msg = Message.new
286
- msg.header.rd = 1
287
- msg.add_question(candidate, type, klass)
288
- msg.do_validation = false
289
- msg.header.cd = false
290
- msg.do_caching = do_caching
291
- @resolver.do_validation = false
292
- @resolver.send_async(msg, q)
293
- id, ret, exception = q.pop
294
- if (exception == nil && ret && ret.rcode == RCode.NOERROR)
295
- return ret, ret.question[0].qname
296
- end
297
- end
298
- raise exception
299
- end
300
-
301
- end
302
- end
303
- #--
304
- #@TODO@ Asynchronous interface. Some sort of Deferrable?
305
- #++
@@ -1,656 +0,0 @@
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
- require 'Dnsruby/select_thread'
17
- require 'ipaddr'
18
- #require 'Dnsruby/iana_ports'
19
- module Dnsruby
20
- class PacketSender # :nodoc: all
21
- @@authoritative_cache = Cache.new
22
- @@recursive_cache = Cache.new
23
-
24
-
25
- def PacketSender.cache(query, response)
26
- return if response.cached
27
- # ONLY cache the response if it is not an update response
28
- question = query.question()[0]
29
- if (query.do_caching && (query.class != Update) &&
30
- (question.qtype != Types::AXFR) && (question.qtype != Types::IXFR) &&
31
- (response.rcode == RCode::NOERROR) &&(!response.tsig) &&
32
- (query.class != Update) &&
33
- (response.header.ancount > 0))
34
- ## @TODO@ What about TSIG-signed responses?
35
- # Don't cache any packets with "*" in the query name! (RFC1034 sec 4.3.3)
36
- if (!question.qname.to_s.include?"*")
37
- # Now cache response RRSets
38
- if (query.header.rd)
39
- PacketSender.cache_recursive(response);
40
- else
41
- PacketSender.cache_authoritative(response);
42
- end
43
- end
44
- end
45
- end
46
- def PacketSender.cache_authoritative(answer)
47
- return if !answer.header.aa
48
- @@authoritative_cache.add(answer)
49
- end
50
- def PacketSender.cache_recursive(answer)
51
- @@recursive_cache.add(answer)
52
- end
53
- def PacketSender.clear_caches
54
- @@recursive_cache.clear
55
- @@authoritative_cache.clear
56
- end
57
- attr_accessor :packet_timeout
58
-
59
- # The port on the resolver to send queries to.
60
- #
61
- # Defaults to 53
62
- attr_accessor :port
63
-
64
- # Use TCP rather than UDP as the transport.
65
- #
66
- # Defaults to false
67
- attr_accessor :use_tcp
68
-
69
- # Use UDP only - don't use TCP
70
- # For test/debug purposes only
71
- # Defaults to false
72
- attr_accessor :no_tcp
73
-
74
- # The TSIG record to sign/verify messages with
75
- attr_reader :tsig
76
-
77
- # Don't worry if the response is truncated - return it anyway.
78
- #
79
- # Defaults to false
80
- attr_accessor :ignore_truncation
81
-
82
- # The source address to send queries from
83
- #
84
- # Defaults to localhost
85
- attr_reader :src_address
86
-
87
- # should the Recursion Desired bit be set on queries?
88
- #
89
- # Defaults to true
90
- attr_accessor :recurse
91
-
92
- # The max UDP packet size
93
- #
94
- # Defaults to 512
95
- attr_reader :udp_size
96
-
97
- # The address of the resolver to send queries to
98
- attr_reader :server
99
-
100
- # Use DNSSEC for this PacketSender
101
- # dnssec defaults to ON
102
- attr_reader :dnssec
103
-
104
- # Set the source address. If the arg is nil, do nothing
105
- def src_address6=(arg)
106
- if (not arg.nil?)
107
- @src_address6 = arg
108
- end
109
- end
110
-
111
- # Set the source address. If the arg is nil, do nothing
112
- def src_address=(arg)
113
- if (not arg.nil?)
114
- @src_address = arg
115
- end
116
- end
117
-
118
- #Sets the TSIG to sign outgoing messages with.
119
- #Pass in either a Dnsruby::RR::TSIG, or a key_name and key (or just a key)
120
- #Pass in nil to stop tsig signing.
121
- #It is possible for client code to sign packets prior to sending - see
122
- #Dnsruby::RR::TSIG#apply and Dnsruby::Message#sign
123
- #Note that pre-signed packets will not be signed by PacketSender.
124
- #* res.tsig=(tsig_rr)
125
- #* res.tsig=(key_name, key)
126
- #* res.tsig=nil # Stop the resolver from signing
127
- def tsig=(*args)
128
- @tsig = Resolver.get_tsig(args)
129
- end
130
-
131
- def dnssec=(on)
132
- @dnssec=on
133
- if (on)
134
- # Set the UDP size (RFC 4035 section 4.1)
135
- if (udp_packet_size < Resolver::MinDnssecUdpSize)
136
- self.udp_size = Resolver::MinDnssecUdpSize
137
- end
138
- end
139
- end
140
-
141
-
142
- def udp_size=(size)
143
- @udp_size = size
144
- end
145
-
146
- def server=(server)
147
- Dnsruby.log.debug{"InternalResolver setting server to #{server}"}
148
- @server=Config.resolve_server(server)
149
- check_ipv6
150
- end
151
-
152
- # Can take a hash with the following optional keys :
153
- #
154
- # * :server
155
- # * :port
156
- # * :use_tcp
157
- # * :no_tcp
158
- # * :ignore_truncation
159
- # * :src_address
160
- # * :src_address6
161
- # * :src_port
162
- # * :udp_size
163
- # * :tsig
164
- # * :packet_timeout
165
- # * :recurse
166
- def initialize(*args)
167
- arg=args[0]
168
- @ipv6 = false
169
- @packet_timeout = Resolver::DefaultPacketTimeout
170
- @port = Resolver::DefaultPort
171
- @udp_size = Resolver::DefaultUDPSize
172
- @dnssec = Resolver::DefaultDnssec
173
- @use_tcp = false
174
- @no_tcp = false
175
- @tsig = nil
176
- @ignore_truncation = false
177
- @src_address = '0.0.0.0'
178
- @src_address6 = '::'
179
- @src_port = [0]
180
- @recurse = true
181
-
182
- if (arg==nil)
183
- # Get default config
184
- config = Config.new
185
- # @server = config.nameserver[0]
186
- elsif (arg.kind_of?String)
187
- @server=arg
188
- elsif (arg.kind_of?Name)
189
- @server=arg
190
- elsif (arg.kind_of?Hash)
191
- arg.keys.each do |attr|
192
- begin
193
- if (((attr.to_s == "src_address")||(attr.to_s == "src_address6")) &&
194
- ((arg[attr] == nil) || (arg[attr] == "")))
195
- else
196
- send(attr.to_s+"=", arg[attr])
197
- end
198
- rescue Exception => e
199
- Dnsruby.log.error{"PacketSender : Argument #{attr}, #{arg[attr]} not valid : #{e}\n"}
200
- end
201
- # end
202
- end
203
- end
204
- #Check server is IP
205
- @server=Config.resolve_server(@server)
206
-
207
- check_ipv6
208
- # ResolverRegister::register_single_resolver(self)
209
- end
210
-
211
- def check_ipv6
212
- begin
213
- i = IPv4.create(@server)
214
- # @src_address = '0.0.0.0'
215
- @ipv6=false
216
- rescue Exception
217
- begin
218
- i = IPv6.create(@server)
219
- # @src_address6 = '::'
220
- @ipv6=true
221
- rescue Exception
222
- Dnsruby.log.error{"Server is neither IPv4 or IPv6!\n"}
223
- end
224
- end
225
- end
226
-
227
- def close
228
- # @TODO@ What about closing?
229
- # Any queries to complete? Sockets to close?
230
- end
231
-
232
- #Asynchronously send a Message to the server. The send can be done using just
233
- #Dnsruby. Support for EventMachine has been deprecated.
234
- #
235
- #== Dnsruby pure Ruby event loop :
236
- #
237
- #A client_queue is supplied by the client,
238
- #along with an optional client_query_id to identify the response. The client_query_id
239
- #is generated, if not supplied, and returned to the client.
240
- #When the response is known, the tuple
241
- #(query_id, response_message, response_exception) is put in the queue for the client to process.
242
- #
243
- #The query is sent synchronously in the caller's thread. The select thread is then used to
244
- #listen for and process the response (up to pushing it to the client_queue). The client thread
245
- #is then used to retrieve the response and deal with it.
246
- #
247
- #Takes :
248
- #
249
- #* msg - the message to send
250
- #* client_queue - a Queue to push the response to, when it arrives
251
- #* client_query_id - an optional ID to identify the query to the client
252
- #* use_tcp - whether to use TCP (defaults to PacketSender.use_tcp)
253
- #
254
- #Returns :
255
- #
256
- #* client_query_id - to identify the query response to the client. This ID is
257
- #generated if it is not passed in by the client
258
- #
259
- #If the native Dsnruby networking layer is being used, then this method returns the client_query_id
260
- #
261
- # id = res.send_async(msg, queue)
262
- # NOT SUPPORTED : id = res.send_async(msg, queue, use_tcp)
263
- # id = res.send_async(msg, queue, id)
264
- # id = res.send_async(msg, queue, id, use_tcp)
265
- #
266
- #Use Message#send_raw to send the packet with an untouched header.
267
- #Use Message#do_caching to tell dnsruby whether to check the cache before
268
- #sending, and update the cache upon receiving a response.
269
- #Use Message#do_validation to tell dnsruby whether or not to do DNSSEC
270
- #validation for this particular packet (assuming SingleResolver#dnssec == true)
271
- #Note that these options should not normally be used!
272
- def send_async(*args) # msg, client_queue, client_query_id, use_tcp=@use_tcp)
273
- # @TODO@ Need to select a good Header ID here - see forgery-resilience RFC draft for details
274
- msg = args[0]
275
- client_query_id = nil
276
- client_queue = nil
277
- use_tcp = @use_tcp
278
- if (msg.kind_of?String)
279
- msg = Message.new(msg)
280
- if (@dnssec)
281
- msg.header.cd = @dnssec # we'll do our own validation by default
282
- if (Dnssec.no_keys?)
283
- msg.header.cd = false
284
- end
285
- end
286
- end
287
- if (args.length > 1)
288
- if (args[1].class==Queue)
289
- client_queue = args[1]
290
- elsif (args.length == 2)
291
- use_tcp = args[1]
292
- end
293
- if (args.length > 2)
294
- client_query_id = args[2]
295
- if (args.length > 3)
296
- use_tcp = args[3]
297
- end
298
- end
299
- end
300
- # Need to keep track of the request mac (if using tsig) so we can validate the response (RFC2845 4.1)
301
- # #Are we using EventMachine or native Dnsruby?
302
- # if (Resolver.eventmachine?)
303
- # return send_eventmachine(query_packet, msg, client_query_id, client_queue, use_tcp)
304
- # else
305
- if (!client_query_id)
306
- client_query_id = Time.now + rand(10000) # is this safe?!
307
- end
308
-
309
- query_packet = make_query_packet(msg, use_tcp)
310
-
311
- if (msg.do_caching && (msg.class != Update))
312
- # Check the cache!!
313
- cachedanswer = nil
314
- if (msg.header.rd)
315
- cachedanswer = @@recursive_cache.find(msg.question()[0].qname, msg.question()[0].type)
316
- else
317
- cachedanswer = @@authoritative_cache.find(msg.question()[0].qname, msg.question()[0].type)
318
- end
319
- if (cachedanswer)
320
- TheLog.debug("Sending cached answer to client\n")
321
- # @TODO@ Fix up the header - ID and flags
322
- cachedanswer.header.id = msg.header.id
323
- # If we can find the answer, send it to the client straight away
324
- # Post the result to the client using SelectThread
325
- st = SelectThread.instance
326
- st.push_response_to_select(client_query_id, client_queue, cachedanswer, msg, self)
327
- return client_query_id
328
- end
329
- end
330
- # Otherwise, run the query
331
- if (udp_packet_size < query_packet.length)
332
- if (@no_tcp)
333
- # Can't send the message - abort!
334
- err=IOError.new("Can't send message - too big for UDP and no_tcp=true")
335
- Dnsruby.log.error{"#{err}"}
336
- st.push_exception_to_select(client_query_id, client_queue, err, nil)
337
- return
338
- end
339
- Dnsruby.log.debug{"Query packet length exceeds max UDP packet size - using TCP"}
340
- use_tcp = true
341
- end
342
- send_dnsruby(query_packet, msg, client_query_id, client_queue, use_tcp)
343
- return client_query_id
344
- # end
345
- end
346
-
347
-
348
- # This method sends the packet using the built-in pure Ruby event loop, with no dependencies.
349
- def send_dnsruby(query_bytes, query, client_query_id, client_queue, use_tcp) #:nodoc: all
350
- endtime = Time.now + @packet_timeout
351
- # First send the query (synchronously)
352
- st = SelectThread.instance
353
- socket = nil
354
- runnextportloop = true
355
- numtries = 0
356
- src_address = @src_address
357
- if (@ipv6)
358
- src_address = @src_address6
359
- end
360
- while (runnextportloop)do
361
- begin
362
- numtries += 1
363
- src_port = get_next_src_port
364
- if (use_tcp)
365
- begin
366
- socket = TCPSocket.new(@server, @port, src_address, src_port)
367
- rescue Errno::EBADF, Errno::ENETUNREACH => e
368
- # Can't create a connection
369
- err=IOError.new("TCP connection error to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp}, exception = #{e.class}, #{e}")
370
- Dnsruby.log.error{"#{err}"}
371
- st.push_exception_to_select(client_query_id, client_queue, err, nil)
372
- return
373
- end
374
- else
375
- socket = nil
376
- # JRuby UDPSocket only takes 0 parameters - no IPv6 support in JRuby...
377
- if (/java/ =~ RUBY_PLATFORM )
378
- socket = UDPSocket.new()
379
- else
380
- # ipv6 = @src_address =~ /:/
381
- socket = UDPSocket.new(@ipv6 ? Socket::AF_INET6 : Socket::AF_INET)
382
- end
383
- socket.bind(src_address, src_port)
384
- socket.connect(@server, @port)
385
- end
386
- runnextportloop = false
387
- rescue Exception => e
388
- if (socket!=nil)
389
- begin
390
- socket.close
391
- rescue Exception
392
- end
393
- end
394
- # Try again if the error was EADDRINUSE and a random source port is used
395
- # Maybe try a max number of times?
396
- if ((e.class != Errno::EADDRINUSE) || (numtries > 50) ||
397
- ((e.class == Errno::EADDRINUSE) && (src_port == @src_port[0])))
398
- err=IOError.new("dnsruby can't connect to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp}, exception = #{e.class}, #{e}")
399
- Dnsruby.log.error{"#{err}"}
400
- st.push_exception_to_select(client_query_id, client_queue, err, nil)
401
- return
402
- end
403
- end
404
- end
405
- if (socket==nil)
406
- err=IOError.new("dnsruby can't connect to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp}")
407
- Dnsruby.log.error{"#{err}"}
408
- st.push_exception_to_select(client_query_id, client_queue, err, nil)
409
- return
410
- end
411
- Dnsruby.log.debug{"Sending packet to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp} : #{query.question()[0].qname}, #{query.question()[0].qtype}"}
412
- # print "#{Time.now} : Sending packet to #{@server} : #{query.question()[0].qname}, #{query.question()[0].qtype}\n"
413
- # Listen for the response before we send the packet (to avoid any race conditions)
414
- query_settings = SelectThread::QuerySettings.new(query_bytes, query, @ignore_truncation, client_queue, client_query_id, socket, @server, @port, endtime, udp_packet_size, self)
415
- begin
416
- if (use_tcp)
417
- lenmsg = [query_bytes.length].pack('n')
418
- socket.send(lenmsg, 0)
419
- end
420
- socket.send(query_bytes, 0)
421
- # The select thread will now wait for the response and send that or a timeout
422
- # back to the client_queue.
423
- st.add_to_select(query_settings)
424
- rescue Exception => e
425
- err=IOError.new("Send failed to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp}, exception : #{e}")
426
- Dnsruby.log.error{"#{err}"}
427
- st.push_exception_to_select(client_query_id, client_queue, err, nil)
428
- begin
429
- socket.close
430
- rescue Exception
431
- end
432
- return
433
- end
434
-
435
- Dnsruby.log.debug{"Packet sent to #{@server}:#{@port} from #{src_address}:#{src_port}, use_tcp=#{use_tcp} : #{query.question()[0].qname}, #{query.question()[0].qtype}"}
436
- # print "Packet sent to #{@server}:#{@port} from #{@src_address}:#{src_port}, use_tcp=#{use_tcp} : #{query.question()[0].qname}, #{query.question()[0].qtype}\n"
437
- end
438
-
439
- # The source port to send queries from
440
- # Returns either a single Fixnum or an Array
441
- # e.g. "0", or "[60001, 60002, 60007]"
442
- #
443
- # Defaults to 0 - random port
444
- def src_port
445
- if (@src_port.length == 1)
446
- return @src_port[0]
447
- end
448
- return @src_port
449
- end
450
-
451
- # Can be a single Fixnum or a Range or an Array
452
- # If an invalid port is selected (one reserved by
453
- # IANA), then an ArgumentError will be raised.
454
- #
455
- # res.src_port=0
456
- # res.src_port=[60001,60005,60010]
457
- # res.src_port=60015..60115
458
- #
459
- def src_port=(p)
460
- @src_port=[]
461
- add_src_port(p)
462
- end
463
-
464
- # Can be a single Fixnum or a Range or an Array
465
- # If an invalid port is selected (one reserved by
466
- # IANA), then an ArgumentError will be raised.
467
- # "0" means "any valid port" - this is only a viable
468
- # option if it is the only port in the list.
469
- # An ArgumentError will be raised if "0" is added to
470
- # an existing set of source ports.
471
- #
472
- # res.add_src_port(60000)
473
- # res.add_src_port([60001,60005,60010])
474
- # res.add_src_port(60015..60115)
475
- #
476
- def add_src_port(p)
477
- if (Resolver.check_port(p, @src_port))
478
- a = Resolver.get_ports_from(p)
479
- a.each do |x|
480
- if ((@src_port.length > 0) && (x == 0))
481
- raise ArgumentError.new("src_port of 0 only allowed as only src_port value (currently #{@src_port.length} values")
482
- end
483
- @src_port.push(x)
484
- end
485
- end
486
- end
487
-
488
-
489
- def get_next_src_port
490
- #Different OSes have different interpretations of "random port" here.
491
- #Apparently, Linux will just give you the same port as last time, unless it is still
492
- #open, in which case you get n+1.
493
- #We need to determine an actual (random) number here, then ask the OS for it, and
494
- #continue until we get one.
495
- if (@src_port[0] == 0)
496
- candidate = -1
497
- # # better to construct an array of all the ports we *can* use, and then just pick one at random!
498
- # candidate = Iana::UNRESERVED_PORTS[rand(Iana::UNRESERVED_PORTS.length())]
499
- # # while (!(Resolver.port_in_range(candidate)))
500
- # # candidate = (rand(65535-1024) + 1024)
501
- # # end
502
- # @TODO@ Should probably construct a bitmap of the IANA ports...
503
- candidate = 50000 + (rand(15535)) # pick one over 50000
504
- return candidate
505
- end
506
- pos = rand(@src_port.length)
507
- return @src_port[pos]
508
- end
509
-
510
- def check_response(response, response_bytes, query, client_queue, client_query_id, tcp)
511
- # @TODO@ Should send_raw avoid this?
512
- if (!query.send_raw)
513
- sig_value = check_tsig(query, response, response_bytes)
514
- if (sig_value != :okay)
515
- # Should send error back up to Resolver here, and then NOT QUERY AGAIN!!!
516
- return sig_value
517
- end
518
- # Should check that question section is same as question that was sent! RFC 5452
519
- # If it's not an update...
520
- if (query.class == Update)
521
- # @TODO@!!
522
- else
523
- if ((response.question.size == 0) ||
524
- (response.question[0].qname.labels != query.question[0].qname.labels) ||
525
- (response.question[0].qtype != query.question[0].qtype) ||
526
- (response.question[0].qclass != query.question[0].qclass) ||
527
- (response.question.length != query.question.length) ||
528
- (response.header.id != query.header.id))
529
- TheLog.info("Incorrect packet returned : #{response.to_s}")
530
- return false
531
- end
532
- end
533
- end
534
- # IF WE GET FORMERR BACK HERE (and we have EDNS0 on) THEN
535
- # TRY AGAIN WITH NO OPT RECORDS! (rfc2671 section 5.3)
536
- if ((response.header.get_header_rcode == RCode.FORMERR) &&
537
- (query.header.arcount > 0))
538
- # try resending the message with no OPT record
539
- query.remove_additional
540
- query.send_raw = true
541
- send_async(query, client_queue, client_query_id, false)
542
- return false
543
- end
544
- if (response.header.tc && !tcp && !@ignore_truncation)
545
- if (@no_tcp)
546
- Dnsruby.log.debug{"Truncated response - not resending over TCP as no_tcp==true"}
547
- else
548
- # Try to resend over tcp
549
- Dnsruby.log.debug{"Truncated - resending over TCP"}
550
- # @TODO@ Are the query options used correctly here? DNSSEC in particular...
551
- # query.send_raw = true # Make sure that the packet is not messed with.
552
- send_async(query, client_queue, client_query_id, true)
553
- return false
554
- end
555
- end
556
- return true
557
- end
558
-
559
- def check_tsig(query, response, response_bytes)
560
- if (query.tsig)
561
- if (response.tsig)
562
- if !query.tsig.verify(query, response, response_bytes)
563
- # Discard packet and wait for correctly signed response
564
- Dnsruby.log.error{"TSIG authentication failed!"}
565
- return TsigError.new
566
- end
567
- else
568
- # Treated as having format error and discarded (RFC2845, 4.6)
569
- # but return a different error code, because some servers fail at
570
- # this
571
- Dnsruby.log.error{"Expecting TSIG signed response, but got unsigned response - discarding"}
572
- return TsigNotSignedResponseError.new
573
- end
574
- elsif (response.tsig)
575
- # Error - signed response to unsigned query
576
- Dnsruby.log.error{"Signed response to unsigned query"}
577
- return TsigError.new
578
- end
579
- return :okay
580
- end
581
-
582
- def make_query(name, type = Types::A, klass = Classes::IN, set_cd=@dnssec)
583
- msg = Message.new
584
- msg.header.rd = 1
585
- msg.add_question(name, type, klass)
586
- if (@dnssec)
587
- msg.header.cd = set_cd # We do our own validation by default
588
- end
589
- return msg
590
- end
591
-
592
- # Prepare the packet for sending
593
- def make_query_packet(packet, use_tcp = @use_tcp) #:nodoc: all
594
- if (!packet.send_raw) # Don't mess with this packet!
595
- if (packet.header.opcode == OpCode.QUERY || @recurse)
596
- packet.header.rd=@recurse
597
- end
598
-
599
- # Only do this if the packet has not been prepared already!
600
- if (@dnssec)
601
- prepare_for_dnssec(packet)
602
- elsif ((udp_packet_size > Resolver::DefaultUDPSize) && !use_tcp)
603
- # if ((udp_packet_size > Resolver::DefaultUDPSize) && !use_tcp)
604
- # @TODO@ What if an existing OPT RR is not big enough? Should we replace it?
605
- add_opt_rr(packet)
606
- end
607
- end
608
-
609
- if (@tsig && !packet.signed?)
610
- @tsig.apply(packet)
611
- end
612
- return packet.encode
613
- end
614
-
615
- def add_opt_rr(packet)
616
- Dnsruby.log.debug{";; Adding EDNS extension with UDP packetsize #{udp_packet_size}.\n"}
617
- # RFC 3225
618
- optrr = RR::OPT.new(udp_packet_size)
619
-
620
- # Only one OPT RR allowed per packet - do we already have one?
621
- if (packet.additional.rrset(packet.question()[0].qname, Types::OPT).rrs.length == 0)
622
- packet.add_additional(optrr)
623
- end
624
- end
625
-
626
- def prepare_for_dnssec(packet)
627
- # RFC 4035
628
- Dnsruby.log.debug{";; Adding EDNS extension with UDP packetsize #{udp_packet_size} and DNS OK bit set\n"}
629
- optrr = RR::OPT.new(udp_packet_size) # Decimal UDPpayload
630
- optrr.dnssec_ok=true
631
-
632
- if (packet.additional.rrset(packet.question()[0].qname, Types::OPT).rrs.length == 0)
633
- packet.add_additional(optrr)
634
- end
635
-
636
- packet.header.ad = false # RFC 4035 section 4.6
637
-
638
- # SHOULD SET CD HERE!!!
639
- if (packet.do_validation)
640
- packet.header.cd = true
641
- end
642
- if (Dnssec.no_keys?)
643
- packet.header.cd = false
644
- end
645
-
646
- end
647
-
648
- # Return the packet size to use for UDP
649
- def udp_packet_size
650
- # if @udp_size > DefaultUDPSize then we use EDNS and
651
- # @udp_size should be taken as the maximum packet_data length
652
- ret = (@udp_size > Resolver::DefaultUDPSize ? @udp_size : Resolver::DefaultUDPSize)
653
- return ret
654
- end
655
- end
656
- end