]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
* ipv6 on win32 "milestone": 1st snapshot that passes all unittests
authorJuanJo Ciarlante <jjo@google.com>
Sat, 19 Sep 2009 19:36:46 +0000 (21:36 +0200)
committerJuanJo Ciarlante <juanjosec@gmail.com>
Fri, 25 Mar 2011 12:30:29 +0000 (13:30 +0100)
socket.c
socket.h
syshead.h
win32.h

index 3340314f9b40bcea5c93bb355f5eea70cc40d4ab..3024ea4e96cc08cd5b86e6551d151bdb9b027260 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -2993,11 +2993,19 @@ socket_recv_queue (struct link_socket *sock, int maxsize)
       int status;
 
       /* reset buf to its initial state */
-      if (sock->info.proto == PROTO_UDPv4)
+      if (sock->info.proto == PROTO_UDPv4
+#ifdef USE_PF_INET6
+          || sock->info.proto == PROTO_UDPv6
+#endif
+        )
        {
          sock->reads.buf = sock->reads.buf_init;
        }
-      else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER)
+      else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER
+#ifdef USE_PF_INET6
+              || sock->info.proto == PROTO_TCPv6_CLIENT || sock->info.proto == PROTO_TCPv6_SERVER
+#endif
+              )
        {
          stream_buf_get_next (&sock->stream_buf, &sock->reads.buf);
        }
@@ -3017,10 +3025,19 @@ socket_recv_queue (struct link_socket *sock, int maxsize)
       ASSERT (ResetEvent (sock->reads.overlapped.hEvent));
       sock->reads.flags = 0;
 
-      if (sock->info.proto == PROTO_UDPv4)
+      if (sock->info.proto == PROTO_UDPv4
+#ifdef USE_PF_INET6
+          || sock->info.proto == PROTO_UDPv6
+#endif
+         )
        {
          sock->reads.addr_defined = true;
-         sock->reads.addrlen = sizeof (sock->reads.addr);
+#ifdef USE_PF_INET6
+         if (sock->info.proto == PROTO_UDPv6)
+           sock->reads.addrlen = sizeof (sock->reads.addr6);
+         else
+#endif
+           sock->reads.addrlen = sizeof (sock->reads.addr);
          status = WSARecvFrom(
                               sock->sd,
                               wsabuf,
@@ -3032,7 +3049,12 @@ socket_recv_queue (struct link_socket *sock, int maxsize)
                               &sock->reads.overlapped,
                               NULL);
        }
