The get_socket() function is the heart of util/mount/network.c.  Change
the function's signature to accept a "struct sockaddr *", and add support
for AF_INET6 addresses inside get_socket().

Signed-off-by: Chuck Lever <[EMAIL PROTECTED]>
---

 utils/mount/network.c |  109 ++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 80 insertions(+), 29 deletions(-)

diff --git a/utils/mount/network.c b/utils/mount/network.c
index 5720a4e..ee8aa28 100644
--- a/utils/mount/network.c
+++ b/utils/mount/network.c
@@ -254,6 +254,49 @@ static int __nfs_gs_err_connect(const int socket, const 
struct sockaddr *saddr,
        return __nfs_gs_err_done(error);
 }
 
+static void __nfs_gs_init_any_ipv4(struct sockaddr *sap, socklen_t *len)
+{
+       struct sockaddr_in *sin = (struct sockaddr_in *)sap;
+
+       sin->sin_family = AF_INET;
+       sin->sin_addr.s_addr = htonl(INADDR_ANY);
+       sin->sin_port = 0;
+
+       *len = sizeof(struct sockaddr_in);
+}
+
+#ifdef IPV6_SUPPORTED
+static void __nfs_gs_init_any_ipv6(struct sockaddr *sap, socklen_t *len)
+{
+       struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
+
+       sin6->sin6_family = AF_INET6;
+       sin6->sin6_addr = in6addr_any;
+       sin6->sin6_port = 0;
+
+       *len = sizeof(struct sockaddr_in6);
+}
+
+static void __nfs_gs_init_any_address(const sa_family_t family,
+                                       struct sockaddr *sap, socklen_t *len)
+{
+       *len = 0;
+
+       switch (family) {
+       case AF_INET:
+               __nfs_gs_init_any_ipv4(sap, len);
+       case AF_INET6:
+               __nfs_gs_init_any_ipv6(sap, len);
+       }
+}
+#else
+static void __nfs_gs_init_any_address(const sa_family_t family,
+                                       struct sockaddr *sap, socklen_t *len)
+{
+       __nfs_gs_init_any_ipv4(sap, len);
+}
+#endif
+
 #ifdef IPV6_SUPPORTED
 static int __nfs_bindresvport(const int socket, struct sockaddr *sap)
 {
@@ -326,35 +369,40 @@ out:
 /*
  * Create a socket that is locally bound to a reserved or non-reserved port.
  *
- * The caller should check rpc_createerr to determine the cause of any error.
+ * Returns a positive integer representing a freshly created socket
+ * file descriptor, or the value RPC_ANYSOCK if an error occurs.  The caller
+ * should check rpc_createerr to determine the cause of the error.
  */
-static int get_socket(struct sockaddr_in *saddr, unsigned int p_prot,
-                       time_t timeout, int resvp, int conn)
+static int nfs_getsocket(const struct sockaddr *saddr,
+                               const unsigned short protocol,
+                               const time_t timeout,
+                               const int resvp, const int conn)
 {
-       int so, type;
-       struct sockaddr_in laddr;
-       socklen_t namelen = sizeof(laddr);
+       struct sockaddr_in6 dummy;
+       struct sockaddr *any_addr = (struct sockaddr *)&dummy;
+       socklen_t addrlen;
+       int type = (protocol == IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM;
+       int so;
+
+       /* Use address family and protocol family interchangeably */
+       so = socket(saddr->sa_family, type, protocol);
+       if (so < 0)
+               return __nfs_gs_err_socket(protocol, errno);
 
-       type = (p_prot == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM);
-       if ((so = socket(AF_INET, type, p_prot)) < 0)
-               return __nfs_gs_err_socket(p_prot, errno);
+       __nfs_gs_init_any_address(saddr->sa_family, any_addr, &addrlen);
 
-       laddr.sin_family = AF_INET;
-       laddr.sin_port = 0;
-       laddr.sin_addr.s_addr = htonl(INADDR_ANY);
        if (resvp) {
-               if (__nfs_bindresvport(so, (struct sockaddr *)&laddr) < 0)
-                       return __nfs_gs_err_bindresvport(so, p_prot, errno);
-       } else {
-               if (bind(so, (struct sockaddr *)&laddr, namelen) < 0)
-                       return __nfs_gs_err_bind(so, p_prot, errno);
-       }
-       if (type == SOCK_STREAM || conn) {
-               if (__nfs_gs_connect_with_timeout(so, (struct sockaddr *)saddr,
-                                                       namelen, timeout) < 0)
-                       return __nfs_gs_err_connect(so, (struct sockaddr 
*)saddr,
-                                                       errno);
-       }
+               if (__nfs_bindresvport(so, any_addr) < 0)
+                       return __nfs_gs_err_bindresvport(so, protocol, errno);
+       } else
+               if (bind(so, any_addr, addrlen) < 0)
+                       return __nfs_gs_err_bind(so, protocol, errno);
+
+       if (type == SOCK_STREAM || conn)
+               if (__nfs_gs_connect_with_timeout(so, saddr, addrlen,
+                                                               timeout) < 0)
+                       return __nfs_gs_err_connect(so, saddr, errno);
+
        return so;
 }
 
@@ -381,7 +429,8 @@ static unsigned short getport(struct sockaddr_in *saddr,
        bind_saddr = *saddr;
        bind_saddr.sin_port = htons(PMAPPORT);
 
-       socket = get_socket(&bind_saddr, proto, PMAP_TIMEOUT, FALSE, FALSE);
+       socket = nfs_getsocket((struct sockaddr *)&bind_saddr, proto,
+                               PMAP_TIMEOUT, FALSE, FALSE);
        if (socket == RPC_ANYSOCK) {
                if (proto == IPPROTO_TCP &&
                    rpc_createerr.cf_error.re_errno == ETIMEDOUT)
@@ -674,8 +723,8 @@ CLIENT *mnt_openclnt(clnt_addr_t *mnt_server, int *msock)
        CLIENT *clnt = NULL;
 
        mnt_saddr->sin_port = htons((u_short)mnt_pmap->pm_port);
-       *msock = get_socket(mnt_saddr, mnt_pmap->pm_prot, MOUNT_TIMEOUT,
-                               TRUE, FALSE);
+       *msock = nfs_getsocket((struct sockaddr *)mnt_saddr, mnt_pmap->pm_prot,
+                               MOUNT_TIMEOUT, TRUE, FALSE);
        if (*msock == RPC_ANYSOCK) {
                if (rpc_createerr.cf_error.re_errno == EADDRINUSE)
                        /*
@@ -750,7 +799,8 @@ int clnt_ping(struct sockaddr_in *saddr, const unsigned 
long prog,
        struct sockaddr dissolve;
 
        rpc_createerr.cf_stat = stat = 0;
-       sock = get_socket(saddr, prot, CONNECT_TIMEOUT, FALSE, TRUE);
+       sock = nfs_getsocket((struct sockaddr *)saddr, prot,
+                               CONNECT_TIMEOUT, FALSE, TRUE);
        if (sock == RPC_ANYSOCK) {
                if (rpc_createerr.cf_error.re_errno == ETIMEDOUT) {
                        /*
@@ -827,7 +877,8 @@ int get_client_address(struct sockaddr_in *saddr, struct 
sockaddr_in *caddr)
        socklen_t len = sizeof(*caddr);
        int socket, err;
 
-       socket = get_socket(saddr, IPPROTO_UDP, CONNECT_TIMEOUT, FALSE, TRUE);
+       socket = nfs_getsocket((struct sockaddr *)saddr, IPPROTO_UDP,
+                               CONNECT_TIMEOUT, FALSE, TRUE);
        if (socket == RPC_ANYSOCK)
                return 0;
 

-
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to