aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/tcp_input.c
diff options
context:
space:
mode:
authorBjoern A. Zeeb <bz@FreeBSD.org>2008-09-07 18:50:25 +0000
committerBjoern A. Zeeb <bz@FreeBSD.org>2008-09-07 18:50:25 +0000
commit3cee92e074e9c9887f3264f2fcc13d3074722ef7 (patch)
tree37f18dd43810b276a89f19f44de627bae766a8c6 /sys/netinet/tcp_input.c
parent941f9f10b218cb91e8b79b8e35c184b041289a7e (diff)
downloadsrc-3cee92e074e9c9887f3264f2fcc13d3074722ef7.tar.gz
src-3cee92e074e9c9887f3264f2fcc13d3074722ef7.zip
Notes
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r--sys/netinet/tcp_input.c71
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;
}
/*