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