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-ms | 10000 | عدد صحیح ۱ تا ۸۶٬۴۰۰٬۰۰۰؛ مهلت کل تا handshake معتبر و بازشدن stream برنامه. ورودی ناقص آن را از نو آغاز نمیکند. |
idle-timeout-ms | 60000 | عدد صحیح ۱ تا ۸۶٬۴۰۰٬۰۰۰؛ زمان بیکاری QUIC با درنظرگرفتن مذاکرهٔ همتا و عمر مستقل حامل. |
max-packet-size | 1350 | عدد صحیح ۱۲۰۰ تا ۱۴۵۲؛ بیشینهٔ دیتاگرام خروجی بدون پوشش حالت stream. |
max-buffered-bytes | 2097152 | عدد صحیح ۶۵٬۵۳۶ تا ۶۷٬۱۰۸٬۸۶۴؛ سقف مستقل backlogهای هر line، شامل plaintext پذیرفتهشده ولی تأییدنشده. |
max-buffered-buffers | 1024 | عدد صحیح ۱ تا ۶۵٬۵۳۶؛ سقف entryهای هر backlog، شامل نگهداری فعال. |
receive-window-bytes | 1048576 | ۱۶٬۳۸۴ تا ۱۶٬۷۷۷٬۲۱۶ و حداکثر max-buffered-bytes؛ اعتبار اولیهٔ دریافت stream. |
verbose | false | بولی؛ گزارش حالت بیشتر، بدون 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 flags | kNodeFlagBlocksSplice |
can_have_prev | true |
can_have_next | true |
layer_group | kNodeLayer4 |
layer_group_prev_node | kNodeLayer4 |
layer_group_next_node | kNodeLayer4 |
required_padding_left | 0 bytes |