ICE 是以 P2P 連線為前提的一種協調方法,主要是 VOIP、P2P視訊在使用。因為現在的網路終端,通常都在 Firewall 裡面,透過 NAT 上網,導致 P2P 連線的困難度大增,因此 ICE 透過 Stun 的技術,判讀 NAT 類型,當遇到特殊的 NAT 類型,無法處理 P2P 時,就搭配 Turn Server 為兩個終端進行資料中繼傳輸。
ICE
ref: Introduction to WebRTC protocols
主要用在 UDP 多媒體 session,為了解決 NAT 的問題,ICE 可嘗試找到多個 candidates,取得最佳的連線方法。
ICE 透過 stun server 查詢 NAT 類型,以及取得自己對外的 IP:Port。
如果無法直接 p2p 連線,就會改用 Turn Server 中繼,互相傳遞資料。
SDP
RFC4566 SDP 是用來協調 session 傳輸所要交換的資訊,內容可能會有這些
會話描述:
v= (protocol version)
o= (originator and session identifier)
s= (session name)
i=* (session information)
u=* (URI of description)
e=* (email address)
p=* (phone number)
c=* (connection information -- not required if included in
all media)
b=* (zero or more bandwidth information lines)
One or more time descriptions ("t=" and "r=" lines; see below)
z=* (time zone adjustments)
k=* (encryption key)
a=* (zero or more session attribute lines)
Zero or more media descriptions
時間資訊描述:
t= (time the session is active)
r=* (zero or more repeat times)
多媒體資訊描述(如果有的話):
m= (media name and transport address)
i=* (media title)
c=* (connection information -- optional if included at
session level)
b=* (zero or more bandwidth information lines)
k=* (encryption key)
a=* (zero or more media attribute lines)
ex:
v=0
o=jdoe 2890844526 2890842807 IN IP4 10.47.16.5
s=SDP Seminar
i=A Seminar on the session description protocol
u=http://www.example.com/seminars/sdp.pdf
e=j.doe@example.com (Jane Doe)
c=IN IP4 224.2.17.12/127
t=2873397496 2873404696
a=recvonly
m=audio 49170 RTP/AVP 0
m=video 51372 RTP/AVP 99
a=rtpmap:99 h263-1998/90000
NAT
依據 NAT的限制方式,可分為四種:
Full Cone NAT(one-to-one)
- 只是單純的做位址轉換,並未對進出的封包設限
Address-Restricted Cone NAT
- 從內部送出之封包的目的地 IP 位址會被記住。只有這些曾經收過這些封包的位址可以送封包進入內部 IP。由其他位址送進來的封包,都會被拒絕。
Port-Restricted cone NAT
- 封包進出比 Restricted Cone 增加了一個限制, 從內部送出之封包的目的地的IP 位址及 Port Number 會被記住。 由外部送進來的封包,除了由那些接收過內部所送出的封包的IP 位址及 Port Number 所送來的封包之外,都會被拒絕。
Symmetric NAT
- 前三種NAT在做位址轉換時,無論封包是送往哪裡, NAT內部同一內部位址都對應到同一個外部位址:Port,但 Symmetric NAT 內則每一內部位址對於不同的目的地,會對應到不同的外部 IP address:Port。
- Symmetric NAT只允許先由私有網域內的機器,發送封包到網際網路中的接收端可以回傳封包
判斷方法
NAT Test 提供一種方式,可以判斷是否為 Symmetric NAT,因為 Understanding Different NAT Types and Hole-Punching 的說明,只要有一端為 Symmetric NAT,就無法直接 p2p 連線。
判斷的方法是利用 RTCPeerConnection 對 google stun server 建立連線,由 onicecandidate 判讀, port 跟 rport 是否一樣。
// JScript File
function parseCandidate(line) {
console.log("parseCandidate="+line);
// candidate:842163049 1 udp 1677729535 220.132.127.162 42280 typ srflx raddr 0.0.0.0 rport 0 generation 0 ufrag 1cTw network-cost 999
var parts;
// Parse both variants.
// 兩種:a=candidate: or candidate:
if (line.indexOf('a=candidate:') === 0) {
parts = line.substring(12).split(' ');
} else {
parts = line.substring(10).split(' ');
}
var candidate = {
foundation: parts[0],
component: parts[1],
protocol: parts[2].toLowerCase(),
priority: parseInt(parts[3], 10),
ip: parts[4],
port: parseInt(parts[5], 10),
// skip parts[6] == 'typ'
type: parts[7]
};
for (var i = 8; i < parts.length; i += 2) {
switch (parts[i]) {
case 'raddr':
candidate.relatedAddress = parts[i + 1];
break;
case 'rport':
candidate.relatedPort = parseInt(parts[i + 1], 10);
break;
case 'tcptype':
candidate.tcpType = parts[i + 1];
break;
default: // Unknown extensions are silently ignored.
break;
}
}
console.log("candidate=",candidate);
// {
// "foundation": "842163049",
// "component": "1",
// "protocol": "udp",
// "priority": 1677729535,
// "ip": "220.132.127.162",
// "port": 42280,
// "type": "srflx",
// "relatedAddress": "0.0.0.0",
// "relatedPort": 0
// }
return candidate;
};
function testNat() {
//reset lblResult
document.getElementById("MainContent_lblResult").style.color = "#696969";
document.getElementById("MainContent_lblResult").innerHTML = "Test started " + new Date().toLocaleString() + "<br>";
var candidates = {};
var pc = new RTCPeerConnection({
iceServers: [
{ urls: 'stun:stun1.l.google.com:19302' },
{ urls: 'stun:stun2.l.google.com:19302' }
]
});
document.getElementById("MainContent_lblResult").innerHTML += "Create data channel to Google STUN servers<br>";
pc.createDataChannel("foo");
document.getElementById("MainContent_lblResult").innerHTML += "Testing...Please Wait...<br>";
pc.onicecandidate = function (e) {
console.log(e);
if (e.candidate && e.candidate.candidate.indexOf('srflx') !== -1) {
console.log("e.candidate.candidate="+e.candidate.candidate);
var cand = parseCandidate(e.candidate.candidate);
// console.log("candidates[cand.relatedPort]=",candidates[cand.relatedPort]);
if (!candidates[cand.relatedPort]) candidates[cand.relatedPort] = [];
// console.log("candidates[cand.relatedPort]=",candidates[cand.relatedPort]);
candidates[cand.relatedPort].push(cand.port);
// console.log("candidates[cand.relatedPort]=",candidates[cand.relatedPort]);
} else if (!e.candidate) {
// All ICE candidates have been sent
console.log("candidates=",candidates);
// {
// "0": [
// 42280
// ]
// }
if (Object.keys(candidates).length === 1) {
var ports = candidates[Object.keys(candidates)[0]];
console.log("ports", ports);
//window.alert(ports.length === 1 ? 'normal nat' : 'symmetric nat');
if (ports.length === 1) {
document.getElementById("MainContent_lblResult2").innerHTML = "Completed: Normal NAT";
} else {
document.getElementById("MainContent_lblResult2").innerHTML = "Completed: Symmetric NAT";
}
document.getElementById("MainContent_lblResult2").style.color = "green";
}
}
};
pc.createOffer()
.then(offer => pc.setLocalDescription(offer))
};
另一個判斷的 TypeScript: isNormalNat.ts
ICE协议下NAT穿越的实现(STUN&TURN) 這邊有說明,stun server 是如何判斷 NAT 類型的
candidate type
ref: RFC 5245
ref: WebRTC connectivity
udp 有四種:host, srflx, prflx, relay
host:實體 IP,可直接連線
srflx:Server Reflexive and Relayed Candidates
host 因為經過 NAT,透過 Stun/Turn server 產生的 candidate
prflx: Peer Reflexive Candidates
其中一端來自 symmetric NAT
relay
由 Turn Server 產生的中繼 IP:Port
tcp 有三種:active, passive, so
active
會打開 outbound connection,且不接受 incoming connection request。這是最常見的類型
passive
只會接受 incoming connection
so
會嘗試同時在兩個終端直接打開連線
References
ICE (Interactive Connectivity Establishment)
30-29之 WebRTC 的 P2P 打洞術 ( ICE )
Peer-to-Peer Communication Across Network Address Translators
about 82% of the NATs tested support hole punching for UDP, and about 64% support hole punching for TCP streams
[筆記] WebRTC 網路影音-通訊協定篇(protocol of media, video and audio)
Understanding Different NAT Types and Hole-Punching
30-28之 WebRTC 連線前傳 - 為什麼 P2P 連線很麻煩 ? ( NAT )
WebRTC ICE candidate里面的raddr和rport表示什么?
Network Configuration for VoIP Providers
C ICE implementation library
沒有留言:
張貼留言