You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Jeff Trawick <tr...@bellsouth.net> on 2000/11/16 14:25:38 UTC

[PATCH] add apr_create_socket(), some additional IPv6 support

This adds apr_inet_ntop(), apr_inet_pton(), apr_create_socket(), and
fixes apr_get_ipaddr() to be thread-safe and to support IPv6.

apr_create_socket() supports the AF_UNSPEC idiom outlined in my last
post which means get AF_INET6 if you can but fall back to AF_INET
because I don't really care.

concerns?

? network_io/unix/inet_ntop.c
? network_io/unix/inet_pton.c
Index: include/apr_network_io.h
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/lib/apr/include/apr_network_io.h,v
retrieving revision 1.70
diff -u -r1.70 apr_network_io.h
--- include/apr_network_io.h	2000/11/16 01:51:33	1.70
+++ include/apr_network_io.h	2000/11/16 13:23:23
@@ -199,6 +199,9 @@
  */
 apr_status_t apr_create_tcp_socket(apr_socket_t **new_sock, apr_pool_t *cont);
 
+apr_status_t apr_create_socket(apr_socket_t **new_sock, int family,
+                               int type, apr_pool_t *cont);
+
 /**
  * Shutdown either reading, writing, or both sides of a tcp socket.
  * @param thesocket The socket to close 
Index: include/arch/unix/networkio.h
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/lib/apr/include/arch/unix/networkio.h,v
retrieving revision 1.34
diff -u -r1.34 networkio.h
--- include/arch/unix/networkio.h	2000/11/16 01:51:34	1.34
+++ include/arch/unix/networkio.h	2000/11/16 13:23:23
@@ -149,5 +149,8 @@
 
 };
 
+const char *apr_inet_ntop(int af, const void *src, char *dst, apr_size_t size);
+int apr_inet_pton(int af, const char *src, void *dst);
+
 #endif  /* ! NETWORK_IO_H */
 
Index: network_io/unix/Makefile.in
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/lib/apr/network_io/unix/Makefile.in,v
retrieving revision 1.20
diff -u -r1.20 Makefile.in
--- network_io/unix/Makefile.in	2000/11/15 11:50:06	1.20
+++ network_io/unix/Makefile.in	2000/11/16 13:23:23
@@ -16,7 +16,9 @@
 	sendrecv.o \
 	sockets.o \
 	sockopt.o \
-	sockaddr.o
+	sockaddr.o \
+	inet_ntop.o \
+	inet_pton.o
 
 .c.o:
 	$(CC) $(CFLAGS) -c $(INCLUDES) $<
Index: network_io/unix/sa_common.c
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/lib/apr/network_io/unix/sa_common.c,v
retrieving revision 1.5
diff -u -r1.5 sa_common.c
--- network_io/unix/sa_common.c	2000/11/16 01:51:35	1.5
+++ network_io/unix/sa_common.c	2000/11/16 13:23:23
@@ -68,7 +68,7 @@
 apr_status_t apr_set_port(apr_socket_t *sock, apr_interface_e which, 
                          apr_port_t port)
 {
-        /* XXX IPv6 */
+    /* XXX IPv6: assumes sin_port and sin6_port at same offset */
     if (which == APR_LOCAL)
         sock->local_addr->sa.sin.sin_port = htons(port);
     else if (which == APR_REMOTE)
@@ -80,6 +80,7 @@
 
 apr_status_t apr_get_port(apr_port_t *port, apr_interface_e which, apr_socket_t *sock)
 {
+    /* XXX IPv6: assumes sin_port and sin6_port at same offset */
     if (which == APR_LOCAL)
     {
         if (sock->local_port_unknown) {
@@ -89,8 +90,6 @@
                 return rv;
             }
         }
-
-        /* XXX IPv6 */
         *port = ntohs(sock->local_addr->sa.sin.sin_port);
     } else if (which == APR_REMOTE)
         *port = ntohs(sock->remote_addr->sa.sin.sin_port);
@@ -101,7 +100,7 @@
 
 apr_status_t apr_get_ipaddr(char **addr, apr_interface_e which, apr_socket_t *sock)
 {
-    if (which == APR_LOCAL){
+    if (which == APR_LOCAL) {
         if (sock->local_interface_unknown) {
             apr_status_t rv = get_local_addr(sock);
 
@@ -109,11 +108,19 @@
                 return rv;
             }
         }
-        /* XXX IPv6 */
-        *addr = apr_pstrdup(sock->cntxt, inet_ntoa(sock->local_addr->sa.sin.sin_addr));
-    } else if (which == APR_REMOTE)
-        /* XXX IPv6 */
-        *addr = apr_pstrdup(sock->cntxt, inet_ntoa(sock->remote_addr->sa.sin.sin_addr));
+        *addr = apr_palloc(sock->cntxt, sock->local_addr->addr_str_len);
+        apr_inet_ntop(sock->local_addr->sa.sin.sin_family,
+                      sock->local_addr->ipaddr_ptr,
+                      *addr,
+                      sock->local_addr->addr_str_len);
+    } 
+    else if (which == APR_REMOTE) {
+        *addr = apr_palloc(sock->cntxt, sock->remote_addr->addr_str_len);
+        apr_inet_ntop(sock->remote_addr->sa.sin.sin_family,
+                      sock->remote_addr->ipaddr_ptr,
+                      *addr,
+                      sock->remote_addr->addr_str_len);
+    }
     else 
         return APR_EINVAL;
 
Index: network_io/unix/sockets.c
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/lib/apr/network_io/unix/sockets.c,v
retrieving revision 1.55
diff -u -r1.55 sockets.c
--- network_io/unix/sockets.c	2000/11/16 01:51:35	1.55
+++ network_io/unix/sockets.c	2000/11/16 13:23:24
@@ -107,19 +107,33 @@
                                                         sizeof(apr_sockaddr_t));
 }
 
