<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      單連接多路徑,合并多服務(wù)器公網(wǎng)帶寬---MPTCP---aggligator

      https://sliphua.work/try-mptcp/#%E5%BC%80%E5%8F%91%E8%80%85%E6%8E%A5%E5%85%A5

       

       

      對單一連接進(jìn)行拆分發(fā)送合并接收,有拓展傳輸層 TCP 的 MPTCP 標(biāo)準(zhǔn),也有使用普通 TCP 自定義應(yīng)用層協(xié)議來實(shí)現(xiàn)的純上層工具。理論上來說,前者的上限更高,后者兼容度更廣。

      這幾天分別嘗試了一下 Linux 內(nèi)核支持的 MPTCP 和基于一般 TCP 的應(yīng)用層工具 aggligator,來合并兩臺(tái)內(nèi)網(wǎng)互聯(lián)的服務(wù)器的帶寬,公網(wǎng)帶寬一臺(tái) 5 Mbps,一臺(tái) 4 Mbps。測試結(jié)果振奮人心,帶寬真的合并了;同時(shí)出乎意料,內(nèi)核級的 MPTCP 慢了一些??赡軠y試次數(shù)不夠,可能內(nèi)核優(yōu)化還不完善,也可能部分配置項(xiàng)需要精調(diào)。

      兩只龜龜服務(wù)器的帶寬疊加前后

      合成大烏龜

      標(biāo)準(zhǔn) MPTCP

      兼容性考量

      標(biāo)準(zhǔn)多路徑 TCP 應(yīng)當(dāng)可以概括為對 TCP 協(xié)議的一種拓展,是在 TCP 協(xié)議頭中定義的一堆專用的 TCP Options 和相關(guān)邏輯。

      在握手階段,任一端就可以通過收到的相關(guān) Option 知道另一端是否支持 MPTCP,對端支持則后續(xù)接著使用 MPTCP 專用字段溝通需要的額外信息;對端不支持則無縫切換一般 TCP 行為邏輯。

      MPTCP socket 兼容一般 TCP

      Apple 部分內(nèi)置應(yīng)用 2013 年就開始使用 MPTCP v0(RFC 6824),Linux 內(nèi)核自 5.6 開始支持 MPTCP v1(RFC 8684)。但終端碼農(nóng)角度的文章不論中外目前還是很少,好多問題需要自己啃規(guī)范原文找到答案。幸運(yùn)的是,相關(guān)內(nèi)核開發(fā)者為了進(jìn)一步降低接入門檻,寫了很多文檔和代碼工具,大大降低了理解和接入成本。

      “多路徑”理解

      MPTCP 在握手期間雙方生成一個(gè) key 并交換,用于判斷后續(xù)對話的是哪個(gè)連接。

      握手后,不論包從哪里哪個(gè) IP 來,從哪個(gè)端口來,只要拿著對應(yīng)的 key,就可能與內(nèi)核建立一條新的子流 Subflow,內(nèi)核幫你把數(shù)據(jù)合并入一個(gè) socket。流與流之間另用一個(gè) Address ID 字段區(qū)分。

      發(fā)包的時(shí)候,內(nèi)核看看已有的子流,選一個(gè)發(fā)出去。如果對面有建議過還可走哪條道、自己有多張網(wǎng)卡等,就可能嘗試新建一條子流。也可以發(fā)建議給對面,建議對面主動(dòng)與建議地址建立子流。

      子流的建立、維護(hù)、關(guān)閉等行為與一般 TCP 連接類似,但是“連接”是一個(gè)整體的概念,子流是連接的一部分。對內(nèi)核來說,子流是 MPTCP 連接的一條路徑;對應(yīng)用層來說,子流是完全透明的,只需要像使用一般 TCP socket 一樣使用 MPTCP socket。

      MPTCP socket 多路徑傳遞信息

      完整步驟還要加上哈希認(rèn)證、排序重傳、路徑管理模式、調(diào)度策略等,精準(zhǔn)的行為邏輯建議閱讀規(guī)范原文,RFC 8684: TCP Extensions for Multipath Operation with Multiple Addresses。

      服務(wù)端接入

      Linux MPTCP 開發(fā)者提供了一些實(shí)用工具幫助接入 MPTCP,包括:

      • mptcpd: 提供用戶空間的路徑管理接口。
      • mptcpize: 讓目標(biāo)程序或服務(wù)創(chuàng)建的 TCP socket 都變?yōu)?MPTCP socket。

      假設(shè),要在某臺(tái) Debian 服務(wù)器 2024 端口搭建一個(gè) Minecraft Java 服務(wù)器,稱為主服;另一臺(tái)服務(wù)器稱為中轉(zhuǎn)服。

      中轉(zhuǎn)配置

      規(guī)范允許服務(wù)端以中轉(zhuǎn) IP 主動(dòng)與客戶端建立子流,也允許將中轉(zhuǎn)地址作為建議發(fā)給客戶端,讓客戶端主動(dòng)建立。

      考慮到公網(wǎng),NAT 普及,太多時(shí)候只能客戶端主動(dòng)與服務(wù)器建聯(lián)。所以最實(shí)用簡單的,我們將中轉(zhuǎn)服某一端口 NAT 內(nèi)網(wǎng)轉(zhuǎn)發(fā)到主服,即完成中轉(zhuǎn)配置。這樣也使不經(jīng) NAT 的少數(shù)客戶端的體驗(yàn)一致了,都是客戶端主動(dòng)建立子流,避免偶現(xiàn)奇奇怪怪的問題。

      子流建立時(shí)序

      具體而言,配置中轉(zhuǎn)服轉(zhuǎn)發(fā)到主服,又有兩種模式可選:

      • 單轉(zhuǎn)發(fā)單服務(wù)模式:一個(gè) NAT 端口轉(zhuǎn)發(fā),對應(yīng)一個(gè)主服 MPTCP 服務(wù)端口。這種模式目前配置起來最簡單,就是需要為每一個(gè)服務(wù)端口都配置一個(gè) NAT 中轉(zhuǎn)地址。
      • 單轉(zhuǎn)發(fā)多服務(wù)模式:一個(gè) NAT 端口轉(zhuǎn)發(fā),可以對應(yīng)多個(gè)主服 MPTCP 服務(wù)端口。這種模式要求主服分配一個(gè)專用的端口給內(nèi)核,配置中轉(zhuǎn)服轉(zhuǎn)發(fā)到主服這個(gè)專用端口上。內(nèi)核目前尚未完全支持這種模式,Linux 內(nèi)核開發(fā)者有提出暫時(shí)的變通方案,但是筆者沒有試驗(yàn)成功。

      這兩種轉(zhuǎn)發(fā)模式,在中轉(zhuǎn)服上的配置不同。不過正好,多服務(wù)模式本人沒有嘗試成功,所以后文只介紹單轉(zhuǎn)發(fā)單服務(wù)模式的配置。

      假設(shè)中轉(zhuǎn)服同樣選用 2024 端口,NAT 內(nèi)網(wǎng)轉(zhuǎn)發(fā)到主服的 2024 端。

      值得注意的是,由于 MPTCP 的相關(guān)參數(shù)含于 TCP 數(shù)據(jù)包頭,L7 層的端口轉(zhuǎn)發(fā),即通過與目的端新建一條連接,然后不斷中轉(zhuǎn)兩條連接的數(shù)據(jù)體實(shí)現(xiàn)的轉(zhuǎn)發(fā),不能用于服務(wù)端 MPTCP 中轉(zhuǎn)。

      主服準(zhǔn)備

      首先,升級內(nèi)核至 6.1+,并確保 MPTCP 已經(jīng)啟用。舊內(nèi)核可能不支持后續(xù)操作。

      sudo -i sysctl net.mptcp.enabled
       

      可選地,打開 MPTCP 的校驗(yàn)和功能。規(guī)范建議在不可控環(huán)境中開啟??蛻舳朔?wù)端只要有一端開啟,這個(gè)功能就是雙端生效的。幾次測試下來沒看到速度差別。看自己需求了。

      sudo -i sysctl -w net.mptcp.mptcp_checksum=1
       

      你可能需要采用某種方法使這處變更在重啟后依然生效。

      主服路徑管理

      接下來,我們配置主服向 MPTCP 客戶端發(fā)送中轉(zhuǎn) IP 和相關(guān)端口,告訴客戶端還有中轉(zhuǎn)路徑可走。

      這一步可以通過單純調(diào)整內(nèi)核配置來實(shí)現(xiàn),也可以通過使用 mptcpd 用戶空間應(yīng)用來實(shí)現(xiàn)。

      純內(nèi)核配置

      單純調(diào)整內(nèi)核配置的優(yōu)點(diǎn)是簡單快捷,不需要編寫編譯額外代碼,缺點(diǎn)是

      • 要求中轉(zhuǎn)端口號與主服端口號一致;
      • 會(huì)針對所有的 MPTCP 連接生效,即不區(qū)分本地端口是否為 2024。

      假設(shè)中轉(zhuǎn)服 IP 為 2.2.2.2,執(zhí)行下面的命令,即可。

      sudo ip mptcp endpoint add 2.2.2.2 signal
       
      用戶空間接口

      或者,我們使用 mptcpd,在用戶空間自定義靈活的路徑管理策略。mptcpd

      • 不要求中轉(zhuǎn)端口號與主服端口號一致;
      • 支持特定連接特定處理,可以僅針對 2024 端口的連接,向?qū)Χ税l(fā)送地址建議。

      不過,目前 mptcpd 尚不支持建議會(huì)經(jīng) NAT 中轉(zhuǎn)的 IP,需要像下面這樣調(diào)整。

      安裝編譯依賴。

      sudo apt install build-essential autoconf automake libtool autoconf-archive libell-dev
       

      克隆 mptcpd

      git clone https://github.com/multipath-tcp/mptcpd.git
      cd mptcpd
       

      找到 upstream_announce 函數(shù)(截至發(fā)文,src/netlink_pm_upstream.c 第 219 行),該函數(shù)用于向?qū)Χ税l(fā)送地址建議。注意開頭的偵聽調(diào)用 (232-235 行),由于無法偵聽外部 IP 會(huì)失敗,由此阻止了我們對外發(fā)送中轉(zhuǎn)建議。調(diào)用上方 @todo 也提到這處偵聽不是強(qiáng)制的。為了盡早嘗鮮,我們直接將這塊調(diào)用注釋掉,保存。

      編譯,安裝。

      ./bootstrap
      ./configure
      make
      sudo make install
       

      接著,我們就可以通過創(chuàng)建 mptcpd 路徑管理插件,自定義路徑管理策略,使得每建立一個(gè) 2024 端口的 MPTCP 連接,我們都向?qū)Χ税l(fā)送中轉(zhuǎn)地址建議。

      各連接地址之間是平級的,內(nèi)核允許客戶端先走中轉(zhuǎn)地址創(chuàng)建連接,再走主服地址新增子流。要做到這一點(diǎn),可以直接向?qū)Χ税l(fā)送所有可用地址建議,對端會(huì)自行篩選;也可以自行編寫邏輯判斷當(dāng)前地址,再向?qū)Χ税l(fā)送剩余地址建議。本文不作展開。

      閱讀 mptcpd 插件開發(fā) wiki,跟隨示例,編寫我們需要的插件。下面給出一個(gè)簡單的例子,新建一個(gè)文件夾,把下面的三個(gè)文件放進(jìn)去。

      1/3,suggest.c:

      #include <arpa/inet.h>
      #include <ell/ell.h>
      #include <mptcpd/id_manager.h>
      #include <mptcpd/path_manager.h>
      #include <mptcpd/plugin.h>
      
      #define PLUGIN_NAME suggest // 插件名,以 suggest 為例
      
      #define MATCH_PORT 2024 // 主服端口
      #define SUGGEST_IP "2.2.2.2" // 中轉(zhuǎn)機(jī) IP
      #define SUGGEST_PORT 2024 // 中轉(zhuǎn)機(jī)端口
      
      // 在 MPTCP 連接建立時(shí),
      static void on_connection_established(
        mptcpd_token_t token,
        struct sockaddr const *laddr,
        struct sockaddr const *raddr,
        bool server_side,
        struct mptcpd_pm *pm)
      {
        // 獲取本地端口,
        struct sockaddr_in *sin = (struct sockaddr_in *)laddr;
        uint16_t port = ntohs(sin->sin_port);
      
        // 不是服務(wù)端口,不處理;
        if (port != MATCH_PORT) {
          return;
        }
      
        // 是服務(wù)端口,則生成中轉(zhuǎn)地址的結(jié)構(gòu)體,
        struct sockaddr_in alt_addr = {};
        alt_addr.sin_family = AF_INET;
        alt_addr.sin_addr.s_addr = inet_addr(SUGGEST_IP);
        alt_addr.sin_port = htons(SUGGEST_PORT);
      
        // 為其注冊一個(gè) Address ID 用于給內(nèi)核分辨,
        struct mptcpd_idm *const idm = mptcpd_pm_get_idm(pm);
        mptcpd_aid_t const id = mptcpd_idm_get_id(idm, (struct sockaddr *)&alt_addr);
        if (id == 0) {
          l_error("Unable to map suggesting address to ID.");
          return;
        }
      
        // 然后向?qū)Χ税l(fā)送。
        if (mptcpd_pm_add_addr(pm, (struct sockaddr *)&alt_addr, id, token) != 0) {
          l_error("Unable to suggest address to connection with token '%d'.", token);
          return;
        }
      
        l_info("Suggested subflow address to connection with token '%d'.", token);
      }
      
      // 把上面的函數(shù)存到一個(gè)路徑管理器的操作集中,
      static struct mptcpd_plugin_ops const pm_ops = {
        .connection_established = on_connection_established,
      };
      
      // 在插件初始化時(shí),
      static int suggest_init(struct mptcpd_pm *pm)
      {
        static char const name[] = L_STRINGIFY(PLUGIN_NAME);
      
        // 注冊上述操作集。
        if (!mptcpd_plugin_register_ops(name, &pm_ops)) {
          l_error("Failed to initialize suggest path manager.");
      
          return -1;
        }
      
        l_info("MPTCP suggest path manager initialized.");
      
        return 0;
      }
      
      static void suggest_exit(struct mptcpd_pm *pm)
      {
        l_info("MPTCP suggest path manager exited.");
      }
      
      // 注冊自身為一個(gè) MPTCP 路徑管理插件。
      MPTCPD_PLUGIN_DEFINE(PLUGIN_NAME,
                          "Suggest path management plugin",
                          MPTCPD_PLUGIN_PRIORITY_DEFAULT,
                          suggest_init,
                          suggest_exit);
       

      2/3,configure.ac:

      AC_PREREQ([2.71])
      AC_INIT([suggest_plugin],[0.1])
      
      AM_INIT_AUTOMAKE([foreign])
      LT_INIT([disable-static])
      
      AC_CONFIG_SRCDIR([suggest.c])
      AC_CONFIG_MACRO_DIRS([m4])
      
      # ---------------------------------------------------------------
      # Checks for programs.
      # ---------------------------------------------------------------
      AC_PROG_CC
      AM_PROG_CC_C_O
      
      # ---------------------------------------------------------------
      # Checks for libraries.
      # ---------------------------------------------------------------
      # Find mptcpd.
      PKG_CHECK_MODULES([MPTCPD], [mptcpd])
      
      # Determine default mptcpd plugin directory.
      PKG_CHECK_VAR([MPTCPD_PLUGINDIR], [mptcpd], [plugindir])
      
      # ---------------------------------------------------------------
      # Generate our build files.
      # ---------------------------------------------------------------
      AC_CONFIG_FILES([Makefile])
      AC_OUTPUT
       

      3/3,Makefile.am:

      ## "plugindir" specifies where plugins should be installed.
      ## Override as needed if the default mptcpd plugin directory
      ## is not used.
      plugindir = @MPTCPD_PLUGINDIR@
      plugin_LTLIBRARIES = suggest.la
      
      suggest_la_SOURCES = suggest.c
      suggest_la_CFLAGS  = $(MPTCPD_CFLAGS)
      suggest_la_LDFLAGS = -no-undefined -module -avoid-version
      suggest_la_LIBADD  = $(MPTCPD_LIBS)
       

      編譯,安裝。

      autoreconf
      ./configure
      make
      sudo make install
       

      編輯 mptcpd 配置文件 /usr/local/etc/mptcpd/mptcpd.conf,將路徑管理插件,即 path-manager 字段,由 addr_adv 設(shè)為剛編譯安裝好的 suggest,保存。

      修改內(nèi)核參數(shù),使 MPTCP 使用用戶模式的路徑管理器(默認(rèn)為內(nèi)核模式)。只有用戶模式的路徑管理器才能對不同連接進(jìn)行不同配置。

      sudo -i sysctl -w net.mptcp.pm_type=1
       

      你可能需要采用某種方法使這處變更在重啟后依然生效。

      重啟 mptcp 服務(wù)。

      sudo systemctl restart mptcp
       

      確認(rèn) mptcp 服務(wù)正確加載了 suggest 插件。

      sudo systemctl status mptcp
       

      上面的輸出中,應(yīng)包含 MPTCP suggest path manager initialized.

      主服服務(wù)啟動(dòng)

      啟動(dòng)前,確認(rèn)每個(gè)連接所允許新增的子流數(shù)量不為 0。下面命令的輸出中, subflow 字段后面的數(shù)字即為該數(shù)量。

      ip mptcp limits show
       

      可以使用如下的命令進(jìn)行調(diào)整。

      sudo ip mptcp limits set subflow 2
       

      你可能需要采用某種方法使這處變更在重啟后依然生效。

      主服服務(wù)程序有多種方法可以接入,選一種即可。

      1. 使用 mptcpize。如果在上一節(jié)選用了 mptcpd 管理路徑,mptcpize 應(yīng)當(dāng)已經(jīng)隨 mptcpd 同時(shí)完成了編譯安裝。如果沒有裝過,可以運(yùn)行:

        sudo apt install mptcpize
         

        使用時(shí),只需在服務(wù)程序運(yùn)行命令前加 mptcpize run,例如:

        mptcpize run java -Xmx1024M -Xms1024M -jar server.jar --port 2024 --nogui
         

        mptcpize 同樣支持 systemd 服務(wù),可以查閱該命令 help 信息。

        mptcpize 劫持目標(biāo)程序?qū)?Linux socket 函數(shù)的調(diào)用,將 IPv4/IPv6 的 TCP 流,直接替換成 MPTCP 協(xié)議的對應(yīng)流。簡單有效。

      2. 或者,安裝使用 socat 工具,將 2024 端口的 MPTCP 連接轉(zhuǎn)換為服務(wù)程序所在端口的 TCP 連接。例如:

        socat TCP4-LISTEN:2024,fork,protocol=0x106,nodelay TCP:127.0.0.1:52024
        java -Xmx1024M -Xms1024M -jar server.jar --port 52024 --nogui
         

        注意:這種方法會(huì)讓服務(wù)程序認(rèn)為所有的客戶端都來自本機(jī),可能會(huì)影響一些功能。

      3. 或者,使用 TUN 等虛擬網(wǎng)卡技術(shù),透明代理 2024 端口的入站 MPTCP 連接為服務(wù)程序所在端口的 TCP 連接。有些前沿代理工具已經(jīng)可以做到這一點(diǎn)。

      4. 如果合適,嘗試聯(lián)系開發(fā)者添加支持。

      5. 使用原生 socket 函數(shù)的開發(fā)者,可以參考本文#開發(fā)者接入一節(jié),完成 MPTCP 適配。

      至此,服務(wù)端的配置全部完成。對支持 MPTCP 的客戶端,會(huì)使用 MPTCP 協(xié)議,并在建連后向客戶端建議中轉(zhuǎn)地址創(chuàng)建子流。對不支持的客戶端,會(huì)無縫回落使用一般 TCP 協(xié)議。

      客戶端接入

      Linux

      首先,升級內(nèi)核至 5.15+,并確認(rèn) MPTCP 已經(jīng)啟用。舊內(nèi)核可能不支持某些操作。

      sudo -i sysctl net.mptcp.enabled
       

      在啟動(dòng)客戶端前,確認(rèn)每個(gè)連接允許接受的建議地址數(shù)量、每個(gè)連接允許新增的子流數(shù)量均不為 0。下面命令的輸出中, add_addr_acceptedsubflow 字段后面的數(shù)字即分別為上述數(shù)量。

      ip mptcp limits show
       

      可以使用如下的命令進(jìn)行調(diào)整。

      sudo ip mptcp limits set add_addr_accepted 2
      sudo ip mptcp limits set subflow 2
       

      你可能需要采用某種方法使這些變更在重啟后依然生效。

      Linux 客戶端程序有多種方法可以接入,選一種即可。

      1. 安裝使用 socat 工具,將 TCP 流轉(zhuǎn)換為連接主服的 MPTCP 流,例如:

        socat TCP4-LISTEN:2024,fork TCP:1.1.1.1:2024,protocol=0x106,nodelay
         

        然后,運(yùn)行客戶端程序,讓其以本機(jī) 2024 端口為服務(wù)端。

      2. 或者,使用 mptcpize。安裝:

        sudo apt install mptcpize
         

        配置:由于安裝 mptcpize 同時(shí)也會(huì)安裝 mptcpd,而 mptcpd 默認(rèn)又總會(huì)將“每個(gè)連接允許接受的地址建議數(shù)量”設(shè)為 0,我們需要修改其配置,在 /etc/mptcpd/mptcpd.conf 文件中取消掉 addr-flags 字段的注釋,保存。mptcpd 在安裝期間可能已經(jīng)重設(shè)了一次接受數(shù)量限制,重啟它,再次確認(rèn)接受數(shù)量限制、新增子流數(shù)量限制不為 0:

        sudo sed -i 's/# addr-flags=subflow/addr-flags=subflow/' /etc/mptcpd/mptcpd.conf # 編輯配置
        sudo systemctl restart mptcp # 重啟
        ip mptcp limits show # 檢查
         

        運(yùn)行:在客戶端運(yùn)行命令前加 mptcpize run 即可,例如

        mptcpize run wget https://example.com/
         

        mptcpize 同樣支持處理 systemd 服務(wù),可以查閱該命令 help 信息。

      3. 或者,使用 TUN 等虛擬網(wǎng)卡技術(shù),透明代理所有/特定出站 TCP 為 MPTCP 連接。有些前沿代理工具已經(jīng)可以做到這一點(diǎn)。

      4. 如果合適,嘗試聯(lián)系開發(fā)者添加支持。

      5. 使用原生 socket 函數(shù)的開發(fā)者,可以參考本文#開發(fā)者接入一節(jié),完成 MPTCP 適配。

      Windows

      Windows 內(nèi)核尚未支持 MPTCP。WSL 官方內(nèi)核也不支持,但可以自己編譯調(diào)整。嘗試讓 Windows 上的客戶端程序,通過 WSL 以 MPTCP 協(xié)議轉(zhuǎn)發(fā)連接。

      首先在 WSL 內(nèi),安裝編譯依賴。

      sudo apt install build-essential flex bison dwarves libssl-dev libelf-dev
       

      將 WSL 內(nèi)核源碼克隆到本地。

      git clone https://github.com/microsoft/WSL2-Linux-Kernel.git
      cd WSL2-Linux-Kernel
       

      調(diào)整配置文件開啟 MPTCP 支持:編輯 .config,找到 #CONFIG_MPTCP is not set 這一行,將其改為 CONFIG_MPTCP=y,保存。

      cp Microsoft/config-wsl .config
      sed -i 's/#CONFIG_MPTCP is not set/CONFIG_MPTCP=y/' .config
       

      編譯內(nèi)核。假設(shè)我們將編譯后的內(nèi)核文件放到 C:\wsl\bzImage

      make -j$((`nproc`+1))
      cp arch/x86/boot/bzImage /mnt/c/wsl/
       

      Windows 端,創(chuàng)建或編輯 %USERPROFILE%\.wslconfig 文件,添加以下內(nèi)容,保存。

      [wsl2]
      kernel=C:\\wsl\\bzImage
       

      Windows 端,完全關(guān)閉 WSL 實(shí)例。

      wsl --shutdown
       

      重新進(jìn)入 WSL 實(shí)例后,就可以走前文 Linux 接入流程了??梢赃x用 socat 接入方式,然后讓 Windows 運(yùn)行的客戶端程序,連接本機(jī) 2024 端口。

      確保 WSL 默認(rèn)開啟的 localhostForwarding 功能沒有設(shè)為關(guān)閉。如果依然連不通,可能需要調(diào)整防火墻、解除 UWP 回環(huán)限制、和/或 更新 Windows/WSL 版本。

      也可以在 WSL 起一個(gè)本地代理,Windows 端通過環(huán)境變量、系統(tǒng)代理或 TUN 等方式連接,將所有/特定 TCP 轉(zhuǎn)換為 MPTCP 連接。文章頭圖即為使用 WSL 代理前后的 Windows 測試結(jié)果。

      未經(jīng)涂畫加工的測試結(jié)果截圖

      可以看到,使用 MPTCP 前,平均下載速度為 467 KiB/s (3.83 Mbps),僅主服提供網(wǎng)絡(luò)帶寬;使用 MPTCP 后,平均下載速度升至 1.04 MiB/s (8.72 Mbps),兩臺(tái)服務(wù)器共同提供網(wǎng)絡(luò)帶寬,公網(wǎng)流量十分穩(wěn)定。

      MPTCP 子流新增需要額外的時(shí)間,這里的數(shù)據(jù)不足以計(jì)算出 MPTCP 的傳輸效率。按照 Linux 內(nèi)核開發(fā)者 @matttbe 的說法(golang/go#56539 評論),大量數(shù)據(jù)傳輸 MPTCP 相比 TCP 帶來的額外開銷應(yīng)該在 1% 左右。

      OpenWrt

      可以安裝使用 OpenMPTCProuter,將經(jīng)過軟路由的所有/特定 TCP 連接轉(zhuǎn)換為 MPTCP 連接。

      開發(fā)者接入

      使用原生 socket 函數(shù)的開發(fā)者,可以修改創(chuàng)建 IPv4/IPv6 TCP socket 時(shí)的參數(shù),創(chuàng)建 IPPROTO_MPTCP 協(xié)議的 socket,即完成 MPTCP 適配。如: socket(AF_INET, SOCK_STREAM, IPPROTO_MPTCP)。其中,IPPROTO_MPTCP == IPPROTO_TCP + 256 == 0x106

      考慮不支持 MPTCP 的環(huán)境,可以參考 Go 語言的官方實(shí)現(xiàn),src/net/mptcpsock_linux.go,整合了下面的錯(cuò)誤處理和回落判斷邏輯。

      錯(cuò)誤處理

      Ref: golang/go#56539 評論

      MPTCP socket 在創(chuàng)建時(shí)可能產(chǎn)生:

      • EINVAL 22 Invalid argument:內(nèi)核完全不認(rèn)識(shí) MPTCP。(Linux 內(nèi)核 5.5-)
      • EPROTONOSUPPORT 93 Protocol not supported:MPTCP 沒有編譯進(jìn)內(nèi)核。(Linux 內(nèi)核 5.6+)
      • ENOPROTOOPT 92 Protocol not available:內(nèi)核包含 MPTCP,但沒有啟用。(net.mptcp.enabled 為 0)
      • 其他錯(cuò)誤:MPTCP 被 SELinux、BPF 或其他安全機(jī)制禁用。

      如果第一次創(chuàng)建 MPTCP socket 時(shí),就返回前兩類錯(cuò)誤(EINVALEPROTONOSUPPORT),即意味著當(dāng)前運(yùn)行內(nèi)核不可能支持 MPTCP??梢詫⒔Y(jié)果緩存起來,后續(xù)創(chuàng)建 socket 時(shí)直接使用一般 TCP socket。其他錯(cuò)誤則可能是臨時(shí)的,可以在每次遇到時(shí)才使用一般 TCP socket。

      回落判斷

      Ref: multipath-tcp/mptcp_net-next#294

      Linux 內(nèi)核 5.16+ 提供了 SOL_MPTCP 常量,可以用來判斷當(dāng)前 socket 連接是否在使用 MPTCP。使用 getsockopt 函數(shù)來獲取 socket 的 SOL_MPTCP 選項(xiàng)時(shí),如果產(chǎn)生錯(cuò)誤,即返回值 < 0,即表示當(dāng)前 socket 不使用 MPTCP。這可能是因?yàn)橄嚓P(guān) socket 創(chuàng)建時(shí)并未指定 MPTCP 協(xié)議,也可能是因?yàn)檫B接對端不支持 MPTCP,回落到了一般 TCP。

      應(yīng)用層模擬實(shí)現(xiàn)

      標(biāo)準(zhǔn) MPTCP 的落地程度還不高,需要內(nèi)核支持,而且目前子流斷線后不會(huì)重連,自定義行為需要寫 C。幸運(yùn)的是,我們可以轉(zhuǎn)而自定義應(yīng)用層協(xié)議,通過構(gòu)建雙端配合的 TCP 代理,來實(shí)現(xiàn)類似的功能,同時(shí)兼容更多的系統(tǒng)。aggligator 就是這樣一個(gè)能拆分聚合 WiFi、Ethernet、USB 等網(wǎng)口連接的應(yīng)用層工具。在筆者隨手進(jìn)行的幾次測試中,aggligator 多數(shù)時(shí)候發(fā)揮了比當(dāng)前版本的原生 MPTCP 更佳的性能。

      客戶端代理拆分發(fā)送,服務(wù)端代理合并接收

      由于應(yīng)用層實(shí)現(xiàn)沒有統(tǒng)一的規(guī)范標(biāo)準(zhǔn),這里給出 aggligator 的一種可行配置步驟,不作過多深入。

      安裝

      服務(wù)端和客戶端的安裝流程基本一致,首先安裝 Rust 工具鏈,然后使用 cargo 安裝 aggligator-util,一個(gè)基于 aggligator 的命令行工具。國內(nèi)網(wǎng)絡(luò)環(huán)境可能需要換源加速。

      cargo install aggligator-util
       

      服務(wù)端配置

      假設(shè)將服務(wù)端程序所運(yùn)行的服務(wù)器稱為主服,另一服務(wù)器稱為中轉(zhuǎn)服,服務(wù)程序已經(jīng)運(yùn)行在 7003 端口。

       內(nèi)網(wǎng) IP公網(wǎng) IP
      主服 10.0.1.1 30.1.1.1
      中轉(zhuǎn)服 10.0.1.2 30.1.1.2

      主服運(yùn)行:

      agg-tunnel server --tcp 7001 --port 7003
       

      中轉(zhuǎn)服:任意方式 TCP 轉(zhuǎn)發(fā)自身 7002 端口到 10.0.1.1:7001。

      客戶端配置

      如果服務(wù)器公網(wǎng)和內(nèi)網(wǎng)對應(yīng)同一個(gè)網(wǎng)絡(luò)接口,很可能會(huì)有一條子流被“優(yōu)化”掉——這是因?yàn)?aggligator 類似 MPTCP,主要是為了更好地支援單客戶端/單服務(wù)端的多網(wǎng)口而設(shè)計(jì)的,aggligator 的策略更為激進(jìn)??梢灾付?--tcp-link-filterinterface-ip,來避免這種情況。

      執(zhí)行:

      agg-tunnel client --tcp-link-filter interface-ip --tcp 30.1.1.1:7001 --tcp 30.1.1.2:7002 --port 7003:2024
       

      最后,運(yùn)行客戶端程序,以本機(jī) 2024 端口為服務(wù)端。

      結(jié)語

      MPTCP 是一個(gè)很有意思的協(xié)議,但目前落地程度還不高。內(nèi)核開發(fā)、上層語言支持、相關(guān)應(yīng)用層工具都處在比較初級的階段。這既是機(jī)遇,也是挑戰(zhàn)。

      我是一名前端新人,抓住大四的小尾巴不務(wù)正業(yè),對 TCP、MPTCP 等網(wǎng)絡(luò)協(xié)議的理解很膚淺,本文只是記錄了在嘗鮮 MPTCP 過程中的一些經(jīng)驗(yàn),希望能幫助到有需要的人。如有錯(cuò)誤之處,還望海涵,歡迎聯(lián)系指正。

       

      posted @ 2024-06-13 15:46  張同光  閱讀(133)  評論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 天天综合色一区二区三区| 国产色悠悠视频在线观看| 日本真人添下面视频免费| 人妻系列中文字幕精品| 久久精品国产99久久6| 青草99在线免费观看| 亚洲乱码国产乱码精品精大量| 亚洲国产午夜理论片不卡| 岑溪市| 国产午夜精品在人线播放| 国产第一页浮力影院入口| 亚洲人妻系列中文字幕| 欧美亚洲h在线一区二区| 天天做天天爱夜夜爽导航| 国产在线无遮挡免费观看| 妇女性内射冈站hdwww000| 自拍偷区亚洲综合第二区| 中文午夜乱理片无码| 成人无码午夜在线观看| 成人无码一区二区三区网站| av网站免费线看精品| 免费看一区无码无a片www| 色综合天天综合天天综| 亚洲精品国产综合麻豆久久99| 开化县| 国产美女直播亚洲一区色| 精品国产迷系列在线观看| 亚洲人成影院在线观看| 亚洲精品99久久久久久欧美版 | 亚洲国产成人AⅤ片在线观看| 欧美性xxxxx极品| 成人免费区一区二区三区 | 国产麻豆成人精品av| 日韩成av在线免费观看| 日韩在线观看精品亚洲| AV区无码字幕中文色| 色综合久久精品亚洲国产| 男女猛烈无遮挡免费视频| 国产粉嫩一区二区三区av| 四虎永久精品在线视频| 亚洲色欲色欲WWW在线丝|