chore: add android feature and patch
This commit is contained in:
parent
b73382f60a
commit
d9cfdc3242
6 changed files with 67 additions and 17 deletions
|
@ -12,6 +12,8 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/metacubex/mihomo/component/resolver"
|
"github.com/metacubex/mihomo/component/resolver"
|
||||||
|
"github.com/metacubex/mihomo/constant/features"
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
type dialFunc func(ctx context.Context, network string, ips []netip.Addr, port string, opt *option) (net.Conn, error)
|
type dialFunc func(ctx context.Context, network string, ips []netip.Addr, port string, opt *option) (net.Conn, error)
|
||||||
|
@ -70,6 +72,10 @@ func DialContext(ctx context.Context, network, address string, options ...Option
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListenPacket(ctx context.Context, network, address string, options ...Option) (net.PacketConn, error) {
|
func ListenPacket(ctx context.Context, network, address string, options ...Option) (net.PacketConn, error) {
|
||||||
|
if slices.Contains(features.TAGS, "cmfa") {
|
||||||
|
return listenPacketHooked(ctx, network, address)
|
||||||
|
}
|
||||||
|
|
||||||
cfg := applyOptions(options...)
|
cfg := applyOptions(options...)
|
||||||
|
|
||||||
lc := &net.ListenConfig{}
|
lc := &net.ListenConfig{}
|
||||||
|
@ -114,6 +120,10 @@ func GetTcpConcurrent() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func dialContext(ctx context.Context, network string, destination netip.Addr, port string, opt *option) (net.Conn, error) {
|
func dialContext(ctx context.Context, network string, destination netip.Addr, port string, opt *option) (net.Conn, error) {
|
||||||
|
if slices.Contains(features.TAGS, "cmfa") {
|
||||||
|
return dialContextHooked(ctx, network, destination, port)
|
||||||
|
}
|
||||||
|
|
||||||
address := net.JoinHostPort(destination.String(), port)
|
address := net.JoinHostPort(destination.String(), port)
|
||||||
|
|
||||||
netDialer := opt.netDialer
|
netDialer := opt.netDialer
|
||||||
|
|
17
component/dialer/patch_common.go
Normal file
17
component/dialer/patch_common.go
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// +build !cmfa
|
||||||
|
|
||||||
|
package dialer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net"
|
||||||
|
"net/netip"
|
||||||
|
)
|
||||||
|
|
||||||
|
func dialContextHooked(ctx context.Context, network string, destination netip.Addr, port string) (net.Conn, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func listenPacketHooked(ctx context.Context, network, address string) (net.PacketConn, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
|
@ -13,6 +13,10 @@ import (
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
minInterval = time.Minute * 5
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
fileMode os.FileMode = 0o666
|
fileMode os.FileMode = 0o666
|
||||||
dirMode os.FileMode = 0o755
|
dirMode os.FileMode = 0o755
|
||||||
|
@ -24,8 +28,7 @@ type Fetcher[V any] struct {
|
||||||
resourceType string
|
resourceType string
|
||||||
name string
|
name string
|
||||||
vehicle types.Vehicle
|
vehicle types.Vehicle
|
||||||
UpdatedAt *time.Time
|
UpdatedAt time.Time
|
||||||
ticker *time.Ticker
|
|
||||||
done chan struct{}
|
done chan struct{}
|
||||||
hash [16]byte
|
hash [16]byte
|
||||||
parser Parser[V]
|
parser Parser[V]
|
||||||
|
@ -56,14 +59,15 @@ func (f *Fetcher[V]) Initial() (V, error) {
|
||||||
if stat, fErr := os.Stat(f.vehicle.Path()); fErr == nil {
|
if stat, fErr := os.Stat(f.vehicle.Path()); fErr == nil {
|
||||||
buf, err = os.ReadFile(f.vehicle.Path())
|
buf, err = os.ReadFile(f.vehicle.Path())
|
||||||
modTime := stat.ModTime()
|
modTime := stat.ModTime()
|
||||||
f.UpdatedAt = &modTime
|
f.UpdatedAt = modTime
|
||||||
isLocal = true
|
isLocal = true
|
||||||
if f.interval != 0 && modTime.Add(f.interval).Before(time.Now()) {
|
if f.interval != 0 && modTime.Add(f.interval).Before(time.Now()) {
|
||||||
log.Warnln("[Provider] %s not updated for %s, force update", f.Name(), time.Now().Sub(modTime))
|
log.Warnln("[Provider] %s not updated for a long time, force refresh", f.Name())
|
||||||
forceUpdate = true
|
forceUpdate = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buf, err = f.vehicle.Read()
|
buf, err = f.vehicle.Read()
|
||||||
|
f.UpdatedAt = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -113,7 +117,7 @@ func (f *Fetcher[V]) Initial() (V, error) {
|
||||||
f.hash = md5.Sum(buf)
|
f.hash = md5.Sum(buf)
|
||||||
|
|
||||||
// pull contents automatically
|
// pull contents automatically
|
||||||
if f.ticker != nil {
|
if f.interval > 0 {
|
||||||
go f.pullLoop()
|
go f.pullLoop()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +133,7 @@ func (f *Fetcher[V]) Update() (V, bool, error) {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
hash := md5.Sum(buf)
|
hash := md5.Sum(buf)
|
||||||
if bytes.Equal(f.hash[:], hash[:]) {
|
if bytes.Equal(f.hash[:], hash[:]) {
|
||||||
f.UpdatedAt = &now
|
f.UpdatedAt = now
|
||||||
_ = os.Chtimes(f.vehicle.Path(), now, now)
|
_ = os.Chtimes(f.vehicle.Path(), now, now)
|
||||||
return lo.Empty[V](), true, nil
|
return lo.Empty[V](), true, nil
|
||||||
}
|
}
|
||||||
|
@ -145,23 +149,31 @@ func (f *Fetcher[V]) Update() (V, bool, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f.UpdatedAt = &now
|
f.UpdatedAt = now
|
||||||
f.hash = hash
|
f.hash = hash
|
||||||
|
|
||||||
return contents, false, nil
|
return contents, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Fetcher[V]) Destroy() error {
|
func (f *Fetcher[V]) Destroy() error {
|
||||||
if f.ticker != nil {
|
if f.interval > 0 {
|
||||||
f.done <- struct{}{}
|
f.done <- struct{}{}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Fetcher[V]) pullLoop() {
|
func (f *Fetcher[V]) pullLoop() {
|
||||||
|
initialInterval := f.interval - time.Since(f.UpdatedAt)
|
||||||
|
if initialInterval < minInterval {
|
||||||
|
initialInterval = minInterval
|
||||||
|
}
|
||||||
|
|
||||||
|
timer := time.NewTimer(initialInterval)
|
||||||
|
defer timer.Stop()
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-f.ticker.C:
|
case <-timer.C:
|
||||||
|
timer.Reset(f.interval)
|
||||||
elm, same, err := f.Update()
|
elm, same, err := f.Update()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorln("[Provider] %s pull error: %s", f.Name(), err.Error())
|
log.Errorln("[Provider] %s pull error: %s", f.Name(), err.Error())
|
||||||
|
@ -178,7 +190,6 @@ func (f *Fetcher[V]) pullLoop() {
|
||||||
f.OnUpdate(elm)
|
f.OnUpdate(elm)
|
||||||
}
|
}
|
||||||
case <-f.done:
|
case <-f.done:
|
||||||
f.ticker.Stop()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,17 +208,12 @@ func safeWrite(path string, buf []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFetcher[V any](name string, interval time.Duration, vehicle types.Vehicle, parser Parser[V], onUpdate func(V)) *Fetcher[V] {
|
func NewFetcher[V any](name string, interval time.Duration, vehicle types.Vehicle, parser Parser[V], onUpdate func(V)) *Fetcher[V] {
|
||||||
var ticker *time.Ticker
|
|
||||||
if interval != 0 {
|
|
||||||
ticker = time.NewTicker(interval)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Fetcher[V]{
|
return &Fetcher[V]{
|
||||||
name: name,
|
name: name,
|
||||||
ticker: ticker,
|
|
||||||
vehicle: vehicle,
|
vehicle: vehicle,
|
||||||
parser: parser,
|
parser: parser,
|
||||||
done: make(chan struct{}, 1),
|
done: make(chan struct{}, 8),
|
||||||
OnUpdate: onUpdate,
|
OnUpdate: onUpdate,
|
||||||
interval: interval,
|
interval: interval,
|
||||||
}
|
}
|
||||||
|
|
6
constant/features/cmfa.go
Normal file
6
constant/features/cmfa.go
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
//go:build cmfa
|
||||||
|
package features
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
TAGS = append(TAGS, "cmfa")
|
||||||
|
}
|
|
@ -35,6 +35,8 @@ import (
|
||||||
"github.com/metacubex/mihomo/log"
|
"github.com/metacubex/mihomo/log"
|
||||||
"github.com/metacubex/mihomo/ntp"
|
"github.com/metacubex/mihomo/ntp"
|
||||||
"github.com/metacubex/mihomo/tunnel"
|
"github.com/metacubex/mihomo/tunnel"
|
||||||
|
"github.com/metacubex/mihomo/constant/features"
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
var mux sync.Mutex
|
var mux sync.Mutex
|
||||||
|
@ -170,7 +172,9 @@ func updateListeners(general *config.General, listeners map[string]C.InboundList
|
||||||
listener.ReCreateHTTP(general.Port, tunnel.Tunnel)
|
listener.ReCreateHTTP(general.Port, tunnel.Tunnel)
|
||||||
listener.ReCreateSocks(general.SocksPort, tunnel.Tunnel)
|
listener.ReCreateSocks(general.SocksPort, tunnel.Tunnel)
|
||||||
listener.ReCreateRedir(general.RedirPort, tunnel.Tunnel)
|
listener.ReCreateRedir(general.RedirPort, tunnel.Tunnel)
|
||||||
|
if !slices.Contains(features.TAGS, "cmfa") {
|
||||||
listener.ReCreateAutoRedir(general.EBpf.AutoRedir, tunnel.Tunnel)
|
listener.ReCreateAutoRedir(general.EBpf.AutoRedir, tunnel.Tunnel)
|
||||||
|
}
|
||||||
listener.ReCreateTProxy(general.TProxyPort, tunnel.Tunnel)
|
listener.ReCreateTProxy(general.TProxyPort, tunnel.Tunnel)
|
||||||
listener.ReCreateMixed(general.MixedPort, tunnel.Tunnel)
|
listener.ReCreateMixed(general.MixedPort, tunnel.Tunnel)
|
||||||
listener.ReCreateShadowSocks(general.ShadowSocksConfig, tunnel.Tunnel)
|
listener.ReCreateShadowSocks(general.ShadowSocksConfig, tunnel.Tunnel)
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"github.com/metacubex/mihomo/adapter/inbound"
|
"github.com/metacubex/mihomo/adapter/inbound"
|
||||||
"github.com/metacubex/mihomo/common/cache"
|
"github.com/metacubex/mihomo/common/cache"
|
||||||
C "github.com/metacubex/mihomo/constant"
|
C "github.com/metacubex/mihomo/constant"
|
||||||
|
"github.com/metacubex/mihomo/constant/features"
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Listener struct {
|
type Listener struct {
|
||||||
|
@ -65,6 +67,11 @@ func NewWithAuthenticate(addr string, tunnel C.Tunnel, authenticate bool, additi
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if slices.Contains(features.TAGS, "cmfa") {
|
||||||
|
if t, ok := conn.(*net.TCPConn); ok {
|
||||||
|
t.SetKeepAlive(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
go HandleConn(conn, tunnel, c, additions...)
|
go HandleConn(conn, tunnel, c, additions...)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
Loading…
Reference in a new issue