mirror of
https://github.com/bolucat/Archive.git
synced 2026-04-22 16:07:49 +08:00
Update On Mon Jun 17 20:31:37 CEST 2024
This commit is contained in:
@@ -675,3 +675,4 @@ Update On Thu Jun 13 20:31:26 CEST 2024
|
||||
Update On Fri Jun 14 20:32:58 CEST 2024
|
||||
Update On Sat Jun 15 20:30:01 CEST 2024
|
||||
Update On Sun Jun 16 20:31:07 CEST 2024
|
||||
Update On Mon Jun 17 20:31:27 CEST 2024
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
list "github.com/bahlo/generic-list-go"
|
||||
)
|
||||
|
||||
type Callback[T any] struct {
|
||||
list list.List[func(T)]
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
func NewCallback[T any]() *Callback[T] {
|
||||
return &Callback[T]{}
|
||||
}
|
||||
|
||||
func (c *Callback[T]) Register(item func(T)) io.Closer {
|
||||
c.mutex.RLock()
|
||||
defer c.mutex.RUnlock()
|
||||
element := c.list.PushBack(item)
|
||||
return &callbackCloser[T]{
|
||||
element: element,
|
||||
callback: c,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Callback[T]) Emit(item T) {
|
||||
c.mutex.RLock()
|
||||
defer c.mutex.RUnlock()
|
||||
for element := c.list.Front(); element != nil; element = element.Next() {
|
||||
go element.Value(item)
|
||||
}
|
||||
}
|
||||
|
||||
type callbackCloser[T any] struct {
|
||||
element *list.Element[func(T)]
|
||||
callback *Callback[T]
|
||||
once sync.Once
|
||||
}
|
||||
|
||||
func (c *callbackCloser[T]) Close() error {
|
||||
c.once.Do(func() {
|
||||
c.callback.mutex.Lock()
|
||||
defer c.callback.mutex.Unlock()
|
||||
c.callback.list.Remove(c.element)
|
||||
})
|
||||
return nil
|
||||
}
|
||||
@@ -43,12 +43,12 @@ func (set *IpCidrSet) IsContainForString(ipString string) bool {
|
||||
}
|
||||
|
||||
func (set *IpCidrSet) IsContain(ip netip.Addr) bool {
|
||||
return set.toIPSet().Contains(ip.WithZone(""))
|
||||
return set.ToIPSet().Contains(ip.WithZone(""))
|
||||
}
|
||||
|
||||
func (set *IpCidrSet) Merge() error {
|
||||
var b netipx.IPSetBuilder
|
||||
b.AddSet(set.toIPSet())
|
||||
b.AddSet(set.ToIPSet())
|
||||
i, err := b.IPSet()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -57,7 +57,9 @@ func (set *IpCidrSet) Merge() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (set *IpCidrSet) toIPSet() *netipx.IPSet {
|
||||
// ToIPSet not safe convert to *netipx.IPSet
|
||||
// be careful, must be used after Merge
|
||||
func (set *IpCidrSet) ToIPSet() *netipx.IPSet {
|
||||
return (*netipx.IPSet)(unsafe.Pointer(set))
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,9 @@ import (
|
||||
|
||||
type Interface struct {
|
||||
Index int
|
||||
MTU int
|
||||
Name string
|
||||
Addrs []netip.Prefix
|
||||
Addresses []netip.Prefix
|
||||
HardwareAddr net.HardwareAddr
|
||||
}
|
||||
|
||||
@@ -61,8 +62,9 @@ func Interfaces() (map[string]*Interface, error) {
|
||||
|
||||
r[iface.Name] = &Interface{
|
||||
Index: iface.Index,
|
||||
MTU: iface.MTU,
|
||||
Name: iface.Name,
|
||||
Addrs: ipNets,
|
||||
Addresses: ipNets,
|
||||
HardwareAddr: iface.HardwareAddr,
|
||||
}
|
||||
}
|
||||
@@ -92,7 +94,7 @@ func IsLocalIp(ip netip.Addr) (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
for _, iface := range ifaces {
|
||||
for _, addr := range iface.Addrs {
|
||||
for _, addr := range iface.Addresses {
|
||||
if addr.Contains(ip) {
|
||||
return true, nil
|
||||
}
|
||||
@@ -120,7 +122,7 @@ func (iface *Interface) PickIPv6Addr(destination netip.Addr) (netip.Prefix, erro
|
||||
func (iface *Interface) pickIPAddr(destination netip.Addr, accept func(addr netip.Prefix) bool) (netip.Prefix, error) {
|
||||
var fallback netip.Prefix
|
||||
|
||||
for _, addr := range iface.Addrs {
|
||||
for _, addr := range iface.Addresses {
|
||||
if !accept(addr) {
|
||||
continue
|
||||
}
|
||||
|
||||
+64
-43
@@ -246,31 +246,39 @@ type RawTun struct {
|
||||
DNSHijack []string `yaml:"dns-hijack" json:"dns-hijack"`
|
||||
AutoRoute bool `yaml:"auto-route" json:"auto-route"`
|
||||
AutoDetectInterface bool `yaml:"auto-detect-interface"`
|
||||
RedirectToTun []string `yaml:"-" json:"-"`
|
||||
|
||||
MTU uint32 `yaml:"mtu" json:"mtu,omitempty"`
|
||||
GSO bool `yaml:"gso" json:"gso,omitempty"`
|
||||
GSOMaxSize uint32 `yaml:"gso-max-size" json:"gso-max-size,omitempty"`
|
||||
//Inet4Address []netip.Prefix `yaml:"inet4-address" json:"inet4_address,omitempty"`
|
||||
Inet6Address []netip.Prefix `yaml:"inet6-address" json:"inet6_address,omitempty"`
|
||||
StrictRoute bool `yaml:"strict-route" json:"strict_route,omitempty"`
|
||||
Inet6Address []netip.Prefix `yaml:"inet6-address" json:"inet6_address,omitempty"`
|
||||
IPRoute2TableIndex int `yaml:"iproute2-table-index" json:"iproute2_table_index,omitempty"`
|
||||
IPRoute2RuleIndex int `yaml:"iproute2-rule-index" json:"iproute2_rule_index,omitempty"`
|
||||
AutoRedirect bool `yaml:"auto-redirect" json:"auto_redirect,omitempty"`
|
||||
AutoRedirectInputMark uint32 `yaml:"auto-redirect-input-mark" json:"auto_redirect_input_mark,omitempty"`
|
||||
AutoRedirectOutputMark uint32 `yaml:"auto-redirect-output-mark" json:"auto_redirect_output_mark,omitempty"`
|
||||
StrictRoute bool `yaml:"strict-route" json:"strict_route,omitempty"`
|
||||
RouteAddress []netip.Prefix `yaml:"route-address" json:"route_address,omitempty"`
|
||||
RouteAddressSet []string `yaml:"route-address-set" json:"route_address_set,omitempty"`
|
||||
RouteExcludeAddress []netip.Prefix `yaml:"route-exclude-address" json:"route_exclude_address,omitempty"`
|
||||
RouteExcludeAddressSet []string `yaml:"route-exclude-address-set" json:"route_exclude_address_set,omitempty"`
|
||||
IncludeInterface []string `yaml:"include-interface" json:"include-interface,omitempty"`
|
||||
ExcludeInterface []string `yaml:"exclude-interface" json:"exclude-interface,omitempty"`
|
||||
IncludeUID []uint32 `yaml:"include-uid" json:"include_uid,omitempty"`
|
||||
IncludeUIDRange []string `yaml:"include-uid-range" json:"include_uid_range,omitempty"`
|
||||
ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude_uid,omitempty"`
|
||||
ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude_uid_range,omitempty"`
|
||||
IncludeAndroidUser []int `yaml:"include-android-user" json:"include_android_user,omitempty"`
|
||||
IncludePackage []string `yaml:"include-package" json:"include_package,omitempty"`
|
||||
ExcludePackage []string `yaml:"exclude-package" json:"exclude_package,omitempty"`
|
||||
EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint_independent_nat,omitempty"`
|
||||
UDPTimeout int64 `yaml:"udp-timeout" json:"udp_timeout,omitempty"`
|
||||
FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"`
|
||||
|
||||
Inet4RouteAddress []netip.Prefix `yaml:"inet4-route-address" json:"inet4_route_address,omitempty"`
|
||||
Inet6RouteAddress []netip.Prefix `yaml:"inet6-route-address" json:"inet6_route_address,omitempty"`
|
||||
Inet4RouteExcludeAddress []netip.Prefix `yaml:"inet4-route-exclude-address" json:"inet4_route_exclude_address,omitempty"`
|
||||
Inet6RouteExcludeAddress []netip.Prefix `yaml:"inet6-route-exclude-address" json:"inet6_route_exclude_address,omitempty"`
|
||||
IncludeInterface []string `yaml:"include-interface" json:"include-interface,omitempty"`
|
||||
ExcludeInterface []string `yaml:"exclude-interface" json:"exclude-interface,omitempty"`
|
||||
IncludeUID []uint32 `yaml:"include-uid" json:"include_uid,omitempty"`
|
||||
IncludeUIDRange []string `yaml:"include-uid-range" json:"include_uid_range,omitempty"`
|
||||
ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude_uid,omitempty"`
|
||||
ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude_uid_range,omitempty"`
|
||||
IncludeAndroidUser []int `yaml:"include-android-user" json:"include_android_user,omitempty"`
|
||||
IncludePackage []string `yaml:"include-package" json:"include_package,omitempty"`
|
||||
ExcludePackage []string `yaml:"exclude-package" json:"exclude_package,omitempty"`
|
||||
EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint_independent_nat,omitempty"`
|
||||
UDPTimeout int64 `yaml:"udp-timeout" json:"udp_timeout,omitempty"`
|
||||
FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"`
|
||||
TableIndex int `yaml:"table-index" json:"table-index"`
|
||||
}
|
||||
|
||||
type RawTuicServer struct {
|
||||
@@ -564,13 +572,13 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
|
||||
}
|
||||
config.RuleProviders = ruleProviders
|
||||
|
||||
subRules, err := parseSubRules(rawCfg, proxies)
|
||||
subRules, err := parseSubRules(rawCfg, proxies, ruleProviders)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
config.SubRules = subRules
|
||||
|
||||
rules, err := parseRules(rawCfg.Rule, proxies, subRules, "rules")
|
||||
rules, err := parseRules(rawCfg.Rule, proxies, ruleProviders, subRules, "rules")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -666,7 +674,6 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
|
||||
updater.ExternalUIURL = cfg.ExternalUIURL
|
||||
}
|
||||
|
||||
cfg.Tun.RedirectToTun = cfg.EBpf.RedirectToTun
|
||||
return &General{
|
||||
Inbound: Inbound{
|
||||
Port: cfg.Port,
|
||||
@@ -845,6 +852,7 @@ func parseListeners(cfg *RawConfig) (listeners map[string]C.InboundListener, err
|
||||
}
|
||||
|
||||
func parseRuleProviders(cfg *RawConfig) (ruleProviders map[string]providerTypes.RuleProvider, err error) {
|
||||
RP.SetTunnel(T.Tunnel)
|
||||
ruleProviders = map[string]providerTypes.RuleProvider{}
|
||||
// parse rule provider
|
||||
for name, mapping := range cfg.RuleProvider {
|
||||
@@ -854,12 +862,11 @@ func parseRuleProviders(cfg *RawConfig) (ruleProviders map[string]providerTypes.
|
||||
}
|
||||
|
||||
ruleProviders[name] = rp
|
||||
RP.SetRuleProvider(rp)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parseSubRules(cfg *RawConfig, proxies map[string]C.Proxy) (subRules map[string][]C.Rule, err error) {
|
||||
func parseSubRules(cfg *RawConfig, proxies map[string]C.Proxy, ruleProviders map[string]providerTypes.RuleProvider) (subRules map[string][]C.Rule, err error) {
|
||||
subRules = map[string][]C.Rule{}
|
||||
for name := range cfg.SubRules {
|
||||
subRules[name] = make([]C.Rule, 0)
|
||||
@@ -869,7 +876,7 @@ func parseSubRules(cfg *RawConfig, proxies map[string]C.Proxy) (subRules map[str
|
||||
return nil, fmt.Errorf("sub-rule name is empty")
|
||||
}
|
||||
var rules []C.Rule
|
||||
rules, err = parseRules(rawRules, proxies, subRules, fmt.Sprintf("sub-rules[%s]", name))
|
||||
rules, err = parseRules(rawRules, proxies, ruleProviders, subRules, fmt.Sprintf("sub-rules[%s]", name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -922,7 +929,7 @@ func verifySubRuleCircularReferences(n string, subRules map[string][]C.Rule, arr
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseRules(rulesConfig []string, proxies map[string]C.Proxy, subRules map[string][]C.Rule, format string) ([]C.Rule, error) {
|
||||
func parseRules(rulesConfig []string, proxies map[string]C.Proxy, ruleProviders map[string]providerTypes.RuleProvider, subRules map[string][]C.Rule, format string) ([]C.Rule, error) {
|
||||
var rules []C.Rule
|
||||
|
||||
// parse rules
|
||||
@@ -971,6 +978,12 @@ func parseRules(rulesConfig []string, proxies map[string]C.Proxy, subRules map[s
|
||||
return nil, fmt.Errorf("%s[%d] [%s] error: %s", format, idx, line, parseErr.Error())
|
||||
}
|
||||
|
||||
for _, name := range parsed.ProviderNames() {
|
||||
if _, ok := ruleProviders[name]; !ok {
|
||||
return nil, fmt.Errorf("%s[%d] [%s] error: rule set [%s] not found", format, idx, line, name)
|
||||
}
|
||||
}
|
||||
|
||||
rules = append(rules, parsed)
|
||||
}
|
||||
|
||||
@@ -1455,31 +1468,39 @@ func parseTun(rawTun RawTun, general *General) error {
|
||||
DNSHijack: rawTun.DNSHijack,
|
||||
AutoRoute: rawTun.AutoRoute,
|
||||
AutoDetectInterface: rawTun.AutoDetectInterface,
|
||||
RedirectToTun: rawTun.RedirectToTun,
|
||||
|
||||
MTU: rawTun.MTU,
|
||||
GSO: rawTun.GSO,
|
||||
GSOMaxSize: rawTun.GSOMaxSize,
|
||||
Inet4Address: []netip.Prefix{tunAddressPrefix},
|
||||
Inet6Address: rawTun.Inet6Address,
|
||||
StrictRoute: rawTun.StrictRoute,
|
||||
MTU: rawTun.MTU,
|
||||
GSO: rawTun.GSO,
|
||||
GSOMaxSize: rawTun.GSOMaxSize,
|
||||
Inet4Address: []netip.Prefix{tunAddressPrefix},
|
||||
Inet6Address: rawTun.Inet6Address,
|
||||
IPRoute2TableIndex: rawTun.IPRoute2TableIndex,
|
||||
IPRoute2RuleIndex: rawTun.IPRoute2RuleIndex,
|
||||
AutoRedirect: rawTun.AutoRedirect,
|
||||
AutoRedirectInputMark: rawTun.AutoRedirectInputMark,
|
||||
AutoRedirectOutputMark: rawTun.AutoRedirectOutputMark,
|
||||
StrictRoute: rawTun.StrictRoute,
|
||||
RouteAddress: rawTun.RouteAddress,
|
||||
RouteAddressSet: rawTun.RouteAddressSet,
|
||||
RouteExcludeAddress: rawTun.RouteExcludeAddress,
|
||||
RouteExcludeAddressSet: rawTun.RouteExcludeAddressSet,
|
||||
IncludeInterface: rawTun.IncludeInterface,
|
||||
ExcludeInterface: rawTun.ExcludeInterface,
|
||||
IncludeUID: rawTun.IncludeUID,
|
||||
IncludeUIDRange: rawTun.IncludeUIDRange,
|
||||
ExcludeUID: rawTun.ExcludeUID,
|
||||
ExcludeUIDRange: rawTun.ExcludeUIDRange,
|
||||
IncludeAndroidUser: rawTun.IncludeAndroidUser,
|
||||
IncludePackage: rawTun.IncludePackage,
|
||||
ExcludePackage: rawTun.ExcludePackage,
|
||||
EndpointIndependentNat: rawTun.EndpointIndependentNat,
|
||||
UDPTimeout: rawTun.UDPTimeout,
|
||||
FileDescriptor: rawTun.FileDescriptor,
|
||||
|
||||
Inet4RouteAddress: rawTun.Inet4RouteAddress,
|
||||
Inet6RouteAddress: rawTun.Inet6RouteAddress,
|
||||
Inet4RouteExcludeAddress: rawTun.Inet4RouteExcludeAddress,
|
||||
Inet6RouteExcludeAddress: rawTun.Inet6RouteExcludeAddress,
|
||||
IncludeInterface: rawTun.IncludeInterface,
|
||||
ExcludeInterface: rawTun.ExcludeInterface,
|
||||
IncludeUID: rawTun.IncludeUID,
|
||||
IncludeUIDRange: rawTun.IncludeUIDRange,
|
||||
ExcludeUID: rawTun.ExcludeUID,
|
||||
ExcludeUIDRange: rawTun.ExcludeUIDRange,
|
||||
IncludeAndroidUser: rawTun.IncludeAndroidUser,
|
||||
IncludePackage: rawTun.IncludePackage,
|
||||
ExcludePackage: rawTun.ExcludePackage,
|
||||
EndpointIndependentNat: rawTun.EndpointIndependentNat,
|
||||
UDPTimeout: rawTun.UDPTimeout,
|
||||
FileDescriptor: rawTun.FileDescriptor,
|
||||
TableIndex: rawTun.TableIndex,
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -84,7 +84,7 @@ type RuleProvider interface {
|
||||
Match(*constant.Metadata) bool
|
||||
ShouldResolveIP() bool
|
||||
ShouldFindProcess() bool
|
||||
AsRule(adaptor string) constant.Rule
|
||||
Strategy() any
|
||||
}
|
||||
|
||||
// Rule Behavior
|
||||
@@ -127,3 +127,9 @@ func (rf RuleFormat) String() string {
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
type Tunnel interface {
|
||||
Providers() map[string]ProxyProvider
|
||||
RuleProviders() map[string]RuleProvider
|
||||
RuleUpdateCallback() *utils.Callback[RuleProvider]
|
||||
}
|
||||
|
||||
@@ -116,4 +116,5 @@ type Rule interface {
|
||||
Payload() string
|
||||
ShouldResolveIP() bool
|
||||
ShouldFindProcess() bool
|
||||
ProviderNames() []string
|
||||
}
|
||||
|
||||
@@ -37,14 +37,17 @@ func (p geositePolicy) Match(domain string) []dnsClient {
|
||||
}
|
||||
|
||||
type domainSetPolicy struct {
|
||||
domainSetProvider provider.RuleProvider
|
||||
dnsClients []dnsClient
|
||||
tunnel provider.Tunnel
|
||||
name string
|
||||
dnsClients []dnsClient
|
||||
}
|
||||
|
||||
func (p domainSetPolicy) Match(domain string) []dnsClient {
|
||||
metadata := &C.Metadata{Host: domain}
|
||||
if ok := p.domainSetProvider.Match(metadata); ok {
|
||||
return p.dnsClients
|
||||
if ruleProvider, ok := p.tunnel.RuleProviders()[p.name]; ok {
|
||||
metadata := &C.Metadata{Host: domain}
|
||||
if ok := ruleProvider.Match(metadata); ok {
|
||||
return p.dnsClients
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -414,7 +414,7 @@ type Config struct {
|
||||
Pool *fakeip.Pool
|
||||
Hosts *trie.DomainTrie[resolver.HostValue]
|
||||
Policy *orderedmap.OrderedMap[string, []NameServer]
|
||||
RuleProviders map[string]provider.RuleProvider
|
||||
Tunnel provider.Tunnel
|
||||
CacheAlgorithm string
|
||||
}
|
||||
|
||||
@@ -502,11 +502,12 @@ func NewResolver(config Config) *Resolver {
|
||||
key := temp[1]
|
||||
switch prefix {
|
||||
case "rule-set":
|
||||
if p, ok := config.RuleProviders[key]; ok {
|
||||
if _, ok := config.Tunnel.RuleProviders()[key]; ok {
|
||||
log.Debugln("Adding rule-set policy: %s ", key)
|
||||
insertPolicy(domainSetPolicy{
|
||||
domainSetProvider: p,
|
||||
dnsClients: cacheTransform(nameserver),
|
||||
tunnel: config.Tunnel,
|
||||
name: key,
|
||||
dnsClients: cacheTransform(nameserver),
|
||||
})
|
||||
continue
|
||||
} else {
|
||||
|
||||
@@ -116,13 +116,25 @@ tun:
|
||||
# mtu: 9000 # 最大传输单元
|
||||
# gso: false # 启用通用分段卸载,仅支持 Linux
|
||||
# gso-max-size: 65536 # 通用分段卸载包的最大大小
|
||||
auto-redirect: false # 自动配置 iptables 以重定向 TCP 连接。仅支持 Linux。带有 auto-redirect 的 auto-route 现在可以在路由器上按预期工作,无需干预。
|
||||
# strict-route: true # 将所有连接路由到 tun 来防止泄漏,但你的设备将无法其他设备被访问
|
||||
inet4-route-address: # 启用 auto-route 时使用自定义路由而不是默认路由
|
||||
route-address-set: # 将指定规则集中的目标 IP CIDR 规则添加到防火墙, 不匹配的流量将绕过路由, 仅支持 Linux,且需要 nftables,`auto-route` 和 `auto-redirect` 已启用。
|
||||
- ruleset-1
|
||||
- ruleset-2
|
||||
route-exclude-address-set: # 将指定规则集中的目标 IP CIDR 规则添加到防火墙, 匹配的流量将绕过路由, 仅支持 Linux,且需要 nftables,`auto-route` 和 `auto-redirect` 已启用。
|
||||
- ruleset-3
|
||||
- ruleset-4
|
||||
route-address: # 启用 auto-route 时使用自定义路由而不是默认路由
|
||||
- 0.0.0.0/1
|
||||
- 128.0.0.0/1
|
||||
inet6-route-address: # 启用 auto-route 时使用自定义路由而不是默认路由
|
||||
- "::/1"
|
||||
- "8000::/1"
|
||||
# inet4-route-address: # 启用 auto-route 时使用自定义路由而不是默认路由(旧写法)
|
||||
# - 0.0.0.0/1
|
||||
# - 128.0.0.0/1
|
||||
# inet6-route-address: # 启用 auto-route 时使用自定义路由而不是默认路由(旧写法)
|
||||
# - "::/1"
|
||||
# - "8000::/1"
|
||||
# endpoint-independent-nat: false # 启用独立于端点的 NAT
|
||||
# include-interface: # 限制被路由的接口。默认不限制,与 `exclude-interface` 冲突
|
||||
# - "lan0"
|
||||
|
||||
+13
-12
@@ -24,7 +24,7 @@ require (
|
||||
github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72
|
||||
github.com/metacubex/sing-shadowsocks v0.2.6
|
||||
github.com/metacubex/sing-shadowsocks2 v0.2.0
|
||||
github.com/metacubex/sing-tun v0.2.7-0.20240521155100-e8316a45a414
|
||||
github.com/metacubex/sing-tun v0.2.7-0.20240617013029-d05cf9df9cfe
|
||||
github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63
|
||||
github.com/metacubex/tfo-go v0.0.0-20240228025757-be1269474a66
|
||||
@@ -35,8 +35,8 @@ require (
|
||||
github.com/oschwald/maxminddb-golang v1.12.0
|
||||
github.com/puzpuzpuz/xsync/v3 v3.1.0
|
||||
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97
|
||||
github.com/sagernet/sing v0.3.8
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a
|
||||
github.com/sagernet/sing v0.5.0-alpha.10
|
||||
github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6
|
||||
github.com/sagernet/sing-shadowtls v0.1.4
|
||||
github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e
|
||||
@@ -47,11 +47,11 @@ require (
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8
|
||||
go.uber.org/automaxprocs v1.5.3
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
|
||||
golang.org/x/crypto v0.23.0
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
|
||||
golang.org/x/net v0.25.0
|
||||
golang.org/x/crypto v0.24.0
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
|
||||
golang.org/x/net v0.26.0
|
||||
golang.org/x/sync v0.7.0
|
||||
golang.org/x/sys v0.20.0
|
||||
golang.org/x/sys v0.21.0
|
||||
google.golang.org/protobuf v1.34.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
lukechampine.com/blake3 v1.3.0
|
||||
@@ -92,6 +92,7 @@ require (
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
|
||||
github.com/sagernet/nftables v0.3.0-beta.4 // indirect
|
||||
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/sina-ghaderi/poly1305 v0.0.0-20220724002748-c5926b03988b // indirect
|
||||
@@ -100,14 +101,14 @@ require (
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
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.0-20211101163701-50045581ed74 // indirect
|
||||
github.com/vishvananda/netns v0.0.4 // 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.17.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
golang.org/x/mod v0.18.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.21.0 // indirect
|
||||
golang.org/x/tools v0.22.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20240518125217-e63d65a914d1
|
||||
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20240617013425-3e3bd9dab6a2
|
||||
|
||||
+25
-24
@@ -108,16 +108,16 @@ github.com/metacubex/quic-go v0.45.1-0.20240610004319-163fee60637e h1:bLYn3GuRvW
|
||||
github.com/metacubex/quic-go v0.45.1-0.20240610004319-163fee60637e/go.mod h1:Yza2H7Ax1rxWPUcJx0vW+oAt9EsPuSiyQFhFabUPzwU=
|
||||
github.com/metacubex/randv2 v0.2.0 h1:uP38uBvV2SxYfLj53kuvAjbND4RUDfFJjwr4UigMiLs=
|
||||
github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY=
|
||||
github.com/metacubex/sing v0.0.0-20240518125217-e63d65a914d1 h1:7hDHLTmjgtRoAp59STwPQpe5Pinwi4cWex+FB3Ohvco=
|
||||
github.com/metacubex/sing v0.0.0-20240518125217-e63d65a914d1/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI=
|
||||
github.com/metacubex/sing v0.0.0-20240617013425-3e3bd9dab6a2 h1:N5tidgg/FRmkgPw/AjRwhLUinKDx/ODCSbvv9xqRoLM=
|
||||
github.com/metacubex/sing v0.0.0-20240617013425-3e3bd9dab6a2/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72 h1:Wr4g1HCb5Z/QIFwFiVNjO2qL+dRu25+Mdn9xtAZZ+ew=
|
||||
github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72/go.mod h1:g7Mxj7b7zm7YVqD975mk/hSmrb0A0G4bVvIMr2MMzn8=
|
||||
github.com/metacubex/sing-shadowsocks v0.2.6 h1:6oEB3QcsFYnNiFeoevcXrCwJ3sAablwVSgtE9R3QeFQ=
|
||||
github.com/metacubex/sing-shadowsocks v0.2.6/go.mod h1:zIkMeSnb8Mbf4hdqhw0pjzkn1d99YJ3JQm/VBg5WMTg=
|
||||
github.com/metacubex/sing-shadowsocks2 v0.2.0 h1:hqwT/AfI5d5UdPefIzR6onGHJfDXs5zgOM5QSgaM/9A=
|
||||
github.com/metacubex/sing-shadowsocks2 v0.2.0/go.mod h1:LCKF6j1P94zN8ZS+LXRK1gmYTVGB3squivBSXAFnOg8=
|
||||
github.com/metacubex/sing-tun v0.2.7-0.20240521155100-e8316a45a414 h1:IPxTZgQV6fVUBS8tozLMSFPHV3imYc/NbuGfp0bLQq0=
|
||||
github.com/metacubex/sing-tun v0.2.7-0.20240521155100-e8316a45a414/go.mod h1:4VsMwZH1IlgPGFK1ZbBomZ/B2MYkTgs2+gnBAr5GOIo=
|
||||
github.com/metacubex/sing-tun v0.2.7-0.20240617013029-d05cf9df9cfe h1:NrWjVEkRmEkdREVSpohMgEBoznS0PrRfJDr6iCV4348=
|
||||
github.com/metacubex/sing-tun v0.2.7-0.20240617013029-d05cf9df9cfe/go.mod h1:WwJGbCx7bQcBzuQXiDOJvZH27R0kIjKNNlISIWsL6kM=
|
||||
github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f h1:QjXrHKbTMBip/C+R79bvbfr42xH1gZl3uFb0RELdZiQ=
|
||||
github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY=
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63 h1:AGyIB55UfQm/0ZH0HtQO9u3l//yjtHUpjeRjjPGfGRI=
|
||||
@@ -159,8 +159,10 @@ github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a h1:+NkI2670SQpQWvkkD2QgdTuzQG263YZ+2emfpeyGqW0=
|
||||
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a/go.mod h1:63s7jpZqcDAIpj8oI/1v4Izok+npJOHACFCU6+huCkM=
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
|
||||
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZNjr6sGeT00J8uU7JF4cNUdb44/Duis=
|
||||
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
|
||||
github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I=
|
||||
github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8=
|
||||
github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6 h1:5bCAkvDDzSMITiHFjolBwpdqYsvycdTu71FsMEFXQ14=
|
||||
github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6/go.mod h1:khzr9AOPocLa+g53dBplwNDz4gdsyx/YM3swtAhlkHQ=
|
||||
github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
|
||||
@@ -206,8 +208,8 @@ github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923/go.mod h1:eLL9Nub3yfAho
|
||||
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
|
||||
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/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/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=
|
||||
@@ -222,18 +224,18 @@ 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.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
|
||||
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||
golang.org/x/mod v0.18.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.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
@@ -252,19 +254,18 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
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=
|
||||
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
|
||||
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
|
||||
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
|
||||
@@ -97,7 +97,7 @@ func ApplyConfig(cfg *config.Config, force bool) {
|
||||
updateHosts(cfg.Hosts)
|
||||
updateGeneral(cfg.General)
|
||||
updateNTP(cfg.NTP)
|
||||
updateDNS(cfg.DNS, cfg.RuleProviders, cfg.General.IPv6)
|
||||
updateDNS(cfg.DNS, cfg.General.IPv6)
|
||||
updateListeners(cfg.General, cfg.Listeners, force)
|
||||
updateIPTables(cfg)
|
||||
updateTun(cfg.General)
|
||||
@@ -211,7 +211,7 @@ func updateNTP(c *config.NTP) {
|
||||
}
|
||||
}
|
||||
|
||||
func updateDNS(c *config.DNS, ruleProvider map[string]provider.RuleProvider, generalIPv6 bool) {
|
||||
func updateDNS(c *config.DNS, generalIPv6 bool) {
|
||||
if !c.Enable {
|
||||
resolver.DefaultResolver = nil
|
||||
resolver.DefaultHostMapper = nil
|
||||
@@ -237,7 +237,7 @@ func updateDNS(c *config.DNS, ruleProvider map[string]provider.RuleProvider, gen
|
||||
Default: c.DefaultNameserver,
|
||||
Policy: c.NameServerPolicy,
|
||||
ProxyServer: c.ProxyServerNameserver,
|
||||
RuleProviders: ruleProvider,
|
||||
Tunnel: tunnel.Tunnel,
|
||||
CacheAlgorithm: c.CacheAlgorithm,
|
||||
}
|
||||
|
||||
@@ -355,7 +355,7 @@ func updateTun(general *config.General) {
|
||||
return
|
||||
}
|
||||
listener.ReCreateTun(general.Tun, tunnel.Tunnel)
|
||||
listener.ReCreateRedirToTun(general.Tun.RedirectToTun)
|
||||
listener.ReCreateRedirToTun(general.EBpf.RedirectToTun)
|
||||
}
|
||||
|
||||
func updateSniffer(sniffer *config.Sniffer) {
|
||||
@@ -507,9 +507,7 @@ func updateIPTables(cfg *config.Config) {
|
||||
inboundInterface = iptables.InboundInterface
|
||||
}
|
||||
|
||||
if dialer.DefaultRoutingMark.Load() == 0 {
|
||||
dialer.DefaultRoutingMark.Store(2158)
|
||||
}
|
||||
dialer.DefaultRoutingMark.CompareAndSwap(0, 2158)
|
||||
|
||||
err = tproxy.SetTProxyIPTables(inboundInterface, bypass, uint16(tProxyPort), DnsRedirect, dnsPort.Port())
|
||||
if err != nil {
|
||||
|
||||
@@ -68,25 +68,34 @@ type tunSchema struct {
|
||||
GSO *bool `yaml:"gso" json:"gso,omitempty"`
|
||||
GSOMaxSize *uint32 `yaml:"gso-max-size" json:"gso-max-size,omitempty"`
|
||||
//Inet4Address *[]netip.Prefix `yaml:"inet4-address" json:"inet4-address,omitempty"`
|
||||
Inet6Address *[]netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"`
|
||||
StrictRoute *bool `yaml:"strict-route" json:"strict-route,omitempty"`
|
||||
Inet6Address *[]netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"`
|
||||
IPRoute2TableIndex *int `yaml:"iproute2-table-index" json:"iproute2_table_index,omitempty"`
|
||||
IPRoute2RuleIndex *int `yaml:"iproute2-rule-index" json:"iproute2_rule_index,omitempty"`
|
||||
AutoRedirect *bool `yaml:"auto-redirect" json:"auto_redirect,omitempty"`
|
||||
AutoRedirectInputMark *uint32 `yaml:"auto-redirect-input-mark" json:"auto_redirect_input_mark,omitempty"`
|
||||
AutoRedirectOutputMark *uint32 `yaml:"auto-redirect-output-mark" json:"auto_redirect_output_mark,omitempty"`
|
||||
StrictRoute *bool `yaml:"strict-route" json:"strict-route,omitempty"`
|
||||
RouteAddress *[]netip.Prefix `yaml:"route-address" json:"route_address,omitempty"`
|
||||
RouteAddressSet *[]string `yaml:"route-address-set" json:"route_address_set,omitempty"`
|
||||
RouteExcludeAddress *[]netip.Prefix `yaml:"route-exclude-address" json:"route_exclude_address,omitempty"`
|
||||
RouteExcludeAddressSet *[]string `yaml:"route-exclude-address-set" json:"route_exclude_address_set,omitempty"`
|
||||
IncludeInterface *[]string `yaml:"include-interface" json:"include-interface,omitempty"`
|
||||
ExcludeInterface *[]string `yaml:"exclude-interface" json:"exclude-interface,omitempty"`
|
||||
IncludeUID *[]uint32 `yaml:"include-uid" json:"include-uid,omitempty"`
|
||||
IncludeUIDRange *[]string `yaml:"include-uid-range" json:"include-uid-range,omitempty"`
|
||||
ExcludeUID *[]uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"`
|
||||
ExcludeUIDRange *[]string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"`
|
||||
IncludeAndroidUser *[]int `yaml:"include-android-user" json:"include-android-user,omitempty"`
|
||||
IncludePackage *[]string `yaml:"include-package" json:"include-package,omitempty"`
|
||||
ExcludePackage *[]string `yaml:"exclude-package" json:"exclude-package,omitempty"`
|
||||
EndpointIndependentNat *bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"`
|
||||
UDPTimeout *int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"`
|
||||
FileDescriptor *int `yaml:"file-descriptor" json:"file-descriptor"`
|
||||
|
||||
Inet4RouteAddress *[]netip.Prefix `yaml:"inet4-route-address" json:"inet4-route-address,omitempty"`
|
||||
Inet6RouteAddress *[]netip.Prefix `yaml:"inet6-route-address" json:"inet6-route-address,omitempty"`
|
||||
Inet4RouteExcludeAddress *[]netip.Prefix `yaml:"inet4-route-exclude-address" json:"inet4-route-exclude-address,omitempty"`
|
||||
Inet6RouteExcludeAddress *[]netip.Prefix `yaml:"inet6-route-exclude-address" json:"inet6-route-exclude-address,omitempty"`
|
||||
IncludeInterface *[]string `yaml:"include-interface" json:"include-interface,omitempty"`
|
||||
ExcludeInterface *[]string `yaml:"exclude-interface" json:"exclude-interface,omitempty"`
|
||||
IncludeUID *[]uint32 `yaml:"include-uid" json:"include-uid,omitempty"`
|
||||
IncludeUIDRange *[]string `yaml:"include-uid-range" json:"include-uid-range,omitempty"`
|
||||
ExcludeUID *[]uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"`
|
||||
ExcludeUIDRange *[]string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"`
|
||||
IncludeAndroidUser *[]int `yaml:"include-android-user" json:"include-android-user,omitempty"`
|
||||
IncludePackage *[]string `yaml:"include-package" json:"include-package,omitempty"`
|
||||
ExcludePackage *[]string `yaml:"exclude-package" json:"exclude-package,omitempty"`
|
||||
EndpointIndependentNat *bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"`
|
||||
UDPTimeout *int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"`
|
||||
FileDescriptor *int `yaml:"file-descriptor" json:"file-descriptor"`
|
||||
TableIndex *int `yaml:"table-index" json:"table-index"`
|
||||
}
|
||||
|
||||
type tuicServerSchema struct {
|
||||
@@ -157,6 +166,36 @@ func pointerOrDefaultTun(p *tunSchema, def LC.Tun) LC.Tun {
|
||||
if p.Inet6Address != nil {
|
||||
def.Inet6Address = *p.Inet6Address
|
||||
}
|
||||
if p.IPRoute2TableIndex != nil {
|
||||
def.IPRoute2TableIndex = *p.IPRoute2TableIndex
|
||||
}
|
||||
if p.IPRoute2RuleIndex != nil {
|
||||
def.IPRoute2RuleIndex = *p.IPRoute2RuleIndex
|
||||
}
|
||||
if p.AutoRedirect != nil {
|
||||
def.AutoRedirect = *p.AutoRedirect
|
||||
}
|
||||
if p.AutoRedirectInputMark != nil {
|
||||
def.AutoRedirectInputMark = *p.AutoRedirectInputMark
|
||||
}
|
||||
if p.AutoRedirectOutputMark != nil {
|
||||
def.AutoRedirectOutputMark = *p.AutoRedirectOutputMark
|
||||
}
|
||||
if p.StrictRoute != nil {
|
||||
def.StrictRoute = *p.StrictRoute
|
||||
}
|
||||
if p.RouteAddress != nil {
|
||||
def.RouteAddress = *p.RouteAddress
|
||||
}
|
||||
if p.RouteAddressSet != nil {
|
||||
def.RouteAddressSet = *p.RouteAddressSet
|
||||
}
|
||||
if p.RouteExcludeAddress != nil {
|
||||
def.RouteExcludeAddress = *p.RouteExcludeAddress
|
||||
}
|
||||
if p.RouteExcludeAddressSet != nil {
|
||||
def.RouteExcludeAddressSet = *p.RouteExcludeAddressSet
|
||||
}
|
||||
if p.Inet4RouteAddress != nil {
|
||||
def.Inet4RouteAddress = *p.Inet4RouteAddress
|
||||
}
|
||||
@@ -205,9 +244,6 @@ func pointerOrDefaultTun(p *tunSchema, def LC.Tun) LC.Tun {
|
||||
if p.FileDescriptor != nil {
|
||||
def.FileDescriptor = *p.FileDescriptor
|
||||
}
|
||||
if p.TableIndex != nil {
|
||||
def.TableIndex = *p.TableIndex
|
||||
}
|
||||
}
|
||||
return def
|
||||
}
|
||||
|
||||
@@ -27,27 +27,36 @@ type Tun struct {
|
||||
AutoDetectInterface bool `yaml:"auto-detect-interface" json:"auto-detect-interface"`
|
||||
RedirectToTun []string `yaml:"-" json:"-"`
|
||||
|
||||
MTU uint32 `yaml:"mtu" json:"mtu,omitempty"`
|
||||
GSO bool `yaml:"gso" json:"gso,omitempty"`
|
||||
GSOMaxSize uint32 `yaml:"gso-max-size" json:"gso-max-size,omitempty"`
|
||||
Inet4Address []netip.Prefix `yaml:"inet4-address" json:"inet4-address,omitempty"`
|
||||
Inet6Address []netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"`
|
||||
StrictRoute bool `yaml:"strict-route" json:"strict-route,omitempty"`
|
||||
MTU uint32 `yaml:"mtu" json:"mtu,omitempty"`
|
||||
GSO bool `yaml:"gso" json:"gso,omitempty"`
|
||||
GSOMaxSize uint32 `yaml:"gso-max-size" json:"gso-max-size,omitempty"`
|
||||
Inet4Address []netip.Prefix `yaml:"inet4-address" json:"inet4-address,omitempty"`
|
||||
Inet6Address []netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"`
|
||||
IPRoute2TableIndex int `yaml:"iproute2-table-index" json:"iproute2_table_index,omitempty"`
|
||||
IPRoute2RuleIndex int `yaml:"iproute2-rule-index" json:"iproute2_rule_index,omitempty"`
|
||||
AutoRedirect bool `yaml:"auto-redirect" json:"auto_redirect,omitempty"`
|
||||
AutoRedirectInputMark uint32 `yaml:"auto-redirect-input-mark" json:"auto_redirect_input_mark,omitempty"`
|
||||
AutoRedirectOutputMark uint32 `yaml:"auto-redirect-output-mark" json:"auto_redirect_output_mark,omitempty"`
|
||||
StrictRoute bool `yaml:"strict-route" json:"strict-route,omitempty"`
|
||||
RouteAddress []netip.Prefix `yaml:"route-address" json:"route_address,omitempty"`
|
||||
RouteAddressSet []string `yaml:"route-address-set" json:"route_address_set,omitempty"`
|
||||
RouteExcludeAddress []netip.Prefix `yaml:"route-exclude-address" json:"route_exclude_address,omitempty"`
|
||||
RouteExcludeAddressSet []string `yaml:"route-exclude-address-set" json:"route_exclude_address_set,omitempty"`
|
||||
IncludeInterface []string `yaml:"include-interface" json:"include-interface,omitempty"`
|
||||
ExcludeInterface []string `yaml:"exclude-interface" json:"exclude-interface,omitempty"`
|
||||
IncludeUID []uint32 `yaml:"include-uid" json:"include-uid,omitempty"`
|
||||
IncludeUIDRange []string `yaml:"include-uid-range" json:"include-uid-range,omitempty"`
|
||||
ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"`
|
||||
ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"`
|
||||
IncludeAndroidUser []int `yaml:"include-android-user" json:"include-android-user,omitempty"`
|
||||
IncludePackage []string `yaml:"include-package" json:"include-package,omitempty"`
|
||||
ExcludePackage []string `yaml:"exclude-package" json:"exclude-package,omitempty"`
|
||||
EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"`
|
||||
UDPTimeout int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"`
|
||||
FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"`
|
||||
|
||||
Inet4RouteAddress []netip.Prefix `yaml:"inet4-route-address" json:"inet4-route-address,omitempty"`
|
||||
Inet6RouteAddress []netip.Prefix `yaml:"inet6-route-address" json:"inet6-route-address,omitempty"`
|
||||
Inet4RouteExcludeAddress []netip.Prefix `yaml:"inet4-route-exclude-address" json:"inet4-route-exclude-address,omitempty"`
|
||||
Inet6RouteExcludeAddress []netip.Prefix `yaml:"inet6-route-exclude-address" json:"inet6-route-exclude-address,omitempty"`
|
||||
IncludeInterface []string `yaml:"include-interface" json:"include-interface,omitempty"`
|
||||
ExcludeInterface []string `yaml:"exclude-interface" json:"exclude-interface,omitempty"`
|
||||
IncludeUID []uint32 `yaml:"include-uid" json:"include-uid,omitempty"`
|
||||
IncludeUIDRange []string `yaml:"include-uid-range" json:"include-uid-range,omitempty"`
|
||||
ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"`
|
||||
ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"`
|
||||
IncludeAndroidUser []int `yaml:"include-android-user" json:"include-android-user,omitempty"`
|
||||
IncludePackage []string `yaml:"include-package" json:"include-package,omitempty"`
|
||||
ExcludePackage []string `yaml:"exclude-package" json:"exclude-package,omitempty"`
|
||||
EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"`
|
||||
UDPTimeout int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"`
|
||||
FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"`
|
||||
TableIndex int `yaml:"table-index" json:"table-index"`
|
||||
}
|
||||
|
||||
@@ -18,29 +18,38 @@ type TunOption struct {
|
||||
AutoRoute bool `inbound:"auto-route,omitempty"`
|
||||
AutoDetectInterface bool `inbound:"auto-detect-interface,omitempty"`
|
||||
|
||||
MTU uint32 `inbound:"mtu,omitempty"`
|
||||
GSO bool `inbound:"gso,omitempty"`
|
||||
GSOMaxSize uint32 `inbound:"gso-max-size,omitempty"`
|
||||
Inet4Address []string `inbound:"inet4_address,omitempty"`
|
||||
Inet6Address []string `inbound:"inet6_address,omitempty"`
|
||||
StrictRoute bool `inbound:"strict_route,omitempty"`
|
||||
MTU uint32 `inbound:"mtu,omitempty"`
|
||||
GSO bool `inbound:"gso,omitempty"`
|
||||
GSOMaxSize uint32 `inbound:"gso-max-size,omitempty"`
|
||||
Inet4Address []string `inbound:"inet4_address,omitempty"`
|
||||
Inet6Address []string `inbound:"inet6_address,omitempty"`
|
||||
IPRoute2TableIndex int `inbound:"iproute2-table-index"`
|
||||
IPRoute2RuleIndex int `inbound:"iproute2-rule-index"`
|
||||
AutoRedirect bool `inbound:"auto-redirect"`
|
||||
AutoRedirectInputMark uint32 `inbound:"auto-redirect-input-mark"`
|
||||
AutoRedirectOutputMark uint32 `inbound:"auto-redirect-output-mark"`
|
||||
StrictRoute bool `inbound:"strict_route,omitempty"`
|
||||
RouteAddress []string `inbound:"route-address"`
|
||||
RouteAddressSet []string `inbound:"route-address-set"`
|
||||
RouteExcludeAddress []string `inbound:"route-exclude-address"`
|
||||
RouteExcludeAddressSet []string `inbound:"route-exclude-address-set"`
|
||||
IncludeInterface []string `inbound:"include-interface,omitempty"`
|
||||
ExcludeInterface []string `inbound:"exclude-interface"`
|
||||
IncludeUID []uint32 `inbound:"include_uid,omitempty"`
|
||||
IncludeUIDRange []string `inbound:"include_uid_range,omitempty"`
|
||||
ExcludeUID []uint32 `inbound:"exclude_uid,omitempty"`
|
||||
ExcludeUIDRange []string `inbound:"exclude_uid_range,omitempty"`
|
||||
IncludeAndroidUser []int `inbound:"include_android_user,omitempty"`
|
||||
IncludePackage []string `inbound:"include_package,omitempty"`
|
||||
ExcludePackage []string `inbound:"exclude_package,omitempty"`
|
||||
EndpointIndependentNat bool `inbound:"endpoint_independent_nat,omitempty"`
|
||||
UDPTimeout int64 `inbound:"udp_timeout,omitempty"`
|
||||
FileDescriptor int `inbound:"file-descriptor,omitempty"`
|
||||
|
||||
Inet4RouteAddress []string `inbound:"inet4_route_address,omitempty"`
|
||||
Inet6RouteAddress []string `inbound:"inet6_route_address,omitempty"`
|
||||
Inet4RouteExcludeAddress []string `inbound:"inet4_route_exclude_address,omitempty"`
|
||||
Inet6RouteExcludeAddress []string `inbound:"inet6_route_exclude_address,omitempty"`
|
||||
IncludeInterface []string `inbound:"include-interface,omitempty"`
|
||||
ExcludeInterface []string `inbound:"exclude-interface" json:"exclude-interface,omitempty"`
|
||||
IncludeUID []uint32 `inbound:"include_uid,omitempty"`
|
||||
IncludeUIDRange []string `inbound:"include_uid_range,omitempty"`
|
||||
ExcludeUID []uint32 `inbound:"exclude_uid,omitempty"`
|
||||
ExcludeUIDRange []string `inbound:"exclude_uid_range,omitempty"`
|
||||
IncludeAndroidUser []int `inbound:"include_android_user,omitempty"`
|
||||
IncludePackage []string `inbound:"include_package,omitempty"`
|
||||
ExcludePackage []string `inbound:"exclude_package,omitempty"`
|
||||
EndpointIndependentNat bool `inbound:"endpoint_independent_nat,omitempty"`
|
||||
UDPTimeout int64 `inbound:"udp_timeout,omitempty"`
|
||||
FileDescriptor int `inbound:"file-descriptor,omitempty"`
|
||||
TableIndex int `inbound:"table-index,omitempty"`
|
||||
}
|
||||
|
||||
func (o TunOption) Equal(config C.InboundConfig) bool {
|
||||
@@ -63,6 +72,16 @@ func NewTun(options *TunOption) (*Tun, error) {
|
||||
if !exist {
|
||||
return nil, errors.New("invalid tun stack")
|
||||
}
|
||||
|
||||
routeAddress, err := LC.StringSliceToNetipPrefixSlice(options.RouteAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
routeExcludeAddress, err := LC.StringSliceToNetipPrefixSlice(options.RouteExcludeAddress)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
inet4Address, err := LC.StringSliceToNetipPrefixSlice(options.Inet4Address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -91,35 +110,44 @@ func NewTun(options *TunOption) (*Tun, error) {
|
||||
Base: base,
|
||||
config: options,
|
||||
tun: LC.Tun{
|
||||
Enable: true,
|
||||
Device: options.Device,
|
||||
Stack: stack,
|
||||
DNSHijack: options.DNSHijack,
|
||||
AutoRoute: options.AutoRoute,
|
||||
AutoDetectInterface: options.AutoDetectInterface,
|
||||
MTU: options.MTU,
|
||||
GSO: options.GSO,
|
||||
GSOMaxSize: options.GSOMaxSize,
|
||||
Inet4Address: inet4Address,
|
||||
Inet6Address: inet6Address,
|
||||
StrictRoute: options.StrictRoute,
|
||||
Enable: true,
|
||||
Device: options.Device,
|
||||
Stack: stack,
|
||||
DNSHijack: options.DNSHijack,
|
||||
AutoRoute: options.AutoRoute,
|
||||
AutoDetectInterface: options.AutoDetectInterface,
|
||||
MTU: options.MTU,
|
||||
GSO: options.GSO,
|
||||
GSOMaxSize: options.GSOMaxSize,
|
||||
Inet4Address: inet4Address,
|
||||
Inet6Address: inet6Address,
|
||||
IPRoute2TableIndex: options.IPRoute2TableIndex,
|
||||
IPRoute2RuleIndex: options.IPRoute2RuleIndex,
|
||||
AutoRedirect: options.AutoRedirect,
|
||||
AutoRedirectInputMark: options.AutoRedirectInputMark,
|
||||
AutoRedirectOutputMark: options.AutoRedirectOutputMark,
|
||||
StrictRoute: options.StrictRoute,
|
||||
RouteAddress: routeAddress,
|
||||
RouteAddressSet: options.RouteAddressSet,
|
||||
RouteExcludeAddress: routeExcludeAddress,
|
||||
RouteExcludeAddressSet: options.RouteExcludeAddressSet,
|
||||
IncludeInterface: options.IncludeInterface,
|
||||
ExcludeInterface: options.ExcludeInterface,
|
||||
IncludeUID: options.IncludeUID,
|
||||
IncludeUIDRange: options.IncludeUIDRange,
|
||||
ExcludeUID: options.ExcludeUID,
|
||||
ExcludeUIDRange: options.ExcludeUIDRange,
|
||||
IncludeAndroidUser: options.IncludeAndroidUser,
|
||||
IncludePackage: options.IncludePackage,
|
||||
ExcludePackage: options.ExcludePackage,
|
||||
EndpointIndependentNat: options.EndpointIndependentNat,
|
||||
UDPTimeout: options.UDPTimeout,
|
||||
FileDescriptor: options.FileDescriptor,
|
||||
|
||||
Inet4RouteAddress: inet4RouteAddress,
|
||||
Inet6RouteAddress: inet6RouteAddress,
|
||||
Inet4RouteExcludeAddress: inet4RouteExcludeAddress,
|
||||
Inet6RouteExcludeAddress: inet6RouteExcludeAddress,
|
||||
IncludeInterface: options.IncludeInterface,
|
||||
ExcludeInterface: options.ExcludeInterface,
|
||||
IncludeUID: options.IncludeUID,
|
||||
IncludeUIDRange: options.IncludeUIDRange,
|
||||
ExcludeUID: options.ExcludeUID,
|
||||
ExcludeUIDRange: options.ExcludeUIDRange,
|
||||
IncludeAndroidUser: options.IncludeAndroidUser,
|
||||
IncludePackage: options.IncludePackage,
|
||||
ExcludePackage: options.ExcludePackage,
|
||||
EndpointIndependentNat: options.EndpointIndependentNat,
|
||||
UDPTimeout: options.UDPTimeout,
|
||||
FileDescriptor: options.FileDescriptor,
|
||||
TableIndex: options.TableIndex,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -820,11 +820,15 @@ func hasTunConfigChange(tunConf *LC.Tun) bool {
|
||||
LastTunConf.MTU != tunConf.MTU ||
|
||||
LastTunConf.GSO != tunConf.GSO ||
|
||||
LastTunConf.GSOMaxSize != tunConf.GSOMaxSize ||
|
||||
LastTunConf.IPRoute2TableIndex != tunConf.IPRoute2TableIndex ||
|
||||
LastTunConf.IPRoute2RuleIndex != tunConf.IPRoute2RuleIndex ||
|
||||
LastTunConf.AutoRedirect != tunConf.AutoRedirect ||
|
||||
LastTunConf.AutoRedirectInputMark != tunConf.AutoRedirectInputMark ||
|
||||
LastTunConf.AutoRedirectOutputMark != tunConf.AutoRedirectOutputMark ||
|
||||
LastTunConf.StrictRoute != tunConf.StrictRoute ||
|
||||
LastTunConf.EndpointIndependentNat != tunConf.EndpointIndependentNat ||
|
||||
LastTunConf.UDPTimeout != tunConf.UDPTimeout ||
|
||||
LastTunConf.FileDescriptor != tunConf.FileDescriptor ||
|
||||
LastTunConf.TableIndex != tunConf.TableIndex {
|
||||
LastTunConf.FileDescriptor != tunConf.FileDescriptor {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -836,6 +840,22 @@ func hasTunConfigChange(tunConf *LC.Tun) bool {
|
||||
return tunConf.DNSHijack[i] < tunConf.DNSHijack[j]
|
||||
})
|
||||
|
||||
sort.Slice(tunConf.RouteAddress, func(i, j int) bool {
|
||||
return tunConf.RouteAddress[i].String() < tunConf.RouteAddress[j].String()
|
||||
})
|
||||
|
||||
sort.Slice(tunConf.RouteAddressSet, func(i, j int) bool {
|
||||
return tunConf.RouteAddressSet[i] < tunConf.RouteAddressSet[j]
|
||||
})
|
||||
|
||||
sort.Slice(tunConf.RouteExcludeAddress, func(i, j int) bool {
|
||||
return tunConf.RouteExcludeAddress[i].String() < tunConf.RouteExcludeAddress[j].String()
|
||||
})
|
||||
|
||||
sort.Slice(tunConf.RouteExcludeAddressSet, func(i, j int) bool {
|
||||
return tunConf.RouteExcludeAddressSet[i] < tunConf.RouteExcludeAddressSet[j]
|
||||
})
|
||||
|
||||
sort.Slice(tunConf.Inet4Address, func(i, j int) bool {
|
||||
return tunConf.Inet4Address[i].String() < tunConf.Inet4Address[j].String()
|
||||
})
|
||||
@@ -897,6 +917,10 @@ func hasTunConfigChange(tunConf *LC.Tun) bool {
|
||||
})
|
||||
|
||||
if !slices.Equal(tunConf.DNSHijack, LastTunConf.DNSHijack) ||
|
||||
!slices.Equal(tunConf.RouteAddress, LastTunConf.RouteAddress) ||
|
||||
!slices.Equal(tunConf.RouteAddressSet, LastTunConf.RouteAddressSet) ||
|
||||
!slices.Equal(tunConf.RouteExcludeAddress, LastTunConf.RouteExcludeAddress) ||
|
||||
!slices.Equal(tunConf.RouteExcludeAddressSet, LastTunConf.RouteExcludeAddressSet) ||
|
||||
!slices.Equal(tunConf.Inet4Address, LastTunConf.Inet4Address) ||
|
||||
!slices.Equal(tunConf.Inet6Address, LastTunConf.Inet6Address) ||
|
||||
!slices.Equal(tunConf.Inet4RouteAddress, LastTunConf.Inet4RouteAddress) ||
|
||||
|
||||
@@ -198,6 +198,12 @@ func (h *ListenerHandler) NewError(ctx context.Context, err error) {
|
||||
log.Warnln("%s listener get error: %+v", h.Type.String(), err)
|
||||
}
|
||||
|
||||
func (h *ListenerHandler) TypeMutation(typ C.Type) *ListenerHandler {
|
||||
handler := *h
|
||||
handler.Type = typ
|
||||
return &handler
|
||||
}
|
||||
|
||||
func ShouldIgnorePacketError(err error) bool {
|
||||
// ignore simple error
|
||||
if E.IsTimeout(err) || E.IsClosed(err) || E.IsCanceled(err) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/metacubex/mihomo/component/resolver"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/listener/sing"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
|
||||
@@ -124,3 +125,9 @@ func (h *ListenerHandler) NewPacketConnection(ctx context.Context, conn network.
|
||||
}
|
||||
return h.ListenerHandler.NewPacketConnection(ctx, conn, metadata)
|
||||
}
|
||||
|
||||
func (h *ListenerHandler) TypeMutation(typ C.Type) *ListenerHandler {
|
||||
handle := *h
|
||||
handle.ListenerHandler = h.ListenerHandler.TypeMutation(typ)
|
||||
return &handle
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package sing_tun
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/netip"
|
||||
|
||||
"github.com/metacubex/mihomo/component/iface"
|
||||
|
||||
"github.com/sagernet/sing/common/control"
|
||||
)
|
||||
|
||||
type defaultInterfaceFinder struct{}
|
||||
|
||||
var DefaultInterfaceFinder control.InterfaceFinder = (*defaultInterfaceFinder)(nil)
|
||||
|
||||
func (f *defaultInterfaceFinder) Interfaces() []control.Interface {
|
||||
ifaces, err := iface.Interfaces()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
interfaces := make([]control.Interface, 0, len(ifaces))
|
||||
for _, _interface := range ifaces {
|
||||
interfaces = append(interfaces, control.Interface(*_interface))
|
||||
}
|
||||
|
||||
return interfaces
|
||||
}
|
||||
|
||||
var errNoSuchInterface = errors.New("no such network interface")
|
||||
|
||||
func (f *defaultInterfaceFinder) InterfaceIndexByName(name string) (int, error) {
|
||||
ifaces, err := iface.Interfaces()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
for _, netInterface := range ifaces {
|
||||
if netInterface.Name == name {
|
||||
return netInterface.Index, nil
|
||||
}
|
||||
}
|
||||
return 0, errNoSuchInterface
|
||||
}
|
||||
|
||||
func (f *defaultInterfaceFinder) InterfaceNameByIndex(index int) (string, error) {
|
||||
ifaces, err := iface.Interfaces()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, netInterface := range ifaces {
|
||||
if netInterface.Index == index {
|
||||
return netInterface.Name, nil
|
||||
}
|
||||
}
|
||||
return "", errNoSuchInterface
|
||||
}
|
||||
|
||||
func (f *defaultInterfaceFinder) InterfaceByAddr(addr netip.Addr) (*control.Interface, error) {
|
||||
ifaces, err := iface.Interfaces()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, netInterface := range ifaces {
|
||||
for _, prefix := range netInterface.Addresses {
|
||||
if prefix.Contains(addr) {
|
||||
return (*control.Interface)(netInterface), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, errNoSuchInterface
|
||||
}
|
||||
@@ -3,27 +3,33 @@ package sing_tun
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/metacubex/mihomo/adapter/inbound"
|
||||
"github.com/metacubex/mihomo/component/dialer"
|
||||
"github.com/metacubex/mihomo/component/iface"
|
||||
"github.com/metacubex/mihomo/component/resolver"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/constant/provider"
|
||||
LC "github.com/metacubex/mihomo/listener/config"
|
||||
"github.com/metacubex/mihomo/listener/sing"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
|
||||
tun "github.com/metacubex/sing-tun"
|
||||
"github.com/sagernet/sing/common"
|
||||
"github.com/sagernet/sing/common/control"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
F "github.com/sagernet/sing/common/format"
|
||||
"github.com/sagernet/sing/common/ranges"
|
||||
|
||||
"go4.org/netipx"
|
||||
"golang.org/x/exp/maps"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
@@ -43,10 +49,21 @@ type Listener struct {
|
||||
networkUpdateMonitor tun.NetworkUpdateMonitor
|
||||
defaultInterfaceMonitor tun.DefaultInterfaceMonitor
|
||||
packageManager tun.PackageManager
|
||||
autoRedirect tun.AutoRedirect
|
||||
autoRedirectOutputMark int32
|
||||
|
||||
ruleUpdateCallbackCloser io.Closer
|
||||
ruleUpdateMutex sync.Mutex
|
||||
routeAddressMap map[string]*netipx.IPSet
|
||||
routeExcludeAddressMap map[string]*netipx.IPSet
|
||||
routeAddressSet []*netipx.IPSet
|
||||
routeExcludeAddressSet []*netipx.IPSet
|
||||
|
||||
dnsServerIp []string
|
||||
}
|
||||
|
||||
var emptyAddressSet = []*netipx.IPSet{{}}
|
||||
|
||||
func CalculateInterfaceName(name string) (tunName string) {
|
||||
if runtime.GOOS == "darwin" {
|
||||
tunName = "utun"
|
||||
@@ -110,14 +127,45 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
|
||||
inbound.WithSpecialRules(""),
|
||||
}
|
||||
}
|
||||
ctx := context.TODO()
|
||||
rpTunnel := tunnel.(provider.Tunnel)
|
||||
if options.GSOMaxSize == 0 {
|
||||
options.GSOMaxSize = 65536
|
||||
}
|
||||
if runtime.GOOS != "linux" {
|
||||
options.AutoRedirect = false
|
||||
}
|
||||
tunName := options.Device
|
||||
if tunName == "" || !checkTunName(tunName) {
|
||||
tunName = CalculateInterfaceName(InterfaceName)
|
||||
options.Device = tunName
|
||||
}
|
||||
routeAddress := options.RouteAddress
|
||||
if len(options.Inet4RouteAddress) > 0 {
|
||||
routeAddress = append(routeAddress, options.Inet4RouteAddress...)
|
||||
}
|
||||
if len(options.Inet6RouteAddress) > 0 {
|
||||
routeAddress = append(routeAddress, options.Inet6RouteAddress...)
|
||||
}
|
||||
inet4RouteAddress := common.Filter(routeAddress, func(it netip.Prefix) bool {
|
||||
return it.Addr().Is4()
|
||||
})
|
||||
inet6RouteAddress := common.Filter(routeAddress, func(it netip.Prefix) bool {
|
||||
return it.Addr().Is6()
|
||||
})
|
||||
routeExcludeAddress := options.RouteExcludeAddress
|
||||
if len(options.Inet4RouteExcludeAddress) > 0 {
|
||||
routeExcludeAddress = append(routeExcludeAddress, options.Inet4RouteExcludeAddress...)
|
||||
}
|
||||
if len(options.Inet6RouteExcludeAddress) > 0 {
|
||||
routeExcludeAddress = append(routeExcludeAddress, options.Inet6RouteExcludeAddress...)
|
||||
}
|
||||
inet4RouteExcludeAddress := common.Filter(routeExcludeAddress, func(it netip.Prefix) bool {
|
||||
return it.Addr().Is4()
|
||||
})
|
||||
inet6RouteExcludeAddress := common.Filter(routeExcludeAddress, func(it netip.Prefix) bool {
|
||||
return it.Addr().Is6()
|
||||
})
|
||||
tunMTU := options.MTU
|
||||
if tunMTU == 0 {
|
||||
tunMTU = 9000
|
||||
@@ -128,9 +176,21 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
|
||||
} else {
|
||||
udpTimeout = int64(sing.UDPTimeout.Seconds())
|
||||
}
|
||||
tableIndex := options.TableIndex
|
||||
tableIndex := options.IPRoute2TableIndex
|
||||
if tableIndex == 0 {
|
||||
tableIndex = 2022
|
||||
tableIndex = tun.DefaultIPRoute2TableIndex
|
||||
}
|
||||
ruleIndex := options.IPRoute2RuleIndex
|
||||
if ruleIndex == 0 {
|
||||
ruleIndex = tun.DefaultIPRoute2RuleIndex
|
||||
}
|
||||
inputMark := options.AutoRedirectInputMark
|
||||
if inputMark == 0 {
|
||||
inputMark = tun.DefaultAutoRedirectInputMark
|
||||
}
|
||||
outputMark := options.AutoRedirectOutputMark
|
||||
if outputMark == 0 {
|
||||
outputMark = tun.DefaultAutoRedirectOutputMark
|
||||
}
|
||||
includeUID := uidToRange(options.IncludeUID)
|
||||
if len(options.IncludeUIDRange) > 0 {
|
||||
@@ -202,6 +262,8 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
|
||||
}
|
||||
}()
|
||||
|
||||
interfaceFinder := DefaultInterfaceFinder
|
||||
|
||||
networkUpdateMonitor, err := tun.NewNetworkUpdateMonitor(log.SingLogger)
|
||||
if err != nil {
|
||||
err = E.Cause(err, "create NetworkUpdateMonitor")
|
||||
@@ -236,11 +298,15 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
|
||||
Inet4Address: options.Inet4Address,
|
||||
Inet6Address: options.Inet6Address,
|
||||
AutoRoute: options.AutoRoute,
|
||||
IPRoute2TableIndex: tableIndex,
|
||||
IPRoute2RuleIndex: ruleIndex,
|
||||
AutoRedirectInputMark: inputMark,
|
||||
AutoRedirectOutputMark: outputMark,
|
||||
StrictRoute: options.StrictRoute,
|
||||
Inet4RouteAddress: options.Inet4RouteAddress,
|
||||
Inet6RouteAddress: options.Inet6RouteAddress,
|
||||
Inet4RouteExcludeAddress: options.Inet4RouteExcludeAddress,
|
||||
Inet6RouteExcludeAddress: options.Inet6RouteExcludeAddress,
|
||||
Inet4RouteAddress: inet4RouteAddress,
|
||||
Inet6RouteAddress: inet6RouteAddress,
|
||||
Inet4RouteExcludeAddress: inet4RouteExcludeAddress,
|
||||
Inet6RouteExcludeAddress: inet6RouteExcludeAddress,
|
||||
IncludeInterface: options.IncludeInterface,
|
||||
ExcludeInterface: options.ExcludeInterface,
|
||||
IncludeUID: includeUID,
|
||||
@@ -250,7 +316,56 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
|
||||
ExcludePackage: options.ExcludePackage,
|
||||
FileDescriptor: options.FileDescriptor,
|
||||
InterfaceMonitor: defaultInterfaceMonitor,
|
||||
TableIndex: tableIndex,
|
||||
}
|
||||
|
||||
if options.AutoRedirect {
|
||||
l.routeAddressMap = make(map[string]*netipx.IPSet)
|
||||
l.routeExcludeAddressMap = make(map[string]*netipx.IPSet)
|
||||
|
||||
if !options.AutoRoute {
|
||||
return nil, E.New("`auto-route` is required by `auto-redirect`")
|
||||
}
|
||||
disableNFTables, dErr := strconv.ParseBool(os.Getenv("DISABLE_NFTABLES"))
|
||||
l.autoRedirect, err = tun.NewAutoRedirect(tun.AutoRedirectOptions{
|
||||
TunOptions: &tunOptions,
|
||||
Context: ctx,
|
||||
Handler: handler.TypeMutation(C.REDIR),
|
||||
Logger: log.SingLogger,
|
||||
NetworkMonitor: networkUpdateMonitor,
|
||||
InterfaceFinder: interfaceFinder,
|
||||
TableName: "mihomo",
|
||||
DisableNFTables: dErr == nil && disableNFTables,
|
||||
RouteAddressSet: &l.routeAddressSet,
|
||||
RouteExcludeAddressSet: &l.routeExcludeAddressSet,
|
||||
})
|
||||
if err != nil {
|
||||
err = E.Cause(err, "initialize auto redirect")
|
||||
return
|
||||
}
|
||||
|
||||
var markMode bool
|
||||
for _, routeAddressSet := range options.RouteAddressSet {
|
||||
rp, loaded := rpTunnel.RuleProviders()[routeAddressSet]
|
||||
if !loaded {
|
||||
err = E.New("parse route-address-set: rule-set not found: ", routeAddressSet)
|
||||
return
|
||||
}
|
||||
l.updateRule(rp, false, false)
|
||||
markMode = true
|
||||
}
|
||||
for _, routeExcludeAddressSet := range options.RouteExcludeAddressSet {
|
||||
rp, loaded := rpTunnel.RuleProviders()[routeExcludeAddressSet]
|
||||
if !loaded {
|
||||
err = E.New("parse route-exclude_address-set: rule-set not found: ", routeExcludeAddressSet)
|
||||
return
|
||||
}
|
||||
l.updateRule(rp, true, false)
|
||||
markMode = true
|
||||
}
|
||||
if markMode {
|
||||
tunOptions.AutoRedirectMarkMode = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
err = l.buildAndroidRules(&tunOptions)
|
||||
@@ -269,14 +384,14 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
|
||||
resolver.AddSystemDnsBlacklist(dnsServerIp...)
|
||||
|
||||
stackOptions := tun.StackOptions{
|
||||
Context: context.TODO(),
|
||||
Context: ctx,
|
||||
Tun: tunIf,
|
||||
TunOptions: tunOptions,
|
||||
EndpointIndependentNat: options.EndpointIndependentNat,
|
||||
UDPTimeout: udpTimeout,
|
||||
Handler: handler,
|
||||
Logger: log.SingLogger,
|
||||
InterfaceFinder: control.DefaultInterfaceFinder(),
|
||||
InterfaceFinder: interfaceFinder,
|
||||
EnforceBindInterface: EnforceBindInterface,
|
||||
}
|
||||
|
||||
@@ -299,13 +414,76 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
|
||||
}
|
||||
l.tunStack = tunStack
|
||||
|
||||
if l.autoRedirect != nil {
|
||||
if len(l.options.RouteAddressSet) > 0 && len(l.routeAddressSet) == 0 {
|
||||
l.routeAddressSet = emptyAddressSet // without this we can't call UpdateRouteAddressSet after Start
|
||||
}
|
||||
if len(l.options.RouteExcludeAddressSet) > 0 && len(l.routeExcludeAddressSet) == 0 {
|
||||
l.routeExcludeAddressSet = emptyAddressSet // without this we can't call UpdateRouteAddressSet after Start
|
||||
}
|
||||
err = l.autoRedirect.Start()
|
||||
if err != nil {
|
||||
err = E.Cause(err, "auto redirect")
|
||||
return
|
||||
}
|
||||
if tunOptions.AutoRedirectMarkMode {
|
||||
l.autoRedirectOutputMark = int32(outputMark)
|
||||
dialer.DefaultRoutingMark.Store(l.autoRedirectOutputMark)
|
||||
l.autoRedirect.UpdateRouteAddressSet()
|
||||
l.ruleUpdateCallbackCloser = rpTunnel.RuleUpdateCallback().Register(l.ruleUpdateCallback)
|
||||
}
|
||||
}
|
||||
|
||||
//l.openAndroidHotspot(tunOptions)
|
||||
|
||||
l.addrStr = fmt.Sprintf("%s(%s,%s), mtu: %d, auto route: %v, ip stack: %s",
|
||||
tunName, tunOptions.Inet4Address, tunOptions.Inet6Address, tunMTU, options.AutoRoute, options.Stack)
|
||||
l.addrStr = fmt.Sprintf("%s(%s,%s), mtu: %d, auto route: %v, auto redir: %v, ip stack: %s",
|
||||
tunName, tunOptions.Inet4Address, tunOptions.Inet6Address, tunMTU, options.AutoRoute, options.AutoRedirect, options.Stack)
|
||||
return
|
||||
}
|
||||
|
||||
func (l *Listener) ruleUpdateCallback(ruleProvider provider.RuleProvider) {
|
||||
name := ruleProvider.Name()
|
||||
if slices.Contains(l.options.RouteAddressSet, name) {
|
||||
l.updateRule(ruleProvider, false, true)
|
||||
return
|
||||
}
|
||||
if slices.Contains(l.options.RouteExcludeAddressSet, name) {
|
||||
l.updateRule(ruleProvider, true, true)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Listener) updateRule(ruleProvider provider.RuleProvider, exclude bool, update bool) {
|
||||
l.ruleUpdateMutex.Lock()
|
||||
defer l.ruleUpdateMutex.Unlock()
|
||||
name := ruleProvider.Name()
|
||||
switch rp := ruleProvider.Strategy().(type) {
|
||||
case interface{ ToIpCidr() *netipx.IPSet }:
|
||||
if !exclude {
|
||||
ipCidr := rp.ToIpCidr()
|
||||
if ipCidr != nil {
|
||||
l.routeAddressMap[name] = ipCidr
|
||||
} else {
|
||||
delete(l.routeAddressMap, name)
|
||||
}
|
||||
l.routeAddressSet = maps.Values(l.routeAddressMap)
|
||||
} else {
|
||||
ipCidr := rp.ToIpCidr()
|
||||
if ipCidr != nil {
|
||||
l.routeExcludeAddressMap[name] = ipCidr
|
||||
} else {
|
||||
delete(l.routeExcludeAddressMap, name)
|
||||
}
|
||||
l.routeExcludeAddressSet = maps.Values(l.routeExcludeAddressMap)
|
||||
}
|
||||
default:
|
||||
return
|
||||
}
|
||||
if update && l.autoRedirect != nil {
|
||||
l.autoRedirect.UpdateRouteAddressSet()
|
||||
}
|
||||
}
|
||||
|
||||
func (l *Listener) FlushDefaultInterface() {
|
||||
if l.options.AutoDetectInterface {
|
||||
for _, destination := range []netip.Addr{netip.IPv4Unspecified(), netip.IPv6Unspecified(), netip.MustParseAddr("1.1.1.1")} {
|
||||
@@ -347,11 +525,11 @@ func parseRange(uidRanges []ranges.Range[uint32], rangeList []string) ([]ranges.
|
||||
}
|
||||
var start, end uint64
|
||||
var err error
|
||||
start, err = strconv.ParseUint(uidRange[:subIndex], 10, 32)
|
||||
start, err = strconv.ParseUint(uidRange[:subIndex], 0, 32)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "parse range start")
|
||||
}
|
||||
end, err = strconv.ParseUint(uidRange[subIndex+1:], 10, 32)
|
||||
end, err = strconv.ParseUint(uidRange[subIndex+1:], 0, 32)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "parse range end")
|
||||
}
|
||||
@@ -363,9 +541,14 @@ func parseRange(uidRanges []ranges.Range[uint32], rangeList []string) ([]ranges.
|
||||
func (l *Listener) Close() error {
|
||||
l.closed = true
|
||||
resolver.RemoveSystemDnsBlacklist(l.dnsServerIp...)
|
||||
if l.autoRedirectOutputMark != 0 {
|
||||
dialer.DefaultRoutingMark.CompareAndSwap(l.autoRedirectOutputMark, 0)
|
||||
}
|
||||
return common.Close(
|
||||
l.ruleUpdateCallbackCloser,
|
||||
l.tunStack,
|
||||
l.tunIf,
|
||||
l.autoRedirect,
|
||||
l.defaultInterfaceMonitor,
|
||||
l.networkUpdateMonitor,
|
||||
l.packageManager,
|
||||
|
||||
@@ -119,9 +119,7 @@ func CleanupTProxyIPTables() {
|
||||
|
||||
log.Warnln("Cleanup tproxy linux iptables")
|
||||
|
||||
if int(dialer.DefaultRoutingMark.Load()) == 2158 {
|
||||
dialer.DefaultRoutingMark.Store(0)
|
||||
}
|
||||
dialer.DefaultRoutingMark.CompareAndSwap(2158, 0)
|
||||
|
||||
if _, err := cmd.ExecCmd("iptables -t mangle -L mihomo_divert"); err != nil {
|
||||
return
|
||||
|
||||
@@ -20,6 +20,8 @@ func (b *Base) ShouldResolveIP() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *Base) ProviderNames() []string { return nil }
|
||||
|
||||
func HasNoResolve(params []string) bool {
|
||||
for _, p := range params {
|
||||
if p == noResolve {
|
||||
|
||||
@@ -298,3 +298,10 @@ func (logic *Logic) ShouldResolveIP() bool {
|
||||
func (logic *Logic) ShouldFindProcess() bool {
|
||||
return logic.needProcess
|
||||
}
|
||||
|
||||
func (logic *Logic) ProviderNames() (names []string) {
|
||||
for _, rule := range logic.rules {
|
||||
names = append(names, rule.ProviderNames()...)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"github.com/metacubex/mihomo/component/cidr"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
"github.com/metacubex/mihomo/log"
|
||||
|
||||
"go4.org/netipx"
|
||||
)
|
||||
|
||||
type ipcidrStrategy struct {
|
||||
@@ -52,6 +54,10 @@ func (i *ipcidrStrategy) FinishInsert() {
|
||||
i.cidrSet.Merge()
|
||||
}
|
||||
|
||||
func (i *ipcidrStrategy) ToIpCidr() *netipx.IPSet {
|
||||
return i.cidrSet.ToIPSet()
|
||||
}
|
||||
|
||||
func NewIPCidrStrategy() *ipcidrStrategy {
|
||||
return &ipcidrStrategy{}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ type UpdatableProvider interface {
|
||||
UpdatedAt() time.Time
|
||||
}
|
||||
|
||||
func (f *ruleSetProvider) UpdatedAt() time.Time {
|
||||
return f.Fetcher.UpdatedAt
|
||||
func (rp *ruleSetProvider) UpdatedAt() time.Time {
|
||||
return rp.Fetcher.UpdatedAt
|
||||
}
|
||||
|
||||
func (rp *ruleSetProvider) Close() error {
|
||||
|
||||
@@ -15,12 +15,14 @@ import (
|
||||
P "github.com/metacubex/mihomo/constant/provider"
|
||||
)
|
||||
|
||||
var (
|
||||
ruleProviders = map[string]P.RuleProvider{}
|
||||
)
|
||||
var tunnel P.Tunnel
|
||||
|
||||
func SetTunnel(t P.Tunnel) {
|
||||
tunnel = t
|
||||
}
|
||||
|
||||
type ruleSetProvider struct {
|
||||
*resource.Fetcher[any]
|
||||
*resource.Fetcher[ruleStrategy]
|
||||
behavior P.RuleBehavior
|
||||
format P.RuleFormat
|
||||
strategy ruleStrategy
|
||||
@@ -49,16 +51,6 @@ type ruleStrategy interface {
|
||||
FinishInsert()
|
||||
}
|
||||
|
||||
func RuleProviders() map[string]P.RuleProvider {
|
||||
return ruleProviders
|
||||
}
|
||||
|
||||
func SetRuleProvider(ruleProvider P.RuleProvider) {
|
||||
if ruleProvider != nil {
|
||||
ruleProviders[(ruleProvider).Name()] = ruleProvider
|
||||
}
|
||||
}
|
||||
|
||||
func (rp *ruleSetProvider) Type() P.ProviderType {
|
||||
return P.Rule
|
||||
}
|
||||
@@ -99,8 +91,8 @@ func (rp *ruleSetProvider) ShouldFindProcess() bool {
|
||||
return rp.strategy.ShouldFindProcess()
|
||||
}
|
||||
|
||||
func (rp *ruleSetProvider) AsRule(adaptor string) C.Rule {
|
||||
panic("implement me")
|
||||
func (rp *ruleSetProvider) Strategy() any {
|
||||
return rp.strategy
|
||||
}
|
||||
|
||||
func (rp *ruleSetProvider) MarshalJSON() ([]byte, error) {
|
||||
@@ -123,13 +115,15 @@ func NewRuleSetProvider(name string, behavior P.RuleBehavior, format P.RuleForma
|
||||
format: format,
|
||||
}
|
||||
|
||||
onUpdate := func(elm interface{}) {
|
||||
strategy := elm.(ruleStrategy)
|
||||
onUpdate := func(strategy ruleStrategy) {
|
||||
rp.strategy = strategy
|
||||
tunnel.RuleUpdateCallback().Emit(rp)
|
||||
}
|
||||
|
||||
rp.strategy = newStrategy(behavior, parse)
|
||||
rp.Fetcher = resource.NewFetcher(name, interval, vehicle, func(bytes []byte) (any, error) { return rulesParse(bytes, newStrategy(behavior, parse), format) }, onUpdate)
|
||||
rp.Fetcher = resource.NewFetcher(name, interval, vehicle, func(bytes []byte) (ruleStrategy, error) {
|
||||
return rulesParse(bytes, newStrategy(behavior, parse), format)
|
||||
}, onUpdate)
|
||||
|
||||
wrapper := &RuleSetProvider{
|
||||
rp,
|
||||
@@ -158,7 +152,7 @@ func newStrategy(behavior P.RuleBehavior, parse func(tp, payload, target string,
|
||||
|
||||
var ErrNoPayload = errors.New("file must have a `payload` field")
|
||||
|
||||
func rulesParse(buf []byte, strategy ruleStrategy, format P.RuleFormat) (any, error) {
|
||||
func rulesParse(buf []byte, strategy ruleStrategy, format P.RuleFormat) (ruleStrategy, error) {
|
||||
strategy.Reset()
|
||||
|
||||
schema := &RulePayload{}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
C "github.com/metacubex/mihomo/constant"
|
||||
P "github.com/metacubex/mihomo/constant/provider"
|
||||
"github.com/metacubex/mihomo/rules/common"
|
||||
@@ -11,13 +10,18 @@ type RuleSet struct {
|
||||
*common.Base
|
||||
ruleProviderName string
|
||||
adapter string
|
||||
ruleProvider P.RuleProvider
|
||||
noResolveIP bool
|
||||
shouldFindProcess bool
|
||||
}
|
||||
|
||||
func (rs *RuleSet) ShouldFindProcess() bool {
|
||||
return rs.shouldFindProcess || rs.getProviders().ShouldFindProcess()
|
||||
if rs.shouldFindProcess {
|
||||
return true
|
||||
}
|
||||
if provider, ok := rs.getProvider(); ok {
|
||||
return provider.ShouldFindProcess()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rs *RuleSet) RuleType() C.RuleType {
|
||||
@@ -25,7 +29,10 @@ func (rs *RuleSet) RuleType() C.RuleType {
|
||||
}
|
||||
|
||||
func (rs *RuleSet) Match(metadata *C.Metadata) (bool, string) {
|
||||
return rs.getProviders().Match(metadata), rs.adapter
|
||||
if provider, ok := rs.getProvider(); ok {
|
||||
return provider.Match(metadata), rs.adapter
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
func (rs *RuleSet) Adapter() string {
|
||||
@@ -33,31 +40,37 @@ func (rs *RuleSet) Adapter() string {
|
||||
}
|
||||
|
||||
func (rs *RuleSet) Payload() string {
|
||||
return rs.getProviders().Name()
|
||||
if provider, ok := rs.getProvider(); ok {
|
||||
return provider.Name()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (rs *RuleSet) ShouldResolveIP() bool {
|
||||
return !rs.noResolveIP && rs.getProviders().ShouldResolveIP()
|
||||
}
|
||||
func (rs *RuleSet) getProviders() P.RuleProvider {
|
||||
if rs.ruleProvider == nil {
|
||||
rp := RuleProviders()[rs.ruleProviderName]
|
||||
rs.ruleProvider = rp
|
||||
if rs.noResolveIP {
|
||||
return false
|
||||
}
|
||||
if provider, ok := rs.getProvider(); ok {
|
||||
return provider.ShouldResolveIP()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
return rs.ruleProvider
|
||||
func (rs *RuleSet) ProviderNames() []string {
|
||||
return []string{rs.ruleProviderName}
|
||||
}
|
||||
|
||||
func (rs *RuleSet) getProvider() (P.RuleProvider, bool) {
|
||||
pp, ok := tunnel.RuleProviders()[rs.ruleProviderName]
|
||||
return pp, ok
|
||||
}
|
||||
|
||||
func NewRuleSet(ruleProviderName string, adapter string, noResolveIP bool) (*RuleSet, error) {
|
||||
rp, ok := RuleProviders()[ruleProviderName]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("rule set %s not found", ruleProviderName)
|
||||
}
|
||||
return &RuleSet{
|
||||
rs := &RuleSet{
|
||||
Base: &common.Base{},
|
||||
ruleProviderName: ruleProviderName,
|
||||
adapter: adapter,
|
||||
ruleProvider: rp,
|
||||
noResolveIP: noResolveIP,
|
||||
}, nil
|
||||
}
|
||||
return rs, nil
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"time"
|
||||
|
||||
N "github.com/metacubex/mihomo/common/net"
|
||||
"github.com/metacubex/mihomo/common/utils"
|
||||
"github.com/metacubex/mihomo/component/loopback"
|
||||
"github.com/metacubex/mihomo/component/nat"
|
||||
P "github.com/metacubex/mihomo/component/process"
|
||||
@@ -50,11 +51,15 @@ var (
|
||||
findProcessMode P.FindProcessMode
|
||||
|
||||
fakeIPRange netip.Prefix
|
||||
|
||||
ruleUpdateCallback = utils.NewCallback[provider.RuleProvider]()
|
||||
)
|
||||
|
||||
type tunnel struct{}
|
||||
|
||||
var Tunnel C.Tunnel = tunnel{}
|
||||
var Tunnel = tunnel{}
|
||||
var _ C.Tunnel = Tunnel
|
||||
var _ provider.Tunnel = Tunnel
|
||||
|
||||
func (t tunnel) HandleTCPConn(conn net.Conn, metadata *C.Metadata) {
|
||||
connCtx := icontext.NewConnContext(conn, metadata)
|
||||
@@ -73,6 +78,18 @@ func (t tunnel) NatTable() C.NatTable {
|
||||
return natTable
|
||||
}
|
||||
|
||||
func (t tunnel) Providers() map[string]provider.ProxyProvider {
|
||||
return providers
|
||||
}
|
||||
|
||||
func (t tunnel) RuleProviders() map[string]provider.RuleProvider {
|
||||
return ruleProviders
|
||||
}
|
||||
|
||||
func (t tunnel) RuleUpdateCallback() *utils.Callback[provider.RuleProvider] {
|
||||
return ruleUpdateCallback
|
||||
}
|
||||
|
||||
func OnSuspend() {
|
||||
status.Store(Suspend)
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ pub fn create_window(app_handle: &AppHandle) {
|
||||
let mut builder = tauri::window::WindowBuilder::new(
|
||||
app_handle,
|
||||
"main".to_string(),
|
||||
tauri::WindowUrl::App("/proxies".into()),
|
||||
tauri::WindowUrl::App("/dashboard".into()),
|
||||
)
|
||||
.title("Clash Nyanpasu")
|
||||
.fullscreen(false)
|
||||
|
||||
@@ -22,6 +22,8 @@ export const useClashWS = () => {
|
||||
return {
|
||||
connections: resolveUrl("connections"),
|
||||
logs: resolveUrl("logs"),
|
||||
traffic: resolveUrl("traffic"),
|
||||
memory: resolveUrl("memory"),
|
||||
};
|
||||
}
|
||||
}, [getClashInfo.data]);
|
||||
@@ -30,8 +32,14 @@ export const useClashWS = () => {
|
||||
|
||||
const logs = useWebSocket(url?.logs ?? "");
|
||||
|
||||
const traffic = useWebSocket(url?.traffic ?? "");
|
||||
|
||||
const memory = useWebSocket(url?.memory ?? "");
|
||||
|
||||
return {
|
||||
connections,
|
||||
logs,
|
||||
traffic,
|
||||
memory,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -189,3 +189,13 @@ export interface ProviderItem {
|
||||
updatedAt: string;
|
||||
vehicleType: string;
|
||||
}
|
||||
|
||||
export interface Traffic {
|
||||
up: number;
|
||||
down: number;
|
||||
}
|
||||
|
||||
export interface Memory {
|
||||
inuse: number;
|
||||
oslimit: number;
|
||||
}
|
||||
|
||||
@@ -56,9 +56,10 @@
|
||||
"@typescript-eslint/eslint-plugin": "7.13.0",
|
||||
"@typescript-eslint/parser": "7.13.0",
|
||||
"@vitejs/plugin-react": "4.3.1",
|
||||
"@vitejs/plugin-react-swc": "^3.7.0",
|
||||
"@vitejs/plugin-react-swc": "3.7.0",
|
||||
"sass": "1.77.5",
|
||||
"shiki": "1.6.5",
|
||||
"shiki": "1.7.0",
|
||||
"tailwindcss-textshadow": "2.1.3",
|
||||
"vite": "5.3.1",
|
||||
"vite-plugin-monaco-editor": "1.1.3",
|
||||
"vite-plugin-sass-dts": "1.3.22",
|
||||
|
||||
@@ -34,13 +34,29 @@ export const AppDrawer = ({ isDrawer }: { isDrawer?: boolean }) => {
|
||||
data-windrag
|
||||
>
|
||||
<div
|
||||
className="w-full h-full max-w-32 max-h-32 ml-auto mr-auto"
|
||||
data-windrag
|
||||
className={classNames(
|
||||
"flex items-center justify-center gap-4 ",
|
||||
isDrawer && "mx-2",
|
||||
)}
|
||||
>
|
||||
<AnimatedLogo className="w-full h-full" data-windrag />
|
||||
<div
|
||||
className={classNames(
|
||||
isDrawer && "w-10 h-10",
|
||||
"w-full h-full max-w-32 max-h-32 ml-auto mr-auto",
|
||||
)}
|
||||
data-windrag
|
||||
>
|
||||
<AnimatedLogo className="w-full h-full" data-windrag />
|
||||
</div>
|
||||
|
||||
{isDrawer && (
|
||||
<div className="text-lg text-nowrap font-bold mt-1" data-windrag>
|
||||
Clash Nyanpasu
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex flex-col gap-2 overflow-y-auto scrollbar-hidden">
|
||||
{Object.entries(routes).map(([name, { path, icon }]) => {
|
||||
return (
|
||||
<RouteListItem key={name} name={name} path={path} icon={icon} />
|
||||
|
||||
@@ -23,7 +23,7 @@ export const RouteListItem = ({
|
||||
|
||||
return (
|
||||
<ListItemButton
|
||||
className="!pr-12 !rounded-full"
|
||||
className="!pr-14 !rounded-full"
|
||||
sx={{
|
||||
backgroundColor: match ? alpha(palette.primary.main, 0.3) : undefined,
|
||||
|
||||
@@ -42,7 +42,7 @@ export const RouteListItem = ({
|
||||
</ListItemIcon>
|
||||
|
||||
<div
|
||||
className="pt-1 pb-1"
|
||||
className="pt-1 pb-1 w-full text-center text-nowrap"
|
||||
style={{ color: match ? palette.primary.main : undefined }}
|
||||
>
|
||||
{t(`label_${name}`)}
|
||||
|
||||
@@ -45,9 +45,14 @@ export const ConnectionsTable = () => {
|
||||
? connection.upload - previousConnection.upload
|
||||
: 0;
|
||||
|
||||
const host = String(
|
||||
connection.metadata.host || connection.metadata.destinationIP,
|
||||
);
|
||||
|
||||
updatedConnections.push({
|
||||
...connection,
|
||||
...connection.metadata,
|
||||
host,
|
||||
downloadSpeed,
|
||||
uploadSpeed,
|
||||
});
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
import Dataline, { DatalineProps } from "@/components/dashboard/dataline";
|
||||
import {
|
||||
Connection,
|
||||
Memory,
|
||||
Traffic,
|
||||
useClashWS,
|
||||
useNyanpasu,
|
||||
} from "@nyanpasu/interface";
|
||||
import { useInterval } from "ahooks";
|
||||
import { useState } from "react";
|
||||
import {
|
||||
ArrowDownward,
|
||||
ArrowUpward,
|
||||
MemoryOutlined,
|
||||
SettingsEthernet,
|
||||
} from "@mui/icons-material";
|
||||
import Grid from "@mui/material/Unstable_Grid2";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export const DataPanel = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [traffic, setTraffice] = useState<Traffic[]>(
|
||||
new Array(16).fill({ up: 0, down: 0 }),
|
||||
);
|
||||
|
||||
const [memory, setMemory] = useState<Memory[]>(
|
||||
new Array(16).fill({ inuse: 0 }),
|
||||
);
|
||||
|
||||
const [connection, setConnection] = useState<
|
||||
{
|
||||
downloadTotal: number;
|
||||
uploadTotal: number;
|
||||
connections: number;
|
||||
}[]
|
||||
>(
|
||||
new Array(16).fill({
|
||||
downloadTotal: 0,
|
||||
uploadTotal: 0,
|
||||
connections: 0,
|
||||
}),
|
||||
);
|
||||
|
||||
const {
|
||||
traffic: { latestMessage: latestTraffic },
|
||||
memory: { latestMessage: latestMemory },
|
||||
connections: { latestMessage: latestConnections },
|
||||
} = useClashWS();
|
||||
|
||||
useInterval(() => {
|
||||
const trafficData = latestTraffic?.data
|
||||
? (JSON.parse(latestTraffic.data) as Traffic)
|
||||
: { up: 0, down: 0 };
|
||||
|
||||
setTraffice((prevData) => [...prevData.slice(1), trafficData]);
|
||||
|
||||
const meomryData = latestMemory?.data
|
||||
? (JSON.parse(latestMemory.data) as Memory)
|
||||
: { inuse: 0, oslimit: 0 };
|
||||
|
||||
setMemory((prevData) => [...prevData.slice(1), meomryData]);
|
||||
|
||||
const connectionsData = latestConnections?.data
|
||||
? (JSON.parse(latestConnections.data) as Connection.Response)
|
||||
: {
|
||||
downloadTotal: 0,
|
||||
uploadTotal: 0,
|
||||
};
|
||||
|
||||
setConnection((prevData) => [
|
||||
...prevData.slice(1),
|
||||
{
|
||||
downloadTotal: connectionsData.downloadTotal,
|
||||
uploadTotal: connectionsData.uploadTotal,
|
||||
connections: connectionsData.connections?.length ?? 0,
|
||||
},
|
||||
]);
|
||||
}, 1000);
|
||||
|
||||
const { nyanpasuConfig } = useNyanpasu();
|
||||
|
||||
const supportMemory =
|
||||
nyanpasuConfig?.clash_core &&
|
||||
["mihomo", "mihomo-alpha"].includes(nyanpasuConfig?.clash_core);
|
||||
|
||||
const Datalines: DatalineProps[] = [
|
||||
{
|
||||
data: traffic.map((item) => item.up),
|
||||
icon: ArrowUpward,
|
||||
title: t("Upload Traffic"),
|
||||
total: connection.at(-1)?.uploadTotal,
|
||||
type: "speed",
|
||||
},
|
||||
{
|
||||
data: traffic.map((item) => item.down),
|
||||
icon: ArrowDownward,
|
||||
title: t("Download Traffic"),
|
||||
total: connection.at(-1)?.downloadTotal,
|
||||
type: "speed",
|
||||
},
|
||||
{
|
||||
data: connection.map((item) => item.connections),
|
||||
icon: SettingsEthernet,
|
||||
title: t("Active Connections"),
|
||||
type: "raw",
|
||||
},
|
||||
];
|
||||
|
||||
if (supportMemory) {
|
||||
Datalines.splice(2, 0, {
|
||||
data: memory.map((item) => item.inuse),
|
||||
icon: MemoryOutlined,
|
||||
title: t("Memory"),
|
||||
});
|
||||
}
|
||||
|
||||
const gridLayout = {
|
||||
sm: 12,
|
||||
md: 6,
|
||||
lg: supportMemory ? 3 : 4,
|
||||
xl: supportMemory ? 3 : 4,
|
||||
};
|
||||
|
||||
return Datalines.map((props, index) => {
|
||||
return (
|
||||
<Grid key={`data-${index}`} {...gridLayout} className="w-full">
|
||||
<Dataline {...props} className="min-h-48 max-h-1/8" />
|
||||
</Grid>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
export default DataPanel;
|
||||
@@ -0,0 +1,53 @@
|
||||
import parseTraffic from "@/utils/parse-traffic";
|
||||
import { SvgIconComponent } from "@mui/icons-material";
|
||||
import { Paper } from "@mui/material";
|
||||
import { Sparkline } from "@nyanpasu/ui";
|
||||
import { FC, cloneElement } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export interface DatalineProps {
|
||||
data: number[];
|
||||
icon: SvgIconComponent;
|
||||
title: string;
|
||||
total?: number;
|
||||
type?: "speed" | "raw";
|
||||
}
|
||||
|
||||
export const Dataline: FC<DatalineProps> = ({
|
||||
data,
|
||||
icon,
|
||||
title,
|
||||
total,
|
||||
type,
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Paper className="!rounded-3xl relative">
|
||||
<Sparkline data={data} className="rounded-3xl" />
|
||||
|
||||
<div className="absolute top-0 p-4 h-full flex flex-col gap-4 justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
{cloneElement(icon)}
|
||||
|
||||
<div className="font-bold">{title}</div>
|
||||
</div>
|
||||
|
||||
<div className="font-bold text-2xl text-shadow-md">
|
||||
{type === "raw" ? data.at(-1) : parseTraffic(data.at(-1)).join(" ")}
|
||||
{type === "speed" && "/s"}
|
||||
</div>
|
||||
|
||||
<div className=" h-5">
|
||||
{total && (
|
||||
<span className="text-shadow-sm">
|
||||
{t("Total")}: {parseTraffic(total).join(" ")}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</Paper>
|
||||
);
|
||||
};
|
||||
|
||||
export default Dataline;
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"label_dashboard": "Dashboard",
|
||||
"label_proxies": "Proxies",
|
||||
"label_profiles": "Profiles",
|
||||
"label_connections": "Connections",
|
||||
@@ -7,8 +8,10 @@
|
||||
"label_settings": "Settings",
|
||||
"label_providers": "Providers",
|
||||
"Connections": "Connections",
|
||||
"Upload Total": "Upload Total",
|
||||
"Download Total": "Download Total",
|
||||
"Upload Traffic": "Upload",
|
||||
"Download Traffic": "Download",
|
||||
"Total": "Total",
|
||||
"Memory": "Memory",
|
||||
"Active Connections": "Active Connections",
|
||||
"Logs": "Logs",
|
||||
"Clear": "Clear",
|
||||
@@ -18,6 +21,7 @@
|
||||
"global": "global",
|
||||
"direct": "direct",
|
||||
"script": "script",
|
||||
"Dashboard": "Dashboard",
|
||||
"Profiles": "Profiles",
|
||||
"Profile URL": "Profile URL",
|
||||
"Import": "Import",
|
||||
@@ -116,7 +120,6 @@
|
||||
"Retain 30 Days": "Retain 30 Days",
|
||||
"Retain 90 Days": "Retain 90 Days",
|
||||
"Max Log Files": "Max Log Files",
|
||||
|
||||
"Collect Logs": "Collect Logs",
|
||||
"Back": "Back",
|
||||
"Save": "Save",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"label_dashboard": "概 览",
|
||||
"label_proxies": "代 理",
|
||||
"label_profiles": "配 置",
|
||||
"label_connections": "连 接",
|
||||
@@ -6,10 +7,13 @@
|
||||
"label_rules": "规 则",
|
||||
"label_settings": "设 置",
|
||||
"label_providers": "资 源",
|
||||
|
||||
"Connections": "连接",
|
||||
"Upload Total": "上传总量",
|
||||
"Download Total": "下载总量",
|
||||
"Upload Traffic": "上传流量",
|
||||
"Download Traffic": "下载流量",
|
||||
"Total": "总量",
|
||||
"Memory": "内存占用",
|
||||
"Active Connections": "活动连接",
|
||||
"Logs": "日志",
|
||||
"Clear": "清除",
|
||||
@@ -19,7 +23,7 @@
|
||||
"global": "全局",
|
||||
"direct": "直连",
|
||||
"script": "脚本",
|
||||
|
||||
"Dashboard": "概览",
|
||||
"Profiles": "配置",
|
||||
"Profile URL": "配置文件链接",
|
||||
"Import": "导入",
|
||||
@@ -42,7 +46,6 @@
|
||||
"Update All Profiles": "更新所有配置",
|
||||
"View Runtime Config": "查看运行时配置",
|
||||
"Reactivate Profiles": "重新激活配置",
|
||||
|
||||
"Location": "当前节点",
|
||||
"Delay check": "延迟测试",
|
||||
"Sort by default": "默认排序",
|
||||
@@ -53,7 +56,6 @@
|
||||
"Filter": "过滤节点",
|
||||
"Filter conditions": "过滤条件",
|
||||
"Refresh profiles": "刷新配置",
|
||||
|
||||
"Type": "类型",
|
||||
"Name": "名称",
|
||||
"Descriptions": "描述",
|
||||
@@ -61,7 +63,6 @@
|
||||
"Update Interval": "更新间隔",
|
||||
"Use System Proxy": "使用系统代理更新",
|
||||
"Use Clash Proxy": "使用Clash代理更新",
|
||||
|
||||
"Settings": "设置",
|
||||
"Clash Setting": "Clash 设置",
|
||||
"System Setting": "系统设置",
|
||||
@@ -113,7 +114,6 @@
|
||||
"ReadOnly": "只读",
|
||||
"Check Updates": "检查更新",
|
||||
"Restart": "重启内核",
|
||||
|
||||
"Tasks": "定期任务",
|
||||
"Auto Log Clean": "自动清理日志",
|
||||
"Never Clean": "不清理",
|
||||
@@ -122,16 +122,13 @@
|
||||
"Retain 30 Days": "保留30天",
|
||||
"Retain 90 Days": "保留90天",
|
||||
"Max Log Files": "最大日志文件数",
|
||||
|
||||
"Collect Logs": "收集日志",
|
||||
"Back": "返回",
|
||||
"Save": "保存",
|
||||
"Cancel": "取消",
|
||||
|
||||
"Default": "默认",
|
||||
"Download Speed": "下载速度",
|
||||
"Upload Speed": "上传速度",
|
||||
|
||||
"open_or_close_dashboard": "打开/关闭面板",
|
||||
"clash_mode_rule": "规则模式",
|
||||
"clash_mode_global": "全局模式",
|
||||
@@ -143,26 +140,21 @@
|
||||
"toggle_tun_mode": "切换Tun模式",
|
||||
"enable_tun_mode": "开启Tun模式",
|
||||
"disable_tun_mode": "关闭Tun模式",
|
||||
|
||||
"App Log Level": "App日志等级",
|
||||
"Auto Close Connections": "自动关闭连接",
|
||||
"Enable Clash Fields Filter": "开启Clash字段过滤",
|
||||
"Enable Builtin Enhanced": "开启内建增强功能",
|
||||
"Proxy Layout Column": "代理页布局列数",
|
||||
"Default Latency Test": "默认测试链接",
|
||||
|
||||
"Error": "错误",
|
||||
"Success": "成功",
|
||||
|
||||
"Providers": "资源",
|
||||
"Rules Providers": "规则集",
|
||||
"Update Rules Providers All": "全部更新",
|
||||
"Rule Set rules": "{{rule}} 条规则",
|
||||
"Last Update": "{{fromNow}}更新",
|
||||
"Update Rules Providers Success": "更新规则集成功",
|
||||
|
||||
"Portable Update Error": "便携版无法自动更新,请到 Github 下载最新版本",
|
||||
|
||||
"Enable Tray Proxies Selector": "开启托盘代理选择",
|
||||
"Proxy Set proxies": "{{rule}} 个节点",
|
||||
"Update Proxies Providers All": "全部更新",
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { BasePage } from "@nyanpasu/ui";
|
||||
import Grid from "@mui/material/Unstable_Grid2";
|
||||
import DataPanel from "@/components/dashboard/data-panel";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
export const Dashboard = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<BasePage title={t("Dashboard")}>
|
||||
<Grid container spacing={2} sx={{ width: "calc(100% + 24px)" }}>
|
||||
<DataPanel />
|
||||
</Grid>
|
||||
</BasePage>
|
||||
);
|
||||
};
|
||||
|
||||
export default Dashboard;
|
||||
@@ -1,23 +1,26 @@
|
||||
// Generouted, changes to this file will be overriden
|
||||
/* eslint-disable */
|
||||
|
||||
import { components, hooks, utils } from '@generouted/react-router/client'
|
||||
import { components, hooks, utils } from "@generouted/react-router/client";
|
||||
|
||||
export type Path =
|
||||
| `/connections`
|
||||
| `/dashboard`
|
||||
| `/logs`
|
||||
| `/profiles`
|
||||
| `/providers`
|
||||
| `/proxies`
|
||||
| `/rules`
|
||||
| `/settings`
|
||||
| `/settings`;
|
||||
|
||||
export type Params = {
|
||||
|
||||
}
|
||||
export type Params = {};
|
||||
|
||||
export type ModalPath = never
|
||||
export type ModalPath = never;
|
||||
|
||||
export const { Link, Navigate } = components<Path, Params>()
|
||||
export const { useModals, useNavigate, useParams } = hooks<Path, Params, ModalPath>()
|
||||
export const { redirect } = utils<Path, Params>()
|
||||
export const { Link, Navigate } = components<Path, Params>();
|
||||
export const { useModals, useNavigate, useParams } = hooks<
|
||||
Path,
|
||||
Params,
|
||||
ModalPath
|
||||
>();
|
||||
export const { redirect } = utils<Path, Params>();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {
|
||||
Apps,
|
||||
Dashboard,
|
||||
DesignServices,
|
||||
GridView,
|
||||
Public,
|
||||
@@ -10,6 +11,7 @@ import {
|
||||
} from "@mui/icons-material";
|
||||
|
||||
const routes: { [key: string]: SvgIconComponent } = {
|
||||
dashboard: Dashboard,
|
||||
proxies: Public,
|
||||
profiles: GridView,
|
||||
connections: SettingsEthernet,
|
||||
|
||||
@@ -1,8 +1,24 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const plugin = require("tailwindcss/plugin");
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: ["./src/**/*.{tsx,ts}"],
|
||||
theme: {
|
||||
extend: {},
|
||||
extend: {
|
||||
maxHeight: {
|
||||
"1/8": "calc(100vh / 8)",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
plugins: [
|
||||
require("tailwindcss-textshadow"),
|
||||
plugin(({ addBase }) => {
|
||||
addBase({
|
||||
".scrollbar-hidden::-webkit-scrollbar": {
|
||||
width: "0px",
|
||||
},
|
||||
});
|
||||
}),
|
||||
],
|
||||
};
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
"@/*": ["src/*"],
|
||||
"~/*": ["./*"],
|
||||
},
|
||||
"jsxImportSource": "@emotion/react",
|
||||
},
|
||||
"include": ["./src"],
|
||||
"references": [{ "path": "../interface/tsconfig.json" }],
|
||||
|
||||
@@ -46,7 +46,6 @@ export default defineConfig(({ command }) => {
|
||||
tsconfigPaths(),
|
||||
svgr(),
|
||||
react({
|
||||
jsxImportSource: "@emotion/react",
|
||||
// babel: {
|
||||
// plugins: ["@emotion/babel-plugin"],
|
||||
// },
|
||||
@@ -57,12 +56,7 @@ export default defineConfig(({ command }) => {
|
||||
isDev && devtools(),
|
||||
],
|
||||
optimizeDeps: {
|
||||
include: [
|
||||
"@emotion/react",
|
||||
"@emotion/styled",
|
||||
"@mui/lab/*",
|
||||
"@mui/material/*",
|
||||
],
|
||||
include: ["@emotion/styled", "@mui/lab/*", "@mui/material/*"],
|
||||
},
|
||||
esbuild: {
|
||||
drop: isDev ? undefined : ["console", "debugger"],
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./sparkline";
|
||||
@@ -0,0 +1,100 @@
|
||||
import { CSSProperties, FC, useEffect, useRef } from "react";
|
||||
import * as d3 from "d3";
|
||||
import { alpha, useTheme } from "@mui/material";
|
||||
|
||||
interface SparklineProps {
|
||||
data: number[];
|
||||
className?: string;
|
||||
style?: CSSProperties;
|
||||
}
|
||||
|
||||
export const Sparkline: FC<SparklineProps> = ({ data, className, style }) => {
|
||||
const { palette } = useTheme();
|
||||
|
||||
const svgRef = useRef<SVGSVGElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!svgRef.current) return;
|
||||
|
||||
const svg = d3.select(svgRef.current);
|
||||
|
||||
const { width, height } = svg.node()?.getBoundingClientRect() ?? {
|
||||
width: 0,
|
||||
height: 0,
|
||||
};
|
||||
|
||||
const maxHeight = () => {
|
||||
const dataRange = d3.max(data)! - d3.min(data)!;
|
||||
|
||||
if (dataRange / d3.max(data)! < 0.1) {
|
||||
return height * 0.65;
|
||||
}
|
||||
|
||||
if (d3.max(data)) {
|
||||
return height * 0.35;
|
||||
} else {
|
||||
return height;
|
||||
}
|
||||
};
|
||||
|
||||
const xScale = d3
|
||||
.scaleLinear()
|
||||
.domain([0, data.length - 1])
|
||||
.range([0, width]);
|
||||
|
||||
const yScale = d3
|
||||
.scaleLinear()
|
||||
.domain([0, d3.max(data) ?? 0])
|
||||
.range([height, maxHeight()]);
|
||||
|
||||
const line = d3
|
||||
.line<number>()
|
||||
.x((d, i) => xScale(i))
|
||||
.y((d) => yScale(d))
|
||||
.curve(d3.curveCatmullRom.alpha(0.5));
|
||||
|
||||
const area = d3
|
||||
.area<number>()
|
||||
.x((d, i) => xScale(i))
|
||||
.y0(height)
|
||||
.y1((d) => yScale(d))
|
||||
.curve(d3.curveCatmullRom.alpha(0.5));
|
||||
|
||||
svg.selectAll("*").remove();
|
||||
|
||||
svg
|
||||
.append("path")
|
||||
.datum(data)
|
||||
.attr("class", "area")
|
||||
.attr("fill", alpha(palette.primary.main, 0.1))
|
||||
.attr("d", area);
|
||||
|
||||
svg
|
||||
.append("path")
|
||||
.datum(data)
|
||||
.attr("class", "line")
|
||||
.attr("fill", "none")
|
||||
.attr("stroke", alpha(palette.primary.main, 0.7))
|
||||
.attr("stroke-width", 2)
|
||||
.attr("d", line);
|
||||
|
||||
const updateChart = () => {
|
||||
xScale.domain([0, data.length - 1]);
|
||||
yScale.domain([0, d3.max(data) ?? 0]);
|
||||
|
||||
svg.select(".area").datum(data).attr("d", area);
|
||||
|
||||
svg.select(".line").datum(data).attr("d", line);
|
||||
};
|
||||
|
||||
updateChart();
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<svg
|
||||
className={className}
|
||||
ref={svgRef}
|
||||
style={{ width: "100%", height: "100%", ...style }}
|
||||
></svg>
|
||||
);
|
||||
};
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useTheme } from "@mui/material";
|
||||
import { useSetState } from "ahooks";
|
||||
import { appWindow } from "@tauri-apps/api/window";
|
||||
import { useDebounceFn, useSetState } from "ahooks";
|
||||
import { useEffect, useCallback, useMemo } from "react";
|
||||
|
||||
export const useBreakpoint = (
|
||||
@@ -23,7 +24,13 @@ export const useBreakpoint = (
|
||||
}, [breakpoints.values]);
|
||||
|
||||
const getBreakpoint = useCallback(
|
||||
(width: number) => {
|
||||
async (width: number) => {
|
||||
const isMinimized = await appWindow.isMinimized();
|
||||
|
||||
if (isMinimized) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const [key, value] of breakpointsValues) {
|
||||
if (value >= width) {
|
||||
if (key !== breakpoint.key) {
|
||||
@@ -46,21 +53,25 @@ export const useBreakpoint = (
|
||||
[breakpointsValues, columnMapping, breakpoint.key, setBreakpoint],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new ResizeObserver((entries) => {
|
||||
if (!Array.isArray(entries) || !entries.length) return;
|
||||
|
||||
const { width } = entries[0].contentRect;
|
||||
|
||||
const { run: triggerBreakpoint } = useDebounceFn(
|
||||
() => {
|
||||
const width = document.body.clientWidth;
|
||||
getBreakpoint(width);
|
||||
});
|
||||
},
|
||||
{
|
||||
wait: 100,
|
||||
},
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new ResizeObserver(triggerBreakpoint);
|
||||
|
||||
observer.observe(document.body);
|
||||
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
};
|
||||
}, [getBreakpoint]);
|
||||
}, [triggerBreakpoint]);
|
||||
|
||||
return breakpoint;
|
||||
};
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from "./materialYou";
|
||||
export * from "./hooks";
|
||||
export * from "./chart";
|
||||
|
||||
@@ -8,8 +8,11 @@
|
||||
"@mui/icons-material": "5.15.20",
|
||||
"@mui/lab": "5.0.0-alpha.170",
|
||||
"@mui/material": "5.15.20",
|
||||
"@tauri-apps/api": "1.5.6",
|
||||
"@types/d3": "7.4.3",
|
||||
"@types/react": "18.3.3",
|
||||
"ahooks": "3.8.0",
|
||||
"d3": "7.9.0",
|
||||
"framer-motion": "11.2.10",
|
||||
"react": "18.3.1",
|
||||
"react-error-boundary": "4.0.13",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"manifest_version": 1,
|
||||
"latest": {
|
||||
"mihomo": "v1.18.5",
|
||||
"mihomo_alpha": "alpha-40f40f6",
|
||||
"mihomo_alpha": "alpha-0738e18",
|
||||
"clash_rs": "v0.1.18",
|
||||
"clash_premium": "2023-09-05-gdcc8d87"
|
||||
},
|
||||
@@ -36,5 +36,5 @@
|
||||
"darwin-x64": "clash-darwin-amd64-n{}.gz"
|
||||
}
|
||||
},
|
||||
"updated_at": "2024-06-15T22:19:49.581Z"
|
||||
"updated_at": "2024-06-16T22:20:26.121Z"
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
"stylelint-order": "6.0.4",
|
||||
"stylelint-scss": "6.3.1",
|
||||
"tailwindcss": "3.4.4",
|
||||
"tsx": "4.15.5",
|
||||
"tsx": "4.15.6",
|
||||
"typescript": "5.4.5"
|
||||
},
|
||||
"packageManager": "pnpm@9.3.0",
|
||||
|
||||
Generated
+1050
-249
File diff suppressed because it is too large
Load Diff
@@ -24,10 +24,10 @@
|
||||
"@emotion/react": "^11.11.4",
|
||||
"@emotion/styled": "^11.11.5",
|
||||
"@juggle/resize-observer": "^3.4.0",
|
||||
"@mui/icons-material": "^5.15.19",
|
||||
"@mui/icons-material": "^5.15.20",
|
||||
"@mui/lab": "5.0.0-alpha.149",
|
||||
"@mui/material": "^5.15.19",
|
||||
"@mui/x-data-grid": "^6.20.1",
|
||||
"@mui/material": "^5.15.20",
|
||||
"@mui/x-data-grid": "^7.7.0",
|
||||
"@tauri-apps/api": "^1.5.6",
|
||||
"@types/json-schema": "^7.0.15",
|
||||
"ahooks": "^3.8.0",
|
||||
@@ -43,7 +43,7 @@
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-error-boundary": "^3.1.4",
|
||||
"react-hook-form": "^7.51.5",
|
||||
"react-hook-form": "^7.52.0",
|
||||
"react-i18next": "^13.5.0",
|
||||
"react-markdown": "^9.0.1",
|
||||
"react-router-dom": "^6.23.1",
|
||||
@@ -76,7 +76,7 @@
|
||||
"sass": "^1.77.5",
|
||||
"terser": "^5.31.1",
|
||||
"typescript": "^5.4.5",
|
||||
"vite": "^5.2.13",
|
||||
"vite": "^5.3.1",
|
||||
"vite-plugin-monaco-editor": "^1.1.0",
|
||||
"vite-plugin-svgr": "^4.2.0"
|
||||
},
|
||||
|
||||
Generated
+180
-179
@@ -26,17 +26,17 @@ importers:
|
||||
specifier: ^3.4.0
|
||||
version: 3.4.0
|
||||
"@mui/icons-material":
|
||||
specifier: ^5.15.19
|
||||
version: 5.15.19(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
|
||||
specifier: ^5.15.20
|
||||
version: 5.15.20(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/lab":
|
||||
specifier: 5.0.0-alpha.149
|
||||
version: 5.0.0-alpha.149(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
version: 5.0.0-alpha.149(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
"@mui/material":
|
||||
specifier: ^5.15.19
|
||||
version: 5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
specifier: ^5.15.20
|
||||
version: 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
"@mui/x-data-grid":
|
||||
specifier: ^6.20.1
|
||||
version: 6.20.1(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
specifier: ^7.7.0
|
||||
version: 7.7.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
"@tauri-apps/api":
|
||||
specifier: ^1.5.6
|
||||
version: 1.5.6
|
||||
@@ -83,8 +83,8 @@ importers:
|
||||
specifier: ^3.1.4
|
||||
version: 3.1.4(react@18.3.1)
|
||||
react-hook-form:
|
||||
specifier: ^7.51.5
|
||||
version: 7.51.5(react@18.3.1)
|
||||
specifier: ^7.52.0
|
||||
version: 7.52.0(react@18.3.1)
|
||||
react-i18next:
|
||||
specifier: ^13.5.0
|
||||
version: 13.5.0(i18next@23.11.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -139,10 +139,10 @@ importers:
|
||||
version: 4.4.10
|
||||
"@vitejs/plugin-legacy":
|
||||
specifier: ^5.4.1
|
||||
version: 5.4.1(terser@5.31.1)(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))
|
||||
version: 5.4.1(terser@5.31.1)(vite@5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))
|
||||
"@vitejs/plugin-react":
|
||||
specifier: ^4.3.1
|
||||
version: 4.3.1(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))
|
||||
version: 4.3.1(vite@5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))
|
||||
adm-zip:
|
||||
specifier: ^0.5.14
|
||||
version: 0.5.14
|
||||
@@ -177,14 +177,14 @@ importers:
|
||||
specifier: ^5.4.5
|
||||
version: 5.4.5
|
||||
vite:
|
||||
specifier: ^5.2.13
|
||||
version: 5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)
|
||||
specifier: ^5.3.1
|
||||
version: 5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)
|
||||
vite-plugin-monaco-editor:
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0(monaco-editor@0.49.0)
|
||||
vite-plugin-svgr:
|
||||
specifier: ^4.2.0
|
||||
version: 4.2.0(rollup@4.18.0)(typescript@5.4.5)(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))
|
||||
version: 4.2.0(rollup@4.18.0)(typescript@5.4.5)(vite@5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))
|
||||
|
||||
packages:
|
||||
"@actions/github@5.1.1":
|
||||
@@ -1251,208 +1251,208 @@ packages:
|
||||
integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==,
|
||||
}
|
||||
|
||||
"@esbuild/aix-ppc64@0.20.2":
|
||||
"@esbuild/aix-ppc64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==,
|
||||
integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [ppc64]
|
||||
os: [aix]
|
||||
|
||||
"@esbuild/android-arm64@0.20.2":
|
||||
"@esbuild/android-arm64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==,
|
||||
integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
|
||||
"@esbuild/android-arm@0.20.2":
|
||||
"@esbuild/android-arm@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==,
|
||||
integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
|
||||
"@esbuild/android-x64@0.20.2":
|
||||
"@esbuild/android-x64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==,
|
||||
integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [x64]
|
||||
os: [android]
|
||||
|
||||
"@esbuild/darwin-arm64@0.20.2":
|
||||
"@esbuild/darwin-arm64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==,
|
||||
integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
"@esbuild/darwin-x64@0.20.2":
|
||||
"@esbuild/darwin-x64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==,
|
||||
integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
"@esbuild/freebsd-arm64@0.20.2":
|
||||
"@esbuild/freebsd-arm64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==,
|
||||
integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
|
||||
"@esbuild/freebsd-x64@0.20.2":
|
||||
"@esbuild/freebsd-x64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==,
|
||||
integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
"@esbuild/linux-arm64@0.20.2":
|
||||
"@esbuild/linux-arm64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==,
|
||||
integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
"@esbuild/linux-arm@0.20.2":
|
||||
"@esbuild/linux-arm@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==,
|
||||
integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
"@esbuild/linux-ia32@0.20.2":
|
||||
"@esbuild/linux-ia32@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==,
|
||||
integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [ia32]
|
||||
os: [linux]
|
||||
|
||||
"@esbuild/linux-loong64@0.20.2":
|
||||
"@esbuild/linux-loong64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==,
|
||||
integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
|
||||
"@esbuild/linux-mips64el@0.20.2":
|
||||
"@esbuild/linux-mips64el@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==,
|
||||
integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [mips64el]
|
||||
os: [linux]
|
||||
|
||||
"@esbuild/linux-ppc64@0.20.2":
|
||||
"@esbuild/linux-ppc64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==,
|
||||
integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
|
||||
"@esbuild/linux-riscv64@0.20.2":
|
||||
"@esbuild/linux-riscv64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==,
|
||||
integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
|
||||
"@esbuild/linux-s390x@0.20.2":
|
||||
"@esbuild/linux-s390x@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==,
|
||||
integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
"@esbuild/linux-x64@0.20.2":
|
||||
"@esbuild/linux-x64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==,
|
||||
integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
"@esbuild/netbsd-x64@0.20.2":
|
||||
"@esbuild/netbsd-x64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==,
|
||||
integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [x64]
|
||||
os: [netbsd]
|
||||
|
||||
"@esbuild/openbsd-x64@0.20.2":
|
||||
"@esbuild/openbsd-x64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==,
|
||||
integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
|
||||
"@esbuild/sunos-x64@0.20.2":
|
||||
"@esbuild/sunos-x64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==,
|
||||
integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [x64]
|
||||
os: [sunos]
|
||||
|
||||
"@esbuild/win32-arm64@0.20.2":
|
||||
"@esbuild/win32-arm64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==,
|
||||
integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
"@esbuild/win32-ia32@0.20.2":
|
||||
"@esbuild/win32-ia32@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==,
|
||||
integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
"@esbuild/win32-x64@0.20.2":
|
||||
"@esbuild/win32-x64@0.21.5":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==,
|
||||
integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
cpu: [x64]
|
||||
@@ -1565,16 +1565,16 @@ packages:
|
||||
"@types/react":
|
||||
optional: true
|
||||
|
||||
"@mui/core-downloads-tracker@5.15.19":
|
||||
"@mui/core-downloads-tracker@5.15.20":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-tCHSi/Tomez9ERynFhZRvFO6n9ATyrPs+2N80DMDzp6xDVirbBjEwhPcE+x7Lj+nwYw0SqFkOxyvMP0irnm55w==,
|
||||
integrity: sha512-DoL2ppgldL16utL8nNyj/P12f8mCNdx/Hb/AJnX9rLY4b52hCMIx1kH83pbXQ6uMy6n54M3StmEbvSGoj2OFuA==,
|
||||
}
|
||||
|
||||
"@mui/icons-material@5.15.19":
|
||||
"@mui/icons-material@5.15.20":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-RsEiRxA5azN9b8gI7JRqekkgvxQUlitoBOtZglflb8cUDyP12/cP4gRwhb44Ea1/zwwGGjAj66ZJpGHhKfibNA==,
|
||||
integrity: sha512-oGcKmCuHaYbAAoLN67WKSXtHmEgyWcJToT1uRtmPyxMj9N5uqwc/mRtEnst4Wj/eGr+zYH2FiZQ79v9k7kSk1Q==,
|
||||
}
|
||||
engines: { node: ">=12.0.0" }
|
||||
peerDependencies:
|
||||
@@ -1606,10 +1606,10 @@ packages:
|
||||
"@types/react":
|
||||
optional: true
|
||||
|
||||
"@mui/material@5.15.19":
|
||||
"@mui/material@5.15.20":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-lp5xQBbcRuxNtjpWU0BWZgIrv2XLUz4RJ0RqFXBdESIsKoGCQZ6P3wwU5ZPuj5TjssNiKv9AlM+vHopRxZhvVQ==,
|
||||
integrity: sha512-tVq3l4qoXx/NxUgIx/x3lZiPn/5xDbdTE8VrLczNpfblLYZzlrbxA7kb9mI8NoBF6+w9WE9IrxWnKK5KlPI2bg==,
|
||||
}
|
||||
engines: { node: ">=12.0.0" }
|
||||
peerDependencies:
|
||||
@@ -1626,10 +1626,10 @@ packages:
|
||||
"@types/react":
|
||||
optional: true
|
||||
|
||||
"@mui/private-theming@5.15.14":
|
||||
"@mui/private-theming@5.15.20":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-UH0EiZckOWcxiXLX3Jbb0K7rC8mxTr9L9l6QhOZxYc4r8FHUkefltV9VDGLrzCaWh30SQiJvAEd7djX3XXY6Xw==,
|
||||
integrity: sha512-BK8F94AIqSrnaPYXf2KAOjGZJgWfvqAVQ2gVR3EryvQFtuBnG6RwodxrCvd3B48VuMy6Wsk897+lQMUxJyk+6g==,
|
||||
}
|
||||
engines: { node: ">=12.0.0" }
|
||||
peerDependencies:
|
||||
@@ -1655,10 +1655,10 @@ packages:
|
||||
"@emotion/styled":
|
||||
optional: true
|
||||
|
||||
"@mui/system@5.15.15":
|
||||
"@mui/system@5.15.20":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-aulox6N1dnu5PABsfxVGOZffDVmlxPOVgj56HrUnJE8MCSh8lOvvkd47cebIVQQYAjpwieXQXiDPj5pwM40jTQ==,
|
||||
integrity: sha512-LoMq4IlAAhxzL2VNUDBTQxAb4chnBe8JvRINVNDiMtHE2PiPOoHlhOPutSxEbaL5mkECPVWSv6p8JEV+uykwIA==,
|
||||
}
|
||||
engines: { node: ">=12.0.0" }
|
||||
peerDependencies:
|
||||
@@ -1685,10 +1685,10 @@ packages:
|
||||
"@types/react":
|
||||
optional: true
|
||||
|
||||
"@mui/utils@5.15.14":
|
||||
"@mui/utils@5.15.20":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-0lF/7Hh/ezDv5X7Pry6enMsbYyGKjADzvHyo3Qrc/SSlTsQ1VkbDMbH0m2t3OR5iIVLwMoxwM7yGd+6FCMtTFA==,
|
||||
integrity: sha512-mAbYx0sovrnpAu1zHc3MDIhPqL8RPVC5W5xcO1b7PiSCJPtckIZmBkp8hefamAvUiAV8gpfMOM6Zb+eSisbI2A==,
|
||||
}
|
||||
engines: { node: ">=12.0.0" }
|
||||
peerDependencies:
|
||||
@@ -1698,15 +1698,14 @@ packages:
|
||||
"@types/react":
|
||||
optional: true
|
||||
|
||||
"@mui/x-data-grid@6.20.1":
|
||||
"@mui/x-data-grid@7.7.0":
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-x1muWWIG9otkk4FuvoTxH3I4foyA1caFu8ZC9TvMQ+7NSBKcfy/JeLQfKkZk8ACUUosvENdrRIkhqU2xdIqIVg==,
|
||||
integrity: sha512-s3Oii9EKcYPnL7M4g5evNley/J0slLL6xWRi0VwYqTHPGntBAMntUktMZ63bD/xko99f5ZcFoRBYTc55+mJ+AQ==,
|
||||
}
|
||||
engines: { node: ">=14.0.0" }
|
||||
peerDependencies:
|
||||
"@mui/material": ^5.4.1
|
||||
"@mui/system": ^5.4.1
|
||||
"@mui/material": ^5.15.14
|
||||
react: ^17.0.0 || ^18.0.0
|
||||
react-dom: ^17.0.0 || ^18.0.0
|
||||
|
||||
@@ -2314,10 +2313,10 @@ packages:
|
||||
peerDependencies:
|
||||
vite: ^4.2.0 || ^5.0.0
|
||||
|
||||
acorn@8.11.3:
|
||||
acorn@8.12.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==,
|
||||
integrity: sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==,
|
||||
}
|
||||
engines: { node: ">=0.4.0" }
|
||||
hasBin: true
|
||||
@@ -2472,10 +2471,10 @@ packages:
|
||||
}
|
||||
engines: { node: ">=10" }
|
||||
|
||||
caniuse-lite@1.0.30001632:
|
||||
caniuse-lite@1.0.30001636:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-udx3o7yHJfUxMLkGohMlVHCvFvWmirKh9JAH/d7WOLPetlH+LTL5cocMZ0t7oZx/mdlOWXti97xLZWc8uURRHg==,
|
||||
integrity: sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==,
|
||||
}
|
||||
|
||||
ccount@2.0.1:
|
||||
@@ -2706,10 +2705,10 @@ packages:
|
||||
integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==,
|
||||
}
|
||||
|
||||
electron-to-chromium@1.4.799:
|
||||
electron-to-chromium@1.4.803:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-3D3DwWkRTzrdEpntY0hMLYwj7SeBk1138CkPE8sBDSj3WzrzOiG2rHm3luw8jucpf+WiyLBCZyU9lMHyQI9M9Q==,
|
||||
integrity: sha512-61H9mLzGOCLLVsnLiRzCbc63uldP0AniRYPV3hbGVtONA1pI7qSGILdbofR7A8TMbOypDocEAjH/e+9k1QIe3g==,
|
||||
}
|
||||
|
||||
end-of-stream@1.4.4:
|
||||
@@ -2731,10 +2730,10 @@ packages:
|
||||
integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==,
|
||||
}
|
||||
|
||||
esbuild@0.20.2:
|
||||
esbuild@0.21.5:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==,
|
||||
integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==,
|
||||
}
|
||||
engines: { node: ">=12" }
|
||||
hasBin: true
|
||||
@@ -3785,14 +3784,14 @@ packages:
|
||||
integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==,
|
||||
}
|
||||
|
||||
react-hook-form@7.51.5:
|
||||
react-hook-form@7.52.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-J2ILT5gWx1XUIJRETiA7M19iXHlG74+6O3KApzvqB/w8S5NQR7AbU8HVZrMALdmDgWpRPYiZJl0zx8Z4L2mP6Q==,
|
||||
integrity: sha512-mJX506Xc6mirzLsmXUJyqlAI3Kj9Ph2RhplYhUVffeOQSnubK2uVqBFOBJmvKikvbFV91pxVXmDiR+QMF19x6A==,
|
||||
}
|
||||
engines: { node: ">=12.22.0" }
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17 || ^18
|
||||
react: ^16.8.0 || ^17 || ^18 || ^19
|
||||
|
||||
react-i18next@13.5.0:
|
||||
resolution:
|
||||
@@ -4348,10 +4347,10 @@ packages:
|
||||
peerDependencies:
|
||||
vite: ^2.6.0 || 3 || 4 || 5
|
||||
|
||||
vite@5.2.13:
|
||||
vite@5.3.1:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==,
|
||||
integrity: sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==,
|
||||
}
|
||||
engines: { node: ^18.0.0 || >=20.0.0 }
|
||||
hasBin: true
|
||||
@@ -5389,73 +5388,73 @@ snapshots:
|
||||
|
||||
"@emotion/weak-memoize@0.3.1": {}
|
||||
|
||||
"@esbuild/aix-ppc64@0.20.2":
|
||||
"@esbuild/aix-ppc64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/android-arm64@0.20.2":
|
||||
"@esbuild/android-arm64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/android-arm@0.20.2":
|
||||
"@esbuild/android-arm@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/android-x64@0.20.2":
|
||||
"@esbuild/android-x64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/darwin-arm64@0.20.2":
|
||||
"@esbuild/darwin-arm64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/darwin-x64@0.20.2":
|
||||
"@esbuild/darwin-x64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/freebsd-arm64@0.20.2":
|
||||
"@esbuild/freebsd-arm64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/freebsd-x64@0.20.2":
|
||||
"@esbuild/freebsd-x64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/linux-arm64@0.20.2":
|
||||
"@esbuild/linux-arm64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/linux-arm@0.20.2":
|
||||
"@esbuild/linux-arm@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/linux-ia32@0.20.2":
|
||||
"@esbuild/linux-ia32@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/linux-loong64@0.20.2":
|
||||
"@esbuild/linux-loong64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/linux-mips64el@0.20.2":
|
||||
"@esbuild/linux-mips64el@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/linux-ppc64@0.20.2":
|
||||
"@esbuild/linux-ppc64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/linux-riscv64@0.20.2":
|
||||
"@esbuild/linux-riscv64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/linux-s390x@0.20.2":
|
||||
"@esbuild/linux-s390x@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/linux-x64@0.20.2":
|
||||
"@esbuild/linux-x64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/netbsd-x64@0.20.2":
|
||||
"@esbuild/netbsd-x64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/openbsd-x64@0.20.2":
|
||||
"@esbuild/openbsd-x64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/sunos-x64@0.20.2":
|
||||
"@esbuild/sunos-x64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/win32-arm64@0.20.2":
|
||||
"@esbuild/win32-arm64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/win32-ia32@0.20.2":
|
||||
"@esbuild/win32-ia32@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@esbuild/win32-x64@0.20.2":
|
||||
"@esbuild/win32-x64@0.21.5":
|
||||
optional: true
|
||||
|
||||
"@fastify/busboy@2.1.1": {}
|
||||
@@ -5506,7 +5505,7 @@ snapshots:
|
||||
"@babel/runtime": 7.24.7
|
||||
"@floating-ui/react-dom": 2.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
"@mui/types": 7.2.14(@types/react@18.3.3)
|
||||
"@mui/utils": 5.15.14(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/utils": 5.15.20(@types/react@18.3.3)(react@18.3.1)
|
||||
"@popperjs/core": 2.11.8
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
@@ -5520,7 +5519,7 @@ snapshots:
|
||||
"@babel/runtime": 7.24.7
|
||||
"@floating-ui/react-dom": 2.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
"@mui/types": 7.2.14(@types/react@18.3.3)
|
||||
"@mui/utils": 5.15.14(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/utils": 5.15.20(@types/react@18.3.3)(react@18.3.1)
|
||||
"@popperjs/core": 2.11.8
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
@@ -5529,25 +5528,25 @@ snapshots:
|
||||
optionalDependencies:
|
||||
"@types/react": 18.3.3
|
||||
|
||||
"@mui/core-downloads-tracker@5.15.19": {}
|
||||
"@mui/core-downloads-tracker@5.15.20": {}
|
||||
|
||||
"@mui/icons-material@5.15.19(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)":
|
||||
"@mui/icons-material@5.15.20(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)":
|
||||
dependencies:
|
||||
"@babel/runtime": 7.24.7
|
||||
"@mui/material": 5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
"@mui/material": 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
react: 18.3.1
|
||||
optionalDependencies:
|
||||
"@types/react": 18.3.3
|
||||
|
||||
"@mui/lab@5.0.0-alpha.149(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)":
|
||||
"@mui/lab@5.0.0-alpha.149(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)":
|
||||
dependencies:
|
||||
"@babel/runtime": 7.24.7
|
||||
"@mui/base": 5.0.0-beta.20(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
"@mui/material": 5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
"@mui/system": 5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/material": 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
"@mui/system": 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/types": 7.2.14(@types/react@18.3.3)
|
||||
"@mui/utils": 5.15.14(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/x-tree-view": 6.0.0-alpha.1(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/base@5.0.0-beta.20(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
"@mui/utils": 5.15.20(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/x-tree-view": 6.0.0-alpha.1(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/base@5.0.0-beta.20(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
react: 18.3.1
|
||||
@@ -5557,14 +5556,14 @@ snapshots:
|
||||
"@emotion/styled": 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
|
||||
"@types/react": 18.3.3
|
||||
|
||||
"@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)":
|
||||
"@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)":
|
||||
dependencies:
|
||||
"@babel/runtime": 7.24.7
|
||||
"@mui/base": 5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
"@mui/core-downloads-tracker": 5.15.19
|
||||
"@mui/system": 5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/core-downloads-tracker": 5.15.20
|
||||
"@mui/system": 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/types": 7.2.14(@types/react@18.3.3)
|
||||
"@mui/utils": 5.15.14(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/utils": 5.15.20(@types/react@18.3.3)(react@18.3.1)
|
||||
"@types/react-transition-group": 4.4.10
|
||||
clsx: 2.1.1
|
||||
csstype: 3.1.3
|
||||
@@ -5578,10 +5577,10 @@ snapshots:
|
||||
"@emotion/styled": 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
|
||||
"@types/react": 18.3.3
|
||||
|
||||
"@mui/private-theming@5.15.14(@types/react@18.3.3)(react@18.3.1)":
|
||||
"@mui/private-theming@5.15.20(@types/react@18.3.3)(react@18.3.1)":
|
||||
dependencies:
|
||||
"@babel/runtime": 7.24.7
|
||||
"@mui/utils": 5.15.14(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/utils": 5.15.20(@types/react@18.3.3)(react@18.3.1)
|
||||
prop-types: 15.8.1
|
||||
react: 18.3.1
|
||||
optionalDependencies:
|
||||
@@ -5598,13 +5597,13 @@ snapshots:
|
||||
"@emotion/react": 11.11.4(@types/react@18.3.3)(react@18.3.1)
|
||||
"@emotion/styled": 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
|
||||
|
||||
"@mui/system@5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)":
|
||||
"@mui/system@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)":
|
||||
dependencies:
|
||||
"@babel/runtime": 7.24.7
|
||||
"@mui/private-theming": 5.15.14(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/private-theming": 5.15.20(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/styled-engine": 5.15.14(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(react@18.3.1)
|
||||
"@mui/types": 7.2.14(@types/react@18.3.3)
|
||||
"@mui/utils": 5.15.14(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/utils": 5.15.20(@types/react@18.3.3)(react@18.3.1)
|
||||
clsx: 2.1.1
|
||||
csstype: 3.1.3
|
||||
prop-types: 15.8.1
|
||||
@@ -5618,7 +5617,7 @@ snapshots:
|
||||
optionalDependencies:
|
||||
"@types/react": 18.3.3
|
||||
|
||||
"@mui/utils@5.15.14(@types/react@18.3.3)(react@18.3.1)":
|
||||
"@mui/utils@5.15.20(@types/react@18.3.3)(react@18.3.1)":
|
||||
dependencies:
|
||||
"@babel/runtime": 7.24.7
|
||||
"@types/prop-types": 15.7.12
|
||||
@@ -5628,29 +5627,31 @@ snapshots:
|
||||
optionalDependencies:
|
||||
"@types/react": 18.3.3
|
||||
|
||||
"@mui/x-data-grid@6.20.1(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)":
|
||||
"@mui/x-data-grid@7.7.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)":
|
||||
dependencies:
|
||||
"@babel/runtime": 7.24.7
|
||||
"@mui/material": 5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
"@mui/system": 5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/utils": 5.15.14(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/material": 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
"@mui/system": 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/utils": 5.15.20(@types/react@18.3.3)(react@18.3.1)
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
reselect: 4.1.8
|
||||
transitivePeerDependencies:
|
||||
- "@emotion/react"
|
||||
- "@emotion/styled"
|
||||
- "@types/react"
|
||||
|
||||
"@mui/x-tree-view@6.0.0-alpha.1(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/base@5.0.0-beta.20(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)":
|
||||
"@mui/x-tree-view@6.0.0-alpha.1(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/base@5.0.0-beta.20(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)":
|
||||
dependencies:
|
||||
"@babel/runtime": 7.24.7
|
||||
"@emotion/react": 11.11.4(@types/react@18.3.3)(react@18.3.1)
|
||||
"@emotion/styled": 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/base": 5.0.0-beta.20(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
"@mui/material": 5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
"@mui/system": 5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/utils": 5.15.14(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/material": 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
"@mui/system": 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
|
||||
"@mui/utils": 5.15.20(@types/react@18.3.3)(react@18.3.1)
|
||||
"@types/react-transition-group": 4.4.10
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
@@ -5981,7 +5982,7 @@ snapshots:
|
||||
|
||||
"@ungap/structured-clone@1.2.0": {}
|
||||
|
||||
"@vitejs/plugin-legacy@5.4.1(terser@5.31.1)(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))":
|
||||
"@vitejs/plugin-legacy@5.4.1(terser@5.31.1)(vite@5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))":
|
||||
dependencies:
|
||||
"@babel/core": 7.24.7
|
||||
"@babel/preset-env": 7.24.7(@babel/core@7.24.7)
|
||||
@@ -5992,22 +5993,22 @@ snapshots:
|
||||
regenerator-runtime: 0.14.1
|
||||
systemjs: 6.15.1
|
||||
terser: 5.31.1
|
||||
vite: 5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)
|
||||
vite: 5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
"@vitejs/plugin-react@4.3.1(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))":
|
||||
"@vitejs/plugin-react@4.3.1(vite@5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))":
|
||||
dependencies:
|
||||
"@babel/core": 7.24.7
|
||||
"@babel/plugin-transform-react-jsx-self": 7.24.7(@babel/core@7.24.7)
|
||||
"@babel/plugin-transform-react-jsx-source": 7.24.7(@babel/core@7.24.7)
|
||||
"@types/babel__core": 7.20.5
|
||||
react-refresh: 0.14.2
|
||||
vite: 5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)
|
||||
vite: 5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
acorn@8.11.3: {}
|
||||
acorn@8.12.0: {}
|
||||
|
||||
adm-zip@0.5.14: {}
|
||||
|
||||
@@ -6098,8 +6099,8 @@ snapshots:
|
||||
|
||||
browserslist@4.23.1:
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001632
|
||||
electron-to-chromium: 1.4.799
|
||||
caniuse-lite: 1.0.30001636
|
||||
electron-to-chromium: 1.4.803
|
||||
node-releases: 2.0.14
|
||||
update-browserslist-db: 1.0.16(browserslist@4.23.1)
|
||||
|
||||
@@ -6109,7 +6110,7 @@ snapshots:
|
||||
|
||||
camelcase@6.3.0: {}
|
||||
|
||||
caniuse-lite@1.0.30001632: {}
|
||||
caniuse-lite@1.0.30001636: {}
|
||||
|
||||
ccount@2.0.1: {}
|
||||
|
||||
@@ -6230,7 +6231,7 @@ snapshots:
|
||||
no-case: 3.0.4
|
||||
tslib: 2.6.3
|
||||
|
||||
electron-to-chromium@1.4.799: {}
|
||||
electron-to-chromium@1.4.803: {}
|
||||
|
||||
end-of-stream@1.4.4:
|
||||
dependencies:
|
||||
@@ -6242,31 +6243,31 @@ snapshots:
|
||||
dependencies:
|
||||
is-arrayish: 0.2.1
|
||||
|
||||
esbuild@0.20.2:
|
||||
esbuild@0.21.5:
|
||||
optionalDependencies:
|
||||
"@esbuild/aix-ppc64": 0.20.2
|
||||
"@esbuild/android-arm": 0.20.2
|
||||
"@esbuild/android-arm64": 0.20.2
|
||||
"@esbuild/android-x64": 0.20.2
|
||||
"@esbuild/darwin-arm64": 0.20.2
|
||||
"@esbuild/darwin-x64": 0.20.2
|
||||
"@esbuild/freebsd-arm64": 0.20.2
|
||||
"@esbuild/freebsd-x64": 0.20.2
|
||||
"@esbuild/linux-arm": 0.20.2
|
||||
"@esbuild/linux-arm64": 0.20.2
|
||||
"@esbuild/linux-ia32": 0.20.2
|
||||
"@esbuild/linux-loong64": 0.20.2
|
||||
"@esbuild/linux-mips64el": 0.20.2
|
||||
"@esbuild/linux-ppc64": 0.20.2
|
||||
"@esbuild/linux-riscv64": 0.20.2
|
||||
"@esbuild/linux-s390x": 0.20.2
|
||||
"@esbuild/linux-x64": 0.20.2
|
||||
"@esbuild/netbsd-x64": 0.20.2
|
||||
"@esbuild/openbsd-x64": 0.20.2
|
||||
"@esbuild/sunos-x64": 0.20.2
|
||||
"@esbuild/win32-arm64": 0.20.2
|
||||
"@esbuild/win32-ia32": 0.20.2
|
||||
"@esbuild/win32-x64": 0.20.2
|
||||
"@esbuild/aix-ppc64": 0.21.5
|
||||
"@esbuild/android-arm": 0.21.5
|
||||
"@esbuild/android-arm64": 0.21.5
|
||||
"@esbuild/android-x64": 0.21.5
|
||||
"@esbuild/darwin-arm64": 0.21.5
|
||||
"@esbuild/darwin-x64": 0.21.5
|
||||
"@esbuild/freebsd-arm64": 0.21.5
|
||||
"@esbuild/freebsd-x64": 0.21.5
|
||||
"@esbuild/linux-arm": 0.21.5
|
||||
"@esbuild/linux-arm64": 0.21.5
|
||||
"@esbuild/linux-ia32": 0.21.5
|
||||
"@esbuild/linux-loong64": 0.21.5
|
||||
"@esbuild/linux-mips64el": 0.21.5
|
||||
"@esbuild/linux-ppc64": 0.21.5
|
||||
"@esbuild/linux-riscv64": 0.21.5
|
||||
"@esbuild/linux-s390x": 0.21.5
|
||||
"@esbuild/linux-x64": 0.21.5
|
||||
"@esbuild/netbsd-x64": 0.21.5
|
||||
"@esbuild/openbsd-x64": 0.21.5
|
||||
"@esbuild/sunos-x64": 0.21.5
|
||||
"@esbuild/win32-arm64": 0.21.5
|
||||
"@esbuild/win32-ia32": 0.21.5
|
||||
"@esbuild/win32-x64": 0.21.5
|
||||
|
||||
escalade@3.1.2: {}
|
||||
|
||||
@@ -6938,7 +6939,7 @@ snapshots:
|
||||
|
||||
react-fast-compare@3.2.2: {}
|
||||
|
||||
react-hook-form@7.51.5(react@18.3.1):
|
||||
react-hook-form@7.52.0(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
@@ -7169,7 +7170,7 @@ snapshots:
|
||||
terser@5.31.1:
|
||||
dependencies:
|
||||
"@jridgewell/source-map": 0.3.6
|
||||
acorn: 8.11.3
|
||||
acorn: 8.12.0
|
||||
commander: 2.20.3
|
||||
source-map-support: 0.5.21
|
||||
|
||||
@@ -7277,20 +7278,20 @@ snapshots:
|
||||
dependencies:
|
||||
monaco-editor: 0.49.0
|
||||
|
||||
vite-plugin-svgr@4.2.0(rollup@4.18.0)(typescript@5.4.5)(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)):
|
||||
vite-plugin-svgr@4.2.0(rollup@4.18.0)(typescript@5.4.5)(vite@5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)):
|
||||
dependencies:
|
||||
"@rollup/pluginutils": 5.1.0(rollup@4.18.0)
|
||||
"@svgr/core": 8.1.0(typescript@5.4.5)
|
||||
"@svgr/plugin-jsx": 8.1.0(@svgr/core@8.1.0(typescript@5.4.5))
|
||||
vite: 5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)
|
||||
vite: 5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
- supports-color
|
||||
- typescript
|
||||
|
||||
vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1):
|
||||
vite@5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1):
|
||||
dependencies:
|
||||
esbuild: 0.20.2
|
||||
esbuild: 0.21.5
|
||||
postcss: 8.4.38
|
||||
rollup: 4.18.0
|
||||
optionalDependencies:
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import dayjs from "dayjs";
|
||||
import { useMemo, useState } from "react";
|
||||
import {
|
||||
DataGrid,
|
||||
GridColDef,
|
||||
GridValueFormatterParams,
|
||||
} from "@mui/x-data-grid";
|
||||
import { DataGrid, GridColDef } from "@mui/x-data-grid";
|
||||
import { truncateStr } from "@/utils/truncate-str";
|
||||
import parseTraffic from "@/utils/parse-traffic";
|
||||
import { t } from "i18next";
|
||||
@@ -21,7 +17,7 @@ export const ConnectionTable = (props: Props) => {
|
||||
Partial<Record<keyof IConnectionsItem, boolean>>
|
||||
>({});
|
||||
|
||||
const columns: GridColDef[] = [
|
||||
const [columns] = useState<GridColDef[]>([
|
||||
{ field: "host", headerName: t("Host"), flex: 220, minWidth: 220 },
|
||||
{
|
||||
field: "download",
|
||||
@@ -29,8 +25,7 @@ export const ConnectionTable = (props: Props) => {
|
||||
width: 88,
|
||||
align: "right",
|
||||
headerAlign: "right",
|
||||
valueFormatter: (params: GridValueFormatterParams<number>) =>
|
||||
parseTraffic(params.value).join(" "),
|
||||
valueFormatter: (value: number) => parseTraffic(value).join(" "),
|
||||
},
|
||||
{
|
||||
field: "upload",
|
||||
@@ -38,8 +33,7 @@ export const ConnectionTable = (props: Props) => {
|
||||
width: 88,
|
||||
align: "right",
|
||||
headerAlign: "right",
|
||||
valueFormatter: (params: GridValueFormatterParams<number>) =>
|
||||
parseTraffic(params.value).join(" "),
|
||||
valueFormatter: (value: number) => parseTraffic(value).join(" "),
|
||||
},
|
||||
{
|
||||
field: "dlSpeed",
|
||||
@@ -47,8 +41,7 @@ export const ConnectionTable = (props: Props) => {
|
||||
width: 88,
|
||||
align: "right",
|
||||
headerAlign: "right",
|
||||
valueFormatter: (params: GridValueFormatterParams<number>) =>
|
||||
parseTraffic(params.value).join(" ") + "/s",
|
||||
valueFormatter: (value: number) => parseTraffic(value).join(" ") + "/s",
|
||||
},
|
||||
{
|
||||
field: "ulSpeed",
|
||||
@@ -56,8 +49,7 @@ export const ConnectionTable = (props: Props) => {
|
||||
width: 88,
|
||||
align: "right",
|
||||
headerAlign: "right",
|
||||
valueFormatter: (params: GridValueFormatterParams<number>) =>
|
||||
parseTraffic(params.value).join(" ") + "/s",
|
||||
valueFormatter: (value: number) => parseTraffic(value).join(" ") + "/s",
|
||||
},
|
||||
{ field: "chains", headerName: t("Chains"), flex: 360, minWidth: 360 },
|
||||
{ field: "rule", headerName: t("Rule"), flex: 300, minWidth: 250 },
|
||||
@@ -69,11 +61,9 @@ export const ConnectionTable = (props: Props) => {
|
||||
minWidth: 100,
|
||||
align: "right",
|
||||
headerAlign: "right",
|
||||
sortComparator: (v1, v2) => {
|
||||
return new Date(v2).getTime() - new Date(v1).getTime();
|
||||
},
|
||||
valueFormatter: (params: GridValueFormatterParams<string>) =>
|
||||
dayjs(params.value).fromNow(),
|
||||
sortComparator: (v1: string, v2: string) =>
|
||||
new Date(v2).getTime() - new Date(v1).getTime(),
|
||||
valueFormatter: (value: number) => dayjs(value).fromNow(),
|
||||
},
|
||||
{ field: "source", headerName: t("Source"), flex: 200, minWidth: 130 },
|
||||
{
|
||||
@@ -83,7 +73,7 @@ export const ConnectionTable = (props: Props) => {
|
||||
minWidth: 130,
|
||||
},
|
||||
{ field: "type", headerName: t("Type"), flex: 160, minWidth: 100 },
|
||||
];
|
||||
]);
|
||||
|
||||
const connRows = useMemo(() => {
|
||||
return connections.map((each) => {
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
import { useClashInfo } from "@/hooks/use-clash";
|
||||
import { useVerge } from "@/hooks/use-verge";
|
||||
import { TrafficGraph, type TrafficRef } from "./traffic-graph";
|
||||
import { useLogSetup } from "./use-log-setup";
|
||||
import { useLogData } from "@/hooks/use-log-data";
|
||||
import { useVisibility } from "@/hooks/use-visibility";
|
||||
import parseTraffic from "@/utils/parse-traffic";
|
||||
import useSWRSubscription from "swr/subscription";
|
||||
@@ -30,8 +30,10 @@ export const LayoutTraffic = () => {
|
||||
const trafficRef = useRef<TrafficRef>(null);
|
||||
const pageVisible = useVisibility();
|
||||
|
||||
// setup log ws during layout
|
||||
useLogSetup();
|
||||
// https://swr.vercel.app/docs/subscription#deduplication
|
||||
// useSWRSubscription auto deduplicates to one subscription per key per entire app
|
||||
// So we can simply invoke it here acting as preconnect
|
||||
useLogData();
|
||||
|
||||
const { data: traffic = { up: 0, down: 0 } } = useSWRSubscription<
|
||||
ITrafficItem,
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
import dayjs from "dayjs";
|
||||
import { useEffect } from "react";
|
||||
import { getClashLogs } from "@/services/cmds";
|
||||
import { useClashInfo } from "@/hooks/use-clash";
|
||||
import { useEnableLog, useSetLogData } from "@/services/states";
|
||||
import { useWebsocket } from "@/hooks/use-websocket";
|
||||
|
||||
const MAX_LOG_NUM = 1000;
|
||||
|
||||
// setup the log websocket
|
||||
export const useLogSetup = () => {
|
||||
const { clashInfo } = useClashInfo();
|
||||
|
||||
const [enableLog] = useEnableLog();
|
||||
const setLogData = useSetLogData();
|
||||
|
||||
const { connect, disconnect } = useWebsocket((event) => {
|
||||
const data = JSON.parse(event.data) as ILogItem;
|
||||
const time = dayjs().format("MM-DD HH:mm:ss");
|
||||
setLogData((l) => {
|
||||
if (l.length >= MAX_LOG_NUM) l.shift();
|
||||
return [...l, { ...data, time }];
|
||||
});
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!enableLog || !clashInfo) return;
|
||||
|
||||
getClashLogs().then(setLogData);
|
||||
|
||||
const { server = "", secret = "" } = clashInfo;
|
||||
connect(`ws://${server}/logs?token=${encodeURIComponent(secret)}`);
|
||||
|
||||
return () => {
|
||||
disconnect();
|
||||
};
|
||||
}, [clashInfo, enableLog]);
|
||||
};
|
||||
@@ -32,7 +32,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
/^((\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|(\d{1,3}\.){1,3}\d{1,3}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\*|\d{1,3}\.\d{1,3}\.\*|\d{1,3}\.\*|([a-fA-F0-9:]+:+)+[a-fA-F0-9]+|localhost|<local>)(;((\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|(\d{1,3}\.){1,3}\d{1,3}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\*|\d{1,3}\.\d{1,3}\.\*|\d{1,3}\.\*|([a-fA-F0-9:]+:+)+[a-fA-F0-9]+|localhost|<local>))*;?$/;
|
||||
} else {
|
||||
validReg =
|
||||
/^((\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|(\d{1,3}\.){1,3}\d{1,3}(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\d{1,3}\.\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|([a-fA-F0-9:]+:+)+[a-fA-F0-9]+(\/\d{1,3})?|localhost|<local>)(;((\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|(\d{1,3}\.){1,3}\d{1,3}(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\d{1,3}\.\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|([a-fA-F0-9:]+:+)+[a-fA-F0-9]+(\/\d{1,3})?|localhost|<local>))*;?$/;
|
||||
/^((\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|(\d{1,3}\.){1,3}\d{1,3}(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\d{1,3}\.\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|([a-fA-F0-9:]+:+)+[a-fA-F0-9]+(\/\d{1,3})?|localhost|<local>)(,((\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|(\d{1,3}\.){1,3}\d{1,3}(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\d{1,3}\.\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|([a-fA-F0-9:]+:+)+[a-fA-F0-9]+(\/\d{1,3})?|localhost|<local>))*,?$/;
|
||||
}
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import useSWRSubscription from "swr/subscription";
|
||||
import { useEnableLog } from "../services/states";
|
||||
import { createSockette } from "../utils/websocket";
|
||||
import { useClashInfo } from "./use-clash";
|
||||
import dayjs from "dayjs";
|
||||
import { getClashLogs } from "../services/cmds";
|
||||
|
||||
const MAX_LOG_NUM = 1000;
|
||||
|
||||
export const useLogData = () => {
|
||||
const { clashInfo } = useClashInfo();
|
||||
|
||||
const [enableLog] = useEnableLog();
|
||||
!enableLog || !clashInfo;
|
||||
|
||||
return useSWRSubscription<ILogItem[], any, "getClashLog" | null>(
|
||||
enableLog && clashInfo ? "getClashLog" : null,
|
||||
(_key, { next }) => {
|
||||
const { server = "", secret = "" } = clashInfo!;
|
||||
|
||||
// populate the initial logs
|
||||
getClashLogs().then(
|
||||
(logs) => next(null, logs),
|
||||
(err) => next(err)
|
||||
);
|
||||
|
||||
const s = createSockette(
|
||||
`ws://${server}/logs?token=${encodeURIComponent(secret)}`,
|
||||
{
|
||||
onmessage(event) {
|
||||
const data = JSON.parse(event.data) as ILogItem;
|
||||
|
||||
// append new log item on socket message
|
||||
next(null, (l = []) => {
|
||||
const time = dayjs().format("MM-DD HH:mm:ss");
|
||||
|
||||
if (l.length >= MAX_LOG_NUM) l.shift();
|
||||
return [...l, { ...data, time }];
|
||||
});
|
||||
},
|
||||
onerror(event) {
|
||||
this.close();
|
||||
next(event);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return () => {
|
||||
s.close();
|
||||
};
|
||||
},
|
||||
{
|
||||
fallbackData: { up: 0, down: 0 },
|
||||
keepPreviousData: true,
|
||||
}
|
||||
);
|
||||
};
|
||||
@@ -1,60 +0,0 @@
|
||||
import { useRef } from "react";
|
||||
|
||||
export type WsMsgFn = (event: MessageEvent<any>) => void;
|
||||
|
||||
export interface WsOptions {
|
||||
errorCount?: number; // default is 5
|
||||
retryInterval?: number; // default is 2500
|
||||
onError?: (event: Event) => void;
|
||||
onClose?: (event: CloseEvent) => void;
|
||||
}
|
||||
|
||||
export const useWebsocket = (onMessage: WsMsgFn, options?: WsOptions) => {
|
||||
const wsRef = useRef<WebSocket | null>(null);
|
||||
const timerRef = useRef<any>(null);
|
||||
|
||||
const disconnect = () => {
|
||||
if (wsRef.current) {
|
||||
wsRef.current.close();
|
||||
wsRef.current = null;
|
||||
}
|
||||
if (timerRef.current) {
|
||||
clearTimeout(timerRef.current);
|
||||
}
|
||||
};
|
||||
|
||||
const connect = (url: string) => {
|
||||
let errorCount = options?.errorCount ?? 5;
|
||||
|
||||
if (!url) return;
|
||||
|
||||
const connectHelper = () => {
|
||||
disconnect();
|
||||
|
||||
const ws = new WebSocket(url);
|
||||
wsRef.current = ws;
|
||||
|
||||
ws.addEventListener("message", (event) => {
|
||||
errorCount = 0; // reset counter
|
||||
onMessage(event);
|
||||
});
|
||||
ws.addEventListener("error", (event) => {
|
||||
errorCount -= 1;
|
||||
|
||||
if (errorCount >= 0) {
|
||||
timerRef.current = setTimeout(connectHelper, 2500);
|
||||
} else {
|
||||
disconnect();
|
||||
options?.onError?.(event);
|
||||
}
|
||||
});
|
||||
ws.addEventListener("close", (event) => {
|
||||
options?.onClose?.(event);
|
||||
});
|
||||
};
|
||||
|
||||
connectHelper();
|
||||
};
|
||||
|
||||
return { connect, disconnect };
|
||||
};
|
||||
@@ -16,7 +16,6 @@ import Layout from "./pages/_layout";
|
||||
import "./services/i18n";
|
||||
import {
|
||||
LoadingCacheProvider,
|
||||
LogDataProvider,
|
||||
ThemeModeProvider,
|
||||
UpdateStateProvider,
|
||||
} from "./services/states";
|
||||
@@ -45,7 +44,6 @@ document.addEventListener("keydown", (event) => {
|
||||
|
||||
const contexts = [
|
||||
<ThemeModeProvider />,
|
||||
<LogDataProvider />,
|
||||
<LoadingCacheProvider />,
|
||||
<UpdateStateProvider />,
|
||||
];
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useMemo, useRef, useState } from "react";
|
||||
import { useLockFn } from "ahooks";
|
||||
import { Box, Button, IconButton, MenuItem } from "@mui/material";
|
||||
import { Virtuoso } from "react-virtuoso";
|
||||
@@ -8,7 +8,6 @@ import { closeAllConnections } from "@/services/api";
|
||||
import { useConnectionSetting } from "@/services/states";
|
||||
import { useClashInfo } from "@/hooks/use-clash";
|
||||
import { BaseEmpty, BasePage } from "@/components/base";
|
||||
import { useWebsocket } from "@/hooks/use-websocket";
|
||||
import { ConnectionItem } from "@/components/connection/connection-item";
|
||||
import { ConnectionTable } from "@/components/connection/connection-table";
|
||||
import {
|
||||
@@ -19,8 +18,14 @@ import parseTraffic from "@/utils/parse-traffic";
|
||||
import { useCustomTheme } from "@/components/layout/use-custom-theme";
|
||||
import { BaseSearchBox } from "@/components/base/base-search-box";
|
||||
import { BaseStyledSelect } from "@/components/base/base-styled-select";
|
||||
import useSWRSubscription from "swr/subscription";
|
||||
import { createSockette } from "@/utils/websocket";
|
||||
|
||||
const initConn = { uploadTotal: 0, downloadTotal: 0, connections: [] };
|
||||
const initConn: IConnections = {
|
||||
uploadTotal: 0,
|
||||
downloadTotal: 0,
|
||||
connections: [],
|
||||
};
|
||||
|
||||
type OrderFunc = (list: IConnectionsItem[]) => IConnectionsItem[];
|
||||
|
||||
@@ -31,7 +36,6 @@ const ConnectionsPage = () => {
|
||||
const isDark = theme.palette.mode === "dark";
|
||||
const [match, setMatch] = useState(() => (_: string) => true);
|
||||
const [curOrderOpt, setOrderOpt] = useState("Default");
|
||||
const [connData, setConnData] = useState<IConnections>(initConn);
|
||||
|
||||
const [setting, setSetting] = useConnectionSetting();
|
||||
|
||||
@@ -49,6 +53,63 @@ const ConnectionsPage = () => {
|
||||
list.sort((a, b) => b.curDownload! - a.curDownload!),
|
||||
};
|
||||
|
||||
const { data: connData = initConn } = useSWRSubscription<
|
||||
IConnections,
|
||||
any,
|
||||
"getClashConnections" | null
|
||||
>(clashInfo ? "getClashConnections" : null, (_key, { next }) => {
|
||||
const { server = "", secret = "" } = clashInfo!;
|
||||
|
||||
const s = createSockette(
|
||||
`ws://${server}/connections?token=${encodeURIComponent(secret)}`,
|
||||
{
|
||||
onmessage(event) {
|
||||
// meta v1.15.0 出现 data.connections 为 null 的情况
|
||||
const data = JSON.parse(event.data) as IConnections;
|
||||
// 尽量与前一次 connections 的展示顺序保持一致
|
||||
next(null, (old = initConn) => {
|
||||
const oldConn = old.connections;
|
||||
const maxLen = data.connections?.length;
|
||||
|
||||
const connections: IConnectionsItem[] = [];
|
||||
|
||||
const rest = (data.connections || []).filter((each) => {
|
||||
const index = oldConn.findIndex((o) => o.id === each.id);
|
||||
|
||||
if (index >= 0 && index < maxLen) {
|
||||
const old = oldConn[index];
|
||||
each.curUpload = each.upload - old.upload;
|
||||
each.curDownload = each.download - old.download;
|
||||
|
||||
connections[index] = each;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
for (let i = 0; i < maxLen; ++i) {
|
||||
if (!connections[i] && rest.length > 0) {
|
||||
connections[i] = rest.shift()!;
|
||||
connections[i].curUpload = 0;
|
||||
connections[i].curDownload = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return { ...data, connections };
|
||||
});
|
||||
},
|
||||
onerror(event) {
|
||||
next(event);
|
||||
},
|
||||
},
|
||||
3
|
||||
);
|
||||
|
||||
return () => {
|
||||
s.close();
|
||||
};
|
||||
});
|
||||
|
||||
const [filterConn, download, upload] = useMemo(() => {
|
||||
const orderFunc = orderOpts[curOrderOpt];
|
||||
let connections = connData.connections.filter((conn) =>
|
||||
@@ -56,6 +117,7 @@ const ConnectionsPage = () => {
|
||||
);
|
||||
|
||||
if (orderFunc) connections = orderFunc(connections);
|
||||
|
||||
let download = 0;
|
||||
let upload = 0;
|
||||
connections.forEach((x) => {
|
||||
@@ -65,55 +127,6 @@ const ConnectionsPage = () => {
|
||||
return [connections, download, upload];
|
||||
}, [connData, match, curOrderOpt]);
|
||||
|
||||
const { connect, disconnect } = useWebsocket(
|
||||
(event) => {
|
||||
// meta v1.15.0 出现data.connections为null的情况
|
||||
const data = JSON.parse(event.data) as IConnections;
|
||||
// 尽量与前一次connections的展示顺序保持一致
|
||||
setConnData((old) => {
|
||||
const oldConn = old.connections;
|
||||
const maxLen = data.connections?.length;
|
||||
|
||||
const connections: typeof oldConn = [];
|
||||
|
||||
const rest = (data.connections || []).filter((each) => {
|
||||
const index = oldConn.findIndex((o) => o.id === each.id);
|
||||
|
||||
if (index >= 0 && index < maxLen) {
|
||||
const old = oldConn[index];
|
||||
each.curUpload = each.upload - old.upload;
|
||||
each.curDownload = each.download - old.download;
|
||||
|
||||
connections[index] = each;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
for (let i = 0; i < maxLen; ++i) {
|
||||
if (!connections[i] && rest.length > 0) {
|
||||
connections[i] = rest.shift()!;
|
||||
connections[i].curUpload = 0;
|
||||
connections[i].curDownload = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return { ...data, connections };
|
||||
});
|
||||
},
|
||||
{ errorCount: 3, retryInterval: 1000 }
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!clashInfo) return;
|
||||
const { server = "", secret = "" } = clashInfo;
|
||||
connect(`ws://${server}/connections?token=${encodeURIComponent(secret)}`);
|
||||
|
||||
return () => {
|
||||
disconnect();
|
||||
};
|
||||
}, [clashInfo]);
|
||||
|
||||
const onCloseAll = useLockFn(closeAllConnections);
|
||||
|
||||
const detailRef = useRef<ConnectionDetailRef>(null!);
|
||||
|
||||
@@ -6,17 +6,18 @@ import {
|
||||
PlayCircleOutlineRounded,
|
||||
PauseCircleOutlineRounded,
|
||||
} from "@mui/icons-material";
|
||||
import { useEnableLog, useLogData, useSetLogData } from "@/services/states";
|
||||
import { useLogData } from "@/hooks/use-log-data";
|
||||
import { useEnableLog } from "@/services/states";
|
||||
import { BaseEmpty, BasePage } from "@/components/base";
|
||||
import LogItem from "@/components/log/log-item";
|
||||
import { useCustomTheme } from "@/components/layout/use-custom-theme";
|
||||
import { BaseSearchBox } from "@/components/base/base-search-box";
|
||||
import { BaseStyledSelect } from "@/components/base/base-styled-select";
|
||||
import { mutate } from "swr";
|
||||
|
||||
const LogPage = () => {
|
||||
const { t } = useTranslation();
|
||||
const logData = useLogData();
|
||||
const setLogData = useSetLogData();
|
||||
const { data: logData = [] } = useLogData();
|
||||
const [enableLog, setEnableLog] = useEnableLog();
|
||||
const { theme } = useCustomTheme();
|
||||
const isDark = theme.palette.mode === "dark";
|
||||
@@ -54,7 +55,9 @@ const LogPage = () => {
|
||||
<Button
|
||||
size="small"
|
||||
variant="contained"
|
||||
onClick={() => setLogData([])}
|
||||
// useSWRSubscription adds a prefix "$sub$" to the cache key
|
||||
// https://github.com/vercel/swr/blob/1585a3e37d90ad0df8097b099db38f1afb43c95d/src/subscription/index.ts#L37
|
||||
onClick={() => mutate("$sub$getClashLog", [])}
|
||||
>
|
||||
{t("Clear")}
|
||||
</Button>
|
||||
|
||||
@@ -5,10 +5,6 @@ const [ThemeModeProvider, useThemeMode, useSetThemeMode] = createContextState<
|
||||
"light" | "dark"
|
||||
>("light");
|
||||
|
||||
const [LogDataProvider, useLogData, useSetLogData] = createContextState<
|
||||
ILogItem[]
|
||||
>([]);
|
||||
|
||||
export const useEnableLog = () => useLocalStorage("enable-log", true);
|
||||
|
||||
interface IConnectionSetting {
|
||||
@@ -39,9 +35,6 @@ export {
|
||||
ThemeModeProvider,
|
||||
useThemeMode,
|
||||
useSetThemeMode,
|
||||
LogDataProvider,
|
||||
useLogData,
|
||||
useSetLogData,
|
||||
LoadingCacheProvider,
|
||||
useLoadingCache,
|
||||
useSetLoadingCache,
|
||||
|
||||
@@ -6,7 +6,7 @@ var (
|
||||
// allow change in test
|
||||
IdleTimeOut = 10 * time.Second
|
||||
|
||||
Version = "1.1.4-dev"
|
||||
Version = "1.1.4"
|
||||
GitBranch string
|
||||
GitRevision string
|
||||
BuildTime string
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
LINUX_VERSION-5.10 = .218
|
||||
LINUX_KERNEL_HASH-5.10.218 = 9c36b243e8c3ec1d5963366618f336710b84340bf95be2037b26c452392cb2d6
|
||||
LINUX_VERSION-5.10 = .219
|
||||
LINUX_KERNEL_HASH-5.10.219 = 93b73f15cc376463e6422cce09ccd9d0a20fb113921ffebddf3352c44d84cd30
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
LINUX_VERSION-5.4 = .277
|
||||
LINUX_KERNEL_HASH-5.4.277 = 7e1f5b28588e49ddfd18e7772476e4e8b52bdc9c3e19beafcbb7c103e6c01f51
|
||||
LINUX_VERSION-5.4 = .278
|
||||
LINUX_KERNEL_HASH-5.4.278 = e5a00606115545f444ef2766af5652f5539e3c96f46a9778bede89b98ffb8588
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
LINUX_VERSION-6.1 = .92
|
||||
LINUX_KERNEL_HASH-6.1.92 = 9019f427bfdc9ced5bc954d760d37ac08c0cdffb45ad28087fc45a73e64336c9
|
||||
LINUX_VERSION-6.1 = .94
|
||||
LINUX_KERNEL_HASH-6.1.94 = 38ea71ad22ae0187fd8ee5ff879b33b0d9bd58161ac9a3e868ae0b4c66b95369
|
||||
|
||||
@@ -43,7 +43,7 @@ endef
|
||||
define Package/nss-firmware-ipq8074
|
||||
$(Package/nss-firmware-default)
|
||||
TITLE:=NSS firmware for IPQ8074 devices
|
||||
NSS_ARCHIVE:=$(VERSION_PATH)/IPQ8074.ATH.12.0.0/BIN-NSS.FW.12.0.r1-002-HK.R.tar.bz2
|
||||
NSS_ARCHIVE:=$(VERSION_PATH)/IPQ8074.ATH.12.0.0/BIN-NSS.FW.12.1-022-HK.R.tar.bz2
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
From 648c906a27d3713f589717f4be36583fc64f2ba1 Mon Sep 17 00:00:00 2001
|
||||
From: Steve Glendinning <steve.glendinning@smsc.com>
|
||||
Date: Thu, 19 Feb 2015 18:47:12 +0000
|
||||
Subject: [PATCH] smsx95xx: fix crimes against truesize
|
||||
|
||||
smsc95xx is adjusting truesize when it shouldn't, and following a recent patch from Eric this is now triggering warnings.
|
||||
|
||||
This patch stops smsc95xx from changing truesize.
|
||||
|
||||
Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com>
|
||||
---
|
||||
drivers/net/usb/smsc95xx.c | 10 ++++++++--
|
||||
1 file changed, 8 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/usb/smsc95xx.c
|
||||
+++ b/drivers/net/usb/smsc95xx.c
|
||||
@@ -79,6 +79,10 @@ static bool turbo_mode = true;
|
||||
module_param(turbo_mode, bool, 0644);
|
||||
MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
|
||||
|
||||
+static bool truesize_mode = false;
|
||||
+module_param(truesize_mode, bool, 0644);
|
||||
+MODULE_PARM_DESC(truesize_mode, "Report larger truesize value");
|
||||
+
|
||||
static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index,
|
||||
u32 *data)
|
||||
{
|
||||
@@ -1870,7 +1874,8 @@ static int smsc95xx_rx_fixup(struct usbn
|
||||
if (dev->net->features & NETIF_F_RXCSUM)
|
||||
smsc95xx_rx_csum_offload(skb);
|
||||
skb_trim(skb, skb->len - 4); /* remove fcs */
|
||||
- skb->truesize = size + sizeof(struct sk_buff);
|
||||
+ if (truesize_mode)
|
||||
+ skb->truesize = size + sizeof(struct sk_buff);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1888,7 +1893,8 @@ static int smsc95xx_rx_fixup(struct usbn
|
||||
if (dev->net->features & NETIF_F_RXCSUM)
|
||||
smsc95xx_rx_csum_offload(ax_skb);
|
||||
skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
|
||||
- ax_skb->truesize = size + sizeof(struct sk_buff);
|
||||
+ if (truesize_mode)
|
||||
+ ax_skb->truesize = size + sizeof(struct sk_buff);
|
||||
|
||||
usbnet_skb_return(dev, ax_skb);
|
||||
}
|
||||
+4
-4
@@ -11,9 +11,9 @@ See: http://forum.kodi.tv/showthread.php?tid=285288
|
||||
|
||||
--- a/drivers/net/usb/smsc95xx.c
|
||||
+++ b/drivers/net/usb/smsc95xx.c
|
||||
@@ -83,6 +83,10 @@ static bool truesize_mode = false;
|
||||
module_param(truesize_mode, bool, 0644);
|
||||
MODULE_PARM_DESC(truesize_mode, "Report larger truesize value");
|
||||
@@ -79,6 +79,10 @@ static bool turbo_mode = true;
|
||||
module_param(turbo_mode, bool, 0644);
|
||||
MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
|
||||
|
||||
+static int packetsize = 2560;
|
||||
+module_param(packetsize, int, 0644);
|
||||
@@ -22,7 +22,7 @@ See: http://forum.kodi.tv/showthread.php?tid=285288
|
||||
static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index,
|
||||
u32 *data)
|
||||
{
|
||||
@@ -936,13 +940,13 @@ static int smsc95xx_reset(struct usbnet
|
||||
@@ -932,13 +936,13 @@ static int smsc95xx_reset(struct usbnet
|
||||
|
||||
if (!turbo_mode) {
|
||||
burst_cap = 0;
|
||||
|
||||
+3
-3
@@ -22,7 +22,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
|
||||
|
||||
--- a/drivers/net/usb/smsc95xx.c
|
||||
+++ b/drivers/net/usb/smsc95xx.c
|
||||
@@ -87,6 +87,10 @@ static int packetsize = 2560;
|
||||
@@ -83,6 +83,10 @@ static int packetsize = 2560;
|
||||
module_param(packetsize, int, 0644);
|
||||
MODULE_PARM_DESC(packetsize, "Override the RX URB packet size");
|
||||
|
||||
@@ -33,7 +33,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
|
||||
static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index,
|
||||
u32 *data)
|
||||
{
|
||||
@@ -809,6 +813,52 @@ static int smsc95xx_ioctl(struct net_dev
|
||||
@@ -805,6 +809,52 @@ static int smsc95xx_ioctl(struct net_dev
|
||||
return phy_mii_ioctl(netdev->phydev, rq, cmd);
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
|
||||
static void smsc95xx_init_mac_address(struct usbnet *dev)
|
||||
{
|
||||
u8 addr[ETH_ALEN];
|
||||
@@ -832,6 +882,10 @@ static void smsc95xx_init_mac_address(st
|
||||
@@ -828,6 +878,10 @@ static void smsc95xx_init_mac_address(st
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -27,7 +27,7 @@ Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
|
||||
|
||||
--- a/drivers/firmware/raspberrypi.c
|
||||
+++ b/drivers/firmware/raspberrypi.c
|
||||
@@ -32,6 +32,8 @@ struct rpi_firmware {
|
||||
@@ -33,6 +33,8 @@ struct rpi_firmware {
|
||||
struct kref consumers;
|
||||
};
|
||||
|
||||
@@ -36,7 +36,7 @@ Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
|
||||
static DEFINE_MUTEX(transaction_lock);
|
||||
|
||||
static void response_callback(struct mbox_client *cl, void *msg)
|
||||
@@ -280,6 +282,7 @@ static int rpi_firmware_probe(struct pla
|
||||
@@ -281,6 +283,7 @@ static int rpi_firmware_probe(struct pla
|
||||
kref_init(&fw->consumers);
|
||||
|
||||
platform_set_drvdata(pdev, fw);
|
||||
@@ -44,7 +44,7 @@ Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
|
||||
|
||||
rpi_firmware_print_firmware_revision(fw);
|
||||
rpi_register_hwmon_driver(dev, fw);
|
||||
@@ -308,6 +311,7 @@ static int rpi_firmware_remove(struct pl
|
||||
@@ -309,6 +312,7 @@ static int rpi_firmware_remove(struct pl
|
||||
rpi_clk = NULL;
|
||||
|
||||
rpi_firmware_put(fw);
|
||||
@@ -52,7 +52,7 @@ Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -382,7 +386,18 @@ static struct platform_driver rpi_firmwa
|
||||
@@ -383,7 +387,18 @@ static struct platform_driver rpi_firmwa
|
||||
.shutdown = rpi_firmware_shutdown,
|
||||
.remove = rpi_firmware_remove,
|
||||
};
|
||||
|
||||
+1
-1
@@ -156,7 +156,7 @@ See: https://github.com/raspberrypi/linux/issues/1064
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- a/include/linux/leds.h
|
||||
+++ b/include/linux/leds.h
|
||||
@@ -85,6 +85,9 @@ struct led_classdev {
|
||||
@@ -95,6 +95,9 @@ struct led_classdev {
|
||||
#define LED_BRIGHT_HW_CHANGED BIT(21)
|
||||
#define LED_RETAIN_AT_SHUTDOWN BIT(22)
|
||||
#define LED_INIT_DEFAULT_TRIGGER BIT(23)
|
||||
|
||||
+3
-3
@@ -13,7 +13,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
|
||||
|
||||
--- a/drivers/firmware/raspberrypi.c
|
||||
+++ b/drivers/firmware/raspberrypi.c
|
||||
@@ -12,6 +12,7 @@
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
@@ -21,7 +21,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
|
||||
#include <linux/slab.h>
|
||||
#include <soc/bcm2835/raspberrypi-firmware.h>
|
||||
|
||||
@@ -179,6 +180,26 @@ int rpi_firmware_property(struct rpi_fir
|
||||
@@ -180,6 +181,26 @@ int rpi_firmware_property(struct rpi_fir
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpi_firmware_property);
|
||||
|
||||
@@ -48,7 +48,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
|
||||
static void
|
||||
rpi_firmware_print_firmware_revision(struct rpi_firmware *fw)
|
||||
{
|
||||
@@ -387,15 +408,32 @@ static struct platform_driver rpi_firmwa
|
||||
@@ -388,15 +409,32 @@ static struct platform_driver rpi_firmwa
|
||||
.remove = rpi_firmware_remove,
|
||||
};
|
||||
|
||||
|
||||
+4
-4
@@ -16,7 +16,7 @@ Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
|
||||
|
||||
--- a/drivers/firmware/raspberrypi.c
|
||||
+++ b/drivers/firmware/raspberrypi.c
|
||||
@@ -31,6 +31,7 @@ struct rpi_firmware {
|
||||
@@ -32,6 +32,7 @@ struct rpi_firmware {
|
||||
u32 enabled;
|
||||
|
||||
struct kref consumers;
|
||||
@@ -24,7 +24,7 @@ Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
|
||||
};
|
||||
|
||||
static struct platform_device *g_pdev;
|
||||
@@ -176,6 +177,12 @@ int rpi_firmware_property(struct rpi_fir
|
||||
@@ -177,6 +178,12 @@ int rpi_firmware_property(struct rpi_fir
|
||||
|
||||
kfree(data);
|
||||
|
||||
@@ -37,7 +37,7 @@ Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpi_firmware_property);
|
||||
@@ -200,6 +207,27 @@ static int rpi_firmware_notify_reboot(st
|
||||
@@ -201,6 +208,27 @@ static int rpi_firmware_notify_reboot(st
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
|
||||
static void
|
||||
rpi_firmware_print_firmware_revision(struct rpi_firmware *fw)
|
||||
{
|
||||
@@ -229,6 +257,11 @@ rpi_register_hwmon_driver(struct device
|
||||
@@ -230,6 +258,11 @@ rpi_register_hwmon_driver(struct device
|
||||
|
||||
rpi_hwmon = platform_device_register_data(dev, "raspberrypi-hwmon",
|
||||
-1, NULL, 0);
|
||||
|
||||
+3
-3
@@ -26,7 +26,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
|
||||
|
||||
--- a/drivers/firmware/raspberrypi.c
|
||||
+++ b/drivers/firmware/raspberrypi.c
|
||||
@@ -233,6 +233,15 @@ rpi_firmware_print_firmware_revision(str
|
||||
@@ -234,6 +234,15 @@ rpi_firmware_print_firmware_revision(str
|
||||
{
|
||||
time64_t date_and_time;
|
||||
u32 packet;
|
||||
@@ -42,7 +42,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
|
||||
int ret = rpi_firmware_property(fw,
|
||||
RPI_FIRMWARE_GET_FIRMWARE_REVISION,
|
||||
&packet, sizeof(packet));
|
||||
@@ -242,7 +251,35 @@ rpi_firmware_print_firmware_revision(str
|
||||
@@ -243,7 +252,35 @@ rpi_firmware_print_firmware_revision(str
|
||||
|
||||
/* This is not compatible with y2038 */
|
||||
date_and_time = packet;
|
||||
@@ -79,7 +79,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -339,6 +376,7 @@ static int rpi_firmware_probe(struct pla
|
||||
@@ -340,6 +377,7 @@ static int rpi_firmware_probe(struct pla
|
||||
g_pdev = pdev;
|
||||
|
||||
rpi_firmware_print_firmware_revision(fw);
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ Co-authored-by: Phil Elwell <phil@raspberrypi.org>
|
||||
MODULE_DESCRIPTION("BCM2835 clock driver");
|
||||
--- a/drivers/firmware/raspberrypi.c
|
||||
+++ b/drivers/firmware/raspberrypi.c
|
||||
@@ -499,7 +499,7 @@ out2:
|
||||
@@ -500,7 +500,7 @@ out2:
|
||||
out1:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
|
||||
|
||||
--- a/drivers/spi/spi.c
|
||||
+++ b/drivers/spi/spi.c
|
||||
@@ -3690,6 +3690,7 @@ static int spi_set_cs_timing(struct spi_
|
||||
@@ -3694,6 +3694,7 @@ static int spi_set_cs_timing(struct spi_
|
||||
*/
|
||||
int spi_setup(struct spi_device *spi)
|
||||
{
|
||||
@@ -40,7 +40,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
|
||||
unsigned bad_bits, ugly_bits;
|
||||
int status = 0;
|
||||
|
||||
@@ -3710,6 +3711,14 @@ int spi_setup(struct spi_device *spi)
|
||||
@@ -3714,6 +3715,14 @@ int spi_setup(struct spi_device *spi)
|
||||
(SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL |
|
||||
SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL)))
|
||||
return -EINVAL;
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@ mechanism to be implemented for OS upgrades.
|
||||
|
||||
--- a/drivers/firmware/raspberrypi.c
|
||||
+++ b/drivers/firmware/raspberrypi.c
|
||||
@@ -193,6 +193,7 @@ static int rpi_firmware_notify_reboot(st
|
||||
@@ -194,6 +194,7 @@ static int rpi_firmware_notify_reboot(st
|
||||
{
|
||||
struct rpi_firmware *fw;
|
||||
struct platform_device *pdev = g_pdev;
|
||||
@@ -27,7 +27,7 @@ mechanism to be implemented for OS upgrades.
|
||||
|
||||
if (!pdev)
|
||||
return 0;
|
||||
@@ -201,8 +202,28 @@ static int rpi_firmware_notify_reboot(st
|
||||
@@ -202,8 +203,28 @@ static int rpi_firmware_notify_reboot(st
|
||||
if (!fw)
|
||||
return 0;
|
||||
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
||||
|
||||
--- a/drivers/gpu/drm/panel/panel-simple.c
|
||||
+++ b/drivers/gpu/drm/panel/panel-simple.c
|
||||
@@ -3193,6 +3193,31 @@ static const struct panel_desc qishenglo
|
||||
@@ -3196,6 +3196,31 @@ static const struct panel_desc qishenglo
|
||||
.connector_type = DRM_MODE_CONNECTOR_DPI,
|
||||
};
|
||||
|
||||
@@ -47,7 +47,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
||||
static const struct display_timing rocktech_rk070er9427_timing = {
|
||||
.pixelclock = { 26400000, 33300000, 46800000 },
|
||||
.hactive = { 800, 800, 800 },
|
||||
@@ -4226,6 +4251,9 @@ static const struct of_device_id platfor
|
||||
@@ -4229,6 +4254,9 @@ static const struct of_device_id platfor
|
||||
.compatible = "qishenglong,gopher2b-lcd",
|
||||
.data = &qishenglong_gopher2b_lcd,
|
||||
}, {
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ Acked-by: Maxime Ripard <maxime@cerno.tech>
|
||||
static const struct drm_display_mode giantplus_gpg482739qs5_mode = {
|
||||
.clock = 9000,
|
||||
.hdisplay = 480,
|
||||
@@ -4110,6 +4136,9 @@ static const struct of_device_id platfor
|
||||
@@ -4113,6 +4139,9 @@ static const struct of_device_id platfor
|
||||
.compatible = "friendlyarm,hd702e",
|
||||
.data = &friendlyarm_hd702e,
|
||||
}, {
|
||||
|
||||
+2
-2
@@ -19,7 +19,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||||
|
||||
--- a/drivers/firmware/raspberrypi.c
|
||||
+++ b/drivers/firmware/raspberrypi.c
|
||||
@@ -429,6 +429,18 @@ static int rpi_firmware_remove(struct pl
|
||||
@@ -430,6 +430,18 @@ static int rpi_firmware_remove(struct pl
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||||
/**
|
||||
* rpi_firmware_get - Get pointer to rpi_firmware structure.
|
||||
* @firmware_node: Pointer to the firmware Device Tree node.
|
||||
@@ -484,12 +496,6 @@ struct rpi_firmware *devm_rpi_firmware_g
|
||||
@@ -485,12 +497,6 @@ struct rpi_firmware *devm_rpi_firmware_g
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_rpi_firmware_get);
|
||||
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||||
|
||||
--- a/drivers/firmware/raspberrypi.c
|
||||
+++ b/drivers/firmware/raspberrypi.c
|
||||
@@ -342,6 +342,26 @@ static void rpi_register_clk_driver(stru
|
||||
@@ -343,6 +343,26 @@ static void rpi_register_clk_driver(stru
|
||||
-1, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
#include <sound/hdmi-codec.h>
|
||||
#include <sound/pcm_drm_eld.h>
|
||||
@@ -3695,7 +3696,7 @@ static int vc4_hdmi_bind(struct device *
|
||||
@@ -3697,7 +3698,7 @@ static int vc4_hdmi_bind(struct device *
|
||||
|
||||
if (variant->max_pixel_clock == 600000000) {
|
||||
struct vc4_dev *vc4 = to_vc4_dev(drm);
|
||||
|
||||
+1
-1
@@ -91,7 +91,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
if (info->max_tmds_clock && clock > (info->max_tmds_clock * 1000))
|
||||
@@ -3694,14 +3695,6 @@ static int vc4_hdmi_bind(struct device *
|
||||
@@ -3696,14 +3697,6 @@ static int vc4_hdmi_bind(struct device *
|
||||
vc4_hdmi->disable_wifi_frequencies =
|
||||
of_property_read_bool(dev->of_node, "wifi-2.4ghz-coexistence");
|
||||
|
||||
|
||||
+1
-1
@@ -165,7 +165,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
|
||||
static const struct drm_display_mode innolux_at070tn92_mode = {
|
||||
.clock = 33333,
|
||||
.hdisplay = 800,
|
||||
@@ -4146,6 +4178,9 @@ static const struct of_device_id platfor
|
||||
@@ -4149,6 +4181,9 @@ static const struct of_device_id platfor
|
||||
.compatible = "innolux,at043tn24",
|
||||
.data = &innolux_at043tn24,
|
||||
}, {
|
||||
|
||||
+5
-3
@@ -8,8 +8,8 @@ Slave addresses for DMA are meant to be supplied as physical addresses
|
||||
|
||||
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
|
||||
---
|
||||
drivers/gpu/drm/vc4/vc4_hdmi.c | 13 ++++---------
|
||||
1 file changed, 4 insertions(+), 9 deletions(-)
|
||||
drivers/gpu/drm/vc4/vc4_hdmi.c | 15 ++++-----------
|
||||
1 file changed, 4 insertions(+), 11 deletions(-)
|
||||
|
||||
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
|
||||
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
|
||||
@@ -22,7 +22,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
|
||||
int index, len;
|
||||
int ret;
|
||||
|
||||
@@ -2755,20 +2755,15 @@ static int vc4_hdmi_audio_init(struct vc
|
||||
@@ -2755,22 +2755,15 @@ static int vc4_hdmi_audio_init(struct vc
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -40,6 +40,8 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
|
||||
+ iomem = platform_get_resource(vc4_hdmi->pdev, IORESOURCE_MEM, index);
|
||||
|
||||
- addr = of_get_address(dev->of_node, index, NULL, NULL);
|
||||
- if (!addr)
|
||||
- return -EINVAL;
|
||||
-
|
||||
- vc4_hdmi->audio.dma_data.addr = be32_to_cpup(addr) + mai_data->offset;
|
||||
+ vc4_hdmi->audio.dma_data.addr = iomem->start + mai_data->offset;
|
||||
|
||||
+2
-2
@@ -43,7 +43,7 @@ Signed-off-by: Lukas Wunner <lukas@wunner.de>
|
||||
|
||||
--- a/drivers/net/usb/smsc95xx.c
|
||||
+++ b/drivers/net/usb/smsc95xx.c
|
||||
@@ -814,49 +814,18 @@ static int smsc95xx_ioctl(struct net_dev
|
||||
@@ -810,49 +810,18 @@ static int smsc95xx_ioctl(struct net_dev
|
||||
}
|
||||
|
||||
/* Check the macaddr module parameter for a MAC address */
|
||||
@@ -103,7 +103,7 @@ Signed-off-by: Lukas Wunner <lukas@wunner.de>
|
||||
}
|
||||
|
||||
static void smsc95xx_init_mac_address(struct usbnet *dev)
|
||||
@@ -883,8 +852,12 @@ static void smsc95xx_init_mac_address(st
|
||||
@@ -879,8 +848,12 @@ static void smsc95xx_init_mac_address(st
|
||||
}
|
||||
|
||||
/* Check module parameters */
|
||||
|
||||
@@ -50,7 +50,7 @@ sdhci: remove PYA0_INTR_BUG quirk. Add quirks to disable some of the higher SDR
|
||||
};
|
||||
|
||||
/*****************************************************************************\
|
||||
@@ -4605,6 +4615,15 @@ int sdhci_setup_host(struct sdhci_host *
|
||||
@@ -4611,6 +4621,15 @@ int sdhci_setup_host(struct sdhci_host *
|
||||
!(host->quirks2 & SDHCI_QUIRK2_BROKEN_DDR50))
|
||||
mmc->caps |= MMC_CAP_UHS_DDR50;
|
||||
|
||||
@@ -68,7 +68,7 @@ sdhci: remove PYA0_INTR_BUG quirk. Add quirks to disable some of the higher SDR
|
||||
host->flags |= SDHCI_SDR50_NEEDS_TUNING;
|
||||
--- a/drivers/mmc/host/sdhci.h
|
||||
+++ b/drivers/mmc/host/sdhci.h
|
||||
@@ -481,6 +481,11 @@ struct sdhci_host {
|
||||
@@ -482,6 +482,11 @@ struct sdhci_host {
|
||||
/* Issue CMD and DATA reset together */
|
||||
#define SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER (1<<19)
|
||||
|
||||
@@ -80,7 +80,7 @@ sdhci: remove PYA0_INTR_BUG quirk. Add quirks to disable some of the higher SDR
|
||||
int irq; /* Device IRQ */
|
||||
void __iomem *ioaddr; /* Mapped address */
|
||||
phys_addr_t mapbase; /* physical address base */
|
||||
@@ -663,6 +668,7 @@ struct sdhci_ops {
|
||||
@@ -664,6 +669,7 @@ struct sdhci_ops {
|
||||
void (*request_done)(struct sdhci_host *host,
|
||||
struct mmc_request *mrq);
|
||||
void (*dump_vendor_regs)(struct sdhci_host *host);
|
||||
|
||||
+2
-2
@@ -18,7 +18,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||||
|
||||
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
|
||||
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
|
||||
@@ -3625,6 +3625,7 @@ static int vc4_hdmi_runtime_suspend(stru
|
||||
@@ -3627,6 +3627,7 @@ static int vc4_hdmi_runtime_suspend(stru
|
||||
{
|
||||
struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
|
||||
|
||||
@@ -26,7 +26,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||||
clk_disable_unprepare(vc4_hdmi->hsm_rpm_clock);
|
||||
|
||||
return 0;
|
||||
@@ -3666,6 +3667,10 @@ static int vc4_hdmi_runtime_resume(struc
|
||||
@@ -3668,6 +3669,10 @@ static int vc4_hdmi_runtime_resume(struc
|
||||
goto err_disable_clk;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -73,7 +73,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||||
VC4_HD_VID_CTL_ENABLE |
|
||||
VC4_HD_VID_CTL_CLRRGB |
|
||||
VC4_HD_VID_CTL_UNDERFLOW_ENABLE |
|
||||
@@ -3796,7 +3808,9 @@ static int vc4_hdmi_bind(struct device *
|
||||
@@ -3798,7 +3810,9 @@ static int vc4_hdmi_bind(struct device *
|
||||
return ret;
|
||||
|
||||
if ((of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi0") ||
|
||||
@@ -84,7 +84,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
|
||||
HDMI_READ(HDMI_VID_CTL) & VC4_HD_VID_CTL_ENABLE) {
|
||||
clk_prepare_enable(vc4_hdmi->pixel_clock);
|
||||
clk_prepare_enable(vc4_hdmi->hsm_clock);
|
||||
@@ -3931,10 +3945,66 @@ static const struct vc4_hdmi_variant bcm
|
||||
@@ -3933,10 +3947,66 @@ static const struct vc4_hdmi_variant bcm
|
||||
.hp_detect = vc5_hdmi_hp_detect,
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
|
||||
|
||||
--- a/drivers/gpu/drm/panel/panel-simple.c
|
||||
+++ b/drivers/gpu/drm/panel/panel-simple.c
|
||||
@@ -3241,11 +3241,11 @@ static const struct panel_desc qishenglo
|
||||
@@ -3244,11 +3244,11 @@ static const struct panel_desc qishenglo
|
||||
};
|
||||
|
||||
static const struct drm_display_mode raspberrypi_7inch_mode = {
|
||||
|
||||
+2
-2
@@ -74,7 +74,7 @@ Signed-off-by: Dom Cobley <popcornmix@gmail.com>
|
||||
},
|
||||
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
|
||||
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
|
||||
@@ -3958,7 +3958,7 @@ static const struct vc4_hdmi_variant bcm
|
||||
@@ -3960,7 +3960,7 @@ static const struct vc4_hdmi_variant bcm
|
||||
PHY_LANE_2,
|
||||
PHY_LANE_CK,
|
||||
},
|
||||
@@ -83,7 +83,7 @@ Signed-off-by: Dom Cobley <popcornmix@gmail.com>
|
||||
.external_irq_controller = true,
|
||||
|
||||
.init_resources = vc5_hdmi_init_resources,
|
||||
@@ -3985,7 +3985,7 @@ static const struct vc4_hdmi_variant bcm
|
||||
@@ -3987,7 +3987,7 @@ static const struct vc4_hdmi_variant bcm
|
||||
PHY_LANE_2,
|
||||
PHY_LANE_CK,
|
||||
},
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
|
||||
if (!mmc_op_tuning(host->cmd->opcode))
|
||||
--- a/drivers/mmc/host/sdhci.h
|
||||
+++ b/drivers/mmc/host/sdhci.h
|
||||
@@ -486,6 +486,9 @@ struct sdhci_host {
|
||||
@@ -487,6 +487,9 @@ struct sdhci_host {
|
||||
#define SDHCI_QUIRK2_NO_SDR50 (1<<20)
|
||||
#define SDHCI_QUIRK2_NO_SDR104 (1<<21)
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ Signed-off-by: Timon Skerutsch <kernel@diodes-delight.com>
|
||||
|
||||
/**
|
||||
* struct panel_desc - Describes a simple panel.
|
||||
@@ -4662,6 +4663,9 @@ static const struct panel_desc_dsi osd10
|
||||
@@ -4665,6 +4666,9 @@ static const struct panel_desc_dsi osd10
|
||||
.lanes = 4,
|
||||
};
|
||||
|
||||
@@ -33,7 +33,7 @@ Signed-off-by: Timon Skerutsch <kernel@diodes-delight.com>
|
||||
static const struct of_device_id dsi_of_match[] = {
|
||||
{
|
||||
.compatible = "auo,b080uan01",
|
||||
@@ -4685,14 +4689,118 @@ static const struct of_device_id dsi_of_
|
||||
@@ -4688,14 +4692,118 @@ static const struct of_device_id dsi_of_
|
||||
.compatible = "osddisplays,osd101t2045-53ts",
|
||||
.data = &osd101t2045_53ts
|
||||
}, {
|
||||
@@ -152,7 +152,7 @@ Signed-off-by: Timon Skerutsch <kernel@diodes-delight.com>
|
||||
const struct of_device_id *id;
|
||||
int err;
|
||||
|
||||
@@ -4700,7 +4808,20 @@ static int panel_simple_dsi_probe(struct
|
||||
@@ -4703,7 +4811,20 @@ static int panel_simple_dsi_probe(struct
|
||||
if (!id)
|
||||
return -ENODEV;
|
||||
|
||||
|
||||
+1
-1
@@ -1815,7 +1815,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
}
|
||||
--- a/drivers/net/usb/smsc95xx.c
|
||||
+++ b/drivers/net/usb/smsc95xx.c
|
||||
@@ -901,11 +901,12 @@ static int smsc95xx_ioctl(struct net_dev
|
||||
@@ -903,11 +903,12 @@ static int smsc95xx_ioctl(struct net_dev
|
||||
|
||||
static void smsc95xx_init_mac_address(struct usbnet *dev)
|
||||
{
|
||||
|
||||
+3
-3
@@ -17,7 +17,7 @@ Link: https://lore.kernel.org/linux-mtd/20230308082021.870459-4-michael@walle.cc
|
||||
|
||||
--- a/drivers/mtd/mtdcore.c
|
||||
+++ b/drivers/mtd/mtdcore.c
|
||||
@@ -953,8 +953,8 @@ static int mtd_otp_nvmem_add(struct mtd_
|
||||
@@ -955,8 +955,8 @@ static int mtd_otp_nvmem_add(struct mtd_
|
||||
nvmem = mtd_otp_nvmem_register(mtd, "user-otp", size,
|
||||
mtd_nvmem_user_otp_reg_read);
|
||||
if (IS_ERR(nvmem)) {
|
||||
@@ -28,7 +28,7 @@ Link: https://lore.kernel.org/linux-mtd/20230308082021.870459-4-michael@walle.cc
|
||||
}
|
||||
mtd->otp_user_nvmem = nvmem;
|
||||
}
|
||||
@@ -971,7 +971,6 @@ static int mtd_otp_nvmem_add(struct mtd_
|
||||
@@ -973,7 +973,6 @@ static int mtd_otp_nvmem_add(struct mtd_
|
||||
nvmem = mtd_otp_nvmem_register(mtd, "factory-otp", size,
|
||||
mtd_nvmem_fact_otp_reg_read);
|
||||
if (IS_ERR(nvmem)) {
|
||||
@@ -36,7 +36,7 @@ Link: https://lore.kernel.org/linux-mtd/20230308082021.870459-4-michael@walle.cc
|
||||
err = PTR_ERR(nvmem);
|
||||
goto err;
|
||||
}
|
||||
@@ -983,7 +982,7 @@ static int mtd_otp_nvmem_add(struct mtd_
|
||||
@@ -985,7 +984,7 @@ static int mtd_otp_nvmem_add(struct mtd_
|
||||
|
||||
err:
|
||||
nvmem_unregister(mtd->otp_user_nvmem);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user