zeroconf 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 39d1c369a77bb16908b77e600e166c264662ec1fc624de8aee2f62fc752e3aae
4
- data.tar.gz: 6f58a84ef9926d9e900182390249b6b029312332a7376cc1f1229b182812bb59
3
+ metadata.gz: 0a6933171abe1ab052bf99d2bdb6efa5bd0378f536859e0cf812f2dd68b23461
4
+ data.tar.gz: 9c016607692b33ed3a516a872aa80117a119f3ac138a997a19a845684914890c
5
5
  SHA512:
6
- metadata.gz: 5a515ce4490d93f37439bec362b84a6bb99c4d42098892f8250d9059537984c9ac6f0c90e9cbf005374f0fdb9abd0a78cb4fd2f7b54e87e05f8acce6eee892cb
7
- data.tar.gz: be3a38c8bfab29934aca1d2d1100fa4fdda4aa7bfc8c31fe095a461337cffc67b44ac1d982c2faf8f6131891c9eee1a9d444932fa5899b353b0f12e9b8968210
6
+ metadata.gz: bdc315b09c4ada48b56f6f102c24b5c0a51740c6163ccb3b9a96e67c7f262a35e95126c950bb1efd394b4cbea06ec0b29e1ae3e55bd02bbd63b42b4159faa06f
7
+ data.tar.gz: 663cc13801926e626a61aea7aebe75d51e92e07ab5133723c53be48259dc19bec30c42cbe10348c3a6881028fac9124afb8c50a697203736f8e394060b479b99
@@ -14,7 +14,7 @@ module ZeroConf
14
14
  end
15
15
 
16
16
  def run timeout: 3
17
- sockets = open_interfaces interfaces.map(&:addr), Resolv::MDNS::Port
17
+ sockets = open_interfaces interfaces.map(&:addr), 0
18
18
 
19
19
  query = get_query
20
20
  sockets.each { |socket| multicast_send(socket, query.encode) }
@@ -7,15 +7,17 @@ module ZeroConf
7
7
  include Utils
8
8
 
9
9
  attr_reader :service, :service_port, :hostname, :service_interfaces,
10
- :service_name, :qualified_host, :text
10
+ :service_name, :qualified_host, :text, :abort_on_malformed_requests
11
11
 
12
- def initialize service, service_port, hostname = Socket.gethostname, service_interfaces: ZeroConf.service_interfaces, text: [""]
12
+ def initialize service, service_port, hostname = Socket.gethostname, service_interfaces: ZeroConf.service_interfaces, text: [""], abort_on_malformed_requests: false, started_callback: nil
13
13
  @service = service
14
14
  @service_port = service_port
15
15
  @hostname = hostname
16
16
  @service_interfaces = service_interfaces
17
+ @abort_on_malformed_requests = abort_on_malformed_requests
17
18
  @service_name = "#{hostname}.#{service}"
18
19
  @qualified_host = "#{hostname}.local."
20
+ @started_callback = started_callback
19
21
  @text = text
20
22
  @started = false
21
23
  @rd, @wr = IO.pipe
@@ -88,6 +90,7 @@ module ZeroConf
88
90
  end
89
91
 
90
92
  def stop
93
+ return unless @started
91
94
  @wr.write "x"
92
95
  @wr.close
93
96
  @started = false
@@ -104,16 +107,27 @@ module ZeroConf
104
107
  multicast_send(sock, msg.encode)
105
108
 
106
109
  @started = true
110
+ @started_callback&.call
107
111
 
108
112
  loop do
109
113
  readers, = IO.select(sockets, [], [])
110
114
  next unless readers
111
115
 
112
116
  readers.each do |reader|
113
- return if reader == @rd
117
+ if reader == @rd
118
+ @rd.close
119
+ return
120
+ end
114
121
 
115
122
  buf, from = reader.recvfrom 2048
116
- msg = Resolv::DNS::Message.decode(buf)
123
+ msg = begin
124
+ Resolv::DNS::Message.decode(buf)
125
+ rescue Resolv::DNS::DecodeError
126
+ next unless abort_on_malformed_requests
127
+ @rd.close
128
+ stop
129
+ raise
130
+ end
117
131
 
