[Openvpn-devel] [PATCH] Implement --mssfix handling for IPv6 packets.

2012-12-02 Thread Gert Doering
Rename process_ipv4_header() to process_ip_header() and PIPV4_MSSFIX
flag to PIP_MSSFIX, to make visible that it's no longer IPv4-only.

Inside process_ip_header(), call out to mss_fixup_ipv6() if --mssfix
is active and IPv6 packet seen.

Rename mss_fixup() to mss_fixup_ipv4(), implement mss_fixup_ipv6().

Signed-off-by: Gert Doering 
---
 src/openvpn/forward.c |   26 +
 src/openvpn/forward.h |4 +-
 src/openvpn/mss.c |   57 -
 src/openvpn/mss.h |3 +-
 src/openvpn/multi.c   |6 ++--
 src/openvpn/proto.c   |   19 +--
 src/openvpn/proto.h   |3 +-
 7 files changed, 97 insertions(+), 21 deletions(-)

diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c
index 57c7846..024cd58 100644
--- a/src/openvpn/forward.c
+++ b/src/openvpn/forward.c
@@ -985,9 +985,9 @@ process_incoming_tun (struct context *c)
 {
   /*
* The --passtos and --mssfix options require
-   * us to examine the IPv4 header.
+   * us to examine the IP header (IPv4 or IPv6).
*/
-  process_ipv4_header (c, PIPV4_PASSTOS|PIPV4_MSSFIX|PIPV4_CLIENT_NAT, 
>c2.buf);
+  process_ip_header (c, PIPV4_PASSTOS|PIP_MSSFIX|PIPV4_CLIENT_NAT, 
>c2.buf);

 #ifdef PACKET_TRUNCATION_CHECK
   /* if (c->c2.buf.len > 1) --c->c2.buf.len; */
@@ -1009,10 +1009,10 @@ process_incoming_tun (struct context *c)
 }

 void
-process_ipv4_header (struct context *c, unsigned int flags, struct buffer *buf)
+process_ip_header (struct context *c, unsigned int flags, struct buffer *buf)
 {
   if (!c->options.ce.mssfix)
-flags &= ~PIPV4_MSSFIX;
+flags &= ~PIP_MSSFIX;
 #if PASSTOS_CAPABILITY
   if (!c->options.passtos)
 flags &= ~PIPV4_PASSTOS;
@@ -1027,9 +1027,9 @@ process_ipv4_header (struct context *c, unsigned int 
flags, struct buffer *buf)
* us to examine the IPv4 header.
*/
 #if PASSTOS_CAPABILITY
-  if (flags & (PIPV4_PASSTOS|PIPV4_MSSFIX))
+  if (flags & (PIPV4_PASSTOS|PIP_MSSFIX))
 #else
-  if (flags & PIPV4_MSSFIX)
+  if (flags & PIP_MSSFIX)
 #endif
{
  struct buffer ipbuf = *buf;
@@ -1042,8 +1042,8 @@ process_ipv4_header (struct context *c, unsigned int 
flags, struct buffer *buf)
 #endif

  /* possibly alter the TCP MSS */
- if (flags & PIPV4_MSSFIX)
-   mss_fixup (, MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC 
(>c2.frame)));
+ if (flags & PIP_MSSFIX)
+   mss_fixup_ipv4 (, MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC 
(>c2.frame)));

 #ifdef ENABLE_CLIENT_NAT
  /* possibly do NAT on packet */
@@ -1061,6 +1061,12 @@ process_ipv4_header (struct context *c, unsigned int 
flags, struct buffer *buf)
route_list_add_vpn_gateway (c->c1.route_list, c->c2.es, 
dhcp_router);
}
}
+ else if (is_ipv6 (TUNNEL_TYPE (c->c1.tuntap), ))
+   {
+ /* possibly alter the TCP MSS */
+ if (flags & PIP_MSSFIX)
+   mss_fixup_ipv6 (, MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC 
(>c2.frame)));
+   }
}
 }
 }
