summaryrefslogtreecommitdiff
path: root/sys/netinet/tcp_subr.c
diff options
context:
space:
mode:
authorPoul-Henning Kamp <phk@FreeBSD.org>2001-02-18 09:34:55 +0000
committerPoul-Henning Kamp <phk@FreeBSD.org>2001-02-18 09:34:55 +0000
commit90fcbbd6354bc360cc2b9881027a0290df8fc168 (patch)
treecdceb4557f647af9bd8bfc42bc8d49f14d5591b9 /sys/netinet/tcp_subr.c
parent3e8bea9634ab85d8b13764affeb81df185de5977 (diff)
Notes
Diffstat (limited to 'sys/netinet/tcp_subr.c')
-rw-r--r--sys/netinet/tcp_subr.c55
1 files changed, 43 insertions, 12 deletions
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 0da8440682df..654101404a8c 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -135,24 +135,31 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, pcbcount, CTLFLAG_RD,
&tcbinfo.ipi_count, 0, "Number of active PCBs");
/*
- * Treat ICMP administratively prohibited like a TCP RST
- * as required by rfc1122 section 3.2.2.1
+ * Treat ICMP unreachables like a TCP RST as required by rfc1122 section 3.2.2.1
+ *
+ * Administatively prohibited kill's sessions regardless of
+ * their current state, other unreachable by default only kill
+ * sessions if they are in SYN-SENT state, this ensure temporary
+ * routing problems doesn't kill existing TCP sessions.
+ * This can be overridden by icmp_like_rst_syn_sent_only.
*/
-static int icmp_admin_prohib_like_rst = 1;
-SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_admin_prohib_like_rst, CTLFLAG_RW,
- &icmp_admin_prohib_like_rst, 0,
- "Treat ICMP administratively prohibited messages like TCP RST, rfc1122 section 3.2.2.1");
+static int icmp_unreach_like_rst = 1;
+SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_unreach_like_rst, CTLFLAG_RW,
+ &icmp_unreach_like_rst, 0,
+ "Treat ICMP unreachable messages like TCP RST, rfc1122 section 3.2.2.1");
/*
- * When icmp_admin_prohib_like_rst is enabled, only act on
- * sessions in SYN-SENT state
+ * Control if ICMP unreachable messages other that administratively prohibited
+ * ones will kill sessions not in SYN-SENT state.
+ *
+ * Has no effect unless icmp_unreach_like_rst is enabled.
*/
static int icmp_like_rst_syn_sent_only = 1;
SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_like_rst_syn_sent_only, CTLFLAG_RW,
&icmp_like_rst_syn_sent_only, 0,
- "When icmp_admin_prohib_like_rst is enabled, only act on sessions in SYN-SENT state");
+ "When icmp_unreach_like_rst is enabled, only act on sessions in SYN-SENT state");
static void tcp_cleartaocache __P((void));
static void tcp_notify __P((struct inpcb *, int));
@@ -983,17 +990,27 @@ tcp_ctlinput(cmd, sa, vip)
if (cmd == PRC_QUENCH)
notify = tcp_quench;
- else if ((icmp_admin_prohib_like_rst == 1) && (cmd == PRC_UNREACH_PORT) &&
- (ip) && ((IP_VHL_HL(ip->ip_vhl) << 2) == sizeof(struct ip))) {
+ else if ((icmp_unreach_like_rst == 1) && ((cmd == PRC_UNREACH_HOST) ||
+ (cmd == PRC_UNREACH_ADMIN_PROHIB)) && (ip) &&
+ ((IP_VHL_HL(ip->ip_vhl) << 2) == sizeof(struct ip))) {
/*
* Only go here if the length of the IP header in the ICMP packet
* is 20 bytes, that is it doesn't have options, if it does have
* options, we will not have the first 8 bytes of the TCP header,
* and thus we cannot match against TCP source/destination port
* numbers and TCP sequence number.
+ *
+ * If PRC_UNREACH_ADMIN_PROHIB drop session regardsless of current
+ * state, else we check the sysctl icmp_like_rst_syn_sent_only to
+ * see if we should drop the session only in SYN-SENT state, or
+ * in all states.
*/
tcp_seq_check = 1;
- notify = tcp_drop_syn_sent;
+ if (cmd == PRC_UNREACH_ADMIN_PROHIB) {
+ notify = tcp_drop_all_states;
+ } else {
+ notify = tcp_drop_syn_sent;
+ }
} else if (cmd == PRC_MSGSIZE)
notify = tcp_mtudisc;
else if (!PRC_IS_REDIRECT(cmd) &&
@@ -1150,6 +1167,20 @@ tcp_drop_syn_sent(inp, errno)
}
/*
+ * When a ICMP unreachable is recieved, drop the
+ * TCP connection, regardless of the state.
+ */
+void
+tcp_drop_all_states(inp, errno)
+ struct inpcb *inp;
+ int errno;
+{
+ struct tcpcb *tp = intotcpcb(inp);
+ if(tp)
+ tcp_drop(tp, errno);
+}
+
+/*
* When `need fragmentation' ICMP is received, update our idea of the MSS
* based on the new value in the route. Also nudge TCP to send something,
* since we know the packet we just sent was dropped.