پرش به مطلب اصلی

QuicServer

QuicServer دیتاگرام‌های upstream حامل را به جریان بایت برنامه decode می‌کند و بایت‌های downstream برنامه را به دیتاگرام QUIC تبدیل می‌کند. Google QUICHE QUIC v1/TLS 1.3 را اجرا می‌کند. adapter موجود همتا را می‌پذیرد و مالک line عادی آن است؛ این نود listener یا socket نمی‌سازد.

UdpListener -> QuicServer -> TcpConnector
UdpListener -> QuicServer -> VlessServer -> SpeedTestServer

مثال​

{
"name": "quic-server",
"type": "QuicServer",
"next": "application-out",
"settings": {
"cert-file": "server.crt",
"key-file": "server.key",
"protocol": "h3",
"carrier-mode": "datagram"
}
}

فیلدهای name، type، next و object تنظیمات لازم‌اند. مقدار type دقیقاً QuicServer است. پیکربندی کامل UDP و TCP قاب‌بندی‌شده و دستور ساخت گواهی محلی در مثال‌های QUIC قرار دارد.

تنظیمات سرور​

تنظیمپیش‌فرضرفتار
cert-fileلازمchain گواهی خوانای PEM با leaf در ابتدا.
key-fileلازمکلید خصوصی خوانای PEM که با گواهی تطابق دارد.

credential ناخوانا، خراب یا جفت کلید و گواهی نامنطبق startup را رد می‌کند. سرور تنظیمات امضا را تا بازنشستگی همهٔ نشست‌ها نگه می‌دارد. reload گواهی و اعتبارسنجی گواهی کلاینت در رابط این نود نیست. QUICHE نخستین Initial معتبر را parse می‌کند و پیش از اعتبارسنجی آدرس همتا anti-amplification را حفظ می‌کند؛ وجود line در WaterWall به‌تنهایی آدرس را معتبر نمی‌کند.

تنظیمات مشترک​

تنظیمپیش‌فرضمحدوده و رفتار
protocol"h3"یک ALPN دقیق با ۱ تا ۲۵۵ بایت ASCII قابل‌چاپ؛ دو طرف باید برابر باشند.
carrier-mode"datagram"فقط datagram یا stream؛ برای حامل جریان بایت، حالت را صریح انتخاب کنید.
handshake-timeout-ms10000عدد صحیح ۱ تا ۸۶٬۴۰۰٬۰۰۰؛ مهلت کل تا handshake معتبر و بازشدن stream برنامه. ورودی ناقص آن را از نو آغاز نمی‌کند.
idle-timeout-ms60000عدد صحیح ۱ تا ۸۶٬۴۰۰٬۰۰۰؛ زمان بیکاری QUIC با درنظرگرفتن مذاکرهٔ همتا و عمر مستقل حامل.
max-packet-size1350عدد صحیح ۱۲۰۰ تا ۱۴۵۲؛ بیشینهٔ دیتاگرام خروجی بدون پوشش حالت stream.
max-buffered-bytes2097152عدد صحیح ۶۵٬۵۳۶ تا ۶۷٬۱۰۸٬۸۶۴؛ سقف مستقل backlogهای هر line، شامل plaintext پذیرفته‌شده ولی تأییدنشده.
max-buffered-buffers1024عدد صحیح ۱ تا ۶۵٬۵۳۶؛ سقف entryهای هر backlog، شامل نگهداری فعال.
receive-window-bytes1048576۱۶٬۳۸۴ تا ۱۶٬۷۷۷٬۲۱۶ و حداکثر max-buffered-bytes؛ اعتبار اولیهٔ دریافت stream.
verbosefalseبولی؛ گزارش حالت بیشتر، بدون plaintext، کلید خصوصی یا secret نشست.

فیلدهای عدد صحیح باید token صحیح JSON باشند؛ string، مقدار بولی و کسر پذیرفته نمی‌شوند. تنظیم نامعتبر startup را با خطای مشخص همان فیلد متوقف می‌کند. اگر بودجهٔ بایت را از مقدار پیش‌فرض پنجره کمتر می‌کنید، receive-window-bytes را نیز تنظیم کنید.

برای descriptor هر entry باید شرط (max-buffered-buffers + 1) * 24 <= max-buffered-bytes برقرار باشد. ledger ارسال برای هر entry تنظیم‌شده ۱۶ بایت و هر backlog خروجی wire/plaintext برای هر entry تعداد ۲۴ بایت ظرفیت ثابت رزرو می‌کند. این chargeهای backing حتی در ring خالی نیز در بودجهٔ allocation حساب می‌شوند و هنگام close آزاد می‌شوند.

معنای حامل و دادهٔ برنامه​

رابط برنامه یک جریان بایت قابل‌اعتماد است و مرز بافرهای Payload برنامه حفظ نمی‌شود. هر line عادی موجود، یک اتصال QUIC و یک stream دوطرفه با آغازگر کلاینت دارد. نود QUIC این line را قرض می‌گیرد؛ adapter یا منبع برنامه مالک socket و ساختن و نابودکردن line است.

