diff -urN linux-2.4.0-test4-pre5.orig/include/linux/netfilter_ipv4/ip_conntrack_protocol.h linux-2.4.0-test4-pre5/include/linux/netfilter_ipv4/ip_conntrack_protocol.h --- linux-2.4.0-test4-pre5.orig/include/linux/netfilter_ipv4/ip_conntrack_protocol.h Mon Jul 10 22:25:04 2000 +++ linux-2.4.0-test4-pre5/include/linux/netfilter_ipv4/ip_conntrack_protocol.h Fri Jul 14 08:38:03 2000 @@ -35,7 +35,8 @@ /* Returns verdict for packet, or -1 for invalid. */ int (*packet)(struct ip_conntrack *conntrack, struct iphdr *iph, size_t len, - enum ip_conntrack_info ctinfo); + enum ip_conntrack_info ctinfo, + int *set_reply); /* Called when a new connection for this protocol found; * returns timeout. If so, packet() called next. */ diff -urN linux-2.4.0-test4-pre5.orig/net/ipv4/netfilter/ip_conntrack_core.c linux-2.4.0-test4-pre5/net/ipv4/netfilter/ip_conntrack_core.c --- linux-2.4.0-test4-pre5.orig/net/ipv4/netfilter/ip_conntrack_core.c Fri Jul 7 06:20:00 2000 +++ linux-2.4.0-test4-pre5/net/ipv4/netfilter/ip_conntrack_core.c Fri Jul 14 08:13:41 2000 @@ -675,7 +675,7 @@ IP_NF_ASSERT((*pskb)->nfct); - ret = proto->packet(ct, (*pskb)->nh.iph, (*pskb)->len, ctinfo); + ret = proto->packet(ct, (*pskb)->nh.iph, (*pskb)->len, ctinfo, &set_reply); if (ret == -1) { /* Invalid */ nf_conntrack_put((*pskb)->nfct); diff -urN linux-2.4.0-test4-pre5.orig/net/ipv4/netfilter/ip_conntrack_proto_generic.c linux-2.4.0-test4-pre5/net/ipv4/netfilter/ip_conntrack_proto_generic.c --- linux-2.4.0-test4-pre5.orig/net/ipv4/netfilter/ip_conntrack_proto_generic.c Tue Jun 20 23:32:27 2000 +++ linux-2.4.0-test4-pre5/net/ipv4/netfilter/ip_conntrack_proto_generic.c Fri Jul 14 08:14:11 2000 @@ -41,7 +41,8 @@ /* Returns verdict for packet, or -1 for invalid. */ static int established(struct ip_conntrack *conntrack, struct iphdr *iph, size_t len, - enum ip_conntrack_info conntrackinfo) + enum ip_conntrack_info conntrackinfo, + int *set_reply) { ip_ct_refresh(conntrack, GENERIC_TIMEOUT); return NF_ACCEPT; diff -urN linux-2.4.0-test4-pre5.orig/net/ipv4/netfilter/ip_conntrack_proto_icmp.c linux-2.4.0-test4-pre5/net/ipv4/netfilter/ip_conntrack_proto_icmp.c --- linux-2.4.0-test4-pre5.orig/net/ipv4/netfilter/ip_conntrack_proto_icmp.c Fri Apr 14 18:37:57 2000 +++ linux-2.4.0-test4-pre5/net/ipv4/netfilter/ip_conntrack_proto_icmp.c Fri Jul 14 08:14:27 2000 @@ -70,7 +70,8 @@ /* Returns verdict for packet, or -1 for invalid. */ static int icmp_packet(struct ip_conntrack *ct, struct iphdr *iph, size_t len, - enum ip_conntrack_info ctinfo) + enum ip_conntrack_info ctinfo, + int *set_reply) { /* FIXME: Should keep count of orig - reply packets: if == 0, destroy --RR */ diff -urN linux-2.4.0-test4-pre5.orig/net/ipv4/netfilter/ip_conntrack_proto_tcp.c linux-2.4.0-test4-pre5/net/ipv4/netfilter/ip_conntrack_proto_tcp.c --- linux-2.4.0-test4-pre5.orig/net/ipv4/netfilter/ip_conntrack_proto_tcp.c Tue Jun 20 23:32:27 2000 +++ linux-2.4.0-test4-pre5/net/ipv4/netfilter/ip_conntrack_proto_tcp.c Fri Jul 14 08:23:33 2000 @@ -159,9 +159,11 @@ /* Returns verdict for packet, or -1 for invalid. */ static int tcp_packet(struct ip_conntrack *conntrack, struct iphdr *iph, size_t len, - enum ip_conntrack_info ctinfo) + enum ip_conntrack_info ctinfo, + int *set_reply) { enum tcp_conntrack newconntrack, oldtcpstate; + enum ip_conntrack_dir direction; struct tcphdr *tcph = (struct tcphdr *)((u_int32_t *)iph + iph->ihl); /* We're guaranteed to have the base header, but maybe not the @@ -173,15 +175,16 @@ WRITE_LOCK(&tcp_lock); oldtcpstate = conntrack->proto.tcp_state; + direction = CTINFO2DIR(ctinfo); newconntrack = tcp_conntracks - [CTINFO2DIR(ctinfo)] + [direction] [get_conntrack_index(tcph)][oldtcpstate]; /* Invalid */ if (newconntrack == TCP_CONNTRACK_MAX) { DEBUGP("ip_conntrack_tcp: Invalid dir=%i index=%u conntrack=%u\n", - CTINFO2DIR(ctinfo), get_conntrack_index(tcph), + direction, get_conntrack_index(tcph), conntrack->proto.tcp_state); WRITE_UNLOCK(&tcp_lock); return -1; @@ -190,13 +193,20 @@ conntrack->proto.tcp_state = newconntrack; WRITE_UNLOCK(&tcp_lock); - /* If only reply is a RST, we can consider ourselves not to - have an established connection: this is a fairly common - problem case, so we can delete the conntrack - immediately. --RR */ - if (!(conntrack->status & IPS_SEEN_REPLY) && tcph->rst) { - if (del_timer(&conntrack->timeout)) - conntrack->timeout.function((unsigned long)conntrack); + if (!(conntrack->status & IPS_SEEN_REPLY)) { + /* If only reply is a RST, we can consider ourselves not to + have an established connection: this is a fairly common + problem case, so we can delete the conntrack + immediately. --RR */ + if (tcph->rst) { + if (del_timer(&conntrack->timeout)) + conntrack->timeout.function((unsigned long)conntrack); + } else if (tcph->syn) + /* + * The connection is not considered to be established + * until the 3-way handshake is completed. + */ + *set_reply = 0; } else ip_ct_refresh(conntrack, tcp_timeouts[newconntrack]); diff -urN linux-2.4.0-test4-pre5.orig/net/ipv4/netfilter/ip_conntrack_proto_udp.c linux-2.4.0-test4-pre5/net/ipv4/netfilter/ip_conntrack_proto_udp.c --- linux-2.4.0-test4-pre5.orig/net/ipv4/netfilter/ip_conntrack_proto_udp.c Tue Jun 20 23:32:27 2000 +++ linux-2.4.0-test4-pre5/net/ipv4/netfilter/ip_conntrack_proto_udp.c Fri Jul 14 08:14:41 2000 @@ -47,7 +47,8 @@ /* Returns verdict for packet, and may modify conntracktype */ static int udp_packet(struct ip_conntrack *conntrack, struct iphdr *iph, size_t len, - enum ip_conntrack_info conntrackinfo) + enum ip_conntrack_info conntrackinfo, + int *set_reply) { /* If we've seen traffic both ways, this is some kind of UDP stream. Extend timeout. */