Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/inetd Add mDNS Service Directory support to inetd(8).



details:   https://anonhg.NetBSD.org/src/rev/88b64367482a
branches:  trunk
changeset: 748378:88b64367482a
user:      jkunz <jkunz%NetBSD.org@localhost>
date:      Thu Oct 22 16:34:27 2009 +0000

description:
Add mDNS Service Directory support to inetd(8).
inetd(8) can now advertize services in the mDNS-SD.
(Per service configuration option in inetd.conf(5).)

diffstat:

 usr.sbin/inetd/Makefile |    8 ++-
 usr.sbin/inetd/inetd.8  |   18 ++++-
 usr.sbin/inetd/inetd.c  |  152 ++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 169 insertions(+), 9 deletions(-)

diffs (truncated from 318 to 300 lines):

diff -r 7fdd7d7ef074 -r 88b64367482a usr.sbin/inetd/Makefile
--- a/usr.sbin/inetd/Makefile   Thu Oct 22 15:53:19 2009 +0000
+++ b/usr.sbin/inetd/Makefile   Thu Oct 22 16:34:27 2009 +0000
@@ -1,5 +1,5 @@
 #      from: @(#)Makefile      8.1 (Berkeley) 6/6/93
-#      $NetBSD: Makefile,v 1.21 2007/05/28 12:06:35 tls Exp $
+#      $NetBSD: Makefile,v 1.22 2009/10/22 16:34:27 jkunz Exp $
 
 .include <bsd.own.mk>
 
@@ -20,6 +20,12 @@
 CPPFLAGS+=-DINET6
 .endif
 
+.if (${MKMDNS} != "no")
+CPPFLAGS+=-DMDNS
+LDADD+= -ldns_sd
+DPADD+=        ${LIBDNS_SD}
+.endif
+
 CPPFLAGS+=-DIPSEC
 SRCS+= ipsec.c
 LDADD+= -lipsec
diff -r 7fdd7d7ef074 -r 88b64367482a usr.sbin/inetd/inetd.8
--- a/usr.sbin/inetd/inetd.8    Thu Oct 22 15:53:19 2009 +0000
+++ b/usr.sbin/inetd/inetd.8    Thu Oct 22 16:34:27 2009 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: inetd.8,v 1.52 2009/07/14 08:24:15 wiz Exp $
+.\"    $NetBSD: inetd.8,v 1.53 2009/10/22 16:34:27 jkunz Exp $
 .\"
 .\" Copyright (c) 1998 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -118,7 +118,7 @@
 [addr:]service-name
 socket-type[:accept_filter]
 protocol[,sndbuf=size][,rcvbuf=size]
-wait/nowait[:max]
+[mdns,]wait/nowait[:max]
 user[:group]
 server-program
 server program arguments
@@ -132,7 +132,7 @@
 service-name/version
 socket-type
 rpc/protocol[,sndbuf=size][,rcvbuf=size]
-wait/nowait[:max]
+[mdns,]wait/nowait[:max]
 user[:group]
 server-program
 server program arguments
@@ -145,7 +145,7 @@
 path
 socket-type
 unix[,sndbuf=size][,rcvbuf=size]
-wait/nowait[:max]
+[mdns,]wait/nowait[:max]
 user[:group]
 server-program
 server program arguments
@@ -279,6 +279,16 @@
 Socket buffer sizes may be specified for all
 services and protocols except for tcpmux services.
 .Pp
+If the
+.Em mdns
+option is present then
+.Nm
+advertises the service in the mDNS Service Directory.
+.Xr mdnsd 8
+needs to run for this to work. Note that mDNS does not distinguish IPv4 and
+IPv6. If a service is enabled for IPv6 only and IPv4 addresses are configured
+on the affected interface, the service will be advertized for IPv4 and IPv6.
+.Pp
 The
 .Em wait/nowait
 entry is used to tell
diff -r 7fdd7d7ef074 -r 88b64367482a usr.sbin/inetd/inetd.c
--- a/usr.sbin/inetd/inetd.c    Thu Oct 22 15:53:19 2009 +0000
+++ b/usr.sbin/inetd/inetd.c    Thu Oct 22 16:34:27 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: inetd.c,v 1.113 2009/07/13 19:05:41 roy Exp $  */
+/*     $NetBSD: inetd.c,v 1.114 2009/10/22 16:34:27 jkunz Exp $        */
 
 /*-
  * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
 #if 0
 static char sccsid[] = "@(#)inetd.c    8.4 (Berkeley) 4/13/94";
 #else
-__RCSID("$NetBSD: inetd.c,v 1.113 2009/07/13 19:05:41 roy Exp $");
+__RCSID("$NetBSD: inetd.c,v 1.114 2009/10/22 16:34:27 jkunz Exp $");
 #endif
 #endif /* not lint */
 
