UDP 홀펀칭

2007. 1. 15. 14:33Java

UDP 홀펀칭을 하는 이유는 클라이언트와 클라이언트간 UDP 통신을 하기 위함이다.
서버와는 굳이 사용할필요없을듯. TCP로 사용하면 되니

1. A와 B가 서버로 TCP를 통해 접속하게 만들어 봅시다.

2. 사용자 A와 B가 UDP로 통신하고 싶을때에 서버로 UDP를 쏘게 합시다.
   (물론 서버는 UDP 쓰레드가 따로 하나 필요하겠죠..)

3. UDP 쓰레드에서 A와 B로부터 UDP 패킷을 받으면 TCP로 그만 쏘라고 보냅니다.
   (이건 뮤텍스나 락을 걸어서 각각의 쓰레드가 안전하도록 잘 설계합니다.)

4. TCP로 A와 B에게 상대방의 공인아이피와 포트를 알립니다.

5. A와 B는 서로의 공인아이피로 UDP 통신을 합니다.

* UDP는 자기가 보낸적이 있는 장소(ip:port) 로 들어오는것들만 받을수 있다.

======================================================================================





================================================================================
0. 들어가기 전 알아두어야 할 용어들.
- NAT [Network Address Translation]
OSI 모델의 3계층인 네트워크 계층에서 사설 IP 주소를 공인 IP 주소로 변환하는데 사용하는 통신망의 주소 변환기.
http://100.naver.com/100.nhn?docid=717874
우리가 흔히 말하는 공유기, 라우터 등이 이런 역할을 수행한다고 보면 된다.


1. 개요
Hole Punch 란 종이에 철을 하기 위해 동그란 구멍을 뚫어주는 사무용 기기이다.
그런 개념으로 접근하여 막힌 뭔가를 뻥 뚫어준다는 것으로 이해하고 출발하여 보자.
일단은 P2P 연결을 위한 여러 기술들을 알아보기로 한다. (홀 펀칭은 그 중의 하나이므로..)



2. 이해
- 전제 : 통신을 하기 위한 Client A와 Client B가 존재하며경우에 따라 NAT아래 놓일 수 있다.
이들의 통신을 중계하기 위한 Server S가 존재한다.
NAT과의 P2P 커뮤니케이션하기 위해서는 몇가지의 기술이 있다.
Relaying, Connection Reversal, UDP Hole Punching, UDP Port Number Prediction, Simultaneous TCP Connection Initiation 이 그것이다.
일단 Relaying부터 살펴보도록 하자.


3. 기술
3.1 Relaying


Relaying은 간단히 중계 서버를 두고 중계 서버를 통해 통신을 한다.
A가 서버 S에게 메세지를 보내고 서버 S는 B에게 메세지를 보낸다.
A와 B가 서버에 접속이 유효한 동안은 메세지를 계속 주고 받을 수 있다.
하지만 불필요한 대역폭의 낭비와 서버의 리소스를 소모하게 된다.



3.2 Connection Reversal

이 경우는 하나의 클라이언트가 NAT뒤에 위치해 있는 경우이다.
B가 A와의 연결을 하고자 할때 A믜 사설IP로는 당연히 접속이 불가능하고, 서버 S가 관찰하는 NAT의 공인 IP로의 접속은 A에서 나가는 것만 허용하기 때문에 역시 접속이 불가능하다.
그래서 중계 서버 S를 이용해 "내가 못가니까 니가 나와라" 고 해서 B의 공인 IP를 서버 S에게 알려 준 다음 역으로 A가 접속을 시도하여 커넥션을 맺게 하는 방식이다.


3.3 UDP Hole Punching


이 경우는 두 클라이언트가 전부 NAT 뒤에 있는 경우이다.
여기서 두 클라이언트가 같은 NAT 뒤에 있는가 혹은 다른 NAT 뒤에 있는가로 다시 경우가 나뉘어 진다.



3.3.1 두 클라이언트가 다른 NAT 뒤에 있을 때.

클라이언트 A가 B와 커넥션을 맺고 싶을 떄 일반적으로는 3.2의 경우와 같이 커넥션이 맺어지지 않으므로 중계서버 S를 이용하여야 한다.
서버 S에 접속할때 서버는 클라이언트 A의 정보 (사설,공인 IP)를 취득하여 저장하게 되고 B가 접속할때도 이 정보를 저장하게 된다.
그리고 만약 A가 B에 대해서 연결을 요청하게 되면 중계서버 S는 A와 B에게 동시에 서로의 IP 정보를 보내 주게 되고 커넥션 희망여부를 전달받은 각 클라이언트는 각각 연결 시도를 하게 되어 커넥션이 맺어질 수 있게 된다.

- 추가사항 : UDP 커넥션의 경우에는 지속적인 핑퐁 메세지가 없으면 연결이 끊어질수 있기 때문에 일정간격으로 연락을 해 주어야 한다. NAT의 종류에 따라서 되는것도 있고 안되는것도 있다고 한다..(성공 확률 분포 등에 대한 자료는 PDF문서 참조)

일단 기본적인 기술은 여기까지 이해하고 나머지 추가적인 기술과 내용들은 아래의 주소에서 더 확인이 가능하다.
(사실 이거 이해를 하려고 꽤나 머리를 싸맸다. 아직 확실한지는 잘 모르겠지만서도 -_-)


[ Network Address Translation and Peer-to-Peer Applications (NATP2P) ]
[ (PDF)
TCP Connections for P2P Apps ]
[ (PDF)
Peer-to-Peer Communication Across Network Address Translators ]
[
P2P에서 UDP를 쓰는 이유 (Gpg study forum) ]


by ncanis(조성준)