انتقال شبکه net.transport
جریان بایتی زیر پروتکلهای ویپیان: اتصال TCP، TLS، وبسوکت و ارتقای HTTP با نام سرور، ALPN و تکهتکه کردن ClientHello، همراه با بافر بایت و نشانی.
واردسازی شبکه.انتقال شبکه
نام آرگومانها شناسهی خود کد است و معادل فارسی ندارد؛ گونهها، کلیدواژهها و نام بستهها با معادل فارسی نوشته میشوند.
پروتکل پراکسی مثل وی لس یا وی مس میگوید بایتهای اول یک اتصال چه معنایی دارند. اینکه خود اتصال چطور ساخته میشود را نمیگوید، و فیلتر دقیقاً به همین بخش نگاه میکند: TCP ساده است، TLS است و به کدام نام، وبسوکت است و روی کدام مسیر و با کدام سربرگ میزبان. این بسته همان لایه است. «به این میزبان و درگاه با این تنظیمات وصل شو» را به یک اتصال تبدیل میکند که هر چه زیرش باشد به یک شکل خوانده و نوشته میشود.
بسته چهار کار دارد:
- حاملها.
شماره گیریوشنودروی TCP ساده، TLS، وبسوکت (تنها یا داخل TLS) و یک ارتقای سادهی HTTP کار میکنند.از جریانوبه عنوان جریاناجازه میدهند هر جریان تونل هم حامل یک پروتکل باشد، پس یک پروتکل میتواند داخل پروتکل دیگری اجرا شود. - شبیه چیز دیگری بودن. نام سرور TLS (
نام سرور) و سرآیندHostدو تنظیم جدا هستند، پس کارخواه میتواند به نام جلویی یک CDN وصل شود و سایت دیگری را بخواهد. مسیر وبسوکت مثل یک رمز مشترک کار میکند: درخواست برای هر مسیر دیگر یک صفحهی جعلی ۴۰۴ شبیه nginx میگیرد. - تکهتکه کردن ClientHello.
تکه تکه کردنبایتهای اول دستدهی TLS را در تکههای کوچک و با مکث بین آنها میفرستد، که فیلترهایی را که نام سرور را از بستهی اول میخوانند گیج میکند. - زیرساخت مشترک.
بایتهابافر رشدکنندهای است که بستههای پروتکل سرآیندشان را در آن میسازند ونشانینشانی مقصد است که شکل روی سیم خودش را میداند.
هر مقدار تنظیمات کدام حامل را انتخاب میکند
هر فراخوانی شمارهگیری و شنود یک مقدار تنظیمات میگیرد. مقدار صفر آن TCP ساده است.
| تنظیمات | حامل |
|---|---|
شبکه = "tcp" (پیشفرض) | جریان خام، و وقتی تی ال اس = درست باشد TLS روی آن. |
شبکه = "ws" | یک درخواست HTTP/1.1 که به وبسوکت ارتقا مییابد و بعد قابهای دودویی. قابهای کارخواه طبق استاندارد نقابدارند. با تی ال اس = درست همان wss است. |
شبکه = "httpupgrade" | همان درخواست ارتقا بدون قاببندی وبسوکت: بعد از پاسخ 101 بایتها خام جریان مییابند. از ws سبکتر است و برای پراکسیای که فقط درخواست اول را میخواند همان شکل را دارد. |
تی ال اس = درست | کارخواه گواهی سرور را با ریشههای سیستم یا پرونده گواهی ریشه میسنجد و نام را از نام سرور (یا میزبانِ شمارهگیریشده وقتی خالی است) میگیرد. سرور به پرونده گواهی و پرونده کلید نیاز دارد. |
هر متن دیگری برای شبکه اینجا رد نمیشود: اتصال همان ساده میماند. تجزیهگر پیوند بستههای پروتکل نوعهای پشتیبانینشده را قبل از رسیدن به اینجا رد میکنند.
چیزهایی که گیر میاندازند
پذیرشهر اتصال تازه را به یک کارگر میسپارد. TLS و ارتقای وبسوکت در یک کارگر با سقف زمان (مهلت دست دادن، ۱۰ ثانیه) اجرا میشوند و حداکثربیشینه دست دادن(۱۲۸) همزمان؛ کارخواه گیرکرده رها میشود و اتصال بیش از سقف بلافاصله بسته میشود.پذیرشاتصال تمامشدهی بعدی را برمیگرداند، یا اتصال بستهای کهخطایش میگوید دستدهی چرا شکست خورد.پذیرش خاموارتقابرای حلقهی خودتان هنوز هستند.نام سرورباسربرگ میزبانیکی نیست.نام سرورنام داخل دستدهی TLS است و گواهی با آن سنجیده میشود؛سربرگ میزبانسرآیندHostداخل درخواست ارتقا است. پشت CDN معمولاً این دو فرق دارند.- تنظیم ALPN یک رشته است.
"h2"یا"http/1.1"بدهید، نه فهرست. روی وبسوکت"http/1.1"بگذارید، چون ارتقا ویژگی HTTP/1.1 است. اثر انگشتچیزی را عوض نمیکند. فیلد فقط نگه داشته میشود تا پیوندهایی کهfp=chromeدارند رفت و برگشت شوند، اما دستدهی TLS مال خود این کتابخانه است و کپی مرورگر نیست. فیلتری که شکل دستدهی را تشخیص دهد فریب نمیخورد.مهلت میلی ثانیهفقط اتصال را محدود میکند. برای اتصال برقرارمهلت بی کاری خواندنومهلت بی کاری نوشتنرا بگذارید: خواندن یا نوشتنی که اینقدر منتظر بماند با ۰ یا کمتر تمام میشود. اینها سقف بیکاریاند، پس برای تونلی که ممکن است ساکت بماند ۰ بگذارید.- بافرها دستیاند.
بایتهای جدیدحافظه میگیرد وآزادسازی بایتهاآزاد میکند؛ چیزی خودکار جمعشان نمیکند. - XHTTP، کوییک و انتقال HTTP/2 ساده نیست. gRPC (
شبکه = "grpc")، ریالیتی (امنیت = "reality") و Mux.Cool هست؛ بخشهای پایین را ببینید.
بافرها و نشانیها
یک مقدار بایتها یک اشارهگر، یک طول و یک ظرفیت است. توابع نوشتن (نوشتن بایت و همخانوادهها) اضافه میکنند و در صورت نیاز بافر را بزرگ میکنند، بایت در و خواندن شانزده بیت میخوانند و به هگزا محتوا را نشان میدهد. نشانی مقصد یک نشانی است: نشانی جدید متن را میبیند و بین IP نسخه ۴، IP نسخه ۶ و نام دامنه تصمیم میگیرد و نوشتن نشانی آن را به ترتیبی مینویسد که سرآیند ویلس و ویمس میخواهند (درگاه، نوع، نشانی). تجزیه یو یو آی دی متن ۳۶ نویسهای معمول را به ۱۶ بایتی که شناسهی کاربر روی سیم است تبدیل میکند و اگر متن UUID نباشد خراب را درست میگذارد.
// زبان: فارسی
واردسازی شبکه.انتقال شبکه
تابع ریشه:
ناپایا b := انتقال شبکه.بایتهای جدید(16)
انتقال شبکه.نوشتن بایت(b، 0x7f)
انتقال شبکه.نوشتن شانزده بیت(b، 443)
انتقال شبکه.نوشتن رشته(b، "hi")
سرچاپ انتقال شبکه.به هگزا(b)، b.طول
سرچاپ انتقال شبکه.خواندن شانزده بیت(b، 1)، انتقال شبکه.بایت در(b، 3) برگردان صحیح
انتقال شبکه.آزادسازی بایتها(b)
a := انتقال شبکه.نشانی جدید("example.com"، 443)
سرچاپ a.میزبان، a.درگاه، a.نوع برابر انتقال شبکه.نشانی دامنه
سرچاپ انتقال شبکه.نشانی جدید("192.168.1.9"، 80).نوع برابر انتقال شبکه.نشانی آی پی چهار
سرچاپ انتقال شبکه.نشانی جدید("2001:db8::1"، 8080).نوع برابر انتقال شبکه.نشانی آی پی شش
ناپایا wire := انتقال شبکه.بایتهای جدید(32)
انتقال شبکه.نوشتن نشانی(wire، a)
سرچاپ انتقال شبکه.به هگزا(wire)
ناپایا back := انتقال شبکه.نشانی {}
used := انتقال شبکه.خواندن نشانی(wire، 0، back)
سرچاپ used، back.میزبان، back.درگاه
انتقال شبکه.آزادسازی بایتها(wire)
id := انتقال شبکه.تجزیه یو یو آی دی("b831381d-6324-4d53-ad4f-8cda48b30811")
سرچاپ id.خراب، id.طول، انتقال شبکه.قالب یو یو آی دی(id)
سرچاپ انتقال شبکه.تجزیه یو یو آی دی("not a uuid").خراب
پایانشروع سریع: یک کارخواه و یک سرور
شنود درگاهی را میگیرد (۰ یعنی درگاه آزاد و درگاه شنونده میگوید کدام)، پذیرش منتظر کارخواه میماند و خواندن و نوشتن بایت جابهجا میکنند. وقتی طرف مقابل بسته باشد خواندن ۰ یا کمتر برمیگرداند. بعد از شمارهگیری معتبر را بررسی کنید و اگر نادرست بود خطا را بخوانید. این برنامه سرور را در یک نخ اجرا میکند و از راه نشانی حلقهی محلی با آن حرف میزند.
// زبان: فارسی
واردسازی حافظه
واردسازی همگام سازی
واردسازی شبکه.انتقال شبکه
ناپایا port := 0
ناپایا ready := همگام سازی.گروه انتظار جدید()
تابع echo_once():
settings := انتقال شبکه.تنظیمات {}
l := انتقال شبکه.شنود(0، settings)
port = انتقال شبکه.درگاه شنونده(l)
همگام سازی.اتمام(ready)
ناپایا c := انتقال شبکه.پذیرش(l)
buf := حافظه.تخصیص(4096 برگردان طبیعی۶۴)
n := انتقال شبکه.خواندن(c، buf، 4096)
اگر n بزرگتر 0:
انتقال شبکه.نوشتن(c، buf، n)
پایان
حافظه.آزادسازی(buf)
انتقال شبکه.بستن(c)
انتقال شبکه.بستن شنونده(l)
پایان
تابع ریشه:
همگام سازی.افزودن(ready، 1 برگردان صحیح۶۴)
t := نخساز(echo_once)
همگام سازی.انتظار(ready)
ناپایا c := انتقال شبکه.شماره گیری("127.0.0.1"، port، انتقال شبکه.تنظیمات {})
اگر وارونه انتقال شبکه.معتبر(c):
سرچاپ "شمارهگیری شکست خورد:"، c.خطا
برگشت
پایان
ناپایا msg := انتقال شبکه.از رشته("hello transport")
انتقال شبکه.ارسال بایت ها(c، msg)
buf := حافظه.تخصیص(4096 برگردان طبیعی۶۴)
n := انتقال شبکه.خواندن(c، buf، 4096)
سرچاپ "پژواک"، n، "بایت:"، (buf برگردان رشته).زیررشته(0، n)
حافظه.آزادسازی(buf)
انتقال شبکه.آزادسازی بایتها(msg)
انتقال شبکه.بستن(c)
نخپیوند(t)
پایانوبسوکت و اینکه چرا پذیرش کافی نیست
در دو طرف شبکه = "ws"، یک مسیر و اگر خواستید یک سربرگ میزبان بگذارید. کارخواه یک GET عادی با User-Agent مرورگر میفرستد. سرور مسیر را و، اگر سربرگ میزبان گذاشته باشید، سرآیند Host را میسنجد؛ ناهمخوانی با یک صفحهی 404 Not Found به سبک nginx پاسخ داده میشود و اتصال بسته میشود، پس کاوشگری که مسیر دیگری را امتحان کند یک وبسرور معمولی میبیند.
برنامهی زیر سمت سرور را محتاطانه انجام میدهد: پذیرش خام فقط اتصال TCP (و وقتی تی ال اس روشن است دستدهی TLS) را میگیرد و ارتقا بعد درخواست را میخواند. در سرور واقعی فراخوانی ارتقا و هر چه بعدش میآید برای هر اتصال در یک نخ کارگر قرار میگیرد تا کارخواهی که گیر کرده جلوی بقیه را نگیرد. نیمهی دوم رد شدن یک مسیر اشتباه را نشان میدهد.
// زبان: فارسی
واردسازی حافظه
واردسازی همگام سازی
واردسازی شبکه.انتقال شبکه
ناپایا port := 0
ناپایا ready := همگام سازی.گروه انتظار جدید()
ناپایا seen_path := ""
ناپایا seen_host := ""
تابع settings(): انتقال شبکه.تنظیمات:
ناپایا s := انتقال شبکه.تنظیمات {}
s.شبکه = "ws"
s.مسیر = "/tunnel"
s.سربرگ میزبان = "cdn.example.com"
برگشت s
پایان
تابع worker():
s := settings()
l := انتقال شبکه.شنود(0، s)
port = انتقال شبکه.درگاه شنونده(l)
همگام سازی.اتمام(ready)
ناپایا c := انتقال شبکه.پذیرش خام(l)
اگر انتقال شبکه.ارتقا(c، s):
seen_path = c.مسیر درخواست
seen_host = c.میزبان درخواست
buf := حافظه.تخصیص(4096 برگردان طبیعی۶۴)
n := انتقال شبکه.خواندن(c، buf، 4096)
انتقال شبکه.نوشتن(c، buf، n)
حافظه.آزادسازی(buf)
پایان
انتقال شبکه.بستن(c)
انتقال شبکه.بستن شنونده(l)
پایان
تابع ریشه:
همگام سازی.افزودن(ready، 1 برگردان صحیح۶۴)
t := نخساز(worker)
همگام سازی.انتظار(ready)
ناپایا c := انتقال شبکه.شماره گیری("127.0.0.1"، port، settings())
ناپایا msg := انتقال شبکه.از رشته("inside a websocket")
انتقال شبکه.ارسال بایت ها(c، msg)
buf := حافظه.تخصیص(4096 برگردان طبیعی۶۴)
n := انتقال شبکه.خواندن(c، buf، 4096)
سرچاپ (buf برگردان رشته).زیررشته(0، n)
حافظه.آزادسازی(buf)
انتقال شبکه.آزادسازی بایتها(msg)
انتقال شبکه.بستن(c)
نخپیوند(t)
سرچاپ "سرور مسیر را دید"، seen_path، "و میزبان"، seen_host
ناپایا wrong := settings()
wrong.مسیر = "/other"
همگام سازی.افزودن(ready، 1 برگردان صحیح۶۴)
t2 := نخساز(worker)
همگام سازی.انتظار(ready)
bad := انتقال شبکه.شماره گیری("127.0.0.1"، port، wrong)
سرچاپ "مسیر اشتباه پذیرفته شد:"، انتقال شبکه.معتبر(bad)
سرچاپ bad.خطا
نخپیوند(t2)
پایانداده زودهنگام همان ترفند «صفر رفتوبرگشت» به سبک Xray است: بایتهای اول بار در سرآیند Sec-WebSocket-Protocol درخواست ارتقا میروند. آنها را به شماره گیری با داده زودهنگام بدهید و داده زودهنگام را روی بزرگترین اندازهای که در دو طرف اجازه میدهید بگذارید. سرور این بایتها را در اولین خواندن پس میدهد.
ویلس یا ویمس روی وبسوکت و TLS پشت CDN
این راه معمول اجرای پراکسیای است که باید زنده بماند: سرور واقعی پشت یک CDN پنهان است، اتصال به CDN HTTPS معمولی است و CDN درخواستهای وبسوکت برای یک مسیر محرمانه را به سرور میرساند.
- یک دامنه را روی CDN بگذارید و به سرور اشاره دهید. پراکسی (ابر نارنجی) را روشن کنید و وبسوکت را فعال کنید. درگاهی را بگیرید که CDN برای HTTPS میپذیرد، مثل ۴۴۳، ۲۰۵۳، ۲۰۸۳، ۲۰۸۷ یا ۲۰۹۶.
- بگذارید CDN TLS را تمام کند. حالت «Full» آن را با گواهی مبدأ انتخاب کنید، یا سرور را با
تی ال اس = درستو گواهی و کلید درپرونده گواهیوپرونده کلیداجرا کنید. اگر نمیخواهید مبدأ اصلاً TLS حرف بزند، باwsساده روی یک درگاه محلی پشت پراکسی معکوس خودتان گوش دهید. - در سرور با
شبکه = "ws"، یکمسیرتصادفی بلند وسربرگ میزبانبرابر دامنهی خودتانشنودکنید. هر درخواست برای مسیر دیگر، ۴۰۴ شبیه nginx میگیرد. - در کارخواه به نام جلویی (هر نامی که به CDN میرسد) با
تی ال اس = درست،نام سروربرابر نام جلویی،سربرگ میزبانبرابر دامنهی خودتان و همانمسیرشمارهگیری کنید. شبکهی بین شما و CDN فقط TLS به نام جلویی را میبیند. الپن = "http/1.1"بگذارید.داده زودهنگامرا فقط وقتی تنظیم کنید که CDN سرآیندSec-WebSocket-Protocolرا رد کند.
// زبان: فارسی
واردسازی شبکه.انتقال شبکه
تابع client_settings(): انتقال شبکه.تنظیمات:
ناپایا s := انتقال شبکه.تنظیمات {}
s.شبکه = "ws"
s.تی ال اس = درست
s.نام سرور = "front.example.net"
s.سربرگ میزبان = "vpn.example.org"
s.مسیر = "/ws-8f3a"
s.الپن = "http/1.1"
s.داده زودهنگام = 2048
s.مهلت میلی ثانیه = 8000
برگشت s
پایان
تابع server_settings(): انتقال شبکه.تنظیمات:
ناپایا s := انتقال شبکه.تنظیمات {}
s.شبکه = "ws"
s.مسیر = "/ws-8f3a"
s.سربرگ میزبان = "vpn.example.org"
برگشت s
پایان
تابع ریشه:
c := انتقال شبکه.شماره گیری("front.example.net"، 443، client_settings())
سرچاپ انتقال شبکه.معتبر(c)، c.خطا
l := انتقال شبکه.شنود(10000، server_settings())
سرچاپ انتقال شبکه.شنونده معتبر(l)
انتقال شبکه.بستن شنونده(l)
پایانسایت این برنامه را فقط وارسی میکند و اجرا نمیکند، چون به سرور شما نیاز دارد. همین چیدمان را روی یک پروتکل در صفحههای وی لس و وی مس ببینید و برای وصل کردنش به یک پراکسی محلی صفحهی تونل را. CDN بین دو پای TLS خودش همهی ترافیک شما را آشکار میبیند: TLS را برای شما تمام میکند و فقط پروتکل داخلی (ویمس) یا نبودنش (ویلس با encryption=none) باقی میماند. اگر به CDN برای بار خود اعتماد ندارید، ویمس را با امنیت ای ای اس۱۲۸ جی سی ام یا امنیت چاچا۲۰ پلی۱۳۰۵ بگیرید.
تکهتکه کردن ClientHello در TLS
بعضی فیلترهای ملی، از جمله فیلتر ایران، نام سرور را از بستهی اول اتصال TLS میخوانند و اگر نام در فهرست باشد اتصال را میبرند. اغلب این کار را بدون سرهمکردن TCP یا رکوردهای TLS میکنند، پس ClientHello که تکهتکه برسد تطبیق نمیخورد. تکه تکه کردن = درست این کار را در لایهی رکورد TLS سمت کارخواه انجام میدهد، بدون نخ یا سوکت کمکی. حالت تکه تکه کردن میگوید چه چیز شکسته شود:
"tcp"(پیشفرض): رکورد ClientHello در چند بستهی TCP به اندازهی تصادفیکمینه تکهتابیشینه تکهبا فاصلهیتاخیر تکه میلی ثانیهنوشته میشود."tls": خود رکورد ClientHello به چند رکورد TLS (هر کدام با سرآیند خودش) شکسته میشود که سرور دوباره سرهم میکند. رکوردها هر کدام در یک بسته میروند."both": رکورد شکسته میشود و نتیجه به بستههای TCP هم بریده میشود.
برش نام سرور = درست یک برش میان نام سرور میافزاید تا هیچ تکه و رکوردی آن را کامل نداشته باشد؛ اگر کمینه و بیشینه هر دو ۰ باشند تنها برش است. شمار نوشتن های تکه شده میگوید چند نوشتن اول دستدهی تکه شود (۱ همان ClientHello است). سرور در هر دو حالت همان بایتهای دستدهی را میبیند؛ آزمونها نشان میدهند سرور واقعی TLS دستدهی را کامل میکند و یک گیرنده رکوردها را به همان ClientHello یکسان سرهم میکند.
اندازه تکه ها تابعی است که اندازهها را برمیگزیند. عمومی است تا ببینید یک تنظیم چه تولید میکند: همهی تکهها بهجز آخری در بازهاند و مجموعشان برابر کل است.
// زبان: فارسی
واردسازی شبکه.انتقال شبکه
تابع ریشه:
sizes := انتقال شبکه.اندازه تکه ها(517، 5، 20)
ناپایا total := 0
ناپایا in_range := درست
تکرار sizes.طول() در i:
n := sizes.بگیر(i)
total += n
اگر i کوچکتر sizes.طول() - 1 و (n کوچکتر 5 یا n بزرگتر 20):
in_range = نادرست
پایان
پایان
سرچاپ "مجموع تکهها برابر است با"، total
سرچاپ "همهی تکهها جز آخری ۵ تا ۲۰ بایتاند:"، in_range
سرچاپ "بیش از ۲۵ تکه:"، sizes.طول() بزرگتر 25
سرچاپ "یک تکه وقتی کمینه و بیشینه کل پیام را میپوشانند:"، انتقال شبکه.اندازه تکه ها(10، 50، 60).طول()
پایانبرای روشن کردن آن در یک شمارهگیری TLS:
// زبان: فارسی
واردسازی شبکه.انتقال شبکه
تابع ریشه:
ناپایا s := انتقال شبکه.تنظیمات {}
s.تی ال اس = درست
s.نام سرور = "example.com"
s.تکه تکه کردن = درست
s.کمینه تکه = 3
s.بیشینه تکه = 30
s.تاخیر تکه میلی ثانیه = 5
s.مهلت میلی ثانیه = 8000
ناپایا c := انتقال شبکه.شماره گیری("example.com"، 443، s)
سرچاپ انتقال شبکه.معتبر(c)، c.خطا
انتقال شبکه.بستن(c)
پایانبا تکههای ۳ تا ۳۰ بایت و مکث ۵ تا ۱۰ میلیثانیه شروع کنید. تکهی کوچکتر و مکث بلندتر فیلترهای بیشتری را گیج میکند و دستدهی را کندتر؛ اگر اتصال شروع به شکست یا پایان مهلت کرد، تکهها را بزرگتر یا مکث را کوتاهتر کنید. تکهتکه کردن فقط در کارخواه و فقط با تی ال اس = درست کار میکند. باید همانجایی که هستید امتحانش کنید: فیلتری که جریان را بازسازی کند، یا فیلتری که روی نشانی IP یا چیزی جز نام سرور مسدود کند، تأثیر نمیپذیرد، و آنچه جواب میدهد با زمان عوض میشود. تکهتکه کردن نام را از فیلتر پنهان میکند؛ پنهان نمیکند که پراکسی به کار بردهاید و شکل خود دستدهی را عوض نمیکند (بالا دربارهی اثر انگشت ببینید).
gRPC (gun و multi)
شبکه = "grpc" بایتها را در یک جریان HTTP/2 از پیامهای gRPC میبرد، همان شکل «gun» V2Ray: کارخواه به /نامسرویس/Tun POST میکند و هر پیام یک فیلد پروتوبافر با داده دارد. حالت جی آر پی سی = "multi" از /نامسرویس/TunMulti استفاده میکند. با تی ال اس = درست ALPN بهطور پیشفرض h2 است؛ بدون TLS HTTP/2 ساده است. نام سرویس را دو طرف بگذارید (پیوندها آن را serviceName میبرند)؛ درخواست برای نام دیگر با خطای gRPC پاسخ داده میشود و اتصالی ساخته نمیشود. قاببندی HTTP/2 در همین بسته با HPACK از net.http2 نوشته شده، چون اتصال باید همزمان از دو نخ خوانده و نوشته شود. سرور چند جریان روی یک اتصال HTTP/2 را میپذیرد و هر کدام یک اتصال از پذیرش میشود. فقط با خودش آزموده شده و با همتای واقعی gRPC Xray اجرا نشده است.
Mux.Cool
چندگانه ساز کارخواه جدید و چندگانه ساز کارساز جدید نشستها را روی یک جریان چندپلکس میکنند، با قاببندی V2Ray و Xray برای CmdMux: باز کردن نشست نشستی به یک مقصد باز میکند و جریانش را میدهد و پذیرش نشست در سمت دیگر هر نشست بازشده را با مقصدش برمیگرداند. MuxClient و MuxServer در بستههای ویلس و ویمس این را برای اتصالی که با CmdMux ساخته شده میپوشانند. مثل اصل، کنترل جریان میان نشستها نیست و یک نشست گیرکرده میتواند بقیه را نگه دارد؛ افزونههای XUDP (شناسهی سراسری، نشانی هر بسته) پیاده نشده است. نشست یودیپی در هر نوشتن یک دیتاگرام میبرد؛ ایکسری اگر دیتاگرامی بزرگتر از ۸۱۹۲ بایت برسد کل اتصال Mux را میبندد، پس بیشینه بسته چندگانه ساز اعمال میشود: نوشتن بزرگتر رد میشود (۱- برمیگرداند) و نشست باز میماند. با ایکسری نشست یودیپی تا ۸۱۹۲ بایت کار میکند و با سینگباکس تا ۱۶۰۰۰ اندازهگیری شد.
ریالیتی
با امنیت = "reality" کارخواه دستدهی ریالیتی net.reality را بهجای TLS اجرا میکند (ریلیتی را با کلید عمومی و شناسهی کوتاه بگذارید) و شنونده سمت سرور را از ریلیتی کارساز انجام میدهد؛ اتصالی که احراز نشود به سایت پوشش رله میشود. بعد از دستدهی همهچیز مثل TLS است.
محدودیتها و امنیت
- گواهیها بهطور پیشفرض سنجیده میشوند.
اجازه ناامن = درستسنجش را خاموش میکند و هر کسی روی مسیر میتواند اتصال را بخواند و تغییر دهد. فقط برای آزمایش با گواهی خودامضا از آن استفاده کنید، یا بهجایش مرجع گواهی را بهپرونده گواهی ریشهبدهید. - تکهتکه کردن فقط به نوشتنهای اول دست میزند. رکوردهای بعدی مهر شدهاند و هرگز شکسته نمیشوند؛
شمار نوشتن های تکه شدهبیش از ۱ فقط برای دستدهیهایی که بیش از یک دسته پیام (flight) میفرستند اثر دارد. - ۴۰۴ جعلی تمام پوشش است. بازدیدکنندهای که مسیر درست را دارد ولی دستدهی وبسوکت ندارد،
400 Bad Requestرا به همان سبک nginx میگیرد. هیچ چیز دیگر سرور شبیه یک وبسایت ساخته نمیشود؛ اگر لازم دارید، یک پراکسی معکوس واقعی جلویش بگذارید. - شنونده بهطور پیشفرض روی نشانی loopback مینشیند.
شنودازنشانی شنود(127.0.0.1) استفاده میکند؛ برای پذیرش از ماشینهای دیگرشنود همهیاشنود در نشانیبا"0.0.0.0"را صدا بزنید. کارخواههای گیرکرده با سقف زمان دستدهی رها میشوند؛ برای بیکارهامهلت بی کاری خواندنبگذارید. - مقایسهی زنده با Xray یا V2Ray انجام نشده. بسته با خودش و با بردارهای بایتی آزموده شده؛ اینکه یک CDN یا یک ساخت Xray درخواستهایش را بپذیرد باید در محیط خودتان امتحان شود.
گونهها
تنظیمات Settings
ساختار تنظیمات| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| شبکه | network | رشته = "tcp" | "tcp"، "ws" یا "httpupgrade". |
| تی ال اس | tls | منطقی = نادرست | اتصال را در TLS بپیچد. شنونده علاوه بر آن به پرونده گواهی و پرونده کلید نیاز دارد. |
| نام سرور | sni | رشته = "" | نام سرور که در دستدهی TLS فرستاده میشود و گواهی با آن سنجیده میشود. خالی یعنی میزبان شمارهگیریشده. |
| الپن | alpn | رشته = "" | تنها پروتکل ALPN برای پیشنهاد، مثل "http/1.1". یک رشته است، نه فهرست. |
| اثر انگشت | fingerprint | رشته = "" | نام یک مرورگر مثل "chrome". برای پیوندهایی که آن را دارند نگه داشته میشود؛ دستدهی را عوض نمیکند. |
| اجازه ناامن | allow_insecure | منطقی = نادرست | سنجش گواهی را رد میکند. روی شبکهی واقعی ناامن است. |
| پرونده گواهی ریشه | ca_file | رشته = "" | پروندهی PEM مرجعهای گواهی که بهجای مرجعهای سیستم باور میشوند. |
| مسیر | path | رشته = "/" | مسیر درخواست وبسوکت یا ارتقا. سرور هر مسیر دیگری را رد میکند. |
| سربرگ میزبان | host | رشته = "" | سرآیند Host درخواست ارتقا. سروری که این را گذاشته باشد نامهای میزبان دیگر را رد میکند. |
| سربرگ ها | headers | رشته = "" | سرآیندهای اضافهی درخواست کارخواه، به صورت خطهای Name: value که با \r\n جدا شدهاند. |
| داده زودهنگام | early_data | صحیح = 0 | بیشترین تعداد بایت بار که در سرآیند Sec-WebSocket-Protocol فرستاده میشود. ۰ دادهی زودهنگام را خاموش میکند. |
| تکه تکه کردن | fragment | منطقی = نادرست | بایتهای اول دستدهی TLS را در تکههای کوچک میفرستد. سمت کارخواه و فقط با تی ال اس. |
| کمینه تکه | fragment_min | صحیح = 5 | کوچکترین تکه به بایت. |
| بیشینه تکه | fragment_max | صحیح = 20 | بزرگترین تکه به بایت. |
| تاخیر تکه میلی ثانیه | fragment_delay_ms | صحیح = 10 | مکث بین دو تکه به میلیثانیه. |
| پرونده گواهی | cert_file | رشته = "" | زنجیرهی گواهی سرور، به صورت پروندهی PEM. |
| پرونده کلید | key_file | رشته = "" | کلید خصوصی سرور، به صورت پروندهی PEM. |
| مهلت میلی ثانیه | timeout_ms | صحیح = 0 | اتصال TCP چقدر میتواند طول بکشد. ۰ یعنی پیشفرض سیستم. خواندن را محدود نمیکند. |
| مهلت بی کاری خواندن | read_timeout_ms | صحیح = 0 | مهلت بیکاری خواندن یک اتصال برقرار به میلیثانیه. ۰ یعنی همیشه منتظر ماندن. |
| مهلت بی کاری نوشتن | write_timeout_ms | صحیح = 0 | مهلت بیکاری نوشتن یک اتصال برقرار به میلیثانیه. ۰ یعنی همیشه منتظر ماندن. |
| حالت تکه تکه کردن | fragment_mode | رشته = "tcp" | تکه تکه کردن چه چیزی را میشکند: "tcp" (پیشفرض) هلو را در چند بستهی TCP مینویسد، "tls" رکورد ClientHello را به چند رکورد TLS میشکند و "both" هر دو را. |
| برش نام سرور | fragment_sni | منطقی = نادرست | در میانهی نام سرور هم برش میزند تا هیچ تکهای نام کامل را نداشته باشد. اگر کمینه و بیشینه هر دو ۰ باشند این تنها برش است. |
| شمار نوشتن های تکه شده | fragment_writes | صحیح = 1 | چند نوشتن اول دستدهی تکه میشود. پیشفرض ۱ همان ClientHello است. |
| نشانی شنود | bind | رشته = "127.0.0.1" | نشانیای که شنونده روی آن مینشیند. پیشفرض 127.0.0.1 است؛ برای همهی رابطها از شنود همه یا "0.0.0.0" استفاده کنید. |
| مهلت دست دادن | handshake_timeout_ms | صحیح = 10000 | سرور چقدر به یک اتصال تازه وقت میدهد دستدهی TLS و ارتقا را تمام کند، پیش از آنکه رهایش کند. پیشفرض ۱۰۰۰۰. |
| بیشینه دست دادن همزمان | max_handshakes | صحیح = 128 | یک شنونده چند دستدهی را همزمان پیش میبرد. اتصالهای بیشتر بلافاصله بسته میشوند. پیشفرض ۱۲۸. |
| بیشینه دست دادن مبدا | max_per_source | صحیح = 0 | یک نشانی مبدا چند دستدهی همزمان میتواند داشته باشد. اتصالهای بیشتر از آن بیدرنگ بسته میشوند. ۰ یعنی بدون سقف. |
| امنیت | security | رشته = "" | تهی برای انتخاب ساده یا tls، یا "reality" تا بهجای TLS دستدهی ریالیتی اجرا شود. |
| ریلیتی | reality | ریالیتی.تنظیمات | تنظیمات کارخواه ریالیتی (net.reality) وقتی security برابر "reality" است. |
| ریلیتی کارساز | reality_server | ریالیتی.تنظیمات سرور | تنظیمات کارساز ریالیتی وقتی security برابر "reality" است. |
| نام سرویس | service_name | رشته = "" | نام سرویس gRPC برای network = "grpc". مسیر درخواست /service/Tun است (در حالت multi: /service/TunMulti). |
| حالت جی آر پی سی | grpc_mode | رشته = "gun" | "gun" (پیشفرض) یا "multi" برای network = "grpc". |
اتصال Conn
ساختار اتصال| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نوع | kind | صحیح = 0 | نوع تی سی پی، نوع تی ال اس یا نوع جریان. |
| تی سی پی | tcp | تی سی پی.اتصال شبکه | سوکت TCP، اگر باشد. |
| تی ال اس | tls | تی ال اس.اتصال | نشست TLS، اگر باشد. |
| جریان زیرین | up | dyn تونل.جریان | جریان زیر اتصال وقتی نوعش نوع جریان است. |
| وب سوکت | ws | منطقی = نادرست | بعد از ارتقای وبسوکت درست است: خواندن و نوشتن از آن به بعد با چارچوب است. |
| کارخواه | client | منطقی = نادرست | در طرفی که شمارهگیری کرده درست است. |
| باز | open | منطقی = نادرست | تا وقتی اتصال قابل استفاده است درست است. معتبر همین را برمیگرداند. |
| خطا | err | رشته = "" | دلیل شکست شمارهگیری، پذیرش یا ارتقا، و در غیر این صورت خالی. |
| باقی چارچوب | fr_left | صحیح = 0 | بایتهای چارچوب وبسوکت جاری که هنوز خوانده نشدهاند. |
| نقابدار | fr_masked | منطقی = نادرست | چارچوب جاری نقابدار است. |
| نقاب | fr_mask | صحیح۶۴ = 0 | نقاب چارچوب جاری. |
| جایگاه چارچوب | fr_pos | صحیح = 0 | جایگاه داخل قاب جاری، برای برداشتن نقاب. |
| پیش خوانده | pre | بایتها | دادهی زودهنگامی که با درخواست ارتقا رسیده. اولین خواندنها آن را برمیگردانند. |
| مسیر درخواست | request_path | رشته = "" | در سرور بعد از ارتقا: مسیری که کارخواه خواسته. |
| میزبان درخواست | request_host | رشته = "" | در سرور بعد از ارتقا: سرآیند Host که کارخواه فرستاده. |
| بافر نوشتن | wbuf | بایتها | بافر قابل استفادهی دوبارهای که قابهای وبسوکت پیش از یک نوشتن در آن ساخته میشوند. |
| مبدا | remote | رشته = "" | نشانی همتا، یا تهی وقتی دانسته نیست. |
| بسته شده | closed | منطقی = نادرست | پس از اجرای Close درست است، پس بستن دوباره کاری نمیکند. |
شنونده Listener
ساختار شنونده| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| سرور | server | تی سی پی.سرور | سوکت سرور TCP. |
| تنظیمات | settings | تنظیمات | تنظیماتی که به شنود داده شده. |
| پیکربندی تی ال اس | tls_cfg | تی ال اس.پیکربندی کارساز | پیکربندی TLS سرور که از گواهی و کلید بارگیری شده. |
| آماده | ready | کانال.کانال<اتصال> | صف اتصالهایی که دستدهیشان تمام شده و پذیرش از آن برمیدارد. |
| پرچم ها | flags | صحیح۶۴* | شمارندههای مشترک حلقهی پذیرش: آغاز شده، متوقف شده. |
| جایگاه ها | slots | همگام سازی.نشانگر | سقف دستدهیهای همزمان در حال انجام. |
| مبداها | sources | تونل.جدول مبداها | دستدهیهای در جریان برای هر نشانی مبدا. |
نشست پذیرفته MuxIncoming
ساختار نشست پذیرفته| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| جریان | stream | dyn تونل.جریان | جریان نشست. بستنش فقط نشست را پایان میدهد. |
| نشانی | addr | نشانی | مقصدی که کارخواه خواسته. |
| یو دی پی | udp | منطقی = نادرست | درست وقتی هر نوشتن و خواندن جریان یک دیتاگرام است. |
چندگانه ساز Mux
ساختار چندگانه ساز| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| هسته | core | تهی* | وضعیت مشترک چندگانهساز. |
| معتبر | ok | منطقی = نادرست | درست وقتی چندگانهساز ساخته شده باشد. |
نشانی Addr
ساختار نشانی| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نوع | kind | صحیح = 2 | نشانی آی پی چهار، نشانی دامنه یا نشانی آی پی شش. |
| میزبان | host | رشته = "" | نشانی یا نام به صورت متن. |
| درگاه | port | صحیح = 0 | درگاه. |
بایتها Bytes
ساختار بایتهاآزادسازی بایتها آزادش کنید.| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| نشانگر | p | تهی* | آغاز حافظه. |
| طول | len | صحیح = 0 | چند بایت در حال استفاده است. |
| ظرفیت | cap | صحیح = 0 | چند بایت جا دارد تا بافر بزرگ شود. |
| خراب | bad | منطقی = نادرست | وقتی بافر نتیجهی یک تجزیه یا تبدیل ناموفق باشد، مثل هگزا یا UUID نامعتبر، درست است. |
پایاها و متغیرها
نوع اتصال Kind…
نوع یک اتصال: نوع تی سی پی (۰) TCP ساده، نوع تی ال اس (۱) TLS، نوع جریان (۲) یک جریان net.tunnel.| نام | انگلیسی | مقدار |
|---|---|---|
| نوع تی سی پی | KindTCP | 0 |
| نوع تی ال اس | KindTLS | 1 |
| نوع جریان | KindStream | 2 |
بیشینه بسته چندگانه ساز MuxMaxPacket
پایا بیشینه بسته چندگانه ساز: صحیح۳۲ = 8192نشانی آی پی چهار AddrIPv4
پایا نشانی آی پی چهار: صحیح۳۲ = 1نشانی دامنه AddrDomain
پایا نشانی دامنه: صحیح۳۲ = 2نشانی آی پی شش AddrIPv6
پایا نشانی آی پی شش: صحیح۳۲ = 3تابعها
اندازه تکه ها FragmentSizes
تابع اندازه تکه ها(total: صحیح، min: صحیح، max: صحیح): وکتور<صحیح>total بایتی به کار میبرد: هر تکه بین min و max بایت است، شاید بهجز آخری، و مجموعشان total است. اندازهها تصادفیاند.معتبر Ok
تابع معتبر(c: اتصال): منطقیخواندن Read
تابع خواندن(c &: اتصال، buf: تهی*، max: صحیح): صحیحmax بایت میخواند و میگوید چند بایت رسید. اتصال وبسوکت بار قابهای دودویی را برمیگرداند و پینگ را خودش پاسخ میدهد. ۰ یا کمتر یعنی اتصال تمام شد.خواندن کامل ReadFull
تابع خواندن کامل(c &: اتصال، buf: تهی*، n: صحیح): منطقیn بایت میخواند. اگر اتصال زودتر تمام شود نادرست است.نوشتن Write
تابع نوشتن(c &: اتصال، p: تهی*، n: صحیح): منطقیn بایت از یک اشارهگر مینویسد، در اتصال وبسوکت به صورت یک قاب. اگر شکست بخورد نادرست است.ارسال بایت ها WriteBytes
تابع ارسال بایت ها(c &: اتصال، b: بایتها): منطقیتغییر به خواندن مستقیم SwitchDirect
تابع تغییر به خواندن مستقیم(c &: اتصال): منطقیمهلت خواندن SetReadTimeout
تابع مهلت خواندن(c &: اتصال، ms: صحیح)بستن Close
تابع بستن(c &: اتصال)شماره گیری با داده زودهنگام DialEarly
تابع شماره گیری با داده زودهنگام(host: رشته، port: صحیح، s: تنظیمات، early: بایتها): اتصالشماره گیری وصل میشود و اگر تنظیمات دادهی زودهنگام را اجازه بدهند early را در درخواست ارتقا میفرستد.شماره گیری Dial
تابع شماره گیری(host: رشته، port: صحیح، s: تنظیمات): اتصالمعتبر را بررسی کنید و اگر نادرست بود خطا را بخوانید.شنود در نشانی ListenAt
تابع شنود در نشانی(host: رشته، port: صحیح، s: تنظیمات): شنونده"all" یا "0.0.0.0" یعنی همهی رابطها.شنونده از سرور ListenerFrom
تابع شنونده از سرور(server: تی سی پی.سرور، s: تنظیمات): شنوندهrawsock.ListenOn)، با صف پذیرش، سقف دستدهی و TLS سرور آماده. net.vpn از آن استفاده میکند.شنود Listen
تابع شنود(port: صحیح، s: تنظیمات): شنوندهشنود همه ListenAll
تابع شنود همه(port: صحیح، s: تنظیمات): شنوندهشنود اما روی همهی رابطهای شبکه. این همان پذیرش صریح است: خود شنود فقط روی نشانی loopback مینشیند.شنونده معتبر ListenerOk
تابع شنونده معتبر(l: شنونده): منطقیدرگاه شنونده ListenerPort
تابع درگاه شنونده(l: شنونده): صحیحبستن شنونده CloseListener
تابع بستن شنونده(l: شنونده)پذیرش خام AcceptRaw
تابع پذیرش خام(l: شنونده): اتصالارتقا Upgrade
تابع ارتقا(c &: اتصال، s: تنظیمات): منطقیپذیرش خام میخواند، مسیر و میزبان را میسنجد، پاسخ میدهد و اتصال را به وبسوکت یا حالت خام میبرد. برای tcp ساده کاری نمیکند. درخواست ردشده پاسخ میگیرد و اتصال بسته میشود.خاموش کردن اتصال ShutdownConn
تابع خاموش کردن اتصال(c &: اتصال)خواندنی که در نخ دیگری منتظر است ۰ یا کمتر برگرداند و طرف مقابل پایان را ببیند. پس از آن بستن را صدا بزنید. اتصالی که روی جریان net.tunnel است دستنخورده میماند.// زبان: فارسی
واردسازی حافظه
واردسازی همگام سازی
واردسازی شبکه.انتقال شبکه
ناپایا port := 0
ناپایا ready := همگام سازی.گروه انتظار جدید()
تابع count_then_answer():
l := انتقال شبکه.شنود(0، انتقال شبکه.تنظیمات {})
port = انتقال شبکه.درگاه شنونده(l)
همگام سازی.اتمام(ready)
ناپایا c := انتقال شبکه.پذیرش(l)
buf := حافظه.تخصیص(4096 برگردان طبیعی۶۴)
ناپایا total := 0
ناپایا n := انتقال شبکه.خواندن(c، buf، 4096)
تا n بزرگتر 0:
total += n
n = انتقال شبکه.خواندن(c، buf، 4096)
پایان
حافظه.آزادسازی(buf)
ناپایا reply := انتقال شبکه.از رشته("سرور " + total + " بایت خواند")
انتقال شبکه.ارسال بایت ها(c، reply)
انتقال شبکه.آزادسازی بایتها(reply)
انتقال شبکه.خاموش کردن اتصال(c)
انتقال شبکه.بستن(c)
انتقال شبکه.بستن شنونده(l)
پایان
تابع ریشه:
همگام سازی.افزودن(ready، 1 برگردان صحیح۶۴)
t := نخساز(count_then_answer)
همگام سازی.انتظار(ready)
ناپایا c := انتقال شبکه.شماره گیری("127.0.0.1"، port، انتقال شبکه.تنظیمات {})
اگر وارونه انتقال شبکه.معتبر(c):
سرچاپ "شمارهگیری شکست خورد:"، c.خطا
برگشت
پایان
ناپایا msg := انتقال شبکه.از رشته("first part, second part")
انتقال شبکه.ارسال بایت ها(c، msg)
انتقال شبکه.آزادسازی بایتها(msg)
انتقال شبکه.بستن نوشتن اتصال(c)
buf := حافظه.تخصیص(4096 برگردان طبیعی۶۴)
n := انتقال شبکه.خواندن(c، buf، 4096)
سرچاپ (buf برگردان رشته).زیررشته(0، n)
سرچاپ "بعد"، انتقال شبکه.خواندن(c، buf، 4096)
حافظه.آزادسازی(buf)
انتقال شبکه.بستن(c)
نخپیوند(t)
پایانبستن نوشتن اتصال CloseWriteConn
تابع بستن نوشتن اتصال(c &: اتصال)net.tunnel فراخوانی را به لایهی زیرین میدهد. سپس خواندن طرف مقابل ۰ برمیگرداند.نمونهی این مورد همراه با موارد بالاتر آمده است: net-transport-CloseWriteConn.salam
پذیرش Accept
تابع پذیرش(l: شنونده): اتصالپذیرش خام و بعد ارتقا، در نخ فراخواننده. کارخواه گیرکرده فراخواننده را نگه میدارد.به عنوان جریان AsStream
تابع به عنوان جریان(c: اتصال): dyn تونل.جریانtunnel.Stream میپیچد تا کد تونل از آن استفاده کند.از جریان FromStream
تابع از جریان(s: dyn تونل.جریان، client: منطقی): اتصالtunnel.Stream را حامل یک اتصال میکند. با client بگویید کدام طرف است.چندگانه ساز کارخواه جدید NewMuxClient
تابع چندگانه ساز کارخواه جدید(up: dyn تونل.جریان): چندگانه سازچندگانه ساز کارساز جدید NewMuxServer
تابع چندگانه ساز کارساز جدید(up: dyn تونل.جریان): چندگانه سازباز کردن نشست MuxOpen
تابع باز کردن نشست(m: چندگانه ساز، addr: نشانی، udp: منطقی): dyn تونل.جریانپذیرش نشست MuxAccept
تابع پذیرش نشست(m: چندگانه ساز، out &: نشست پذیرفته): منطقیout میگذارد. نادرست وقتی حامل تمام شده باشد.چندگانه ساز معتبر MuxOk
تابع چندگانه ساز معتبر(m: چندگانه ساز): منطقیبستن چندگانه ساز MuxClose
تابع بستن چندگانه ساز(m: چندگانه ساز)تشخیص نوع نشانی DetectKind
تابع تشخیص نوع نشانی(host: رشته): صحیحنشانی جدید NewAddr
تابع نشانی جدید(host: رشته، port: صحیح): نشانینوشتن نشانی PutAddr
تابع نوشتن نشانی(b &: بایتها، a: نشانی): منطقیقالب آی پی شش FormatIPv6
تابع قالب آی پی شش(p: طبیعی۸*): رشتهخواندن نشانی ReadAddr
تابع خواندن نشانی(b: بایتها، off: صحیح، a &: نشانی): صحیحتجزیه یو یو آی دی ParseUUID
تابع تجزیه یو یو آی دی(s: رشته): بایتهاخراب درست میشود.قالب یو یو آی دی FormatUUID
تابع قالب یو یو آی دی(b: بایتها): رشتهبایتهای جدید NewBytes
تابع بایتهای جدید(cap0: صحیح): بایتهاcap0 بایت میگیرد.آزادسازی بایتها FreeBytes
تابع آزادسازی بایتها(b &: بایتها)بازنشانی بایتها ResetBytes
تابع بازنشانی بایتها(b &: بایتها)نشانگر بایتها BytesPtr
تابع نشانگر بایتها(b: بایتها، off: صحیح): تهی*off، برای دادن به تابعی که حافظه را پر یا میخواند.رزرو Reserve
تابع رزرو(b &: بایتها، need: صحیح)need بایت دیگر بدون بزرگ شدن دوباره جا شود.نوشتن بایت Put8
تابع نوشتن بایت(b &: بایتها، v: صحیح)نوشتن شانزده بیت Put16
تابع نوشتن شانزده بیت(b &: بایتها، v: صحیح)نوشتن سیودو بیت Put32
تابع نوشتن سیودو بیت(b &: بایتها، v: صحیح۶۴)نوشتن شصتوچهار بیت Put64
تابع نوشتن شصتوچهار بیت(b &: بایتها، v: طبیعی۶۴)نوشتن خام PutRaw
تابع نوشتن خام(b &: بایتها، src: تهی*، n: صحیح)n بایت از یک اشارهگر اضافه میکند.نوشتن بایتها PutBytes
تابع نوشتن بایتها(b &: بایتها، src: بایتها)نوشتن رشته PutStr
تابع نوشتن رشته(b &: بایتها، s: رشته)نوشتن صفرها PutZeros
تابع نوشتن صفرها(b &: بایتها، n: صحیح)n بایت صفر اضافه میکند.بایت در At
تابع بایت در(b: بایتها، i: صحیح): صحیحi به صورت عددی از ۰ تا ۲۵۵.تنظیم بایت Set8
تابع تنظیم بایت(b &: بایتها، i: صحیح، v: صحیح)i را بازنویسی میکند.خواندن شانزده بیت Peek16
تابع خواندن شانزده بیت(b: بایتها، i: صحیح): صحیحخواندن سیودو بیت Peek32
تابع خواندن سیودو بیت(b: بایتها، i: صحیح): صحیح۶۴مصرف Consume
تابع مصرف(b &: بایتها، n: صحیح)n بایت اول را دور میریزد.برابر Equal
تابع برابر(a: بایتها، b: بایتها): منطقیبه هگزا ToHex
تابع به هگزا(b: بایتها): رشتهاز هگزا FromHex
تابع از هگزا(h: رشته): بایتهاخراب درست میشود.از رشته FromStr
تابع از رشته(s: رشته): بایتها