mirror of
https://github.com/SagerNet/sing-box.git
synced 2025-06-13 21:54:13 +08:00
add support for uot on hysteria2
Co-authored-by: chise0713 <serika@milkdog.onmicrosoft.com>
This commit is contained in:
parent
cca9c06704
commit
25f44254d5
@ -15,6 +15,7 @@
|
||||
},
|
||||
"password": "goofy_ahh_password",
|
||||
"network": "tcp",
|
||||
"udp_over_stream": false,
|
||||
"tls": {},
|
||||
"brutal_debug": false,
|
||||
|
||||
@ -72,6 +73,15 @@ One of `tcp` `udp`.
|
||||
|
||||
Both is enabled by default.
|
||||
|
||||
#### udp_over_stream
|
||||
|
||||
This is the Hysteria2 port of the [UDP over TCP protocol](/configuration/shared/udp-over-tcp), designed to provide a QUIC
|
||||
stream based UDP relay mode that Hysteria2 does not provide. Since it is an add-on protocol, you will need to use sing-box or
|
||||
another program compatible with the protocol as a server.
|
||||
|
||||
This mode can improve reliability in proxying UDP traffic in lossy networks, as it supports retransmitting lost packets using
|
||||
QUIC's loss detection mechanisms.
|
||||
|
||||
#### tls
|
||||
|
||||
==Required==
|
||||
|
@ -15,6 +15,7 @@
|
||||
},
|
||||
"password": "goofy_ahh_password",
|
||||
"network": "tcp",
|
||||
"udp_over_stream": false,
|
||||
"tls": {},
|
||||
"brutal_debug": false,
|
||||
|
||||
@ -70,6 +71,15 @@ QUIC 流量混淆器密码.
|
||||
|
||||
默认所有。
|
||||
|
||||
#### udp_over_stream
|
||||
|
||||
这是 Hysteria2 版本的 [UDP over TCP protocol](/configuration/shared/udp-over-tcp), 设计为提供一个Hysteria2没有的,
|
||||
基于QUIC stream的UDP中继模式。由于这是一个附加的协议,你需要使用
|
||||
sing-box 或者与这个协议兼容的其他软件作为服务器。
|
||||
|
||||
这个协议可以增加在恶劣环境代理UDP的可靠性,因为它支持使用
|
||||
QUIC 的丢失检测机制重传丢失的数据包。
|
||||
|
||||
#### tls
|
||||
|
||||
==必填==
|
||||
|
@ -4,6 +4,7 @@ package inbound
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/sagernet/sing-box/common/uot"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
@ -81,7 +82,7 @@ func NewHysteria2(ctx context.Context, router adapter.Router, logger log.Context
|
||||
protocol: C.TypeHysteria2,
|
||||
network: []string{N.NetworkUDP},
|
||||
ctx: ctx,
|
||||
router: router,
|
||||
router: uot.NewRouter(router, logger),
|
||||
logger: logger,
|
||||
tag: tag,
|
||||
listenOptions: options.ListenOptions,
|
||||
|
@ -31,5 +31,6 @@ type Hysteria2OutboundOptions struct {
|
||||
Password string `json:"password,omitempty"`
|
||||
Network NetworkList `json:"network,omitempty"`
|
||||
OutboundTLSOptionsContainer
|
||||
UDPOverStream bool `json:"udp_over_stream,omitempty"`
|
||||
BrutalDebug bool `json:"brutal_debug,omitempty"`
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ package outbound
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/sagernet/sing/common/uot"
|
||||
"net"
|
||||
"os"
|
||||
|
||||
@ -29,7 +30,8 @@ var (
|
||||
|
||||
type Hysteria2 struct {
|
||||
myOutboundAdapter
|
||||
client *hysteria2.Client
|
||||
client *hysteria2.Client
|
||||
udpStream bool
|
||||
}
|
||||
|
||||
func NewHysteria2(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.Hysteria2OutboundOptions) (*Hysteria2, error) {
|
||||
@ -83,7 +85,8 @@ func NewHysteria2(ctx context.Context, router adapter.Router, logger log.Context
|
||||
tag: tag,
|
||||
dependencies: withDialerDependency(options.DialerOptions),
|
||||
},
|
||||
client: client,
|
||||
client: client,
|
||||
udpStream: options.UDPOverStream,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -93,19 +96,43 @@ func (h *Hysteria2) DialContext(ctx context.Context, network string, destination
|
||||
h.logger.InfoContext(ctx, "outbound connection to ", destination)
|
||||
return h.client.DialConn(ctx, destination)
|
||||
case N.NetworkUDP:
|
||||
conn, err := h.ListenPacket(ctx, destination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if h.udpStream {
|
||||
h.logger.InfoContext(ctx, "outbound stream packet connection to ", destination)
|
||||
streamConn, err := h.client.DialConn(ctx, uot.RequestDestination(uot.Version))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uot.NewLazyConn(streamConn, uot.Request{
|
||||
IsConnect: true,
|
||||
Destination: destination,
|
||||
}), nil
|
||||
} else {
|
||||
conn, err := h.ListenPacket(ctx, destination)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bufio.NewBindPacketConn(conn, destination), nil
|
||||
}
|
||||
return bufio.NewBindPacketConn(conn, destination), nil
|
||||
default:
|
||||
return nil, E.New("unsupported network: ", network)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Hysteria2) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||
h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
return h.client.ListenPacket(ctx)
|
||||
if h.udpStream {
|
||||
h.logger.InfoContext(ctx, "outbound stream packet connection to ", destination)
|
||||
streamConn, err := h.client.DialConn(ctx, uot.RequestDestination(uot.Version))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return uot.NewLazyConn(streamConn, uot.Request{
|
||||
IsConnect: false,
|
||||
Destination: destination,
|
||||
}), nil
|
||||
} else {
|
||||
h.logger.InfoContext(ctx, "outbound packet connection to ", destination)
|
||||
return h.client.ListenPacket(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Hysteria2) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
|
||||
|
Loading…
x
Reference in New Issue
Block a user