ippfind.c: Make multiple simultaneous searches in Avahi reliable#620
ippfind.c: Make multiple simultaneous searches in Avahi reliable#620zdohnal wants to merge 1 commit intoOpenPrinting:masterfrom
Conversation
|
OK, so this is something like: and you want ippfind to wait for at least one match for |
No, my original idea (the one I had implemented in this PR) was to wait until we have data from Avahi which matches the number of searches we started, because Avahi always sends ALL_FOR_NOW every time when it finished the search (regardless it found a match or not) - so the idea was to wait until we saw a specific number of ALL_FOR_NOW events and then start processing. However your review gave me an idea to introduce it only as default which can be overriden by setting a timeout via '-T', in case a script runs ippfind and expects it to finish in time.
Unfortunately this is a problem if empty response arrives sooner than the response with match or Avahi sends both responses in one write() (unfortunately Avahi sometimes bundles responses if they are sent from the same source...) - ippfind processes the empty response and finishes before the match is added into My main goal with this PR is that |
3e03982 to
c1d8e89
Compare
Since ippfind is a CLI tool, try to get a full answer by default and apply smaller timeout only if it is specified by `-T` parameter. ippfind will now return after one of the three scenarios are fullfilled: - for -T <= 1 and >= 0 - it will return immediately once there is no data from Avahi and all services are processed - without -T - returns once all services are processed and we have data from all searches - for -T > 1 - returns once while() loop finishes
72ada38 to
e06e757
Compare
|
Hmm, I'm still not happy with the proposed "fix". The "all for now" flag isn't even reliable with mDNSResponder so the strategy ippfind (and dnssd) use is to keep the browse going until all of the found services have been resolved/queried or the timeout expires, with a minimum of 1 second to find services with the browse. So let's actually try to fix the Avahi issue and not work around it... WRT the "driverless" backend, if it ran the "dnssd" backend to find printers then it wouldn't wake up every printer it finds and would choose the best/preferred protocol based on the priority key in the TXT records. |
You're right - when I was testing the fix, I saw ALL_FOR_NOW event in strace output, but now I don't see it in the response... so we can't rely on it :( .
Ok :( since we don't have a reliable way how to know whether we have all data from Avahi...
I've reported it upstream as avahi/avahi#442 - @pemensik and some other people are working on reviving Avahi now.
@tillkamppeter WDYT? It would be great if driverless was reliable in most situations (right now it isn't in case there is no IPPS printer and Avahi bundles the response) and this sounds feasible - either way we can raise ippfind timeout a little (a default cups-deviced timeout is 15s) in driverless in the meantime. |
|
Wait, what TXT priority key in TXT record? Doesn't it already use SRV records, which have both priority and weight fields already? Why would it need priority duplicated again in its TXT record? |
|
Using I already saw that it was a little slow and did many attempts to get it faster, partially also with the help of several GSoC contributors, in 2022 even having one whose task was optimizing Avahi usage in general. If the |
The Bonjour Printing Specification defines the "priority" key in TXT records to tell network clients which print protocol to prefer for that printer. The DNS SRV priority/weight mechanism is for choosing amongst equivalent services, for example choosing between NTP servers for a domain. |
That is pretty easy - just drop any device URI that doesn't contain |
|
FYI an interesting finding - Avahi actually does not bundle the response, I see two separate messages in DBUS monitoring, but they end up in one sendmsg() syscall, which triggers my issue. So not much in Avahi for fixing - I will try to spawn separate Avahi clients for searches and see whether it fixes the issue. |
Currently we mark data from Avahi as ready if there are data on a specific descriptor - this does not work if ippfind is called to do multiple simultaneous searches, and the first search result is empty, so ippfind returns nothing even if the other search(es) return(s) data.
The patch works with 'avahi_got_data' global variable, which is now incremented everytime 'browse_callback()' processes event ALL_FOR_NOW, which indicates the end of result for one search. ippfind will start the processing the data once 'avahi_got_data' matches with number of searches ippfind was told to do. The change slows the processing, but it will give use more reliable answers.