【libp2p——NAT】

1. 什么是NAT

NAT(Network Address Translation,网络地址转换)是指一种网络技术,它允许多个设备通过一个公共IP地址连接到互联网。NAT通常被用在家庭或小型办公室的路由器上,以允许多台计算机共享一个互联网连接。这种做法可以节省IPv4地址空间,并且为内部网络提供了一定程度的安全性,因为外部网络无法直接访问内部网络中的设备。

许多路由器支持用于端口转发的自动配置协议,最常见的是UPnP(通用即插即用)或NAT-PMP(NAT端口映射协议)。

2. libp2p如何解决NAT问题

对于libp2p这样的点对点通信库来说,NAT是一个挑战,因为它使得两个位于不同私有网络后面的节点很难直接建立连接。libp2p需要处理NAT穿透问题,以便让这些节点能够相互通信。

为此,libp2p采用了多种技术和协议来解决这个问题,包括但不限于:

  1. STUN (Session Traversal Utilities for NAT): STUN是一种协议,用于发现NAT类型以及获取外部可见的IP地址和端口。
  2. TURN (Traversal Using Relays around NAT): 当直接的P2P连接不可行时,TURN服务器可以作为中继点来转发数据流。
  3. ICE (Interactive Connectivity Establishment): ICE是一种框架,结合了STUN和TURN的功能,用来尝试建立最佳的连接路径。
  4. Hole Punching: 这是一种技术,其中一个节点可以通过向另一个节点发送数据包来“打洞”穿越NAT,从而创建一条直接的UDP连接路径。
  5. UPnP (Universal Plug and Play) / NAT-PMP (NAT Port Mapping Protocol): 这些协议允许应用程序自动配置路由器上的端口映射,以便外部网络可以直接访问内部网络中的服务。

libp2p通过使用诸如STUN、TURN等技术来帮助节点发现它们对外部世界的可访问地址,从而避免了这个问题。此外,libp2p还利用自动NAT配置协议(如UPnP或NAT-PMP)来设置端口映射,以确保节点能够接收来自外部的入站连接。

3. AutoNAT

3.1 背景

虽然识别协议允许对等节点互相告知它们观察到的网络地址,但有时这些地址是不可访问的,因为该对等节点可能位于一个私有网络中(即,在NAT或防火墙之后)。

为了解决广播和尝试连接不可达地址的问题,libp2p实现了一个名为AutoNAT的协议。该协议允许节点判断它们是否位于NAT之后。通过这种方式,节点可以确定它们的公网可达性,并避免广播那些实际上无法被其他节点访问的地址,从而提高P2P网络的整体效率和稳定性。

3.2 协议介绍

AutoNAT允许一个节点通过拨打预定的公共地址来请求其他节点。

  • 对于NAT背后的私有节点,强烈建议如下
    • 不广播私有地址
    • 通过NAT获得一个预留的中继的地址
    • 广播这个中继地址
  • 对于在公网上的节点
    • 启动中继功能以帮助其他节点
    • 考虑激活DHT服务器模式以改善与公网的连接

如果大多数拨号尝试都成功,则该节点可以合理地确定它不在 NAT 后面。另一方面,如果大多数拨号尝试都失败,则强烈表明 NAT 正在阻止传入连接。

3.3 协议实现

AutoNAT协议使用协议ID为/libp2p/autonat/1.0.0,涉及到Dial和DialResponse消息的交换。

启动该协议时,节点1发送一个Dial消息到一个的节点2,该消息包含一个列表的multiaddresses。节点2开始拨打这些地址。如果只少有一个dial是成功的,则节点2发送一个DialResponse消息给node1。消息的主体是ResponseStatus: SUCCESS。如果全部失败,则返回ResponseStatus: E_DIAL_ERROR。
节点1可以通过返回的消息判断自己是否在一个NAT后。

如果响应表明成功,则该节点可能不在NAT后面,并且不需要使用中继服务器来改善其连通性。如果响应指示错误,则该节点可能在NAT之后,可能需要使用中继服务器与网络中的其他节点进行通信。

发起方使用从多个对等体获得的响应来确定自己的NAT状态。如果超过3个节点报告一个成功拨号的地址,节点应该假设它不在NAT后面,并且是可公开访问的。另一方面,如果超过3个对等体报告拨号失败,则该节点应该假定它是不可公开访问的。

4. Circuit Relay

