aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c29
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c29
2 files changed, 40 insertions, 18 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index 625981676776..aeb7353d4777 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -272,9 +272,9 @@ static const enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
272 * sCL -> sCL 272 * sCL -> sCL
273 */ 273 */
274/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */ 274/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
275/*ack*/ { sIV, sIV, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV }, 275/*ack*/ { sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV },
276/* 276/*
277 * sSS -> sIV Might be a half-open connection. 277 * sSS -> sIG Might be a half-open connection.
278 * sSR -> sSR Might answer late resent SYN. 278 * sSR -> sSR Might answer late resent SYN.
279 * sES -> sES :-) 279 * sES -> sES :-)
280 * sFW -> sCW Normal close request answered by ACK. 280 * sFW -> sCW Normal close request answered by ACK.
@@ -917,8 +917,12 @@ static int tcp_packet(struct ip_conntrack *conntrack,
917 917
918 switch (new_state) { 918 switch (new_state) {
919 case TCP_CONNTRACK_IGNORE: 919 case TCP_CONNTRACK_IGNORE:
920 /* Either SYN in ORIGINAL 920 /* Ignored packets:
921 * or SYN/ACK in REPLY. */ 921 *
922 * a) SYN in ORIGINAL
923 * b) SYN/ACK in REPLY
924 * c) ACK in reply direction after initial SYN in original.
925 */
922 if (index == TCP_SYNACK_SET 926 if (index == TCP_SYNACK_SET
923 && conntrack->proto.tcp.last_index == TCP_SYN_SET 927 && conntrack->proto.tcp.last_index == TCP_SYN_SET
924 && conntrack->proto.tcp.last_dir != dir 928 && conntrack->proto.tcp.last_dir != dir
@@ -985,13 +989,20 @@ static int tcp_packet(struct ip_conntrack *conntrack,
985 } 989 }
986 case TCP_CONNTRACK_CLOSE: 990 case TCP_CONNTRACK_CLOSE:
987 if (index == TCP_RST_SET 991 if (index == TCP_RST_SET
988 && test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) 992 && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
989 && conntrack->proto.tcp.last_index == TCP_SYN_SET 993 && conntrack->proto.tcp.last_index == TCP_SYN_SET)
994 || (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
995 && conntrack->proto.tcp.last_index == TCP_ACK_SET))
990 && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) { 996 && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) {
991 /* RST sent to invalid SYN we had let trough 997 /* RST sent to invalid SYN or ACK we had let trough
992 * SYN was in window then, tear down connection. 998 * at a) and c) above:
999 *
1000 * a) SYN was in window then
1001 * c) we hold a half-open connection.
1002 *
1003 * Delete our connection entry.
993 * We skip window checking, because packet might ACK 1004 * We skip window checking, because packet might ACK
994 * segments we ignored in the SYN. */ 1005 * segments we ignored. */
995 goto in_window; 1006 goto in_window;
996 } 1007 }
997 /* Just fall trough */ 1008 /* Just fall trough */
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 5a6fcf349bdf..6035633d8225 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -280,9 +280,9 @@ static enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
280 * sCL -> sCL 280 * sCL -> sCL
281 */ 281 */
282/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */ 282/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
283/*ack*/ { sIV, sIV, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV }, 283/*ack*/ { sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV },
284/* 284/*
285 * sSS -> sIV Might be a half-open connection. 285 * sSS -> sIG Might be a half-open connection.
286 * sSR -> sSR Might answer late resent SYN. 286 * sSR -> sSR Might answer late resent SYN.
287 * sES -> sES :-) 287 * sES -> sES :-)
288 * sFW -> sCW Normal close request answered by ACK. 288 * sFW -> sCW Normal close request answered by ACK.
@@ -912,8 +912,12 @@ static int tcp_packet(struct nf_conn *conntrack,
912 912
913 switch (new_state) { 913 switch (new_state) {
914 case TCP_CONNTRACK_IGNORE: 914 case TCP_CONNTRACK_IGNORE:
915 /* Either SYN in ORIGINAL 915 /* Ignored packets:
916 * or SYN/ACK in REPLY. */ 916 *
917 * a) SYN in ORIGINAL
918 * b) SYN/ACK in REPLY
919 * c) ACK in reply direction after initial SYN in original.
920 */
917 if (index == TCP_SYNACK_SET 921 if (index == TCP_SYNACK_SET
918 && conntrack->proto.tcp.last_index == TCP_SYN_SET 922 && conntrack->proto.tcp.last_index == TCP_SYN_SET
919 && conntrack->proto.tcp.last_dir != dir 923 && conntrack->proto.tcp.last_dir != dir
@@ -979,13 +983,20 @@ static int tcp_packet(struct nf_conn *conntrack,
979 } 983 }
980 case TCP_CONNTRACK_CLOSE: 984 case TCP_CONNTRACK_CLOSE:
981 if (index == TCP_RST_SET 985 if (index == TCP_RST_SET
982 && test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) 986 && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
983 && conntrack->proto.tcp.last_index == TCP_SYN_SET 987 && conntrack->proto.tcp.last_index == TCP_SYN_SET)
988 || (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
989 && conntrack->proto.tcp.last_index == TCP_ACK_SET))
984 && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) { 990 && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) {
985 /* RST sent to invalid SYN we had let trough 991 /* RST sent to invalid SYN or ACK we had let trough
986 * SYN was in window then, tear down connection. 992 * at a) and c) above:
993 *
994 * a) SYN was in window then
995 * c) we hold a half-open connection.
996 *
997 * Delete our connection entry.
987 * We skip window checking, because packet might ACK 998 * We skip window checking, because packet might ACK
988 * segments we ignored in the SYN. */ 999 * segments we ignored. */
989 goto in_window; 1000 goto in_window;
990 } 1001 }
991 /* Just fall trough */ 1002 /* Just fall trough */