mirror of
https://github.com/shtorm-7/sing-box-extended.git
synced 2026-05-23 04:39:52 +03:00
Add MTProxy, MASQUE, VPN, Link parser. Update AmneziaWG. Remove Tunneling
This commit is contained in:
38
protocol/mtproxy/dialer.go
Normal file
38
protocol/mtproxy/dialer.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package mtproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
)
|
||||
|
||||
type Dialer struct {
|
||||
handler adapter.ConnectionHandlerFuncEx
|
||||
}
|
||||
|
||||
func NewDialer(handler adapter.ConnectionHandlerFuncEx) *Dialer {
|
||||
return &Dialer{handler}
|
||||
}
|
||||
|
||||
func (d *Dialer) Dial(network, address string) (net.Conn, error) {
|
||||
return d.DialContext(context.Background(), network, address)
|
||||
}
|
||||
|
||||
func (d *Dialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
inConn, outConn := net.Pipe()
|
||||
var metadata adapter.InboundContext
|
||||
if streamContext, ok := ctx.(streamContext); ok {
|
||||
metadata.Source = M.SocksaddrFromNet(streamContext.ClientAddr())
|
||||
metadata.User = streamContext.SecretName()
|
||||
}
|
||||
metadata.Destination = M.ParseSocksaddr(address)
|
||||
d.handler(ctx, inConn, metadata, func(error) {})
|
||||
return outConn, nil
|
||||
}
|
||||
|
||||
type streamContext interface {
|
||||
ClientAddr() net.Addr
|
||||
SecretName() string
|
||||
}
|
||||
132
protocol/mtproxy/inbound.go
Normal file
132
protocol/mtproxy/inbound.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package mtproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
|
||||
"github.com/dolonet/mtg-multi/antireplay"
|
||||
"github.com/dolonet/mtg-multi/events"
|
||||
"github.com/dolonet/mtg-multi/ipblocklist"
|
||||
"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(),
|
||||
IPBlocklist: ipblocklist.NewNoop(),
|
||||
IPAllowlist: ipblocklist.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)
|
||||
}
|
||||
60
protocol/mtproxy/logger.go
Normal file
60
protocol/mtproxy/logger.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package mtproxy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/dolonet/mtg-multi/mtglib"
|
||||
"github.com/sagernet/sing/common/logger"
|
||||
)
|
||||
|
||||
type LoggerAdapter struct {
|
||||
logger logger.Logger
|
||||
}
|
||||
|
||||
func NewLoggerAdapter(logger logger.Logger) *LoggerAdapter {
|
||||
return &LoggerAdapter{logger}
|
||||
}
|
||||
|
||||
func (l *LoggerAdapter) Named(name string) mtglib.Logger {
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *LoggerAdapter) BindInt(name string, value int) mtglib.Logger {
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *LoggerAdapter) BindStr(name, value string) mtglib.Logger {
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *LoggerAdapter) BindJSON(name, value string) mtglib.Logger {
|
||||
return l
|
||||
}
|
||||
|
||||
func (l *LoggerAdapter) Printf(format string, args ...any) {
|
||||
l.logger.Info(fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
func (l *LoggerAdapter) Info(msg string) {
|
||||
l.logger.Info(msg)
|
||||
}
|
||||
|
||||
func (l *LoggerAdapter) InfoError(msg string, err error) {
|
||||
l.logger.Error(msg, err)
|
||||
}
|
||||
|
||||
func (l *LoggerAdapter) Warning(msg string) {
|
||||
l.logger.Warn(msg)
|
||||
}
|
||||
|
||||
func (l *LoggerAdapter) WarningError(msg string, err error) {
|
||||
l.logger.Warn(msg, err)
|
||||
}
|
||||
|
||||
func (l *LoggerAdapter) Debug(msg string) {
|
||||
l.logger.Debug(msg)
|
||||
}
|
||||
|
||||
func (l *LoggerAdapter) DebugError(msg string, err error) {
|
||||
l.logger.Debug(msg, err)
|
||||
}
|
||||
43
protocol/mtproxy/network.go
Normal file
43
protocol/mtproxy/network.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package mtproxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/dolonet/mtg-multi/essentials"
|
||||
)
|
||||
|
||||
type NetworkAdapter struct {
|
||||
ctx context.Context
|
||||
dialer essentials.Dialer
|
||||
}
|
||||
|
||||
func NewNetworkAdapter(ctx context.Context, dialer essentials.Dialer) *NetworkAdapter {
|
||||
return &NetworkAdapter{ctx, dialer}
|
||||
}
|
||||
|
||||
func (a *NetworkAdapter) Dial(network, address string) (essentials.Conn, error) {
|
||||
return a.DialContext(a.ctx, network, address)
|
||||
}
|
||||
|
||||
func (a *NetworkAdapter) DialContext(ctx context.Context, network, address string) (essentials.Conn, error) {
|
||||
conn, err := a.dialer.DialContext(ctx, network, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return essentials.WrapNetConn(conn), nil
|
||||
}
|
||||
|
||||
func (a *NetworkAdapter) MakeHTTPClient(func(ctx context.Context, network, address string) (essentials.Conn, error)) *http.Client {
|
||||
return &http.Client{
|
||||
Timeout: 10,
|
||||
Transport: &http.Transport{DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
return a.DialContext(ctx, network, addr)
|
||||
}},
|
||||
}
|
||||
}
|
||||
|
||||
func (a *NetworkAdapter) NativeDialer() essentials.Dialer {
|
||||
return a.dialer
|
||||
}
|
||||
Reference in New Issue
Block a user