정보공간_1

[4기 신촌 김형진] UDP Hole Punching 소개 본문

IT 놀이터/Elite Member Tech & Talk

[4기 신촌 김형진] UDP Hole Punching 소개

알 수 없는 사용자 2013. 10. 28. 21:18

안녕하세요.

신촌멤버십 22-2기 김형진입니다.

네트워크에서의 Hole Punching이라는 개념에 대해 소개하도록 하겠습니다.

 

1. 개요


일반적으로 두 컴퓨터 간에 Client-To-Client형식으로 소켓 통신이 이루어지기 위해서는 두 컴퓨터가 직접 연결되어 있어야 제약 없이 통신이 가능합니다. 위의 그림에서 연두색으로 표기된 두 클라이언트 간을 의미합니다.

하지만, 실제로 많은 수의 컴퓨터들이 아래 파란색으로 표기된 클라이언트의 형식을 가지고 있습니다. NAT에 연결되어 있는 경우를 말합니다.

NAT, 간략히 설명하면 사설 IP”공인 IP”로 바꿔주는 통신상의 주소 변환기입니다. , 개별 클라이언트는 사설 IP를 가지고 있지만, 외부에 이 클라이언트에 접속하기 위해서는 공인 IP를 사용해야 합니다. 이러한 NAT의 기능은 라우터, 공유기 등에 포함되어 있습니다.

일반적인 가정의 네트워크 환경이라면, 컴퓨터가 1대인 경우에는 공유기 없이 사용하게 되는데, 이때는 사설IP와 공인IP가 동일합니다. 하지만 공유기가 설치되어 있는 경우에는, 공유기가 NAT의 역할을 하게 됩니다. 이 경우 공유기에 연결된 각각의 컴퓨터에 다음과 같이 사설IP가 할당됩니다.


이 경우의 공인IP는 모든 공유기에 연결된 클라이언트가 동일하게 다음과 같이 나오게 됩니다.



, 공인IP만을 이용해서 클라이언트를 구별할 방법이 없습니다.

따라서 이러한 환경에서는 Client-To-Client 형식의 네트워크 프로그램을 직접 구동할 수는 없습니다. 하지만 이러한 제약을 해결하기 위하여 Hole Punching과 같은 기법을 사용할 수 있습니다.

 

2. Hole Punching?

Hole Punching이란, 이러한 Client-To-Client 통신을 하기 위해, 직접 통신이 불가능한 클라이언트 간에 “Relay” 서버를 도입하여 통신을 하는 것입니다.


물론 직접 통신에 비해 효율이 떨어지지만, Relay서버의 역할을 단지 문자 그대로 중계의 역할만 하도록 역할을 최소화함으로써 직접 통신을 하는 것처럼 두 클라이언트 간에 통신을 할 수 있습니다.

하지만, Relay서버만 두고 통신을 할 수는 없습니다.

그 이유는, 만약 A라는 클라이언트가 B라는 다른 클라이언트와 통신을 해야 하는 경우가 있다면, 일반적인 Client-To-Client 프로그램에서는 B의 공인IP만으로 통신을 할 수 있습니다. 하지만 B의 공인IP를 통해 통신이 불가능한 상태라면, 다른 방법으로 B를 구별해 주어야 합니다. , B의 공인IP정보와 함께 사설IP정보를 알아야 Relay서버를 통해 통신을 시작할 수 있습니다.

하지만 모든 경우에 다 Relay서버가 필요한 것은 아니고, 사설IP만으로 혹은 공인IP만으로 통신이 가능한 경우가 있기 때문에, 개별 클라이언트에 대한 정보를 한 군데에 모아 해당 클라이언트가 어떤 유형인지를 다른 클라이언트에 알려 주는 서버가 필요합니다. 이러한 역할을 하는 서버를 “Stun” 서버라고 합니다.

, Hole Punching은 두 개 이상의 서버를 두어, 직접 통신을 할 수 없는 두 클라이언트 간의 통신을 원활하게 하도록 하는 통신 기법입니다.

여기서 Relay서버는 실질적으로 개별 클라이언트의 모든 통신을 관할해야 하므로, 만약 이 기법을 실제 서비스에 사용한다면 Relay서버의 수용능력이 실질적인 서비스의 질을 결정할 수 있습니다.

 

3. 연결의 유형에 따른 구현방법

일반적인 클라이언트는 다음과 같은 4가지 유형이 존재합니다. (이하 편의상 번호로 칭하겠습니다.)

1) NAT NAT

2) NAT NAT

3) NAT NAT (같은 NAT)

4) NAT NAT (다른 NAT)

방화벽이 없다는 가정 하에, 1, 3번 유형은 무제약 통신이 가능하지만, 2, 4번 유형은 직접 통신에 제약이 존재합니다. 따라서 2, 4번 유형에 한해 Relay서버를 이용한 통신을 해야 합니다.

 

먼저 1번 유형, 두 클라이언트 모두 NAT가 연결되지 않은 경우입니다. 이 경우에는 공인 IP가 곧 해당 클라이언트를 지칭하는 것이 되므로, 공인 IP를 이용해 직접 통신이 가능합니다.




 

다음 4번 유형, 두 클라이언트가 같은 NAT 아래 있는 경우입니다. 이 경우에는 NAT 안에서는 사설 IP가 곧 해당 클라이언트를 가리키므로, 사설 IP를 이용해 직접 통신이 가능합니다.



 

유형 2, 3번 유형은 모두 자신의 NAT 밖의 클라이언트와 통신해야 하는 경우입니다. 이때 Hole Punching 기법을 사용해야 하는데, 이를 위하여 Relay서버를 거쳐서 통신하도록 합니다.





 

Relay 서버를 거쳐 통신하는 경우에는 다음 그림과 같이 됩니다.



 

여기에 덧붙여 Stun서버는 다음과 같이 모든 클라이언트 간에 다른 클라이언트에 대한 정보를 주고받습니다.



 

4. 일반적인 구현방법

상기한 내용을 정리하면, Hole-Punching을 이용한 Client-To-Client 서비스의 구현은 다음과 같은 일련의 순서로 이루어집니다.

1) Stun 서버에 각 클라이언트 접속정보 저장할 공간을 둔다.

2) 각 클라이언트는 Stun서버에 자신의 접속정보를 보낸다.

3) 다른 클라이언트는 Stun을 통해 접속방법을 파악한다.

4) 유형 2, 3인 경우 Relay서버를 사용하여 접속한다.

5) 유형 1, 4인 경우 직접 접속한다.

6) Relay서버는 각 클라이언트와 항시 연결되어야 한다.

 

UDP 통신을 이용하는 경우 TCP 통신보다 Hole Punching을 구현하기 더 쉽습니다. 그 이유는 명확한 서버/클라이언트 구별이 없기 때문에 여러 대의 클라이언트가 되더라도 자연스럽게 통신할 수 있습니다.

하지만, UDP에서는 전송의 신뢰성이 부족한 단점 때문에 TCP 통신을 이용하게 되면, 두 클라이언트간의 통신인 경우에는 서버/클라이언트만 명확히 구별해 주면 되지만, 클라이언트가 3개 이상인 경우 서로 통신하기 위해서는 각각의 접속 방법에 따라 서버/클라이언트 구별이 어렵습니다. 물론 구현할 수 없는 것은 아니지만, UDP에 비해서 구현하기 어렵습니다.

따라서 TCP의 장점을 이용할 것이 아니라면 Hole Punching을 구현하기 위해서는 일반적으로 UDP 통신을 이용하는 것이 더 좋습니다.