@@ -1217,9 +1223,9 @@ process_outgoing_tun (struct context *c)

   /*
* The --mssfix option requires
-   * us to examine the IPv4 header.
+   * us to examine the IP header (IPv4 or IPv6).
*/
-  process_ipv4_header (c, 
PIPV4_MSSFIX|PIPV4_EXTRACT_DHCP_ROUTER|PIPV4_CLIENT_NAT|PIPV4_OUTGOING, 
>c2.to_tun);
+  process_ip_header (c, 
PIP_MSSFIX|PIPV4_EXTRACT_DHCP_ROUTER|PIPV4_CLIENT_NAT|PIPV4_OUTGOING, 
>c2.to_tun);

   if (c->c2.to_tun.len <= MAX_RW_SIZE_TUN (>c2.frame))
 {
diff --git a/src/openvpn/forward.h b/src/openvpn/forward.h
index 0f829bd..1830a00 100644
--- a/src/openvpn/forward.h
+++ b/src/openvpn/forward.h
@@ -228,12 +228,12 @@ void process_outgoing_tun (struct context *c);
 bool send_control_channel_string (struct context *c, const char *str, int 
msglevel);

 #define PIPV4_PASSTOS (1<<0)
-#define PIPV4_MSSFIX  (1<<1)
+#define PIP_MSSFIX(1<<1) /* v4 and v6 */
 #define PIPV4_OUTGOING(1<<2)
 #define PIPV4_EXTRACT_DHCP_ROUTER (1<<3)
 #define PIPV4_CLIENT_NAT  (1<<4)

-void process_ipv4_header (struct context *c, unsigned int flags, struct buffer 
*buf);
+void process_ip_header (struct context *c, unsigned int flags, struct buffer 
*buf);

 #if P2MP
 void schedule_exit (struct context *c, const int n_seconds, const int signal);
diff --git a/src/openvpn/mss.c b/src/openvpn/mss.c
index 8981bad..64fd722 100644
--- a/src/openvpn/mss.c
+++ b/src/openvpn/mss.c
@@ -38,8 +38,13 @@
  * problems which arise from protocol
  * encapsulation.
  */
+
+/*
+ * IPv4 packet: find TCP header, check flags for "SYN"
+ *  if yes, hand to mss_fixup_dowork()
+ */
 void
-mss_fixup (struct buffer *buf, int maxmss)
+mss_fixup_ipv4 (struct buffer *buf, int maxmss)
 {
   const struct openvpn_iphdr *pip;
   int hlen;
@@ -69,6 +74,56 @@ mss_fixup (struct buffer *buf, int 

[Openvpn-devel] Implement --mssfix handling for IPv6 packets

2012-12-02 Thread Gert Doering
Hi,

in the next mail you'll find a patch to extend the existing --mssfix
code to handle IPv6 packets as well.

The actual mssfix implementation is only about half the change, but I
took the liberty to rename process_ipv4_header() to process_ip_header(),
and (after discussion on IRC) the PIPV4_MSSFIX flag to PIP_MSSFIX - to
make it obvious that this is no longer "IPv4 only".

The code has been tested on our corporate VPN server for 3 days now,
and did what advertised - adjusted MSS; not breaking anything else.  It
does fix the connectivity problems one of my users had - sitting behind a
router with broken PMTU handling *and* broken IPv4 fragment handling,
which killed IPv6 SSH-Sessions (all crypted, not compressible) quite
reliably.

Testing this is a bit tricky - the t_client framework won't cover it
(as it doesn't do TCP payload tests yet), so to actually *see* the
change you either need to have a broken network wrt IPv4 PMTU/fragment
handling before, or look at TCP SYN / SYN ACK packets with wireshark.

Anyway, I believe it's ready for inclusion in RC2, and should most 
definitely be in 2.3-RELEASE (as we'll see more users with broken
networks then).

gert