diff --git a/.github/update.log b/.github/update.log index 26dfffb3a8..d6cd2dd4d1 100644 --- a/.github/update.log +++ b/.github/update.log @@ -776,3 +776,4 @@ Update On Mon Sep 23 20:34:03 CEST 2024 Update On Tue Sep 24 20:37:16 CEST 2024 Update On Wed Sep 25 20:37:03 CEST 2024 Update On Thu Sep 26 20:35:45 CEST 2024 +Update On Fri Sep 27 20:34:20 CEST 2024 diff --git a/brook/protocol/user.md b/brook/protocol/user.md index 059547c04e..ddc4af15c8 100644 --- a/brook/protocol/user.md +++ b/brook/protocol/user.md @@ -77,6 +77,6 @@ You can count the traffic of each user from serverLog brook link --server 1.2.3.4:9999 --password hello --token xxx ``` -## Basic reference implementation +## A sample implementation -https://github.com/TxThinkingInc/brook-user-system +https://github.com/TxThinkingInc/brook-store diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/adapter.go b/clash-meta-android/core/src/foss/golang/clash/adapter/adapter.go index 8136827a09..3efc8166f0 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/adapter.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/adapter.go @@ -39,6 +39,11 @@ type Proxy struct { extra *xsync.MapOf[string, *internalProxyState] } +// Adapter implements C.Proxy +func (p *Proxy) Adapter() C.ProxyAdapter { + return p.ProxyAdapter +} + // AliveForTestUrl implements C.Proxy func (p *Proxy) AliveForTestUrl(url string) bool { if state, ok := p.extra.Load(url); ok { diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/inbound/listen.go b/clash-meta-android/core/src/foss/golang/clash/adapter/inbound/listen.go index 1b86c811a7..318c9675db 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/inbound/listen.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/inbound/listen.go @@ -3,6 +3,9 @@ package inbound import ( "context" "net" + "sync" + + "github.com/metacubex/mihomo/component/keepalive" "github.com/metacubex/tfo-go" ) @@ -11,28 +14,47 @@ var ( lc = tfo.ListenConfig{ DisableTFO: true, } + mutex sync.RWMutex ) func SetTfo(open bool) { + mutex.Lock() + defer mutex.Unlock() lc.DisableTFO = !open } func Tfo() bool { + mutex.RLock() + defer mutex.RUnlock() return !lc.DisableTFO } func SetMPTCP(open bool) { + mutex.Lock() + defer mutex.Unlock() setMultiPathTCP(&lc.ListenConfig, open) } func MPTCP() bool { + mutex.RLock() + defer mutex.RUnlock() return getMultiPathTCP(&lc.ListenConfig) } func ListenContext(ctx context.Context, network, address string) (net.Listener, error) { + mutex.RLock() + defer mutex.RUnlock() return lc.Listen(ctx, network, address) } func Listen(network, address string) (net.Listener, error) { return ListenContext(context.Background(), network, address) } + +func init() { + keepalive.SetDisableKeepAliveCallback.Register(func(b bool) { + mutex.Lock() + defer mutex.Unlock() + keepalive.SetNetListenConfig(&lc.ListenConfig) + }) +} diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/inbound/listen_notwindows.go b/clash-meta-android/core/src/foss/golang/clash/adapter/inbound/listen_notwindows.go new file mode 100644 index 0000000000..8fdfb7b8e6 --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/inbound/listen_notwindows.go @@ -0,0 +1,14 @@ +//go:build !windows + +package inbound + +import ( + "net" + "os" +) + +const SupportNamedPipe = false + +func ListenNamedPipe(path string) (net.Listener, error) { + return nil, os.ErrInvalid +} diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/inbound/listen_windows.go b/clash-meta-android/core/src/foss/golang/clash/adapter/inbound/listen_windows.go new file mode 100644 index 0000000000..d19239da18 --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/inbound/listen_windows.go @@ -0,0 +1,32 @@ +package inbound + +import ( + "net" + "os" + + "github.com/metacubex/wireguard-go/ipc/namedpipe" + "golang.org/x/sys/windows" +) + +const SupportNamedPipe = true + +// windowsSDDL is the Security Descriptor set on the namedpipe. +// It provides read/write access to all users and the local system. +const windowsSDDL = "D:PAI(A;OICI;GWGR;;;BU)(A;OICI;GWGR;;;SY)" + +func ListenNamedPipe(path string) (net.Listener, error) { + sddl := os.Getenv("LISTEN_NAMEDPIPE_SDDL") + if sddl == "" { + sddl = windowsSDDL + } + securityDescriptor, err := windows.SecurityDescriptorFromString(sddl) + if err != nil { + return nil, err + } + namedpipeLC := namedpipe.ListenConfig{ + SecurityDescriptor: securityDescriptor, + InputBufferSize: 256 * 1024, + OutputBufferSize: 256 * 1024, + } + return namedpipeLC.Listen(path) +} diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/direct.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/direct.go index 7114045d63..15f081f2bf 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/direct.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/direct.go @@ -6,7 +6,6 @@ import ( "os" "strconv" - N "github.com/metacubex/mihomo/common/net" "github.com/metacubex/mihomo/component/dialer" "github.com/metacubex/mihomo/component/loopback" "github.com/metacubex/mihomo/component/resolver" @@ -38,7 +37,6 @@ func (d *Direct) DialContext(ctx context.Context, metadata *C.Metadata, opts ... if err != nil { return nil, err } - N.TCPKeepAlive(c) return d.loopBack.NewConn(NewConn(c, d)), nil } diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/http.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/http.go index b837e49a94..ebb1d67cc5 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/http.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/http.go @@ -7,13 +7,11 @@ import ( "encoding/base64" "errors" "fmt" - "io" "net" "net/http" "strconv" - 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" @@ -76,7 +74,6 @@ func (h *Http) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metad if err != nil { return nil, fmt.Errorf("%s connect error: %w", h.addr, err) } - N.TCPKeepAlive(c) defer func(c net.Conn) { safeConnClose(c, err) diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/shadowsocks.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/shadowsocks.go index 88fb84566b..021fbc0a26 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/shadowsocks.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/shadowsocks.go @@ -149,7 +149,6 @@ func (ss *ShadowSocks) DialContextWithDialer(ctx context.Context, dialer C.Diale if err != nil { return nil, fmt.Errorf("%s connect error: %w", ss.addr, err) } - N.TCPKeepAlive(c) defer func(c net.Conn) { safeConnClose(c, err) diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/shadowsocksr.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/shadowsocksr.go index 07d780477a..437695b4c8 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/shadowsocksr.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/shadowsocksr.go @@ -80,7 +80,6 @@ func (ssr *ShadowSocksR) DialContextWithDialer(ctx context.Context, dialer C.Dia if err != nil { return nil, fmt.Errorf("%s connect error: %w", ssr.addr, err) } - N.TCPKeepAlive(c) defer func(c net.Conn) { safeConnClose(c, err) diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/snell.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/snell.go index 76ed4be916..f6a4b4f9aa 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/snell.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/snell.go @@ -6,7 +6,6 @@ import ( "net" "strconv" - 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" @@ -94,7 +93,6 @@ func (s *Snell) DialContextWithDialer(ctx context.Context, dialer C.Dialer, meta if err != nil { return nil, fmt.Errorf("%s connect error: %w", s.addr, err) } - N.TCPKeepAlive(c) defer func(c net.Conn) { safeConnClose(c, err) @@ -122,7 +120,6 @@ func (s *Snell) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met if err != nil { return nil, err } - N.TCPKeepAlive(c) c = streamConn(c, streamOption{s.psk, s.version, s.addr, s.obfsOption}) err = snell.WriteUDPHeader(c, s.version) @@ -207,8 +204,7 @@ func NewSnell(option SnellOption) (*Snell, error) { if err != nil { return nil, err } - - N.TCPKeepAlive(c) + return streamConn(c, streamOption{psk, option.Version, addr, obfsOption}), nil }) } diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/socks5.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/socks5.go index c17ee6a7a5..1908167abc 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/socks5.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/socks5.go @@ -10,7 +10,6 @@ import ( "net/netip" "strconv" - 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" @@ -82,7 +81,6 @@ func (ss *Socks5) DialContextWithDialer(ctx context.Context, dialer C.Dialer, me if err != nil { return nil, fmt.Errorf("%s connect error: %w", ss.addr, err) } - N.TCPKeepAlive(c) defer func(c net.Conn) { safeConnClose(c, err) @@ -128,7 +126,6 @@ func (ss *Socks5) ListenPacketContext(ctx context.Context, metadata *C.Metadata, safeConnClose(c, err) }(c) - N.TCPKeepAlive(c) var user *socks5.User if ss.user != "" { user = &socks5.User{ diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/ssh.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/ssh.go index 8b2776a663..9e23b463dd 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/ssh.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/ssh.go @@ -77,7 +77,6 @@ func (s *sshClient) connect(ctx context.Context, cDialer C.Dialer, addr string) if err != nil { return nil, err } - N.TCPKeepAlive(c) defer func(c net.Conn) { safeConnClose(c, err) diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/trojan.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/trojan.go index 938a885835..b3a611af05 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/trojan.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/trojan.go @@ -9,7 +9,6 @@ import ( "net/http" "strconv" - 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" @@ -154,7 +153,6 @@ func (t *Trojan) DialContextWithDialer(ctx context.Context, dialer C.Dialer, met if err != nil { return nil, fmt.Errorf("%s connect error: %w", t.addr, err) } - N.TCPKeepAlive(c) defer func(c net.Conn) { safeConnClose(c, err) @@ -212,7 +210,6 @@ func (t *Trojan) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, me defer func(c net.Conn) { safeConnClose(c, err) }(c) - N.TCPKeepAlive(c) c, err = t.plainStream(ctx, c) if err != nil { return nil, fmt.Errorf("%s connect error: %w", t.addr, err) @@ -314,7 +311,6 @@ func NewTrojan(option TrojanOption) (*Trojan, error) { if err != nil { return nil, fmt.Errorf("%s connect error: %s", t.addr, err.Error()) } - N.TCPKeepAlive(c) return c, nil } diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/vless.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/vless.go index b18bf4dac6..7905887409 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/vless.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/vless.go @@ -262,7 +262,6 @@ func (v *Vless) DialContextWithDialer(ctx context.Context, dialer C.Dialer, meta if err != nil { return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error()) } - N.TCPKeepAlive(c) defer func(c net.Conn) { safeConnClose(c, err) }(c) @@ -327,7 +326,6 @@ func (v *Vless) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met if err != nil { return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error()) } - N.TCPKeepAlive(c) defer func(c net.Conn) { safeConnClose(c, err) }(c) @@ -574,7 +572,6 @@ func NewVless(option VlessOption) (*Vless, error) { if err != nil { return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error()) } - N.TCPKeepAlive(c) return c, nil } diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/vmess.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/vmess.go index 7d5a7224e1..8797374dd8 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/vmess.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/vmess.go @@ -312,7 +312,6 @@ func (v *Vmess) DialContextWithDialer(ctx context.Context, dialer C.Dialer, meta if err != nil { return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error()) } - N.TCPKeepAlive(c) defer func(c net.Conn) { safeConnClose(c, err) }(c) @@ -373,7 +372,6 @@ func (v *Vmess) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, met if err != nil { return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error()) } - N.TCPKeepAlive(c) defer func(c net.Conn) { safeConnClose(c, err) }(c) @@ -473,7 +471,6 @@ func NewVmess(option VmessOption) (*Vmess, error) { if err != nil { return nil, fmt.Errorf("%s connect error: %s", v.addr, err.Error()) } - N.TCPKeepAlive(c) return c, nil } diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/wireguard.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/wireguard.go index 430463845c..3928ab1b7e 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/wireguard.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outbound/wireguard.go @@ -272,6 +272,7 @@ func NewWireGuard(option WireGuardOption) (*WireGuard, error) { }, } if option.AmneziaWGOption != nil { + outbound.bind.SetParseReserved(false) // AmneziaWG don't need parse reserved outbound.device = amnezia.NewDevice(outbound.tunDevice, outbound.bind, logger, option.Workers) } else { outbound.device = device.NewDevice(outbound.tunDevice, outbound.bind, logger, option.Workers) @@ -295,7 +296,7 @@ func NewWireGuard(option WireGuardOption) (*WireGuard, error) { for i := range nss { nss[i].ProxyAdapter = refP } - outbound.resolver = dns.NewResolver(dns.Config{ + outbound.resolver, _ = dns.NewResolver(dns.Config{ Main: nss, IPv6: has6, }) diff --git a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/util.go b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/util.go index 84216377b1..66b2510c19 100644 --- a/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/util.go +++ b/clash-meta-android/core/src/foss/golang/clash/adapter/outboundgroup/util.go @@ -4,3 +4,7 @@ type SelectAble interface { Set(string) error ForceSet(name string) } + +var _ SelectAble = (*Fallback)(nil) +var _ SelectAble = (*URLTest)(nil) +var _ SelectAble = (*Selector)(nil) diff --git a/clash-meta-android/core/src/foss/golang/clash/common/net/tcp_keepalive.go b/clash-meta-android/core/src/foss/golang/clash/common/net/tcp_keepalive.go deleted file mode 100644 index 047a1c05eb..0000000000 --- a/clash-meta-android/core/src/foss/golang/clash/common/net/tcp_keepalive.go +++ /dev/null @@ -1,23 +0,0 @@ -package net - -import ( - "net" - "runtime" - "time" -) - -var ( - KeepAliveIdle = 0 * time.Second - KeepAliveInterval = 0 * time.Second - DisableKeepAlive = false -) - -func TCPKeepAlive(c net.Conn) { - if tcp, ok := c.(*net.TCPConn); ok { - if runtime.GOOS == "android" || DisableKeepAlive { - _ = tcp.SetKeepAlive(false) - } else { - tcpKeepAlive(tcp) - } - } -} diff --git a/clash-meta-android/core/src/foss/golang/clash/common/net/tcp_keepalive_go122.go b/clash-meta-android/core/src/foss/golang/clash/common/net/tcp_keepalive_go122.go deleted file mode 100644 index 1287316868..0000000000 --- a/clash-meta-android/core/src/foss/golang/clash/common/net/tcp_keepalive_go122.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build !go1.23 - -package net - -import "net" - -func tcpKeepAlive(tcp *net.TCPConn) { - _ = tcp.SetKeepAlive(true) - _ = tcp.SetKeepAlivePeriod(KeepAliveInterval) -} diff --git a/clash-meta-android/core/src/foss/golang/clash/common/net/tcp_keepalive_go123.go b/clash-meta-android/core/src/foss/golang/clash/common/net/tcp_keepalive_go123.go deleted file mode 100644 index 2dd4754bbe..0000000000 --- a/clash-meta-android/core/src/foss/golang/clash/common/net/tcp_keepalive_go123.go +++ /dev/null @@ -1,19 +0,0 @@ -//go:build go1.23 - -package net - -import "net" - -func tcpKeepAlive(tcp *net.TCPConn) { - config := net.KeepAliveConfig{ - Enable: true, - Idle: KeepAliveIdle, - Interval: KeepAliveInterval, - } - if !SupportTCPKeepAliveCount() { - // it's recommended to set both Idle and Interval to non-negative values in conjunction with a -1 - // for Count on those old Windows if you intend to customize the TCP keep-alive settings. - config.Count = -1 - } - _ = tcp.SetKeepAliveConfig(config) -} diff --git a/clash-meta-android/core/src/foss/golang/clash/common/utils/hash.go b/clash-meta-android/core/src/foss/golang/clash/common/utils/hash.go index 38ba15b498..6957e2c3ec 100644 --- a/clash-meta-android/core/src/foss/golang/clash/common/utils/hash.go +++ b/clash-meta-android/core/src/foss/golang/clash/common/utils/hash.go @@ -3,6 +3,7 @@ package utils import ( "crypto/md5" "encoding/hex" + "errors" ) // HashType warps hash array inside struct @@ -15,14 +16,6 @@ func MakeHash(data []byte) HashType { return HashType{md5.Sum(data)} } -func MakeHashFromBytes(hashBytes []byte) (h HashType) { - if len(hashBytes) != md5.Size { - return - } - copy(h.md5[:], hashBytes) - return -} - func (h HashType) Equal(hash HashType) bool { return h.md5 == hash.md5 } @@ -35,6 +28,30 @@ func (h HashType) String() string { return hex.EncodeToString(h.Bytes()) } +func (h HashType) MarshalText() ([]byte, error) { + return []byte(h.String()), nil +} + +func (h *HashType) UnmarshalText(data []byte) error { + if hex.DecodedLen(len(data)) != md5.Size { + return errors.New("invalid hash length") + } + _, err := hex.Decode(h.md5[:], data) + return err +} + +func (h HashType) MarshalBinary() ([]byte, error) { + return h.md5[:], nil +} + +func (h *HashType) UnmarshalBinary(data []byte) error { + if len(data) != md5.Size { + return errors.New("invalid hash length") + } + copy(h.md5[:], data) + return nil +} + func (h HashType) Len() int { return len(h.md5) } diff --git a/clash-meta-android/core/src/foss/golang/clash/component/auth/auth.go b/clash-meta-android/core/src/foss/golang/clash/component/auth/auth.go index b52fa13557..176b21d793 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/auth/auth.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/auth/auth.go @@ -5,6 +5,11 @@ type Authenticator interface { Users() []string } +type AuthStore interface { + Authenticator() Authenticator + SetAuthenticator(Authenticator) +} + type AuthUser struct { User string Pass string diff --git a/clash-meta-android/core/src/foss/golang/clash/component/dialer/dialer.go b/clash-meta-android/core/src/foss/golang/clash/component/dialer/dialer.go index 41f79b8e52..3dfd3159bb 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/dialer/dialer.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/dialer/dialer.go @@ -12,6 +12,7 @@ import ( "sync" "time" + "github.com/metacubex/mihomo/component/keepalive" "github.com/metacubex/mihomo/component/resolver" "github.com/metacubex/mihomo/log" ) @@ -144,6 +145,7 @@ func dialContext(ctx context.Context, network string, destination netip.Addr, po } dialer := netDialer.(*net.Dialer) + keepalive.SetNetDialer(dialer) if opt.mpTcp { setMultiPathTCP(dialer) } diff --git a/clash-meta-android/core/src/foss/golang/clash/component/keepalive/tcp_keepalive.go b/clash-meta-android/core/src/foss/golang/clash/component/keepalive/tcp_keepalive.go new file mode 100644 index 0000000000..9b24c45ada --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/component/keepalive/tcp_keepalive.go @@ -0,0 +1,65 @@ +package keepalive + +import ( + "net" + "runtime" + "time" + + "github.com/metacubex/mihomo/common/atomic" + "github.com/metacubex/mihomo/common/utils" +) + +var ( + keepAliveIdle = atomic.NewTypedValue[time.Duration](0 * time.Second) + keepAliveInterval = atomic.NewTypedValue[time.Duration](0 * time.Second) + disableKeepAlive = atomic.NewBool(false) + + SetDisableKeepAliveCallback = utils.NewCallback[bool]() +) + +func SetKeepAliveIdle(t time.Duration) { + keepAliveIdle.Store(t) +} + +func SetKeepAliveInterval(t time.Duration) { + keepAliveInterval.Store(t) +} + +func KeepAliveIdle() time.Duration { + return keepAliveIdle.Load() +} + +func KeepAliveInterval() time.Duration { + return keepAliveInterval.Load() +} + +func SetDisableKeepAlive(disable bool) { + if runtime.GOOS == "android" { + setDisableKeepAlive(false) + } else { + setDisableKeepAlive(disable) + } +} + +func setDisableKeepAlive(disable bool) { + disableKeepAlive.Store(disable) + SetDisableKeepAliveCallback.Emit(disable) +} + +func DisableKeepAlive() bool { + return disableKeepAlive.Load() +} + +func SetNetDialer(dialer *net.Dialer) { + setNetDialer(dialer) +} + +func SetNetListenConfig(lc *net.ListenConfig) { + setNetListenConfig(lc) +} + +func TCPKeepAlive(c net.Conn) { + if tcp, ok := c.(*net.TCPConn); ok && tcp != nil { + tcpKeepAlive(tcp) + } +} diff --git a/clash-meta-android/core/src/foss/golang/clash/component/keepalive/tcp_keepalive_go122.go b/clash-meta-android/core/src/foss/golang/clash/component/keepalive/tcp_keepalive_go122.go new file mode 100644 index 0000000000..5d88827d71 --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/component/keepalive/tcp_keepalive_go122.go @@ -0,0 +1,30 @@ +//go:build !go1.23 + +package keepalive + +import "net" + +func tcpKeepAlive(tcp *net.TCPConn) { + if DisableKeepAlive() { + _ = tcp.SetKeepAlive(false) + } else { + _ = tcp.SetKeepAlive(true) + _ = tcp.SetKeepAlivePeriod(KeepAliveInterval()) + } +} + +func setNetDialer(dialer *net.Dialer) { + if DisableKeepAlive() { + dialer.KeepAlive = -1 // If negative, keep-alive probes are disabled. + } else { + dialer.KeepAlive = KeepAliveInterval() + } +} + +func setNetListenConfig(lc *net.ListenConfig) { + if DisableKeepAlive() { + lc.KeepAlive = -1 // If negative, keep-alive probes are disabled. + } else { + lc.KeepAlive = KeepAliveInterval() + } +} diff --git a/clash-meta-android/core/src/foss/golang/clash/component/keepalive/tcp_keepalive_go123.go b/clash-meta-android/core/src/foss/golang/clash/component/keepalive/tcp_keepalive_go123.go new file mode 100644 index 0000000000..4c08118b3b --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/component/keepalive/tcp_keepalive_go123.go @@ -0,0 +1,45 @@ +//go:build go1.23 + +package keepalive + +import "net" + +func keepAliveConfig() net.KeepAliveConfig { + config := net.KeepAliveConfig{ + Enable: true, + Idle: KeepAliveIdle(), + Interval: KeepAliveInterval(), + } + if !SupportTCPKeepAliveCount() { + // it's recommended to set both Idle and Interval to non-negative values in conjunction with a -1 + // for Count on those old Windows if you intend to customize the TCP keep-alive settings. + config.Count = -1 + } + return config +} + +func tcpKeepAlive(tcp *net.TCPConn) { + if DisableKeepAlive() { + _ = tcp.SetKeepAlive(false) + } else { + _ = tcp.SetKeepAliveConfig(keepAliveConfig()) + } +} + +func setNetDialer(dialer *net.Dialer) { + if DisableKeepAlive() { + dialer.KeepAlive = -1 // If negative, keep-alive probes are disabled. + dialer.KeepAliveConfig.Enable = false + } else { + dialer.KeepAliveConfig = keepAliveConfig() + } +} + +func setNetListenConfig(lc *net.ListenConfig) { + if DisableKeepAlive() { + lc.KeepAlive = -1 // If negative, keep-alive probes are disabled. + lc.KeepAliveConfig.Enable = false + } else { + lc.KeepAliveConfig = keepAliveConfig() + } +} diff --git a/clash-meta-android/core/src/foss/golang/clash/common/net/tcp_keepalive_go123_unix.go b/clash-meta-android/core/src/foss/golang/clash/component/keepalive/tcp_keepalive_go123_unix.go similarity index 91% rename from clash-meta-android/core/src/foss/golang/clash/common/net/tcp_keepalive_go123_unix.go rename to clash-meta-android/core/src/foss/golang/clash/component/keepalive/tcp_keepalive_go123_unix.go index 0ead7ca472..8033cc6c94 100644 --- a/clash-meta-android/core/src/foss/golang/clash/common/net/tcp_keepalive_go123_unix.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/keepalive/tcp_keepalive_go123_unix.go @@ -1,6 +1,6 @@ //go:build go1.23 && unix -package net +package keepalive func SupportTCPKeepAliveIdle() bool { return true diff --git a/clash-meta-android/core/src/foss/golang/clash/common/net/tcp_keepalive_go123_windows.go b/clash-meta-android/core/src/foss/golang/clash/component/keepalive/tcp_keepalive_go123_windows.go similarity index 99% rename from clash-meta-android/core/src/foss/golang/clash/common/net/tcp_keepalive_go123_windows.go rename to clash-meta-android/core/src/foss/golang/clash/component/keepalive/tcp_keepalive_go123_windows.go index 8f1e61f959..2462e80c36 100644 --- a/clash-meta-android/core/src/foss/golang/clash/common/net/tcp_keepalive_go123_windows.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/keepalive/tcp_keepalive_go123_windows.go @@ -2,7 +2,7 @@ // copy and modify from golang1.23's internal/syscall/windows/version_windows.go -package net +package keepalive import ( "errors" diff --git a/clash-meta-android/core/src/foss/golang/clash/component/nat/table.go b/clash-meta-android/core/src/foss/golang/clash/component/nat/table.go index bb5ab75579..66241fb472 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/nat/table.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/nat/table.go @@ -10,47 +10,30 @@ import ( ) type Table struct { - mapping *xsync.MapOf[string, *Entry] - lockMap *xsync.MapOf[string, *sync.Cond] + mapping *xsync.MapOf[string, *entry] } -type Entry struct { - PacketConn C.PacketConn - WriteBackProxy C.WriteBackProxy +type entry struct { + PacketSender C.PacketSender LocalUDPConnMap *xsync.MapOf[string, *net.UDPConn] LocalLockMap *xsync.MapOf[string, *sync.Cond] } -func (t *Table) Set(key string, e C.PacketConn, w C.WriteBackProxy) { - t.mapping.Store(key, &Entry{ - PacketConn: e, - WriteBackProxy: w, - LocalUDPConnMap: xsync.NewMapOf[string, *net.UDPConn](), - LocalLockMap: xsync.NewMapOf[string, *sync.Cond](), +func (t *Table) GetOrCreate(key string, maker func() C.PacketSender) (C.PacketSender, bool) { + item, loaded := t.mapping.LoadOrCompute(key, func() *entry { + return &entry{ + PacketSender: maker(), + LocalUDPConnMap: xsync.NewMapOf[string, *net.UDPConn](), + LocalLockMap: xsync.NewMapOf[string, *sync.Cond](), + } }) -} - -func (t *Table) Get(key string) (C.PacketConn, C.WriteBackProxy) { - entry, exist := t.getEntry(key) - if !exist { - return nil, nil - } - return entry.PacketConn, entry.WriteBackProxy -} - -func (t *Table) GetOrCreateLock(key string) (*sync.Cond, bool) { - item, loaded := t.lockMap.LoadOrCompute(key, makeLock) - return item, loaded + return item.PacketSender, loaded } func (t *Table) Delete(key string) { t.mapping.Delete(key) } -func (t *Table) DeleteLock(lockKey string) { - t.lockMap.Delete(lockKey) -} - func (t *Table) GetForLocalConn(lAddr, rAddr string) *net.UDPConn { entry, exist := t.getEntry(lAddr) if !exist { @@ -105,7 +88,7 @@ func (t *Table) DeleteLockForLocalConn(lAddr, key string) { entry.LocalLockMap.Delete(key) } -func (t *Table) getEntry(key string) (*Entry, bool) { +func (t *Table) getEntry(key string) (*entry, bool) { return t.mapping.Load(key) } @@ -116,7 +99,6 @@ func makeLock() *sync.Cond { // New return *Cache func New() *Table { return &Table{ - mapping: xsync.NewMapOf[string, *Entry](), - lockMap: xsync.NewMapOf[string, *sync.Cond](), + mapping: xsync.NewMapOf[string, *entry](), } } diff --git a/clash-meta-android/core/src/foss/golang/clash/component/profile/cachefile/cache.go b/clash-meta-android/core/src/foss/golang/clash/component/profile/cachefile/cache.go index 6a9180417c..f5101f5bb7 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/profile/cachefile/cache.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/profile/cachefile/cache.go @@ -1,12 +1,10 @@ package cachefile import ( - "math" "os" "sync" "time" - "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/component/profile" C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/log" @@ -72,58 +70,6 @@ func (c *CacheFile) SelectedMap() map[string]string { return mapping } -func (c *CacheFile) SetETagWithHash(url string, hash utils.HashType, etag string) { - if c.DB == nil { - return - } - - lenHash := hash.Len() - if lenHash > math.MaxUint8 { - return // maybe panic is better - } - - data := make([]byte, 1, 1+lenHash+len(etag)) - data[0] = uint8(lenHash) - data = append(data, hash.Bytes()...) - data = append(data, etag...) - - err := c.DB.Batch(func(t *bbolt.Tx) error { - bucket, err := t.CreateBucketIfNotExists(bucketETag) - if err != nil { - return err - } - - return bucket.Put([]byte(url), data) - }) - if err != nil { - log.Warnln("[CacheFile] write cache to %s failed: %s", c.DB.Path(), err.Error()) - return - } -} -func (c *CacheFile) GetETagWithHash(key string) (hash utils.HashType, etag string) { - if c.DB == nil { - return - } - c.DB.View(func(t *bbolt.Tx) error { - if bucket := t.Bucket(bucketETag); bucket != nil { - if v := bucket.Get([]byte(key)); v != nil { - if len(v) == 0 { - return nil - } - lenHash := int(v[0]) - if len(v) < 1+lenHash { - return nil - } - hash = utils.MakeHashFromBytes(v[1 : 1+lenHash]) - etag = string(v[1+lenHash:]) - } - } - return nil - }) - - return -} - func (c *CacheFile) Close() error { return c.DB.Close() } diff --git a/clash-meta-android/core/src/foss/golang/clash/component/profile/cachefile/etag.go b/clash-meta-android/core/src/foss/golang/clash/component/profile/cachefile/etag.go new file mode 100644 index 0000000000..028fe50433 --- /dev/null +++ b/clash-meta-android/core/src/foss/golang/clash/component/profile/cachefile/etag.go @@ -0,0 +1,58 @@ +package cachefile + +import ( + "time" + + "github.com/metacubex/mihomo/common/utils" + "github.com/metacubex/mihomo/log" + + "github.com/metacubex/bbolt" + "github.com/vmihailenco/msgpack/v5" +) + +type EtagWithHash struct { + Hash utils.HashType + ETag string + Time time.Time +} + +func (c *CacheFile) SetETagWithHash(url string, etagWithHash EtagWithHash) { + if c.DB == nil { + return + } + + data, err := msgpack.Marshal(etagWithHash) + if err != nil { + return // maybe panic is better + } + + err = c.DB.Batch(func(t *bbolt.Tx) error { + bucket, err := t.CreateBucketIfNotExists(bucketETag) + if err != nil { + return err + } + + return bucket.Put([]byte(url), data) + }) + if err != nil { + log.Warnln("[CacheFile] write cache to %s failed: %s", c.DB.Path(), err.Error()) + return + } +} +func (c *CacheFile) GetETagWithHash(key string) (etagWithHash EtagWithHash) { + if c.DB == nil { + return + } + c.DB.View(func(t *bbolt.Tx) error { + if bucket := t.Bucket(bucketETag); bucket != nil { + if v := bucket.Get([]byte(key)); v != nil { + if err := msgpack.Unmarshal(v, &etagWithHash); err != nil { + return err + } + } + } + return nil + }) + + return +} diff --git a/clash-meta-android/core/src/foss/golang/clash/component/resolver/resolver.go b/clash-meta-android/core/src/foss/golang/clash/component/resolver/resolver.go index feb3f98fb5..bcdbb7e2c4 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/resolver/resolver.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/resolver/resolver.go @@ -47,6 +47,7 @@ type Resolver interface { ExchangeContext(ctx context.Context, m *dns.Msg) (msg *dns.Msg, err error) Invalid() bool ClearCache() + ResetConnection() } // LookupIPv4WithResolver same as LookupIPv4, but with a resolver @@ -256,6 +257,15 @@ func LookupIPProxyServerHost(ctx context.Context, host string) ([]netip.Addr, er return LookupIP(ctx, host) } +func ResetConnection() { + if DefaultResolver != nil { + go DefaultResolver.ResetConnection() + } + if ProxyServerHostResolver != nil { + go ProxyServerHostResolver.ResetConnection() + } +} + func SortationAddr(ips []netip.Addr) (ipv4s, ipv6s []netip.Addr) { for _, v := range ips { if v.Unmap().Is4() { diff --git a/clash-meta-android/core/src/foss/golang/clash/component/resource/vehicle.go b/clash-meta-android/core/src/foss/golang/clash/component/resource/vehicle.go index b24adfa95a..a9382329fc 100644 --- a/clash-meta-android/core/src/foss/golang/clash/component/resource/vehicle.go +++ b/clash-meta-android/core/src/foss/golang/clash/component/resource/vehicle.go @@ -117,14 +117,14 @@ func (h *HTTPVehicle) Read(ctx context.Context, oldHash utils.HashType) (buf []b header := h.header setIfNoneMatch := false if etag && oldHash.IsValid() { - hashBytes, etag := cachefile.Cache().GetETagWithHash(h.url) - if oldHash.Equal(hashBytes) && etag != "" { + etagWithHash := cachefile.Cache().GetETagWithHash(h.url) + if oldHash.Equal(etagWithHash.Hash) && etagWithHash.ETag != "" { if header == nil { header = http.Header{} } else { header = header.Clone() } - header.Set("If-None-Match", etag) + header.Set("If-None-Match", etagWithHash.ETag) setIfNoneMatch = true } } @@ -146,7 +146,11 @@ func (h *HTTPVehicle) Read(ctx context.Context, oldHash utils.HashType) (buf []b } hash = utils.MakeHash(buf) if etag { - cachefile.Cache().SetETagWithHash(h.url, hash, resp.Header.Get("ETag")) + cachefile.Cache().SetETagWithHash(h.url, cachefile.EtagWithHash{ + Hash: hash, + ETag: resp.Header.Get("ETag"), + Time: time.Now(), + }) } return } diff --git a/clash-meta-android/core/src/foss/golang/clash/config/config.go b/clash-meta-android/core/src/foss/golang/clash/config/config.go index 2a75ddd64e..9067d14ff9 100644 --- a/clash-meta-android/core/src/foss/golang/clash/config/config.go +++ b/clash-meta-android/core/src/foss/golang/clash/config/config.go @@ -15,13 +15,13 @@ import ( "github.com/metacubex/mihomo/adapter/outbound" "github.com/metacubex/mihomo/adapter/outboundgroup" "github.com/metacubex/mihomo/adapter/provider" - N "github.com/metacubex/mihomo/common/net" "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/component/auth" "github.com/metacubex/mihomo/component/cidr" "github.com/metacubex/mihomo/component/fakeip" "github.com/metacubex/mihomo/component/geodata" mihomoHttp "github.com/metacubex/mihomo/component/http" + "github.com/metacubex/mihomo/component/keepalive" P "github.com/metacubex/mihomo/component/process" "github.com/metacubex/mihomo/component/resolver" "github.com/metacubex/mihomo/component/resource" @@ -103,6 +103,7 @@ type Controller struct { ExternalController string ExternalControllerTLS string ExternalControllerUnix string + ExternalControllerPipe string ExternalUI string ExternalDohServer string Secret string @@ -364,6 +365,7 @@ type RawConfig struct { LogLevel log.LogLevel `yaml:"log-level" json:"log-level"` IPv6 bool `yaml:"ipv6" json:"ipv6"` ExternalController string `yaml:"external-controller" json:"external-controller"` + ExternalControllerPipe string `yaml:"external-controller-pipe" json:"external-controller-pipe"` ExternalControllerUnix string `yaml:"external-controller-unix" json:"external-controller-unix"` ExternalControllerTLS string `yaml:"external-controller-tls" json:"external-controller-tls"` ExternalUI string `yaml:"external-ui" json:"external-ui"` @@ -697,12 +699,12 @@ func parseGeneral(cfg *RawConfig) (*General, error) { resource.SetETag(cfg.ETagSupport) if cfg.KeepAliveIdle != 0 { - N.KeepAliveIdle = time.Duration(cfg.KeepAliveIdle) * time.Second + keepalive.SetKeepAliveIdle(time.Duration(cfg.KeepAliveIdle) * time.Second) } if cfg.KeepAliveInterval != 0 { - N.KeepAliveInterval = time.Duration(cfg.KeepAliveInterval) * time.Second + keepalive.SetKeepAliveInterval(time.Duration(cfg.KeepAliveInterval) * time.Second) } - N.DisableKeepAlive = cfg.DisableKeepAlive + keepalive.SetDisableKeepAlive(cfg.DisableKeepAlive) // checkout externalUI exist if cfg.ExternalUI != "" { @@ -769,6 +771,7 @@ func parseController(cfg *RawConfig) (*Controller, error) { ExternalController: cfg.ExternalController, ExternalUI: cfg.ExternalUI, Secret: cfg.Secret, + ExternalControllerPipe: cfg.ExternalControllerPipe, ExternalControllerUnix: cfg.ExternalControllerUnix, ExternalControllerTLS: cfg.ExternalControllerTLS, ExternalDohServer: cfg.ExternalDohServer, diff --git a/clash-meta-android/core/src/foss/golang/clash/constant/adapters.go b/clash-meta-android/core/src/foss/golang/clash/constant/adapters.go index cb213b3c34..b303eb846b 100644 --- a/clash-meta-android/core/src/foss/golang/clash/constant/adapters.go +++ b/clash-meta-android/core/src/foss/golang/clash/constant/adapters.go @@ -158,6 +158,7 @@ type DelayHistoryStoreType int type Proxy interface { ProxyAdapter + Adapter() ProxyAdapter AliveForTestUrl(url string) bool DelayHistory() []DelayHistory ExtraDelayHistories() map[string]ProxyState @@ -255,12 +256,16 @@ type UDPPacketInAddr interface { // PacketAdapter is a UDP Packet adapter for socks/redir/tun type PacketAdapter interface { UDPPacket + // Metadata returns destination metadata Metadata() *Metadata + // Key is a SNAT key + Key() string } type packetAdapter struct { UDPPacket metadata *Metadata + key string } // Metadata returns destination metadata @@ -268,10 +273,16 @@ func (s *packetAdapter) Metadata() *Metadata { return s.metadata } +// Key is a SNAT key +func (s *packetAdapter) Key() string { + return s.key +} + func NewPacketAdapter(packet UDPPacket, metadata *Metadata) PacketAdapter { return &packetAdapter{ packet, metadata, + packet.LocalAddr().String(), } } @@ -284,17 +295,23 @@ type WriteBackProxy interface { UpdateWriteBack(wb WriteBack) } +type PacketSender interface { + // Send will send PacketAdapter nonblocking + // the implement must call UDPPacket.Drop() inside Send + Send(PacketAdapter) + // Process is a blocking loop to send PacketAdapter to PacketConn and update the WriteBackProxy + Process(PacketConn, WriteBackProxy) + // ResolveUDP do a local resolve UDP dns blocking if metadata is not resolved + ResolveUDP(*Metadata) error + // Close stop the Process loop + Close() +} + type NatTable interface { - Set(key string, e PacketConn, w WriteBackProxy) - - Get(key string) (PacketConn, WriteBackProxy) - - GetOrCreateLock(key string) (*sync.Cond, bool) + GetOrCreate(key string, maker func() PacketSender) (PacketSender, bool) Delete(key string) - DeleteLock(key string) - GetForLocalConn(lAddr, rAddr string) *net.UDPConn AddForLocalConn(lAddr, rAddr string, conn *net.UDPConn) bool diff --git a/clash-meta-android/core/src/foss/golang/clash/dns/client.go b/clash-meta-android/core/src/foss/golang/clash/dns/client.go index 096b96a7f5..62fc12f9c3 100644 --- a/clash-meta-android/core/src/foss/golang/clash/dns/client.go +++ b/clash-meta-android/core/src/foss/golang/clash/dns/client.go @@ -103,3 +103,5 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error) return ret.msg, ret.err } } + +func (c *client) ResetConnection() {} diff --git a/clash-meta-android/core/src/foss/golang/clash/dns/dhcp.go b/clash-meta-android/core/src/foss/golang/clash/dns/dhcp.go index dc1344f500..e3829b7c2c 100644 --- a/clash-meta-android/core/src/foss/golang/clash/dns/dhcp.go +++ b/clash-meta-android/core/src/foss/golang/clash/dns/dhcp.go @@ -53,6 +53,12 @@ func (d *dhcpClient) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, return } +func (d *dhcpClient) ResetConnection() { + for _, client := range d.clients { + client.ResetConnection() + } +} + func (d *dhcpClient) resolve(ctx context.Context) ([]dnsClient, error) { d.lock.Lock() diff --git a/clash-meta-android/core/src/foss/golang/clash/dns/doh.go b/clash-meta-android/core/src/foss/golang/clash/dns/doh.go index ffb65fcef0..027afd58cc 100644 --- a/clash-meta-android/core/src/foss/golang/clash/dns/doh.go +++ b/clash-meta-android/core/src/foss/golang/clash/dns/doh.go @@ -203,11 +203,23 @@ func (doh *dnsOverHTTPS) Close() (err error) { return doh.closeClient(doh.client) } -// closeClient cleans up resources used by client if necessary. Note, that at -// this point it should only be done for HTTP/3 as it may leak due to keep-alive -// connections. +func (doh *dnsOverHTTPS) ResetConnection() { + doh.clientMu.Lock() + defer doh.clientMu.Unlock() + + if doh.client == nil { + return + } + + _ = doh.closeClient(doh.client) + doh.client = nil +} + +// closeClient cleans up resources used by client if necessary. func (doh *dnsOverHTTPS) closeClient(client *http.Client) (err error) { - if isHTTP3(client) { + client.CloseIdleConnections() + + if isHTTP3(client) { // HTTP/3 may leak due to keep-alive connections. return client.Transport.(io.Closer).Close() } @@ -508,6 +520,13 @@ func (h *http3Transport) Close() (err error) { return h.baseTransport.Close() } +func (h *http3Transport) CloseIdleConnections() { + h.mu.RLock() + defer h.mu.RUnlock() + + h.baseTransport.CloseIdleConnections() +} + // createTransportH3 tries to create an HTTP/3 transport for this upstream. // We should be able to fall back to H1/H2 in case if HTTP/3 is unavailable or // if it is too slow. In order to do that, this method will run two probes diff --git a/clash-meta-android/core/src/foss/golang/clash/dns/doq.go b/clash-meta-android/core/src/foss/golang/clash/dns/doq.go index ad936f9575..29fdd00660 100644 --- a/clash-meta-android/core/src/foss/golang/clash/dns/doq.go +++ b/clash-meta-android/core/src/foss/golang/clash/dns/doq.go @@ -144,6 +144,10 @@ func (doq *dnsOverQUIC) Close() (err error) { return err } +func (doq *dnsOverQUIC) ResetConnection() { + doq.closeConnWithError(nil) +} + // exchangeQUIC attempts to open a QUIC connection, send the DNS message // through it and return the response it got from the server. func (doq *dnsOverQUIC) exchangeQUIC(ctx context.Context, msg *D.Msg) (resp *D.Msg, err error) { diff --git a/clash-meta-android/core/src/foss/golang/clash/dns/patch_android.go b/clash-meta-android/core/src/foss/golang/clash/dns/patch_android.go index 6579ef071a..e3dcd2492f 100644 --- a/clash-meta-android/core/src/foss/golang/clash/dns/patch_android.go +++ b/clash-meta-android/core/src/foss/golang/clash/dns/patch_android.go @@ -12,6 +12,7 @@ func FlushCacheWithDefaultResolver() { if r := resolver.DefaultResolver; r != nil { r.ClearCache() } + resolver.ResetConnection() } func UpdateSystemDNS(addr []string) { @@ -30,3 +31,9 @@ func UpdateSystemDNS(addr []string) { func (c *systemClient) getDnsClients() ([]dnsClient, error) { return systemResolver, nil } + +func (c *systemClient) ResetConnection() { + for _, r := range systemResolver { + r.ResetConnection() + } +} diff --git a/clash-meta-android/core/src/foss/golang/clash/dns/rcode.go b/clash-meta-android/core/src/foss/golang/clash/dns/rcode.go index 9777d2e77b..901d1019d3 100644 --- a/clash-meta-android/core/src/foss/golang/clash/dns/rcode.go +++ b/clash-meta-android/core/src/foss/golang/clash/dns/rcode.go @@ -48,3 +48,5 @@ func (r rcodeClient) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, err func (r rcodeClient) Address() string { return r.addr } + +func (r rcodeClient) ResetConnection() {} diff --git a/clash-meta-android/core/src/foss/golang/clash/dns/resolver.go b/clash-meta-android/core/src/foss/golang/clash/dns/resolver.go index e03feef46f..ec59f42857 100644 --- a/clash-meta-android/core/src/foss/golang/clash/dns/resolver.go +++ b/clash-meta-android/core/src/foss/golang/clash/dns/resolver.go @@ -24,6 +24,7 @@ import ( type dnsClient interface { ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, err error) Address() string + ResetConnection() } type dnsCache interface { @@ -48,7 +49,7 @@ type Resolver struct { group singleflight.Group[*D.Msg] cache dnsCache policy []dnsPolicy - proxyServer []dnsClient + defaultResolver *Resolver } func (r *Resolver) LookupIPPrimaryIPv4(ctx context.Context, host string) (ips []netip.Addr, err error) { @@ -376,6 +377,20 @@ func (r *Resolver) ClearCache() { } } +func (r *Resolver) ResetConnection() { + if r != nil { + for _, c := range r.main { + c.ResetConnection() + } + for _, c := range r.fallback { + c.ResetConnection() + } + if dr := r.defaultResolver; dr != nil { + dr.ResetConnection() + } + } +} + type NameServer struct { Net string Addr string @@ -425,16 +440,18 @@ type Config struct { CacheAlgorithm string } -func NewResolver(config Config) *Resolver { - var cache dnsCache - if config.CacheAlgorithm == "lru" { - cache = lru.New(lru.WithSize[string, *D.Msg](4096), lru.WithStale[string, *D.Msg](true)) +func (config Config) newCache() dnsCache { + if config.CacheAlgorithm == "" || config.CacheAlgorithm == "lru" { + return lru.New(lru.WithSize[string, *D.Msg](4096), lru.WithStale[string, *D.Msg](true)) } else { - cache = arc.New(arc.WithSize[string, *D.Msg](4096)) + return arc.New(arc.WithSize[string, *D.Msg](4096)) } +} + +func NewResolver(config Config) (r *Resolver, pr *Resolver) { defaultResolver := &Resolver{ main: transform(config.Default, nil), - cache: cache, + cache: config.newCache(), ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond, } @@ -465,27 +482,29 @@ func NewResolver(config Config) *Resolver { return } - if config.CacheAlgorithm == "" || config.CacheAlgorithm == "lru" { - cache = lru.New(lru.WithSize[string, *D.Msg](4096), lru.WithStale[string, *D.Msg](true)) - } else { - cache = arc.New(arc.WithSize[string, *D.Msg](4096)) - } - r := &Resolver{ + r = &Resolver{ ipv6: config.IPv6, main: cacheTransform(config.Main), - cache: cache, + cache: config.newCache(), hosts: config.Hosts, ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond, } + r.defaultResolver = defaultResolver + + if len(config.ProxyServer) != 0 { + pr = &Resolver{ + ipv6: config.IPv6, + main: cacheTransform(config.ProxyServer), + cache: config.newCache(), + hosts: config.Hosts, + ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond, + } + } if len(config.Fallback) != 0 { r.fallback = cacheTransform(config.Fallback) } - if len(config.ProxyServer) != 0 { - r.proxyServer = cacheTransform(config.ProxyServer) - } - if len(config.Policy) != 0 { r.policy = make([]dnsPolicy, 0) @@ -516,18 +535,7 @@ func NewResolver(config Config) *Resolver { r.fallbackIPFilters = config.FallbackIPFilter r.fallbackDomainFilters = config.FallbackDomainFilter - return r -} - -func NewProxyServerHostResolver(old *Resolver) *Resolver { - r := &Resolver{ - ipv6: old.ipv6, - main: old.proxyServer, - cache: old.cache, - hosts: old.hosts, - ipv6Timeout: old.ipv6Timeout, - } - return r + return } var ParseNameServer func(servers []string) ([]NameServer, error) // define in config/config.go diff --git a/clash-meta-android/core/src/foss/golang/clash/dns/system_common.go b/clash-meta-android/core/src/foss/golang/clash/dns/system_common.go index 06dc0b3020..e6dabdcfff 100644 --- a/clash-meta-android/core/src/foss/golang/clash/dns/system_common.go +++ b/clash-meta-android/core/src/foss/golang/clash/dns/system_common.go @@ -69,3 +69,5 @@ func (c *systemClient) getDnsClients() ([]dnsClient, error) { } return nil, err } + +func (c *systemClient) ResetConnection() {} diff --git a/clash-meta-android/core/src/foss/golang/clash/docs/config.yaml b/clash-meta-android/core/src/foss/golang/clash/docs/config.yaml index b3515a2060..9c480b3f2a 100644 --- a/clash-meta-android/core/src/foss/golang/clash/docs/config.yaml +++ b/clash-meta-android/core/src/foss/golang/clash/docs/config.yaml @@ -63,6 +63,10 @@ external-controller-tls: 0.0.0.0:9443 # RESTful API HTTPS 监听地址,需要 # 测试方法: curl -v --unix-socket "mihomo.sock" http://localhost/ external-controller-unix: mihomo.sock +# RESTful API Windows namedpipe 监听地址 +# !!!注意: 从Windows namedpipe访问api接口不会验证secret, 如果开启请自行保证安全问题 !!! +external-controller-pipe: \\.\pipe\mihomo + # tcp-concurrent: true # TCP 并发连接所有 IP, 将使用最快握手的 TCP # 配置 WEB UI 目录,使用 http://{{external-controller}}/ui 访问 diff --git a/clash-meta-android/core/src/foss/golang/clash/go.mod b/clash-meta-android/core/src/foss/golang/clash/go.mod index e3eeb456b0..b74cee92e1 100644 --- a/clash-meta-android/core/src/foss/golang/clash/go.mod +++ b/clash-meta-android/core/src/foss/golang/clash/go.mod @@ -28,7 +28,7 @@ require ( github.com/metacubex/sing-shadowsocks2 v0.2.2 github.com/metacubex/sing-tun v0.2.7-0.20240729131039-ed03f557dee1 github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 - github.com/metacubex/sing-wireguard v0.0.0-20240922131718-0f10c39a5531 + github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3 github.com/metacubex/tfo-go v0.0.0-20240830120620-c5e019b67785 github.com/metacubex/utls v1.6.6 github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181 @@ -46,14 +46,15 @@ require ( github.com/shirou/gopsutil/v3 v3.24.5 github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 + github.com/vmihailenco/msgpack/v5 v5.4.1 github.com/wk8/go-ordered-map/v2 v2.1.8 gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 - go.uber.org/automaxprocs v1.5.3 + go.uber.org/automaxprocs v1.6.0 go4.org/netipx v0.0.0-20231129151722-fdeea329fbba - golang.org/x/crypto v0.26.0 + golang.org/x/crypto v0.27.0 golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa - golang.org/x/net v0.28.0 - golang.org/x/sys v0.24.0 + golang.org/x/net v0.29.0 + golang.org/x/sys v0.25.0 google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 lukechampine.com/blake3 v1.3.0 @@ -104,12 +105,13 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect github.com/vishvananda/netns v0.0.4 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect go.uber.org/mock v0.4.0 // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.24.0 // indirect ) diff --git a/clash-meta-android/core/src/foss/golang/clash/go.sum b/clash-meta-android/core/src/foss/golang/clash/go.sum index e1f5490d5b..ba2d181951 100644 --- a/clash-meta-android/core/src/foss/golang/clash/go.sum +++ b/clash-meta-android/core/src/foss/golang/clash/go.sum @@ -122,8 +122,8 @@ github.com/metacubex/sing-tun v0.2.7-0.20240729131039-ed03f557dee1 h1:ypfofGDZbP github.com/metacubex/sing-tun v0.2.7-0.20240729131039-ed03f557dee1/go.mod h1:olbEx9yVcaw5tHTNlRamRoxmMKcvDvcVS1YLnQGzvWE= github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 h1:OAXiCosqY8xKDp3pqTW3qbrCprZ1l6WkrXSFSCwyY4I= github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY= -github.com/metacubex/sing-wireguard v0.0.0-20240922131718-0f10c39a5531 h1:BoIL2fZZTPzvSxuhng9kWwvUZ8fiMJyrWbgdHIX0CDs= -github.com/metacubex/sing-wireguard v0.0.0-20240922131718-0f10c39a5531/go.mod h1:6nitcmzPDL3MXnLdhu6Hm126Zk4S1fBbX3P7jxUxSFw= +github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3 h1:xg71VmzLS6ByAzi/57phwDvjE+dLLs+ozH00k4DnOns= +github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3/go.mod h1:6nitcmzPDL3MXnLdhu6Hm126Zk4S1fBbX3P7jxUxSFw= github.com/metacubex/tfo-go v0.0.0-20240830120620-c5e019b67785 h1:NNmI+ZV0DzNuqaAInRQuZFLHlWVuyHeow8jYpdKjHjo= github.com/metacubex/tfo-go v0.0.0-20240830120620-c5e019b67785/go.mod h1:c7bVFM9f5+VzeZ/6Kg77T/jrg1Xp8QpqlSHvG/aXVts= github.com/metacubex/utls v1.6.6 h1:3D12YKHTf2Z41UPhQU2dWerNWJ5TVQD9gKoQ+H+iLC8= @@ -210,6 +210,10 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17 github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= @@ -218,16 +222,16 @@ gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 h1:UNrDfkQqiE gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7/go.mod h1:E+rxHvJG9H6PUdzq9NRG6csuLN3XUx98BfGOVWNYnXs= gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec h1:FpfFs4EhNehiVfzQttTuxanPIT43FtkkCFypIod8LHo= gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec/go.mod h1:BZ1RAoRPbCxum9Grlv5aeksu2H8BiKehBYooU2LFiOQ= -go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= -go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= @@ -236,8 +240,8 @@ golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= @@ -257,12 +261,12 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= diff --git a/clash-meta-android/core/src/foss/golang/clash/hub/executor/executor.go b/clash-meta-android/core/src/foss/golang/clash/hub/executor/executor.go index 66bbc89ba4..214407b477 100644 --- a/clash-meta-android/core/src/foss/golang/clash/hub/executor/executor.go +++ b/clash-meta-android/core/src/foss/golang/clash/hub/executor/executor.go @@ -118,6 +118,8 @@ func ApplyConfig(cfg *config.Config, force bool) { tunnel.OnRunning() hcCompatibleProvider(cfg.Providers) initExternalUI() + + resolver.ResetConnection() } func initInnerTcp() { @@ -127,7 +129,7 @@ func initInnerTcp() { func GetGeneral() *config.General { ports := listener.GetPorts() var authenticator []string - if auth := authStore.Authenticator(); auth != nil { + if auth := authStore.Default.Authenticator(); auth != nil { authenticator = auth.Users() } @@ -253,8 +255,7 @@ func updateDNS(c *config.DNS, generalIPv6 bool) { CacheAlgorithm: c.CacheAlgorithm, } - r := dns.NewResolver(cfg) - pr := dns.NewProxyServerHostResolver(r) + r, pr := dns.NewResolver(cfg) m := dns.NewEnhancer(cfg) // reuse cache of old host mapper @@ -422,7 +423,7 @@ func updateGeneral(general *config.General) { func updateUsers(users []auth.AuthUser) { authenticator := auth.NewAuthenticator(users) - authStore.SetAuthenticator(authenticator) + authStore.Default.SetAuthenticator(authenticator) if authenticator != nil { log.Infoln("Authentication of local server updated") } @@ -444,12 +445,12 @@ func patchSelectGroup(proxies map[string]C.Proxy) { } for name, proxy := range proxies { - outbound, ok := proxy.(*adapter.Proxy) + outbound, ok := proxy.(C.Proxy) if !ok { continue } - selector, ok := outbound.ProxyAdapter.(outboundgroup.SelectAble) + selector, ok := outbound.Adapter().(outboundgroup.SelectAble) if !ok { continue } diff --git a/clash-meta-android/core/src/foss/golang/clash/hub/hub.go b/clash-meta-android/core/src/foss/golang/clash/hub/hub.go index e22f721970..73a44eee66 100644 --- a/clash-meta-android/core/src/foss/golang/clash/hub/hub.go +++ b/clash-meta-android/core/src/foss/golang/clash/hub/hub.go @@ -27,6 +27,12 @@ func WithExternalControllerUnix(externalControllerUnix string) Option { } } +func WithExternalControllerPipe(externalControllerPipe string) Option { + return func(cfg *config.Config) { + cfg.Controller.ExternalControllerPipe = externalControllerPipe + } +} + func WithSecret(secret string) Option { return func(cfg *config.Config) { cfg.Controller.Secret = secret @@ -47,6 +53,7 @@ func applyRoute(cfg *config.Config) { Addr: cfg.Controller.ExternalController, TLSAddr: cfg.Controller.ExternalControllerTLS, UnixAddr: cfg.Controller.ExternalControllerUnix, + PipeAddr: cfg.Controller.ExternalControllerPipe, Secret: cfg.Controller.Secret, Certificate: cfg.TLS.Certificate, PrivateKey: cfg.TLS.PrivateKey, diff --git a/clash-meta-android/core/src/foss/golang/clash/hub/route/groups.go b/clash-meta-android/core/src/foss/golang/clash/hub/route/groups.go index c4e9501f2d..68d1f3542b 100644 --- a/clash-meta-android/core/src/foss/golang/clash/hub/route/groups.go +++ b/clash-meta-android/core/src/foss/golang/clash/hub/route/groups.go @@ -9,7 +9,6 @@ import ( "github.com/go-chi/chi/v5" "github.com/go-chi/render" - "github.com/metacubex/mihomo/adapter" "github.com/metacubex/mihomo/adapter/outboundgroup" "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/component/profile/cachefile" @@ -32,7 +31,7 @@ func GroupRouter() http.Handler { func getGroups(w http.ResponseWriter, r *http.Request) { var gs []C.Proxy for _, p := range tunnel.Proxies() { - if _, ok := p.(*adapter.Proxy).ProxyAdapter.(C.Group); ok { + if _, ok := p.Adapter().(C.Group); ok { gs = append(gs, p) } } @@ -43,7 +42,7 @@ func getGroups(w http.ResponseWriter, r *http.Request) { func getGroup(w http.ResponseWriter, r *http.Request) { proxy := r.Context().Value(CtxKeyProxy).(C.Proxy) - if _, ok := proxy.(*adapter.Proxy).ProxyAdapter.(C.Group); ok { + if _, ok := proxy.Adapter().(C.Group); ok { render.JSON(w, r, proxy) return } @@ -53,25 +52,15 @@ func getGroup(w http.ResponseWriter, r *http.Request) { func getGroupDelay(w http.ResponseWriter, r *http.Request) { proxy := r.Context().Value(CtxKeyProxy).(C.Proxy) - group, ok := proxy.(*adapter.Proxy).ProxyAdapter.(C.Group) + group, ok := proxy.Adapter().(C.Group) if !ok { render.Status(r, http.StatusNotFound) render.JSON(w, r, ErrNotFound) return } - switch proxy.(*adapter.Proxy).Type() { - case C.URLTest: - if urlTestGroup, ok := proxy.(*adapter.Proxy).ProxyAdapter.(*outboundgroup.URLTest); ok { - urlTestGroup.ForceSet("") - } - case C.Fallback: - if fallbackGroup, ok := proxy.(*adapter.Proxy).ProxyAdapter.(*outboundgroup.Fallback); ok { - fallbackGroup.ForceSet("") - } - } - - if proxy.(*adapter.Proxy).Type() != C.Selector { + if selectAble, ok := proxy.Adapter().(outboundgroup.SelectAble); ok && proxy.Type() != C.Selector { + selectAble.ForceSet("") cachefile.Cache().SetSelected(proxy.Name(), "") } diff --git a/clash-meta-android/core/src/foss/golang/clash/hub/route/proxies.go b/clash-meta-android/core/src/foss/golang/clash/hub/route/proxies.go index 69c8e44651..ba4e03f902 100644 --- a/clash-meta-android/core/src/foss/golang/clash/hub/route/proxies.go +++ b/clash-meta-android/core/src/foss/golang/clash/hub/route/proxies.go @@ -7,7 +7,6 @@ import ( "strconv" "time" - "github.com/metacubex/mihomo/adapter" "github.com/metacubex/mihomo/adapter/outboundgroup" "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/component/profile/cachefile" @@ -31,6 +30,7 @@ func proxyRouter() http.Handler { r.Get("/", getProxy) r.Get("/delay", getProxyDelay) r.Put("/", updateProxy) + r.Delete("/", unfixedProxy) }) return r } @@ -81,8 +81,8 @@ func updateProxy(w http.ResponseWriter, r *http.Request) { return } - proxy := r.Context().Value(CtxKeyProxy).(*adapter.Proxy) - selector, ok := proxy.ProxyAdapter.(outboundgroup.SelectAble) + proxy := r.Context().Value(CtxKeyProxy).(C.Proxy) + selector, ok := proxy.Adapter().(outboundgroup.SelectAble) if !ok { render.Status(r, http.StatusBadRequest) render.JSON(w, r, newError("Must be a Selector")) @@ -146,3 +146,15 @@ func getProxyDelay(w http.ResponseWriter, r *http.Request) { "delay": delay, }) } + +func unfixedProxy(w http.ResponseWriter, r *http.Request) { + proxy := r.Context().Value(CtxKeyProxy).(C.Proxy) + if selectAble, ok := proxy.Adapter().(outboundgroup.SelectAble); ok && proxy.Type() != C.Selector { + selectAble.ForceSet("") + cachefile.Cache().SetSelected(proxy.Name(), "") + render.NoContent(w, r) + return + } + render.Status(r, http.StatusBadRequest) + render.JSON(w, r, ErrBadRequest) +} diff --git a/clash-meta-android/core/src/foss/golang/clash/hub/route/server.go b/clash-meta-android/core/src/foss/golang/clash/hub/route/server.go index b707756321..4c22609cfc 100644 --- a/clash-meta-android/core/src/foss/golang/clash/hub/route/server.go +++ b/clash-meta-android/core/src/foss/golang/clash/hub/route/server.go @@ -35,6 +35,7 @@ var ( httpServer *http.Server tlsServer *http.Server unixServer *http.Server + pipeServer *http.Server ) type Traffic struct { @@ -51,6 +52,7 @@ type Config struct { Addr string TLSAddr string UnixAddr string + PipeAddr string Secret string Certificate string PrivateKey string @@ -62,6 +64,9 @@ func ReCreateServer(cfg *Config) { go start(cfg) go startTLS(cfg) go startUnix(cfg) + if inbound.SupportNamedPipe { + go startPipe(cfg) + } } func SetUIPath(path string) { @@ -233,7 +238,37 @@ func startUnix(cfg *Config) { log.Errorln("External controller unix serve error: %s", err) } } +} +func startPipe(cfg *Config) { + // first stop existing server + if pipeServer != nil { + _ = pipeServer.Close() + pipeServer = nil + } + + // handle addr + if len(cfg.PipeAddr) > 0 { + if !strings.HasPrefix(cfg.PipeAddr, "\\\\.\\pipe\\") { // windows namedpipe must start with "\\.\pipe\" + log.Errorln("External controller pipe listen error: windows namedpipe must start with \"\\\\.\\pipe\\\"") + return + } + + l, err := inbound.ListenNamedPipe(cfg.PipeAddr) + if err != nil { + log.Errorln("External controller pipe listen error: %s", err) + return + } + log.Infoln("RESTful API pipe listening at: %s", l.Addr().String()) + + server := &http.Server{ + Handler: router(cfg.IsDebug, "", cfg.DohServer), + } + pipeServer = server + if err = server.Serve(l); err != nil { + log.Errorln("External controller pipe serve error: %s", err) + } + } } func setPrivateNetworkAccess(next http.Handler) http.Handler { diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/auth/auth.go b/clash-meta-android/core/src/foss/golang/clash/listener/auth/auth.go index 772be3bdd7..9e7632e868 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/auth/auth.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/auth/auth.go @@ -4,14 +4,30 @@ import ( "github.com/metacubex/mihomo/component/auth" ) -var authenticator auth.Authenticator - -func Authenticator() auth.Authenticator { - return authenticator +type authStore struct { + authenticator auth.Authenticator } -func SetAuthenticator(au auth.Authenticator) { - authenticator = au +func (a *authStore) Authenticator() auth.Authenticator { + return a.authenticator } -func Nil() auth.Authenticator { return nil } +func (a *authStore) SetAuthenticator(authenticator auth.Authenticator) { + a.authenticator = authenticator +} + +func NewAuthStore(authenticator auth.Authenticator) auth.AuthStore { + return &authStore{authenticator} +} + +var Default auth.AuthStore = NewAuthStore(nil) + +type nilAuthStore struct{} + +func (a *nilAuthStore) Authenticator() auth.Authenticator { + return nil +} + +func (a *nilAuthStore) SetAuthenticator(authenticator auth.Authenticator) {} + +var Nil auth.AuthStore = (*nilAuthStore)(nil) // always return nil, even call SetAuthenticator() with a non-nil authenticator diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/http/proxy.go b/clash-meta-android/core/src/foss/golang/clash/listener/http/proxy.go index 04ab98eb8c..5c08cd458a 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/http/proxy.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/http/proxy.go @@ -30,7 +30,7 @@ func (b *bodyWrapper) Read(p []byte) (n int, err error) { return n, err } -func HandleConn(c net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) { +func HandleConn(c net.Conn, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) { additions = append(additions, inbound.Placeholder) // Add a placeholder for InUser inUserIdx := len(additions) - 1 client := newClient(c, tunnel, additions) @@ -41,7 +41,7 @@ func HandleConn(c net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, conn := N.NewBufferedConn(c) - authenticator := getAuth() + authenticator := store.Authenticator() keepAlive := true trusted := authenticator == nil // disable authenticate if lru is nil lastUser := "" diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/http/server.go b/clash-meta-android/core/src/foss/golang/clash/listener/http/server.go index 48f12dc5f1..24f07e8bd1 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/http/server.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/http/server.go @@ -4,7 +4,6 @@ import ( "net" "github.com/metacubex/mihomo/adapter/inbound" - N "github.com/metacubex/mihomo/common/net" "github.com/metacubex/mihomo/component/auth" C "github.com/metacubex/mihomo/constant" authStore "github.com/metacubex/mihomo/listener/auth" @@ -33,20 +32,20 @@ func (l *Listener) Close() error { } func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) { - return NewWithAuthenticator(addr, tunnel, authStore.Authenticator, additions...) + return NewWithAuthenticator(addr, tunnel, authStore.Default, additions...) } // NewWithAuthenticate // never change type traits because it's used in CMFA func NewWithAuthenticate(addr string, tunnel C.Tunnel, authenticate bool, additions ...inbound.Addition) (*Listener, error) { - getAuth := authStore.Authenticator + store := authStore.Default if !authenticate { - getAuth = authStore.Nil + store = authStore.Default } - return NewWithAuthenticator(addr, tunnel, getAuth, additions...) + return NewWithAuthenticator(addr, tunnel, store, additions...) } -func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) (*Listener, error) { +func NewWithAuthenticator(addr string, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) (*Listener, error) { isDefault := false if len(additions) == 0 { isDefault = true @@ -55,8 +54,8 @@ func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Auth inbound.WithSpecialRules(""), } } - l, err := inbound.Listen("tcp", addr) + l, err := inbound.Listen("tcp", addr) if err != nil { return nil, err } @@ -74,19 +73,18 @@ func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Auth } continue } - N.TCPKeepAlive(conn) - getAuth := getAuth - if isDefault { // only apply on default listener + store := store + if isDefault || store == authStore.Default { // only apply on default listener if !inbound.IsRemoteAddrDisAllowed(conn.RemoteAddr()) { _ = conn.Close() continue } if inbound.SkipAuthRemoteAddr(conn.RemoteAddr()) { - getAuth = authStore.Nil + store = authStore.Nil } } - go HandleConn(conn, tunnel, getAuth, additions...) + go HandleConn(conn, tunnel, store, additions...) } }() diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/inbound/auth.go b/clash-meta-android/core/src/foss/golang/clash/listener/inbound/auth.go index 41f18fc089..85e7249455 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/inbound/auth.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/inbound/auth.go @@ -12,7 +12,7 @@ type AuthUser struct { type AuthUsers []AuthUser -func (a AuthUsers) GetAuth() func() auth.Authenticator { +func (a AuthUsers) GetAuthStore() auth.AuthStore { if a != nil { // structure's Decode will ensure value not nil when input has value even it was set an empty array if len(a) == 0 { return authStore.Nil @@ -25,7 +25,7 @@ func (a AuthUsers) GetAuth() func() auth.Authenticator { } } authenticator := auth.NewAuthenticator(users) - return func() auth.Authenticator { return authenticator } + return authStore.NewAuthStore(authenticator) } - return authStore.Authenticator + return authStore.Default } diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/inbound/http.go b/clash-meta-android/core/src/foss/golang/clash/listener/inbound/http.go index c78abefd5f..e20a9a2357 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/inbound/http.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/inbound/http.go @@ -45,7 +45,7 @@ func (h *HTTP) Address() string { // Listen implements constant.InboundListener func (h *HTTP) Listen(tunnel C.Tunnel) error { var err error - h.l, err = http.NewWithAuthenticator(h.RawAddress(), tunnel, h.config.Users.GetAuth(), h.Additions()...) + h.l, err = http.NewWithAuthenticator(h.RawAddress(), tunnel, h.config.Users.GetAuthStore(), h.Additions()...) if err != nil { return err } diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/inbound/mixed.go b/clash-meta-android/core/src/foss/golang/clash/listener/inbound/mixed.go index 443a256452..1d79929acc 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/inbound/mixed.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/inbound/mixed.go @@ -53,7 +53,7 @@ func (m *Mixed) Address() string { // Listen implements constant.InboundListener func (m *Mixed) Listen(tunnel C.Tunnel) error { var err error - m.l, err = mixed.NewWithAuthenticator(m.RawAddress(), tunnel, m.config.Users.GetAuth(), m.Additions()...) + m.l, err = mixed.NewWithAuthenticator(m.RawAddress(), tunnel, m.config.Users.GetAuthStore(), m.Additions()...) if err != nil { return err } diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/inbound/socks.go b/clash-meta-android/core/src/foss/golang/clash/listener/inbound/socks.go index cf6d1ce433..119eec8281 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/inbound/socks.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/inbound/socks.go @@ -71,7 +71,7 @@ func (s *Socks) Address() string { // Listen implements constant.InboundListener func (s *Socks) Listen(tunnel C.Tunnel) error { var err error - if s.stl, err = socks.NewWithAuthenticator(s.RawAddress(), tunnel, s.config.Users.GetAuth(), s.Additions()...); err != nil { + if s.stl, err = socks.NewWithAuthenticator(s.RawAddress(), tunnel, s.config.Users.GetAuthStore(), s.Additions()...); err != nil { return err } if s.udp { diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/mixed/mixed.go b/clash-meta-android/core/src/foss/golang/clash/listener/mixed/mixed.go index 12390061c0..5ac6301153 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/mixed/mixed.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/mixed/mixed.go @@ -37,10 +37,10 @@ func (l *Listener) Close() error { } func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) { - return NewWithAuthenticator(addr, tunnel, authStore.Authenticator, additions...) + return NewWithAuthenticator(addr, tunnel, authStore.Default, additions...) } -func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) (*Listener, error) { +func NewWithAuthenticator(addr string, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) (*Listener, error) { isDefault := false if len(additions) == 0 { isDefault = true @@ -49,6 +49,7 @@ func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Auth inbound.WithSpecialRules(""), } } + l, err := inbound.Listen("tcp", addr) if err != nil { return nil, err @@ -67,26 +68,24 @@ func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Auth } continue } - getAuth := getAuth - if isDefault { // only apply on default listener + store := store + if isDefault || store == authStore.Default { // only apply on default listener if !inbound.IsRemoteAddrDisAllowed(c.RemoteAddr()) { _ = c.Close() continue } if inbound.SkipAuthRemoteAddr(c.RemoteAddr()) { - getAuth = authStore.Nil + store = authStore.Nil } } - go handleConn(c, tunnel, getAuth, additions...) + go handleConn(c, tunnel, store, additions...) } }() return ml, nil } -func handleConn(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) { - N.TCPKeepAlive(conn) - +func handleConn(conn net.Conn, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) { bufConn := N.NewBufferedConn(conn) head, err := bufConn.Peek(1) if err != nil { @@ -95,10 +94,10 @@ func handleConn(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticato switch head[0] { case socks4.Version: - socks.HandleSocks4(bufConn, tunnel, getAuth, additions...) + socks.HandleSocks4(bufConn, tunnel, store, additions...) case socks5.Version: - socks.HandleSocks5(bufConn, tunnel, getAuth, additions...) + socks.HandleSocks5(bufConn, tunnel, store, additions...) default: - http.HandleConn(bufConn, tunnel, getAuth, additions...) + http.HandleConn(bufConn, tunnel, store, additions...) } } diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/redir/tcp.go b/clash-meta-android/core/src/foss/golang/clash/listener/redir/tcp.go index 8474a8e215..47363182d0 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/redir/tcp.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/redir/tcp.go @@ -4,7 +4,7 @@ import ( "net" "github.com/metacubex/mihomo/adapter/inbound" - N "github.com/metacubex/mihomo/common/net" + "github.com/metacubex/mihomo/component/keepalive" C "github.com/metacubex/mihomo/constant" ) @@ -37,10 +37,12 @@ func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener inbound.WithSpecialRules(""), } } + l, err := net.Listen("tcp", addr) if err != nil { return nil, err } + rl := &Listener{ listener: l, addr: addr, @@ -68,6 +70,6 @@ func handleRedir(conn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition) conn.Close() return } - N.TCPKeepAlive(conn) + keepalive.TCPKeepAlive(conn) tunnel.HandleTCPConn(inbound.NewSocket(target, conn, C.REDIR, additions...)) } diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/shadowsocks/tcp.go b/clash-meta-android/core/src/foss/golang/clash/listener/shadowsocks/tcp.go index c38438142d..b150e4cbc1 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/shadowsocks/tcp.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/shadowsocks/tcp.go @@ -59,7 +59,6 @@ func New(config LC.ShadowsocksServer, tunnel C.Tunnel, additions ...inbound.Addi } continue } - N.TCPKeepAlive(c) go sl.HandleConn(c, tunnel, additions...) } }() diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/sing_shadowsocks/server.go b/clash-meta-android/core/src/foss/golang/clash/listener/sing_shadowsocks/server.go index 1cb798f7d0..5f2a4292e3 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/sing_shadowsocks/server.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/sing_shadowsocks/server.go @@ -7,7 +7,6 @@ import ( "strings" "github.com/metacubex/mihomo/adapter/inbound" - N "github.com/metacubex/mihomo/common/net" "github.com/metacubex/mihomo/common/sockopt" C "github.com/metacubex/mihomo/constant" LC "github.com/metacubex/mihomo/listener/config" @@ -153,7 +152,6 @@ func New(config LC.ShadowsocksServer, tunnel C.Tunnel, additions ...inbound.Addi } continue } - N.TCPKeepAlive(c) go sl.HandleConn(c, tunnel) } diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/sing_tun/server.go b/clash-meta-android/core/src/foss/golang/clash/listener/sing_tun/server.go index c2c668b34e..79856c466c 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/sing_tun/server.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/sing_tun/server.go @@ -440,6 +440,10 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis //l.openAndroidHotspot(tunOptions) + if !l.options.AutoDetectInterface { + resolver.ResetConnection() + } + if options.FileDescriptor != 0 { tunName = fmt.Sprintf("%s(fd=%d)", tunName, options.FileDescriptor) } @@ -507,6 +511,7 @@ func (l *Listener) FlushDefaultInterface() { if old := dialer.DefaultInterface.Swap(autoDetectInterfaceName); old != autoDetectInterfaceName { log.Warnln("[TUN] default interface changed by monitor, %s => %s", old, autoDetectInterfaceName) iface.FlushCache() + resolver.ResetConnection() // reset resolver's connection after default interface changed } return } diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/sing_vmess/server.go b/clash-meta-android/core/src/foss/golang/clash/listener/sing_vmess/server.go index ce422b1652..7a0afa0b73 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/sing_vmess/server.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/sing_vmess/server.go @@ -121,7 +121,6 @@ func New(config LC.VmessServer, tunnel C.Tunnel, additions ...inbound.Addition) } continue } - N.TCPKeepAlive(c) go sl.HandleConn(c, tunnel) } diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/socks/tcp.go b/clash-meta-android/core/src/foss/golang/clash/listener/socks/tcp.go index 3e98a60276..cc66613e2a 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/socks/tcp.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/socks/tcp.go @@ -36,10 +36,10 @@ func (l *Listener) Close() error { } func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) { - return NewWithAuthenticator(addr, tunnel, authStore.Authenticator, additions...) + return NewWithAuthenticator(addr, tunnel, authStore.Default, additions...) } -func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) (*Listener, error) { +func NewWithAuthenticator(addr string, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) (*Listener, error) { isDefault := false if len(additions) == 0 { isDefault = true @@ -48,6 +48,7 @@ func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Auth inbound.WithSpecialRules(""), } } + l, err := inbound.Listen("tcp", addr) if err != nil { return nil, err @@ -66,25 +67,24 @@ func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Auth } continue } - getAuth := getAuth - if isDefault { // only apply on default listener + store := store + if isDefault || store == authStore.Default { // only apply on default listener if !inbound.IsRemoteAddrDisAllowed(c.RemoteAddr()) { _ = c.Close() continue } if inbound.SkipAuthRemoteAddr(c.RemoteAddr()) { - getAuth = authStore.Nil + store = authStore.Nil } } - go handleSocks(c, tunnel, getAuth, additions...) + go handleSocks(c, tunnel, store, additions...) } }() return sl, nil } -func handleSocks(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) { - N.TCPKeepAlive(conn) +func handleSocks(conn net.Conn, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) { bufConn := N.NewBufferedConn(conn) head, err := bufConn.Peek(1) if err != nil { @@ -94,16 +94,16 @@ func handleSocks(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticat switch head[0] { case socks4.Version: - HandleSocks4(bufConn, tunnel, getAuth, additions...) + HandleSocks4(bufConn, tunnel, store, additions...) case socks5.Version: - HandleSocks5(bufConn, tunnel, getAuth, additions...) + HandleSocks5(bufConn, tunnel, store, additions...) default: conn.Close() } } -func HandleSocks4(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) { - authenticator := getAuth() +func HandleSocks4(conn net.Conn, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) { + authenticator := store.Authenticator() addr, _, user, err := socks4.ServerHandshake(conn, authenticator) if err != nil { conn.Close() @@ -113,8 +113,8 @@ func HandleSocks4(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authentica tunnel.HandleTCPConn(inbound.NewSocket(socks5.ParseAddr(addr), conn, C.SOCKS4, additions...)) } -func HandleSocks5(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) { - authenticator := getAuth() +func HandleSocks5(conn net.Conn, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) { + authenticator := store.Authenticator() target, command, user, err := socks5.ServerHandshake(conn, authenticator) if err != nil { conn.Close() diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/tproxy/tproxy.go b/clash-meta-android/core/src/foss/golang/clash/listener/tproxy/tproxy.go index fa7e7dbe47..6056047a41 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/tproxy/tproxy.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/tproxy/tproxy.go @@ -4,7 +4,7 @@ import ( "net" "github.com/metacubex/mihomo/adapter/inbound" - N "github.com/metacubex/mihomo/common/net" + "github.com/metacubex/mihomo/component/keepalive" C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/transport/socks5" ) @@ -33,7 +33,7 @@ func (l *Listener) Close() error { func (l *Listener) handleTProxy(conn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition) { target := socks5.ParseAddrToSocksAddr(conn.LocalAddr()) - N.TCPKeepAlive(conn) + keepalive.TCPKeepAlive(conn) // TProxy's conn.LocalAddr() is target address, so we set from l.listener additions = append([]inbound.Addition{inbound.WithInAddr(l.listener.Addr())}, additions...) tunnel.HandleTCPConn(inbound.NewSocket(target, conn, C.TPROXY, additions...)) diff --git a/clash-meta-android/core/src/foss/golang/clash/listener/tunnel/tcp.go b/clash-meta-android/core/src/foss/golang/clash/listener/tunnel/tcp.go index 794dc8ac62..7c916a38f5 100644 --- a/clash-meta-android/core/src/foss/golang/clash/listener/tunnel/tcp.go +++ b/clash-meta-android/core/src/foss/golang/clash/listener/tunnel/tcp.go @@ -5,7 +5,6 @@ import ( "net" "github.com/metacubex/mihomo/adapter/inbound" - N "github.com/metacubex/mihomo/common/net" C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/transport/socks5" ) @@ -35,7 +34,6 @@ func (l *Listener) Close() error { } func (l *Listener) handleTCP(conn net.Conn, tunnel C.Tunnel, additions ...inbound.Addition) { - N.TCPKeepAlive(conn) tunnel.HandleTCPConn(inbound.NewSocket(l.target, conn, C.TUNNEL, additions...)) } diff --git a/clash-meta-android/core/src/foss/golang/clash/main.go b/clash-meta-android/core/src/foss/golang/clash/main.go index 8910a00653..505cdb2566 100644 --- a/clash-meta-android/core/src/foss/golang/clash/main.go +++ b/clash-meta-android/core/src/foss/golang/clash/main.go @@ -35,6 +35,7 @@ var ( externalUI string externalController string externalControllerUnix string + externalControllerPipe string secret string ) @@ -45,6 +46,7 @@ func init() { flag.StringVar(&externalUI, "ext-ui", os.Getenv("CLASH_OVERRIDE_EXTERNAL_UI_DIR"), "override external ui directory") flag.StringVar(&externalController, "ext-ctl", os.Getenv("CLASH_OVERRIDE_EXTERNAL_CONTROLLER"), "override external controller address") flag.StringVar(&externalControllerUnix, "ext-ctl-unix", os.Getenv("CLASH_OVERRIDE_EXTERNAL_CONTROLLER_UNIX"), "override external controller unix address") + flag.StringVar(&externalControllerPipe, "ext-ctl-pipe", os.Getenv("CLASH_OVERRIDE_EXTERNAL_CONTROLLER_PIPE"), "override external controller pipe address") flag.StringVar(&secret, "secret", os.Getenv("CLASH_OVERRIDE_SECRET"), "override secret for RESTful API") flag.BoolVar(&geodataMode, "m", false, "set geodata mode") flag.BoolVar(&version, "v", false, "show current version of mihomo") @@ -133,6 +135,9 @@ func main() { if externalControllerUnix != "" { options = append(options, hub.WithExternalControllerUnix(externalControllerUnix)) } + if externalControllerPipe != "" { + options = append(options, hub.WithExternalControllerPipe(externalControllerPipe)) + } if secret != "" { options = append(options, hub.WithSecret(secret)) } @@ -156,19 +161,9 @@ func main() { case <-termSign: return case <-hupSign: - var cfg *config.Config - var err error - if configString != "" { - cfg, err = executor.ParseWithBytes(configBytes) - } else { - cfg, err = executor.ParseWithPath(C.Path.Config()) - } - if err == nil { - hub.ApplyConfig(cfg) - } else { + if err := hub.Parse(configBytes, options...); err != nil { log.Errorln("Parse config error: %s", err.Error()) } - } } } diff --git a/clash-meta-android/core/src/foss/golang/clash/tunnel/connection.go b/clash-meta-android/core/src/foss/golang/clash/tunnel/connection.go index e96545e80b..1ea0678cd7 100644 --- a/clash-meta-android/core/src/foss/golang/clash/tunnel/connection.go +++ b/clash-meta-android/core/src/foss/golang/clash/tunnel/connection.go @@ -1,16 +1,109 @@ package tunnel import ( + "context" "errors" "net" "net/netip" "time" + "github.com/metacubex/mihomo/common/lru" N "github.com/metacubex/mihomo/common/net" + "github.com/metacubex/mihomo/component/resolver" C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/log" ) +type packetSender struct { + ctx context.Context + cancel context.CancelFunc + ch chan C.PacketAdapter + cache *lru.LruCache[string, netip.Addr] +} + +// newPacketSender return a chan based C.PacketSender +// It ensures that packets can be sent sequentially and without blocking +func newPacketSender() C.PacketSender { + ctx, cancel := context.WithCancel(context.Background()) + ch := make(chan C.PacketAdapter, senderCapacity) + return &packetSender{ + ctx: ctx, + cancel: cancel, + ch: ch, + cache: lru.New[string, netip.Addr](lru.WithSize[string, netip.Addr](senderCapacity)), + } +} + +func (s *packetSender) Process(pc C.PacketConn, proxy C.WriteBackProxy) { + for { + select { + case <-s.ctx.Done(): + return // sender closed + case packet := <-s.ch: + if proxy != nil { + proxy.UpdateWriteBack(packet) + } + if err := s.ResolveUDP(packet.Metadata()); err != nil { + log.Warnln("[UDP] Resolve Ip error: %s", err) + } else { + _ = handleUDPToRemote(packet, pc, packet.Metadata()) + } + packet.Drop() + } + } +} + +func (s *packetSender) dropAll() { + for { + select { + case data := <-s.ch: + data.Drop() // drop all data still in chan + default: + return // no data, exit goroutine + } + } +} + +func (s *packetSender) Send(packet C.PacketAdapter) { + select { + case <-s.ctx.Done(): + packet.Drop() // sender closed before Send() + return + default: + } + + select { + case s.ch <- packet: + // put ok, so don't drop packet, will process by other side of chan + case <-s.ctx.Done(): + packet.Drop() // sender closed when putting data to chan + default: + packet.Drop() // chan is full + } +} + +func (s *packetSender) Close() { + s.cancel() + s.dropAll() +} + +func (s *packetSender) ResolveUDP(metadata *C.Metadata) (err error) { + // local resolve UDP dns + if !metadata.Resolved() { + ip, ok := s.cache.Get(metadata.Host) + if !ok { + ip, err = resolver.ResolveIP(s.ctx, metadata.Host) + if err != nil { + return err + } + s.cache.Set(metadata.Host, ip) + } + + metadata.DstIP = ip + } + return nil +} + func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata) error { addr := metadata.UDPAddr() if addr == nil { @@ -26,8 +119,9 @@ func handleUDPToRemote(packet C.UDPPacket, pc C.PacketConn, metadata *C.Metadata return nil } -func handleUDPToLocal(writeBack C.WriteBack, pc N.EnhancePacketConn, key string, oAddrPort netip.AddrPort, fAddr netip.Addr) { +func handleUDPToLocal(writeBack C.WriteBack, pc N.EnhancePacketConn, sender C.PacketSender, key string, oAddrPort netip.AddrPort, fAddr netip.Addr) { defer func() { + sender.Close() _ = pc.Close() closeAllLocalCoon(key) natTable.Delete(key) diff --git a/clash-meta-android/core/src/foss/golang/clash/tunnel/tunnel.go b/clash-meta-android/core/src/foss/golang/clash/tunnel/tunnel.go index 60ba03234d..5c136eb24e 100644 --- a/clash-meta-android/core/src/foss/golang/clash/tunnel/tunnel.go +++ b/clash-meta-android/core/src/foss/golang/clash/tunnel/tunnel.go @@ -28,10 +28,15 @@ import ( "github.com/metacubex/mihomo/tunnel/statistic" ) +const ( + queueCapacity = 64 // chan capacity tcpQueue and udpQueue + senderCapacity = 128 // chan capacity of PacketSender +) + var ( status = newAtomicStatus(Suspend) - tcpQueue = make(chan C.ConnContext, 200) - udpQueue = make(chan C.PacketAdapter, 200) + udpInit sync.Once + udpQueues []chan C.PacketAdapter natTable = nat.New() rules []C.Rule listeners = make(map[string]C.InboundListener) @@ -41,6 +46,12 @@ var ( ruleProviders map[string]provider.RuleProvider configMux sync.RWMutex + // for compatibility, lazy init + tcpQueue chan C.ConnContext + tcpInOnce sync.Once + udpQueue chan C.PacketAdapter + udpInOnce sync.Once + // Outbound Rule mode = Rule @@ -68,11 +79,33 @@ func (t tunnel) HandleTCPConn(conn net.Conn, metadata *C.Metadata) { handleTCPConn(connCtx) } +func initUDP() { + numUDPWorkers := 4 + if num := runtime.GOMAXPROCS(0); num > numUDPWorkers { + numUDPWorkers = num + } + + udpQueues = make([]chan C.PacketAdapter, numUDPWorkers) + for i := 0; i < numUDPWorkers; i++ { + queue := make(chan C.PacketAdapter, queueCapacity) + udpQueues[i] = queue + go processUDP(queue) + } +} + func (t tunnel) HandleUDPPacket(packet C.UDPPacket, metadata *C.Metadata) { + udpInit.Do(initUDP) + packetAdapter := C.NewPacketAdapter(packet, metadata) + key := packetAdapter.Key() + + hash := utils.MapHash(key) + queueNo := uint(hash) % uint(len(udpQueues)) + select { - case udpQueue <- packetAdapter: + case udpQueues[queueNo] <- packetAdapter: default: + packet.Drop() } } @@ -128,19 +161,31 @@ func IsSniffing() bool { return sniffingEnable } -func init() { - go process() -} - // TCPIn return fan-in queue // Deprecated: using Tunnel instead func TCPIn() chan<- C.ConnContext { + tcpInOnce.Do(func() { + tcpQueue = make(chan C.ConnContext, queueCapacity) + go func() { + for connCtx := range tcpQueue { + go handleTCPConn(connCtx) + } + }() + }) return tcpQueue } // UDPIn return fan-in udp queue // Deprecated: using Tunnel instead func UDPIn() chan<- C.PacketAdapter { + udpInOnce.Do(func() { + udpQueue = make(chan C.PacketAdapter, queueCapacity) + go func() { + for packet := range udpQueue { + Tunnel.HandleUDPPacket(packet, packet.Metadata()) + } + }() + }) return udpQueue } @@ -242,29 +287,6 @@ func isHandle(t C.Type) bool { return status == Running || (status == Inner && t == C.INNER) } -// processUDP starts a loop to handle udp packet -func processUDP() { - queue := udpQueue - for conn := range queue { - handleUDPConn(conn) - } -} - -func process() { - numUDPWorkers := 4 - if num := runtime.GOMAXPROCS(0); num > numUDPWorkers { - numUDPWorkers = num - } - for i := 0; i < numUDPWorkers; i++ { - go processUDP() - } - - queue := tcpQueue - for conn := range queue { - go handleTCPConn(conn) - } -} - func needLookupIP(metadata *C.Metadata) bool { return resolver.MappingEnabled() && metadata.Host == "" && metadata.DstIP.IsValid() } @@ -324,6 +346,13 @@ func resolveMetadata(metadata *C.Metadata) (proxy C.Proxy, rule C.Rule, err erro return } +// processUDP starts a loop to handle udp packet +func processUDP(queue chan C.PacketAdapter) { + for conn := range queue { + handleUDPConn(conn) + } +} + func handleUDPConn(packet C.PacketAdapter) { if !isHandle(packet.Metadata().Type) { packet.Drop() @@ -353,85 +382,58 @@ func handleUDPConn(packet C.PacketAdapter) { snifferDispatcher.UDPSniff(packet) } - // local resolve UDP dns - if !metadata.Resolved() { - ip, err := resolver.ResolveIP(context.Background(), metadata.Host) - if err != nil { - return - } - metadata.DstIP = ip - } - - key := packet.LocalAddr().String() - - handle := func() bool { - pc, proxy := natTable.Get(key) - if pc != nil { - if proxy != nil { - proxy.UpdateWriteBack(packet) + key := packet.Key() + sender, loaded := natTable.GetOrCreate(key, newPacketSender) + if !loaded { + dial := func() (C.PacketConn, C.WriteBackProxy, error) { + if err := sender.ResolveUDP(metadata); err != nil { + log.Warnln("[UDP] Resolve Ip error: %s", err) + return nil, nil, err } - _ = handleUDPToRemote(packet, pc, metadata) - return true - } - return false - } - if handle() { - packet.Drop() - return - } + proxy, rule, err := resolveMetadata(metadata) + if err != nil { + log.Warnln("[UDP] Parse metadata failed: %s", err.Error()) + return nil, nil, err + } - cond, loaded := natTable.GetOrCreateLock(key) + ctx, cancel := context.WithTimeout(context.Background(), C.DefaultUDPTimeout) + defer cancel() + rawPc, err := retry(ctx, func(ctx context.Context) (C.PacketConn, error) { + return proxy.ListenPacketContext(ctx, metadata.Pure()) + }, func(err error) { + logMetadataErr(metadata, rule, proxy, err) + }) + if err != nil { + return nil, nil, err + } + logMetadata(metadata, rule, rawPc) - go func() { - defer packet.Drop() + pc := statistic.NewUDPTracker(rawPc, statistic.DefaultManager, metadata, rule, 0, 0, true) - if loaded { - cond.L.Lock() - cond.Wait() - handle() - cond.L.Unlock() - return + if rawPc.Chains().Last() == "REJECT-DROP" { + _ = pc.Close() + return nil, nil, errors.New("rejected drop packet") + } + + oAddrPort := metadata.AddrPort() + writeBackProxy := nat.NewWriteBackProxy(packet) + + go handleUDPToLocal(writeBackProxy, pc, sender, key, oAddrPort, fAddr) + return pc, writeBackProxy, nil } - defer func() { - natTable.DeleteLock(key) - cond.Broadcast() + go func() { + pc, proxy, err := dial() + if err != nil { + sender.Close() + natTable.Delete(key) + return + } + sender.Process(pc, proxy) }() - - proxy, rule, err := resolveMetadata(metadata) - if err != nil { - log.Warnln("[UDP] Parse metadata failed: %s", err.Error()) - return - } - - ctx, cancel := context.WithTimeout(context.Background(), C.DefaultUDPTimeout) - defer cancel() - rawPc, err := retry(ctx, func(ctx context.Context) (C.PacketConn, error) { - return proxy.ListenPacketContext(ctx, metadata.Pure()) - }, func(err error) { - logMetadataErr(metadata, rule, proxy, err) - }) - if err != nil { - return - } - logMetadata(metadata, rule, rawPc) - - pc := statistic.NewUDPTracker(rawPc, statistic.DefaultManager, metadata, rule, 0, 0, true) - - if rawPc.Chains().Last() == "REJECT-DROP" { - pc.Close() - return - } - - oAddrPort := metadata.AddrPort() - writeBackProxy := nat.NewWriteBackProxy(packet) - natTable.Set(key, pc, writeBackProxy) - - go handleUDPToLocal(writeBackProxy, pc, key, oAddrPort, fAddr) - - handle() - }() + } + sender.Send(packet) // nonblocking } func handleTCPConn(connCtx C.ConnContext) { diff --git a/clash-meta-android/core/src/foss/golang/go.mod b/clash-meta-android/core/src/foss/golang/go.mod index 6ae819dfa0..57a73c9529 100644 --- a/clash-meta-android/core/src/foss/golang/go.mod +++ b/clash-meta-android/core/src/foss/golang/go.mod @@ -56,7 +56,7 @@ require ( github.com/metacubex/sing-shadowsocks2 v0.2.2 // indirect github.com/metacubex/sing-tun v0.2.7-0.20240729131039-ed03f557dee1 // indirect github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 // indirect - github.com/metacubex/sing-wireguard v0.0.0-20240922131718-0f10c39a5531 // indirect + github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3 // indirect github.com/metacubex/tfo-go v0.0.0-20240830120620-c5e019b67785 // indirect github.com/metacubex/utls v1.6.6 // indirect github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181 // indirect @@ -89,19 +89,21 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect github.com/vishvananda/netns v0.0.4 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 // indirect gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect go.uber.org/mock v0.4.0 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect - golang.org/x/crypto v0.26.0 // indirect + golang.org/x/crypto v0.27.0 // indirect golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.28.0 // indirect + golang.org/x/net v0.29.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.24.0 // indirect google.golang.org/protobuf v1.34.2 // indirect diff --git a/clash-meta-android/core/src/foss/golang/go.sum b/clash-meta-android/core/src/foss/golang/go.sum index 7bd978137f..1fda649591 100644 --- a/clash-meta-android/core/src/foss/golang/go.sum +++ b/clash-meta-android/core/src/foss/golang/go.sum @@ -118,8 +118,8 @@ github.com/metacubex/sing-tun v0.2.7-0.20240729131039-ed03f557dee1 h1:ypfofGDZbP github.com/metacubex/sing-tun v0.2.7-0.20240729131039-ed03f557dee1/go.mod h1:olbEx9yVcaw5tHTNlRamRoxmMKcvDvcVS1YLnQGzvWE= github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 h1:OAXiCosqY8xKDp3pqTW3qbrCprZ1l6WkrXSFSCwyY4I= github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY= -github.com/metacubex/sing-wireguard v0.0.0-20240922131718-0f10c39a5531 h1:BoIL2fZZTPzvSxuhng9kWwvUZ8fiMJyrWbgdHIX0CDs= -github.com/metacubex/sing-wireguard v0.0.0-20240922131718-0f10c39a5531/go.mod h1:6nitcmzPDL3MXnLdhu6Hm126Zk4S1fBbX3P7jxUxSFw= +github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3 h1:xg71VmzLS6ByAzi/57phwDvjE+dLLs+ozH00k4DnOns= +github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3/go.mod h1:6nitcmzPDL3MXnLdhu6Hm126Zk4S1fBbX3P7jxUxSFw= github.com/metacubex/tfo-go v0.0.0-20240830120620-c5e019b67785 h1:NNmI+ZV0DzNuqaAInRQuZFLHlWVuyHeow8jYpdKjHjo= github.com/metacubex/tfo-go v0.0.0-20240830120620-c5e019b67785/go.mod h1:c7bVFM9f5+VzeZ/6Kg77T/jrg1Xp8QpqlSHvG/aXVts= github.com/metacubex/utls v1.6.6 h1:3D12YKHTf2Z41UPhQU2dWerNWJ5TVQD9gKoQ+H+iLC8= @@ -205,6 +205,10 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17 github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= @@ -219,8 +223,8 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= @@ -229,8 +233,8 @@ golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= @@ -250,12 +254,12 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= diff --git a/clash-meta-android/core/src/main/golang/go.mod b/clash-meta-android/core/src/main/golang/go.mod index 5279083743..e900bf5311 100644 --- a/clash-meta-android/core/src/main/golang/go.mod +++ b/clash-meta-android/core/src/main/golang/go.mod @@ -63,7 +63,7 @@ require ( github.com/metacubex/sing-shadowsocks2 v0.2.2 // indirect github.com/metacubex/sing-tun v0.2.7-0.20240729131039-ed03f557dee1 // indirect github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 // indirect - github.com/metacubex/sing-wireguard v0.0.0-20240922131718-0f10c39a5531 // indirect + github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3 // indirect github.com/metacubex/tfo-go v0.0.0-20240830120620-c5e019b67785 // indirect github.com/metacubex/utls v1.6.6 // indirect github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181 // indirect @@ -96,18 +96,20 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect github.com/vishvananda/netns v0.0.4 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect + github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 // indirect gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect go.uber.org/mock v0.4.0 // indirect go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect - golang.org/x/crypto v0.26.0 // indirect + golang.org/x/crypto v0.27.0 // indirect golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa // indirect golang.org/x/mod v0.20.0 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.24.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.24.0 // indirect google.golang.org/protobuf v1.34.2 // indirect diff --git a/clash-meta-android/core/src/main/golang/go.sum b/clash-meta-android/core/src/main/golang/go.sum index 7bd978137f..1fda649591 100644 --- a/clash-meta-android/core/src/main/golang/go.sum +++ b/clash-meta-android/core/src/main/golang/go.sum @@ -118,8 +118,8 @@ github.com/metacubex/sing-tun v0.2.7-0.20240729131039-ed03f557dee1 h1:ypfofGDZbP github.com/metacubex/sing-tun v0.2.7-0.20240729131039-ed03f557dee1/go.mod h1:olbEx9yVcaw5tHTNlRamRoxmMKcvDvcVS1YLnQGzvWE= github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 h1:OAXiCosqY8xKDp3pqTW3qbrCprZ1l6WkrXSFSCwyY4I= github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY= -github.com/metacubex/sing-wireguard v0.0.0-20240922131718-0f10c39a5531 h1:BoIL2fZZTPzvSxuhng9kWwvUZ8fiMJyrWbgdHIX0CDs= -github.com/metacubex/sing-wireguard v0.0.0-20240922131718-0f10c39a5531/go.mod h1:6nitcmzPDL3MXnLdhu6Hm126Zk4S1fBbX3P7jxUxSFw= +github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3 h1:xg71VmzLS6ByAzi/57phwDvjE+dLLs+ozH00k4DnOns= +github.com/metacubex/sing-wireguard v0.0.0-20240924052438-b0976fc59ea3/go.mod h1:6nitcmzPDL3MXnLdhu6Hm126Zk4S1fBbX3P7jxUxSFw= github.com/metacubex/tfo-go v0.0.0-20240830120620-c5e019b67785 h1:NNmI+ZV0DzNuqaAInRQuZFLHlWVuyHeow8jYpdKjHjo= github.com/metacubex/tfo-go v0.0.0-20240830120620-c5e019b67785/go.mod h1:c7bVFM9f5+VzeZ/6Kg77T/jrg1Xp8QpqlSHvG/aXVts= github.com/metacubex/utls v1.6.6 h1:3D12YKHTf2Z41UPhQU2dWerNWJ5TVQD9gKoQ+H+iLC8= @@ -205,6 +205,10 @@ github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17 github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= @@ -219,8 +223,8 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= @@ -229,8 +233,8 @@ golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= @@ -250,12 +254,12 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= diff --git a/clash-meta-android/core/src/main/golang/native/config/fetch.go b/clash-meta-android/core/src/main/golang/native/config/fetch.go index c1b25105c2..ba08ebccbd 100644 --- a/clash-meta-android/core/src/main/golang/native/config/fetch.go +++ b/clash-meta-android/core/src/main/golang/native/config/fetch.go @@ -112,7 +112,7 @@ func FetchAndValid( return err } - forEachProviders(rawCfg, func(index int, total int, name string, provider map[string]any) { + forEachProviders(rawCfg, func(index int, total int, name string, provider map[string]any, prefix string) { bytes, _ := json.Marshal(&Status{ Action: "FetchProviders", Args: []string{name}, diff --git a/clash-meta-android/core/src/main/golang/native/config/process.go b/clash-meta-android/core/src/main/golang/native/config/process.go index 09a4f8d18f..9c98696196 100644 --- a/clash-meta-android/core/src/main/golang/native/config/process.go +++ b/clash-meta-android/core/src/main/golang/native/config/process.go @@ -10,6 +10,7 @@ import ( "cfa/native/common" + "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/config" C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/log" @@ -109,10 +110,16 @@ func patchListeners(cfg *config.RawConfig, _ string) error { } func patchProviders(cfg *config.RawConfig, profileDir string) error { - forEachProviders(cfg, func(index int, total int, key string, provider map[string]any) { - if path, ok := provider["path"].(string); ok { - provider["path"] = profileDir + "/providers/" + common.ResolveAsRoot(path) + forEachProviders(cfg, func(index int, total int, key string, provider map[string]any, prefix string) { + path, _ := provider["path"].(string) + if len(path) > 0 { + path = common.ResolveAsRoot(path) + } else if url, ok := provider["url"].(string); ok { + path = prefix + "/" + utils.MakeHash([]byte(url)).String() // same as C.GetPathByHash + } else { + return // both path and url is empty, WTF??? } + provider["path"] = profileDir + "/providers/" + path }) return nil diff --git a/clash-meta-android/core/src/main/golang/native/config/provider.go b/clash-meta-android/core/src/main/golang/native/config/provider.go index 28506a5e6e..ebf4f34af5 100644 --- a/clash-meta-android/core/src/main/golang/native/config/provider.go +++ b/clash-meta-android/core/src/main/golang/native/config/provider.go @@ -6,18 +6,23 @@ import ( "github.com/metacubex/mihomo/config" ) -func forEachProviders(rawCfg *config.RawConfig, fun func(index int, total int, key string, provider map[string]any)) { +const ( + PROXIES = "proxies" + RULES = "rules" +) + +func forEachProviders(rawCfg *config.RawConfig, fun func(index int, total int, key string, provider map[string]any, prefix string)) { total := len(rawCfg.ProxyProvider) + len(rawCfg.RuleProvider) index := 0 for k, v := range rawCfg.ProxyProvider { - fun(index, total, k, v) + fun(index, total, k, v, PROXIES) index++ } for k, v := range rawCfg.RuleProvider { - fun(index, total, k, v) + fun(index, total, k, v, RULES) index++ } diff --git a/clash-meta-android/core/src/main/golang/native/tunnel/connectivity.go b/clash-meta-android/core/src/main/golang/native/tunnel/connectivity.go index 7a89edac0e..be716784ea 100644 --- a/clash-meta-android/core/src/main/golang/native/tunnel/connectivity.go +++ b/clash-meta-android/core/src/main/golang/native/tunnel/connectivity.go @@ -3,7 +3,6 @@ package tunnel import ( "sync" - "github.com/metacubex/mihomo/adapter" "github.com/metacubex/mihomo/adapter/outboundgroup" "github.com/metacubex/mihomo/constant/provider" "github.com/metacubex/mihomo/log" @@ -19,7 +18,7 @@ func HealthCheck(name string) { return } - g, ok := p.(*adapter.Proxy).ProxyAdapter.(outboundgroup.ProxyGroup) + g, ok := p.Adapter().(outboundgroup.ProxyGroup) if !ok { log.Warnln("Request health check for `%s`: invalid type %s", name, p.Type().String()) diff --git a/clash-meta-android/core/src/main/golang/native/tunnel/proxies.go b/clash-meta-android/core/src/main/golang/native/tunnel/proxies.go index 8a40218596..83ad15ecc0 100644 --- a/clash-meta-android/core/src/main/golang/native/tunnel/proxies.go +++ b/clash-meta-android/core/src/main/golang/native/tunnel/proxies.go @@ -6,8 +6,6 @@ import ( "github.com/dlclark/regexp2" - "github.com/metacubex/mihomo/adapter" - "github.com/metacubex/mihomo/adapter/outboundgroup" C "github.com/metacubex/mihomo/constant" "github.com/metacubex/mihomo/constant/provider" @@ -61,7 +59,7 @@ func QueryProxyGroupNames(excludeNotSelectable bool) []string { return []string{} } - global := tunnel.Proxies()["GLOBAL"].(*adapter.Proxy).ProxyAdapter.(outboundgroup.ProxyGroup) + global := tunnel.Proxies()["GLOBAL"].Adapter().(outboundgroup.ProxyGroup) proxies := global.Providers()[0].Proxies() result := make([]string, 0, len(proxies)+1) @@ -70,7 +68,7 @@ func QueryProxyGroupNames(excludeNotSelectable bool) []string { } for _, p := range proxies { - if _, ok := p.(*adapter.Proxy).ProxyAdapter.(outboundgroup.ProxyGroup); ok { + if _, ok := p.Adapter().(outboundgroup.ProxyGroup); ok { if !excludeNotSelectable || p.Type() == C.Selector { result = append(result, p.Name()) } @@ -89,7 +87,7 @@ func QueryProxyGroup(name string, sortMode SortMode, uiSubtitlePattern *regexp2. return nil } - g, ok := p.(*adapter.Proxy).ProxyAdapter.(outboundgroup.ProxyGroup) + g, ok := p.Adapter().(outboundgroup.ProxyGroup) if !ok { log.Warnln("Query group `%s`: invalid type %s", name, p.Type().String()) @@ -138,14 +136,14 @@ func PatchSelector(selector, name string) bool { return false } - g, ok := p.(*adapter.Proxy).ProxyAdapter.(outboundgroup.ProxyGroup) + g, ok := p.Adapter().(outboundgroup.ProxyGroup) if !ok { log.Warnln("Patch selector `%s`: invalid type %s", selector, p.Type().String()) return false } - s, ok := g.(*outboundgroup.Selector) + s, ok := g.(outboundgroup.SelectAble) if !ok { log.Warnln("Patch selector `%s`: invalid type %s", selector, p.Type().String()) @@ -172,7 +170,7 @@ func convertProxies(proxies []C.Proxy, uiSubtitlePattern *regexp2.Regexp) []*Pro subtitle := p.Type().String() if uiSubtitlePattern != nil { - if _, ok := p.(*adapter.Proxy).ProxyAdapter.(outboundgroup.ProxyGroup); !ok { + if _, ok := p.Adapter().(outboundgroup.ProxyGroup); !ok { runes := []rune(name) match, err := uiSubtitlePattern.FindRunesMatch(runes) if err == nil && match != nil { @@ -210,7 +208,7 @@ func collectProviders(providers []provider.ProxyProvider, uiSubtitlePattern *reg subtitle := px.Type().String() if uiSubtitlePattern != nil { - if _, ok := px.(*adapter.Proxy).ProxyAdapter.(outboundgroup.ProxyGroup); !ok { + if _, ok := px.Adapter().(outboundgroup.ProxyGroup); !ok { runes := []rune(name) match, err := uiSubtitlePattern.FindRunesMatch(runes) if err == nil && match != nil { diff --git a/clash-meta/adapter/adapter.go b/clash-meta/adapter/adapter.go index 8136827a09..3efc8166f0 100644 --- a/clash-meta/adapter/adapter.go +++ b/clash-meta/adapter/adapter.go @@ -39,6 +39,11 @@ type Proxy struct { extra *xsync.MapOf[string, *internalProxyState] } +// Adapter implements C.Proxy +func (p *Proxy) Adapter() C.ProxyAdapter { + return p.ProxyAdapter +} + // AliveForTestUrl implements C.Proxy func (p *Proxy) AliveForTestUrl(url string) bool { if state, ok := p.extra.Load(url); ok { diff --git a/clash-meta/adapter/inbound/listen_notwindows.go b/clash-meta/adapter/inbound/listen_notwindows.go new file mode 100644 index 0000000000..8fdfb7b8e6 --- /dev/null +++ b/clash-meta/adapter/inbound/listen_notwindows.go @@ -0,0 +1,14 @@ +//go:build !windows + +package inbound + +import ( + "net" + "os" +) + +const SupportNamedPipe = false + +func ListenNamedPipe(path string) (net.Listener, error) { + return nil, os.ErrInvalid +} diff --git a/clash-meta/adapter/inbound/listen_windows.go b/clash-meta/adapter/inbound/listen_windows.go new file mode 100644 index 0000000000..d19239da18 --- /dev/null +++ b/clash-meta/adapter/inbound/listen_windows.go @@ -0,0 +1,32 @@ +package inbound + +import ( + "net" + "os" + + "github.com/metacubex/wireguard-go/ipc/namedpipe" + "golang.org/x/sys/windows" +) + +const SupportNamedPipe = true + +// windowsSDDL is the Security Descriptor set on the namedpipe. +// It provides read/write access to all users and the local system. +const windowsSDDL = "D:PAI(A;OICI;GWGR;;;BU)(A;OICI;GWGR;;;SY)" + +func ListenNamedPipe(path string) (net.Listener, error) { + sddl := os.Getenv("LISTEN_NAMEDPIPE_SDDL") + if sddl == "" { + sddl = windowsSDDL + } + securityDescriptor, err := windows.SecurityDescriptorFromString(sddl) + if err != nil { + return nil, err + } + namedpipeLC := namedpipe.ListenConfig{ + SecurityDescriptor: securityDescriptor, + InputBufferSize: 256 * 1024, + OutputBufferSize: 256 * 1024, + } + return namedpipeLC.Listen(path) +} diff --git a/clash-meta/adapter/outbound/wireguard.go b/clash-meta/adapter/outbound/wireguard.go index 6f5a18f35d..3928ab1b7e 100644 --- a/clash-meta/adapter/outbound/wireguard.go +++ b/clash-meta/adapter/outbound/wireguard.go @@ -296,7 +296,7 @@ func NewWireGuard(option WireGuardOption) (*WireGuard, error) { for i := range nss { nss[i].ProxyAdapter = refP } - outbound.resolver = dns.NewResolver(dns.Config{ + outbound.resolver, _ = dns.NewResolver(dns.Config{ Main: nss, IPv6: has6, }) diff --git a/clash-meta/adapter/outboundgroup/util.go b/clash-meta/adapter/outboundgroup/util.go index 84216377b1..66b2510c19 100644 --- a/clash-meta/adapter/outboundgroup/util.go +++ b/clash-meta/adapter/outboundgroup/util.go @@ -4,3 +4,7 @@ type SelectAble interface { Set(string) error ForceSet(name string) } + +var _ SelectAble = (*Fallback)(nil) +var _ SelectAble = (*URLTest)(nil) +var _ SelectAble = (*Selector)(nil) diff --git a/clash-meta/component/auth/auth.go b/clash-meta/component/auth/auth.go index b52fa13557..176b21d793 100644 --- a/clash-meta/component/auth/auth.go +++ b/clash-meta/component/auth/auth.go @@ -5,6 +5,11 @@ type Authenticator interface { Users() []string } +type AuthStore interface { + Authenticator() Authenticator + SetAuthenticator(Authenticator) +} + type AuthUser struct { User string Pass string diff --git a/clash-meta/component/resolver/resolver.go b/clash-meta/component/resolver/resolver.go index feb3f98fb5..bcdbb7e2c4 100644 --- a/clash-meta/component/resolver/resolver.go +++ b/clash-meta/component/resolver/resolver.go @@ -47,6 +47,7 @@ type Resolver interface { ExchangeContext(ctx context.Context, m *dns.Msg) (msg *dns.Msg, err error) Invalid() bool ClearCache() + ResetConnection() } // LookupIPv4WithResolver same as LookupIPv4, but with a resolver @@ -256,6 +257,15 @@ func LookupIPProxyServerHost(ctx context.Context, host string) ([]netip.Addr, er return LookupIP(ctx, host) } +func ResetConnection() { + if DefaultResolver != nil { + go DefaultResolver.ResetConnection() + } + if ProxyServerHostResolver != nil { + go ProxyServerHostResolver.ResetConnection() + } +} + func SortationAddr(ips []netip.Addr) (ipv4s, ipv6s []netip.Addr) { for _, v := range ips { if v.Unmap().Is4() { diff --git a/clash-meta/config/config.go b/clash-meta/config/config.go index 27cde1fbd2..9067d14ff9 100644 --- a/clash-meta/config/config.go +++ b/clash-meta/config/config.go @@ -103,6 +103,7 @@ type Controller struct { ExternalController string ExternalControllerTLS string ExternalControllerUnix string + ExternalControllerPipe string ExternalUI string ExternalDohServer string Secret string @@ -364,6 +365,7 @@ type RawConfig struct { LogLevel log.LogLevel `yaml:"log-level" json:"log-level"` IPv6 bool `yaml:"ipv6" json:"ipv6"` ExternalController string `yaml:"external-controller" json:"external-controller"` + ExternalControllerPipe string `yaml:"external-controller-pipe" json:"external-controller-pipe"` ExternalControllerUnix string `yaml:"external-controller-unix" json:"external-controller-unix"` ExternalControllerTLS string `yaml:"external-controller-tls" json:"external-controller-tls"` ExternalUI string `yaml:"external-ui" json:"external-ui"` @@ -769,6 +771,7 @@ func parseController(cfg *RawConfig) (*Controller, error) { ExternalController: cfg.ExternalController, ExternalUI: cfg.ExternalUI, Secret: cfg.Secret, + ExternalControllerPipe: cfg.ExternalControllerPipe, ExternalControllerUnix: cfg.ExternalControllerUnix, ExternalControllerTLS: cfg.ExternalControllerTLS, ExternalDohServer: cfg.ExternalDohServer, diff --git a/clash-meta/constant/adapters.go b/clash-meta/constant/adapters.go index cb47f87166..b303eb846b 100644 --- a/clash-meta/constant/adapters.go +++ b/clash-meta/constant/adapters.go @@ -158,6 +158,7 @@ type DelayHistoryStoreType int type Proxy interface { ProxyAdapter + Adapter() ProxyAdapter AliveForTestUrl(url string) bool DelayHistory() []DelayHistory ExtraDelayHistories() map[string]ProxyState diff --git a/clash-meta/dns/client.go b/clash-meta/dns/client.go index 096b96a7f5..62fc12f9c3 100644 --- a/clash-meta/dns/client.go +++ b/clash-meta/dns/client.go @@ -103,3 +103,5 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error) return ret.msg, ret.err } } + +func (c *client) ResetConnection() {} diff --git a/clash-meta/dns/dhcp.go b/clash-meta/dns/dhcp.go index dc1344f500..e3829b7c2c 100644 --- a/clash-meta/dns/dhcp.go +++ b/clash-meta/dns/dhcp.go @@ -53,6 +53,12 @@ func (d *dhcpClient) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, return } +func (d *dhcpClient) ResetConnection() { + for _, client := range d.clients { + client.ResetConnection() + } +} + func (d *dhcpClient) resolve(ctx context.Context) ([]dnsClient, error) { d.lock.Lock() diff --git a/clash-meta/dns/doh.go b/clash-meta/dns/doh.go index ffb65fcef0..027afd58cc 100644 --- a/clash-meta/dns/doh.go +++ b/clash-meta/dns/doh.go @@ -203,11 +203,23 @@ func (doh *dnsOverHTTPS) Close() (err error) { return doh.closeClient(doh.client) } -// closeClient cleans up resources used by client if necessary. Note, that at -// this point it should only be done for HTTP/3 as it may leak due to keep-alive -// connections. +func (doh *dnsOverHTTPS) ResetConnection() { + doh.clientMu.Lock() + defer doh.clientMu.Unlock() + + if doh.client == nil { + return + } + + _ = doh.closeClient(doh.client) + doh.client = nil +} + +// closeClient cleans up resources used by client if necessary. func (doh *dnsOverHTTPS) closeClient(client *http.Client) (err error) { - if isHTTP3(client) { + client.CloseIdleConnections() + + if isHTTP3(client) { // HTTP/3 may leak due to keep-alive connections. return client.Transport.(io.Closer).Close() } @@ -508,6 +520,13 @@ func (h *http3Transport) Close() (err error) { return h.baseTransport.Close() } +func (h *http3Transport) CloseIdleConnections() { + h.mu.RLock() + defer h.mu.RUnlock() + + h.baseTransport.CloseIdleConnections() +} + // createTransportH3 tries to create an HTTP/3 transport for this upstream. // We should be able to fall back to H1/H2 in case if HTTP/3 is unavailable or // if it is too slow. In order to do that, this method will run two probes diff --git a/clash-meta/dns/doq.go b/clash-meta/dns/doq.go index ad936f9575..29fdd00660 100644 --- a/clash-meta/dns/doq.go +++ b/clash-meta/dns/doq.go @@ -144,6 +144,10 @@ func (doq *dnsOverQUIC) Close() (err error) { return err } +func (doq *dnsOverQUIC) ResetConnection() { + doq.closeConnWithError(nil) +} + // exchangeQUIC attempts to open a QUIC connection, send the DNS message // through it and return the response it got from the server. func (doq *dnsOverQUIC) exchangeQUIC(ctx context.Context, msg *D.Msg) (resp *D.Msg, err error) { diff --git a/clash-meta/dns/patch_android.go b/clash-meta/dns/patch_android.go index 6579ef071a..e3dcd2492f 100644 --- a/clash-meta/dns/patch_android.go +++ b/clash-meta/dns/patch_android.go @@ -12,6 +12,7 @@ func FlushCacheWithDefaultResolver() { if r := resolver.DefaultResolver; r != nil { r.ClearCache() } + resolver.ResetConnection() } func UpdateSystemDNS(addr []string) { @@ -30,3 +31,9 @@ func UpdateSystemDNS(addr []string) { func (c *systemClient) getDnsClients() ([]dnsClient, error) { return systemResolver, nil } + +func (c *systemClient) ResetConnection() { + for _, r := range systemResolver { + r.ResetConnection() + } +} diff --git a/clash-meta/dns/rcode.go b/clash-meta/dns/rcode.go index 9777d2e77b..901d1019d3 100644 --- a/clash-meta/dns/rcode.go +++ b/clash-meta/dns/rcode.go @@ -48,3 +48,5 @@ func (r rcodeClient) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, err func (r rcodeClient) Address() string { return r.addr } + +func (r rcodeClient) ResetConnection() {} diff --git a/clash-meta/dns/resolver.go b/clash-meta/dns/resolver.go index e03feef46f..ec59f42857 100644 --- a/clash-meta/dns/resolver.go +++ b/clash-meta/dns/resolver.go @@ -24,6 +24,7 @@ import ( type dnsClient interface { ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, err error) Address() string + ResetConnection() } type dnsCache interface { @@ -48,7 +49,7 @@ type Resolver struct { group singleflight.Group[*D.Msg] cache dnsCache policy []dnsPolicy - proxyServer []dnsClient + defaultResolver *Resolver } func (r *Resolver) LookupIPPrimaryIPv4(ctx context.Context, host string) (ips []netip.Addr, err error) { @@ -376,6 +377,20 @@ func (r *Resolver) ClearCache() { } } +func (r *Resolver) ResetConnection() { + if r != nil { + for _, c := range r.main { + c.ResetConnection() + } + for _, c := range r.fallback { + c.ResetConnection() + } + if dr := r.defaultResolver; dr != nil { + dr.ResetConnection() + } + } +} + type NameServer struct { Net string Addr string @@ -425,16 +440,18 @@ type Config struct { CacheAlgorithm string } -func NewResolver(config Config) *Resolver { - var cache dnsCache - if config.CacheAlgorithm == "lru" { - cache = lru.New(lru.WithSize[string, *D.Msg](4096), lru.WithStale[string, *D.Msg](true)) +func (config Config) newCache() dnsCache { + if config.CacheAlgorithm == "" || config.CacheAlgorithm == "lru" { + return lru.New(lru.WithSize[string, *D.Msg](4096), lru.WithStale[string, *D.Msg](true)) } else { - cache = arc.New(arc.WithSize[string, *D.Msg](4096)) + return arc.New(arc.WithSize[string, *D.Msg](4096)) } +} + +func NewResolver(config Config) (r *Resolver, pr *Resolver) { defaultResolver := &Resolver{ main: transform(config.Default, nil), - cache: cache, + cache: config.newCache(), ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond, } @@ -465,27 +482,29 @@ func NewResolver(config Config) *Resolver { return } - if config.CacheAlgorithm == "" || config.CacheAlgorithm == "lru" { - cache = lru.New(lru.WithSize[string, *D.Msg](4096), lru.WithStale[string, *D.Msg](true)) - } else { - cache = arc.New(arc.WithSize[string, *D.Msg](4096)) - } - r := &Resolver{ + r = &Resolver{ ipv6: config.IPv6, main: cacheTransform(config.Main), - cache: cache, + cache: config.newCache(), hosts: config.Hosts, ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond, } + r.defaultResolver = defaultResolver + + if len(config.ProxyServer) != 0 { + pr = &Resolver{ + ipv6: config.IPv6, + main: cacheTransform(config.ProxyServer), + cache: config.newCache(), + hosts: config.Hosts, + ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond, + } + } if len(config.Fallback) != 0 { r.fallback = cacheTransform(config.Fallback) } - if len(config.ProxyServer) != 0 { - r.proxyServer = cacheTransform(config.ProxyServer) - } - if len(config.Policy) != 0 { r.policy = make([]dnsPolicy, 0) @@ -516,18 +535,7 @@ func NewResolver(config Config) *Resolver { r.fallbackIPFilters = config.FallbackIPFilter r.fallbackDomainFilters = config.FallbackDomainFilter - return r -} - -func NewProxyServerHostResolver(old *Resolver) *Resolver { - r := &Resolver{ - ipv6: old.ipv6, - main: old.proxyServer, - cache: old.cache, - hosts: old.hosts, - ipv6Timeout: old.ipv6Timeout, - } - return r + return } var ParseNameServer func(servers []string) ([]NameServer, error) // define in config/config.go diff --git a/clash-meta/dns/system_common.go b/clash-meta/dns/system_common.go index 06dc0b3020..e6dabdcfff 100644 --- a/clash-meta/dns/system_common.go +++ b/clash-meta/dns/system_common.go @@ -69,3 +69,5 @@ func (c *systemClient) getDnsClients() ([]dnsClient, error) { } return nil, err } + +func (c *systemClient) ResetConnection() {} diff --git a/clash-meta/docs/config.yaml b/clash-meta/docs/config.yaml index b3515a2060..9c480b3f2a 100644 --- a/clash-meta/docs/config.yaml +++ b/clash-meta/docs/config.yaml @@ -63,6 +63,10 @@ external-controller-tls: 0.0.0.0:9443 # RESTful API HTTPS 监听地址,需要 # 测试方法: curl -v --unix-socket "mihomo.sock" http://localhost/ external-controller-unix: mihomo.sock +# RESTful API Windows namedpipe 监听地址 +# !!!注意: 从Windows namedpipe访问api接口不会验证secret, 如果开启请自行保证安全问题 !!! +external-controller-pipe: \\.\pipe\mihomo + # tcp-concurrent: true # TCP 并发连接所有 IP, 将使用最快握手的 TCP # 配置 WEB UI 目录,使用 http://{{external-controller}}/ui 访问 diff --git a/clash-meta/go.mod b/clash-meta/go.mod index 22af95b3b8..b74cee92e1 100644 --- a/clash-meta/go.mod +++ b/clash-meta/go.mod @@ -49,12 +49,12 @@ require ( github.com/vmihailenco/msgpack/v5 v5.4.1 github.com/wk8/go-ordered-map/v2 v2.1.8 gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 - go.uber.org/automaxprocs v1.5.3 + go.uber.org/automaxprocs v1.6.0 go4.org/netipx v0.0.0-20231129151722-fdeea329fbba - golang.org/x/crypto v0.26.0 + golang.org/x/crypto v0.27.0 golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa - golang.org/x/net v0.28.0 - golang.org/x/sys v0.24.0 + golang.org/x/net v0.29.0 + golang.org/x/sys v0.25.0 google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 lukechampine.com/blake3 v1.3.0 @@ -111,7 +111,7 @@ require ( go.uber.org/mock v0.4.0 // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.24.0 // indirect ) diff --git a/clash-meta/go.sum b/clash-meta/go.sum index 9b824fc561..ba2d181951 100644 --- a/clash-meta/go.sum +++ b/clash-meta/go.sum @@ -222,16 +222,16 @@ gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 h1:UNrDfkQqiE gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7/go.mod h1:E+rxHvJG9H6PUdzq9NRG6csuLN3XUx98BfGOVWNYnXs= gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec h1:FpfFs4EhNehiVfzQttTuxanPIT43FtkkCFypIod8LHo= gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec/go.mod h1:BZ1RAoRPbCxum9Grlv5aeksu2H8BiKehBYooU2LFiOQ= -go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= -go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= @@ -240,8 +240,8 @@ golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= @@ -261,12 +261,12 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= diff --git a/clash-meta/hub/executor/executor.go b/clash-meta/hub/executor/executor.go index 66bbc89ba4..214407b477 100644 --- a/clash-meta/hub/executor/executor.go +++ b/clash-meta/hub/executor/executor.go @@ -118,6 +118,8 @@ func ApplyConfig(cfg *config.Config, force bool) { tunnel.OnRunning() hcCompatibleProvider(cfg.Providers) initExternalUI() + + resolver.ResetConnection() } func initInnerTcp() { @@ -127,7 +129,7 @@ func initInnerTcp() { func GetGeneral() *config.General { ports := listener.GetPorts() var authenticator []string - if auth := authStore.Authenticator(); auth != nil { + if auth := authStore.Default.Authenticator(); auth != nil { authenticator = auth.Users() } @@ -253,8 +255,7 @@ func updateDNS(c *config.DNS, generalIPv6 bool) { CacheAlgorithm: c.CacheAlgorithm, } - r := dns.NewResolver(cfg) - pr := dns.NewProxyServerHostResolver(r) + r, pr := dns.NewResolver(cfg) m := dns.NewEnhancer(cfg) // reuse cache of old host mapper @@ -422,7 +423,7 @@ func updateGeneral(general *config.General) { func updateUsers(users []auth.AuthUser) { authenticator := auth.NewAuthenticator(users) - authStore.SetAuthenticator(authenticator) + authStore.Default.SetAuthenticator(authenticator) if authenticator != nil { log.Infoln("Authentication of local server updated") } @@ -444,12 +445,12 @@ func patchSelectGroup(proxies map[string]C.Proxy) { } for name, proxy := range proxies { - outbound, ok := proxy.(*adapter.Proxy) + outbound, ok := proxy.(C.Proxy) if !ok { continue } - selector, ok := outbound.ProxyAdapter.(outboundgroup.SelectAble) + selector, ok := outbound.Adapter().(outboundgroup.SelectAble) if !ok { continue } diff --git a/clash-meta/hub/hub.go b/clash-meta/hub/hub.go index e22f721970..73a44eee66 100644 --- a/clash-meta/hub/hub.go +++ b/clash-meta/hub/hub.go @@ -27,6 +27,12 @@ func WithExternalControllerUnix(externalControllerUnix string) Option { } } +func WithExternalControllerPipe(externalControllerPipe string) Option { + return func(cfg *config.Config) { + cfg.Controller.ExternalControllerPipe = externalControllerPipe + } +} + func WithSecret(secret string) Option { return func(cfg *config.Config) { cfg.Controller.Secret = secret @@ -47,6 +53,7 @@ func applyRoute(cfg *config.Config) { Addr: cfg.Controller.ExternalController, TLSAddr: cfg.Controller.ExternalControllerTLS, UnixAddr: cfg.Controller.ExternalControllerUnix, + PipeAddr: cfg.Controller.ExternalControllerPipe, Secret: cfg.Controller.Secret, Certificate: cfg.TLS.Certificate, PrivateKey: cfg.TLS.PrivateKey, diff --git a/clash-meta/hub/route/groups.go b/clash-meta/hub/route/groups.go index c4e9501f2d..68d1f3542b 100644 --- a/clash-meta/hub/route/groups.go +++ b/clash-meta/hub/route/groups.go @@ -9,7 +9,6 @@ import ( "github.com/go-chi/chi/v5" "github.com/go-chi/render" - "github.com/metacubex/mihomo/adapter" "github.com/metacubex/mihomo/adapter/outboundgroup" "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/component/profile/cachefile" @@ -32,7 +31,7 @@ func GroupRouter() http.Handler { func getGroups(w http.ResponseWriter, r *http.Request) { var gs []C.Proxy for _, p := range tunnel.Proxies() { - if _, ok := p.(*adapter.Proxy).ProxyAdapter.(C.Group); ok { + if _, ok := p.Adapter().(C.Group); ok { gs = append(gs, p) } } @@ -43,7 +42,7 @@ func getGroups(w http.ResponseWriter, r *http.Request) { func getGroup(w http.ResponseWriter, r *http.Request) { proxy := r.Context().Value(CtxKeyProxy).(C.Proxy) - if _, ok := proxy.(*adapter.Proxy).ProxyAdapter.(C.Group); ok { + if _, ok := proxy.Adapter().(C.Group); ok { render.JSON(w, r, proxy) return } @@ -53,25 +52,15 @@ func getGroup(w http.ResponseWriter, r *http.Request) { func getGroupDelay(w http.ResponseWriter, r *http.Request) { proxy := r.Context().Value(CtxKeyProxy).(C.Proxy) - group, ok := proxy.(*adapter.Proxy).ProxyAdapter.(C.Group) + group, ok := proxy.Adapter().(C.Group) if !ok { render.Status(r, http.StatusNotFound) render.JSON(w, r, ErrNotFound) return } - switch proxy.(*adapter.Proxy).Type() { - case C.URLTest: - if urlTestGroup, ok := proxy.(*adapter.Proxy).ProxyAdapter.(*outboundgroup.URLTest); ok { - urlTestGroup.ForceSet("") - } - case C.Fallback: - if fallbackGroup, ok := proxy.(*adapter.Proxy).ProxyAdapter.(*outboundgroup.Fallback); ok { - fallbackGroup.ForceSet("") - } - } - - if proxy.(*adapter.Proxy).Type() != C.Selector { + if selectAble, ok := proxy.Adapter().(outboundgroup.SelectAble); ok && proxy.Type() != C.Selector { + selectAble.ForceSet("") cachefile.Cache().SetSelected(proxy.Name(), "") } diff --git a/clash-meta/hub/route/proxies.go b/clash-meta/hub/route/proxies.go index 69c8e44651..ba4e03f902 100644 --- a/clash-meta/hub/route/proxies.go +++ b/clash-meta/hub/route/proxies.go @@ -7,7 +7,6 @@ import ( "strconv" "time" - "github.com/metacubex/mihomo/adapter" "github.com/metacubex/mihomo/adapter/outboundgroup" "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/component/profile/cachefile" @@ -31,6 +30,7 @@ func proxyRouter() http.Handler { r.Get("/", getProxy) r.Get("/delay", getProxyDelay) r.Put("/", updateProxy) + r.Delete("/", unfixedProxy) }) return r } @@ -81,8 +81,8 @@ func updateProxy(w http.ResponseWriter, r *http.Request) { return } - proxy := r.Context().Value(CtxKeyProxy).(*adapter.Proxy) - selector, ok := proxy.ProxyAdapter.(outboundgroup.SelectAble) + proxy := r.Context().Value(CtxKeyProxy).(C.Proxy) + selector, ok := proxy.Adapter().(outboundgroup.SelectAble) if !ok { render.Status(r, http.StatusBadRequest) render.JSON(w, r, newError("Must be a Selector")) @@ -146,3 +146,15 @@ func getProxyDelay(w http.ResponseWriter, r *http.Request) { "delay": delay, }) } + +func unfixedProxy(w http.ResponseWriter, r *http.Request) { + proxy := r.Context().Value(CtxKeyProxy).(C.Proxy) + if selectAble, ok := proxy.Adapter().(outboundgroup.SelectAble); ok && proxy.Type() != C.Selector { + selectAble.ForceSet("") + cachefile.Cache().SetSelected(proxy.Name(), "") + render.NoContent(w, r) + return + } + render.Status(r, http.StatusBadRequest) + render.JSON(w, r, ErrBadRequest) +} diff --git a/clash-meta/hub/route/server.go b/clash-meta/hub/route/server.go index b707756321..1810a707cf 100644 --- a/clash-meta/hub/route/server.go +++ b/clash-meta/hub/route/server.go @@ -35,6 +35,7 @@ var ( httpServer *http.Server tlsServer *http.Server unixServer *http.Server + pipeServer *http.Server ) type Traffic struct { @@ -51,6 +52,7 @@ type Config struct { Addr string TLSAddr string UnixAddr string + PipeAddr string Secret string Certificate string PrivateKey string @@ -62,6 +64,9 @@ func ReCreateServer(cfg *Config) { go start(cfg) go startTLS(cfg) go startUnix(cfg) + if inbound.SupportNamedPipe { + go startPipe(cfg) + } } func SetUIPath(path string) { @@ -223,6 +228,7 @@ func startUnix(cfg *Config) { log.Errorln("External controller unix listen error: %s", err) return } + _ = os.Chmod(addr, 0o666) log.Infoln("RESTful API unix listening at: %s", l.Addr().String()) server := &http.Server{ @@ -233,7 +239,37 @@ func startUnix(cfg *Config) { log.Errorln("External controller unix serve error: %s", err) } } +} +func startPipe(cfg *Config) { + // first stop existing server + if pipeServer != nil { + _ = pipeServer.Close() + pipeServer = nil + } + + // handle addr + if len(cfg.PipeAddr) > 0 { + if !strings.HasPrefix(cfg.PipeAddr, "\\\\.\\pipe\\") { // windows namedpipe must start with "\\.\pipe\" + log.Errorln("External controller pipe listen error: windows namedpipe must start with \"\\\\.\\pipe\\\"") + return + } + + l, err := inbound.ListenNamedPipe(cfg.PipeAddr) + if err != nil { + log.Errorln("External controller pipe listen error: %s", err) + return + } + log.Infoln("RESTful API pipe listening at: %s", l.Addr().String()) + + server := &http.Server{ + Handler: router(cfg.IsDebug, "", cfg.DohServer), + } + pipeServer = server + if err = server.Serve(l); err != nil { + log.Errorln("External controller pipe serve error: %s", err) + } + } } func setPrivateNetworkAccess(next http.Handler) http.Handler { diff --git a/clash-meta/listener/auth/auth.go b/clash-meta/listener/auth/auth.go index 772be3bdd7..9e7632e868 100644 --- a/clash-meta/listener/auth/auth.go +++ b/clash-meta/listener/auth/auth.go @@ -4,14 +4,30 @@ import ( "github.com/metacubex/mihomo/component/auth" ) -var authenticator auth.Authenticator - -func Authenticator() auth.Authenticator { - return authenticator +type authStore struct { + authenticator auth.Authenticator } -func SetAuthenticator(au auth.Authenticator) { - authenticator = au +func (a *authStore) Authenticator() auth.Authenticator { + return a.authenticator } -func Nil() auth.Authenticator { return nil } +func (a *authStore) SetAuthenticator(authenticator auth.Authenticator) { + a.authenticator = authenticator +} + +func NewAuthStore(authenticator auth.Authenticator) auth.AuthStore { + return &authStore{authenticator} +} + +var Default auth.AuthStore = NewAuthStore(nil) + +type nilAuthStore struct{} + +func (a *nilAuthStore) Authenticator() auth.Authenticator { + return nil +} + +func (a *nilAuthStore) SetAuthenticator(authenticator auth.Authenticator) {} + +var Nil auth.AuthStore = (*nilAuthStore)(nil) // always return nil, even call SetAuthenticator() with a non-nil authenticator diff --git a/clash-meta/listener/http/proxy.go b/clash-meta/listener/http/proxy.go index 04ab98eb8c..5c08cd458a 100644 --- a/clash-meta/listener/http/proxy.go +++ b/clash-meta/listener/http/proxy.go @@ -30,7 +30,7 @@ func (b *bodyWrapper) Read(p []byte) (n int, err error) { return n, err } -func HandleConn(c net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) { +func HandleConn(c net.Conn, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) { additions = append(additions, inbound.Placeholder) // Add a placeholder for InUser inUserIdx := len(additions) - 1 client := newClient(c, tunnel, additions) @@ -41,7 +41,7 @@ func HandleConn(c net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, conn := N.NewBufferedConn(c) - authenticator := getAuth() + authenticator := store.Authenticator() keepAlive := true trusted := authenticator == nil // disable authenticate if lru is nil lastUser := "" diff --git a/clash-meta/listener/http/server.go b/clash-meta/listener/http/server.go index 04f32f4ff5..24f07e8bd1 100644 --- a/clash-meta/listener/http/server.go +++ b/clash-meta/listener/http/server.go @@ -32,20 +32,20 @@ func (l *Listener) Close() error { } func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) { - return NewWithAuthenticator(addr, tunnel, authStore.Authenticator, additions...) + return NewWithAuthenticator(addr, tunnel, authStore.Default, additions...) } // NewWithAuthenticate // never change type traits because it's used in CMFA func NewWithAuthenticate(addr string, tunnel C.Tunnel, authenticate bool, additions ...inbound.Addition) (*Listener, error) { - getAuth := authStore.Authenticator + store := authStore.Default if !authenticate { - getAuth = authStore.Nil + store = authStore.Default } - return NewWithAuthenticator(addr, tunnel, getAuth, additions...) + return NewWithAuthenticator(addr, tunnel, store, additions...) } -func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) (*Listener, error) { +func NewWithAuthenticator(addr string, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) (*Listener, error) { isDefault := false if len(additions) == 0 { isDefault = true @@ -74,17 +74,17 @@ func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Auth continue } - getAuth := getAuth - if isDefault { // only apply on default listener + store := store + if isDefault || store == authStore.Default { // only apply on default listener if !inbound.IsRemoteAddrDisAllowed(conn.RemoteAddr()) { _ = conn.Close() continue } if inbound.SkipAuthRemoteAddr(conn.RemoteAddr()) { - getAuth = authStore.Nil + store = authStore.Nil } } - go HandleConn(conn, tunnel, getAuth, additions...) + go HandleConn(conn, tunnel, store, additions...) } }() diff --git a/clash-meta/listener/inbound/auth.go b/clash-meta/listener/inbound/auth.go index 41f18fc089..85e7249455 100644 --- a/clash-meta/listener/inbound/auth.go +++ b/clash-meta/listener/inbound/auth.go @@ -12,7 +12,7 @@ type AuthUser struct { type AuthUsers []AuthUser -func (a AuthUsers) GetAuth() func() auth.Authenticator { +func (a AuthUsers) GetAuthStore() auth.AuthStore { if a != nil { // structure's Decode will ensure value not nil when input has value even it was set an empty array if len(a) == 0 { return authStore.Nil @@ -25,7 +25,7 @@ func (a AuthUsers) GetAuth() func() auth.Authenticator { } } authenticator := auth.NewAuthenticator(users) - return func() auth.Authenticator { return authenticator } + return authStore.NewAuthStore(authenticator) } - return authStore.Authenticator + return authStore.Default } diff --git a/clash-meta/listener/inbound/http.go b/clash-meta/listener/inbound/http.go index c78abefd5f..e20a9a2357 100644 --- a/clash-meta/listener/inbound/http.go +++ b/clash-meta/listener/inbound/http.go @@ -45,7 +45,7 @@ func (h *HTTP) Address() string { // Listen implements constant.InboundListener func (h *HTTP) Listen(tunnel C.Tunnel) error { var err error - h.l, err = http.NewWithAuthenticator(h.RawAddress(), tunnel, h.config.Users.GetAuth(), h.Additions()...) + h.l, err = http.NewWithAuthenticator(h.RawAddress(), tunnel, h.config.Users.GetAuthStore(), h.Additions()...) if err != nil { return err } diff --git a/clash-meta/listener/inbound/mixed.go b/clash-meta/listener/inbound/mixed.go index 443a256452..1d79929acc 100644 --- a/clash-meta/listener/inbound/mixed.go +++ b/clash-meta/listener/inbound/mixed.go @@ -53,7 +53,7 @@ func (m *Mixed) Address() string { // Listen implements constant.InboundListener func (m *Mixed) Listen(tunnel C.Tunnel) error { var err error - m.l, err = mixed.NewWithAuthenticator(m.RawAddress(), tunnel, m.config.Users.GetAuth(), m.Additions()...) + m.l, err = mixed.NewWithAuthenticator(m.RawAddress(), tunnel, m.config.Users.GetAuthStore(), m.Additions()...) if err != nil { return err } diff --git a/clash-meta/listener/inbound/socks.go b/clash-meta/listener/inbound/socks.go index cf6d1ce433..119eec8281 100644 --- a/clash-meta/listener/inbound/socks.go +++ b/clash-meta/listener/inbound/socks.go @@ -71,7 +71,7 @@ func (s *Socks) Address() string { // Listen implements constant.InboundListener func (s *Socks) Listen(tunnel C.Tunnel) error { var err error - if s.stl, err = socks.NewWithAuthenticator(s.RawAddress(), tunnel, s.config.Users.GetAuth(), s.Additions()...); err != nil { + if s.stl, err = socks.NewWithAuthenticator(s.RawAddress(), tunnel, s.config.Users.GetAuthStore(), s.Additions()...); err != nil { return err } if s.udp { diff --git a/clash-meta/listener/mixed/mixed.go b/clash-meta/listener/mixed/mixed.go index ac3a0c5886..5ac6301153 100644 --- a/clash-meta/listener/mixed/mixed.go +++ b/clash-meta/listener/mixed/mixed.go @@ -37,10 +37,10 @@ func (l *Listener) Close() error { } func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) { - return NewWithAuthenticator(addr, tunnel, authStore.Authenticator, additions...) + return NewWithAuthenticator(addr, tunnel, authStore.Default, additions...) } -func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) (*Listener, error) { +func NewWithAuthenticator(addr string, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) (*Listener, error) { isDefault := false if len(additions) == 0 { isDefault = true @@ -68,24 +68,24 @@ func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Auth } continue } - getAuth := getAuth - if isDefault { // only apply on default listener + store := store + if isDefault || store == authStore.Default { // only apply on default listener if !inbound.IsRemoteAddrDisAllowed(c.RemoteAddr()) { _ = c.Close() continue } if inbound.SkipAuthRemoteAddr(c.RemoteAddr()) { - getAuth = authStore.Nil + store = authStore.Nil } } - go handleConn(c, tunnel, getAuth, additions...) + go handleConn(c, tunnel, store, additions...) } }() return ml, nil } -func handleConn(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) { +func handleConn(conn net.Conn, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) { bufConn := N.NewBufferedConn(conn) head, err := bufConn.Peek(1) if err != nil { @@ -94,10 +94,10 @@ func handleConn(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticato switch head[0] { case socks4.Version: - socks.HandleSocks4(bufConn, tunnel, getAuth, additions...) + socks.HandleSocks4(bufConn, tunnel, store, additions...) case socks5.Version: - socks.HandleSocks5(bufConn, tunnel, getAuth, additions...) + socks.HandleSocks5(bufConn, tunnel, store, additions...) default: - http.HandleConn(bufConn, tunnel, getAuth, additions...) + http.HandleConn(bufConn, tunnel, store, additions...) } } diff --git a/clash-meta/listener/sing_tun/server.go b/clash-meta/listener/sing_tun/server.go index c2c668b34e..79856c466c 100644 --- a/clash-meta/listener/sing_tun/server.go +++ b/clash-meta/listener/sing_tun/server.go @@ -440,6 +440,10 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis //l.openAndroidHotspot(tunOptions) + if !l.options.AutoDetectInterface { + resolver.ResetConnection() + } + if options.FileDescriptor != 0 { tunName = fmt.Sprintf("%s(fd=%d)", tunName, options.FileDescriptor) } @@ -507,6 +511,7 @@ func (l *Listener) FlushDefaultInterface() { if old := dialer.DefaultInterface.Swap(autoDetectInterfaceName); old != autoDetectInterfaceName { log.Warnln("[TUN] default interface changed by monitor, %s => %s", old, autoDetectInterfaceName) iface.FlushCache() + resolver.ResetConnection() // reset resolver's connection after default interface changed } return } diff --git a/clash-meta/listener/socks/tcp.go b/clash-meta/listener/socks/tcp.go index 950384c1f9..cc66613e2a 100644 --- a/clash-meta/listener/socks/tcp.go +++ b/clash-meta/listener/socks/tcp.go @@ -36,10 +36,10 @@ func (l *Listener) Close() error { } func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) { - return NewWithAuthenticator(addr, tunnel, authStore.Authenticator, additions...) + return NewWithAuthenticator(addr, tunnel, authStore.Default, additions...) } -func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) (*Listener, error) { +func NewWithAuthenticator(addr string, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) (*Listener, error) { isDefault := false if len(additions) == 0 { isDefault = true @@ -67,24 +67,24 @@ func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Auth } continue } - getAuth := getAuth - if isDefault { // only apply on default listener + store := store + if isDefault || store == authStore.Default { // only apply on default listener if !inbound.IsRemoteAddrDisAllowed(c.RemoteAddr()) { _ = c.Close() continue } if inbound.SkipAuthRemoteAddr(c.RemoteAddr()) { - getAuth = authStore.Nil + store = authStore.Nil } } - go handleSocks(c, tunnel, getAuth, additions...) + go handleSocks(c, tunnel, store, additions...) } }() return sl, nil } -func handleSocks(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) { +func handleSocks(conn net.Conn, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) { bufConn := N.NewBufferedConn(conn) head, err := bufConn.Peek(1) if err != nil { @@ -94,16 +94,16 @@ func handleSocks(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticat switch head[0] { case socks4.Version: - HandleSocks4(bufConn, tunnel, getAuth, additions...) + HandleSocks4(bufConn, tunnel, store, additions...) case socks5.Version: - HandleSocks5(bufConn, tunnel, getAuth, additions...) + HandleSocks5(bufConn, tunnel, store, additions...) default: conn.Close() } } -func HandleSocks4(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) { - authenticator := getAuth() +func HandleSocks4(conn net.Conn, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) { + authenticator := store.Authenticator() addr, _, user, err := socks4.ServerHandshake(conn, authenticator) if err != nil { conn.Close() @@ -113,8 +113,8 @@ func HandleSocks4(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authentica tunnel.HandleTCPConn(inbound.NewSocket(socks5.ParseAddr(addr), conn, C.SOCKS4, additions...)) } -func HandleSocks5(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) { - authenticator := getAuth() +func HandleSocks5(conn net.Conn, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) { + authenticator := store.Authenticator() target, command, user, err := socks5.ServerHandshake(conn, authenticator) if err != nil { conn.Close() diff --git a/clash-meta/main.go b/clash-meta/main.go index 8910a00653..505cdb2566 100644 --- a/clash-meta/main.go +++ b/clash-meta/main.go @@ -35,6 +35,7 @@ var ( externalUI string externalController string externalControllerUnix string + externalControllerPipe string secret string ) @@ -45,6 +46,7 @@ func init() { flag.StringVar(&externalUI, "ext-ui", os.Getenv("CLASH_OVERRIDE_EXTERNAL_UI_DIR"), "override external ui directory") flag.StringVar(&externalController, "ext-ctl", os.Getenv("CLASH_OVERRIDE_EXTERNAL_CONTROLLER"), "override external controller address") flag.StringVar(&externalControllerUnix, "ext-ctl-unix", os.Getenv("CLASH_OVERRIDE_EXTERNAL_CONTROLLER_UNIX"), "override external controller unix address") + flag.StringVar(&externalControllerPipe, "ext-ctl-pipe", os.Getenv("CLASH_OVERRIDE_EXTERNAL_CONTROLLER_PIPE"), "override external controller pipe address") flag.StringVar(&secret, "secret", os.Getenv("CLASH_OVERRIDE_SECRET"), "override secret for RESTful API") flag.BoolVar(&geodataMode, "m", false, "set geodata mode") flag.BoolVar(&version, "v", false, "show current version of mihomo") @@ -133,6 +135,9 @@ func main() { if externalControllerUnix != "" { options = append(options, hub.WithExternalControllerUnix(externalControllerUnix)) } + if externalControllerPipe != "" { + options = append(options, hub.WithExternalControllerPipe(externalControllerPipe)) + } if secret != "" { options = append(options, hub.WithSecret(secret)) } @@ -156,19 +161,9 @@ func main() { case <-termSign: return case <-hupSign: - var cfg *config.Config - var err error - if configString != "" { - cfg, err = executor.ParseWithBytes(configBytes) - } else { - cfg, err = executor.ParseWithPath(C.Path.Config()) - } - if err == nil { - hub.ApplyConfig(cfg) - } else { + if err := hub.Parse(configBytes, options...); err != nil { log.Errorln("Parse config error: %s", err.Error()) } - } } } diff --git a/clash-nyanpasu/backend/Cargo.lock b/clash-nyanpasu/backend/Cargo.lock index ed0dfc32d2..153bb7e827 100644 --- a/clash-nyanpasu/backend/Cargo.lock +++ b/clash-nyanpasu/backend/Cargo.lock @@ -2440,9 +2440,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.33" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ "crc32fast", "miniz_oxide 0.8.0", @@ -3999,7 +3999,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.52.6", + "windows-targets 0.48.5", ] [[package]] @@ -5051,9 +5051,9 @@ checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" [[package]] name = "oxc_allocator" -version = "0.30.1" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb29dfe8933200c2ed2aff14a11889f95fdf2506dd87a3d0dd58f73cbe93abcc" +checksum = "5856e86222d0929c0541c4ef77f57817a72cec373698ed159b40ee6ecceaec48" dependencies = [ "allocator-api2", "bumpalo", @@ -5061,9 +5061,9 @@ dependencies = [ [[package]] name = "oxc_ast" -version = "0.30.1" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e29c42d4b6b16eac9f2ae2ab0031a080cbf24d217df8b65cefe5852785a0e5a" +checksum = "42fc7521939bdb481ea018325fdee67d33f068c95d0a1d905983fadbef4d1139" dependencies = [ "bitflags 2.6.0", "num-bigint", @@ -5076,9 +5076,9 @@ dependencies = [ [[package]] name = "oxc_ast_macros" -version = "0.30.1" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91b198610e90b69db5779517e8a01745229a8eebf6bfae08601d3ca4a5fbcb3" +checksum = "3fdd270f2adce786b7ace8ece582b8472e219272361caee5f1f5444e01b943ec" dependencies = [ "proc-macro2", "quote", @@ -5087,9 +5087,9 @@ dependencies = [ [[package]] name = "oxc_diagnostics" -version = "0.30.1" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4accda097d689b524b5ded9179c752e9836f13316a84058aa616f8e5b06640c" +checksum = "65ddc84c1721fc53330229a91e7df618580f612da883de23b54eba750d400cf0" dependencies = [ "miette", "owo-colors", @@ -5100,15 +5100,15 @@ dependencies = [ [[package]] name = "oxc_index" -version = "0.30.1" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597589a2b06ac33cd4cee0a47878c2a4a3923f5f27955c02ee657ebaa32df6f5" +checksum = "6162fbc11517843670a55c3d6474adbf1ff3d9a83f05fd5c6ec3695ccecdaf2d" [[package]] name = "oxc_parser" -version = "0.30.1" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c9fe0fc2d3ecf99b5d8f5b8dc874cc0e52402a842de8d6480a151ab056cfa49" +checksum = "7ddb413496714a71112b74469805e55af9f10963fe2bbd94f27a37d336b10f62" dependencies = [ "assert-unchecked", "bitflags 2.6.0", @@ -5128,9 +5128,9 @@ dependencies = [ [[package]] name = "oxc_regular_expression" -version = "0.30.1" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff953ea7603a0d27b08e8c90d57e4f261f7412cc37afa1ed7b7f16315d1c055" +checksum = "f0da2dc761af764bc3a35d81613d56fb16655b93385b45144ffb992a72999fb8" dependencies = [ "oxc_allocator", "oxc_ast_macros", @@ -5143,9 +5143,9 @@ dependencies = [ [[package]] name = "oxc_span" -version = "0.30.1" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36de6b8a1e2e97bc9954ab46f795899c57096eb0a2d76f590345ff9507c44ed8" +checksum = "c3dcf991a98a69c0f1de9b8d674faa1635ae7a66b01f1225daddb3205ea7d619" dependencies = [ "compact_str", "miette", @@ -5155,9 +5155,9 @@ dependencies = [ [[package]] name = "oxc_syntax" -version = "0.30.1" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758bd2aa4be0704702cb7641070bdb3a6194f01dc3bc6f482c74515850a61415" +checksum = "7ca95787731fa6c09ffc2fbdbb6d1cded482cf6bcfb9c79e85777e30e03f212f" dependencies = [ "assert-unchecked", "bitflags 2.6.0", diff --git a/clash-nyanpasu/frontend/nyanpasu/package.json b/clash-nyanpasu/frontend/nyanpasu/package.json index cf70ddcd45..58b2a2d0d9 100644 --- a/clash-nyanpasu/frontend/nyanpasu/package.json +++ b/clash-nyanpasu/frontend/nyanpasu/package.json @@ -21,7 +21,7 @@ "@mui/material": "6.1.1", "@nyanpasu/interface": "workspace:^", "@nyanpasu/ui": "workspace:^", - "@tanstack/router-zod-adapter": "1.58.9", + "@tanstack/router-zod-adapter": "1.58.11", "@tauri-apps/api": "2.0.0-rc.5", "@types/json-schema": "7.0.15", "ahooks": "3.8.1", @@ -55,8 +55,8 @@ "@emotion/react": "11.13.3", "@iconify/json": "2.2.253", "@monaco-editor/react": "4.6.0", - "@tanstack/react-router": "1.58.9", - "@tanstack/router-devtools": "1.58.9", + "@tanstack/react-router": "1.58.11", + "@tanstack/router-devtools": "1.58.11", "@tanstack/router-plugin": "1.58.10", "@tauri-apps/plugin-clipboard-manager": "2.0.0-rc.2", "@tauri-apps/plugin-dialog": "2.0.0-rc.1", @@ -76,7 +76,7 @@ "monaco-yaml": "5.2.2", "nanoid": "5.0.7", "sass": "1.79.3", - "shiki": "1.19.0", + "shiki": "1.20.0", "tailwindcss-textshadow": "2.1.3", "unplugin-auto-import": "0.18.3", "unplugin-icons": "0.19.3", diff --git a/clash-nyanpasu/frontend/nyanpasu/src/components/app/app-container.tsx b/clash-nyanpasu/frontend/nyanpasu/src/components/app/app-container.tsx index f2be334ba7..044478fc5e 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/components/app/app-container.tsx +++ b/clash-nyanpasu/frontend/nyanpasu/src/components/app/app-container.tsx @@ -1,10 +1,12 @@ -import { Allotment } from "allotment"; import getSystem from "@/utils/get-system"; import { alpha, useTheme } from "@mui/material"; import Paper from "@mui/material/Paper"; import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow"; import "allotment/dist/style.css"; +import { useAtomValue } from "jotai"; import { ReactNode } from "react"; +import { atomIsDrawerOnlyIcon } from "@/store"; +import { cn } from "@nyanpasu/ui"; import { LayoutControl } from "../layout/layout-control"; import styles from "./app-container.module.scss"; import AppDrawer from "./app-drawer"; @@ -21,13 +23,10 @@ export const AppContainer = ({ children?: ReactNode; isDrawer?: boolean; }) => { - // TODO: move layout sidecar size to nyanpasu config file for better compatibility? - // const onLayout = useDebounce(() => {}, { - // wait: 100, - // }); - const { palette } = useTheme(); + const onlyIcon = useAtomValue(atomIsDrawerOnlyIcon); + return ( {isDrawer && } - - {!isDrawer && ( - - - + {!isDrawer && ( +
+ +
+ )} + +
+ {OS === "windows" && ( + )} - - {OS === "windows" && ( - - )} - - {OS === "macos" && ( -
- )} - + {OS === "macos" && (
+ )} - {children} - - +
+ + {children} +
); }; diff --git a/clash-nyanpasu/frontend/nyanpasu/src/components/app/app-drawer.tsx b/clash-nyanpasu/frontend/nyanpasu/src/components/app/app-drawer.tsx index 9058ed5962..762fbfb59e 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/components/app/app-drawer.tsx +++ b/clash-nyanpasu/frontend/nyanpasu/src/components/app/app-drawer.tsx @@ -2,7 +2,7 @@ import { AnimatePresence, motion } from "framer-motion"; import { useState } from "react"; import getSystem from "@/utils/get-system"; import { MenuOpen } from "@mui/icons-material"; -import { alpha, Backdrop, darken, IconButton, lighten } from "@mui/material"; +import { alpha, Backdrop, IconButton } from "@mui/material"; import { cn } from "@nyanpasu/ui"; import AnimatedLogo from "../layout/animated-logo"; import DrawerContent from "./drawer-content"; @@ -83,26 +83,7 @@ export const AppDrawer = () => { type: "tween", }} > - - OS === "linux" - ? { - backgroundColor: lighten( - theme.palette.primary.light, - 0.9, - ), - ...theme.applyStyles("dark", { - backgroundColor: darken( - theme.palette.primary.dark, - 0.9, - ), - }), - } - : {}, - ]} - /> +
diff --git a/clash-nyanpasu/frontend/nyanpasu/src/components/app/drawer-content.tsx b/clash-nyanpasu/frontend/nyanpasu/src/components/app/drawer-content.tsx index 966d7c29eb..4a473f22a7 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/components/app/drawer-content.tsx +++ b/clash-nyanpasu/frontend/nyanpasu/src/components/app/drawer-content.tsx @@ -1,58 +1,21 @@ -import { useSize } from "ahooks"; -import { useAtom } from "jotai"; -import { useCallback, useEffect, useRef } from "react"; -import { atomIsDrawerOnlyIcon } from "@/store"; import getSystem from "@/utils/get-system"; -import { languageQuirks } from "@/utils/language"; import { getRoutesWithIcon } from "@/utils/routes-utils"; -import { Box, SxProps, Theme } from "@mui/material"; -import { useNyanpasu } from "@nyanpasu/interface"; +import { Box } from "@mui/material"; import { cn } from "@nyanpasu/ui"; import AnimatedLogo from "../layout/animated-logo"; import RouteListItem from "./modules/route-list-item"; export const DrawerContent = ({ className, - sx, + onlyIcon, }: { className?: string; - sx?: SxProps; + onlyIcon?: boolean; }) => { - const [onlyIcon, setOnlyIcon] = useAtom(atomIsDrawerOnlyIcon); - - const { nyanpasuConfig } = useNyanpasu(); - const routes = getRoutesWithIcon(); - const contentRef = useRef(null); - - const size = useSize(contentRef); - - const handleResize = useCallback( - (value?: number) => { - if (value) { - if ( - value < - languageQuirks[nyanpasuConfig?.language ?? "en"].drawer.minWidth - ) { - setOnlyIcon(true); - } else { - setOnlyIcon(false); - } - } else { - setOnlyIcon(false); - } - }, - [nyanpasuConfig?.language, setOnlyIcon], - ); - - useEffect(() => { - handleResize(size?.width); - }, [handleResize, size?.width]); - return ( {"Clash\nNyanpasu"} diff --git a/clash-nyanpasu/frontend/nyanpasu/src/components/setting/setting-nyanpasu-ui.tsx b/clash-nyanpasu/frontend/nyanpasu/src/components/setting/setting-nyanpasu-ui.tsx index 33b4ab27d7..59129b4ab5 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/components/setting/setting-nyanpasu-ui.tsx +++ b/clash-nyanpasu/frontend/nyanpasu/src/components/setting/setting-nyanpasu-ui.tsx @@ -1,12 +1,15 @@ +import { useAtom } from "jotai"; import { MuiColorInput } from "mui-color-input"; import { useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { isHexColor } from "validator"; +import { defaultTheme } from "@/pages/-theme"; +import { atomIsDrawerOnlyIcon } from "@/store"; import { languageOptions } from "@/utils/language"; import Done from "@mui/icons-material/Done"; import { Box, Button, List, ListItem, ListItemText } from "@mui/material"; import { useNyanpasu, VergeConfig } from "@nyanpasu/interface"; -import { BaseCard, Expand, MenuItem } from "@nyanpasu/ui"; +import { BaseCard, Expand, MenuItem, SwitchItem } from "@nyanpasu/ui"; export const SettingNyanpasuUI = () => { const { t } = useTranslation(); @@ -20,7 +23,7 @@ export const SettingNyanpasuUI = () => { }; const [themeColor, setThemeColor] = useState( - nyanpasuConfig?.theme_setting?.primary_color || "#fff", + nyanpasuConfig?.theme_setting?.primary_color, ); const themeColorRef = useRef(themeColor); @@ -28,6 +31,8 @@ export const SettingNyanpasuUI = () => { width: 128, }; + const [onlyIcon, setOnlyIcon] = useAtom(atomIsDrawerOnlyIcon); + return ( @@ -59,11 +64,13 @@ export const SettingNyanpasuUI = () => { { - if (!isHexColor(themeColorRef.current)) { + if ( + !isHexColor(themeColorRef.current ?? defaultTheme.primary_color) + ) { setThemeColor(themeColorRef.current); return; } @@ -98,6 +105,12 @@ export const SettingNyanpasuUI = () => { + + setOnlyIcon(!onlyIcon)} + /> ); diff --git a/clash-nyanpasu/frontend/nyanpasu/src/components/setting/setting-page.tsx b/clash-nyanpasu/frontend/nyanpasu/src/components/setting/setting-page.tsx index 751f49551c..57270ec4fc 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/components/setting/setting-page.tsx +++ b/clash-nyanpasu/frontend/nyanpasu/src/components/setting/setting-page.tsx @@ -37,7 +37,6 @@ export const SettingPage = () => { }} spacing={3} sequential - sx={{ width: "calc(100% + 24px)" }} > diff --git a/clash-nyanpasu/frontend/nyanpasu/src/locales/en.json b/clash-nyanpasu/frontend/nyanpasu/src/locales/en.json index 06aab66270..6536ef0bd2 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/locales/en.json +++ b/clash-nyanpasu/frontend/nyanpasu/src/locales/en.json @@ -89,6 +89,7 @@ "Theme Mode": "Theme Mode", "Theme Blur": "Theme Blur", "Theme Setting": "Theme Setting", + "Icon Navigation Bar": "Icon Navigation Bar", "Layout Setting": "Layout Setting", "Miscellaneous": "Miscellaneous", "Hotkey Setting": "Hotkey Setting", diff --git a/clash-nyanpasu/frontend/nyanpasu/src/locales/zh.json b/clash-nyanpasu/frontend/nyanpasu/src/locales/zh.json index 67bae360a6..16444cf80b 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/locales/zh.json +++ b/clash-nyanpasu/frontend/nyanpasu/src/locales/zh.json @@ -91,6 +91,7 @@ "Theme Mode": "主题模式", "Theme Blur": "背景模糊", "Theme Setting": "主题设置", + "Icon Navigation Bar": "图标导航栏", "Layout Setting": "界面设置", "Miscellaneous": "杂项设置", "Hotkey Setting": "热键设置", diff --git a/clash-nyanpasu/frontend/nyanpasu/src/pages/settings.tsx b/clash-nyanpasu/frontend/nyanpasu/src/pages/settings.tsx index 029fac8cef..0c2e380f22 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/pages/settings.tsx +++ b/clash-nyanpasu/frontend/nyanpasu/src/pages/settings.tsx @@ -98,6 +98,9 @@ function SettingPage() {
} + sectionStyle={{ + paddingRight: 0, + }} > diff --git a/clash-nyanpasu/frontend/nyanpasu/src/store/index.ts b/clash-nyanpasu/frontend/nyanpasu/src/store/index.ts index 00fc7425e9..87c14e182d 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/store/index.ts +++ b/clash-nyanpasu/frontend/nyanpasu/src/store/index.ts @@ -62,7 +62,10 @@ export const atomEnableLog = atomWithLocalStorage( export const atomIsDrawer = atom(); -export const atomIsDrawerOnlyIcon = atom(); +export const atomIsDrawerOnlyIcon = atomWithStorage( + "atomIsDrawerOnlyIcon", + true, +); // save the state of each profile item loading export const atomLoadingCache = atom>({}); diff --git a/clash-nyanpasu/manifest/version.json b/clash-nyanpasu/manifest/version.json index 7c855cf0d5..d175c56b20 100644 --- a/clash-nyanpasu/manifest/version.json +++ b/clash-nyanpasu/manifest/version.json @@ -2,7 +2,7 @@ "manifest_version": 1, "latest": { "mihomo": "v1.18.8", - "mihomo_alpha": "alpha-5812a7b", + "mihomo_alpha": "alpha-43cb482", "clash_rs": "v0.4.0", "clash_premium": "2023-09-05-gdcc8d87", "clash_rs_alpha": "0.4.0-alpha+sha.afe4cb0" @@ -69,5 +69,5 @@ "linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf" } }, - "updated_at": "2024-09-25T22:20:40.764Z" + "updated_at": "2024-09-26T22:20:38.515Z" } diff --git a/clash-nyanpasu/package.json b/clash-nyanpasu/package.json index 6b674cb2bd..585a240004 100644 --- a/clash-nyanpasu/package.json +++ b/clash-nyanpasu/package.json @@ -63,7 +63,7 @@ "@tauri-apps/cli": "2.0.0-rc.16", "@types/fs-extra": "11.0.4", "@types/lodash-es": "4.17.12", - "@types/node": "22.7.2", + "@types/node": "22.7.3", "@typescript-eslint/eslint-plugin": "8.7.0", "@typescript-eslint/parser": "8.7.0", "autoprefixer": "10.4.20", @@ -82,7 +82,7 @@ "eslint-plugin-react": "7.36.1", "eslint-plugin-react-compiler": "0.0.0-experimental-92aaa43-20240925", "eslint-plugin-react-hooks": "4.6.2", - "knip": "5.30.5", + "knip": "5.30.6", "lint-staged": "15.2.10", "npm-run-all2": "6.2.3", "postcss": "8.4.47", diff --git a/clash-nyanpasu/pnpm-lock.yaml b/clash-nyanpasu/pnpm-lock.yaml index 3143ba11c4..fc4e2528b8 100644 --- a/clash-nyanpasu/pnpm-lock.yaml +++ b/clash-nyanpasu/pnpm-lock.yaml @@ -22,7 +22,7 @@ importers: devDependencies: '@commitlint/cli': specifier: 19.5.0 - version: 19.5.0(@types/node@22.7.2)(typescript@5.6.2) + version: 19.5.0(@types/node@22.7.3)(typescript@5.6.2) '@commitlint/config-conventional': specifier: 19.5.0 version: 19.5.0 @@ -39,8 +39,8 @@ importers: specifier: 4.17.12 version: 4.17.12 '@types/node': - specifier: 22.7.2 - version: 22.7.2 + specifier: 22.7.3 + version: 22.7.3 '@typescript-eslint/eslint-plugin': specifier: 8.7.0 version: 8.7.0(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1)(typescript@5.6.2) @@ -96,8 +96,8 @@ importers: specifier: 4.6.2 version: 4.6.2(eslint@8.57.1) knip: - specifier: 5.30.5 - version: 5.30.5(@types/node@22.7.2)(typescript@5.6.2) + specifier: 5.30.6 + version: 5.30.6(@types/node@22.7.3)(typescript@5.6.2) lint-staged: specifier: 15.2.10 version: 15.2.10 @@ -166,16 +166,16 @@ importers: version: 2.0.0-rc.5 ahooks: specifier: 3.8.1 - version: 3.8.1(react@19.0.0-rc-778e1ed2-20240926) + version: 3.8.1(react@19.0.0-rc-67fee58b-20240926) ofetch: specifier: 1.4.0 version: 1.4.0 react: specifier: rc - version: 19.0.0-rc-778e1ed2-20240926 + version: 19.0.0-rc-67fee58b-20240926 swr: specifier: 2.2.5 - version: 2.2.5(react@19.0.0-rc-778e1ed2-20240926) + version: 2.2.5(react@19.0.0-rc-67fee58b-20240926) devDependencies: '@types/react': specifier: npm:types-react@rc @@ -185,16 +185,16 @@ importers: dependencies: '@dnd-kit/core': specifier: 6.1.0 - version: 6.1.0(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + version: 6.1.0(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) '@dnd-kit/sortable': specifier: 8.0.0 - version: 8.0.0(@dnd-kit/core@6.1.0(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + version: 8.0.0(@dnd-kit/core@6.1.0(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) '@dnd-kit/utilities': specifier: 3.2.2 - version: 3.2.2(react@19.0.0-rc-778e1ed2-20240926) + version: 3.2.2(react@19.0.0-rc-67fee58b-20240926) '@emotion/styled': specifier: 11.13.0 - version: 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + version: 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@juggle/resize-observer': specifier: 3.4.0 version: 3.4.0 @@ -203,13 +203,13 @@ importers: version: 0.3.0 '@mui/icons-material': specifier: 6.1.1 - version: 6.1.1(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + version: 6.1.1(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@mui/lab': specifier: 6.0.0-beta.10 - version: 6.0.0-beta.10(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + version: 6.0.0-beta.10(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@mui/material': specifier: 6.1.1 - version: 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + version: 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@nyanpasu/interface': specifier: workspace:^ version: link:../interface @@ -217,8 +217,8 @@ importers: specifier: workspace:^ version: link:../ui '@tanstack/router-zod-adapter': - specifier: 1.58.9 - version: 1.58.9(@tanstack/react-router@1.58.9(@tanstack/router-generator@1.58.1)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926))(zod@3.23.8) + specifier: 1.58.11 + version: 1.58.11(@tanstack/react-router@1.58.11(@tanstack/router-generator@1.58.1)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926))(zod@3.23.8) '@tauri-apps/api': specifier: 2.0.0-rc.5 version: 2.0.0-rc.5 @@ -227,10 +227,10 @@ importers: version: 7.0.15 ahooks: specifier: 3.8.1 - version: 3.8.1(react@19.0.0-rc-778e1ed2-20240926) + version: 3.8.1(react@19.0.0-rc-67fee58b-20240926) allotment: specifier: 1.20.2 - version: 1.20.2(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + version: 1.20.2(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) country-code-emoji: specifier: 2.3.0 version: 2.3.0 @@ -239,61 +239,61 @@ importers: version: 1.11.13 framer-motion: specifier: 12.0.0-alpha.1 - version: 12.0.0-alpha.1(@emotion/is-prop-valid@1.3.0)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + version: 12.0.0-alpha.1(@emotion/is-prop-valid@1.3.0)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) i18next: specifier: 23.15.1 version: 23.15.1 jotai: specifier: 2.10.0 - version: 2.10.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + version: 2.10.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) json-schema: specifier: 0.4.0 version: 0.4.0 material-react-table: specifier: 3.0.1 - version: 3.0.1(scdjpuj6p6tus776axypnmttum) + version: 3.0.1(nlfhyyeq2nu7jsjvmhefqx54wq) monaco-editor: specifier: 0.52.0 version: 0.52.0 mui-color-input: specifier: 4.0.1 - version: 4.0.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + version: 4.0.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) react: specifier: rc - version: 19.0.0-rc-778e1ed2-20240926 + version: 19.0.0-rc-67fee58b-20240926 react-dom: specifier: rc - version: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + version: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) react-error-boundary: specifier: 4.0.13 - version: 4.0.13(react@19.0.0-rc-778e1ed2-20240926) + version: 4.0.13(react@19.0.0-rc-67fee58b-20240926) react-fast-marquee: specifier: 1.6.5 - version: 1.6.5(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + version: 1.6.5(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) react-hook-form-mui: specifier: 7.2.0 - version: 7.2.0(kxevavldinoaaue37dtxsp7rui) + version: 7.2.0(sgiyhgbj7j5wqkzxbwdllyfaoi) react-i18next: specifier: 15.0.2 - version: 15.0.2(i18next@23.15.1)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + version: 15.0.2(i18next@23.15.1)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) react-markdown: specifier: 9.0.1 - version: 9.0.1(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + version: 9.0.1(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) react-router-dom: specifier: 6.26.2 - version: 6.26.2(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + version: 6.26.2(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) react-split-grid: specifier: 1.0.4 - version: 1.0.4(react@19.0.0-rc-778e1ed2-20240926) + version: 1.0.4(react@19.0.0-rc-67fee58b-20240926) react-use: specifier: 17.5.1 - version: 17.5.1(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + version: 17.5.1(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) swr: specifier: 2.2.5 - version: 2.2.5(react@19.0.0-rc-778e1ed2-20240926) + version: 2.2.5(react@19.0.0-rc-67fee58b-20240926) virtua: specifier: 0.34.2 - version: 0.34.2(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + version: 0.34.2(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) vite-bundle-visualizer: specifier: 1.2.1 version: 1.2.1(rollup@4.21.0) @@ -306,22 +306,22 @@ importers: version: 11.12.0 '@emotion/react': specifier: 11.13.3 - version: 11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + version: 11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@iconify/json': specifier: 2.2.253 version: 2.2.253 '@monaco-editor/react': specifier: 4.6.0 - version: 4.6.0(monaco-editor@0.52.0)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + version: 4.6.0(monaco-editor@0.52.0)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) '@tanstack/react-router': - specifier: 1.58.9 - version: 1.58.9(@tanstack/router-generator@1.58.1)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + specifier: 1.58.11 + version: 1.58.11(@tanstack/router-generator@1.58.1)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) '@tanstack/router-devtools': - specifier: 1.58.9 - version: 1.58.9(@tanstack/react-router@1.58.9(@tanstack/router-generator@1.58.1)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926))(csstype@3.1.3)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + specifier: 1.58.11 + version: 1.58.11(@tanstack/react-router@1.58.11(@tanstack/router-generator@1.58.1)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926))(csstype@3.1.3)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) '@tanstack/router-plugin': specifier: 1.58.10 - version: 1.58.10(vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0))(webpack-sources@3.2.3) + version: 1.58.10(vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0))(webpack-sources@3.2.3) '@tauri-apps/plugin-clipboard-manager': specifier: 2.0.0-rc.2 version: 2.0.0-rc.2 @@ -357,10 +357,10 @@ importers: version: 13.12.2 '@vitejs/plugin-react': specifier: 4.3.1 - version: 4.3.1(vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)) + version: 4.3.1(vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)) '@vitejs/plugin-react-swc': specifier: 3.7.0 - version: 3.7.0(vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)) + version: 3.7.0(vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)) clsx: specifier: 2.1.1 version: 2.1.1 @@ -377,8 +377,8 @@ importers: specifier: 1.79.3 version: 1.79.3 shiki: - specifier: 1.19.0 - version: 1.19.0 + specifier: 1.20.0 + version: 1.20.0 tailwindcss-textshadow: specifier: 2.1.3 version: 2.1.3 @@ -393,16 +393,16 @@ importers: version: 13.12.0 vite: specifier: 5.4.8 - version: 5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) + version: 5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) vite-plugin-sass-dts: specifier: 1.3.29 - version: 1.3.29(postcss@8.4.47)(prettier@3.3.3)(sass-embedded@1.78.0)(vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)) + version: 1.3.29(postcss@8.4.47)(prettier@3.3.3)(sass-embedded@1.78.0)(vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)) vite-plugin-svgr: specifier: 4.2.0 - version: 4.2.0(rollup@4.21.0)(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)) + version: 4.2.0(rollup@4.21.0)(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)) vite-tsconfig-paths: specifier: 5.0.1 - version: 5.0.1(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)) + version: 5.0.1(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)) zod: specifier: 3.23.8 version: 3.23.8 @@ -414,19 +414,19 @@ importers: version: 0.3.0 '@mui/icons-material': specifier: 6.1.1 - version: 6.1.1(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + version: 6.1.1(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@mui/lab': specifier: 6.0.0-beta.10 - version: 6.0.0-beta.10(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + version: 6.0.0-beta.10(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@mui/material': specifier: 6.1.1 - version: 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + version: 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@radix-ui/react-portal': specifier: 1.1.1 - version: 1.1.1(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + version: 1.1.1(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@radix-ui/react-scroll-area': specifier: 1.1.0 - version: 1.1.0(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + version: 1.1.0(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@tauri-apps/api': specifier: 2.0.0-rc.5 version: 2.0.0-rc.5 @@ -438,41 +438,41 @@ importers: version: types-react@19.0.0-rc.1 '@vitejs/plugin-react': specifier: 4.3.1 - version: 4.3.1(vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)) + version: 4.3.1(vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)) ahooks: specifier: 3.8.1 - version: 3.8.1(react@19.0.0-rc-778e1ed2-20240926) + version: 3.8.1(react@19.0.0-rc-67fee58b-20240926) d3: specifier: 7.9.0 version: 7.9.0 framer-motion: specifier: 12.0.0-alpha.1 - version: 12.0.0-alpha.1(@emotion/is-prop-valid@1.3.0)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + version: 12.0.0-alpha.1(@emotion/is-prop-valid@1.3.0)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) react: specifier: rc - version: 19.0.0-rc-778e1ed2-20240926 + version: 19.0.0-rc-67fee58b-20240926 react-dom: specifier: rc - version: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + version: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) react-error-boundary: specifier: 4.0.13 - version: 4.0.13(react@19.0.0-rc-778e1ed2-20240926) + version: 4.0.13(react@19.0.0-rc-67fee58b-20240926) react-i18next: specifier: 15.0.2 - version: 15.0.2(i18next@23.15.1)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + version: 15.0.2(i18next@23.15.1)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) react-use: specifier: 17.5.1 - version: 17.5.1(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + version: 17.5.1(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) vite: specifier: 5.4.8 - version: 5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) + version: 5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) vite-tsconfig-paths: specifier: 5.0.1 - version: 5.0.1(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)) + version: 5.0.1(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)) devDependencies: '@emotion/react': specifier: 11.13.3 - version: 11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + version: 11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@types/d3-interpolate-path': specifier: 2.0.3 version: 2.0.3 @@ -493,7 +493,7 @@ importers: version: 5.1.0(typescript@5.6.2) vite-plugin-dts: specifier: 4.2.2 - version: 4.2.2(@types/node@22.7.2)(rollup@4.21.0)(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)) + version: 4.2.2(@types/node@22.7.3)(rollup@4.21.0)(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)) scripts: dependencies: @@ -2037,17 +2037,17 @@ packages: '@rushstack/ts-command-line@4.22.6': resolution: {integrity: sha512-QSRqHT/IfoC5nk9zn6+fgyqOPXHME0BfchII9EUPR19pocsNp/xSbeBCbD3PIR2Lg+Q5qk7OFqk1VhWPMdKHJg==} - '@shikijs/core@1.19.0': - resolution: {integrity: sha512-314J5MPdS1wzfjuD856MXvbAI2wN03ofMnUGkZ5ZDBOza/d38paLwd+YVyuKrrjxJ4hfPMjc4tRmPkXd6UDMPQ==} + '@shikijs/core@1.20.0': + resolution: {integrity: sha512-KlO3iE0THzSdYkzDFugt8SHe6FR3qNYTkmpbdW1d6xo8juQkMjybxAw/cBi2npL2eb2F4PbbnSs5Z9tDusfvyg==} - '@shikijs/engine-javascript@1.19.0': - resolution: {integrity: sha512-D1sioU61n7fLWfDzTC9JNS19zEYZMr7qxkSVzv6ziEWDxnwzy2PvYoKPedJV4qUf+2VnrYPSaArDz2W0XgGB7A==} + '@shikijs/engine-javascript@1.20.0': + resolution: {integrity: sha512-ZUMo758uduM0Tfgzi/kd+0IKMbNdumCxxWjY36uf1DIs2Qyg9HIq3vA1Wfa/vc6HE7tHWFpANRi3mv7UzJ68MQ==} - '@shikijs/engine-oniguruma@1.19.0': - resolution: {integrity: sha512-/JxwIefNVLGB4EmpB8i6P4JB/oVYRuzSixbqvx7m6iPW0lQ1T97c/0wmA+JlKbngEiExckSuPwa48fajlShB7A==} + '@shikijs/engine-oniguruma@1.20.0': + resolution: {integrity: sha512-MQ40WkVTZk7by33ces4PGK6XNFSo6PYvKTSAr2kTWdRNhFmOcnaX+1XzvFwB26eySXR7U74t91czZ1qJkEgxTA==} - '@shikijs/types@1.19.0': - resolution: {integrity: sha512-NZvVp3k1bP4MTRUbmnkGhYzPdoNMjNLSAwczMRUbtUl4oj2LlNRNbwERyeIyJt56Ac9fvPVZ2nn13OXk86E5UQ==} + '@shikijs/types@1.20.0': + resolution: {integrity: sha512-y+EaDvU2K6/GaXOKXxJaGnr1XtmZMF7MfS0pSEDdxEq66gCtKsLwQvVwoQFdp7R7dLlNAro3ijEE19sMZ0pzqg==} '@shikijs/vscode-textmate@9.2.2': resolution: {integrity: sha512-TMp15K+GGYrWlZM8+Lnj9EaHEFmOen0WJBrfa17hF7taDOYthuPPV0GWzfd/9iMij0akS/8Yw2ikquH7uVi/fg==} @@ -2216,8 +2216,8 @@ packages: resolution: {integrity: sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==} engines: {node: '>=12'} - '@tanstack/react-router@1.58.9': - resolution: {integrity: sha512-ODKOo8bUo8nIPGZmJHa7zNul9U3XAMmohnwZLl2A/A3suU03Q+0R5oOfhUKw+qArPIdIcec1VtqYpNk6y7qfrQ==} + '@tanstack/react-router@1.58.11': + resolution: {integrity: sha512-d31Xl4VQuU/EvFL6TYb9QQEKZTFsCK75MV2QvgezBdBzRBnuuZDIjNB0CWze9AzUVmGTgx2Qiy9h4qb8R3X02w==} engines: {node: '>=12'} peerDependencies: '@tanstack/router-generator': 1.58.1 @@ -2246,11 +2246,11 @@ packages: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - '@tanstack/router-devtools@1.58.9': - resolution: {integrity: sha512-caaompIgBaAoGnmz8cn4w/c3DtkvKBPv717hDYoN+nW/oHJgxSgnOyL/QEwGNv1XNtlMHjwEfhlGHnjqorjHKQ==} + '@tanstack/router-devtools@1.58.11': + resolution: {integrity: sha512-Wwig4lZvQ2gsIgzWRUv7gWvL2zV/L9SDs6NlayCndbXkvbh910rv8tlFib+Cx6xSpIQUpzTG0/3jgPkJ1hP/sQ==} engines: {node: '>=12'} peerDependencies: - '@tanstack/react-router': ^1.58.9 + '@tanstack/react-router': ^1.58.11 react: '>=18' react-dom: '>=18' @@ -2273,8 +2273,8 @@ packages: webpack: optional: true - '@tanstack/router-zod-adapter@1.58.9': - resolution: {integrity: sha512-kBtQ98/uet4j1i1S8ph6MfF5hbF6scEiWYj45h5bsB4gE+j4+JkRjsZwaN16zPQOjB0yBSh7euJF3fUyRmahEQ==} + '@tanstack/router-zod-adapter@1.58.11': + resolution: {integrity: sha512-g70U2QQcewe9L31hFlwtoiTapa4NoQkQ//184ACs8dBXv6ALTAfda2VOdpObcVU9R+4J5nxgw5HKLEYE549AXg==} engines: {node: '>=12'} peerDependencies: '@tanstack/react-router': '>=1.43.2' @@ -2581,8 +2581,8 @@ packages: '@types/node@22.5.0': resolution: {integrity: sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==} - '@types/node@22.7.2': - resolution: {integrity: sha512-866lXSrpGpgyHBZUa2m9YNWqHDjjM0aBTJlNtYaGEw4rqY/dcD7deRVTbBBAJelfA7oaGDbNftXF/TL/A6RgoA==} + '@types/node@22.7.3': + resolution: {integrity: sha512-qXKfhXXqGTyBskvWEzJZPUxSslAiLaB6JGP1ic/XTH9ctGgzdgYguuLP1C601aRTSDNlLb0jbKqXjZ48GNraSA==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -4759,8 +4759,8 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - knip@5.30.5: - resolution: {integrity: sha512-opta1VVKAfIzhvj1iyOr/3SgSDC6jYPoUaYkvjftNqMTeURppYY5VqrAa5DOcJnIsdcAdyoIKHUFg9NRiFaM5w==} + knip@5.30.6: + resolution: {integrity: sha512-YkcnRVl0N99xZ7eaXE7KlH/4cPTCn6BGuk9KxINEdCMFN3yita2vGBizApy97ZOHgghy8tb589gQ3xvLMFIO4w==} engines: {node: '>=18.6.0'} hasBin: true peerDependencies: @@ -5768,10 +5768,10 @@ packages: resolution: {integrity: sha512-RcSV/u+lPChcTB+A4fij0xkE204yzKdAsGUFy6+DrfUzWSawB+cu0n3WLmJcJXQ/VnmjSUlIrqmVLicRhT/gLA==} hasBin: true - react-dom@19.0.0-rc-778e1ed2-20240926: - resolution: {integrity: sha512-9FLXiKN8/nxd+TcrjIPKxxWQZVTr4lBbuPIcRly8Ch6FZsTrFmpF3I++0+1HoKDlg4JwPvQ/H3+4OfRpgNn7bQ==} + react-dom@19.0.0-rc-67fee58b-20240926: + resolution: {integrity: sha512-fyLfI8S7pXwVguPdS9z8gY8SWOLP3ZiraOAYM0mAeMrjeU2PbN2lXx4huN5WlbBkCMCKNxTkLJpOpWfJ0Gi2jw==} peerDependencies: - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 react-error-boundary@4.0.13: resolution: {integrity: sha512-b6PwbdSv8XeOSYvjt8LpgpKrZ0yGdtZokYwkwV2wlcZbxgopHX/hgPl5VgpnoVOWd868n1hktM8Qm4b+02MiLQ==} @@ -5873,8 +5873,8 @@ packages: react: '*' react-dom: '*' - react@19.0.0-rc-778e1ed2-20240926: - resolution: {integrity: sha512-Z0qJs/iVQ+tHmnTa+4jK9kx+GEwDj5GmbqX26CQE6RPx2RCHzpls/o/UeN6IC8xCZL5hQiLcF5dtq3cWo7F8Fg==} + react@19.0.0-rc-67fee58b-20240926: + resolution: {integrity: sha512-VCp63TASDf1XDh+oGCV0kV/jTFOn2sxg5HrbuMyjbZXHdTzcNvUw/sEbrtC1QoU+vledZiR4AV7wQW7Ka9qruw==} engines: {node: '>=0.10.0'} read-cache@1.0.0: @@ -6173,8 +6173,8 @@ packages: sax@1.3.0: resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==} - scheduler@0.25.0-rc-778e1ed2-20240926: - resolution: {integrity: sha512-X3XrKE/18iWn/pG0QA9WEx7P1ohOzrddY5Jv8V7tC3U1+mO/eQTn7OjemdWAJ+BOyhbeYZxye5BIOq6Auvo67A==} + scheduler@0.25.0-rc-67fee58b-20240926: + resolution: {integrity: sha512-saTMMKVkRbIoAyrqnFgRa864RnAxiU85yXZaBXBAXQDaXPz+EdtjZy8BQCnSRZwq8CHvXvzDI8Ox9icBftZ/nw==} screenfull@5.2.0: resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==} @@ -6243,8 +6243,8 @@ packages: shell-quote@1.8.1: resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} - shiki@1.19.0: - resolution: {integrity: sha512-Ng7Gd6XgWFLsv4Z3so65hOyXjV78qz1M117MuZHwdPQD6fgb5wR2IoLMvSlM/Ml14EXH7n+/YxIpTD74i7kDdw==} + shiki@1.20.0: + resolution: {integrity: sha512-MZJJ1PCFsQB1Piq+25wiz0a75yUv8Q3/fzy7SzRx5ONdjdtGdyiKwYn8vb/FnK5kjS0voWGnPpjG16POauUR+g==} side-channel@1.0.6: resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} @@ -7548,11 +7548,11 @@ snapshots: '@bufbuild/protobuf@1.10.0': {} - '@commitlint/cli@19.5.0(@types/node@22.7.2)(typescript@5.6.2)': + '@commitlint/cli@19.5.0(@types/node@22.7.3)(typescript@5.6.2)': dependencies: '@commitlint/format': 19.5.0 '@commitlint/lint': 19.5.0 - '@commitlint/load': 19.5.0(@types/node@22.7.2)(typescript@5.6.2) + '@commitlint/load': 19.5.0(@types/node@22.7.3)(typescript@5.6.2) '@commitlint/read': 19.5.0 '@commitlint/types': 19.5.0 tinyexec: 0.3.0 @@ -7599,7 +7599,7 @@ snapshots: '@commitlint/rules': 19.5.0 '@commitlint/types': 19.5.0 - '@commitlint/load@19.5.0(@types/node@22.7.2)(typescript@5.6.2)': + '@commitlint/load@19.5.0(@types/node@22.7.3)(typescript@5.6.2)': dependencies: '@commitlint/config-validator': 19.5.0 '@commitlint/execute-rule': 19.5.0 @@ -7607,7 +7607,7 @@ snapshots: '@commitlint/types': 19.5.0 chalk: 5.3.0 cosmiconfig: 9.0.0(typescript@5.6.2) - cosmiconfig-typescript-loader: 5.0.0(@types/node@22.7.2)(cosmiconfig@9.0.0(typescript@5.6.2))(typescript@5.6.2) + cosmiconfig-typescript-loader: 5.0.0(@types/node@22.7.3)(cosmiconfig@9.0.0(typescript@5.6.2))(typescript@5.6.2) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -7679,29 +7679,29 @@ snapshots: '@ctrl/tinycolor@4.1.0': {} - '@dnd-kit/accessibility@3.1.0(react@19.0.0-rc-778e1ed2-20240926)': + '@dnd-kit/accessibility@3.1.0(react@19.0.0-rc-67fee58b-20240926)': dependencies: - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 tslib: 2.6.2 - '@dnd-kit/core@6.1.0(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)': + '@dnd-kit/core@6.1.0(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)': dependencies: - '@dnd-kit/accessibility': 3.1.0(react@19.0.0-rc-778e1ed2-20240926) - '@dnd-kit/utilities': 3.2.2(react@19.0.0-rc-778e1ed2-20240926) - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + '@dnd-kit/accessibility': 3.1.0(react@19.0.0-rc-67fee58b-20240926) + '@dnd-kit/utilities': 3.2.2(react@19.0.0-rc-67fee58b-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) tslib: 2.6.2 - '@dnd-kit/sortable@8.0.0(@dnd-kit/core@6.1.0(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)': + '@dnd-kit/sortable@8.0.0(@dnd-kit/core@6.1.0(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)': dependencies: - '@dnd-kit/core': 6.1.0(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) - '@dnd-kit/utilities': 3.2.2(react@19.0.0-rc-778e1ed2-20240926) - react: 19.0.0-rc-778e1ed2-20240926 + '@dnd-kit/core': 6.1.0(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) + '@dnd-kit/utilities': 3.2.2(react@19.0.0-rc-67fee58b-20240926) + react: 19.0.0-rc-67fee58b-20240926 tslib: 2.6.2 - '@dnd-kit/utilities@3.2.2(react@19.0.0-rc-778e1ed2-20240926)': + '@dnd-kit/utilities@3.2.2(react@19.0.0-rc-67fee58b-20240926)': dependencies: - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 tslib: 2.6.2 '@dual-bundle/import-meta-resolve@4.1.0': {} @@ -7758,17 +7758,17 @@ snapshots: '@emotion/memoize@0.9.0': {} - '@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: '@babel/runtime': 7.24.8 '@emotion/babel-plugin': 11.12.0 '@emotion/cache': 11.13.0 '@emotion/serialize': 1.3.1 - '@emotion/use-insertion-effect-with-fallbacks': 1.1.0(react@19.0.0-rc-778e1ed2-20240926) + '@emotion/use-insertion-effect-with-fallbacks': 1.1.0(react@19.0.0-rc-67fee58b-20240926) '@emotion/utils': 1.4.0 '@emotion/weak-memoize': 0.4.0 hoist-non-react-statics: 3.3.2 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 optionalDependencies: '@types/react': types-react@19.0.0-rc.1 @@ -7790,16 +7790,16 @@ snapshots: '@emotion/sheet@1.4.0': {} - '@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: '@babel/runtime': 7.24.8 '@emotion/babel-plugin': 11.12.0 '@emotion/is-prop-valid': 1.3.0 - '@emotion/react': 11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@emotion/react': 11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@emotion/serialize': 1.3.0 - '@emotion/use-insertion-effect-with-fallbacks': 1.1.0(react@19.0.0-rc-778e1ed2-20240926) + '@emotion/use-insertion-effect-with-fallbacks': 1.1.0(react@19.0.0-rc-67fee58b-20240926) '@emotion/utils': 1.4.0 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 optionalDependencies: '@types/react': types-react@19.0.0-rc.1 @@ -7807,9 +7807,9 @@ snapshots: '@emotion/unitless@0.9.0': {} - '@emotion/use-insertion-effect-with-fallbacks@1.1.0(react@19.0.0-rc-778e1ed2-20240926)': + '@emotion/use-insertion-effect-with-fallbacks@1.1.0(react@19.0.0-rc-67fee58b-20240926)': dependencies: - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 '@emotion/utils@1.4.0': {} @@ -7990,11 +7990,11 @@ snapshots: '@floating-ui/core': 1.6.1 '@floating-ui/utils': 0.2.2 - '@floating-ui/react-dom@2.1.2(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)': + '@floating-ui/react-dom@2.1.2(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)': dependencies: '@floating-ui/dom': 1.6.5 - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) '@floating-ui/utils@0.2.2': {} @@ -8080,23 +8080,23 @@ snapshots: '@material/material-color-utilities@0.3.0': {} - '@microsoft/api-extractor-model@7.29.6(@types/node@22.7.2)': + '@microsoft/api-extractor-model@7.29.6(@types/node@22.7.3)': dependencies: '@microsoft/tsdoc': 0.15.0 '@microsoft/tsdoc-config': 0.17.0 - '@rushstack/node-core-library': 5.7.0(@types/node@22.7.2) + '@rushstack/node-core-library': 5.7.0(@types/node@22.7.3) transitivePeerDependencies: - '@types/node' - '@microsoft/api-extractor@7.47.7(@types/node@22.7.2)': + '@microsoft/api-extractor@7.47.7(@types/node@22.7.3)': dependencies: - '@microsoft/api-extractor-model': 7.29.6(@types/node@22.7.2) + '@microsoft/api-extractor-model': 7.29.6(@types/node@22.7.3) '@microsoft/tsdoc': 0.15.0 '@microsoft/tsdoc-config': 0.17.0 - '@rushstack/node-core-library': 5.7.0(@types/node@22.7.2) + '@rushstack/node-core-library': 5.7.0(@types/node@22.7.3) '@rushstack/rig-package': 0.5.3 - '@rushstack/terminal': 0.14.0(@types/node@22.7.2) - '@rushstack/ts-command-line': 4.22.6(@types/node@22.7.2) + '@rushstack/terminal': 0.14.0(@types/node@22.7.3) + '@rushstack/ts-command-line': 4.22.6(@types/node@22.7.3) lodash: 4.17.21 minimatch: 3.0.8 resolve: 1.22.8 @@ -8120,204 +8120,204 @@ snapshots: monaco-editor: 0.52.0 state-local: 1.0.7 - '@monaco-editor/react@4.6.0(monaco-editor@0.52.0)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)': + '@monaco-editor/react@4.6.0(monaco-editor@0.52.0)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)': dependencies: '@monaco-editor/loader': 1.4.0(monaco-editor@0.52.0) monaco-editor: 0.52.0 - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) - '@mui/base@5.0.0-beta.58(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@mui/base@5.0.0-beta.58(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: '@babel/runtime': 7.25.6 - '@floating-ui/react-dom': 2.1.2(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + '@floating-ui/react-dom': 2.1.2(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) '@mui/types': 7.2.17(types-react@19.0.0-rc.1) - '@mui/utils': 6.0.0-rc.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@mui/utils': 6.0.0-rc.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@popperjs/core': 2.11.8 clsx: 2.1.1 prop-types: 15.8.1 - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) optionalDependencies: '@types/react': types-react@19.0.0-rc.1 '@mui/core-downloads-tracker@6.1.1': {} - '@mui/icons-material@6.1.1(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@mui/icons-material@6.1.1(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: '@babel/runtime': 7.25.6 - '@mui/material': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - react: 19.0.0-rc-778e1ed2-20240926 + '@mui/material': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + react: 19.0.0-rc-67fee58b-20240926 optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@mui/lab@6.0.0-beta.10(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@mui/lab@6.0.0-beta.10(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: '@babel/runtime': 7.25.6 - '@mui/base': 5.0.0-beta.58(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@mui/material': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@mui/system': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@mui/base': 5.0.0-beta.58(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@mui/material': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@mui/system': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@mui/types': 7.2.17(types-react@19.0.0-rc.1) - '@mui/utils': 6.1.1(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@mui/utils': 6.1.1(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) clsx: 2.1.1 prop-types: 15.8.1 - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) optionalDependencies: - '@emotion/react': 11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@emotion/react': 11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@types/react': types-react@19.0.0-rc.1 - '@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: '@babel/runtime': 7.25.6 '@mui/core-downloads-tracker': 6.1.1 - '@mui/system': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@mui/system': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@mui/types': 7.2.17(types-react@19.0.0-rc.1) - '@mui/utils': 6.1.1(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@mui/utils': 6.1.1(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@popperjs/core': 2.11.8 '@types/react-transition-group': 4.4.11 clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) react-is: 18.3.1 - react-transition-group: 4.4.5(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + react-transition-group: 4.4.5(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) optionalDependencies: - '@emotion/react': 11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@emotion/react': 11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@types/react': types-react@19.0.0-rc.1 - '@mui/private-theming@5.16.6(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@mui/private-theming@5.16.6(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: '@babel/runtime': 7.25.6 - '@mui/utils': 5.16.6(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@mui/utils': 5.16.6(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) prop-types: 15.8.1 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@mui/private-theming@6.1.1(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@mui/private-theming@6.1.1(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: '@babel/runtime': 7.25.6 - '@mui/utils': 6.1.1(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@mui/utils': 6.1.1(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) prop-types: 15.8.1 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@mui/styled-engine@5.16.6(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)': + '@mui/styled-engine@5.16.6(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)': dependencies: '@babel/runtime': 7.25.6 '@emotion/cache': 11.13.1 csstype: 3.1.3 prop-types: 15.8.1 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 optionalDependencies: - '@emotion/react': 11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@emotion/react': 11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) - '@mui/styled-engine@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)': + '@mui/styled-engine@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)': dependencies: '@babel/runtime': 7.25.6 '@emotion/cache': 11.13.1 '@emotion/sheet': 1.4.0 csstype: 3.1.3 prop-types: 15.8.1 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 optionalDependencies: - '@emotion/react': 11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@emotion/react': 11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) - '@mui/system@5.16.7(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@mui/system@5.16.7(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: '@babel/runtime': 7.25.6 - '@mui/private-theming': 5.16.6(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@mui/styled-engine': 5.16.6(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926) + '@mui/private-theming': 5.16.6(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@mui/styled-engine': 5.16.6(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926) '@mui/types': 7.2.17(types-react@19.0.0-rc.1) - '@mui/utils': 5.16.6(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@mui/utils': 5.16.6(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 optionalDependencies: - '@emotion/react': 11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@emotion/react': 11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@types/react': types-react@19.0.0-rc.1 - '@mui/system@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@mui/system@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: '@babel/runtime': 7.25.6 - '@mui/private-theming': 6.1.1(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@mui/styled-engine': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926) + '@mui/private-theming': 6.1.1(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@mui/styled-engine': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926) '@mui/types': 7.2.17(types-react@19.0.0-rc.1) - '@mui/utils': 6.1.1(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@mui/utils': 6.1.1(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 optionalDependencies: - '@emotion/react': 11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@emotion/react': 11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@types/react': types-react@19.0.0-rc.1 '@mui/types@7.2.17(types-react@19.0.0-rc.1)': optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@mui/utils@5.16.6(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@mui/utils@5.16.6(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: '@babel/runtime': 7.25.6 '@mui/types': 7.2.17(types-react@19.0.0-rc.1) '@types/prop-types': 15.7.12 clsx: 2.1.1 prop-types: 15.8.1 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 react-is: 18.3.1 optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@mui/utils@6.0.0-rc.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@mui/utils@6.0.0-rc.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: '@babel/runtime': 7.25.6 '@mui/types': 7.2.17(types-react@19.0.0-rc.1) '@types/prop-types': 15.7.12 clsx: 2.1.1 prop-types: 15.8.1 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 react-is: 18.3.1 optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@mui/utils@6.1.1(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@mui/utils@6.1.1(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: '@babel/runtime': 7.25.6 '@mui/types': 7.2.17(types-react@19.0.0-rc.1) '@types/prop-types': 15.7.12 clsx: 2.1.1 prop-types: 15.8.1 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 react-is: 18.3.1 optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@mui/x-date-pickers@7.9.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(dayjs@1.11.13)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@mui/x-date-pickers@7.9.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(dayjs@1.11.13)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: '@babel/runtime': 7.25.6 - '@mui/base': 5.0.0-beta.58(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@mui/material': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@mui/system': 5.16.7(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@mui/utils': 5.16.6(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@mui/base': 5.0.0-beta.58(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@mui/material': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@mui/system': 5.16.7(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@mui/utils': 5.16.6(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@types/react-transition-group': 4.4.11 clsx: 2.1.1 prop-types: 15.8.1 - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) - react-transition-group: 4.4.5(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) + react-transition-group: 4.4.5(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) optionalDependencies: - '@emotion/react': 11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@emotion/react': 11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) dayjs: 1.11.13 transitivePeerDependencies: - '@types/react' @@ -8544,82 +8544,82 @@ snapshots: '@radix-ui/primitive@1.1.0': {} - '@radix-ui/react-compose-refs@1.1.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@radix-ui/react-compose-refs@1.1.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@radix-ui/react-context@1.1.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@radix-ui/react-context@1.1.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@radix-ui/react-direction@1.1.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@radix-ui/react-direction@1.1.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@radix-ui/react-portal@1.1.1(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@radix-ui/react-portal@1.1.1(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: - '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@radix-ui/react-presence@1.1.0(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@radix-ui/react-presence@1.1.0(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@radix-ui/react-primitive@2.0.0(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@radix-ui/react-primitive@2.0.0(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: - '@radix-ui/react-slot': 1.1.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + '@radix-ui/react-slot': 1.1.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@radix-ui/react-scroll-area@1.1.0(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@radix-ui/react-scroll-area@1.1.0(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: '@radix-ui/number': 1.1.0 '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@radix-ui/react-direction': 1.1.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@radix-ui/react-presence': 1.1.0(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@radix-ui/react-context': 1.1.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@radix-ui/react-direction': 1.1.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@radix-ui/react-presence': 1.1.0(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@radix-ui/react-primitive': 2.0.0(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@radix-ui/react-use-callback-ref': 1.1.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@radix-ui/react-use-layout-effect': 1.1.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@radix-ui/react-slot@1.1.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@radix-ui/react-slot@1.1.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: - '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - react: 19.0.0-rc-778e1ed2-20240926 + '@radix-ui/react-compose-refs': 1.1.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + react: 19.0.0-rc-67fee58b-20240926 optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@radix-ui/react-use-callback-ref@1.1.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@radix-ui/react-use-callback-ref@1.1.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - '@radix-ui/react-use-layout-effect@1.1.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1)': + '@radix-ui/react-use-layout-effect@1.1.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1)': dependencies: - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 optionalDependencies: '@types/react': types-react@19.0.0-rc.1 @@ -8683,7 +8683,7 @@ snapshots: '@rtsao/scc@1.1.0': {} - '@rushstack/node-core-library@5.7.0(@types/node@22.7.2)': + '@rushstack/node-core-library@5.7.0(@types/node@22.7.3)': dependencies: ajv: 8.13.0 ajv-draft-04: 1.0.0(ajv@8.13.0) @@ -8694,50 +8694,50 @@ snapshots: resolve: 1.22.8 semver: 7.5.4 optionalDependencies: - '@types/node': 22.7.2 + '@types/node': 22.7.3 '@rushstack/rig-package@0.5.3': dependencies: resolve: 1.22.8 strip-json-comments: 3.1.1 - '@rushstack/terminal@0.14.0(@types/node@22.7.2)': + '@rushstack/terminal@0.14.0(@types/node@22.7.3)': dependencies: - '@rushstack/node-core-library': 5.7.0(@types/node@22.7.2) + '@rushstack/node-core-library': 5.7.0(@types/node@22.7.3) supports-color: 8.1.1 optionalDependencies: - '@types/node': 22.7.2 + '@types/node': 22.7.3 - '@rushstack/ts-command-line@4.22.6(@types/node@22.7.2)': + '@rushstack/ts-command-line@4.22.6(@types/node@22.7.3)': dependencies: - '@rushstack/terminal': 0.14.0(@types/node@22.7.2) + '@rushstack/terminal': 0.14.0(@types/node@22.7.3) '@types/argparse': 1.0.38 argparse: 1.0.10 string-argv: 0.3.2 transitivePeerDependencies: - '@types/node' - '@shikijs/core@1.19.0': + '@shikijs/core@1.20.0': dependencies: - '@shikijs/engine-javascript': 1.19.0 - '@shikijs/engine-oniguruma': 1.19.0 - '@shikijs/types': 1.19.0 + '@shikijs/engine-javascript': 1.20.0 + '@shikijs/engine-oniguruma': 1.20.0 + '@shikijs/types': 1.20.0 '@shikijs/vscode-textmate': 9.2.2 '@types/hast': 3.0.4 hast-util-to-html: 9.0.3 - '@shikijs/engine-javascript@1.19.0': + '@shikijs/engine-javascript@1.20.0': dependencies: - '@shikijs/types': 1.19.0 + '@shikijs/types': 1.20.0 '@shikijs/vscode-textmate': 9.2.2 oniguruma-to-js: 0.4.3 - '@shikijs/engine-oniguruma@1.19.0': + '@shikijs/engine-oniguruma@1.20.0': dependencies: - '@shikijs/types': 1.19.0 + '@shikijs/types': 1.20.0 '@shikijs/vscode-textmate': 9.2.2 - '@shikijs/types@1.19.0': + '@shikijs/types@1.20.0': dependencies: '@shikijs/vscode-textmate': 9.2.2 '@types/hast': 3.0.4 @@ -8884,43 +8884,43 @@ snapshots: dependencies: remove-accents: 0.5.0 - '@tanstack/react-router@1.58.9(@tanstack/router-generator@1.58.1)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)': + '@tanstack/react-router@1.58.11(@tanstack/router-generator@1.58.1)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)': dependencies: '@tanstack/history': 1.57.6 - '@tanstack/react-store': 0.5.5(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + '@tanstack/react-store': 0.5.5(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) tiny-invariant: 1.3.3 tiny-warning: 1.0.3 optionalDependencies: '@tanstack/router-generator': 1.58.1 - '@tanstack/react-store@0.5.5(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)': + '@tanstack/react-store@0.5.5(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)': dependencies: '@tanstack/store': 0.5.5 - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) - use-sync-external-store: 1.2.2(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) + use-sync-external-store: 1.2.2(react@19.0.0-rc-67fee58b-20240926) - '@tanstack/react-table@8.20.5(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)': + '@tanstack/react-table@8.20.5(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)': dependencies: '@tanstack/table-core': 8.20.5 - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) - '@tanstack/react-virtual@3.10.6(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)': + '@tanstack/react-virtual@3.10.6(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)': dependencies: '@tanstack/virtual-core': 3.10.6 - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) - '@tanstack/router-devtools@1.58.9(@tanstack/react-router@1.58.9(@tanstack/router-generator@1.58.1)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926))(csstype@3.1.3)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)': + '@tanstack/router-devtools@1.58.11(@tanstack/react-router@1.58.11(@tanstack/router-generator@1.58.1)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926))(csstype@3.1.3)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)': dependencies: - '@tanstack/react-router': 1.58.9(@tanstack/router-generator@1.58.1)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + '@tanstack/react-router': 1.58.11(@tanstack/router-generator@1.58.1)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) clsx: 2.1.1 goober: 2.1.14(csstype@3.1.3) - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) transitivePeerDependencies: - csstype @@ -8931,7 +8931,7 @@ snapshots: tsx: 4.19.1 zod: 3.23.8 - '@tanstack/router-plugin@1.58.10(vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0))(webpack-sources@3.2.3)': + '@tanstack/router-plugin@1.58.10(vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0))(webpack-sources@3.2.3)': dependencies: '@babel/core': 7.25.2 '@babel/generator': 7.25.6 @@ -8952,14 +8952,14 @@ snapshots: unplugin: 1.14.1(webpack-sources@3.2.3) zod: 3.23.8 optionalDependencies: - vite: 5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) + vite: 5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) transitivePeerDependencies: - supports-color - webpack-sources - '@tanstack/router-zod-adapter@1.58.9(@tanstack/react-router@1.58.9(@tanstack/router-generator@1.58.1)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926))(zod@3.23.8)': + '@tanstack/router-zod-adapter@1.58.11(@tanstack/react-router@1.58.11(@tanstack/router-generator@1.58.1)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926))(zod@3.23.8)': dependencies: - '@tanstack/react-router': 1.58.9(@tanstack/router-generator@1.58.1)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + '@tanstack/react-router': 1.58.11(@tanstack/router-generator@1.58.1)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) zod: 3.23.8 '@tanstack/store@0.5.5': {} @@ -9099,12 +9099,12 @@ snapshots: dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 22.7.2 + '@types/node': 22.7.3 '@types/responselike': 1.0.3 '@types/conventional-commits-parser@5.0.0': dependencies: - '@types/node': 22.7.2 + '@types/node': 22.7.3 '@types/d3-array@3.2.1': {} @@ -9240,7 +9240,7 @@ snapshots: '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 22.7.2 + '@types/node': 22.7.3 '@types/geojson@7946.0.14': {} @@ -9258,11 +9258,11 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 22.7.2 + '@types/node': 22.7.3 '@types/keyv@3.1.4': dependencies: - '@types/node': 22.7.2 + '@types/node': 22.7.3 '@types/lodash-es@4.17.12': dependencies: @@ -9282,7 +9282,7 @@ snapshots: dependencies: undici-types: 6.19.8 - '@types/node@22.7.2': + '@types/node@22.7.3': dependencies: undici-types: 6.19.8 @@ -9304,7 +9304,7 @@ snapshots: '@types/responselike@1.0.3': dependencies: - '@types/node': 22.7.2 + '@types/node': 22.7.3 '@types/retry@0.12.2': {} @@ -9316,7 +9316,7 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 22.7.2 + '@types/node': 22.7.3 optional: true '@typescript-eslint/eslint-plugin@8.7.0(@typescript-eslint/parser@8.7.0(eslint@8.57.1)(typescript@5.6.2))(eslint@8.57.1)(typescript@5.6.2)': @@ -9402,21 +9402,21 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@vitejs/plugin-react-swc@3.7.0(vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0))': + '@vitejs/plugin-react-swc@3.7.0(vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0))': dependencies: '@swc/core': 1.6.1 - vite: 5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) + vite: 5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) transitivePeerDependencies: - '@swc/helpers' - '@vitejs/plugin-react@4.3.1(vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0))': + '@vitejs/plugin-react@4.3.1(vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0))': dependencies: '@babel/core': 7.24.5 '@babel/plugin-transform-react-jsx-self': 7.24.5(@babel/core@7.24.5) '@babel/plugin-transform-react-jsx-source': 7.24.1(@babel/core@7.24.5) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) + vite: 5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) transitivePeerDependencies: - supports-color @@ -9506,14 +9506,14 @@ snapshots: clean-stack: 5.2.0 indent-string: 5.0.0 - ahooks@3.8.1(react@19.0.0-rc-778e1ed2-20240926): + ahooks@3.8.1(react@19.0.0-rc-67fee58b-20240926): dependencies: '@babel/runtime': 7.24.8 dayjs: 1.11.12 intersection-observer: 0.12.2 js-cookie: 3.0.5 lodash: 4.17.21 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 react-fast-compare: 3.2.2 resize-observer-polyfill: 1.5.1 screenfull: 5.2.0 @@ -9555,16 +9555,16 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - allotment@1.20.2(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926): + allotment@1.20.2(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926): dependencies: classnames: 2.5.1 eventemitter3: 5.0.1 lodash.clamp: 4.0.3 lodash.debounce: 4.0.8 lodash.isequal: 4.5.0 - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) - use-resize-observer: 9.1.0(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) + use-resize-observer: 9.1.0(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) ansi-align@2.0.0: dependencies: @@ -9998,9 +9998,9 @@ snapshots: dependencies: toggle-selection: 1.0.6 - cosmiconfig-typescript-loader@5.0.0(@types/node@22.7.2)(cosmiconfig@9.0.0(typescript@5.6.2))(typescript@5.6.2): + cosmiconfig-typescript-loader@5.0.0(@types/node@22.7.3)(cosmiconfig@9.0.0(typescript@5.6.2))(typescript@5.6.2): dependencies: - '@types/node': 22.7.2 + '@types/node': 22.7.3 cosmiconfig: 9.0.0(typescript@5.6.2) jiti: 1.21.6 typescript: 5.6.2 @@ -11024,13 +11024,13 @@ snapshots: fraction.js@4.3.7: {} - framer-motion@12.0.0-alpha.1(@emotion/is-prop-valid@1.3.0)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926): + framer-motion@12.0.0-alpha.1(@emotion/is-prop-valid@1.3.0)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926): dependencies: tslib: 2.6.2 optionalDependencies: '@emotion/is-prop-valid': 1.3.0 - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) fs-extra@11.2.0: dependencies: @@ -11642,10 +11642,10 @@ snapshots: jju@1.4.0: {} - jotai@2.10.0(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1): + jotai@2.10.0(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1): optionalDependencies: '@types/react': types-react@19.0.0-rc.1 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 js-cookie@2.2.1: {} @@ -11713,11 +11713,11 @@ snapshots: kind-of@6.0.3: {} - knip@5.30.5(@types/node@22.7.2)(typescript@5.6.2): + knip@5.30.6(@types/node@22.7.3)(typescript@5.6.2): dependencies: '@nodelib/fs.walk': 1.2.8 '@snyk/github-codeowners': 1.1.0 - '@types/node': 22.7.2 + '@types/node': 22.7.3 easy-table: 1.2.0 enhanced-resolve: 5.17.1 fast-glob: 3.3.2 @@ -11892,19 +11892,19 @@ snapshots: escape-string-regexp: 4.0.0 optional: true - material-react-table@3.0.1(scdjpuj6p6tus776axypnmttum): + material-react-table@3.0.1(nlfhyyeq2nu7jsjvmhefqx54wq): dependencies: - '@emotion/react': 11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@mui/icons-material': 6.1.1(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@mui/material': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@mui/x-date-pickers': 7.9.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(dayjs@1.11.13)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@emotion/react': 11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@mui/icons-material': 6.1.1(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@mui/material': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@mui/x-date-pickers': 7.9.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(dayjs@1.11.13)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) '@tanstack/match-sorter-utils': 8.19.4 - '@tanstack/react-table': 8.20.5(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) - '@tanstack/react-virtual': 3.10.6(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) + '@tanstack/react-table': 8.20.5(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) + '@tanstack/react-virtual': 3.10.6(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) highlight-words: 1.2.2 - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) mathml-tag-names@2.1.3: {} @@ -12237,14 +12237,14 @@ snapshots: muggle-string@0.4.1: {} - mui-color-input@4.0.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1): + mui-color-input@4.0.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1): dependencies: '@ctrl/tinycolor': 4.1.0 - '@emotion/react': 11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@mui/material': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + '@emotion/react': 11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@emotion/styled': 11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@mui/material': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) optionalDependencies: '@types/react': types-react@19.0.0-rc.1 @@ -12254,15 +12254,15 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 - nano-css@5.6.2(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926): + nano-css@5.6.2(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926): dependencies: '@jridgewell/sourcemap-codec': 1.5.0 css-tree: 1.1.3 csstype: 3.1.3 fastest-stable-stringify: 2.0.2 inline-style-prefixer: 7.0.1 - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) rtl-css-js: 1.16.1 stacktrace-js: 2.0.2 stylis: 4.3.2 @@ -12805,50 +12805,50 @@ snapshots: - supports-color - utf-8-validate - react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926): + react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926): dependencies: - react: 19.0.0-rc-778e1ed2-20240926 - scheduler: 0.25.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 + scheduler: 0.25.0-rc-67fee58b-20240926 - react-error-boundary@4.0.13(react@19.0.0-rc-778e1ed2-20240926): + react-error-boundary@4.0.13(react@19.0.0-rc-67fee58b-20240926): dependencies: '@babel/runtime': 7.24.5 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 react-fast-compare@3.2.2: {} - react-fast-marquee@1.6.5(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926): + react-fast-marquee@1.6.5(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926): dependencies: - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) - react-hook-form-mui@7.2.0(kxevavldinoaaue37dtxsp7rui): + react-hook-form-mui@7.2.0(sgiyhgbj7j5wqkzxbwdllyfaoi): dependencies: - '@mui/material': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - react: 19.0.0-rc-778e1ed2-20240926 - react-hook-form: 7.52.1(react@19.0.0-rc-778e1ed2-20240926) + '@mui/material': 6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + react: 19.0.0-rc-67fee58b-20240926 + react-hook-form: 7.52.1(react@19.0.0-rc-67fee58b-20240926) optionalDependencies: - '@mui/icons-material': 6.1.1(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) - '@mui/x-date-pickers': 7.9.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1))(dayjs@1.11.13)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1) + '@mui/icons-material': 6.1.1(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) + '@mui/x-date-pickers': 7.9.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@mui/material@6.1.1(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(@emotion/styled@11.13.0(@emotion/react@11.13.3(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1))(dayjs@1.11.13)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1) - react-hook-form@7.52.1(react@19.0.0-rc-778e1ed2-20240926): + react-hook-form@7.52.1(react@19.0.0-rc-67fee58b-20240926): dependencies: - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 - react-i18next@15.0.2(i18next@23.15.1)(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926): + react-i18next@15.0.2(i18next@23.15.1)(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926): dependencies: '@babel/runtime': 7.25.6 html-parse-stringify: 3.0.1 i18next: 23.15.1 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 optionalDependencies: - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) react-is@16.13.1: {} react-is@18.3.1: {} - react-markdown@9.0.1(react@19.0.0-rc-778e1ed2-20240926)(types-react@19.0.0-rc.1): + react-markdown@9.0.1(react@19.0.0-rc-67fee58b-20240926)(types-react@19.0.0-rc.1): dependencies: '@types/hast': 3.0.4 '@types/react': types-react@19.0.0-rc.1 @@ -12856,7 +12856,7 @@ snapshots: hast-util-to-jsx-runtime: 2.3.0 html-url-attributes: 3.0.0 mdast-util-to-hast: 13.1.0 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 remark-parse: 11.0.0 remark-rehype: 11.1.0 unified: 11.0.4 @@ -12867,39 +12867,39 @@ snapshots: react-refresh@0.14.2: {} - react-router-dom@6.26.2(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926): + react-router-dom@6.26.2(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926): dependencies: '@remix-run/router': 1.19.2 - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) - react-router: 6.26.2(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) + react-router: 6.26.2(react@19.0.0-rc-67fee58b-20240926) - react-router@6.26.2(react@19.0.0-rc-778e1ed2-20240926): + react-router@6.26.2(react@19.0.0-rc-67fee58b-20240926): dependencies: '@remix-run/router': 1.19.2 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 - react-split-grid@1.0.4(react@19.0.0-rc-778e1ed2-20240926): + react-split-grid@1.0.4(react@19.0.0-rc-67fee58b-20240926): dependencies: prop-types: 15.8.1 - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 split-grid: 1.0.11 - react-transition-group@4.4.5(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926): + react-transition-group@4.4.5(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926): dependencies: '@babel/runtime': 7.25.6 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) - react-universal-interface@0.6.2(react@19.0.0-rc-778e1ed2-20240926)(tslib@2.6.2): + react-universal-interface@0.6.2(react@19.0.0-rc-67fee58b-20240926)(tslib@2.6.2): dependencies: - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 tslib: 2.6.2 - react-use@17.5.1(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926): + react-use@17.5.1(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926): dependencies: '@types/js-cookie': 2.2.7 '@xobotyi/scrollbar-width': 1.9.5 @@ -12907,10 +12907,10 @@ snapshots: fast-deep-equal: 3.1.3 fast-shallow-equal: 1.0.0 js-cookie: 2.2.1 - nano-css: 5.6.2(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926) - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) - react-universal-interface: 0.6.2(react@19.0.0-rc-778e1ed2-20240926)(tslib@2.6.2) + nano-css: 5.6.2(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) + react-universal-interface: 0.6.2(react@19.0.0-rc-67fee58b-20240926)(tslib@2.6.2) resize-observer-polyfill: 1.5.1 screenfull: 5.2.0 set-harmonic-interval: 1.0.1 @@ -12918,7 +12918,7 @@ snapshots: ts-easing: 0.2.0 tslib: 2.6.2 - react@19.0.0-rc-778e1ed2-20240926: {} + react@19.0.0-rc-67fee58b-20240926: {} read-cache@1.0.0: dependencies: @@ -13214,7 +13214,7 @@ snapshots: sax@1.3.0: {} - scheduler@0.25.0-rc-778e1ed2-20240926: {} + scheduler@0.25.0-rc-67fee58b-20240926: {} screenfull@5.2.0: {} @@ -13274,12 +13274,12 @@ snapshots: shell-quote@1.8.1: {} - shiki@1.19.0: + shiki@1.20.0: dependencies: - '@shikijs/core': 1.19.0 - '@shikijs/engine-javascript': 1.19.0 - '@shikijs/engine-oniguruma': 1.19.0 - '@shikijs/types': 1.19.0 + '@shikijs/core': 1.20.0 + '@shikijs/engine-javascript': 1.20.0 + '@shikijs/engine-oniguruma': 1.20.0 + '@shikijs/types': 1.20.0 '@shikijs/vscode-textmate': 9.2.2 '@types/hast': 3.0.4 @@ -13622,11 +13622,11 @@ snapshots: svg-tags@1.0.0: {} - swr@2.2.5(react@19.0.0-rc-778e1ed2-20240926): + swr@2.2.5(react@19.0.0-rc-67fee58b-20240926): dependencies: client-only: 0.0.1 - react: 19.0.0-rc-778e1ed2-20240926 - use-sync-external-store: 1.2.2(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + use-sync-external-store: 1.2.2(react@19.0.0-rc-67fee58b-20240926) synckit@0.9.1: dependencies: @@ -14065,15 +14065,15 @@ snapshots: dependencies: prepend-http: 1.0.4 - use-resize-observer@9.1.0(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926): + use-resize-observer@9.1.0(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926): dependencies: '@juggle/resize-observer': 3.4.0 - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) - use-sync-external-store@1.2.2(react@19.0.0-rc-778e1ed2-20240926): + use-sync-external-store@1.2.2(react@19.0.0-rc-67fee58b-20240926): dependencies: - react: 19.0.0-rc-778e1ed2-20240926 + react: 19.0.0-rc-67fee58b-20240926 utf-8-validate@5.0.10: dependencies: @@ -14096,10 +14096,10 @@ snapshots: unist-util-stringify-position: 4.0.0 vfile-message: 4.0.2 - virtua@0.34.2(react-dom@19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926))(react@19.0.0-rc-778e1ed2-20240926): + virtua@0.34.2(react-dom@19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926))(react@19.0.0-rc-67fee58b-20240926): optionalDependencies: - react: 19.0.0-rc-778e1ed2-20240926 - react-dom: 19.0.0-rc-778e1ed2-20240926(react@19.0.0-rc-778e1ed2-20240926) + react: 19.0.0-rc-67fee58b-20240926 + react-dom: 19.0.0-rc-67fee58b-20240926(react@19.0.0-rc-67fee58b-20240926) vite-bundle-visualizer@1.2.1(rollup@4.21.0): dependencies: @@ -14111,9 +14111,9 @@ snapshots: - rollup - supports-color - vite-plugin-dts@4.2.2(@types/node@22.7.2)(rollup@4.21.0)(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)): + vite-plugin-dts@4.2.2(@types/node@22.7.3)(rollup@4.21.0)(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)): dependencies: - '@microsoft/api-extractor': 7.47.7(@types/node@22.7.2) + '@microsoft/api-extractor': 7.47.7(@types/node@22.7.3) '@rollup/pluginutils': 5.1.0(rollup@4.21.0) '@volar/typescript': 2.4.5 '@vue/language-core': 2.1.6(typescript@5.6.2) @@ -14124,49 +14124,49 @@ snapshots: magic-string: 0.30.11 typescript: 5.6.2 optionalDependencies: - vite: 5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) + vite: 5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) transitivePeerDependencies: - '@types/node' - rollup - supports-color - vite-plugin-sass-dts@1.3.29(postcss@8.4.47)(prettier@3.3.3)(sass-embedded@1.78.0)(vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)): + vite-plugin-sass-dts@1.3.29(postcss@8.4.47)(prettier@3.3.3)(sass-embedded@1.78.0)(vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)): dependencies: postcss: 8.4.47 postcss-js: 4.0.1(postcss@8.4.47) prettier: 3.3.3 sass-embedded: 1.78.0 - vite: 5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) + vite: 5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) - vite-plugin-svgr@4.2.0(rollup@4.21.0)(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)): + vite-plugin-svgr@4.2.0(rollup@4.21.0)(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)): dependencies: '@rollup/pluginutils': 5.1.0(rollup@4.21.0) '@svgr/core': 8.1.0(typescript@5.6.2) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.6.2)) - vite: 5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) + vite: 5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) transitivePeerDependencies: - rollup - supports-color - typescript - vite-tsconfig-paths@5.0.1(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)): + vite-tsconfig-paths@5.0.1(typescript@5.6.2)(vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0)): dependencies: debug: 4.3.6 globrex: 0.1.2 tsconfck: 3.0.3(typescript@5.6.2) optionalDependencies: - vite: 5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) + vite: 5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0) transitivePeerDependencies: - supports-color - typescript - vite@5.4.8(@types/node@22.7.2)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0): + vite@5.4.8(@types/node@22.7.3)(less@4.2.0)(sass-embedded@1.78.0)(sass@1.79.3)(stylus@0.62.0): dependencies: esbuild: 0.21.5 postcss: 8.4.47 rollup: 4.21.0 optionalDependencies: - '@types/node': 22.7.2 + '@types/node': 22.7.3 fsevents: 2.3.3 less: 4.2.0 sass: 1.79.3 diff --git a/lede/package/kernel/linux/modules/netdevices.mk b/lede/package/kernel/linux/modules/netdevices.mk index 6a8bfd3de0..cdedbf83ea 100644 --- a/lede/package/kernel/linux/modules/netdevices.mk +++ b/lede/package/kernel/linux/modules/netdevices.mk @@ -483,6 +483,72 @@ endef $(eval $(call KernelPackage,phy-aquantia)) +define KernelPackage/dsa + SUBMENU:=$(NETWORK_DEVICES_MENU) + TITLE:=Distributed Switch Architecture support + DEPENDS:=+kmod-mdio-devres +kmod-net-selftests +kmod-phylink + KCONFIG:=CONFIG_NET_DSA + FILES:=$(LINUX_DIR)/net/dsa/dsa_core.ko +endef + +define KernelPackage/dsa/description + Kernel module support for Distributed Switch Architecture +endef + +$(eval $(call KernelPackage,dsa)) + +define KernelPackage/dsa-tag-dsa + SUBMENU:=$(NETWORK_DEVICES_MENU) + TITLE:=Marvell DSA type DSA and EDSA taggers + DEPENDS:=+kmod-dsa + KCONFIG:= CONFIG_NET_DSA_TAG_DSA_COMMON \ + CONFIG_NET_DSA_TAG_DSA \ + CONFIG_NET_DSA_TAG_EDSA + FILES:=$(LINUX_DIR)/net/dsa/tag_dsa.ko + AUTOLOAD:=$(call AutoLoad,40,tag_dsa,1) +endef + +define KernelPackage/dsa-tag-dsa/description + Kernel modules for Marvell DSA and EDSA tagging +endef + +$(eval $(call KernelPackage,dsa-tag-dsa)) + +define KernelPackage/dsa-mv88e6xxx + SUBMENU:=$(NETWORK_DEVICES_MENU) + TITLE:=Marvell MV88E6XXX DSA Switch + DEPENDS:=+kmod-dsa +kmod-ptp +kmod-phy-marvell +kmod-dsa-tag-dsa + KCONFIG:=CONFIG_NET_DSA_MV88E6XXX \ + CONFIG_NET_DSA_MV88E6XXX_PTP=y + FILES:=$(LINUX_DIR)/drivers/net/dsa/mv88e6xxx/mv88e6xxx.ko + AUTOLOAD:=$(call AutoLoad,41,mv88e6xxx,1) +endef + +define KernelPackage/dsa-mv88e6xxx/description + Kernel modules for MV88E6XXX DSA switches +endef + +$(eval $(call KernelPackage,dsa-mv88e6xxx)) + +define KernelPackage/dsa-qca8k + SUBMENU:=$(NETWORK_DEVICES_MENU) + TITLE:=Qualcomm Atheros QCA8xxx switch family DSA support + DEPENDS:=+kmod-dsa +kmod-regmap-core + KCONFIG:= \ + CONFIG_NET_DSA_QCA8K \ + CONFIG_NET_DSA_QCA8K_LEDS_SUPPORT=y \ + CONFIG_NET_DSA_TAG_QCA + FILES:= \ + $(LINUX_DIR)/drivers/net/dsa/qca/qca8k.ko \ + $(LINUX_DIR)/net/dsa/tag_qca.ko + AUTOLOAD:=$(call AutoLoad,42,qca8k,1) +endef + +define KernelPackage/dsa-qca8k/description + DSA based kernel modules for the Qualcomm Atheros QCA8xxx switch family +endef + +$(eval $(call KernelPackage,dsa-qca8k)) define KernelPackage/swconfig SUBMENU:=$(NETWORK_DEVICES_MENU) diff --git a/mihomo/adapter/adapter.go b/mihomo/adapter/adapter.go index 8136827a09..3efc8166f0 100644 --- a/mihomo/adapter/adapter.go +++ b/mihomo/adapter/adapter.go @@ -39,6 +39,11 @@ type Proxy struct { extra *xsync.MapOf[string, *internalProxyState] } +// Adapter implements C.Proxy +func (p *Proxy) Adapter() C.ProxyAdapter { + return p.ProxyAdapter +} + // AliveForTestUrl implements C.Proxy func (p *Proxy) AliveForTestUrl(url string) bool { if state, ok := p.extra.Load(url); ok { diff --git a/mihomo/adapter/inbound/listen_notwindows.go b/mihomo/adapter/inbound/listen_notwindows.go new file mode 100644 index 0000000000..8fdfb7b8e6 --- /dev/null +++ b/mihomo/adapter/inbound/listen_notwindows.go @@ -0,0 +1,14 @@ +//go:build !windows + +package inbound + +import ( + "net" + "os" +) + +const SupportNamedPipe = false + +func ListenNamedPipe(path string) (net.Listener, error) { + return nil, os.ErrInvalid +} diff --git a/mihomo/adapter/inbound/listen_windows.go b/mihomo/adapter/inbound/listen_windows.go new file mode 100644 index 0000000000..d19239da18 --- /dev/null +++ b/mihomo/adapter/inbound/listen_windows.go @@ -0,0 +1,32 @@ +package inbound + +import ( + "net" + "os" + + "github.com/metacubex/wireguard-go/ipc/namedpipe" + "golang.org/x/sys/windows" +) + +const SupportNamedPipe = true + +// windowsSDDL is the Security Descriptor set on the namedpipe. +// It provides read/write access to all users and the local system. +const windowsSDDL = "D:PAI(A;OICI;GWGR;;;BU)(A;OICI;GWGR;;;SY)" + +func ListenNamedPipe(path string) (net.Listener, error) { + sddl := os.Getenv("LISTEN_NAMEDPIPE_SDDL") + if sddl == "" { + sddl = windowsSDDL + } + securityDescriptor, err := windows.SecurityDescriptorFromString(sddl) + if err != nil { + return nil, err + } + namedpipeLC := namedpipe.ListenConfig{ + SecurityDescriptor: securityDescriptor, + InputBufferSize: 256 * 1024, + OutputBufferSize: 256 * 1024, + } + return namedpipeLC.Listen(path) +} diff --git a/mihomo/adapter/outbound/wireguard.go b/mihomo/adapter/outbound/wireguard.go index 6f5a18f35d..3928ab1b7e 100644 --- a/mihomo/adapter/outbound/wireguard.go +++ b/mihomo/adapter/outbound/wireguard.go @@ -296,7 +296,7 @@ func NewWireGuard(option WireGuardOption) (*WireGuard, error) { for i := range nss { nss[i].ProxyAdapter = refP } - outbound.resolver = dns.NewResolver(dns.Config{ + outbound.resolver, _ = dns.NewResolver(dns.Config{ Main: nss, IPv6: has6, }) diff --git a/mihomo/adapter/outboundgroup/util.go b/mihomo/adapter/outboundgroup/util.go index 84216377b1..66b2510c19 100644 --- a/mihomo/adapter/outboundgroup/util.go +++ b/mihomo/adapter/outboundgroup/util.go @@ -4,3 +4,7 @@ type SelectAble interface { Set(string) error ForceSet(name string) } + +var _ SelectAble = (*Fallback)(nil) +var _ SelectAble = (*URLTest)(nil) +var _ SelectAble = (*Selector)(nil) diff --git a/mihomo/component/auth/auth.go b/mihomo/component/auth/auth.go index b52fa13557..176b21d793 100644 --- a/mihomo/component/auth/auth.go +++ b/mihomo/component/auth/auth.go @@ -5,6 +5,11 @@ type Authenticator interface { Users() []string } +type AuthStore interface { + Authenticator() Authenticator + SetAuthenticator(Authenticator) +} + type AuthUser struct { User string Pass string diff --git a/mihomo/component/resolver/resolver.go b/mihomo/component/resolver/resolver.go index feb3f98fb5..bcdbb7e2c4 100644 --- a/mihomo/component/resolver/resolver.go +++ b/mihomo/component/resolver/resolver.go @@ -47,6 +47,7 @@ type Resolver interface { ExchangeContext(ctx context.Context, m *dns.Msg) (msg *dns.Msg, err error) Invalid() bool ClearCache() + ResetConnection() } // LookupIPv4WithResolver same as LookupIPv4, but with a resolver @@ -256,6 +257,15 @@ func LookupIPProxyServerHost(ctx context.Context, host string) ([]netip.Addr, er return LookupIP(ctx, host) } +func ResetConnection() { + if DefaultResolver != nil { + go DefaultResolver.ResetConnection() + } + if ProxyServerHostResolver != nil { + go ProxyServerHostResolver.ResetConnection() + } +} + func SortationAddr(ips []netip.Addr) (ipv4s, ipv6s []netip.Addr) { for _, v := range ips { if v.Unmap().Is4() { diff --git a/mihomo/config/config.go b/mihomo/config/config.go index 27cde1fbd2..9067d14ff9 100644 --- a/mihomo/config/config.go +++ b/mihomo/config/config.go @@ -103,6 +103,7 @@ type Controller struct { ExternalController string ExternalControllerTLS string ExternalControllerUnix string + ExternalControllerPipe string ExternalUI string ExternalDohServer string Secret string @@ -364,6 +365,7 @@ type RawConfig struct { LogLevel log.LogLevel `yaml:"log-level" json:"log-level"` IPv6 bool `yaml:"ipv6" json:"ipv6"` ExternalController string `yaml:"external-controller" json:"external-controller"` + ExternalControllerPipe string `yaml:"external-controller-pipe" json:"external-controller-pipe"` ExternalControllerUnix string `yaml:"external-controller-unix" json:"external-controller-unix"` ExternalControllerTLS string `yaml:"external-controller-tls" json:"external-controller-tls"` ExternalUI string `yaml:"external-ui" json:"external-ui"` @@ -769,6 +771,7 @@ func parseController(cfg *RawConfig) (*Controller, error) { ExternalController: cfg.ExternalController, ExternalUI: cfg.ExternalUI, Secret: cfg.Secret, + ExternalControllerPipe: cfg.ExternalControllerPipe, ExternalControllerUnix: cfg.ExternalControllerUnix, ExternalControllerTLS: cfg.ExternalControllerTLS, ExternalDohServer: cfg.ExternalDohServer, diff --git a/mihomo/constant/adapters.go b/mihomo/constant/adapters.go index cb47f87166..b303eb846b 100644 --- a/mihomo/constant/adapters.go +++ b/mihomo/constant/adapters.go @@ -158,6 +158,7 @@ type DelayHistoryStoreType int type Proxy interface { ProxyAdapter + Adapter() ProxyAdapter AliveForTestUrl(url string) bool DelayHistory() []DelayHistory ExtraDelayHistories() map[string]ProxyState diff --git a/mihomo/dns/client.go b/mihomo/dns/client.go index 096b96a7f5..62fc12f9c3 100644 --- a/mihomo/dns/client.go +++ b/mihomo/dns/client.go @@ -103,3 +103,5 @@ func (c *client) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, error) return ret.msg, ret.err } } + +func (c *client) ResetConnection() {} diff --git a/mihomo/dns/dhcp.go b/mihomo/dns/dhcp.go index dc1344f500..e3829b7c2c 100644 --- a/mihomo/dns/dhcp.go +++ b/mihomo/dns/dhcp.go @@ -53,6 +53,12 @@ func (d *dhcpClient) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, return } +func (d *dhcpClient) ResetConnection() { + for _, client := range d.clients { + client.ResetConnection() + } +} + func (d *dhcpClient) resolve(ctx context.Context) ([]dnsClient, error) { d.lock.Lock() diff --git a/mihomo/dns/doh.go b/mihomo/dns/doh.go index ffb65fcef0..027afd58cc 100644 --- a/mihomo/dns/doh.go +++ b/mihomo/dns/doh.go @@ -203,11 +203,23 @@ func (doh *dnsOverHTTPS) Close() (err error) { return doh.closeClient(doh.client) } -// closeClient cleans up resources used by client if necessary. Note, that at -// this point it should only be done for HTTP/3 as it may leak due to keep-alive -// connections. +func (doh *dnsOverHTTPS) ResetConnection() { + doh.clientMu.Lock() + defer doh.clientMu.Unlock() + + if doh.client == nil { + return + } + + _ = doh.closeClient(doh.client) + doh.client = nil +} + +// closeClient cleans up resources used by client if necessary. func (doh *dnsOverHTTPS) closeClient(client *http.Client) (err error) { - if isHTTP3(client) { + client.CloseIdleConnections() + + if isHTTP3(client) { // HTTP/3 may leak due to keep-alive connections. return client.Transport.(io.Closer).Close() } @@ -508,6 +520,13 @@ func (h *http3Transport) Close() (err error) { return h.baseTransport.Close() } +func (h *http3Transport) CloseIdleConnections() { + h.mu.RLock() + defer h.mu.RUnlock() + + h.baseTransport.CloseIdleConnections() +} + // createTransportH3 tries to create an HTTP/3 transport for this upstream. // We should be able to fall back to H1/H2 in case if HTTP/3 is unavailable or // if it is too slow. In order to do that, this method will run two probes diff --git a/mihomo/dns/doq.go b/mihomo/dns/doq.go index ad936f9575..29fdd00660 100644 --- a/mihomo/dns/doq.go +++ b/mihomo/dns/doq.go @@ -144,6 +144,10 @@ func (doq *dnsOverQUIC) Close() (err error) { return err } +func (doq *dnsOverQUIC) ResetConnection() { + doq.closeConnWithError(nil) +} + // exchangeQUIC attempts to open a QUIC connection, send the DNS message // through it and return the response it got from the server. func (doq *dnsOverQUIC) exchangeQUIC(ctx context.Context, msg *D.Msg) (resp *D.Msg, err error) { diff --git a/mihomo/dns/patch_android.go b/mihomo/dns/patch_android.go index 6579ef071a..e3dcd2492f 100644 --- a/mihomo/dns/patch_android.go +++ b/mihomo/dns/patch_android.go @@ -12,6 +12,7 @@ func FlushCacheWithDefaultResolver() { if r := resolver.DefaultResolver; r != nil { r.ClearCache() } + resolver.ResetConnection() } func UpdateSystemDNS(addr []string) { @@ -30,3 +31,9 @@ func UpdateSystemDNS(addr []string) { func (c *systemClient) getDnsClients() ([]dnsClient, error) { return systemResolver, nil } + +func (c *systemClient) ResetConnection() { + for _, r := range systemResolver { + r.ResetConnection() + } +} diff --git a/mihomo/dns/rcode.go b/mihomo/dns/rcode.go index 9777d2e77b..901d1019d3 100644 --- a/mihomo/dns/rcode.go +++ b/mihomo/dns/rcode.go @@ -48,3 +48,5 @@ func (r rcodeClient) ExchangeContext(ctx context.Context, m *D.Msg) (*D.Msg, err func (r rcodeClient) Address() string { return r.addr } + +func (r rcodeClient) ResetConnection() {} diff --git a/mihomo/dns/resolver.go b/mihomo/dns/resolver.go index e03feef46f..ec59f42857 100644 --- a/mihomo/dns/resolver.go +++ b/mihomo/dns/resolver.go @@ -24,6 +24,7 @@ import ( type dnsClient interface { ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, err error) Address() string + ResetConnection() } type dnsCache interface { @@ -48,7 +49,7 @@ type Resolver struct { group singleflight.Group[*D.Msg] cache dnsCache policy []dnsPolicy - proxyServer []dnsClient + defaultResolver *Resolver } func (r *Resolver) LookupIPPrimaryIPv4(ctx context.Context, host string) (ips []netip.Addr, err error) { @@ -376,6 +377,20 @@ func (r *Resolver) ClearCache() { } } +func (r *Resolver) ResetConnection() { + if r != nil { + for _, c := range r.main { + c.ResetConnection() + } + for _, c := range r.fallback { + c.ResetConnection() + } + if dr := r.defaultResolver; dr != nil { + dr.ResetConnection() + } + } +} + type NameServer struct { Net string Addr string @@ -425,16 +440,18 @@ type Config struct { CacheAlgorithm string } -func NewResolver(config Config) *Resolver { - var cache dnsCache - if config.CacheAlgorithm == "lru" { - cache = lru.New(lru.WithSize[string, *D.Msg](4096), lru.WithStale[string, *D.Msg](true)) +func (config Config) newCache() dnsCache { + if config.CacheAlgorithm == "" || config.CacheAlgorithm == "lru" { + return lru.New(lru.WithSize[string, *D.Msg](4096), lru.WithStale[string, *D.Msg](true)) } else { - cache = arc.New(arc.WithSize[string, *D.Msg](4096)) + return arc.New(arc.WithSize[string, *D.Msg](4096)) } +} + +func NewResolver(config Config) (r *Resolver, pr *Resolver) { defaultResolver := &Resolver{ main: transform(config.Default, nil), - cache: cache, + cache: config.newCache(), ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond, } @@ -465,27 +482,29 @@ func NewResolver(config Config) *Resolver { return } - if config.CacheAlgorithm == "" || config.CacheAlgorithm == "lru" { - cache = lru.New(lru.WithSize[string, *D.Msg](4096), lru.WithStale[string, *D.Msg](true)) - } else { - cache = arc.New(arc.WithSize[string, *D.Msg](4096)) - } - r := &Resolver{ + r = &Resolver{ ipv6: config.IPv6, main: cacheTransform(config.Main), - cache: cache, + cache: config.newCache(), hosts: config.Hosts, ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond, } + r.defaultResolver = defaultResolver + + if len(config.ProxyServer) != 0 { + pr = &Resolver{ + ipv6: config.IPv6, + main: cacheTransform(config.ProxyServer), + cache: config.newCache(), + hosts: config.Hosts, + ipv6Timeout: time.Duration(config.IPv6Timeout) * time.Millisecond, + } + } if len(config.Fallback) != 0 { r.fallback = cacheTransform(config.Fallback) } - if len(config.ProxyServer) != 0 { - r.proxyServer = cacheTransform(config.ProxyServer) - } - if len(config.Policy) != 0 { r.policy = make([]dnsPolicy, 0) @@ -516,18 +535,7 @@ func NewResolver(config Config) *Resolver { r.fallbackIPFilters = config.FallbackIPFilter r.fallbackDomainFilters = config.FallbackDomainFilter - return r -} - -func NewProxyServerHostResolver(old *Resolver) *Resolver { - r := &Resolver{ - ipv6: old.ipv6, - main: old.proxyServer, - cache: old.cache, - hosts: old.hosts, - ipv6Timeout: old.ipv6Timeout, - } - return r + return } var ParseNameServer func(servers []string) ([]NameServer, error) // define in config/config.go diff --git a/mihomo/dns/system_common.go b/mihomo/dns/system_common.go index 06dc0b3020..e6dabdcfff 100644 --- a/mihomo/dns/system_common.go +++ b/mihomo/dns/system_common.go @@ -69,3 +69,5 @@ func (c *systemClient) getDnsClients() ([]dnsClient, error) { } return nil, err } + +func (c *systemClient) ResetConnection() {} diff --git a/mihomo/docs/config.yaml b/mihomo/docs/config.yaml index b3515a2060..9c480b3f2a 100644 --- a/mihomo/docs/config.yaml +++ b/mihomo/docs/config.yaml @@ -63,6 +63,10 @@ external-controller-tls: 0.0.0.0:9443 # RESTful API HTTPS 监听地址,需要 # 测试方法: curl -v --unix-socket "mihomo.sock" http://localhost/ external-controller-unix: mihomo.sock +# RESTful API Windows namedpipe 监听地址 +# !!!注意: 从Windows namedpipe访问api接口不会验证secret, 如果开启请自行保证安全问题 !!! +external-controller-pipe: \\.\pipe\mihomo + # tcp-concurrent: true # TCP 并发连接所有 IP, 将使用最快握手的 TCP # 配置 WEB UI 目录,使用 http://{{external-controller}}/ui 访问 diff --git a/mihomo/go.mod b/mihomo/go.mod index 22af95b3b8..b74cee92e1 100644 --- a/mihomo/go.mod +++ b/mihomo/go.mod @@ -49,12 +49,12 @@ require ( github.com/vmihailenco/msgpack/v5 v5.4.1 github.com/wk8/go-ordered-map/v2 v2.1.8 gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 - go.uber.org/automaxprocs v1.5.3 + go.uber.org/automaxprocs v1.6.0 go4.org/netipx v0.0.0-20231129151722-fdeea329fbba - golang.org/x/crypto v0.26.0 + golang.org/x/crypto v0.27.0 golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa - golang.org/x/net v0.28.0 - golang.org/x/sys v0.24.0 + golang.org/x/net v0.29.0 + golang.org/x/sys v0.25.0 google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v3 v3.0.1 lukechampine.com/blake3 v1.3.0 @@ -111,7 +111,7 @@ require ( go.uber.org/mock v0.4.0 // indirect golang.org/x/mod v0.20.0 // indirect golang.org/x/sync v0.8.0 // indirect - golang.org/x/text v0.17.0 // indirect + golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.24.0 // indirect ) diff --git a/mihomo/go.sum b/mihomo/go.sum index 9b824fc561..ba2d181951 100644 --- a/mihomo/go.sum +++ b/mihomo/go.sum @@ -222,16 +222,16 @@ gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 h1:UNrDfkQqiE gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7/go.mod h1:E+rxHvJG9H6PUdzq9NRG6csuLN3XUx98BfGOVWNYnXs= gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec h1:FpfFs4EhNehiVfzQttTuxanPIT43FtkkCFypIod8LHo= gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec/go.mod h1:BZ1RAoRPbCxum9Grlv5aeksu2H8BiKehBYooU2LFiOQ= -go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= -go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= @@ -240,8 +240,8 @@ golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= @@ -261,12 +261,12 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg= -golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= diff --git a/mihomo/hub/executor/executor.go b/mihomo/hub/executor/executor.go index 66bbc89ba4..214407b477 100644 --- a/mihomo/hub/executor/executor.go +++ b/mihomo/hub/executor/executor.go @@ -118,6 +118,8 @@ func ApplyConfig(cfg *config.Config, force bool) { tunnel.OnRunning() hcCompatibleProvider(cfg.Providers) initExternalUI() + + resolver.ResetConnection() } func initInnerTcp() { @@ -127,7 +129,7 @@ func initInnerTcp() { func GetGeneral() *config.General { ports := listener.GetPorts() var authenticator []string - if auth := authStore.Authenticator(); auth != nil { + if auth := authStore.Default.Authenticator(); auth != nil { authenticator = auth.Users() } @@ -253,8 +255,7 @@ func updateDNS(c *config.DNS, generalIPv6 bool) { CacheAlgorithm: c.CacheAlgorithm, } - r := dns.NewResolver(cfg) - pr := dns.NewProxyServerHostResolver(r) + r, pr := dns.NewResolver(cfg) m := dns.NewEnhancer(cfg) // reuse cache of old host mapper @@ -422,7 +423,7 @@ func updateGeneral(general *config.General) { func updateUsers(users []auth.AuthUser) { authenticator := auth.NewAuthenticator(users) - authStore.SetAuthenticator(authenticator) + authStore.Default.SetAuthenticator(authenticator) if authenticator != nil { log.Infoln("Authentication of local server updated") } @@ -444,12 +445,12 @@ func patchSelectGroup(proxies map[string]C.Proxy) { } for name, proxy := range proxies { - outbound, ok := proxy.(*adapter.Proxy) + outbound, ok := proxy.(C.Proxy) if !ok { continue } - selector, ok := outbound.ProxyAdapter.(outboundgroup.SelectAble) + selector, ok := outbound.Adapter().(outboundgroup.SelectAble) if !ok { continue } diff --git a/mihomo/hub/hub.go b/mihomo/hub/hub.go index e22f721970..73a44eee66 100644 --- a/mihomo/hub/hub.go +++ b/mihomo/hub/hub.go @@ -27,6 +27,12 @@ func WithExternalControllerUnix(externalControllerUnix string) Option { } } +func WithExternalControllerPipe(externalControllerPipe string) Option { + return func(cfg *config.Config) { + cfg.Controller.ExternalControllerPipe = externalControllerPipe + } +} + func WithSecret(secret string) Option { return func(cfg *config.Config) { cfg.Controller.Secret = secret @@ -47,6 +53,7 @@ func applyRoute(cfg *config.Config) { Addr: cfg.Controller.ExternalController, TLSAddr: cfg.Controller.ExternalControllerTLS, UnixAddr: cfg.Controller.ExternalControllerUnix, + PipeAddr: cfg.Controller.ExternalControllerPipe, Secret: cfg.Controller.Secret, Certificate: cfg.TLS.Certificate, PrivateKey: cfg.TLS.PrivateKey, diff --git a/mihomo/hub/route/groups.go b/mihomo/hub/route/groups.go index c4e9501f2d..68d1f3542b 100644 --- a/mihomo/hub/route/groups.go +++ b/mihomo/hub/route/groups.go @@ -9,7 +9,6 @@ import ( "github.com/go-chi/chi/v5" "github.com/go-chi/render" - "github.com/metacubex/mihomo/adapter" "github.com/metacubex/mihomo/adapter/outboundgroup" "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/component/profile/cachefile" @@ -32,7 +31,7 @@ func GroupRouter() http.Handler { func getGroups(w http.ResponseWriter, r *http.Request) { var gs []C.Proxy for _, p := range tunnel.Proxies() { - if _, ok := p.(*adapter.Proxy).ProxyAdapter.(C.Group); ok { + if _, ok := p.Adapter().(C.Group); ok { gs = append(gs, p) } } @@ -43,7 +42,7 @@ func getGroups(w http.ResponseWriter, r *http.Request) { func getGroup(w http.ResponseWriter, r *http.Request) { proxy := r.Context().Value(CtxKeyProxy).(C.Proxy) - if _, ok := proxy.(*adapter.Proxy).ProxyAdapter.(C.Group); ok { + if _, ok := proxy.Adapter().(C.Group); ok { render.JSON(w, r, proxy) return } @@ -53,25 +52,15 @@ func getGroup(w http.ResponseWriter, r *http.Request) { func getGroupDelay(w http.ResponseWriter, r *http.Request) { proxy := r.Context().Value(CtxKeyProxy).(C.Proxy) - group, ok := proxy.(*adapter.Proxy).ProxyAdapter.(C.Group) + group, ok := proxy.Adapter().(C.Group) if !ok { render.Status(r, http.StatusNotFound) render.JSON(w, r, ErrNotFound) return } - switch proxy.(*adapter.Proxy).Type() { - case C.URLTest: - if urlTestGroup, ok := proxy.(*adapter.Proxy).ProxyAdapter.(*outboundgroup.URLTest); ok { - urlTestGroup.ForceSet("") - } - case C.Fallback: - if fallbackGroup, ok := proxy.(*adapter.Proxy).ProxyAdapter.(*outboundgroup.Fallback); ok { - fallbackGroup.ForceSet("") - } - } - - if proxy.(*adapter.Proxy).Type() != C.Selector { + if selectAble, ok := proxy.Adapter().(outboundgroup.SelectAble); ok && proxy.Type() != C.Selector { + selectAble.ForceSet("") cachefile.Cache().SetSelected(proxy.Name(), "") } diff --git a/mihomo/hub/route/proxies.go b/mihomo/hub/route/proxies.go index 69c8e44651..ba4e03f902 100644 --- a/mihomo/hub/route/proxies.go +++ b/mihomo/hub/route/proxies.go @@ -7,7 +7,6 @@ import ( "strconv" "time" - "github.com/metacubex/mihomo/adapter" "github.com/metacubex/mihomo/adapter/outboundgroup" "github.com/metacubex/mihomo/common/utils" "github.com/metacubex/mihomo/component/profile/cachefile" @@ -31,6 +30,7 @@ func proxyRouter() http.Handler { r.Get("/", getProxy) r.Get("/delay", getProxyDelay) r.Put("/", updateProxy) + r.Delete("/", unfixedProxy) }) return r } @@ -81,8 +81,8 @@ func updateProxy(w http.ResponseWriter, r *http.Request) { return } - proxy := r.Context().Value(CtxKeyProxy).(*adapter.Proxy) - selector, ok := proxy.ProxyAdapter.(outboundgroup.SelectAble) + proxy := r.Context().Value(CtxKeyProxy).(C.Proxy) + selector, ok := proxy.Adapter().(outboundgroup.SelectAble) if !ok { render.Status(r, http.StatusBadRequest) render.JSON(w, r, newError("Must be a Selector")) @@ -146,3 +146,15 @@ func getProxyDelay(w http.ResponseWriter, r *http.Request) { "delay": delay, }) } + +func unfixedProxy(w http.ResponseWriter, r *http.Request) { + proxy := r.Context().Value(CtxKeyProxy).(C.Proxy) + if selectAble, ok := proxy.Adapter().(outboundgroup.SelectAble); ok && proxy.Type() != C.Selector { + selectAble.ForceSet("") + cachefile.Cache().SetSelected(proxy.Name(), "") + render.NoContent(w, r) + return + } + render.Status(r, http.StatusBadRequest) + render.JSON(w, r, ErrBadRequest) +} diff --git a/mihomo/hub/route/server.go b/mihomo/hub/route/server.go index b707756321..1810a707cf 100644 --- a/mihomo/hub/route/server.go +++ b/mihomo/hub/route/server.go @@ -35,6 +35,7 @@ var ( httpServer *http.Server tlsServer *http.Server unixServer *http.Server + pipeServer *http.Server ) type Traffic struct { @@ -51,6 +52,7 @@ type Config struct { Addr string TLSAddr string UnixAddr string + PipeAddr string Secret string Certificate string PrivateKey string @@ -62,6 +64,9 @@ func ReCreateServer(cfg *Config) { go start(cfg) go startTLS(cfg) go startUnix(cfg) + if inbound.SupportNamedPipe { + go startPipe(cfg) + } } func SetUIPath(path string) { @@ -223,6 +228,7 @@ func startUnix(cfg *Config) { log.Errorln("External controller unix listen error: %s", err) return } + _ = os.Chmod(addr, 0o666) log.Infoln("RESTful API unix listening at: %s", l.Addr().String()) server := &http.Server{ @@ -233,7 +239,37 @@ func startUnix(cfg *Config) { log.Errorln("External controller unix serve error: %s", err) } } +} +func startPipe(cfg *Config) { + // first stop existing server + if pipeServer != nil { + _ = pipeServer.Close() + pipeServer = nil + } + + // handle addr + if len(cfg.PipeAddr) > 0 { + if !strings.HasPrefix(cfg.PipeAddr, "\\\\.\\pipe\\") { // windows namedpipe must start with "\\.\pipe\" + log.Errorln("External controller pipe listen error: windows namedpipe must start with \"\\\\.\\pipe\\\"") + return + } + + l, err := inbound.ListenNamedPipe(cfg.PipeAddr) + if err != nil { + log.Errorln("External controller pipe listen error: %s", err) + return + } + log.Infoln("RESTful API pipe listening at: %s", l.Addr().String()) + + server := &http.Server{ + Handler: router(cfg.IsDebug, "", cfg.DohServer), + } + pipeServer = server + if err = server.Serve(l); err != nil { + log.Errorln("External controller pipe serve error: %s", err) + } + } } func setPrivateNetworkAccess(next http.Handler) http.Handler { diff --git a/mihomo/listener/auth/auth.go b/mihomo/listener/auth/auth.go index 772be3bdd7..9e7632e868 100644 --- a/mihomo/listener/auth/auth.go +++ b/mihomo/listener/auth/auth.go @@ -4,14 +4,30 @@ import ( "github.com/metacubex/mihomo/component/auth" ) -var authenticator auth.Authenticator - -func Authenticator() auth.Authenticator { - return authenticator +type authStore struct { + authenticator auth.Authenticator } -func SetAuthenticator(au auth.Authenticator) { - authenticator = au +func (a *authStore) Authenticator() auth.Authenticator { + return a.authenticator } -func Nil() auth.Authenticator { return nil } +func (a *authStore) SetAuthenticator(authenticator auth.Authenticator) { + a.authenticator = authenticator +} + +func NewAuthStore(authenticator auth.Authenticator) auth.AuthStore { + return &authStore{authenticator} +} + +var Default auth.AuthStore = NewAuthStore(nil) + +type nilAuthStore struct{} + +func (a *nilAuthStore) Authenticator() auth.Authenticator { + return nil +} + +func (a *nilAuthStore) SetAuthenticator(authenticator auth.Authenticator) {} + +var Nil auth.AuthStore = (*nilAuthStore)(nil) // always return nil, even call SetAuthenticator() with a non-nil authenticator diff --git a/mihomo/listener/http/proxy.go b/mihomo/listener/http/proxy.go index 04ab98eb8c..5c08cd458a 100644 --- a/mihomo/listener/http/proxy.go +++ b/mihomo/listener/http/proxy.go @@ -30,7 +30,7 @@ func (b *bodyWrapper) Read(p []byte) (n int, err error) { return n, err } -func HandleConn(c net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) { +func HandleConn(c net.Conn, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) { additions = append(additions, inbound.Placeholder) // Add a placeholder for InUser inUserIdx := len(additions) - 1 client := newClient(c, tunnel, additions) @@ -41,7 +41,7 @@ func HandleConn(c net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, conn := N.NewBufferedConn(c) - authenticator := getAuth() + authenticator := store.Authenticator() keepAlive := true trusted := authenticator == nil // disable authenticate if lru is nil lastUser := "" diff --git a/mihomo/listener/http/server.go b/mihomo/listener/http/server.go index 04f32f4ff5..24f07e8bd1 100644 --- a/mihomo/listener/http/server.go +++ b/mihomo/listener/http/server.go @@ -32,20 +32,20 @@ func (l *Listener) Close() error { } func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) { - return NewWithAuthenticator(addr, tunnel, authStore.Authenticator, additions...) + return NewWithAuthenticator(addr, tunnel, authStore.Default, additions...) } // NewWithAuthenticate // never change type traits because it's used in CMFA func NewWithAuthenticate(addr string, tunnel C.Tunnel, authenticate bool, additions ...inbound.Addition) (*Listener, error) { - getAuth := authStore.Authenticator + store := authStore.Default if !authenticate { - getAuth = authStore.Nil + store = authStore.Default } - return NewWithAuthenticator(addr, tunnel, getAuth, additions...) + return NewWithAuthenticator(addr, tunnel, store, additions...) } -func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) (*Listener, error) { +func NewWithAuthenticator(addr string, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) (*Listener, error) { isDefault := false if len(additions) == 0 { isDefault = true @@ -74,17 +74,17 @@ func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Auth continue } - getAuth := getAuth - if isDefault { // only apply on default listener + store := store + if isDefault || store == authStore.Default { // only apply on default listener if !inbound.IsRemoteAddrDisAllowed(conn.RemoteAddr()) { _ = conn.Close() continue } if inbound.SkipAuthRemoteAddr(conn.RemoteAddr()) { - getAuth = authStore.Nil + store = authStore.Nil } } - go HandleConn(conn, tunnel, getAuth, additions...) + go HandleConn(conn, tunnel, store, additions...) } }() diff --git a/mihomo/listener/inbound/auth.go b/mihomo/listener/inbound/auth.go index 41f18fc089..85e7249455 100644 --- a/mihomo/listener/inbound/auth.go +++ b/mihomo/listener/inbound/auth.go @@ -12,7 +12,7 @@ type AuthUser struct { type AuthUsers []AuthUser -func (a AuthUsers) GetAuth() func() auth.Authenticator { +func (a AuthUsers) GetAuthStore() auth.AuthStore { if a != nil { // structure's Decode will ensure value not nil when input has value even it was set an empty array if len(a) == 0 { return authStore.Nil @@ -25,7 +25,7 @@ func (a AuthUsers) GetAuth() func() auth.Authenticator { } } authenticator := auth.NewAuthenticator(users) - return func() auth.Authenticator { return authenticator } + return authStore.NewAuthStore(authenticator) } - return authStore.Authenticator + return authStore.Default } diff --git a/mihomo/listener/inbound/http.go b/mihomo/listener/inbound/http.go index c78abefd5f..e20a9a2357 100644 --- a/mihomo/listener/inbound/http.go +++ b/mihomo/listener/inbound/http.go @@ -45,7 +45,7 @@ func (h *HTTP) Address() string { // Listen implements constant.InboundListener func (h *HTTP) Listen(tunnel C.Tunnel) error { var err error - h.l, err = http.NewWithAuthenticator(h.RawAddress(), tunnel, h.config.Users.GetAuth(), h.Additions()...) + h.l, err = http.NewWithAuthenticator(h.RawAddress(), tunnel, h.config.Users.GetAuthStore(), h.Additions()...) if err != nil { return err } diff --git a/mihomo/listener/inbound/mixed.go b/mihomo/listener/inbound/mixed.go index 443a256452..1d79929acc 100644 --- a/mihomo/listener/inbound/mixed.go +++ b/mihomo/listener/inbound/mixed.go @@ -53,7 +53,7 @@ func (m *Mixed) Address() string { // Listen implements constant.InboundListener func (m *Mixed) Listen(tunnel C.Tunnel) error { var err error - m.l, err = mixed.NewWithAuthenticator(m.RawAddress(), tunnel, m.config.Users.GetAuth(), m.Additions()...) + m.l, err = mixed.NewWithAuthenticator(m.RawAddress(), tunnel, m.config.Users.GetAuthStore(), m.Additions()...) if err != nil { return err } diff --git a/mihomo/listener/inbound/socks.go b/mihomo/listener/inbound/socks.go index cf6d1ce433..119eec8281 100644 --- a/mihomo/listener/inbound/socks.go +++ b/mihomo/listener/inbound/socks.go @@ -71,7 +71,7 @@ func (s *Socks) Address() string { // Listen implements constant.InboundListener func (s *Socks) Listen(tunnel C.Tunnel) error { var err error - if s.stl, err = socks.NewWithAuthenticator(s.RawAddress(), tunnel, s.config.Users.GetAuth(), s.Additions()...); err != nil { + if s.stl, err = socks.NewWithAuthenticator(s.RawAddress(), tunnel, s.config.Users.GetAuthStore(), s.Additions()...); err != nil { return err } if s.udp { diff --git a/mihomo/listener/mixed/mixed.go b/mihomo/listener/mixed/mixed.go index ac3a0c5886..5ac6301153 100644 --- a/mihomo/listener/mixed/mixed.go +++ b/mihomo/listener/mixed/mixed.go @@ -37,10 +37,10 @@ func (l *Listener) Close() error { } func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) { - return NewWithAuthenticator(addr, tunnel, authStore.Authenticator, additions...) + return NewWithAuthenticator(addr, tunnel, authStore.Default, additions...) } -func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) (*Listener, error) { +func NewWithAuthenticator(addr string, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) (*Listener, error) { isDefault := false if len(additions) == 0 { isDefault = true @@ -68,24 +68,24 @@ func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Auth } continue } - getAuth := getAuth - if isDefault { // only apply on default listener + store := store + if isDefault || store == authStore.Default { // only apply on default listener if !inbound.IsRemoteAddrDisAllowed(c.RemoteAddr()) { _ = c.Close() continue } if inbound.SkipAuthRemoteAddr(c.RemoteAddr()) { - getAuth = authStore.Nil + store = authStore.Nil } } - go handleConn(c, tunnel, getAuth, additions...) + go handleConn(c, tunnel, store, additions...) } }() return ml, nil } -func handleConn(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) { +func handleConn(conn net.Conn, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) { bufConn := N.NewBufferedConn(conn) head, err := bufConn.Peek(1) if err != nil { @@ -94,10 +94,10 @@ func handleConn(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticato switch head[0] { case socks4.Version: - socks.HandleSocks4(bufConn, tunnel, getAuth, additions...) + socks.HandleSocks4(bufConn, tunnel, store, additions...) case socks5.Version: - socks.HandleSocks5(bufConn, tunnel, getAuth, additions...) + socks.HandleSocks5(bufConn, tunnel, store, additions...) default: - http.HandleConn(bufConn, tunnel, getAuth, additions...) + http.HandleConn(bufConn, tunnel, store, additions...) } } diff --git a/mihomo/listener/sing_tun/server.go b/mihomo/listener/sing_tun/server.go index c2c668b34e..79856c466c 100644 --- a/mihomo/listener/sing_tun/server.go +++ b/mihomo/listener/sing_tun/server.go @@ -440,6 +440,10 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis //l.openAndroidHotspot(tunOptions) + if !l.options.AutoDetectInterface { + resolver.ResetConnection() + } + if options.FileDescriptor != 0 { tunName = fmt.Sprintf("%s(fd=%d)", tunName, options.FileDescriptor) } @@ -507,6 +511,7 @@ func (l *Listener) FlushDefaultInterface() { if old := dialer.DefaultInterface.Swap(autoDetectInterfaceName); old != autoDetectInterfaceName { log.Warnln("[TUN] default interface changed by monitor, %s => %s", old, autoDetectInterfaceName) iface.FlushCache() + resolver.ResetConnection() // reset resolver's connection after default interface changed } return } diff --git a/mihomo/listener/socks/tcp.go b/mihomo/listener/socks/tcp.go index 950384c1f9..cc66613e2a 100644 --- a/mihomo/listener/socks/tcp.go +++ b/mihomo/listener/socks/tcp.go @@ -36,10 +36,10 @@ func (l *Listener) Close() error { } func New(addr string, tunnel C.Tunnel, additions ...inbound.Addition) (*Listener, error) { - return NewWithAuthenticator(addr, tunnel, authStore.Authenticator, additions...) + return NewWithAuthenticator(addr, tunnel, authStore.Default, additions...) } -func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) (*Listener, error) { +func NewWithAuthenticator(addr string, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) (*Listener, error) { isDefault := false if len(additions) == 0 { isDefault = true @@ -67,24 +67,24 @@ func NewWithAuthenticator(addr string, tunnel C.Tunnel, getAuth func() auth.Auth } continue } - getAuth := getAuth - if isDefault { // only apply on default listener + store := store + if isDefault || store == authStore.Default { // only apply on default listener if !inbound.IsRemoteAddrDisAllowed(c.RemoteAddr()) { _ = c.Close() continue } if inbound.SkipAuthRemoteAddr(c.RemoteAddr()) { - getAuth = authStore.Nil + store = authStore.Nil } } - go handleSocks(c, tunnel, getAuth, additions...) + go handleSocks(c, tunnel, store, additions...) } }() return sl, nil } -func handleSocks(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) { +func handleSocks(conn net.Conn, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) { bufConn := N.NewBufferedConn(conn) head, err := bufConn.Peek(1) if err != nil { @@ -94,16 +94,16 @@ func handleSocks(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticat switch head[0] { case socks4.Version: - HandleSocks4(bufConn, tunnel, getAuth, additions...) + HandleSocks4(bufConn, tunnel, store, additions...) case socks5.Version: - HandleSocks5(bufConn, tunnel, getAuth, additions...) + HandleSocks5(bufConn, tunnel, store, additions...) default: conn.Close() } } -func HandleSocks4(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) { - authenticator := getAuth() +func HandleSocks4(conn net.Conn, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) { + authenticator := store.Authenticator() addr, _, user, err := socks4.ServerHandshake(conn, authenticator) if err != nil { conn.Close() @@ -113,8 +113,8 @@ func HandleSocks4(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authentica tunnel.HandleTCPConn(inbound.NewSocket(socks5.ParseAddr(addr), conn, C.SOCKS4, additions...)) } -func HandleSocks5(conn net.Conn, tunnel C.Tunnel, getAuth func() auth.Authenticator, additions ...inbound.Addition) { - authenticator := getAuth() +func HandleSocks5(conn net.Conn, tunnel C.Tunnel, store auth.AuthStore, additions ...inbound.Addition) { + authenticator := store.Authenticator() target, command, user, err := socks5.ServerHandshake(conn, authenticator) if err != nil { conn.Close() diff --git a/mihomo/main.go b/mihomo/main.go index 8910a00653..505cdb2566 100644 --- a/mihomo/main.go +++ b/mihomo/main.go @@ -35,6 +35,7 @@ var ( externalUI string externalController string externalControllerUnix string + externalControllerPipe string secret string ) @@ -45,6 +46,7 @@ func init() { flag.StringVar(&externalUI, "ext-ui", os.Getenv("CLASH_OVERRIDE_EXTERNAL_UI_DIR"), "override external ui directory") flag.StringVar(&externalController, "ext-ctl", os.Getenv("CLASH_OVERRIDE_EXTERNAL_CONTROLLER"), "override external controller address") flag.StringVar(&externalControllerUnix, "ext-ctl-unix", os.Getenv("CLASH_OVERRIDE_EXTERNAL_CONTROLLER_UNIX"), "override external controller unix address") + flag.StringVar(&externalControllerPipe, "ext-ctl-pipe", os.Getenv("CLASH_OVERRIDE_EXTERNAL_CONTROLLER_PIPE"), "override external controller pipe address") flag.StringVar(&secret, "secret", os.Getenv("CLASH_OVERRIDE_SECRET"), "override secret for RESTful API") flag.BoolVar(&geodataMode, "m", false, "set geodata mode") flag.BoolVar(&version, "v", false, "show current version of mihomo") @@ -133,6 +135,9 @@ func main() { if externalControllerUnix != "" { options = append(options, hub.WithExternalControllerUnix(externalControllerUnix)) } + if externalControllerPipe != "" { + options = append(options, hub.WithExternalControllerPipe(externalControllerPipe)) + } if secret != "" { options = append(options, hub.WithSecret(secret)) } @@ -156,19 +161,9 @@ func main() { case <-termSign: return case <-hupSign: - var cfg *config.Config - var err error - if configString != "" { - cfg, err = executor.ParseWithBytes(configBytes) - } else { - cfg, err = executor.ParseWithPath(C.Path.Config()) - } - if err == nil { - hub.ApplyConfig(cfg) - } else { + if err := hub.Parse(configBytes, options...); err != nil { log.Errorln("Parse config error: %s", err.Error()) } - } } } diff --git a/openwrt-passwall/.github/workflows/Auto compile with openwrt sdk.yml b/openwrt-passwall/.github/workflows/Auto compile with openwrt sdk.yml index 6a97922cf2..dce62463d0 100644 --- a/openwrt-passwall/.github/workflows/Auto compile with openwrt sdk.yml +++ b/openwrt-passwall/.github/workflows/Auto compile with openwrt sdk.yml @@ -97,7 +97,7 @@ jobs: sudo -E rm -rf /usr/share/dotnet /etc/mysql /etc/php /etc/apt/sources.list.d /usr/local/lib/android echo "Install packages" sudo -E apt-get -qq update - sudo -E apt-get -qq install build-essential clang flex bison g++ gawk gcc-multilib g++-multilib gettext git libncurses5-dev libssl-dev python3-distutils rsync unzip zlib1g-dev file wget + sudo -E apt-get -qq install build-essential clang flex bison g++ gawk gcc-multilib g++-multilib gettext git libncurses-dev libssl-dev python3-distutils python3-setuptools rsync swig unzip zlib1g-dev file wget sudo -E apt-get -qq autoremove --purge sudo -E apt-get -qq clean @@ -235,7 +235,7 @@ jobs: sudo -E rm -rf /usr/share/dotnet /etc/mysql /etc/php /etc/apt/sources.list.d /usr/local/lib/android echo "install packages!!!!!!" sudo -E apt-get -qq update - sudo -E apt-get -qq install $(curl -fsSL https://github.com/smallprogram/OpenWrtAction/raw/main/diy_script/official_dependence) + sudo -E apt-get -qq install build-essential clang flex bison g++ gawk gcc-multilib g++-multilib gettext git libncurses-dev libssl-dev python3-distutils python3-setuptools rsync swig unzip zlib1g-dev file wget sudo -E apt-get -qq autoremove --purge sudo -E apt-get -qq clean diff --git a/openwrt-passwall2/.github/workflows/Auto compile with openwrt sdk.yml b/openwrt-passwall2/.github/workflows/Auto compile with openwrt sdk.yml index d8adfe3a07..6e5b35e018 100644 --- a/openwrt-passwall2/.github/workflows/Auto compile with openwrt sdk.yml +++ b/openwrt-passwall2/.github/workflows/Auto compile with openwrt sdk.yml @@ -94,7 +94,7 @@ jobs: df -hT echo "Install packages" sudo -E apt-get -qq update - sudo -E apt-get -qq install build-essential clang flex bison g++ gawk gcc-multilib g++-multilib gettext git libncurses5-dev libssl-dev python3-distutils rsync unzip zlib1g-dev file wget + sudo -E apt-get -qq install build-essential clang flex bison g++ gawk gcc-multilib g++-multilib gettext git libncurses-dev libssl-dev python3-distutils python3-setuptools rsync swig unzip zlib1g-dev file wget sudo -E apt-get -qq autoremove --purge sudo -E apt-get -qq clean @@ -249,7 +249,7 @@ jobs: df -hT echo "install packages!!!!!!" sudo -E apt-get -qq update - sudo -E apt-get -qq install $(curl -fsSL https://github.com/smallprogram/OpenWrtAction/raw/main/diy_script/official_dependence) + sudo -E apt-get -qq install build-essential clang flex bison g++ gawk gcc-multilib g++-multilib gettext git libncurses-dev libssl-dev python3-distutils python3-setuptools rsync swig unzip zlib1g-dev file wget sudo -E apt-get -qq autoremove --purge sudo -E apt-get -qq clean diff --git a/shadowsocks-rust/Cargo.lock b/shadowsocks-rust/Cargo.lock index 7146cbc1d1..1121f4c15a 100644 --- a/shadowsocks-rust/Cargo.lock +++ b/shadowsocks-rust/Cargo.lock @@ -1009,9 +1009,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.33" +version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" dependencies = [ "crc32fast", "miniz_oxide", @@ -3986,9 +3986,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tun2" -version = "3.1.4" +version = "3.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af810bc5d0c82f056aabd0d7448ba3ccb8bb586f2d5cb95692111ee67ccbccda" +checksum = "65414b3733383dcd25fa2f4dafac78dad8154cdc41d99c68152b834b1cf66c6b" dependencies = [ "bytes", "cfg-if", diff --git a/shadowsocks-rust/crates/shadowsocks-service/Cargo.toml b/shadowsocks-rust/crates/shadowsocks-service/Cargo.toml index 9658447569..50bb51c1c0 100644 --- a/shadowsocks-rust/crates/shadowsocks-service/Cargo.toml +++ b/shadowsocks-rust/crates/shadowsocks-service/Cargo.toml @@ -186,7 +186,7 @@ flate2 = { version = "1.0", optional = true } brotli = { version = "6.0", optional = true } zstd = { version = "0.13", optional = true } -tun2 = { version = "3.1.4", optional = true, default-features = false, features = [ +tun2 = { version = "3.1", optional = true, default-features = false, features = [ "async", ] } etherparse = { version = "0.16", optional = true } diff --git a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua index 5dd95324eb..2a387b5a6c 100644 --- a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua +++ b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua @@ -174,7 +174,7 @@ if has_xray then o.default = "10-20" o:depends("fragment", true) - o = s_xray:option(Flag, "noise", translate("Noise"), translate("UDP noise. Under some circumstances it can bypass some udp based protocol restrictions.")) + o = s_xray:option(Flag, "noise", translate("Noise"), translate("UDP noise, Under some circumstances it can bypass some UDP based protocol restrictions.")) o.default = 0 o = s_xray:option(Flag, "sniffing_override_dest", translate("Override the connection destination address"), translate("Override the connection destination address with the sniffed domain.")) diff --git a/small/luci-app-passwall/po/zh-cn/passwall.po b/small/luci-app-passwall/po/zh-cn/passwall.po index 59b5536719..da6f05a1fd 100644 --- a/small/luci-app-passwall/po/zh-cn/passwall.po +++ b/small/luci-app-passwall/po/zh-cn/passwall.po @@ -1660,8 +1660,8 @@ msgstr "分片间隔(ms)" msgid "Noise" msgstr "噪声" -msgid "UDP noise. Under some circumstances it can bypass some udp based protocol restrictions." -msgstr "UDP噪声。在某些情况下,它可以绕过一些针对UDP协议的限制。" +msgid "UDP noise, Under some circumstances it can bypass some UDP based protocol restrictions." +msgstr "UDP 噪声,在某些情况下可以绕过一些针对 UDP 协议的限制。" msgid "To send noise packets, select \"Noise\" in Xray Settings." msgstr "在 Xray 设置中勾选 “噪声” 以发送噪声包。" diff --git a/small/mihomo/Makefile b/small/mihomo/Makefile index 87187a5a40..7fe7167e4c 100644 --- a/small/mihomo/Makefile +++ b/small/mihomo/Makefile @@ -5,9 +5,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/MetaCubeX/mihomo.git -PKG_SOURCE_DATE:=2024-09-24 -PKG_SOURCE_VERSION:=a4e84f047918fc692aa9e83439964367c228feae -PKG_MIRROR_HASH:=7e0c9d1bd7b572df38e28b9883eb8c03433059cf028e118951e426d475a448a5 +PKG_SOURCE_DATE:=2024-09-26 +PKG_SOURCE_VERSION:=43cb48231ac5adc5404868ff61d044aeb34e0608 +PKG_MIRROR_HASH:=338beb15b7c641b3a09990c28e54749b75c34a0bb895d37007bde4445c9fd353 PKG_LICENSE:=MIT PKG_MAINTAINER:=Joseph Mory @@ -16,7 +16,7 @@ PKG_BUILD_DEPENDS:=golang/host PKG_BUILD_PARALLEL:=1 PKG_BUILD_FLAGS:=no-mips16 -PKG_BUILD_VERSION:=alpha-a4e84f0 +PKG_BUILD_VERSION:=alpha-43cb482 PKG_BUILD_TIME:=$(shell date -u -Iseconds) GO_PKG:=github.com/metacubex/mihomo diff --git a/v2rayn/v2rayN/ServiceLib/Handler/TaskHandler.cs b/v2rayn/v2rayN/ServiceLib/Handler/TaskHandler.cs index b010d7160c..3d2df325d6 100644 --- a/v2rayn/v2rayN/ServiceLib/Handler/TaskHandler.cs +++ b/v2rayn/v2rayN/ServiceLib/Handler/TaskHandler.cs @@ -12,7 +12,7 @@ public void RegUpdateTask(Config config, Action update) { Task.Run(() => UpdateTaskRunSubscription(config, update)); - //Task.Run(() => UpdateTaskRunGeo(config, update)); + Task.Run(() => UpdateTaskRunGeo(config, update)); } private async Task UpdateTaskRunSubscription(Config config, Action update) @@ -50,12 +50,14 @@ { var autoUpdateGeoTime = DateTime.Now; - await Task.Delay(1000 * 120); + //await Task.Delay(1000 * 120); Logging.SaveLog("UpdateTaskRunGeo"); var updateHandle = new UpdateHandler(); while (true) { + await Task.Delay(1000 * 3600); + var dtNow = DateTime.Now; if (config.guiItem.autoUpdateInterval > 0) { @@ -68,8 +70,6 @@ autoUpdateGeoTime = dtNow; } } - - await Task.Delay(1000 * 3600); } } } diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Styles/GlobalStyles.axaml b/v2rayn/v2rayN/v2rayN.Desktop/Styles/GlobalStyles.axaml index aaeec2c53a..bf7440e6b0 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Styles/GlobalStyles.axaml +++ b/v2rayn/v2rayN/v2rayN.Desktop/Styles/GlobalStyles.axaml @@ -6,18 +6,18 @@ \ No newline at end of file diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml b/v2rayn/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml index a691685bec..f55c395751 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml +++ b/v2rayn/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml @@ -13,152 +13,152 @@ ShowInTaskbar="False" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> - - + -