summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2005-04-21 12:37:12 +0000
committerandre <andre@FreeBSD.org>2005-04-21 12:37:12 +0000
commit34a84acceeef772a5b9acdda87fdf6cc6581e62d (patch)
tree7b9a0e3c485902d0bc77850e4bcc3582acddb4c4 /sys
parent50df456889d520f12a65d284becf49069ee5aa76 (diff)
downloadFreeBSD-src-34a84acceeef772a5b9acdda87fdf6cc6581e62d.zip
FreeBSD-src-34a84acceeef772a5b9acdda87fdf6cc6581e62d.tar.gz
Ignore ICMP Source Quench messages for TCP sessions. Source Quench is
ineffective, depreciated and can be abused to degrade the performance of active TCP sessions if spoofed. Replace a bogus call to tcp_quench() in tcp_output() with the direct equivalent tcpcb variable assignment. Security: draft-gont-tcpm-icmp-attacks-03.txt Section 7.1 MFC after: 3 days
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/tcp_output.c2
-rw-r--r--sys/netinet/tcp_subr.c35
-rw-r--r--sys/netinet/tcp_timewait.c35
-rw-r--r--sys/netinet/tcp_var.h2
4 files changed, 23 insertions, 51 deletions
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index fce9c9c..37a4ef1 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -1066,7 +1066,7 @@ out:
!callout_active(tp->tt_persist))
callout_reset(tp->tt_rexmt, tp->t_rxtcur,
tcp_timer_rexmt, tp);
- tcp_quench(tp->t_inpcb, 0);
+ tp->snd_cwnd = tp->t_maxseg;
return (0);
}
if (error == EMSGSIZE) {
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 3516c74..02e753a 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -1117,19 +1117,22 @@ tcp_ctlinput(cmd, sa, vip)
if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY)
return;
- if (cmd == PRC_QUENCH)
- notify = tcp_quench;
+ if (cmd == PRC_MSGSIZE)
+ notify = tcp_mtudisc;
else if (icmp_may_rst && (cmd == PRC_UNREACH_ADMIN_PROHIB ||
cmd == PRC_UNREACH_PORT || cmd == PRC_TIMXCEED_INTRANS) && ip)
notify = tcp_drop_syn_sent;
- else if (cmd == PRC_MSGSIZE)
- notify = tcp_mtudisc;
/*
* Redirects don't need to be handled up here.
*/
else if (PRC_IS_REDIRECT(cmd))
return;
/*
+ * Source quench is depreciated.
+ */
+ else if (cmd == PRC_QUENCH)
+ return;
+ /*
* Hostdead is ugly because it goes linearly through all PCBs.
* XXX: We never get this from ICMP, otherwise it makes an
* excellent DoS attack on machines with many connections.
@@ -1197,13 +1200,14 @@ tcp6_ctlinput(cmd, sa, d)
sa->sa_len != sizeof(struct sockaddr_in6))
return;
- if (cmd == PRC_QUENCH)
- notify = tcp_quench;
- else if (cmd == PRC_MSGSIZE)
+ if (cmd == PRC_MSGSIZE)
notify = tcp_mtudisc;
else if (!PRC_IS_REDIRECT(cmd) &&
((unsigned)cmd >= PRC_NCMDS || inet6ctlerrmap[cmd] == 0))
return;
+ /* Source quench is depreciated. */
+ else if (cmd == PRC_QUENCH)
+ return;
/* if the parameter is from icmp6, decode it. */
if (d != NULL) {
@@ -1373,23 +1377,6 @@ tcp_isn_tick(xtp)
}
/*
- * When a source quench is received, close congestion window
- * to one segment. We will gradually open it again as we proceed.
- */
-struct inpcb *
-tcp_quench(inp, errno)
- struct inpcb *inp;
- int errno;
-{
- struct tcpcb *tp = intotcpcb(inp);
-
- INP_LOCK_ASSERT(inp);
- if (tp != NULL)
- tp->snd_cwnd = tp->t_maxseg;
- return (inp);
-}
-
-/*
* When a specific ICMP unreachable message is received and the
* connection state is SYN-SENT, drop the connection. This behavior
* is controlled by the icmp_may_rst sysctl.
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index 3516c74..02e753a 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -1117,19 +1117,22 @@ tcp_ctlinput(cmd, sa, vip)
if (sa->sa_family != AF_INET || faddr.s_addr == INADDR_ANY)
return;
- if (cmd == PRC_QUENCH)
- notify = tcp_quench;
+ if (cmd == PRC_MSGSIZE)
+ notify = tcp_mtudisc;
else if (icmp_may_rst && (cmd == PRC_UNREACH_ADMIN_PROHIB ||
cmd == PRC_UNREACH_PORT || cmd == PRC_TIMXCEED_INTRANS) && ip)
notify = tcp_drop_syn_sent;
- else if (cmd == PRC_MSGSIZE)
- notify = tcp_mtudisc;
/*
* Redirects don't need to be handled up here.
*/
else if (PRC_IS_REDIRECT(cmd))
return;
/*
+ * Source quench is depreciated.
+ */
+ else if (cmd == PRC_QUENCH)
+ return;
+ /*
* Hostdead is ugly because it goes linearly through all PCBs.
* XXX: We never get this from ICMP, otherwise it makes an
* excellent DoS attack on machines with many connections.
@@ -1197,13 +1200,14 @@ tcp6_ctlinput(cmd, sa, d)
sa->sa_len != sizeof(struct sockaddr_in6))
return;
- if (cmd == PRC_QUENCH)
- notify = tcp_quench;
- else if (cmd == PRC_MSGSIZE)
+ if (cmd == PRC_MSGSIZE)
notify = tcp_mtudisc;
else if (!PRC_IS_REDIRECT(cmd) &&
((unsigned)cmd >= PRC_NCMDS || inet6ctlerrmap[cmd] == 0))
return;
+ /* Source quench is depreciated. */
+ else if (cmd == PRC_QUENCH)
+ return;
/* if the parameter is from icmp6, decode it. */
if (d != NULL) {
@@ -1373,23 +1377,6 @@ tcp_isn_tick(xtp)
}
/*
- * When a source quench is received, close congestion window
- * to one segment. We will gradually open it again as we proceed.
- */
-struct inpcb *
-tcp_quench(inp, errno)
- struct inpcb *inp;
- int errno;
-{
- struct tcpcb *tp = intotcpcb(inp);
-
- INP_LOCK_ASSERT(inp);
- if (tp != NULL)
- tp->snd_cwnd = tp->t_maxseg;
- return (inp);
-}
-
-/*
* When a specific ICMP unreachable message is received and the
* connection state is SYN-SENT, drop the connection. This behavior
* is controlled by the icmp_may_rst sysctl.
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index 26e410e..2a727a0 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -534,8 +534,6 @@ struct inpcb *
struct tcpcb *
tcp_newtcpcb(struct inpcb *);
int tcp_output(struct tcpcb *);
-struct inpcb *
- tcp_quench(struct inpcb *, int);
void tcp_respond(struct tcpcb *, void *,
struct tcphdr *, struct mbuf *, tcp_seq, tcp_seq, int);
int tcp_twrespond(struct tcptw *, int);
OpenPOWER on IntegriCloud