aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuanJo Ciarlante <jjo@google.com>2009-09-19 21:36:46 +0200
committerJuanJo Ciarlante <juanjosec@gmail.com>2011-03-25 13:30:29 +0100
commitb7f203c8cfd2c0e412afd6f5ca0aa4eb62a031d2 (patch)
tree4d47ccfacf956e6c99b40aacc4ea28a97f1f29cc
parent* fixed win32 non-ipv6 build (diff)
downloadopenvpn-b7f203c8cfd2c0e412afd6f5ca0aa4eb62a031d2.tar.xz
* ipv6 on win32 "milestone": 1st snapshot that passes all unittests
-rw-r--r--socket.c95
-rw-r--r--socket.h2
-rw-r--r--syshead.h7
-rw-r--r--win32.h5
4 files changed, 98 insertions, 11 deletions
diff --git a/socket.c b/socket.c
index 3340314..3024ea4 100644
--- 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);
}
diff --git a/socket.h b/socket.h
index def8104..092d448 100644
--- 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;
diff --git a/syshead.h b/syshead.h
index 30ff556..d589531 100644
--- a/syshead.h
+++ b/syshead.h
@@ -28,6 +28,10 @@
/*
* 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
@@ -339,6 +343,9 @@
#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 fcc3062..6184206 100644
--- 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;