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