Show GN: Noctiluca - 원격 제어 소프트웨어의 미래는 WebRTC가 아니라 QUIC이었던 것 같습니다
(x.com/cheese_rulez)안녕하세요, unstabler라고 합니다. 처음으로 글을 써봅니다.
평소에 글을 자주 쓰는 편이 아니어서 두서가 없는 장황한 글이지만 잘 부탁드립니다!
macOS가 싫어서 macOS에 집착하기 시작했습니다
저는 2011년부터 Linux 데스크톱을 주로 사용해 왔었습니다. Ubuntu, Debian, Fedora를 거쳐 Arch Linux + KDE Plasma를 메인 OS로 계속 써왔습니다. 이런 저런 사정으로 인해, 2021년부터 SI 업체 비슷하게 굴러가는 회사를 세우게 되었고, 임베디드 C++건, 모바일 앱이건, 단순 웹사이트건, 재밌게 할 수 있는 일이라면 뭐든 받아서 했습니다.
그러던 와중에, iOS 앱을 만드는 일의 비중이 점점 많아졌습니다. 하지만 Mac은 별로 쓰고 싶지 않았습니다. 처음에는 카라비너로 키바인드도 이리 저리 바꿔보고 하다, 구글 원격 데스크톱으로 접속하여 작업을 하곤 했지만 너무 느리기도 하고, Xcode에서 키 입력이나 마우스가 일부 이상하게 작동하여 스트레스를 많이 받았습니다.
그러고보니 RDP! xrdp가 있었지!
RDP가 문득 떠올랐습니다. RDP는 Microsoft Windows용으로 개발된 프로토콜이지만, xrdp라고 하는 오픈 소스 구현체가 있었습니다. 하지만 xrdp는 기본으로 X11 사용을 전제로 하고 있고, macOS에서는 기본 화면 공유 + VNC 백엔드의 조합이 사용 가능했지만, 화면 해상도가 1:1로 맞지 않으면 도저히 사용이 불가능할 지경이었습니다.
그래서 xrdp의 VNC 백엔드와 ScreenCaptureKit을 기반으로 ''麗 -ulalaca-' 라는 xrdp 백엔드 플러그인을 만들게 되었지만, 실사용이 가능할 수준까지는 이르지 못했습니다.
-
최신 버전의 Windows (mstsc.exe)에서 사라져버린 GFX (H.264) / RFX 지원:
제가 개발을 시작했을 즈음에는 이미 GFX / RemoteFX 코덱에 대한 지원이 빠지기 시작했었습니다. Linux용 클라이언트인 FreeRDP에는 여전히 지원이 남아있지만, 현재 버전의 Windows에서는 RLE 기반의 압축만 남아있는 것으로 보입니다. - 극악의 개발 / 디버깅 난이도: 화면 표시 기능 외에는 개발이 너무 어려웠고, 디버깅 또한 너무 어려웠습니다. 처음에는 의욕을 잔뜩 가지고 소리 출력 / 클립보드 동기화 등도 만들어 보고 싶었지만, 가뜩이나 ADHD를 앓고 있었기 때문에 흥미가 빠르게 식어갔습니다.
WebRTC로 다시 한번 만들어보자! 하지만...
ulalaca를 방치하고 약 반년 뒤, Noctiluca를 구상하면서 'WebRTC로 다시 한번 제대로 만들어 보자!' 같은 생각이 들었습니다. 하지만, WebRTC 구현도 만만치 않았습니다.
- 커스터마이징의 어려움: 화면 데이터를 비디오 소스로 사용하기 위해서, Google Chromium의 소스 코드를 받아서 수정해야만 했습니다. 코덱 파라미터를 수정한 뒤로 하드웨어 인코딩이 동작하지 않았던 때는, 그 이유를 알기 위해 소스 코드를 헤집고 다니면서 로그를 추가하고, 매번 새로 빌드해야만 했습니다.
- 포트 고정 불가: 시그널링 서버도 필요하고, TURN/STUN도 필요했고, 무엇보다 나가는 포트의 고정이 불가능하고 포트 재사용이 불가능했습니다. 너무 괴로웠습니다.
- SCTP의 저주: WebRTC DataChannel은 SCTP를 내부적으로 사용합니다. 한 메시지의 페이로드 사이즈가 MTU보다 커지면, 비디오 / 오디오 스트림에 렉이 걸리기 시작한다는 문제가 있습니다.
결국, 돌아서 돌아서 QUIC으로
WebRTC의 복잡함에 지쳐, 이번에도 Noctiluca를 반년 가까이 방치해 버렸습니다. 카페에서 멍 때리고 돌아가는 길에, 문득 HTTP/3의 기반이 된다는 QUIC이 떠올랐습니다. 마침 macOS / iOS에서도 Network.framework 에서 QUIC 구현체를 제공하고 있었기 때문에, 기존 소스 코드를 베이스로 프로토타입은 금방 만들 수 있었는데, 프로토타입 레벨에서 아래 문제가 곧바로 해결되었습니다.
-
Head-of-Line Blocking (HOL) 해결: TCP 기반의 솔루션들이나, SCTP를 쓰는 WebRTC DataChannel의 가장 큰 문제는 패킷 하나가 유실되면 뒤따라오는 모든 데이터가 멈춘다는 것입니다. 하지만 QUIC은 스트림이 독립적입니다. 오디오 패킷 하나가 튀어도, 마우스 입력이나 비디오 프레임은 계속 쏟아져 들어옵니다.
-
단일 UDP 포트와 Connection Migration: WebRTC처럼 시그널링 서버니 STUN/TURN이니 복잡하게 구성할 필요가 없었습니다. 그냥 UDP 포트 하나만 열면 끝입니다. Wi-Fi AP를 전환해도 Connection Migration 덕분에 연결이 유지되었습니다.
결론: 베타 테스터를 모십니다!
이러한 사연을 가지고 있는 'Noctiluca'라는 원격 제어 소프트웨어의 베타 테스터 분들을 모십니다.
-
QUIC 기반의 'Sirius'라는 자체 설계 프로토콜을 사용합니다.
- 조만간 스펙 등이 확정되면 오픈 소스로 공개할 예정입니다!
-
H.264 / H.265 (HEVC)를 지원합니다.
- VM 환경을 위한 전통적인 타일 기반 이미지 코덱 (MJPG, RLE, WebP)도 지원합니다.
-
HDR 컨텐츠의 전송을 지원합니다. (실험적)
-
클라이언트-서버 간 코덱 요구사항을 협상할 수 있습니다.
-
PAM (username-password), password-only, SSH 키를 사용한 인증을 지원합니다.
-
플러그인으로 기능을 확장할 수 있습니다. 추후 fail2ban 등을 구현하여 추가 기능으로 제공할 예정입니다.
- 플러그인을 직접 작성하여 인증 메커니즘을 확장할 수 있습니다.
-
클라이언트는 현재 iOS / macOS 버전만 존재합니다.
- Qt / C++ 기반의 Linux / Windows 클라이언트를 개발할 예정입니다!
제 리눅스 랩탑으로 iOS 앱 개발이 가능해지는 그 날까지!
오늘도 저의 리눅스 랩탑으로 돌아가기 위한 여정은 계속됩니다.
감사합니다.
(+ 사실 구글 드라이브 링크를 곧바로 여기에 올려도 되는지 모르겠어서 일단 예전에 소개할 때 올렸던 X 포스트를 링크로 올렸습니다..!)
- 첫 테스트 버전의 구글 드라이브 링크: https://drive.google.com/drive/folders/1r4m7lGZ-f988dp_piLAEwlJRLPODPNQq?usp=drive_link
(++ Noctiluca를 개발하면서 바이브 코딩으로 만든 부산물(?)이지만 이쪽도 잘 부탁드립니다..!)
- swift-msquic: iOS / macOS에서 MsQuic을 Swift로 쉽게 쓸 수 있도록 만든 wrapper 모듈입니다!
- Xuanxue: Swift에서 SSH 키를 사용하여 서명 / 서명 검증을 수행할 수 있도록 해주는 모듈입니다! 너무 게으른 나머지 뭐든 날로 먹고 싶어서 이렇게 이름을 지었습니다!