Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Timeout for cupsEnumDests() too short (using Linux with Avahi) #751

Closed
tillkamppeter opened this issue Jul 12, 2023 · 7 comments · Fixed by #806
Closed

Timeout for cupsEnumDests() too short (using Linux with Avahi) #751

tillkamppeter opened this issue Jul 12, 2023 · 7 comments · Fixed by #806
Labels
bug Something isn't working priority-medium
Milestone

Comments

@tillkamppeter
Copy link
Member

tillkamppeter commented Jul 12, 2023

Describe the bug
Already for some time lpstat -e only lists the permanent CUPS queues, not discovered IPP printers on which CUPS can print using a temporary queue. Investigating the code revealed that the timeout for asynchronous Avahi resolving in the cupsGetDests() API function which uses the internal (static) function cups_get_dests() with its is too short.

In cups/dest.c is defined:

#  define _CUPS_DNSSD_GET_DESTS 250     /* Milliseconds for cupsGetDests */

setting it to

#  define _CUPS_DNSSD_GET_DESTS 1000    /* Milliseconds for cupsGetDests */

solves the problem. Now the loop in cups_get_dests() stays running long enough for the asynchronous Avahi resolving calls for the discovered IPP print destinatiuons to finish and the results being caught.

I have found out that for timeouts < 620 no resolving process at all is finishing in time and so no discovered IPP print destinations get listed and with only a little more than 620 msec, for example 630 msec, all the resolving processes finish and all the resukts get taken into account, making all printers listed (I had 27 in the test). Th 100 msec seem to be a very safe bet.

To Reproduce
Without the fix

lpstat -l -e

ouputs one line for each permanent CUPS queue, so if lpstat -v outputs a line like

device for testprinter: ipps://hp8730._ipps._tcp.local/

the lpstat -l -e gives the corresponding line

testprinter permanent ipp://localhost/printers/testprinter ipps://till-x1yoga.local:8002/ipp/print/hp8730

So we get one line for each permanent CUPS queue and no further lines for discovered printers.

With the timeout corrected and with IPP print destinations available (The driverless command lists all of them) the command

lpstat -l -e

has more output, in addition to the lines for permanent queues there are lines for discovered IPP printers.
For each output line of driverless like

ipps://test._ipps._tcp.local/

you get a line

test network none ipps://test._ipps._tcp.local/

