mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-09 18:43:14 +00:00
Update UoT protocol
This commit is contained in:
parent
a3a5185b15
commit
43f31b40ba
|
@ -12,7 +12,7 @@
|
|||
"plugin": "",
|
||||
"plugin_opts": "",
|
||||
"network": "udp",
|
||||
"udp_over_tcp": false,
|
||||
"udp_over_tcp": false | {},
|
||||
"multiplex": {},
|
||||
|
||||
... // Dial Fields
|
||||
|
@ -87,7 +87,9 @@ Both is enabled by default.
|
|||
|
||||
#### udp_over_tcp
|
||||
|
||||
Enable the UDP over TCP protocol.
|
||||
UDP over TCP configuration.
|
||||
|
||||
See [UDP Over TCP](/configuration/shared/udp-over-tcp) for details.
|
||||
|
||||
Conflict with `multiplex`.
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"plugin": "",
|
||||
"plugin_opts": "",
|
||||
"network": "udp",
|
||||
"udp_over_tcp": false,
|
||||
"udp_over_tcp": false | {},
|
||||
"multiplex": {},
|
||||
|
||||
... // 拨号字段
|
||||
|
@ -87,7 +87,9 @@ Shadowsocks SIP003 插件参数。
|
|||
|
||||
#### udp_over_tcp
|
||||
|
||||
启用 UDP over TCP 协议。
|
||||
UDP over TCP 配置。
|
||||
|
||||
参阅 [UDP Over TCP](/zh/configuration/shared/udp-over-tcp)。
|
||||
|
||||
与 `multiplex` 冲突。
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"username": "sekai",
|
||||
"password": "admin",
|
||||
"network": "udp",
|
||||
"udp_over_tcp": false,
|
||||
"udp_over_tcp": false | {},
|
||||
|
||||
... // Dial Fields
|
||||
}
|
||||
|
@ -57,7 +57,9 @@ Both is enabled by default.
|
|||
|
||||
#### udp_over_tcp
|
||||
|
||||
Enable the UDP over TCP protocol.
|
||||
UDP over TCP protocol settings.
|
||||
|
||||
See [UDP Over TCP](/configuration/shared/udp-over-tcp) for details.
|
||||
|
||||
### Dial Fields
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"username": "sekai",
|
||||
"password": "admin",
|
||||
"network": "udp",
|
||||
"udp_over_tcp": false,
|
||||
"udp_over_tcp": false | {},
|
||||
|
||||
... // 拨号字段
|
||||
}
|
||||
|
@ -57,7 +57,9 @@ SOCKS5 密码。
|
|||
|
||||
#### udp_over_tcp
|
||||
|
||||
启用 UDP over TCP 协议。
|
||||
UDP over TCP 配置。
|
||||
|
||||
参阅 [UDP Over TCP](/zh/configuration/shared/udp-over-tcp)。
|
||||
|
||||
### 拨号字段
|
||||
|
||||
|
|
81
docs/configuration/shared/udp-over-tcp.md
Normal file
81
docs/configuration/shared/udp-over-tcp.md
Normal file
|
@ -0,0 +1,81 @@
|
|||
# UDP over TCP
|
||||
|
||||
!!! warning ""
|
||||
|
||||
It's a proprietary protocol created by SagerNet, not part of shadowsocks.
|
||||
|
||||
The UDP over TCP protocol is used to transmit UDP packets in TCP.
|
||||
|
||||
### Structure
|
||||
|
||||
```json
|
||||
{
|
||||
"enabled": true,
|
||||
"version": 2
|
||||
}
|
||||
```
|
||||
|
||||
!!! info ""
|
||||
|
||||
The structure can be replaced with a boolean value when the version is not specified.
|
||||
|
||||
### Fields
|
||||
|
||||
#### enabled
|
||||
|
||||
Enable the UDP over TCP protocol.
|
||||
|
||||
#### version
|
||||
|
||||
The protocol version, `1` or `2`.
|
||||
|
||||
2 is used by default.
|
||||
|
||||
### Application support
|
||||
|
||||
| Project | UoT v1 | UoT v2 |
|
||||
|--------------|----------------------|------------|
|
||||
| sing-box | v0 (2022/08/11) | v1.2-beta9 |
|
||||
| Xray-core | v1.5.7 (2022/06/05) | / |
|
||||
| Clash.Meta | v1.12.0 (2022/07/02) | / |
|
||||
| Shadowrocket | v2.2.12 (2022/08/13) | / |
|
||||
|
||||
### Protocol details
|
||||
|
||||
#### Protocol version 1
|
||||
|
||||
The client requests the magic address to the upper layer proxy protocol to indicate the request: `sp.udp-over-tcp.arpa`
|
||||
|
||||
#### Stream format
|
||||
|
||||
| ATYP | address | port | length | data |
|
||||
|------|----------|-------|--------|----------|
|
||||
| u8 | variable | u16be | u16be | variable |
|
||||
|
||||
*ATYP / address / port*: Uses the SOCKS address format.
|
||||
|
||||
#### Protocol version 2
|
||||
|
||||
Protocol version 2 uses a new magic address: `sp.v2.udp-over-tcp.arpa`
|
||||
|
||||
##### Request format
|
||||
|
||||
| isConnect | ATYP | address | port |
|
||||
|-----------|------|----------|-------|
|
||||
| u8 | u8 | variable | u16be |
|
||||
|
||||
**version**: Fixed to 2.
|
||||
|
||||
**isConnect**: Set to 1 to indicates that the stream uses the connect format, 0 to disable.
|
||||
|
||||
**ATYP / address / port**: Request destination, uses the SOCKS address format.
|
||||
|
||||
##### Connect stream format
|
||||
|
||||
| length | data |
|
||||
|--------|----------|
|
||||
| u16be | variable |
|
||||
|
||||
##### Non-connect stream format
|
||||
|
||||
As the same as the stream format in protocol version 1.
|
|
@ -1,5 +1,9 @@
|
|||
# Shadowsocks
|
||||
|
||||
!!! warning ""
|
||||
|
||||
For censorship bypass usage in China, we recommend using UDP over TCP and disabling UDP on the server.
|
||||
|
||||
## Single User
|
||||
|
||||
#### Server
|
||||
|
@ -11,6 +15,7 @@
|
|||
"type": "shadowsocks",
|
||||
"listen": "::",
|
||||
"listen_port": 8080,
|
||||
"network": "tcp",
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg=="
|
||||
}
|
||||
|
@ -35,7 +40,8 @@
|
|||
"server": "127.0.0.1",
|
||||
"server_port": 8080,
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg=="
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg==",
|
||||
"udp_over_tcp": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
"type": "shadowsocks",
|
||||
"tag": "shadowsocks-in",
|
||||
"listen": "127.0.0.1",
|
||||
"network": "tcp",
|
||||
"method": "2022-blake3-aes-128-gcm",
|
||||
"password": "8JCsPssfgS8tiRwiMlhARg=="
|
||||
}
|
||||
|
@ -46,6 +47,7 @@
|
|||
"max_connections": 4,
|
||||
"min_streams": 4
|
||||
}
|
||||
// or "udp_over_tcp": true
|
||||
},
|
||||
{
|
||||
"type": "shadowtls",
|
||||
|
|
2
go.mod
2
go.mod
|
@ -25,7 +25,7 @@ require (
|
|||
github.com/sagernet/gomobile v0.0.0-20221130124640-349ebaa752ca
|
||||
github.com/sagernet/quic-go v0.0.0-20230202071646-a8c8afb18b32
|
||||
github.com/sagernet/reality v0.0.0-20230312150606-35ea9af0e0b8
|
||||
github.com/sagernet/sing v0.1.9-0.20230315163130-ed73785ecc78
|
||||
github.com/sagernet/sing v0.1.9-0.20230317044231-85a9429eadb6
|
||||
github.com/sagernet/sing-dns v0.1.4
|
||||
github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9
|
||||
github.com/sagernet/sing-shadowtls v0.1.0
|
||||
|
|
4
go.sum
4
go.sum
|
@ -111,8 +111,8 @@ github.com/sagernet/reality v0.0.0-20230312150606-35ea9af0e0b8 h1:4M3+0/kqvJuTsi
|
|||
github.com/sagernet/reality v0.0.0-20230312150606-35ea9af0e0b8/go.mod h1:B8lp4WkQ1PwNnrVMM6KyuFR20pU8jYBD+A4EhJovEXU=
|
||||
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
|
||||
github.com/sagernet/sing v0.1.8/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
|
||||
github.com/sagernet/sing v0.1.9-0.20230315163130-ed73785ecc78 h1:SO7TITxjoKyQFBVR0MJhTji9msxEXcv5p60imPrEyY4=
|
||||
github.com/sagernet/sing v0.1.9-0.20230315163130-ed73785ecc78/go.mod h1:9uHswk2hITw8leDbiLS/xn0t9nzBcbePxzm9PJhwdlw=
|
||||
github.com/sagernet/sing v0.1.9-0.20230317044231-85a9429eadb6 h1:h1wGLPBJLjujj9kYSbLiP1Tt6+IQnZ7Ok7jQd4u3xxk=
|
||||
github.com/sagernet/sing v0.1.9-0.20230317044231-85a9429eadb6/go.mod h1:9uHswk2hITw8leDbiLS/xn0t9nzBcbePxzm9PJhwdlw=
|
||||
github.com/sagernet/sing-dns v0.1.4 h1:7VxgeoSCiiazDSaXXQVcvrTBxFpOePPq/4XdgnUDN+0=
|
||||
github.com/sagernet/sing-dns v0.1.4/go.mod h1:1+6pCa48B1AI78lD+/i/dLgpw4MwfnsSpZo0Ds8wzzk=
|
||||
github.com/sagernet/sing-shadowsocks v0.1.2-0.20230221080503-769c01d6bba9 h1:qS39eA4C7x+zhEkySbASrtmb6ebdy5v0y2M6mgkmSO0=
|
||||
|
|
|
@ -64,6 +64,7 @@ nav:
|
|||
- TLS: configuration/shared/tls.md
|
||||
- Multiplex: configuration/shared/multiplex.md
|
||||
- V2Ray Transport: configuration/shared/v2ray-transport.md
|
||||
- UDP over TCP: configuration/shared/udp-over-tcp.md
|
||||
- Inbound:
|
||||
- configuration/inbound/index.md
|
||||
- Direct: configuration/inbound/direct.md
|
||||
|
|
|
@ -23,12 +23,11 @@ type ShadowsocksDestination struct {
|
|||
type ShadowsocksOutboundOptions struct {
|
||||
DialerOptions
|
||||
ServerOptions
|
||||
Method string `json:"method"`
|
||||
Password string `json:"password"`
|
||||
Plugin string `json:"plugin,omitempty"`
|
||||
PluginOptions string `json:"plugin_opts,omitempty"`
|
||||
Network NetworkList `json:"network,omitempty"`
|
||||
UoT bool `json:"udp_over_tcp,omitempty"`
|
||||
UoTVersion int `json:"udp_over_tcp_version,omitempty"`
|
||||
MultiplexOptions *MultiplexOptions `json:"multiplex,omitempty"`
|
||||
Method string `json:"method"`
|
||||
Password string `json:"password"`
|
||||
Plugin string `json:"plugin,omitempty"`
|
||||
PluginOptions string `json:"plugin_opts,omitempty"`
|
||||
Network NetworkList `json:"network,omitempty"`
|
||||
UDPOverTCPOptions *UDPOverTCPOptions `json:"udp_over_tcp,omitempty"`
|
||||
MultiplexOptions *MultiplexOptions `json:"multiplex,omitempty"`
|
||||
}
|
||||
|
|
|
@ -17,12 +17,11 @@ type HTTPMixedInboundOptions struct {
|
|||
type SocksOutboundOptions struct {
|
||||
DialerOptions
|
||||
ServerOptions
|
||||
Version string `json:"version,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Network NetworkList `json:"network,omitempty"`
|
||||
UoT bool `json:"udp_over_tcp,omitempty"`
|
||||
UoTVersion int `json:"udp_over_tcp_version,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Network NetworkList `json:"network,omitempty"`
|
||||
UDPOverTCPOptions *UDPOverTCPOptions `json:"udp_over_tcp,omitempty"`
|
||||
}
|
||||
|
||||
type HTTPOutboundOptions struct {
|
||||
|
|
30
option/udp_over_tcp.go
Normal file
30
option/udp_over_tcp.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
package option
|
||||
|
||||
import (
|
||||
"github.com/sagernet/sing-box/common/json"
|
||||
"github.com/sagernet/sing/common/uot"
|
||||
)
|
||||
|
||||
type _UDPOverTCPOptions struct {
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
Version uint8 `json:"version,omitempty"`
|
||||
}
|
||||
|
||||
type UDPOverTCPOptions _UDPOverTCPOptions
|
||||
|
||||
func (o UDPOverTCPOptions) MarshalJSON() ([]byte, error) {
|
||||
switch o.Version {
|
||||
case 0, uot.Version:
|
||||
return json.Marshal(o.Enabled)
|
||||
default:
|
||||
return json.Marshal(_UDPOverTCPOptions(o))
|
||||
}
|
||||
}
|
||||
|
||||
func (o *UDPOverTCPOptions) UnmarshalJSON(bytes []byte) error {
|
||||
err := json.Unmarshal(bytes, &o.Enabled)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return json.Unmarshal(bytes, (*_UDPOverTCPOptions)(o))
|
||||
}
|
|
@ -29,8 +29,7 @@ type Shadowsocks struct {
|
|||
method shadowsocks.Method
|
||||
serverAddr M.Socksaddr
|
||||
plugin sip003.Plugin
|
||||
uot bool
|
||||
uotVersion int
|
||||
uotClient *uot.Client
|
||||
multiplexDialer N.Dialer
|
||||
}
|
||||
|
||||
|
@ -50,7 +49,6 @@ func NewShadowsocks(ctx context.Context, router adapter.Router, logger log.Conte
|
|||
dialer: dialer.New(router, options.DialerOptions),
|
||||
method: method,
|
||||
serverAddr: options.ServerOptions.Build(),
|
||||
uot: options.UoT,
|
||||
}
|
||||
if options.Plugin != "" {
|
||||
outbound.plugin, err = sip003.CreatePlugin(options.Plugin, options.PluginOptions, router, outbound.dialer, outbound.serverAddr)
|
||||
|
@ -58,19 +56,18 @@ func NewShadowsocks(ctx context.Context, router adapter.Router, logger log.Conte
|
|||
return nil, err
|
||||
}
|
||||
}
|
||||
if !options.UoT {
|
||||
uotOptions := common.PtrValueOrDefault(options.UDPOverTCPOptions)
|
||||
if !uotOptions.Enabled {
|
||||
outbound.multiplexDialer, err = mux.NewClientWithOptions(ctx, (*shadowsocksDialer)(outbound), common.PtrValueOrDefault(options.MultiplexOptions))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
switch options.UoTVersion {
|
||||
case uot.LegacyVersion:
|
||||
outbound.uotVersion = uot.LegacyVersion
|
||||
case 0, uot.Version:
|
||||
outbound.uotVersion = uot.Version
|
||||
default:
|
||||
return nil, E.New("unknown udp over tcp protocol version ", options.UoTVersion)
|
||||
if uotOptions.Enabled {
|
||||
outbound.uotClient = &uot.Client{
|
||||
Dialer: (*shadowsocksDialer)(outbound),
|
||||
Version: uotOptions.Version,
|
||||
}
|
||||
}
|
||||
return outbound, nil
|
||||
}
|
||||
|
@ -84,25 +81,12 @@ func (h *Shadowsocks) DialContext(ctx context.Context, network string, destinati
|
|||
case N.NetworkTCP:
|
||||
h.logger.InfoContext(ctx, "outbound connection to ", destination)
|
||||
case N.NetworkUDP:
|
||||
if h.uot {
|
||||
h.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination)
|
||||
var uotDestination M.Socksaddr
|
||||
if h.uotVersion == uot.Version {
|
||||
uotDestination.Fqdn = uot.MagicAddress
|
||||
} else {
|
||||
uotDestination.Fqdn = uot.LegacyMagicAddress
|
||||
}
|
||||
tcpConn, err := (*shadowsocksDialer)(h).DialContext(ctx, N.NetworkTCP, uotDestination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if h.uotVersion == uot.Version {
|
||||
return uot.NewLazyConn(tcpConn, uot.Request{IsConnect: true, Destination: destination}), nil
|
||||
} else {
|
||||
return uot.NewConn(tcpConn, false, destination), nil
|
||||
}
|
||||
if h.uotClient != nil {
|
||||
h.logger.InfoContext(ctx, "outbound UoT connect packet connection to ", destination)
|
||||
return h.uotClient.DialContext(ctx, network, destination)
|
||||
} else {
|
||||
h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
}
|
||||
h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
}
|
||||
return (*shadowsocksDialer)(h).DialContext(ctx, network, destination)
|
||||
} else {
|
||||
|
@ -121,23 +105,11 @@ func (h *Shadowsocks) ListenPacket(ctx context.Context, destination M.Socksaddr)
|
|||
metadata.Outbound = h.tag
|
||||
metadata.Destination = destination
|
||||
if h.multiplexDialer == nil {
|
||||
if h.uot {
|
||||
if h.uotClient != nil {
|
||||
h.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination)
|
||||
var uotDestination M.Socksaddr
|
||||
if h.uotVersion == uot.Version {
|
||||
uotDestination.Fqdn = uot.MagicAddress
|
||||
} else {
|
||||
uotDestination.Fqdn = uot.LegacyMagicAddress
|
||||
}
|
||||
tcpConn, err := (*shadowsocksDialer)(h).DialContext(ctx, N.NetworkTCP, uotDestination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if h.uotVersion == uot.Version {
|
||||
return uot.NewLazyConn(tcpConn, uot.Request{Destination: destination}), nil
|
||||
} else {
|
||||
return uot.NewConn(tcpConn, false, destination), nil
|
||||
}
|
||||
return h.uotClient.ListenPacket(ctx, destination)
|
||||
} else {
|
||||
h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
}
|
||||
h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
return (*shadowsocksDialer)(h).ListenPacket(ctx, destination)
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing/common"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
@ -20,10 +21,9 @@ var _ adapter.Outbound = (*Socks)(nil)
|
|||
|
||||
type Socks struct {
|
||||
myOutboundAdapter
|
||||
client *socks.Client
|
||||
resolve bool
|
||||
uot bool
|
||||
uotVersion int
|
||||
client *socks.Client
|
||||
resolve bool
|
||||
uotClient *uot.Client
|
||||
}
|
||||
|
||||
func NewSocks(router adapter.Router, logger log.ContextLogger, tag string, options option.SocksOutboundOptions) (*Socks, error) {
|
||||
|
@ -47,15 +47,13 @@ func NewSocks(router adapter.Router, logger log.ContextLogger, tag string, optio
|
|||
},
|
||||
client: socks.NewClient(dialer.New(router, options.DialerOptions), options.ServerOptions.Build(), version, options.Username, options.Password),
|
||||
resolve: version == socks.Version4,
|
||||
uot: options.UoT,
|
||||
}
|
||||
switch options.UoTVersion {
|
||||
case uot.LegacyVersion:
|
||||
outbound.uotVersion = uot.LegacyVersion
|
||||
case 0, uot.Version:
|
||||
outbound.uotVersion = uot.Version
|
||||
default:
|
||||
return nil, E.New("unknown udp over tcp protocol version ", options.UoTVersion)
|
||||
uotOptions := common.PtrValueOrDefault(options.UDPOverTCPOptions)
|
||||
if uotOptions.Enabled {
|
||||
outbound.uotClient = &uot.Client{
|
||||
Dialer: outbound.client,
|
||||
Version: uotOptions.Version,
|
||||
}
|
||||
}
|
||||
return outbound, nil
|
||||
}
|
||||
|
@ -68,23 +66,9 @@ func (h *Socks) DialContext(ctx context.Context, network string, destination M.S
|
|||
case N.NetworkTCP:
|
||||
h.logger.InfoContext(ctx, "outbound connection to ", destination)
|
||||
case N.NetworkUDP:
|
||||
if h.uot {
|
||||
h.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination)
|
||||
var uotDestination M.Socksaddr
|
||||
if h.uotVersion == uot.Version {
|
||||
uotDestination.Fqdn = uot.MagicAddress
|
||||
} else {
|
||||
uotDestination.Fqdn = uot.LegacyMagicAddress
|
||||
}
|
||||
tcpConn, err := h.client.DialContext(ctx, N.NetworkTCP, uotDestination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if h.uotVersion == uot.Version {
|
||||
return uot.NewLazyConn(tcpConn, uot.Request{IsConnect: true, Destination: destination}), nil
|
||||
} else {
|
||||
return uot.NewConn(tcpConn, false, destination), nil
|
||||
}
|
||||
if h.uotClient != nil {
|
||||
h.logger.InfoContext(ctx, "outbound UoT connect packet connection to ", destination)
|
||||
return h.uotClient.DialContext(ctx, network, destination)
|
||||
}
|
||||
h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
default:
|
||||
|
@ -104,23 +88,9 @@ func (h *Socks) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.
|
|||
ctx, metadata := adapter.AppendContext(ctx)
|
||||
metadata.Outbound = h.tag
|
||||
metadata.Destination = destination
|
||||
if h.uot {
|
||||
if h.uotClient != nil {
|
||||
h.logger.InfoContext(ctx, "outbound UoT packet connection to ", destination)
|
||||
var uotDestination M.Socksaddr
|
||||
if h.uotVersion == uot.Version {
|
||||
uotDestination.Fqdn = uot.MagicAddress
|
||||
} else {
|
||||
uotDestination.Fqdn = uot.LegacyMagicAddress
|
||||
}
|
||||
tcpConn, err := h.client.DialContext(ctx, N.NetworkTCP, uotDestination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if h.uotVersion == uot.Version {
|
||||
return uot.NewLazyConn(tcpConn, uot.Request{Destination: destination}), nil
|
||||
} else {
|
||||
return uot.NewConn(tcpConn, false, destination), nil
|
||||
}
|
||||
return h.uotClient.ListenPacket(ctx, destination)
|
||||
}
|
||||
h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
return h.client.ListenPacket(ctx, destination)
|
||||
|
|
|
@ -589,12 +589,12 @@ func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata ad
|
|||
}
|
||||
metadata.Domain = metadata.Destination.Fqdn
|
||||
metadata.Destination = request.Destination
|
||||
return r.RoutePacketConnection(ctx, uot.NewConn(conn, request.IsConnect, metadata.Destination), metadata)
|
||||
return r.RoutePacketConnection(ctx, uot.NewConn(conn, *request), metadata)
|
||||
case uot.LegacyMagicAddress:
|
||||
r.logger.InfoContext(ctx, "inbound legacy UoT connection")
|
||||
metadata.Domain = metadata.Destination.Fqdn
|
||||
metadata.Destination = M.Socksaddr{Addr: netip.IPv4Unspecified()}
|
||||
return r.RoutePacketConnection(ctx, uot.NewConn(conn, false, metadata.Destination), metadata)
|
||||
return r.RoutePacketConnection(ctx, uot.NewConn(conn, uot.Request{}), metadata)
|
||||
}
|
||||
if metadata.InboundOptions.SniffEnabled {
|
||||
buffer := buf.NewPacket()
|
||||
|
|
Loading…
Reference in a new issue