Peer GUID: 使用 Global 唯一性标识
Peer GUID Ring: 形成一个环的连接
需要解决: 每个Peer能够连接到网络中的其它所有peer,但是只存储其中几个Peer->递进
使用Peer Routing Table
-> (GUID, IP Address, TCP Port)
一种Routing Table: Exponential GUID Distance Referencing (Chord and Kademlia)
GUID的位数 = Routing table项数,每项与其距离为2^n (这个距离只是考虑数字逻辑,不考虑实际地理位置 需要改进,地理位置近延时低 现在的方案相当于随机)
(如果距离为2^n的peer不在网络中,则可能选择离其最近的)
The routing table has the same number of cells as the number of bits in the GUID. Thus, if the GUID is 64 bit, then there are 64 cells in the routing table. Thus, a 64 bit “GUID space” has space for 2^64 GUID’s (peers) total, and each peer needs a 64 cell routing table.
所以整个网络能容纳的peer数为2^length
这个距离(2^n)的计算有很多方法 (e.g. Chord and Kademlia)
公共前缀-前缀越长,范围越小,只存跟自己近的
Chord
就是图中的指数式指向的方式
Kademila
distance(A, B) = A XOR B
这种方法双向计算结果一致,所以这种距离计算方式保证peer之间的线都是双向的(每个节点有一根线指向其”前置”peer,其他指向后续peer)
实际上随时退出加入,很难对称,退出时也不通知
Finding Peer
每个节点找距离需要的GUID最近的peer,向他询问,逐级,logN次,收敛,所以能够
长度n的GUID网络,共2^n个peer,最多找n步
(定时更新距离最近的peer)
Booting the P2P Network
Joining Peer向Boot Peer 报告(peer配置文件中有几个设定好的peer地址,社区认为稳定的),Boot Peer
分配GUID, Joining Peer先复制Boot Peer的routing table来找自己计算出的应该存储的peer
Leaving the P2P Network
(实际上没有通知)Leaving Peer向存储了它 的Peer(Kademila方法中存有它的节点它自己也有存)通知,其他peer删除后即可下线;
或一个节点周期性检查其他peer,如果无response则删除
节点被删除后用距离最近的peer填充空缺
K-桶其实是一个链表,前面最近,后面最新,先检查头部,加入到尾端
libp2p
main里面是测试文件
p2p是主要代码文件夹
P2P
Peer理解成一个软件,包含 client server
不一定?有center
匿名
应用层-覆盖在TCP/IP上 硬件依然有路由器(可能造成路径长度变长,浪费资源?)
公私钥:只要私钥签名就一定不可篡改,
缺点: 难管理
集中式
存所有节点的目录服务器,作为中心服务,管理–现在方式
无结构分布式
所有节点功能相同,只能全网广播,实现简单,但是效率低
结构化分布式 e.g. IPFS
DHT 分布式哈希表(每个节点只存跟自己最相关的信息,CAT算法?),可以按照routing较快找到节点
半分布式拓扑
LibP2P
IPFS+中心节点->libp2p(代码库)
提供pubsub 可以在应用层实现组播 (路由器一直无法实现的)
多路复用: 加包头,分给不同进程,使用同一管道
每个连接需要一个socket,分配资源(计算&存储),需要延时
模块化,传输层支持TCP UCP quick(1 RTT连接,更快)等都可
peerID 密码学hash生成(重复率低)
NAT 穿越
NAT解决IP不够的问题 ,内网IP(10.1.1.0),对于发出的请求是透明的,但是外界不知道你的内网IP
自动路由配置
NAT是路由器-转换表(IP port)实现的,在路由器中加入软件恢复,依靠硬件
Hole-Punching
从路由器获取自己的公网IP和NAT中port,这样就可以让外界找到它
SO REUSERPORT 允许连回来的情况下,配置,即可连接回来
AutoNAT
每个peer有个server/client, NAT中的client请求外界server,外界server知道内部的IP+port,使用外界client dial back,就知道这个IP+port能否用于连接back
Circult Relate
通过中间人
现在使用nPNP 和 Relay
私有网络
PNET
对整个数据包做异或,
PubSub
都是一份数据传给多个neibour,在全网生成一个树,避免形成环(重复通知)
floodsub
每个人都发给所有peer,不断转发,直到重复(不在接收),内存中定时清除
浪费带宽, 大量冗余
randomSub
发给随机subset,会造成随机路径
meshSub
固定发给谁,
如果这个路径很长,就会造成浪费
gossipSub
mesh+fanout+other
mesh的固定路径可能不够好,摘要(很多消息的头数据)打包发给其他节点,可能mesh发的人没有接收到,这个摘要可以用于索要数据,