dnsruby 1.73.1 → 2.0.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 (167) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +16 -4
  3. data/DNSSEC +3 -2
  4. data/EXAMPLES +1 -1
  5. data/README.md +370 -64
  6. data/RELEASE_NOTES.md +314 -1
  7. data/Rakefile +0 -3
  8. data/demo/axfr.rb +24 -6
  9. data/dnsruby.gemspec +6 -4
  10. data/lib/dnsruby/cache.rb +279 -49
  11. data/lib/dnsruby/code_mapper.rb +35 -8
  12. data/lib/dnsruby/code_mappers.rb +63 -49
  13. data/lib/dnsruby/config.rb +77 -4
  14. data/lib/dnsruby/deadline_queue.rb +75 -0
  15. data/lib/dnsruby/dnssec.rb +148 -45
  16. data/lib/dnsruby/ipv6.rb +45 -5
  17. data/lib/dnsruby/key_cache.rb +202 -35
  18. data/lib/dnsruby/message/decoder.rb +85 -19
  19. data/lib/dnsruby/message/encoder.rb +27 -16
  20. data/lib/dnsruby/message/header.rb +8 -12
  21. data/lib/dnsruby/message/message.rb +53 -22
  22. data/lib/dnsruby/message/section.rb +12 -34
  23. data/lib/dnsruby/name.rb +5 -2
  24. data/lib/dnsruby/packet_sender.rb +664 -207
  25. data/lib/dnsruby/presentation.rb +147 -0
  26. data/lib/dnsruby/query_control.rb +132 -0
  27. data/lib/dnsruby/recursor.rb +798 -341
  28. data/lib/dnsruby/resolver.rb +472 -176
  29. data/lib/dnsruby/resource/CAA.rb +67 -16
  30. data/lib/dnsruby/resource/DLV.rb +6 -0
  31. data/lib/dnsruby/resource/DNSKEY.rb +108 -16
  32. data/lib/dnsruby/resource/DS.rb +27 -28
  33. data/lib/dnsruby/resource/HTTPS.rb +16 -0
  34. data/lib/dnsruby/resource/IN.rb +21 -2
  35. data/lib/dnsruby/resource/MX.rb +2 -2
  36. data/lib/dnsruby/resource/NSEC.rb +6 -10
  37. data/lib/dnsruby/resource/NSEC3.rb +55 -19
  38. data/lib/dnsruby/resource/NSEC3PARAM.rb +4 -6
  39. data/lib/dnsruby/resource/OPT.rb +2 -3
  40. data/lib/dnsruby/resource/RR.rb +108 -65
  41. data/lib/dnsruby/resource/RRSIG.rb +5 -5
  42. data/lib/dnsruby/resource/RRSet.rb +38 -22
  43. data/lib/dnsruby/resource/SRV.rb +2 -2
  44. data/lib/dnsruby/resource/SVCB.rb +775 -0
  45. data/lib/dnsruby/resource/TSIG.rb +266 -231
  46. data/lib/dnsruby/resource/TXT.rb +34 -42
  47. data/lib/dnsruby/resource/domain_name.rb +1 -1
  48. data/lib/dnsruby/resource/generic.rb +31 -0
  49. data/lib/dnsruby/resource/generic_cache.rb +384 -0
  50. data/lib/dnsruby/resource/generic_constants.rb +79 -0
  51. data/lib/dnsruby/select_thread.rb +986 -291
  52. data/lib/dnsruby/serial_time.rb +25 -0
  53. data/lib/dnsruby/single_resolver.rb +25 -6
  54. data/lib/dnsruby/single_verifier.rb +1620 -530
  55. data/lib/dnsruby/transport_clock.rb +9 -0
  56. data/lib/dnsruby/update.rb +8 -6
  57. data/lib/dnsruby/validation_budget.rb +143 -0
  58. data/lib/dnsruby/validator_thread.rb +139 -58
  59. data/lib/dnsruby/version.rb +1 -1
  60. data/lib/dnsruby/zone_reader.rb +196 -129
  61. data/lib/dnsruby/zone_transfer.rb +157 -25
  62. data/lib/dnsruby.rb +7 -2
  63. data/test/ci_watchdog.rb +33 -0
  64. data/test/fixtures/org-ds-2026-11-05.zone +5 -0
  65. data/test/fixtures/root-dnskey-2026-11-05.zone +7 -0
  66. data/test/fork_test_helper.rb +37 -0
  67. data/test/local_dns_server.rb +57 -0
  68. data/test/soak_server.rb +152 -0
  69. data/test/socket_helpers.rb +26 -0
  70. data/test/spec_helper.rb +8 -13
  71. data/test/tc_attempt_configuration.rb +137 -0
  72. data/test/tc_caa.rb +2 -2
  73. data/test/tc_cache_keys.rb +36 -0
  74. data/test/tc_cancelled_send_capacity.rb +158 -0
  75. data/test/tc_dnssec_alias_validation.rb +289 -0
  76. data/test/tc_dnssec_budget.rb +489 -0
  77. data/test/tc_dnssec_cache_bounds.rb +197 -0
  78. data/test/tc_dnssec_cache_lifetime.rb +615 -0
  79. data/test/tc_dnssec_denial_proofs.rb +285 -0
  80. data/test/tc_dnssec_recursion_limits.rb +186 -0
  81. data/test/tc_dnssec_recursor_review_fixes.rb +351 -0
  82. data/test/tc_dnssec_trust_anchors.rb +286 -0
  83. data/test/tc_dnssec_trust_races.rb +147 -0
  84. data/test/tc_dnssec_wildcard_proofs.rb +249 -0
  85. data/test/tc_ds.rb +5 -5
  86. data/test/tc_edns_retry_regressions.rb +255 -0
  87. data/test/tc_escapedchars.rb +8 -0
  88. data/test/tc_final_review_fixes.rb +167 -0
  89. data/test/tc_final_transport_contracts.rb +104 -0
  90. data/test/tc_generic_cache.rb +852 -0
  91. data/test/tc_header.rb +26 -0
  92. data/test/tc_ipv6.rb +120 -0
  93. data/test/tc_key_cache_identity.rb +382 -0
  94. data/test/tc_malformed_tcp.rb +712 -0
  95. data/test/tc_name.rb +99 -5
  96. data/test/tc_nameserver_bootstrap.rb +322 -0
  97. data/test/tc_nsec.rb +4 -45
  98. data/test/tc_nsec3.rb +17 -1
  99. data/test/tc_pipeline_retirement.rb +358 -0
  100. data/test/tc_pipeline_retry.rb +462 -0
  101. data/test/tc_pipeline_send.rb +663 -0
  102. data/test/tc_protocol_review_fixes.rb +95 -0
  103. data/test/tc_query_control.rb +90 -0
  104. data/test/tc_record_codec_contracts.rb +107 -0
  105. data/test/tc_record_regressions.rb +225 -0
  106. data/test/tc_recur.rb +1 -0
  107. data/test/tc_recursor_address_fallback.rb +169 -0
  108. data/test/tc_recursor_limits.rb +139 -0
  109. data/test/tc_release_auxiliary_fixes.rb +288 -0
  110. data/test/tc_release_configuration_fixes.rb +612 -0
  111. data/test/tc_release_dnssec_completion.rb +405 -0
  112. data/test/tc_release_dnssec_fixes.rb +305 -0
  113. data/test/tc_release_negative_cache.rb +327 -0
  114. data/test/tc_release_recursor_cache.rb +212 -0
  115. data/test/tc_release_review_transport.rb +372 -0
  116. data/test/tc_release_review_transport_native.rb +56 -0
  117. data/test/tc_release_transport.rb +906 -0
  118. data/test/tc_release_transport_fixes.rb +196 -0
  119. data/test/tc_release_zone_defaults.rb +157 -0
  120. data/test/tc_release_zone_ttls.rb +39 -0
  121. data/test/tc_res_config.rb +53 -2
  122. data/test/tc_res_opt.rb +21 -1
  123. data/test/tc_resolver.rb +34 -19
  124. data/test/tc_resolver_concurrency.rb +383 -0
  125. data/test/tc_resolver_configuration_contracts.rb +31 -0
  126. data/test/tc_resolver_validation.rb +211 -0
  127. data/test/tc_review_cache.rb +163 -0
  128. data/test/tc_review_code_mapper.rb +279 -0
  129. data/test/tc_review_control_deadlines.rb +169 -0
  130. data/test/tc_review_followup_transport.rb +583 -0
  131. data/test/tc_review_packet_contracts.rb +369 -0
  132. data/test/tc_review_presentation.rb +213 -0
  133. data/test/tc_review_record_compatibility.rb +101 -0
  134. data/test/tc_review_transport_fixes.rb +195 -0
  135. data/test/tc_review_transport_native.rb +415 -0
  136. data/test/tc_review_validation_priming.rb +178 -0
  137. data/test/tc_rr-opt.rb +5 -2
  138. data/test/tc_rr-unknown.rb +19 -0
  139. data/test/tc_rr.rb +14 -0
  140. data/test/tc_rrset_grouping.rb +50 -0
  141. data/test/tc_rrset_review_fixes.rb +58 -0
  142. data/test/tc_rrsig.rb +21 -1
  143. data/test/tc_scoped_ipv6.rb +153 -0
  144. data/test/tc_scoped_ipv6_select.rb +157 -0
  145. data/test/tc_scoped_ipv6_transport.rb +329 -0
  146. data/test/tc_selector_wakeup.rb +42 -0
  147. data/test/tc_soak.rb +118 -196
  148. data/test/tc_socket_helpers.rb +90 -0
  149. data/test/tc_supporting_lookup_limits.rb +252 -0
  150. data/test/tc_svcb.rb +1043 -0
  151. data/test/tc_svcb_signed_target.rb +145 -0
  152. data/test/tc_svcb_transport.rb +120 -0
  153. data/test/tc_tcp.rb +69 -43
  154. data/test/tc_tcp_pipelining.rb +95 -204
  155. data/test/tc_transport_fork.rb +179 -0
  156. data/test/tc_tsig.rb +2 -2
  157. data/test/tc_tsig_api.rb +251 -0
  158. data/test/tc_tsig_rfc8945.rb +357 -0
  159. data/test/tc_v2_release_dnssec.rb +442 -0
  160. data/test/tc_v2_release_transport.rb +304 -0
  161. data/test/tc_v2_zone_transfer_native.rb +58 -0
  162. data/test/tc_zone_reader.rb +217 -1
  163. data/test/tcp_pipelining_server.rb +150 -0
  164. data/test/ts_offline.rb +77 -6
  165. data/test/ts_online.rb +2 -1
  166. metadata +127 -14
  167. data/.coveralls.yml +0 -2
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dnsruby
4
+ # RRSIG times are serial numbers, not absolute Unix timestamps (RFC 4034
5
+ # section 3.1.5). Resolve each field into the era nearest the current time
6
+ # before comparing it with ordinary, absolute cache deadlines.
7
+ module SerialTime #:nodoc: all
8
+ MASK = (1 << 32) - 1
9
+ HALF = 1 << 31
10
+
11
+ def self.absolute(value, reference)
12
+ distance = (value.to_i - reference.to_i) & MASK
13
+ # RFC 1982 deliberately leaves this ordering undefined.
14
+ return nil if distance == HALF
15
+ distance -= MASK + 1 if distance > HALF
16
+ reference.to_i + distance
17
+ end
18
+
19
+ def self.valid?(inception, expiration, now = Time.now.to_i)
20
+ starts = absolute(inception, now)
21
+ ends = absolute(expiration, now)
22
+ starts && ends && starts <= now && now <= ends
23
+ end
24
+ end
25
+ end
@@ -20,8 +20,8 @@ module Dnsruby
20
20
  # This class has been deprecated.
