From 541bf913ec64dee719b34d2a6850fcfee550e6c0 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 17 Nov 2008 16:13:48 -0500 Subject: [PATCH 1/1] Introduce rpcbind client utility functions It turns out that at least the mount command and the showmount command need to query a server's rpcbind daemon. They need to query over AF_INET6 as well as AF_INET. libtirpc provides an rpcbind query capability with the rpcb_getaddr(3) interface, but it takes a hostname and netconfig entry rather than a sockaddr and a protocol type, and always uses a lengthy timeout. The former is important to the mount command because it sometimes must operate using a specific port and IP address rather than depending on rpcbind and DNS to convert a [hostname, RPC program, netconfig] tuple to a [socket address, port number, transport protocol] tuple. The rpcb_getaddr(3) API also always uses a privileged port (at least for setuid root executables like mount.nfs), which is not required for an rpcbind query. This can exhaust the local system's reserved port space quickly. This patch provides a reserved-port-friendly AF_INET6-capable rpcbind query C API that can be shared among commands and tools in nfs-utils, and allows a query to a specified socket address and port rather than a hostname. In addition to an rpcbind query interface, this patch also provides a facility to ping the remote RPC service to ensure that it is operating as advertised by rpcbind. It's useful to combine an RPC ping with an rpcbind query because in many cases, components of nfs-utils already ping an RPC service immediately after receiving a successful GETPORT result. There are also a handful of utility routines provided, such as a functions that can map between [sockaddr, port] and a universal address. I've made an attempt to make these new functions build and operate on systems that do not have libtirpc. Signed-off-by: Chuck Lever Signed-off-by: Steve Dickson --- support/include/nfsrpc.h | 71 ++++++++++++++++++++++++++++++++++++++++ support/nfs/Makefile.am | 2 +- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/support/include/nfsrpc.h b/support/include/nfsrpc.h index e129a72..1529d44 100644 --- a/support/include/nfsrpc.h +++ b/support/include/nfsrpc.h @@ -67,4 +67,75 @@ extern CLIENT *nfs_get_rpcclient(const struct sockaddr *, const rpcprog_t, const rpcvers_t, struct timeval *); +/* + * Convert a socket address to a universal address + */ +extern char *nfs_sockaddr2universal(const struct sockaddr *, + const socklen_t); + +/* + * Extract port number from a universal address + */ +extern int nfs_universal2port(const char *); + +/* + * Generic function that maps an RPC service tuple to an IP port + * number of the service on a remote post, and sends a NULL + * request to determine if the service is responding to requests + */ +extern int nfs_getport_ping(struct sockaddr *sap, + const socklen_t salen, + const rpcprog_t program, + const rpcvers_t version, + const unsigned short protocol); + +/* + * Generic function that maps an RPC service tuple to an IP port + * number of the service on a remote host + */ +extern unsigned short nfs_getport(const struct sockaddr *, + const socklen_t, const rpcprog_t, + const rpcvers_t, const unsigned short); + +/* + * Generic function that maps an RPC service tuple to an IP port + * number of the service on the local host + */ +extern unsigned short nfs_getlocalport(const rpcprot_t, + const rpcvers_t, const unsigned short); + +/* + * Function to invoke an rpcbind v3/v4 GETADDR request + */ +extern unsigned short nfs_rpcb_getaddr(const struct sockaddr *, + const socklen_t, + const unsigned short, + const struct sockaddr *, + const socklen_t, + const rpcprog_t, + const rpcvers_t, + const unsigned short, + const struct timeval *); + +/* + * Function to invoke a portmap GETPORT request + */ +extern unsigned long nfs_pmap_getport(const struct sockaddr_in *, + const unsigned short, + const unsigned long, + const unsigned long, + const unsigned long, + const struct timeval *); + +/* + * Contact a remote RPC service to discover whether it is responding + * to requests. + */ +extern int nfs_rpc_ping(const struct sockaddr *sap, + const socklen_t salen, + const rpcprog_t program, + const rpcvers_t version, + const unsigned short protocol, + const struct timeval *timeout); + #endif /* __NFS_UTILS_NFSRPC_H */ diff --git a/support/nfs/Makefile.am b/support/nfs/Makefile.am index d6d71d9..86f52a1 100644 --- a/support/nfs/Makefile.am +++ b/support/nfs/Makefile.am @@ -3,7 +3,7 @@ noinst_LIBRARIES = libnfs.a libnfs_a_SOURCES = exports.c rmtab.c xio.c rpcmisc.c rpcdispatch.c \ xlog.c xcommon.c wildmat.c nfssvc.c nfsclient.c \ - nfsexport.c getfh.c nfsctl.c rpc_socket.c \ + nfsexport.c getfh.c nfsctl.c rpc_socket.c getport.c \ svc_socket.c cacheio.c closeall.c nfs_mntent.c MAINTAINERCLEANFILES = Makefile.in -- 2.39.2