O SACK foi adicionado posteriormente, portanto, há uma necessidade de compatibilidade com versões anteriores, tanto para hosts finais quanto para middleboxes (veja também abaixo). A opção SACK-permitted
preenche exatamente isso.
SACK-permitted
é enviado de A para B para indicar que A está disposto a receber opções de SACK. Para o manuseio de SACK (como para a maioria dos manuseios de retransmissão), o TCP pode ser considerado como consistindo de duas conexões simplex com estados diferentes cada. Portanto, é perfeitamente legal (mas incomum) ter o SACK viajando somente em uma direção (a direção reversa do SACK-permitted
durante SYN ou SYNACK).
Normalmente, você pode querer deixar o SACK ativado, pois melhora o desempenho. No entanto, existem (e talvez ainda existam) firewalls e caixas NAT que alteram os campos de cabeçalho SEQ e ACK, mas não têm conhecimento do SACK e, portanto, não adaptam os números de seqüência nas opções do SACK. Isso pode levar a conexões pendentes (como SACK reconheceu um segmento diferente que não foi recebido). Esta é a razão pela qual você pode querer desabilitar o SACK, mesmo que as duas máquinas o suportem.
O SACK pode ser desativado (para testes ou com as middleboxes presentes acima mencionadas) em sistemas * BSD (incluindo MacOS X) inserindo sysctl -w net.inet.tcp.sack=0
e reenabled configurando-o de volta para 1. No Linux, sysctl -w net.ipv4.tcp_sack=0
atinge o mesmo efeito.
O primeiro parágrafo da seção 4 da RFC 2018 permite que o SACK seja enviado quando o SACK permitido tiver recebido. Normalmente, um host com capacidade para SACK anunciará SACK permitido. Não consigo imaginar um cenário útil em que um host com capacidade para SACK não anunciará SACK permitido, mas usará o SACK (um exemplo irreal seria uma middlebox mal mexendo com SACKs em apenas uma direção). Portanto, não espero que o SACK seja usado apenas em uma direção.
Um teste rápido com o Wireshark contra o Linux, MacOSX (provavelmente generalizável para * BSD) e uma impressora HP mostra que eles responderão com o SACK permitido no SYNACK exatamente quando o SACK-permitido estiver no SYN. No entanto, não vejo nada no RFC que exija ou incentive esse comportamento.