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