Peering

Peering / 블로그

iPhone은 어떻게 어디서나 Mac에 닿을까

Mac은 공유기 뒤에 있고 iPhone은 모바일 네트워크에 있습니다. 어느 쪽도 상대에게 먼저 연결할 수 없습니다. 두 기기가 대화를 시작하기까지의 과정을, 일어나는 순서대로 설명합니다.

같은 네트워크에서: Bonjour와 포트 하나

Mac 앱은 TCP 포트 51515에서 대기하며, Bonjour로 _remotedesktop._tcp 서비스를 알립니다. 여기에는 기기 ID, Mac의 이름, 프로토콜 버전이라는 작은 정보 세 가지가 붙습니다. iPhone이 이 서비스를 탐색하므로, 같은 Wi-Fi에 있는 Mac은 주소를 입력하지 않아도 주변 목록에 나타납니다.

이 알림은 힌트일 뿐입니다. 네트워크에 있는 누구나 무엇이든 알릴 수 있으므로, 보안과 관련된 판단은 여기서 하지 않습니다. 중요한 것은 다음 단계입니다. iPhone이 TLS 1.3 연결을 열고, 양쪽이 인증서를 제시하며, 각자 상대의 공개 키를 페어링할 때 저장해 둔 키와 비교합니다. 페어링이 작동하는 방식은 별도의 글에서 다룹니다.

집 네트워크에서 iPhone은 연결을 두 개 엽니다. 하나는 제어용(입력, 설정, 창 목록)이고, 다른 하나는 화면만 전달합니다. 영상을 제어 스트림에서 분리해 두면, 큰 키프레임 때문에 마우스 클릭이 그 뒤에서 기다리는 일이 생기지 않습니다.

iPhone의 Peering: 주변 Mac 목록, 다른 곳에 있는 Mac과 페어링하는 방법, 신뢰하는 Mac이 표시된 연결 화면.
주변 Mac은 Bonjour로 찾습니다. 신뢰하는 Mac은 이미 페어링한 기기입니다.

네트워크 밖에서: 소개만 하는 릴레이

집을 나서면 iPhone은 공유기 뒤의 사설 주소에 닿을 수 없고, 공유기는 아무도 요청하지 않은 연결을 받지 않습니다. 그래서 Mac이 먼저, 일찍 움직입니다. 실행 중인 동안 Mac은 Peering 릴레이로 나가는 WebSocket을 하나 열어 두고 25초마다 작은 핑을 보냅니다. 이렇게 열려 있는 소켓이 곧 Mac의 존재 신호이며, 릴레이는 이것으로 Mac이 있고 깨어 있다는 것을 압니다.

iPhone에서 내 Mac을 탭하면 다음 일이 일어납니다.

  1. iPhone이 릴레이에 Mac의 기기 ID로 연결해 달라고 요청합니다.
  2. 릴레이가 양쪽에 주소와, 제어용과 영상용으로 한 쌍인 무작위 16바이트 토큰을 알려 줍니다.
  3. 두 기기가 각각 릴레이로 나가는 TCP 연결을 열고, 가장 먼저 자기 토큰을 씁니다.
  4. 릴레이가 두 토큰을 맞춰 보고 소켓을 이어 붙여, 한쪽의 바이트를 다른 쪽으로 복사합니다.

그다음 iPhone은 집 네트워크에서 쓰던 것과 같은 TLS 핸드셰이크를 시작하며, 이는 릴레이를 그대로 통과해 Mac에 도달합니다. 릴레이는 파이프일 뿐 대화의 당사자가 아닙니다. 키를 가진 적이 없습니다. 릴레이가 알 수 있는 것과 없는 것은 릴레이가 볼 수 있는 것에서 자세히 읽어 보세요.

화면은 지름길로 갑니다

모든 것을 릴레이로 보내도 동작은 하지만, 가장 느리고 비용이 큰 경로입니다. 그래서 화면은 TCP 연결에 머물지 않고 영상에 더 알맞은 UDP로 옮겨 갑니다. 늦게 도착한 프레임은 쓸모가 없고, 재전송은 다음 프레임을 더 늦출 뿐입니다.

양쪽은 릴레이에 질문도 하나 합니다. 상대는 어떤 주소에서 접속하는가? 릴레이는 자신이 관찰한 주소를 알려 주고, 두 기기는 250밀리초마다 서로에게 봉인된 작은 프로브 패킷을 보내기 시작합니다. 프로브 하나하나가 보낸 쪽 공유기에 구멍을 내며, 두 구멍이 맞물리면 프로브가 통과해 인증됩니다. 그 순간부터 화면은 Mac에서 iPhone으로 곧장 가고, 릴레이는 영상 경로에서 빠집니다.

이 기법은 보통 홀 펀칭이라고 부릅니다. 대부분의 가정용 공유기에서 동작하고, 엄격한 일부 모바일 및 회사 네트워크에서는 실패하며, 그 경우 화면은 그대로 릴레이를 거쳐 계속 흐릅니다. 어느 쪽이든 설정하거나 포트를 열 필요가 없습니다.

UDP가 막혀 있을 때

일부 네트워크는 UDP를 아예 차단합니다. 제어 연결은 여전히 응답하는데 3초 동안 화면이 도착하지 않으면, iPhone은 Mac에 영상을 제어 스트림으로 조각내어 보내 달라고 요청합니다. 비트레이트 상한이 낮아 화면이 흐릿해 보이지만, 흐릿한 화면이 멈춘 화면보다 낫습니다. Mac은 빠른 경로로도 몇 초마다 키프레임을 계속 보내고, iPhone이 그 경로가 회복된 것을 보면 다시 전환합니다.

이렇게 만든 이유

사용자 관점의 설명과, 외출 중에도 Mac에 접속할 수 있게 유지하는 설정은 어디서나 Mac에 접속하기와 원격 접속을 위해 Mac을 깨어 있게 유지하기를 참고하세요.

자주 묻는 질문

집 밖에서 Peering을 쓰려면 공유기의 포트를 열어야 하나요?

아니요. 모든 연결은 바깥쪽으로 나가는 방향입니다. Mac은 릴레이에 연결을 하나 열어 두고, 두 기기가 모두 릴레이로 접속하므로 포트 포워딩이 필요 없습니다.

Peering은 세션 내내 릴레이를 쓰나요?

릴레이는 연결 초기에만 관여합니다. 그 뒤 화면은 Mac과 iPhone 사이를 직접 오가려 하고, 네트워크가 직접 경로를 허용하지 않으면 릴레이로 되돌아갑니다.