X-Git-Url: https://git.distorted.org.uk/~mdw/tripe/blobdiff_plain/88510d86bc0300f9a30ac9904826e75eaa4e791c..6090fc43d207d7e882839923c6bf8710beecf21b:/pathmtu/pathmtu.c?ds=sidebyside diff --git a/pathmtu/pathmtu.c b/pathmtu/pathmtu.c index d347b0dd..32f67a11 100644 --- a/pathmtu/pathmtu.c +++ b/pathmtu/pathmtu.c @@ -9,29 +9,25 @@ * * This file is part of Trivial IP Encryption (TrIPE). * - * TrIPE is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * TrIPE is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your + * option) any later version. * - * TrIPE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * TrIPE is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. * * You should have received a copy of the GNU General Public License - * along with TrIPE; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * along with TrIPE. If not, see . */ /*----- Header files ------------------------------------------------------*/ -#if defined(linux) -# define _BSD_SOURCE -#endif - #include "config.h" +#include #include #include #include @@ -238,6 +234,8 @@ static int pathmtu(const struct param *pp) * try to hug that initially. */ for (;;) { + assert(lo <= mtu && mtu <= hi); + if (pp->f & F_VERBOSE) moan("probe: %d <= %d <= %d", lo, mtu, hi); rc = probe(&ps, st, mtu); switch (rc) { @@ -295,19 +293,36 @@ static int pathmtu(const struct param *pp) if (pp->f & F_VERBOSE) moan("probe returned: found correct MTU"); goto done; } - if (pp->f & F_VERBOSE) moan("probe returned: guessing higher"); lo = mtu; + + /* Now we must make a new guess, between lo and hi. We know that lo + * is good; but we're not so sure about hi here. We know that hi > + * lo, so this will find an approximate midpoint, greater than lo and + * no more than hi. + */ + if (pp->f & F_VERBOSE) moan("probe returned: guessing higher"); mtu += (hi - lo + 1)/2; break; case RC_LOWER: lower: - if (mtu == lo) { + /* If this didn't work, and we're already at the bottom of our + * possible range, then something has gone horribly wrong. + */ + assert(lo < mtu); + hi = mtu - 1; + if (lo == hi) { if (pp->f & F_VERBOSE) moan("error returned: found correct MTU"); + mtu = lo; goto done; } + + /* We must make a new guess, between lo and hi. We're probably + * fairly sure that lo will succeed, since either it's the minimum + * MTU or we've tested it already; but we're not quite sure about hi, + * so we want to aim high. + */ if (pp->f & F_VERBOSE) moan("error returned: guessing lower"); - hi = mtu - 1; mtu -= (hi - lo + 1)/2; break; @@ -383,7 +398,7 @@ struct raw_state { static int raw_setup(void *stv, int sk, const struct param *pp) { struct raw_state *st = stv; - size_t sz; + socklen_t sz; int i, mtu = -1; struct ifaddrs *ifa, *ifaa, *ifap; struct ifreq ifr; @@ -597,13 +612,13 @@ static int linux_setup(void *stv, int sk, const struct param *pp) { struct linux_state *st = stv; int i, mtu; - size_t sz; + socklen_t sz; /* Snaffle the UDP socket. */ 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); @@ -635,7 +650,7 @@ static int linux_selproc(void *stv, fd_set *fd_in, struct probestate *ps) { struct linux_state *st = stv; int mtu; - size_t sz; + socklen_t sz; ssize_t n; unsigned char b[65536];