diff options
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | include/rpc/pmap_clnt.h | 4 | ||||
-rw-r--r-- | sunrpc/pm_getmaps.c | 15 | ||||
-rw-r--r-- | sunrpc/pm_getport.c | 52 |
4 files changed, 74 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog index e8ffccf8ab..9e8114b658 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,15 @@ 2005-05-23 Ulrich Drepper <drepper@redhat.com> + * 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. + * 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.q + range to even lower ports. * sysdeps/unix/clock_gettime.c (clock_gettime): Revert last patch. 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/pm_getmaps.c b/sunrpc/pm_getmaps.c index d1d4ca8769..6e304a3372 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 <rpc/pmap_clnt.h> #include <sys/socket.h> #include <netdb.h> +#include <stdbool.h> #include <stdio.h> #include <errno.h> #include <libintl.h> +#include <unistd.h> + /* * 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 reserver 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 <stdbool.h> +#include <unistd.h> #include <rpc/rpc.h> #include <rpc/pmap_prot.h> #include <rpc/pmap_clnt.h> @@ -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; } |