]> err.no Git - linux-2.6/blobdiff - net/netfilter/nf_conntrack_proto_tcp.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/holtmann/bluet...
[linux-2.6] / net / netfilter / nf_conntrack_proto_tcp.c
index 8db13fba10bc823b02c1065634b8894a0789b349..420a10d8eb1ec7fdc449cc4304afcbe00f4b9e98 100644 (file)
@@ -331,12 +331,13 @@ static unsigned int get_conntrack_index(const struct tcphdr *tcph)
 
    I.   Upper bound for valid data:    seq <= sender.td_maxend
    II.  Lower bound for valid data:    seq + len >= sender.td_end - receiver.td_maxwin
-   III.        Upper bound for valid ack:      sack <= receiver.td_end
-   IV. Lower bound for valid ack:      ack >= receiver.td_end - MAXACKWINDOW
+   III.        Upper bound for valid (s)ack:   sack <= receiver.td_end
+   IV. Lower bound for valid (s)ack:   sack >= receiver.td_end - MAXACKWINDOW
 
-   where sack is the highest right edge of sack block found in the packet.
+   where sack is the highest right edge of sack block found in the packet
+   or ack in the case of packet without SACK option.
 
-   The upper bound limit for a valid ack is not ignored -
+   The upper bound limit for a valid (s)ack is not ignored -
    we doesn't have to deal with fragments.
 */
 
@@ -606,12 +607,12 @@ static bool tcp_in_window(const struct nf_conn *ct,
                 before(seq, sender->td_maxend + 1),
                 after(end, sender->td_end - receiver->td_maxwin - 1),
                 before(sack, receiver->td_end + 1),
-                after(ack, receiver->td_end - MAXACKWINDOW(sender)));
+                after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1));
 
        if (before(seq, sender->td_maxend + 1) &&
            after(end, sender->td_end - receiver->td_maxwin - 1) &&
            before(sack, receiver->td_end + 1) &&
-           after(ack, receiver->td_end - MAXACKWINDOW(sender))) {
+           after(sack, receiver->td_end - MAXACKWINDOW(sender) - 1)) {
                /*
                 * Take into account window scaling (RFC 1323).
                 */
@@ -843,8 +844,14 @@ static int tcp_packet(struct nf_conn *ct,
                        /* Attempt to reopen a closed/aborted connection.
                         * Delete this connection and look up again. */
                        write_unlock_bh(&tcp_lock);
-                       nf_ct_kill(ct);
-                       return -NF_REPEAT;
+
+                       /* Only repeat if we can actually remove the timer.
+                        * Destruction may already be in progress in process
+                        * context and we must give it a chance to terminate.
+                        */
+                       if (nf_ct_kill(ct))
+                               return -NF_REPEAT;
+                       return -NF_DROP;
                }
                /* Fall through */
        case TCP_CONNTRACK_IGNORE: