So I went back to read the TFO principle and found that I had a problem with my understanding of TFO-I thought it was possible to bring the request data directly in SYN-and it was easy to attack. The actual process should be:
- The client sends a SYN packet, Baulinga is a FOC request, only 4 bytes.
- The server side receives the FOC request, after verifying, generates the cookie (8 bytes) According to the source IP address, sends this cookie to load Syn+ack the packet the end to send back.
- The client caches the COOKIE that is obtained to be used for the next time.
- The next time the request starts, the client sends the SYN packet, which is followed by a cached COOKIE, followed by the data to be officially sent.
- Server-side authentication COOKIE is correct, the data to the upper application processing to get the response results, and then when sending Syn+ack, no longer wait for the client ACK acknowledgement, that is, start sending response data.
The figure below is as follows:
So you can sum up two points:
The first request will not have time to save the effect of testing at least httping-f-C 2.
From the second start to save time can be considered the first round-trip, httping itself is a head request, can be considered to be 50% savings.
However, operating with-C 2 still does not see RTT changes. This is the most important function to generate cookies with the Stap ' probe kernel.function ("Tcp_fastopen_cookie_gen") {printf ("%d", $foc->len)} ' command (net/ IPV4/TCP_FASTOPEN.C) Incredibly has not been triggered!
Carefully read the Tcp_fastopen_check function called this function (NET/IPV4/TCP_IPV4.C), the previous first step to check the logic of the SYSCTL:
The code is as follows |
Copy Code |
if ((Sysctl_tcp_fastopen & tfo_server_enable) = = 0 | | Fastopenq = = NULL | | Fastopenq->max_qlen = 0) return false; |
This tfo_server_enable constant is 2. And my computer's default Net.ipv4.tcp_fastopen value is 1. 1 only open Client support TFO, so change this here to 2 (or 3 If you don't plan to move the client to another host for testing).
Restarting the httping test, the RTT is still not shortened. This time the STAP command found that the Tcp_fastopen_cookie_gen function was triggered, but the logic that actually worked in the function still did not fire (ie, crypto_cipher_encrypt_one):
The code is as follows |
Copy Code |
void Tcp_fastopen_cookie_ Gen (__be32 addr, struct Tcp_fastopen_cookie *foc) { __be32 peer_addr[4] = {addr, 0, 0, 0}; struct Tcp_fastopen_context *ctx; Rcu_read_lock (); ctx = rcu_dereference (TCP_FASTOPEN_CTX); if (ctx) { crypto_cipher_encrypt_one (ctx-> TFM, Foc->val, (__U8 *) peer_addr); Foc->len = tcp_fastopen_cookie_size; } Rcu_read_unlock (); } |
I tried to see what this $$ was by Stap ' probe kernel.function ("Tcp_fastopen_cookie_gen") {printf ("%s", $ $locals ctx)}. The output shows that the element values in the CTX structure are question marks.
It's stuck here right now.
To verify that there is no other problem with this step, I have "savage" changed the variables in the Tcp_fastopen_cookie_gen through Systemtap. The order is as follows:
The code is as follows |
Copy Code |
Stap ' Probe kernel.function ("Tcp_fastopen_cookie_gen") {$foc->len = 8} ' |
An assignment of 8 is the value of the Tcp_fastopen_cookie_size constant.
Then run the test and find that Httping's second run of RTT time is halved (the last F should be labeled Fastopen)! It is obvious that the problem is here.
The code is as follows |
Copy Code |
$ httping-f-G Http://192.168.0.100-c 2 PING 192.168.0.100:80 (/URL): Connected to 192.168.0.100:80 (154 bytes), seq=0 time=-45.60 ms Connected to 192.168.0.100:80 (154 bytes), seq=1 time=-23.43 Ms F ---http://192.168.0.100/url ping statistics--- 2 Connects, 2 OK, 0.00% failed, time 2069ms Round-trip Min/avg/max = 23.4/34.5/45.6 ms |
Note: The above forced assignment Foc->len does not change the fact that the foc->val is empty, so it is only a test to verify the idea, really use the words between the multiple clients will be messy.