summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_subr.c
diff options
context:
space:
mode:
authorbz <bz@FreeBSD.org>2008-09-07 18:50:25 +0000
committerbz <bz@FreeBSD.org>2008-09-07 18:50:25 +0000
commit315b1413ee280cc24de730d842a4d54a0619cefa (patch)
tree37f18dd43810b276a89f19f44de627bae766a8c6 /sys/netinet/tcp_subr.c
parentf6147056c6e1989d3a47e244083c7b5ad1514887 (diff)
downloadFreeBSD-src-315b1413ee280cc24de730d842a4d54a0619cefa.zip
FreeBSD-src-315b1413ee280cc24de730d842a4d54a0619cefa.tar.gz
Split tcp_mss() in tcp_mss() and tcp_mss_update() where the former
calls the latter. Merge tcp_mss_update() with code from tcp_mtudisc() basically doing the same thing. This gives us one central place where we calcuate and check mss values to update t_maxopd (maximum mss + options length) instead of two slightly different but almost equal implementations to maintain. PR: kern/118455 Reviewed by: silby (back in March) MFC after: 2 months
Diffstat (limited to 'sys/netinet/tcp_subr.c')
-rw-r--r--sys/netinet/tcp_subr.c82
1 files changed, 9 insertions, 73 deletions
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 3a979b0..1d24991 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -1514,13 +1514,7 @@ struct inpcb *
tcp_mtudisc(struct inpcb *inp, int errno)
{
struct tcpcb *tp;
- struct socket *so = inp->inp_socket;
- u_int maxmtu;
- u_int romtu;
- int mss;
-#ifdef INET6
- int isipv6;
-#endif /* INET6 */
+ struct socket *so;
INP_WLOCK_ASSERT(inp);
if ((inp->inp_vflag & INP_TIMEWAIT) ||
@@ -1530,72 +1524,14 @@ tcp_mtudisc(struct inpcb *inp, int errno)
tp = intotcpcb(inp);
KASSERT(tp != NULL, ("tcp_mtudisc: tp == NULL"));
-#ifdef INET6
- isipv6 = (tp->t_inpcb->inp_vflag & INP_IPV6) != 0;
-#endif
- maxmtu = tcp_hc_getmtu(&inp->inp_inc); /* IPv4 and IPv6 */
- romtu =
-#ifdef INET6
- isipv6 ? tcp_maxmtu6(&inp->inp_inc, NULL) :
-#endif /* INET6 */
- tcp_maxmtu(&inp->inp_inc, NULL);
- if (!maxmtu)
- maxmtu = romtu;
- else
- maxmtu = min(maxmtu, romtu);
- if (!maxmtu) {
- tp->t_maxopd = tp->t_maxseg =
-#ifdef INET6
- isipv6 ? V_tcp_v6mssdflt :
-#endif /* INET6 */
- V_tcp_mssdflt;
- return (inp);
- }
- mss = maxmtu -
-#ifdef INET6
- (isipv6 ? sizeof(struct ip6_hdr) + sizeof(struct tcphdr) :
-#endif /* INET6 */
- sizeof(struct tcpiphdr)
-#ifdef INET6
- )
-#endif /* INET6 */
- ;
-
- /*
- * XXX - The above conditional 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.
- */
- if (tp->t_maxopd <= mss)
- return (inp);
- tp->t_maxopd = mss;
-
- if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
- (tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP)
- mss -= TCPOLEN_TSTAMP_APPA;
-#if (MCLBYTES & (MCLBYTES - 1)) == 0
- if (mss > MCLBYTES)
- mss &= ~(MCLBYTES-1);
-#else
- if (mss > MCLBYTES)
- mss = mss / MCLBYTES * MCLBYTES;
-#endif
- if (so->so_snd.sb_hiwat < mss)
- mss = so->so_snd.sb_hiwat;
-
- tp->t_maxseg = mss;
+ tcp_mss_update(tp, -1, NULL);
+
+ so = inp->inp_socket;
+ SOCKBUF_LOCK(&so->so_snd);
+ /* If the mss is larger than the socket buffer, decrease the mss. */
+ if (so->so_snd.sb_hiwat < tp->t_maxseg)
+ tp->t_maxseg = so->so_snd.sb_hiwat;
+ SOCKBUF_UNLOCK(&so->so_snd);
V_tcpstat.tcps_mturesent++;
tp->t_rtttime = 0;
OpenPOWER on IntegriCloud