118
132
  has_flags = (buf.getbyte(3) << 8 | buf.getbyte(2)) != 0
119
133
 
@@ -122,9 +136,7 @@ module ZeroConf
122
136
 
123
137
  break unless class_type == 1 || class_type == 255
124
138
 
125
- legacy = from[1] != Resolv::MDNS::Port
126
- unicast = legacy || type::ClassValue & PTR::MDNS_UNICAST_RESPONSE > 0
127
- reply_id = legacy ? msg.id : 0
139
+ unicast = type::ClassValue & PTR::MDNS_UNICAST_RESPONSE > 0
128
140
 
129
141
  qn = name.to_s + "."
130
142
 
@@ -133,25 +145,25 @@ module ZeroConf
133
145
  break if has_flags
134
146
 
135
147
  if unicast
136
- dnssd_unicast_answer(id: reply_id, legacy: legacy)
148
+ dnssd_unicast_answer
137
149
  else
138
150
  dnssd_multicast_answer
139
151
  end
140
152
  when service
141
153
  if unicast
142
- service_unicast_answer(id: reply_id, legacy: legacy)
154
+ service_unicast_answer
143
155
  else
144
156
  service_multicast_answer
145
157
  end
146
158
  when service_name
147
159
  if unicast
148
- service_instance_unicast_answer(id: reply_id, legacy: legacy)
160
+ service_instance_unicast_answer
149
161
  else
150
162
  service_instance_multicast_answer
151
163
  end
152
164
  when qualified_host
153
165
  if unicast
154
- name_answer_unicast(id: reply_id, legacy: legacy)
166
+ name_answer_unicast
155
167
  else
156
168
  name_answer_multicast
157
169
  end
@@ -178,11 +190,10 @@ module ZeroConf
178
190
 
179
191
  private
180
192
 
181
- def service_instance_unicast_answer(id:, legacy:)
193
+ def service_instance_unicast_answer
182
194
  msg = Resolv::DNS::Message.new(0)
183
195
  msg.qr = 1
184
196
  msg.aa = 1
185
- msg.id = id
186
197
 
187
198
  service_interfaces.each do |iface|
188
199
  if iface.addr.ipv4?
@@ -202,16 +213,15 @@ module ZeroConf
202
213
  Resolv::DNS::Resource::IN::TXT.new(*@text)
203
214
  end
204
215
  msg.add_answer service_name, 10, Resolv::DNS::Resource::IN::SRV.new(0, 0, service_port, qualified_host)
205
- msg.add_question service_name, legacy ? Resolv::DNS::Resource::IN::SRV : MDNS::Announce::IN::SRV
216
+ msg.add_question service_name, MDNS::Announce::IN::SRV
206
217
 
207
218
  msg
208
219
  end
209
220
 
210
- def service_unicast_answer(id:, legacy:)
221
+ def service_unicast_answer
211
222
  msg = Resolv::DNS::Message.new(0)
212
223
  msg.qr = 1
213
224
  msg.aa = 1
214
- msg.id = id
215
225
 
216
226
  msg.add_additional service_name, 10, Resolv::DNS::Resource::IN::SRV.new(0, 0, service_port, qualified_host)
217
227
 
@@ -237,21 +247,20 @@ module ZeroConf
237
247
  10,
238
248
  Resolv::DNS::Resource::IN::PTR.new(Resolv::DNS::Name.create(service_name))
239
249
 
240
- msg.add_question service, legacy ? Resolv::DNS::Resource::IN::PTR : PTR
250
+ msg.add_question service, PTR
241
251
 
242
252
  msg
243
253
  end
244
254
 
245
- def dnssd_unicast_answer(id:, legacy:)
255
+ def dnssd_unicast_answer
246
256
  msg = Resolv::DNS::Message.new(0)
247
257
  msg.qr = 1
248
258
  msg.aa = 1
249
- msg.id = id
250
259
 
251
260
  msg.add_answer DISCOVERY_NAME, 10,
252
261
  Resolv::DNS::Resource::IN::PTR.new(Resolv::DNS::Name.create(service))
253
262
 
254
- msg.add_question DISCOVERY_NAME, legacy ? Resolv::DNS::Resource::IN::PTR : PTR
263
+ msg.add_question DISCOVERY_NAME, PTR
255
264
  msg
