-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Migrate multiplex and UoT server to inbound &
Add tcp-brutal support for multiplex
- Loading branch information
1 parent
58c0759
commit 2444151
Showing
63 changed files
with
709 additions
and
160 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package adapter | ||
|
||
import ( | ||
"context" | ||
"net" | ||
|
||
"github.com/sagernet/sing/common/logger" | ||
M "github.com/sagernet/sing/common/metadata" | ||
N "github.com/sagernet/sing/common/network" | ||
) | ||
|
||
type ConnectionRouter interface { | ||
RouteConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error | ||
RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error | ||
} | ||
|
||
func NewRouteHandler( | ||
metadata InboundContext, | ||
router ConnectionRouter, | ||
logger logger.ContextLogger, | ||
) UpstreamHandlerAdapter { | ||
return &routeHandlerWrapper{ | ||
metadata: metadata, | ||
router: router, | ||
logger: logger, | ||
} | ||
} | ||
|
||
func NewRouteContextHandler( | ||
router ConnectionRouter, | ||
logger logger.ContextLogger, | ||
) UpstreamHandlerAdapter { | ||
return &routeContextHandlerWrapper{ | ||
router: router, | ||
logger: logger, | ||
} | ||
} | ||
|
||
var _ UpstreamHandlerAdapter = (*routeHandlerWrapper)(nil) | ||
|
||
type routeHandlerWrapper struct { | ||
metadata InboundContext | ||
router ConnectionRouter | ||
logger logger.ContextLogger | ||
} | ||
|
||
func (w *routeHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error { | ||
myMetadata := w.metadata | ||
if metadata.Source.IsValid() { | ||
myMetadata.Source = metadata.Source | ||
} | ||
if metadata.Destination.IsValid() { | ||
myMetadata.Destination = metadata.Destination | ||
} | ||
return w.router.RouteConnection(ctx, conn, myMetadata) | ||
} | ||
|
||
func (w *routeHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error { | ||
myMetadata := w.metadata | ||
if metadata.Source.IsValid() { | ||
myMetadata.Source = metadata.Source | ||
} | ||
if metadata.Destination.IsValid() { | ||
myMetadata.Destination = metadata.Destination | ||
} | ||
return w.router.RoutePacketConnection(ctx, conn, myMetadata) | ||
} | ||
|
||
func (w *routeHandlerWrapper) NewError(ctx context.Context, err error) { | ||
w.logger.ErrorContext(ctx, err) | ||
} | ||
|
||
var _ UpstreamHandlerAdapter = (*routeContextHandlerWrapper)(nil) | ||
|
||
type routeContextHandlerWrapper struct { | ||
router ConnectionRouter | ||
logger logger.ContextLogger | ||
} | ||
|
||
func (w *routeContextHandlerWrapper) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error { | ||
myMetadata := ContextFrom(ctx) | ||
if metadata.Source.IsValid() { | ||
myMetadata.Source = metadata.Source | ||
} | ||
if metadata.Destination.IsValid() { | ||
myMetadata.Destination = metadata.Destination | ||
} | ||
return w.router.RouteConnection(ctx, conn, *myMetadata) | ||
} | ||
|
||
func (w *routeContextHandlerWrapper) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata M.Metadata) error { | ||
myMetadata := ContextFrom(ctx) | ||
if metadata.Source.IsValid() { | ||
myMetadata.Source = metadata.Source | ||
} | ||
if metadata.Destination.IsValid() { | ||
myMetadata.Destination = metadata.Destination | ||
} | ||
return w.router.RoutePacketConnection(ctx, conn, *myMetadata) | ||
} | ||
|
||
func (w *routeContextHandlerWrapper) NewError(ctx context.Context, err error) { | ||
w.logger.ErrorContext(ctx, err) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,42 @@ | ||
package mux | ||
|
||
import ( | ||
C "github.com/sagernet/sing-box/constant" | ||
"github.com/sagernet/sing-box/option" | ||
"github.com/sagernet/sing-mux" | ||
E "github.com/sagernet/sing/common/exceptions" | ||
"github.com/sagernet/sing/common/logger" | ||
N "github.com/sagernet/sing/common/network" | ||
) | ||
|
||
func NewClientWithOptions(dialer N.Dialer, options option.MultiplexOptions) (*Client, error) { | ||
type Client = mux.Client | ||
|
||
func NewClientWithOptions(dialer N.Dialer, logger logger.Logger, options option.OutboundMultiplexOptions) (*Client, error) { | ||
if !options.Enabled { | ||
return nil, nil | ||
} | ||
var brutalOptions mux.BrutalOptions | ||
if options.Brutal != nil && options.Brutal.Enabled { | ||
brutalOptions = mux.BrutalOptions{ | ||
Enabled: true, | ||
SendBPS: uint64(options.Brutal.UpMbps * C.MbpsToBps), | ||
ReceiveBPS: uint64(options.Brutal.DownMbps * C.MbpsToBps), | ||
} | ||
if brutalOptions.SendBPS < mux.BrutalMinSpeedBPS { | ||
return nil, E.New("brutal: invalid upload speed") | ||
} | ||
if brutalOptions.ReceiveBPS < mux.BrutalMinSpeedBPS { | ||
return nil, E.New("brutal: invalid download speed") | ||
} | ||
} | ||
return mux.NewClient(mux.Options{ | ||
Dialer: dialer, | ||
Logger: logger, | ||
Protocol: options.Protocol, | ||
MaxConnections: options.MaxConnections, | ||
MinStreams: options.MinStreams, | ||
MaxStreams: options.MaxStreams, | ||
Padding: options.Padding, | ||
Brutal: brutalOptions, | ||
}) | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package mux | ||
|
||
import ( | ||
"context" | ||
"net" | ||
|
||
"github.com/sagernet/sing-box/adapter" | ||
C "github.com/sagernet/sing-box/constant" | ||
"github.com/sagernet/sing-box/log" | ||
"github.com/sagernet/sing-box/option" | ||
"github.com/sagernet/sing-mux" | ||
E "github.com/sagernet/sing/common/exceptions" | ||
"github.com/sagernet/sing/common/logger" | ||
N "github.com/sagernet/sing/common/network" | ||
) | ||
|
||
type Router struct { | ||
router adapter.ConnectionRouter | ||
service *mux.Service | ||
} | ||
|
||
func NewRouterWithOptions(router adapter.ConnectionRouter, logger logger.ContextLogger, options option.InboundMultiplexOptions) (adapter.ConnectionRouter, error) { | ||
if !options.Enabled { | ||
return router, nil | ||
} | ||
var brutalOptions mux.BrutalOptions | ||
if options.Brutal != nil && options.Brutal.Enabled { | ||
brutalOptions = mux.BrutalOptions{ | ||
Enabled: true, | ||
SendBPS: uint64(options.Brutal.UpMbps * C.MbpsToBps), | ||
ReceiveBPS: uint64(options.Brutal.DownMbps * C.MbpsToBps), | ||
} | ||
if brutalOptions.SendBPS < mux.BrutalMinSpeedBPS { | ||
return nil, E.New("brutal: invalid upload speed") | ||
} | ||
if brutalOptions.ReceiveBPS < mux.BrutalMinSpeedBPS { | ||
return nil, E.New("brutal: invalid download speed") | ||
} | ||
} | ||
service, err := mux.NewService(mux.ServiceOptions{ | ||
NewStreamContext: func(ctx context.Context, conn net.Conn) context.Context { | ||
return log.ContextWithNewID(ctx) | ||
}, | ||
Logger: logger, | ||
Handler: adapter.NewRouteContextHandler(router, logger), | ||
Padding: options.Padding, | ||
Brutal: brutalOptions, | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &Router{router, service}, nil | ||
} | ||
|
||
func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { | ||
if metadata.Destination == mux.Destination { | ||
return r.service.NewConnection(adapter.WithContext(ctx, &metadata), conn, adapter.UpstreamMetadata(metadata)) | ||
} else { | ||
return r.router.RouteConnection(ctx, conn, metadata) | ||
} | ||
} | ||
|
||
func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { | ||
return r.router.RoutePacketConnection(ctx, conn, metadata) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package mux | ||
|
||
import ( | ||
"context" | ||
"net" | ||
|
||
"github.com/sagernet/sing-box/adapter" | ||
vmess "github.com/sagernet/sing-vmess" | ||
"github.com/sagernet/sing/common/logger" | ||
N "github.com/sagernet/sing/common/network" | ||
) | ||
|
||
type V2RayLegacyRouter struct { | ||
router adapter.ConnectionRouter | ||
logger logger.ContextLogger | ||
} | ||
|
||
func NewV2RayLegacyRouter(router adapter.ConnectionRouter, logger logger.ContextLogger) adapter.ConnectionRouter { | ||
return &V2RayLegacyRouter{router, logger} | ||
} | ||
|
||
func (r *V2RayLegacyRouter) RouteConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { | ||
if metadata.Destination.Fqdn == vmess.MuxDestination.Fqdn { | ||
r.logger.InfoContext(ctx, "inbound legacy multiplex connection") | ||
return vmess.HandleMuxConnection(ctx, conn, adapter.NewRouteHandler(metadata, r.router, r.logger)) | ||
} | ||
return r.router.RouteConnection(ctx, conn, metadata) | ||
} | ||
|
||
func (r *V2RayLegacyRouter) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { | ||
return r.router.RoutePacketConnection(ctx, conn, metadata) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package uot | ||
|
||
import ( | ||
"context" | ||
"net" | ||
"net/netip" | ||
|
||
"github.com/sagernet/sing-box/adapter" | ||
E "github.com/sagernet/sing/common/exceptions" | ||
"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/uot" | ||
) | ||
|
||
var _ adapter.ConnectionRouter = (*Router)(nil) | ||
|
||
type Router struct { | ||
router adapter.ConnectionRouter | ||
logger logger.ContextLogger | ||
} | ||
|
||
func NewRouter(router adapter.ConnectionRouter, logger logger.ContextLogger) *Router { | ||
return &Router{router, logger} | ||
} | ||
|
||
func (r *Router) RouteConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error { | ||
switch metadata.Destination.Fqdn { | ||
case uot.MagicAddress: | ||
request, err := uot.ReadRequest(conn) | ||
if err != nil { | ||
return E.Cause(err, "read UoT request") | ||
} | ||
if request.IsConnect { | ||
r.logger.InfoContext(ctx, "inbound UoT connect connection to ", request.Destination) | ||
} else { | ||
r.logger.InfoContext(ctx, "inbound UoT connection to ", request.Destination) | ||
} | ||
metadata.Domain = metadata.Destination.Fqdn | ||
metadata.Destination = request.Destination | ||
return r.router.RoutePacketConnection(ctx, uot.NewConn(conn, *request), metadata) | ||
case uot.LegacyMagicAddress: | ||
r.logger.InfoContext(ctx, "inbound legacy UoT connection") | ||
metadata.Domain = metadata.Destination.Fqdn | ||
metadata.Destination = M.Socksaddr{Addr: netip.IPv4Unspecified()} | ||
return r.RoutePacketConnection(ctx, uot.NewConn(conn, uot.Request{}), metadata) | ||
} | ||
return r.router.RouteConnection(ctx, conn, metadata) | ||
} | ||
|
||
func (r *Router) RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error { | ||
return r.router.RoutePacketConnection(ctx, conn, metadata) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package constant | ||
|
||
const MbpsToBps = 125000 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.