linux中TCP Fast Open 測試筆記二

來源:互聯網
上載者:User
於是回頭重新好好讀了一下 TFO 的原理,發現自己對 TFO 的理解是有問題的 - 原先我以為在 SYN 裡是可以直接帶上請求資料的 - 而這很容易被攻擊。實際上的流程應該是:
  1. 用戶端發送 SYN 包,包尾加的是一個 FOC 請求,只有 4 位元組。
  2. 伺服器端收到 FOC 請求,驗證後根據來源 IP 位址產生 COOKIE(8 位元組),將這個 COOKIE 載入 SYN+ACK 包的末尾發送回去。
  3. 用戶端緩衝住擷取到的 COOKIE 可以給下一次使用。
  4. 下一次請求開始,用戶端發送 SYN 包,這時候包後面帶上緩衝的 COOKIE,然後就是要正式發送的資料。
  5. 伺服器端驗證 COOKIE 正確,將資料交給上層應用處理得到響應結果,然後在發送 SYN+ACK 時,不再等待用戶端的 ACK 確認,即開始發送響應資料。
示圖如下:
所以可以總結兩點:

 


    第一次請求是不會有時間節約的效果的,測試至少要 httping -F -c 2。
    從第二次開始節約的時間可以認為是第一個來回,httping 本身是個 HEAD 請求,可以認為是 50% 的節約。

但是用 -c 2 運行依然沒有看到 RTT 變化。這時候用stap 'probe kernel.function("tcp_fastopen_cookie_gen") {printf("%d ", $foc->len)}' 命令發現這個最重要的產生 COOKIE 的函數(net/ipv4/tcp_fastopen.c裡)居然一直沒有被觸發!

認真閱讀了一下調用這個函數的 tcp_fastopen_check 函數(net/ipv4/tcp_ipv4.c裡),原來前面首先有一步檢查 sysctl 的邏輯:

 代碼如下 複製代碼

    if ((sysctl_tcp_fastopen & TFO_SERVER_ENABLE) == 0 ||
        fastopenq == NULL || fastopenq->max_qlen == 0)
        return false;

這個 TFO_SERVER_ENABLE 常量是 2。而我電腦預設的 net.ipv4.tcp_fastopen 值是 1。1 只開啟用戶端支援 TFO,所以這裡要改成 2(或者 3,如果你不打算把用戶端搬到別的主機上測試的話)。

重新開始 httping 測試,RTT 依然沒有縮短。這時候的 stap 命令發現 tcp_fastopen_cookie_gen 函數雖然觸發了,但是函數裡真正幹活的這段邏輯依然沒有觸發(即 crypto_cipher_encrypt_one):

 代碼如下 複製代碼

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();
}

我試圖通過 stap 'probe kernel.function("tcp_fastopen_cookie_gen"){printf("%s ", $$locals$$)}' 來查看這個 ctx 是什麼內容。輸出顯示 ctx 結構裡的元素值都是問號。

目前就卡在這裡。

為了驗證除了這步沒有其他問題,我”野蠻”的通過 systemtap 修改了一下 tcp_fastopen_cookie_gen 裡的變數。命令如下:

 代碼如下 複製代碼

stap 'probe kernel.function("tcp_fastopen_cookie_gen") { $foc->len = 8 }'

賦值為 8,就是 TCP_FASTOPEN_COOKIE_SIZE 常量的值。

然後再運行測試,就發現 httping 的第二次啟動並執行 RTT 時間減半了(最後那個 F 應該就是標記為 Fastopen 的意思吧)!可見目前問題就出在這裡。

 代碼如下 複製代碼

$ 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

註:上面這個強制賦值 foc->len 沒有改變其實 foc->val 是空的事實,所以只能是測實驗證一下想法,真用的話多用戶端之間會亂套的。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.