256
265
  end
257
266
 
@@ -325,11 +334,10 @@ module ZeroConf
325
334
  msg
326
335
  end
327
336
 
328
- def name_answer_unicast(id:, legacy:)
337
+ def name_answer_unicast
329
338
  msg = Resolv::DNS::Message.new(0)
330
339
  msg.qr = 1
331
340
  msg.aa = 1
332
- msg.id = id
333
341
 
334
342
  first = true
335
343
 
@@ -358,7 +366,7 @@ module ZeroConf
358
366
  end
359
367
  end
360
368
 
361
- msg.add_question qualified_host, legacy ? Resolv::DNS::Resource::IN::A : MDNS::Announce::IN::A
369
+ msg.add_question qualified_host, MDNS::Announce::IN::A
362
370
 
363
371
  if @text
364
372
  msg.add_additional service_name,
@@ -4,7 +4,6 @@ require "socket"
4
4
  require "ipaddr"
5
5
  require "fcntl"
6
6
  require "resolv"
7
- require "rbconfig"
8
7
 
9
8
  module ZeroConf
10
9
  MDNS_CACHE_FLUSH = 0x8000
@@ -58,7 +57,7 @@ module ZeroConf
58
57
  def open_ipv4 saddr, port
59
58
  sock = UDPSocket.new Socket::AF_INET
60
59
  sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
61
- sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEPORT, true) unless RbConfig::CONFIG["host_os"].include?("linux")
60
+ sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEPORT, true)
62
61
  sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_MULTICAST_TTL, true)
63
62
  sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_MULTICAST_LOOP, true)
64
63
  sock.setsockopt(Socket::IPPROTO_IP, Socket::IP_ADD_MEMBERSHIP,
@@ -98,7 +97,7 @@ module ZeroConf
98
97
  def open_ipv6 saddr, port
99
98
  sock = UDPSocket.new Socket::AF_INET6
100
99
  sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
101
- sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEPORT, true) unless RbConfig::CONFIG["host_os"].include?("linux")
100
+ sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEPORT, true)
102
101
  sock.setsockopt(Socket::IPPROTO_IPV6, Socket::IPV6_MULTICAST_HOPS, true)
103
102
  sock.setsockopt(Socket::IPPROTO_IPV6, Socket::IPV6_MULTICAST_LOOP, true)
104
103
 
@@ -1,3 +1,3 @@
1
1
  module ZeroConf
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
data/lib/zeroconf.rb CHANGED
@@ -67,8 +67,8 @@ module ZeroConf
67
67
  resolver.run(timeout:, &blk)
68
68
  end
69
69
 
70
- def self.service service, service_port, hostname = Socket.gethostname, service_interfaces: self.service_interfaces, text: [""]
71
- s = Service.new(service, service_port, hostname, service_interfaces:, text:)
70
+ def self.service ...
71
+ s = Service.new(...)
72
72
  s.start
73
73
  end
74
74
 
data/test/client_test.rb CHANGED
@@ -10,9 +10,10 @@ module ZeroConf
10
10
  end
11
11
 
12
12
  def test_resolve
13
- s = make_server iface, "coolhostname"
13
+ latch = Queue.new
14
+ s = make_server iface, "coolhostname", started_callback: -> { latch << :start }
14
15
  runner = Thread.new { s.start }
15
- Thread.pass until s.started?
16
+ latch.pop
16
17
  found = nil
17
18
 
18
19
  name = "coolhostname.local"
@@ -33,9 +34,10 @@ module ZeroConf
33
34
  end
34
35
 
35
36
  def test_resolve_returns_early
36
- s = make_server iface, "coolhostname"
37
+ latch = Queue.new
38
+ s = make_server iface, "coolhostname", started_callback: -> { latch << :start }
37
39
  runner = Thread.new { s.start }
38
- Thread.pass until s.started?
40
+ latch.pop
39
41
  found = nil
40
42
 
41
43
  name = "coolhostname.local"
@@ -57,9 +59,10 @@ module ZeroConf
57
59
  end
58
60
 
59
61
  def test_discover_works
