I've seen this intermittently for mountd. I think the problem is that
the code finds an unused port for udp/ip6 and then tries to use the
same port# for tcp/ip6, udp/ip4, tcp/ip4. All three daemons have
essentially the same function for doing this.
The attached patches changes the behaviour so that it tries to
get an unused port for each of the 4 cases.
(This all applies to the "wildcard" case, where no port# or
hosts have been specified as command args.)
If you have the chance to try these patches, please let us know
how they work for you?
rick
ps: I lost track of the thread, so I don't know who started it, but
hopefully, they are on the cc list?
--- usr.sbin/mountd/mountd.c.sav 2011-02-17 21:45:32.000000000 -0500
+++ usr.sbin/mountd/mountd.c 2011-02-17 23:23:37.000000000 -0500
@@ -510,6 +510,7 @@ create_service(struct netconfig *nconf)
int r;
int registered = 0;
u_int32_t host_addr[4]; /* IPv4 or IPv6 */
+ int mallocd_svcport = 0;
if ((nconf->nc_semantics != NC_TPI_CLTS) &&
(nconf->nc_semantics != NC_TPI_COTS) &&
@@ -620,7 +621,7 @@ create_service(struct netconfig *nconf)
sin->sin_addr.s_addr = htonl(INADDR_ANY);
res->ai_addr = (struct sockaddr*) sin;
res->ai_addrlen = (socklen_t)
- sizeof(res->ai_addr);
+ sizeof(struct sockaddr_in);
break;
case AF_INET6:
sin6 = malloc(sizeof(struct sockaddr_in6));
@@ -631,10 +632,12 @@ create_service(struct netconfig *nconf)
sin6->sin6_addr = in6addr_any;
res->ai_addr = (struct sockaddr*) sin6;
res->ai_addrlen = (socklen_t)
- sizeof(res->ai_addr);
+ sizeof(struct sockaddr_in6);
break;
default:
- break;
+ syslog(LOG_ERR, "bad addr fam %d",
+ res->ai_family);
+ exit(1);
}
} else {
if ((aicode = getaddrinfo(NULL, svcport_str,
@@ -700,6 +703,7 @@ create_service(struct netconfig *nconf)
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,
@@ -715,6 +719,12 @@ create_service(struct netconfig *nconf)
exit(1);
}
+ if (mallocd_svcport != 0) {
+ free(svcport_str);
+ svcport_str = NULL;
+ mallocd_svcport = 0;
+ }
+
servaddr.buf = malloc(res->ai_addrlen);
memcpy(servaddr.buf, res->ai_addr, res->ai_addrlen);
servaddr.len = res->ai_addrlen;
--- usr.sbin/rpc.statd/statd.c.sav 2011-02-17 23:36:15.000000000 -0500
+++ usr.sbin/rpc.statd/statd.c 2011-02-17 23:37:53.000000000 -0500
@@ -233,6 +233,7 @@ create_service(struct netconfig *nconf)
int r;
int registered = 0;
u_int32_t host_addr[4]; /* IPv4 or IPv6 */
+ int mallocd_svcport = 0;
if ((nconf->nc_semantics != NC_TPI_CLTS) &&
(nconf->nc_semantics != NC_TPI_COTS) &&
@@ -326,7 +327,7 @@ create_service(struct netconfig *nconf)
sin->sin_addr.s_addr = htonl(INADDR_ANY);
res->ai_addr = (struct sockaddr*) sin;
res->ai_addrlen = (socklen_t)
- sizeof(res->ai_addr);
+ sizeof(struct sockaddr_in);
break;
case AF_INET6:
sin6 = malloc(sizeof(struct sockaddr_in6));
@@ -336,10 +337,13 @@ create_service(struct netconfig *nconf)
sin6->sin6_port = htons(0);
sin6->sin6_addr = in6addr_any;
res->ai_addr = (struct sockaddr*) sin6;
- res->ai_addrlen = (socklen_t) sizeof(res->ai_addr);
+ res->ai_addrlen = (socklen_t)
+ sizeof(struct sockaddr_in6);
break;
default:
- break;
+ syslog(LOG_ERR, "bad addr fam %d",
+ res->ai_family);
+ exit(1);
}
} else {
if ((aicode = getaddrinfo(NULL, svcport_str,
@@ -401,6 +405,7 @@ create_service(struct netconfig *nconf)
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,
@@ -416,6 +421,12 @@ create_service(struct netconfig *nconf)
exit(1);
}
+ if (mallocd_svcport != 0) {
+ free(svcport_str);
+ svcport_str = NULL;
+ mallocd_svcport = 0;
+ }
+
servaddr.buf = malloc(res->ai_addrlen);
memcpy(servaddr.buf, res->ai_addr, res->ai_addrlen);
servaddr.len = res->ai_addrlen;
--- usr.sbin/rpc.lockd/lockd.c.sav 2011-02-17 23:29:48.000000000 -0500
+++ usr.sbin/rpc.lockd/lockd.c 2011-02-17 23:35:47.000000000 -0500
@@ -403,6 +403,7 @@ create_service(struct netconfig *nconf)
int r;
int registered = 0;
u_int32_t host_addr[4]; /* IPv4 or IPv6 */
+ int mallocd_svcport = 0;
if ((nconf->nc_semantics != NC_TPI_CLTS) &&
(nconf->nc_semantics != NC_TPI_COTS) &&
@@ -497,7 +498,7 @@ create_service(struct netconfig *nconf)
sin->sin_addr.s_addr = htonl(INADDR_ANY);
res->ai_addr = (struct sockaddr*) sin;
res->ai_addrlen = (socklen_t)
- sizeof(res->ai_addr);
+ sizeof(struct sockaddr_in);
break;
case AF_INET6:
sin6 = malloc(sizeof(struct sockaddr_in6));
@@ -507,10 +508,14 @@ create_service(struct netconfig *nconf)
sin6->sin6_port = htons(0);
sin6->sin6_addr = in6addr_any;
res->ai_addr = (struct sockaddr*) sin6;
- res->ai_addrlen = (socklen_t) sizeof(res->ai_addr);
+ res->ai_addrlen = (socklen_t)
+ sizeof(struct sockaddr_in6);
break;
default:
- break;
+ syslog(LOG_ERR,
+ "bad addr fam %d",
+ res->ai_family);
+ exit(1);
}
} else {
if ((aicode = getaddrinfo(NULL, svcport_str,
@@ -585,6 +590,7 @@ create_service(struct netconfig *nconf)
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,
@@ -600,6 +606,12 @@ create_service(struct netconfig *nconf)
exit(1);
}
+ if (mallocd_svcport != 0) {
+ free(svcport_str);
+ svcport_str = NULL;
+ mallocd_svcport = 0;
+ }
+
servaddr.buf = malloc(res->ai_addrlen);
memcpy(servaddr.buf, res->ai_addr, res->ai_addrlen);
servaddr.len = res->ai_addrlen;
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-stable
To unsubscribe, send any mail to "[email protected]"