@@ -98,7 +98,8 @@
  *     socket type[:accf[,arg]]        stream/dgram/raw/rdm/seqpacket,
                                        only stream can name an accept filter
  *     protocol                        must be in /etc/protocols
- *     wait/nowait[:max]               single-threaded/multi-threaded, max #
+ *     [mdns,]wait/nowait[:max]        single-threaded/multi-threaded, max #
+ *                                     if "mdns" register service in mDNS-SD
  *     user[:group]                    user/group to run daemon as
  *     server program                  full path name
  *     server program arguments        maximum of MAXARGS (20)
@@ -107,7 +108,8 @@
  *      service name/version            must be in /etc/rpc
  *     socket type                     stream/dgram/raw/rdm/seqpacket
  *     protocol                        must be in /etc/protocols
- *     wait/nowait[:max]               single-threaded/multi-threaded
+ *     [mdns,]wait/nowait[:max]        single-threaded/multi-threaded
+ *                                     if "mdns" register service in mDNS-SD
  *     user[:group]                    user to run daemon as
  *     server program                  full path name
  *     server program arguments        maximum of MAXARGS (20)
@@ -255,6 +257,10 @@
 int deny_severity = LIBWRAP_DENY_FACILITY|LIBWRAP_DENY_SEVERITY;
 #endif
 
+#ifdef MDNS
+#include <dns_sd.h>
+#endif /* MDNS */
+
 #define        TOOMANY         40              /* don't start more than TOOMANY */
 #define        CNT_INTVL       60              /* servers in CNT_INTVL sec. */
 #define        RETRYTIME       (60*10)         /* retry after bind or server fail */
@@ -320,6 +326,7 @@
        } se_un;                        /* bound address */
 #define se_ctrladdr    se_un.se_un_ctrladdr
 #define se_ctrladdr_in se_un.se_un_ctrladdr_in
+#define se_ctrladdr_in6        se_un.se_un_ctrladdr_in6
 #define se_ctrladdr_un se_un.se_un_ctrladdr_un
        int     se_ctrladdr_size;
        int     se_max;                 /* max # of instances of this service */
@@ -329,6 +336,10 @@
        int     se_log;
 #define MULOG_RFC931   0x40000000
 #endif
+       int     se_mdns;
+#ifdef MDNS
+       DNSServiceRef se_mdns_reg;
+#endif /* MDNS */
        struct  servtab *se_next;
 } *servtab;
 
@@ -388,6 +399,11 @@
 static void    timeout(int);
 static char    *rfc931_name(struct sockaddr *, int);
 #endif
+#ifdef MDNS
+static int     iface_idx(struct servtab *);
+static void    register_mdns(struct servtab *);
+#endif /* MDNS */
+
 
 struct biltin {
        const char *bi_service;         /* internally provided service name */
@@ -990,6 +1006,10 @@
                        continue;
                }
                *sepp = sep->se_next;
+#ifdef MDNS
+               if (sep->se_mdns_reg != NULL)
+                       DNSServiceRefDeallocate(sep->se_mdns_reg);
+#endif /* MDNS */
                if (sep->se_fd >= 0)
                        close_sep(sep);
                if (isrpcservice(sep))
@@ -1047,12 +1067,118 @@
                                unregister_rpc(sep);
                        break;
                }
+#ifdef MDNS
+               if (sep->se_mdns_reg != NULL)
+                       DNSServiceRefDeallocate(sep->se_mdns_reg);
+#endif /* MDNS */
                (void)close(sep->se_fd);
                sep->se_fd = -1;
        }
        exit(0);
 }
 
