mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-07-07 17:01:36 +03:00
Add Snell protocol. Refactor MASQUE HTTP/2, Fair Queue. Update XHTTP, OpenVPN, Sudoku, Fallback. Fixes
This commit is contained in:
@@ -16,12 +16,12 @@ import (
|
||||
"github.com/sagernet/quic-go"
|
||||
"github.com/sagernet/quic-go/http3"
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
"github.com/sagernet/sing-box/common/congestion"
|
||||
"github.com/sagernet/sing-box/common/tls"
|
||||
"github.com/sagernet/sing-box/common/xray/buf"
|
||||
"github.com/sagernet/sing-box/common/xray/net"
|
||||
"github.com/sagernet/sing-box/common/xray/pipe"
|
||||
"github.com/sagernet/sing-box/common/xray/signal/done"
|
||||
"github.com/sagernet/sing-box/common/xray/uuid"
|
||||
"github.com/sagernet/sing-box/log"
|
||||
"github.com/sagernet/sing-box/option"
|
||||
qtls "github.com/sagernet/sing-quic"
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
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/common/ntp"
|
||||
sHTTP "github.com/sagernet/sing/protocol/http"
|
||||
"github.com/sagernet/sing/service"
|
||||
"golang.org/x/net/http2"
|
||||
@@ -42,15 +43,22 @@ type Client struct {
|
||||
baseRequestURL2 url.URL
|
||||
getHTTPClient func() (DialerClient, *XmuxClient)
|
||||
getHTTPClient2 func() (DialerClient, *XmuxClient)
|
||||
xmuxManager *XmuxManager
|
||||
xmuxManager2 *XmuxManager
|
||||
}
|
||||
|
||||
func NewClient(ctx context.Context, logger log.ContextLogger, dialer N.Dialer, serverAddr M.Socksaddr, options option.V2RayXHTTPOptions, tlsConfig tls.Config) (adapter.V2RayClientTransport, error) {
|
||||
if options.Mode == "" {
|
||||
return nil, E.New("mode is not set")
|
||||
}
|
||||
if tlsConfig != nil && len(tlsConfig.NextProtos()) == 0 {
|
||||
tlsConfig.SetNextProtos([]string{"h2"})
|
||||
}
|
||||
if _, err := congestion.NewCongestionControl(options.CongestionController, options.CWND, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if options.Download != nil {
|
||||
if _, err := congestion.NewCongestionControl(options.Download.CongestionController, options.Download.CWND, nil); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
dest := serverAddr
|
||||
baseRequestURL, err := getBaseRequestURL(&options.V2RayXHTTPBaseOptions, dest, tlsConfig)
|
||||
if err != nil {
|
||||
@@ -61,7 +69,7 @@ func NewClient(ctx context.Context, logger log.ContextLogger, dialer N.Dialer, s
|
||||
xmuxOptions = *options.Xmux
|
||||
}
|
||||
xmuxManager := NewXmuxManager(xmuxOptions, func() XmuxConn {
|
||||
return createHTTPClient(dest, dialer, &options.V2RayXHTTPBaseOptions, tlsConfig)
|
||||
return createHTTPClient(ctx, dest, dialer, &options.V2RayXHTTPBaseOptions, tlsConfig)
|
||||
})
|
||||
getHTTPClient := func() (DialerClient, *XmuxClient) {
|
||||
xmuxClient := xmuxManager.GetXmuxClient(ctx)
|
||||
@@ -69,6 +77,7 @@ func NewClient(ctx context.Context, logger log.ContextLogger, dialer N.Dialer, s
|
||||
}
|
||||
baseRequestURL2 := baseRequestURL
|
||||
getHTTPClient2 := getHTTPClient
|
||||
var xmuxManager2 *XmuxManager
|
||||
if options.Download != nil {
|
||||
options2 := options.Download
|
||||
dialer2 := dialer
|
||||
@@ -98,8 +107,8 @@ func NewClient(ctx context.Context, logger log.ContextLogger, dialer N.Dialer, s
|
||||
if options2.Xmux != nil {
|
||||
xmuxOptions2 = *options2.Xmux
|
||||
}
|
||||
xmuxManager2 := NewXmuxManager(xmuxOptions2, func() XmuxConn {
|
||||
return createHTTPClient(dest2, dialer2, &options2.V2RayXHTTPBaseOptions, tlsConfig2)
|
||||
xmuxManager2 = NewXmuxManager(xmuxOptions2, func() XmuxConn {
|
||||
return createHTTPClient(ctx, dest2, dialer2, &options2.V2RayXHTTPBaseOptions, tlsConfig2)
|
||||
})
|
||||
getHTTPClient2 = func() (DialerClient, *XmuxClient) {
|
||||
xmuxClient2 := xmuxManager2.GetXmuxClient(ctx)
|
||||
@@ -113,6 +122,8 @@ func NewClient(ctx context.Context, logger log.ContextLogger, dialer N.Dialer, s
|
||||
getHTTPClient2: getHTTPClient2,
|
||||
baseRequestURL: baseRequestURL,
|
||||
baseRequestURL2: baseRequestURL2,
|
||||
xmuxManager: xmuxManager,
|
||||
xmuxManager2: xmuxManager2,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -121,8 +132,7 @@ func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
|
||||
mode := c.options.Mode
|
||||
sessionId := ""
|
||||
if c.options.Mode != "stream-one" {
|
||||
sessionIdUuid := uuid.New()
|
||||
sessionId = sessionIdUuid.String()
|
||||
sessionId = GenerateSessionID(&c.options.V2RayXHTTPBaseOptions)
|
||||
}
|
||||
requestURL := c.baseRequestURL
|
||||
requestURL2 := c.baseRequestURL2
|
||||
@@ -182,10 +192,7 @@ func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
|
||||
}
|
||||
scMaxEachPostBytes := options.GetNormalizedScMaxEachPostBytes()
|
||||
scMinPostsIntervalMs := options.GetNormalizedScMinPostsIntervalMs()
|
||||
if scMaxEachPostBytes.From <= 0 {
|
||||
panic("`scMaxEachPostBytes` should be bigger than 0")
|
||||
}
|
||||
maxUploadSize := scMaxEachPostBytes.Rand()
|
||||
maxUploadSize := int32(scMaxEachPostBytes.Rand())
|
||||
// WithSizeLimit(0) will still allow single bytes to pass, and a lot of
|
||||
// code relies on this behavior. Subtract 1 so that together with
|
||||
// uploadWriter wrapper, exact size limits can be enforced
|
||||
@@ -255,6 +262,10 @@ func (c *Client) DialContext(ctx context.Context) (net.Conn, error) {
|
||||
}
|
||||
|
||||
func (c *Client) Close() error {
|
||||
c.xmuxManager.Close()
|
||||
if c.xmuxManager2 != nil {
|
||||
c.xmuxManager2.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -294,7 +305,7 @@ func getBaseRequestURL(options *option.V2RayXHTTPBaseOptions, dest M.Socksaddr,
|
||||
return requestURL, nil
|
||||
}
|
||||
|
||||
func createHTTPClient(dest M.Socksaddr, dialer N.Dialer, options *option.V2RayXHTTPBaseOptions, tlsConfig tls.Config) DialerClient {
|
||||
func createHTTPClient(ctx context.Context, dest M.Socksaddr, dialer N.Dialer, options *option.V2RayXHTTPBaseOptions, tlsConfig tls.Config) DialerClient {
|
||||
httpVersion := decideHTTPVersion(tlsConfig)
|
||||
dialContext := func(ctxInner context.Context) (net.Conn, error) {
|
||||
conn, err := dialer.DialContext(ctxInner, "tcp", dest)
|
||||
@@ -319,6 +330,7 @@ func createHTTPClient(dest M.Socksaddr, dialer N.Dialer, options *option.V2RayXH
|
||||
if keepAlivePeriod < 0 {
|
||||
keepAlivePeriod = 0
|
||||
}
|
||||
congestionControlFactory, _ := congestion.NewCongestionControl(options.CongestionController, options.CWND, ntp.TimeFuncFromContext(ctx))
|
||||
quicConfig := &quic.Config{
|
||||
MaxIdleTimeout: net.ConnIdleTimeout,
|
||||
// these two are defaults of quic-go/http3. the default of quic-go (no
|
||||
@@ -334,7 +346,14 @@ func createHTTPClient(dest M.Socksaddr, dialer N.Dialer, options *option.V2RayXH
|
||||
if dErr != nil {
|
||||
return nil, dErr
|
||||
}
|
||||
return qtls.DialEarly(ctx, bufio.NewUnbindPacketConn(udpConn), udpConn.RemoteAddr(), tlsConfig, cfg)
|
||||
conn, dErr := qtls.DialEarly(ctx, bufio.NewUnbindPacketConn(udpConn), udpConn.RemoteAddr(), tlsConfig, cfg)
|
||||
if dErr != nil {
|
||||
return nil, dErr
|
||||
}
|
||||
if congestionControlFactory != nil {
|
||||
conn.SetCongestionControl(congestionControlFactory(conn))
|
||||
}
|
||||
return conn, nil
|
||||
},
|
||||
}
|
||||
case "2":
|
||||
|
||||
Reference in New Issue
Block a user