]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Use binresvport_sa when creating RPC handles
authorAndreas Schneider <asn@samba.org>
Mon, 2 Jun 2014 18:46:48 +0000 (20:46 +0200)
committerGreg Hudson <ghudson@mit.edu>
Fri, 27 Jun 2014 23:36:40 +0000 (19:36 -0400)
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

src/lib/rpc/clnt_tcp.c
src/lib/rpc/clnt_udp.c
src/lib/rpc/svc_tcp.c
src/lib/rpc/svc_udp.c

index 2affc28bda5bab8468d990e310b3e4d689383632..02056fd40c7ca7ce79611578fe80501b0b4de3a0 100644 (file)
@@ -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)) {
index 074b576e4c3c593ba5ae90be3558c3f3cda17a60..7a5191659dfd5ecb8fd27f50199283394550db6e 100644 (file)
@@ -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;
index bbafc1d636841de1cff322f7ab2b1a8c161d51cb..58f7b0e398568e5c4a0902c7e13a8062f59d52a1 100644 (file)
@@ -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);
index 0b01527305186a4eb51897acbc34ee862cf5fee2..460472fe6a79c17137691d1c2bc43f1a8e99d4f2 100644 (file)
@@ -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);