Source-Changes-HG archive

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

[src/trunk]: src/usr.sbin/sup/source make sup/supfilesrv IPv6 ready. supfile...



details:   https://anonhg.NetBSD.org/src/rev/0e9c1e16aea0
branches:  trunk
changeset: 514833:0e9c1e16aea0
user:      itojun <itojun%NetBSD.org@localhost>
date:      Tue Sep 11 03:33:52 2001 +0000

description:
make sup/supfilesrv IPv6 ready.  supfilesrv listens to single socket,
therefore, you will need two instances running for dual stack support
(one with -4 and one with -6).

diffstat:

 usr.sbin/sup/source/scm.c        |  274 ++++++++++++++++++++++----------------
 usr.sbin/sup/source/supextern.h  |    4 +-
 usr.sbin/sup/source/supfilesrv.c |   16 +-
 usr.sbin/sup/source/supservers.8 |   14 +-
 4 files changed, 188 insertions(+), 120 deletions(-)

diffs (truncated from 480 to 300 lines):

diff -r f85ee819198f -r 0e9c1e16aea0 usr.sbin/sup/source/scm.c
--- a/usr.sbin/sup/source/scm.c Tue Sep 11 03:32:55 2001 +0000
+++ b/usr.sbin/sup/source/scm.c Tue Sep 11 03:33:52 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: scm.c,v 1.10 2000/03/12 12:16:49 abs Exp $     */
+/*     $NetBSD: scm.c,v 1.11 2001/09/11 03:33:52 itojun Exp $  */
 
 /*
  * Copyright (c) 1992 Carnegie Mellon University
@@ -181,6 +181,7 @@
 #else
 #include <varargs.h>
 #endif
+#include <ifaddrs.h>
 #include "supcdefs.h"
 #include "supextern.h"
 
@@ -211,7 +212,7 @@
 int netfile = -1;                      /* network file descriptor */
 
 static int sock = -1;                  /* socket used to make connection */
-static struct in_addr remoteaddr;      /* remote host address */
+static struct sockaddr_storage remoteaddr; /* remote host address */
 static char *remotename = NULL;                /* remote host name */
 static int swapmode;                   /* byte-swapping needed on server? */
 
@@ -224,47 +225,71 @@
  ***************************************************/
 
 int
-servicesetup (server)          /* listen for clients */
+servicesetup (server, af)              /* listen for clients */
 char *server;
+int af;
 {
-       struct sockaddr_in sin;
-       struct servent *sp;
-       short port;
+       struct addrinfo hints, *res0, *res;
+       char port[NI_MAXSERV];
+       int error;
+       const char *cause = "unknown";
        int one = 1;
 
-       if (myhost () == NULL)
-               return (scmerr (-1,"Local hostname not known"));
-       if ((sp = getservbyname(server,"tcp")) == 0) {
+       memset(&hints, 0, sizeof(hints));
+       hints.ai_family = af;
+       hints.ai_socktype = SOCK_STREAM;
+       hints.ai_socktype = AI_PASSIVE;
+       error = getaddrinfo(NULL, server, &hints, &res0);
+       if (error) {
+               /* retry with precompiled knowledge */
                if (strcmp(server, FILEPORT) == 0)
-                       port = htons((u_short)FILEPORTNUM);
+                       snprintf(port, sizeof(port), "%u", FILEPORTNUM);
                else if (strcmp(server, DEBUGFPORT) == 0)
-                       port = htons((u_short)DEBUGFPORTNUM);
+                       snprintf(port, sizeof(port), "%u", DEBUGFPORTNUM);
                else
-                       return (scmerr (-1,"Can't find %s server description",server));
-               (void) scmerr (-1,"%s/tcp: unknown service: using port %d",
-                                       server,port);
-       } else
-               port = sp->s_port;
-       endservent ();
-       sock = socket (AF_INET,SOCK_STREAM,0);
-       if (sock < 0)
-               return (scmerr (errno,"Can't create socket for connections"));
-       if (setsockopt (sock,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(int)) < 0)
-               (void) scmerr (errno,"Can't set SO_REUSEADDR socket option");
-       (void) bzero ((char *)&sin,sizeof(sin));
-       sin.sin_family = AF_INET;
-       sin.sin_port = port;
-       if (bind (sock,(struct sockaddr *)&sin,sizeof(sin)) < 0)
-               return (scmerr (errno,"Can't bind socket for connections"));
-       if (listen (sock,NCONNECTS) < 0)
-               return (scmerr (errno,"Can't listen on socket"));
-       return (SCMOK);
+                       port[0] = '\0';
+               if (port[0])
+                       error = getaddrinfo(NULL, port, &hints, &res0);
+               if (error)
+                       return (scmerr (-1, "%s: %s", server,
+                           gai_strerror(error)));
+       }
+       for (res = res0; res; res = res->ai_next) {
+               sock = socket(res->ai_family, res->ai_socktype,
+                   res->ai_protocol);
+               if (sock < 0) {
+                       cause = "socket";
+                       continue;
+               }
+               if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+                   (char *)&one, sizeof(int)) < 0) {
+                       cause = "setsockopt(SO_REUSEADDR)";
+                       close(sock);
+                       continue;
+               }
+               if (bind(sock, res->ai_addr, res->ai_addrlen) < 0) {
+                       cause = "bind";
+                       close(sock);
+                       continue;
+               }
+               if (listen(sock, NCONNECTS) < 0) {
+                       cause = "listen";
+                       close(sock);
+                       continue;
+               }
+
+               freeaddrinfo(res0);
+               return SCMOK;
+       }
+
+       freeaddrinfo(res0);
+       return (scmerr (errno, "%s", cause));
 }
 
 int
 service ()
 {
-       struct sockaddr_in from;
+       struct sockaddr_storage from;
        int x,len;
 
        remotename = NULL;
@@ -274,7 +299,11 @@
        } while (netfile < 0 && errno == EINTR);
        if (netfile < 0)
                return (scmerr (errno,"Can't accept connections"));
