Files
FlClash/core/common.go
T

284 lines
7.3 KiB
Go
Raw Normal View History

2024-04-30 23:38:49 +08:00
package main
import (
2025-05-02 02:24:12 +08:00
b "bytes"
2024-08-04 08:21:14 +08:00
"context"
2025-05-02 02:24:12 +08:00
"encoding/json"
2024-08-05 19:25:35 +08:00
"errors"
2026-02-02 10:14:13 +08:00
"fmt"
2026-05-27 15:16:51 +08:00
"os"
"path/filepath"
"runtime"
"sync"
2024-06-13 23:43:42 +08:00
"github.com/metacubex/mihomo/adapter"
2024-04-30 23:38:49 +08:00
"github.com/metacubex/mihomo/adapter/inbound"
2024-07-02 08:08:31 +08:00
"github.com/metacubex/mihomo/adapter/outboundgroup"
2024-08-04 08:21:14 +08:00
"github.com/metacubex/mihomo/adapter/provider"
"github.com/metacubex/mihomo/common/batch"
2024-04-30 23:38:49 +08:00
"github.com/metacubex/mihomo/component/dialer"
"github.com/metacubex/mihomo/component/resolver"
2026-05-27 15:16:51 +08:00
"github.com/metacubex/mihomo/component/updater"
2024-04-30 23:38:49 +08:00
"github.com/metacubex/mihomo/config"
2024-06-13 23:43:42 +08:00
"github.com/metacubex/mihomo/constant"
2024-12-03 21:47:12 +08:00
"github.com/metacubex/mihomo/constant/features"
2024-08-04 08:21:14 +08:00
cp "github.com/metacubex/mihomo/constant/provider"
2024-06-12 19:28:58 +08:00
"github.com/metacubex/mihomo/hub"
2025-10-14 15:13:52 +08:00
"github.com/metacubex/mihomo/hub/executor"
2024-12-03 21:47:12 +08:00
"github.com/metacubex/mihomo/hub/route"
2024-04-30 23:38:49 +08:00
"github.com/metacubex/mihomo/listener"
"github.com/metacubex/mihomo/log"
2024-08-04 08:21:14 +08:00
rp "github.com/metacubex/mihomo/rules/provider"
2024-04-30 23:38:49 +08:00
"github.com/metacubex/mihomo/tunnel"
)
2024-12-03 21:47:12 +08:00
var (
2025-05-02 02:24:12 +08:00
currentConfig *config.Config
version = 0
isRunning = false
runLock sync.Mutex
mBatch, _ = batch.New[bool](context.Background(), batch.WithConcurrencyNum[bool](50))
2026-02-02 10:14:13 +08:00
debugError = false
2024-12-03 21:47:12 +08:00
)
2024-06-03 18:02:05 +08:00
2024-08-05 19:25:35 +08:00
func getExternalProvidersRaw() map[string]cp.Provider {
eps := make(map[string]cp.Provider)
2024-08-04 08:21:14 +08:00
for n, p := range tunnel.Providers() {
if p.VehicleType() != cp.Compatible {
2024-08-05 19:25:35 +08:00
eps[n] = p
2024-08-04 08:21:14 +08:00
}
}
for n, p := range tunnel.RuleProviders() {
if p.VehicleType() != cp.Compatible {
2024-08-05 19:25:35 +08:00
eps[n] = p
}
}
return eps
}
func toExternalProvider(p cp.Provider) (*ExternalProvider, error) {
switch p.(type) {
case *provider.ProxySetProvider:
psp := p.(*provider.ProxySetProvider)
return &ExternalProvider{
2024-11-09 20:17:57 +08:00
Name: psp.Name(),
Type: psp.Type().String(),
VehicleType: psp.VehicleType().String(),
Count: psp.Count(),
UpdateAt: psp.UpdatedAt(),
Path: psp.Vehicle().Path(),
SubscriptionInfo: psp.GetSubscriptionInfo(),
2024-08-05 19:25:35 +08:00
}, nil
case *rp.RuleSetProvider:
rsp := p.(*rp.RuleSetProvider)
return &ExternalProvider{
Name: rsp.Name(),
Type: rsp.Type().String(),
VehicleType: rsp.VehicleType().String(),
Count: rsp.Count(),
2024-09-05 08:59:45 +08:00
UpdateAt: rsp.UpdatedAt(),
2024-11-09 20:17:57 +08:00
Path: rsp.Vehicle().Path(),
2024-08-05 19:25:35 +08:00
}, nil
default:
return nil, errors.New("not external provider")
}
}
func sideUpdateExternalProvider(p cp.Provider, bytes []byte) error {
switch p.(type) {
case *provider.ProxySetProvider:
psp := p.(*provider.ProxySetProvider)
2024-10-14 10:03:23 +08:00
_, _, err := psp.SideUpdate(bytes)
if err == nil {
return err
2024-08-05 19:25:35 +08:00
}
return nil
case rp.RuleSetProvider:
rsp := p.(*rp.RuleSetProvider)
2024-10-14 10:03:23 +08:00
_, _, err := rsp.SideUpdate(bytes)
if err == nil {
return err
2024-04-30 23:38:49 +08:00
}
2024-08-05 19:25:35 +08:00
return nil
default:
return errors.New("not external provider")
2024-04-30 23:38:49 +08:00
}
}
2025-05-02 02:24:12 +08:00
func updateListeners() {
2024-08-26 20:44:30 +08:00
if !isRunning {
return
}
2025-05-02 02:24:12 +08:00
if currentConfig == nil {
return
2024-12-03 21:47:12 +08:00
}
2025-05-02 02:24:12 +08:00
listeners := currentConfig.Listeners
general := currentConfig.General
2024-08-15 16:18:00 +08:00
listener.PatchInboundListeners(listeners, tunnel.Tunnel, true)
2025-07-31 17:09:18 +08:00
allowLan := general.AllowLan
listener.SetAllowLan(allowLan)
2024-08-15 16:18:00 +08:00
inbound.SetSkipAuthPrefixes(general.SkipAuthPrefixes)
inbound.SetAllowedIPs(general.LanAllowedIPs)
inbound.SetDisAllowedIPs(general.LanDisAllowedIPs)
2025-07-31 17:09:18 +08:00
bindAddress := general.BindAddress
listener.SetBindAddress(bindAddress)
2024-04-30 23:38:49 +08:00
listener.ReCreateHTTP(general.Port, tunnel.Tunnel)
listener.ReCreateSocks(general.SocksPort, tunnel.Tunnel)
listener.ReCreateRedir(general.RedirPort, tunnel.Tunnel)
listener.ReCreateTProxy(general.TProxyPort, tunnel.Tunnel)
listener.ReCreateMixed(general.MixedPort, tunnel.Tunnel)
listener.ReCreateShadowSocks(general.ShadowSocksConfig, tunnel.Tunnel)
listener.ReCreateVmess(general.VmessConfig, tunnel.Tunnel)
listener.ReCreateTuic(general.TuicServer, tunnel.Tunnel)
2024-09-26 14:29:04 +08:00
if !features.Android {
listener.ReCreateTun(general.Tun, tunnel.Tunnel)
}
2024-08-15 16:18:00 +08:00
}
func stopListeners() {
listener.StopListener()
}
2025-05-02 02:24:12 +08:00
func patchSelectGroup(mapping map[string]string) {
2026-02-02 10:14:13 +08:00
for name, proxy := range tunnel.AllProxies() {
2024-07-02 08:08:31 +08:00
outbound, ok := proxy.(*adapter.Proxy)
if !ok {
continue
}
selector, ok := outbound.ProxyAdapter.(outboundgroup.SelectAble)
if !ok {
continue
}
selected, exist := mapping[name]
if !exist {
continue
}
selector.ForceSet(selected)
}
}
2025-05-02 02:24:12 +08:00
func defaultSetupParams() *SetupParams {
return &SetupParams{
TestURL: "https://www.gstatic.com/generate_204",
SelectedMap: map[string]string{},
}
}
func readFile(path string) ([]byte, error) {
if _, err := os.Stat(path); os.IsNotExist(err) {
return nil, err
}
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
return data, err
}
func updateConfig(params *UpdateParams) {
runLock.Lock()
defer runLock.Unlock()
general := currentConfig.General
if params.MixedPort != nil {
general.MixedPort = *params.MixedPort
}
if params.Sniffing != nil {
general.Sniffing = *params.Sniffing
tunnel.SetSniffing(general.Sniffing)
}
if params.FindProcessMode != nil {
general.FindProcessMode = *params.FindProcessMode
tunnel.SetFindProcessMode(general.FindProcessMode)
}
if params.TCPConcurrent != nil {
general.TCPConcurrent = *params.TCPConcurrent
dialer.SetTcpConcurrent(general.TCPConcurrent)
}
if params.Interface != nil {
general.Interface = *params.Interface
dialer.DefaultInterface.Store(general.Interface)
}
if params.UnifiedDelay != nil {
general.UnifiedDelay = *params.UnifiedDelay
adapter.UnifiedDelay.Store(general.UnifiedDelay)
}
if params.Mode != nil {
general.Mode = *params.Mode
tunnel.SetMode(general.Mode)
}
if params.LogLevel != nil {
general.LogLevel = *params.LogLevel
log.SetLevel(general.LogLevel)
}
if params.IPv6 != nil {
general.IPv6 = *params.IPv6
resolver.DisableIPv6 = !general.IPv6
}
if params.ExternalController != nil {
currentConfig.Controller.ExternalController = *params.ExternalController
route.ReCreateServer(&route.Config{
Addr: currentConfig.Controller.ExternalController,
})
}
if params.Tun != nil {
general.Tun.Enable = params.Tun.Enable
general.Tun.AutoRoute = *params.Tun.AutoRoute
general.Tun.Device = *params.Tun.Device
general.Tun.RouteAddress = *params.Tun.RouteAddress
general.Tun.DNSHijack = *params.Tun.DNSHijack
general.Tun.Stack = *params.Tun.Stack
}
2026-05-27 15:16:51 +08:00
if params.GeoAutoUpdate != nil {
updater.SetGeoAutoUpdate(*params.GeoAutoUpdate)
}
if params.GeoUpdateInterval != nil {
updater.SetGeoUpdateInterval(*params.GeoUpdateInterval)
}
2025-05-02 02:24:12 +08:00
updateListeners()
2026-05-27 15:16:51 +08:00
if updater.GeoAutoUpdate() {
updater.RegisterGeoUpdaterWithCancel()
}
2025-05-02 02:24:12 +08:00
}
2025-12-16 11:23:09 +08:00
func applyConfig(params *SetupParams) error {
runtime.GC()
2024-12-03 21:47:12 +08:00
runLock.Lock()
defer runLock.Unlock()
var err error
2025-05-02 02:24:12 +08:00
constant.DefaultTestURL = params.TestURL
2025-10-14 15:13:52 +08:00
currentConfig, err = executor.ParseWithPath(filepath.Join(constant.Path.HomeDir(), "config.yaml"))
2024-04-30 23:38:49 +08:00
if err != nil {
2024-12-03 21:47:12 +08:00
currentConfig, _ = config.ParseRawConfig(config.DefaultRawConfig())
2024-04-30 23:38:49 +08:00
}
2025-05-02 02:24:12 +08:00
hub.ApplyConfig(currentConfig)
patchSelectGroup(params.SelectedMap)
updateListeners()
2026-05-27 15:16:51 +08:00
if updater.GeoAutoUpdate() {
updater.RegisterGeoUpdaterWithCancel()
}
2025-05-02 02:24:12 +08:00
return err
}
func UnmarshalJson(data []byte, v any) error {
decoder := json.NewDecoder(b.NewReader(data))
decoder.UseNumber()
err := decoder.Decode(v)
2024-07-26 08:05:22 +08:00
return err
2024-04-30 23:38:49 +08:00
}
2026-02-02 10:14:13 +08:00
func logError(format string, args ...interface{}) {
log.Errorln(format, args...)
if debugError {
fmt.Fprintf(os.Stderr, "[ERROR] "+format+"\n", args...)
}
}