-      else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER)
+      else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER
+#ifdef USE_PF_INET6
+              || sock->info.proto == PROTO_TCPv6_CLIENT || sock->info.proto == PROTO_TCPv6_SERVER
+#endif
+              )
+
        {
          sock->reads.addr_defined = false;
          status = WSARecv(
@@ -3052,8 +3074,14 @@ socket_recv_queue (struct link_socket *sock, int maxsize)
 
       if (!status) /* operation completed immediately? */
        {
+#ifdef USE_PF_INET6
+         int addrlen = af_addr_size(sock->info.lsa->local.addr.sa.sa_family);
+         if (sock->reads.addr_defined && sock->reads.addrlen != addrlen)
+           bad_address_length (sock->reads.addrlen, addrlen);
+#else
          if (sock->reads.addr_defined && sock->reads.addrlen != sizeof (sock->reads.addr))
            bad_address_length (sock->reads.addrlen, sizeof (sock->reads.addr));
+#endif
 
          sock->reads.iostate = IOSTATE_IMMEDIATE_RETURN;
 
@@ -3112,12 +3140,26 @@ socket_send_queue (struct link_socket *sock, struct buffer *buf, const struct li
       ASSERT (ResetEvent (sock->writes.overlapped.hEvent));
       sock->writes.flags = 0;
 
-      if (sock->info.proto == PROTO_UDPv4)
+      if (sock->info.proto == PROTO_UDPv4
+#ifdef USE_PF_INET6
+         || sock->info.proto == PROTO_UDPv6
+#endif
+        )
        {
          /* set destination address for UDP writes */
          sock->writes.addr_defined = true;
-         sock->writes.addr = to->dest.addr.in4;
-         sock->writes.addrlen = sizeof (sock->writes.addr);
+#ifdef USE_PF_INET6
+         if (sock->info.proto == PROTO_UDPv6)
+           {
+             sock->writes.addr6 = to->dest.addr.in6;
+             sock->writes.addrlen = sizeof (sock->writes.addr6);
+           }
+         else
+#endif
+           {
+             sock->writes.addr = to->dest.addr.in4;
+             sock->writes.addrlen = sizeof (sock->writes.addr);
+           }
 
          status = WSASendTo(
                               sock->sd,
@@ -3130,7 +3172,11 @@ socket_send_queue (struct link_socket *sock, struct buffer *buf, const struct li
                               &sock->writes.overlapped,
                               NULL);
        }
-      else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER)
+      else if (sock->info.proto == PROTO_TCPv4_CLIENT || sock->info.proto == PROTO_TCPv4_SERVER
+#ifdef USE_PF_INET6
+              || sock->info.proto == PROTO_TCPv6_CLIENT || sock->info.proto == PROTO_TCPv6_SERVER
+#endif
+             )
        {
          /* destination address for TCP writes was established on connection initiation */
          sock->writes.addr_defined = false;
@@ -3269,11 +3315,42 @@ socket_finalize (SOCKET s,
   if (from)
     {
       if (ret >= 0 && io->addr_defined)
+#ifdef USE_PF_INET6
+       {
+         /* TODO(jjo): streamline this mess */
+         /* in this func we dont have relevant info about the PF_ of this
+          * endpoint, as link_socket_actual will be zero for the 1st received packet
+          *
+          * Test for inets PF_ possible sizes
+          */
+         switch (io->addrlen)
+           {
+           case sizeof(struct sockaddr_in):
+           case sizeof(struct sockaddr_in6):
+           /* TODO(jjo): for some reason (?) I'm getting 24,28 for AF_INET6 */ 
+           case sizeof(struct sockaddr_in6)-4:
+             break;
+           default:
+             bad_address_length (io->addrlen, af_addr_size(io->addr.sin_family));
+           }
+
+         switch (io->addr.sin_family)
+           {
+           case AF_INET:
+             from->dest.addr.in4 = io->addr;
+             break;
+           case AF_INET6:
+             from->dest.addr.in6 = io->addr6;
+             break;
+           }
+       }
+#else
        {
          if (io->addrlen != sizeof (io->addr))
            bad_address_length (io->addrlen, sizeof (io->addr));
          from->dest.addr.in4 = io->addr;
        }
+#endif
       else
        CLEAR (from->dest.addr);
     }
index def8104e7b48be7d6725bc2b31072417dd2ff752..092d448fbd5dc0a4d4c02a0747c0b4998be2bd36 100644 (file)
--- a/socket.h
+++ b/socket.h
@@ -717,7 +717,7 @@ af_addr_size(unsigned short af)
      default: 
 #if 0
       /* could be called from socket_do_accept() with empty addr */
-      msg (M_ERR, "Bad address family: %d\n", addr->sa_family);
+      msg (M_ERR, "Bad address family: %d\n", af);
       ASSERT(0);
 #endif
        return 0;
index 30ff5561edf169c9fc6e9e674a7a87c0ef34e06a..d589531080159761ccb4f1623f5127375435b702 100644 (file)
--- a/syshead.h
+++ b/syshead.h
 /*
  * Only include if not during configure
  */
+#ifdef WIN32
+/* USE_PF_INET6: win32 ipv6 exists only after 0x0501 (XP) */
+#define WINVER 0x0501
+#endif
 #ifndef PACKAGE_NAME
 #include "config.h"
 #endif
 #ifdef WIN32
 #include <iphlpapi.h>
 #include <wininet.h>
+/* The following two headers are needed of USE_PF_INET6 */
+#include <winsock2.h>
+#include <ws2tcpip.h>
 #endif
 
 #ifdef HAVE_SYS_MMAN_H
diff --git a/win32.h b/win32.h
index fcc3062dfcc316da0320d3d50b30c29c857c3874..6184206e8cabdb03917570304203422a95e4b3d1 100644 (file)
--- a/win32.h
+++ b/win32.h
@@ -195,7 +195,10 @@ struct overlapped_io {
   DWORD flags;
   int status;
   bool addr_defined;
-  struct sockaddr_in addr;
+  union {
+    struct sockaddr_in addr;
+    struct sockaddr_in6 addr6;
+  };
   int addrlen;
   struct buffer buf_init;
   struct buffer buf;