brutella / dnssd

This library implements Multicast DNS (mDNS) and DNS-Based Service Discovery (DNS-SD) for Zero Configuration Networking in Go.
MIT License
207 stars 33 forks source link

bug: v1.2.12 fails to query/browse existing services with spaces in their name #50

Closed b-kamphorst closed 3 weeks ago

b-kamphorst commented 1 month ago

Hi @brutella,

First of all, thank you for the valuable work. I use this package on regular basis, also in professional setting.

Now, I just upgraded to v1.2.12 and came across some issues with services that contain spaces in their name. I run dnssd on Windows 11 in WSL2 (NAT network mode). In order to be more reproducable / ensure that I use the correct dnssd version, I ran the faulty behaviour in docker containers on host network. All output below is from within containers based on a golang:1.22.6 image. Command: docker run -ti --rm --network=host --entrypoint /bin/sh golang:1.22.6

Expected behaviour

Existing services with spaces in their name are discovered when executing dnssd browse. Below you find the behaviour with dnssd@v1.2.11:

Click to see how services are registered. ```console # # Container 1, first to be executed, registers a service with name 'NoSpaces' # go install github.com/brutella/dnssd/cmd/dnssd@v1.2.11 go: downloading github.com/brutella/dnssd v1.2.11 go: downloading github.com/miekg/dns v1.1.54 go: downloading golang.org/x/net v0.10.0 go: downloading golang.org/x/sys v0.8.0 # dnssd register -Name='NoSpaces' -Port='123' -Type='_example._tcp' Registering Service NoSpaces._example._tcp.local. port 123 DATE: –––Thu Oct 3 2024––– 07:35:39.591 ...STARTING... 07:35:41.464 Got a reply for service NoSpaces._example._tcp.local.: Name now registered and active ``` ```console # # Container 2, second to be executed, registers a service with name `With Spaces` # go install github.com/brutella/dnssd/cmd/dnssd@v1.2.11 go: downloading github.com/brutella/dnssd v1.2.11 go: downloading github.com/miekg/dns v1.1.54 go: downloading golang.org/x/net v0.10.0 go: downloading golang.org/x/sys v0.8.0 # dnssd register -Name='With Spaces' -Port='456' -Type='_example._tcp' Registering Service With Spaces._example._tcp.local. port 456 DATE: –––Thu Oct 3 2024––– 07:35:44.477 ...STARTING... 07:35:46.455 Got a reply for service With Spaces._example._tcp.local.: Name now registered and active ```
# # Container 3, last to be executed, browses for services
# go install github.com/brutella/dnssd/cmd/dnssd@v1.2.11
go: downloading github.com/brutella/dnssd v1.2.11
go: downloading github.com/miekg/dns v1.1.54
go: downloading golang.org/x/net v0.10.0
go: downloading golang.org/x/sys v0.8.0
# dnssd browse -Type='_example._tcp'
Browsing for _example._tcp.local.
DATE: –––Thu Oct 3 2024–––
07:35:48.696  ...STARTING...
Timestamp       A/R     if Domain       Service Type    Instance Name
07:35:48.748    Add     eth0    local   _example._tcp   NoSpaces ([172.23.201.13 fe80::215:5dff:fef2:b290])
07:35:48.761    Add     eth0    local   _example._tcp   With Spaces ([172.23.201.13 fe80::215:5dff:fef2:b290])
07:35:48.855    Add     br-62e18f286546 local   _example._tcp   NoSpaces ([172.19.0.1])
07:35:48.855    Add     br-62e18f286546 local   _example._tcp   With Spaces ([172.19.0.1])
07:35:48.921    Add     docker0 local   _example._tcp   NoSpaces ([172.17.0.1 fe80::42:32ff:fe98:2135])
07:35:48.921    Add     docker0 local   _example._tcp   With Spaces ([172.17.0.1 fe80::42:32ff:fe98:2135])
07:35:49.058    Add     br-f127e05ddf56 local   _example._tcp   With Spaces ([172.18.0.1 fe80::42:acff:fe21:bde9])
07:35:49.058    Add     br-f127e05ddf56 local   _example._tcp   NoSpaces ([172.18.0.1 fe80::42:acff:fe21:bde9])
07:35:49.224    Add     veth96b0c3b     local   _example._tcp   NoSpaces ([fe80::78c1:48ff:fe23:d57a])
07:35:49.224    Add     veth96b0c3b     local   _example._tcp   With Spaces ([fe80::78c1:48ff:fe23:d57a])

