本文目錄
MASQUE 節點連得上,檔案也開始下載,傳輸卻突然停住;此時開啟新的網頁又能正常瀏覽。這與整條代理連線中斷不同。先分辨停住的是單一請求還是所有連線,再檢查 Mihomo 的實際版本與該出站節點使用的 IP 協定堆疊。
下載卡住時,如何判斷隧道是否仍在運作?
Mihomo #3325 是 Linux/ImmortalWrt 使用者的回報:單一 TCP 下載中途不再接收資料,同一條 MASQUE 隧道上的新連線仍正常。回報涉及 alpha-bc76c13 與自行編譯的 alpha-94b13ae;改用 gvisor 後,回報者在自己的比較測試中未再遇到相同停滯。
截至本次查核,該回報仍未結案,維護者尚未確認原因,也沒有已發布的修正。本文提供可還原的排查方法,並非認定所有 MASQUE、所有平台或 v1.19.32 都有此缺陷,也不保證切換後一定恢復。
比較同一節點上的既有連線與新連線
| 觀察到的情況 | 下一步 |
|---|---|
| 某筆下載停住,新請求仍正常 | 記錄停止時間、已接收資料量與實際出站節點,再針對單一欄位比較 IP 協定堆疊。 |
| 既有請求與新請求都失敗,或 MASQUE 無法建立連線 | 先處理設定、節點或連線本身的錯誤;單一連線停滯的回報無法解釋所有斷網情況。 |
| 短時間測試暫時正常 | 保留觀察結果,但不能因此排除長連線才會出現的問題,也不必立即擴大測試流量。 |
確認實際核心與 with_gvisor 編譯支援
先另外備份目前可用的設定,記下目標節點名稱、完整的 ip-stack 原始內容、實際核心版本,以及下載工具的請求資訊。圖形介面用戶端的版本不等於核心版本;命令列中的另一份 Mihomo 也無法代表應用程式正在執行的那一份。
以下 mihomo 代表正在執行的核心執行檔。若核心由用戶端或路由器外掛內嵌,請依實際路徑呼叫;不要只根據命令搜尋路徑中的另一個程式判斷。查看版本輸出中的 Use tags,確認是否包含 with_gvisor。
mihomo -v固定於 v1.19.32 的原始碼與回報使用的 94b13ae 原始碼,都支援 MASQUE 的 ip-stack 欄位。已查核的實作將空值視為 auto,而 auto 會選擇 mips;gvisor 則要求編譯時包含 with_gvisor。這裡的 mips 是出站 IP 協定堆疊選項,不是安裝核心時選擇的處理器架構。
本次比較僅適用於使用使用者空間 IP 協定堆疊的 MASQUE 設定。network 為 h3-l4proxy 時,不會經過此堆疊,無法用 ip-stack.mode 進行相同比較;不要為了套用本文而切換 network。
若未編入這項支援,固定版本的原始碼會傳回 gVisor IP stack requires the with_gvisor build tag。遇到此錯誤應撤銷測試設定,無須反覆重新載入。舊版或其他分支可能不認得或忽略此欄位;設定檢查通過,也不足以證明實際採用了該欄位。
部分語言的文件可能仍保留較早的 auto 說明,因此本文依明確版本的固定實作核對其意義。v1.19.32 支援這項設定,不代表此次回報已證明該正式版受到影響。不要為了比較而貿然安裝 Alpha 核心。
只在目標 MASQUE 節點切換 ip-stack
修改位置在既有的 type: masque 出站節點內,ip-stack 與 type、server 等欄位位於同一層。這與 TUN 入站的 stack 不同;將 gvisor 寫入 tun.stack,無法完成本文的出站比較。
以下僅是要併入目標節點的部分內容,並非完整設定。原本已有 ip-stack 時,只修改其中的 mode,保留其他項目;原本沒有則記錄下來,以便測試結束後確實還原。
ip-stack:
mode: gvisor保留原設定,逐一節點比較
找出實際處理失敗請求的節點
在連線紀錄中確認請求使用目標 MASQUE 節點,不要只憑目前的策略群組名稱猜測。保存原訂閱或機上的設定、目標節點的原始內容,以及先前已確認可用的備用節點。
在能持續保存的副本中修改 mode
在自行維護的機上設定副本,或用戶端明確支援且可持續保留的覆寫設定中,只將該節點的 ip-stack.mode 改為 gvisor。遠端訂閱更新可能覆蓋快取;若無法可靠保存,先聯絡設定維護者,不要直接修改暫存檔。
檢查設定,並確認應用程式確實載入
使用目前核心的設定檢查功能;直接執行 Mihomo 時,可依實際路徑使用 -t 與 -f。儲存後,核對最終設定中的目標節點、執行中的核心及啟動紀錄;若有設定或編譯支援錯誤,就恢復原副本。
以新請求進行比較
重新請求同一個目標檔案,保持節點、網路與其他設定不變。先前已建立的 TCP 連線,不能視為切換 IP 協定堆疊後的新請求。記錄結果後,再決定是否保留這次設定。
如何判斷比較結果是否改善?
選擇自己有權存取、且不是安裝套件的測試檔案,預先限制測試時間與流量。先記錄原設定下的表現,再以相同條件重試。不必照搬回報中的超大檔案,也不要因為短時間內未重現,就不斷增加下載量。
若再次停住,保留既有紀錄,同時發出一筆新的短請求:舊下載的接收量不再增加、新請求卻正常,才接近回報的特徵。測速數字、單次開啟網頁或沒有錯誤紀錄,都不足以證明長連線已恢復。
保留這五項驗證結果
- 實際核心版本、Use tags 與目標節點設定,都對應同一份正在執行的核心。
- 最終設定只有目標 ip-stack.mode 依計畫變更,原始內容與獨立備份仍可使用。
- 同一目標檔案的新請求能持續接收資料;另須記錄是達到時限、主動取消,還是自然完成,三者不能混為一談。
- 保留停滯時的新連線比較結果、連線的實際出站節點與簡短紀錄,避免將一般斷網或策略群組切換誤判為單一連線故障。
- 重新載入設定並再次選取該節點後,設定仍保留,實際請求結果也與上次一致;短時間測試的結論只適用於該觀察時段。
失敗時如何還原並回報?
若出現設定錯誤、編譯支援不足或連線變差,恢復目標節點原有的 ip-stack 內容;原本沒有此項時,移除這次新增的部分。重新載入並驗證原設定,再切回先前已可用的備用節點或設定即可,無須重裝或清除所有資料。
即使 gvisor 比較測試改善了目前請求,也僅代表此環境的暫時結果,仍不能宣稱專案已修正。若兩種設定都失敗,或所有新連線也失敗,應保留證據,依實際錯誤繼續檢查,不能一律歸為相同的 IP 協定堆疊問題。
回報時提供實際核心版本與編譯標籤、平台、實際 mode、最小化且移除敏感資訊的設定、請求停止時間與接收量,以及同一隧道的新連線結果。移除 private-key、帳號、訂閱 Token 及其他敏感資訊;無須公開完整憑證,也不必為了回報持續傳輸大檔案。
本文已查核官方文件與固定版本的原始碼,並未在實際路由器上重現此故障,也未獨立驗證回報者的效能數據。日後是否確認原因、發布修正或調整預設行為,仍須以專案維護者的新結論及明確版本紀錄為準。
