کتابخانه‌ی استاندارد · شبکه

شدوساکس net.shadowsocks

کارخواه و سرور شدوساکس: رمزهای AEAD و شدوساکس ۲۰۲۲، پیوندهای ss://‎، پوشش simple-obfs، رله‌ی UDP و اجرا روی هر جریان tunnel.Stream.

واردسازی شبکه.شدوساکس

نام آرگومان‌ها شناسه‌ی خود کد است و معادل فارسی ندارد؛ گونه‌ها، کلیدواژه‌ها و نام بسته‌ها با معادل فارسی نوشته می‌شوند.

شدوساکس یک پروتکل پراکسی رمزشده‌ی کوچک است. کارخواه به سرور شدوساکس وصل می‌شود و می‌گوید به کدام میزبان و درگاه می‌خواهد برسد؛ سرور به آنجا وصل می‌شود و بایت‌ها را در دو جهت می‌رساند. همه‌چیز پس از اولین بایت شبیه داده‌ی تصادفی است، پس دست‌دهی‌ای برای شناسایی وجود ندارد. این بسته کارخواه و سرور آن را با خود سلام و بدون کتابخانه‌ی بومی پیاده می‌کند. یکی از بسته‌های پراکسی است که روی تونل ساخته شده و می‌توان آن را به همان مسیریاب‌ها و زنجیره‌های بقیه وصل کرد.

تابع‌های اصلی کم‌اند. برقراری اتصال از راه یک سرور به مقصدی مثل example.com:443 یک اتصال باز می‌کند و خواندن، نوشتن و بستن مثل هر سوکت دیگری کار می‌کنند. گوش دادن یک سرور راه می‌اندازد و خدمت یا خدمت رله به کارخواه‌ها جواب می‌دهد. پیکربندی نشانی سرور، روش رمز، گذرواژه و پوشش اختیاری پوشش را نگه می‌دارد. بقیه (بافر، رمزگذار، رمزگشا و تابع‌های BLAKE3 و کلید) لایه‌ی پایینی پروتکل است که برای آزمایش یا ساختن قاب‌بندی خودتان عمومی گذاشته شده است.

شروع سریع

این برنامه سروری روی یک درگاه آزاد راه می‌اندازد، کارخواهی را از راه آن به example.com:443 وصل می‌کند و یک پیام می‌فرستد. دستگیره هرگز به example.com وصل نمی‌شود؛ فقط مقصدی را که کارخواه خواسته با مقصد اتصال می‌خواند و بایت‌ها را پس می‌فرستد، پس همه‌چیز روی رابط محلی می‌ماند. توقف سرور حلقه‌ی پذیرش را بیدار می‌کند تا خدمت برگردد و نابودی سرور سرور را آزاد می‌کند.

net-shadowsocks-guide-loopback.salam
واردسازی حافظه
واردسازی شبکه.شدوساکس

پایا PASSWORD := "correct horse"

ناپایا srv := شدوساکس.سرور {}
ناپایا seen := ""

تابع answer(c: شدوساکس.اتصال):
    t := شدوساکس.مقصد اتصال(c)
    seen = t.میزبان + ":" + t.درگاه
    buf := حافظه.تخصیص(4096 برگردان طبیعی۶۴)
    n := شدوساکس.خواندن(c، buf، 4096)
    شدوساکس.نوشتن(c، buf، n)
    حافظه.آزادسازی(buf)
    شدوساکس.بستن(c)
پایان

تابع serve():
    شدوساکس.خدمت(srv، (c: شدوساکس.اتصال): answer(c) پایان)
پایان

تابع ریشه:
    srv = شدوساکس.گوش دادن(0، "chacha20-ietf-poly1305"، PASSWORD)
    سرچاپ شدوساکس.سرور معتبر(srv)
    t := نخ‌ساز(serve)

    cfg := شدوساکس.پیکربندی { میزبان = "127.0.0.1"، درگاه = شدوساکس.درگاه سرور(srv)، روش = "chacha20-ietf-poly1305"، گذرواژه = PASSWORD }
    c := شدوساکس.برقراری اتصال(cfg، "example.com"، 443)
    سرچاپ شدوساکس.معتبر(c)
    شدوساکس.نوشتن رشته(c، "hello through shadowsocks")
    سرچاپ شدوساکس.خواندن رشته(c، 4096)
    شدوساکس.بستن(c)

    شدوساکس.توقف سرور(srv)
    نخ‌پیوند(t)
    شدوساکس.نابودی سرور(srv)
    سرچاپ "سرور دید"، seen
پایان
خروجیtrue true hello through shadowsocks سرور دید example.com:443

یک سرور واقعی از خدمت رله استفاده می‌کند که خودش رساندن را انجام می‌دهد: برای هر کارخواه به مقصد خواسته‌شده وصل می‌شود و بایت‌ها را در دو جهت کپی می‌کند تا یکی از دو طرف ببندد. مثال بعد جلوی یک سرور پژواک TCP کوچک یک رله می‌گذارد و پیامی از آن می‌فرستد.

net-shadowsocks-guide-relay.salam
واردسازی حافظه
واردسازی شبکه.تی سی پی
واردسازی شبکه.شدوساکس

ناپایا target := تی سی پی.سرور {}
ناپایا srv := شدوساکس.سرور {}

تابع echo():
    c := تی سی پی.پذیرش(target)
    buf := حافظه.تخصیص(4096 برگردان طبیعی۶۴)
    n := تی سی پی.خواندن بایت(c، buf، 4096)
    تی سی پی.نوشتن بایت(c، buf، n)
    حافظه.آزادسازی(buf)
    تی سی پی.بستن(c)
پایان

تابع serve():
    شدوساکس.خدمت رله(srv)
پایان

تابع ریشه:
    target = تی سی پی.پیوند(0)
    te := نخ‌ساز(echo)

    srv = شدوساکس.گوش دادن(0، "aes-256-gcm"، "relay password")
    ts := نخ‌ساز(serve)

    cfg := شدوساکس.پیکربندی { میزبان = "127.0.0.1"، درگاه = شدوساکس.درگاه سرور(srv)، روش = "aes-256-gcm"، گذرواژه = "relay password" }
    c := شدوساکس.برقراری اتصال(cfg، "127.0.0.1"، تی سی پی.درگاه(target))
    شدوساکس.نوشتن رشته(c، "through the relay")
    سرچاپ شدوساکس.خواندن رشته(c، 4096)
    شدوساکس.بستن(c)

    نخ‌پیوند(te)
    شدوساکس.توقف سرور(srv)
    نخ‌پیوند(ts)
    شدوساکس.نابودی سرور(srv)
    تی سی پی.بستن سرور(target)
پایان
خروجیthrough the relay

سمت کارخواه فقط برقراری اتصال با یک پیکربندی است. برقراری اتصال بی‌درنگ برمی‌گردد و منتظر سرور نمی‌ماند: نشانی مقصد همراه اولین بسته‌ی رمزشده و اولین نوشتن شما می‌رود. پس گذرواژه‌ی غلط را برقراری اتصال گزارش نمی‌کند؛ سرور اتصال را رها می‌کند و اولین خواندن شما ۰ یا عددی منفی برمی‌گرداند. از معتبر برای اتصالی استفاده کنید که حتی شروع نشد (روش ناشناخته یا سرور دست‌نیافتنی).

رمزها

روش نامی از این جدول است. یافتن روش نام را به یک روش تبدیل می‌کند و برای نام ناشناخته مقداری با معتبر نادرست برمی‌گرداند. نام chacha20-poly1305 هم به‌عنوان نام دیگر chacha20-ietf-poly1305 پذیرفته می‌شود. رمزهای جریانی قدیمی مثل rc4-md5 و aes-256-cfb پشتیبانی نمی‌شوند و نخواهند شد: شکسته‌اند.

روشکلیدنمکشکل گذرواژهتوضیح
aes-128-gcm۱۶ بایت۱۶ بایتهر متنیAEAD کلاسیک. اینجا کند است، پایین را ببینید.
aes-256-gcm۳۲ بایت۳۲ بایتهر متنیAEAD کلاسیک. پیش‌فرض پیکربندی. اینجا کند است، پایین را ببینید.
chacha20-ietf-poly1305۳۲ بایت۳۲ بایتهر متنیAEAD کلاسیک. همین را انتخاب کنید.
2022-blake3-aes-128-gcm۱۶ بایت۱۶ بایتbase64 دقیقاً ۱۶ بایتشدوساکس ۲۰۲۲، TCP و UDP.
2022-blake3-aes-256-gcm۳۲ بایت۳۲ بایتbase64 دقیقاً ۳۲ بایتشدوساکس ۲۰۲۲، TCP و UDP.
2022-blake3-chacha20-poly1305۳۲ بایت۳۲ بایتbase64 دقیقاً ۳۲ بایتشدوساکس ۲۰۲۲، TCP و UDP.
net-shadowsocks-guide-methods.salam
واردسازی شبکه.شدوساکس

تابع show(name: رشته):
    m := شدوساکس.یافتن روش(name)
    سرچاپ m.نام، m.معتبر، m.طول کلید، m.طول نمک، m.نسخه۲۰۲۲
پایان

تابع ریشه:
    show("aes-128-gcm")
    show("aes-256-gcm")
    show("chacha20-ietf-poly1305")
    show("2022-blake3-aes-128-gcm")
    show("2022-blake3-aes-256-gcm")
    show("2022-blake3-chacha20-poly1305")
    show("rc4-md5")
پایان
خروجیaes-128-gcm true 16 16 false aes-256-gcm true 32 32 false chacha20-ietf-poly1305 true 32 32 false 2022-blake3-aes-128-gcm true 16 16 true 2022-blake3-aes-256-gcm true 32 32 true 2022-blake3-chacha20-poly1305 true 32 32 true false 0 0 false

برای سه روش اول، گذرواژه هر متنی است و کلید از آن به شیوه‌ی کلاسیک (بایت به کلید، مبتنی بر MD5) ساخته می‌شود، پس گذرواژه‌ی بلند و تصادفی بگذارید. برای رمزهای ۲۰۲۲ گذرواژه خود کلید است: باید base64 دقیقاً به اندازه‌ی طول کلید باشد، مثلاً خروجی openssl rand -base64 32. گذرواژه‌ای با طول نادرست باعث می‌شود ساخت کلید یک بافر با خراب درست برگرداند و گوش دادن یا برقراری اتصال شکست بخورند. رمزهای ۲۰۲۲ با برچسب زمانی (درخواستی که بیش از ۳۰ ثانیه جابه‌جا باشد رد می‌شود) و حافظه‌ی نمک جلوی بازپخش را می‌گیرند و سرآیند اتصال تصدیق می‌شود.

آنچه وجود ندارد

  • UDP شدوساکس ۲۰۲۲ تابع‌های خودش را دارد. بسته بندی یو دی پی و بازکردن یو دی پی برای روش‌های کلاسیک‌اند و سه روش ۲۰۲۲ را رد می‌کنند؛ از PackUdp2022 و UnpackUdp2022 یا از گوش دادن یو دی پی و اتصال یو دی پی استفاده کنید که روش درست را خودشان برمی‌گزینند.
  • چندکاربره روی یک درگاه (سرآیندهای هویت توسعه‌پذیر ۲۰۲۲) فقط با دو روش AES نسخه‌ی ۲۰۲۲ کار می‌کند. روش ChaCha نسخه‌ی ۲۰۲۲ یک کلید می‌گیرد.
  • برای آزمودن سازگاری simple-obfs و جریان TCP نسخه‌ی ۲۰۲۲ از سرور واقعی استفاده نشده است. آن‌ها با خود این بسته و با بازنویسی‌های جداگانه‌ی پایتونی که از روی مشخصات نوشته شده‌اند آزموده شده‌اند، نه با ssserver، shadowsocks-rust یا obfs-server واقعی. رمزهای AEAD کلاسیک با بردارهای آزمون منتشرشده بررسی شده‌اند. روش‌های ۲۰۲۲ و پوشش را تازه‌کار بدانید و پیش از تکیه کردن، با سرور خودتان آزمایش کنید.
  • AES نرم‌افزاری (bitsliced، برای جلوگیری از نشت زمانی) انجام می‌شود و کند است: در آزمون‌های اینجا حدود چهار تا پنج برابر کندتر از ChaCha20. chacha20-ietf-poly1305 را ترجیح دهید.
  • رله نیم‌بستن (half-close) ندارد: وقتی یک طرف ببندد کل اتصال بسته می‌شود. پروتکلی که کارخواهش درخواست را با بستن تمام می‌کند و باز هم پاسخ را می‌خواند خراب می‌شود.
  • رفتار ضد کاوشگر وجود ندارد: سرور در برابر بسته‌ی اول نادرست، به‌جای تخلیه‌ی آن مثل یک وب‌سرور واقعی، اتصال را فوراً می‌بندد و کاوشگر می‌فهمد وب‌سرور نیست.
  • UDP روی IPv4 و IPv6 کار می‌کند (سوکت‌های کارخواه و رله هر دو را می‌پذیرند؛ UdpListenOn("::"، درگاه) به هر دو خدمت می‌دهد) و رله‌ی UDP فیلتر بازپخش ندارد (TCP دارد: حافظه‌ی نمک با ۱۰۰۰۰۰ مدخل).
  • فقط شکل‌های HTTP و TLS در simple-obfs هست؛ v2ray-plugin و افزونه‌های دیگر نیستند.

