]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - support/nfs/getport.c
getport: Remove AI_ADDRCONFIG from nfs_gp_loopback_address()
[nfs-utils.git] / support / nfs / getport.c
index cf1677e78650869a284c8ca550f02ff83845f2bf..9d85e897090f97e5a26bcd2dbd21783209f306e8 100644 (file)
@@ -65,59 +65,32 @@ static const rpcvers_t default_rpcb_version = RPCBVERS_4;
 static const rpcvers_t default_rpcb_version = PMAPVERS;
 #endif /* !HAVE_LIBTIRPC */
 
-#ifdef HAVE_DECL_AI_ADDRCONFIG
 /*
- * getaddrinfo(3) generates a usable loopback address based on how the
- * local network interfaces are configured.  RFC 3484 requires that the
- * results are sorted so that the first result has the best likelihood
- * of working, so we try just that first result.
+ * There's no easy way to tell how the local system's networking
+ * and rpcbind is configured (ie. whether we want to use IPv6 or
+ * IPv4 loopback to contact RPC services on the local host).  We
+ * punt and simply try to look up "localhost".
  *
  * Returns TRUE on success.
  */
 static int nfs_gp_loopback_address(struct sockaddr *sap, socklen_t *salen)
 {
        struct addrinfo *gai_results;
-       struct addrinfo gai_hint = {
-               .ai_flags       = AI_ADDRCONFIG,
-       };
-       socklen_t len = *salen;
        int ret = 0;
 
-       if (getaddrinfo(NULL, "sunrpc", &gai_hint, &gai_results))
+       if (getaddrinfo("localhost", NULL, NULL, &gai_results))
                return 0;
 
-       switch (gai_results->ai_addr->sa_family) {
-       case AF_INET:
-       case AF_INET6:
-               if (len >= gai_results->ai_addrlen) {
-                       memcpy(sap, gai_results->ai_addr,
-                                       gai_results->ai_addrlen);
-                       *salen = gai_results->ai_addrlen;
-                       ret = 1;
-               }
+       if (*salen >= gai_results->ai_addrlen) {
+               memcpy(sap, gai_results->ai_addr,
+                               gai_results->ai_addrlen);
+               *salen = gai_results->ai_addrlen;
+               ret = 1;
        }
 
        freeaddrinfo(gai_results);
        return ret;
 }
-#else
-/*
- * Old versions of getaddrinfo(3) don't support AI_ADDRCONFIG, so we
- * have a fallback for building on legacy systems.
- */
-static int nfs_gp_loopback_address(struct sockaddr *sap, socklen_t *salen)
-{
-       struct sockaddr_in *sin = (struct sockaddr_in *)sap;
-
-       memset(sin, 0, sizeof(*sin));
-
-       sin->sin_family = AF_INET;
-       sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-       *salen = sizeof(*sin);
-
-       return 1;
-}
-#endif
 
 /*
  * Plant port number in @sap.  @port is already in network byte order.
@@ -201,7 +174,7 @@ static in_port_t nfs_gp_get_rpcb_port(const unsigned short protocol)
  * client.  Otherwise returns NULL, and rpc_createerr.cf_stat is set to
  * reflect the error.
  */
-static CLIENT *nfs_gp_get_rpcbclient(const struct sockaddr *sap,
+static CLIENT *nfs_gp_get_rpcbclient(struct sockaddr *sap,
                                     const socklen_t salen,
                                     const unsigned short transport,
                                     const rpcvers_t version,
@@ -214,14 +187,10 @@ static CLIENT *nfs_gp_get_rpcbclient(const struct sockaddr *sap,
                "sunrpc",
                NULL,
        };
-       struct sockaddr_storage address;
-       struct sockaddr *saddr = (struct sockaddr *)&address;
        rpcprog_t rpcb_prog = nfs_getrpcbyname(RPCBPROG, rpcb_pgmtbl);
 
-       memcpy(saddr, sap, (size_t)salen);
-       nfs_gp_set_port(saddr, nfs_gp_get_rpcb_port(transport));
-
-       return nfs_get_rpcclient(saddr, salen, transport, rpcb_prog,
+       nfs_gp_set_port(sap, nfs_gp_get_rpcb_port(transport));
+       return nfs_get_rpcclient(sap, salen, transport, rpcb_prog,
                                        version, timeout);
 }
 
@@ -458,10 +427,6 @@ static int nfs_gp_ping(CLIENT *client, struct timeval timeout)
 /*
  * Initialize the rpcb argument for a GETADDR request.
  *
- * The rpcbind daemon ignores the parms.r_owner field in GETADDR
- * requests, but we plant an eye-catcher to help distinguish these
- * requests in network traces.
- *
  * Returns 1 if successful, and caller must free strings pointed
  * to by r_netid and r_addr; otherwise 0.
  */
@@ -489,7 +454,7 @@ static int nfs_gp_init_rpcb_parms(const struct sockaddr *sap,
        parms->r_vers   = version;
        parms->r_netid  = netid;
        parms->r_addr   = addr;
-       parms->r_owner  = "nfs-utils";  /* eye-catcher */
+       parms->r_owner  = "";
 
        return 1;
 }
@@ -667,7 +632,7 @@ static unsigned short nfs_gp_getport(CLIENT *client,
 }
 
 /**
- * nfs_rcp_ping - Determine if RPC service is responding to requests
+ * nfs_rpc_ping - Determine if RPC service is responding to requests
  * @sap: pointer to address of server to query (port is already filled in)
  * @salen: length of server address
  * @program: requested RPC program number
@@ -682,6 +647,8 @@ 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)
 {
+       struct sockaddr_storage address;
+       struct sockaddr *saddr = (struct sockaddr *)&address;
        CLIENT *client;
        struct timeval tout = { -1, 0 };
        int result = 0;
@@ -689,7 +656,9 @@ int nfs_rpc_ping(const struct sockaddr *sap, const socklen_t salen,
        if (timeout != NULL)
                tout = *timeout;
 
-       client = nfs_get_rpcclient(sap, salen, protocol, program, version, &tout);
+       memcpy(saddr, sap, (size_t)salen);
+       client = nfs_get_rpcclient(saddr, salen, protocol,
+                                               program, version, &tout);
        if (client != NULL) {
                result = nfs_gp_ping(client, tout);
                CLNT_DESTROY(client);
@@ -744,14 +713,17 @@ unsigned short nfs_getport(const struct sockaddr *sap,
                           const rpcvers_t version,
                           const unsigned short protocol)
 {
+       struct sockaddr_storage address;
+       struct sockaddr *saddr = (struct sockaddr *)&address;
        struct timeval timeout = { -1, 0 };
        unsigned short port = 0;
        CLIENT *client;
 
-       client = nfs_gp_get_rpcbclient(sap, salen, protocol,
+       memcpy(saddr, sap, (size_t)salen);
+       client = nfs_gp_get_rpcbclient(saddr, salen, protocol,
                                                default_rpcb_version, &timeout);
        if (client != NULL) {
-               port = nfs_gp_getport(client, sap, salen, program,
+               port = nfs_gp_getport(client, saddr, salen, program,
                                        version, protocol, timeout);
                CLNT_DESTROY(client);
        }
@@ -840,13 +812,6 @@ int nfs_getport_ping(struct sockaddr *sap, const socklen_t salen,
  * isn't listening on /var/run/rpcbind.sock), send a query via UDP to localhost
  * (UDP doesn't leave a socket in TIME_WAIT, and the timeout is a relatively
  * short 3 seconds).
- *
- * getaddrinfo(3) generates a usable loopback address.  RFC 3484 requires that
- * the results are sorted so that the first result has the best likelihood of
- * working, so we try just that first result.  If IPv6 is all that is
- * available, we are sure to generate an AF_INET6 loopback address and use
- * rpcbindv4/v3 GETADDR.  AF_INET6 requests go via rpcbind v4/3 in order to
- * detect if the requested RPC service supports AF_INET6 or not.
  */
 unsigned short nfs_getlocalport(const rpcprot_t program,
                                const rpcvers_t version,
@@ -934,6 +899,8 @@ unsigned short nfs_rpcb_getaddr(const struct sockaddr *sap,
                                const unsigned short protocol,
                                const struct timeval *timeout)
 {
+       struct sockaddr_storage address;
+       struct sockaddr *saddr = (struct sockaddr *)&address;
        CLIENT *client;
        struct rpcb parms;
        struct timeval tout = { -1, 0 };
@@ -942,7 +909,9 @@ unsigned short nfs_rpcb_getaddr(const struct sockaddr *sap,
        if (timeout != NULL)
                tout = *timeout;
 
-       client = nfs_gp_get_rpcbclient(sap, salen, transport, RPCBVERS_4, &tout);
+       memcpy(saddr, sap, (size_t)salen);
+       client = nfs_gp_get_rpcbclient(saddr, salen, transport,
+                                                       RPCBVERS_4, &tout);
        if (client != NULL) {
                if (nfs_gp_init_rpcb_parms(addr, addrlen, program, version,
                                                protocol, &parms) != 0) {
@@ -1008,6 +977,8 @@ unsigned long nfs_pmap_getport(const struct sockaddr_in *sin,
                               const unsigned long protocol,
                               const struct timeval *timeout)
 {
+       struct sockaddr_in address;
+       struct sockaddr *saddr = (struct sockaddr *)&address;
        CLIENT *client;
        struct pmap parms = {
                .pm_prog        = program,
@@ -1020,8 +991,8 @@ unsigned long nfs_pmap_getport(const struct sockaddr_in *sin,
        if (timeout != NULL)
                tout = *timeout;
 
-       client = nfs_gp_get_rpcbclient((struct sockaddr *)sin,
-                                       (socklen_t)sizeof(*sin),
+       memcpy(saddr, sin, sizeof(address));
+       client = nfs_gp_get_rpcbclient(saddr, (socklen_t)sizeof(*sin),
                                        transport, PMAPVERS, &tout);
        if (client != NULL) {
                port = nfs_gp_pmap_getport(client, &parms, tout);