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"
"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)
@ -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) {
if slices.Contains(features.TAGS, "cmfa") {
return listenPacketHooked(ctx, network, address)
}
cfg := applyOptions(options...)
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) {
if slices.Contains(features.TAGS, "cmfa") {
return dialContextHooked(ctx, network, destination, port)
}
address := net.JoinHostPort(destination.String(), port)
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"
)
const (
minInterval = time.Minute * 5
)
var (
fileMode os.FileMode = 0o666
dirMode os.FileMode = 0o755
@ -24,8 +28,7 @@ type Fetcher[V any] struct {
resourceType string
name string
vehicle types.Vehicle
UpdatedAt *time.Time
ticker *time.Ticker
UpdatedAt time.Time
done chan struct{}
hash [16]byte
parser Parser[V]
@ -56,14 +59,15 @@ func (f *Fetcher[V]) Initial() (V, error) {
if stat, fErr := os.Stat(f.vehicle.Path()); fErr == nil {
buf, err = os.ReadFile(f.vehicle.Path())
modTime := stat.ModTime()
f.UpdatedAt = &modTime
f.UpdatedAt = modTime
isLocal = true
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
}
} else {
buf, err = f.vehicle.Read()
f.UpdatedAt = time.Now()
}
if err != nil {
@ -113,7 +117,7 @@ func (f *Fetcher[V]) Initial() (V, error) {
f.hash = md5.Sum(buf)
// pull contents automatically
if f.ticker != nil {
if f.interval > 0 {
go f.pullLoop()
}
@ -129,7 +133,7 @@ func (f *Fetcher[V]) Update() (V, bool, error) {
now := time.Now()
hash := md5.Sum(buf)
if bytes.Equal(f.hash[:], hash[:]) {
f.UpdatedAt = &now
f.UpdatedAt = now
_ = os.Chtimes(f.vehicle.Path(), now, now)
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
return contents, false, nil
}
func (f *Fetcher[V]) Destroy() error {
if f.ticker != nil {
if f.interval > 0 {
f.done <- struct{}{}
}
return nil
}
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 {
select {
case <-f.ticker.C:
case <-timer.C:
timer.Reset(f.interval)
elm, same, err := f.Update()
if err != nil {
log.Errorln("[Provider] %s pull error: %s", f.Name(), err.Error())
@ -178,7 +190,6 @@ func (f *Fetcher[V]) pullLoop() {
f.OnUpdate(elm)
}
case <-f.done:
f.ticker.Stop()
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] {
var ticker *time.Ticker
if interval != 0 {
ticker = time.NewTicker(interval)
}
return &Fetcher[V]{
name: name,
ticker: ticker,
vehicle: vehicle,
parser: parser,
done: make(chan struct{}, 1),
done: make(chan struct{}, 8),
OnUpdate: onUpdate,
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/ntp"
"github.com/metacubex/mihomo/tunnel"
"github.com/metacubex/mihomo/constant/features"
"golang.org/x/exp/slices"
)
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.ReCreateSocks(general.SocksPort, tunnel.Tunnel)
listener.ReCreateRedir(general.RedirPort, tunnel.Tunnel)
listener.ReCreateAutoRedir(general.EBpf.AutoRedir, tunnel.Tunnel)
if !slices.Contains(features.TAGS, "cmfa") {
listener.ReCreateAutoRedir(general.EBpf.AutoRedir, tunnel.Tunnel)
}
listener.ReCreateTProxy(general.TProxyPort, tunnel.Tunnel)
listener.ReCreateMixed(general.MixedPort, 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/common/cache"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/constant/features"
"golang.org/x/exp/slices"
)
type Listener struct {
@ -65,6 +67,11 @@ func NewWithAuthenticate(addr string, tunnel C.Tunnel, authenticate bool, additi
}
continue
}
if slices.Contains(features.TAGS, "cmfa") {
if t, ok := conn.(*net.TCPConn); ok {
t.SetKeepAlive(false)
}
}
go HandleConn(conn, tunnel, c, additions...)
}
}()