“电路中继”是一种传输协议,它通过第三方“中继”节点在两个对等节点之间路由流量。在许多情况下,对等节点无法穿越其网络地址转换(NAT)和/或防火墙,从而使其公开可访问。目前p2p实现了两个版本的协议,以下主要以v2版本为主。
在这里插入图片描述

4.1 p2p中的Circuit Relay

为了在面对NAT等连接障碍时实现点对点架构,libp2p定义了一种名为p2p-circuit的协议。当一个对等节点无法监听公共地址时,它可以拨号连接到一个中继对等节点,该节点将保持一个长期开放的连接。其他对等节点将能够使用p2p-circuit地址通过中继对等节点进行拨号,该地址将转发流量到其目的地。

电路中继协议的灵感来自于TURN,它是交互式连接建立(Interactive Connectivity Establishment)集合中的一部分NAT穿越技术。

中继协议的一个重要方面是它不是“透明的”。换句话说,源节点和目标节点都意识到流量正在被中继。这一点很有用,因为目标节点可以看到用于打开连接的中继地址,并且可能使用它来构建返回源节点的路径。它也不是匿名的——所有参与者都使用其对等ID进行标识,包括中继节点。

4.2 Relay addresses(中继地址)

中继电路是用一个多地址来标识的,这个多地址包括传输的对等体(侦听对等体或“中继目标”)的对等体ID。

假设我有一个libp2p节点,其Peer ID为QmAlice。我想把我的地址给我的朋友QmBob,但我在NAT后面,不让任何人直接拨给我。

这样的地址表示只能表面这个消息是通过电路中继和p2p协议试图连接到QmAlice这个唯一标识
/p2p-circuit/p2p/QmAlice
包括特定中继对等体QmRelay的标识。如果对等端已经知道如何打开与QmRelay的连接,他们将能够联系到我们。
/p2p/QmRelay/p2p-circuit/p2p/QmAlice
更好的方法是在地址中包含中继对等体的传输地址。假设我已经用对等体ID QmRelay建立了到特定中继的连接。他们通过识别协议告诉我,他们正在监听IPv4地址198.51.100.0的55555端口上的TCP连接。我可以构造一个地址,它描述了通过传输的特定中继给我的路径:
/ip4/198.51.100.0/tcp/55555/p2p/QmRelay/p2p-circuit/p2p/QmAlice

以上/p2p-circuit/之前的所有内容都是中继对等体的地址,其中包括传输地址和它们的对等体ID QmRelay。

/p2p-circuit/之后是线路另一端的对等体ID, QmAlice。
在这里插入图片描述

  1. 节点A位于NAT和/或防火墙后面,例如通过自动识别服务检测到。
  2. 因此,节点A向中继R请求预约,即节点A请求中继R代表它侦听传入的连接。
  3. 节点B想要与节点a建立连接。鉴于节点a没有发布任何直接地址,只有一个中继地址,节点B连接到中继R,要求中继R中继到a的连接。
  4. 中继R将连接请求转发给节点A,最终中继A和B发送的所有数据。

5. DCUtR

5.1 背景知识

使用中继作为代理来遍历nat,但是这在扩展和维护方面的成本可能很高,并且可能导致低带宽、高延迟的连接。穿孔是另一种通过使NAT后面的两个节点直接通信来实现NAT穿越的技术。然而,除了中继节点之外,它还需要另一个称为信令服务器的基础设施。libp2p提供了一个穿孔解决方案,它消除了对集中式信令服务器的需求,并允许使用分布式中继节点。

5.2 通过中继直接连接

libp2p DCUtR (Direct Connection Upgrade through Relay)是一种通过打孔在节点之间建立直接连接的协议,不需要信令服务器。DCUtR包括同步和打开到每个对等端预测的外部地址的连接。

DCUtR协议使用协议ID /libp2p/ DCUtR,包括ConnectSync消息的交换。
DCUtR协议支持TCP、QUIC等不同类型的连接,不同类型的连接建立过程不同。

6. Hole Punching

点对点网络上的节点可以分为公共和非公共两类。公共节点是那些可以不受阻碍地访问互联网的节点,而非公共节点位于某种防火墙后面。这适用于家庭和公司网络的大多数节点,以及移动电话。在大多数配置中,公共和非公共节点都可以拨号连接到其他公共节点。但是,不可能建立从公共互联网到非公共节点的连接。
在这里插入图片描述