پیوند ss:// و گزینه‌های افزونه

سرورهای شدوساکس به شکل پیوند ss:// دست‌به‌دست می‌شوند. تجزیه نشانی شکل SIP002 یعنی ss://base64(method:password)@host:port/?plugin=...#tag، شکلی که اطلاعات کاربر در آن متن ساده‌ی درصدگذاری‌شده است (برای رمزهای ۲۰۲۲) و شکل قدیمی را که کل method:password@host:port در آن base64 است می‌خواند. یک نشانی برمی‌گرداند که معتبر آن فقط وقتی درست است که پیوند سالم و روش شناخته‌شده باشد. قالب بندی نشانی پیوند را دوباره می‌نویسد (پیوند ۲۰۲۲ با روش و گذرواژه‌ی متنی و بقیه با base64). تبدیل به پیکربندی یک نشانی را به پیکربندی‌ای تبدیل می‌کند که برقراری اتصال می‌پذیرد، با گزینه‌های پوشش افزونه.

متن افزونه نام یک افزونه است و پس از آن گزینه‌های key=value که با نقطه‌ویرگول جدا می‌شوند، با بک‌اسلش برای گریز از نقطه‌ویرگول یا علامت مساوی. تجزیه افزونه آن را به یک افزونه می‌شکند و گرفتن گزینه افزونه و گزینه افزونه موجود است گزینه‌ها را می‌خوانند. با آزادسازی افزونه آزادش کنید. تبدیل به پیکربندی نام‌های obfs-local و simple-obfs را با گزینه‌های obfs (مقدار http یا tls) و obfs-host می‌فهمد؛ هر افزونه‌ی دیگری نادیده گرفته می‌شود، پس اگر باید ردش کنید خودتان u.افزونه را بررسی کنید.

net-shadowsocks-guide-uri.salam
واردسازی شبکه.شدوساکس

تابع ریشه:
    u := شدوساکس.تجزیه نشانی("ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpzZWNyZXQ@203.0.113.5:8388/?plugin=obfs-local%3Bobfs%3Dtls%3Bobfs-host%3Dcdn.example.com#my%20server")
    سرچاپ u.معتبر، u.روش، u.گذرواژه، u.میزبان، u.درگاه، u.برچسب
    سرچاپ u.افزونه

    p := شدوساکس.تجزیه افزونه(u.افزونه)
    سرچاپ p.نام، شدوساکس.گرفتن گزینه افزونه(p، "obfs"، "")، شدوساکس.گزینه افزونه موجود است(p، "obfs-host")، شدوساکس.گزینه افزونه موجود است(p، "missing")
    شدوساکس.آزادسازی افزونه(p)

    cfg := شدوساکس.تبدیل به پیکربندی(u)
    سرچاپ cfg.میزبان، cfg.درگاه، cfg.روش، cfg.پوشش، cfg.میزبان پوشش

    سرچاپ شدوساکس.قالب بندی نشانی(u)
    bad := شدوساکس.تجزیه نشانی("ss://not-a-link")
    سرچاپ bad.معتبر
پایان
خروجیtrue chacha20-ietf-poly1305 secret 203.0.113.5 8388 my server obfs-local;obfs=tls;obfs-host=cdn.example.com obfs-local tls true false 203.0.113.5 8388 chacha20-ietf-poly1305 tls cdn.example.com ss://Y2hhY2hhMjAtaWV0Zi1wb2x5MTMwNTpzZWNyZXQ@203.0.113.5:8388/?plugin=obfs-local%3Bobfs%3Dtls%3Bobfs-host%3Dcdn.example.com#my%20server false

simple-obfs

simple-obfs بایت‌های اول اتصال شدوساکس را در چیزی شبیه ترافیک عادی وب پنهان می‌کند و در برابر فیلترهایی که اتصال را از روی بسته‌ی اولش دسته‌بندی می‌کنند کمک می‌کند. در پیکربندی کارخواه پوشش را "http" یا "tls" بگذارید، میزبان پوشش را نام میزبانی که باید نشان داده شود (سرآیند Host یا نام سرور TLS، پیش‌فرض www.bing.com) و سرور را با گوش دادن با پوشش و همان حالت شروع کنید. دو طرف باید هماهنگ باشند: سروری بدون پوشش کارخواه پوشش‌دار را نمی‌فهمد و برعکس.

  • http: بسته‌ی اول کارخواه به شکل یک درخواست HTTP با سرآیند ارتقا به WebSocket فرستاده می‌شود، سرور با 101 Switching Protocols جواب می‌دهد و از آن پس داده همان‌طور که هست رد می‌شود.
  • tls: بسته‌ی اول کارخواه یک ClientHello جعلی TLS است که داده را در افزونه‌ی بلیت نشست و نام سروری که انتخاب کرده‌اید می‌برد، سرور با یک ServerHello جعلی جواب می‌دهد و بقیه در رکوردهای داده‌ی برنامه‌ی TLS پیچیده می‌شود.

این استتار است نه رمزگذاری: رمز شدوساکس زیر آن همچنان از داده محافظت می‌کند. دست‌دهی جعلی ساده است و سانسورچی مصمم می‌تواند اثر انگشتش را بگیرد؛ در برابر کاوشگر فعال هم اتصال را شبیه یک سایت واقعی نمی‌کند. حالت پوشش نام‌ها را به ثابت‌های بدون پوشش، پوشش اچ تی تی پی و پوشش تی ال اس تبدیل می‌کند و آماده سازی پوشش، پوشاندن داده، برداشتن پوشش و آزادسازی پوشش قاب‌بندی را برای کار خودتان در دسترس می‌گذارند.

net-shadowsocks-guide-obfs.salam
واردسازی حافظه
واردسازی شبکه.شدوساکس

ناپایا srv := شدوساکس.سرور {}

تابع answer(c: شدوساکس.اتصال):
    buf := حافظه.تخصیص(4096 برگردان طبیعی۶۴)
    n := شدوساکس.خواندن(c، buf، 4096)
    شدوساکس.نوشتن(c، buf، n)
    حافظه.آزادسازی(buf)
    شدوساکس.بستن(c)
پایان

تابع serve():
    شدوساکس.خدمت(srv، (c: شدوساکس.اتصال): answer(c) پایان)
پایان

تابع ریشه:
    srv = شدوساکس.گوش دادن با پوشش(0، "chacha20-ietf-poly1305"، "pw"، "http")
    t := نخ‌ساز(serve)

    cfg := شدوساکس.پیکربندی { میزبان = "127.0.0.1"، درگاه = شدوساکس.درگاه سرور(srv)، روش = "chacha20-ietf-poly1305"، گذرواژه = "pw"، پوشش = "http"، میزبان پوشش = "cdn.example.com" }
    c := شدوساکس.برقراری اتصال(cfg، "example.com"، 80)
    شدوساکس.نوشتن رشته(c، "inside an http disguise")
    سرچاپ شدوساکس.خواندن رشته(c، 4096)
    شدوساکس.بستن(c)

    شدوساکس.توقف سرور(srv)
    نخ‌پیوند(t)
    شدوساکس.نابودی سرور(srv)
پایان
خروجیinside an http disguise

رله‌ی UDP

شدوساکس UDP را هم می‌برد، برای DNS و بازی، هر بار یک دیتاگرام رمزشده: بسته یک نمک تصادفی، نشانی مقصد و محتوا را دارد که یک‌جا مهر می‌شوند. گوش دادن یو دی پی رله‌ای را روی یک درگاه UDP راه می‌اندازد؛ خدمت یو دی پی تا صدا زدن توقف یو دی پی حلقه می‌زند و گام یو دی پی یک بسته را رسیدگی می‌کند و اگر کاری کرد ۱ برمی‌گرداند تا خودتان آن را براند. رله برای هر کارخواه یک سوکت خروجی نگه می‌دارد و کارخواه را پس از ۶۰ ثانیه سکوت فراموش می‌کند. در سمت کارخواه اتصال یو دی پی یک کلاینت یو دی پی می‌سازد، ارسال یو دی پی محتوایی را از راه رله به مقصدی می‌فرستد و دریافت یو دی پی پاسخ بعدی و فرستنده‌اش را می‌دهد؛ مهلت یو دی پی انتظار را محدود می‌کند. UDP با سه رمز ۲۰۲۲ هم کار می‌کند (SIP022): کارخواه یک شناسه‌ی نشست تصادفی برمی‌گزیند، بسته‌هایش را شماره می‌زند و ۱۶ بایت نخست هر دیتاگرام همان سرآیند است که جدا رمز می‌شود (AES-ECB برای روش‌های AES و یک نانس XChaCha20-Poly1305 برای ChaCha). بسته‌ها زمان‌مهر دارند که باید در ۳۰ ثانیه باشد و رله هر شناسه‌ی بسته‌ای را که در پنجره‌ی ۶۴ بسته‌ای دیده باشد کنار می‌گذارد. روش‌های کلاسیک در رله فیلتر نمک دارند، پس دیتاگرام ضبط‌شده یک بار پاسخ می‌گیرد. مقصد UDP باید IPv4 یا نام دامنه باشد.

net-shadowsocks-guide-udp.salam
واردسازی حافظه
واردسازی رشته
واردسازی شبکه.یو دی پی
واردسازی شبکه.شدوساکس

ناپایا echo_sock := یو دی پی.سوکت یو دی پی {}
ناپایا relay := شدوساکس.سرور یو دی پی {}

تابع echo():
    buf := حافظه.تخصیص(2000 برگردان طبیعی۶۴)
    ناپایا host := ""
    ناپایا port := 0
    n := یو دی پی.دریافت بایت(echo_sock، buf، 2000، host، port)
    یو دی پی.ارسال بایت(echo_sock، host، port، buf، n)
    حافظه.آزادسازی(buf)
پایان

تابع serve():
    شدوساکس.خدمت یو دی پی(relay)
پایان

تابع ریشه:
    echo_sock = یو دی پی.پیوند(0)
    relay = شدوساکس.گوش دادن یو دی پی(0، "chacha20-ietf-poly1305"، "udp password")
    te := نخ‌ساز(echo)
    ts := نخ‌ساز(serve)

    cfg := شدوساکس.پیکربندی { میزبان = "127.0.0.1"، درگاه = شدوساکس.درگاه سرور یو دی پی(relay)، روش = "chacha20-ietf-poly1305"، گذرواژه = "udp password" }
    c := شدوساکس.اتصال یو دی پی(cfg)
    شدوساکس.مهلت یو دی پی(c، 3000)
    شدوساکس.ارسال یو دی پی(c، "127.0.0.1"، یو دی پی.درگاه(echo_sock)، "ping" برگردان تهی*، 4)

    buf := حافظه.تخصیص صفرشده(2000 برگردان طبیعی۶۴)
    ناپایا from := شدوساکس.مقصد {}
    n := شدوساکس.دریافت یو دی پی(c، buf، 1999، from)
    سرچاپ رشته.زیررشته(buf برگردان رشته، 0، n)، from.میزبان، from.درگاه برابر یو دی پی.درگاه(echo_sock)

    حافظه.آزادسازی(buf)
    نخ‌پیوند(te)
    شدوساکس.توقف یو دی پی(relay)
    نخ‌پیوند(ts)
    شدوساکس.بستن یو دی پی(c)
    شدوساکس.نابودی یو دی پی(relay)
    یو دی پی.بستن(echo_sock)
پایان
خروجیping 127.0.0.1 true

چند کاربر روی یک سرور ۲۰۲۲

