QUIC untuk kernel Linux
(lwn.net)- Patch pertama untuk mengintegrasikan protokol QUIC secara resmi ke kernel Linux telah diajukan
- Tujuannya adalah memperbaiki keterbatasan TCP yang ada saat ini, seperti latensi, head-of-line blocking, dan kekakuan protokol akibat perangkat perantara
- QUIC berbasis UDP dan menyediakan dukungan multi-stream serta enkripsi end-to-end, sehingga jika diadopsi ke kernel, peluang pemanfaatan di platform dan perangkat keras yang lebih luas akan meningkat
- Kinerja implementasi awal di kernel terukur masih lebih rendah dibandingkan TCP yang ada dan kernel TLS, tetapi peningkatan performa di masa depan diharapkan melalui hardware offloading dan optimasi
- Saat ini, pembahasan dukungan di Samba, SMB/NFS berbasis kernel,
curl, dan lainnya berlangsung aktif, tetapi penggabungan ke mainline diperkirakan masih membutuhkan waktu
Latar belakang kemunculan protokol QUIC dan keterbatasan TCP
- QUIC dibuat untuk mengatasi berbagai masalah yang dimiliki TCP di internet saat ini
- Latensi akibat 3-way handshake dalam proses koneksi TCP, kurangnya dukungan multi-stream, serta fenomena head-of-line blocking akibat kehilangan paket menurunkan pengalaman penggunaan web
- Metadata TCP dikirim tanpa enkripsi sehingga ada risiko kebocoran informasi, dan middlebox di internet memfilter lalu lintas berdasarkan informasi koneksi tersebut, yang kemudian berkembang menjadi ossification protokol
- Upaya peningkatan TCP, seperti Multipath TCP, juga berada dalam situasi di mana ia tidak dapat berfungsi normal kecuali menyamar sebagai TCP lama
Karakteristik QUIC dan keunggulan teknisnya
- QUIC berjalan di atas UDP, dan dapat membangun koneksi dengan cepat tanpa 3-way handshake terpisah dalam proses koneksinya
- Desain transmisi multi-stream diterapkan agar kehilangan paket tidak memengaruhi seluruh stream
- Data transport terkait QUIC selalu dienkripsi secara end-to-end (berbasis TLS), sehingga perangkat perantara tidak dapat mengakses pesan internal
- Jika lingkungan jaringan memungkinkan paket UDP lewat, maka QUIC juga dapat berfungsi dengan normal
Ikhtisar patch integrasi QUIC di dalam kernel Linux
- Dalam patch yang diajukan, tipe protokol baru bernama IPPROTO_QUIC diperkenalkan, sehingga system call
socket()yang ada dapat dimanfaatkan - Mirip dengan TCP, pemanggilan seperti
bind(),connect(),listen(), danaccept()dapat digunakan, tetapi ada perbedaan pada cara pemrosesan berikutnya - Manajemen sesi TLS serta proses autentikasi/enkripsi ditangani di ruang pengguna, dan setelah koneksi dibuat, TLS handshake harus diselesaikan di masing-masing sisi sebelum pengiriman dan penerimaan data dapat dilakukan
- Setelah koneksi awal, hasil negosiasi TLS dapat di-cache sehingga kecepatan saat menyambung kembali antara dua sistem bisa meningkat secara signifikan
Tantangan performa dan prospeknya
- Implementasi QUIC di dalam kernel yang diajukan masih menunjukkan kelemahan performa dibandingkan kernel TLS dan TCP yang ada
- Dibandingkan in-kernel TLS, throughput-nya kurang dari sepertiga; bahkan saat enkripsi dinonaktifkan pun throughput dapat tertinggal hingga 4 kali dibandingkan TCP
- Penyebab yang disebut antara lain tidak adanya dukungan segmentation offloading, tambahan penyalinan data pada jalur pengiriman, serta proses enkripsi header
- Ke depan, bila dukungan hardware offloading ditambahkan dan implementasi in-kernel dioptimalkan, performanya diperkirakan akan meningkat
Status adopsi dan prospek ke depan
- Pembahasan tentang dukungan QUIC in-kernel berlangsung aktif di berbagai proyek seperti server/klien Samba, kernel SMB dan filesystem NFS, serta
curl - Patch ini berukuran sekitar 9.000 baris dan saat ini hanya mencakup kode dukungan tingkat rendah. Implementasi lengkapnya telah diumumkan akan menyusul melalui patch tambahan
- Pembahasan code review dan penggabungan baru saja dimulai, sehingga diperkirakan masih membutuhkan waktu sebelum bisa digunakan secara nyata
- Mengingat preseden terbaru bahwa penggabungan protokol Homa ke kernel memerlukan 11 kali pengajuan selama 9 bulan, QUIC juga diperkirakan baru akan masuk mainline setelah 2026
1 komentar
Opini Hacker News
ssl_preread_server_nameke konfigurasi NGINX untuk meneruskan permintaan domain tertentu ke instance NGINX lain denganproxy_passInstance pertama hanya meneruskan aliran TLS mentah (termasuk
proxy_protocol), dan instance kedua yang benar-benar menangani terminasi TLSPendekatan ini efektif untuk menerapkan failover - jika jalur utama server mati, record DNS A diperbarui ke NGINX di mesin failover, lalu instance tersebut merutekan permintaan domain tertentu melalui jalur terpisah ke backend asli
Ini praktis karena tidak perlu menggandakan seluruh konfigurasi TLS
Namun, metode ini tidak bisa diterapkan ke HTTP/3
HTTP/3 berbasis QUIC, berjalan di atas UDP, dan mengenkripsi SNI saat handshake sehingga routing berbasis domain tidak bisa dilakukan dengan
ssl_preread_server_nameSaya penasaran apakah ada alternatif yang mendukung routing berbasis SNI di HTTP/3, atau jika butuh fitur ini apakah tetap harus memakai HTTP/1.1 atau HTTP/2 over TLS
Dalam praktiknya, perilakunya berbeda tergantung implementasi klien (lihat status dukungan record HTTPS di Chromium pada tautan isu), tetapi jika koneksi QUIC gagal, klien akan transparan fallback ke HTTP/1.1/2 dan juga menghormati header Alt-Svc penjelasan header
Jika failover sudah direncanakan, Anda juga bisa menunggu timeout ke instance alternatif tanpa mengirim header Alt-Svc
Jika routing QUIC benar-benar diperlukan, untungnya informasi SNI selalu ada di paket pertama sehingga routing bisa dilakukan lewat inspeksi paket
udpgrm milik Cloudflare bisa jadi referensi, dan ini dapat digunakan saat tidak ada ECH (Encrypted Client Hello)
Jika ada ECH, router harus memiliki kunci dekripsi agar bisa membuat keputusan routing, dan failover berantai juga bisa dirancang di tingkat protokol
Implementasi kode konkretnya bisa dilihat di contoh udpgrm
Jika penyerang bisa mengakses server itu, menerbitkan ulang sertifikat SSL juga mudah, jadi daripada memikirkan sistem failover yang rumit, lebih masuk akal melakukan terminasi TLS secara langsung
Secara pribadi saya belum pernah berhasil mereproduksi sendiri keunggulan performa dan keandalan QUIC
Sudah bertahun-tahun saya mengujinya berulang kali, tetapi biasanya saya nonaktifkan karena alasan performa dan lainnya
Failover berbasis DNS juga pada praktiknya butuh beberapa menit untuk benar-benar tercermin, dan klien sederhana seperti browser sering tidak melakukan failover dengan baik
Karena itu saya memakai handler
onerrorsendiri untuk memuat jalur keduaMisalnya saya memakai kode seperti ini untuk pelacakan iklan, dan juga menyediakan wrapper untuk fetch API dengan cara yang sama
Pendekatan ini jauh lebih efisien daripada percobaan lain apa pun yang pernah saya lakukan
Bahkan jika browser gagal membuat koneksi QUIC (termasuk saat diiklankan di DNS), ia akan otomatis fallback ke HTTP/1 atau HTTP/2 over TLS, jadi pendekatan failover yang ada tetap bisa dipakai
Karakteristik desain HTTP/3 memang tidak mengekspos informasi endpoint sampai ke lapisan TLS
Secara pribadi saya menganggap ini sebagai kelebihan
HAProxy bisa menjadi proxy TLS mentah, tetapi tidak bisa melakukan routing berdasarkan nama host
Cloudflare tunnel punya kemampuan khusus untuk routing berbasis nama host tanpa terminasi TLS, tetapi untuk memakainya DNS juga harus diarahkan ke Cloudflare
Lihat bagaimana ini digambarkan di komik xkcd terkait
Saya juga penasaran apakah batasan yang sama berlaku di lingkungan TCP+TLS ketika Encrypted Client Hello digunakan
Saya rasa jawabannya akan hampir sama
Diskusi kali ini terasa mengarah pada upaya menyelesaikan masalah-masalah seperti itu sedikit demi sedikit
Ke depan juga ada kemungkinan dukungan hardware dari kartu jaringan
Namun saat ini sebagian besar trafik internet bergerak antara perangkat mobile dan server, dan di segmen itulah QUIC dan HTTP/3 benar-benar menunjukkan nilainya
Untuk penggunaan lain, TCP tetap bisa terus dipakai
Mungkin akan terlihat seperti banyak koneksi seperti sekarang, tetapi sebenarnya di-cache di balik layar
Saya pribadi lebih suka jika ada objek koneksi eksplisit lalu stream dibuka terpisah, tetapi untuk sementara pendekatan saat ini juga bisa diterima
Dari diskusi terkait, jika ini bukan fitur ekstensi maka sisi server pun bisa membuat stream baru setelah koneksi terbentuk
Di sisi klien, meski pada kenyataannya ini adalah stream, sulit membuat abstraksi terpisah seolah-olah itu "koneksi", dan pada dasarnya tampaknya dibutuhkan abstraksi API yang benar-benar baru
Mungkin tiap stream baru akan menerima file descriptor lewat
recvmsgSaya ingin sesuatu yang tahan masalah jaringan seperti Mosh, tetapi tetap bisa memakai semua fitur OpenSSH (SFTP, SOCKS, port forwarding, manajemen state, roaming, dan sebagainya)
Saya penasaran apakah OpenSSH nantinya bisa memanfaatkan dukungan kernel
Lihat Mosh
Mungkin lebih baik membuat protokol login terpisah berbasis QUIC
Beberapa pendekatan sedang berjalan pada tahap prototipe
Namun sekarang ada pembicaraan bahwa implementasi kernel QUIC saat ini 3~4 kali lebih lambat dibanding Linux, meski selisih performa itu katanya akan segera mengecil
Kecepatan adalah keunggulan QUIC, jadi jika pada kenyataannya lebih lambat, saya penasaran apa alasan memakai QUIC
Menurut penulis PR, sebagian penurunan performa juga berasal dari desain protokol itu sendiri, jadi saya bertanya apakah masih ada masalah di TCP yang perlu diperbaiki secara terpisah
Ringkasnya kebanyakan adalah "belum dioptimalkan"
Misalnya tidak ada dukungan segment offload, ada penyalinan data tambahan di jalur transmisi, dan ada overhead akibat enkripsi header, semuanya sangat mungkin diperbaiki
Benchmark di sini dilakukan dalam lingkungan yang sangat ideal
Di dunia nyata, lingkungan mobile punya variabilitas jaringan yang besar sehingga batasan struktural TCP jadi lebih menonjol
Bahkan di atas TCP pun, banyak yang sudah menerapkan fungsi mirip QUIC seperti pada HTTP/2
Pada akhirnya QUIC adalah stack jaringan komprehensif yang beroperasi di atas lapisan OSI 5 ke atas, sementara TCP adalah mesin di sekitar lapisan 3, sehingga secara struktural memang sulit dibandingkan
Yang terpenting, kelebihan QUIC adalah koneksi dan rekoneksi yang lebih cepat, serta kontinuitas sesi saat IP berubah
Struktur multiplexing dan stream non-blocking secara drastis menyederhanakan desain protokol tingkat atas
Jika struktur ini masuk ke kernel, ruang untuk optimasi performa juga sangat besar
Ke depan, daripada terus membangun solusi berlapis di atas keterbatasan TCP, kita perlu lebih sering memakai fondasi yang lebih maju seperti QUIC dalam penggunaan sehari-hari
Saat ada packet loss, seluruh pengiriman setelahnya tertunda sampai pemulihan selesai (HOL blocking), jadi batasan strukturalnya cukup besar
Ini bukan sekadar soal kecepatan, tetapi perbaikan latensi
Lihat dokumen penjelasan teknis
Context switch antara kernel dan userspace adalah bottleneck utama
Networking userspace (misalnya akses langsung ke NIC) menghilangkan masuk ke kernel
Sebaliknya, menyediakan fungsi di kernel space (misalnya
sendfile, TLS di dalam kernel, NIC offloading, DMA langsung dari disk ke NIC) juga mengurangi total context switch dan penyalinan dataStack QUIC saat ini tidak memanfaatkan keunggulan kedua sisi itu sekaligus
I/O paket masih berbasis syscall, dan penyalinan data juga tidak bisa dihindari
Dengan batch I/O seperti io_uring, jumlah switch bisa dikurangi, tetapi penyalinan itu sendiri tidak berkurang
Ada dua pendekatan: kernel bypass+DMA, atau mengecualikan userspace seperti pada struktur
sendfile/ktlsImplementasi kernel QUIC saat ini tidak mendapat manfaat dari keduanya
Jika bisa langsung menulis lewat DMA, atau harus menyerahkannya lewat syscall kernel, perbedaan performanya besar
Networking userspace hanya meyakinkan jika ada struktur seperti transisi privilege dan DMA tersebut
Ini hanya dimanfaatkan oleh perusahaan skala besar (MOFAANG dan sejenisnya)
Secara teori ada harapan bahwa io_uring akan menggeneralisasi manfaat itu untuk semua orang, tetapi belum sampai tahap penggunaan nyata
Itulah sebabnya TCP/IP tetap berada di kernel pada sistem operasi utama
Saya mengira peran kernel adalah mengelola memori, hardware, dan task, jadi bukankah protokol di atas IP seharusnya diproses di userland?
Sebaliknya, memisahkan stack semacam itu ke userspace juga bisa meningkatkan performa untuk beberapa kasus lain
TCP/UDP di kernel menengahi routing soket berbasis port sehingga banyak program bisa memakai TCP/UDP secara bersamaan
QUIC berjalan di atas UDP, jadi inti argumennya tetap masuk akal
Yang ditekankan adalah hanya protokol tepat di atas IP yang tidak bisa dijalankan dari userspace
Saya berharap internet akan menjadi sedikit lebih cepat ke depannya
Di lingkungan konektivitas seperti 5G mungkin perbedaannya tidak terlalu terasa, tetapi ini tetap kemajuan yang berharga
Menarik bahwa ada struktur handshake tautan terpisah
Ternyata ini berbeda dari dugaan saya sebelumnya bahwa QUIC sepenuhnya menyematkan TLS di dalam dirinya sendiri
Meski begitu, saya rasa latensi game bisa turun lebih jauh berkat teknologi ini
Jika resource komputasi dan efisiensi jaringan meningkat, permintaan itu sendiri juga ikut naik
Dalam game atau komputasi ilmiah, ini tidak masalah karena tujuannya adalah "hasil yang lebih baik"
Tetapi di web, efek baliknya sering buruk karena iklan, pelacakan, dan JavaScript bertambah
bind(),connect(),listen(),accept()dan semacamnya, tetapi setelah itu strukturnya berubah karena memakai syscallsendmsg()danrecvmsg()Saya ingin ada penjelasan juga mengapa pendekatan ini dipilih, dan mengapa tidak membuat syscall terpisah yang memang cocok untuk QUIC