|
Lines 139-147
Link Here
|
| 139 |
* as required by rfc1122 section 3.2.2.1 |
139 |
* as required by rfc1122 section 3.2.2.1 |
| 140 |
*/ |
140 |
*/ |
| 141 |
|
141 |
|
| 142 |
static int icmp_admin_prohib_like_rst = 0; |
142 |
static int icmp_admin_prohib_like_rst = 1; |
| 143 |
SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_admin_prohib_like_rst, CTLFLAG_RW, |
143 |
SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_admin_prohib_like_rst, CTLFLAG_RW, |
| 144 |
&icmp_admin_prohib_like_rst, 0, "Treat ICMP administratively prohibited messages like TCP RST, rfc1122 section 3.2.2.1"); |
144 |
&icmp_admin_prohib_like_rst, 0, |
|
|
145 |
"Treat ICMP administratively prohibited messages like TCP RST, rfc1122 section 3.2.2.1"); |
| 146 |
|
| 147 |
/* |
| 148 |
* When icmp_admin_prohib_like_rst is enabled, only act on |
| 149 |
* sessions in SYN-SENT state |
| 150 |
*/ |
| 151 |
|
| 152 |
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, |
| 154 |
&icmp_like_rst_syn_sent_only, 0, |
| 155 |
"When icmp_admin_prohib_like_rst is enabled, only act on sessions in SYN-SENT state"); |
| 145 |
|
156 |
|
| 146 |
static void tcp_cleartaocache __P((void)); |
157 |
static void tcp_cleartaocache __P((void)); |
| 147 |
static void tcp_notify __P((struct inpcb *, int)); |
158 |
static void tcp_notify __P((struct inpcb *, int)); |
|
Lines 967-976
Link Here
|
| 967 |
register struct ip *ip = vip; |
978 |
register struct ip *ip = vip; |
| 968 |
register struct tcphdr *th; |
979 |
register struct tcphdr *th; |
| 969 |
void (*notify) __P((struct inpcb *, int)) = tcp_notify; |
980 |
void (*notify) __P((struct inpcb *, int)) = tcp_notify; |
|
|
981 |
tcp_seq tcp_sequence = 0; |
| 970 |
|
982 |
|
| 971 |
if (cmd == PRC_QUENCH) |
983 |
if (cmd == PRC_QUENCH) |
| 972 |
notify = tcp_quench; |
984 |
notify = tcp_quench; |
| 973 |
else if ((icmp_admin_prohib_like_rst == 1) && (cmd == PRC_UNREACH_PORT) && (ip)) |
985 |
else if ((icmp_admin_prohib_like_rst == 1) && (cmd == PRC_UNREACH_PORT) && |
|
|
986 |
(ip) && ((IP_VHL_HL(ip->ip_vhl) << 2) == sizeof(struct ip))) |
| 987 |
/* |
| 988 |
* Only go here if the length of the IP header in the ICMP packet |
| 989 |
* is 20 bytes, that is it doesn't have options, if it does have |
| 990 |
* options, we will not have the first 8 bytes of the TCP header, |
| 991 |
* and thus we cannot match against TCP source/destination port |
| 992 |
* numbers and TCP sequence number. |
| 993 |
*/ |
| 974 |
notify = tcp_drop_syn_sent; |
994 |
notify = tcp_drop_syn_sent; |
| 975 |
else if (cmd == PRC_MSGSIZE) |
995 |
else if (cmd == PRC_MSGSIZE) |
| 976 |
notify = tcp_mtudisc; |
996 |
notify = tcp_mtudisc; |
|
Lines 980-989
Link Here
|
| 980 |
if (ip) { |
1000 |
if (ip) { |
| 981 |
th = (struct tcphdr *)((caddr_t)ip |
1001 |
th = (struct tcphdr *)((caddr_t)ip |
| 982 |
+ (IP_VHL_HL(ip->ip_vhl) << 2)); |
1002 |
+ (IP_VHL_HL(ip->ip_vhl) << 2)); |
|
|
1003 |
if (notify == tcp_drop_syn_sent) |
| 1004 |
tcp_sequence = ntohl(th->th_seq); |
| 983 |
in_pcbnotify(&tcb, sa, th->th_dport, ip->ip_src, th->th_sport, |
1005 |
in_pcbnotify(&tcb, sa, th->th_dport, ip->ip_src, th->th_sport, |
| 984 |
cmd, notify); |
1006 |
cmd, notify, tcp_sequence); |
| 985 |
} else |
1007 |
} else |
| 986 |
in_pcbnotify(&tcb, sa, 0, zeroin_addr, 0, cmd, notify); |
1008 |
in_pcbnotify(&tcb, sa, 0, zeroin_addr, 0, cmd, notify, 0); |
| 987 |
} |
1009 |
} |
| 988 |
|
1010 |
|
| 989 |
#ifdef INET6 |
1011 |
#ifdef INET6 |
|
Lines 1070-1075
Link Here
|
| 1070 |
#endif /* INET6 */ |
1092 |
#endif /* INET6 */ |
| 1071 |
|
1093 |
|
| 1072 |
/* |
1094 |
/* |
|
|
1095 |
* Check if the supplied TCP sequence number is a sequence number |
| 1096 |
* for a sent but unacknowledged packet on the given TCP session. |
| 1097 |
*/ |
| 1098 |
int |
| 1099 |
tcp_seq_vs_sess(inp, tcp_sequence) |
| 1100 |
struct inpcb *inp; |
| 1101 |
tcp_seq tcp_sequence; |
| 1102 |
{ |
| 1103 |
struct tcpcb *tp = intotcpcb(inp); |
| 1104 |
/* |
| 1105 |
* If the sequence number is less than that of the last |
| 1106 |
* unacknowledged packet, or greater than that of the |
| 1107 |
* last sent, the given sequence number is not that |
| 1108 |
* of a sent but unacknowledged packet for this session. |
| 1109 |
*/ |
| 1110 |
if (SEQ_LT(tcp_sequence, tp->snd_una) || |
| 1111 |
SEQ_GT(tcp_sequence, tp->snd_max)) { |
| 1112 |
return(0); |
| 1113 |
} else { |
| 1114 |
return(1); |
| 1115 |
} |
| 1116 |
} |
| 1117 |
|
| 1118 |
/* |
| 1073 |
* When a source quench is received, close congestion window |
1119 |
* When a source quench is received, close congestion window |
| 1074 |
* to one segment. We will gradually open it again as we proceed. |
1120 |
* to one segment. We will gradually open it again as we proceed. |
| 1075 |
*/ |
1121 |
*/ |
|
Lines 1086-1092
Link Here
|
| 1086 |
|
1132 |
|
| 1087 |
/* |
1133 |
/* |
| 1088 |
* When a ICMP unreachable is recieved, drop the |
1134 |
* When a ICMP unreachable is recieved, drop the |
| 1089 |
* TCP connection, but only if in SYN_SENT |
1135 |
* TCP connection, depending on the sysctl |
|
|
1136 |
* icmp_like_rst_syn_sent_only, it only drops |
| 1137 |
* the session if it's in SYN-SENT state |
| 1090 |
*/ |
1138 |
*/ |
| 1091 |
void |
1139 |
void |
| 1092 |
tcp_drop_syn_sent(inp, errno) |
1140 |
tcp_drop_syn_sent(inp, errno) |
|
Lines 1094-1101
Link Here
|
| 1094 |
int errno; |
1142 |
int errno; |
| 1095 |
{ |
1143 |
{ |
| 1096 |
struct tcpcb *tp = intotcpcb(inp); |
1144 |
struct tcpcb *tp = intotcpcb(inp); |
| 1097 |
if((tp) && (tp->t_state == TCPS_SYN_SENT)) |
1145 |
if((tp) && ((icmp_like_rst_syn_sent_only == 0) || |
| 1098 |
tcp_drop(tp, errno); |
1146 |
(tp->t_state == TCPS_SYN_SENT))) |
|
|
1147 |
tcp_drop(tp, errno); |
| 1099 |
} |
1148 |
} |
| 1100 |
|
1149 |
|
| 1101 |
/* |
1150 |
/* |