文章閱讀頁通欄

更通用的P2P網絡協議棧——Libp2p

來源: 趣鏈科技 作者:BitXMesh
Libp2p是什么? Libp2p是用于構建P2P網絡的模塊化網絡堆棧和庫,源自開源項目IPFS,模塊化設計使它能夠用來構建各種去中心化應用的P2P網絡層。目前,知......
Libp2p是什么?

Libp2p是用于構建P2P網絡的模塊化網絡堆棧和庫,源自開源項目IPFS,模塊化設計使它能夠用來構建各種去中心化應用的P2P網絡層。目前,知名區塊鏈項目Ethereum 2.0、Pokdot、BitXHub都選擇基于Libp2p庫搭建系統網絡層。Libp2p作為P2P網絡協議棧,它是通過解決實際問題不斷成長的,可以認為是構建P2P網絡經驗的積累。

Libp2p解決了哪些問題?

Libp2p作為網絡協議棧,主要解決兩個問題:

· 節點發現

節點發現用來發現P2P網絡中的其它節點及維護節點在線狀態,并且根據節點狀態調整網絡連接,構建穩定的網絡拓撲。

· 數據傳輸

數據傳輸負責節點間數據的流轉。為了支持各種異構的網絡設備互連,Libp2p核心要求之一就是傳輸層不可知,Libp2p支持不同的傳輸層協議,例如TCP、UDP、QUIC等。在傳輸層建立連接后還需要考慮網絡數據的隱私安全,Libp2p對傳輸通道加密,節點間通過加密通道進行通信。為了高效傳輸數據,Libp2p支持對連接進行多路流復用從而支持節點間多個并發流通信。
 
本文主要討論Libp2p解決數據傳輸問題方案,代碼基于go-libp2p v0.9.2。

Libp2p是如何解決數據傳輸問題的

· 傳輸層不可知

傳輸層不可知是指Libp2p支持多種傳輸層協議,例如TCP、UDP、QUIC等,應用程序開發者在使用Libp2p庫時不需要知道完成數據傳輸使用的傳輸層協議,Libp2p會根據遠程節點地址信息自動完成協議選擇。

· 地址定義

數據傳輸建立在節點連接的基礎上,在可以撥號遠程節點并建立連接之前,需要知道遠程節點的監聽地址。因為每種傳輸協議都有自己的地址格式,所以Libp2p使用一種稱為“multiaddr”的編碼方案來統一不同的協議的地址格式。

TCP/IP傳輸協議“multiaddr”的描述如下:
/ip4/127.0.0.1/tcp/9999

UDP傳輸協議“multiaddr”的描述如下:
/ip4/127.0.0.1/udp/9998

用這種描述方式來代替127.0.0.1:9999的好處是什么呢?“multiaddr”能更明確的描述使用的協議,如127.0.0.1屬于IPv4協議,9999屬于TCP協議,9998屬于UDP協議。

以上為“multiaddr”描述的節點監聽地址,當撥號一個節點時也是使用“multiaddr”,但需要加上遠程節點的ID,例如:

/ip4/192.168.100.100/tcp/9999/p2p/QmcEPrat8ShnCph8WjkREzt5CPXF2RwhYxYBALDcLC1iV6

這樣就知道對方使用IP4,地址:192.168.100.100,TCP協議,端口:9999,是一個P2P節點,節點ID:QmcEPrat8ShnCph8WjkREzt5CPXF2RwhYxYBALDcLC1iV6。

· 節點ID定義
節點ID是一串字符,由節點公鑰的hash產生,并進行base58編碼,節點ID是全網唯一的,撥號時使用節點ID可以有效解決中間人攻擊問題。

· 支持多種傳輸協議

Libp2p的Swarm模塊負責將多個傳輸層組合到一個接口中,從而允許應用程序撥號節點,而不必指定要使用的傳輸層。它還負責協議協商、多路流復用、建立安全通信等接口升級操作。

Network接口是Libp2p對外提供服務的接口,Swarm是Network接口的具體實現。Libp2p在Swarm中維護現有連接的狀態,維護支持的傳輸層協議。Swarm通過以下操作支持多傳輸協議:

· 為了支持多種傳輸層協議,新建節點時(NewNode)會將節點支持的傳輸層協議通過AddTransport加入Swarm的transports結構中。

·  當節點打開監聽(Listen)時,Swarm模塊會調用TransportForListening獲取監聽地址對應的傳輸層協議,并調用相應的傳輸層協議的Listen函數。

