]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Resolve DNS-SD URIs correctly also if they are from a service from localhost
authorTill Kamppeter <till.kamppeter@gmail.com>
Mon, 12 Oct 2020 20:36:35 +0000 (22:36 +0200)
committerTill Kamppeter <till.kamppeter@gmail.com>
Mon, 12 Oct 2020 20:36:35 +0000 (22:36 +0200)
If a service is only available locally, through the loopback device
("lo", "localhost"), like for example the IPP-over-USB daemon ipp-usb
or a Printer Application which is not sharing printers to the network,
the service cannot be accessed through the network host name but only
through the host name "localhost".

To make CUPS' DNS-SD-service-name-based device URIs working also with
these services we check whether the service comes through the loopback
interface and in this case we set the host name in the resolved
standard device URI to "localhost".

cups/http-support.c

index 63175145ee97acae89909529282e97032c5a96c3..8eabaee4c8a44b211520e927b3a76b149c2be97c 100644 (file)
@@ -2483,7 +2483,7 @@ http_poll_cb(
 static void
 http_resolve_cb(
     AvahiServiceResolver   *resolver,  /* I - Resolver (unused) */
-    AvahiIfIndex           interface,  /* I - Interface index (unused) */
+    AvahiIfIndex           interface,  /* I - Interface index */
     AvahiProtocol          protocol,   /* I - Network protocol (unused) */
     AvahiResolverEvent     event,      /* I - Event (found, etc.) */
     const char             *name,      /* I - Service name */
@@ -2504,6 +2504,7 @@ http_resolve_cb(
                        *resdefault;    /* Default path */
   char                 resource[257],  /* Remote path */
                        fqdn[256];      /* FQDN of the .local name */
+  char                 ifname[IF_NAMESIZE]; /* Interface name */
   AvahiStringList      *pair;          /* Current TXT record key/value pair */
   char                 *value;         /* Value for "rp" key */
   size_t               valueLen = 0;   /* Length of "rp" key */
@@ -2630,13 +2631,37 @@ http_resolve_cb(
     strlcpy(resource, resdefault, sizeof(resource));
   }
 
+ /*
+  * Check whether the interface is the loopback interface ("lo"), in this
+  * case set "localhost" as the host name
+  */
+
+  if (!if_indextoname((unsigned int)interface, ifname))
+  {
+    if (uribuf->options & _HTTP_RESOLVE_STDERR)
+      fprintf(stderr,
+             "DEBUG: Unable to find interface name for interface %d: %s\n",
+             interface, strerror(errno));
+    DEBUG_printf(("Unable to find interface name for interface %d: %s\n",
+                 interface, strerror(errno)));
+    ifname[0] = '\0';
+  }
+
+  if (!strcmp(ifname, "lo")) {
+    if (uribuf->options & _HTTP_RESOLVE_STDERR)
+      fputs("DEBUG: Service comes from loopback interface \"lo\", setting \"localhost\" as host name.\n",
+           stderr);
+    DEBUG_puts("Service comes from loopback interface \"lo\", setting \"localhost\" as host name.");
+    hostTarget = "localhost";
+  }
+
  /*
   * Lookup the FQDN if needed...
   */
 
-  if ((uribuf->options & _HTTP_RESOLVE_FQDN) &&
-      (hostptr = hostTarget + strlen(hostTarget) - 6) > hostTarget &&
-      !_cups_strcasecmp(hostptr, ".local"))
+  else if ((uribuf->options & _HTTP_RESOLVE_FQDN) &&
+          (hostptr = hostTarget + strlen(hostTarget) - 6) > hostTarget &&
+          !_cups_strcasecmp(hostptr, ".local"))
   {
    /*
     * OK, we got a .local name but the caller needs a real domain.  Start by