6.1 如何拨打非公共节点

  • 拨号非公共节点的方法:
    • UPnP(通用即插即用):路由器和网络内计算机之间使用的协议。它允许计算机请求某些端口被并转发到该计算机。
    • 端口转发:在路由器上手动配置端口转发。
  • 限制
    • 在许多情况下,UPnP被路由器或防火墙禁用。UPnP也可能无法工作,这取决于路由器的固件。
    • 手动打开端口需要专业技术,并且不强制进行身份验证或授权。

6.2 可能的解决方案(hole punching)

6.2.1 Relaying overview

中继是一种用于在两端之间发送信息的机制。对于非公有节点:
节点A与中继节点R保持永久连接,当节点B想要连接到节点A时,它首先与节点R建立连接,节点R转发该连接上的所有数据包。中继增加了额外的延迟,并且是资源密集型的,因为节点R需要处理大量的流量。使用中继节点还需要技术专长。

6.2.2 如何利用节点R来促成节点A和B直接连接

在其他选择都不够的情况下,网络可以使用一种称为打孔的技术来与非公共节点建立连接。

每个节点连接到中继节点并共享其外部地址和端口信息。服务器临时存储节点的信息,并将每个节点的信息转发给其他节点。客户端可以使用这些信息建立彼此之间的直接连接。

以两个节点A和B为例,它们想要相互拨号:

  1. 两个节点的第一个数据包(例如,在TCP的情况下,一个SYN)通过它们各自的路由器。
  2. 路由器将一个5元组添加到路由器的状态表中。(修改路由器的表)
  3. PacketA和PacketB在各自路由器的防火墙上“打洞”。
  4. 两个包到达对方的路由器。
  5. 当A的数据包到达Router_B时,Router_B检查自己的状态表,发现一个5元组是在节点B发送的数据包中添加的。
  6. 路由器通过“打孔”将数据包转发给B。B的数据包也是如此;到达Router_A后,在Router_A的状态表中匹配一个5元组,将报文转发给a。

路由器状态表(路由表)是存储在路由器中的数据,它列出了到特定网络目的地的路由。5元组结构包括源IP地址、源端口、目的IP地址、目的端口和传输协议。
在这里插入图片描述

6.3 libp2p中的Hole punching

受ICE协议的启发,libp2p包括一个分散的穿孔功能,允许防火墙和NAT穿越,而不需要像STUN和TURN这样的中央协调服务器。

6.3.1 阶段一Preparation

6.3.1.1AutoNAT

在这里插入图片描述
确定节点是否可拨号,例如,发现节点是否位于NAT或防火墙后面。

  • B向它所在网络上的Other_Peers(例如,引导节点)伸出手,并要求每个节点在一组它怀疑可以到达的地址上拨号。libp2p节点有多种发现其地址的方法,但最突出的是使用libp2p标识协议。
  • Other_Peers尝试拨打B的每个地址,并将结果报告给B。
  • 根据报告,B可以判断自己是否是公共节点,并确定是否需要打孔。
6.3.1.2 AutoRelay:动态发现和绑定网络中的中继节点。

IPFS通过Kademlia DHT使用查找方法发现k-最近的公共中继节点:/<RELAY_ADDR>/p2p-circuit/<PEER_ID_B>
在这里插入图片描述
B网络外的Other_Peers可以通过公共中继节点间接呼叫B。在IPFS的情况下,每个公共节点将充当一个中继。B将在Kademlia DHT上查找与其Peer ID最近的对等节点,或者选择已经连接到的公共节点的一个子集。

6.3.1.3 Circuit Relay:连接到发现的中继节点并请求预订。节点可以通过远程中继节点宣布自己可达。

在这里插入图片描述

  • Relay可以通过Circuit Relay v2限制用于中继连接的资源(例如,通过连接数、时间和字节)。在IPFS的情况下,这允许网络中的每个公共节点充当中继,而不会消耗大量资源。
  • 对于每一个被发现的中继
    • B连接到远程节点,并请求中继节点代替它侦听连接,称为reservation;
    • 如果Relay接受预订请求,则B可以宣布自己可通过Relay访问。

6.3.2 阶段二Hole punching

成功率(90%)

6.3.2.1 Circuit Relay(电路中继)

