You are browsing a read-only backup copy of Wikitech. The live site can be found at wikitech.wikimedia.org

Difference between revisions of "TCP Fast Open"

From Wikitech-static
Jump to navigation Jump to search
imported>Ema
 
imported>Ema
 
Line 13: Line 13:
* '''TCPSynRetrans:''' number of SYN and SYN/ACK retransmits to break down retransmissions into SYN, fast-retransmits, timeout retransmits, etc.
* '''TCPSynRetrans:''' number of SYN and SYN/ACK retransmits to break down retransmissions into SYN, fast-retransmits, timeout retransmits, etc.
* '''TCPOrigDataSent:''' number of outgoing packets with original data (excluding retransmission but including data-in-SYN). This counter is different from TcpOutSegs because TcpOutSegs also tracks pure ACKs. TCPOrigDataSent is more useful to track the TCP retransmission rate.
* '''TCPOrigDataSent:''' number of outgoing packets with original data (excluding retransmission but including data-in-SYN). This counter is different from TcpOutSegs because TcpOutSegs also tracks pure ACKs. TCPOrigDataSent is more useful to track the TCP retransmission rate.
== Detecting server-side TFO support ==
The initial portion of the 3WHS can be used to check whether a remote TCP server supports TFO. For example, with [https://github.com/secdev/scapy/ scapy] we can craft a SYN packet with the TFO option set and check whether the SYN/ACK response from the server includes the TFO option as well. If that is the case, TFO is enabled on the target server.
<source lang="Python">
from scapy.all import sr1, IP, TCP
dst = "en.wikipedia.org"
dport = 443
res = sr1(IP(dst=dst)/TCP(dport=dport,flags="S",options=[('TFO', '')]), verbose=False)
print 'TFO' in dict(res[1].options)
</source>
== Python client using BSD sockets ==
<source lang="Python">
#!/usr/bin/env python
import sys
import socket
TCP_FASTOPEN = 0x20000000
dest_name = sys.argv[1]
port = 80
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.sendto("HEAD / HTTP/1.0\r\n\r\n", TCP_FASTOPEN, (dest_name, port))
data = s.recv(1024)
s.close()
print data
</source>
== CLI tools ==
'''tshark''' allows to easily filter packets with TFO option set:
<source lang="Bash">
tshark -f 'tcp[tcpflags] & tcp-syn != 0' -Y 'tcp.option_kind == 34'
</source>
'''curl''' version 7.49.0 or greater allows [https://curl.haxx.se/docs/manpage.html#--tcp-fastopen establishing a TCP connection with TFO], albeit [https://github.com/curl/curl/issues/825 not in combination with TLS] as of July 2016.
<source lang="Bash">
curl --tcp-fastopen http://en.wikipedia.org
</source>


== Server key generation ==
== Server key generation ==

Latest revision as of 15:06, 5 July 2016

Metrics

/proc/net/netstat provides a bunch of TFO-related metrics:

  • TCPFastOpenActive: number of successful outbound TFO connections
  • TCPFastOpenActiveFail: number of SYN-ACK packets received that did not acknowledge data sent in the SYN packet and caused a retransmissions without SYN data. Note that the original SYN packet contained a cookie + data, this is not the number of connections to servers that didn’t support TFO
  • TCPFastOpenPassive: number of successful inbound TFO connections
  • TCPFastOpenPassiveFail: number of inbound SYN packets with TFO cookie that was invalid
  • TCPFastOpenCookieReqd: number of inbound SYN packets requesting TFO with TFO set but no cookie
  • TCPFastOpenListenOverflow: number of inbound SYN packets that will have TFO disabled because the socket has exceeded the max queue length

Other interesting metrics are:

  • TCPSynRetrans: number of SYN and SYN/ACK retransmits to break down retransmissions into SYN, fast-retransmits, timeout retransmits, etc.
  • TCPOrigDataSent: number of outgoing packets with original data (excluding retransmission but including data-in-SYN). This counter is different from TcpOutSegs because TcpOutSegs also tracks pure ACKs. TCPOrigDataSent is more useful to track the TCP retransmission rate.

Detecting server-side TFO support

The initial portion of the 3WHS can be used to check whether a remote TCP server supports TFO. For example, with scapy we can craft a SYN packet with the TFO option set and check whether the SYN/ACK response from the server includes the TFO option as well. If that is the case, TFO is enabled on the target server.

from scapy.all import sr1, IP, TCP

dst = "en.wikipedia.org"
dport = 443

res = sr1(IP(dst=dst)/TCP(dport=dport,flags="S",options=[('TFO', '')]), verbose=False)
print 'TFO' in dict(res[1].options)

Python client using BSD sockets

#!/usr/bin/env python

import sys
import socket

TCP_FASTOPEN = 0x20000000

dest_name = sys.argv[1]
port = 80

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.sendto("HEAD / HTTP/1.0\r\n\r\n", TCP_FASTOPEN, (dest_name, port))

data = s.recv(1024)
s.close()

print data

CLI tools

tshark allows to easily filter packets with TFO option set:

tshark -f 'tcp[tcpflags] & tcp-syn != 0' -Y 'tcp.option_kind == 34'

curl version 7.49.0 or greater allows establishing a TCP connection with TFO, albeit not in combination with TLS as of July 2016.

curl --tcp-fastopen http://en.wikipedia.org

Server key generation

RAND=$(openssl rand -hex 16)
NEWKEY=${RAND:0:8}-${RAND:8:8}-${RAND:16:8}-${RAND:24:8}
echo "net.ipv4.tcp_fastopen_key=$NEWKEY" > /etc/sysctl.d/50-tcp_fastopen_key.conf
chmod 600 /etc/sysctl.d/50-tcp_fastopen_key.conf; chown root /etc/sysctl.d/50-tcp_fastopen_key.conf
sysctl -p /etc/sysctl.d/50-tcp_fastopen_key.conf
unset RAND NEWKEY


References