Date: Mon, 8 Jul 2002 20:40:35 +0200 (CEST) From: Martin Blapp <mb@imp.ch> To: Doug Barton <dougb@FreeBSD.org> Cc: <freebsd-bugs@FreeBSD.org>, <mbr@FreeBSD.org> Subject: Re: bin/39674: the new rpcbind lacks the -h IPAddrs feature of the portmap d. Message-ID: <20020708200029.U41780-100000@levais.imp.ch> In-Reply-To: <200207062024.g66KOmfo052000@freefall.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Hi, > Synopsis: the new rpcbind lacks the -h IPAddrs feature of the portmap d. can you try the following patch (untested). I don't know if it works for IPv6. I can test this tomorrow. Index: rpcbind.8 =================================================================== RCS file: /home/ncvs/src/usr.sbin/rpcbind/rpcbind.8,v retrieving revision 1.2 diff -u -r1.2 rpcbind.8 --- rpcbind.8 20 Aug 2001 00:03:01 -0000 1.2 +++ rpcbind.8 8 Jul 2002 18:35:48 -0000 @@ -72,6 +72,27 @@ during operation, and will abort on certain errors. With this option, the name-to-address translation consistency checks are shown in detail. +.It Fl h +Specify specific IP addresses to bind to for UDP requests. +This option +may be specified multiple times and is typically necessary when running +on a multi-homed host. +If no +.Fl h +option is specified, +.Nm +will bind to +.Dv INADDR_ANY , +which could lead to problems on a multi-homed host due to +.Nm +returning a UDP packet from a different IP address than it was +sent to. +Note that when specifying IP addresses with +.Fl h , +.Nm +will automatically add +.Li 127.0.0.1 +to the list. .It Fl i .Dq Insecure mode. Index: rpcbind.c =================================================================== RCS file: /home/ncvs/src/usr.sbin/rpcbind/rpcbind.c,v retrieving revision 1.2 diff -u -r1.2 rpcbind.c --- rpcbind.c 17 May 2002 05:27:52 -0000 1.2 +++ rpcbind.c 8 Jul 2002 18:35:49 -0000 @@ -86,6 +86,9 @@ int oldstyle_local = 0; int verboselog = 0; +char **hosts = NULL; +int nhosts = 0; + #ifdef WARMSTART /* Local Variable */ static int warmstart = 0; /* Grab a old copy of registrations */ @@ -220,7 +223,9 @@ int status; /* bound checking ? */ int aicode; int addrlen; + int nhostscp; struct sockaddr *sa; + u_int32_t host_addr[4]; /* IPv4 or IPv6 */ struct sockaddr_un sun; mode_t oldmask; @@ -271,20 +276,83 @@ hints.ai_family = si.si_af; hints.ai_socktype = si.si_socktype; hints.ai_protocol = si.si_proto; - if ((aicode = getaddrinfo(NULL, servname, &hints, &res)) != 0) { - syslog(LOG_ERR, "cannot get local address for %s: %s", - nconf->nc_netid, gai_strerror(aicode)); - return 1; + if (nconf->nc_semantics != NC_TPI_CLTS) { + if ((aicode = getaddrinfo(NULL, servname, &hints, &res)) != 0) { + syslog(LOG_ERR, "cannot get local address for %s: %s", + nconf->nc_netid, gai_strerror(aicode)); + return 1; + } + addrlen = res->ai_addrlen; + sa = (struct sockaddr *)res->ai_addr; } - 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: %m", nconf->nc_netid); - if (res != NULL) - freeaddrinfo(res); - return 1; + if (nconf->nc_semantics == NC_TPI_CLTS) { + /* + * If no hosts were specified, just bind to INADDR_ANY. Otherwise + * make sure 127.0.0.1 is added to the list. + */ + nhostscp = nhosts; + ++nhostscp; + hosts = realloc(hosts, nhostscp * sizeof(char *)); + if (nhostscp == 1) + hosts[0] = "*"; + else { + if (strcmp(nconf->nc_proto, NC_UDP) == 0) { + hosts[nhostscp - 1] = "127.0.0.1"; + } else { + hosts[nhostscp - 1] = "::1"; + } + } + + /* + * Add UDP socket(s) - bind to specific IPs if asked to + */ + while (nhostscp > 0) { + --nhostscp; + switch (hints.ai_family) { + case AF_INET: + if (inet_pton(AF_INET, hosts[nhosts], host_addr) == 1) { + hints.ai_flags = AI_NUMERICHOST; + } else { + if (inet_pton(AF_INET6, hosts[nhosts], + host_addr) == 1) + return (1); + } + break; + case AF_INET6: + if (inet_pton(AF_INET6, hosts[nhosts], host_addr) == 1) { + hints.ai_flags = AI_NUMERICHOST; + } else { + if (inet_pton(AF_INET, hosts[nhosts], + host_addr) == 1) + return (1); + } + break; + default: + break; + } + if ((aicode = getaddrinfo(hosts[nhosts], servname, &hints, &res)) != 0) { + syslog(LOG_ERR, "cannot get local address for %s: %s", + nconf->nc_netid, gai_strerror(aicode)); + return 1; + } + addrlen = res->ai_addrlen; + sa = (struct sockaddr *)res->ai_addr; + if (bind(fd, sa, addrlen) != 0) { + syslog(LOG_ERR, "cannot bind %s: %m", nconf->nc_netid); + if (res != NULL) + freeaddrinfo(res); + return 1; + } + } + } else { + if (bind(fd, sa, addrlen) < 0) { + syslog(LOG_ERR, "cannot bind %s: %m", nconf->nc_netid); + if (res != NULL) + freeaddrinfo(res); + return 1; + } } (void) umask(oldmask); @@ -513,7 +581,7 @@ { int c; - while ((c = getopt(argc, argv, "dwailLs")) != -1) { + while ((c = getopt(argc, argv, "dwahilLs")) != -1) { switch (c) { case 'a': doabort = 1; /* when debugging, do an abort on */ @@ -521,6 +589,15 @@ /* only! */ case 'd': debugging = 1; + break; + case 'h': + ++nhosts; + hosts = realloc(hosts, nhosts * sizeof(char *)); + if (hosts == NULL) + errx(1, "Out of memory"); + hosts[nhosts - 1] = optarg; + if (hosts[nhosts - 1] == NULL) + errx(1, "Out of memory"); break; case 'i': insecure = 1; To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20020708200029.U41780-100000>