All services are discovered. The same behaviour is observed if the services are registered with dnssd v1.2.12 while browsed with dnssd v1.2.11.

Observed behaviour

Existing services with spaces in their name are not discovered when executing dnssd browse. Below you find the behaviour with dnssd@v1.2.12:

Click to see how services are registered. ```console # # Container 1, first to be executed, registers a service with name 'NoSpaces' # go install github.com/brutella/dnssd/cmd/dnssd@v1.2.12 go: downloading github.com/brutella/dnssd v1.2.12 go: downloading github.com/miekg/dns v1.1.61 go: downloading github.com/vishvananda/netlink v1.2.1-beta.2 go: downloading golang.org/x/net v0.26.0 go: downloading golang.org/x/sys v0.21.0 go: downloading github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae # dnssd register -Name='NoSpaces' -Port='123' -Type='_example._tcp' Registering Service NoSpaces._example._tcp.local. port 123 DATE: –––Thu Oct 3 2024––– 07:16:59.610 ...STARTING... 07:17:01.576 Got a reply for service NoSpaces._example._tcp.local.: Name now registered and active ``` ```console # # Container 2, second to be executed, registers a service with name `With Spaces` # go install github.com/brutella/dnssd/cmd/dnssd@v1.2.12 go: downloading github.com/brutella/dnssd v1.2.12 go: downloading github.com/miekg/dns v1.1.61 go: downloading golang.org/x/net v0.26.0 go: downloading github.com/vishvananda/netlink v1.2.1-beta.2 go: downloading golang.org/x/sys v0.21.0 go: downloading github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae # dnssd register -Name='With Spaces' -Port='456' -Type='_example._tcp' Registering Service With Spaces._example._tcp.local. port 456 DATE: –––Thu Oct 3 2024––– 07:17:33.796 ...STARTING... 07:17:35.681 Got a reply for service With Spaces._example._tcp.local.: Name now registered and active ```
# # Container 3, last to be executed, browses for services
# go install github.com/brutella/dnssd/cmd/dnssd@v1.2.12
go: downloading github.com/brutella/dnssd v1.2.12
go: downloading github.com/vishvananda/netlink v1.2.1-beta.2
go: downloading golang.org/x/net v0.26.0
go: downloading github.com/miekg/dns v1.1.61
go: downloading golang.org/x/sys v0.21.0
go: downloading github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae
# dnssd browse -Type='_example._tcp'
Browsing for _example._tcp.local.
DATE: –––Thu Oct 3 2024–––
07:17:48.792  ...STARTING...
Timestamp       A/R     if Domain       Service Type    Instance Name
07:17:48.889    Add     eth0    local   _example._tcp   NoSpaces ([172.23.201.13 fe80::215:5dff:fef2:b290])
07:17:49.005    Add     br-62e18f286546 local   _example._tcp   NoSpaces ([172.19.0.1])
07:17:49.108    Add     docker0 local   _example._tcp   NoSpaces ([172.17.0.1 fe80::42:32ff:fe98:2135])
07:17:49.245    Add     br-f127e05ddf56 local   _example._tcp   NoSpaces ([172.18.0.1 fe80::42:acff:fe21:bde9])
07:17:49.398    Add     veth96b0c3b     local   _example._tcp   NoSpaces ([fe80::78c1:48ff:fe23:d57a])

Only the service without spaces in its name is discovered. If I cancel the dnssd register command in the second container and re-run it, then the service is discovered successfully in the active dnssd browse.

The same behaviour is observed if the services are registered with dnssd v1.2.11 while browsed with dnssd v1.2.12. As such, I hypothesise that the issue is in the service browsing / querying logic.

I look forward to your thoughts (and, hopefully, fix🤞).

brutella commented 3 weeks ago

I've fixed this issue in v1.2.14 by using the escaped service instance name as the map key to reference a service in the browsing cache.

b-kamphorst commented 3 weeks ago

Nice, much appreciated!