21
21
  # This implementation exists for legacy clients. New code should use the Dnsruby::Resolver class.
22
22
  # The SingleResolver class targets a single resolver, and controls the sending of a single
23
- # packet with a packet timeout. It performs no retries. Only two threads are used - the client
24
- # thread and a select thread (which is reused across all queries).
23
+ # packet with a packet timeout. It performs no retries. Responses share one
24
+ # select thread; TCP sends initiated by that thread use a shared worker pool.
25
25
  #
26
26
  # == Methods
27
27
  #
@@ -63,6 +63,9 @@ module Dnsruby
63
63
  @udp_size = Resolver::DefaultUDPSize
64
64
  @dnssec = Resolver::DefaultDnssec
65
65
  @use_tcp = false
66
+ @tcp_pipelining = false
67
+ @tcp_pipelining_max_queries = :infinite
68
+ @tcp_idle_timeout = Resolver::DefaultTcpIdleTimeout
66
69
  @no_tcp = false
67
70
  @tsig = nil
68
71
  @ignore_truncation = false
@@ -107,7 +110,8 @@ module Dnsruby
107
110
  else
108
111
  begin
109
112
  send(attr.to_s+"=", arg[attr])
110
- rescue Exception
113
+ rescue Exception => error
114
+ raise if attr.to_s == 'tsig' || ValidationBudget.abort?(error)
111
115
  Dnsruby.log.error{"Argument #{attr} not valid\n"}