60
- s = make_server iface
62
+ latch = Queue.new
63
+ s = make_server iface, started_callback: -> { latch << :start }
61
64
  runner = Thread.new { s.start }
62
- Thread.pass until s.started?
65
+ latch.pop
63
66
  found = nil
64
67
 
65
68
  took = time_it do
@@ -78,9 +81,10 @@ module ZeroConf
78
81
  end
79
82
 
80
83
  def test_discover_return_early
81
- s = make_server iface
84
+ latch = Queue.new
85
+ s = make_server iface, started_callback: -> { latch << :start }
82
86
  runner = Thread.new { s.start }
83
- Thread.pass until s.started?
87
+ latch.pop
84
88
  found = nil
85
89
 
86
90
  took = time_it do
@@ -99,9 +103,10 @@ module ZeroConf
99
103
  end
100
104
 
101
105
  def test_browse
102
- s = make_server iface
106
+ latch = Queue.new
107
+ s = make_server iface, started_callback: -> { latch << :start }
103
108
  runner = Thread.new { s.start }
104
- Thread.pass until s.started?
109
+ latch.pop
105
110
  found = nil
106
111
 
107
112
  took = time_it do
@@ -121,9 +126,10 @@ module ZeroConf
121
126
  end
122
127
 
123
128
  def test_browse_returns_early
124
- s = make_server iface
129
+ latch = Queue.new
130
+ s = make_server iface, started_callback: -> { latch << :start }
125
131
  runner = Thread.new { s.start }
126
- Thread.pass until s.started?
132
+ latch.pop
127
133
  found = nil
128
134
 
129
135
  took = time_it do
data/test/helper.rb CHANGED
@@ -39,16 +39,18 @@ module ZeroConf
39
39
  Process.clock_gettime(Process::CLOCK_MONOTONIC) - start
40
40
  end
41
41
 
42
- def make_server iface, host = HOST_NAME
42
+ def make_server iface, host = HOST_NAME, **opts
43
43
  Service.new SERVICE + ".",
44
44
  42424,
45
45
  host,
46
- service_interfaces: [iface], text: ["test=1", "other=value"]
46
+ service_interfaces: [iface], text: ["test=1", "other=value"],
47
+ **opts
47
48
  end
48
49
 
49
- def make_listener rd, q
50
+ def make_listener rd, q, started_callback: nil
50
51
  Thread.new do
51
52
  sock = open_ipv4 Addrinfo.new(Socket.sockaddr_in(Resolv::MDNS::Port, Socket::INADDR_ANY)), Resolv::MDNS::Port
53
+ started_callback&.call
52
54
  Thread.current[:started] = true
53
55
  loop do
54
56
  readers, = IO.select([sock, rd])
data/test/service_test.rb CHANGED
@@ -27,14 +27,15 @@ module ZeroConf
27
27
  end
28
28
 
29
29
  def test_unicast_service_instance_answer
30
- s = make_server iface
30
+ latch = Queue.new
31
+ s = make_server iface, started_callback: -> { latch << :start }
31
32
  runner = Thread.new { s.start }
32
- Thread.pass until s.started?
33
+ latch.pop
33
34
 
34
- query = Resolv::DNS::Message.new 10
35
+ query = Resolv::DNS::Message.new 0
35
36
  query.add_question "tc-lan-adapter._test-mdns._tcp.local.", SRV
36
37
 
37
- sock = open_ipv4 iface.addr, Resolv::MDNS::Port
38
+ sock = open_ipv4 iface.addr, 0
38
39
  multicast_send sock, query.encode
39
40
  res = Resolv::DNS::Message.decode read_with_timeout(sock).first
40
41
  s.stop
@@ -57,49 +58,19 @@ module ZeroConf
57
58
  assert_equal expected, res
58
59
  end
59
60
 
