NAT과 P2P

게임 서버 프로그래밍/네트워크 개념정리

2020. 2. 19. 16:19

NAT이 뭘까?

NAT은 Network Address Translation의 약자이다. NAT을 설명하기에 앞서서 먼저, NAT의 등장배경을 알아보자.

네트워크 용어에서 사용되어 왔던 모든 IP는 공인 IP를 의미했다.

공인 IP란 공개적으로 라우팅할 수 있다는 말로,

전 세계 인터넷상 어디서건 공인 IP로 패킷을 보내면
이 패킷이 인터넷의 여러 라우터를 거쳐 해당 호스트에 도달할 수 있다는 뜻이다.

이를 위해 공인 IP는 반드시 단 하나의 호스트에 고유하게 할당되어야 한다.

 

IPv4의 주소 공간은 32비트에 불과한데, 할당할 수 있는 공인 IP는 모두 합쳐도 43억 개에 못미친다.

오늘날 사용되는 기기의 숫자는 이를 훨씬 상회하므로 공인 IP는 휘귀한 자원이 되어버렸다.

다행히도 인터넷 공유기 같은 장비가 있으면 서브넷 전체 호스트를 단 하나의 공인 IP로 연결할 수 있다!

이 때 사용하는 기술이 바로 NAT이다.

 

NAT의 사용

네트워크를 NAT으로 구성하기 위해서는 서브넷의 각 호스트마다 공인 IP 대신 사설 IP를 할당해야 한다.

IP 주소 범위 서브넷
10.0.0.0 -10.255.255.255 10.0.0.0/8
172.16.0.0 - 172.31.255.255 172.16.0.0/12
192.168.0.0 - 192.168.255.255 192.168.0.0/16

위의 표는 사설 IP로 사용하려고 챙겨둔 주소 대역인데 이 범위의 주소는 결코 공인 IP로 사용되는 일이 없다.

그리고, 서로 다른 사설망이라면 각자의 IP가 겹쳐도 문제가 없다.

 

사설 IP는 공인 IP와는 다르게 주소를 배정할 때는 인터넷 업체의 허락을 받거나 할 필요가 전혀없다.


NAT을 알아 봤으니 온라인 게임에 있어서 네트워크가 어떻게 P2P로 연결되는지 알아보자.

NAT은 정말 좋은 기술이다. NAT을 통해 보안은 물론 IPv4의 ip 고갈 현상도 해결했으니 말이다.

하지만 NAT를 통해서 인터넷에 접속하는 과정을 통해 온라인 게임에서 P2P로 연결하게 될 시 문제점을 발견할 수 있다.

 

먼저, NAT을 이용해 인터넷에 접속하는 방법이다.

멀티플레이어 게임 프로그래밍 책에서 발췌

NAT를 사용하지 않는 경우부터 살펴보면, 공유기는 WAN 포트를 거쳐 패킷을 인터넷으로 보내고

패킷은 여차여차하여 서버에 도착할 것이다.

문제는 서버에서 응답 패킷을 보낼 수가 없다는 것이다!

왜냐하면 어떠한 공개 라우터도 사설 IP에 접근할 수 없기 때문이다.

만약 접근할 수 있다 하더라도 우리와 같은 사설 IP(사설 IP는 같은 서브넷만 아니라면 중복 가능)를 쓰는

호스트가 어마어마하게 많기 때문에 패킷이 제대로 도착한다는 보장이 없다.

 

이 문제를 해결하기 위해 NAT 모듈은 통과하는 IP 패킷의 발신지의 사설 IP를
공유기 자신의 공인 IP 주소로 재기입한다.

멀티플레이어 게임 프로그래밍 책에서 발췌

사설 IP 192.168.1.2를 18.19.20.21로 고쳐쓰면 공유기와 서버사이의 패킷교환은 가능하다.

하지만, 실제로 패킷을 보낸 장본인은 콘솔이지 공유기가 아니다. 따라서 해당 패킷이 콘솔 게임기로

올바르게 전달해 주려면 추가적인 조치를 취해야 한다.

 

매우 단순한 방법으로 매핑 테이블을 구성하는 것이다.

미리 패킷을 보내는 사설 IP의 주소와 목적지 주소를 적어놓고, 외부에서 패킷이 들어오면

테이블을 보고 해당하는 IP 주소로 응답을 보내는 로직이다.

하지만, 이러한 방식에 문제점은 여러 내부 호스트가 같은 외부 호스트로 패킷을 보내는 경우

외부 호스트 하나에 여러 내부 호스트가 매핑되므로, 그중 어느것인지 판단할 수가 없다.

 

최신 NAT 모듈은 네트워크 계층과 전송 계층의 추상화 경계를 넘나들며 이 문제를 대응한다.

바로 IP 헤더의 IP 주소뿐만 아니라, 전송 계층 헤더의 포트 번호까지 고쳐 쓰는 것이다.

 

 

