Source-Changes-HG archive

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

[src/trunk]: src/usr.sbin/nfsd Update to use ti-rpc interface. Add -6 flag fo...



details:   https://anonhg.NetBSD.org/src/rev/a7b5fec435c1
branches:  trunk
changeset: 487526:a7b5fec435c1
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Fri Jun 09 00:05:02 2000 +0000

description:
Update to use ti-rpc interface. Add -6 flag for IPv6 usage. This flag
will not cause an error if IPv6 is not available, so that things work
on v4 only kernels.

diffstat:

 usr.sbin/nfsd/nfsd.8 |    7 +-
 usr.sbin/nfsd/nfsd.c |  261 +++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 226 insertions(+), 42 deletions(-)

diffs (truncated from 399 to 300 lines):

diff -r ceb6be14fd7a -r a7b5fec435c1 usr.sbin/nfsd/nfsd.8
--- a/usr.sbin/nfsd/nfsd.8      Fri Jun 09 00:03:31 2000 +0000
+++ b/usr.sbin/nfsd/nfsd.8      Fri Jun 09 00:05:02 2000 +0000
@@ -1,4 +1,4 @@
-.\"   $NetBSD: nfsd.8,v 1.12 2000/05/18 09:54:59 bouyer Exp $
+.\"   $NetBSD: nfsd.8,v 1.13 2000/06/09 00:05:02 fvdl Exp $
 .\"
 .\" Copyright (c) 1989, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -43,7 +43,7 @@
 server
 .Sh SYNOPSIS
 .Nm
-.Op Fl rut
+.Op Fl 6rut
 .Op Fl n Ar num_servers
 .Sh DESCRIPTION
 .Nm
@@ -73,6 +73,9 @@
 options to re-register NFS if the portmap server is restarted.
 .It Fl n
 Specifies how many servers to create.
+.It Fl 6
+Listen to IPv6 requests as well as IPv4 requests. If IPv6 support is not
+available, nfsd will silently continue and just use IPv4.
 .It Fl t
 Serve
 .Tn TCP NFS
diff -r ceb6be14fd7a -r a7b5fec435c1 usr.sbin/nfsd/nfsd.c
--- a/usr.sbin/nfsd/nfsd.c      Fri Jun 09 00:03:31 2000 +0000
+++ b/usr.sbin/nfsd/nfsd.c      Fri Jun 09 00:05:02 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nfsd.c,v 1.31 1999/08/31 23:28:34 soren Exp $  */
+/*     $NetBSD: nfsd.c,v 1.32 2000/06/09 00:05:02 fvdl Exp $   */
 
 /*
  * Copyright (c) 1989, 1993, 1994
@@ -46,7 +46,7 @@
 #if 0
 static char sccsid[] = "@(#)nfsd.c     8.9 (Berkeley) 3/29/95";
 #else
-__RCSID("$NetBSD: nfsd.c,v 1.31 1999/08/31 23:28:34 soren Exp $");
+__RCSID("$NetBSD: nfsd.c,v 1.32 2000/06/09 00:05:02 fvdl Exp $");
 #endif
 #endif /* not lint */
 
@@ -87,6 +87,7 @@
 #include <string.h>
 #include <syslog.h>
 #include <unistd.h>
+#include <netdb.h>
 
 /* Global defs */
 #ifdef DEBUG
