From 18d5f6eb91b1f8e1f497b0176c07a91aa6492be0 Mon Sep 17 00:00:00 2001 Message-Id: <18d5f6eb91b1f8e1f497b0176c07a91aa6492be0.1714149384.git.mdw@distorted.org.uk> From: Mark Wooding Date: Sat, 3 May 2014 20:04:44 +0100 Subject: [PATCH] pathmtu/pathmtu.c: Use IP_PMTUDISC_PROBE for sending the lookups. Organization: Straylight/Edgeware From: Mark Wooding Linux's behaviour is very strange if you set IP_PMTUDISC_DO. Suppose we have this situation: host A <-1500-> router B <-1432-> ... <-1500-> host Z We send a 1500-byte probe from A. Router B sends back `fragmentation needed' with maximum size 1432. Linux reports EMSGSIZE back to us, but when we read IP_MTU, we get 1500 again. OK: we send another probe with 1500, for old times' sake, but the write(2) fails with EMSGSIZE. At this point we give up and try binary search. The next size we try is 1038, but write(2) fails again, inexplicably. Subsequent binary search succeeds, so we end up with an MTU of 1037. This is too small for IPv6. Using IP_PMTUDISC_PROBE instead seems to prevent Linux from being hopeless at write(2) time. --- pathmtu/pathmtu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pathmtu/pathmtu.c b/pathmtu/pathmtu.c index 8dac7b11..e8861f70 100644 --- a/pathmtu/pathmtu.c +++ b/pathmtu/pathmtu.c @@ -623,7 +623,7 @@ static int linux_setup(void *stv, int sk, const struct param *pp) st->sk = sk; /* Turn on kernel path-MTU discovery and force DF on. */ - i = IP_PMTUDISC_DO; + i = IP_PMTUDISC_PROBE; if (setsockopt(st->sk, IPPROTO_IP, IP_MTU_DISCOVER, &i, sizeof(i))) return (-1); -- [mdw]