یک سرور ۲۰۲۲ با AES می‌تواند به چند کاربر سرویس دهد و هر کدام کلید خودشان را دارند. کلید خود سرور را گذرواژه بدهید و برای هر کلید کاربر یک بار افزودن کاربر (برای UDP افزودن کاربر یو دی پی) را صدا بزنید. کارخواه با گذرواژه‌ی کلیدسرور:کلیدکاربر وصل می‌شود: یک سرآیند هویت می‌فرستد که کاربرش را بدون فاش کردن کلید نام می‌برد و سرور کلید همان کاربر را برای نشست برمی‌دارد. زنجیره از، مهر سرآیند هویت و گشودن سرآیند هویت قطعه‌های زیرین‌اند. روش ChaCha ۲۰۲۲ سرآیند هویت ندارد و یک کلید می‌گیرد. گوش دادن روی نشانی و گوش دادن یو دی پی روی نشانی به جای همه‌ی رابط‌ها فقط به یک نشانی، مثلاً 127.0.0.1، می‌بندند. وقتی دست‌دهی شکست می‌خورد سرور سوکت را ۱٫۵ تا ۴٫۵ ثانیه‌ی تصادفی باز نگه می‌دارد و آنچه فرستاده می‌شود را می‌خواند، پس کاوشگر نمی‌تواند رد شدن را از کندی سرور تشخیص دهد. رله نیم‌بستن (half-close) را در هر دو جهت می‌رساند: وقتی یک سو فرستادن را تمام کند سوی دیگر آگاه می‌شود و باز می‌تواند پاسخ دهد.

اجرا روی tunnel.Stream

کارخواه معمولاً با TCP به سرورش وصل می‌شود، ولی اتصال روی جریان هر tunnel.Stream را می‌پذیرد: یک WebSocket، یک اتصال TLS، خروجی یک گام پراکسی دیگر یا جریانی که خودتان ساخته‌اید. سمت سرور پذیرش روی جریان را دارد. در هر دو حالت لایه‌ی شدوساکس جریان را همان سیم می‌داند، پس می‌توانید شدوساکس را درون یکی از حالت‌های انتقال شبکه یا پشت یک زنجیره‌ی پراکسی از تونل بگذارید. به عنوان جریان برعکسش است: یک اتصال را به tunnel.Stream تبدیل می‌کند تا اتصال شدوساکس را بتوان به هر چیزی که جریان می‌گیرد داد، مثل خروجی یک مسیریاب یا لایه‌ی پروتکل دیگر.

net-shadowsocks-guide-over-stream.salam
واردسازی حافظه
واردسازی همگام سازی
واردسازی شبکه.تی سی پی
واردسازی شبکه.تونل
واردسازی شبکه.شدوساکس

ناپایا port := 0
ناپایا ready := همگام سازی.گروه انتظار جدید()

تابع server():
    carrier := تی سی پی.پیوند(0)
    port = تی سی پی.درگاه(carrier)
    srv := شدوساکس.گوش دادن(0، "aes-128-gcm"، "inner")
    همگام سازی.اتمام(ready)
    raw := تی سی پی.پذیرش(carrier)
    c := شدوساکس.پذیرش روی جریان(srv، تونل.جریان تی سی پی { اتصال = raw })
    اگر شدوساکس.معتبر(c):
        buf := حافظه.تخصیص(4096 برگردان طبیعی۶۴)
        n := شدوساکس.خواندن(c، buf، 4096)
        شدوساکس.نوشتن(c، buf، n)
        حافظه.آزادسازی(buf)
        شدوساکس.بستن(c)
    پایان
    شدوساکس.نابودی سرور(srv)
    تی سی پی.بستن سرور(carrier)
پایان

تابع ریشه:
    همگام سازی.افزودن(ready، 1 برگردان صحیح۶۴)
    t := نخ‌ساز(server)
    همگام سازی.انتظار(ready)

    link := تونل.جریان تی سی پی { اتصال = تی سی پی.شماره گیری("127.0.0.1"، port) }
    cfg := شدوساکس.پیکربندی { روش = "aes-128-gcm"، گذرواژه = "inner" }
    c := شدوساکس.اتصال روی جریان(link، cfg، "example.com"، 443)
    شدوساکس.نوشتن رشته(c، "any stream will do")
    سرچاپ شدوساکس.خواندن رشته(c، 4096)

    s := شدوساکس.به عنوان جریان(c)
    سرچاپ s.معتبر()
    شدوساکس.بستن(c)
    نخ‌پیوند(t)
پایان
خروجیany stream will do true

لایه‌ی قاب‌بندی

لایه‌ی پایین بسته عمومی است. یک رمزگذار جریان بایت را به تکه‌های AEAD با پیشوند طول مهر می‌کند (اول ارسال نمک، بعد رمزگذاری جریان)؛ یک رمزگشا بایت‌ها را هر وقت رسیدند با خوراندن می‌گیرد و متن ساده را با تکه بعدی یا یک‌جا با رمزگشایی همه می‌دهد. رمزگذاری مقصد و تجزیه مقصد سرآیند نشانی را می‌نویسند و می‌خوانند (نوع آدرس آی پی۴، نوع آدرس دامنه، نوع آدرس آی پی۶) و بسته بندی یو دی پی و بازکردن یو دی پی همین کار را برای یک دیتاگرام می‌کنند. بافر بافر بایت قابل‌رشدی است که همه از آن استفاده می‌کنند: مالکش شمایید، با آزادسازی بافر آزادش کنید و مواد کلیدی را پیش از آن با پاکسازی بافر پاک کنید. پروتکل با همین‌ها و با بردارهای شناخته‌شده آزموده می‌شود، و شما هم می‌توانید با آن‌ها بخش جلویی سفارشی خودتان را بنویسید.

مثال زیر بافر در ادامه یک رفت‌وبرگشت کامل را اجرا می‌کند: یک جریان را مهر و دوباره باز می‌کند، سرآیند نشانی را می‌نویسد و می‌خواند و یک دیتاگرام UDP را بسته‌بندی و باز می‌کند.

نکته‌های کاربردی برای ایران

این‌ها توصیه‌هایی برای کسانی است که برای شبکه‌های با فیلترینگ سنگین ابزار می‌سازند. از روی نحوه‌ی کار پروتکل آمده‌اند، نه از آزمون روی یک اپراتور مشخص، و آنچه کار می‌کند ماه به ماه عوض می‌شود.

  • ChaCha20 را انتخاب کنید. مگر اینکه سر دیگر چیز دیگری بدهد، chacha20-ietf-poly1305 را به کار ببرید. با فاصله‌ی زیاد سریع‌ترین رمز اینجاست و امنیتش با AES-GCM یکی است. روش ۲۰۲۲ را فقط وقتی انتخاب کنید که سرورتان هم آن را بفهمد و بتوانید سرتاسری آزمایشش کنید؛ بهترین طراحی را دارد (ضد بازپخش، سرآیند تصدیق‌شده) ولی کمترین آزمون سازگاری را.
  • گذرواژه‌ی بلند و تصادفی بگذارید برای روش‌های کلاسیک، دست‌کم ۲۰ نویسه از یک مولد گذرواژه. گذرواژه‌ی کوتاه را می‌شود از اتصال ضبط‌شده به‌صورت آفلاین حدس زد.
  • به شدوساکس خالی تکیه نکنید. ترافیک تصادفی‌نما روی درگاهی غیرمعمول خودش نشانه است و نبودن پاسخ ضد کاوشگر شناسایی‌اش را آسان‌تر می‌کند. آن را روی درگاه ۴۴۳ و پشت انتقالی بگذارید که شبیه یک وب‌سایت است (WebSocket روی TLS با اتصال روی جریان و پذیرش روی جریان)، یا simple-obfs را با tls و نام میزبانی به کار ببرید که در آن شبکه مجاز و رایج است.
  • از مسیریاب تونل استفاده کنید. تونل قاعده‌های مسیریابی با پیش‌تنظیم ایران دارد: سایت‌های داخلی مستقیم می‌روند و بقیه از پراکسی، پس شبکه‌ی محلی کند نمی‌شود و سایت‌های داخلی نشانی خارجی نمی‌بینند. از یک پیکربندی یک خروجی شدوساکس بسازید، آن را هر جا شماره‌گیر جریان می‌خواهد با به عنوان جریان بپیچید و بگذارید مسیریاب انتخاب کند. برای ورودی محلی SOCKS یا HTTP به ساکس و پراکسی اچ‌تی‌تی‌پی نگاه کنید.
  • نام‌ها را از راه دور حل کنید. نام میزبان را به برقراری اتصال بدهید و بگذارید سرور حلش کند؛ اول به‌صورت محلی حلش نکنید وگرنه جستجو نشت می‌کند. وقتی جستجوی محلی ناگزیر است، DoH آن را روی HTTPS می‌فرستد.
  • اشتراک‌گذاری را امن نگه دارید. پیوند گذرواژه را جز base64 بی‌پوشش می‌برد: از کانال خصوصی بفرستید و سرورهایی را که می‌خواهید زنده بمانند منتشر نکنید.

گونه‌ها

فیلتر نمک SaltFilter

ساختار فیلتر نمک
فیلتر بازپخش: نمک اتصال‌های اخیر را در دو نسل به یاد می‌سپارد تا حافظه محدود بماند. امن برای نخ‌هاست.
نامانگلیسیگونهتوضیح
نسل جاریcurنگاشت<رشته، منطقی>نسل جاری نمک‌های دیده‌شده.
نسل پیشینoldنگاشت<رشته، منطقی>نسل پیشین که با پر شدن نسل جاری دور ریخته می‌شود.
ظرفیتcapصحیح = 0هر نسل چند نمک نگه می‌دارد.
قفلlockهمگام سازی.قفلقفلی که از هر دو نسل نگهبانی می‌کند.
net-shadowsocks-SaltFilter.salam
// زبان: فارسی
واردسازی شبکه.شدوساکس

تابع ریشه:
    ناپایا f := شدوساکس.فیلتر نمک جدید(1000)
    a := "salt number one, 32 bytes long.."
    b := "salt number two, 32 bytes long.."
    سرچاپ f.ظرفیت، شدوساکس.نمک دیده شده(f، a برگردان تهی*، 32)
    سرچاپ شدوساکس.بررسی فیلتر(f، a برگردان تهی*، 32)، شدوساکس.نمک دیده شده(f، a برگردان تهی*، 32)
    سرچاپ شدوساکس.بررسی فیلتر(f، a برگردان تهی*، 32)، شدوساکس.بررسی فیلتر(f، b برگردان تهی*، 32)
    سرچاپ f.نسل جاری.اندازه()، f.نسل پیشین.اندازه()
    شدوساکس.آزادسازی فیلتر(f)
پایان
خروجی1000 false true true false true 2 0

زنجیره کلید KeyChain

ساختار زنجیره کلید
کلیدهای یک گذرواژه‌ی ۲۰۲۲ که به شکل serverkey:userkey نوشته شده، جدا و رمزگشایی‌شده در یک بافر از کلیدهای هم‌اندازه.
نامانگلیسیگونهتوضیح
کلیدهاkeysبافرهمه‌ی کلیدها پشت سر هم، هر کدام key_len بایت.
تعدادcountصحیح = 0چند کلید هست.
طول کلیدkey_lenصحیح = 0طول یک کلید به بایت.
معتبرokمنطقی = نادرستاگر روش سرآیند هویت نداشته باشد یا بخشی از گذرواژه کلید معتبر نباشد نادرست است.
net-shadowsocks-Identity.salam
// زبان: فارسی
واردسازی حافظه
واردسازی شبکه.شدوساکس

تابع ریشه:
    سرچاپ شدوساکس.طول سرآیند هویت، شدوساکس.زمینه هویت

    m := شدوساکس.یافتن روش("2022-blake3-aes-128-gcm")
    ناپایا chain := شدوساکس.زنجیره از(m، "AAECAwQFBgcICQoLDA0ODw==:EBESExQVFhcYGRobHB0eHw==")
    سرچاپ chain.معتبر، chain.تعداد، chain.طول کلید، chain.کلیدها.طول
    سرچاپ شدوساکس.بافر به هگز(شدوساکس.بافر { اشاره گر = شدوساکس.کلید زنجیره(chain، 1)، طول = 16، ظرفیت = 16 })
    bad := شدوساکس.زنجیره از(m، "not a key")
    سرچاپ bad.معتبر، bad.تعداد

    ipsk := شدوساکس.کلید زنجیره(chain، 0)
    upsk := شدوساکس.کلید زنجیره(chain، 1)
    h := حافظه.تخصیص صفرشده(16 برگردان طبیعی۶۴)
    شدوساکس.هش هویت(upsk، m.طول کلید، h)
    سرچاپ شدوساکس.هگز از(h، 16)

    salt := حافظه.تخصیص صفرشده(16 برگردان طبیعی۶۴)
    ik := حافظه.تخصیص صفرشده(16 برگردان طبیعی۶۴)
    شدوساکس.کلید هویت(ipsk، m.طول کلید، salt، m.طول نمک، ik)
    سرچاپ شدوساکس.هگز از(ik، 16)

    block := حافظه.تخصیص صفرشده(16 برگردان طبیعی۶۴)
    سرچاپ شدوساکس.مهر سرآیند هویت(ipsk، m.طول کلید، salt، m.طول نمک، upsk، block)
    سرچاپ شدوساکس.هگز از(block، 16)
    opened := حافظه.تخصیص صفرشده(16 برگردان طبیعی۶۴)
    سرچاپ شدوساکس.گشودن سرآیند هویت(ipsk، m.طول کلید، salt، m.طول نمک، block، opened)
    سرچاپ شدوساکس.هگز از(opened، 16) برابر شدوساکس.هگز از(h، 16)

    شدوساکس.آزادسازی زنجیره(chain)
    سرچاپ chain.معتبر، chain.تعداد
    حافظه.آزادسازی(h)
    حافظه.آزادسازی(salt)
    حافظه.آزادسازی(ik)
    حافظه.آزادسازی(block)
    حافظه.آزادسازی(opened)
