diff options
author | Mike Frantzen <frantzen@cvs.openbsd.org> | 2004-04-26 18:12:26 +0000 |
---|---|---|
committer | Mike Frantzen <frantzen@cvs.openbsd.org> | 2004-04-26 18:12:26 +0000 |
commit | 60d2bb762f3e34b1cb49541ea7d5d80c8cbcb153 (patch) | |
tree | cdf528af0a644b037169323f65d37f271be4242e | |
parent | 348afb65a199c12cb3f8fa559b1a5237d949eb77 (diff) |
- allow the user to force the TCP mss below the fail-safe 216 with a low
interface MTU.
- break a tcp_output() -> tcp_mtudisc() -> tcp_output() infinite recursion
when the TCP mss ends up larger than the interface MTU (when the if_mtu is
smaller than the tcp header). connections will still stall
feedback from itojun@, claudio@ and provos and testing from beck@
-rw-r--r-- | sys/netinet/tcp_input.c | 8 | ||||
-rw-r--r-- | sys/netinet/tcp_output.c | 4 | ||||
-rw-r--r-- | sys/netinet/tcp_subr.c | 18 |
3 files changed, 17 insertions, 13 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index f0cffa74bb5..57c2a850dae 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_input.c,v 1.164 2004/04/20 20:05:29 markus Exp $ */ +/* $OpenBSD: tcp_input.c,v 1.165 2004/04/26 18:12:25 frantzen Exp $ */ /* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */ /* @@ -3068,13 +3068,15 @@ tcp_mss(tp, offer) * If we compute a larger value, return it for use in sending * a max seg size option, but don't store it for use * unless we received an offer at least that large from peer. - * However, do not accept offers under 216 bytes. + * However, do not accept offers under 216 bytes unless the + * interface MTU is actually that low. */ if (offer > 0) tp->t_peermss = offer; if (tp->t_peermss) mss = min(mss, tp->t_peermss); - mss = max(mss, 216); /* sanity - at least max opt. space */ + /* sanity - at least max opt. space */ + mss = max(mss, min(216, ifp->if_mtu - iphlen - sizeof(struct tcphdr))); /* * maxopd stores the maximum length of data AND options diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index ceeac82cdb9..fd9e97cb04b 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_output.c,v 1.65 2004/02/16 21:51:03 markus Exp $ */ +/* $OpenBSD: tcp_output.c,v 1.66 2004/04/26 18:12:25 frantzen Exp $ */ /* $NetBSD: tcp_output.c,v 1.16 1997/06/03 16:17:09 kml Exp $ */ /* @@ -1190,7 +1190,7 @@ out: * initiate retransmission, so it is important to * not do so here. */ - tcp_mtudisc(tp->t_inpcb, 0); + tcp_mtudisc(tp->t_inpcb, -1); return (0); } if ((error == EHOSTUNREACH || error == ENETDOWN) && diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 27e9bd25203..c46ec66bc9a 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_subr.c,v 1.77 2004/03/02 12:51:12 markus Exp $ */ +/* $OpenBSD: tcp_subr.c,v 1.78 2004/04/26 18:12:25 frantzen Exp $ */ /* $NetBSD: tcp_subr.c,v 1.22 1996/02/13 23:44:00 christos Exp $ */ /* @@ -1018,8 +1018,10 @@ tcp_mtudisc(inp, errno) { struct tcpcb *tp = intotcpcb(inp); struct rtentry *rt = in_pcbrtentry(inp); + int change = 0; if (tp != 0) { + int orig_maxseg = tp->t_maxseg; if (rt != 0) { /* * If this was not a host route, remove and realloc. @@ -1029,18 +1031,18 @@ tcp_mtudisc(inp, errno) if ((rt = in_pcbrtentry(inp)) == 0) return; } - - if (rt->rt_rmx.rmx_mtu != 0) { - /* also takes care of congestion window */ - tcp_mss(tp, -1); - } + if (orig_maxseg != tp->t_maxseg || + (rt->rt_rmx.rmx_locks & RTV_MTU)) + change = 1; } + tcp_mss(tp, -1); /* - * Resend unacknowledged packets. + * Resend unacknowledged packets */ tp->snd_nxt = tp->snd_una; - tcp_output(tp); + if (change || errno > 0) + tcp_output(tp); } } |