60
- def test_legacy_unicast_service_instance_answer
61
- s = make_server iface
62
- runner = Thread.new { s.start }
63
- Thread.pass until s.started?
64
-
65
- query = Resolv::DNS::Message.new 10
66
- query.add_question "tc-lan-adapter._test-mdns._tcp.local.", Resolv::DNS::Resource::IN::SRV
67
-
68
- sock = open_ipv4 iface.addr, 0
69
- multicast_send sock, query.encode
70
- res = Resolv::DNS::Message.decode read_with_timeout(sock).first
71
- s.stop
72
- runner.join
73
-
74
- expected = Resolv::DNS::Message.new(10)
75
- expected.qr = 1
76
- expected.aa = 1
77
-
78
- expected.add_additional s.qualified_host,
79
- 10,
80
- Resolv::DNS::Resource::IN::A.new(iface.addr.ip_address)
81
-
82
- expected.add_additional s.service_name,
83
- 10,
84
- Resolv::DNS::Resource::IN::TXT.new(*s.text)
85
- expected.add_answer s.service_name, 10, Resolv::DNS::Resource::IN::SRV.new(0, 0, s.service_port, s.qualified_host)
86
- expected.add_question s.service_name, Resolv::DNS::Resource::IN::SRV
87
-
88
- assert_equal expected, res
89
- end
90
-
91
61
  def test_multicast_discover
92
62
  q = Queue.new
93
63
  rd, wr = IO.pipe
94
64
 
95
65
  listen = make_listener rd, q
96
- s = make_server iface
66
+ latch = Queue.new
67
+ s = make_server iface, started_callback: -> { latch << :start }
97
68
  server = Thread.new { s.start }
98
- Thread.pass until s.started?
69
+ latch.pop
99
70
 
100
- query = Resolv::DNS::Message.new 10
71
+ query = Resolv::DNS::Message.new 0
101
72
  query.add_question "_services._dns-sd._udp.local.", Resolv::DNS::Resource::IN::PTR
102
- sock = open_ipv4 iface.addr, Resolv::MDNS::Port
73
+ sock = open_ipv4 iface.addr, 0
103
74
  multicast_send sock, query.encode
104
75
 
105
76
  while res = q.pop
@@ -196,14 +167,15 @@ module ZeroConf
196
167
  end
197
168
 
198
169
  def test_dnssd_unicast_answer
199
- s = make_server iface
170
+ latch = Queue.new
171
+ s = make_server iface, started_callback: -> { latch << :start }
200
172
  runner = Thread.new { s.start }
201
- Thread.pass until s.started?
173
+ latch.pop
202
174
 
203
- query = Resolv::DNS::Message.new 10
175
+ query = Resolv::DNS::Message.new 0
204
176
  query.add_question "_services._dns-sd._udp.local.", PTR
205
177
 
206
- sock = open_ipv4 iface.addr, Resolv::MDNS::Port
178
+ sock = open_ipv4 iface.addr, 0
207
179
  multicast_send sock, query.encode
208
180
 
209
181
  res = nil
@@ -230,53 +202,20 @@ module ZeroConf
230
202
  assert_equal expected, res
231
203
  end
232
204
 
233
- def test_dnssd_legacy_unicast_answer
234
- s = make_server iface
235
- runner = Thread.new { s.start }
236
- Thread.pass until s.started?
237
-
238
- query = Resolv::DNS::Message.new 10
239
- query.add_question "_services._dns-sd._udp.local.", Resolv::DNS::Resource::IN::PTR
240
-
241
- sock = open_ipv4 iface.addr, 0
242
- multicast_send sock, query.encode
243
-
244
- res = nil
245
- loop do
246
- buf, from = read_with_timeout sock
247
- res = Resolv::DNS::Message.decode buf
248
- if from.last == iface.addr.ip_address
249
- break if res.answer.find { |name, ttl, data| data.name.to_s == SERVICE }
250
- end
251
- end
252
-
253
- s.stop
254
- runner.join
255
-
256
- expected = Resolv::DNS::Message.new(10)
257
- expected.qr = 1
258
- expected.aa = 1
259
-
260
- expected.add_answer DISCOVERY_NAME, 10,
261
- Resolv::DNS::Resource::IN::PTR.new(Resolv::DNS::Name.create(s.service))
262
-
263
- expected.add_question DISCOVERY_NAME, Resolv::DNS::Resource::IN::PTR
264
-
265
- assert_equal expected, res
266
- end
267
-
268
205
  def test_service_multicast_answer
269
206
  q = Thread::Queue.new
270
207
  rd, wr = IO.pipe
271
208
 