-apr_status_t apr_create_tcp_socket(apr_socket_t **new, apr_pool_t *cont)
+apr_status_t apr_create_socket(apr_socket_t **new, int ofamily, int type,
+                               apr_pool_t *cont)
 {
-    int family = AF_INET;
-    int proto = IPPROTO_TCP;
-    int type = SOCK_STREAM;
+    int family = ofamily;
+
+    if (family == AF_UNSPEC) {
+#if APR_HAVE_IPV6
+        family = AF_INET6;
+#else
+        family = AF_INET;
+#endif
+    }
 
     alloc_socket(new, cont);
 
     if ((*new)->local_addr == NULL || (*new)->remote_addr == NULL) {
         return APR_ENOMEM;
     }
+
+    (*new)->socketdes = socket(family, type, 0);
 
-    (*new)->socketdes = socket(family, type, proto);
+#if APR_HAVE_IPV6
+    if ((*new)->socketdes < 0 && ofamily == AF_UNSPEC) {
+        family = AF_INET;
+        (*new)->socketdes = socket(family, type, 0);
+    }
+#endif
 
     if ((*new)->socketdes < 0) {
         return errno;
@@ -131,6 +145,11 @@
                         socket_cleanup, apr_null_cleanup);
     return APR_SUCCESS;
 } 
