aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/rpc.lockd/lockd.c
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2017-06-21 06:34:06 +0000
committerXin LI <delphij@FreeBSD.org>2017-06-21 06:34:06 +0000
commit8a3cd533f1c97cd4c54625e20db79b776b065855 (patch)
treefed6feb5bb6731e1aae32e14b2866492e99144cd /usr.sbin/rpc.lockd/lockd.c
parent3a5d839ebcd612bdbced9a2d921c059446c6d462 (diff)
downloadsrc-8a3cd533f1c97cd4c54625e20db79b776b065855.tar.gz
src-8a3cd533f1c97cd4c54625e20db79b776b065855.zip
Notes
Diffstat (limited to 'usr.sbin/rpc.lockd/lockd.c')
-rw-r--r--usr.sbin/rpc.lockd/lockd.c271
1 files changed, 76 insertions, 195 deletions
diff --git a/usr.sbin/rpc.lockd/lockd.c b/usr.sbin/rpc.lockd/lockd.c
index e021f6fb16b0..6ac4962c078d 100644
--- a/usr.sbin/rpc.lockd/lockd.c
+++ b/usr.sbin/rpc.lockd/lockd.c
@@ -99,9 +99,8 @@ char localhost[] = "localhost";
static int create_service(struct netconfig *nconf);
static void complete_service(struct netconfig *nconf, char *port_str);
static void clearout_service(void);
-void lookup_addresses(struct netconfig *nconf);
+static void out_of_mem(void) __dead2;
void init_nsm(void);
-void out_of_mem(void);
void usage(void);
void sigalarm_handler(void);
@@ -144,7 +143,6 @@ main(int argc, char **argv)
break;
case 'h':
++nhosts;
- hosts_bak = hosts;
hosts_bak = realloc(hosts, nhosts * sizeof(char *));
if (hosts_bak == NULL) {
if (hosts != NULL) {
@@ -172,7 +170,6 @@ main(int argc, char **argv)
svcport_str = strdup(optarg);
break;
default:
- case '?':
usage();
/* NOTREACHED */
}
@@ -227,7 +224,6 @@ main(int argc, char **argv)
hosts[0] = strdup("*");
nhosts = 1;
} else {
- hosts_bak = hosts;
if (have_v6) {
hosts_bak = realloc(hosts, (nhosts + 2) *
sizeof(char *));
@@ -309,7 +305,7 @@ main(int argc, char **argv)
if (have_v6 == 0 && strcmp(nconf->nc_protofmly, "inet6") == 0) {
/* DO NOTHING */
} else {
- lookup_addresses(nconf);
+ create_service(nconf);
}
}
}
@@ -482,9 +478,14 @@ main(int argc, char **argv)
/*
* This routine creates and binds sockets on the appropriate
- * addresses. It gets called one time for each transport.
+ * addresses if lockd for user NLM, or perform a lookup of
+ * addresses for the kernel to create transports.
+ *
+ * It gets called one time for each transport.
+ *
* It returns 0 upon success, 1 for ingore the call and -1 to indicate
* bind failed with EADDRINUSE.
+ *
* Any file descriptors that have been created are stored in sock_fd and
* the total count of them is maintained in sock_fdcnt.
*/
@@ -528,20 +529,23 @@ create_service(struct netconfig *nconf)
nhostsbak = nhosts;
while (nhostsbak > 0) {
--nhostsbak;
- sock_fd = realloc(sock_fd, (sock_fdcnt + 1) * sizeof(int));
- if (sock_fd == NULL)
- out_of_mem();
- sock_fd[sock_fdcnt++] = -1; /* Set invalid for now. */
mallocd_res = 0;
hints.ai_flags = AI_PASSIVE;
- /*
- * XXX - using RPC library internal functions.
- */
- if ((fd = __rpc_nconf2fd(nconf)) < 0) {
- syslog(LOG_ERR, "cannot create socket for %s",
- nconf->nc_netid);
- continue;
+ if (!kernel_lockd) {
+ sock_fd = realloc(sock_fd, (sock_fdcnt + 1) * sizeof(int));
+ if (sock_fd == NULL)
+ out_of_mem();
+ sock_fd[sock_fdcnt++] = -1; /* Set invalid for now. */
+
+ /*
+ * XXX - using RPC library internal functions.
+ */
+ if ((fd = __rpc_nconf2fd(nconf)) < 0) {
+ syslog(LOG_ERR, "cannot create socket for %s",
+ nconf->nc_netid);
+ continue;
+ }
}
switch (hints.ai_family) {
@@ -555,7 +559,8 @@ create_service(struct netconfig *nconf)
*/
if (inet_pton(AF_INET6, hosts[nhostsbak],
host_addr) == 1) {
- close(fd);
+ if (!kernel_lockd)
+ close(fd);
continue;
}
}
@@ -570,7 +575,8 @@ create_service(struct netconfig *nconf)
*/
if (inet_pton(AF_INET, hosts[nhostsbak],
host_addr) == 1) {
- close(fd);
+ if (!kernel_lockd)
+ close(fd);
continue;
}
}
@@ -584,8 +590,7 @@ create_service(struct netconfig *nconf)
*/
if (strcmp("*", hosts[nhostsbak]) == 0) {
if (svcport_str == NULL) {
- res = malloc(sizeof(struct addrinfo));
- if (res == NULL)
+ if ((res = malloc(sizeof(struct addrinfo))) == NULL)
out_of_mem();
mallocd_res = 1;
res->ai_flags = hints.ai_flags;
@@ -616,7 +621,7 @@ create_service(struct netconfig *nconf)
break;
default:
syslog(LOG_ERR,
- "bad addr fam %d",
+ "bad address family %d",
res->ai_family);
exit(1);
}
@@ -627,7 +632,8 @@ create_service(struct netconfig *nconf)
"cannot get local address for %s: %s",
nconf->nc_netid,
gai_strerror(aicode));
- close(fd);
+ if (!kernel_lockd)
+ close(fd);
continue;
}
}
@@ -637,42 +643,62 @@ create_service(struct netconfig *nconf)
syslog(LOG_ERR,
"cannot get local address for %s: %s",
nconf->nc_netid, gai_strerror(aicode));
- close(fd);
+ if (!kernel_lockd)
+ close(fd);
continue;
}
}
+ if (kernel_lockd) {
+ struct netbuf servaddr;
+ char *uaddr;
- /* Store the fd. */
- sock_fd[sock_fdcnt - 1] = fd;
+ /*
+ * Look up addresses for the kernel to create transports for.
+ */
+ servaddr.len = servaddr.maxlen = res->ai_addrlen;
+ servaddr.buf = res->ai_addr;
+ uaddr = taddr2uaddr(nconf, &servaddr);
- /* Now, attempt the bind. */
- r = bindresvport_sa(fd, res->ai_addr);
- if (r != 0) {
- if (errno == EADDRINUSE && mallocd_svcport != 0) {
- if (mallocd_res != 0) {
- free(res->ai_addr);
- free(res);
- } else
- freeaddrinfo(res);
- return (-1);
+ addrs = realloc(addrs, 2 * (naddrs + 1) * sizeof(char *));
+ if (!addrs)
+ out_of_mem();
+ addrs[2 * naddrs] = strdup(nconf->nc_netid);
+ addrs[2 * naddrs + 1] = uaddr;
+ naddrs++;
+ } else {
+ /* Store the fd. */
+ sock_fd[sock_fdcnt - 1] = fd;
+
+ /* Now, attempt the bind. */
+ r = bindresvport_sa(fd, res->ai_addr);
+ if (r != 0) {
+ if (errno == EADDRINUSE && mallocd_svcport != 0) {
+ if (mallocd_res != 0) {
+ free(res->ai_addr);
+ free(res);
+ } else
+ freeaddrinfo(res);
+ return (-1);
+ }
+ syslog(LOG_ERR, "bindresvport_sa: %m");
+ exit(1);
}
- syslog(LOG_ERR, "bindresvport_sa: %m");
- exit(1);
- }
- if (svcport_str == NULL) {
- svcport_str = malloc(NI_MAXSERV * sizeof(char));
- if (svcport_str == NULL)
- out_of_mem();
- mallocd_svcport = 1;
+ if (svcport_str == NULL) {
+ svcport_str = malloc(NI_MAXSERV * sizeof(char));
+ if (svcport_str == NULL)
+ out_of_mem();
+ mallocd_svcport = 1;
- if (getnameinfo(res->ai_addr,
- res->ai_addr->sa_len, NULL, NI_MAXHOST,
- svcport_str, NI_MAXSERV * sizeof(char),
- NI_NUMERICHOST | NI_NUMERICSERV))
- errx(1, "Cannot get port number");
+ if (getnameinfo(res->ai_addr,
+ res->ai_addr->sa_len, NULL, NI_MAXHOST,
+ svcport_str, NI_MAXSERV * sizeof(char),
+ NI_NUMERICHOST | NI_NUMERICSERV))
+ errx(1, "Cannot get port number");
+ }
}
+
if (mallocd_res != 0) {
free(res->ai_addr);
free(res);
@@ -805,151 +831,6 @@ clearout_service(void)
}
}
-/*
- * Look up addresses for the kernel to create transports for.
- */
-void
-lookup_addresses(struct netconfig *nconf)
-{
- struct addrinfo hints, *res = NULL;
- struct sockaddr_in *sin;
- struct sockaddr_in6 *sin6;
- struct __rpc_sockinfo si;
- struct netbuf servaddr;
- int aicode;
- int nhostsbak;
- u_int32_t host_addr[4]; /* IPv4 or IPv6 */
- char *uaddr;
-
- if ((nconf->nc_semantics != NC_TPI_CLTS) &&
- (nconf->nc_semantics != NC_TPI_COTS) &&
- (nconf->nc_semantics != NC_TPI_COTS_ORD))
- return; /* not my type */
-
- /*
- * XXX - using RPC library internal functions.
- */
- if (!__rpc_nconf2sockinfo(nconf, &si)) {
- syslog(LOG_ERR, "cannot get information for %s",
- nconf->nc_netid);
- return;
- }
-
- /* Get rpc.statd's address on this transport */
- memset(&hints, 0, sizeof hints);
- hints.ai_flags = AI_PASSIVE;
- hints.ai_family = si.si_af;
- hints.ai_socktype = si.si_socktype;
- hints.ai_protocol = si.si_proto;
-
- /*
- * Bind to specific IPs if asked to
- */
- nhostsbak = nhosts;
- while (nhostsbak > 0) {
- --nhostsbak;
-
- switch (hints.ai_family) {
- case AF_INET:
- if (inet_pton(AF_INET, hosts[nhostsbak],
- host_addr) == 1) {
- hints.ai_flags &= AI_NUMERICHOST;
- } else {
- /*
- * Skip if we have an AF_INET6 address.
- */
- 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 address.
- */
- if (inet_pton(AF_INET, hosts[nhostsbak],
- host_addr) == 1) {
- continue;
- }
- }
- break;
- default:
- break;
- }
-
- /*
- * If no hosts were specified, just bind to INADDR_ANY
- */
- if (strcmp("*", hosts[nhostsbak]) == 0) {
- if (svcport_str == NULL) {
- res = malloc(sizeof(struct addrinfo));
- if (res == NULL)
- out_of_mem();
- res->ai_flags = hints.ai_flags;
- res->ai_family = hints.ai_family;
- res->ai_protocol = hints.ai_protocol;
- switch (res->ai_family) {
- case AF_INET:
- sin = malloc(sizeof(struct sockaddr_in));
- if (sin == NULL)
- out_of_mem();
- sin->sin_family = AF_INET;
- sin->sin_port = htons(0);
- sin->sin_addr.s_addr = htonl(INADDR_ANY);
- res->ai_addr = (struct sockaddr*) sin;
- res->ai_addrlen = sizeof(struct sockaddr_in);
- break;
- case AF_INET6:
- sin6 = malloc(sizeof(struct sockaddr_in6));
- if (sin6 == NULL)
- out_of_mem();
- sin6->sin6_family = AF_INET6;
- sin6->sin6_port = htons(0);
- sin6->sin6_addr = in6addr_any;
- res->ai_addr = (struct sockaddr*) sin6;
- res->ai_addrlen = sizeof(struct sockaddr_in6);
- break;
- default:
- break;
- }
- } else {
- if ((aicode = getaddrinfo(NULL, svcport_str,
- &hints, &res)) != 0) {
- syslog(LOG_ERR,
- "cannot get local address for %s: %s",
- nconf->nc_netid,
- gai_strerror(aicode));
- continue;
- }
- }
- } else {
- if ((aicode = getaddrinfo(hosts[nhostsbak], svcport_str,
- &hints, &res)) != 0) {
- syslog(LOG_ERR,
- "cannot get local address for %s: %s",
- nconf->nc_netid, gai_strerror(aicode));
- continue;
- }
- }
-
- servaddr.len = servaddr.maxlen = res->ai_addrlen;
- servaddr.buf = res->ai_addr;
- uaddr = taddr2uaddr(nconf, &servaddr);
-
- addrs = realloc(addrs, 2 * (naddrs + 1) * sizeof(char *));
- if (!addrs)
- out_of_mem();
- addrs[2 * naddrs] = strdup(nconf->nc_netid);
- addrs[2 * naddrs + 1] = uaddr;
- naddrs++;
- } /* end while */
-}
-
void
sigalarm_handler(void)
{