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]"

Reply via email to