mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-04-17 13:23:06 +10:00
Add QUIC support for naiveproxy
This commit is contained in:
@@ -29,7 +29,7 @@ import (
|
||||
"golang.org/x/net/http2/h2c"
|
||||
)
|
||||
|
||||
var ConfigureHTTP3ListenerFunc func(listener *listener.Listener, handler http.Handler, tlsConfig tls.ServerConfig, logger logger.Logger) (io.Closer, error)
|
||||
var ConfigureHTTP3ListenerFunc func(ctx context.Context, logger logger.Logger, listener *listener.Listener, handler http.Handler, tlsConfig tls.ServerConfig, options option.NaiveInboundOptions) (io.Closer, error)
|
||||
|
||||
func RegisterInbound(registry *inbound.Registry) {
|
||||
inbound.Register[option.NaiveInboundOptions](registry, C.TypeNaive, NewInbound)
|
||||
@@ -40,6 +40,7 @@ type Inbound struct {
|
||||
ctx context.Context
|
||||
router adapter.ConnectionRouterEx
|
||||
logger logger.ContextLogger
|
||||
options option.NaiveInboundOptions
|
||||
listener *listener.Listener
|
||||
network []string
|
||||
networkIsDefault bool
|
||||
@@ -121,7 +122,7 @@ func (n *Inbound) Start(stage adapter.StartStage) error {
|
||||
}
|
||||
|
||||
if common.Contains(n.network, N.NetworkUDP) {
|
||||
http3Server, err := ConfigureHTTP3ListenerFunc(n.listener, n, n.tlsConfig, n.logger)
|
||||
http3Server, err := ConfigureHTTP3ListenerFunc(n.ctx, n.logger, n.listener, n, n.tlsConfig, n.options)
|
||||
if err == nil {
|
||||
n.h3Server = http3Server
|
||||
} else if len(n.network) > 1 {
|
||||
|
||||
@@ -160,7 +160,21 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
echConfigList = block.Bytes
|
||||
}
|
||||
}
|
||||
|
||||
var quicCongestionControl cronet.QUICCongestionControl
|
||||
switch options.QUICCongestionControl {
|
||||
case "":
|
||||
quicCongestionControl = cronet.QUICCongestionControlDefault
|
||||
case "bbr":
|
||||
quicCongestionControl = cronet.QUICCongestionControlBBR
|
||||
case "bbr2":
|
||||
quicCongestionControl = cronet.QUICCongestionControlBBRv2
|
||||
case "cubic":
|
||||
quicCongestionControl = cronet.QUICCongestionControlCubic
|
||||
case "reno":
|
||||
quicCongestionControl = cronet.QUICCongestionControlReno
|
||||
default:
|
||||
return nil, E.New("unknown quic congestion control: ", options.QUICCongestionControl)
|
||||
}
|
||||
client, err := cronet.NewNaiveClient(cronet.NaiveClientConfig{
|
||||
Context: ctx,
|
||||
ServerAddress: serverAddress,
|
||||
@@ -176,11 +190,12 @@ func NewOutbound(ctx context.Context, router adapter.Router, logger log.ContextL
|
||||
ECHEnabled: echEnabled,
|
||||
ECHConfigList: echConfigList,
|
||||
ECHQueryServerName: echQueryServerName,
|
||||
QUIC: options.QUIC,
|
||||
QUICCongestionControl: quicCongestionControl,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var uotClient *uot.Client
|
||||
uotOptions := common.PtrValueOrDefault(options.UDPOverTCP)
|
||||
if uotOptions.Enabled {
|
||||
|
||||
@@ -1,21 +1,29 @@
|
||||
package quic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/sagernet/quic-go"
|
||||
"github.com/sagernet/quic-go/congestion"
|
||||
"github.com/sagernet/quic-go/http3"
|
||||
"github.com/sagernet/sing-box/common/listener"
|
||||
"github.com/sagernet/sing-box/common/tls"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
"github.com/sagernet/sing-box/protocol/naive"
|
||||
"github.com/sagernet/sing-quic"
|
||||
"github.com/sagernet/sing-quic/congestion_bbr1"
|
||||
"github.com/sagernet/sing-quic/congestion_bbr2"
|
||||
congestion_meta1 "github.com/sagernet/sing-quic/congestion_meta1"
|
||||
congestion_meta2 "github.com/sagernet/sing-quic/congestion_meta2"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
"github.com/sagernet/sing/common/ntp"
|
||||
)
|
||||
|
||||
func init() {
|
||||
naive.ConfigureHTTP3ListenerFunc = func(listener *listener.Listener, handler http.Handler, tlsConfig tls.ServerConfig, logger logger.Logger) (io.Closer, error) {
|
||||
naive.ConfigureHTTP3ListenerFunc = func(ctx context.Context, logger logger.Logger, listener *listener.Listener, handler http.Handler, tlsConfig tls.ServerConfig, options option.NaiveInboundOptions) (io.Closer, error) {
|
||||
err := qtls.ConfigureHTTP3(tlsConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -26,9 +34,67 @@ func init() {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var congestionControl func(conn *quic.Conn) congestion.CongestionControl
|
||||
switch options.QUICCongestionControl {
|
||||
case "", "bbr":
|
||||
congestionControl = func(conn *quic.Conn) congestion.CongestionControl {
|
||||
return congestion_meta2.NewBbrSender(
|
||||
congestion_meta2.DefaultClock{TimeFunc: ntp.TimeFuncFromContext(ctx)},
|
||||
congestion.ByteCount(conn.Config().InitialPacketSize),
|
||||
congestion.ByteCount(congestion_meta1.InitialCongestionWindow),
|
||||
)
|
||||
}
|
||||
case "bbr_standard":
|
||||
congestionControl = func(conn *quic.Conn) congestion.CongestionControl {
|
||||
return congestion_bbr1.NewBbrSender(
|
||||
congestion_bbr1.DefaultClock{TimeFunc: ntp.TimeFuncFromContext(ctx)},
|
||||
congestion.ByteCount(conn.Config().InitialPacketSize),
|
||||
congestion_bbr1.InitialCongestionWindowPackets,
|
||||
congestion_bbr1.MaxCongestionWindowPackets,
|
||||
)
|
||||
}
|
||||
case "bbr2":
|
||||
congestionControl = func(conn *quic.Conn) congestion.CongestionControl {
|
||||
return congestion_bbr2.NewBBR2Sender(
|
||||
congestion_bbr2.DefaultClock{TimeFunc: ntp.TimeFuncFromContext(ctx)},
|
||||
congestion.ByteCount(conn.Config().InitialPacketSize),
|
||||
0,
|
||||
false,
|
||||
)
|
||||
}
|
||||
case "bbr2_variant":
|
||||
congestionControl = func(conn *quic.Conn) congestion.CongestionControl {
|
||||
return congestion_bbr2.NewBBR2Sender(
|
||||
congestion_bbr2.DefaultClock{TimeFunc: ntp.TimeFuncFromContext(ctx)},
|
||||
congestion.ByteCount(conn.Config().InitialPacketSize),
|
||||
32*congestion.ByteCount(conn.Config().InitialPacketSize),
|
||||
true,
|
||||
)
|
||||
}
|
||||
case "cubic":
|
||||
congestionControl = func(conn *quic.Conn) congestion.CongestionControl {
|
||||
return congestion_meta1.NewCubicSender(
|
||||
congestion_meta1.DefaultClock{TimeFunc: ntp.TimeFuncFromContext(ctx)},
|
||||
congestion.ByteCount(conn.Config().InitialPacketSize),
|
||||
false,
|
||||
)
|
||||
}
|
||||
case "reno":
|
||||
congestionControl = func(conn *quic.Conn) congestion.CongestionControl {
|
||||
return congestion_meta1.NewCubicSender(
|
||||
congestion_meta1.DefaultClock{TimeFunc: ntp.TimeFuncFromContext(ctx)},
|
||||
congestion.ByteCount(conn.Config().InitialPacketSize),
|
||||
true,
|
||||
)
|
||||
}
|
||||
default:
|
||||
return nil, E.New("unknown quic congestion control: ", options.QUICCongestionControl)
|
||||
}
|
||||
|
||||
quicListener, err := qtls.ListenEarly(udpConn, tlsConfig, &quic.Config{
|
||||
MaxIncomingStreams: 1 << 60,
|
||||
Allow0RTT: true,
|
||||
MaxIncomingStreams: 1 << 60,
|
||||
Allow0RTT: true,
|
||||
GetCongestionControl: congestionControl,
|
||||
})
|
||||
if err != nil {
|
||||
udpConn.Close()
|
||||
|
||||
Reference in New Issue
Block a user