272
- listen = make_listener rd, q
273
- s = make_server iface
209
+ latch = Queue.new
210
+ listen = make_listener rd, q, started_callback: -> { latch << :start }
211
+ s = make_server iface, started_callback: -> { latch << :start }
274
212
  server = Thread.new { s.start }
275
- Thread.pass until s.started? && listen[:started]
213
+ latch.pop
214
+ latch.pop
276
215
 
277
- query = Resolv::DNS::Message.new 10
216
+ query = Resolv::DNS::Message.new 0
278
217
  query.add_question "_test-mdns._tcp.local.", Resolv::DNS::Resource::IN::PTR
279
- sock = open_ipv4 iface.addr, Resolv::MDNS::Port
218
+ sock = open_ipv4 iface.addr, 0
280
219
  multicast_send sock, query.encode
281
220
 
282
221
  service = Resolv::DNS::Name.create s.service
@@ -316,14 +255,15 @@ module ZeroConf
316
255
  end
317
256
 
318
257
  def test_service_unicast_answer
319
- s = make_server iface
258
+ latch = Queue.new
259
+ s = make_server iface, started_callback: -> { latch << :start }
320
260
  runner = Thread.new { s.start }
321
- Thread.pass until s.started?
261
+ latch.pop
322
262
 
323
- query = Resolv::DNS::Message.new 10
263
+ query = Resolv::DNS::Message.new 0
324
264
  query.add_question "_test-mdns._tcp.local.", PTR
325
265
 
326
- sock = open_ipv4 iface.addr, Resolv::MDNS::Port
266
+ sock = open_ipv4 iface.addr, 0
327
267
  multicast_send sock, query.encode
328
268
  res = Resolv::DNS::Message.decode read_with_timeout(sock).first
329
269
  s.stop
@@ -349,53 +289,20 @@ module ZeroConf
349
289
  assert_equal expected, res
350
290
  end
351
291
 
352
- def test_service_legacy_unicast_answer
353
- s = make_server iface
354
- runner = Thread.new { s.start }
355
- Thread.pass until s.started?
356
-
357
- query = Resolv::DNS::Message.new 10
358
- query.add_question "_test-mdns._tcp.local.", PTR
359
-
360
- sock = open_ipv4 iface.addr, 0
361
- multicast_send sock, query.encode
362
- res = Resolv::DNS::Message.decode read_with_timeout(sock).first
363
- s.stop
364
- runner.join
365
-
366
- expected = Resolv::DNS::Message.new(10)
367
- expected.qr = 1
368
- expected.aa = 1
369
-
370
- expected.add_additional s.service_name, 10, Resolv::DNS::Resource::IN::SRV.new(0, 0, s.service_port, s.qualified_host)
371
- expected.add_additional s.qualified_host,
372
- 10,
373
- Resolv::DNS::Resource::IN::A.new(iface.addr.ip_address)
374
-
375
- expected.add_additional s.service_name,
376
- 10,
377
- Resolv::DNS::Resource::IN::TXT.new(*s.text)
378
- expected.add_answer s.service,
379
- 10,
380
- Resolv::DNS::Resource::IN::PTR.new(Resolv::DNS::Name.create(s.service_name))
381
- expected.add_question s.service, Resolv::DNS::Resource::IN::PTR
382
-
383
- assert_equal expected, res
384
- end
385
-
386
-
387
292
  def test_multicast_service_instance_answer
388
293
  q = Queue.new
389
294
  rd, wr = IO.pipe
390
295
 
391
- listen = make_listener rd, q
392
- s = make_server iface
296
+ latch = Queue.new
297
+ listen = make_listener rd, q, started_callback: -> { latch << :start }
298
+ s = make_server iface, started_callback: -> { latch << :start }
393
299
  server = Thread.new { s.start }
394
- Thread.pass until s.started?
300
+ latch.pop
301
+ latch.pop
395
302
 
396
- query = Resolv::DNS::Message.new 10
303
+ query = Resolv::DNS::Message.new 0
397
304
  query.add_question "tc-lan-adapter._test-mdns._tcp.local.", Resolv::DNS::Resource::IN::PTR
398
- sock = open_ipv4 iface.addr, Resolv::MDNS::Port
305
+ sock = open_ipv4 iface.addr, 0
399
306
  multicast_send sock, query.encode
