diff -ru linux-orig/net/ipv4/netfilter/ip_nat_helper.c linux-stable/net/ipv4/netfilter/ip_nat_helper.c --- linux-orig/net/ipv4/netfilter/ip_nat_helper.c 2005-03-02 02:37:49.000000000 -0500 +++ linux-stable/net/ipv4/netfilter/ip_nat_helper.c 2005-04-06 00:42:48.736295496 -0400 @@ -72,15 +72,23 @@ LOCK_BH(&ip_nat_seqofs_lock); - /* SYN adjust. If it's uninitialized, or this is after last - * correction, record it: we don't handle more than one - * adjustment in the window, but do deal with common case of a - * retransmit */ - if (this_way->offset_before == this_way->offset_after - || before(this_way->correction_pos, seq)) { - this_way->correction_pos = seq; - this_way->offset_before = this_way->offset_after; - this_way->offset_after += sizediff; + /* SYN adjust. In the case of a retransmit, ip_nat_seq_adjust has + * added offset_before to client's seq, so subtract it to test + * for retransmit here */ + if (seq - this_way->offset_before != this_way->correction_pos) { + /* If it's uninitialized, or this is after last correction, + * record it. We don't handle more than one adjustment in + * the window */ + seq -= this_way->offset_after; + if (this_way->offset_before == this_way->offset_after + || before(this_way->correction_pos, seq)) { + /* Since ip_nat_seq_adjust has added + * offset_after, subtract it to store + * the client's seq in correction_pos */ + this_way->correction_pos = seq; + this_way->offset_before = this_way->offset_after; + this_way->offset_after += sizediff; + } } UNLOCK_BH(&ip_nat_seqofs_lock);