پایان
خروجی16 shadowsocks 2022 identity subkey true 2 16 32 101112131415161718191a1b1c1d1e1f false 0 ea5ff194405ece4f55ae7a150c523884 e80f7e725b072607ae6b9ec3a0822bec true aa0134431e6e7835e63c404ab77bd547 true true false 0

پیکربندی Config

ساختار پیکربندی
چگونه به یک سرور شدوساکس برسیم: نشانی، رمز، گذرواژه و استتار اختیاری. به برقراری اتصال، اتصال روی جریان یا اتصال یو دی پی بدهید.
نامانگلیسیگونهتوضیح
میزبانhostرشته = ""نام یا نشانی میزبان سرور. اتصال روی جریان از آن استفاده نمی‌کند.
درگاهportصحیح = 0درگاه سرور. اتصال روی جریان از آن استفاده نمی‌کند.
روشmethodرشته = "aes-256-gcm"نام روش رمز. پیش‌فرض aes-256-gcm است؛ chacha20-ietf-poly1305 را ترجیح دهید.
گذرواژهpasswordرشته = ""گذرواژه؛ برای روش ۲۰۲۲ base64 کلید.
پوششobfsرشته = ""http، tls یا خالی برای بدون simple-obfs.
میزبان پوششobfs_hostرشته = "www.bing.com"نام میزبانی که استتار نشان می‌دهد. پیش‌فرض www.bing.com است.

وضعیت اتصال ConnState

ساختار وضعیت اتصال
هر چه یک اتصال لازم دارد: سوکت یا جریان زیرین، هر دو رمز، بافرها و پیشرفت دست‌دهی. فقط یک اشاره‌گر به آن را درون یک اتصال دارید.
نامانگلیسیگونهتوضیح
سوکتsockتی سی پی.اتصال شبکهسوکت TCP، وقتی اتصال روی جریان نیست.
روشmethodروشروش رمز.
کلیدkeyبافرکلید اصلی.
رمزگذارencرمزگذاررمزگذار داده‌ی ارسالی.
رمزگشاdecرمزگشارمزگشای داده‌ی دریافتی.
متن سادهplainبافربایت‌های رمزگشایی‌شده که هنوز خوانده نشده‌اند.
موقعیت متن سادهplain_posصحیح = 0چقدر از plain خوانده شده است.
خروجیoutبافربافر موقت برای بایت‌هایی که می‌خواهند فرستاده شوند.
خواندنrdتهی*بافر دریافت.
سرآیند معلقpendingبافرسرآیند نشانی که تا اولین نوشتن نگه داشته می‌شود.
مقصدtargetمقصدمقصد اتصال: خواسته‌ی کارخواه، یا آنچه سرور خوانده است.
پوششobfsپوششلایه‌ی استتار.
جریان زیرینupdyn تونل.جریانجریان زیرین، وقتی use_up درست است.
استفاده از جریان زیرینuse_upمنطقی = نادرستوقتی اتصال روی جریان است و نه سوکت درست است.
خروجی پوششobufبافربافر موقت برای خروجی استتارشده.
ورودی پوششoinبافربایت‌های خام دریافتی پیش از برداشتن استتار.
خواندن خامrd2تهی*بافر دریافت خام.
نسخه۲۰۲۲v2022منطقی = نادرستبرای روش ۲۰۲۲ درست است.
سمت سرورis_serverمنطقی = نادرستدر سمت سرور درست است.
مرحله نوشتنwphaseصحیح = 0مرحله‌ی دست‌دهی سمت نوشتن.
مرحله خواندنrphaseصحیح = 0مرحله‌ی دست‌دهی سمت خواندن.
طول نخستینfirst_lenصحیح = 0طولی که سرآیند اول ۲۰۲۲ اعلام کرد.
مقصد دریافت شدtarget_okمنطقی = نادرستپس از دریافت مقصد درست است.
موقت متغیرvtmpبافربافر موقت برای سرآیند ۲۰۲۲.
زندهliveمنطقی = نادرستتا وقتی اتصال باز است درست است.
سرآیند هویتeihبافرکلیدهای هویت یک گذرواژه‌ی serverkey:userkey، همه‌ی کلیدها جز آخرین، پشت سر هم.
تعداد سرآیند هویتeih_nصحیح = 0eih چند کلید هویت دارد.
سرآیند هویت خوانده شدeih_doneمنطقی = نادرستدر سرور، پس از باز شدن سرآیند هویت کارخواه و به کار افتادن کلید کاربرش درست می‌شود.
کاربرuserرشته = ""در سرور، نام کاربری که سرآیند هویت نام برده است؛ وگرنه خالی.

اتصال Conn

ساختار اتصال
یک اتصال شدوساکس، به‌عنوان کارخواه یا روی سرور. یک اشاره‌گر به وضعیت اتصال خودش دارد؛ با اشاره‌گر تهی اتصال قابل استفاده نیست.
نامانگلیسیگونهتوضیح
وضعیتstوضعیت اتصال*وضعیت اتصال، یا تهی وقتی ساخته نشد.

نشست یو دی پی UdpSession

ساختار نشست یو دی پی
وضعیت یک نشست UDP شدوساکس ۲۰۲۲: شناسه‌ی نشست، شمارنده‌ی بسته و پنجره‌ی ضدتکرار بسته‌های دریافتی.
نامانگلیسیگونهتوضیح
شناسه نشستsidصحیح۶۴ = 0شناسه‌ی نشست ۶۴ بیتی و تصادفی این سو.
شناسه بستهpidصحیح۶۴ = 0شماره‌ی بسته‌ی بعدی که این سو می‌فرستد.
شناسه نشست همتاpeerصحیح۶۴ = 0شناسه‌ی نشست سوی دیگر که از نخستین بسته‌ی معتبرش آموخته می‌شود؛ تا آن زمان ۰.
بالاترین شناسهtopصحیح۶۴ = 0بالاترین شماره‌ی بسته‌ای که تا کنون پذیرفته شده است.
بیت های پنجرهbitsطبیعی۶۴ = 0پنجره‌ی ضدتکرار: بیت k وقتی روشن است که بسته‌ی شماره‌ی top منهای k دیده شده باشد، در ۶۴ بسته‌ی آخر.
بسته دریافت شدanyمنطقی = نادرستپس از پذیرفتن نخستین بسته درست می‌شود تا top و bits معنا داشته باشند.
آخرین شناسه دریافتیlastصحیح۶۴ = 0شماره‌ی بسته‌ی آخرین دیتاگرامی که باز شده است.
net-shadowsocks-Udp2022.salam
// زبان: فارسی
واردسازی شبکه.شدوساکس

تابع ریشه:
    m := شدوساکس.یافتن روش("2022-blake3-aes-128-gcm")
    سرچاپ m.معتبر، m.نسخه۲۰۲۲، m.طول کلید
    ناپایا key := شدوساکس.ساخت کلید(m، "AAECAwQFBgcICQoLDA0ODw==")
    سرچاپ key.طول

    ناپایا client := شدوساکس.نشست یو دی پی جدید()
    ناپایا server := شدوساکس.نشست یو دی پی {}
    سرچاپ client.شناسه نشست نابرابر 0، server.بسته دریافت شد

    ناپایا packet := شدوساکس.بافر جدید(256)
    سرچاپ شدوساکس.بسته بندی یو دی پی نسخه جدید(m، key.اشاره گر، key.اشاره گر، شدوساکس.بافر {}، 0، client، درست، "10.0.0.7"، 53، "query" برگردان تهی*، 5، packet)، packet.طول بزرگتر 60

    ناپایا sid := 0 برگردان صحیح۶۴
    سرچاپ شدوساکس.نگاه به یو دی پی نسخه جدید(m، key.اشاره گر، packet.اشاره گر، packet.طول، sid)، sid برابر client.شناسه نشست

    ناپایا target := شدوساکس.مقصد {}
    ناپایا body := شدوساکس.بافر جدید(64)
    سرچاپ شدوساکس.بازکردن یو دی پی نسخه جدید(m، key.اشاره گر، key.اشاره گر، 0، نادرست، packet.اشاره گر، packet.طول، server، target، body)، target.میزبان، target.درگاه، شدوساکس.بافر به رشته(body)
    سرچاپ server.شناسه نشست همتا برابر client.شناسه نشست، server.آخرین شناسه دریافتی

    سرچاپ شدوساکس.پذیرش شناسه بسته(server، 5)، شدوساکس.پذیرش شناسه بسته(server، 5)، شدوساکس.پذیرش شناسه بسته(server، 3)، server.بالاترین شناسه، server.بسته دریافت شد

    ناپایا chain := شدوساکس.زنجیره از(m، "AAECAwQFBgcICQoLDA0ODw==:EBESExQVFhcYGRobHB0eHw==")
    ipsk := شدوساکس.کلید زنجیره(chain، 0)
    upsk := شدوساکس.کلید زنجیره(chain، 1)
    ناپایا multi := شدوساکس.نشست یو دی پی { شناسه نشست = 7 برگردان صحیح۶۴ }
    ناپایا wire := شدوساکس.بافر جدید(256)
    سرچاپ شدوساکس.بسته بندی یو دی پی نسخه جدید(m، upsk، ipsk، chain.کلیدها، 1، multi، درست، "10.0.0.8"، 443، "hello" برگردان تهی*، 5، wire)
    ناپایا who := شدوساکس.بافر جدید(16)
    who.طول = 16
    سرچاپ شدوساکس.هویت یو دی پی نسخه جدید(m، ipsk، wire.اشاره گر، wire.طول، who.اشاره گر)
    ناپایا expected := شدوساکس.بافر جدید(16)
    expected.طول = 16
    شدوساکس.هش هویت(upsk، m.طول کلید، expected.اشاره گر)
    سرچاپ شدوساکس.بافر به هگز(who) برابر شدوساکس.بافر به هگز(expected)
    ناپایا seen := شدوساکس.نشست یو دی پی {}
    ناپایا inner := شدوساکس.بافر جدید(64)
    سرچاپ شدوساکس.بازکردن یو دی پی نسخه جدید(m، upsk، ipsk، شدوساکس.طول سرآیند هویت، نادرست، wire.اشاره گر، wire.طول، seen، target، inner)، شدوساکس.بافر به رشته(inner)
    شدوساکس.آزادسازی بافر(wire)
    شدوساکس.آزادسازی بافر(who)
    شدوساکس.آزادسازی بافر(expected)
    شدوساکس.آزادسازی بافر(inner)
    شدوساکس.آزادسازی زنجیره(chain)

    شدوساکس.آزادسازی بافر(packet)
    شدوساکس.آزادسازی بافر(body)
    شدوساکس.پاکسازی بافر(key)
    شدوساکس.آزادسازی بافر(key)
پایان
خروجیtrue true 16 16 true false true true true true true 10.0.0.7 53 query true 0 true false true 5 true true true true true hello

افزونه Plugin

ساختار افزونه
متن افزونه‌ی تجزیه‌شده: نام آن و گزینه‌هایش به ترتیب.
نامانگلیسیگونهتوضیح
نامnameرشته = ""نام افزونه، مثل obfs-local.
کلیدهاkeysوکتور<رشته>نام گزینه‌ها.
مقدارهاvaluesوکتور<رشته>مقدار گزینه‌ها به همان ترتیب keys؛ برای گزینه‌ی بی‌مقدار خالی.

نشانی Uri

