krb5 commit: Use binresvport_sa when creating RPC handles

Greg Hudson ghudson at MIT.EDU
Fri Jun 27 22:37:18 EDT 2014


https://github.com/krb5/krb5/commit/b272744422dea77fdf9518a20386660df7a97bf7
commit b272744422dea77fdf9518a20386660df7a97bf7
Author: Andreas Schneider <asn at samba.org>
Date:   Mon Jun 2 20:46:48 2014 +0200

    Use binresvport_sa when creating RPC handles
    
    Make clnttcp_create, clntudp_bufcreate, svctcp_create, and
    svcudp_bufcreate work with unbound IPv6 sockets using bindresvport_sa
    and other socket helpers.  For caller-supplied sockets, call
    getsockname to determine the address family we should attempt to bind.
    
    [ghudson at mit.edu: clarified commit message, minimized code changes,
    used socket-utils.h helpers, fixed fallback find on bindresvport
    failure, restored getsockaddr call to get port after binding]
    
    ticket: 7935

 src/lib/rpc/clnt_tcp.c |    2 +-
 src/lib/rpc/clnt_udp.c |    2 +-
 src/lib/rpc/svc_tcp.c  |   31 ++++++++++++++++++-------------
 src/lib/rpc/svc_udp.c  |   31 +++++++++++++++++++------------
 4 files changed, 39 insertions(+), 27 deletions(-)

