chore: add android feature and patch

This commit is contained in:
Steve Johnson 2023-11-17 13:19:24 +08:00
parent b73382f60a
commit d9cfdc3242
6 changed files with 67 additions and 17 deletions

View file

@ -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

View 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
}

View file

@ -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,
} }

View file

@ -0,0 +1,6 @@
//go:build cmfa
package features
func init() {
TAGS = append(TAGS, "cmfa")
}

View file

@ -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)

View file

@ -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...)
} }
}() }()