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