From owner-svn-src-head@freebsd.org Wed Jun 21 06:34:07 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 65651D87AC9; Wed, 21 Jun 2017 06:34:07 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 413B482392; Wed, 21 Jun 2017 06:34:07 +0000 (UTC) (envelope-from delphij@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v5L6Y6SW074934; Wed, 21 Jun 2017 06:34:06 GMT (envelope-from delphij@FreeBSD.org) Received: (from delphij@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v5L6Y6KO074933; Wed, 21 Jun 2017 06:34:06 GMT (envelope-from delphij@FreeBSD.org) Message-Id: <201706210634.v5L6Y6KO074933@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: delphij set sender to delphij@FreeBSD.org using -f From: Xin LI Date: Wed, 21 Jun 2017 06:34:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r320183 - head/usr.sbin/rpc.lockd X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 Jun 2017 06:34:07 -0000 Author: delphij Date: Wed Jun 21 06:34:06 2017 New Revision: 320183 URL: https://svnweb.freebsd.org/changeset/base/320183 Log: Reduce code duplication in rpc.lockd. Reuse create_service code instead of duplicating it in lookup_addresses for kernel NLM. As a (good) side effect this also fixed a few issues that were already fixed in the former but never applied to the latter. Reviewed by: kevlo MFC after: 3 days Differential Revision: https://reviews.freebsd.org/D11259 Modified: head/usr.sbin/rpc.lockd/lockd.c Modified: head/usr.sbin/rpc.lockd/lockd.c ============================================================================== --- head/usr.sbin/rpc.lockd/lockd.c Wed Jun 21 04:36:46 2017 (r320182) +++ head/usr.sbin/rpc.lockd/lockd.c Wed Jun 21 06:34:06 2017 (r320183) @@ -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); @@ -803,151 +829,6 @@ clearout_service(void) close(sock_fd[i]); } } -} - -/* - * 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