400
307
 
401
308
  service_name = Resolv::DNS::Name.create s.service_name
@@ -430,14 +337,15 @@ module ZeroConf
430
337
  end
431
338
 
432
339
  def test_unicast_name_lookup
433
- s = make_server iface
340
+ latch = Queue.new
341
+ s = make_server iface, started_callback: -> { latch << :start }
434
342
  runner = Thread.new { s.start }
435
- Thread.pass until s.started?
343
+ latch.pop
436
344
 
437
- query = Resolv::DNS::Message.new 10
345
+ query = Resolv::DNS::Message.new 0
438
346
  query.add_question "tc-lan-adapter.local.", A
439
347
 
440
- sock = open_ipv4 iface.addr, Resolv::MDNS::Port
348
+ sock = open_ipv4 iface.addr, 0
441
349
  multicast_send sock, query.encode
442
350
  res = Resolv::DNS::Message.decode read_with_timeout(sock).first
443
351
  s.stop
@@ -459,48 +367,20 @@ module ZeroConf
459
367
  assert_equal expected, res
460
368
  end
461
369
 
462
- def test_legacy_unicast_name_lookup
463
- s = make_server iface
464
- runner = Thread.new { s.start }
465
- Thread.pass until s.started?
466
-
467
- query = Resolv::DNS::Message.new 10
468
- query.add_question "tc-lan-adapter.local.", Resolv::DNS::Resource::IN::A
469
-
470
- sock = open_ipv4 iface.addr, 0
471
- multicast_send sock, query.encode
472
- res = Resolv::DNS::Message.decode read_with_timeout(sock).first
473
- s.stop
474
- runner.join
475
-
476
- expected = Resolv::DNS::Message.new(10)
477
- expected.qr = 1
478
- expected.aa = 1
479
-
480
- expected.add_answer s.qualified_host, 10, Resolv::DNS::Resource::IN::A.new(iface.addr.ip_address)
481
-
482
- expected.add_additional s.service_name,
483
- 10,
484
- Resolv::DNS::Resource::IN::TXT.new(*s.text)
485
-
486
- expected.add_question s.qualified_host,
487
- Resolv::DNS::Resource::IN::A
488
-
489
- assert_equal expected, res
490
- end
491
-
492
370
  def test_multicast_name
493
371
  q = Queue.new
494
372
  rd, wr = IO.pipe
495
373
 
496
- listen = make_listener rd, q
497
- s = make_server iface
374
+ latch = Queue.new
375
+ listen = make_listener rd, q, started_callback: -> { latch << :start }
376
+ s = make_server iface, started_callback: -> { latch << :start }
498
377
  server = Thread.new { s.start }
499
- Thread.pass until s.started?
378
+ latch.pop
379
+ latch.pop
500
380
 
501
- query = Resolv::DNS::Message.new 10
381
+ query = Resolv::DNS::Message.new 0
502
382
  query.add_question "tc-lan-adapter.local.", Resolv::DNS::Resource::IN::A
503
- sock = open_ipv4 iface.addr, Resolv::MDNS::Port
383
+ sock = open_ipv4 iface.addr, 0
504
384
  multicast_send sock, query.encode
505
385
 
506
386
  host = Resolv::DNS::Name.create s.qualified_host
@@ -529,6 +409,21 @@ module ZeroConf
529
409
  assert_equal expected, res
530
410
  end
531
411
 
412
+ def test_raise_on_malformed_requests
413
+ latch = Queue.new
414
+ s = make_server iface, abort_on_malformed_requests: true, started_callback: -> { latch << :start }
415
+ runner = Thread.new {
416
+ assert_raises do
417
+ s.start
418
+ end
419
+ }
420
+ latch.pop
421
+
422
+ sock = open_ipv4 iface.addr, Resolv::MDNS::Port
423
+ multicast_send sock, "not a valid DNS message"
424
+ runner.join
425
+ end
426
+
532
427
  def read_with_timeout sock
533
428
  return unless sock.wait_readable(3)
534
429
  sock.recvfrom(2048)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zeroconf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-15 00:00:00.000000000 Z
11
+ date: 2024-12-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: resolv