mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-05-14 00:51:12 +03:00
130 lines
3.8 KiB
Go
130 lines
3.8 KiB
Go
package mtproxy
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
|
|
"github.com/dolonet/mtg-multi/antireplay"
|
|
"github.com/dolonet/mtg-multi/events"
|
|
"github.com/dolonet/mtg-multi/mtglib"
|
|
"github.com/sagernet/sing-box/adapter"
|
|
"github.com/sagernet/sing-box/adapter/inbound"
|
|
"github.com/sagernet/sing-box/common/listener"
|
|
C "github.com/sagernet/sing-box/constant"
|
|
"github.com/sagernet/sing-box/log"
|
|
"github.com/sagernet/sing-box/option"
|
|
"github.com/sagernet/sing/common"
|
|
E "github.com/sagernet/sing/common/exceptions"
|
|
"github.com/sagernet/sing/common/logger"
|
|
N "github.com/sagernet/sing/common/network"
|
|
)
|
|
|
|
func RegisterInbound(registry *inbound.Registry) {
|
|
inbound.Register[option.MTProxyInboundOptions](registry, C.TypeMTProxy, NewInbound)
|
|
}
|
|
|
|
type Inbound struct {
|
|
inbound.Adapter
|
|
ctx context.Context
|
|
router adapter.ConnectionRouterEx
|
|
logger logger.ContextLogger
|
|
listener *listener.Listener
|
|
proxy *mtglib.Proxy
|
|
}
|
|
|
|
func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLogger, tag string, options option.MTProxyInboundOptions) (adapter.Inbound, error) {
|
|
inbound := &Inbound{
|
|
Adapter: inbound.NewAdapter(C.TypeMTProxy, tag),
|
|
ctx: ctx,
|
|
router: router,
|
|
logger: logger,
|
|
listener: listener.New(listener.Options{
|
|
Context: ctx,
|
|
Logger: logger,
|
|
Listen: options.ListenOptions,
|
|
}),
|
|
}
|
|
mtgLogger := NewLoggerAdapter(logger)
|
|
secrets := make(map[string]mtglib.Secret, len(options.Users))
|
|
for _, user := range options.Users {
|
|
secret := mtglib.Secret{}
|
|
err := secret.Set(user.Secret)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
secrets[user.Name] = secret
|
|
}
|
|
opts := mtglib.ProxyOpts{
|
|
Logger: mtgLogger,
|
|
Network: NewNetworkAdapter(ctx, NewDialer(inbound.newConnection)),
|
|
AntiReplayCache: antireplay.NewNoop(),
|
|
EventStream: events.NewNoopStream(),
|
|
|
|
Secrets: secrets,
|
|
Concurrency: options.GetConcurrency(),
|
|
DomainFrontingPort: options.GetDomainFrontingPort(),
|
|
DomainFrontingIP: options.DomainFrontingIP,
|
|
DomainFrontingProxyProtocol: options.DomainFrontingProxyProtocol,
|
|
PreferIP: options.GetPreferIP(),
|
|
AutoUpdate: options.AutoUpdate,
|
|
|
|
AllowFallbackOnUnknownDC: options.AllowFallbackOnUnknownDC,
|
|
TolerateTimeSkewness: options.TolerateTimeSkewness.Build(),
|
|
IdleTimeout: options.GetIdleTimeout(),
|
|
HandshakeTimeout: options.GetHandshakeTimeout(),
|
|
|
|
DoppelGangerURLs: options.DoppelGangerURLs,
|
|
DoppelGangerPerRaid: options.GetDoppelGangerPerRaid(),
|
|
DoppelGangerEach: options.GetDoppelGangerEach(),
|
|
DoppelGangerDRS: options.DoppelGangerDRS,
|
|
|
|
ThrottleMaxConnections: options.ThrottleMaxConnections,
|
|
ThrottleCheckInterval: options.GetThrottleCheckInterval(),
|
|
}
|
|
proxy, err := mtglib.NewProxy(opts)
|
|
if err != nil {
|
|
return nil, E.New("cannot create a proxy: ", err)
|
|
}
|
|
inbound.proxy = proxy
|
|
return inbound, nil
|
|
}
|
|
|
|
func (n *Inbound) Start(stage adapter.StartStage) error {
|
|
if stage != adapter.StartStateStart {
|
|
return nil
|
|
}
|
|
listener, err := n.listener.ListenTCP()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
go n.proxy.Serve(listener)
|
|
return nil
|
|
}
|
|
|
|
func (n *Inbound) Close() error {
|
|
n.proxy.Shutdown()
|
|
return common.Close(
|
|
&n.listener,
|
|
)
|
|
}
|
|
|
|
func (h *Inbound) UpdateUsers(users []option.MTProxyUser) {
|
|
secrets := make(map[string]mtglib.Secret, len(users))
|
|
for _, user := range users {
|
|
secret := mtglib.Secret{}
|
|
err := secret.Set(user.Secret)
|
|
if err != nil {
|
|
return
|
|
}
|
|
secrets[user.Name] = secret
|
|
}
|
|
h.proxy.UpdateUsers(secrets)
|
|
}
|
|
|
|
func (h *Inbound) newConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext, onClose N.CloseHandlerFunc) {
|
|
metadata.Inbound = h.Tag()
|
|
metadata.InboundType = h.Type()
|
|
h.logger.InfoContext(ctx, "[", metadata.User, "] inbound connection to ", metadata.Destination)
|
|
h.router.RouteConnectionEx(ctx, conn, metadata, onClose)
|
|
}
|