Bug#852436: fixed in cups-filters 1.16.1-1
Dear all,
Unfortunately this bug still happens in Debian Stretch. To fix it I had to
backport the two fixes upstream that are mentioned in this thread. The patches
are attached and apply on top of the debian/stretch branch. A suggested
changelog figures below, extracted from upstream changes to the NEWS file.
* Backport bug-fixes from the 1.16 branch:
- cups-browsed: Make timeouts for HTTP access to the local
CUPS daemon and remote IPP printers configurable. Thanks to
Cedric Dufour (cedric dot dufour at idiap dot ch) for the
patch (Bug #1387, Debian bug #852436).
* Backport bug-fixes from the 1.13 branch:
- cups-browsed: Do not use deprecated names for IPP status
constants
- cups-browsed: Corrected determination whether an IPP status
is an error, to avoid "Unable to create/modify CUPS queue
(Success)" and infinite repetition of a succeeded operation
(Debian bug #852436).
Thanks,
Louis
>From a424e78c1e21cebe6e7d2000f77ed54245a1ed51 Mon Sep 17 00:00:00 2001
From: Till Kamppeter <till.kamppeter@gmail.com>
Date: Tue, 24 Jan 2017 21:57:23 -0200
Subject: [PATCH 1/2] cups-browsed: Corrected determination whether an IPP
status is an error.
This is a backport from 1.13.4
Backport-by: Louis Rilling <l.rilling@av7.net>
---
utils/cups-browsed.c | 38 ++++++++++++++++++++------------------
1 file changed, 20 insertions(+), 18 deletions(-)
diff --git a/utils/cups-browsed.c b/utils/cups-browsed.c
index 991d6da..294e450 100644
--- a/utils/cups-browsed.c
+++ b/utils/cups-browsed.c
@@ -742,7 +742,7 @@ prepare_browse_data (void)
debug_printf("preparing browse data\n");
response = cupsDoRequest (conn, request, "/");
- if (cupsLastError() > IPP_OK_CONFLICT) {
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
debug_printf("browse send failed for localhost: %s\n",
cupsLastErrorString ());
goto fail;
@@ -1753,7 +1753,7 @@ create_subscription ()
"notify-lease-duration", NOTIFY_LEASE_DURATION);
resp = cupsDoRequest (conn, req, "/");
- if (!resp || cupsLastError() != IPP_OK) {
+ if (!resp || cupsLastError() != IPP_STATUS_OK) {
debug_printf ("Error subscribing to CUPS notifications: %s\n",
cupsLastErrorString ());
return 0;
@@ -1792,7 +1792,7 @@ renew_subscription (int id)
"notify-lease-duration", NOTIFY_LEASE_DURATION);
resp = cupsDoRequest (conn, req, "/");
- if (!resp || cupsLastError() != IPP_OK) {
+ if (!resp || cupsLastError() != IPP_STATUS_OK) {
debug_printf ("Error renewing CUPS subscription %d: %s\n",
id, cupsLastErrorString ());
return FALSE;
@@ -1834,7 +1834,7 @@ cancel_subscription (int id)
"notify-subscription-id", id);
resp = cupsDoRequest (conn, req, "/");
- if (!resp || cupsLastError() != IPP_OK) {
+ if (!resp || cupsLastError() != IPP_STATUS_OK) {
debug_printf ("Error subscribing to CUPS notifications: %s\n",
cupsLastErrorString ());
return;
@@ -1979,7 +1979,7 @@ enable_printer (const char *printer) {
ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, uri);
ippDelete(cupsDoRequest (conn, request, "/admin/"));
- if (cupsLastError() > IPP_STATUS_OK_CONFLICTING) {
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
debug_printf("ERROR: Failed enabling printer '%s': %s\n",
printer, cupsLastErrorString());
return -1;
@@ -2006,7 +2006,7 @@ disable_printer (const char *printer, const char *reason) {
ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_TEXT,
"printer-state-message", NULL, reason);
ippDelete(cupsDoRequest (conn, request, "/admin/"));
- if (cupsLastError() > IPP_STATUS_OK_CONFLICTING) {
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
debug_printf("ERROR: Failed disabling printer '%s': %s\n",
printer, cupsLastErrorString());
return -1;
@@ -2033,7 +2033,7 @@ set_cups_default_printer(const char *printer) {
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
NULL, cupsUser());
ippDelete(cupsDoRequest(conn, request, "/admin/"));
- if (cupsLastError() > IPP_STATUS_OK_CONFLICTING) {
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
debug_printf("ERROR: Failed setting CUPS default printer to '%s': %s\n",
printer, cupsLastErrorString());
return -1;
@@ -2059,7 +2059,7 @@ get_cups_default_printer() {
"requesting-user-name", NULL, cupsUser());
/* Do it */
response = cupsDoRequest(conn, request, "/");
- if (cupsLastError() > IPP_OK_CONFLICT || !response) {
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE || !response) {
debug_printf("Could not determine system default printer!\n");
} else {
for (attr = ippFirstAttribute(response); attr != NULL;
@@ -2782,7 +2782,7 @@ on_printer_state_changed (CupsNotifier *object,
cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER);
ippDelete(cupsDoRequest(conn, request, "/admin/"));
cupsFreeOptions(num_options, options);
- if (cupsLastError() > IPP_OK_CONFLICT) {
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
debug_printf("ERROR: Unable to set \"" CUPS_BROWSED_DEST_PRINTER
"-default\" option to communicate the destination server for this job (%s)!\n",
cupsLastErrorString());
@@ -3492,7 +3492,7 @@ gboolean handle_cups_queues(gpointer unused) {
"requesting-user-name", NULL, cupsUser());
/* Do it */
ippDelete(cupsDoRequest(http, request, "/admin/"));
- if (cupsLastError() > IPP_OK_CONFLICT) {
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
debug_printf("Unable to remove CUPS queue!\n");
if (in_shutdown == 0) {
p->timeout = current_time + TIMEOUT_RETRY;
@@ -3864,7 +3864,7 @@ gboolean handle_cups_queues(gpointer unused) {
ippDelete(cupsDoRequest(http, request, "/admin/"));
}
cupsFreeOptions(num_options, options);
- if (cupsLastError() > IPP_OK_CONFLICT) {
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
debug_printf("Unable to create/modify CUPS queue (%s)!\n",
cupsLastErrorString());
p->timeout = current_time + TIMEOUT_RETRY;
@@ -3895,7 +3895,7 @@ gboolean handle_cups_queues(gpointer unused) {
cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER);
ippDelete(cupsDoRequest(http, request, "/admin/"));
cupsFreeOptions(num_options, options);
- if (cupsLastError() > IPP_OK_CONFLICT)
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE)
debug_printf("Unable to set printer-is-shared bit to false (%s)!\n",
cupsLastErrorString());
@@ -3920,7 +3920,7 @@ gboolean handle_cups_queues(gpointer unused) {
cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER);
ippDelete(cupsDoRequest(http, request, "/admin/"));
cupsFreeOptions(num_options, options);
- if (cupsLastError() > IPP_OK_CONFLICT)
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE)
debug_printf("Unable to remove PPD file from the print queue (%s)!\n",
cupsLastErrorString());
}
@@ -5498,7 +5498,7 @@ browse_poll_get_printers (browsepoll_t *context, http_t *conn)
"requesting-user-name", NULL, cupsUser ());
response = cupsDoRequest(conn, request, "/");
- if (cupsLastError() > IPP_OK_CONFLICT) {
+ if (cupsLastError() > IPP_STATUS_OK_EVENTS_COMPLETE) {
debug_printf("cups-browsed [BrowsePoll %s:%d]: failed: %s\n",
context->server, context->port, cupsLastErrorString ());
goto fail;
@@ -5585,7 +5585,8 @@ browse_poll_create_subscription (browsepoll_t *context, http_t *conn)
"notify-time-interval", BrowseInterval);
response = cupsDoRequest (conn, request, "/");
- if (!response || ippGetStatusCode (response) > IPP_OK_CONFLICT) {
+ if (!response ||
+ ippGetStatusCode (response) > IPP_STATUS_OK_EVENTS_COMPLETE) {
debug_printf("cupsd-browsed [BrowsePoll %s:%d]: failed: %s\n",
context->server, context->port, cupsLastErrorString ());
context->subscription_id = -1;
@@ -5652,7 +5653,8 @@ browse_poll_cancel_subscription (browsepoll_t *context)
"notify-subscription-id", context->subscription_id);
response = cupsDoRequest (conn, request, "/");
- if (!response || ippGetStatusCode (response) > IPP_OK_CONFLICT)
+ if (!response ||
+ ippGetStatusCode (response) > IPP_STATUS_OK_EVENTS_COMPLETE)
debug_printf("cupsd-browsed [BrowsePoll %s:%d]: failed: %s\n",
context->server, context->port, cupsLastErrorString ());
@@ -5695,13 +5697,13 @@ browse_poll_get_notifications (browsepoll_t *context, http_t *conn)
else
status = ippGetStatusCode (response);
- if (status == IPP_NOT_FOUND) {
+ if (status == IPP_STATUS_ERROR_NOT_FOUND) {
/* Subscription lease has expired. */
debug_printf ("cups-browsed [BrowsePoll %s:%d]: Lease expired\n",
context->server, context->port);
browse_poll_create_subscription (context, conn);
get_printers = TRUE;
- } else if (status > IPP_OK_CONFLICT) {
+ } else if (status > IPP_STATUS_OK_EVENTS_COMPLETE) {
debug_printf("cups-browsed [BrowsePoll %s:%d]: failed: %s\n",
context->server, context->port, cupsLastErrorString ());
context->can_subscribe = FALSE;
--
2.11.0
>From 93fef84f53776c8a14c4f90affdf755546557ac0 Mon Sep 17 00:00:00 2001
From: Till Kamppeter <till.kamppeter@gmail.com>
Date: Wed, 9 Aug 2017 15:11:06 -0300
Subject: [PATCH 2/2] cups-browsed: Make timeouts for HTTP access to the local
CUPS daemon and remote IPP printers configurable.
This is a backport from 1.16.1
Backport-by: Louis Rilling <l.rilling@av7.net>
---
utils/cups-browsed.c | 28 ++++++++++++++++++++++------
utils/cups-browsed.conf.5 | 13 +++++++++++++
utils/cups-browsed.conf.in | 10 ++++++++++
3 files changed, 45 insertions(+), 6 deletions(-)
diff --git a/utils/cups-browsed.c b/utils/cups-browsed.c
index 294e450..6932591 100644
--- a/utils/cups-browsed.c
+++ b/utils/cups-browsed.c
@@ -339,6 +339,8 @@ static size_t NumBrowsePoll = 0;
static guint update_netifs_sourceid = 0;
static char local_server_str[1024];
static char *DomainSocket = NULL;
+static unsigned int HttpLocalTimeout = 5;
+static unsigned int HttpRemoteTimeout = 10;
static ip_based_uris_t IPBasedDeviceURIs = IP_BASED_URIS_NO;
static unsigned int CreateRemoteRawPrinterQueues = 0;
static unsigned int CreateIPPPrinterQueues = 0;
@@ -579,6 +581,7 @@ httpConnectEncryptShortTimeout(const char *host, int port,
int
http_timeout_cb(http_t *http, void *user_data)
{
+ debug_printf("HTTP timeout! (consider increasing HttpLocalTimeout/HttpRemoteTimeout value)\n");
return 0;
}
@@ -591,7 +594,7 @@ http_connect_local (void)
cupsEncryption());
}
if (local_conn)
- httpSetTimeout(local_conn, 3, http_timeout_cb, NULL);
+ httpSetTimeout(local_conn, HttpLocalTimeout, http_timeout_cb, NULL);
else
debug_printf("cups-browsed: Failed creating http connection to local CUPS daemon: %s:%d\n", cupsServer(), ippPort());
@@ -2617,7 +2620,7 @@ on_printer_state_changed (CupsNotifier *object,
p->port);
if (http) {
/* Check whether the printer is idle, processing, or disabled */
- httpSetTimeout(http, 2, http_timeout_cb, NULL);
+ httpSetTimeout(http, HttpRemoteTimeout, http_timeout_cb, NULL);
request = ippNewRequest(CUPS_GET_PRINTERS);
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
"requested-attributes",
@@ -3576,7 +3579,7 @@ gboolean handle_cups_queues(gpointer unused) {
p->timeout = current_time + TIMEOUT_RETRY;
break;
}
- httpSetTimeout(http, 3, http_timeout_cb, NULL);
+ httpSetTimeout(http, HttpLocalTimeout, http_timeout_cb, NULL);
/* Do not auto-save option settings due to the print queue creation
process */
@@ -3629,7 +3632,7 @@ gboolean handle_cups_queues(gpointer unused) {
p->no_autosave = 0;
break;
}
- httpSetTimeout(remote_http, 3, http_timeout_cb, NULL);
+ httpSetTimeout(remote_http, HttpRemoteTimeout, http_timeout_cb, NULL);
if ((loadedppd = cupsGetPPD2(remote_http, p->name)) == NULL &&
CreateRemoteRawPrinterQueues == 0) {
debug_printf("Unable to load PPD file for %s from the server %s:%d!\n",
@@ -5632,7 +5635,7 @@ browse_poll_cancel_subscription (browsepoll_t *context)
return;
}
- httpSetTimeout(conn, 3, http_timeout_cb, NULL);
+ httpSetTimeout(conn, HttpRemoteTimeout, http_timeout_cb, NULL);
debug_printf ("cups-browsed [BrowsePoll %s:%d]: IPP-Cancel-Subscription\n",
context->server, context->port);
@@ -5774,7 +5777,7 @@ browse_poll (gpointer data)
goto fail;
}
- httpSetTimeout(conn, 3, http_timeout_cb, NULL);
+ httpSetTimeout(conn, HttpRemoteTimeout, http_timeout_cb, NULL);
if (context->can_subscribe) {
if (context->subscription_id == -1) {
@@ -6290,6 +6293,19 @@ read_configuration (const char *filename)
} else if (!strcasecmp(line, "DomainSocket") && value) {
if (value[0] != '\0')
DomainSocket = strdup(value);
+ } else if ((!strcasecmp(line, "HttpLocalTimeout") || !strcasecmp(line, "HttpRemoteTimeout")) && value) {
+ int t = atoi(value);
+ if (t >= 0) {
+ if (!strcasecmp(line, "HttpLocalTimeout"))
+ HttpLocalTimeout = t;
+ else if (!strcasecmp(line, "HttpRemoteTimeout"))
+ HttpRemoteTimeout = t;
+
+ debug_printf("Set %s to %d sec.\n",
+ line, t);
+ } else
+ debug_printf("Invalid %s value: %d\n",
+ line, t);
} else if (!strcasecmp(line, "IPBasedDeviceURIs") && value) {
if (!strcasecmp(value, "IPv4") || !strcasecmp(value, "IPv4Only"))
IPBasedDeviceURIs = IP_BASED_URIS_IPV4_ONLY;
diff --git a/utils/cups-browsed.conf.5 b/utils/cups-browsed.conf.5
index 81da976..30bbb31 100644
--- a/utils/cups-browsed.conf.5
+++ b/utils/cups-browsed.conf.5
@@ -416,6 +416,19 @@ or "Off" lets cups-browsed not use CUPS' domain socket.
.fam T
.fi
+Set HTTP timeout (in seconds) for requests sent to local/remote
+resources Note that too short timeouts can make services getting
+missed when they are present and operations be unneccesarily
+repeated and too long timeouts can make operations take too long
+when the server does not respond.
+.PP
+.nf
+.fam C
+ HttpLocalTimeout 5
+ HttpRemoteTimeout 10
+
+.fam T
+.fi
The interval between browsing/broadcasting cycles, local and/or
remote, can be adjusted with the BrowseInterval directive.
.PP
diff --git a/utils/cups-browsed.conf.in b/utils/cups-browsed.conf.in
index fd197cf..9fbd274 100644
--- a/utils/cups-browsed.conf.in
+++ b/utils/cups-browsed.conf.in
@@ -301,6 +301,16 @@ BrowseRemoteProtocols @BROWSEREMOTEPROTOCOLS@
# DomainSocket Off
+# Set HTTP timeout (in seconds) for requests sent to local/remote
+# resources Note that too short timeouts can make services getting
+# missed when they are present and operations be unneccesarily
+# repeated and too long timeouts can make operations take too long
+# when the server does not respond.
+
+# HttpLocalTimeout 5
+# HttpRemoteTimeout 10
+
+
# Set IPBasedDeviceURIs to "Yes" if cups-browsed should create its
# local queues with device URIs with the IP addresses instead of the
# host names of the remote servers. This mode is there for any
--
2.11.0
Reply to: