Open rainit2006 opened 6 years ago
背景知识 https://cloud.tencent.com/developer/article/1005489 http://www.cnblogs.com/pannengzhi/p/4800526.html
■防火墙(Firewall): 防火墙主要限制内网和公网的通讯,通常丢弃未经许可的数据包。防火墙会检测(但是不修改)试图进入内网数据包的IP地址和TCP/UDP端口信息。
■NAT: 网络地址转换(NAT,Network Address Translation)。 早期的NAT指的是Basic NAT(静态NAT),它在技术上比较简单一点,仅支持地址转换,不支持端口映射。 后期的NAT基本都指的是NAPT(网络地址端口转换)了,这种方式支持端口的映射并允许多台主机共享一个公用IP地址,这样就可以支持同时多个位于NAT后面的机器和外部进行交互了。
NAT带来的问题: [1] NAT使IP会话的保持时效变短。 [2] NAT在实现上将多个内部主机发出的连接复用到一个IP上,这就使依赖IP进行主机跟踪的机制都失效了 [3] NAT工作机制依赖于修改IP包头的信息,这会妨碍一些安全协议的工作 [4] NAT限制了使用一些高层协议(FTP、Quake、SIP)的Peer两端的P2P通信
■P2P通信穿越NAT的技术、方法主要有: (1) 应用层网关(ALG)
限制: ALG技术是利用NAT本身的支持来进行NAT的穿越,这个方案有很大限制,主要的原因是ALG都是为特定协议的特定规范版本而开发的,然而不管是协议本身,还是协议的数量都在变化,这就使得ALG适应性不强。
(2) 中间件技术 这是一种通过开发通用方法解决NAT穿越问题的努力。与前者不同之处是,AGL技术中NAT网关是这一解决方案的唯一参与者,而中间件技术中客户端会参与网关公网映射信息的维护。UPnP就是这样一种方法,UPnP中文全称为通用即插即用,是一个通用的网络终端与网关的通信协议,具备信息发布和管理控制的能力。 原理
NAT只要理解客户端的请求并按照要求去分配响应的映射转换表,不需要自己去分析客户端的应用层数据。网关映射请求可以为客户动态添加映射表项。此时,NAT不再需要理解应用层携带的信息,只转换IP地址和端口信息。而客户端通过控制消息或信令发到公网侧的信息中,直接携带公网映射的IP地址和端口,接收端可以按照此信息建立数据连接。NAT网关在收到数据或连接请求时,按照UPnP建立的表项只转换地址和端口信息,不关心内容,再将数据转发到内网。
限制:这种方案需要网关、内部主机和应用程序都支持UPnP技术,且组网允许内部主机和NAT网关之间可以直接交换UPnP信令才能实施。
(3) 打洞技术(Hole Punching) Hole Punching技术是工作在运输层的技术,可以屏蔽上层应用层的差异,并且不需要NAT网关特定的支持,因此其通用性比较强,应用性也比较广。
打洞技术的原理比较简单,就是NAT内网的节点需要在NAT上建立自己的一条转发映射关系(这就是所谓的在NAT上打下一个洞),然后外网的节点就通过这个”洞”来进行通信。为描述方便,我们将一对IP地址和端口信息的组合称之为一个Endpoint,打洞原理可以简化为下面三个过程: [1] 首先位于NAT后的Peer1节点需要向外发送数据包,以便让NAT建立起内网Endpoint1(IP1、PORT1)和外网Endpoint2(IP2、PORT2)的映射关系; [2] 然后通过某种方式将映射后的外网Endpoint2通知给对端节点Peer2; [3] 最后Peer2往收到的外网Endpoint2发送数据包,然后该数据包就会被NAT转发给内网的Peer1。
要实现打洞穿越NAT,首先需要知道NAT的行为规则(NAT的Endpoint映射规则和对外来数据包的过滤规则),这样才能更好地实现打洞穿越。 NAT行为类型与侦测方法(详细略) “打洞”方式穿越NAT有两种形式:TCP”打洞”和UDP”打洞”。原理上,TCP”打洞”与UDP”打洞”是没有本质的区别的。然而在实现上,TCP”打洞”的成功率远没UDP”打洞”的成功率高,其主要原因有三: [1] 有些NAT防火墙策略对TCP协议不是很友好 有些NAT的防火墙策略不允许来路不明的外部向内网机器发起TCP连接。由于TCP是有连接的,NAT比较容易分清哪些是NAT 内网机器主动进行通信的外部节点,这样防火墙策略比较明确。而UDP是无连接的,没有连接来标明一个数据流,协议比较简单,这样NAT支持的比较多。 [2] TCP协议本身 由于TCP的TIME_WAIT状态引起,同一个NAT后面的其他主机发起的连接被误判。具体可以看下面的文章 http://km.oa.com/group/25569/articles/show/246068
[3] TCP协议的实现API 因为标准的Berkeley sockets API是围绕C/S编程而设计的。这个API通过connect()允许一个TCP流套接字初始化一个向外的连接,通过listen()和 accept()监听一个外入的连接,一个套接字不能既用来监听又用来初始化向外的连接。更进一步讲, TCP套接字通常与本地主机上的TCP端口一一对应:一个套接字绑定到本地主机机上的某个端口后,另一个套接字就不能再绑定到该端口。然而TCP打洞要成功,需要一个本地的TCP端口既可以监听外入的连接,同时又可以发起多个向外的连接。幸运的是,所有主流的操作系统都支持一个特殊的socket选项SO_REUSEADDR,它运行应用程序绑定多个设置了该选项的套接字到同一端口。BSD系统引入了SO_REUSEPORT选项来控制端口重用,从而把端口重用和地址重用相分离。在这样的系统中,两个选项都需要被设置。尽管如此,要进行TCP打洞需要进行TCP三次握手的同时打开,但是有些TCP/IP的实现,可能不支持这种同时打开的情况,这样也就无法建立TCP连接了。
(4) Relay(服务器中转)技术 这是最可靠但也是最低效的一种P2P通信实现。其原理是通过一个有公网IP的服务器中间人对两个内网客户端的通信数据进行中继和转发。
由于进行P2P穿透是否成功与NAT的行为和防火墙策略有很大的关系,因此就算是一个P2P友好NAT也很难保证100%穿透成功。那么一个完整的P2P穿透的解决方案必不可少的一个部分就是relay了,relay部分主要TURN协议描述。
■网络模型 https://keeganlee.me/post/blockchain/20180313 P2P 主要存在四种不同的网络模型,也代表着 P2P 技术的四个发展阶段:集中式、纯分布式、混合式和结构化模型。 1, 集中式 集中式路由的优点就是结构简单、实现容易。但缺点也很明显,由于中心节点需要存储所有节点的路由信息,当节点规模扩展时,就很容易出现性能瓶颈;而且也存在单点故障问题。
2,纯分布式 在一个新加入节点和 P2P 网络中的某个节点间随机建立连接通道,从而形成一个随机拓扑结构。
新节点与邻居节点建立连接后,还需要进行全网广播,让整个网络知道该节点的存在。全网广播的方式就是,该节点首先向邻居节点广播,邻居节点收到广播消息后,再继续向自己的邻居节点广播,以此类推,从而广播到整个网络。这种广播方法也称为泛洪机制(Flooding)。
3, 混合式 其实就是混合了集中式和分布式结构,网络中存在多个超级节点组成分布式网络,而每个超级节点则有多个普通节点与它组成局部的集中式网络。 目前较多系统基于混合式结构进行开发实现。其实,比特币网络如今也是这种结构。
4, 结构化 P2P 网络 与纯分布式结构不同。纯分布式网络就是一个随机网络,而结构化网络则将所有节点按照某种结构进行有序组织,比如形成一个环状网络或树状网络。 而结构化网络的具体实现上,普遍都是基于 DHT(Distributed Hash Table,分布式哈希表) 算法思想。
DHT 只是提出一种网络模型,并不涉及具体实现,主要想解决如何在分布式环境下快速而又准确地路由、定位数据的问题。具体的实现方案有 Chord、Pastry、CAN、Kademlia 等算法,其中 Kademlia 也是以太坊网络的实现算法,很多常用的 P2P 应用如 BitTorrent、电驴等也是使用 Kademlia。
在 P2P 网络中,可以抽象出两种空间:资源空间和节点空间。资源空间就是所有节点保存的资源集合,节点空间就是所有节点的集合。 对所有资源和节点分别进行编号,如把资源名称或内容用 Hash 函数变成一个数值(这也是 DHT 常用的一种方法),这样,每个资源就有对应的一个 ID,每个节点也有一个 ID,资源 ID 和节点 ID 之间建立起一种映射关系,比如,将资源 n 的所有索引信息存放到节点 n 上,那要搜索资源 n 时,只要找到节点 n 即可,从而就可以避免泛洪广播,能更快速而又准确地路由和定位数据。 当然,在实际应用中,资源 ID 和节点 ID 之间是无法做到一一对应的,但因为 ID 都是数字,就存在大小关系或偏序关系等,基于这些关系就能建立两者的映射关系。这就是 DHT 的核心思想。DHT 算法在资源编号和节点编号上就是使用了分布式哈希表,使得资源空间和节点空间的编号有唯一性、均匀分布式等较好的性质,能够适合结构化分布式网络的要求。
■UDP打洞 P2P软件需要服务器,用户与服务器的交互是用来完成登陆、维持在线状态等等,但用户之间的信息传递不需要服务器参与,信息传递方式为:用户A-用户B。这就是典型的P2P应用。
既然P2P可以直接在客户端间建立连接,为啥像电驴,QQ这样的P2P软件还要登录呢。 打个比方,假设有两个用户,A和B。 如果A要跟B打洞,如何知道B的外网IP呢,A只能通过B的UDID 去服务器查询一下对吧。 好,我们得出结论,打洞需要一台服务器做牵线作用
■ UDP P2P打洞原理(通俗地解释) 通过NAT,子网内的计算机向外连结是很容易的(NAT相当于透明的,子网内的和外网的计算机不用知道NAT的情况)。 但是如果外部的计算机想访问子网内的计算机就比较困难了(而这正是P2P所需要的)。
那么我们如果想从外部发送一个数据报给内网的计算机有什么办法呢?首先,我们必须先在内网的NAT上打上一个“洞”(也就是前面我们说的在NAT上建立一个Session),这个洞不能由外部来打,只能由内网内的主机来打。 而且这个洞是有方向的,比如从内部某台主机(比如:192.168.0.10)向外部的某个IP(比如:219.237.60.1)发送一个UDP包,那么就在这个内网的NAT设备上打了一个方向为219.237.60.1的“洞”,(这就是称为UDP Hole Punching的技术)以后219.237.60.1就可以通过这个洞与内网的192.168.0.10联系了。(但是其他的IP不能利用这个洞)。 呵呵,现在该轮到我们的正题P2P了。有了上面的理论,实现两个内网的主机通讯就差最后一步了:那就是鸡生蛋还是蛋生鸡的问题了,两边都无法主动发出连接请求,谁也不知道谁的公网地址,那我们如何来打这个洞呢?我们需要一个中间人(服务器S)来联系这两个内网主机。
■ UDP P2P打洞原理 双方都在局域网内就没有办法TCP直连了,所以像QQ等都会尽量使用UDP直连的. IP地址转换不需要你处理,网关默认就已经进行了转换。服务器接收到DatagramPacket中getAddress和getPort已经是网关的端口
UDP打洞的过程大致如此: 1、双方都通过UDP与服务器通讯后,网关默认就是做了一个外网IP和端口号 与你内网IP与端口号的映射,这个无需设置的,服务器也不需要知道客户的真正内网IP 2、用户A先通过服务器知道用户B的外网地址与端口 3、用户A向用户B的外网地址与端口发送消息, 4、在这一次发送中,用户B的网关会拒收这条消息,因为它的映射中并没有这条规则。 5、但是用户A的网关就会增加了一条允许规则,允许接收从B发送过来的消息 6、服务器要求用户B发送一个消息到用户A的外网IP与端口号 7、用户B发送一条消息,这时用户A就可以接收到B的消息,而且网关B也增加了允许规则 8、之后,由于网关A与网关B都增加了允许规则,所以A与B都可以向对方的外网IP和端口号发送消息.
其基本思想是这样的: 让位于NAT后的两台主机都与处于公共地址空间的、众所周知的第三台服务器相连,然后,一旦NAT设备建立好UDP状态信息就转为直接通信,并寄希望于NAT设备会在分组其实是从另外一个主机传送过来的情况下仍然保持当前状态。
这项技术在P2P软件和VoIP电话领域被广泛采用。它是Skype用以绕过防火墙和NAT设备的技术之一。
■比特币需要服务器吗? 从理论上讲,比特币没有中心服务器。 但在实际上,比特币软件常常会通过DNS Seed来获取一部分对等节点列表,使用户快速发现对等节点,这部分DNS地址被hardcoded在btc core里:
vSeeds.emplace_back("seed.bitcoin.sipa.be", true); // Pieter Wuille, only supports x1, x5, x9, and xd
vSeeds.emplace_back("dnsseed.bluematt.me", true); // Matt Corallo, only supports x9
vSeeds.emplace_back("dnsseed.bitcoin.dashjr.org", false); // Luke Dashjr
vSeeds.emplace_back("seed.bitcoinstats.com", true); // Christian Decker, supports x1 - xf
vSeeds.emplace_back("seed.bitcoin.jonasschnelli.ch", true); // Jonas Schnelli, only supports x1, x5, x9, and xd
vSeeds.emplace_back("seed.btc.petertodd.org", true); // Peter Todd, only supports x1, x5, x9, and xd
以上DNS由btc核心成员维护。 使用DNS的主要原因是:DNS基于UDP协议,不容易被DDoS攻击。
新安装的客户端是有几个种子服务器提供路由的,以后再启动客户端的时候就可以直接连别的节点了,每个比特币节点都自带路由功能。
■ P2P通信在穿透上至少存在着两个问题:防火墙穿透和NAT穿透
https://keeganlee.me/post/blockchain/20180313 比特币网络: 比特币网络中的节点主要有四大功能:钱包、挖矿、区块链数据库、网络路由。每个节点都会具备路由功能,但其他功能不一定都具备,不同类型的节点可能只包含部分功能,一般只有比特币核心(bitcoin core)节点才会包含所有四大功能。
所有节点都会参与校验和广播交易及区块信息,且会发现和维持与其他节点的连接。有些节点会包含完整的区块链数据库,包括所有交易数据,这种节点也称为全节点(Full Node)。另外一些节点只存储了区块链数据库的一部分,一般只存储区块头而不存储交易数据,它们会通过“简化交易验证(SPV)”的方式完成交易校验,这样的节点也称为 SPV节点或轻节点(Lightweight Node)。
除了比特币核心钱包是全节点之外,大部分钱包都是轻节点。
挖矿节点则通过解决工作量证明(PoW)算法问题,与其他挖矿节点相互竞争创建新区块。有些挖矿节点同时也是全节点,即也存储了完整的区块链数据库,这种节点一般都是独立矿工(Solo Miner)。还有一些挖矿节点不是独立挖矿的,而是和其他节点一起连接到矿池,参与集体挖矿,这种节点一般也称为矿池矿工(Pool Miner)。这会形成一个局部的集中式矿池网络,中心节点是一个矿池服务器,其他挖矿节点全部连接到矿池服务器。矿池矿工和矿池服务器之间的通信也不是采用标准的比特币协议,而是使用矿池挖矿协议,而矿池服务器作为一个全节点再与其他比特币节点使用主网络的比特币协议进行通信。
在整个比特币网络中,除了不同节点间使用比特币协议作为通信协议的主网络,也存在很多扩展网络,包括上面提到的矿池网络。不同的矿池网络可能还会使用不同的矿池挖矿协议,目前主流的具体矿池协议应该是 Stratum协议,该协议除了支持挖矿节点,也支持瘦客户端钱包。一个包含了比特币协议主网络各种节点和 Stratum 网络,以及其他矿池网络的扩展比特币网络大概如下图所示:
还需要一个专门的传播网络用来加快新区块在矿工之间的同步传播,这个专门网络也叫比特币传播网络或比特币中继网络(Bitcoin Relay Network)。
以太坊网络 和比特币一样,以太坊的节点也具备钱包、挖矿、区块链数据库、网络路由四大功能,也同样存在很多不同类型的节点,除了主网络之外也同样存在很多扩展网络。但与比特币不同的,比特币主网的 P2P 网络是无结构的,但以太坊的 P2P 网络是有结构的。
以太坊的 P2P 网络主要采用了 Kademlia(简称 Kad) 算法实现,Kad 是一种分布式哈希表(DHT)技术,使用该技术,可以实现在分布式环境下快速而又准确地路由、定位数据的问题。
在 Kad 网络中,每个节点都具有一个唯一的节点 ID。另外,也会计算不同节点之间的距离,但这个距离不是物理上的距离,而是逻辑上的距离,是通过对两个节点 ID 进行 异或(符号为^) 计算得到的,即 A、B 两节点之间的距离的计算公式为:D(A,B) = A.ID^B.ID。 异或有一个重要的性质:假设 a、b、c 为任意三个数,如果 a^b = a^c 成立,那就一定 b = c。因此,如果给定一个结点 a 和距离 L,那就有且仅有一个结点 b, 会使得 D(a,b) = L。通过这种方式,就能有效度量 Kad 网络中不同节点之间的逻辑距离。
在异或距离度量的基础上,Kad 还可以将整个网络拓扑组织成如下图所示的一个二叉前缀树,每个 NodeID 会映射到二叉树上的某个叶子。 映射规则主要是:
在这种二叉树结构下,对每个节点来说,离它越近的节点异或距离也是越近的。接着,可以按照离自己异或距离的远近,对整颗二叉树进行拆分。拆分规则是:从根节点开始,将不包括自己的那颗子树拆分出来,然后在包含自己的子树中,把不包括自己的下一层子树再拆分出来,以此类推,直到只剩下自己。 以上图的 110 节点为例,从根节点开始,由于 110 节点在右子树,所以将左边的整颗子树拆分出来,即包含 000、001、010 这三个节点的这颗子树;接着,到第二层子树,将不包含 110 节点的左子树再拆分出来,即包含 100 和 101 这两个节点的子树;最后,再将 111 拆分出来。这样,就将 110 节点之外的整个二叉树拆分出了三颗子树。
完成子树拆分后,只要知道每个子树里面的其中一个节点,就可以进行递归路由实现整颗二叉树所有节点的遍历。Kad 中有一个叫 K-桶(K-bucket)的概念,每个桶会记录每颗子树里所知道的多个节点。其实,一个K-桶就是一张路由表,如果拆分出来有 m 颗子树,那对应节点就需要维护 m 个路由表。每个节点都会各自维护自己的 m 个 K-桶,每个 K-桶里记录的节点信息一般会包括 NodeID、IP、Endpoint、与 Target 节点(即维护该 K-桶的节点)的异或距离等信息。以太坊中,每个节点维护的 K-桶数量为 256 个,这 256 个 K-桶会根据与 Target 节点的异或距离进行排序,每个 K-桶保存的节点数量上限是 16。
在以太坊的 Kad 网络中,节点之间的通信是基于 UDP 的,另外设置了 4 个主要的通信协议: Ping:用于探测一个节点是否在线 Pong:用于响应 Ping 命令 FindNode:用于查找与 Target 节点异或距离最近的其他节点 Neighbours:用于响应 FindNode 命令,会返回一或多个节点
■TCPとUDP TCPプロトコルとUDPプロトコルの大きな違いは信頼性と速度です。 TCPにはパケット通信を行う他に、開始処理と終了処理がありますが、UDPは即座にパケットを相手に送ります。 また、TCPではパケットを受け取ると、受け取った合図を返して到達性を担保しますが、UDPではパケットを投げっぱなしにするため、相手が受け取ったかどうかはわかりません。
■STUNサーバ NAT配下にあるPCがNATの外側から見た自身のIPアドレスを知るためのもの。 NAT配下にPCがある場合、P2P通信で相手に伝える必要がある自身のIPアドレスを知ることができません。そのため、P2PではSTUNサーバを経由することで、外側から見たIPアドレスを取得しています。
■TURNサーバ PC同士の間に立って、データの中継をしてくれることでNAT越えを実現するサーバ。 NAT配下でP2P通信を実現するためにすべてのパケットをグローバルなサーバとしてパケットを代理で相手PCに届けます。
细谈NAT https://blog.csdn.net/nivana999/article/details/5311942
■分类 NAT共分为两大类:Cone NAT(锥子型)和Symmetric NAT(对称型)。Cone NAT指的是只要源IP端口不变,无论发往的目的IP是否相同,在NAT上都映射为同一个端口,形象的看来就像锥子一样,而SymmetricNAT对于发往不同目的IP的会话在NAT上将映射为不同的端口,也就是不同的会话。 P2P需要用的是Cone NAT。
其中Cone NAT又可细分为3类,分别是Full Cone型、Restricted Cone型和Restricted Port Cone。限制的严格程度和对局域网内主机的保护由松到紧依次为:Full Cone、RestrictedCone、Restricted Port Cone、Symmetric NAT。
这里“限制”指的是NAT对由外到内的数据包进行审查、过滤,看看数据包的源地址和他发送到的“洞”是否有关系,如果没有那么就将其丢弃(说到这里我忽然想起来可不可以使用原始套接字来伪造一个和这个“洞”有关系的UDP包呢?啊哈哈),NAT是不会对自内而外的数据包进行限制的,那是防火墙的事情。
■NAT对会话的映射 A. 源IP不同,忽略其他因素,将映射为不同的Session B. 源IP相同,源端口不同,将映射为不同的Session C. 源IP相同,源端口相同,目的IP相同,目的端口不同,将映射为相同的Session D. 源IP相同,源端口相同,目的IP不同,忽略目的端口,对于不同的NAT可分为不同的情况 a) Cone NAT:将映射为相同的Session b) Symmetric NAT:将映射为不同的Session
■固定端口绑定 UDP打洞技术有一个主要的条件:只有当两个NAT都是Cone NAT(或者非NAT的防火墙)时才能工作。因为其维持了一个给定的(内网IP,内网UDP)二元组 和(公网IP, 公网UDP)二元组固定的端口绑定,只要该UDP端口还在使用中,就不会变化。如果像对称NAT一样,给每个新会话分配一个新的公网端口,就 会导致UDP应用程序无法使用跟外部端点已经打通了的通信链路。
■现实网络里的NAT 在穿越NAT的结论里,只有两种组合不能穿越,即对称型vs对称型、端口限制锥型vs对称型,占比并不高,看起来结论还不错。 但是,理论是美好的,现实是残酷的,生活中对称型NAT的数量并不少。只要是大型组织的网络,一般都采用对称型NAT,因为这类NAT安全性最好。
实际上大部运营商提供的光猫上网服务都是锥形nat的。而光纤入户,3g 4g网络,公共wifi登因为安全因素都是对称nat。 手机之间如果要通过3g 4g网络要进行p2p的话很遗憾是没有办法的。因为两边都是对称型NAT。
Skypeの通話を実現するネットワークの仕組み http://www.atmarkit.co.jp/fwin2k/operation/skype02/skype02_01.html
■実際のSkypeのネットワーク構成
実際のSkypeのネットワークだが、理想的なPtoPとは若干の違いが見られる。 まずSkypeのユーザー登録やログイン時のユーザー認証などを担当する専用のサーバが少数ながら存在する。これらのサーバの負荷はそう多くないし、セキュリティやユーザー管理のためには、PtoPで分散管理する必要はないからだ。
これに対して通話時の通信やノード間のルーティングといった、いわばSkypeネットワークの中核機能はサーバではなくPtoPの各ノードが担当する。
またPtoPではノード同士が対等と述べたが、Skypeのノードは完全に対等ではなく、役割の異なる3種類のノード、「通常ノード」「スーパーノード」「リレー・ノード」が存在する。ただしいずれもSkypeアプリケーションを実行する、通常のコンピュータである。
■通常ノード ユーザーがコンピュータ(例えばクライアントPC)上でSkypeアプリケーションを起動すると、Skypeのログイン用サーバで認証を受けた後、最初は「通常ノード」としてSkypeネットワークに参加することになる。そしてスーパーノードに依頼して通信相手を見つけ、その後さらに、見つかった相手と今度は直接接続を確立するか、もしくはリレー・ノードで中継してもらって、音声やビデオ通話などを行う。
すべてのノードは最初に通常ノードとして通信/通話処理などを行うが、状況によっては、ごく一部のノードが次のスーパーノードやリレー・ノードに昇格することがある。これらのノードでは通常の役割に加えて、Skypeネットワークを管理するための裏方的な役割「も」担当する。
■スーパーノード 「スーパーノード」は、通常ノードとしての機能のほかに、Skypeに参加しているノードの情報を記録したり、探索したりする機能も担当する。
■リレー・ノード スーパーノードに依頼して通信相手のIPアドレスやポート番号(およびログオン状態や登録されているスーパーノードの情報など)が分かれば、Skypeクライアントは、次は直接その相手と通信路を確立しようとする。だが相手との間にあるNATやファイアウォールによって、この試行が失敗することがままある。その場合、Skypeは「リレー・ノード」を使って通信を中継する。
重要なのは、リレー・ノードで中継すると直接通信を確立したときより通話品質は悪化しがちという点である。つまり、リレー・ノードを必要としないようにノード間の直接通信を確立できる方が望ましいということだ。
■ノードの割り当ては自動 どのSkypeアプリケーションにどのノードが割り当てられるかは、Skypeによって自動的に決定されるため、ユーザーが何か特に設定する必要はない。スーパーノードやリレー・ノードの選択基準は、基本的にはグローバルIPアドレスを持っていて(つまりインターネットにNATなしで直接接続されていること)、メモリやCPUパワーに余裕があり、稼働時間が長いノード(長く安定的に稼働しているノード)の中から動的に選択される。システムの状態やネットワークの混雑度/遅延時間などが変わると通常ノードに戻ることもある。
■現在、Skypeがピアツーピアからクラウド(Azure)に移行した。 SkypeといえばP2P方式でユーザー同士が直接パケットをやり取りするのが特徴とされていたが、現在ではP2Pが使われている部分は少なく、多くの機能はMicrosoftのクラウドシステムであるAzureを使用して実装・運用されているという。 現在P2Pが使われていない機能としてはモバイル端末上でのマルチパーティ音声/動画やファイル共有などが挙げられている。また、今後P2Pからクラウドへの移行が難しいサービスの一部についてはサービスを終了する予定だそうだ。
クラウド インフラストラクチャへの移行のメリットは、何ですか? A:クラウド ・ インフラストラクチャは、ピア ツー ピア アーキテクチャよりもバッテリの電力を必要とし、Skype の次世代を含む、エキサイティングな新しいフィーチャーを作成することができます。