(at least if no permanent queue was created for this URI.

System Information:

  • OS is Ubuntu 23.04 and 23.10
  • CUPS is version 2.4.2 or later, up to the current GIT master (libcups.so.2)
  • Avahi is version 0.8
tillkamppeter added a commit to OpenPrinting/cups-snap that referenced this issue Jul 12, 2023
"cups.lpstat -l -e" lists ALL available print destinations and tells
in the first word of each output line, which queue name you have to
use with commands like "lp". It does not only list permanent CUPS
queues, which you create with a printer setup tool or with the
"lpadmin" command, but also IPP print destinations to which CUPS
prints without needing a permanent print queue, where CUPS creates a
temporary queues just for printing your job.

Current CUPS unfortunately has a bug, making "cups.lpstat -l -e"
listing only the permanent queues, the same as it lists with
"cups.lpstat -v", ending up not having a command line tool showing the
IPP print destinations with the CUPS queue names to use for printing
to them ("driverless" only shows the URIs, not the CUPS queue names).

The problem is that the "cupsGetDests()" function has a too short
timeout when waiting for Avahi resolving the DNS-SD records of the
discovered IPP print destinations. The loop stops before any of the
answers arrives, resulting in only the permanent queues being listed,
which are taken directkly from CUPS and do not requires DNS-SD
browsing and resolving.

This commit raises the timeout from 250 msec to 1000 msec and this
makes the discovered IPP destinations appear.

"cups.lpstat -l -e" needs a full second now, but gives the expected
results.

See OpenPrinting/cups#751
@zdohnal
Copy link
Member

zdohnal commented Jul 13, 2023

Hmm... never had this problem on Fedora, is your network full mDNS devices, so Avahi is not able to respond in time?

My current Fedora Linux 38 (CUPS 2.4.6, Avahi 0.8, nss-mdns 0.15.1, cups-browsed does not run and my local printers are not advertised) shows the following:

(Canon IPP-USB printer connected by USB and network, and pure network HP printer)
$ lpstat -l -e
Canon_MF440_Series_USB_1 network none ipp://Canon%20MF440%20Series%20(USB%201)._ipp._tcp.local/
Canon_MF440_Series network none ipps://Canon%20MF440%20Series._ipps._tcp.local/
HP_Color_LaserJet_MFP_M277dw_516EE8 network none ipps://HP%20Color%20LaserJet%20MFP%20M277dw%20(516EE8)._ipps._tcp.local/

Complete driverless output:
$ driverless
ipp://Canon%20MF440%20Series%20(USB%201)._ipp._tcp.local/
ipps://Canon%20MF440%20Series._ipps._tcp.local/
ipps://HP%20Color%20LaserJet%20MFP%20M277dw%20(516EE8)._ipps._tcp.local/

If the network is not crowded with mDNS or mDNS is not delayed by a third party (I recall Avahi has reflector feature, which can relay mDNS between different networks, but it is slower), there can be a downstream patch/bug in Avahi, which causes delays.

Marking @pemensik for heads-up, he might know whether there is such issue in Avahi.

@zdohnal zdohnal added the platform issue Issue is specific to an OS or desktop label Jul 13, 2023
@zdohnal zdohnal added the waiting for reporter There are data requested from the reporter label Aug 1, 2023
@zdohnal
Copy link
Member

zdohnal commented Sep 13, 2023

@tillkamppeter any update?

@tillkamppeter
Copy link
Member Author

Sorry for the late reply, but for me there are indeed many DNS-SD entries. Once I am running several Printer Applications with each having several internal print queues, and second, I have many network interfaces, due to running virtual machinbes and containers, where the appropriate managing software creates (virtual) network interfaces to connect these instances with the host. The Printer Applications appear on each interface again, multiplying the number of entries even more. Also non-printer entries, like network appliances and servers, web admin interfaces, ... get multiplied.

$ avahi-browse -t _ipp._tcp | wc -l
165
$

@zdohnal
Copy link
Member

zdohnal commented Oct 19, 2023

IMO this is not a common setup which users will have (even on cups-sharing admins will probably hardwire the queues permanently than relying on Avahi) and part of the problem lies in Avahi as well, but I would propose a new public function in libcups which would accept the msec parameter which will be used for cups_enum_dests() timeout, and a new 'timeout' option for lpstat. So anyone who needs more time can set the function to do so, and the common use cases won't be hindered by higher timeout.
@michaelrsweet WDYT?

@michaelrsweet
Copy link
Member

@zdohnal The public api (cupsEnumDests) has a timeout argument already... As for extending lpstat -e, maybe but I'd rather just fix the current behavior so that we stick around long enough (up to 10 seconds) to get a more complete list.

@tillkamppeter
Copy link
Member Author

Yes, just extending the default timeout to 10 sec is no problems. Avahi tells when it has finished and so we will not be stuck by 10 seconds, and have Avahi taking ~1 sec on a busy system is no problem, much better than entries missing.

@zdohnal
Copy link
Member

zdohnal commented Oct 23, 2023

@tillkamppeter @michaelrsweet ack - let's go with changed default - I was worried how cupsGetDests() will perform on a system with disabled mDNS service, but libcups is not able to create a new client if there is no running mDNS service, so there is no delay.
I'll create a PR for this.

zdohnal added a commit to zdohnal/cups that referenced this issue Oct 23, 2023
The current timeout is not able to list all network devices if there are
many IPP services on mDNS (the tested number is 165 services).

Raising the timeout to 1s does not slow libcups if there are less
services (Avahi returns earlier) or if Avahi does not run on the system
(libcups cannot create an Avahi client in that case), and provides time
frame for getting reasonable amount of IPP services (big enterprise
servers will use permanent queues and printer profiles than mDNS).

Fixes OpenPrinting#751
@zdohnal zdohnal added bug Something isn't working priority-medium and removed platform issue Issue is specific to an OS or desktop waiting for reporter There are data requested from the reporter labels Oct 23, 2023
@zdohnal zdohnal added this to the v2.4.x milestone Oct 23, 2023
zdohnal added a commit to zdohnal/cups that referenced this issue Oct 23, 2023
zdohnal added a commit that referenced this issue Oct 25, 2023
The current timeout is not able to list all network devices if there are many IPP services on mDNS (the tested number is 165 services).

Raising the timeout to 1s does not slow libcups if there are less services (Avahi returns earlier) or if Avahi does not run on the system (libcups cannot create an Avahi client in that case), and provides time frame for getting reasonable amount of IPP services (big enterprise servers will use permanent queues and printer profiles than mDNS).

Fixes #751
zdohnal added a commit that referenced this issue Oct 25, 2023
zdohnal added a commit that referenced this issue May 21, 2024
Forgot to include in 2.4.8... fixes #751 for series 2.4.x.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working priority-medium
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants