EtherGuard-VPN/example_config/super_mode/README_zh.md
2021-08-27 10:45:19 +00:00

5.6 KiB
Raw Blame History

Etherguard

Super Mode的範例配置檔的說明文件 在了解Super Mode的運作之前建議您先閱讀Static Mode的運作方法,再閱讀本篇會比較好

Super Mode

Super Mode是受到n2n的啟發
分為super node和edge node兩種節點

全部節點都會和supernode建立連線
藉由supernode交換其他節點的資訊以及udp打洞
由supernode執行Floyd-Warshall演算法並把計算結果分發給全部edge node

在super mode模式下設定檔裡面的nexthoptable以及peers是無效的。
這些資訊都是從super node上面下載

SuperMsg

但是比起Static modeSuper mode引入了一種新的 終點ID 叫做 SuperMsg
所有送往Super node的封包都會是這種類型。
這種封包不會在edge node之間傳播收到也會不會轉給任何人如同終點ID == 自己一般

Register

具體運作方式類似這張圖
EGS01
首先edge node發送regiater給super node
super node收到以後就知道這個edge的endpoint IP和埠號。
更新進資料庫以後發布UpdatePeerMsg
其他edge node收到以後就用HTTP API去下載完整的peer list。並且把自己沒有的peer通通加到本地

Ping/Pong

有了peer list以後接下來的運作方式類似這張圖
EGS02
Edge node 會嘗試向其他所有peer發送Ping,裡面會攜帶節點自己的時間
Ping 封包的TTL=0 所以不會被轉發,只會抵達可以直連的節點
收到Ping,就會產生一個Pong,並攜帶時間差。這個時間就是單向延遲
但是他不會把Pong送回給原節點而是送給Super node

轉發表

Super node收到節點們傳來的Pong以後就知道他們的單向延遲了。接下來的運作方式類似這張圖
image
Super node收到Pong以後就會更新它裡面的Distance matrix,並且重新計算轉發表
如果有變動,就發布UpdateNhTableMsg
其他edge node收到以後就用HTTP API去下載完整的轉發表

HTTP API

為什麼要用HTTP額外下載呢?直接UpdateXXX夾帶資訊不好嗎?
因為udp是不可靠協議能攜帶的內容量也有上限。
但是peer list包含了全部的peer資訊長度不是固定的可能超過
所以這樣設計,UpdateXXX單純只是告訴edge node有資訊更新請速速用HTTP下載

而且UpdateXXX本身不可靠說不定根本就沒抵達edge node。
所以UpdateXXX這類資訊都帶了state hash。用HTTP API的時候要帶上
這樣super node收到HTTP API看到state hash就知道這個edge node確實有收到UpdateXXX了。
不然每隔一段時間就會重新發送UpdateXXX給該節點

Guest API

HTTP還有一個API
http://127.0.0.1:3000/api/peerstate?Password=passwd
可以給前端看的,用來顯示現在各節點之間的單向延遲狀況
之後可以用來畫力導向圖。

這個json下載下來有一個叫做infinity的欄位值應該永遠是99999
因為json沒辦法表達無限大。所以大於這個數值的就是無限大不可達的意思
這個數值是編譯時決定的一般不會動。但說不定你想改code改成999呢?
所以有這個欄位,前端顯示時看到數值大於這個,就視為不可達,不用畫線了

接下來你就能了解一下P2P Mode的運作

Config Paramaters

Super mode的edge node有幾個參數

  1. usesupernode: 是否啟用Super mode
  2. connurlv4: Super node的IPv4連線地址
  3. pubkeyv4: Super node的IPv4工鑰
  4. connurlv6: Super node的IPv6連線地址
  5. pubkeyv6: Super node的IPv6工鑰
  6. apiurl: Super node的HTTP(S) API連線地址
  7. supernodeinfotimeout: Supernode Timeout

Super node本身的設定檔

  1. nodename: 節點名稱
  2. privkeyv4: ipv4用的私鑰
  3. privkeyv6: ipv6用的私鑰
  4. listenport: 監聽udp埠號
  5. statepassword: Guest API 的密碼
  6. loglevel: 參考 README_zh.md
  7. repushconfiginterval: 重新pushUpdateXXX的間格
  8. graphrecalculatesetting:
    1. jittertolerance: 抖動容許誤差收到Pong以後一個37ms一個39ms不會觸發重新 計算
    2. jittertolerancemultiplier: 一樣是抖動容許誤差但是高ping的話允許更多誤差
      https://www.desmos.com/calculator/raoti16r5n
    3. nodereporttimeout: 收到的Pong封包的有效期限。太久沒收到就變回Infinity
    4. recalculatecooldown: Floyd-Warshal是O(n^3)時間複雜度,不能太常算。設個冷卻時間
  9. peers: Peer列表參考 README_zh.md
    1. nodeid: 1
    2. pubkey: ZqzLVSbXzjppERslwbf2QziWruW3V/UIx9oqwU8Fn3I=
    3. endpoint: 127.0.0.1:3001
    4. static: true

V4 V6 兩個公鑰

為什麼要分開IPv4和IPv6呢?
因為有這種情況:

OneChannel

這樣的話SuperNode就不知道Node02的ipv4地址就不能幫助Node1和Node2打洞了

TwoChannel

所以要像這樣V4和V6都建立一條通道才能讓V4和V6同時都被處理到