멀티플레이어 게임 프로그래밍 책에서 발췌

  • 게임기의 패킷이 외부로 나가기 전 공유기에 도달하면 NAT 모듈이 그 발신자 IP 주소와 포트 번호를 테이블에 새 항목으로 추가한다.
  • 아직 사용한 적 없는 포트 번호 하나를 임의로 골라 금방 추가한 항목에 같이 기재해 둔다.
  • 외부로 가는 패킷은 이제 공유기의 공인 IP와 식별용 포트 번호를 달고 밖으로 나간다.
  • 서버로 부터 응답을 받은 NAT 모듈은 식별용 포트만 가지고도 NAT 테이블에서 원래 발신 호스트를 정확히 찾아낼 수 있다.

일부 공유기에서는 NAT 테이블에 수신자 IP 주소와 포트도 같이 기재해 두기도 한다.

테이블에 기재된 수신자 IP 주소와 포트가 외부에서 받은 패킷에 기재된 송신자의 것이

맞는지 점검하여 일치하지 않을시 해당 패킷을 폐기할 수 있다.

 

P2P (Peer to Peer)

사전적 정의로는 
각 컴퓨터가 동등한 능력을 가지고 있어, 어떤 컴퓨터에서라도 통신 세션을 시작할 수 있는 통신 모델을 지칭한다

간단히 말하면 클라이언트끼리 서버를 중간에 끼지 않고 통신을 한다는 것이다.

위의 NAT을 이용한 통신에서 만약 인터넷이 아니라 NAT을 사용하는 클라이언트끼리 통신을 한다면 어떻게 될까?

 

멀티 플레이어 게임 플로그래밍 책에서 발췌

호스트 A에 서버를 띄워두고 호스트 B가 서버에 참가하는 방식에서 나타나는 문제점은

호스트 B가 NAT에 의해 호스트 A가 띄워둔 서버에 접속할 방법이 없다는 것이다.

앞서 설명한 인터넷과의 NAT을 이용한 네트워크에서는 인터넷이 공인 IP를 가졌기 때문에

호스트 A가 먼저 패킷을 전달할 수 있었고 그 과정에서 매핑된 테이블덕에 인터넷에서 보낸

응답을 호스트 A가 받을 수 있었던 것이다.

 

하지만, 지금과 같은 경우에는 호스트 A, 호스트 B 모두 NAT에 의해 가려져 매핑 테이블을 만들수

없는 상황이 됐다.

 

NAT 투과를 통한 해결

NAT 투과는 말 그대로 NAT을 투과하여 패킷을 전달하는 것을 의미한다.

첫 번째 방법으로는 직접 공유기를 건드려 포트 포워딩 설정을 하는 것이다. 이는 어느 정도 기술 지식이 있어야 하므로 일반 플레이어가 하기엔 어려울 수도 있다.

두 번째 방법으로는 STUN (Simple traversal of UDP through NAT)이라고 불리는 기술을 사용하는 것이다.

 

STUN의 동작방법

  • 각 플레이어의 호스트는 공인 IP로 공개된 중개 호스트, 즉 Xbox 라이브나 플레이스테이션 네트워크 서버에 연결해야 한다.
  • 먼저 호스트 A는 게임 서버를 개설할 의도를 중개서버에 알리는 패킷을 보낸다.
  • 호스트 N은 플레이어 A가 공인 IP 주소 18.19.20.21:60000의 호스트 A에 게임 서버를 띄워두었다는 사실을 기억해 둔다.
  • 다음 호스트 B는 플레이어 A의 게임에 참여하고 싶다고 호스트 N에 알리는 패킷을 보낸다.
  • 호스트 N이 패킷을 받으면 공인 IP 12.12.6.5:62000의 호스트 B가 호스트 A에 접속하려 한다는 사실을 알게 된다.
  • 앞서 언급한 보안 문제로 대부분 라우터는 패킷의 발신자를 검사하여 원래의 발신자가 아닌 경우에는 차단한다. 이 때문에 호스트 N이 두 호스트의 공인 IP와 포트정보를 알고 있어도 바로 연결을 못하는 것이다.
  • 호스트 N이 호스트 A에 호스트 B에 대한 공인 IP와 포트 정보를 넘기면 호스트 A는 호스트 B에 패킷 하나를 보낸다. 이는 라우터 A의 테이블에 호스트 B의 정보를 매핑하기 위한 행위이며 STUN의 핵심이다!
  • 이제 같은 동작을 호스트 B가 호스트 A에 대하여 한다면, 라우터 A에 호스트 B에 대한 주소와 포트번호가 매핑되어 있어 이를 통과시켜서 호스트 A와 호스트 B가 통신할 수 있는 것이다.

'게임 서버 프로그래밍 > 네트워크 개념정리' 카테고리의 다른 글

압축  (0) 2020.02.24
직렬화  (0) 2020.02.24
TCP (Transmission Control Protocol)  (0) 2020.02.19
UDP (User Datagram Protocol)  (0) 2020.02.19
서브넷과 서브넷 마스크  (0) 2020.02.18