network
p2p에서 udp 홀 펀칭(hole punching)

p2p에서 udp 홀 펀칭(hole punching)

udp 홀 펀칭이란 아웃바운드만 열고 NAT 뒤에 가려진 peer 간에 UDP 기반 peer to peer 통신이 가능하도록 구멍 뚫는것을 말함

서로 다른 NAT 뒤에 Client 가 있을 때

picture 0

위 세개의 이미지 중에서 중간 이미지 가 좀 어려울 수 있다

(1) Request Connection to B(2) Forward B's Endpoints to A 이 부분은 그냥저냥 이해가 되는데

(3) Send to B at 의 그림이 이해가 잘 안간다

(a) 138.76.29.7:31000 이 왜 실패하냐?

최초 A가 B의 퍼블릭 주소로 보내는 UDP 패킷은 B의 NAT 입장에서 인바운드 패킷이고, B의 NAT는 인바운드는 하나도 열어놓지 않았다.

앞서 B의 NAT는 Server S에게 A의 퍼블릭 주소를 획득하기 위해 보냈던 요청(좌측 이미지 참고)으로 인하여 아웃바운드orgin-src:10.1.1.3:4321 / NAT changed-src:138.76.29.7:31000 / dst:18.181.0.31:1234 이라는 맵핑 정보만 저장해놓았기에

Server S(18.181.0.31:1234)138.76.29.7:31000 로 요청을 보낼 경우만 패킷이 허용되는 상태이다

A가 B로 보내는 최초 요청 (a) 138.76.29.7:31000 이 실패했지만

이로 인하여 A의 NAT는 앞서 B의 퍼블릭 주소 획득을 위해 Server S와의 맵핑 정보(좌측 이미지 참고)

orgin-src:10.0.0.1:4321 / NAT changed-src:155.99.25.11:62000 / dst:18.181.0.31:1234

orgin-src:10.0.0.1:4321 / NAT changed-src:155.99.25.11:62000 / dst:138.76.29.7:31000 과 같이 dst를 B의 NAT으로 바꿔서 저장하게된다

이렇게되면 B의 NAT(138.76.29.7:31000)A의 NAT(155.99.25.11:62000) 로 요청을 보낼 수 있는 상태가 된다

이로 인하여 B의 NAT이 들어올 수 있는 구멍 이 뚫림

예시를 통한 연결 과정

  • peer A 내부 주소 : 10.0.0.1:1234
  • peer A 외부 주소 : 11.22.33.44:1111
  • peer B 내부 주소 : 20.0.0.2:5678
  • perr B 외부 주소 : 55.66.77.88:9999
  1. peer A, peer B 가 각각 STUN 을 통하 자기 자신의 외부 주소 를 획득한다
  2. 이때 각각 NAT에 peer 내부 주소:peer 외부주소 <--> STUN 주소포트 매핑 엔트리 가 저장된다
  3. peer A가 peer B에 연결을 시도한다. 이때의 목적지 주소는 20.0.0.2:5678 이다
  4. peer A가 알고 있는 20.0.0.2:5678 는 peer B 의 내부 주소로 peer B NAT뒤에 있기 때문에 peer A가 바로 찾아갈 방법이 없다
  5. peer A는 STUN 에게 20.0.0.2:5678 의 외부 주소를 요청한다
  6. peer A는 STUN 에게 받은 외부 주소로 다시 요청을 보낸다 10.0.0.1:1234(A 내부):11.22.33.44:1111(A 외부) -> 55.66.77.88:9999(B 외부)
  7. peer B도 1~6까지 동일한 과정을 거친다
  8. 이제 peer 끼리 상대방의 외부 주소 로 이어지는 포트 매핑 엔트리가 완성되어있는 상태이다
  9. P2P 가 가능해진다

참고 링크

https://bford.info/pub/net/p2pnat/ (opens in a new tab)