Correctly inizialize local/unix transport. I broke it in rev.1.15.

PR:	 bin/1122566
MFC after:	1 week
This commit is contained in:
Matteo Riondato 2007-05-01 14:47:35 +00:00
parent 5ffa507dce
commit 48e5a99e7f

View File

@ -276,6 +276,21 @@ init_transport(struct netconfig *nconf)
/* /*
* XXX - using RPC library internal functions. * XXX - using RPC library internal functions.
*/ */
if ((strcmp(nconf->nc_netid, "local") == 0) ||
(strcmp(nconf->nc_netid, "unix") == 0)) {
/*
* For other transports we call this later, for each socket we
* like to bind.
*/
if ((fd = __rpc_nconf2fd(nconf)) < 0) {
int non_fatal = 0;
if (errno == EPROTONOSUPPORT)
non_fatal = 1;
syslog(non_fatal?LOG_DEBUG:LOG_ERR, "cannot create socket for %s",
nconf->nc_netid);
return (1);
}
}
if (!__rpc_nconf2sockinfo(nconf, &si)) { if (!__rpc_nconf2sockinfo(nconf, &si)) {
syslog(LOG_ERR, "cannot get information for %s", syslog(LOG_ERR, "cannot get information for %s",
@ -301,115 +316,170 @@ init_transport(struct netconfig *nconf)
hints.ai_socktype = si.si_socktype; hints.ai_socktype = si.si_socktype;
hints.ai_protocol = si.si_proto; hints.ai_protocol = si.si_proto;
} }
/*
* If no hosts were specified, just bind to INADDR_ANY.
* Otherwise make sure 127.0.0.1 is added to the list.
*/
nhostsbak = nhosts;
nhostsbak++;
hosts = realloc(hosts, nhostsbak * sizeof(char *));
if (nhostsbak == 1)
hosts[0] = "*";
else {
if (hints.ai_family == AF_INET) {
hosts[nhostsbak - 1] = "127.0.0.1";
} else if (hints.ai_family == AF_INET6) {
hosts[nhostsbak - 1] = "::1";
} else
return 1;
}
/* if ((strcmp(nconf->nc_netid, "local") != 0) &&
* Bind to specific IPs if asked to (strcmp(nconf->nc_netid, "unix") != 0)) {
*/
checkbind = 1;
while (nhostsbak > 0) {
--nhostsbak;
/* /*
* XXX - using RPC library internal functions. * If no hosts were specified, just bind to INADDR_ANY.
* Otherwise make sure 127.0.0.1 is added to the list.
*/ */
if ((fd = __rpc_nconf2fd(nconf)) < 0) { nhostsbak = nhosts;
int non_fatal = 0; nhostsbak++;
if (errno == EPROTONOSUPPORT && hosts = realloc(hosts, nhostsbak * sizeof(char *));
nconf->nc_semantics != NC_TPI_CLTS) if (nhostsbak == 1)
non_fatal = 1; hosts[0] = "*";
syslog(non_fatal ? LOG_DEBUG : LOG_ERR, else {
"cannot create socket for %s", nconf->nc_netid); if (hints.ai_family == AF_INET) {
return (1); hosts[nhostsbak - 1] = "127.0.0.1";
} else if (hints.ai_family == AF_INET6) {
hosts[nhostsbak - 1] = "::1";
} else
return 1;
} }
switch (hints.ai_family) {
case AF_INET: /*
if (inet_pton(AF_INET, hosts[nhostsbak], * Bind to specific IPs if asked to
host_addr) == 1) { */
hints.ai_flags &= AI_NUMERICHOST; checkbind = 1;
} else { while (nhostsbak > 0) {
/* --nhostsbak;
* Skip if we have an AF_INET6 adress. /*
*/ * XXX - using RPC library internal functions.
if (inet_pton(AF_INET6, */
hosts[nhostsbak], host_addr) == 1) if ((fd = __rpc_nconf2fd(nconf)) < 0) {
continue; int non_fatal = 0;
if (errno == EPROTONOSUPPORT &&
nconf->nc_semantics != NC_TPI_CLTS)
non_fatal = 1;
syslog(non_fatal ? LOG_DEBUG : LOG_ERR,
"cannot create socket for %s", nconf->nc_netid);
return (1);
} }
break; switch (hints.ai_family) {
case AF_INET6: case AF_INET:
if (inet_pton(AF_INET6, hosts[nhostsbak],
host_addr) == 1) {
hints.ai_flags &= AI_NUMERICHOST;
} else {
/*
* Skip if we have an AF_INET adress.
*/
if (inet_pton(AF_INET, hosts[nhostsbak], if (inet_pton(AF_INET, hosts[nhostsbak],
host_addr) == 1) host_addr) == 1) {
hints.ai_flags &= AI_NUMERICHOST;
} else {
/*
* Skip if we have an AF_INET6 adress.
*/
if (inet_pton(AF_INET6,
hosts[nhostsbak], host_addr) == 1)
continue;
}
break;
case AF_INET6:
if (inet_pton(AF_INET6, hosts[nhostsbak],
host_addr) == 1) {
hints.ai_flags &= AI_NUMERICHOST;
} else {
/*
* Skip if we have an AF_INET adress.
*/
if (inet_pton(AF_INET, hosts[nhostsbak],
host_addr) == 1)
continue;
}
if (setsockopt(fd, IPPROTO_IPV6,
IPV6_V6ONLY, &on, sizeof on) < 0) {
syslog(LOG_ERR,
"can't set v6-only binding for "
"ipv6 socket: %m");
continue; continue;
}
break;
default:
break;
} }
if (setsockopt(fd, IPPROTO_IPV6,
IPV6_V6ONLY, &on, sizeof on) < 0) {
syslog(LOG_ERR,
"can't set v6-only binding for "
"ipv6 socket: %m");
continue;
}
break;
default:
break;
}
/* /*
* If no hosts were specified, just bind to INADDR_ANY * If no hosts were specified, just bind to INADDR_ANY
*/ */
if (strcmp("*", hosts[nhostsbak]) == 0) if (strcmp("*", hosts[nhostsbak]) == 0)
hosts[nhostsbak] = NULL; hosts[nhostsbak] = NULL;
if ((strcmp(nconf->nc_netid, "local") != 0) && if ((strcmp(nconf->nc_netid, "local") != 0) &&
(strcmp(nconf->nc_netid, "unix") != 0)) { (strcmp(nconf->nc_netid, "unix") != 0)) {
if ((aicode = getaddrinfo(hosts[nhostsbak], if ((aicode = getaddrinfo(hosts[nhostsbak],
servname, &hints, &res)) != 0) { servname, &hints, &res)) != 0) {
syslog(LOG_ERR, syslog(LOG_ERR,
"cannot get local address for %s: %s", "cannot get local address for %s: %s",
nconf->nc_netid, gai_strerror(aicode)); nconf->nc_netid, gai_strerror(aicode));
continue; continue;
}
addrlen = res->ai_addrlen;
sa = (struct sockaddr *)res->ai_addr;
}
oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
if (bind(fd, sa, addrlen) != 0) {
syslog(LOG_ERR, "cannot bind %s on %s: %m",
(hosts[nhostsbak] == NULL) ? "*" :
hosts[nhostsbak], nconf->nc_netid);
if (res != NULL)
freeaddrinfo(res);
continue;
} else
checkbind++;
(void)umask(oldmask);
/* Copy the address */
taddr.addr.len = taddr.addr.maxlen = addrlen;
taddr.addr.buf = malloc(addrlen);
if (taddr.addr.buf == NULL) {
syslog(LOG_ERR,
"cannot allocate memory for %s address",
nconf->nc_netid);
if (res != NULL)
freeaddrinfo(res);
return 1;
}
memcpy(taddr.addr.buf, sa, addrlen);
#ifdef ND_DEBUG
if (debugging) {
/*
* for debugging print out our universal
* address
*/
char *uaddr;
struct netbuf nb;
nb.buf = sa;
nb.len = nb.maxlen = sa->sa_len;
uaddr = taddr2uaddr(nconf, &nb);
(void)fprintf(stderr,
"rpcbind : my address is %s\n", uaddr);
(void)free(uaddr);
}
#endif
/*ARRIVATO QUI*/
if (nconf->nc_semantics != NC_TPI_CLTS)
listen(fd, SOMAXCONN);
my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, &taddr,
RPC_MAXDATASIZE, RPC_MAXDATASIZE);
if (my_xprt == (SVCXPRT *)NULL) {
syslog(LOG_ERR, "%s: could not create service",
nconf->nc_netid);
goto error;
} }
addrlen = res->ai_addrlen;
sa = (struct sockaddr *)res->ai_addr;
} }
if (!checkbind)
return 1;
} else {
oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH); oldmask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
if (bind(fd, sa, addrlen) != 0) { if (bind(fd, sa, addrlen) < 0) {
syslog(LOG_ERR, "cannot bind %s on %s: %m", syslog(LOG_ERR, "cannot bind %s: %m", nconf->nc_netid);
(hosts[nhostsbak] == NULL) ? "*" :
hosts[nhostsbak], nconf->nc_netid);
if (res != NULL) if (res != NULL)
freeaddrinfo(res); freeaddrinfo(res);
continue; return 1;
} else }
checkbind++; (void) umask(oldmask);
(void)umask(oldmask);
/* Copy the address */ /* Copy the address */
taddr.addr.len = taddr.addr.maxlen = addrlen; taddr.addr.len = taddr.addr.maxlen = addrlen;
taddr.addr.buf = malloc(addrlen); taddr.addr.buf = malloc(addrlen);
if (taddr.addr.buf == NULL) { if (taddr.addr.buf == NULL) {
syslog(LOG_ERR, syslog(LOG_ERR, "cannot allocate memory for %s address",
"cannot allocate memory for %s address",
nconf->nc_netid); nconf->nc_netid);
if (res != NULL) if (res != NULL)
freeaddrinfo(res); freeaddrinfo(res);
@ -418,19 +488,16 @@ init_transport(struct netconfig *nconf)
memcpy(taddr.addr.buf, sa, addrlen); memcpy(taddr.addr.buf, sa, addrlen);
#ifdef ND_DEBUG #ifdef ND_DEBUG
if (debugging) { if (debugging) {
/* /* for debugging print out our universal address */
* for debugging print out our universal
* address
*/
char *uaddr; char *uaddr;
struct netbuf nb; struct netbuf nb;
nb.buf = sa; nb.buf = sa;
nb.len = nb.maxlen = sa->sa_len; nb.len = nb.maxlen = sa->sa_len;
uaddr = taddr2uaddr(nconf, &nb); uaddr = taddr2uaddr(nconf, &nb);
(void)fprintf(stderr, (void) fprintf(stderr, "rpcbind : my address is %s\n",
"rpcbind : my address is %s\n", uaddr); uaddr);
(void)free(uaddr); (void) free(uaddr);
} }
#endif #endif
@ -445,8 +512,6 @@ init_transport(struct netconfig *nconf)
goto error; goto error;
} }
} }
if (!checkbind)
return 1;
#ifdef PORTMAP #ifdef PORTMAP
/* /*