112
116
  end
113
117
  end
@@ -116,11 +120,16 @@ module Dnsruby
116
120
 
117
121
  isr = PacketSender.new({:server=>@server, :port=>@port, :dnssec=>@dnssec,
118
122
  :use_tcp=>@use_tcp, :no_tcp=>@no_tcp, :packet_timeout=>@packet_timeout,
123
+ :tcp_pipelining=>@tcp_pipelining, :tcp_pipelining_max_queries=>@tcp_pipelining_max_queries,
124
+ :tcp_idle_timeout=>@tcp_idle_timeout,
119
125
  :tsig => @tsig, :ignore_truncation=>@ignore_truncation,
120
126
  :src_address=>@src_address, :src_address6=>@src_address6, :src_port=>@src_port,
121
127
  :recurse=>@recurse, :udp_size=>@udp_size})
122
128
 
123
129
  @single_resolvers = [isr]
130
+ @server = isr.server
131
+ @config.nameserver = [@server]
132
+ @configured = true
124
133
 
125
134
  # ResolverRegister::register_single_resolver(self)
126
135
  end
@@ -129,14 +138,23 @@ module Dnsruby
129
138
  if (!@configured)
130
139
  @config.get_ready
131
140
  end
132
- @server = Config.resolve_server(s).to_s
133
- isr = PacketSender.new({:server=>@server, :dnssec=>@dnssec,
141
+ server = Config.resolve_server(s).to_s
142
+ isr = PacketSender.new({:server=>server, :port=>@port, :dnssec=>@dnssec,
134
143
  :use_tcp=>@use_tcp, :no_tcp=>@no_tcp, :packet_timeout=>@packet_timeout,
144
+ :tcp_pipelining=>@tcp_pipelining, :tcp_pipelining_max_queries=>@tcp_pipelining_max_queries,
145
+ :tcp_idle_timeout=>@tcp_idle_timeout,
135
146
  :tsig => @tsig, :ignore_truncation=>@ignore_truncation,
136
147
  :src_address=>@src_address, :src_address6=>@src_address6, :src_port=>@src_port,
137
148
  :recurse=>@recurse, :udp_size=>@udp_size})
138
149
 
139
- @single_res_mutex.synchronize {
150
+ single_res_mutex.synchronize {
151
+ # Hostname resolution and sender construction can run alongside
152
+ # setters. Publish the current configuration, not the earlier snapshot.
153
+ update_internal_res(isr)
154
+ @config.nameserver = [server]
155
+ @server = server
156
+ @configured = true
157
+ @single_resolvers.compact.each(&:close)
140
158
  @single_resolvers = [isr]
141
159
  }
142
160
  end
@@ -161,6 +179,7 @@ module Dnsruby
161
179
  def packet_timeout=(t)
162
180
  @packet_timeout = t
163
181
  @query_timeout = t
182
+ update
164
183
  end
165
184
 
166
185
  # Add the appropriate EDNS OPT RR for the specified packet. This is done