+
+apr_status_t apr_create_tcp_socket(apr_socket_t **new, apr_pool_t *cont)
+{
+    return apr_create_socket(new, AF_INET, SOCK_STREAM, cont);
+}
 
 apr_status_t apr_shutdown(apr_socket_t *thesocket, apr_shutdown_how_e how)
 {
Index: test/server.c
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/lib/apr/test/server.c,v
retrieving revision 1.16
diff -u -r1.16 server.c
--- test/server.c	2000/11/09 15:01:35	1.16
+++ test/server.c	2000/11/16 13:23:24
@@ -88,7 +88,7 @@
     fprintf(stdout, "OK\n");
 
     fprintf(stdout, "\tServer:  Creating new socket.......");
-    if (apr_create_tcp_socket(&sock, context) != APR_SUCCESS) {
+    if (apr_create_socket(&sock, AF_UNSPEC, SOCK_STREAM, context) != APR_SUCCESS) {
         fprintf(stderr, "Couldn't create socket\n");
         exit(-1);
     }
@@ -127,7 +127,7 @@
     fprintf(stdout, "OK\n");
     
     fprintf(stdout, "\tServer:  Listening to socket.......");
-    if (apr_listen(sock, 8021) != APR_SUCCESS) {
+    if (apr_listen(sock, 5) != APR_SUCCESS) {
         apr_close_socket(sock);
         fprintf(stderr, "Could not listen\n");
         exit(-1);


-- 
Jeff Trawick | trawick@ibm.net | PGP public key at web site:
     http://www.geocities.com/SiliconValley/Park/9289/
          Born in Roswell... married an alien...

Re: [PATCH] add apr_create_socket(), some additional IPv6 support

Posted by David Reid <dr...@jetnet.co.uk>.
+1 from me.

----- Original Message -----
From: "Jeff Trawick" <tr...@bellsouth.net>
To: <de...@apr.apache.org>
Sent: Thursday, November 16, 2000 1:25 PM
Subject: [PATCH] add apr_create_socket(), some additional IPv6 support


> This adds apr_inet_ntop(), apr_inet_pton(), apr_create_socket(), and
> fixes apr_get_ipaddr() to be thread-safe and to support IPv6.
>
> apr_create_socket() supports the AF_UNSPEC idiom outlined in my last
> post which means get AF_INET6 if you can but fall back to AF_INET
> because I don't really care.
>
> concerns?
>
> ? network_io/unix/inet_ntop.c
> ? network_io/unix/inet_pton.c
> Index: include/apr_network_io.h
> ===================================================================
> RCS file:
/home/cvspublic/apache-2.0/src/lib/apr/include/apr_network_io.h,v
> retrieving revision 1.70
> diff -u -r1.70 apr_network_io.h
> --- include/apr_network_io.h 2000/11/16 01:51:33 1.70
> +++ include/apr_network_io.h 2000/11/16 13:23:23
> @@ -199,6 +199,9 @@
>   */
>  apr_status_t apr_create_tcp_socket(apr_socket_t **new_sock, apr_pool_t
*cont);
>
> +apr_status_t apr_create_socket(apr_socket_t **new_sock, int family,
> +                               int type, apr_pool_t *cont);
> +
>  /**
>   * Shutdown either reading, writing, or both sides of a tcp socket.
>   * @param thesocket The socket to close
> Index: include/arch/unix/networkio.h
> ===================================================================
> RCS file:
/home/cvspublic/apache-2.0/src/lib/apr/include/arch/unix/networkio.h,v
> retrieving revision 1.34
> diff -u -r1.34 networkio.h
> --- include/arch/unix/networkio.h 2000/11/16 01:51:34 1.34
> +++ include/arch/unix/networkio.h 2000/11/16 13:23:23
> @@ -149,5 +149,8 @@
>
>  };
>
> +const char *apr_inet_ntop(int af, const void *src, char *dst, apr_size_t
size);
> +int apr_inet_pton(int af, const char *src, void *dst);
> +
>  #endif  /* ! NETWORK_IO_H */
>
> Index: network_io/unix/Makefile.in
> ===================================================================
> RCS file:
/home/cvspublic/apache-2.0/src/lib/apr/network_io/unix/Makefile.in,v
> retrieving revision 1.20
> diff -u -r1.20 Makefile.in
> --- network_io/unix/Makefile.in 2000/11/15 11:50:06 1.20
> +++ network_io/unix/Makefile.in 2000/11/16 13:23:23
> @@ -16,7 +16,9 @@
>   sendrecv.o \
>   sockets.o \
>   sockopt.o \
> - sockaddr.o
> + sockaddr.o \
> + inet_ntop.o \
> + inet_pton.o
>
>  .c.o:
>   $(CC) $(CFLAGS) -c $(INCLUDES) $<
> Index: network_io/unix/sa_common.c
> ===================================================================
> RCS file:
/home/cvspublic/apache-2.0/src/lib/apr/network_io/unix/sa_common.c,v
> retrieving revision 1.5
> diff -u -r1.5 sa_common.c
> --- network_io/unix/sa_common.c 2000/11/16 01:51:35 1.5
> +++ network_io/unix/sa_common.c 2000/11/16 13:23:23
> @@ -68,7 +68,7 @@
>  apr_status_t apr_set_port(apr_socket_t *sock, apr_interface_e which,
>                           apr_port_t port)
>  {
> -        /* XXX IPv6 */
> +    /* XXX IPv6: assumes sin_port and sin6_port at same offset */
>      if (which == APR_LOCAL)
>          sock->local_addr->sa.sin.sin_port = htons(port);
>      else if (which == APR_REMOTE)
> @@ -80,6 +80,7 @@
>
>  apr_status_t apr_get_port(apr_port_t *port, apr_interface_e which,
apr_socket_t *sock)
>  {
> +    /* XXX IPv6: assumes sin_port and sin6_port at same offset */
>      if (which == APR_LOCAL)
>      {
>          if (sock->local_port_unknown) {
> @@ -89,8 +90,6 @@
>                  return rv;
>              }
>          }
> -
> -        /* XXX IPv6 */
>          *port = ntohs(sock->local_addr->sa.sin.sin_port);
>      } else if (which == APR_REMOTE)
>          *port = ntohs(sock->remote_addr->sa.sin.sin_port);
> @@ -101,7 +100,7 @@
>
>  apr_status_t apr_get_ipaddr(char **addr, apr_interface_e which,
apr_socket_t *sock)
>  {
> -    if (which == APR_LOCAL){
> +    if (which == APR_LOCAL) {
>          if (sock->local_interface_unknown) {
>              apr_status_t rv = get_local_addr(sock);
>
> @@ -109,11 +108,19 @@
>                  return rv;
>              }
>          }
> -        /* XXX IPv6 */
> -        *addr = apr_pstrdup(sock->cntxt,
inet_ntoa(sock->local_addr->sa.sin.sin_addr));
> -    } else if (which == APR_REMOTE)
> -        /* XXX IPv6 */
> -        *addr = apr_pstrdup(sock->cntxt,
inet_ntoa(sock->remote_addr->sa.sin.sin_addr));
> +        *addr = apr_palloc(sock->cntxt, sock->local_addr->addr_str_len);
> +        apr_inet_ntop(sock->local_addr->sa.sin.sin_family,
> +                      sock->local_addr->ipaddr_ptr,
> +                      *addr,
> +                      sock->local_addr->addr_str_len);
> +    }
> +    else if (which == APR_REMOTE) {
> +        *addr = apr_palloc(sock->cntxt, sock->remote_addr->addr_str_len);
> +        apr_inet_ntop(sock->remote_addr->sa.sin.sin_family,
> +                      sock->remote_addr->ipaddr_ptr,
> +                      *addr,
> +                      sock->remote_addr->addr_str_len);
> +    }
>      else
>          return APR_EINVAL;
>
> Index: network_io/unix/sockets.c
> ===================================================================
> RCS file:
/home/cvspublic/apache-2.0/src/lib/apr/network_io/unix/sockets.c,v
> retrieving revision 1.55
> diff -u -r1.55 sockets.c
> --- network_io/unix/sockets.c 2000/11/16 01:51:35 1.55
> +++ network_io/unix/sockets.c 2000/11/16 13:23:24
> @@ -107,19 +107,33 @@
>
sizeof(apr_sockaddr_t));
>  }
>
> -apr_status_t apr_create_tcp_socket(apr_socket_t **new, apr_pool_t *cont)
> +apr_status_t apr_create_socket(apr_socket_t **new, int ofamily, int type,
> +                               apr_pool_t *cont)
>  {
> -    int family = AF_INET;
> -    int proto = IPPROTO_TCP;
> -    int type = SOCK_STREAM;
> +    int family = ofamily;
> +
> +    if (family == AF_UNSPEC) {
> +#if APR_HAVE_IPV6
> +        family = AF_INET6;
> +#else
> +        family = AF_INET;
> +#endif
> +    }
>
>      alloc_socket(new, cont);
>
>      if ((*new)->local_addr == NULL || (*new)->remote_addr == NULL) {
>          return APR_ENOMEM;
>      }
> +
> +    (*new)->socketdes = socket(family, type, 0);
>
> -    (*new)->socketdes = socket(family, type, proto);
> +#if APR_HAVE_IPV6
> +    if ((*new)->socketdes < 0 && ofamily == AF_UNSPEC) {
> +        family = AF_INET;
> +        (*new)->socketdes = socket(family, type, 0);
> +    }
> +#endif
>
>      if ((*new)->socketdes < 0) {
>          return errno;
> @@ -131,6 +145,11 @@
>                          socket_cleanup, apr_null_cleanup);
>      return APR_SUCCESS;
>  }
> +
> +apr_status_t apr_create_tcp_socket(apr_socket_t **new, apr_pool_t *cont)
> +{
> +    return apr_create_socket(new, AF_INET, SOCK_STREAM, cont);
> +}
>
>  apr_status_t apr_shutdown(apr_socket_t *thesocket, apr_shutdown_how_e
how)
>  {
> Index: test/server.c
> ===================================================================
> RCS file: /home/cvspublic/apache-2.0/src/lib/apr/test/server.c,v
> retrieving revision 1.16
> diff -u -r1.16 server.c
> --- test/server.c 2000/11/09 15:01:35 1.16
> +++ test/server.c 2000/11/16 13:23:24
> @@ -88,7 +88,7 @@
>      fprintf(stdout, "OK\n");
>
>      fprintf(stdout, "\tServer:  Creating new socket.......");
> -    if (apr_create_tcp_socket(&sock, context) != APR_SUCCESS) {
> +    if (apr_create_socket(&sock, AF_UNSPEC, SOCK_STREAM, context) !=
APR_SUCCESS) {
>          fprintf(stderr, "Couldn't create socket\n");
>          exit(-1);
>      }
> @@ -127,7 +127,7 @@
>      fprintf(stdout, "OK\n");
>
>      fprintf(stdout, "\tServer:  Listening to socket.......");
> -    if (apr_listen(sock, 8021) != APR_SUCCESS) {
> +    if (apr_listen(sock, 5) != APR_SUCCESS) {
>          apr_close_socket(sock);
>          fprintf(stderr, "Could not listen\n");
>          exit(-1);
>
>
> --
> Jeff Trawick | trawick@ibm.net | PGP public key at web site:
>      http://www.geocities.com/SiliconValley/Park/9289/
>           Born in Roswell... married an alien...
>