diff mbox

TCP CLOSE_WAIT unacceptable ACK behavior and RFC 793 compliance

Message ID CADVnQy=cw6Z+8tTUHp6-b0+0M6iPar+VFTZAc+sgfm8tpZbQ2A@mail.gmail.com
State RFC, archived
Delegated to: David Miller
Headers show

Commit Message

Neal Cardwell May 8, 2014, 7:20 p.m. UTC
On Thu, May 8, 2014 at 1:13 PM,  <P.Fiterau-Brostean@science.ru.nl> wrote:
> In short, when the SERVER is in CLOSE_WAIT state and the CLIENT sends an
> ACK  (or a FIN+ACK) with a valid seq number but an unacceptable ack
> number, the SERVER either responds with an ACK (re-transmission of last
> ACK sent by the server) or it doesn't respond at all. I attached a capture

Yes, this does not seem to match the RFC.

Have you tried this scenario with SEG.ACK > SND.NXT in other states,
e.g. ESTABLISHED?

Have you checked what other OSes do?

Here would be a proposed change, if we decide to send an ACK instead
of dropping (please excuse the formatting; for the real patch I'd use
git send-email...):


I am playing with that.

neal

---

BTW, here is a packetdrill test case to reproduce this scenario:

// Set up a server listening socket.
0.000 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0    setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0    bind(3, ..., ...) = 0
+0    listen(3, 1) = 0

// Establish connection
+0    < S 0:0(0) win 32792 <mss 1460,nop,nop,sackOK>
+0    > S. 0:0(0) ack 1    <mss 1460,nop,nop,sackOK>
+.010 < . 1:1(0) ack 1 win 32792

+0 accept(3, ..., ...) = 4

+.010 < F. 1:1(0) ack 1 win 32792
+0    > . 1:1(0) ack 2
+.010 < . 2:2(0) ack 500 win 32792
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

P.Fiterau-Brostean@science.ru.nl May 9, 2014, 12:01 a.m. UTC | #1
First of all, thanks for your very fast reply. My posts on stackoverflow
and other sites were starting to gather cobwebs.

> Have you checked what other OSes do?
Yes, so far we ran this scenario on Ubuntu 13.10, Ubuntu 12.04 and a very
recent version on MacOs. For all these 3 systems we got the same behavior
in terms of the server CLOSE_WAIT state. We also tested the Windows 8
implementation, where we found that we'd always get a timeout. We suspect
that for versions of Windows starting from Vista we would get a similar
timeout behavior.

>Have you tried this scenario with SEG.ACK > SND.NXT in other states,
>e.g. ESTABLISHED?
From what I can remember, it was only in CLOSE_WAIT from 4 states tested
that we encountered this behavior but will need to check again. I attached
here the partial state models we obtained for Ubuntu 13.10 and Windows 8.
The Ubuntu 13.10 model lacks 3 inputs: ACK and FIN+ACK segment with the
valid seq but invalid ack (to avoid non-determinism) , and a RST+ACK with
valid seq and invalid ack because it proved too difficult to incorporate.
In the diagrams we use some condensed notations: V = an acceptable value,
INV = an unacceptable value, LAS = last ack sent, CLSN = sequence number
on the client side...

Perhaps it might interest you how we came up with models. We used tools
that can actively and automatically learn/infer a state model for symbolic
i/o blackbox systems, we then placed an adapter over the learner software
in order to map those symbolic i/o to packets that would be sent
to/received from the server. These tools always fail when the system
behaves non-deterministically. In the scenario I showed, the system
behaved non-deterministically with regards to the inputs given (flags, seq
and ack). Once I eliminated those inputs and the time constraints were
suppressed, a deterministic 4 state model was learned.

packetdrill could perhaps be used as an adapter for learning niches of TCP
for Linux systems in the future. So far, we had to make do with Scapy,
which can be slow and unreliable. Our plan, aside from advancing the
current algorithms, is to incorporate more parameters or to learn
different niches of TCP, as well as to learn other protocols and see if
the implementation meets the specification.

I will rerun the experiments tomorrow to see if ACK/timeout occurs in
other states other than CLOSE_WAIT for Ubuntu 13.10.

Cheers, Paul
diff mbox

Patch

diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index d6b46eb..08f2f55 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3383,11 +3383,15 @@  static int tcp_ack(...
                goto old_ack;
        }

-       /* If the ack includes data we haven't sent yet, discard
-        * this segment (RFC793 Section 3.9).
+       /* "If the ACK acks something not yet sent (SEG.ACK > SND.NXT)
+         * then send an ACK, drop the segment, and return." (RFC793
+         * Section 3.9, p. 72).
         */
-       if (after(ack, tp->snd_nxt))
+       if (after(ack, tp->snd_nxt)) {
+               /* RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] */
+               tcp_send_challenge_ack(sk);
                goto invalid_ack;
+       }

        if (icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS ||
            icsk->icsk_pending == ICSK_TIME_LOSS_PROBE)