# Firefox의 Rust 기반 고속 UDP I/O

> Clean Markdown view of GeekNews topic #23318. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=23318](https://news.hada.io/topic?id=23318)
- GeekNews Markdown: [https://news.hada.io/topic/23318.md](https://news.hada.io/topic/23318.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-09-28T09:53:38+09:00
- Updated: 2025-09-28T09:53:38+09:00
- Original source: [max-inden.de](https://max-inden.de/post/fast-udp-io-in-firefox/)
- Points: 1
- Comments: 1

## Topic Body

- **Firefox**의 HTTP 트래픽 약 20%가 **HTTP/3**을 사용하며, 이는 QUIC 및 UDP 위에서 작동함
- 기존 네트워크 I/O 계층인 **NSPR**를 **Rust 기반 quinn-udp**로 대체하면서 **성능과 메모리 안전성**을 강화함
- **각 운영체제별로 최신 시스템 콜**(multi-message, segmentation offloading 등)을 적극적으로 활용해 성능 최적화를 적용함
- **Windows** 및 **MacOS**에서는 일부 기능이 호환성, 드라이버 이슈 등으로 제한되었으나, **Linux**에서는 최적 성능을 확인함
- **QUIC ECN 지원과 UDP I/O** 관련 다양한 플랫폼별 시행착오, 버그 해결 경험이 **향후 프로젝트 및 오픈소스 생태계**에도 도움이 될 전망임

---

### 동기

- Firefox HTTP 트래픽의 약 20%가 **HTTP/3**을 사용하며, 이는 **QUIC**을 통해 동작하고, 다시 **UDP** 위에서 구현됨
- Firefox는 역사적으로 **NSPR** 라이브러리를 네트워크 I/O에 사용했으나, UDP I/O 관련 기능이 **오래되고 제한적임** (주요 함수는 `PR_SendTo`, `PR_RecvFrom`)
- 운영체제들은 최근에 **멀티 메시지 시스템 콜**(ex. `sendmmsg`, `recvmmsg`)과 **세그멘테이션 오프로드**(GSO, GRO) 같은 네트워크 최적화를 제공함
- 이러한 기술들은 UDP I/O **성능을 크게 향상**시킬 수 있음
- Firefox가 **기존 UDP I/O 스택을 현대적 시스템 콜로 교체**해 이점을 얻을 수 있는지 모색함

### 개요

- 프로젝트는 2024년 중반 시작, 목표는 **Firefox의 QUIC UDP I/O 스택을 모든 지원 OS에서 현대적 시스템 콜로 재구축**하는 것임
- 성능 개선과 더불어, UDP I/O에 **메모리 안전성이 보장되는 Rust**를 활용해 보안성 향상도 도모함
- QUIC 자체는 이미 Rust로 구현되어 있어서, **Rust 기반 quinn-udp 라이브러리** 위에서 개발을 진행함
- OS 간 시스템 콜 차이는 개발 난이도를 높였으나, quinn-udp 덕분에 개발 속도가 크게 개선됨
- 2025년 중반 현재, 대다수 Firefox 사용자에게 적용이 진행 중이며, 성능 벤치마크에서 **최대 4Gbit/s로 대폭 상승**하는 결과를 보임

### UDP I/O 구조와 현대적 최적화 방식

#### 단일 데이터그램 전송

- 기존 방식은 `sendto`와 `recvfrom`을 사용, 한 번에 **단일 UDP 데이터그램**만 송수신
- 사용자 공간과 커널 공간 간의 전환 비용은 데이터그램 단위로 지불되어, 대용량 트래픽 환경에서는 **비효율적임**
- 예시: 1500바이트 미만의 패킷을 초당 수백 Mbit 이상으로 보내려면 상당한 오버헤드 발생

#### 다중 데이터그램 배치 전송

- **Linux 등 일부 OS**에서 `sendmmsg` 및 `recvmmsg`와 같은 멀티 메시지 시스템 콜 지원
- 여러 데이터그램을 한 번에 송수신 하여, **오버헤드를 대폭 줄일 수 있음**

#### 단일 대용량 세그먼티드 데이터그램

- **GSO(송신)** , **GRO(수신)** 등 오프로드 기술로 **큰 UDP 데이터그램을 OS 또는 NIC에서 자동으로 분할**해 전송
- 네트워크 인터페이스가 패킷 단위로 분리, 체크섬 계산 및 헤더 붙이기를 처리
- 이를 통해 애플리케이션 단은 **단 한 번의 시스템 콜만으로 다수의 실제 패킷 처리 가능**
- GSO 활성화 상태에서는 Wireshark 등 일부 네트워크 툴의 패킷 분석 지원이 미흡

### Firefox의 NSPR 대체 과정

- 우선 **단일 데이터그램 송수신** 구조에서 **quinn-udp**로 NSPR를 대체
- QUIC 구현체의 데이터그램 처리 파이프라인을 **배치 송수신 및 세그먼테이션을 지원하도록 리팩터링**
- multi-message 콜, segmentation offload 콜 모두 상황에 맞게 활용
- 플랫폼별 예외 처리 및 다양한 I/O 개선 기능이 추가됨

### 플랫폼별 세부 사항

#### Windows

- Windows는 `WSASendMsg`/`WSARecvMsg`를 제공, 전통적인 MTU 사이즈 데이터그램 또는 대형 세그먼티드 데이터그램 지원
- Linux의 GSO/GRO에 대응하는 Windows의 **USO(송신) / URO(수신)** 
- 초기에는 단일 데이터그램 콜만 사용하여 문제 없었으나, URO 활성화 시 특정 환경(예: **Windows on ARM + WSL**)에서 **QUIC 패킷 길이 판별 불가**로 인해 페이지 로딩 실패 버그 발생
- USO/송신도 사용했으나, Firefox Windows 설치 환경에서 **패킷 손실 증가 및 네트워크 드라이버 크래시** 등 부작용 발견
- 현재 Firefox에서는 **URO/USO 비활성화 상태** 유지 및 추가 디버깅 진행 중

#### MacOS

- MacOS에서는 기존 `sendto`/`recvfrom` 대신 `sendmsg`/`recvmsg`로 quinn-udp 도입
- 세그멘테이션 오프로드 기능은 활성화되어 있지 않음
- 대신 공식 문서화되지 않은 `sendmsg_x`/`recvmsg_x`로 **배치 전송** 지원, quinn-udp에 비공식적으로 적용
- 애플이 향후 해당 호출을 제거할 수 있음에 따라, **기본 활성화 없이 테스트만 진행** 후 실제 릴리즈에는 미포함

#### Linux

- **sendmmsg/recvmmsg** 및 **GSO/GRO** 모두 지원, quinn-udp는 송신 시 GSO를 기본 우선시함
- Firefox는 **연결마다 UDP 소켓을 별도로 사용**해 프라이버시 강화를 도모(4-tuple 구분)
- 이 구조에서는 **세그멘테이션 오프로드의 이점이 극대화**, sendmmsg/recvmmsg의 교차 전송 이점은 제한적
- 네트워크 샌드박스, 런타임 GSO 지원 체크 등 소규모 변경 외 어려움 없이 도입 성공

#### Android

- Android는 Linux와 달리 시스템 콜 처리 경로 및 보안 필터(예: seccomp)가 다름
- x86 기반 Android 5 등 **매우 오래된 플랫폼의 지원** 및, `socketcall` 우회, 오류 처리 등 다양한 호환성 이슈 존재
- 일부 환경에서는 ECN 비트가 활성화된 송신 호출 시 오류(EINVAL) 발생, quinn-udp에서 **재시도 및 옵션 해제 전략** 적용
- Quinn 커뮤니티에서의 다양한 개선 이점 덕분에 **Firefox도 자동으로 개선 효과를 누릴 수 있음**

### ECN(명시적 혼잡 알림) 지원

- 최신 시스템 콜 도입 덕분에 ancillary data(부가 데이터) 송수신 지원, **QUIC ECN** 지원 가능
- 소규모 버그는 있었으나, Firefox Nightly에서 **절반 이상의 QUIC 연결이 ECN outbound 경로로 동작**
- L4S 등 신기술이 부각됨에 따라 **ECN 지원의 중요도와 활용성 상승**

### 결론 요약

- Firefox의 QUIC UDP I/O 계층을 **quinn-udp 기반 Rust 구현체로 교체**, 성능과 보안성을 동시에 확보
- dated 시스템 콜 대신 **각 OS별 최신 I/O 시스템 콜**을 활용하여 처리량 향상 및 ECN 지원이 가능해짐
- Windows 등 일부 최적화 기능은 호환성 이슈로 추가 개선 필요
- QUIC 사용률이 지속적으로 늘어남에 따라, 앞으로도 OS/드라이버 수준의 지원이 계속 발전할 것임

## Comments



### Comment 44353

- Author: neo
- Created: 2025-09-28T09:53:38+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=45387462) 
- 글의 핵심은 중간에 숨어 있음  
  > 극단적인 경우로 CPU 바운드 벤치마크에서 < 1Gbit/s에서 4 Gbit/s로 향상됨. CPU flamegraph상 대부분의 시간은 I/O 시스템 콜과 암호화 코드에서 소모됨  
  네트워크 처리량이 400% 증가했다는 점은 UDP 네트워크 트래픽에서 CPU 사용량이 크게 줄어듦을 의미함  
  이는 특히 모바일 및 노트북 등 휴대용 클라이언트에서 전력 효율 향상 측면에서도 인상적인 부분임  
  이런 전환이 항상 좋은 것으로 받아들여지는 분위기가 있지만, 이 글은 실제 데이터를 통해 입증해서 신선하게 느껴짐

  - 언젠가 유저와 시스템 프로그램 간의 컨텍스트를 넘나드는 메시지 패싱이 하드웨어 가속으로 돌아가는 날이 올지 궁금함

- 여기서 나온 개선은 실제 초고속(100Gb/s 이상)을 위해 필수이긴 하지만, 4Gb/s는 사실 별로 빠르지 않은 속도임  
  500MB/s라 이건 뭔가 심각하게 느린 병목 지점이 있다는 의미임  
  커널 컨텍스트 스위치가 1us대라는데 사실 시스템 콜 치고는 높은 편임  
  하지만 패킷당 평균 약 500바이트만 되도 500MB/s, 즉 4Gb/s 달성 가능함  
  예전 1Gb/s는 패킷 크기가 더 작았을 때였고, UDP 패킷을 단순히 NIC 버퍼에 밀어넣는 건 메모리 복사 속도로도 충분히 가능한 수준임  
  암호화가 느리다 해도 실제론 그렇지 않음  
  예를 들어 Intel i5-6500이 1729MB/s AES-128 GCM 속도를 낸 바 있음  
  지금 CPU는 코어당 3-5GB/s, 즉 25-40Gb/s도 가능한데 여기서 말한 4Gb/s는 너무 낮은 수치임  
  ([AES-128 GCM 성능 참고 링크](https://calomel.org/aesni_ssl_performance.html))

    - 시스템 콜 대기 시간이 높다 했는데, 그 원인은 spectre & meltdown 대응 조치 때문일 수 있음  
      TCP는 경로 바인딩이 있지만 UDP에는 없어 경로 설정에 차이가 큼  
      암호화가 느리다는 건, 작은 PDU(프로토콜 데이터 단위)에서는 맞는 말임  
      대부분이 대용량 TCP 프레임 기준으로 최적화 및 벤치마킹되어 실제로는 작은 패킷에서 상태 설정 비용이 두드러짐  
      tight loop에서 마이크로벤치마크 돌리면 수치가 잘 나오지만, 실제 랜덤성 있는 환경에서는 캐시 활용 효율도 낮아지고, 1KB 이하 패킷은 효율이 뚝 떨어짐  
      여기에 추가적인 프레이밍 오버헤드, 바깥 밴드 데이터 유효성 검사 등 꽤 비싸게 작동함  
      UDP 버퍼 메모리도 기본 값이 부족해 실사용엔 문제가 많음  
      TCP 운영하며 버퍼 크기 계속 키웠지만 UDP는 90~00년대 보수적인 값에 머물러 있음  
      진짜 필요한 API는, fd 포크해서 connect(2) 및 라우트 바인딩 완전 지원, 이후 submission queue 기반(uring, rio 등) 이어야 함  
      암호화 측면에서, KDF 접근 방식이 상태 비용을 많이 줄일 수 있음  
      PSP 방식은 일부 벤더가 인정하지만 IETF 등에서 많이 거부당해서 널리 퍼지지 않음  
      벤더들의 대규모 동시성 테스트에선 기존 TLS류보다 월등히 높은 스케일링 수치 나옴

    - 벤치마크한 CPU가 어떤 등급인지는 전혀 언급 안 됨  
      그리고 암호화 오버헤드는 QUIC 프로토콜 자체 처리 비용임  
      QUIC은 암호화 오프로드(하드웨어 처리)가 TCP 대비 미흡한데, TCP는 kTLS 오프로드로 어느 정도 NIC 처리 가능함

- 이런 기술 콘텐츠 정말 만족스러웠음  
  Mozilla의 모든 기술 자료가 이렇게 실무 엔지니어가 제대로 작성한 깊이 있는 내용이었으면 좋겠음  
  낙관론(alegria) 따위 없이, 읽을 가치가 높음

- 왜 Android 5를 아직도 지원하는지 모르겠음  
  출시된 지 10년이 넘었고, 그 기기를 쓰는 유저는 더 오래된 레거시임  
  요즘 웹은 너무 무거워서 이런 구형 기기로는 제대로 브라우징하기조차 힘들 텐데 굳이 지원하는 이유가 궁금함  
  아마 옛날 OnePlus 같은 기기를 보수해서 충전기 꼽아두고 LineageOS 같은 국민 롬도 안 올리고 대체 앱스토어에서 파이어폭스 써보는 해커들 정도임  
  현실적으로는 전체 개발 속도를 늦추는 비용임

-  
  > 이슈 리포터(마찬가지로 Mozilla 직원)와 수많은 시간을 왔다 갔다 하다가, 결국 문제 재현을 위해 노트북까지 똑같은 모델, 색상으로 사서 테스트했다는 부분  
  네트워크 재현의 미친 현실을 XKCD 2259 에서처럼 보여줘서 재밌었음  
  ([xkcd 만화 링크](https://xkcd.com/2259/))

    -  
      "The map download struggle"라는 Factorio 개발 블로그에도 이와 관련된 흥미로운 에피소드가 있으니 추천함  
      ([관련 블로그 글](https://www.factorio.com/blog/post/fff-176))

    -  
      실제로 네트워크 문제 다뤄 본 사람이라면 미스터리한 패킷 런트(mystery packet runts) 때문에 더 공감할 내용임  
      대부분의 네트워크 장비들이 이런 패킷 처리 잘 못함  
      UDP나 QUIC 기반 트래픽은 일정한 수준 이상의 대형 클라우드 환경이 아니면 쉽게 공격에 휘둘림  
      이 때문에 소규모 혹은 자체 운영하는 호스팅 업체는 점점 운영이 어려워지고, 대형 트래픽 처리 역량이 있는 곳만 남게 됨  
      그래서 대부분의 LAN 환경에선 UDP 트래픽 대부분을 드롭하고 필요한 부분만 레이트 리밋해서 처리 중임

-  
  [모질라 버그 트래커](https://bugzilla.mozilla.org/show_bug.cgi?id=1979683)  
  macOS와 Fedora에서 Cloudflare가 호스팅하는 사이트를 Firefox로 접속 시 여전히 같은 현상을 겪고 있음

-  
  Windows와 MacOS에도 GSO/GRO(대용량 네트워크 패킷 처리) 유사 기능이 있다는 사실을 이번에 알게 됐음  
  다만 실제론 버그가 많다니 아쉬움

    -  
      Microsoft와 Apple이 왜 자기네 네트워크 스택 품질에 좀 더 신경을 안 쓰는지 의문임  
      GSO/GRO만 버그가 있는 게 아닐 거라는 생각도 듦

-  
  UDP GSO/GRO가 구조적으로 어떻게 동작하는지 설명 가능한 사람 있냐는 질문임  
  UDP는 순서가 없는 패킷인데, QUIC 한 패킷이 여러 UDP 패킷으로 쪼개질 때 헤더에 시퀀스 정보도 없는데 수신 측에서 어떻게 순서 맞춰 합치는지 궁금함

    -  
      내가 파악한 바로는, 애플리케이션 레벨에서는 GRO가 활성화돼 있어도 사실상 합쳐진 UDP 데이터그램을 받는 일이 없음  
      커널이 여러 데이터그램을 하나의 구조체에 담아서, 각 계층끼리 경계(예, sk_buff 내 data fragments)를 유지한 채로 넘기는 개념임  
      정확한 전문가는 아니지만 이 방식이 어떻게 동작하는지 찾아보다가 [이 글](https://lwn.net/Articles/768995/)을 참고하게 됨

-  
  "우리는 Quinn 프로젝트의 UDP I/O 라이브러리인 quinn-udp 위에서 개발을 시작했으며 이 덕에 개발 속도가 훨씬 빨라졌다"고 언급했는데  
  그럼 혹시 Quinn 프로젝트에 후원을 진행했는지 궁금함  
  ([Quinn 후원 링크](https://opencollective.com/quinn-rs))

    -  
      재정 지원 관련해서 직접 물어봤더니, Mozilla의 Senior Principal Software Engineer가 "Mozilla는 돈이 없어요"라고 답변해줬음  
      다만 코드는 엄청나게 많이 기여해줘서 정말 감사하게 생각하고 있음  
      (나는 Quinn 메인테이너임)

    -  
      "후원했나요?"라는 질문에, 굳이 오픈소스 후원 안 해도 CEO 연봉에 수백만 달러 더 쓰는 게 Mozilla의 방식이라는 의견 제시함  
      플래그십 제품(Firefox)까지도 무너져가는데 말임

    -  
      코드 등 다른 방식으로 기여한 점이 있다면 궁금함

-  
  sendmmsg/recvmmsg가 “최신”이라 불린다는 게 놀라움  
  사실 꽤 오랜 시간 존재한 시스템 콜임  
  Linux 관련 내용에서 io_uring도 언급될 줄 알았는데 없어서 아쉬움

    -  
      io_uring은 여러 UDP 다이어그램을 한 번에 처리하는 진짜 의미의 배치 기능이 없음  
      최선을 다해도 sendmsg, recvmsg 여러 개를 한 번에 요청하는 것 정도임  
      GSO/GRO가 정답임  
      sendmmsg/recvmmsg는 이미 매우 오래된 기술이며, 커널 개발자들 중엔 이제 없애고 싶다는 사람도 있음  
      ([관련 GitHub 토론](https://github.com/axboe/liburing/discussions/1346))
