diff options
author | Bjoern A. Zeeb <bz@FreeBSD.org> | 2008-09-07 18:50:25 +0000 |
---|---|---|
committer | Bjoern A. Zeeb <bz@FreeBSD.org> | 2008-09-07 18:50:25 +0000 |
commit | 3cee92e074e9c9887f3264f2fcc13d3074722ef7 (patch) | |
tree | 37f18dd43810b276a89f19f44de627bae766a8c6 /sys/netinet/tcp_input.c | |
parent | 941f9f10b218cb91e8b79b8e35c184b041289a7e (diff) | |
download | src-3cee92e074e9c9887f3264f2fcc13d3074722ef7.tar.gz src-3cee92e074e9c9887f3264f2fcc13d3074722ef7.zip |
Notes
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r-- | sys/netinet/tcp_input.c | 71 |
1 files changed, 56 insertions, 15 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index f8ae94e9ed55..e96ef443a5db 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -2790,13 +2790,11 @@ tcp_xmit_timer(struct tcpcb *tp, int rtt) * segment. Outgoing SYN/ACK MSS settings are handled in tcp_mssopt(). */ void -tcp_mss(struct tcpcb *tp, int offer) +tcp_mss_update(struct tcpcb *tp, int offer, struct hc_metrics_lite *metricptr) { - int rtt, mss; - u_long bufsize; + int mss; u_long maxmtu; struct inpcb *inp = tp->t_inpcb; - struct socket *so; struct hc_metrics_lite metrics; int origoffer = offer; int mtuflags = 0; @@ -2829,6 +2827,10 @@ tcp_mss(struct tcpcb *tp, int offer) if (maxmtu == 0) return; + /* Check the interface for TSO capabilities. */ + if (mtuflags & CSUM_TSO) + tp->t_flags |= TF_TSO; + /* What have we got? */ switch (offer) { case 0: @@ -2852,19 +2854,14 @@ tcp_mss(struct tcpcb *tp, int offer) * to at least minmss. */ offer = max(offer, V_tcp_minmss); - /* - * Sanity check: make sure that maxopd will be large - * enough to allow some data on segments even if the - * all the option space is used (40bytes). Otherwise - * funny things may happen in tcp_output. - */ - offer = max(offer, 64); } /* * rmx information is now retrieved from tcp_hostcache. */ tcp_hc_get(&inp->inp_inc, &metrics); + if (metricptr != NULL) + bcopy(&metrics, metricptr, sizeof(struct hc_metrics_lite)); /* * If there's a discovered mtu int tcp hostcache, use it @@ -2887,10 +2884,36 @@ tcp_mss(struct tcpcb *tp, int offer) !in_localaddr(inp->inp_faddr)) mss = min(mss, V_tcp_mssdflt); } + /* + * XXX - The above conditional (mss = maxmtu - min_protoh) + * probably violates the TCP spec. + * The problem is that, since we don't know the + * other end's MSS, we are supposed to use a conservative + * default. But, if we do that, then MTU discovery will + * never actually take place, because the conservative + * default is much less than the MTUs typically seen + * on the Internet today. For the moment, we'll sweep + * this under the carpet. + * + * The conservative default might not actually be a problem + * if the only case this occurs is when sending an initial + * SYN with options and data to a host we've never talked + * to before. Then, they will reply with an MSS value which + * will get recorded and the new parameters should get + * recomputed. For Further Study. + */ } mss = min(mss, offer); /* + * Sanity check: make sure that maxopd will be large + * enough to allow some data on segments even if the + * all the option space is used (40bytes). Otherwise + * funny things may happen in tcp_output. + */ + mss = max(mss, 64); + + /* * maxopd stores the maximum length of data AND options * in a segment; maxseg is the amount of data in a normal * segment. We need to store this value (maxopd) apart @@ -2916,6 +2939,28 @@ tcp_mss(struct tcpcb *tp, int offer) mss = mss / MCLBYTES * MCLBYTES; #endif tp->t_maxseg = mss; +} + +void +tcp_mss(struct tcpcb *tp, int offer) +{ + int rtt, mss; + u_long bufsize; + struct inpcb *inp; + struct socket *so; + struct hc_metrics_lite metrics; +#ifdef INET6 + int isipv6; +#endif + KASSERT(tp != NULL, ("%s: tp == NULL", __func__)); + + tcp_mss_update(tp, offer, &metrics); + + mss = tp->t_maxseg; + inp = tp->t_inpcb; +#ifdef INET6 + isipv6 = ((inp->inp_vflag & INP_IPV6) != 0) ? 1 : 0; +#endif /* * If there's a pipesize, change the socket buffer to that size, @@ -3022,10 +3067,6 @@ tcp_mss(struct tcpcb *tp, int offer) tp->snd_cwnd = mss * V_ss_fltsz_local; else tp->snd_cwnd = mss * V_ss_fltsz; - - /* Check the interface for TSO capabilities. */ - if (mtuflags & CSUM_TSO) - tp->t_flags |= TF_TSO; } /* |