First Commmit
This commit is contained in:
128
protocol/naive/quic/inbound_init.go
Normal file
128
protocol/naive/quic/inbound_init.go
Normal file
@@ -0,0 +1,128 @@
|
||||
package quic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"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/log"
|
||||
"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(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
|
||||
}
|
||||
|
||||
udpConn, err := listener.ListenUDP()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var congestionControl func(conn *quic.Conn) congestion.CongestionControl
|
||||
timeFunc := ntp.TimeFuncFromContext(ctx)
|
||||
if timeFunc == nil {
|
||||
timeFunc = time.Now
|
||||
}
|
||||
switch options.QUICCongestionControl {
|
||||
case "", "bbr":
|
||||
congestionControl = func(conn *quic.Conn) congestion.CongestionControl {
|
||||
return congestion_meta2.NewBbrSender(
|
||||
congestion_meta2.DefaultClock{TimeFunc: timeFunc},
|
||||
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: timeFunc},
|
||||
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: timeFunc},
|
||||
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: timeFunc},
|
||||
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: timeFunc},
|
||||
congestion.ByteCount(conn.Config().InitialPacketSize),
|
||||
false,
|
||||
)
|
||||
}
|
||||
case "reno":
|
||||
congestionControl = func(conn *quic.Conn) congestion.CongestionControl {
|
||||
return congestion_meta1.NewCubicSender(
|
||||
congestion_meta1.DefaultClock{TimeFunc: timeFunc},
|
||||
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,
|
||||
})
|
||||
if err != nil {
|
||||
udpConn.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
h3Server := &http3.Server{
|
||||
Handler: handler,
|
||||
ConnContext: func(ctx context.Context, conn *quic.Conn) context.Context {
|
||||
conn.SetCongestionControl(congestionControl(conn))
|
||||
return log.ContextWithNewID(ctx)
|
||||
},
|
||||
}
|
||||
|
||||
go func() {
|
||||
sErr := h3Server.ServeListener(quicListener)
|
||||
udpConn.Close()
|
||||
if sErr != nil && !E.IsClosedOrCanceled(sErr) {
|
||||
logger.Error("http3 server closed: ", sErr)
|
||||
}
|
||||
}()
|
||||
|
||||
return quicListener, nil
|
||||
}
|
||||
naive.WrapError = qtls.WrapError
|
||||
}
|
||||
Reference in New Issue
Block a user