电路中继:通过公共中继节点建立安全的中继连接。节点A与中继节点建立直连。然后节点B通过中继节点请求到节点a的中继连接,创建一个双向通道,并使用TLS来保护该通道。
在这里插入图片描述

  1. A使用B的通告地址中包含的信息通过中继建立到B的中继连接。
  2. A首先建立到Relay的直接连接,然后从Relay请求到B的中继连接。
  3. Relay将请求转发给B并接受。
  4. 继电器将接收转发给A。
  5. A和B可以使用中继上的双向信道进行通信。
  6. A和B使用TLS等安全协议升级中继连接
6.3.2.2 DCUtR:使用DCUtR作为同步机构来协调冲孔。

在这里插入图片描述

  1. A通过Relay向B发送Connect消息。
  2. 连接包含a的地址。libp2p提供了多种机制来发现一个人的地址,例如,通过libp2p识别协议。
  3. B在中继连接上接收Connect消息,并回复一个包含其(非中继)地址的Connect消息。
  4. A测量发送消息和接收B消息之间的时间,从而确定A和B之间通过Relay的往返时间。
  5. 然后,A在中继连接上向B发送同步消息。
  6. A等待一半的往返时间,然后通过B的Connect接收到的地址直接拨打B。
  7. 一旦B收到A的Sync消息,它就直接使用A的Connect消息中提供的地址拨打A。
  8. 一旦A和B同时拨号,就会发生打孔。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1547639.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

深入理解函数【JavaScript】

在 JavaScript 中&#xff0c;函数作为一种重要的基本结构&#xff0c;承载着编程中的许多关键概念。下面是与函数相关的内容介绍&#xff1a; 1. 函数定义 JavaScript 中有多种方式定义函数&#xff1a; 1.1 函数声明&#xff08;Function Declaration&#xff09; functi…

C# 委托(Delegate)一

一.Delegate的定义说明&#xff1a; C# 中的委托&#xff08;Delegate&#xff09;就是类似于 C 或 C 中函数的指针。Delegate 是存有对某个方法引用的一种引用类型变量&#xff0c;引用可在运行时是可以被改变的&#xff0c;特别适用于实现事件和回调方法。所有的Delegate都是…

C# 委托(Delegate)二

一.委托的多播&#xff08;Multicasting of a Delegate&#xff09;&#xff1a; 委托对象&#xff0c;使用 "" 运算符进行合并&#xff0c;一个合并委托调用它所合并的两个委托。使用"-" 运算符从合并的委托中移除组件委托。 注&#xff1a;只有相同类型…

linux文件下载分类

在下载图片时各个网站命名不统一&#xff0c;管理起来很麻烦&#xff0c;想要写一个脚本将下载的图片或者其他资源实现格式统一&#xff0c;方便管理 $0&#xff1a;表示脚本路径。运行 ./myscript.sh&#xff0c;$0 将会保存 ./myscript.sh。 $1&#xff1a;表示传递给脚本的…

Leetcode 968. 监控二叉树 树形dp、状态机 C++实现

问题&#xff1a;Leetcode 968. 监控二叉树 给定一个二叉树&#xff0c;我们在树的节点上安装摄像头。 节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。 计算监控树的所有节点所需的最小摄像头数量。 /*** Definition for a binary tree node.* struct TreeNo…

数据结构 ——— 移除元素(快慢指针)

目录 题目要求 代码实现&#xff08;快慢指针&#xff09; 题目要求 编写函数&#xff0c;给你一个数组 nums 和一个值 val&#xff0c;你需要在 nums 数组 原地 移除所有数值等于 val 的元素&#xff0c;并且返回移除后数组的新长度 不能使用额外的数组空间&#xff0c;要…

数据统计与分析-Numpy入门

Numpy入门 导包1.演示Numpy的属性演示打印Numpy数据类型shape()形状维度ndim() 轴dtype() 元素类型size()元素个数itemsize()每个匀速所占大小 2.创建Numpy对象2.1数组方式创建,函数:arrray()2.2创建空的ndarray对象2.2.1 zeros()2.2.2 ones()2.2.3 empty() 2.3创建1个指定范围…

大数据毕业设计选题推荐-内蒙古旅游景点数据分析系统-Hive-Hadoop-Spark

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

【智能控制】16章 基于Hopfield网络的路径优化,TSP问题

目录 15.6 基于Hopfield网络的路径优化 15.6.1 TSP问题 15.6.2 求解TSP问题的Hopfield神经网络设计 15.6 基于Hopfield网络的路径优化 15.6.1 TSP问题 旅行商问题&#xff08;Traveling Salesman Problem&#xff0c;简称TSP&#xff09;可描述为&#xff1a;已知N个城市之…