diff --git a/src/lib/rpc/clnt_tcp.c b/src/lib/rpc/clnt_tcp.c
index 2affc28..02056fd 100644
--- a/src/lib/rpc/clnt_tcp.c
+++ b/src/lib/rpc/clnt_tcp.c
@@ -167,7 +167,7 @@ clnttcp_create(
 	 */
 	if (*sockp < 0) {
 		*sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-		(void)bindresvport(*sockp, (struct sockaddr_in *)0);
+		(void)bindresvport_sa(*sockp, NULL);
 		if ((*sockp < 0)
 		    || (connect(*sockp, (struct sockaddr *)raddr,
 		    sizeof(*raddr)) < 0)) {
diff --git a/src/lib/rpc/clnt_udp.c b/src/lib/rpc/clnt_udp.c
index 074b576..7a51916 100644
--- a/src/lib/rpc/clnt_udp.c
+++ b/src/lib/rpc/clnt_udp.c
@@ -187,7 +187,7 @@ clntudp_bufcreate(
 			goto fooy;
 		}
 		/* attempt to bind to prov port */
-		(void)bindresvport(*sockp, (struct sockaddr_in *)0);
+		(void)bindresvport_sa(*sockp, NULL);
 		/* the sockets rpc controls are non-blocking */
 		(void)ioctl(*sockp, FIONBIO, (char *) &dontblock);
 		cu->cu_closeit = TRUE;
diff --git a/src/lib/rpc/svc_tcp.c b/src/lib/rpc/svc_tcp.c
index bbafc1d..58f7b0e 100644
--- a/src/lib/rpc/svc_tcp.c
+++ b/src/lib/rpc/svc_tcp.c
@@ -148,9 +148,9 @@ svctcp_create(
 	bool_t madesock = FALSE;
 	register SVCXPRT *xprt;
 	register struct tcp_rendezvous *r;
-	struct sockaddr_in sin;
-	struct sockaddr_storage addr;
-	socklen_t len = sizeof(addr);
+	struct sockaddr_storage ss;
+	struct sockaddr *sa = (struct sockaddr *)&ss;
+	socklen_t len;
 
 	if (sock == RPC_ANYSOCK) {
 		if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
@@ -159,17 +159,22 @@ svctcp_create(
 		}
 		set_cloexec_fd(sock);
 		madesock = TRUE;
+		memset(sa, 0, sizeof(struct sockaddr_in));
+		sa->sa_family = AF_INET;
+	} else {
+		len = sizeof(struct sockaddr_storage);
+		if (getsockname(sock, sa, &len) != 0) {
+			perror("svc_tcp.c - cannot getsockname");
+			return ((SVCXPRT *)NULL);
+		}
 	}
-	memset(&sin, 0, sizeof(sin));
-#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
-	sin.sin_len = sizeof(sin);
-#endif
-	sin.sin_family = AF_INET;
-	if (bindresvport(sock, &sin)) {
-		sin.sin_port = 0;
-		(void)bind(sock, (struct sockaddr *)&sin, sizeof(sin));
+
+	if (bindresvport_sa(sock, sa)) {
+		sa_setport(sa, 0);
+		(void)bind(sock, sa, socklen(sa));
 	}
-	if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) {
+	len = sizeof(struct sockaddr_storage);
+	if (getsockname(sock, sa, &len) != 0) {
 		perror("svc_tcp.c - cannot getsockname");
                 if (madesock)
                         (void)closesocket(sock);
@@ -198,7 +203,7 @@ svctcp_create(
 	xprt->xp_auth = NULL;
 	xprt->xp_verf = gssrpc__null_auth;
 	xprt->xp_ops = &svctcp_rendezvous_op;
-	xprt->xp_port = sa_getport((struct sockaddr *) &addr);
+	xprt->xp_port = sa_getport(sa);
 	xprt->xp_sock = sock;
 	xprt->xp_laddrlen = 0;
 	xprt_register(xprt);
diff --git a/src/lib/rpc/svc_udp.c b/src/lib/rpc/svc_udp.c
index 0b01527..460472f 100644
--- a/src/lib/rpc/svc_udp.c
+++ b/src/lib/rpc/svc_udp.c
@@ -52,6 +52,7 @@ static char sccsid[] = "@(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro";
 #include <sys/uio.h>
 #endif
 #include <port-sockets.h>
+#include <socket-utils.h>
 #include "k5-platform.h"
 
 
@@ -118,8 +119,9 @@ svcudp_bufcreate(
 	bool_t madesock = FALSE;
 	register SVCXPRT *xprt;
 	register struct svcudp_data *su;
-	struct sockaddr_in addr;
-	GETSOCKNAME_ARG3_TYPE len = sizeof(struct sockaddr_in);
+	struct sockaddr_storage ss;
+	struct sockaddr *sa = (struct sockaddr *)&ss;
+	socklen_t len;
 
 	if (sock == RPC_ANYSOCK) {
 		if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
@@ -128,17 +130,22 @@ svcudp_bufcreate(
 		}
 		set_cloexec_fd(sock);
 		madesock = TRUE;
+		memset(sa, 0, sizeof(struct sockaddr_in));
+		sa->sa_family = AF_INET;
+	} else {
+		len = sizeof(struct sockaddr_storage);
+		if (getsockname(sock, sa, &len) < 0) {
+			perror("svcudp_create - cannot getsockname");
+			return ((SVCXPRT *)NULL);
+		}
 	}
-	memset(&addr, 0, sizeof (addr));
-#if HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
-	addr.sin_len = sizeof(addr);
-#endif
-	addr.sin_family = AF_INET;
-	if (bindresvport(sock, &addr)) {
-		addr.sin_port = 0;
-		(void)bind(sock, (struct sockaddr *)&addr, len);
+
+	if (bindresvport_sa(sock, sa)) {
+		sa_setport(sa, 0);
+		(void)bind(sock, sa, socklen(sa));
 	}
-	if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) {
+	len = sizeof(struct sockaddr_storage);
+	if (getsockname(sock, sa, &len) != 0) {
 		perror("svcudp_create - cannot getsockname");
 		if (madesock)
 			(void)close(sock);
@@ -166,7 +173,7 @@ svcudp_bufcreate(
 	xprt->xp_auth = NULL;
 	xprt->xp_verf.oa_base = su->su_verfbody;
 	xprt->xp_ops = &svcudp_op;
-	xprt->xp_port = ntohs(addr.sin_port);
+	xprt->xp_port = sa_getport(sa);
 	xprt->xp_sock = sock;
 	xprt_register(xprt);
 	return (xprt);


More information about the cvs-krb5 mailing list