Centos

TCP 源埠增加 2,即使對於 curl / wget 也是如此

  • September 25, 2017

當使用 curl 和 wget 時,如果源埠不是手動設置的(比如 curl 中的 –local-port),源 TCP 埠總是偶數,並且會增加 2,而不是 1。

EG:在 tcpdump 中,當我建立連接時,我看到源埠 45080 被使用,然後下一個連接將使用 45082,而不是 45801。使用本地埠我可以強制它使用奇數埠,並且 tcpdump 確認這些埠被成功使用.

這導致我在網路測試台中出現問題,我無法終生弄清楚是什麼控制了隱式 tcp 埠選擇。我可以改變範圍,但我不能改變“增量”。

使用 centos7 和“3.10.0-514.el7.x86_64”核心。

在 tcpdump 中,我使用 wget 和 curl 看到了相同的行為,這讓我相信這不是 curl 特定的問題,而是使用引擎蓋機制來選擇埠的任何東西。

此外,如果我看到 curl 使用埠 45080,例如,我知道它將使用的下一個埠是 45082。如果我強制 –local-port 為 50000,然後再次 curl 沒有 –local-port,它將是45082,就像一個單獨的計數器增加它一樣,不受“最後”使用的埠的影響。

或者,如果執行與上述步驟相同的操作,但不是強制埠 50000,而是強制它使用 45082,它可能要選擇的埠,然後我再次使用 curl 而不強製本地埠,它將選擇 45083 ,那麼如果它再次選擇 45084,那麼 45086…

我可以讓它自然地選擇一個奇數的唯一另一種方法是,如果我將範圍限制為奇數個埠。

是否有系統呼叫或某種核心操作來選擇源埠,有沒有辦法改變它?

謝謝!

我相信我能夠證明核心本身就是以這種方式增加埠的。

Strace 顯示 wget 和 curl 呼叫 connect() 而不呼叫 bind() 來顯式設置源埠。

我寫了一個python腳本來模擬同樣的事情,看起來3.1核心增加了2,而2.6核心沒有。

有趣的是,這僅在使用 connect() 時才成立,如果您綁定到埠 0,從而讓核心選擇下一個可用埠,這幾乎是隨機的。

我的腳本:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('10.28.0.2', 80))
addr = s.getsockname()
print addr[1]
s.close()

輸出:

$ python port_test.py
45008
$ python port_test.py
45010
$ python port_test.py
45012

引用自:https://serverfault.com/questions/875438