chiark / gitweb /
pathmtu/pathmtu.c: Use IP_PMTUDISC_PROBE for sending the lookups.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 3 May 2014 19:04:44 +0000 (20:04 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 3 May 2014 19:27:55 +0000 (20:27 +0100)
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

index 8dac7b1..e8861f7 100644 (file)
@@ -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);