-       remoteaddr = from.sin_addr;
+       if (len > sizeof(remoteaddr)) {
+               close(netfile);
+               return (scmerr (errno,"Can't accept connections"));
+       }
+       memcpy(&remoteaddr, &from, len);
        if (read(netfile,(char *)&x,sizeof(int)) != sizeof(int))
                return (scmerr (errno,"Can't transmit data on connection"));
        if (x == 0x01020304)
@@ -358,54 +387,65 @@
 char *hostname;
 int *retry;
 {
-       int x, backoff;
-       struct hostent *h;
-       struct servent *sp;
-       struct sockaddr_in sin, tin;
-       short port;
+       struct addrinfo hints, *res, *res0;
+       int error;
+       char port[NI_MAXSERV];
+       int backoff;
+       int x;
 
-       if ((sp = getservbyname(server,"tcp")) == 0) {
+       memset(&hints, 0, sizeof(hints));
+       hints.ai_family = PF_UNSPEC;
+       hints.ai_socktype = SOCK_STREAM;
+       error = getaddrinfo(hostname, server, &hints, &res0);
+       if (error) {
+               /* retry with precompiled knowledge */
                if (strcmp(server, FILEPORT) == 0)
-                       port = htons((u_short)FILEPORTNUM);
+                       snprintf(port, sizeof(port), "%u", FILEPORTNUM);
                else if (strcmp(server, DEBUGFPORT) == 0)
-                       port = htons((u_short)DEBUGFPORTNUM);
+                       snprintf(port, sizeof(port), "%u", DEBUGFPORTNUM);
                else
-                       return (scmerr (-1,"Can't find %s server description",
-                                       server));
-               if (!silent)
-                   (void) scmerr (-1,"%s/tcp: unknown service: using port %d",
-                                   server,port);
-       } else
-               port = sp->s_port;
-       (void) bzero ((char *)&sin,sizeof(sin));
-       sin.sin_family = AF_INET;
-       sin.sin_addr.s_addr = inet_addr (hostname);
-       if (sin.sin_addr.s_addr == (u_long) INADDR_NONE) {
-               if ((h = gethostbyname (hostname)) == NULL)
-                       return (scmerr (-1,"Can't find host entry for %s",
-                                       hostname));
-               hostname = h->h_name;
-               (void) bcopy (h->h_addr,(char *)&sin.sin_addr,h->h_length);
+                       port[0] = '\0';
+               if (port[0])
+                       error = getaddrinfo(hostname, port, &hints, &res0);
+               if (error)
+                       return (scmerr (-1, "%s: %s", server,
+                           gai_strerror(error)));
        }
-       sin.sin_port = port;
        backoff = 1;
-       for (;;) {
-               netfile = socket (AF_INET,SOCK_STREAM,0);
-               if (netfile < 0)
-                       return (scmerr (errno,"Can't create socket"));
-               tin = sin;
-               if (connect(netfile,(struct sockaddr *)&tin,sizeof(tin)) >= 0)
+       while (1) {
+               netfile = -1;
+               for (res = res0; res; res = res->ai_next) {
+                       if (res->ai_addrlen > sizeof(remoteaddr))
+                               continue;
+                       netfile = socket(res->ai_family, res->ai_socktype,
+                           res->ai_protocol);
+                       if (netfile < 0)
+                               continue;
+                       if (connect(netfile, res->ai_addr, res->ai_addrlen) < 0) {
+                               close(netfile);
+                               netfile = -1;
+                               continue;
+                       }
+
                        break;
-               (void) scmerr (errno,"Can't connect to server for %s",server);
-               (void) close(netfile);
-               if (!dobackoff (retry,&backoff))
-                       return (SCMERR);
+               }
+
+               if (netfile < 0) {
+                       if (!dobackoff (retry, &backoff)) {
+                               freeaddrinfo(res0);
+                               return (SCMERR);
+                       }
+                       continue;
+               } else
+                       break;
        }
-       remoteaddr = sin.sin_addr;
+
+       memcpy(&remoteaddr, res->ai_addr, res->ai_addrlen);
        remotename = salloc(hostname);
        x = 0x01020304;
        (void) write (netfile,(char *)&x,sizeof(int));
        swapmode = 0;           /* swap only on server, not client */
+       freeaddrinfo(res0);
        return (SCMOK);
 }
 
@@ -447,12 +487,13 @@
 
 char *remotehost ()    /* remote host name (if known) */
 {
-       register struct hostent *h;
+       char h1[NI_MAXHOST];
 
        if (remotename == NULL) {
-               h = gethostbyaddr ((char *)&remoteaddr,sizeof(remoteaddr),
-                                   AF_INET);
-               remotename = salloc (h ? h->h_name : inet_ntoa(remoteaddr));
+               if (getnameinfo((struct sockaddr *)&remoteaddr,
+                   remoteaddr.ss_len, h1, sizeof(h1), NULL, 0, 0))
+                       return("UNKNOWN");
+               remotename = salloc (h1);
                if (remotename == NULL)
                        return("UNKNOWN");
        }
@@ -474,59 +515,66 @@
 
 int samehost ()                /* is remote host same as local host? */
 {
-       static struct in_addr *intp;
-       static int nint = 0;
-       struct in_addr *ifp;
-       int n;
-
-       if (nint <= 0) {
-               int s;
-               char buf[BUFSIZ];
-               struct ifconf ifc;
-               struct ifreq *ifr;
-               struct sockaddr_in sin;
+       struct ifaddrs *ifap, *ifa;
+       char h1[NI_MAXHOST], h2[NI_MAXHOST];
+#ifdef NI_WITHSCOPEID
+       const int niflags = NI_NUMERICHOST | NI_WITHSCOPEID;
+#else
+       const int niflags = NI_NUMERICHOST;
+#endif
 
-               if ((s = socket (AF_INET,SOCK_DGRAM,0)) < 0)
-                       logquit (1,"Can't create socket for SIOCGIFCONF");
-               ifc.ifc_len = sizeof(buf);
-               ifc.ifc_buf = buf;
-               if (ioctl (s,SIOCGIFCONF,(char *)&ifc) < 0)
-                       logquit (1,"SIOCGIFCONF failed");
-               (void) close(s);
-               if ((nint = ifc.ifc_len/sizeof(struct ifreq)) <= 0)
-                       return (0);
-               intp = (struct in_addr *)
-                       malloc ((unsigned) nint*sizeof(struct in_addr));
-               if ((ifp = intp) == 0)
-                       logquit (1,"no space for interfaces");
-               for (ifr = ifc.ifc_req, n = nint; n > 0; --n, ifr++) {
-                       (void) bcopy ((char *)&ifr->ifr_addr,(char *)&sin,sizeof(sin));
-                       *ifp++ = sin.sin_addr;
+       if (getnameinfo((struct sockaddr *)&remoteaddr, remoteaddr.ss_len,



Home | Main Index | Thread Index | Old Index