ساختار نشانی
یک پیوند ss:// تجزیه‌شده.
نامانگلیسیگونهتوضیح
روشmethodرشته = ""نام روش رمز.
گذرواژهpasswordرشته = ""گذرواژه، یا کلید base64 برای روش ۲۰۲۲.
میزبانhostرشته = ""نام یا نشانی میزبان سرور (IPv6 بدون کروشه).
درگاهportصحیح = 0درگاه سرور.
افزونهpluginرشته = ""متن خام افزونه، خالی وقتی پیوند افزونه ندارد.
برچسبtagرشته = ""نام پس از #، رمزگشایی‌شده.
معتبرokمنطقی = نادرستدرست وقتی پیوند تجزیه شد و روش را این بسته پشتیبانی می‌کند.

پوشش Obfs

ساختار پوشش
وضعیت لایه‌ی simple-obfs یک اتصال.
نامانگلیسیگونهتوضیح
حالتmodeصحیح = 0یکی از ثابت‌های OBFS_.
سمت سرورserverمنطقی = نادرستدر سمت سرور درست است.
میزبانhostرشته = ""نام میزبانی که در درخواست یا hello جعلی نشان داده می‌شود.
ارسال نخست انجام شدsent_firstمنطقی = نادرستپس از فرستادن بسته‌ی اول درست است.
دریافت نخست انجام شدgot_firstمنطقی = نادرستپس از دریافت و بررسی بسته‌ی اول درست است.
پیام آغاز دیده شدseen_helloمنطقی = نادرستپس از خواندن رکورد hello جعلی TLS درست می‌شود تا رکورد دست‌دهی بعدی آغاز داده شمرده شود.
دریافتیrxبافربایت‌های دریافتی که هنوز یک رکورد کامل نشده‌اند.
باقیمانده قابframe_leftصحیح = 0چند بایت از رکورد جاری TLS مانده است.
کلید وب سوکتws_keyرشته = ""کلید WebSocket در ارتقای جعلی HTTP.

مقصد Target

ساختار مقصد
یک مقصد: میزبان (نام یا نشانی) و درگاه.
نامانگلیسیگونهتوضیح
میزبانhostرشته = ""نام میزبان یا نشانی IP به‌صورت متن.
درگاهportصحیح = 0درگاه.
net-shadowsocks-Codec.salam
واردسازی شبکه.شدوساکس

تابع ریشه:
    m := شدوساکس.یافتن روش("chacha20-ietf-poly1305")
    ناپایا key := شدوساکس.ساخت کلید(m، "codec password")

    ناپایا enc := شدوساکس.رمزگذار جدید تصادفی(m، key.اشاره گر)
    ناپایا wire := شدوساکس.بافر جدید(256)
    شدوساکس.ارسال نمک(enc، wire)
    شدوساکس.رمزگذاری جریان(enc، "hello codec" برگردان تهی*، 11، wire)
    سرچاپ "wire bytes"، wire.طول، "salt"، m.طول نمک، "overhead"، wire.طول - 11 - m.طول نمک

    ناپایا dec := شدوساکس.رمزگشا جدید(m، key.اشاره گر)
    ناپایا plain := شدوساکس.بافر جدید(64)
    سرچاپ شدوساکس.رمزگشایی همه(dec، wire.اشاره گر، wire.طول، plain)، شدوساکس.بافر به رشته(plain)

    ناپایا head := شدوساکس.بافر جدید(64)
    سرچاپ شدوساکس.رمزگذاری مقصد("example.com"، 8443، head)، head.طول، شدوساکس.بافر به هگز(head)
    ناپایا t := شدوساکس.مقصد {}
    used := شدوساکس.تجزیه مقصد(head.اشاره گر، head.طول، t)
    سرچاپ used، t.میزبان، t.درگاه

    ناپایا packet := شدوساکس.بافر جدید(128)
    سرچاپ شدوساکس.بسته بندی یو دی پی(m، key.اشاره گر، "10.0.0.7"، 53، "query" برگردان تهی*، 5، packet)، packet.طول
    ناپایا got := شدوساکس.مقصد {}
    ناپایا body := شدوساکس.بافر جدید(64)
    سرچاپ شدوساکس.بازکردن یو دی پی(m، key.اشاره گر، packet.اشاره گر، packet.طول، got، body)، got.میزبان، got.درگاه، شدوساکس.بافر به رشته(body)

    شدوساکس.آزادسازی رمزگذار(enc)
    شدوساکس.آزادسازی رمزگشا(dec)
    شدوساکس.آزادسازی بافر(wire)
    شدوساکس.آزادسازی بافر(plain)
    شدوساکس.آزادسازی بافر(head)
    شدوساکس.آزادسازی بافر(packet)
    شدوساکس.آزادسازی بافر(body)
    شدوساکس.پاکسازی بافر(key)
    شدوساکس.آزادسازی بافر(key)
پایان
خروجیwire bytes 77 salt 32 overhead 34 true hello codec true 15 030b6578616d706c652e636f6d20fb 15 example.com 8443 true 60 true 10.0.0.7 53 query

بافر Buf

ساختار بافر
بافر بایت قابل‌رشد با حافظه‌ی خودش. باید با آزادسازی بافر آزادش کنید.
نامانگلیسیگونهتوضیح
اشاره گرpتهی*ابتدای حافظه.
طولlenصحیح = 0چند بایت در حال استفاده است.
ظرفیتcapصحیح = 0چند بایت تخصیص داده شده است.
خرابbadمنطقی = نادرستپس از شکست تخصیص یا خطای تجزیه درست است؛ دیگر نباید به بافر اعتماد کرد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

رمزگذار Encoder

ساختار رمزگذار
جریان بایت را به تکه‌های AEAD شدوساکس مهر می‌کند. کلید نشست، شمارنده‌ی nonce و اینکه نمک رفته است یا نه را نگه می‌دارد.
نامانگلیسیگونهتوضیح
روشmethodروشروش رمز.
زمینهctxتهی*زمینه‌ی AEAD که کلید نشست را دارد.
نانسnonceتهی*شمارنده‌ی ۱۲ بایتی که nonce است و با هر تکه‌ی مهرشده بالا می‌رود.
نمکsaltبافرنمک تصادفی این جهت.
نمک فرستاده شدsalt_sentمنطقی = نادرستپس از فرستادن نمک درست است.
بیشینه تکهmax_chunkصحیح = 16383بزرگ‌ترین محتوای یک تکه: ۱۶۳۸۳ بایت، یا ۶۵۵۳۵ برای روش‌های ۲۰۲۲.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

رمزگشا Decoder

ساختار رمزگشا
جریان AEAD شدوساکس را در تکه‌هایی با هر اندازه می‌خواند و متن ساده را می‌دهد. تکه‌های ناقص را بافر می‌کند.
نامانگلیسیگونهتوضیح
روشmethodروشروش رمز.
کلید اصلیmasterتهی*کلید اصلی که کلید نشست از آن مشتق می‌شود.
زمینهctxتهی*زمینه‌ی AEAD که با رسیدن نمک ساخته می‌شود.
نانسnonceتهی*شمارنده‌ی ۱۲ بایتی که nonce است.
نمکsaltبافرنمکی که از ابتدای جریان خوانده شد.
نمک دریافت شدhave_saltمنطقی = نادرستپس از خواندن نمک درست است.
ورودیinbبافربایت‌های دریافتی که هنوز استفاده نشده‌اند.
جابجاییoffصحیح = 0جابه‌جایی خواندن در inb.
نیازneedصحیح = -1تکه‌ی بعدی چند بایت لازم دارد، یا ۱- وقتی هنوز معلوم نیست.
موقتtmpبافربافر موقت برای فیلد طول.
خرابbadمنطقی = نادرستپس از شکست تصدیق درست است؛ جریان دیگر قابل استفاده نیست.
بیشینه تکهmax_chunkصحیح = 16383بزرگ‌ترین اندازه‌ی تکه‌ی پذیرفته‌شده.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

وضعیت سرور ServerState

ساختار وضعیت سرور
وضعیت یک سرور در حال اجرا: سوکت شنونده، رمز و کلید، فیلتر بازپخش و استخر کارگرها. آن را درون یک سرور می‌گیرید و فقط دست‌به‌دستش می‌کنید.
نامانگلیسیگونهتوضیح
شنوندهlsتی سی پی.سرورسوکت TCP شنونده.
میزبان شنودhostرشته = ""نشانی‌ای که سرور روی آن گوش می‌دهد؛ خالی یعنی همه‌ی رابط‌های IPv4. توقف از آن برای بیدار کردن حلقه‌ی پذیرش استفاده می‌کند.
روشmethodروشرمزی که سرور به کار می‌برد.
کلیدkeyبافرکلید اصلی، ساخته‌شده از گذرواژه.
فیلترfilterفیلتر نمکحافظه‌ی نمک که اتصال بازپخش‌شده را رد می‌کند.
کارگرهاworkersاستخر.استخر نخاستخر نخ‌هایی که دستگیره‌ی کارخواه‌ها را اجرا می‌کنند.
توقفstopصحیح۶۴*پرچمی که به خدمت می‌گوید بایستد؛ توقف سرور آن را می‌گذارد.
صف اتصال هاjobsکانال.کانال<صحیح۶۴>صف اتصال‌های پذیرفته‌شده که منتظر کارگرند.
حالت پوششobfs_modeرشته = ""حالت پوشش: http، tls یا خالی برای هیچ.
کاربرانusersنگاشت<رشته، بافر>کلید کاربرانی که با AddUser افزوده شده‌اند، به هگز چکیده‌ای که کاربر را در سرآیند هویت نام می‌برد.
نام کاربرانuser_namesنگاشت<رشته، رشته>نام همان کاربران، با همان هگز.
تعداد کاربرانuser_nصحیح = 0چند کاربر افزوده شده است.
net-shadowsocks-IPv6.salam
// زبان: فارسی
واردسازی شبکه.شدوساکس

تابع ریشه:
    server := شدوساکس.گوش دادن روی نشانی("::1"، 0، "aes-256-gcm"، "secret"، "")
    سرچاپ شدوساکس.سرور معتبر(server)، server.وضعیت.میزبان شنود
    شدوساکس.توقف سرور(server)
    شدوساکس.نابودی سرور(server)
پایان

سرور Server

ساختار سرور
یک سرور شدوساکس. یک اشاره‌گر به وضعیت سرور خودش دارد؛ مقدار صفر (st تهی) یعنی سرور راه نیفتاد.
نامانگلیسیگونهتوضیح
وضعیتstوضعیت سرور*وضعیت سرور، یا تهی وقتی گوش دادن شکست خورد.

روش Method

ساختار روش
یک روش رمز: نام، اندازه‌ی کلید و نمک و اینکه روش ۲۰۲۲ است یا نه.
نامانگلیسیگونهتوضیح
نامnameرشته = ""نام روش، با نام‌های دیگر حل‌شده.
نوعkindصحیح = 0نوع AEAD، همان‌طور که net.tls می‌نامد.
طول کلیدkey_lenصحیح = 0طول کلید به بایت، ۱۶ یا ۳۲.
طول نمکsalt_lenصحیح = 0طول نمک به بایت، ۱۶ یا ۳۲.
نسخه۲۰۲۲v2022منطقی = نادرستبرای روش‌های ۲۰۲۲ درست است.
معتبرokمنطقی = نادرستدرست وقتی نام یک روش شناخته‌شده بود.

کلاینت یو دی پی UdpClient

ساختار کلاینت یو دی پی
کارخواه UDP که با رله‌ی UDP شدوساکس حرف می‌زند.
نامانگلیسیگونهتوضیح
سوکتsockیو دی پی.سوکت یو دی پیسوکت UDP محلی.
میزبانhostرشته = ""میزبان رله.
درگاهportصحیح = 0درگاه رله.
روشmethodروشروش رمز.
کلیدkeyبافرکلید اصلی.
بافر دریافتrbufتهی*بافر دریافت.
معتبرokمنطقی = نادرستدرست وقتی کارخواه برپا شد.
نشستsessنشست یو دی پی*نشست ۲۰۲۲ این کارخواه؛ برای روش کلاسیک تهی.
سرآیند هویتeihبافرکلیدهای هویت یک گذرواژه‌ی serverkey:userkey، همه‌ی کلیدها جز آخرین، پشت سر هم.
تعداد سرآیند هویتeih_nصحیح = 0eih چند کلید هویت دارد.

سرور یو دی پی UdpServer

