diff options
author | Andreas Schneider <asn@samba.org> | 2014-06-02 20:46:48 +0200 |
---|---|---|
committer | Greg Hudson <ghudson@mit.edu> | 2014-06-27 19:36:40 -0400 |
commit | b272744422dea77fdf9518a20386660df7a97bf7 (patch) | |
tree | 348cfb4c66f3c3775b50165a268472f04ff47dfb | |
parent | 0d04b60d159ab83b943e43802b1449a3b074bc83 (diff) | |
download | krb5-b272744422dea77fdf9518a20386660df7a97bf7.tar.gz krb5-b272744422dea77fdf9518a20386660df7a97bf7.tar.xz krb5-b272744422dea77fdf9518a20386660df7a97bf7.zip |
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@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
-rw-r--r-- | src/lib/rpc/clnt_tcp.c | 2 | ||||
-rw-r--r-- | src/lib/rpc/clnt_udp.c | 2 | ||||
-rw-r--r-- | src/lib/rpc/svc_tcp.c | 31 | ||||
-rw-r--r-- | 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 2affc28bd..02056fd40 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 074b576e4..7a5191659 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 bbafc1d63..58f7b0e39 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 0b0152730..460472fe6 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); |