I can read in an article (about packet checking sequence) that if the ACK number is invalid, we drop the TCP packet.
If it is valid, we then do a 0-payload-check, if the payload's size is 0, we ignore the packet.
Is there a difference?
Basically none. DROP will increment the drop counter; ignore doesn't.
Related
In a situation where both client and server sets their respective sequence number to 0, I read that the following is true:
C-->S: SYN=1, SEQ=0 (No data bytes)
C<--S: SYN=1, SEQ=0, ACK=1 (No data bytes)
C-->S: SEQ=1, ACK=1 (Data bytes optional)
In the third part, I understand the server is expecting the next sequence number to be 1, but aren't sequence numbers supposed to be set to initial_seq_num + sent_data_bytes_num? Since there was no data bytes sent in the first part of the handshake shouldn't the seq # be 0?
Is this just an exception during the handshake or are segments sent to with no data bytes supposed to increment the sequence number by 1 if they can be sent at all?
(There is a similar Q & A but the answer doesn't explain if this is an exception during the handshake phase OR if this happens after a TCP connection has been establish. I'm not even sure if a segment with no data bytes can even be sent. I'm assuming you can't)
ADDED It seems TCP keep-alive packets have no payload either. RFC 1122 says in these packets, SEG.SEQ = SND.NXT-1, and because this sequence number will be an already ACKed number, and a duplicate ACK will be sent, so as to keep the sequence number of the server the same.
Otherwise, I couldn't find any indications of what needs to be done when the sequence number is correct but there is no payload. I might be wrong since I only briefly scanned the document, but there is also no statement of rules of sequence numbering during the handshake except for examples.
In RFC 1122, it says
Unfortunately, some misbehaved TCP implementations fail to respond to a segment with SEG.SEQ = SND.NXT-1 unless the segment contains data.
So I'm assuming it depends on each implementation, but if there is any statement of a) the sequence numbering during handshake, and b) how to behave when the sequence # is correct but there is no payload, I would really appreciate it if someone could point me to that part.
Thanks!
The first ACK (that occurs as part of Handshake) acknowledges the reception of SYN from the other end. The SYN segment does not carry any data. But to allow the provision for acknowledging the reception of SYN, the first ACK is incremented though no payload is present.
The 32-bit acknowledgement field, say x, on the TCP header
tells the other host that "I received all the bytes up until and including x-1,
now expecting
the bytes from x and on". In this case, the receiver may have received some
further bytes, say x+100 through x+180,
but it hasn't yet received x-th byte yet.
Is there a case that, although the receiver hasn't received
x through x+100 bytes but received the bytes say x+100 through x+180,
the receiver is acknowledging that it received x+180?
One resource I read indicates the acknowledgement of bytes received despite a gap in the earlier bytes.
However, every other source tells
"acknowledgement of x tells all bytes up until x-1 are received".
Are there any exceptional cases? I'm looking to verify this.
TIA.
This can be achieved by TCP option called SACK.
Here, client can say through a duplicate ACK that it has only up to particular packet number 2 (sequence number of packet) in order and append SACK(Selective Acknowledgement) option for the range of contiguous packets received like packets numbered 4 to 5 (sequence number). This in turn shall enable the server to retransmit only the packets(3 sequence number) that were not received by the client.
Provided below an extract from RFC 2018 : TCP Selective Acknowledgement Options
The SACK option is to be sent by a data receiver to inform the data
sender of non-contiguous blocks of data that have been received and
queued. The data receiver awaits the receipt of data (perhaps by
means of retransmissions) to fill the gaps in sequence space between
received blocks. When missing segments are received, the data
receiver acknowledges the data normally by advancing the left window
edge in the Acknowledgement Number Field of the TCP header. The SACK
option does not change the meaning of the Acknowledgement Number
field.
From the TCP RFC at https://www.rfc-editor.org/rfc/rfc793.txt:
3.3. Sequence Numbers
A fundamental notion in the design is that every octet of data sent
over a TCP connection has a sequence number. Since every octet is
sequenced, each of them can be acknowledged. The acknowledgment
mechanism employed is cumulative so that an acknowledgment of sequence
number X indicates that all octets up to but not including X have been
received.
That seems pretty clear to me, the sequence number stops at the first missing data.
Why do we need the sequence number and the next sequence number field in the TCP header?
Below is a TCP header from a packet captured using wireshark.
First, fields in Wireshark enclosed by [brackets] are computed fields - they're not in the packet. That next sequence number field shown by Wireshark is one such field. Wireshark is computing that by taking the 'sequence number' field and adding it to the payload size of your packet. It's no surprise then that the difference between these two numbers is 1430 - a common TCP payload size.
Sequence numbers in TCP are in units of bytes - they basically say, what byte location in the TCP stream this packet's payload is inserted at.
The 'acknowledged' sequence number shows how many bytes I'm acknowledging as having received.
Since TCP is bidirectional, each end has to declare
Where the bytes its transmitting should go in the stream and
What bytes that you've sent me that I've received.
As such, each TCP packet has two fields that refer to sequence numbers - the 'sequence number' field, and the 'acknowledgment number' field.
Without the 'sequence number' field, the receiving end wouldn't be able to tell if packets were received out of order. Without the 'acknowledgment number' field, the transmitting end wouldn't know if some of his packets had been dropped and the receiver never received them.
Because TCP is a reliable pipe. This means that packets are delivered in sequence (and only once) even though the lower layers don't offer that guarantee. IN order to do this TCP needs housekeeping data, acks, nacks,....
https://en.wikipedia.org/wiki/Transmission_Control_Protocol
The 'next sequence' is an artifact of wireshark, its not actually in the TCP header, ws is just telling you the next packet in its capture file
I am trying to understand the rationale behind such a design. I skimmed through a few RFCs but did not find anything obvious.
It's not particularly subtle - it's so that the SYN and FIN bits themselves can be acknowledged (and therefore re-sent if they're lost).
For example, if the connection is closed without sending any more data, then if the FIN did not consume a sequence number the closing end couldn't tell the difference between an ACK for the FIN, and an ACK for the data that was sent prior to the FIN.
SYNs and FINs require acknowledgement, thus they increment the stream's sequence number by one when used.
I am not sure if people find this obvious but I have two questions:
During the 3-way handshake, why is ACK = SEQ + 1 i.e. why am I ACKing for the next byte that I am expecting from the sender?
After the handshake, my ACK = SEQ + len. Why is this different from the handshake? Why not just ACK for the next byte I am expecting as well (the same as during the handshake)?
I know I must've missed out a basic point somewhere. Can someone clarify this?
This is because the first byte of sequence number space corresponds to the SYN flag, not to a data byte. (The FIN flag at the end also consumes a byte of sequence number space itself.)
During the handshake you're synchronizing. The sequence number is the known data. Once you've synced, the data length is the known data as well as a useful pseudo-random verifier. Sender knows how much he sent and if you reply, he assumes you got it. This is easier than reply with, say a checksum or hash of the data, and is usually sufficient.
Both the SYN and FIN flags cause the sequence number of the stream to increment by one. Thus
SYN (seq x) -------------->
<--- SYNACK (ack x+1, seq y)
ACK (seq x+1, ack y+1) --->
Is your three way handshake. It's done that way because SYNs and FINs require acknowledgement of receipt. That way everyone can be on the same page during the lifetime of the connection.
Theoretically any packet in part of the TWHS could have payload, but if either of the packets with the SYN flag set have payload, the opposite side needs to acknowledge both data AND the flag.