ساختار سرور یو دی پی
رله‌ی UDP شدوساکس با یک سوکت خروجی برای هر کارخواه.
نامانگلیسیگونهتوضیح
سوکتsockیو دی پی.سوکت یو دی پیسوکت UDP که کارخواه‌ها به آن می‌فرستند.
روشmethodروشروش رمز.
کلیدkeyبافرکلید اصلی.
بافر دریافتrbufتهی*بافر دریافت.
ارتباط هاassocنگاشت<رشته، یو دی پی.سوکت یو دی پی>سوکت خروجی هر کارخواه، با کلید نشانی کارخواه.
آخرین فعالیتseenنگاشت<رشته، صحیح۶۴>آخرین زمانی که از هر کارخواه خبری رسید، بر حسب میلی‌ثانیه.
کلاینت هاclientsنگاشت<رشته، مقصد>نشانی‌ای که هر کارخواه از آن می‌فرستد، برای پاسخ‌ها.
پرچم توقفstopcصحیح۶۴*پرچمی که خدمت یو دی پی را می‌ایستاند.
معتبرokمنطقی = نادرستدرست وقتی رله راه افتاد.
نشست هاsessنگاشت<رشته، نشست یو دی پی>نشست ۲۰۲۲ هر کارخواه، با کلید نشانی کارخواه.
کلید نشست هاskeysنگاشت<رشته، بافر>کلید کاربری که هر کارخواه با آن وارد شده، با کلید نشانی کارخواه.
کاربرانusersنگاشت<رشته، بافر>کلید کاربرانی که با UdpAddUser افزوده شده‌اند، به هگز چکیده‌ای که کاربر را در سرآیند هویت نام می‌برد.
تعداد کاربرانuser_nصحیح = 0چند کاربر افزوده شده است.
فیلترfilterفیلتر نمکحافظه‌ی نمک که دیتاگرام تکراری را رد می‌کند.

پایاها و متغیرها

زمینه هویت IDENTITY_CONTEXT

پایا زمینه هویت: رشته = "shadowsocks 2022 identity subkey"
زمینه‌ی مشتق‌گیری کلید BLAKE3 برای کلید سرآیند هویت.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Identity.salam

طول سرآیند هویت EIH_LEN

پایا طول سرآیند هویت: صحیح۳۲ = 16
طول یک بلوک سرآیند هویت به بایت: ۱۶.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Identity.salam

حالت‌های پوشش OBFS_…

simple-obfs از کدام استتار استفاده کند.
نامانگلیسیمقدار
بدون پوششOBFS_NONE0
پوشش اچ تی تی پیOBFS_HTTP1
پوشش تی ال اسOBFS_TLS2

نوع نشانی ATYP_…

نخستین بایت سرآیند نشانی: چه نوع نشانی‌ای در پی می‌آید.
نامانگلیسیمقدار
نوع آدرس آی پی۴ATYP_IPV41
نوع آدرس دامنهATYP_DOMAIN3
نوع آدرس آی پی۶ATYP_IPV64

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

بیشینه تکه MAX_CHUNK

پایا بیشینه تکه: صحیح۳۲ = 16383
بزرگ‌ترین محتوای یک تکه در جریان کلاسیک، ۱۶۳۸۳ بایت.

طول برچسب TAG_LEN

پایا طول برچسب: صحیح۳۲ = 16
طول برچسب تصدیق AEAD، ۱۶ بایت.

تابع‌ها

فیلتر نمک جدید NewSaltFilter

تابع فیلتر نمک جدید(cap: صحیح): فیلتر نمک
فیلتری می‌سازد که هر نسلش تا cap نمک (دست‌کم ۱۶) نگه می‌دارد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-SaltFilter.salam

نمک دیده شده FilterSeen

تابع نمک دیده شده(f &: فیلتر نمک، salt: تهی*، n: صحیح): منطقی
اگر نمک پیش‌تر در فیلتر باشد درست برمی‌گرداند، بی‌آنکه آن را ثبت کند. سروری که پیش از اعتماد به اتصال باید تکه‌ی نخست را احراز کند، اول همین را می‌پرسد و بررسی فیلتر را فقط وقتی صدا می‌زند که تکه درست بود، تا بسته‌ی جعلی نتواند فیلتر را پر کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-SaltFilter.salam

بررسی فیلتر FilterCheck

تابع بررسی فیلتر(f &: فیلتر نمک، salt: تهی*، n: صحیح): منطقی
یک نمک را ثبت می‌کند و اگر تازه بود درست برمی‌گرداند؛ اگر پیش‌تر دیده شده بود نادرست، و اتصال باید رد شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-SaltFilter.salam

آزادسازی فیلتر FilterFree

تابع آزادسازی فیلتر(f &: فیلتر نمک)
فیلتر را آزاد می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-SaltFilter.salam

ساخت کلید MakeKey

تابع ساخت کلید(m: روش، password: رشته): بافر
گذرواژه را به کلید اصلی یک روش تبدیل می‌کند: برای روش کلاسیک کلید مشتق‌شده، برای روش ۲۰۲۲ گذرواژه‌ی base64 رمزگشایی‌شده. اگر گذرواژه‌ی ۲۰۲۲ طول نادرست داشته باشد خراب در بافر برگشتی درست است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

زنجیره از ChainOf

تابع زنجیره از(m: روش، password: رشته): زنجیره کلید
گذرواژه‌ی ۲۰۲۲ را که به شکل serverkey:userkey نوشته شده (تا ۸ کلید base64) به یک KeyChain جدا می‌کند. برای روش کلاسیک، بیش از ۸ بخش یا بخشی که کلید با طول درست نیست ok نادرست است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Identity.salam

کلید زنجیره ChainKey

تابع کلید زنجیره(c: زنجیره کلید، i: صحیح): تهی*
اشاره‌گری به کلید شماره‌ی i زنجیره، از ۰ شروع می‌شود. آخرین کلید همان کلید کاربر است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Identity.salam

آزادسازی زنجیره ChainFree

تابع آزادسازی زنجیره(c &: زنجیره کلید)
کلیدهای زنجیره را پاک و آزاد می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Identity.salam

هش هویت IdentityHash

تابع هش هویت(psk: تهی*، klen: صحیح، out16: تهی*)
چکیده‌ی ۱۶ بایتی BLAKE3 یک کلید را می‌نویسد که کاربر را در سرآیند هویت نام می‌برد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Identity.salam

کلید هویت IdentityKey

تابع کلید هویت(ipsk: تهی*، klen: صحیح، salt: تهی*، slen: صحیح، out: تهی*)
کلیدی را که سرآیند هویت را مهر می‌کند مشتق می‌گیرد: مشتق‌گیری کلید BLAKE3 با IDENTITY_CONTEXT روی کلید هویت و پس از آن نمک. klen بایت می‌نویسد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Identity.salam

مهر سرآیند هویت EihSeal

تابع مهر سرآیند هویت(ipsk: تهی*، klen: صحیح، salt: تهی*، slen: صحیح، next_psk: تهی*، out16: تهی*): منطقی
یک بلوک سرآیند هویت می‌سازد: چکیده‌ی کلید بعدی زنجیره که با AES زیر کلید IdentityKey رمز شده است. ۱۶ بایت می‌نویسد. برای طول کلید بد نادرست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Identity.salam

گشودن سرآیند هویت EihOpen

تابع گشودن سرآیند هویت(ipsk: تهی*، klen: صحیح، salt: تهی*، slen: صحیح، block16: تهی*، out_hash16: تهی*): منطقی
وارونه‌ی EihSeal: یک بلوک را رمزگشایی می‌کند و چکیده‌ی ۱۶ بایتی کلید بعدی را می‌نویسد. برای طول کلید بد نادرست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Identity.salam

معتبر Ok

تابع معتبر(c: اتصال): منطقی
می‌گوید اتصال ساخته شد یا نه. پس از برقراری اتصال فقط یعنی برپایی و اتصال TCP کار کرد، نه اینکه سرور گذرواژه را پذیرفته است.

مقصد اتصال TargetOf

تابع مقصد اتصال(c: اتصال): مقصد
مقصد یک اتصال: روی سرور، میزبان و درگاهی که کارخواه خواسته است.

نوشتن Write

تابع نوشتن(c: اتصال، data: تهی*، n: صحیح): صحیح
بایت‌ها را رمز می‌کند و می‌فرستد. تعداد فرستاده‌شده یا ۱- در شکست برمی‌گرداند. روی اتصال تازه‌ی کارخواه، اولین نوشتن نشانی مقصد را هم می‌برد.

نوشتن رشته WriteStr

تابع نوشتن رشته(c: اتصال، s: رشته): صحیح
یک رشته می‌فرستد. همان نوشتن با طول رشته.

خواندن Read

تابع خواندن(c: اتصال، buf: تهی*، max: صحیح): صحیح
منتظر داده می‌ماند و تا max بایت را در بافر کپی می‌کند. طول را برمی‌گرداند، ۰ وقتی طرف مقابل بست و عدد منفی در خطا یا شکست تصدیق.

خواندن رشته ReadStr

تابع خواندن رشته(c: اتصال، max: صحیح): رشته
تا max بایت را به‌صورت رشته می‌خواند؛ در پایان یا خطا خالی. داده‌ی دودویی بایت صفر دارد که رشته را کوتاه می‌کند، پس برای آن خواندن را به کار ببرید.

بستن Close

تابع بستن(c: اتصال)
اتصال را می‌بندد و وضعیتش را آزاد می‌کند. استفاده از اتصال پس از آن خطاست.

قطع Shutdown

تابع قطع(c: اتصال)
اتصال را بی‌آنکه آزاد کند قطع می‌کند و نخی را که روی خواندن مانده بیدار می‌کند.

برقراری اتصال Dial

تابع برقراری اتصال(cfg: پیکربندی، target_host: رشته، target_port: صحیح): اتصال
به یک سرور شدوساکس وصل می‌شود و از آن می‌خواهد به میزبان و درگاه یک مقصد برسد. میزبان می‌تواند نام باشد؛ سرور حلش می‌کند. بی‌درنگ برمی‌گردد و مقصد همراه اولین نوشتن فرستاده می‌شود.

اتصال روی جریان DialOver

تابع اتصال روی جریان(s: dyn تونل.جریان، cfg: پیکربندی، target_host: رشته، target_port: صحیح): اتصال
مثل برقراری اتصال ولی به‌جای باز کردن اتصال TCP روی جریانی که می‌دهید اجرا می‌شود. host و port پیکربندی نادیده گرفته می‌شوند.

به عنوان جریان AsStream

تابع به عنوان جریان(c: اتصال): dyn تونل.جریان
یک اتصال را به‌صورت tunnel.Stream می‌پیچد تا هر کدی که جریان می‌گیرد بتواند از آن استفاده کند.

نشست یو دی پی جدید NewUdpSession

تابع نشست یو دی پی جدید(): نشست یو دی پی
یک نشست با شناسه‌ی نشست ۶۴ بیتی تصادفی می‌سازد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Udp2022.salam

پذیرش شناسه بسته SessionAccept

تابع پذیرش شناسه بسته(s &: نشست یو دی پی، pid: صحیح۶۴): منطقی
شماره‌ی بسته‌ی یک دیتاگرام دریافتی را با پنجره‌ی ضدتکرار نشست می‌سنجد. اگر شماره تازه باشد و بیش از ۶۳ تا از بالاترین عقب نباشد درست برمی‌گرداند و آن را ثبت می‌کند؛ برای تکراری یا خیلی کهنه نادرست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Udp2022.salam

بسته بندی یو دی پی نسخه جدید PackUdp2022

تابع بسته بندی یو دی پی نسخه جدید(m: روش، ukey: تهی*، hdr_key: تهی*، eih: بافر، eih_n: صحیح، s &: نشست یو دی پی، client: منطقی، host: رشته، port: صحیح، data: تهی*، n: صحیح، out &: بافر): منطقی
یک دیتاگرام شدوساکس ۲۰۲۲ می‌سازد و به بافر می‌افزاید: سرآیند رمزشده با شناسه‌ی نشست و شماره‌ی بسته، بلوک‌های سرآیند هویت برای گذرواژه‌ی چندکاربره، سپس بدنه‌ی مهرشده با زمان، مقصد و محتوا. ukey کلید کاربر و hdr_key کلید بلوک سرآیند است؛ برای یک کلید هر دو همان کلیدند و با کلیدهای هویت نخستین آن‌ها. client می‌گوید کدام سو می‌فرستد. برای روش کلاسیک یا مقصد بد نادرست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Udp2022.salam

نگاه به یو دی پی نسخه جدید Udp2022Peek

تابع نگاه به یو دی پی نسخه جدید(m: روش، hdr_key: تهی*، p: تهی*، n: صحیح، sid &: صحیح۶۴): منطقی
شناسه‌ی نشست را از سرآیند یک دیتاگرام می‌خواند بی‌آنکه بدنه را باز کند، تا رله بتواند نخست نشست را پیدا کند. فقط برای روش‌های AES نسخه‌ی ۲۰۲۲ کار می‌کند؛ برای ChaCha یا بسته‌ی کوتاه نادرست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Udp2022.salam

