GNOME Bugzilla – Bug 653867
dnssd backend can only find one service
Last modified: 2011-07-08 04:24:37 UTC
for some reason i haven't fully isolated yet it seems like the dnssd backend can't resolve anything other than the last service discovered: ** (abraca:74688): DEBUG: dns_service_browse_reply (): success ** (abraca:74688): DEBUG: adding a service: pulstar ** (abraca:74688): DEBUG: dns_service_browse_reply (): success ** (abraca:74688): DEBUG: adding a service: pulstar ** (abraca:74688): DEBUG: dns_service_browse_reply (): success ** (abraca:74688): DEBUG: adding a service: kahless ** (abraca:74688): DEBUG: dns_service_browse_reply (): success ** (abraca:74688): DEBUG: adding a service: neutronstar ** (abraca:74688): DEBUG: Success processing DNS-SD browse result ** (abraca:74688): DEBUG: dns_service_resolve_reply (): success ** (abraca:74688): DEBUG: browser_add_service () ** (abraca:74688): DEBUG: dmap_mdns_browser_resolve () ** (abraca:74688): DEBUG: server_model.vala:42: neutronstar.local. 0 the last line is the only time the service_added signal is emited.. using dnssd from command line yields: here's another run with another service being found last, and thus properly added: ** (abraca:74787): DEBUG: dns_service_browse_reply (): success ** (abraca:74787): DEBUG: adding a service: pulstar ** (abraca:74787): DEBUG: dns_service_browse_reply (): success ** (abraca:74787): DEBUG: adding a service: pulstar ** (abraca:74787): DEBUG: dns_service_browse_reply (): success ** (abraca:74787): DEBUG: adding a service: neutronstar ** (abraca:74787): DEBUG: dns_service_browse_reply (): success ** (abraca:74787): DEBUG: adding a service: kahless ** (abraca:74787): DEBUG: Success processing DNS-SD browse result ** (abraca:74787): DEBUG: dns_service_resolve_reply (): success ** (abraca:74787): DEBUG: browser_add_service () ** (abraca:74787): DEBUG: dmap_mdns_browser_resolve () ** (abraca:74787): DEBUG: server_model.vala:42: kahless.local. 9667
It seems like the dnssd-backend processes all browse replies, overwriting the browse structure data with the latest service found each time callback during DNSServiceProcessResult is called. When DNSServiceProcessResult finishes it resolves the service found in the browse structure, which is naturally the last service found.
I solved this in my project by simply filling a GSList *backlog with what I call ServiceContext. This is a structure that is created in the browse-reply function and appended to the backlog-list. In the browse-available function this list is populated as the process-results is called. Once done all service contexts are dispatched as resolve-requests and deleted from the list. the requests get this context in their gio-function and the resolve-process-results is run to set the remaining data into the structure. once done each service found emits a signal in the glib main loop and any listener gets its data from the correct thread. Unfortunately my arm is in cast, and I'm short on time so I can't clean this up right now, but I'll attach my mutilated dnssd backend that implements what I described here.
Created attachment 191176 [details] a hacky proof-of-concept implementation of described solution if nobody adopts this in the near future i might come back in a couple of weeks and fix it good.
The DNS-SD code that used Apple's API gets less attention than the Avahi code, especially on the client side. I would surely appreciate a clean solution.
Okay, I installed Apple's dns_sd library so that I can help with this (I found that Avahi's Apple dns_sd compatibility library does not work quite right; so I went with the more invasive option of building and installing Apple's library). I went ahead and pushed the proposal from comment #3 to Git master after some quick testing. Hopefully I will find some time in the near future to look at this some more so that we can get it cleaned up.
Ouch, that wasn't really my idea. I thought the description "a hacky proof-of-concept" was enough to put you off :D service_result_available_cb does for example leak, throw in a service_context_free at the end there. Ok.. so now my shitty code is in the tree, with a reference to my name attached to it, so I guess I better start working on a proper version :D
Well, this is Git master after all.
Should be fixed in Git master now.