C# 的枚举(Enum)应用说明

一.Enum的定义&#xff1a; 枚举是一组命名整型的常量。枚举类型是使用 enum 关键字声明的&#xff0c;它是值类型。枚举包含自己的值&#xff0c;且不能继承或传递继承。 二.声明 enum 变量&#xff1a; 声明枚举的一般语法&#xff1a; enum <enum_name> { enumerati…

如何使用ssm实现基于BS的库存管理软件设计与实现+vue

TOC ssm708基于BS的库存管理软件设计与实现vue 绪论 课题背景 身处网络时代&#xff0c;随着网络系统体系发展的不断成熟和完善&#xff0c;人们的生活也随之发生了很大的变化。目前&#xff0c;人们在追求较高物质生活的同时&#xff0c;也在想着如何使自身的精神内涵得到…

FPGA学习(1)-mux2,2选1多路器

目录 1 开发板配套资料 1.1学习网址和资料网址 2.创建工程文件 2.1创建过程 2.2写程序及仿真测试 2.2.1 写程序生成电路 2.2.2仿真 2.2.3 生成执行文件并烧录 3.实验现象 买的小梅哥店铺的开发板&#xff1a;xc7z020clg400 看的小梅哥的视频&#xff1a;03C _基于ZYN…

Oracle 相关的工具使用 SQL Developer , sqlplus

Oracle 相关的工具使用 SQL Developer &#xff0c; sqlplus 一&#xff0c;Oracle SQL Developer 连接数据库 今天在连接sqldeveloper服务器时遇到了很多问题&#xff0c;但最终还是通过网上的博客解决了问题&#xff0c;我就在总结一下我的解决过程。 一.界面 首先&#…

混拨动态IP代理的优势是什么

在当今互联网时代&#xff0c;隐私保护和网络安全成为了人们关注的焦点。无论是个人用户还是企业&#xff0c;都希望能够在网络上自由、安全地进行各种活动。混拨动态IP代理作为一种新兴的技术手段&#xff0c;正逐渐受到大家的青睐。那么&#xff0c;混拨动态IP代理到底有哪些…

c语言常量变量

c语言常量变量 const 修饰常变量 #define定义标识符常量 #define num 10 //这里不需要分号int anum;enum枚举常量 enum Color {RED,GREEN,BLUE }; int main(){enum Color cRED;//枚举常量不允许修改 }//定义常量 int a10; char ba;错误语法注意 //定义常变量 const int a10…

windows 桌面采集音频

头文件&#xff1a; #ifndef __CAPTURE_AUDIO__ #define __CAPTURE_AUDIO__#include <functional> #include <windows.h> #pragma comment(lib, "winmm.lib")class CaptureAudio { public:CaptureAudio();~CaptureAudio();public:bool Init(const std::…

JSON与CSV之间的主要区别

今天要和大家深入探讨一个数据处理中的常见问题——JSON与CSV之间的主要区别。这两种数据格式各有千秋&#xff0c;适用于不同的场景。让我们一起来了解它们的特点和应用。 一、数据结构的差异 首先&#xff0c;JSON是一种轻量级的数据交换格式&#xff0c;能够表示复杂的数据…

Unity开发绘画板——04.笔刷大小调节

笔刷大小调节 上面的代码中其实我们已经提供了笔刷大小的字段&#xff0c;即brushSize&#xff0c;现在只需要将该字段和界面中的Slider绑定即可&#xff0c;Slider值的范围我们设置为1~20 代码中只需要做如下改动&#xff1a; public Slider brushSizeSlider; //控制笔刷大…

深圳易图讯科技场区态势感知系统

一、功能与目标优化描述&#xff1a; .图像采集、传输、存储与管理系统&#xff1a; 实时采集&#xff1a;利用摄像头、移动摄像设备及微距摄像头&#xff0c;全面覆盖场区内固定点位和重要场地&#xff0c;实现视频图像的实时采集。 高效传输&#xff1a;通过有线、无线网…

秒懂Linux之信号

目录 信号的基本概念 信号的处理方式 默认动作 自定义处理信号 忽略该信号 信号的产生方式 kill命令 键盘组合键 系统调用 软件条件 异常 信号产生的深层理解 core的功能 信号的阻塞 内核中的表示 sigset_t 信号集操作函数 sigprocmask sigpending …