Linux kernel के लिए QUIC
(lwn.net)- QUIC प्रोटोकॉल को Linux kernel में आधिकारिक रूप से एकीकृत करने वाला पहला पैच सबमिट किया गया है
- इसका उद्देश्य मौजूदा TCP की सीमाओं, जैसे latency, head-of-line blocking, और मध्यवर्ती डिवाइसों के कारण होने वाली protocol ossification, को सुधारना है
- QUIC UDP-आधारित है और multistream support तथा end-to-end encryption देता है, इसलिए kernel में आने पर अधिक व्यापक platforms और hardware के उपयोग की संभावना बढ़ती है
- शुरुआती kernel implementation का performance मौजूदा TCP और kernel TLS की तुलना में कम मापा गया, लेकिन आगे hardware offloading और optimization के जरिए performance बेहतर होने की उम्मीद है
- फिलहाल Samba, kernel-आधारित SMB/NFS, curl आदि में इसके समर्थन पर सक्रिय चर्चा चल रही है, लेकिन mainline merge तक अभी और समय लगने की संभावना है
QUIC प्रोटोकॉल के आने की पृष्ठभूमि और TCP की सीमाएँ
- QUIC को मौजूदा इंटरनेट में TCP की कई समस्याओं को हल करने के उद्देश्य से बनाया गया था
- TCP के connection process में होने वाली 3-way handshake से latency बढ़ती है, multistream support कमजोर है, और packet loss होने पर head-of-line blocking जैसी समस्या के कारण web experience खराब होता है
- TCP metadata बिना encryption के ट्रांसफर होता है, जिससे information leak का जोखिम रहता है, और इंटरनेट के middleboxes connection information के आधार पर traffic filter करते हैं, जिसके परिणामस्वरूप protocol ossification बढ़ती है
- TCP को सुधारने की कोशिशें, जैसे Multipath TCP, भी अक्सर तब तक ठीक से काम नहीं कर पातीं जब तक वे खुद को मौजूदा TCP जैसा दिखाएँ नहीं
QUIC की विशेषताएँ और तकनीकी फायदे
- QUIC UDP के ऊपर काम करता है और connection process में अलग से 3-way handshake के बिना तेज़ी से connection set up कर सकता है
- packet loss पूरे stream को प्रभावित न करे, इसके लिए multistream transmission design अपनाया गया है
- QUIC से संबंधित transport data हमेशा end-to-end encrypted (TLS-आधारित) रहता है, इसलिए middleboxes internal messages तक पहुँच नहीं पाते
- अगर network environment में UDP packets गुजर सकते हैं, तो QUIC भी सामान्य रूप से काम कर सकता है
Linux kernel में QUIC integration patch का सार
- सबमिट किए गए patch में IPPROTO_QUIC नाम का नया protocol type जोड़ा गया है, जिससे मौजूदा socket() system call का उपयोग किया जा सकता है
- TCP की तरह bind(), connect(), listen(), accept() जैसी calls इस्तेमाल की जा सकती हैं, लेकिन उसके बाद की processing में अंतर है
- TLS session management तथा authentication/encryption process user space में handle किए जाते हैं, और connection के बाद दोनों तरफ TLS handshake पूरा होने पर ही data send/receive किया जा सकता है
- शुरुआती connection के बाद TLS negotiation result को cache किया जा सकता है, जिससे दो systems के बीच reconnect होने पर गति काफी बढ़ सकती है
Performance से जुड़ी चुनौतियाँ और आगे की दिशा
- सबमिट किया गया in-kernel QUIC implementation अभी performance के मामले में मौजूदा kernel TLS और TCP से पीछे है
- in-kernel TLS की तुलना में throughput 3 गुना से भी कम है, और encryption बंद होने पर भी TCP की तुलना में throughput अधिकतम 4 गुना तक कम है
- इसके कारणों में segmentation offloading का अभाव, transmit path में अतिरिक्त data copy, और header encryption process शामिल बताए गए हैं
- आगे hardware offloading support जुड़ने और in-kernel implementation के optimize होने पर performance बेहतर होने की उम्मीद है
अपनाने की स्थिति और आगे का अनुमान
- Samba server/client, kernel SMB और NFS filesystem, curl जैसे कई projects में in-kernel QUIC support पर चर्चा सक्रिय है
- यह patch लगभग 9,000 lines का है और फिलहाल इसमें सिर्फ low-level support code शामिल है। पूरी implementation आगे आने वाले patches में जोड़ी जानी है
- code review और merge पर चर्चा अभी शुरुआती चरण में है, इसलिए वास्तविक उपयोग तक पहुँचने में अभी समय लगेगा
- हाल में Homa protocol को kernel में merge होने के लिए 9 महीनों में 11 submissions की ज़रूरत पड़ी थी; इस उदाहरण को देखते हुए QUIC के भी 2026 के बाद mainline में आने की संभावना है
1 टिप्पणियां
Hacker News की राय
ssl_preread_server_nameजोड़कर खास डोमेन रिक्वेस्ट्स को दूसरे NGINX instance परproxy_passकिया गयापहला instance सिर्फ raw TLS stream को आगे भेजता है (
proxy_protocolसहित), और दूसरा instance वास्तविक TLS termination संभालता हैfailover लागू करने में यह तरीका प्रभावी है - अगर सर्वर का primary path डाउन हो जाए, तो DNS A record को failover machine के NGINX पर अपडेट किया जाता है, और वह instance खास डोमेन रिक्वेस्ट्स को अलग path से मूल backend तक route करता है
इससे पूरे TLS configuration को replicate करने की ज़रूरत नहीं पड़ती, जो सुविधाजनक है
लेकिन यह तरीका HTTP/3 पर लागू नहीं होता
HTTP/3, QUIC-आधारित है, UDP पर चलता है, और handshake के समय SNI को encrypt करता है, इसलिए
ssl_preread_server_nameसे domain-based routing संभव नहींजिज्ञासा है कि HTTP/3 में SNI-based routing को सपोर्ट करने का कोई विकल्प है या, अगर यह सुविधा चाहिए, तो क्या अभी भी HTTP/1.1 या HTTP/2 over TLS पर ही रहना होगा
व्यवहार में client implementation के अनुसार नतीजे अलग हो सकते हैं (Chromium में HTTPS record support की स्थिति के लिए issue link देखें), लेकिन QUIC connection fail होने पर client आम तौर पर पारदर्शी रूप से HTTP/1.1/2 पर fallback कर देता है, और Alt-Svc header description header का भी सम्मान करता है
अगर failover planned हो, तो Alt-Svc header भेजना बंद करके वैकल्पिक instance पर timeout होने का इंतज़ार भी किया जा सकता है
अगर QUIC routing वास्तव में ज़रूरी हो, तो सौभाग्य से SNI जानकारी हमेशा पहले packet में होती है, इसलिए packet inspection से routing संभव है
cloudflare का udpgrm संदर्भ के लिए उपयोगी हो सकता है, और यह ECH (Encrypted Client Hello) न होने पर काम करता है
ECH होने पर router के पास decryption key होनी चाहिए ताकि routing decision लिया जा सके, और protocol स्तर पर cascade failover भी डिज़ाइन किया जा सकता है
ठोस code implementation udpgrm example में देखी जा सकती है
अगर attacker उस server तक पहुँच जाए, तो SSL certificate फिर से जारी करना भी आसान है, इसलिए बहुत जटिल failover system पर सोचने की बजाय सीधे TLS termination करना अधिक तर्कसंगत लगता है
व्यक्तिगत रूप से मैंने QUIC के performance और reliability के फायदे कभी प्रत्यक्ष रूप से पुन: सिद्ध नहीं किए
कई सालों से बार-बार test किया, लेकिन performance वगैरह के कारण ज़्यादातर इसे disable ही रखा
DNS-आधारित failover भी व्यवहार में असर दिखाने में कई मिनट लेता है, और browser जैसे साधारण client में failover ठीक से नहीं होता
इसलिए मैं सीधे
onerrorhandler लिखकर दूसरा path load करने का तरीका इस्तेमाल करता हूँउदाहरण के लिए ad tracking के लिए इस तरह का code उपयोग करता हूँ, और fetch API को भी इसी तरह wrap करके देता हूँ
यह तरीका किसी भी दूसरे प्रयास से कहीं अधिक प्रभावी है
browser अगर QUIC connection में fail हो जाए (यहाँ तक कि DNS में advertise किया गया हो), तब भी वह अपने-आप HTTP/1 या HTTP/2 over TLS पर fallback कर देता है, इसलिए वही पुराना failover तरीका इस्तेमाल किया जा सकता है
HTTP/3 की design feature ही यह है कि TLS layer तक endpoint जानकारी उजागर नहीं की जाती
व्यक्तिगत रूप से मुझे यह बात एक फ़ायदे की तरह लगती है
HAProxy raw TLS proxy कर सकता है, लेकिन hostname के आधार पर routing नहीं कर सकता
Cloudflare tunnel में एक विशेष सुविधा है जो TLS termination के बिना hostname-based routing कर सकती है, लेकिन इसके लिए DNS भी Cloudflare पर point करना होगा
इससे जुड़ी भावना xkcd comic में अच्छी तरह व्यक्त की गई है
सोचता हूँ कि TCP+TLS माहौल में भी, अगर Encrypted Client Hello इस्तेमाल हो, तो क्या यही सीमा लागू होगी
लगता है जवाब लगभग वही होगा
इस बार की चर्चा उन समस्याओं को धीरे-धीरे सुलझाने की दिशा जैसी लगती है
आगे चलकर network card के hardware support की संभावना भी खुली है
लेकिन आजकल का अधिकतर internet traffic mobile और server के बीच चलता है, और उस हिस्से में QUIC और HTTP/3 अपनी असली ताकत दिखाते हैं
बाकी उपयोगों में TCP का इस्तेमाल जारी रह सकता है
शायद ऊपर से वह पहले की तरह कई connections जैसा दिखे, लेकिन अंदरूनी तौर पर cache किया जाए
मुझे तो बेहतर लगता कि साफ़ तौर पर connection object मिले और उसके भीतर अलग stream खोली जाए, लेकिन फिलहाल मौजूदा तरीका भी स्वीकार्य है
संबंधित चर्चा देखने पर पता चलता है कि यदि यह extension feature न हो, तो server side पर भी connection स्थापित होने के बाद नई stream बनाई जा सकती है
client में वास्तविकता stream की होती है, लेकिन उसे "connection" जैसी अलग abstraction देना कठिन है, और मूल रूप से एक पूरी नई API abstraction की ज़रूरत लगती है
शायद हर नई stream के लिए
recvmsgसे file descriptor मिलने वाली संरचना होMosh की तरह network समस्याओं के प्रति मज़बूत हो, लेकिन OpenSSH की सारी सुविधाएँ भी जस की तस मिलें—जैसे SFTP, SOCKS, port forwarding, state management, roaming आदि
जिज्ञासा है कि क्या OpenSSH kernel support का उपयोग कर पाएगा
Mosh देखें
शायद QUIC-आधारित अलग login protocol नया बनाना ज़्यादा बेहतर हो
कई approaches अभी prototype चरण में चल रही हैं
फिर सुनने में आता है कि मौजूदा QUIC kernel implementation Linux की तुलना में 3~4 गुना धीमा है, और performance gap भी जल्द कम हो जाएगा
अगर speed ही QUIC का फ़ायदा है, और व्यवहार में वही धीमा निकले, तो QUIC इस्तेमाल करने का कारण क्या है, यह सवाल है
PR के लेखक के अनुसार कुछ performance loss का कारण protocol design में भी है, तो क्या TCP में अलग से ठीक किए जाने वाले मुद्दे और भी हैं
अधिकांश का सार यही है कि "अभी optimization नहीं की गई"
जैसे segment offload का अभाव, transmission path में अतिरिक्त data copy, header encryption का overhead आदि, और इन सबके हल होने की संभावना काफ़ी है
यहाँ benchmarking बहुत ideal environment में की गई थी
वास्तविक mobile environment में network variability बहुत अधिक होती है, इसलिए TCP की संरचनात्मक सीमाएँ ज़्यादा उभरती हैं
वास्तव में HTTP/2 की तरह, TCP के ऊपर भी QUIC जैसी कई सुविधाएँ पहले से लागू की जाती रही हैं
अंततः QUIC, OSI layer 5 और उससे ऊपर काम करने वाला एक समग्र networking stack है, जबकि TCP layer 3 स्तर का engine है, इसलिए संरचनात्मक तुलना आसान नहीं
सबसे बढ़कर QUIC का लाभ तेज़ connection setup और reconnection है, और IP बदलने पर भी session continuity बनाए रखना है
multiplexing और non-blocking stream structure upper-layer protocol design को काफ़ी सरल बना देती है
अगर यह संरचना kernel में आ जाए तो performance optimization की गुंजाइश भी बहुत बड़ी है
आगे चलकर TCP की सीमाओं के ऊपर कई-स्तरीय समाधान बनाने की बजाय, QUIC जैसी उन्नत आधार तकनीकों का अधिक सामान्य उपयोग होना चाहिए
packet loss होने पर उसके बाद का पूरा transmission recovery होने तक delay होता है (HOL blocking), इसलिए इसकी संरचनात्मक सीमा बड़ी है
यह सिर्फ speed का नहीं, latency improvement का मामला है
तकनीकी विवरण दस्तावेज़ देखें
kernel और userspace के बीच context switch एक बड़ा bottleneck है
userspace networking (जैसे NIC तक direct access) kernel entry को समाप्त कर देती है
दूसरी ओर kernel space में features देना (जैसे sendfile, in-kernel TLS, NIC offloading, disk से NIC तक direct DMA) कुल context switch और data copy को कम करता है
मौजूदा QUIC stacks दोनों में से किसी भी पक्ष का पूरा लाभ नहीं लेते
packet I/O syscall-आधारित है, और data copy से बचा नहीं जा सकता
io_uring आदि से batch I/O करने पर switch तो कम होते हैं, लेकिन copy अपने-आप कम नहीं होती
kernel bypass+DMA, या sendfile/ktls जैसी userspace को हटाने वाली संरचना—दो अलग तरीके हैं
QUIC kernel implementation में दोनों के लाभ पूरी तरह नहीं मिलते
अगर DMA से NIC descriptors सीधे लिखे जा सकते हों, या kernel syscall के ज़रिए देना पड़े, तो performance का अंतर बड़ा होता है
userspace networking तभी वाजिब लगती है जब इस तरह का privilege transition और DMA ढाँचा उपलब्ध हो
इसका उपयोग ज़्यादातर बड़े संगठनों (MOFAANG आदि) में ही होता है
सिद्धांत रूप में उम्मीद है कि io_uring इन फ़ायदों को आम बना देगा, लेकिन अभी यह पूरी तरह व्यावहारिक नहीं है
इसी वजह से TCP/IP प्रमुख OSes में kernel के भीतर बना हुआ है
मेरा मानना था कि kernel का काम memory, hardware और task management है; क्या IP के ऊपर के protocol userspace में नहीं होने चाहिए?
उल्टा, इन stacks को userspace में अलग करने से भी कुछ मामलों में performance लाभ मिलता है
क्योंकि TCP/UDP kernel में port-आधारित socket routing का मध्यस्थ काम करते हैं, इसलिए कई programs एक साथ TCP/UDP इस्तेमाल कर सकते हैं
QUIC, UDP के ऊपर चलता है, इसलिए इस चर्चा का मूल तर्क अब भी प्रभावी है
यहाँ ज़ोर इस बात पर है कि सीधे IP के ऊपर वाले protocol को userspace में चलाना आसान नहीं
उम्मीद है कि इससे internet थोड़ा और तेज़ होगा
5G जैसे communication environment में शायद फर्क महसूस न हो, फिर भी यह मूल्यवान प्रगति है
अलग link handshake structure होना दिलचस्प है
पहले मुझे लगा था कि QUIC में TLS खुद अंदर ही शामिल होता है, पर बात वैसी नहीं निकली
फिर भी मुझे लगता है कि gaming latency इस तकनीक से और कम हो सकती है
computing resources और network efficiency बढ़ने पर demand भी बढ़ती है
gaming या scientific computing में "बेहतर परिणाम" के लिए यह स्वीकार्य है
लेकिन web में ads, tracking और JavaScript बढ़ने से अक्सर उल्टा असर होता है
bind(),connect(),listen(),accept()आदि से connection स्थापित करता है, लेकिन उसके बादsendmsg()औरrecvmsg()syscall वाली संरचना में बदल जाता हैअच्छा होता अगर यह भी समझाया जाता कि यह approach क्यों चुनी गई, और QUIC के लिए अलग system calls क्यों नहीं बनाए गए