@@ -140,14 +141,19 @@
        char *argv[];
 {
        struct nfsd_args nfsdargs;
-       struct sockaddr_in inetaddr, inetpeer;
+       struct addrinfo *ai_udp, *ai_tcp, *ai_udp6, *ai_tcp6, hints;
+       struct netconfig *nconf_udp, *nconf_tcp, *nconf_udp6, *nconf_tcp6;
+       struct netbuf nb_udp, nb_tcp, nb_udp6, nb_tcp6;
+       struct sockaddr_in inetpeer;
+       struct sockaddr_in6 inet6peer;
 #ifdef ISO
        struct sockaddr_iso isoaddr, isopeer;
 #endif
        fd_set ready, sockbits;
        int ch, cltpflag, connect_type_cnt, i, len, maxsock, msgsock;
-       int nfsdcnt, nfssvc_flag, on, reregister, sock, tcpflag, tcpsock;
-       int tp4cnt, tp4flag, tpipcnt, tpipflag, udpflag;
+       int nfsdcnt, nfssvc_flag, on = 1, reregister, sock, tcpflag, tcpsock;
+       int tcp6sock, ip6flag;
+       int tp4cnt, tp4flag, tpipcnt, tpipflag, udpflag, ecode, s;
 #ifdef NFSKERB
        struct group *grp;
        struct passwd *pwd;
@@ -161,17 +167,26 @@
 #define        DEFNFSDCNT       4
        nfsdcnt = DEFNFSDCNT;
        cltpflag = reregister = tcpflag = tp4cnt = tp4flag = tpipcnt = 0;
-       tpipflag = udpflag = 0;
+       tpipflag = udpflag = ip6flag = 0;
        maxsock = tcpsock = 0;
 #ifdef ISO
-#define        GETOPT  "cn:rtu"
+#define        GETOPT  "6cn:rtu"
 #define        USAGE   "[-crtu] [-n num_servers]"
 #else
-#define        GETOPT  "n:rtu"
+#define        GETOPT  "6n:rtu"
 #define        USAGE   "[-rtu] [-n num_servers]"
 #endif
        while ((ch = getopt(argc, argv, GETOPT)) != -1) {
                switch (ch) {
+               case '6':
+                       ip6flag = 1;
+                       s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+                       if (s < 0 && (errno == EPROTONOSUPPORT ||
+                           errno == EPFNOSUPPORT || errno == EAFNOSUPPORT))
+                               ip6flag = 0;
+                       else
+                               close(s);
+                       break;
                case 'n':
                        nfsdcnt = atoi(optarg);
                        if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
@@ -238,17 +253,110 @@
        }
        (void)signal(SIGCHLD, reapchild);
 
-       if (reregister) {
-               if (udpflag &&
-                   (!pmap_set(RPCPROG_NFS, 2, IPPROTO_UDP, NFS_PORT) ||
-                    !pmap_set(RPCPROG_NFS, 3, IPPROTO_UDP, NFS_PORT)))
-                       err(1, "can't register with portmap for UDP.");
-               if (tcpflag &&
-                   (!pmap_set(RPCPROG_NFS, 2, IPPROTO_TCP, NFS_PORT) ||
-                    !pmap_set(RPCPROG_NFS, 3, IPPROTO_TCP, NFS_PORT)))
-                       err(1, "can't register with portmap for TCP.");
-               exit(0);
+       if (udpflag) {
+               memset(&hints, 0, sizeof hints);
+               hints.ai_flags = AI_PASSIVE;
+               hints.ai_family = PF_INET;
+               hints.ai_socktype = SOCK_DGRAM;
+               hints.ai_protocol = IPPROTO_UDP;
+
+               ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp);
+               if (ecode != 0) {
+                       syslog(LOG_ERR, "getaddrinfo udp: %s",
+                           gai_strerror(ecode));
+                       exit(1);
+               }
+
+               nconf_udp = getnetconfigent("udp");
+
+               if (nconf_udp == NULL)
+                       err(1, "getnetconfigent udp failed");
+
+               nb_udp.buf = ai_udp->ai_addr;
+               nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen;
+               if (reregister)
+                       if (!rpcb_set(RPCPROG_NFS, 2, nconf_udp, &nb_udp))
+                               err(1, "rpcb_set udp failed");
+       }
+
+       if (tcpflag) {
+               memset(&hints, 0, sizeof hints);
+               hints.ai_flags = AI_PASSIVE;
+               hints.ai_family = PF_INET;
+               hints.ai_socktype = SOCK_STREAM;
+               hints.ai_protocol = IPPROTO_TCP;
+
+               ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp);
+               if (ecode != 0) {
+                       syslog(LOG_ERR, "getaddrinfo udp: %s",
+                           gai_strerror(ecode));
+                       exit(1);
+               }
+
+               nconf_tcp = getnetconfigent("tcp");
+
+               if (nconf_tcp == NULL)
+                       err(1, "getnetconfigent tcp failed");
+
+               nb_tcp.buf = ai_tcp->ai_addr;
+               nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen;
+               if (reregister)
+                       if (!rpcb_set(RPCPROG_NFS, 2, nconf_tcp, &nb_tcp))
+                               err(1, "rpcb_set tcp failed");
        }
+
+       if (udpflag && ip6flag) {
+               memset(&hints, 0, sizeof hints);
+               hints.ai_flags = AI_PASSIVE;
+               hints.ai_family = PF_INET6;
+               hints.ai_socktype = SOCK_DGRAM;
+               hints.ai_protocol = IPPROTO_UDP;
+
+               ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6);
+               if (ecode != 0) {
+                       syslog(LOG_ERR, "getaddrinfo udp: %s",
+                           gai_strerror(ecode));
+                       exit(1);
+               }
+
+               nconf_udp6 = getnetconfigent("udp6");
+
+               if (nconf_udp6 == NULL)
+                       err(1, "getnetconfigent udp6 failed");
+
+               nb_udp6.buf = ai_udp6->ai_addr;
+               nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen;
+               if (reregister)
+                       if (!rpcb_set(RPCPROG_NFS, 2, nconf_udp6, &nb_udp6))
+                               err(1, "rpcb_set udp6 failed");
+       }
+
+       if (tcpflag && ip6flag) {
+               memset(&hints, 0, sizeof hints);
+               hints.ai_flags = AI_PASSIVE;
+               hints.ai_family = PF_INET6;
+               hints.ai_socktype = SOCK_STREAM;
+               hints.ai_protocol = IPPROTO_TCP;
+
+               ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6);
+               if (ecode != 0) {
+                       syslog(LOG_ERR, "getaddrinfo udp: %s",
+                           gai_strerror(ecode));
+                       exit(1);
+               }
+
+               nconf_tcp6 = getnetconfigent("tcp6");
+
+               if (nconf_tcp6 == NULL)
+                       err(1, "getnetconfigent tcp6 failed");
+
+               nb_tcp6.buf = ai_tcp6->ai_addr;
+               nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen;
+               if (reregister)
+                       if (!rpcb_set(RPCPROG_NFS, 2, nconf_tcp6, &nb_tcp6))
+                               err(1, "rpcb_set tcp6 failed");
+       }
+
        openlog("nfsd:", LOG_PID, LOG_DAEMON);
 
        for (i = 0; i < nfsdcnt; i++) {
@@ -365,22 +473,17 @@
 
        /* If we are serving udp, set up the socket. */
        if (udpflag) {
-               if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+               if ((sock = socket(ai_udp->ai_family, ai_udp->ai_socktype,
+                   ai_udp->ai_protocol)) < 0) {
                        syslog(LOG_ERR, "can't create udp socket");
                        exit(1);
                }
-               inetaddr.sin_family = AF_INET;
-               inetaddr.sin_addr.s_addr = INADDR_ANY;
-               inetaddr.sin_port = htons(NFS_PORT);
-               inetaddr.sin_len = sizeof(inetaddr);
-               memset(inetaddr.sin_zero, 0, sizeof(inetaddr.sin_zero));
-               if (bind(sock,
-                   (struct sockaddr *)&inetaddr, sizeof(inetaddr)) < 0) {
+               if (bind(sock, ai_udp->ai_addr, ai_udp->ai_addrlen) < 0) {
                        syslog(LOG_ERR, "can't bind udp addr");
                        exit(1);
                }
-               if (!pmap_set(RPCPROG_NFS, 2, IPPROTO_UDP, NFS_PORT) ||
-                   !pmap_set(RPCPROG_NFS, 3, IPPROTO_UDP, NFS_PORT)) {
+               if (!rpcb_set(RPCPROG_NFS, 2, nconf_udp, &nb_udp) ||
+                   !rpcb_set(RPCPROG_NFS, 3, nconf_udp, &nb_udp)) {
                        syslog(LOG_ERR, "can't register with udp portmap");
                        exit(1);
                }
@@ -388,7 +491,38 @@
                nfsdargs.name = NULL;
                nfsdargs.namelen = 0;
                if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
-                       syslog(LOG_ERR, "can't Add UDP socket");
+                       syslog(LOG_ERR, "can't add UDP socket");
+                       exit(1);
+               }
+               (void)close(sock);
+       }
+
+       if (udpflag &&ip6flag) {
+               if ((sock = socket(ai_udp6->ai_family, ai_udp6->ai_socktype,
+                   ai_udp6->ai_protocol)) < 0) {
+                       syslog(LOG_ERR, "can't create udp socket");
+                       exit(1);
+               }
+               if (setsockopt(sock, IPPROTO_IPV6, IPV6_BINDV6ONLY,
+                   &on, sizeof on) < 0) {
+                       syslog(LOG_ERR, "can't set v6-only binding for udp6 "
+                                       "socket: %m");
+                       exit(1);
+               }
+               if (bind(sock, ai_udp6->ai_addr, ai_udp6->ai_addrlen) < 0) {
+                       syslog(LOG_ERR, "can't bind udp addr");
+                       exit(1);
+               }
+               if (!rpcb_set(RPCPROG_NFS, 2, nconf_udp6, &nb_udp6) ||
+                   !rpcb_set(RPCPROG_NFS, 3, nconf_udp6, &nb_udp6)) {
+                       syslog(LOG_ERR, "can't register with udp portmap");
+                       exit(1);
+               }
+               nfsdargs.sock = sock;
+               nfsdargs.name = NULL;
+               nfsdargs.namelen = 0;
+               if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
+                       syslog(LOG_ERR, "can't add UDP6 socket");
                        exit(1);
                }
                (void)close(sock);
@@ -440,20 +574,15 @@
        FD_ZERO(&sockbits);
        connect_type_cnt = 0;
        if (tcpflag) {



Home | Main Index | Thread Index | Old Index