zeroconf 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/zeroconf/client.rb +1 -1
- data/lib/zeroconf/service.rb +31 -23
- data/lib/zeroconf/utils.rb +2 -3
- data/lib/zeroconf/version.rb +1 -1
- data/lib/zeroconf.rb +2 -2
- data/test/client_test.rb +18 -12
- data/test/helper.rb +5 -3
- data/test/service_test.rb +61 -166
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a6933171abe1ab052bf99d2bdb6efa5bd0378f536859e0cf812f2dd68b23461
|
4
|
+
data.tar.gz: 9c016607692b33ed3a516a872aa80117a119f3ac138a997a19a845684914890c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bdc315b09c4ada48b56f6f102c24b5c0a51740c6163ccb3b9a96e67c7f262a35e95126c950bb1efd394b4cbea06ec0b29e1ae3e55bd02bbd63b42b4159faa06f
|
7
|
+
data.tar.gz: 663cc13801926e626a61aea7aebe75d51e92e07ab5133723c53be48259dc19bec30c42cbe10348c3a6881028fac9124afb8c50a697203736f8e394060b479b99
|
data/lib/zeroconf/client.rb
CHANGED
@@ -14,7 +14,7 @@ module ZeroConf
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def run timeout: 3
|
17
|
-
sockets = open_interfaces interfaces.map(&:addr),
|
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) }
|
data/lib/zeroconf/service.rb
CHANGED
@@ -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
|
-
|
117
|
+
if reader == @rd
|
118
|
+
@rd.close
|
119
|
+
return
|
120
|
+
end
|
114
121
|
|
115
122
|
buf, from = reader.recvfrom 2048
|
116
|
-
msg =
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
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,
|
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
|
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,
|
250
|
+
msg.add_question service, PTR
|
241
251
|
|
242
252
|
msg
|
243
253
|
end
|
244
254
|
|
245
|
-
def dnssd_unicast_answer
|
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,
|
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
|
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,
|
369
|
+
msg.add_question qualified_host, MDNS::Announce::IN::A
|
362
370
|
|
363
371
|
if @text
|
364
372
|
msg.add_additional service_name,
|
data/lib/zeroconf/utils.rb
CHANGED
@@ -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)
|
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)
|
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
|
|
data/lib/zeroconf/version.rb
CHANGED
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
|
71
|
-
s = Service.new(
|
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
|
-
|
13
|
+
latch = Queue.new
|
14
|
+
s = make_server iface, "coolhostname", started_callback: -> { latch << :start }
|
14
15
|
runner = Thread.new { s.start }
|
15
|
-
|
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
|
-
|
37
|
+
latch = Queue.new
|
38
|
+
s = make_server iface, "coolhostname", started_callback: -> { latch << :start }
|
37
39
|
runner = Thread.new { s.start }
|
38
|
-
|
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
|
-
|
62
|
+
latch = Queue.new
|
63
|
+
s = make_server iface, started_callback: -> { latch << :start }
|
61
64
|
runner = Thread.new { s.start }
|
62
|
-
|
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
|
-
|
84
|
+
latch = Queue.new
|
85
|
+
s = make_server iface, started_callback: -> { latch << :start }
|
82
86
|
runner = Thread.new { s.start }
|
83
|
-
|
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
|
-
|
106
|
+
latch = Queue.new
|
107
|
+
s = make_server iface, started_callback: -> { latch << :start }
|
103
108
|
runner = Thread.new { s.start }
|
104
|
-
|
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
|
-
|
129
|
+
latch = Queue.new
|
130
|
+
s = make_server iface, started_callback: -> { latch << :start }
|
125
131
|
runner = Thread.new { s.start }
|
126
|
-
|
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
|
-
|
30
|
+
latch = Queue.new
|
31
|
+
s = make_server iface, started_callback: -> { latch << :start }
|
31
32
|
runner = Thread.new { s.start }
|
32
|
-
|
33
|
+
latch.pop
|
33
34
|
|
34
|
-
query = Resolv::DNS::Message.new
|
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,
|
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
|
-
|
66
|
+
latch = Queue.new
|
67
|
+
s = make_server iface, started_callback: -> { latch << :start }
|
97
68
|
server = Thread.new { s.start }
|
98
|
-
|
69
|
+
latch.pop
|
99
70
|
|
100
|
-
query = Resolv::DNS::Message.new
|
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,
|
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
|
-
|
170
|
+
latch = Queue.new
|
171
|
+
s = make_server iface, started_callback: -> { latch << :start }
|
200
172
|
runner = Thread.new { s.start }
|
201
|
-
|
173
|
+
latch.pop
|
202
174
|
|
203
|
-
query = Resolv::DNS::Message.new
|
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,
|
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
|
-
|
273
|
-
|
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
|
-
|
213
|
+
latch.pop
|
214
|
+
latch.pop
|
276
215
|
|
277
|
-
query = Resolv::DNS::Message.new
|
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,
|
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
|
-
|
258
|
+
latch = Queue.new
|
259
|
+
s = make_server iface, started_callback: -> { latch << :start }
|
320
260
|
runner = Thread.new { s.start }
|
321
|
-
|
261
|
+
latch.pop
|
322
262
|
|
323
|
-
query = Resolv::DNS::Message.new
|
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,
|
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
|
-
|
392
|
-
|
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
|
-
|
300
|
+
latch.pop
|
301
|
+
latch.pop
|
395
302
|
|
396
|
-
query = Resolv::DNS::Message.new
|
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,
|
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
|
-
|
340
|
+
latch = Queue.new
|
341
|
+
s = make_server iface, started_callback: -> { latch << :start }
|
434
342
|
runner = Thread.new { s.start }
|
435
|
-
|
343
|
+
latch.pop
|
436
344
|
|
437
|
-
query = Resolv::DNS::Message.new
|
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,
|
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
|
-
|
497
|
-
|
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
|
-
|
378
|
+
latch.pop
|
379
|
+
latch.pop
|
500
380
|
|
501
|
-
query = Resolv::DNS::Message.new
|
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,
|
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
|
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-
|
11
|
+
date: 2024-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: resolv
|