WebRTC를 사용할 때 필요한 지식들에 대한 개념정리 입니다.
NAT는 쉽게 말해서 공유기이다.
기기별로 IP가 있고, 그 IP는 고정IP, 유동IP로 나뉘어서 실제 고유의 값일 수도 있고 아닐 수도 있다.
더 나아가서는 회사망/내부망(LAN)은 Private IP이기 때문에 다른 네트워크 등 다른 네트워크에서는 통용되지 않는다.
그렇기 때문에,
우리가 통상적인 네트워크에서 데이터를 주고 받기 위해서는 Public IP가 필요하다.
NAT는 Private IP를 Public IP로 1대1 대응시켜 변환하는 장치를 말한다.

하지만, WebRTC 통신은 Peer to Peer 방식으로 서로 데이터를 주고 받아야 하기 때문에 보내고 받는 Peer의 정보(Public IP)를 알고 있어야 한다.
그러나 Public IP는 요청을 보낼 때 마다 private IP -> public IP로 NAT에 의해 변환되기 때문에 동일한 Public IP로 통신할 수 없는 문제점이 발생하게 된다.
또한 방화벽 또한 외부의 요청들을 무시하기 때문에 peer와 peer가 통신을 할 때 이런 장벽들에 막히게 된다.
이러한 문제를 해결하고 WebRTC를 사용하며 데이터를 주고 받을 수 있는 방법이 있다.
바로 STUN, TURN 서버를 사용하는 것이다.
NAT는 사설 네트워크에 속한 여러 개의 호스트가 하나의 공인 IP 주소를 사용하여 인터넷에 접속하기 위함이다.
즉, private ip를 사용하고 있는 컴퓨터가 사설 바깥쪽에 있는 public ip에 해당되는 외부세계에 접속할 수 있게 된다. 이때 사용하는 기술이 NAT이다.
ICE는 두 단말이 서로 통신할 수 있는 최적의 경로를 찾게 도와주는 프레임워크이다.
왜 ICE를 사용해야 하느냐?
ICE 혼자는 작동하지 않고 **STUN과 TURN 서버를 사용해야 한다.
공개 주소를 발견하거나 peer 간의 직접 연결을 막는 등 라우터의 제한을 결정하며 ICE를 보완하는 프로토콜이다.
STUN 서버는 해당 Peer의 Public IP 주소를 보내는 역할을 한다.
STUN은 두 엔드 포인트 간의 연결을 확인하고 NAT 바인딩을 유지하기 위한 연결 유지 프로토콜로도 사용할 수 있다.

위 그림처럼, STUN 서버는 클라이언트로부터 요청을 받으면 클라이언트의 공용 IP주소와 포트를 응답해주는 역할을 하는 것이다.
Peer는 응답받은 IP주소를 통해 Peer와 P2P 통신을 진행하게 된다.
하지만, STUN은 항상 효과적이진 않다.
두 단말이 같은 NAT 환경에 있을 경우 또는 NAT의 보안정책이 엄격하거나 등의 이유에 따라 STUN이 완벽한 해결책이 되진 않는다.
보안정책이 엄격하다는 예시 중 하나로, 방화벽의 종류가 있다.
1. Full Cone NAT : 모든걸 열어둔다.
2. Restricted Cone : White List같은거. 일단 막고, 내가 허용한 애들은 다 댇고옴
3. Port Restricted : White List + 경로(Port)까지 맞춰야하는 친구.
4. Symmetric NAT : 매번 포트가 바뀌어서 요청하는? 아주 까다로운 놈임. 그래서 보안은 우수하지만 실제 사용하기에 굉장히 까다롭다.(P2P에선 사실상 불가능)
이런식으로 Symetric 보안정책이라면 사실상 STUN으로 P2P 통신을 하긴 힘들어진다는 것이다.
STUN의 확장으로 NAT 환경에서 릴레이하여 통신을 하게 된다.
위에 서술한대로 NAT 보안정책이 너무 엄격하거나, NAT 순회를 하기위해 필요한 NAT 바인딩을 성공적으로 생성할 수 없는 경우에 TURN을 사용한다.
TURN 서버는 인터넷망에 위치하고 각 Peer들이 사설망(Private IP) 안에서 통신한다.
각 Peer들이 직접 통신하는 것이 아니라 릴레이 역할을 하는 TURN 서버를 사용하여 경유한다.
TURN은 이러한 릴레이로부터 IP주소와 포트를 클라이언트가 취득할 수 있는 릴레이 주소를 할당한다.
TURN은 장단이 명확한데, STUN에 비해 연결 안정성이 좋지만, 그만큼 리소스 낭비가 심하다. 그렇기 때문에, ICE Cadidate 과정에서 최후 우선순위로 밀리는 기술이다.

수집한 후보지를 서로에게 전달한다.
서로 교환한 이 후보지들이 연결이 되는지를 체크해본다.
위의 후보지들의 우선순위(1 -> 2 -> 3)를 기반으로 가장 최적의 경로를 선정한다.
연결을 유지하고 통신한다.