Implement --mssfix handling for IPv6 packets
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
PATCH 1/1 Implement --mssfix handling for IPv6 packets.
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().
--- 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(-)
src/openvpn/forward.c +16 -10
@@ -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 , &c->c2.buf); +process_ip_header (c,PIPV4_PASSTOS |PIP_MSSFIX |PIPV4_CLIENT_NAT , &c->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 (&ipbuf,MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC (&c->c2.frame))); +if (flags &PIP_MSSFIX ) +mss_fixup_ipv4 (&ipbuf,MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC (&c->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), &ipbuf)) + { +/* possibly alter the TCP MSS */ +if (flags &PIP_MSSFIX ) +mss_fixup_ipv6 (&ipbuf,MTU_TO_MSS (TUN_MTU_SIZE_DYNAMIC (&c->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 , &c->c2.to_tun); +process_ip_header (c,PIP_MSSFIX |PIPV4_EXTRACT_DHCP_ROUTER |PIPV4_CLIENT_NAT |PIPV4_OUTGOING , &c->c2.to_tun);if (c->c2.to_tun.len <=MAX_RW_SIZE_TUN (&c->c2.frame)) {
src/openvpn/forward.h +2 -2
@@ -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);
src/openvpn/mss.c +56 -1
70 lines not on this page · raw message
src/openvpn/mss.h +2 -1
@@ -28,7 +28,8 @@#include "proto.h" #include "error.h" -void mss_fixup (struct buffer *buf,int maxmss); +void mss_fixup_ipv4 (struct buffer *buf,int maxmss); +void mss_fixup_ipv6 (struct buffer *buf,int maxmss);void mss_fixup_dowork (struct buffer *buf,uint16_t maxmss);#endif
src/openvpn/multi.c +3 -3
@@ -2411,13 +2411,13 @@ multi_get_queue (struct mbuf_set *ms)if (mbuf_extract_item (ms, &item))/* cleartext IP packet */ { -unsigned int pipv4_flags =PIPV4_PASSTOS ; +unsigned int pip_flags =PIPV4_PASSTOS ;set_prefix (item.instance); item.instance->context.c2.buf = item.buffer->buf;if (item.buffer->flags &MF_UNICAST )/* --mssfix doesn't make sense for broadcast or multicast */ - pipv4_flags |=PIPV4_MSSFIX ; -process_ipv4_header (&item.instance->context, pipv4_flags, &item.instance->context.c2.buf); + pip_flags |=PIP_MSSFIX ; +process_ip_header (&item.instance->context, pip_flags, &item.instance->context.c2.buf);encrypt_sign (&item.instance->context, true);mbuf_free_buf (item.buffer);
src/openvpn/proto.c +16 -3
@@ -36,11 +36,12 @@#include "memdbg.h" /* -* If raw tunnel packet is IPv4, return true and increment +* If raw tunnel packet is IPv<X>, return true and increment * buffer offset to start of IP header. */ +static bool -is_ipv4 (int tunnel_type,struct buffer *buf) +is_ipv_X (int tunnel_type,struct buffer *buf,int ip_ver ) {int offset;const struct openvpn_iphdr *ih;
@@ -68,12 +69,24 @@ is_ipv4 (int tunnel_type, struct buffer *buf) ih = (const struct openvpn_iphdr *) (BPTR (buf) + offset); -if (OPENVPN_IPH_GET_VER (ih->version_len) ==4 ) +/* IP version is stored in the same bits for IPv4 or IPv6 header */ +if (OPENVPN_IPH_GET_VER (ih->version_len) == ip_ver)return buf_advance (buf, offset);else return false; } +bool +is_ipv4 (int tunnel_type,struct buffer *buf) +{ +return is_ipv_X ( tunnel_type, buf,4 ); +} +bool +is_ipv6 (int tunnel_type,struct buffer *buf) +{ +return is_ipv_X ( tunnel_type, buf,6 ); +} +#ifdef PACKET_TRUNCATION_CHECK void
src/openvpn/proto.h +2 -1
@@ -219,10 +219,11 @@ struct ip_tcp_udp_hdr { - sizeof(struct openvpn_tcphdr))/* -* If raw tunnel packet is IPv4, return true and increment +* If raw tunnel packet is IPv4 or IPv6, return true and increment * buffer offset to start of IP header. */ bool is_ipv4 (int tunnel_type,struct buffer *buf); +bool is_ipv6 (int tunnel_type,struct buffer *buf);#ifdef PACKET_TRUNCATION_CHECK void ipv4_packet_size_verify (const uint8_t *data,
Signature · 1 line
1.7.8.6
Re: [Openvpn-devel] [PATCH] Implement --mssfix handling for IPv6 packets.
Am 02.12.12 22:11, schrieb Gert Doering:
Quoted 9 lines
Rename
process_ipv4_header()toprocess_ip_header()andPIPV4_MSSFIXflag toPIP_MSSFIX, to make visible that it's no longer IPv4-only.Inside
process_ip_header(), call out tomss_fixup_ipv6()if --mssfix is active and IPv6 packet seen.Rename
mss_fixup()tomss_fixup_ipv4(), implementmss_fixup_ipv6().
I have no setup with broken mss but I looked through the patch and I think is the right fix.
Arne
David Sommerseth
AppliedRe: [Openvpn-devel] [PATCH] Implement --mssfix handling for IPv6 packets.
In reply to Gert DoeringQuoted 9 lines · Gert Doering
Rename
process_ipv4_header()toprocess_ip_header()andPIPV4_MSSFIXflag toPIP_MSSFIX, to make visible that it's no longer IPv4-only.Inside
process_ip_header(), call out tomss_fixup_ipv6()if --mssfix is active and IPv6 packet seen.Rename
mss_fixup()tomss_fixup_ipv4(), implementmss_fixup_ipv6().Signed-off-by Gert Doering <[email protected]...>
Quoted 9 lines
--- 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(-)
Applied in master and beta/2.3
commit f0e8997a874a89b3fe1f82109c443232e8967b01 (master) commit 729c8464021ff7c41a7fbb03501465eca55909a3 (beta/2.3)
Author: Gert Doering <[email protected]...> Date: Sun Dec 2 22:11:12 2012 +0100
Implement --mssfix handling for IPv6 packets.
Signed-off-by: Gert Doering <[email protected]...>
Acked-by: Arne Schwabe <[email protected]...>
Message-Id: [email protected]...
URL: http://article.gmane.org/gmane.network.openvpn.devel/7173
Signed-off-by: David Sommerseth <[email protected]...>Signature · 3 lines
kind regards, David Sommerseth