بازکردن یو دی پی نسخه جدید UnpackUdp2022

تابع بازکردن یو دی پی نسخه جدید(m: روش، ukey: تهی*، hdr_key: تهی*، skip: صحیح، client: منطقی، p: تهی*، n: صحیح، s &: نشست یو دی پی، t &: مقصد، out &: بافر): منطقی
یک دیتاگرام ۲۰۲۲ را باز می‌کند: سرآیند و برچسب، زمان (تا ۳۰ ثانیه) و سو را می‌سنجد، مقصد را پر می‌کند و محتوا را به بافر می‌افزاید. skip شمار بایت‌های سرآیند هویت میان سرآیند و بدنه است. در سمت کارخواه بسته‌های تکراری را هم با نشست رد می‌کند. اگر چیزی نادرست باشد نادرست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Udp2022.salam

هویت یو دی پی نسخه جدید Udp2022Identity

تابع هویت یو دی پی نسخه جدید(m: روش، ipsk: تهی*، p: تهی*، n: صحیح، out_hash16: تهی*): منطقی
بلوک سرآیند هویت یک دیتاگرام را با کلید هویت سرور باز می‌کند و چکیده‌ی ۱۶ بایتی کلید کاربری را که نام می‌برد می‌نویسد. فقط برای روش‌های AES نسخه‌ی ۲۰۲۲؛ برای ChaCha یا بسته‌ی کوتاه نادرست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Udp2022.salam

تجزیه نشانی ParseUri

تابع تجزیه نشانی(text: رشته): نشانی
پیوند ss:// را در شکل SIP002، شکل اطلاعات کاربر با متن ساده یا شکل قدیمی همه‌چیز base64 می‌خواند. برای ورودی بد ok نتیجه نادرست است.

قالب بندی نشانی FormatUri

تابع قالب بندی نشانی(u: نشانی): رشته
یک نشانی را به‌صورت پیوند ss:// می‌نویسد، با افزونه و برچسب وقتی تنظیم شده‌اند.

تجزیه افزونه ParsePlugin

تابع تجزیه افزونه(text: رشته): افزونه
متن افزونه‌ای مثل obfs-local;obfs=tls;obfs-host=a.com را به نام و گزینه می‌شکند. نتیجه را با آزادسازی افزونه آزاد کنید.

گرفتن گزینه افزونه PluginGet

تابع گرفتن گزینه افزونه(p: افزونه، key: رشته، fallback: رشته): رشته
مقدار یک گزینه، یا مقدار پیش‌فرض وقتی گزینه نیست.

گزینه افزونه موجود است PluginHas

تابع گزینه افزونه موجود است(p: افزونه، key: رشته): منطقی
می‌گوید گزینه‌ای هست یا نه.

آزادسازی افزونه PluginFree

تابع آزادسازی افزونه(p: افزونه)
بردارهای یک افزونه را آزاد می‌کند.

تبدیل به پیکربندی ToConfig

تابع تبدیل به پیکربندی(u: نشانی): پیکربندی
از یک نشانی یک پیکربندی می‌سازد و گزینه‌های simple-obfs افزونه‌اش را اعمال می‌کند.

پوشاندن داده ObfsWrap

تابع پوشاندن داده(o &: پوشش، p: تهی*، n: صحیح، out &: بافر)
بایت‌های خروجی را در استتار می‌پیچد (درخواست یا hello جعلی برای بسته‌ی اول، سپس رکوردهای TLS) و نتیجه را به بافر می‌افزاید.

برداشتن پوشش ObfsUnwrap

تابع برداشتن پوشش(o &: پوشش، p: تهی*، n: صحیح، out &: بافر): صحیح
استتار را از بایت‌های ورودی برمی‌دارد و محتوا را به بافر می‌افزاید. تعداد بایت‌های مصرف‌شده را برمی‌گرداند، ۰ وقتی بایت بیشتری لازم است و عدد منفی وقتی داده استتار معتبری نیست.

آماده سازی پوشش ObfsInit

تابع آماده سازی پوشش(mode: صحیح، server: منطقی، host: رشته): پوشش
وضعیت یک حالت را برای سمت کارخواه یا سرور، با نام میزبانی که باید نشان داده شود، می‌سازد.

آزادسازی پوشش ObfsFree

تابع آزادسازی پوشش(o &: پوشش)
یک پوشش را آزاد می‌کند.

حالت پوشش ObfsMode

تابع حالت پوشش(name: رشته): صحیح
http یا tls را به ثابت OBFS_ تبدیل می‌کند؛ هر چیز دیگر بدون پوشش می‌دهد.

رمزگذاری مقصد EncodeTarget

تابع رمزگذاری مقصد(host: رشته، port: صحیح، out &: بافر): منطقی
سرآیند نشانی یک میزبان و درگاه را به بافر می‌افزاید. میزبانی که شبیه نشانی IPv4 یا IPv6 باشد همان‌طور فرستاده می‌شود و بقیه به‌صورت نام تا ۲۵۵ بایت. برای درگاه یا نام بد نادرست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

تجزیه مقصد ParseTarget

تابع تجزیه مقصد(p: تهی*، n: صحیح، t &: مقصد): صحیح
سرآیند نشانی را از بایت‌ها در یک مقصد می‌خواند. تعداد بایت‌هایی را که سرآیند گرفت برمی‌گرداند، یا ۰ وقتی بایت‌ها کم یا نامعتبرند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

بافر در BufAt

تابع بافر در(b: بافر، off: صحیح): تهی*
اشاره‌گر به بایت در یک جابه‌جایی از بافر.

اشاره گر در PtrAt

تابع اشاره گر در(p: تهی*، off: صحیح): تهی*
اشاره‌گری که چند بایت پس از اشاره‌گر دیگر است.

بافر جدید NewBuf

تابع بافر جدید(cap0: صحیح): بافر
بافر خالی می‌سازد با جا برای دست‌کم آن تعداد بایت (هرگز کمتر از ۶۴).

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

آزادسازی بافر BufFree

تابع آزادسازی بافر(b &: بافر)
حافظه‌ی بافر را آزاد می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

پاکسازی بافر BufWipe

تابع پاکسازی بافر(b &: بافر)
کل تخصیص را با صفر بازنویسی می‌کند و طول را ۰ می‌گذارد. پیش از آزاد کردن کلیدها به کار ببرید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

رزرو بافر BufReserve

تابع رزرو بافر(b &: بافر، extra: صحیح)
برای آن تعداد بایت بیشتر جا باز می‌کند و در صورت نیاز بافر را بزرگ می‌کند.

افزودن به بافر BufAppend

تابع افزودن به بافر(b &: بافر، src: تهی*، n: صحیح)
بایت‌هایی را از حافظه می‌افزاید.

افزودن بایت به بافر BufAppendByte

تابع افزودن بایت به بافر(b &: بافر، v: صحیح)
یک بایت می‌افزاید (۸ بیت پایین عدد).

افزودن رشته به بافر BufAppendStr

تابع افزودن رشته به بافر(b &: بافر، s: رشته)
بایت‌های یک رشته را می‌افزاید.

مصرف بافر BufConsume

تابع مصرف بافر(b &: بافر، n: صحیح)
بایت‌ها را از ابتدای بافر برمی‌دارد و بقیه را پایین می‌آورد.

بافر به رشته BufToStr

تابع بافر به رشته(b: بافر): رشته
بافر را در یک رشته‌ی تازه کپی می‌کند. نتیجه در بایت صفر قطع می‌شود، پس فقط برای متن.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

بافر به هگز BufToHex

تابع بافر به هگز(b: بافر): رشته
بافر به‌صورت متن هگزادسیمال با حروف کوچک.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

هگز از HexOf

تابع هگز از(p: تهی*، n: صحیح): رشته
متن هگزادسیمال با حروف کوچک از بایت‌های حافظه.

بافر از هگز BufFromHex

تابع بافر از هگز(hex: رشته): بافر
متن هگزادسیمال را در یک بافر تازه می‌خواند؛ اگر متن هگز درست نباشد خراب گذاشته می‌شود.

رمزگذار جدید NewEncoder

تابع رمزگذار جدید(m: روش، master: تهی*، salt: تهی*): رمزگذار
رمزگذاری با یک نمک مشخص می‌سازد.

رمزگذار جدید تصادفی NewEncoderRandom

تابع رمزگذار جدید تصادفی(m: روش، master: تهی*): رمزگذار
رمزگذاری با یک نمک تصادفی تازه می‌سازد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

آزادسازی رمزگذار EncoderFree

تابع آزادسازی رمزگذار(e &: رمزگذار)
رمزگذار و مواد کلیدی‌اش را آزاد می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

مهر قاب SealFrame

تابع مهر قاب(e &: رمزگذار، pt: تهی*، n: صحیح، out &: بافر)
یک تکه داده را با AEAD مهر می‌کند و متن رمز و برچسب را به بافر می‌افزاید.

ارسال نمک EmitSalt

تابع ارسال نمک(e &: رمزگذار، out &: بافر)
نمک را یک بار، در آغاز اتصال، به بافر می‌افزاید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

رمزگذاری جریان EncodeStream

تابع رمزگذاری جریان(e &: رمزگذار، data: تهی*، n: صحیح، out &: بافر)
داده را به‌صورت تکه‌های رمزشده با پیشوند طول به بافر می‌افزاید و در max_chunk می‌شکند. اول نمک را بفرستید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

رمزگشا جدید NewDecoder

تابع رمزگشا جدید(m: روش، master: تهی*): رمزگشا
رمزگشایی برای یک روش و یک کلید اصلی می‌سازد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

آزادسازی رمزگشا DecoderFree

تابع آزادسازی رمزگشا(d &: رمزگشا)
رمزگشا را آزاد می‌کند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

خوراندن Feed

تابع خوراندن(d &: رمزگشا، data: تهی*، n: صحیح)
بایت‌هایی را که از شبکه رسیده‌اند به رمزگشا می‌دهد.

گرفتن نمک TakeSalt

تابع گرفتن نمک(d &: رمزگشا): منطقی
نمک را از بایت‌هایی که تا اینجا داده شده می‌خواند و کلید را برپا می‌کند. وقتی آماده است درست برمی‌گرداند.

گرفتن قاب TakeFrame

تابع گرفتن قاب(d &: رمزگشا، n: صحیح، out &: بافر): صحیح
یک تکه با اندازه‌ی مشخص را می‌خواند و باز می‌کند. طولش را برمی‌گرداند، یا عددی منفی وقتی بایت بیشتری لازم است یا تصدیق شکست خورد.

تکه بعدی NextChunk

تابع تکه بعدی(d &: رمزگشا، out &: بافر): صحیح
تکه‌ی کامل رمزگشایی‌شده‌ی بعدی را به بافر می‌افزاید و طولش را برمی‌گرداند، ۰ وقتی بایت بیشتری لازم است و عدد منفی در خطا.

رمزگشایی همه DecodeAll

تابع رمزگشایی همه(d &: رمزگشا، data: تهی*، n: صحیح، out &: بافر): منطقی
هر چیز را در یک بلوک بایت که یک جریان کامل دارد رمزگشایی می‌کند و متن ساده را می‌افزاید. در خطا نادرست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

گوش دادن Listen

تابع گوش دادن(port: صحیح، method: رشته، password: رشته): سرور
سروری روی یک درگاه TCP (۰ یعنی یک درگاه آزاد) با یک روش و یک گذرواژه راه می‌اندازد. برای روش ۲۰۲۲ گذرواژه base64 کلید است. برای روش، گذرواژه یا درگاه نادرست، سروری برمی‌گرداند که سرور معتبر نیست.

گوش دادن روی نشانی ListenOn

تابع گوش دادن روی نشانی(host: رشته، port: صحیح، method: رشته، password: رشته، obfs: رشته): سرور
مثل ListenObfs است، اما فقط روی نشانی داده‌شده گوش می‌دهد، مثلاً 127.0.0.1، نه روی همه‌ی رابط‌ها. آخرین آرگومان استتار است: http، tls یا خالی برای هیچ.
net-shadowsocks-MultiUser.salam
// زبان: فارسی
واردسازی شبکه.شدوساکس

