Module Name: src
Committed By: jkunz
Date: Thu Oct 22 16:34:27 UTC 2009
Modified Files:
src/usr.sbin/inetd: Makefile inetd.8 inetd.c
Log Message:
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).)
To generate a diff of this commit:
cvs rdiff -u -r1.21 -r1.22 src/usr.sbin/inetd/Makefile
cvs rdiff -u -r1.52 -r1.53 src/usr.sbin/inetd/inetd.8
cvs rdiff -u -r1.113 -r1.114 src/usr.sbin/inetd/inetd.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.sbin/inetd/Makefile
diff -u src/usr.sbin/inetd/Makefile:1.21 src/usr.sbin/inetd/Makefile:1.22
--- src/usr.sbin/inetd/Makefile:1.21 Mon May 28 12:06:35 2007
+++ src/usr.sbin/inetd/Makefile Thu Oct 22 16:34:27 2009
@@ -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
Index: src/usr.sbin/inetd/inetd.8
diff -u src/usr.sbin/inetd/inetd.8:1.52 src/usr.sbin/inetd/inetd.8:1.53
--- src/usr.sbin/inetd/inetd.8:1.52 Tue Jul 14 08:24:15 2009
+++ src/usr.sbin/inetd/inetd.8 Thu Oct 22 16:34:27 2009
@@ -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
Index: src/usr.sbin/inetd/inetd.c
diff -u src/usr.sbin/inetd/inetd.c:1.113 src/usr.sbin/inetd/inetd.c:1.114
--- src/usr.sbin/inetd/inetd.c:1.113 Mon Jul 13 19:05:41 2009
+++ src/usr.sbin/inetd/inetd.c Thu Oct 22 16:34:27 2009
@@ -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 "
+ "%s requested by inetd.conf(5), but mDNS is disabled at "
+ "compile time.", sep->se_service);
+#endif /* else MDNS */
+ }
if (sep->se_fd > maxsock) {
maxsock = sep->se_fd;
if (maxsock > (int)(rlim_ofile_cur - FD_MARGIN))
@@ -1607,6 +1747,10 @@
}
}
arg = sskip(&cp);
+ if (strncmp(arg, "mdns,", 5) == 0) {
+ sep->se_mdns = 1;
+ arg += 5;
+ }
{
char *cp1;
if ((cp1 = strchr(arg, ':')) == NULL)