Refactor: HTTP clients, unified HTTP2/QUIC options, Apple engines
This commit is contained in:
@@ -77,15 +77,9 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
ReceiveBPS: receiveBps,
|
||||
XPlusPassword: options.Obfs,
|
||||
TLSConfig: tlsConfig,
|
||||
QUICOptions: buildInboundQUICOptions(options),
|
||||
UDPTimeout: udpTimeout,
|
||||
Handler: inbound,
|
||||
|
||||
// Legacy options
|
||||
|
||||
ConnReceiveWindow: options.ReceiveWindowConn,
|
||||
StreamReceiveWindow: options.ReceiveWindowClient,
|
||||
MaxIncomingStreams: int64(options.MaxConnClient),
|
||||
DisableMTUDiscovery: options.DisableMTUDiscovery,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -70,21 +70,19 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
receiveBps = uint64(options.DownMbps) * hysteria.MbpsToBps
|
||||
}
|
||||
client, err := hysteria.NewClient(hysteria.ClientOptions{
|
||||
Context: ctx,
|
||||
Dialer: outboundDialer,
|
||||
Logger: logger,
|
||||
ServerAddress: options.ServerOptions.Build(),
|
||||
ServerPorts: options.ServerPorts,
|
||||
HopInterval: time.Duration(options.HopInterval),
|
||||
SendBPS: sendBps,
|
||||
ReceiveBPS: receiveBps,
|
||||
XPlusPassword: options.Obfs,
|
||||
Password: password,
|
||||
TLSConfig: tlsConfig,
|
||||
UDPDisabled: !common.Contains(networkList, N.NetworkUDP),
|
||||
ConnReceiveWindow: options.ReceiveWindowConn,
|
||||
StreamReceiveWindow: options.ReceiveWindow,
|
||||
DisableMTUDiscovery: options.DisableMTUDiscovery,
|
||||
Context: ctx,
|
||||
Dialer: outboundDialer,
|
||||
Logger: logger,
|
||||
ServerAddress: options.ServerOptions.Build(),
|
||||
ServerPorts: options.ServerPorts,
|
||||
HopInterval: time.Duration(options.HopInterval),
|
||||
SendBPS: sendBps,
|
||||
ReceiveBPS: receiveBps,
|
||||
XPlusPassword: options.Obfs,
|
||||
Password: password,
|
||||
TLSConfig: tlsConfig,
|
||||
QUICOptions: buildOutboundQUICOptions(options),
|
||||
UDPDisabled: !common.Contains(networkList, N.NetworkUDP),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package hysteria
|
||||
|
||||
import (
|
||||
"github.com/sagernet/sing-box/option"
|
||||
qtls "github.com/sagernet/sing-quic"
|
||||
)
|
||||
|
||||
func buildBaseQUICOptions(options option.QUICOptions) qtls.QUICOptions {
|
||||
return qtls.QUICOptions{
|
||||
IdleTimeout: options.IdleTimeout.Build(),
|
||||
KeepAlivePeriod: options.KeepAlivePeriod.Build(),
|
||||
StreamReceiveWindow: options.StreamReceiveWindow.Value(),
|
||||
ConnectionReceiveWindow: options.ConnectionReceiveWindow.Value(),
|
||||
MaxConcurrentStreams: options.MaxConcurrentStreams,
|
||||
InitialPacketSize: options.InitialPacketSize,
|
||||
DisablePathMTUDiscovery: options.DisablePathMTUDiscovery,
|
||||
}
|
||||
}
|
||||
|
||||
func buildInboundQUICOptions(options option.HysteriaInboundOptions) qtls.QUICOptions {
|
||||
quicOptions := buildBaseQUICOptions(options.QUICOptions)
|
||||
if quicOptions.ConnectionReceiveWindow == 0 {
|
||||
quicOptions.ConnectionReceiveWindow = options.ReceiveWindowConn //nolint:staticcheck
|
||||
}
|
||||
if quicOptions.StreamReceiveWindow == 0 {
|
||||
quicOptions.StreamReceiveWindow = options.ReceiveWindowClient //nolint:staticcheck
|
||||
}
|
||||
if quicOptions.MaxConcurrentStreams == 0 {
|
||||
quicOptions.MaxConcurrentStreams = options.MaxConnClient //nolint:staticcheck
|
||||
}
|
||||
if !quicOptions.DisablePathMTUDiscovery {
|
||||
quicOptions.DisablePathMTUDiscovery = options.DisableMTUDiscovery //nolint:staticcheck
|
||||
}
|
||||
return quicOptions
|
||||
}
|
||||
|
||||
func buildOutboundQUICOptions(options option.HysteriaOutboundOptions) qtls.QUICOptions {
|
||||
quicOptions := buildBaseQUICOptions(options.QUICOptions)
|
||||
if quicOptions.ConnectionReceiveWindow == 0 {
|
||||
quicOptions.ConnectionReceiveWindow = options.ReceiveWindowConn //nolint:staticcheck
|
||||
}
|
||||
if quicOptions.StreamReceiveWindow == 0 {
|
||||
quicOptions.StreamReceiveWindow = options.ReceiveWindow //nolint:staticcheck
|
||||
}
|
||||
if !quicOptions.DisablePathMTUDiscovery {
|
||||
quicOptions.DisablePathMTUDiscovery = options.DisableMTUDiscovery //nolint:staticcheck
|
||||
}
|
||||
return quicOptions
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import (
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
qtls "github.com/sagernet/sing-quic"
|
||||
"github.com/sagernet/sing-quic/hysteria"
|
||||
"github.com/sagernet/sing-quic/hysteria2"
|
||||
"github.com/sagernet/sing/common"
|
||||
@@ -114,13 +115,22 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
udpTimeout = C.UDPTimeout
|
||||
}
|
||||
service, err := hysteria2.NewService[int](hysteria2.ServiceOptions{
|
||||
Context: ctx,
|
||||
Logger: logger,
|
||||
BrutalDebug: options.BrutalDebug,
|
||||
SendBPS: uint64(options.UpMbps * hysteria.MbpsToBps),
|
||||
ReceiveBPS: uint64(options.DownMbps * hysteria.MbpsToBps),
|
||||
SalamanderPassword: salamanderPassword,
|
||||
TLSConfig: tlsConfig,
|
||||
Context: ctx,
|
||||
Logger: logger,
|
||||
BrutalDebug: options.BrutalDebug,
|
||||
SendBPS: uint64(options.UpMbps * hysteria.MbpsToBps),
|
||||
ReceiveBPS: uint64(options.DownMbps * hysteria.MbpsToBps),
|
||||
SalamanderPassword: salamanderPassword,
|
||||
TLSConfig: tlsConfig,
|
||||
QUICOptions: qtls.QUICOptions{
|
||||
IdleTimeout: options.IdleTimeout.Build(),
|
||||
KeepAlivePeriod: options.KeepAlivePeriod.Build(),
|
||||
StreamReceiveWindow: options.StreamReceiveWindow.Value(),
|
||||
ConnectionReceiveWindow: options.ConnectionReceiveWindow.Value(),
|
||||
MaxConcurrentStreams: options.MaxConcurrentStreams,
|
||||
InitialPacketSize: options.InitialPacketSize,
|
||||
DisablePathMTUDiscovery: options.DisablePathMTUDiscovery,
|
||||
},
|
||||
IgnoreClientBandwidth: options.IgnoreClientBandwidth,
|
||||
UDPTimeout: udpTimeout,
|
||||
Handler: inbound,
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing-box/protocol/tuic"
|
||||
qtls "github.com/sagernet/sing-quic"
|
||||
"github.com/sagernet/sing-quic/hysteria"
|
||||
"github.com/sagernet/sing-quic/hysteria2"
|
||||
"github.com/sagernet/sing/common"
|
||||
@@ -79,8 +80,17 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
SalamanderPassword: salamanderPassword,
|
||||
Password: options.Password,
|
||||
TLSConfig: tlsConfig,
|
||||
UDPDisabled: !common.Contains(networkList, N.NetworkUDP),
|
||||
BBRProfile: options.BBRProfile,
|
||||
QUICOptions: qtls.QUICOptions{
|
||||
IdleTimeout: options.IdleTimeout.Build(),
|
||||
KeepAlivePeriod: options.KeepAlivePeriod.Build(),
|
||||
StreamReceiveWindow: options.StreamReceiveWindow.Value(),
|
||||
ConnectionReceiveWindow: options.ConnectionReceiveWindow.Value(),
|
||||
MaxConcurrentStreams: options.MaxConcurrentStreams,
|
||||
InitialPacketSize: options.InitialPacketSize,
|
||||
DisablePathMTUDiscovery: options.DisablePathMTUDiscovery,
|
||||
},
|
||||
UDPDisabled: !common.Contains(networkList, N.NetworkUDP),
|
||||
BBRProfile: options.BBRProfile,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -39,9 +39,6 @@ func NewCertificateProvider(ctx context.Context, _ log.ContextLogger, tag string
|
||||
return nil, E.New("missing tailscale endpoint tag")
|
||||
}
|
||||
endpointManager := service.FromContext[adapter.EndpointManager](ctx)
|
||||
if endpointManager == nil {
|
||||
return nil, E.New("missing endpoint manager in context")
|
||||
}
|
||||
rawEndpoint, loaded := endpointManager.Get(options.Endpoint)
|
||||
if !loaded {
|
||||
return nil, E.New("endpoint not found: ", options.Endpoint)
|
||||
|
||||
@@ -4,7 +4,6 @@ package tailscale
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -28,6 +27,7 @@ import (
|
||||
"github.com/sagernet/sing-box/adapter/endpoint"
|
||||
"github.com/sagernet/sing-box/common/dialer"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/experimental/deprecated"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing-box/route/rule"
|
||||
@@ -41,7 +41,6 @@ import (
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/sing/common/ntp"
|
||||
"github.com/sagernet/sing/service"
|
||||
"github.com/sagernet/sing/service/filemanager"
|
||||
tailscaleroot "github.com/sagernet/tailscale"
|
||||
@@ -199,6 +198,19 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
// controlplane.tailscale.com
|
||||
remoteIsDomain = true
|
||||
}
|
||||
hasLegacyDialer := !reflect.DeepEqual(options.DialerOptions, option.DialerOptions{})
|
||||
hasControlHTTPClient := options.ControlHTTPClient != nil && !options.ControlHTTPClient.IsEmpty()
|
||||
if hasLegacyDialer && hasControlHTTPClient {
|
||||
return nil, E.New("control_http_client is conflict with deprecated dialer options")
|
||||
}
|
||||
controlHTTPClientOptions := common.PtrValueOrDefault(options.ControlHTTPClient)
|
||||
if hasLegacyDialer {
|
||||
deprecated.Report(ctx, deprecated.OptionLegacyTailscaleEndpointDialer)
|
||||
controlHTTPClientOptions.DialerOptions = options.DialerOptions
|
||||
}
|
||||
if remoteIsDomain {
|
||||
controlHTTPClientOptions.ResolveOnDetour = true
|
||||
}
|
||||
outboundDialer, err := dialer.NewWithOptions(dialer.Options{
|
||||
Context: ctx,
|
||||
Options: options.DialerOptions,
|
||||
@@ -210,6 +222,12 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
dnsRouter := service.FromContext[adapter.DNSRouter](ctx)
|
||||
httpClientManager := service.FromContext[adapter.HTTPClientManager](ctx)
|
||||
controlTransport, err := httpClientManager.ResolveTransport(ctx, logger, controlHTTPClientOptions)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "create control HTTP client")
|
||||
}
|
||||
controlHTTPClient := &http.Client{Transport: controlTransport}
|
||||
server := &tsnet.Server{
|
||||
Dir: stateDirectory,
|
||||
Hostname: hostname,
|
||||
@@ -227,19 +245,8 @@ func NewEndpoint(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
LookupHook: func(ctx context.Context, host string) ([]netip.Addr, error) {
|
||||
return dnsRouter.Lookup(ctx, host, outboundDialer.(dialer.ResolveDialer).QueryOptions())
|
||||
},
|
||||
DNS: &dnsConfigurtor{},
|
||||
HTTPClient: &http.Client{
|
||||
Transport: &http.Transport{
|
||||
ForceAttemptHTTP2: true,
|
||||
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
return outboundDialer.DialContext(ctx, network, M.ParseSocksaddr(address))
|
||||
},
|
||||
TLSClientConfig: &tls.Config{
|
||||
RootCAs: adapter.RootPoolFromContext(ctx),
|
||||
Time: ntp.TimeFuncFromContext(ctx),
|
||||
},
|
||||
},
|
||||
},
|
||||
DNS: &dnsConfigurtor{},
|
||||
HTTPClient: controlHTTPClient,
|
||||
}
|
||||
return &Endpoint{
|
||||
Adapter: endpoint.NewAdapter(C.TypeTailscale, tag, []string{N.NetworkTCP, N.NetworkUDP, N.NetworkICMP}, nil),
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/adapter/outbound"
|
||||
"github.com/sagernet/sing-box/common/dialer"
|
||||
"github.com/sagernet/sing-box/common/proxybridge"
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
@@ -34,7 +35,7 @@ type Outbound struct {
|
||||
outbound.Adapter
|
||||
ctx context.Context
|
||||
logger logger.ContextLogger
|
||||
proxy *ProxyListener
|
||||
proxy *proxybridge.Bridge
|
||||
startConf *tor.StartConf
|
||||
options map[string]string
|
||||
events chan control.Event
|
||||
@@ -79,11 +80,15 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
proxy, err := proxybridge.New(ctx, logger, "proxy", outboundDialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Outbound{
|
||||
Adapter: outbound.NewAdapterWithDialerOptions(C.TypeTor, tag, []string{N.NetworkTCP}, options.DialerOptions),
|
||||
ctx: ctx,
|
||||
logger: logger,
|
||||
proxy: NewProxyListener(ctx, logger, outboundDialer),
|
||||
proxy: proxy,
|
||||
startConf: &startConf,
|
||||
options: options.Options,
|
||||
}, nil
|
||||
@@ -117,10 +122,6 @@ func (t *Outbound) start() error {
|
||||
return err
|
||||
}
|
||||
go t.recvLoop()
|
||||
err = t.proxy.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
proxyPort := "127.0.0.1:" + F.ToString(t.proxy.Port())
|
||||
proxyUsername := t.proxy.Username()
|
||||
proxyPassword := t.proxy.Password()
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
package tor
|
||||
|
||||
import (
|
||||
std_bufio "bufio"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"net"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/auth"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/sing/protocol/socks"
|
||||
"github.com/sagernet/sing/service"
|
||||
)
|
||||
|
||||
type ProxyListener struct {
|
||||
ctx context.Context
|
||||
logger log.ContextLogger
|
||||
dialer N.Dialer
|
||||
connection adapter.ConnectionManager
|
||||
tcpListener *net.TCPListener
|
||||
username string
|
||||
password string
|
||||
authenticator *auth.Authenticator
|
||||
}
|
||||
|
||||
func NewProxyListener(ctx context.Context, logger log.ContextLogger, dialer N.Dialer) *ProxyListener {
|
||||
var usernameB [64]byte
|
||||
var passwordB [64]byte
|
||||
rand.Read(usernameB[:])
|
||||
rand.Read(passwordB[:])
|
||||
username := hex.EncodeToString(usernameB[:])
|
||||
password := hex.EncodeToString(passwordB[:])
|
||||
return &ProxyListener{
|
||||
ctx: ctx,
|
||||
logger: logger,
|
||||
dialer: dialer,
|
||||
connection: service.FromContext[adapter.ConnectionManager](ctx),
|
||||
authenticator: auth.NewAuthenticator([]auth.User{{Username: username, Password: password}}),
|
||||
username: username,
|
||||
password: password,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ProxyListener) Start() error {
|
||||
tcpListener, err := net.ListenTCP("tcp", &net.TCPAddr{
|
||||
IP: net.IPv4(127, 0, 0, 1),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l.tcpListener = tcpListener
|
||||
go l.acceptLoop()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *ProxyListener) Port() uint16 {
|
||||
if l.tcpListener == nil {
|
||||
panic("start listener first")
|
||||
}
|
||||
return M.SocksaddrFromNet(l.tcpListener.Addr()).Port
|
||||
}
|
||||
|
||||
func (l *ProxyListener) Username() string {
|
||||
return l.username
|
||||
}
|
||||
|
||||
func (l *ProxyListener) Password() string {
|
||||
return l.password
|
||||
}
|
||||
|
||||
func (l *ProxyListener) Close() error {
|
||||
return common.Close(l.tcpListener)
|
||||
}
|
||||
|
||||
func (l *ProxyListener) acceptLoop() {
|
||||
for {
|
||||
tcpConn, err := l.tcpListener.AcceptTCP()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ctx := log.ContextWithNewID(l.ctx)
|
||||
go func() {
|
||||
hErr := l.accept(ctx, tcpConn)
|
||||
if hErr != nil {
|
||||
if E.IsClosedOrCanceled(hErr) {
|
||||
l.logger.DebugContext(ctx, E.Cause(hErr, "proxy connection closed"))
|
||||
return
|
||||
}
|
||||
l.logger.ErrorContext(ctx, E.Cause(hErr, "proxy"))
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ProxyListener) accept(ctx context.Context, conn *net.TCPConn) error {
|
||||
return socks.HandleConnectionEx(ctx, conn, std_bufio.NewReader(conn), l.authenticator, l, nil, 0, M.SocksaddrFromNet(conn.RemoteAddr()), nil)
|
||||
}
|
||||
|
||||
func (l *ProxyListener) NewConnectionEx(ctx context.Context, conn net.Conn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Source = source
|
||||
metadata.Destination = destination
|
||||
metadata.Network = N.NetworkTCP
|
||||
l.logger.InfoContext(ctx, "proxy connection to ", metadata.Destination)
|
||||
l.connection.NewConnection(ctx, l.dialer, conn, metadata, onClose)
|
||||
}
|
||||
|
||||
func (l *ProxyListener) NewPacketConnectionEx(ctx context.Context, conn N.PacketConn, source M.Socksaddr, destination M.Socksaddr, onClose N.CloseHandlerFunc) {
|
||||
var metadata adapter.InboundContext
|
||||
metadata.Source = source
|
||||
metadata.Destination = destination
|
||||
metadata.Network = N.NetworkUDP
|
||||
l.logger.InfoContext(ctx, "proxy packet connection to ", metadata.Destination)
|
||||
l.connection.NewPacketConnection(ctx, l.dialer, conn, metadata, onClose)
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
qtls "github.com/sagernet/sing-quic"
|
||||
"github.com/sagernet/sing-quic/tuic"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/auth"
|
||||
@@ -64,9 +65,18 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
udpTimeout = C.UDPTimeout
|
||||
}
|
||||
service, err := tuic.NewService[int](tuic.ServiceOptions{
|
||||
Context: ctx,
|
||||
Logger: logger,
|
||||
TLSConfig: tlsConfig,
|
||||
Context: ctx,
|
||||
Logger: logger,
|
||||
TLSConfig: tlsConfig,
|
||||
QUICOptions: qtls.QUICOptions{
|
||||
IdleTimeout: options.IdleTimeout.Build(),
|
||||
KeepAlivePeriod: options.KeepAlivePeriod.Build(),
|
||||
StreamReceiveWindow: options.StreamReceiveWindow.Value(),
|
||||
ConnectionReceiveWindow: options.ConnectionReceiveWindow.Value(),
|
||||
MaxConcurrentStreams: options.MaxConcurrentStreams,
|
||||
InitialPacketSize: options.InitialPacketSize,
|
||||
DisablePathMTUDiscovery: options.DisablePathMTUDiscovery,
|
||||
},
|
||||
CongestionControl: options.CongestionControl,
|
||||
AuthTimeout: time.Duration(options.AuthTimeout),
|
||||
ZeroRTTHandshake: options.ZeroRTTHandshake,
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
C "github.com/sagernet/sing-box/constant"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
qtls "github.com/sagernet/sing-quic"
|
||||
"github.com/sagernet/sing-quic/tuic"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/bufio"
|
||||
@@ -65,10 +66,19 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
return nil, err
|
||||
}
|
||||
client, err := tuic.NewClient(tuic.ClientOptions{
|
||||
Context: ctx,
|
||||
Dialer: outboundDialer,
|
||||
ServerAddress: options.ServerOptions.Build(),
|
||||
TLSConfig: tlsConfig,
|
||||
Context: ctx,
|
||||
Dialer: outboundDialer,
|
||||
ServerAddress: options.ServerOptions.Build(),
|
||||
TLSConfig: tlsConfig,
|
||||
QUICOptions: qtls.QUICOptions{
|
||||
IdleTimeout: options.IdleTimeout.Build(),
|
||||
KeepAlivePeriod: options.KeepAlivePeriod.Build(),
|
||||
StreamReceiveWindow: options.StreamReceiveWindow.Value(),
|
||||
ConnectionReceiveWindow: options.ConnectionReceiveWindow.Value(),
|
||||
MaxConcurrentStreams: options.MaxConcurrentStreams,
|
||||
InitialPacketSize: options.InitialPacketSize,
|
||||
DisablePathMTUDiscovery: options.DisablePathMTUDiscovery,
|
||||
},
|
||||
UUID: userUUID,
|
||||
Password: options.Password,
|
||||
CongestionControl: options.CongestionControl,
|
||||
|
||||
Reference in New Issue
Block a user