Skip to content

Commit cdeb8e1

Browse files
committed
Fix DNS-SD sharing issues (Issue #1217)
- Follow mDNS hostname changes unless explicitly configured with the DNSSDHostName directive. - Add DNSSDComputerName directive to control the "@ computer name" suffix on share names. - Update registrations whenever we detect a conflict or a hostname change. - Add RWLock for Printers array so that we can iterate over the printers list in the registration callback (separate thread). - Update cupsd.conf man page.
1 parent b1f4704 commit cdeb8e1

11 files changed

Lines changed: 512 additions & 463 deletions

File tree

CHANGES.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ Changes in CUPS v2.5b1 (YYYY-MM-DD)
3636
- Added new `cupsGetClock` API.
3737
- Added new `cupsParseOptions2` API with "end" argument.
3838
- Added `cups-oauth` and `cups-x509` utilities (Issue #1184)
39+
- Added `DNSSDComputerName` directive to "cupsd.conf" and updated cupsd to
40+
correctly update the mDNS hostname only if the `DNSSDHostName` directive is
41+
not specified (Issue #1217)
3942
- Updated documentation (Issue #984, Issue #1086, Issue #1182)
4043
- Updated translations (Issue #1146, Issue #1161, Issue #1164)
4144
- Updated the configure script to default to installing to /usr/local.

doc/help/man-cupsd.conf.html

Lines changed: 182 additions & 172 deletions
Large diffs are not rendered by default.

man/cupsd.conf.5

Lines changed: 184 additions & 172 deletions
Large diffs are not rendered by default.

scheduler/classes.c

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
/*
22
* Printer class routines for the CUPS scheduler.
33
*
4-
* Copyright © 2020-2024 by OpenPrinting.
5-
* Copyright 2007-2017 by Apple Inc.
6-
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
4+
* Copyright © 2020-2025 by OpenPrinting.
5+
* Copyright © 2007-2017 by Apple Inc.
6+
* Copyright © 1997-2007 by Easy Software Products, all rights reserved.
77
*
8-
* Licensed under Apache License v2.0. See the file "LICENSE" for more information.
8+
* Licensed under Apache License v2.0. See the file "LICENSE" for more
9+
* information.
910
*/
1011

1112
/*
@@ -662,7 +663,8 @@ cupsdSaveAllClasses(void)
662663
value[2048], /* Value string */
663664
*name; /* Current user name */
664665
cupsd_printer_t *pclass; /* Current printer class */
665-
int i; /* Looping var */
666+
int i, j, /* Looping vars */
667+
pcount; /* Number of printers */
666668
cups_option_t *option; /* Current option */
667669

668670

@@ -689,14 +691,16 @@ cupsdSaveAllClasses(void)
689691
* Write each local class known to the system...
690692
*/
691693

692-
for (pclass = (cupsd_printer_t *)cupsArrayFirst(Printers);
693-
pclass;
694-
pclass = (cupsd_printer_t *)cupsArrayNext(Printers))
694+
cupsRWLockRead(&PrintersLock);
695+
696+
for (i = 0, pcount = cupsArrayGetCount(Printers); i < pcount; i ++)
695697
{
696698
/*
697699
* Skip remote destinations and regular printers...
698700
*/
699701

702+
pclass = (cupsd_printer_t *)cupsArrayGetElement(Printers, i);
703+
700704
if ((pclass->type & CUPS_PTYPE_REMOTE) ||
701705
!(pclass->type & CUPS_PTYPE_CLASS))
702706
continue;
@@ -768,8 +772,8 @@ cupsdSaveAllClasses(void)
768772
pclass->job_sheets[1]);
769773
cupsFilePutConf(fp, "JobSheets", value);
770774

771-
for (i = 0; i < pclass->num_printers; i ++)
772-
cupsFilePrintf(fp, "Printer %s\n", pclass->printers[i]->name);
775+
for (j = 0; j < pclass->num_printers; j ++)
776+
cupsFilePrintf(fp, "Printer %s\n", pclass->printers[j]->name);
773777

774778
cupsFilePrintf(fp, "QuotaPeriod %d\n", pclass->quota_period);
775779
cupsFilePrintf(fp, "PageLimit %d\n", pclass->page_limit);
@@ -785,9 +789,9 @@ cupsdSaveAllClasses(void)
785789
if (pclass->error_policy)
786790
cupsFilePutConf(fp, "ErrorPolicy", pclass->error_policy);
787791

788-
for (i = pclass->num_options, option = pclass->options;
789-
i > 0;
790-
i --, option ++)
792+
for (j = pclass->num_options, option = pclass->options;
793+
j > 0;
794+
j --, option ++)
791795
{
792796
snprintf(value, sizeof(value), "%s %s", option->name, option->value);
793797
cupsFilePutConf(fp, "Option", value);
@@ -799,5 +803,7 @@ cupsdSaveAllClasses(void)
799803
cupsFilePuts(fp, "</Class>\n");
800804
}
801805

806+
cupsRWUnlock(&PrintersLock);
807+
802808
cupsdCloseCreatedConfFile(fp, filename);
803809
}

scheduler/conf.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ static const cupsd_var_t cupsd_vars[] =
7979
{ "DefaultPolicy", &DefaultPolicy, CUPSD_VARTYPE_STRING },
8080
{ "DefaultShared", &DefaultShared, CUPSD_VARTYPE_BOOLEAN },
8181
{ "DirtyCleanInterval", &DirtyCleanInterval, CUPSD_VARTYPE_TIME },
82+
{ "DNSSDComputerName", &DNSSDComputerName, CUPSD_VARTYPE_STRING },
8283
{ "DNSSDHostName", &DNSSDHostName, CUPSD_VARTYPE_STRING },
8384
{ "ErrorPolicy", &ErrorPolicy, CUPSD_VARTYPE_STRING },
8485
{ "FilterLimit", &FilterLimit, CUPSD_VARTYPE_INTEGER },
@@ -757,8 +758,9 @@ cupsdReadConfiguration(void)
757758
Browsing = CUPS_DEFAULT_BROWSING;
758759
DefaultShared = CUPS_DEFAULT_DEFAULT_SHARED;
759760

760-
cupsdSetString(&DNSSDSubTypes, "_cups,_print,_universal");
761+
cupsdClearString(&DNSSDComputerName);
761762
cupsdClearString(&DNSSDHostName);
763+
cupsdSetString(&DNSSDSubTypes, "_cups,_print,_universal");
762764

763765
cupsdSetString(&ErrorPolicy, CUPS_DEFAULT_ERROR_POLICY);
764766

@@ -866,6 +868,12 @@ cupsdReadConfiguration(void)
866868
return (0);
867869
}
868870

871+
DNSSDComputerNameConfigured = DNSSDComputerName != NULL;
872+
DNSSDHostNameConfigured = DNSSDHostName != NULL;
873+
874+
if (DNSSDComputerName && (!*DNSSDComputerName || !strcmp(DNSSDComputerName, "none")))
875+
cupsdClearString(&DNSSDComputerName);
876+
869877
RunUser = getuid();
870878

871879
cupsdLogMessage(CUPSD_LOG_INFO, "Remote access is %s.",

scheduler/dirsvc.c

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,6 @@ cupsdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
9090
void
9191
cupsdStartBrowsing(void)
9292
{
93-
cupsd_printer_t *p; /* Current printer */
94-
95-
9693
if (!Browsing || !BrowseLocalProtocols)
9794
return;
9895

@@ -112,16 +109,6 @@ cupsdStartBrowsing(void)
112109

113110
DNSSDPort = 0;
114111
cupsdUpdateDNSSDName();
115-
116-
/*
117-
* Register the individual printers
118-
*/
119-
120-
for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers))
121-
{
122-
if (!(p->type & (CUPS_PTYPE_REMOTE | CUPS_PTYPE_SCANNER)))
123-
dnssdRegisterPrinter(p);
124-
}
125112
}
126113
}
127114

@@ -152,7 +139,10 @@ cupsdStopBrowsing(void)
152139
void
153140
cupsdUpdateDNSSDName(void)
154141
{
155-
char name[1024]; /* Computer/host name */
142+
char name[1024]; /* Computer/host name */
143+
cupsd_printer_t *p; /* Current printer */
144+
int i, /* Looping var */
145+
pcount; /* Number of printers */
156146

157147

158148
/*
@@ -182,42 +172,41 @@ cupsdUpdateDNSSDName(void)
182172
if (!DNSSDPort)
183173
return;
184174

175+
cupsdLogMessage(CUPSD_LOG_DEBUG, "Using port %d for DNS-SD services.", DNSSDPort);
176+
185177
/*
186178
* Get the computer name...
187179
*/
188180

189-
if (cupsDNSSDCopyComputerName(DNSSDContext, name, sizeof(name)) && name[0])
190-
cupsdSetString(&DNSSDComputerName, name);
191-
192-
if (!DNSSDComputerName)
181+
if (!DNSSDComputerNameConfigured)
193182
{
194-
/*
195-
* Use the ServerName instead...
196-
*/
197-
198-
cupsdLogMessage(CUPSD_LOG_DEBUG, "Using ServerName \"%s\" as computer name.", ServerName);
199-
cupsdSetString(&DNSSDComputerName, ServerName);
183+
if (cupsDNSSDCopyComputerName(DNSSDContext, name, sizeof(name)) && name[0])
184+
cupsdSetString(&DNSSDComputerName, name);
185+
else
186+
cupsdSetString(&DNSSDComputerName, ServerName);
200187
}
201188

189+
if (DNSSDComputerName)
190+
cupsdLogMessage(CUPSD_LOG_DEBUG, "Appending \"@ %s\" to DNS-SD shared printer names.", DNSSDComputerName);
191+
202192
/*
203193
* Get the hostname...
204194
*/
205195

206-
if (cupsDNSSDCopyHostName(DNSSDContext, name, sizeof(name)))
207-
cupsdSetString(&DNSSDHostName, name);
208-
209-
if (!DNSSDHostName)
196+
if (!DNSSDHostNameConfigured)
210197
{
211-
if (strchr(ServerName, '.'))
198+
if (cupsDNSSDCopyHostName(DNSSDContext, name, sizeof(name)))
199+
cupsdSetString(&DNSSDHostName, name);
200+
else if (strchr(ServerName, '.'))
212201
cupsdSetString(&DNSSDHostName, ServerName);
213202
else
214203
cupsdSetStringf(&DNSSDHostName, "%s.local", ServerName);
215204

216-
cupsdLogMessage(CUPSD_LOG_INFO, "Defaulting to \"DNSSDHostName %s\".", DNSSDHostName);
205+
cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD host name is now \"%s\".", DNSSDHostName);
217206
}
218207

219208
/*
220-
* Then (re)register the web interface if enabled...
209+
* Then (re)register the web interface if enabled and any shared printers...
221210
*/
222211

223212
cupsDNSSDServiceDelete(DNSSDWebIF);
@@ -236,6 +225,20 @@ cupsdUpdateDNSSDName(void)
236225
cupsDNSSDServiceAdd(DNSSDWebIF, "_http._tcp", /*domain*/NULL, DNSSDHostName, (uint16_t)DNSSDPort, /*num_txt*/0, /*txt*/NULL);
237226
cupsDNSSDServicePublish(DNSSDWebIF);
238227
}
228+
229+
/*
230+
* (Re)register the individual printers
231+
*/
232+
233+
cupsRWLockRead(&PrintersLock);
234+
for (i = 0, pcount = cupsArrayGetCount(Printers); i < pcount; i ++)
235+
{
236+
p = (cupsd_printer_t *)cupsArrayGetElement(Printers, i);
237+
238+
if (!(p->type & (CUPS_PTYPE_REMOTE | CUPS_PTYPE_SCANNER)))
239+
dnssdRegisterPrinter(p);
240+
}
241+
cupsRWUnlock(&PrintersLock);
239242
}
240243

