From 7cfcf20b10c97faaf764f5c7784c4f2fa7922c5f Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 23 May 2005 17:53:19 +0000 Subject: [PATCH] 2005-05-23 Ulrich Drepper * sunrpc/pm_getport.c (__get_socket): New function. (pmap_getport): Use it to open a non-reserved socket to the portmapper for TCP. * include/rpc/pmap_clnt.h (__get_socket): Declare. * sunrpc/pm_getmaps.c (pmap_getmaps): Use __get_socket to get an non-reserved socket for the portmapper. Based on a patch by Steve Dickson . * sunrpc/bindrsvprt.c (bindresvport): Try harder to find a port. If we tried looking at the usual range without success extend the range to even lower ports. --- ChangeLog | 12 ++++++++++++ include/rpc/pmap_clnt.h | 4 ++++ sunrpc/bindrsvprt.c | 23 +++++++++++++++++----- sunrpc/pm_getmaps.c | 15 ++++++++++++-- sunrpc/pm_getport.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 96 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index d8469746aa..8c8376d8c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,17 @@ 2005-05-23 Ulrich Drepper + * sunrpc/pm_getport.c (__get_socket): New function. + (pmap_getport): Use it to open a non-reserved socket to the portmapper + for TCP. + * include/rpc/pmap_clnt.h (__get_socket): Declare. + * sunrpc/pm_getmaps.c (pmap_getmaps): Use __get_socket to get an + non-reserved socket for the portmapper. + Based on a patch by Steve Dickson . + + * sunrpc/bindrsvprt.c (bindresvport): Try harder to find a port. + If we tried looking at the usual range without success extend the + range to even lower ports. + * sysdeps/unix/clock_gettime.c (clock_gettime): Revert last patch. 2005-05-22 Dmitry V. Levin diff --git a/include/rpc/pmap_clnt.h b/include/rpc/pmap_clnt.h index 2d02ff2096..9a22082287 100644 --- a/include/rpc/pmap_clnt.h +++ b/include/rpc/pmap_clnt.h @@ -5,4 +5,8 @@ libc_hidden_proto (pmap_getport) libc_hidden_proto (pmap_set) libc_hidden_proto (pmap_unset) +/* Defined in pm_getport.c. */ +extern int __get_socket (struct sockaddr_in *saddr) + attribute_hidden internal_function; + #endif diff --git a/sunrpc/bindrsvprt.c b/sunrpc/bindrsvprt.c index 374518716e..39c1e8063d 100644 --- a/sunrpc/bindrsvprt.c +++ b/sunrpc/bindrsvprt.c @@ -43,14 +43,15 @@ int bindresvport (int sd, struct sockaddr_in *sin) { - int res; static short port; struct sockaddr_in myaddr; int i; #define STARTPORT 600 +#define LOWPORT 200 #define ENDPORT (IPPORT_RESERVED - 1) #define NPORTS (ENDPORT - STARTPORT + 1) + static short startport = STARTPORT; if (sin == (struct sockaddr_in *) 0) { @@ -68,17 +69,29 @@ bindresvport (int sd, struct sockaddr_in *sin) { port = (__getpid () % NPORTS) + STARTPORT; } - res = -1; - __set_errno (EADDRINUSE); - for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; ++i) + /* Initialize to make gcc happy. */ + int res = -1; + + int nports = ENDPORT - startport + 1; + again: + for (i = 0; i < nports; ++i) { sin->sin_port = htons (port++); if (port > ENDPORT) { - port = STARTPORT; + port = startport; } res = __bind (sd, sin, sizeof (struct sockaddr_in)); + if (res >= 0 || errno != EADDRINUSE) + break; + } + + if (i == nports && startport != LOWPORT) + { + startport = LOWPORT; + nports = STARTPORT - LOWPORT; + goto again; } return res; diff --git a/sunrpc/pm_getmaps.c b/sunrpc/pm_getmaps.c index d1d4ca8769..2a6876d9d8 100644 --- a/sunrpc/pm_getmaps.c +++ b/sunrpc/pm_getmaps.c @@ -44,9 +44,12 @@ static char sccsid[] = "@(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro"; #include #include #include +#include #include #include #include +#include + /* * Get a copy of the current port maps. @@ -56,13 +59,19 @@ struct pmaplist * pmap_getmaps (struct sockaddr_in *address) { struct pmaplist *head = (struct pmaplist *) NULL; - int socket = -1; struct timeval minutetimeout; CLIENT *client; + bool closeit = false; minutetimeout.tv_sec = 60; minutetimeout.tv_usec = 0; address->sin_port = htons (PMAPPORT); + + /* Don't need a reserved port to get ports from the portmapper. */ + int socket = __get_socket (address); + if (socket != -1) + closeit = true; + client = INTUSE(clnttcp_create) (address, PMAPPROG, PMAPVERS, &socket, 50, 500); if (client != (CLIENT *) NULL) @@ -75,7 +84,9 @@ pmap_getmaps (struct sockaddr_in *address) } CLNT_DESTROY (client); } - /* (void)close(socket); CLNT_DESTROY already closed it */ + /* We only need to close the socket here if we opened it. */ + if (closeit) + (void) __close (socket); address->sin_port = 0; return head; } diff --git a/sunrpc/pm_getport.c b/sunrpc/pm_getport.c index 00e1ba95bf..2d309841f3 100644 --- a/sunrpc/pm_getport.c +++ b/sunrpc/pm_getport.c @@ -38,6 +38,8 @@ static char sccsid[] = "@(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro"; * Copyright (C) 1984, Sun Microsystems, Inc. */ +#include +#include #include #include #include @@ -49,6 +51,41 @@ static const struct timeval tottimeout = {60, 0}; /* + * Create a socket that is locally bound to a non-reserve port. For + * any failures, -1 is returned which will cause the RPC code to + * create the socket. + */ +int +internal_function +__get_socket (struct sockaddr_in *saddr) +{ + int so = __socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (so < 0) + return -1; + + struct sockaddr_in laddr; + socklen_t namelen = sizeof (laddr); + laddr.sin_family = AF_INET; + laddr.sin_port = 0; + laddr.sin_addr.s_addr = htonl (INADDR_ANY); + + int cc = __bind (so, (struct sockaddr *) &laddr, namelen); + if (__builtin_expect (cc < 0, 0)) + { + fail: + __close (so); + return -1; + } + + cc = __connect (so, (struct sockaddr *) saddr, namelen); + if (__builtin_expect (cc < 0, 0)) + goto fail; + + return so; +} + + +/* * Find the mapped port for program,version. * Calls the pmap service remotely to do the lookup. * Returns 0 if no map exists. @@ -64,11 +101,18 @@ pmap_getport (address, program, version, protocol) int socket = -1; CLIENT *client; struct pmap parms; + bool closeit = false; address->sin_port = htons (PMAPPORT); if (protocol == IPPROTO_TCP) - client = INTUSE(clnttcp_create) (address, PMAPPROG, PMAPVERS, &socket, - RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + { + /* Don't need a reserved port to get ports from the portmapper. */ + socket = __get_socket(address); + if (socket != -1) + closeit = true; + client = INTUSE(clnttcp_create) (address, PMAPPROG, PMAPVERS, &socket, + RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + } else client = INTUSE(clntudp_bufcreate) (address, PMAPPROG, PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, @@ -93,7 +137,9 @@ pmap_getport (address, program, version, protocol) } CLNT_DESTROY (client); } - /* (void)close(socket); CLNT_DESTROY already closed it */ + /* We only need to close the socket here if we opened it. */ + if (closeit) + (void) __close (socket); address->sin_port = 0; return port; } -- 2.11.4.GIT