summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2014-06-02 20:46:48 +0200
committerGreg Hudson <ghudson@mit.edu>2014-06-27 19:36:40 -0400
commitb272744422dea77fdf9518a20386660df7a97bf7 (patch)
tree348cfb4c66f3c3775b50165a268472f04ff47dfb
parent0d04b60d159ab83b943e43802b1449a3b074bc83 (diff)
downloadkrb5-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.c2
-rw-r--r--src/lib/rpc/clnt_udp.c2
-rw-r--r--src/lib/rpc/svc_tcp.c31
-rw-r--r--src/lib/rpc/svc_udp.c31
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);