- Firefox HTTP trafiğinin yaklaşık %20’si HTTP/3 kullanıyor; bu da QUIC ve UDP üzerinde çalışıyor
- Mevcut ağ I/O katmanı NSPR, Rust tabanlı quinn-udp ile değiştirilerek performans ve bellek güvenliği güçlendirildi
- Her işletim sistemine özel en yeni sistem çağrıları (multi-message, segmentation offloading vb.) aktif biçimde kullanılarak performans optimizasyonu uygulandı
- Windows ve MacOS’ta bazı özellikler uyumluluk ve sürücü sorunları nedeniyle sınırlı kalırken, Linux’ta en iyi performans doğrulandı
- QUIC ECN desteği ve UDP I/O ile ilgili platform bazlı çeşitli denemeler, sorunlar ve hata düzeltme deneyimlerinin gelecekteki projeler ve açık kaynak ekosistemi için de faydalı olması bekleniyor
Motivasyon
- Firefox HTTP trafiğinin yaklaşık %20’si HTTP/3 kullanıyor; bu da QUIC üzerinden çalışıyor ve sonuçta UDP üzerinde uygulanıyor
- Firefox tarihsel olarak ağ I/O için NSPR kütüphanesini kullandı, ancak UDP I/O ile ilgili işlevler eski ve sınırlı durumda (başlıca işlevler
PR_SendTo, PR_RecvFrom)
- İşletim sistemleri son dönemde çoklu mesaj sistem çağrıları (örn.
sendmmsg, recvmmsg) ve segmentation offload (GSO, GRO) gibi ağ optimizasyonları sunuyor
- Bu teknikler UDP I/O performansını önemli ölçüde artırabilir
- Firefox, mevcut UDP I/O yığınını modern sistem çağrılarıyla değiştirerek bu avantajlardan yararlanıp yararlanamayacağını araştırdı
Genel bakış
- Proje 2024’ün ortalarında başladı; hedef, Firefox’un QUIC UDP I/O yığınını desteklenen tüm işletim sistemlerinde modern sistem çağrılarıyla yeniden inşa etmekti
- Performans artışının yanında, UDP I/O’da bellek güvenliği sağlayan Rust kullanılarak güvenliğin de artırılması hedeflendi
- QUIC’in kendisi zaten Rust ile uygulanmış olduğundan, Rust tabanlı quinn-udp kütüphanesi üzerinde geliştirme yapıldı
- İşletim sistemleri arasındaki sistem çağrısı farkları geliştirmeyi zorlaştırsa da, quinn-udp sayesinde geliştirme hızı büyük ölçüde arttı
- 2025 ortası itibarıyla çoğu Firefox kullanıcısına dağıtım sürüyor ve performans karşılaştırmalarında 4 Gbit/s’ye kadar büyük artış görüldü
UDP I/O yapısı ve modern optimizasyon yöntemleri
Tek datagram gönderimi
- Mevcut yöntem
sendto ve recvfrom kullanıyor; bir seferde yalnızca tek bir UDP datagramı gönderilip alınıyor
- Kullanıcı alanı ile çekirdek alanı arasındaki geçiş maliyeti datagram başına ödendiği için, yüksek hacimli trafik ortamlarında verimsiz kalıyor
- Örnek: 1500 bayttan küçük paketleri saniyede yüzlerce Mbit’in üzerinde göndermek ciddi ek yük oluşturuyor
Çoklu datagram toplu gönderimi
- Linux gibi bazı işletim sistemleri,
sendmmsg ve recvmmsg gibi çoklu mesaj sistem çağrılarını destekliyor
- Birden fazla datagramı tek seferde gönderip alarak ek yükü büyük ölçüde azaltmak mümkün
Tek büyük segmentlere ayrılmış datagram
- GSO (gönderim) ve GRO (alım) gibi offload teknikleriyle büyük UDP datagramları OS veya NIC tarafından otomatik olarak bölünerek iletiliyor
- Ağ arayüzü paketleri paket düzeyinde ayırıyor, sağlama toplamı hesaplama ve başlık ekleme işlemlerini üstleniyor
- Böylece uygulama tarafı tek bir sistem çağrısıyla çok sayıda gerçek paketi işleyebiliyor
- GSO etkin olduğunda Wireshark gibi bazı ağ araçlarının paket analizi desteği yetersiz kalabiliyor
Firefox’ta NSPR’nin değiştirilme süreci
- İlk olarak tek datagram gönderme/alma yapısında NSPR, quinn-udp ile değiştirildi
- QUIC uygulamasının datagram işleme hattı, toplu gönderim/alım ve segmentasyonu destekleyecek şekilde yeniden düzenlendi
- Multi-message çağrıları ve segmentation offload çağrıları duruma göre birlikte kullanıldı
- Platforma özel istisna işleme ve çeşitli I/O iyileştirmeleri eklendi
Platform bazlı ayrıntılar
Windows
- Windows,
WSASendMsg/WSARecvMsg sağlıyor; geleneksel MTU boyutlu datagramları veya büyük segmentlere ayrılmış datagramları destekliyor
- Linux’taki GSO/GRO’ya karşılık Windows’ta USO (gönderim) / URO (alım) bulunuyor
- Başlangıçta yalnızca tek datagram çağrıları kullanıldığında sorun yoktu; ancak URO etkinleştirildiğinde belirli ortamlarda (örn. Windows on ARM + WSL) QUIC paket uzunluğunun belirlenememesi nedeniyle sayfa yükleme hataları oluştu
- USO/gönderim de kullanıldı, ancak Firefox’un Windows kurulum ortamlarında artan paket kaybı ve ağ sürücüsü çökmesi gibi yan etkiler görüldü
- Şu anda Firefox’ta URO/USO devre dışı tutuluyor ve ek hata ayıklama sürüyor
MacOS
- MacOS’ta quinn-udp, mevcut
sendto/recvfrom yerine sendmsg/recvmsg kullanılarak devreye alındı
- Segmentation offload özelliği etkin değil
- Bunun yerine resmî olarak belgelenmemiş
sendmsg_x/recvmsg_x ile toplu aktarım destekleniyor ve bu, quinn-udp’ye gayriresmî olarak uygulandı
- Apple’ın ileride bu çağrıları kaldırma ihtimali nedeniyle, varsayılan olarak etkinleştirilmeden yalnızca test edildi ve gerçek sürüme dahil edilmedi
Linux
- sendmmsg/recvmmsg ile GSO/GRO desteğinin tamamı mevcut; quinn-udp gönderimde varsayılan olarak GSO’yu önceliklendiriyor
- Firefox, gizliliği artırmak için her bağlantı için ayrı bir UDP soketi kullanıyor (4-tuple ayrımı)
- Bu yapıda segmentation offload’un faydası en üst düzeye çıkarken, sendmmsg/recvmmsg’nin bağlantılar arası toplu iletim avantajı sınırlı kalıyor
- Ağ sandbox’ı, çalışma zamanında GSO desteği kontrolü gibi küçük değişiklikler dışında, zorluk yaşamadan başarıyla devreye alındı
Android
- Android, Linux’tan farklı olarak sistem çağrısı işleme yolu ve güvenlik filtreleri (örn. seccomp) açısından ayrışıyor
- x86 tabanlı Android 5 gibi çok eski platform desteği,
socketcall etrafından dolaşma ve hata işleme gibi çeşitli uyumluluk sorunları bulunuyor
- Bazı ortamlarda ECN biti etkin gönderim çağrılarında hata (
EINVAL) oluştu; quinn-udp içinde yeniden deneme ve seçeneği kapatma stratejisi uygulandı
- Quinn topluluğundaki çeşitli iyileştirmeler sayesinde Firefox da bu gelişmelerden otomatik olarak yararlanabiliyor
ECN (Açık Tıkanıklık Bildirimi) desteği
- Modern sistem çağrılarının benimsenmesi sayesinde ancillary data (ek veri) gönderme/alma desteği geldi ve QUIC ECN desteği mümkün oldu
- Küçük ölçekli bazı hatalar olsa da, Firefox Nightly’de QUIC bağlantılarının yarısından fazlası ECN outbound yolu üzerinden çalışıyor
- L4S gibi yeni teknolojiler öne çıktıkça ECN desteğinin önemi ve kullanım alanı artıyor
Sonuç özeti
- Firefox’un QUIC UDP I/O katmanı, quinn-udp tabanlı Rust uygulamasıyla değiştirilerek performans ve güvenlik birlikte iyileştirildi
- Eski sistem çağrıları yerine her işletim sistemine uygun modern I/O sistem çağrıları kullanılarak daha yüksek throughput ve ECN desteği sağlandı
- Windows gibi bazı platformlarda belirli optimizasyonlar için uyumluluk sorunları nedeniyle ek iyileştirmeler gerekiyor
- QUIC kullanım oranı artmaya devam ettikçe, ileride işletim sistemi ve sürücü düzeyindeki desteğin de gelişmeye devam etmesi bekleniyor
1 yorum
Hacker News görüşleri
Yazının can alıcı noktası arada gizlenmiş
Buradaki iyileştirme gerçekten ultra yüksek hızlar (100Gb/s ve üstü) için gerekli ama 4Gb/s aslında pek de hızlı sayılmaz
500MB/s ediyor; yani bir yerlerde ciddi biçimde yavaş bir bottleneck var demek
Kernel context switch'in 1us seviyesinde olduğu söylenmiş ama bu aslında bir sistem çağrısı için yüksek
Yine de paket başına ortalama yaklaşık 500 bayt olsa bile 500MB/s, yani 4Gb/s'ye ulaşmak mümkün
Eski 1Gb/s değeri paketler daha küçükkenmiş ve UDP paketlerini sadece NIC buffer'ına itmek, bellek kopyalama hızlarıyla bile rahatça yapılabilecek bir iş
Şifreleme yavaş dense de pratikte öyle değil
Örneğin Intel i5-6500'ün 1729MB/s AES-128 GCM hızına ulaştığı görülmüştü
Güncel CPU'lar çekirdek başına 3-5GB/s, yani 25-40Gb/s yapabiliyorken burada sözü edilen 4Gb/s çok düşük bir değer
(AES-128 GCM performans bağlantısı)
Sistem çağrısı gecikmesinin yüksek olduğu söylenmişti; bunun nedeni spectre & meltdown önlemleri olabilir
TCP'de path binding var ama UDP'de yok, dolayısıyla yol yapılandırmasında ciddi fark var
Şifrelemenin yavaş olduğu iddiası küçük PDU'lar (protokol veri birimleri) için doğru
Optimizasyon ve benchmarkların çoğu büyük TCP frame'lerine göre yapıldığından, küçük paketlerde state kurulum maliyeti gerçekte daha belirgin hale geliyor
Sıkı bir loop içinde microbenchmark çalıştırınca rakamlar iyi görünür ama gerçek dünyadaki rastgelelikte cache kullanım verimi düşüyor ve 1KB altı paketlerde verim keskin biçimde azalıyor
Buna ek framing overhead'i, bant dışı veri doğrulaması gibi şeyler de epey pahalı çalışıyor
UDP buffer belleğinin varsayılan değeri de yetersiz; gerçek kullanımda çok sorun çıkarıyor
TCP işletilirken buffer boyutları sürekli büyütüldü ama UDP, 90'lar ve 2000'lerin temkinli varsayılanlarında kaldı
Aslında ihtiyaç duyulan API; fd'yi fork edip
connect(2)ve route binding'i tam destekleyen, sonrasında da submission queue tabanlı (uring,riovb.) bir yapı olmalıŞifreleme tarafında KDF yaklaşımı state maliyetini ciddi biçimde azaltabilir
PSP yöntemi bazı vendor'larca kabul görüyor ama IETF gibi yerlerde sıkça reddedildiği için yaygınlaşmadı
Vendor'ların büyük eşzamanlılık testlerinde, geleneksel TLS türevlerine kıyasla çok daha iyi ölçeklenme rakamları çıkıyor
Benchmark yapılan CPU'nun hangi sınıfta olduğu hiç belirtilmemiş
Ayrıca şifreleme overhead'i, QUIC protokolünün kendi işleme maliyeti
QUIC'te şifreleme offload'u (donanımda işleme) TCP'ye göre daha zayıf; TCP ise kTLS offload ile bir ölçüde NIC üzerinde işlenebiliyor
Bu tür teknik içerikler gerçekten çok tatmin ediciydi
Mozilla'nın tüm teknik yazıları keşke böyle işi bilen mühendislerin düzgünce yazdığı, derinlikli içerikler olsa
İçi boş iyimserlikler olmadan, okumaya değer bir yazı
Android 5'in neden hâlâ desteklendiğini anlamıyorum
Çıkışının üzerinden 10 yıldan fazla geçti ve o cihazları kullananlar da artık iyice eski bir kitle
Günümüz web'i o kadar ağır ki, bu kadar eski cihazlarda düzgün gezinmek bile zor olmalı; neden hâlâ destek verildiğini merak ediyorum
Muhtemelen eski OnePlus benzeri cihazları tamir edip şarja takılı bırakan, LineageOS gibi halk arasında bilinen bir ROM bile kurmadan alternatif uygulama mağazasından Firefox kullanan hacker'lardan ibaret bir kitle vardır
Gerçekte bunun bedeli, genel geliştirme hızının yavaşlaması
Factorio geliştirici blogundaki "The map download struggle" yazısında da bununla ilgili ilginç bir anekdot var, tavsiye ederim
(ilgili blog yazısı)
Ağ sorunlarıyla gerçekten uğraşmış olan herkes, gizemli packet runt'lar yüzünden buna daha da çok katılır
Ağ ekipmanlarının çoğu bu tür paketleri iyi işleyemiyor
UDP veya QUIC tabanlı trafik, belirli bir ölçeğin üzerindeki büyük cloud ortamları dışında saldırılara karşı kolayca savunmasız kalıyor
Bu yüzden küçük ya da kendi altyapısını işleten hosting sağlayıcılarının işi giderek zorlaşıyor ve sonunda sadece büyük trafik kaldırabilenler ayakta kalıyor
Bu nedenle çoğu LAN ortamında UDP trafiğinin büyük kısmı drop ediliyor, yalnızca gerekli bölümler rate limit uygulanarak işleniyor
Mozilla bug tracker
macOS ve Fedora'da Cloudflare'ın barındırdığı sitelere Firefox ile girerken hâlâ aynı sorunu yaşıyorum
Windows ve macOS'ta da GSO/GRO'ya (büyük ağ paketlerini işleme) benzer özellikler olduğunu bunu okuyunca öğrendim
Ama pratikte çok hatalı oldukları söylenmesi üzücü
Sadece GSO/GRO değil, muhtemelen başka sorunlar da vardır
UDP GSO/GRO'nun yapısal olarak nasıl çalıştığını açıklayabilecek biri var mı diye soruluyor
UDP sırasız bir paket yapısıyken, tek bir QUIC paketi birden fazla UDP paketine bölündüğünde başlıkta sıra bilgisi de yoksa alıcı taraf bunları hangi sırayla yeniden birleştiriyor diye merak edilmiş
Kernel birden fazla datagram'ı tek bir yapıda toplayıp, katmanlar arasında sınırları (örneğin
sk_buffiçindeki data fragment'ları) koruyarak iletiyorKonunun tam uzmanı değilim ama bunun nasıl çalıştığını araştırırken şu yazıya rastladım
"Quinn projesinin UDP I/O kütüphanesi olan quinn-udp üzerinde geliştirmeye başladık ve bu sayede çok daha hızlı ilerledik" denmiş
O hâlde Quinn projesine maddi destek verilip verilmediğini merak ediyorum
(Quinn destek bağlantısı)
Finansal destek konusunda doğrudan sorduğumda, Mozilla'da Senior Principal Software Engineer olarak çalışan biri bana "Mozilla'nın parası yok" diye yanıt verdi
Ama koda çok büyük katkı sağladılar; bunun için gerçekten minnettarız
(Ben Quinn'in ana maintainer'ıyım)
"Destek oldular mı?" sorusuna karşılık, Mozilla'nın açık kaynağa bağış yapmak yerine CEO maaşına birkaç milyon dolar daha harcamayı tercih ettiği yönünde bir görüş dile getiriliyor
Üstelik amiral gemisi ürünleri olan Firefox bile gerilemekteyken
Kod gibi başka şekillerde ne tür katkılar yaptıklarını merak ediyorum
sendmmsg/recvmmsg'nin “modern” diye anılması şaşırtıcıAslında epey uzun zamandır var olan sistem çağrıları bunlar
Linux kısmında
io_uring'den de söz edilmesini beklerdim ama yoktuio_uring, çok sayıda UDP datagram'ını tek seferde işleyen gerçekten anlamlı bir batch özelliği sunmuyorEn iyi ihtimalle birden fazla
sendmsg,recvmsgçağrısını aynı anda istemek mümkünDoğru çözüm GSO/GRO
sendmmsg/recvmmsgzaten oldukça eski teknolojiler ve bazı kernel geliştiricileri artık bunlardan kurtulmak istiyor(ilgili GitHub tartışması)