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.
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