4

I'm doing a research project, which needs to split tcp connection. so I have some pecular questions, which may happen in my development. The problem is understanding of TCP SACK-permitted negotiation. I read the RFC and can't find answer there.

For 3-way tcp handshake between two tcp programs: A and B. if A send a TCP SYN to B with SACK-permitted, will B surely respond a SYN/ACK packet with SACK-permitted? if B reply with a TCP SYN/ACK without SACK-permitted, does it mean

1) SACK-permmited is enabled only on A. A can selectively acknowledge tcp packets from A, but A can't selectively acknowledge tcp packets from B.

or

2) SACK-permmited is not enabled on both A and B

if A sends a TCP SYN to B without SACK-permitted, may B respond a SYN/ACK packet with SACK-permitted?

besides, why SACK-permitted is allowed or disallowed? it depends on the Operating system or kernel setting or something else? is it possible to control it? thanks!

3 Answers 3

4

SACK was added later, so there is a need for backward compatibility, both for end hosts and for middleboxes (also see below). The SACK-permitted option fulfills just that.

SACK-permitted is sent from A to B to indicate that A is willing to receive SACK options. For SACK handling (as for most retransmission handling), TCP can be thought of as consisting of two simplex connections with different state each. So it is perfectly legal (but uncommon) to have SACK traveling only in one direction (the reverse direction of the SACK-permitted during SYN or SYNACK).

Normally, you may want to leave SACK enabled, as it improves performance. However, there were (and maybe still are) firewalls and NAT boxes out there that change the SEQ and ACK header fields but are unaware of SACK and thus do not correspondingly adapt the sequence numbers in SACK options. This can lead to connections hanging (as SACK has acknowledged a different segment which has not been received). This is the reason you may want to disable SACK even if both machines do support it.

SACK can be disabled (for testing or with the abovementioned ugly middleboxes present) on *BSD systems (including MacOS X) by entering sysctl -w net.inet.tcp.sack=0 and reenabled by setting it back to 1. On Linux, sysctl -w net.ipv4.tcp_sack=0 achieves the same effect.

The first paragraph of section 4 in RFC 2018 allows SACK to be sent when SACK-permitted has been received. Normally, a SACK-capable host will announce SACK-permitted. I cannot imagine a useful scenario where a SACK-capable host will not advertise SACK-permitted, but will use SACK (an unrealistic example would be a middlebox badly fiddling with SACKs in one direction only). Therefore, I do not expect SACK used in one direction only.

A quick test with Wireshark against Linux, MacOSX (probably generalizable to *BSD) and an HP printer shows that they will respond with SACK-permitted in the SYNACK exactly when SACK-permitted was in the SYN. However, I see nothing in the RFC that would require or encourage this behaviour.

4
  • If A send a SYN or SYN/ACK with Sack-permitted, but B doesn't. Then A can accept SACK from B, but because B doesn't support Sack-permitted. I'm just wondering whether B knows how to send SACK or not. Besides, about the one direction SACK travelling, are there any reference or related articles/papers? thanks!
    – misteryes
    Jun 5, 2013 at 10:29
  • Besides, if A send a SYN to B without sack-permitted, will B respond a SYN/ACK with sack-permitted?
    – misteryes
    Jun 5, 2013 at 10:30
  • The first paragraph of section 4 in RFC 2018 allows SACK to be sent when SACK-permitted has been received. Normally, a SACK-capable host will announce SACK-permitted. I cannot imagine a useful scenario where a SACK-capable host will not advertise SACK-permitted, but will use SACK (an unrealistic example would be a middlebox badly fiddling with SACKs in one direction only). Therefore, I do not expect SACK used in one direction only. Jun 5, 2013 at 11:03
  • 1
    A quick test with Wireshark against Linux, MacOSX (probably generalizable to *BSD) and an HP printer shows that they will respond with SACK-permitted in the SYNACK exactly when SACK-permitted was in the SYN. However, I see nothing in the RFC that would require or encourage this behaviour. Jun 5, 2013 at 11:07
1

SACK-permitted may be lost due to packet loss (some bytes in TCP header that were sent in the handshaking messages are dropped). This maybe because of PMTUD is not functioning well at your end. Try to reduce manually the MTU size at the your end.

0

This is a question that, unless Van Jacobsen or his colleagues happened to be hanging out in this forum, is likely going to entail a great deal of effort on the part of whomever attempts to answer it as you've asked. If you think about it, the level of research required to answer your question would be as great or greater than the research project you're currently engaged in. This is likely going to strike most folks as lacking somewhat in parity.

However, many of us have also had occasion to have to ask tough questions where answers were not obvious or nor readily available. While in my case, I'd ultimately have to find the answer to such questions myself, I was fortunate enough to have helpful folks to get me pointed in the right direction...

I don't currently have root access on two BSD-unix systems, but if I did... I know selective ACks can be controlled with sysctl. On my Mac, the entry that enables SACKs is net.inet.tcp.sack. When enabled, it has a value of 1; to disable, sysctl -w net.inet.tcp.sack=0. I'd set various scenarios up and use tcpdump to test your problems.

Others may have different hints for you...

1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .