mirror of
https://github.com/bolucat/Archive.git
synced 2025-12-24 13:28:37 +08:00
Update On Tue Dec 2 19:43:48 CET 2025
This commit is contained in:
@@ -7,7 +7,6 @@ import (
|
||||
"time"
|
||||
|
||||
CN "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/transport/anytls"
|
||||
@@ -20,7 +19,6 @@ import (
|
||||
type AnyTLS struct {
|
||||
*Base
|
||||
client *anytls.Client
|
||||
dialer proxydialer.SingDialer
|
||||
option *AnyTLSOption
|
||||
}
|
||||
|
||||
@@ -101,9 +99,8 @@ func NewAnyTLS(option AnyTLSOption) (*AnyTLS, error) {
|
||||
},
|
||||
option: &option,
|
||||
}
|
||||
|
||||
singDialer := proxydialer.NewByNameSingDialer(option.DialerProxy, dialer.NewDialer(outbound.DialOptions()...))
|
||||
outbound.dialer = singDialer
|
||||
outbound.dialer = option.NewDialer(outbound.DialOptions())
|
||||
singDialer := proxydialer.NewSingDialer(outbound.dialer)
|
||||
|
||||
tOption := anytls.ClientConfig{
|
||||
Password: option.Password,
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/common/utils"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
"github.com/metacubex/mihomo/component/resolver"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
@@ -35,6 +36,7 @@ type Base struct {
|
||||
rmark int
|
||||
id string
|
||||
prefer C.DNSPrefer
|
||||
dialer C.Dialer
|
||||
}
|
||||
|
||||
// Name implements C.ProxyAdapter
|
||||
@@ -56,35 +58,15 @@ func (b *Base) Type() C.AdapterType {
|
||||
return b.tp
|
||||
}
|
||||
|
||||
// StreamConnContext implements C.ProxyAdapter
|
||||
func (b *Base) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.Metadata) (net.Conn, error) {
|
||||
return c, C.ErrNotSupport
|
||||
}
|
||||
|
||||
func (b *Base) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn, error) {
|
||||
return nil, C.ErrNotSupport
|
||||
}
|
||||
|
||||
// DialContextWithDialer implements C.ProxyAdapter
|
||||
func (b *Base) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
return nil, C.ErrNotSupport
|
||||
}
|
||||
|
||||
// ListenPacketContext implements C.ProxyAdapter
|
||||
func (b *Base) ListenPacketContext(ctx context.Context, metadata *C.Metadata) (C.PacketConn, error) {
|
||||
return nil, C.ErrNotSupport
|
||||
}
|
||||
|
||||
// ListenPacketWithDialer implements C.ProxyAdapter
|
||||
func (b *Base) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||
return nil, C.ErrNotSupport
|
||||
}
|
||||
|
||||
// SupportWithDialer implements C.ProxyAdapter
|
||||
func (b *Base) SupportWithDialer() C.NetWork {
|
||||
return C.InvalidNet
|
||||
}
|
||||
|
||||
// SupportUOT implements C.ProxyAdapter
|
||||
func (b *Base) SupportUOT() bool {
|
||||
return false
|
||||
@@ -184,6 +166,20 @@ type BasicOption struct {
|
||||
RoutingMark int `proxy:"routing-mark,omitempty"`
|
||||
IPVersion string `proxy:"ip-version,omitempty"`
|
||||
DialerProxy string `proxy:"dialer-proxy,omitempty"` // don't apply this option into groups, but can set a group name in a proxy
|
||||
|
||||
DialerForAPI C.Dialer `proxy:"-"` // the dialer used for API usage has higher priority than all the above configurations.
|
||||
}
|
||||
|
||||
func (b *BasicOption) NewDialer(opts []dialer.Option) C.Dialer {
|
||||
cDialer := b.DialerForAPI
|
||||
if cDialer == nil {
|
||||
if b.DialerProxy != "" {
|
||||
cDialer = proxydialer.NewByName(b.DialerProxy)
|
||||
} else {
|
||||
cDialer = dialer.NewDialer(opts...)
|
||||
}
|
||||
}
|
||||
return cDialer
|
||||
}
|
||||
|
||||
type BaseOption struct {
|
||||
@@ -348,17 +344,6 @@ func (p *autoCloseProxyAdapter) DialContext(ctx context.Context, metadata *C.Met
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (p *autoCloseProxyAdapter) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
c, err := p.ProxyAdapter.DialContextWithDialer(ctx, dialer, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if c, ok := c.(AddRef); ok {
|
||||
c.AddRef(p)
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (p *autoCloseProxyAdapter) ListenPacketContext(ctx context.Context, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||
pc, err := p.ProxyAdapter.ListenPacketContext(ctx, metadata)
|
||||
if err != nil {
|
||||
@@ -370,17 +355,6 @@ func (p *autoCloseProxyAdapter) ListenPacketContext(ctx context.Context, metadat
|
||||
return pc, nil
|
||||
}
|
||||
|
||||
func (p *autoCloseProxyAdapter) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||
pc, err := p.ProxyAdapter.ListenPacketWithDialer(ctx, dialer, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if pc, ok := pc.(AddRef); ok {
|
||||
pc.AddRef(p)
|
||||
}
|
||||
return pc, nil
|
||||
}
|
||||
|
||||
func (p *autoCloseProxyAdapter) Close() error {
|
||||
p.closeOnce.Do(func() {
|
||||
log.Debugln("Closing outdated proxy [%s]", p.Name())
|
||||
|
||||
@@ -13,8 +13,6 @@ import (
|
||||
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/component/ca"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
)
|
||||
|
||||
@@ -61,18 +59,7 @@ func (h *Http) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.Me
|
||||
|
||||
// DialContext implements C.ProxyAdapter
|
||||
func (h *Http) DialContext(ctx context.Context, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
return h.DialContextWithDialer(ctx, dialer.NewDialer(h.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// DialContextWithDialer implements C.ProxyAdapter
|
||||
func (h *Http) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
if len(h.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(h.option.DialerProxy, dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
c, err := dialer.DialContext(ctx, "tcp", h.addr)
|
||||
c, err := h.dialer.DialContext(ctx, "tcp", h.addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %w", h.addr, err)
|
||||
}
|
||||
@@ -89,11 +76,6 @@ func (h *Http) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metad
|
||||
return NewConn(c, h), nil
|
||||
}
|
||||
|
||||
// SupportWithDialer implements C.ProxyAdapter
|
||||
func (h *Http) SupportWithDialer() C.NetWork {
|
||||
return C.TCP
|
||||
}
|
||||
|
||||
// ProxyInfo implements C.ProxyAdapter
|
||||
func (h *Http) ProxyInfo() C.ProxyInfo {
|
||||
info := h.Base.ProxyInfo()
|
||||
@@ -183,7 +165,7 @@ func NewHttp(option HttpOption) (*Http, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return &Http{
|
||||
outbound := &Http{
|
||||
Base: &Base{
|
||||
name: option.Name,
|
||||
addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)),
|
||||
@@ -198,5 +180,7 @@ func NewHttp(option HttpOption) (*Http, error) {
|
||||
pass: option.Password,
|
||||
tlsConfig: tlsConfig,
|
||||
option: &option,
|
||||
}, nil
|
||||
}
|
||||
outbound.dialer = option.NewDialer(outbound.DialOptions())
|
||||
return outbound, nil
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"github.com/metacubex/mihomo/component/ca"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/ech"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
tlsC "github.com/metacubex/mihomo/component/tls"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
@@ -74,16 +73,8 @@ func (h *Hysteria) genHdc(ctx context.Context) utils.PacketDialer {
|
||||
return &hyDialerWithContext{
|
||||
ctx: context.Background(),
|
||||
hyDialer: func(network string, rAddr net.Addr) (net.PacketConn, error) {
|
||||
var err error
|
||||
var cDialer C.Dialer = dialer.NewDialer(h.DialOptions()...)
|
||||
if len(h.option.DialerProxy) > 0 {
|
||||
cDialer, err = proxydialer.NewByName(h.option.DialerProxy, cDialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
rAddrPort, _ := netip.ParseAddrPort(rAddr.String())
|
||||
return cDialer.ListenPacket(ctx, network, "", rAddrPort)
|
||||
return h.dialer.ListenPacket(ctx, network, "", rAddrPort)
|
||||
},
|
||||
remoteAddr: func(addr string) (net.Addr, error) {
|
||||
udpAddr, err := resolveUDPAddr(ctx, "udp", addr, h.prefer)
|
||||
@@ -263,6 +254,7 @@ func NewHysteria(option HysteriaOption) (*Hysteria, error) {
|
||||
tlsConfig: tlsClientConfig,
|
||||
echConfig: echConfig,
|
||||
}
|
||||
outbound.dialer = option.NewDialer(outbound.DialOptions())
|
||||
|
||||
return outbound, nil
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
CN "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/common/utils"
|
||||
"github.com/metacubex/mihomo/component/ca"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
tlsC "github.com/metacubex/mihomo/component/tls"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
@@ -36,7 +35,6 @@ type Hysteria2 struct {
|
||||
|
||||
option *Hysteria2Option
|
||||
client *hysteria2.Client
|
||||
dialer proxydialer.SingDialer
|
||||
}
|
||||
|
||||
type Hysteria2Option struct {
|
||||
@@ -119,9 +117,8 @@ func NewHysteria2(option Hysteria2Option) (*Hysteria2, error) {
|
||||
},
|
||||
option: &option,
|
||||
}
|
||||
|
||||
singDialer := proxydialer.NewByNameSingDialer(option.DialerProxy, dialer.NewDialer(outbound.DialOptions()...))
|
||||
outbound.dialer = singDialer
|
||||
outbound.dialer = option.NewDialer(outbound.DialOptions())
|
||||
singDialer := proxydialer.NewSingDialer(outbound.dialer)
|
||||
|
||||
var salamanderPassword string
|
||||
if len(option.Obfs) > 0 {
|
||||
|
||||
@@ -9,8 +9,6 @@ import (
|
||||
"sync"
|
||||
|
||||
CN "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
"github.com/metacubex/mihomo/component/resolver"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
|
||||
@@ -130,20 +128,12 @@ func (m *Mieru) ensureClientIsRunning() error {
|
||||
}
|
||||
|
||||
// Create a dialer and add it to the client config, before starting the client.
|
||||
var dialer C.Dialer = dialer.NewDialer(m.DialOptions()...)
|
||||
var err error
|
||||
if len(m.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(m.option.DialerProxy, dialer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
config, err := m.client.Load()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
config.Dialer = dialer
|
||||
config.PacketDialer = mieruPacketDialer{Dialer: dialer}
|
||||
config.Dialer = m.dialer
|
||||
config.PacketDialer = mieruPacketDialer{Dialer: m.dialer}
|
||||
config.Resolver = mieruDNSResolver{prefer: m.prefer}
|
||||
if err := m.client.Store(config); err != nil {
|
||||
return err
|
||||
@@ -187,6 +177,7 @@ func NewMieru(option MieruOption) (*Mieru, error) {
|
||||
option: &option,
|
||||
client: c,
|
||||
}
|
||||
outbound.dialer = option.NewDialer(outbound.DialOptions())
|
||||
return outbound, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ type Reject struct {
|
||||
}
|
||||
|
||||
type RejectOption struct {
|
||||
BasicOption
|
||||
Name string `proxy:"name"`
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,6 @@ import (
|
||||
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/common/structure"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
gost "github.com/metacubex/mihomo/transport/gost-plugin"
|
||||
@@ -191,17 +189,6 @@ func (ss *ShadowSocks) StreamConnContext(ctx context.Context, c net.Conn, metada
|
||||
|
||||
// DialContext implements C.ProxyAdapter
|
||||
func (ss *ShadowSocks) DialContext(ctx context.Context, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
return ss.DialContextWithDialer(ctx, dialer.NewDialer(ss.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// DialContextWithDialer implements C.ProxyAdapter
|
||||
func (ss *ShadowSocks) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
if len(ss.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(ss.option.DialerProxy, dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
var c net.Conn
|
||||
if ss.kcptunClient != nil {
|
||||
c, err = ss.kcptunClient.OpenStream(ctx, func(ctx context.Context) (net.PacketConn, net.Addr, error) {
|
||||
@@ -213,7 +200,7 @@ func (ss *ShadowSocks) DialContextWithDialer(ctx context.Context, dialer C.Diale
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pc, err := dialer.ListenPacket(ctx, "udp", "", addr.AddrPort())
|
||||
pc, err := ss.dialer.ListenPacket(ctx, "udp", "", addr.AddrPort())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -221,7 +208,7 @@ func (ss *ShadowSocks) DialContextWithDialer(ctx context.Context, dialer C.Diale
|
||||
return pc, addr, nil
|
||||
})
|
||||
} else {
|
||||
c, err = dialer.DialContext(ctx, "tcp", ss.addr)
|
||||
c, err = ss.dialer.DialContext(ctx, "tcp", ss.addr)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %w", ss.addr, err)
|
||||
@@ -237,25 +224,14 @@ func (ss *ShadowSocks) DialContextWithDialer(ctx context.Context, dialer C.Diale
|
||||
|
||||
// ListenPacketContext implements C.ProxyAdapter
|
||||
func (ss *ShadowSocks) ListenPacketContext(ctx context.Context, metadata *C.Metadata) (C.PacketConn, error) {
|
||||
return ss.ListenPacketWithDialer(ctx, dialer.NewDialer(ss.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// ListenPacketWithDialer implements C.ProxyAdapter
|
||||
func (ss *ShadowSocks) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||
if ss.option.UDPOverTCP {
|
||||
tcpConn, err := ss.DialContextWithDialer(ctx, dialer, metadata)
|
||||
tcpConn, err := ss.DialContext(ctx, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ss.ListenPacketOnStreamConn(ctx, tcpConn, metadata)
|
||||
}
|
||||
if len(ss.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(ss.option.DialerProxy, dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err = ss.ResolveUDP(ctx, metadata); err != nil {
|
||||
if err := ss.ResolveUDP(ctx, metadata); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addr, err := resolveUDPAddr(ctx, "udp", ss.addr, ss.prefer)
|
||||
@@ -263,7 +239,7 @@ func (ss *ShadowSocks) ListenPacketWithDialer(ctx context.Context, dialer C.Dial
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pc, err := dialer.ListenPacket(ctx, "udp", "", addr.AddrPort())
|
||||
pc, err := ss.dialer.ListenPacket(ctx, "udp", "", addr.AddrPort())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -271,11 +247,6 @@ func (ss *ShadowSocks) ListenPacketWithDialer(ctx context.Context, dialer C.Dial
|
||||
return newPacketConn(pc, ss), nil
|
||||
}
|
||||
|
||||
// SupportWithDialer implements C.ProxyAdapter
|
||||
func (ss *ShadowSocks) SupportWithDialer() C.NetWork {
|
||||
return C.ALLNet
|
||||
}
|
||||
|
||||
// ProxyInfo implements C.ProxyAdapter
|
||||
func (ss *ShadowSocks) ProxyInfo() C.ProxyInfo {
|
||||
info := ss.Base.ProxyInfo()
|
||||
@@ -482,7 +453,7 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
|
||||
return nil, fmt.Errorf("ss %s unknown udp over tcp protocol version: %d", addr, option.UDPOverTCPVersion)
|
||||
}
|
||||
|
||||
return &ShadowSocks{
|
||||
outbound := &ShadowSocks{
|
||||
Base: &Base{
|
||||
name: option.Name,
|
||||
addr: addr,
|
||||
@@ -504,5 +475,7 @@ func NewShadowSocks(option ShadowSocksOption) (*ShadowSocks, error) {
|
||||
shadowTLSOption: shadowTLSOpt,
|
||||
restlsConfig: restlsConfig,
|
||||
kcptunClient: kcptunClient,
|
||||
}, nil
|
||||
}
|
||||
outbound.dialer = option.NewDialer(outbound.DialOptions())
|
||||
return outbound, nil
|
||||
}
|
||||
|
||||
@@ -8,8 +8,6 @@ import (
|
||||
"strconv"
|
||||
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/transport/shadowsocks/core"
|
||||
"github.com/metacubex/mihomo/transport/shadowsocks/shadowaead"
|
||||
@@ -68,18 +66,7 @@ func (ssr *ShadowSocksR) StreamConnContext(ctx context.Context, c net.Conn, meta
|
||||
|
||||
// DialContext implements C.ProxyAdapter
|
||||
func (ssr *ShadowSocksR) DialContext(ctx context.Context, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
return ssr.DialContextWithDialer(ctx, dialer.NewDialer(ssr.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// DialContextWithDialer implements C.ProxyAdapter
|
||||
func (ssr *ShadowSocksR) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
if len(ssr.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(ssr.option.DialerProxy, dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
c, err := dialer.DialContext(ctx, "tcp", ssr.addr)
|
||||
c, err := ssr.dialer.DialContext(ctx, "tcp", ssr.addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %w", ssr.addr, err)
|
||||
}
|
||||
@@ -94,18 +81,7 @@ func (ssr *ShadowSocksR) DialContextWithDialer(ctx context.Context, dialer C.Dia
|
||||
|
||||
// ListenPacketContext implements C.ProxyAdapter
|
||||
func (ssr *ShadowSocksR) ListenPacketContext(ctx context.Context, metadata *C.Metadata) (C.PacketConn, error) {
|
||||
return ssr.ListenPacketWithDialer(ctx, dialer.NewDialer(ssr.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// ListenPacketWithDialer implements C.ProxyAdapter
|
||||
func (ssr *ShadowSocksR) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||
if len(ssr.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(ssr.option.DialerProxy, dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err = ssr.ResolveUDP(ctx, metadata); err != nil {
|
||||
if err := ssr.ResolveUDP(ctx, metadata); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
addr, err := resolveUDPAddr(ctx, "udp", ssr.addr, ssr.prefer)
|
||||
@@ -113,7 +89,7 @@ func (ssr *ShadowSocksR) ListenPacketWithDialer(ctx context.Context, dialer C.Di
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pc, err := dialer.ListenPacket(ctx, "udp", "", addr.AddrPort())
|
||||
pc, err := ssr.dialer.ListenPacket(ctx, "udp", "", addr.AddrPort())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -123,11 +99,6 @@ func (ssr *ShadowSocksR) ListenPacketWithDialer(ctx context.Context, dialer C.Di
|
||||
return newPacketConn(&ssrPacketConn{EnhancePacketConn: epc, rAddr: addr}, ssr), nil
|
||||
}
|
||||
|
||||
// SupportWithDialer implements C.ProxyAdapter
|
||||
func (ssr *ShadowSocksR) SupportWithDialer() C.NetWork {
|
||||
return C.ALLNet
|
||||
}
|
||||
|
||||
// ProxyInfo implements C.ProxyAdapter
|
||||
func (ssr *ShadowSocksR) ProxyInfo() C.ProxyInfo {
|
||||
info := ssr.Base.ProxyInfo()
|
||||
@@ -186,7 +157,7 @@ func NewShadowSocksR(option ShadowSocksROption) (*ShadowSocksR, error) {
|
||||
return nil, fmt.Errorf("ssr %s initialize protocol error: %w", addr, err)
|
||||
}
|
||||
|
||||
return &ShadowSocksR{
|
||||
outbound := &ShadowSocksR{
|
||||
Base: &Base{
|
||||
name: option.Name,
|
||||
addr: addr,
|
||||
@@ -202,7 +173,9 @@ func NewShadowSocksR(option ShadowSocksROption) (*ShadowSocksR, error) {
|
||||
cipher: coreCiph,
|
||||
obfs: obfs,
|
||||
protocol: protocol,
|
||||
}, nil
|
||||
}
|
||||
outbound.dialer = option.NewDialer(outbound.DialOptions())
|
||||
return outbound, nil
|
||||
}
|
||||
|
||||
type ssrPacketConn struct {
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
|
||||
CN "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
@@ -17,7 +16,6 @@ import (
|
||||
type SingMux struct {
|
||||
ProxyAdapter
|
||||
client *mux.Client
|
||||
dialer proxydialer.SingDialer
|
||||
onlyTcp bool
|
||||
}
|
||||
|
||||
@@ -96,7 +94,7 @@ func NewSingMux(option SingMuxOption, proxy ProxyAdapter) (ProxyAdapter, error)
|
||||
// TODO
|
||||
// "TCP Brutal is only supported on Linux-based systems"
|
||||
|
||||
singDialer := proxydialer.NewSingDialer(proxy, dialer.NewDialer(proxy.DialOptions()...), option.Statistic)
|
||||
singDialer := proxydialer.NewSingDialer(proxydialer.New(proxy, option.Statistic))
|
||||
client, err := mux.NewClient(mux.Options{
|
||||
Dialer: singDialer,
|
||||
Logger: log.SingLogger,
|
||||
@@ -117,7 +115,6 @@ func NewSingMux(option SingMuxOption, proxy ProxyAdapter) (ProxyAdapter, error)
|
||||
outbound := &SingMux{
|
||||
ProxyAdapter: proxy,
|
||||
client: client,
|
||||
dialer: singDialer,
|
||||
onlyTcp: option.OnlyTcp,
|
||||
}
|
||||
return outbound, nil
|
||||
|
||||
@@ -8,8 +8,6 @@ import (
|
||||
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/common/structure"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
obfs "github.com/metacubex/mihomo/transport/simple-obfs"
|
||||
"github.com/metacubex/mihomo/transport/snell"
|
||||
@@ -89,18 +87,7 @@ func (s *Snell) DialContext(ctx context.Context, metadata *C.Metadata) (_ C.Conn
|
||||
return NewConn(c, s), err
|
||||
}
|
||||
|
||||
return s.DialContextWithDialer(ctx, dialer.NewDialer(s.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// DialContextWithDialer implements C.ProxyAdapter
|
||||
func (s *Snell) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
if len(s.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(s.option.DialerProxy, dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
c, err := dialer.DialContext(ctx, "tcp", s.addr)
|
||||
c, err := s.dialer.DialContext(ctx, "tcp", s.addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %w", s.addr, err)
|
||||
}
|
||||
@@ -115,22 +102,11 @@ func (s *Snell) DialContextWithDialer(ctx context.Context, dialer C.Dialer, meta
|
||||
|
||||
// ListenPacketContext implements C.ProxyAdapter
|
||||
func (s *Snell) ListenPacketContext(ctx context.Context, metadata *C.Metadata) (C.PacketConn, error) {
|
||||
return s.ListenPacketWithDialer(ctx, dialer.NewDialer(s.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// ListenPacketWithDialer implements C.ProxyAdapter
|
||||
func (s *Snell) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (C.PacketConn, error) {
|
||||
var err error
|
||||
if len(s.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(s.option.DialerProxy, dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err = s.ResolveUDP(ctx, metadata); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c, err := dialer.DialContext(ctx, "tcp", s.addr)
|
||||
c, err := s.dialer.DialContext(ctx, "tcp", s.addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -141,11 +117,6 @@ func (s *Snell) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met
|
||||
return newPacketConn(pc, s), nil
|
||||
}
|
||||
|
||||
// SupportWithDialer implements C.ProxyAdapter
|
||||
func (s *Snell) SupportWithDialer() C.NetWork {
|
||||
return C.ALLNet
|
||||
}
|
||||
|
||||
// SupportUOT implements C.ProxyAdapter
|
||||
func (s *Snell) SupportUOT() bool {
|
||||
return true
|
||||
@@ -206,18 +177,11 @@ func NewSnell(option SnellOption) (*Snell, error) {
|
||||
obfsOption: obfsOption,
|
||||
version: option.Version,
|
||||
}
|
||||
s.dialer = option.NewDialer(s.DialOptions())
|
||||
|
||||
if option.Version == snell.Version2 {
|
||||
s.pool = snell.NewPool(func(ctx context.Context) (*snell.Snell, error) {
|
||||
var err error
|
||||
var cDialer C.Dialer = dialer.NewDialer(s.DialOptions()...)
|
||||
if len(s.option.DialerProxy) > 0 {
|
||||
cDialer, err = proxydialer.NewByName(s.option.DialerProxy, cDialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
c, err := cDialer.DialContext(ctx, "tcp", addr)
|
||||
c, err := s.dialer.DialContext(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -12,8 +12,6 @@ import (
|
||||
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/component/ca"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/transport/socks5"
|
||||
)
|
||||
@@ -69,18 +67,7 @@ func (ss *Socks5) StreamConnContext(ctx context.Context, c net.Conn, metadata *C
|
||||
|
||||
// DialContext implements C.ProxyAdapter
|
||||
func (ss *Socks5) DialContext(ctx context.Context, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
return ss.DialContextWithDialer(ctx, dialer.NewDialer(ss.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// DialContextWithDialer implements C.ProxyAdapter
|
||||
func (ss *Socks5) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
if len(ss.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(ss.option.DialerProxy, dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
c, err := dialer.DialContext(ctx, "tcp", ss.addr)
|
||||
c, err := ss.dialer.DialContext(ctx, "tcp", ss.addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %w", ss.addr, err)
|
||||
}
|
||||
@@ -97,24 +84,12 @@ func (ss *Socks5) DialContextWithDialer(ctx context.Context, dialer C.Dialer, me
|
||||
return NewConn(c, ss), nil
|
||||
}
|
||||
|
||||
// SupportWithDialer implements C.ProxyAdapter
|
||||
func (ss *Socks5) SupportWithDialer() C.NetWork {
|
||||
return C.TCP
|
||||
}
|
||||
|
||||
// ListenPacketContext implements C.ProxyAdapter
|
||||
func (ss *Socks5) ListenPacketContext(ctx context.Context, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||
var cDialer C.Dialer = dialer.NewDialer(ss.DialOptions()...)
|
||||
if len(ss.option.DialerProxy) > 0 {
|
||||
cDialer, err = proxydialer.NewByName(ss.option.DialerProxy, cDialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err = ss.ResolveUDP(ctx, metadata); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c, err := cDialer.DialContext(ctx, "tcp", ss.addr)
|
||||
c, err := ss.dialer.DialContext(ctx, "tcp", ss.addr)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("%s connect error: %w", ss.addr, err)
|
||||
return
|
||||
@@ -161,7 +136,7 @@ func (ss *Socks5) ListenPacketContext(ctx context.Context, metadata *C.Metadata)
|
||||
bindUDPAddr.IP = serverAddr.IP
|
||||
}
|
||||
|
||||
pc, err := cDialer.ListenPacket(ctx, "udp", "", bindUDPAddr.AddrPort())
|
||||
pc, err := ss.dialer.ListenPacket(ctx, "udp", "", bindUDPAddr.AddrPort())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -210,7 +185,7 @@ func NewSocks5(option Socks5Option) (*Socks5, error) {
|
||||
}
|
||||
}
|
||||
|
||||
return &Socks5{
|
||||
outbound := &Socks5{
|
||||
Base: &Base{
|
||||
name: option.Name,
|
||||
addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)),
|
||||
@@ -228,7 +203,9 @@ func NewSocks5(option Socks5Option) (*Socks5, error) {
|
||||
tls: option.TLS,
|
||||
skipCertVerify: option.SkipCertVerify,
|
||||
tlsConfig: tlsConfig,
|
||||
}, nil
|
||||
}
|
||||
outbound.dialer = option.NewDialer(outbound.DialOptions())
|
||||
return outbound, nil
|
||||
}
|
||||
|
||||
type socksPacketConn struct {
|
||||
|
||||
@@ -12,8 +12,6 @@ import (
|
||||
"sync"
|
||||
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
|
||||
"github.com/metacubex/randv2"
|
||||
@@ -44,14 +42,7 @@ type SshOption struct {
|
||||
}
|
||||
|
||||
func (s *Ssh) DialContext(ctx context.Context, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
var cDialer C.Dialer = dialer.NewDialer(s.DialOptions()...)
|
||||
if len(s.option.DialerProxy) > 0 {
|
||||
cDialer, err = proxydialer.NewByName(s.option.DialerProxy, cDialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
client, err := s.connect(ctx, cDialer, s.addr)
|
||||
client, err := s.connect(ctx, s.addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -63,13 +54,13 @@ func (s *Ssh) DialContext(ctx context.Context, metadata *C.Metadata) (_ C.Conn,
|
||||
return NewConn(c, s), nil
|
||||
}
|
||||
|
||||
func (s *Ssh) connect(ctx context.Context, cDialer C.Dialer, addr string) (client *ssh.Client, err error) {
|
||||
func (s *Ssh) connect(ctx context.Context, addr string) (client *ssh.Client, err error) {
|
||||
s.cMutex.Lock()
|
||||
defer s.cMutex.Unlock()
|
||||
if s.client != nil {
|
||||
return s.client, nil
|
||||
}
|
||||
c, err := cDialer.DialContext(ctx, "tcp", addr)
|
||||
c, err := s.dialer.DialContext(ctx, "tcp", addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -203,6 +194,6 @@ func NewSsh(option SshOption) (*Ssh, error) {
|
||||
option: &option,
|
||||
config: &config,
|
||||
}
|
||||
|
||||
outbound.dialer = option.NewDialer(outbound.DialOptions())
|
||||
return outbound, nil
|
||||
}
|
||||
|
||||
@@ -11,17 +11,14 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/log"
|
||||
|
||||
"github.com/saba-futai/sudoku/apis"
|
||||
"github.com/saba-futai/sudoku/pkg/crypto"
|
||||
"github.com/saba-futai/sudoku/pkg/obfs/httpmask"
|
||||
"github.com/saba-futai/sudoku/pkg/obfs/sudoku"
|
||||
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
)
|
||||
|
||||
type Sudoku struct {
|
||||
@@ -45,25 +42,13 @@ type SudokuOption struct {
|
||||
}
|
||||
|
||||
// DialContext implements C.ProxyAdapter
|
||||
func (s *Sudoku) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn, error) {
|
||||
return s.DialContextWithDialer(ctx, dialer.NewDialer(s.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// DialContextWithDialer implements C.ProxyAdapter
|
||||
func (s *Sudoku) DialContextWithDialer(ctx context.Context, d C.Dialer, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
if len(s.option.DialerProxy) > 0 {
|
||||
d, err = proxydialer.NewByName(s.option.DialerProxy, d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Sudoku) DialContext(ctx context.Context, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
cfg, err := s.buildConfig(metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, err := d.DialContext(ctx, "tcp", s.addr)
|
||||
c, err := s.dialer.DialContext(ctx, "tcp", s.addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %w", s.addr, err)
|
||||
}
|
||||
@@ -95,11 +80,6 @@ func (s *Sudoku) SupportUOT() bool {
|
||||
return false // Sudoku protocol only supports TCP
|
||||
}
|
||||
|
||||
// SupportWithDialer implements C.ProxyAdapter
|
||||
func (s *Sudoku) SupportWithDialer() C.NetWork {
|
||||
return C.TCP
|
||||
}
|
||||
|
||||
// ProxyInfo implements C.ProxyAdapter
|
||||
func (s *Sudoku) ProxyInfo() C.ProxyInfo {
|
||||
info := s.Base.ProxyInfo()
|
||||
@@ -206,7 +186,7 @@ func NewSudoku(option SudokuOption) (*Sudoku, error) {
|
||||
baseConf.AEADMethod = option.AEADMethod
|
||||
}
|
||||
|
||||
return &Sudoku{
|
||||
outbound := &Sudoku{
|
||||
Base: &Base{
|
||||
name: option.Name,
|
||||
addr: baseConf.ServerAddress,
|
||||
@@ -221,7 +201,9 @@ func NewSudoku(option SudokuOption) (*Sudoku, error) {
|
||||
option: &option,
|
||||
table: table,
|
||||
baseConf: baseConf,
|
||||
}, nil
|
||||
}
|
||||
outbound.dialer = option.NewDialer(outbound.DialOptions())
|
||||
return outbound, nil
|
||||
}
|
||||
|
||||
func buildSudokuHandshakePayload(key string) [16]byte {
|
||||
|
||||
@@ -11,9 +11,7 @@ import (
|
||||
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/component/ca"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/ech"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
tlsC "github.com/metacubex/mihomo/component/tls"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/transport/gun"
|
||||
@@ -196,18 +194,7 @@ func (t *Trojan) DialContext(ctx context.Context, metadata *C.Metadata) (_ C.Con
|
||||
|
||||
return NewConn(c, t), nil
|
||||
}
|
||||
return t.DialContextWithDialer(ctx, dialer.NewDialer(t.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// DialContextWithDialer implements C.ProxyAdapter
|
||||
func (t *Trojan) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
if len(t.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(t.option.DialerProxy, dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
c, err := dialer.DialContext(ctx, "tcp", t.addr)
|
||||
c, err = t.dialer.DialContext(ctx, "tcp", t.addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %w", t.addr, err)
|
||||
}
|
||||
@@ -250,21 +237,10 @@ func (t *Trojan) ListenPacketContext(ctx context.Context, metadata *C.Metadata)
|
||||
pc := trojan.NewPacketConn(c)
|
||||
return newPacketConn(pc, t), err
|
||||
}
|
||||
return t.ListenPacketWithDialer(ctx, dialer.NewDialer(t.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// ListenPacketWithDialer implements C.ProxyAdapter
|
||||
func (t *Trojan) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||
if len(t.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(t.option.DialerProxy, dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err = t.ResolveUDP(ctx, metadata); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c, err := dialer.DialContext(ctx, "tcp", t.addr)
|
||||
c, err = t.dialer.DialContext(ctx, "tcp", t.addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %w", t.addr, err)
|
||||
}
|
||||
@@ -280,11 +256,6 @@ func (t *Trojan) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, me
|
||||
return newPacketConn(pc, t), err
|
||||
}
|
||||
|
||||
// SupportWithDialer implements C.ProxyAdapter
|
||||
func (t *Trojan) SupportWithDialer() C.NetWork {
|
||||
return C.ALLNet
|
||||
}
|
||||
|
||||
// SupportUOT implements C.ProxyAdapter
|
||||
func (t *Trojan) SupportUOT() bool {
|
||||
return true
|
||||
@@ -327,6 +298,7 @@ func NewTrojan(option TrojanOption) (*Trojan, error) {
|
||||
option: &option,
|
||||
hexPassword: trojan.Key(option.Password),
|
||||
}
|
||||
t.dialer = option.NewDialer(t.DialOptions())
|
||||
|
||||
var err error
|
||||
t.realityConfig, err = option.RealityOpts.Parse()
|
||||
@@ -355,15 +327,7 @@ func NewTrojan(option TrojanOption) (*Trojan, error) {
|
||||
|
||||
if option.Network == "grpc" {
|
||||
dialFn := func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
var err error
|
||||
var cDialer C.Dialer = dialer.NewDialer(t.DialOptions()...)
|
||||
if len(t.option.DialerProxy) > 0 {
|
||||
cDialer, err = proxydialer.NewByName(t.option.DialerProxy, cDialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
c, err := cDialer.DialContext(ctx, "tcp", t.addr)
|
||||
c, err := t.dialer.DialContext(ctx, "tcp", t.addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %s", t.addr, err.Error())
|
||||
}
|
||||
|
||||
@@ -10,9 +10,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/component/ca"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/ech"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
tlsC "github.com/metacubex/mihomo/component/tls"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/transport/tuic"
|
||||
@@ -70,12 +68,7 @@ type TuicOption struct {
|
||||
|
||||
// DialContext implements C.ProxyAdapter
|
||||
func (t *Tuic) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn, error) {
|
||||
return t.DialContextWithDialer(ctx, dialer.NewDialer(t.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// DialContextWithDialer implements C.ProxyAdapter
|
||||
func (t *Tuic) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (C.Conn, error) {
|
||||
conn, err := t.client.DialContextWithDialer(ctx, metadata, dialer, t.dialWithDialer)
|
||||
conn, err := t.client.DialContext(ctx, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -84,11 +77,6 @@ func (t *Tuic) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metad
|
||||
|
||||
// ListenPacketContext implements C.ProxyAdapter
|
||||
func (t *Tuic) ListenPacketContext(ctx context.Context, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||
return t.ListenPacketWithDialer(ctx, dialer.NewDialer(t.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// ListenPacketWithDialer implements C.ProxyAdapter
|
||||
func (t *Tuic) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||
if err = t.ResolveUDP(ctx, metadata); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -98,7 +86,7 @@ func (t *Tuic) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, meta
|
||||
uotMetadata := *metadata
|
||||
uotMetadata.Host = uotDestination.Fqdn
|
||||
uotMetadata.DstPort = uotDestination.Port
|
||||
c, err := t.DialContextWithDialer(ctx, dialer, &uotMetadata)
|
||||
c, err := t.DialContext(ctx, &uotMetadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -112,25 +100,14 @@ func (t *Tuic) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, meta
|
||||
return newPacketConn(uot.NewLazyConn(c, uot.Request{Destination: destination}), t), nil
|
||||
}
|
||||
}
|
||||
pc, err := t.client.ListenPacketWithDialer(ctx, metadata, dialer, t.dialWithDialer)
|
||||
pc, err := t.client.ListenPacket(ctx, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newPacketConn(pc, t), nil
|
||||
}
|
||||
|
||||
// SupportWithDialer implements C.ProxyAdapter
|
||||
func (t *Tuic) SupportWithDialer() C.NetWork {
|
||||
return C.ALLNet
|
||||
}
|
||||
|
||||
func (t *Tuic) dialWithDialer(ctx context.Context, dialer C.Dialer) (transport *quic.Transport, addr net.Addr, err error) {
|
||||
if len(t.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(t.option.DialerProxy, dialer)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
func (t *Tuic) dial(ctx context.Context) (transport *quic.Transport, addr net.Addr, err error) {
|
||||
udpAddr, err := resolveUDPAddr(ctx, "udp", t.addr, t.prefer)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -141,7 +118,7 @@ func (t *Tuic) dialWithDialer(ctx context.Context, dialer C.Dialer) (transport *
|
||||
}
|
||||
addr = udpAddr
|
||||
var pc net.PacketConn
|
||||
pc, err = dialer.ListenPacket(ctx, "udp", "", udpAddr.AddrPort())
|
||||
pc, err = t.dialer.ListenPacket(ctx, "udp", "", udpAddr.AddrPort())
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -285,6 +262,7 @@ func NewTuic(option TuicOption) (*Tuic, error) {
|
||||
tlsConfig: tlsClientConfig,
|
||||
echConfig: echConfig,
|
||||
}
|
||||
t.dialer = option.NewDialer(t.DialOptions())
|
||||
|
||||
clientMaxOpenStreams := int64(option.MaxOpenStreams)
|
||||
|
||||
@@ -313,7 +291,7 @@ func NewTuic(option TuicOption) (*Tuic, error) {
|
||||
CWND: option.CWND,
|
||||
}
|
||||
|
||||
t.client = tuic.NewPoolClientV4(clientOption)
|
||||
t.client = tuic.NewPoolClientV4(clientOption, t.dial)
|
||||
} else {
|
||||
maxUdpRelayPacketSize := option.MaxUdpRelayPacketSize
|
||||
if maxUdpRelayPacketSize > tuic.MaxFragSizeV5 {
|
||||
@@ -332,7 +310,7 @@ func NewTuic(option TuicOption) (*Tuic, error) {
|
||||
CWND: option.CWND,
|
||||
}
|
||||
|
||||
t.client = tuic.NewPoolClientV5(clientOption)
|
||||
t.client = tuic.NewPoolClientV5(clientOption, t.dial)
|
||||
}
|
||||
|
||||
return t, nil
|
||||
|
||||
@@ -12,9 +12,7 @@ import (
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/common/utils"
|
||||
"github.com/metacubex/mihomo/component/ca"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/ech"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
tlsC "github.com/metacubex/mihomo/component/tls"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/transport/gun"
|
||||
@@ -252,18 +250,7 @@ func (v *Vless) DialContext(ctx context.Context, metadata *C.Metadata) (_ C.Conn
|
||||
|
||||
return NewConn(c, v), nil
|
||||
}
|
||||
return v.DialContextWithDialer(ctx, dialer.NewDialer(v.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// DialContextWithDialer implements C.ProxyAdapter
|
||||
func (v *Vless) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
if len(v.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(v.option.DialerProxy, dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
c, err := dialer.DialContext(ctx, "tcp", v.addr)
|
||||
c, err = v.dialer.DialContext(ctx, "tcp", v.addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error())
|
||||
}
|
||||
@@ -301,23 +288,12 @@ func (v *Vless) ListenPacketContext(ctx context.Context, metadata *C.Metadata) (
|
||||
|
||||
return v.ListenPacketOnStreamConn(ctx, c, metadata)
|
||||
}
|
||||
return v.ListenPacketWithDialer(ctx, dialer.NewDialer(v.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// ListenPacketWithDialer implements C.ProxyAdapter
|
||||
func (v *Vless) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||
if len(v.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(v.option.DialerProxy, dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err = v.ResolveUDP(ctx, metadata); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, err := dialer.DialContext(ctx, "tcp", v.addr)
|
||||
c, err = v.dialer.DialContext(ctx, "tcp", v.addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error())
|
||||
}
|
||||
@@ -333,11 +309,6 @@ func (v *Vless) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met
|
||||
return v.ListenPacketOnStreamConn(ctx, c, metadata)
|
||||
}
|
||||
|
||||
// SupportWithDialer implements C.ProxyAdapter
|
||||
func (v *Vless) SupportWithDialer() C.NetWork {
|
||||
return C.ALLNet
|
||||
}
|
||||
|
||||
// ListenPacketOnStreamConn implements C.ProxyAdapter
|
||||
func (v *Vless) ListenPacketOnStreamConn(ctx context.Context, c net.Conn, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||
if err = v.ResolveUDP(ctx, metadata); err != nil {
|
||||
@@ -457,6 +428,7 @@ func NewVless(option VlessOption) (*Vless, error) {
|
||||
client: client,
|
||||
option: &option,
|
||||
}
|
||||
v.dialer = option.NewDialer(v.DialOptions())
|
||||
|
||||
v.encryption, err = encryption.NewClient(option.Encryption)
|
||||
if err != nil {
|
||||
@@ -480,15 +452,7 @@ func NewVless(option VlessOption) (*Vless, error) {
|
||||
}
|
||||
case "grpc":
|
||||
dialFn := func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
var err error
|
||||
var cDialer C.Dialer = dialer.NewDialer(v.DialOptions()...)
|
||||
if len(v.option.DialerProxy) > 0 {
|
||||
cDialer, err = proxydialer.NewByName(v.option.DialerProxy, cDialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
c, err := cDialer.DialContext(ctx, "tcp", v.addr)
|
||||
c, err := v.dialer.DialContext(ctx, "tcp", v.addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error())
|
||||
}
|
||||
|
||||
@@ -14,9 +14,7 @@ import (
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/common/utils"
|
||||
"github.com/metacubex/mihomo/component/ca"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/ech"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
tlsC "github.com/metacubex/mihomo/component/tls"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/ntp"
|
||||
@@ -313,18 +311,7 @@ func (v *Vmess) DialContext(ctx context.Context, metadata *C.Metadata) (_ C.Conn
|
||||
|
||||
return NewConn(c, v), nil
|
||||
}
|
||||
return v.DialContextWithDialer(ctx, dialer.NewDialer(v.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// DialContextWithDialer implements C.ProxyAdapter
|
||||
func (v *Vmess) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.Conn, err error) {
|
||||
if len(v.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(v.option.DialerProxy, dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
c, err := dialer.DialContext(ctx, "tcp", v.addr)
|
||||
c, err = v.dialer.DialContext(ctx, "tcp", v.addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error())
|
||||
}
|
||||
@@ -358,23 +345,12 @@ func (v *Vmess) ListenPacketContext(ctx context.Context, metadata *C.Metadata) (
|
||||
}
|
||||
return v.ListenPacketOnStreamConn(ctx, c, metadata)
|
||||
}
|
||||
return v.ListenPacketWithDialer(ctx, dialer.NewDialer(v.DialOptions()...), metadata)
|
||||
}
|
||||
|
||||
// ListenPacketWithDialer implements C.ProxyAdapter
|
||||
func (v *Vmess) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||
if len(v.option.DialerProxy) > 0 {
|
||||
dialer, err = proxydialer.NewByName(v.option.DialerProxy, dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err = v.ResolveUDP(ctx, metadata); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, err := dialer.DialContext(ctx, "tcp", v.addr)
|
||||
c, err = v.dialer.DialContext(ctx, "tcp", v.addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error())
|
||||
}
|
||||
@@ -389,11 +365,6 @@ func (v *Vmess) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met
|
||||
return v.ListenPacketOnStreamConn(ctx, c, metadata)
|
||||
}
|
||||
|
||||
// SupportWithDialer implements C.ProxyAdapter
|
||||
func (v *Vmess) SupportWithDialer() C.NetWork {
|
||||
return C.ALLNet
|
||||
}
|
||||
|
||||
// ProxyInfo implements C.ProxyAdapter
|
||||
func (v *Vmess) ProxyInfo() C.ProxyInfo {
|
||||
info := v.Base.ProxyInfo()
|
||||
@@ -467,6 +438,7 @@ func NewVmess(option VmessOption) (*Vmess, error) {
|
||||
client: client,
|
||||
option: &option,
|
||||
}
|
||||
v.dialer = option.NewDialer(v.DialOptions())
|
||||
|
||||
v.realityConfig, err = v.option.RealityOpts.Parse()
|
||||
if err != nil {
|
||||
@@ -485,15 +457,7 @@ func NewVmess(option VmessOption) (*Vmess, error) {
|
||||
}
|
||||
case "grpc":
|
||||
dialFn := func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||
var err error
|
||||
var cDialer C.Dialer = dialer.NewDialer(v.DialOptions()...)
|
||||
if len(v.option.DialerProxy) > 0 {
|
||||
cDialer, err = proxydialer.NewByName(v.option.DialerProxy, cDialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
c, err := cDialer.DialContext(ctx, "tcp", v.addr)
|
||||
c, err := v.dialer.DialContext(ctx, "tcp", v.addr)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error())
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ type WireGuard struct {
|
||||
bind *wireguard.ClientBind
|
||||
device wireguardGoDevice
|
||||
tunDevice wireguard.Device
|
||||
dialer proxydialer.SingDialer
|
||||
resolver resolver.Resolver
|
||||
|
||||
initOk atomic.Bool
|
||||
@@ -177,8 +176,8 @@ func NewWireGuard(option WireGuardOption) (*WireGuard, error) {
|
||||
prefer: C.NewDNSPrefer(option.IPVersion),
|
||||
},
|
||||
}
|
||||
singDialer := proxydialer.NewSlowDownSingDialer(proxydialer.NewByNameSingDialer(option.DialerProxy, dialer.NewDialer(outbound.DialOptions()...)), slowdown.New())
|
||||
outbound.dialer = singDialer
|
||||
outbound.dialer = option.NewDialer(outbound.DialOptions())
|
||||
singDialer := proxydialer.NewSlowDownSingDialer(proxydialer.NewSingDialer(outbound.dialer), slowdown.New())
|
||||
|
||||
var reserved [3]uint8
|
||||
if len(option.Reserved) > 0 {
|
||||
@@ -196,7 +195,7 @@ func NewWireGuard(option WireGuardOption) (*WireGuard, error) {
|
||||
outbound.connectAddr = option.Addr()
|
||||
}
|
||||
}
|
||||
outbound.bind = wireguard.NewClientBind(context.Background(), wgSingErrorHandler{outbound.Name()}, outbound.dialer, isConnect, outbound.connectAddr.AddrPort(), reserved)
|
||||
outbound.bind = wireguard.NewClientBind(context.Background(), wgSingErrorHandler{outbound.Name()}, singDialer, isConnect, outbound.connectAddr.AddrPort(), reserved)
|
||||
|
||||
var err error
|
||||
outbound.localPrefixes, err = option.Prefixes()
|
||||
|
||||
@@ -35,18 +35,6 @@ func (lb *LoadBalance) Now() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (r *Relay) Providers() []P.ProxyProvider {
|
||||
return r.providers
|
||||
}
|
||||
|
||||
func (r *Relay) Proxies() []C.Proxy {
|
||||
return r.GetProxies(false)
|
||||
}
|
||||
|
||||
func (r *Relay) Now() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (s *Selector) Providers() []P.ProxyProvider {
|
||||
return s.providers
|
||||
}
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
package outboundgroup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/metacubex/mihomo/adapter/outbound"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
P "github.com/metacubex/mihomo/constant/provider"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
)
|
||||
|
||||
type Relay struct {
|
||||
*GroupBase
|
||||
Hidden bool
|
||||
Icon string
|
||||
}
|
||||
|
||||
// DialContext implements C.ProxyAdapter
|
||||
func (r *Relay) DialContext(ctx context.Context, metadata *C.Metadata) (C.Conn, error) {
|
||||
proxies, chainProxies := r.proxies(metadata, true)
|
||||
|
||||
switch len(proxies) {
|
||||
case 0:
|
||||
return outbound.NewDirect().DialContext(ctx, metadata)
|
||||
case 1:
|
||||
return proxies[0].DialContext(ctx, metadata)
|
||||
}
|
||||
var d C.Dialer
|
||||
d = dialer.NewDialer()
|
||||
for _, proxy := range proxies[:len(proxies)-1] {
|
||||
d = proxydialer.New(proxy, d, false)
|
||||
}
|
||||
last := proxies[len(proxies)-1]
|
||||
conn, err := last.DialContextWithDialer(ctx, d, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := len(chainProxies) - 2; i >= 0; i-- {
|
||||
conn.AppendToChains(chainProxies[i])
|
||||
}
|
||||
|
||||
conn.AppendToChains(r)
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// ListenPacketContext implements C.ProxyAdapter
|
||||
func (r *Relay) ListenPacketContext(ctx context.Context, metadata *C.Metadata) (_ C.PacketConn, err error) {
|
||||
proxies, chainProxies := r.proxies(metadata, true)
|
||||
|
||||
switch len(proxies) {
|
||||
case 0:
|
||||
return outbound.NewDirect().ListenPacketContext(ctx, metadata)
|
||||
case 1:
|
||||
return proxies[0].ListenPacketContext(ctx, metadata)
|
||||
}
|
||||
|
||||
var d C.Dialer
|
||||
d = dialer.NewDialer()
|
||||
for _, proxy := range proxies[:len(proxies)-1] {
|
||||
d = proxydialer.New(proxy, d, false)
|
||||
}
|
||||
last := proxies[len(proxies)-1]
|
||||
pc, err := last.ListenPacketWithDialer(ctx, d, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := len(chainProxies) - 2; i >= 0; i-- {
|
||||
pc.AppendToChains(chainProxies[i])
|
||||
}
|
||||
|
||||
pc.AppendToChains(r)
|
||||
|
||||
return pc, nil
|
||||
}
|
||||
|
||||
// SupportUDP implements C.ProxyAdapter
|
||||
func (r *Relay) SupportUDP() bool {
|
||||
proxies, _ := r.proxies(nil, false)
|
||||
if len(proxies) == 0 { // C.Direct
|
||||
return true
|
||||
}
|
||||
for i := len(proxies) - 1; i >= 0; i-- {
|
||||
proxy := proxies[i]
|
||||
if !proxy.SupportUDP() {
|
||||
return false
|
||||
}
|
||||
if proxy.SupportUOT() {
|
||||
return true
|
||||
}
|
||||
switch proxy.SupportWithDialer() {
|
||||
case C.ALLNet:
|
||||
case C.UDP:
|
||||
default: // C.TCP and C.InvalidNet
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// MarshalJSON implements C.ProxyAdapter
|
||||
func (r *Relay) MarshalJSON() ([]byte, error) {
|
||||
all := []string{}
|
||||
for _, proxy := range r.GetProxies(false) {
|
||||
all = append(all, proxy.Name())
|
||||
}
|
||||
return json.Marshal(map[string]any{
|
||||
"type": r.Type().String(),
|
||||
"all": all,
|
||||
"hidden": r.Hidden,
|
||||
"icon": r.Icon,
|
||||
})
|
||||
}
|
||||
|
||||
func (r *Relay) proxies(metadata *C.Metadata, touch bool) ([]C.Proxy, []C.Proxy) {
|
||||
rawProxies := r.GetProxies(touch)
|
||||
|
||||
var proxies []C.Proxy
|
||||
var chainProxies []C.Proxy
|
||||
var targetProxies []C.Proxy
|
||||
|
||||
for n, proxy := range rawProxies {
|
||||
proxies = append(proxies, proxy)
|
||||
chainProxies = append(chainProxies, proxy)
|
||||
subproxy := proxy.Unwrap(metadata, touch)
|
||||
for subproxy != nil {
|
||||
chainProxies = append(chainProxies, subproxy)
|
||||
proxies[n] = subproxy
|
||||
subproxy = subproxy.Unwrap(metadata, touch)
|
||||
}
|
||||
}
|
||||
|
||||
for _, proxy := range proxies {
|
||||
if proxy.Type() != C.Direct && proxy.Type() != C.Compatible {
|
||||
targetProxies = append(targetProxies, proxy)
|
||||
}
|
||||
}
|
||||
|
||||
return targetProxies, chainProxies
|
||||
}
|
||||
|
||||
func (r *Relay) Addr() string {
|
||||
proxies, _ := r.proxies(nil, false)
|
||||
return proxies[len(proxies)-1].Addr()
|
||||
}
|
||||
|
||||
func NewRelay(option *GroupCommonOption, providers []P.ProxyProvider) *Relay {
|
||||
log.Warnln("The group [%s] with relay type is deprecated, please using dialer-proxy instead", option.Name)
|
||||
return &Relay{
|
||||
GroupBase: NewGroupBase(GroupBaseOption{
|
||||
Name: option.Name,
|
||||
Type: C.Relay,
|
||||
Providers: providers,
|
||||
}),
|
||||
Hidden: option.Hidden,
|
||||
Icon: option.Icon,
|
||||
}
|
||||
}
|
||||
@@ -8,146 +8,151 @@ import (
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
)
|
||||
|
||||
func ParseProxy(mapping map[string]any) (C.Proxy, error) {
|
||||
func ParseProxy(mapping map[string]any, options ...ProxyOption) (C.Proxy, error) {
|
||||
decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true, KeyReplacer: structure.DefaultKeyReplacer})
|
||||
proxyType, existType := mapping["type"].(string)
|
||||
if !existType {
|
||||
return nil, fmt.Errorf("missing type")
|
||||
}
|
||||
|
||||
opt := applyProxyOptions(options...)
|
||||
basicOption := outbound.BasicOption{
|
||||
DialerForAPI: opt.DialerForAPI,
|
||||
}
|
||||
|
||||
var (
|
||||
proxy outbound.ProxyAdapter
|
||||
err error
|
||||
)
|
||||
switch proxyType {
|
||||
case "ss":
|
||||
ssOption := &outbound.ShadowSocksOption{}
|
||||
ssOption := &outbound.ShadowSocksOption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, ssOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy, err = outbound.NewShadowSocks(*ssOption)
|
||||
case "ssr":
|
||||
ssrOption := &outbound.ShadowSocksROption{}
|
||||
ssrOption := &outbound.ShadowSocksROption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, ssrOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy, err = outbound.NewShadowSocksR(*ssrOption)
|
||||
case "socks5":
|
||||
socksOption := &outbound.Socks5Option{}
|
||||
socksOption := &outbound.Socks5Option{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, socksOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy, err = outbound.NewSocks5(*socksOption)
|
||||
case "http":
|
||||
httpOption := &outbound.HttpOption{}
|
||||
httpOption := &outbound.HttpOption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, httpOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy, err = outbound.NewHttp(*httpOption)
|
||||
case "vmess":
|
||||
vmessOption := &outbound.VmessOption{}
|
||||
vmessOption := &outbound.VmessOption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, vmessOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy, err = outbound.NewVmess(*vmessOption)
|
||||
case "vless":
|
||||
vlessOption := &outbound.VlessOption{}
|
||||
vlessOption := &outbound.VlessOption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, vlessOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy, err = outbound.NewVless(*vlessOption)
|
||||
case "snell":
|
||||
snellOption := &outbound.SnellOption{}
|
||||
snellOption := &outbound.SnellOption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, snellOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy, err = outbound.NewSnell(*snellOption)
|
||||
case "trojan":
|
||||
trojanOption := &outbound.TrojanOption{}
|
||||
trojanOption := &outbound.TrojanOption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, trojanOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy, err = outbound.NewTrojan(*trojanOption)
|
||||
case "hysteria":
|
||||
hyOption := &outbound.HysteriaOption{}
|
||||
hyOption := &outbound.HysteriaOption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, hyOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy, err = outbound.NewHysteria(*hyOption)
|
||||
case "hysteria2":
|
||||
hyOption := &outbound.Hysteria2Option{}
|
||||
hyOption := &outbound.Hysteria2Option{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, hyOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy, err = outbound.NewHysteria2(*hyOption)
|
||||
case "wireguard":
|
||||
wgOption := &outbound.WireGuardOption{}
|
||||
wgOption := &outbound.WireGuardOption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, wgOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy, err = outbound.NewWireGuard(*wgOption)
|
||||
case "tuic":
|
||||
tuicOption := &outbound.TuicOption{}
|
||||
tuicOption := &outbound.TuicOption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, tuicOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy, err = outbound.NewTuic(*tuicOption)
|
||||
case "direct":
|
||||
directOption := &outbound.DirectOption{}
|
||||
directOption := &outbound.DirectOption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, directOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy = outbound.NewDirectWithOption(*directOption)
|
||||
case "dns":
|
||||
dnsOptions := &outbound.DnsOption{}
|
||||
dnsOptions := &outbound.DnsOption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, dnsOptions)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy = outbound.NewDnsWithOption(*dnsOptions)
|
||||
case "reject":
|
||||
rejectOption := &outbound.RejectOption{}
|
||||
rejectOption := &outbound.RejectOption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, rejectOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy = outbound.NewRejectWithOption(*rejectOption)
|
||||
case "ssh":
|
||||
sshOption := &outbound.SshOption{}
|
||||
sshOption := &outbound.SshOption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, sshOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy, err = outbound.NewSsh(*sshOption)
|
||||
case "mieru":
|
||||
mieruOption := &outbound.MieruOption{}
|
||||
mieruOption := &outbound.MieruOption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, mieruOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy, err = outbound.NewMieru(*mieruOption)
|
||||
case "anytls":
|
||||
anytlsOption := &outbound.AnyTLSOption{}
|
||||
anytlsOption := &outbound.AnyTLSOption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, anytlsOption)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
proxy, err = outbound.NewAnyTLS(*anytlsOption)
|
||||
case "sudoku":
|
||||
sudokuOption := &outbound.SudokuOption{}
|
||||
sudokuOption := &outbound.SudokuOption{BasicOption: basicOption}
|
||||
err = decoder.Decode(mapping, sudokuOption)
|
||||
if err != nil {
|
||||
break
|
||||
@@ -178,3 +183,23 @@ func ParseProxy(mapping map[string]any) (C.Proxy, error) {
|
||||
proxy = outbound.NewAutoCloseProxyAdapter(proxy)
|
||||
return NewProxy(proxy), nil
|
||||
}
|
||||
|
||||
type proxyOption struct {
|
||||
DialerForAPI C.Dialer
|
||||
}
|
||||
|
||||
func applyProxyOptions(options ...ProxyOption) proxyOption {
|
||||
opt := proxyOption{}
|
||||
for _, o := range options {
|
||||
o(&opt)
|
||||
}
|
||||
return opt
|
||||
}
|
||||
|
||||
type ProxyOption func(opt *proxyOption)
|
||||
|
||||
func WithDialerForAPI(dialer C.Dialer) ProxyOption {
|
||||
return func(opt *proxyOption) {
|
||||
opt.DialerForAPI = dialer
|
||||
}
|
||||
}
|
||||
|
||||
37
mihomo/component/proxydialer/byname.go
Normal file
37
mihomo/component/proxydialer/byname.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package proxydialer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/tunnel"
|
||||
)
|
||||
|
||||
type byNameProxyDialer struct {
|
||||
proxyName string
|
||||
}
|
||||
|
||||
func (d byNameProxyDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
proxies := tunnel.Proxies()
|
||||
proxy, ok := proxies[d.proxyName]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("proxyName[%s] not found", d.proxyName)
|
||||
}
|
||||
return New(proxy, true).DialContext(ctx, network, address)
|
||||
}
|
||||
|
||||
func (d byNameProxyDialer) ListenPacket(ctx context.Context, network, address string, rAddrPort netip.AddrPort) (net.PacketConn, error) {
|
||||
proxies := tunnel.Proxies()
|
||||
proxy, ok := proxies[d.proxyName]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("proxyName[%s] not found", d.proxyName)
|
||||
}
|
||||
return New(proxy, true).ListenPacket(ctx, network, address, rAddrPort)
|
||||
}
|
||||
|
||||
func NewByName(proxyName string) C.Dialer {
|
||||
return byNameProxyDialer{proxyName: proxyName}
|
||||
}
|
||||
@@ -2,34 +2,22 @@ package proxydialer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"strings"
|
||||
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/tunnel"
|
||||
"github.com/metacubex/mihomo/tunnel/statistic"
|
||||
)
|
||||
|
||||
type proxyDialer struct {
|
||||
proxy C.ProxyAdapter
|
||||
dialer C.Dialer
|
||||
statistic bool
|
||||
}
|
||||
|
||||
func New(proxy C.ProxyAdapter, dialer C.Dialer, statistic bool) C.Dialer {
|
||||
return proxyDialer{proxy: proxy, dialer: dialer, statistic: statistic}
|
||||
}
|
||||
|
||||
func NewByName(proxyName string, dialer C.Dialer) (C.Dialer, error) {
|
||||
proxies := tunnel.Proxies()
|
||||
if proxy, ok := proxies[proxyName]; ok {
|
||||
return New(proxy, dialer, true), nil
|
||||
}
|
||||
return nil, fmt.Errorf("proxyName[%s] not found", proxyName)
|
||||
func New(proxy C.ProxyAdapter, statistic bool) C.Dialer {
|
||||
return proxyDialer{proxy: proxy, statistic: statistic}
|
||||
}
|
||||
|
||||
func (p proxyDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
@@ -50,13 +38,7 @@ func (p proxyDialer) DialContext(ctx context.Context, network, address string) (
|
||||
}
|
||||
return N.NewBindPacketConn(pc, currentMeta.UDPAddr()), nil
|
||||
}
|
||||
var conn C.Conn
|
||||
var err error
|
||||
if _, ok := p.dialer.(dialer.Dialer); ok { // first using old function to let mux work
|
||||
conn, err = p.proxy.DialContext(ctx, currentMeta)
|
||||
} else {
|
||||
conn, err = p.proxy.DialContextWithDialer(ctx, p.dialer, currentMeta)
|
||||
}
|
||||
conn, err := p.proxy.DialContext(ctx, currentMeta)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -72,14 +54,8 @@ func (p proxyDialer) ListenPacket(ctx context.Context, network, address string,
|
||||
}
|
||||
|
||||
func (p proxyDialer) listenPacket(ctx context.Context, currentMeta *C.Metadata) (C.PacketConn, error) {
|
||||
var pc C.PacketConn
|
||||
var err error
|
||||
currentMeta.NetWork = C.UDP
|
||||
if _, ok := p.dialer.(dialer.Dialer); ok { // first using old function to let mux work
|
||||
pc, err = p.proxy.ListenPacketContext(ctx, currentMeta)
|
||||
} else {
|
||||
pc, err = p.proxy.ListenPacketWithDialer(ctx, p.dialer, currentMeta)
|
||||
}
|
||||
pc, err := p.proxy.ListenPacketContext(ctx, currentMeta)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -12,71 +12,22 @@ import (
|
||||
|
||||
type SingDialer interface {
|
||||
N.Dialer
|
||||
SetDialer(dialer C.Dialer)
|
||||
}
|
||||
|
||||
type singDialer proxyDialer
|
||||
type singDialer struct {
|
||||
cDialer C.Dialer
|
||||
}
|
||||
|
||||
var _ N.Dialer = (*singDialer)(nil)
|
||||
|
||||
func (d *singDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||
return (*proxyDialer)(d).DialContext(ctx, network, destination.String())
|
||||
func (d singDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||
return d.cDialer.DialContext(ctx, network, destination.String())
|
||||
}
|
||||
|
||||
func (d *singDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||
return (*proxyDialer)(d).ListenPacket(ctx, "udp", "", destination.AddrPort())
|
||||
func (d singDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||
return d.cDialer.ListenPacket(ctx, "udp", "", destination.AddrPort())
|
||||
}
|
||||
|
||||
func (d *singDialer) SetDialer(dialer C.Dialer) {
|
||||
(*proxyDialer)(d).dialer = dialer
|
||||
}
|
||||
|
||||
func NewSingDialer(proxy C.ProxyAdapter, dialer C.Dialer, statistic bool) SingDialer {
|
||||
return (*singDialer)(&proxyDialer{
|
||||
proxy: proxy,
|
||||
dialer: dialer,
|
||||
statistic: statistic,
|
||||
})
|
||||
}
|
||||
|
||||
type byNameSingDialer struct {
|
||||
dialer C.Dialer
|
||||
proxyName string
|
||||
}
|
||||
|
||||
var _ N.Dialer = (*byNameSingDialer)(nil)
|
||||
|
||||
func (d *byNameSingDialer) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
|
||||
var cDialer C.Dialer = d.dialer
|
||||
if len(d.proxyName) > 0 {
|
||||
pd, err := NewByName(d.proxyName, d.dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cDialer = pd
|
||||
}
|
||||
return cDialer.DialContext(ctx, network, destination.String())
|
||||
}
|
||||
|
||||
func (d *byNameSingDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||
var cDialer C.Dialer = d.dialer
|
||||
if len(d.proxyName) > 0 {
|
||||
pd, err := NewByName(d.proxyName, d.dialer)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cDialer = pd
|
||||
}
|
||||
return cDialer.ListenPacket(ctx, "udp", "", destination.AddrPort())
|
||||
}
|
||||
|
||||
func (d *byNameSingDialer) SetDialer(dialer C.Dialer) {
|
||||
d.dialer = dialer
|
||||
}
|
||||
|
||||
func NewByNameSingDialer(proxyName string, dialer C.Dialer) SingDialer {
|
||||
return &byNameSingDialer{
|
||||
dialer: dialer,
|
||||
proxyName: proxyName,
|
||||
}
|
||||
func NewSingDialer(cDialer C.Dialer) SingDialer {
|
||||
return singDialer{cDialer: cDialer}
|
||||
}
|
||||
|
||||
@@ -121,17 +121,6 @@ type ProxyAdapter interface {
|
||||
ProxyInfo() ProxyInfo
|
||||
MarshalJSON() ([]byte, error)
|
||||
|
||||
// Deprecated: use DialContextWithDialer and ListenPacketWithDialer instead.
|
||||
// StreamConn wraps a protocol around net.Conn with Metadata.
|
||||
//
|
||||
// Examples:
|
||||
// conn, _ := net.DialContext(context.Background(), "tcp", "host:port")
|
||||
// conn, _ = adapter.StreamConnContext(context.Background(), conn, metadata)
|
||||
//
|
||||
// It returns a C.Conn with protocol which start with
|
||||
// a new session (if any)
|
||||
StreamConnContext(ctx context.Context, c net.Conn, metadata *Metadata) (net.Conn, error)
|
||||
|
||||
// DialContext return a C.Conn with protocol which
|
||||
// contains multiplexing-related reuse logic (if any)
|
||||
DialContext(ctx context.Context, metadata *Metadata) (Conn, error)
|
||||
@@ -140,13 +129,6 @@ type ProxyAdapter interface {
|
||||
// SupportUOT return UDP over TCP support
|
||||
SupportUOT() bool
|
||||
|
||||
// SupportWithDialer only for deprecated relay group, the new protocol does not need to be implemented.
|
||||
SupportWithDialer() NetWork
|
||||
// DialContextWithDialer only for deprecated relay group, the new protocol does not need to be implemented.
|
||||
DialContextWithDialer(ctx context.Context, dialer Dialer, metadata *Metadata) (Conn, error)
|
||||
// ListenPacketWithDialer only for deprecated relay group, the new protocol does not need to be implemented.
|
||||
ListenPacketWithDialer(ctx context.Context, dialer Dialer, metadata *Metadata) (PacketConn, error)
|
||||
|
||||
// IsL3Protocol return ProxyAdapter working in L3 (tell dns module not pass the domain to avoid loopback)
|
||||
IsL3Protocol(metadata *Metadata) bool
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/proxydialer"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
mihomoNtp "github.com/metacubex/mihomo/ntp"
|
||||
|
||||
@@ -36,9 +37,13 @@ func ReCreateNTPService(server string, interval time.Duration, dialerProxy strin
|
||||
return
|
||||
}
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
var cDialer C.Dialer = dialer.NewDialer()
|
||||
if dialerProxy != "" {
|
||||
cDialer = proxydialer.NewByName(dialerProxy)
|
||||
}
|
||||
globalSrv = &Service{
|
||||
server: M.ParseSocksaddr(server),
|
||||
dialer: proxydialer.NewByNameSingDialer(dialerProxy, dialer.NewDialer()),
|
||||
dialer: proxydialer.NewSingDialer(cDialer),
|
||||
ticker: time.NewTicker(interval * time.Minute),
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
|
||||
@@ -18,13 +18,12 @@ var (
|
||||
TooManyOpenStreams = errors.New("tuic: too many open streams")
|
||||
)
|
||||
|
||||
type DialFunc func(ctx context.Context, dialer C.Dialer) (transport *quic.Transport, addr net.Addr, err error)
|
||||
type DialFunc func(ctx context.Context) (transport *quic.Transport, addr net.Addr, err error)
|
||||
|
||||
type Client interface {
|
||||
DialContextWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn DialFunc) (net.Conn, error)
|
||||
ListenPacketWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn DialFunc) (net.PacketConn, error)
|
||||
DialContext(ctx context.Context, metadata *C.Metadata) (net.Conn, error)
|
||||
ListenPacket(ctx context.Context, metadata *C.Metadata) (net.PacketConn, error)
|
||||
OpenStreams() int64
|
||||
DialerRef() C.Dialer
|
||||
LastVisited() time.Time
|
||||
SetLastVisited(last time.Time)
|
||||
Close()
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"net"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
@@ -17,30 +18,21 @@ import (
|
||||
list "github.com/bahlo/generic-list-go"
|
||||
)
|
||||
|
||||
type dialResult struct {
|
||||
transport *quic.Transport
|
||||
addr net.Addr
|
||||
err error
|
||||
}
|
||||
|
||||
type PoolClient struct {
|
||||
newClientOptionV4 *ClientOptionV4
|
||||
newClientOptionV5 *ClientOptionV5
|
||||
dialResultMap map[C.Dialer]dialResult
|
||||
dialResultMutex *sync.Mutex
|
||||
tcpClients *list.List[Client]
|
||||
tcpClientsMutex *sync.Mutex
|
||||
udpClients *list.List[Client]
|
||||
udpClientsMutex *sync.Mutex
|
||||
|
||||
dialHelper *poolDialHelper
|
||||
tcpClients list.List[Client]
|
||||
tcpClientsMutex sync.Mutex
|
||||
udpClients list.List[Client]
|
||||
udpClientsMutex sync.Mutex
|
||||
}
|
||||
|
||||
func (t *PoolClient) DialContextWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn DialFunc) (net.Conn, error) {
|
||||
newDialFn := func(ctx context.Context, dialer C.Dialer) (transport *quic.Transport, addr net.Addr, err error) {
|
||||
return t.dial(ctx, dialer, dialFn)
|
||||
}
|
||||
conn, err := t.getClient(false, dialer).DialContextWithDialer(ctx, metadata, dialer, newDialFn)
|
||||
func (t *PoolClient) DialContext(ctx context.Context, metadata *C.Metadata) (net.Conn, error) {
|
||||
conn, err := t.getClient(false).DialContext(ctx, metadata)
|
||||
if errors.Is(err, TooManyOpenStreams) {
|
||||
conn, err = t.newClient(false, dialer).DialContextWithDialer(ctx, metadata, dialer, newDialFn)
|
||||
conn, err = t.newClient(false).DialContext(ctx, metadata)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -48,13 +40,10 @@ func (t *PoolClient) DialContextWithDialer(ctx context.Context, metadata *C.Meta
|
||||
return N.NewRefConn(conn, t), err
|
||||
}
|
||||
|
||||
func (t *PoolClient) ListenPacketWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn DialFunc) (net.PacketConn, error) {
|
||||
newDialFn := func(ctx context.Context, dialer C.Dialer) (transport *quic.Transport, addr net.Addr, err error) {
|
||||
return t.dial(ctx, dialer, dialFn)
|
||||
}
|
||||
pc, err := t.getClient(true, dialer).ListenPacketWithDialer(ctx, metadata, dialer, newDialFn)
|
||||
func (t *PoolClient) ListenPacket(ctx context.Context, metadata *C.Metadata) (net.PacketConn, error) {
|
||||
pc, err := t.getClient(true).ListenPacket(ctx, metadata)
|
||||
if errors.Is(err, TooManyOpenStreams) {
|
||||
pc, err = t.newClient(true, dialer).ListenPacketWithDialer(ctx, metadata, dialer, newDialFn)
|
||||
pc, err = t.newClient(true).ListenPacket(ctx, metadata)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -62,58 +51,63 @@ func (t *PoolClient) ListenPacketWithDialer(ctx context.Context, metadata *C.Met
|
||||
return N.NewRefPacketConn(pc, t), nil
|
||||
}
|
||||
|
||||
func (t *PoolClient) dial(ctx context.Context, dialer C.Dialer, dialFn DialFunc) (transport *quic.Transport, addr net.Addr, err error) {
|
||||
t.dialResultMutex.Lock()
|
||||
dr, ok := t.dialResultMap[dialer]
|
||||
t.dialResultMutex.Unlock()
|
||||
if ok {
|
||||
return dr.transport, dr.addr, dr.err
|
||||
// poolDialHelper is a helper for dialFn
|
||||
// using a standalone struct to let finalizer working
|
||||
type poolDialHelper struct {
|
||||
dialFn DialFunc
|
||||
dialResult atomic.Pointer[dialResult]
|
||||
}
|
||||
|
||||
type dialResult struct {
|
||||
transport *quic.Transport
|
||||
addr net.Addr
|
||||
}
|
||||
|
||||
func (t *poolDialHelper) dial(ctx context.Context) (transport *quic.Transport, addr net.Addr, err error) {
|
||||
if dr := t.dialResult.Load(); dr != nil {
|
||||
return dr.transport, dr.addr, nil
|
||||
}
|
||||
|
||||
transport, addr, err = dialFn(ctx, dialer)
|
||||
transport, addr, err = t.dialFn(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if _, ok := transport.Conn.(*net.UDPConn); ok { // only cache the system's UDPConn
|
||||
transport.SetSingleUse(false) // don't close transport in each dial
|
||||
dr.transport, dr.addr, dr.err = transport, addr, err
|
||||
|
||||
t.dialResultMutex.Lock()
|
||||
t.dialResultMap[dialer] = dr
|
||||
t.dialResultMutex.Unlock()
|
||||
dr := &dialResult{transport: transport, addr: addr}
|
||||
t.dialResult.Store(dr)
|
||||
}
|
||||
|
||||
return transport, addr, err
|
||||
}
|
||||
|
||||
func (t *PoolClient) forceClose() {
|
||||
t.dialResultMutex.Lock()
|
||||
defer t.dialResultMutex.Unlock()
|
||||
for key := range t.dialResultMap {
|
||||
transport := t.dialResultMap[key].transport
|
||||
func (t *poolDialHelper) forceClose() {
|
||||
if dr := t.dialResult.Swap(nil); dr != nil {
|
||||
transport := dr.transport
|
||||
if transport != nil {
|
||||
_ = transport.Close()
|
||||
}
|
||||
delete(t.dialResultMap, key)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *PoolClient) newClient(udp bool, dialer C.Dialer) (client Client) {
|
||||
clients := t.tcpClients
|
||||
clientsMutex := t.tcpClientsMutex
|
||||
func (t *PoolClient) newClient(udp bool) (client Client) {
|
||||
clients := &t.tcpClients
|
||||
clientsMutex := &t.tcpClientsMutex
|
||||
if udp {
|
||||
clients = t.udpClients
|
||||
clientsMutex = t.udpClientsMutex
|
||||
clients = &t.udpClients
|
||||
clientsMutex = &t.udpClientsMutex
|
||||
}
|
||||
|
||||
clientsMutex.Lock()
|
||||
defer clientsMutex.Unlock()
|
||||
|
||||
dialHelper := t.dialHelper
|
||||
if t.newClientOptionV4 != nil {
|
||||
client = NewClientV4(t.newClientOptionV4, udp, dialer)
|
||||
client = NewClientV4(t.newClientOptionV4, udp, dialHelper.dial)
|
||||
} else {
|
||||
client = NewClientV5(t.newClientOptionV5, udp, dialer)
|
||||
client = NewClientV5(t.newClientOptionV5, udp, dialHelper.dial)
|
||||
}
|
||||
|
||||
client.SetLastVisited(time.Now())
|
||||
@@ -122,12 +116,12 @@ func (t *PoolClient) newClient(udp bool, dialer C.Dialer) (client Client) {
|
||||
return client
|
||||
}
|
||||
|
||||
func (t *PoolClient) getClient(udp bool, dialer C.Dialer) Client {
|
||||
clients := t.tcpClients
|
||||
clientsMutex := t.tcpClientsMutex
|
||||
func (t *PoolClient) getClient(udp bool) Client {
|
||||
clients := &t.tcpClients
|
||||
clientsMutex := &t.tcpClientsMutex
|
||||
if udp {
|
||||
clients = t.udpClients
|
||||
clientsMutex = t.udpClientsMutex
|
||||
clients = &t.udpClients
|
||||
clientsMutex = &t.udpClientsMutex
|
||||
}
|
||||
var bestClient Client
|
||||
|
||||
@@ -142,46 +136,39 @@ func (t *PoolClient) getClient(udp bool, dialer C.Dialer) Client {
|
||||
it = next
|
||||
continue
|
||||
}
|
||||
if client.DialerRef() == dialer {
|
||||
if bestClient == nil {
|
||||
if bestClient == nil {
|
||||
bestClient = client
|
||||
} else {
|
||||
if client.OpenStreams() < bestClient.OpenStreams() {
|
||||
bestClient = client
|
||||
} else {
|
||||
if client.OpenStreams() < bestClient.OpenStreams() {
|
||||
bestClient = client
|
||||
}
|
||||
}
|
||||
}
|
||||
it = it.Next()
|
||||
}
|
||||
}()
|
||||
for it := clients.Front(); it != nil; {
|
||||
client := it.Value
|
||||
if client != bestClient && client.OpenStreams() == 0 && time.Now().Sub(client.LastVisited()) > 30*time.Minute {
|
||||
client.Close()
|
||||
next := it.Next()
|
||||
clients.Remove(it)
|
||||
it = next
|
||||
continue
|
||||
for it := clients.Front(); it != nil; {
|
||||
client := it.Value
|
||||
if client != bestClient && client.OpenStreams() == 0 && time.Now().Sub(client.LastVisited()) > 30*time.Minute {
|
||||
client.Close()
|
||||
next := it.Next()
|
||||
clients.Remove(it)
|
||||
it = next
|
||||
continue
|
||||
}
|
||||
it = it.Next()
|
||||
}
|
||||
it = it.Next()
|
||||
}
|
||||
}()
|
||||
|
||||
if bestClient == nil {
|
||||
return t.newClient(udp, dialer)
|
||||
return t.newClient(udp)
|
||||
} else {
|
||||
bestClient.SetLastVisited(time.Now())
|
||||
return bestClient
|
||||
}
|
||||
}
|
||||
|
||||
func NewPoolClientV4(clientOption *ClientOptionV4) *PoolClient {
|
||||
func NewPoolClientV4(clientOption *ClientOptionV4, dialFn DialFunc) *PoolClient {
|
||||
p := &PoolClient{
|
||||
dialResultMap: make(map[C.Dialer]dialResult),
|
||||
dialResultMutex: &sync.Mutex{},
|
||||
tcpClients: list.New[Client](),
|
||||
tcpClientsMutex: &sync.Mutex{},
|
||||
udpClients: list.New[Client](),
|
||||
udpClientsMutex: &sync.Mutex{},
|
||||
dialHelper: &poolDialHelper{dialFn: dialFn},
|
||||
}
|
||||
newClientOption := *clientOption
|
||||
p.newClientOptionV4 = &newClientOption
|
||||
@@ -190,14 +177,9 @@ func NewPoolClientV4(clientOption *ClientOptionV4) *PoolClient {
|
||||
return p
|
||||
}
|
||||
|
||||
func NewPoolClientV5(clientOption *ClientOptionV5) *PoolClient {
|
||||
func NewPoolClientV5(clientOption *ClientOptionV5, dialFn DialFunc) *PoolClient {
|
||||
p := &PoolClient{
|
||||
dialResultMap: make(map[C.Dialer]dialResult),
|
||||
dialResultMutex: &sync.Mutex{},
|
||||
tcpClients: list.New[Client](),
|
||||
tcpClientsMutex: &sync.Mutex{},
|
||||
udpClients: list.New[Client](),
|
||||
udpClientsMutex: &sync.Mutex{},
|
||||
dialHelper: &poolDialHelper{dialFn: dialFn},
|
||||
}
|
||||
newClientOption := *clientOption
|
||||
p.newClientOptionV5 = &newClientOption
|
||||
@@ -208,5 +190,5 @@ func NewPoolClientV5(clientOption *ClientOptionV5) *PoolClient {
|
||||
|
||||
func closeClientPool(client *PoolClient) {
|
||||
log.Debugln("Close Tuic PoolClient at %p", client)
|
||||
client.forceClose()
|
||||
client.dialHelper.forceClose()
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package tuic
|
||||
|
||||
import (
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/transport/tuic/common"
|
||||
v4 "github.com/metacubex/mihomo/transport/tuic/v4"
|
||||
v5 "github.com/metacubex/mihomo/transport/tuic/v5"
|
||||
@@ -12,12 +11,12 @@ type ClientOptionV5 = v5.ClientOption
|
||||
|
||||
type Client = common.Client
|
||||
|
||||
func NewClientV4(clientOption *ClientOptionV4, udp bool, dialerRef C.Dialer) Client {
|
||||
return v4.NewClient(clientOption, udp, dialerRef)
|
||||
func NewClientV4(clientOption *ClientOptionV4, udp bool, dialFn DialFunc) Client {
|
||||
return v4.NewClient(clientOption, udp, dialFn)
|
||||
}
|
||||
|
||||
func NewClientV5(clientOption *ClientOptionV5, udp bool, dialerRef C.Dialer) Client {
|
||||
return v5.NewClient(clientOption, udp, dialerRef)
|
||||
func NewClientV5(clientOption *ClientOptionV5, udp bool, dialFn DialFunc) Client {
|
||||
return v5.NewClient(clientOption, udp, dialFn)
|
||||
}
|
||||
|
||||
type DialFunc = common.DialFunc
|
||||
|
||||
@@ -40,7 +40,8 @@ type ClientOption struct {
|
||||
|
||||
type clientImpl struct {
|
||||
*ClientOption
|
||||
udp bool
|
||||
dialFn common.DialFunc
|
||||
udp bool
|
||||
|
||||
quicConn *quic.Conn
|
||||
connMutex sync.Mutex
|
||||
@@ -51,7 +52,6 @@ type clientImpl struct {
|
||||
udpInputMap xsync.Map[uint32, net.Conn]
|
||||
|
||||
// only ready for PoolClient
|
||||
dialerRef C.Dialer
|
||||
lastVisited atomic2.TypedValue[time.Time]
|
||||
}
|
||||
|
||||
@@ -59,10 +59,6 @@ func (t *clientImpl) OpenStreams() int64 {
|
||||
return t.openStreams.Load()
|
||||
}
|
||||
|
||||
func (t *clientImpl) DialerRef() C.Dialer {
|
||||
return t.dialerRef
|
||||
}
|
||||
|
||||
func (t *clientImpl) LastVisited() time.Time {
|
||||
return t.lastVisited.Load()
|
||||
}
|
||||
@@ -71,13 +67,13 @@ func (t *clientImpl) SetLastVisited(last time.Time) {
|
||||
t.lastVisited.Store(last)
|
||||
}
|
||||
|
||||
func (t *clientImpl) getQuicConn(ctx context.Context, dialer C.Dialer, dialFn common.DialFunc) (*quic.Conn, error) {
|
||||
func (t *clientImpl) getQuicConn(ctx context.Context) (*quic.Conn, error) {
|
||||
t.connMutex.Lock()
|
||||
defer t.connMutex.Unlock()
|
||||
if t.quicConn != nil {
|
||||
return t.quicConn, nil
|
||||
}
|
||||
transport, addr, err := dialFn(ctx, dialer)
|
||||
transport, addr, err := t.dialFn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -262,7 +258,7 @@ func (t *clientImpl) forceClose(quicConn *quic.Conn, err error) {
|
||||
if quicConn != nil {
|
||||
_ = quicConn.CloseWithError(ProtocolError, errStr)
|
||||
}
|
||||
udpInputMap := t.udpInputMap
|
||||
udpInputMap := &t.udpInputMap
|
||||
udpInputMap.Range(func(key uint32, value net.Conn) bool {
|
||||
conn := value
|
||||
_ = conn.Close()
|
||||
@@ -278,8 +274,8 @@ func (t *clientImpl) Close() {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *clientImpl) DialContextWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn common.DialFunc) (net.Conn, error) {
|
||||
quicConn, err := t.getQuicConn(ctx, dialer, dialFn)
|
||||
func (t *clientImpl) DialContext(ctx context.Context, metadata *C.Metadata) (net.Conn, error) {
|
||||
quicConn, err := t.getQuicConn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -353,8 +349,8 @@ func (t *clientImpl) DialContextWithDialer(ctx context.Context, metadata *C.Meta
|
||||
return bufConn, nil
|
||||
}
|
||||
|
||||
func (t *clientImpl) ListenPacketWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn common.DialFunc) (net.PacketConn, error) {
|
||||
quicConn, err := t.getQuicConn(ctx, dialer, dialFn)
|
||||
func (t *clientImpl) ListenPacket(ctx context.Context, metadata *C.Metadata) (net.PacketConn, error) {
|
||||
quicConn, err := t.getQuicConn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -397,16 +393,16 @@ type Client struct {
|
||||
*clientImpl // use an independent pointer to let Finalizer can work no matter somewhere handle an influence in clientImpl inner
|
||||
}
|
||||
|
||||
func (t *Client) DialContextWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn common.DialFunc) (net.Conn, error) {
|
||||
conn, err := t.clientImpl.DialContextWithDialer(ctx, metadata, dialer, dialFn)
|
||||
func (t *Client) DialContext(ctx context.Context, metadata *C.Metadata) (net.Conn, error) {
|
||||
conn, err := t.clientImpl.DialContext(ctx, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return N.NewRefConn(conn, t), err
|
||||
}
|
||||
|
||||
func (t *Client) ListenPacketWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn common.DialFunc) (net.PacketConn, error) {
|
||||
pc, err := t.clientImpl.ListenPacketWithDialer(ctx, metadata, dialer, dialFn)
|
||||
func (t *Client) ListenPacket(ctx context.Context, metadata *C.Metadata) (net.PacketConn, error) {
|
||||
pc, err := t.clientImpl.ListenPacket(ctx, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -417,11 +413,11 @@ func (t *Client) forceClose() {
|
||||
t.clientImpl.forceClose(nil, common.ClientClosed)
|
||||
}
|
||||
|
||||
func NewClient(clientOption *ClientOption, udp bool, dialerRef C.Dialer) *Client {
|
||||
func NewClient(clientOption *ClientOption, udp bool, dialFn common.DialFunc) *Client {
|
||||
ci := &clientImpl{
|
||||
ClientOption: clientOption,
|
||||
dialFn: dialFn,
|
||||
udp: udp,
|
||||
dialerRef: dialerRef,
|
||||
}
|
||||
c := &Client{ci}
|
||||
runtime.SetFinalizer(c, closeClient)
|
||||
|
||||
@@ -39,7 +39,8 @@ type ClientOption struct {
|
||||
|
||||
type clientImpl struct {
|
||||
*ClientOption
|
||||
udp bool
|
||||
dialFn common.DialFunc
|
||||
udp bool
|
||||
|
||||
quicConn *quic.Conn
|
||||
connMutex sync.Mutex
|
||||
@@ -50,7 +51,6 @@ type clientImpl struct {
|
||||
udpInputMap xsync.Map[uint16, net.Conn]
|
||||
|
||||
// only ready for PoolClient
|
||||
dialerRef C.Dialer
|
||||
lastVisited atomic2.TypedValue[time.Time]
|
||||
}
|
||||
|
||||
@@ -58,10 +58,6 @@ func (t *clientImpl) OpenStreams() int64 {
|
||||
return t.openStreams.Load()
|
||||
}
|
||||
|
||||
func (t *clientImpl) DialerRef() C.Dialer {
|
||||
return t.dialerRef
|
||||
}
|
||||
|
||||
func (t *clientImpl) LastVisited() time.Time {
|
||||
return t.lastVisited.Load()
|
||||
}
|
||||
@@ -70,13 +66,13 @@ func (t *clientImpl) SetLastVisited(last time.Time) {
|
||||
t.lastVisited.Store(last)
|
||||
}
|
||||
|
||||
func (t *clientImpl) getQuicConn(ctx context.Context, dialer C.Dialer, dialFn common.DialFunc) (*quic.Conn, error) {
|
||||
func (t *clientImpl) getQuicConn(ctx context.Context) (*quic.Conn, error) {
|
||||
t.connMutex.Lock()
|
||||
defer t.connMutex.Unlock()
|
||||
if t.quicConn != nil {
|
||||
return t.quicConn, nil
|
||||
}
|
||||
transport, addr, err := dialFn(ctx, dialer)
|
||||
transport, addr, err := t.dialFn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -270,7 +266,7 @@ func (t *clientImpl) forceClose(quicConn *quic.Conn, err error) {
|
||||
if quicConn != nil {
|
||||
_ = quicConn.CloseWithError(ProtocolError, errStr)
|
||||
}
|
||||
udpInputMap := t.udpInputMap
|
||||
udpInputMap := &t.udpInputMap
|
||||
udpInputMap.Range(func(key uint16, value net.Conn) bool {
|
||||
conn := value
|
||||
_ = conn.Close()
|
||||
@@ -286,8 +282,8 @@ func (t *clientImpl) Close() {
|
||||
}
|
||||
}
|
||||
|
||||
func (t *clientImpl) DialContextWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn common.DialFunc) (net.Conn, error) {
|
||||
quicConn, err := t.getQuicConn(ctx, dialer, dialFn)
|
||||
func (t *clientImpl) DialContext(ctx context.Context, metadata *C.Metadata) (net.Conn, error) {
|
||||
quicConn, err := t.getQuicConn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -337,8 +333,8 @@ func (t *clientImpl) DialContextWithDialer(ctx context.Context, metadata *C.Meta
|
||||
return stream, nil
|
||||
}
|
||||
|
||||
func (t *clientImpl) ListenPacketWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn common.DialFunc) (net.PacketConn, error) {
|
||||
quicConn, err := t.getQuicConn(ctx, dialer, dialFn)
|
||||
func (t *clientImpl) ListenPacket(ctx context.Context, metadata *C.Metadata) (net.PacketConn, error) {
|
||||
quicConn, err := t.getQuicConn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -381,16 +377,16 @@ type Client struct {
|
||||
*clientImpl // use an independent pointer to let Finalizer can work no matter somewhere handle an influence in clientImpl inner
|
||||
}
|
||||
|
||||
func (t *Client) DialContextWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn common.DialFunc) (net.Conn, error) {
|
||||
conn, err := t.clientImpl.DialContextWithDialer(ctx, metadata, dialer, dialFn)
|
||||
func (t *Client) DialContext(ctx context.Context, metadata *C.Metadata) (net.Conn, error) {
|
||||
conn, err := t.clientImpl.DialContext(ctx, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return N.NewRefConn(conn, t), err
|
||||
}
|
||||
|
||||
func (t *Client) ListenPacketWithDialer(ctx context.Context, metadata *C.Metadata, dialer C.Dialer, dialFn common.DialFunc) (net.PacketConn, error) {
|
||||
pc, err := t.clientImpl.ListenPacketWithDialer(ctx, metadata, dialer, dialFn)
|
||||
func (t *Client) ListenPacket(ctx context.Context, metadata *C.Metadata) (net.PacketConn, error) {
|
||||
pc, err := t.clientImpl.ListenPacket(ctx, metadata)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -401,11 +397,11 @@ func (t *Client) forceClose() {
|
||||
t.clientImpl.forceClose(nil, common.ClientClosed)
|
||||
}
|
||||
|
||||
func NewClient(clientOption *ClientOption, udp bool, dialerRef C.Dialer) *Client {
|
||||
func NewClient(clientOption *ClientOption, udp bool, dialFn common.DialFunc) *Client {
|
||||
ci := &clientImpl{
|
||||
ClientOption: clientOption,
|
||||
dialFn: dialFn,
|
||||
udp: udp,
|
||||
dialerRef: dialerRef,
|
||||
}
|
||||
c := &Client{ci}
|
||||
runtime.SetFinalizer(c, closeClient)
|
||||
|
||||
Reference in New Issue
Block a user