|
Lines 135-158
Link Here
|
| 135 |
&tcbinfo.ipi_count, 0, "Number of active PCBs"); |
135 |
&tcbinfo.ipi_count, 0, "Number of active PCBs"); |
| 136 |
|
136 |
|
| 137 |
/* |
137 |
/* |
| 138 |
* Treat ICMP administratively prohibited like a TCP RST |
138 |
* Treat ICMP unreachables like a TCP RST as required by rfc1122 section 3.2.2.1 |
| 139 |
* as required by rfc1122 section 3.2.2.1 |
139 |
* |
|
|
140 |
* Administatively prohibited kill's sessions regardless of |
| 141 |
* their current state, other unreachable by default only kill |
| 142 |
* sessions if they are in SYN-SENT state, this ensure temporary |
| 143 |
* routing problems doesn't kill existing TCP sessions. |
| 144 |
* This can be overridden by icmp_like_rst_syn_sent_only. |
| 140 |
*/ |
145 |
*/ |
| 141 |
|
146 |
|
| 142 |
static int icmp_admin_prohib_like_rst = 1; |
147 |
static int icmp_unreach_like_rst = 1; |
| 143 |
SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_admin_prohib_like_rst, CTLFLAG_RW, |
148 |
SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_unreach_like_rst, CTLFLAG_RW, |
| 144 |
&icmp_admin_prohib_like_rst, 0, |
149 |
&icmp_unreach_like_rst, 0, |
| 145 |
"Treat ICMP administratively prohibited messages like TCP RST, rfc1122 section 3.2.2.1"); |
150 |
"Treat ICMP unreachable messages like TCP RST, rfc1122 section 3.2.2.1"); |
| 146 |
|
151 |
|
| 147 |
/* |
152 |
/* |
| 148 |
* When icmp_admin_prohib_like_rst is enabled, only act on |
153 |
* Control if ICMP unreachable messages other that administratively prohibited |
| 149 |
* sessions in SYN-SENT state |
154 |
* ones will kill sessions not in SYN-SENT state. |
|
|
155 |
* |
| 156 |
* Has no effect unless icmp_unreach_like_rst is enabled. |
| 150 |
*/ |
157 |
*/ |
| 151 |
|
158 |
|
| 152 |
static int icmp_like_rst_syn_sent_only = 1; |
159 |
static int icmp_like_rst_syn_sent_only = 1; |
| 153 |
SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_like_rst_syn_sent_only, CTLFLAG_RW, |
160 |
SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_like_rst_syn_sent_only, CTLFLAG_RW, |
| 154 |
&icmp_like_rst_syn_sent_only, 0, |
161 |
&icmp_like_rst_syn_sent_only, 0, |
| 155 |
"When icmp_admin_prohib_like_rst is enabled, only act on sessions in SYN-SENT state"); |
162 |
"When icmp_unreach_like_rst is enabled, only act on sessions in SYN-SENT state"); |
| 156 |
|
163 |
|
| 157 |
static void tcp_cleartaocache __P((void)); |
164 |
static void tcp_cleartaocache __P((void)); |
| 158 |
static void tcp_notify __P((struct inpcb *, int)); |
165 |
static void tcp_notify __P((struct inpcb *, int)); |
|
Lines 983-999
Link Here
|
| 983 |
|
990 |
|
| 984 |
if (cmd == PRC_QUENCH) |
991 |
if (cmd == PRC_QUENCH) |
| 985 |
notify = tcp_quench; |
992 |
notify = tcp_quench; |
| 986 |
else if ((icmp_admin_prohib_like_rst == 1) && (cmd == PRC_UNREACH_PORT) && |
993 |
else if ((icmp_unreach_like_rst == 1) && ((cmd == PRC_UNREACH_HOST) || |
| 987 |
(ip) && ((IP_VHL_HL(ip->ip_vhl) << 2) == sizeof(struct ip))) { |
994 |
(cmd == PRC_UNREACH_ADMIN_PROHIB)) && (ip) && |
|
|
995 |
((IP_VHL_HL(ip->ip_vhl) << 2) == sizeof(struct ip))) { |
| 988 |
/* |
996 |
/* |
| 989 |
* Only go here if the length of the IP header in the ICMP packet |
997 |
* Only go here if the length of the IP header in the ICMP packet |
| 990 |
* is 20 bytes, that is it doesn't have options, if it does have |
998 |
* is 20 bytes, that is it doesn't have options, if it does have |
| 991 |
* options, we will not have the first 8 bytes of the TCP header, |
999 |
* options, we will not have the first 8 bytes of the TCP header, |
| 992 |
* and thus we cannot match against TCP source/destination port |
1000 |
* and thus we cannot match against TCP source/destination port |
| 993 |
* numbers and TCP sequence number. |
1001 |
* numbers and TCP sequence number. |
|
|
1002 |
* |
| 1003 |
* If PRC_UNREACH_ADMIN_PROHIB drop session regardsless of current |
| 1004 |
* state, else we check the sysctl icmp_like_rst_syn_sent_only to |
| 1005 |
* see if we should drop the session only in SYN-SENT state, or |
| 1006 |
* in all states. |
| 994 |
*/ |
1007 |
*/ |
| 995 |
tcp_seq_check = 1; |
1008 |
tcp_seq_check = 1; |
| 996 |
notify = tcp_drop_syn_sent; |
1009 |
if (cmd == PRC_UNREACH_ADMIN_PROHIB) { |
|
|
1010 |
notify = tcp_drop_all_states; |
| 1011 |
} else { |
| 1012 |
notify = tcp_drop_syn_sent; |
| 1013 |
} |
| 997 |
} else if (cmd == PRC_MSGSIZE) |
1014 |
} else if (cmd == PRC_MSGSIZE) |
| 998 |
notify = tcp_mtudisc; |
1015 |
notify = tcp_mtudisc; |
| 999 |
else if (!PRC_IS_REDIRECT(cmd) && |
1016 |
else if (!PRC_IS_REDIRECT(cmd) && |
|
Lines 1146-1151
Link Here
|
| 1146 |
struct tcpcb *tp = intotcpcb(inp); |
1163 |
struct tcpcb *tp = intotcpcb(inp); |
| 1147 |
if((tp) && ((icmp_like_rst_syn_sent_only == 0) || |
1164 |
if((tp) && ((icmp_like_rst_syn_sent_only == 0) || |
| 1148 |
(tp->t_state == TCPS_SYN_SENT))) |
1165 |
(tp->t_state == TCPS_SYN_SENT))) |
|
|
1166 |
tcp_drop(tp, errno); |
| 1167 |
} |
| 1168 |
|
| 1169 |
/* |
| 1170 |
* When a ICMP unreachable is recieved, drop the |
| 1171 |
* TCP connection, regardless of the state. |
| 1172 |
*/ |
| 1173 |
void |
| 1174 |
tcp_drop_all_states(inp, errno) |
| 1175 |
struct inpcb *inp; |
| 1176 |
int errno; |
| 1177 |
{ |
| 1178 |
struct tcpcb *tp = intotcpcb(inp); |
| 1179 |
if(tp) |
| 1149 |
tcp_drop(tp, errno); |
1180 |
tcp_drop(tp, errno); |
| 1150 |
} |
1181 |
} |
| 1151 |
|
1182 |
|