· 當節點主動連接(Dial)其它節點時,Swarm模塊會調用TransportForDialing獲取撥號地址使用的傳輸協議,并調用相應的傳輸層協議的Dial函數。

Libp2p通過“multiaddr”的編碼方案來統一不同協議的地址格式,在Swarm模塊根據“multiaddr”解析協議并調用相應協議的接口完成具體操作,從而達到了應用層不需要關注使用的傳輸層協議的目的。

數據安全傳輸

以上過程在節點間建立了連接,Libp2p是如何保證傳輸數據隱私的?這里以TCP協議為例進行展開介紹。

TcpTransport是TCP的傳輸層實現模塊,其中組合了Upgrader模塊,Upgrader負責把一個原始的TCP連接升級為支持加密,支持多路流復用的連接。secio和tls是兩個實現了SecureTransport接口的庫,Libp2p庫默認使用secio加密庫。

以上為TCP收到一個遠程節點連接請求的調用流程,主動撥號遠程節點調用過程類似。這里使用secio包的runHandshakeSync函數對連接進行加密。

secio庫密鑰交換使用Diffie-Hellman密鑰協商算法(secio協議具體內容)。當然也可以使用tls對連接進行加密。

多路流復用

Libp2p應用程序通常會在節點之間打開許多獨立的通信流,并且可能會與某個遠程節點同時打開多個并發流。多路流復用允許與遠程節點建立一次連接即可完成整個生命周期的數據收發,同樣只需要處理一次NAT操作,因為和同一個遠程節點所有的流都共享相同的底層傳輸連接。在配置Libp2p時,會啟用流復用模塊,Swarm將在撥號遠程節點和偵聽連接時使用它們。如果遠程節點支持相同的多路流復用實現,則Swarm將在建立連接時選擇并使用它;如果撥號Swarm已經與之建立連接的遠程節點,則新建流將自動在現有連接上進行多路復用。

upgrader的muxer模塊負責將加密后的連接升級為支持多路流復用的連接。MuxedConn為多路流復用操作接口,multiplex為多路流復用操作具體實現,負責具體的流創建及管理。除了默認的multiplex,Libp2p還支持yamux、spdy、muxado等不同的多路復用器實現。

還是以監聽為例,收到連接請求后,Upgrader的Secure模塊首先會將連接升級為加密連接。然后通過NewMultiplex創建多路復用器實例,多路復用器實例把接口升級為支持流復用的接口。

MuxedConn的OpenStream接口用于向遠程節點發送新建流請求,AcceptStream接口用于接收遠程節點創建流的請求。

由于節點間通信多個流使用的仍是同一個連接,為了區別不同的流,multiplex模塊實際上是對發送的數據添加了header字段。

header高61bits為stream id,每次新建流時stream id會自增。

header低3位表示消息類型,總共定義了4種流消息:

newStreamTag = 0  // 創建流消息
messageTag= 2 // 數據消息
closeTag= 4 // 關閉流消息
resetTag= 6 // 重置流消息

Libp2p通過upgrader的muxer模塊將普通接口升級為支持流復用的接口,節點間數據傳輸時會在連接上通過流進行并行數據收發,而不是新建連接,從而減少了節點間新建連接的消耗。為了區別不同的流上的信息,流復用器對收發數據添加了表示流信息的header字段。

總結

從Libp2p解決數據傳輸問題能夠看到Libp2p有很多小組件組成,解決相同問題小組件遵循相同接口,可以根據使用場景進行替換,各組件庫可以單獨開發升級,而不會對其它部分產生影響。“multiaddr”的地址編碼方案使基于Libp2p的應用層開發不需要關注底層使用的傳輸層協議。節點間可以通過協議協商選擇共同支持的加密模塊對數據傳輸通道進行加密,從而保證數據隱私性。

關鍵詞: P2P網絡協議  Libp2p  
0/300
? 波克城市捕鱼游戏 江西多乐彩走势图工 内蒙古快3开将结果 贵州Ⅱ选五开奖一定牛 天赐材料股票股吧 体彩宁夏11选五5开奖今天 贵州快三玩法中奖介绍 秒速赛车技巧规律 辽宁35选7开奖号码结果2019006期 股票价格指数怎么算 北京快乐八官方网站 云南十一选五遗漏真准网 内蒙古快3助手下载 月薪2000元理财 贵州快三开奖结果查询 pk10一分赛车技 快乐12开奖结果查询