در datagram، هر Payload سمت حامل دقیقاً یک دیتاگرام کامل QUIC بدون پیشوند خصوصی است. در stream، هر دیتاگرام با طول چهار‌بایتی unsigned به‌ترتیب big-endian و سپس بایت‌های دیتاگرام ارسال می‌شود. هر دو همتا باید برای حامل جریان بایت stream را انتخاب کنند. parser پیشوند و بدنهٔ تکه‌تکه و چند frame ادغام‌شده را می‌پذیرد؛ طول صفر یا بیشتر از ۱٬۴۷۲ ارتباط را می‌بندد. تشخیص خودکار حالت، fallback یا افزودن خودکار adapter وجود ندارد.

کلاینت پیش از دادهٔ برنامه یک بایت رمز‌شدهٔ 0x00 می‌فرستد که سرور داخل پروتکل مصرف می‌کند. در نتیجه برنامهٔ سرور حتی بدون دادهٔ اولیه از کلاینت می‌تواند زودتر صحبت کند. NUL واقعی ابتدای دادهٔ برنامه حفظ می‌شود. stream اضافی برنامه و رابط QUIC DATAGRAM ارائه نمی‌شود.

protocol="h3" فقط ALPN را اعلام می‌کند. نگاشت stream خصوصی و خام است؛ درخواست، پاسخ، QPACK و control streamهای HTTP/3 وجود ندارند. همتای عادی HTTP/3 با آن سازگار نیست. این تنظیم ادعای تقلید Chrome/Cloudflare یا عبور از classifier ندارد و HttpClient و HttpServer را تغییر نمی‌دهد.

جریان، حافظه و پایان ارتباط​

هر Est پشتیبانی‌شدهٔ حامل، حتی تکراری، فوراً relay می‌شود؛ handshake معتبر و آمادگی stream موانع داخلی جداگانه‌اند. پیش از آمادگی، دادهٔ پذیرفته‌شده در FIFO با سقف قطعی می‌ماند. Pause/Resume مشورتی‌اند و همهٔ تکرارها relay می‌شوند. alarm بازیابی loss، پردازش ACK و خروجی آمادهٔ مرتب در Pause نیز پیش می‌روند. فشار محلی ارسال فقط از تولیدکنندهٔ برنامه Pause می‌خواهد، وقتی یکی از شمارنده‌های بایت، entry یا هزینهٔ allocation از سه‌چهارم سقف خود بیشتر شود. تنها وقتی هر سه کمتر از نصف سقف شوند Resume می‌کند؛ برابری hold را حفظ می‌کند. سقف allocation دو برابر بودجهٔ بایت است و ACK بدون دادهٔ برنامهٔ تازه نیز می‌تواند این فشار را آزاد کند.

سقف بایت و entry برای backlogهای مستقل اعمال می‌شود؛ هزینهٔ allocation نگه‌داشته‌شدهٔ متعلق به WaterWall نیز حداکثر دو برابر بودجهٔ بایت مربوط است. قطعهٔ پذیرفته‌شدهٔ ارسال تا تأییدشدن charge دارد؛ ACK دیرتر از شکاف قبلی ledger عبور نمی‌کند. این سقف‌ها ادعای محدودکردن همهٔ allocationهای heap در QUICHE نیستند.

یک adapter UDP مجاور ممکن است در Pause خارجی خواندن را، شامل ACK، متوقف کند. Pause محدود می‌تواند بازیابی شود؛ Pause طولانی ممکن است مهلت QUIC را منقضی کند. هر دو نود splice را مسدود می‌کنند. pooling اتصال، migration بین lineهای حامل، بازپیوستن NAT rebinding، resumption و 0-RTT ارائه نمی‌شوند.

دریافت Finish پیش از relay فقط دور از فرستنده، state محلی را بازنشسته و timerها را لغو می‌کند. Finish سمت برنامه یک تلاش همگام محدود برای تحویل packetهای آمادهٔ queued به حامل هنوز باز، با رعایت کنترل ازدحام و pacing، انجام می‌دهد. line قرضی نمی‌تواند برای ACK نهایی QUIC به‌طور ناهمگام زنده بماند. تحویل پس از teardown محلی تضمین نمی‌شود؛ packet نهایی گم‌شده با timeout محدود همتا حل می‌شود. FIN/reset stream پس از بایت‌های decodeشدهٔ قبلی کل ارتباط را می‌بندد؛ half-close برنامه وجود ندارد.

متادیتای نود​

هر دو نود transform میانی Layer 4 هستند، همسایهٔ قبلی و بعدی را می‌پذیرند، kNodeFlagBlocksSplice دارند و padding اضافی چپ نمی‌خواهند. نوع adapter مجاور را بررسی یا رد نمی‌کنند. Google QUICHE و وابستگی‌های runtime آن به‌صورت static و از طریق provider مشترک BoringSSL با پیشوند پروژه لینک می‌شوند.

metadata برگرفته از کد منبع:

ویژگیمقدار
node flagskNodeFlagBlocksSplice
can_have_prevtrue
can_have_nexttrue
layer_groupkNodeLayer4
layer_group_prev_nodekNodeLayer4
layer_group_next_nodekNodeLayer4
required_padding_left0 bytes