summaryrefslogtreecommitdiffstats
path: root/src/openvpn/mss.c
diff options
context:
space:
mode:
authorGert Doering <gert@greenie.muc.de>2012-12-02 22:11:12 +0100
committerDavid Sommerseth <davids@redhat.com>2012-12-13 16:46:01 +0100
commit729c8464021ff7c41a7fbb03501465eca55909a3 (patch)
tree03c0625e2c2ddf94f8f4dd2dbb5873ac5ff783d9 /src/openvpn/mss.c
parent34bc52d611deec62e7fe56622771b58921d52176 (diff)
downloadopenvpn-729c8464021ff7c41a7fbb03501465eca55909a3.tar.gz
openvpn-729c8464021ff7c41a7fbb03501465eca55909a3.tar.xz
openvpn-729c8464021ff7c41a7fbb03501465eca55909a3.zip
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(). Signed-off-by: Gert Doering <gert@greenie.muc.de> Acked-by: Arne Schwabe <arne@rfc2549.org> Message-Id: 1354482672-16136-2-git-send-email-gert@greenie.muc.de URL: http://article.gmane.org/gmane.network.openvpn.devel/7173 Signed-off-by: David Sommerseth <davids@redhat.com> (cherry picked from commit f0e8997a874a89b3fe1f82109c443232e8967b01)
Diffstat (limited to 'src/openvpn/mss.c')
-rw-r--r--src/openvpn/mss.c57
1 files changed, 56 insertions, 1 deletions
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 maxmss)
}
}
+/*
+ * IPv6 packet: find TCP header, check flags for "SYN"
+ * if yes, hand to mss_fixup_dowork()
+ * (IPv6 header structure is sufficiently different from IPv4...)
+ */
+void
+mss_fixup_ipv6 (struct buffer *buf, int maxmss)
+{
+ const struct openvpn_ipv6hdr *pip6;
+ struct buffer newbuf;
+
+ if (BLEN (buf) < (int) sizeof (struct openvpn_ipv6hdr))
+ return;
+
+ verify_align_4 (buf);
+ pip6 = (struct openvpn_ipv6hdr *) BPTR (buf);
+
+ /* do we have the full IPv6 packet?
+ * "payload_len" does not include IPv6 header (+40 bytes)
+ */
+ if (BLEN (buf) != (int) ntohs(pip6->payload_len)+40 )
+ return;
+
+ /* follow header chain until we reach final header, then check for TCP
+ *
+ * An IPv6 packet could, theoretically, have a chain of multiple headers
+ * before the final header (TCP, UDP, ...), so we'd need to walk that
+ * chain (see RFC 2460 and RFC 6564 for details).
+ *
+ * In practice, "most typically used" extention headers (AH, routing,
+ * fragment, mobility) are very unlikely to be seen inside an OpenVPN
+ * tun, so for now, we only handle the case of "single next header = TCP"
+ */
+ if ( pip6->nexthdr != OPENVPN_IPPROTO_TCP )
+ return;
+
+ newbuf = *buf;
+ if ( buf_advance( &newbuf, 40 ) )
+ {
+ struct openvpn_tcphdr *tc = (struct openvpn_tcphdr *) BPTR (&newbuf);
+ if (tc->flags & OPENVPN_TCPH_SYN_MASK)
+ mss_fixup_dowork (&newbuf, (uint16_t) maxmss-20);
+ }
+}
+
+/*
+ * change TCP MSS option in SYN/SYN-ACK packets, if present
+ * this is generic for IPv4 and IPv6, as the TCP header is the same
+ */
+
void
mss_fixup_dowork (struct buffer *buf, uint16_t maxmss)
{