بروتوكولات SOCKS وHTTP وMixed
ينفذ sing-box بروتوكولات SOCKS4/5 وHTTP CONNECT ومستمعاً مدمجاً "mixed" يكتشف البروتوكول تلقائياً. تتشارك البروتوكولات الثلاثة في أنماط متشابهة: الاستماع على TCP فقط، TLS اختياري، مصادقة اسم المستخدم/كلمة المرور، ودعم UoT (UDP-over-TCP).
المصدر: protocol/socks/inbound.go، protocol/http/inbound.go، protocol/mixed/inbound.go، protocol/socks/outbound.go، protocol/http/outbound.go
وارد SOCKS
البنية
type Inbound struct {
inbound.Adapter
router adapter.ConnectionRouterEx
logger logger.ContextLogger
listener *listener.Listener
authenticator *auth.Authenticator
udpTimeout time.Duration
}ينفذ وارد SOCKS واجهة adapter.TCPInjectableInbound:
var _ adapter.TCPInjectableInbound = (*Inbound)(nil)معالجة الاتصال
يتم تفويض اتصالات SOCKS إلى sing/protocol/socks.HandleConnectionEx، التي تعالج مصافحة SOCKS4/5 الكاملة:
func (h *Inbound) NewConnectionEx(ctx, conn, metadata, onClose) {
err := socks.HandleConnectionEx(ctx, conn, std_bufio.NewReader(conn),
h.authenticator,
adapter.NewUpstreamHandlerEx(metadata, h.newUserConnection, h.streamUserPacketConnection),
h.listener, // مستمع ربط UDP
h.udpTimeout,
metadata.Source,
onClose,
)
N.CloseOnHandshakeFailure(conn, onClose, err)
}يستقبل المعالج اتصالات TCP المفككة واتصالات حزم UDP بعد مصافحة SOCKS:
func (h *Inbound) newUserConnection(ctx, conn, metadata, onClose) {
metadata.Inbound = h.Tag()
metadata.InboundType = h.Type()
user, loaded := auth.UserFromContext[string](ctx)
if loaded {
metadata.User = user
}
h.router.RouteConnectionEx(ctx, conn, metadata, onClose)
}دعم UoT
يتم تغليف الموجه بدعم UoT لمعالجة UDP-over-TCP:
inbound.router = uot.NewRouter(router, logger)مستمع TCP فقط
يستمع SOCKS على TCP فقط. يتم معالجة اتصالات ربط UDP من خلال آلية ترحيل UDP في SOCKS5 (باستخدام listener كهدف ربط UDP):
inbound.listener = listener.New(listener.Options{
Network: []string{N.NetworkTCP},
ConnectionHandler: inbound,
})وارد HTTP
البنية
type Inbound struct {
inbound.Adapter
router adapter.ConnectionRouterEx
logger log.ContextLogger
listener *listener.Listener
authenticator *auth.Authenticator
tlsConfig tls.ServerConfig
}دعم TLS مع kTLS
يدعم وارد HTTP تفعيل TLS مع توافق kTLS:
if options.TLS != nil {
tlsConfig, _ := tls.NewServerWithOptions(tls.ServerOptions{
KTLSCompatible: true,
})
inbound.tlsConfig = tlsConfig
}معالجة الاتصال
يتم إجراء مصافحة TLS أولاً (إذا تم تكوينها)، ثم يعالج معالج HTTP CONNECT الطلب:
func (h *Inbound) NewConnectionEx(ctx, conn, metadata, onClose) {
if h.tlsConfig != nil {
tlsConn, _ := tls.ServerHandshake(ctx, conn, h.tlsConfig)
conn = tlsConn
}
err := http.HandleConnectionEx(ctx, conn, std_bufio.NewReader(conn),
h.authenticator,
adapter.NewUpstreamHandlerEx(metadata, h.newUserConnection, h.streamUserPacketConnection),
metadata.Source,
onClose,
)
}وكيل النظام
يمكن لوارد HTTP تكوين نفسه كوكيل النظام:
inbound.listener = listener.New(listener.Options{
SetSystemProxy: options.SetSystemProxy,
SystemProxySOCKS: false,
})وارد Mixed
يجمع وارد Mixed بين SOCKS وHTTP على منفذ واحد عن طريق فحص أول بايت من كل اتصال.
البنية
type Inbound struct {
inbound.Adapter
router adapter.ConnectionRouterEx
logger log.ContextLogger
listener *listener.Listener
authenticator *auth.Authenticator
tlsConfig tls.ServerConfig
udpTimeout time.Duration
}اكتشاف البروتوكول
المنطق الأساسي يفحص أول بايت لتحديد البروتوكول:
func (h *Inbound) newConnection(ctx, conn, metadata, onClose) error {
if h.tlsConfig != nil {
conn = tls.ServerHandshake(ctx, conn, h.tlsConfig)
}
reader := std_bufio.NewReader(conn)
headerBytes, _ := reader.Peek(1)
switch headerBytes[0] {
case socks4.Version, socks5.Version:
// SOCKS4 (0x04) أو SOCKS5 (0x05)
return socks.HandleConnectionEx(ctx, conn, reader, h.authenticator, ...)
default:
// أي شيء آخر يُعامل كـ HTTP
return http.HandleConnectionEx(ctx, conn, reader, h.authenticator, ...)
}
}- SOCKS4: أول بايت هو
0x04 - SOCKS5: أول بايت هو
0x05 - HTTP: أي بايت أول آخر (عادة
Cلـ CONNECT،Gلـ GET، إلخ)
وكيل النظام (Mixed)
عند تعيين mixed كوكيل النظام، يُبلغ عن منفذ SOCKS:
inbound.listener = listener.New(listener.Options{
SetSystemProxy: options.SetSystemProxy,
SystemProxySOCKS: true, // الإعلان عن منفذ SOCKS في وكيل النظام
})صادر SOCKS
يتصل صادر SOCKS عبر خادم SOCKS5 علوي. تم تنفيذه في protocol/socks/outbound.go ويستخدم نوع Client من مكتبة sing/protocol/socks.
صادر HTTP
يتصل صادر HTTP عبر وكيل HTTP CONNECT علوي. يدعم TLS إلى خادم الوكيل.
الأنماط المشتركة
مصادقة المستخدم
تستخدم أنواع الوارد الثلاثة نفس آلية المصادقة:
authenticator := auth.NewAuthenticator(options.Users)المستخدمون هم بنى auth.User تحتوي على حقول Username وPassword. يتم تمرير المصادق إلى معالجات البروتوكول.
البيانات الوصفية للمستخدم
بعد المصادقة، يتم استخراج اسم المستخدم من السياق وتخزينه في البيانات الوصفية:
user, loaded := auth.UserFromContext[string](ctx)
if loaded {
metadata.User = user
}TCP القابل للحقن
ينفذ كل من وارد SOCKS وMixed واجهة adapter.TCPInjectableInbound، مما يسمح للمكونات الأخرى بحقن اتصالات TCP فيها (تُستخدم بواسطة آليات الوكيل الشفاف).
أمثلة على التكوين
وارد SOCKS
{
"type": "socks",
"tag": "socks-in",
"listen": "127.0.0.1",
"listen_port": 1080,
"users": [
{ "username": "user1", "password": "pass1" }
]
}وارد HTTP (مع TLS)
{
"type": "http",
"tag": "http-in",
"listen": "127.0.0.1",
"listen_port": 8080,
"users": [
{ "username": "user1", "password": "pass1" }
],
"tls": {
"enabled": true,
"certificate_path": "/path/to/cert.pem",
"key_path": "/path/to/key.pem"
},
"set_system_proxy": true
}وارد Mixed
{
"type": "mixed",
"tag": "mixed-in",
"listen": "127.0.0.1",
"listen_port": 2080,
"users": [
{ "username": "user1", "password": "pass1" }
],
"set_system_proxy": true
}