HalfDuplex
HalfDuplex یک قابلیت است که هر اتصال (Connection) را به دو اتصال تبدیل میکند:
- یک اتصال فقط برای ارسال دادهها استفاده میشود.
- اتصال دیگر فقط برای دریافت دادهها استفاده میشود.
در ابتدای برقراری هر کدام از این اتصالات، یک Handshake
از نوع TLS
انجام
میشود، حتی اگر دامنههای متفاوتی داشته باشند.
مزایای HalfDuplex:
- محدود کردن تحلیل ترافیک توسط فایروال: چون دادهها روی هر اتصال به صورت یک طرفه منتقل میشوند.
- قابل پیادهسازی در اتصالات مستقیم (نه فقط تونل): میتواند از فیلتر شدن پیکربندیهای مستقیم جلوگیری کند.
نکات:
- اتصالات با انتقال دوطرفه داده، معمولاً نشاندهنده وجود تونل هستند.
- مثلاً در
HTTP/2
معمولی، ابتدا آپلود کم و سپس دانلود زیاد انجام میشود. - اما در
VPN
باMultiplexing
، آپلود به طور مداوم روی اتصال انجام میشود.
- مثلاً در
- این ویژگی برای تونلهای معکوس (
Reverse Tunnel
) برای حفظ کیفیت سرویس ضروری است. - احتمالاً تونلهای عادی
port-to-port
را نیز در برابر فیلتر شدن مقاوم میکند (هنوز تست نشده).
ویدیو های آموزشی
آموزش تانل زدن به روش waterwall بین سرور ایران و خارج: آموزش تانل v2ray
اجرای ساده چند پورت (Multi-port)
نحوه اعمال HalfDuplex در حالت چند پورت ساده، با فرض آدرس سرور خارج 1.1.1.1
:
سرور ایران
{
"name": "simple_multiport_hd_client",
"nodes": [
{
"name": "input",
"type": "TcpListener",
"settings": {
"address": "0.0.0.0",
"port": [23, 65535],
"nodelay": true
},
"next": "port_header"
},
{
"name": "port_header",
"type": "HeaderClient",
"settings": {
"data": "src_context->port"
},
"next": "halfc"
},
{
"name": "halfc",
"type": "HalfDuplexClient",
"next": "output"
},
{
"name": "output",
"type": "TcpConnector",
"settings": {
"nodelay": true,
"address": "1.1.1.1",
"port": 443
}
}
]
}
سرور خارج
{
"name": "simple_multiport_hd_server",
"nodes": [
{
"name": "input",
"type": "TcpListener",
"settings": {
"address": "0.0.0.0",
"port": 443,
"nodelay": true
},
"next": "halfs"
},
{
"name": "halfs",
"type": "HalfDuplexServer",
"settings": {},
"next": "port_header"
},
{
"name": "port_header",
"type": "HeaderServer",
"settings": {
"override": "dest_context->port"
},
"next": "output"
},
{
"name": "output",
"type": "TcpConnector",
"settings": {
"nodelay": true,
"address": "127.0.0.1",
"port": "dest_context->port"
}
}
]
}
پیکربندی Reverse Reality با mux
پیکربندی Reverse Reality با استفاده از mux که توسط نویسنده برای کاربرانش استفاده میشود:
فرضیات
- fake sni: sahab.ir
- ip kharej: 2.2.2.2
- password: passwd
سرور ایران
{
"name": "reverse_reality_grpc_client_hd_multiport_client",
"nodes": [
{
"name": "outbound_to_core",
"type": "TcpConnector",
"settings": {
"nodelay": true,
"address": "127.0.0.1",
"port": "dest_context->port"
}
},
{
"name": "header",
"type": "HeaderServer",
"settings": {
"override": "dest_context->port"
},
"next": "outbound_to_core"
},
{
"name": "bridge1",
"type": "Bridge",
"settings": {
"pair": "bridge2"
},
"next": "header"
},
{
"name": "bridge2",
"type": "Bridge",
"settings": {
"pair": "bridge1"
},
"next": "reverse_client"
},
{
"name": "reverse_client",
"type": "ReverseClient",
"settings": {
"minimum-unused": 16
},
"next": "pbclient"
},
{
"name": "pbclient",
"type": "ProtoBufClient",
"settings": {},
"next": "h2client"
},
{
"name": "h2client",
"type": "Http2Client",
"settings": {
"host": "sahab.ir",
"port": 443,
"path": "/",
"content-type": "application/grpc",
"concurrency": 64
},
"next": "halfc"
},
{
"name": "halfc",
"type": "HalfDuplexClient",
"next": "reality_client"
},
{
"name": "reality_client",
"type": "RealityClient",
"settings": {
"sni": "sahab.ir",
"password": "passwd"
},
"next": "outbound_to_iran"
},
{
"name": "outbound_to_iran",
"type": "TcpConnector",
"settings": {
"nodelay": true,
"address": "1.1.1.1",
"port": 443
}
}
]
}
فرضیات
- fake sni: sahab.ir
- ip kharej: 2.2.2.2
- password: passwd
سرور خارج
{
"name": "reverse_reality_grpc_hd_multiport_server",
"nodes": [
{
"name": "users_inbound",
"type": "TcpListener",
"settings": {
"address": "0.0.0.0",
"port": [23, 65535],
"nodelay": true
},
"next": "header"
},
{
"name": "header",
"type": "HeaderClient",
"settings": {
"data": "src_context->port"
},
"next": "bridge2"
},
{
"name": "bridge2",
"type": "Bridge",
"settings": {
"pair": "bridge1"
}
},
{
"name": "bridge1",
"type": "Bridge",
"settings": {
"pair": "bridge2"
}
},
{
"name": "reverse_server",
"type": "ReverseServer",
"settings": {},
"next": "bridge1"
},
{
"name": "pbserver",
"type": "ProtoBufServer",
"settings": {},
"next": "reverse_server"
},
{
"name": "h2server",
"type": "Http2Server",
"settings": {},
"next": "pbserver"
},
{
"name": "halfs",
"type": "HalfDuplexServer",
"settings": {},
"next": "h2server"
},
{
"name": "reality_server",
"type": "RealityServer",
"settings": {
"destination": "reality_dest",
"password": "passwd"
},
"next": "halfs"
},
{
"name": "kharej_inbound",
"type": "TcpListener",
"settings": {
"address": "0.0.0.0",
"port": 443,
"nodelay": true,
"whitelist": ["2.2.2.2/32"]
},
"next": "reality_server"
},
{
"name": "reality_dest",
"type": "TcpConnector",
"settings": {
"nodelay": true,
"address": "sahab.ir",
"port": 443
}
}
]
}
نکته مهم بدون توجه به تعداد هستههای سرور، تعداد Worker ها در سرور خارج
را همیشه 4 برابر تعداد Worker های سرور ایران قرار دهید (حتی اگر 8 برابر). این کار سرعت را به میزان قابل توجهی بهبود میبخشد.
دلیل آن ارتباطی به مصرف CPU ندارد، بلکه هر Worker یک اتصال مجزا ایجاد میکند و کاربران روی یک اتصال Multiplexed قرار نمیگیرند.
توجه این نکته فقط برای Reverse Reality با mux صادق است. در سایر روشها،
بهتر است تعداد Worker ها صفر باشد.