summaryrefslogtreecommitdiff
path: root/sys/netinet/tcp_input.c
diff options
context:
space:
mode:
authorMarkus Friedl <markus@cvs.openbsd.org>2005-06-30 08:51:32 +0000
committerMarkus Friedl <markus@cvs.openbsd.org>2005-06-30 08:51:32 +0000
commitd0da6045c3473c63c2c5ebcb604695383312ac92 (patch)
tree47b24d0d2ccf633ec13c5ec6181e8098952eea3e /sys/netinet/tcp_input.c
parent9a113f7cb87a9e2074ec670f5a343663a903c767 (diff)
implement PMTU checks from
http://www.gont.com.ar/drafts/icmp-attacks-against-tcp.html i.e. don't act on ICMP-need-frag immediately if adhoc checks on the advertised mtu fail. the mtu update is delayed until a tcp retransmit happens. initial patch by Fernando Gont, tested by many.
Diffstat (limited to 'sys/netinet/tcp_input.c')
-rw-r--r--sys/netinet/tcp_input.c70
1 files changed, 69 insertions, 1 deletions
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 61f7c8940a7..3c112d968a6 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_input.c,v 1.187 2005/04/25 17:55:52 brad Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.188 2005/06/30 08:51:31 markus Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
@@ -1010,6 +1010,24 @@ after_listen:
tcpstat.tcps_rcvackbyte += acked;
ND6_HINT(tp);
sbdrop(&so->so_snd, acked);
+
+ /*
+ * If we had a pending ICMP message that
+ * referres to data that have just been
+ * acknowledged, disregard the recorded ICMP
+ * message.
+ */
+ if ((tp->t_flags & TF_PMTUD_PEND) &&
+ SEQ_GT(th->th_ack, tp->t_pmtud_th_seq))
+ tp->t_flags &= ~TF_PMTUD_PEND;
+
+ /*
+ * Keep track of the largest chunk of data
+ * acknowledged since last PMTU update
+ */
+ if (tp->t_pmtud_mss_acked < acked)
+ tp->t_pmtud_mss_acked = acked;
+
tp->snd_una = th->th_ack;
#if defined(TCP_SACK) || defined(TCP_ECN)
/*
@@ -1811,6 +1829,23 @@ trimthenstep6:
}
if (sb_notify(&so->so_snd))
sowwakeup(so);
+
+ /*
+ * If we had a pending ICMP message that referred to data
+ * that have just been acknowledged, disregard the recorded
+ * ICMP message.
+ */
+ if ((tp->t_flags & TF_PMTUD_PEND) &&
+ SEQ_GT(th->th_ack, tp->t_pmtud_th_seq))
+ tp->t_flags &= ~TF_PMTUD_PEND;
+
+ /*
+ * Keep track of the largest chunk of data acknowledged
+ * since last PMTU update
+ */
+ if (tp->t_pmtud_mss_acked < acked)
+ tp->t_pmtud_mss_acked = acked;
+
tp->snd_una = th->th_ack;
#ifdef TCP_ECN
/* sync snd_last with snd_una */
@@ -3045,6 +3080,9 @@ tcp_mss(tp, offer)
if (offer == -1) {
/* mss changed due to Path MTU discovery */
+ tp->t_flags &= ~TF_PMTUD_PEND;
+ tp->t_pmtud_mtu_sent = 0;
+ tp->t_pmtud_mss_acked = 0;
if (mss < tp->t_maxseg) {
/*
* Follow suggestion in RFC 2414 to reduce the
@@ -3065,6 +3103,36 @@ tcp_mss(tp, offer)
return (offer != -1 ? mssopt : mss);
}
+u_int
+tcp_hdrsz(struct tcpcb *tp)
+{
+ u_int hlen;
+
+ switch (tp->pf) {
+#ifdef INET6
+ case AF_INET6:
+ hlen = sizeof(struct ip6_hdr);
+ break;
+#endif
+ case AF_INET:
+ hlen = sizeof(struct ip);
+ break;
+ default:
+ hlen = 0;
+ break;
+ }
+ hlen += sizeof(struct tcphdr);
+
+ if ((tp->t_flags & (TF_REQ_TSTMP|TF_NOOPT)) == TF_REQ_TSTMP &&
+ (tp->t_flags & TF_RCVD_TSTMP) == TF_RCVD_TSTMP)
+ hlen += TCPOLEN_TSTAMP_APPA;
+#ifdef TCP_SIGNATURE
+ if (tp->t_flags & TF_SIGNATURE)
+ hlen += TCPOLEN_SIGLEN;
+#endif
+ return (hlen);
+}
+
/*
* Set connection variables based on the effective MSS.
* We are passed the TCPCB for the actual connection. If we