+
+#ifdef MDNS
+static int
+iface_idx(struct servtab *sep)
+{
+       int if_idx;
+       struct ifaddrs *ifp;
+       struct ifaddrs *ifa;
+
+       if (sep->se_hostaddr[0] == '*' && sep->se_hostaddr[1] == '\0')
+               return 0;
+       /* Optimize: getifaddrs(3) once and cache result. */
+       if (getifaddrs(&ifp) < 0)
+               return 0;
+       if_idx = 0;
+       for (ifa = ifp; ifa != NULL; ifa = ifa->ifa_next) {
+               if (ifa->ifa_addr->sa_family == AF_INET &&
+                   sep->se_family == AF_INET &&
+                   ((struct sockaddr_in*)ifa->ifa_addr)->sin_addr.s_addr ==
+                   sep->se_ctrladdr_in.sin_addr.s_addr) {
+                       if_idx = if_nametoindex(ifa->ifa_name);
+                       break;
+               }
+#ifdef INET6
+               if (ifa->ifa_addr->sa_family == AF_INET6 &&
+                   sep->se_family == AF_INET6 &&
+                   IN6_ARE_ADDR_EQUAL(
+                   &((struct sockaddr_in6*) ifa->ifa_addr)->sin6_addr,
+                   &sep->se_ctrladdr_in6.sin6_addr)) {
+                       if_idx = if_nametoindex(ifa->ifa_name);
+                       break;
+               }
+#endif /* INET6 */
+       }
+       freeifaddrs(ifp);
+       return if_idx;
+}
+
+
+static void
+register_mdns(struct servtab *sep)
+{
+       char regtype[kDNSServiceMaxDomainName];
+       int port, iface, err;
+#ifdef INET6
+       struct servtab *sep2;
+
+       /* skip INET6 if there is a registration for INET */
+       for (sep2 = servtab; sep2 != NULL; sep2 = sep2->se_next)
+               if (strcmp(sep2->se_service, sep->se_service) == 0 &&
+                   strncmp(sep2->se_proto, sep->se_proto, 3) == 0 &&
+                   ISMUX(sep2) == ISMUX(sep) &&
+                   sep->se_family == AF_INET6 &&
+                   sep2->se_family == AF_INET && sep2->se_mdns != 0)
+                       break;
+       if (sep2 != NULL)
+               return;
+#endif /* INET6 */
+       if (sep->se_socktype == SOCK_STREAM)
+               snprintf(regtype, sizeof(regtype), "_%s._tcp",
+                   sep->se_service);
+       else
+               snprintf(regtype, sizeof(regtype), "_%s._udp",
+                   sep->se_service);
+#ifdef INET6
+       if (sep->se_family == AF_INET)
+               port = sep->se_ctrladdr_in.sin_port;
+       else
+               port = sep->se_ctrladdr_in6.sin6_port;
+#else /* INET6 */
+       port = sep->se_ctrladdr_in.sin_port;
+#endif /* else INET6 */
+       iface = iface_idx(sep);
+       if (sep->se_mdns_reg != NULL)
+               DNSServiceRefDeallocate(sep->se_mdns_reg);
+       err = DNSServiceRegister(&sep->se_mdns_reg, 0, iface, NULL, regtype,
+           NULL, NULL, port, 0, NULL, NULL, NULL);
+       if (err != kDNSServiceErr_NoError) {
+               syslog(LOG_ERR, "Can't register mDNS service %s, error=%d.",
+                   sep->se_service, err);
+               DNSServiceRefDeallocate(sep->se_mdns_reg);
+               sep->se_mdns_reg = NULL;
+       } else {
+               if (fcntl(DNSServiceRefSockFD(sep->se_mdns_reg), F_SETFD,
+                   FD_CLOEXEC) < 0)
+                       syslog(LOG_ERR, "MDNS: %s/%s: fcntl(F_SETFD, "
+                           "FD_CLOEXEC): %m", sep->se_service, sep->se_proto);
+               if (DNSServiceRefSockFD(sep->se_mdns_reg) > maxsock) {
+                       maxsock = DNSServiceRefSockFD(sep->se_mdns_reg);
+                       if (maxsock > (int)(rlim_ofile_cur - FD_MARGIN))
+                               bump_nofile();
+               }
+       }
+       if (debug)
+               fprintf(stderr, "MDNS: regtype=%s port=%d iface=%d fd=%d "
+                   "error=%d\n", regtype, port, iface,
+                   sep->se_mdns_reg == NULL ? -1 :
+                   DNSServiceRefSockFD(sep->se_mdns_reg), err);
+}
+#endif /* MDNS */
+
+
 static void
 setup(struct servtab *sep)
 {
@@ -1145,6 +1271,20 @@
        ev = allocchange();
        EV_SET(ev, sep->se_fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0,
            (intptr_t)sep);
+       if (sep->se_mdns != 0 && ! isrpcservice(sep) &&
+#ifdef INET6
+           (sep->se_family == AF_INET || sep->se_family == AF_INET6)) {
+#else /* INET6 */
+           (sep->se_family == AF_INET)) {
+#endif /* else INET6 */
+#ifdef MDNS
+               register_mdns(sep);
+#else /* MDNS */
+               syslog(LOG_WARNING, "Warning: mDNS-SD registation for service "



Home | Main Index | Thread Index | Old Index