如果你看OpenVxx的manual,裏面有個鏈接:
http://sites.inka.de/sites/bigred/devel/tcp-tcp.html
我研究這個問題研究了好幾年,從2013年就開始了,後來我煩了,於是見人就跟人說, 用UDP隧道,不要用TCP隧道,不然重傳疊加會讓連接崩潰!!
那些年,我還是術業不精,難免要照本宣科,扯些什麼TCP就是按序接收,重傳保序之類云云。
我太老實了。
如若我想構建隧道,比如CDN動態加速的隧道,我肯定是要用這隧道去運輸一些別的東西,換句話說, 這隧道肯定不是端到端的!
那麼OK,類似丟包,重傳這些,肯定有端到端的協議來保證,無論是TCP,還是QUIC,還是基於UDP的其它可靠傳輸,均有這樣的處理邏輯,我一箇中間隧道,何必去care這些!
那麼我如何既採用TCP構建隧道,又忽略掉TCP的複雜的處理邏輯呢?
很好的想法,在給出一個解答之前,我先來解釋一下 爲什麼非要用TCP來構建隧道。
- 因爲運營商可能會對UDP不友好啊…
- 因爲中間路由器會對TCP友好啊…
- …
路由器不是故意對TCP友好,而是UDP太難處理了,無連接,無session,機器內部還要維護一個表,這根本就不是路由器的主職啊。
哈哈…
所以呢,入鄉隨俗,就按着要求的來,就用TCP構建隧道唄。
中間路由器能看到的只是一個TCP頭而已,它哪能知道我這TCP頭是端到端按照TCP協議協商的,還是手工封裝上去的呢?它根本區分不出來!
那好,那就這樣:
- 截獲感興趣流的數據包,封裝一個隧道對端可以識別的TCP頭。
- 把這個僞造的TCP包扔進網絡。
- 這個包進入中間路由器,被路由器認爲是一個TCP流的包。
- 這個包按照路由器的規則排隊等待發送。
- …
- 數據包到達隧道對端,被識別,剝掉TCP頭…
有意思吧。TCP頭只是爲了迎合中間路由器的區分服務。
你穿雙皮鞋裝X就會被誤認爲是經理,但事實上並不是經理,對吧,但大部分人就是以貌取人,這就對了,迎合他就是了。
經理,您好!
如果我把IP地址和端口按照我自己能識別的規則散列開來,中間路由器就會認爲這是不同的stream,那這裏就是你發揮的空間了。
浙江溫州皮鞋溼,下雨進水不會胖!