IPFS协议栈以及身份层、网络层和路由层
与HTTP类似,IPFS是基于TCP/IP的应用层协议,同时作为一个分布式的文件系统,IPFS提供了一个支持部署和写入的平台,同时能够支持大文件的分发和版本管理。IPFS协议栈由七层负责不同功能的子协议构成:
- 身份层:管理节点身份生成和验证。
- 网络层:管理与其他对等体的连接,使用各种底层网络协议。
- 路由层:维护信息以定位特定的对等体和对象。响应本地和远程查询。默认为DHT,但可更换。
- 交换层:一种支持有效块分配的新型块交换协议(BitSwap),模拟可信市场,弱化数据复制,防作弊。
- 对象层:具有链接的内容寻址不可更改对象的Merkle DAG,用于表示任意数据结构,例如文件层次和通信系统。
- 文件层:由Git启发的版本化文件系统层次结构。
- 命名层:自我认证的可变名称系统。
身份层(Identity)
所有节点在IPFS网络中都要一个唯一的NodeId进行标识,其实就是一个公钥的哈希,然而为了增加攻击者的成本,IPFS使用了S/Kademlia中提到的算法增加创建新身份的成本,源码定义如下:
difficulty = <integer parameter>
n = Node{}
do {
n.PubKey,n.PrivKey = PKI.genKeyPair()
n.NodeId = hash(n.PubKey)
p = count_preceding_zero_bits(hash(n.NodeId))
} while (p<difficulty)
S/K要求每个节点在接入网络前必须解决两个密码学问题。静态问题是:产生一对公钥和私钥,公钥两次哈希运算后,具有C1个前导零。公钥的一次哈希值就是节点的NodeID。动态问题是:不断生成一个随机数X,将X与NodeID求XOR再求哈希,哈希值要求C2个前导零。这样设计,第一个静态问题,保证节点不能再自由选择节点ID,后一个动态问题,提高了大量生成ID的成本。女巫攻击和日蚀攻击将难以进行。
每一个节点在IPFS网络中由Node结构体来表示,其中只包含NodeId以及一个公私钥对:
type NodeId Multihash
type Multihash []byte //子描述加密哈希摘要
type PublicKey []byte
type PrivateKey []byte // 子描述的私钥
type Node struct {
NodeId NodeID
PubKey PublicKey
PriKey PrivateKey
}
身份系统的主要作用是标识IPFS网络中的每一个节点,有点像用户信息的生成。在节点建立首次连接时,对等节点将交换公钥,并检查hash(other.PublicKey)是否等于other.NodeId,相当于校验用户信息,如果校验结果不相等,则用户信息不匹配,节点连接立即终止。
哈希加密算法并不是直接定死使用某种,IPFS的哈希算法比较灵活,支持根据输入自定义值来调整,默认以Multihash格式存储,源码定义如下:
<function code><digest length><digest bytes>
这种加密方式有两个优势:
- 根据需求选择最佳功能用例。在更强的安全性和更快的性能之间做一个平衡取舍。
- 随着功能的变化而演变,自定义值可以兼容不同场景下的参数选择。
网络层(Network)
IPFS节点与其他节点连接通信的时候,会跨越广域网,IPFS网络堆栈的特点如下:
- 1.传输:IPFS兼容现有的主流传输协议,其中最适合浏览器端使用的WebRTC Data Channels,低延时uTP(LEDBAT)传输协议等。
- 2.可靠性:使用uTP和sctp来保障,这两种协议可以动态调整网络状态。
- 3.可连接性:使用ICE等NAT穿越技术来实现广域网的可连接性。
- 4.完整性:使用哈希校验检查数据完整性,IPFS中所有数据块都有唯一的Hash。
- 5.可验证性:使用数据发送者的公钥以及HMAC消息认证码来检查消息的真实性。
WebRTC(Web browser Real Time Conmunication)网页实时通信技术,适用于网页间音视频实时通信,点对点数据共享。免费开源的WebRTC内置于浏览器中,用户不需要使用任何插件或者软件通过浏览器实现实时通信。
如需更多对WebRTC的连接,查看如下网页:详解WebRTC——网页实时通信技术
LEDBAT(Low Extra Delay Background Transport)是一种在不阻塞网络的情况下快速传输数据的方法。LEDBAT是一种基于延迟的拥塞控制算法,它使用所有可用的带宽,同时限制延迟的增加。它通过测量单向延迟和使用测量的变化来限制LEDBAT流本身在网络中引发的拥塞。
IPFS可以使用任意的网络进行通信,并没有完全依赖于IP层,IPFS是通过multiaddr的格式来表示目标地址和使用的协议,以此来兼容和扩展未来可能出现的其他网络协议:
# an SCTP/IPv4 connection
/ip4/10.20.30.40/sctp/1234/
# an SCTP/IPv4 connection proxied over TCP/IPv4
/ip4/5.6.7.8/tcp/5678/ip4/1.2.3.4/sctp/1234/
这也意味着IPFS的网络通信模型是遵循覆盖网络(Overlay Network)的理念设计的,下面的模型图说明IPFS的网络架构模型是叠加的虚拟化技术模式,建立在已有网络的虚拟网,用逻辑节点和逻辑链路构成。多个容器在跨主机通信的时候,使用Overlay Network这个网络模式,会虚拟出一个网络比如10.0.9.3这个IP地址,一个类似服务网关的地址,然后把数据包转发到Host物理服务器地址,最终通过路由和交换,达到另一个Host服务器的IP地址。
覆盖网络模型路由层(Routing)
IPFS节点需要一个路由系统,可用于查找:
- 同伴节点的网络地址。
- 服务特定对象的对等节点。
IPFS路由层数据结构使用的是S/Kademlia和Coral技术的分布式松散哈希表(DSHT),IPFS的DSHT结构会根据所存数据的大小值进行区分:小的值(等于或小于1KB)直接存储在DHT上,更大的值,DHT只存储值索引,这个索引就是一个对等节点的NodeId,该对等节点可以提供对该类型值的具体服务,DSHT的接口位于libP2P模块中,如下:
type IpfsRouting interface {
ConnectRouting //内容路由
PeerRouting //节点路由:获取特定NodeId的网络地址
ValueStore //数据操作:对DHT中的元数据进行操作
Bootstrap(context.Context) error
}
type ConnectRouting interface {
Provide(context.Context,*cid.Cid,bool) error
FindProvidersAsync(context.Context,*cid.Cid,int) <-chan pstore.PeerInfo
}
type PeerRouting interface{
FindPeer(context.Context,peer.ID)(pstore.PeerInfo,error)
}
type ValueStore interface {
PutValue(context.Context,string,[]byte) error
GetValue(context.Context,string) ([]byte,error)
GetValues(c context.Context,k string,count int) ([]RecvdVal,error)
}
IPFS的路由层需要实现三种基本的功能:内容路由,节点路由和数据存储。集成这些功能的接口降低了系统的耦合度,可以让开发者根据业务需求进行底层自定义的同时也不会影响系统其它部分的正常工作。
文章借鉴《IPFS与区块链:原理与实战》推荐大家购买正版书籍。
网友评论