تابع ریشه:
    method := "2022-blake3-aes-128-gcm"
    ipsk := "AAECAwQFBgcICQoLDA0ODw=="
    server := شدوساکس.گوش دادن روی نشانی("127.0.0.1"، 0، method، ipsk، "")
    سرچاپ شدوساکس.سرور معتبر(server)، شدوساکس.درگاه سرور(server) بزرگتر 0
    سرچاپ شدوساکس.افزودن کاربر(server، "alice"، "EBESExQVFhcYGRobHB0eHw==")
    سرچاپ شدوساکس.افزودن کاربر(server، "bob"، "ICEiIyQlJicoKSorLC0uLw==")
    سرچاپ شدوساکس.افزودن کاربر(server، "bad"، "short")
    سرچاپ server.وضعیت.تعداد کاربران، server.وضعیت.کاربران.دارد("x")، server.وضعیت.نام کاربران.اندازه()
    شدوساکس.نابودی سرور(server)

    classic := شدوساکس.گوش دادن روی نشانی("127.0.0.1"، 0، "chacha20-ietf-poly1305"، "password"، "")
    سرچاپ شدوساکس.افزودن کاربر(classic، "carol"، "password")
    شدوساکس.نابودی سرور(classic)

    ناپایا relay := شدوساکس.گوش دادن یو دی پی روی نشانی("127.0.0.1"، 0، method، ipsk)
    سرچاپ relay.معتبر، شدوساکس.درگاه سرور یو دی پی(relay) بزرگتر 0
    سرچاپ شدوساکس.افزودن کاربر یو دی پی(relay، "EBESExQVFhcYGRobHB0eHw==")
    سرچاپ شدوساکس.افزودن کاربر یو دی پی(relay، "short")
    سرچاپ relay.تعداد کاربران، relay.کاربران.اندازه()، relay.نشست ها.اندازه()
    شدوساکس.نابودی یو دی پی(relay)
پایان
خروجیtrue true true true false 2 false 2 false true true true false 1 1 0

گوش دادن با پوشش ListenObfs

تابع گوش دادن با پوشش(port: صحیح، method: رشته، password: رشته، obfs: رشته): سرور
مثل گوش دادن ولی انتظار دارد کارخواه‌ها از حالت http یا tls در simple-obfs استفاده کنند؛ رشته‌ی خالی یعنی هیچ.

افزودن کاربر AddUser

تابع افزودن کاربر(s: سرور، name: رشته، password: رشته): منطقی
یک کاربر به سرور AES نسخه‌ی ۲۰۲۲ می‌افزاید: نامی که در گزارش‌ها دیده می‌شود و کلید کاربر به base64. کارخواه‌ها از آن پس با گذرواژه‌ی serverkey:userkey وصل می‌شوند. برای روش کلاسیک، ChaCha نسخه‌ی ۲۰۲۲ یا کلید بد نادرست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-MultiUser.salam

سرور معتبر ServerOk

تابع سرور معتبر(s: سرور): منطقی
می‌گوید سرور راه افتاده است یا نه.

درگاه سرور ServerPort

تابع درگاه سرور(s: سرور): صحیح
درگاهی که سرور روی آن گوش می‌دهد؛ پس از Listen(0, ...) به کار می‌آید.

پذیرش Accept

تابع پذیرش(s: سرور): اتصال
منتظر کارخواه بعدی می‌ماند که دست‌دهی‌اش موفق شود و اتصال آن را برمی‌گرداند. اتصالی که دست‌دهی را ببازد (گذرواژه‌ی غلط، بازپخش، زمان نادرست) بی‌جواب بسته می‌شود و انتظار ادامه می‌یابد. مقصد اتصال می‌گوید کارخواه کجا می‌خواهد برود.

پذیرش روی جریان AcceptOver

تابع پذیرش روی جریان(s: سرور، io: dyn تونل.جریان): اتصال
مثل پذیرش ولی برای یک کارخواه که روی جریانی که از پیش دارید می‌رسد، مثل یک WebSocket. اگر دست‌دهی شکست بخورد اتصالی برمی‌گرداند که معتبر نیست.

رله Relay

تابع رله(c: اتصال)
یک اتصال پذیرفته‌شده را مثل پراکسی خدمت می‌کند: به مقصدی که کارخواه خواسته وصل می‌شود و بایت‌ها را در دو جهت کپی می‌کند تا یک طرف تمام کند و بعد همه‌چیز را می‌بندد. نیم‌بستن ندارد.

خدمت Serve

تابع خدمت(s: سرور، handler: تابع(اتصال))
تا صدا زدن توقف سرور کارخواه‌ها را می‌پذیرد و دستگیره را برای هر یک روی یک نخ کارگر اجرا می‌کند. دستگیره مالک اتصال است و باید آن را ببندد.

خدمت رله ServeRelay

تابع خدمت رله(s: سرور)
هر کارخواه را با رله خدمت می‌کند. این کل سرور یک پراکسی شدوساکس ساده است.

توقف سرور Stop

تابع توقف سرور(s: سرور)
از خدمت می‌خواهد برگردد. از نخی دیگر صدایش بزنید، منتظر نخ خدمت‌دهنده بمانید و نابودی سرور را صدا بزنید.

نابودی سرور Destroy

تابع نابودی سرور(s: سرور)
سرور را آزاد و کلیدش را پاک می‌کند. یک بار صدایش بزنید، پس از برگشتن خدمت.

یافتن روش LookupMethod

تابع یافتن روش(name: رشته): روش
روشی را با نام پیدا می‌کند. برای نام ناشناخته ok نتیجه نادرست است.

بایت به کلید BytesToKey

تابع بایت به کلید(password: رشته، klen: صحیح، out: تهی*)
تابع کلاسیک گذرواژه به کلید (MD5 تکراری) که klen بایت در out می‌نویسد.

اچ کی دی اف شا۱ HkdfSha1

تابع اچ کی دی اف شا۱(key: تهی*، klen: صحیح، salt: تهی*، slen: صحیح، info: رشته، out: تهی*، olen: صحیح)
HKDF با SHA-1: از یک کلید، یک نمک و یک رشته‌ی info به اندازه‌ی olen بایت مشتق می‌کند. کلید نشست کلاسیک از آن استفاده می‌کند.

زیرکلید نشست SessionSubkey

تابع زیرکلید نشست(m: روش، master: تهی*، salt: تهی*، out: تهی*)
کلید نشست کلاسیک برای یک کلید اصلی و یک نمک (HKDF با info برابر ss-subkey).

نمک تصادفی RandomSalt

تابع نمک تصادفی(m: روش، out: تهی*)
out را با نمک تصادفی به اندازه‌ی طول روش پر می‌کند.

کلید گذرواژه PasswordKey

تابع کلید گذرواژه(m: روش، password: رشته): بافر
کلید اصلی یک روش کلاسیک از گذرواژه، به‌صورت یک بافر تازه.

بسته بندی یو دی پی PackUdp

تابع بسته بندی یو دی پی(m: روش، key: تهی*، host: رشته، port: صحیح، data: تهی*، n: صحیح، out &: بافر): منطقی
یک دیتاگرام UDP می‌سازد: یک نمک تصادفی و سپس مقصد و محتوا که با هم مهر می‌شوند. آن را به بافر می‌افزاید. برای روش ۲۰۲۲ یا مقصد بد نادرست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

بازکردن یو دی پی UnpackUdp

تابع بازکردن یو دی پی(m: روش، key: تهی*، p: تهی*، n: صحیح، t &: مقصد، out &: بافر): منطقی
یک دیتاگرام را باز می‌کند، مقصد را پر می‌کند و محتوا را به بافر می‌افزاید. وقتی تصدیق شکست بخورد، بسته کوتاه باشد یا روش ۲۰۲۲ باشد نادرست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-Codec.salam

اتصال یو دی پی UdpDial

تابع اتصال یو دی پی(cfg: پیکربندی): کلاینت یو دی پی
کارخواه UDP برای سرور و روش در پیکربندی می‌سازد. برای روش ۲۰۲۲ گذرواژه می‌تواند serverkey:userkey باشد. برای روش ناشناخته یا گذرواژه‌ی بد ok نادرست است.

ارسال یو دی پی UdpSend

تابع ارسال یو دی پی(c: کلاینت یو دی پی، host: رشته، port: صحیح، data: تهی*، n: صحیح): منطقی
محتوایی را از راه رله به یک مقصد می‌فرستد. وقتی دیتاگرام فرستاده شد درست برمی‌گرداند.

دریافت یو دی پی UdpRecv

تابع دریافت یو دی پی(c: کلاینت یو دی پی، buf: تهی*، max: صحیح، from &: مقصد): صحیح
منتظر یک پاسخ می‌ماند، آن را باز می‌کند و محتوا را در بافر کپی می‌کند (تا max بایت) و from را با فرستنده پر می‌کند. طول را برمی‌گرداند، یا عددی منفی در پایان مهلت یا بسته‌ای که تصدیق نمی‌شود.

مهلت یو دی پی UdpSetTimeout

تابع مهلت یو دی پی(c: کلاینت یو دی پی، millis: صحیح)
دریافت یو دی پی حداکثر چند میلی‌ثانیه منتظر بماند.

بستن یو دی پی UdpClose

تابع بستن یو دی پی(c: کلاینت یو دی پی)
کارخواه را می‌بندد و بافرهایش را آزاد می‌کند.

گوش دادن یو دی پی UdpListen

تابع گوش دادن یو دی پی(port: صحیح، method: رشته، password: رشته): سرور یو دی پی
رله‌ی UDP روی یک درگاه با یک روش و یک گذرواژه راه می‌اندازد. برای روش ۲۰۲۲ گذرواژه همان کلید base64 است. برای روش ناشناخته، گذرواژه‌ی بد یا درگاه اشغال ok نادرست است.

گوش دادن یو دی پی روی نشانی UdpListenOn

تابع گوش دادن یو دی پی روی نشانی(host: رشته، port: صحیح، method: رشته، password: رشته): سرور یو دی پی
مثل UdpListen است، اما فقط روی نشانی داده‌شده گوش می‌دهد، مثلاً 127.0.0.1.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-MultiUser.salam

افزودن کاربر یو دی پی UdpAddUser

تابع افزودن کاربر یو دی پی(s &: سرور یو دی پی، password: رشته): منطقی
یک کلید کاربر به رله‌ی UDP نسخه‌ی ۲۰۲۲ AES می‌افزاید. برای روش کلاسیک، ChaCha نسخه‌ی ۲۰۲۲ یا کلید بد نادرست برمی‌گرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-shadowsocks-MultiUser.salam

درگاه سرور یو دی پی UdpServerPort

تابع درگاه سرور یو دی پی(s: سرور یو دی پی): صحیح
درگاهی که رله روی آن گوش می‌دهد.

گام یو دی پی UdpStep

تابع گام یو دی پی(s &: سرور یو دی پی): صحیح
حداکثر یک دیتاگرام منتظر را رسیدگی و ارسال می‌کند، پاسخ‌های معلق را به کارخواهشان برمی‌گرداند و کارخواه‌های بیکار را حذف می‌کند. وقتی دیتاگرامی رسیدگی شد ۱ برمی‌گرداند، وگرنه ۰. حدود ۲۰ میلی‌ثانیه منتظر بسته می‌ماند.

خدمت یو دی پی UdpServe

تابع خدمت یو دی پی(s &: سرور یو دی پی)
گام یو دی پی را تا توقف یو دی پی در حلقه صدا می‌زند. روی نخ خودش اجرایش کنید.

توقف یو دی پی UdpStop

تابع توقف یو دی پی(s: سرور یو دی پی)
از خدمت یو دی پی می‌خواهد برگردد.

نابودی یو دی پی UdpDestroy

تابع نابودی یو دی پی(s &: سرور یو دی پی)
رله، سوکت‌ها و کلیدش را می‌بندد.

هش بلیک۳ Blake3Hash

تابع هش بلیک۳(p: تهی*، n: صحیح، out: تهی*، outlen: صحیح)
هش BLAKE3 از بایت‌ها، نوشته‌شده به‌صورت outlen بایت در out (۳۲ طول معمول است).

هش کلیددار بلیک۳ Blake3KeyedHash

تابع هش کلیددار بلیک۳(key32: تهی*، p: تهی*، n: صحیح، out: تهی*، outlen: صحیح)
هش کلیددار BLAKE3 برای کلید ۳۲ بایتی.

اشتقاق کلید بلیک۳ Blake3DeriveKey

تابع اشتقاق کلید بلیک۳(context: رشته، p: تهی*، n: صحیح، out: تهی*، outlen: صحیح)
اشتقاق کلید BLAKE3 با یک رشته‌ی زمینه.

کلید نشست بلیک۳ Blake3SessionKey

تابع کلید نشست بلیک۳(psk: تهی*، klen: صحیح، salt: تهی*، slen: صحیح، out: تهی*)
کلید نشست شدوساکس ۲۰۲۲: مشتق از کلید پیش‌اشتراکی و نمک.