241244

@@ -425,11 +428,11 @@ dnssdRegisterCallback(
425428
const char *reg_name; // Updated service name
426429

427430

428-
if (flags & CUPS_DNSSD_FLAGS_ERROR)
431+
if ((flags & CUPS_DNSSD_FLAGS_ERROR) || !p)
429432
return;
430433

431-
if (!p)
432-
return;
434+
if (flags & CUPS_DNSSD_FLAGS_HOST_CHANGE)
435+
cupsdUpdateDNSSDName();
433436

434437
reg_name = cupsDNSSDServiceGetName(service);
435438

scheduler/dirsvc.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* Directory services definitions for the CUPS scheduler.
33
*
4-
* Copyright © 2020-2024 by OpenPrinting.
4+
* Copyright © 2020-2025 by OpenPrinting.
55
* Copyright © 2007-2017 by Apple Inc.
66
* Copyright © 1997-2007 by Easy Software Products, all rights reserved.
77
*
@@ -28,11 +28,15 @@ VAR int Browsing VALUE(TRUE),
2828
BrowseLocalProtocols
2929
VALUE(BROWSE_ALL);
3030
/* Protocols to support for local printers */
31-
VAR char *DNSSDComputerName VALUE(NULL),
31+
VAR char *DNSSDComputerName VALUE(NULL);
3232
/* Computer/server name */
33-
*DNSSDHostName VALUE(NULL),
33+
VAR int DNSSDComputerNameConfigured VALUE(0);
34+
/* Was the DNSSDComputerName value configured in cupsd.conf? */
35+
VAR char *DNSSDHostName VALUE(NULL);
3436
/* Hostname */
35-
*DNSSDSubTypes VALUE(NULL);
37+
VAR int DNSSDHostNameConfigured VALUE(0);
38+
/* Was the DNSSDHostName value configured in cupsd.conf? */
39+
VAR char *DNSSDSubTypes VALUE(NULL);
3640
/* Bonjour registration subtypes */
3741
VAR cups_array_t *DNSSDAlias VALUE(NULL);
3842
/* List of dynamic ServerAlias's */

scheduler/ipp.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7532,6 +7532,8 @@ get_printers(cupsd_client_t *con, /* I - Client connection */
75327532
* OK, build a list of printers for this printer...
75337533
*/
75347534

7535+
cupsRWLockWrite(&PrintersLock); // Should be a reader lock, but we can't easily update loop logic right now
7536+
75357537
if (first_printer_name)
75367538
{
75377539
if ((printer = cupsdFindDest(first_printer_name)) == NULL)
@@ -7581,6 +7583,8 @@ get_printers(cupsd_client_t *con, /* I - Client connection */
75817583
}
75827584
}
75837585

7586+
cupsRWUnlock(&PrintersLock);
7587+
75847588
cupsArrayDelete(ra);
75857589

75867590
con->response->request.status.status_code = IPP_STATUS_OK;

scheduler/libcupsmime.exp

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)