feat: share more code from android branch
This commit is contained in:
parent
d28c3b50e3
commit
9e96d70840
17 changed files with 333 additions and 5 deletions
|
@ -12,6 +12,8 @@ func NewHTTP(target socks5.Addr, srcConn net.Conn, conn net.Conn, additions ...A
|
||||||
metadata := parseSocksAddr(target)
|
metadata := parseSocksAddr(target)
|
||||||
metadata.NetWork = C.TCP
|
metadata.NetWork = C.TCP
|
||||||
metadata.Type = C.HTTP
|
metadata.Type = C.HTTP
|
||||||
|
metadata.RawSrcAddr = srcConn.RemoteAddr()
|
||||||
|
metadata.RawDstAddr = srcConn.LocalAddr()
|
||||||
ApplyAdditions(metadata, WithSrcAddr(srcConn.RemoteAddr()), WithInAddr(conn.LocalAddr()))
|
ApplyAdditions(metadata, WithSrcAddr(srcConn.RemoteAddr()), WithInAddr(conn.LocalAddr()))
|
||||||
ApplyAdditions(metadata, additions...)
|
ApplyAdditions(metadata, additions...)
|
||||||
return conn, metadata
|
return conn, metadata
|
||||||
|
|
|
@ -10,6 +10,8 @@ func NewPacket(target socks5.Addr, packet C.UDPPacket, source C.Type, additions
|
||||||
metadata := parseSocksAddr(target)
|
metadata := parseSocksAddr(target)
|
||||||
metadata.NetWork = C.UDP
|
metadata.NetWork = C.UDP
|
||||||
metadata.Type = source
|
metadata.Type = source
|
||||||
|
metadata.RawSrcAddr = packet.LocalAddr()
|
||||||
|
metadata.RawDstAddr = metadata.UDPAddr()
|
||||||
ApplyAdditions(metadata, WithSrcAddr(packet.LocalAddr()))
|
ApplyAdditions(metadata, WithSrcAddr(packet.LocalAddr()))
|
||||||
if p, ok := packet.(C.UDPPacketInAddr); ok {
|
if p, ok := packet.(C.UDPPacketInAddr); ok {
|
||||||
ApplyAdditions(metadata, WithInAddr(p.InAddr()))
|
ApplyAdditions(metadata, WithInAddr(p.InAddr()))
|
||||||
|
|
64
adapter/outboundgroup/patch_android.go
Normal file
64
adapter/outboundgroup/patch_android.go
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
// +build android
|
||||||
|
|
||||||
|
package outboundgroup
|
||||||
|
|
||||||
|
import (
|
||||||
|
C "github.com/metacubex/mihomo/constant"
|
||||||
|
"github.com/metacubex/mihomo/constant/provider"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProxyGroup interface {
|
||||||
|
C.ProxyAdapter
|
||||||
|
|
||||||
|
Providers() []provider.ProxyProvider
|
||||||
|
Proxies() []C.Proxy
|
||||||
|
Now() string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Fallback) Providers() []provider.ProxyProvider {
|
||||||
|
return f.providers
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lb *LoadBalance) Providers() []provider.ProxyProvider {
|
||||||
|
return lb.providers
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Fallback) Proxies() []C.Proxy {
|
||||||
|
return f.GetProxies(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lb *LoadBalance) Proxies() []C.Proxy {
|
||||||
|
return lb.GetProxies(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lb *LoadBalance) Now() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Relay) Providers() []provider.ProxyProvider {
|
||||||
|
return r.providers
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Relay) Proxies() []C.Proxy {
|
||||||
|
return r.GetProxies(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Relay) Now() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Selector) Providers() []provider.ProxyProvider {
|
||||||
|
return s.providers
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Selector) Proxies() []C.Proxy {
|
||||||
|
return s.GetProxies(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *URLTest) Providers() []provider.ProxyProvider {
|
||||||
|
return u.providers
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *URLTest) Proxies() []C.Proxy {
|
||||||
|
return u.GetProxies(false)
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultURLTestTimeout = time.Second * 5
|
defaultURLTestTimeout = time.Second * 5
|
||||||
|
defaultURLTestURL = "https://www.gstatic.com/generate_204"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HealthCheckOption struct {
|
type HealthCheckOption struct {
|
||||||
|
@ -148,6 +149,10 @@ func (hc *HealthCheck) stop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hc *HealthCheck) check() {
|
func (hc *HealthCheck) check() {
|
||||||
|
if len(hc.proxies) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
_, _, _ = hc.singleDo.Do(func() (struct{}, error) {
|
_, _, _ = hc.singleDo.Do(func() (struct{}, error) {
|
||||||
id := utils.NewUUIDV4().String()
|
id := utils.NewUUIDV4().String()
|
||||||
log.Debugln("Start New Health Checking {%s}", id)
|
log.Debugln("Start New Health Checking {%s}", id)
|
||||||
|
@ -223,6 +228,7 @@ func NewHealthCheck(proxies []C.Proxy, url string, interval uint, lazy bool, exp
|
||||||
if len(url) == 0 {
|
if len(url) == 0 {
|
||||||
interval = 0
|
interval = 0
|
||||||
expectedStatus = nil
|
expectedStatus = nil
|
||||||
|
url = defaultURLTestURL
|
||||||
}
|
}
|
||||||
|
|
||||||
return &HealthCheck{
|
return &HealthCheck{
|
||||||
|
|
36
adapter/provider/patch_android.go
Normal file
36
adapter/provider/patch_android.go
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
// +build android
|
||||||
|
|
||||||
|
package provider
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
suspended bool
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdatableProvider interface {
|
||||||
|
UpdatedAt() time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pp *proxySetProvider) UpdatedAt() time.Time {
|
||||||
|
return pp.Fetcher.UpdatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pp *proxySetProvider) Close() error {
|
||||||
|
pp.healthCheck.close()
|
||||||
|
pp.Fetcher.Destroy()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cp *compatibleProvider) Close() error {
|
||||||
|
cp.healthCheck.close()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Suspend(s bool) {
|
||||||
|
suspended = s
|
||||||
|
}
|
39
component/dialer/patch_android.go
Normal file
39
component/dialer/patch_android.go
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// +build android
|
||||||
|
|
||||||
|
package dialer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net"
|
||||||
|
"net/netip"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SocketControl func(network, address string, conn syscall.RawConn) error
|
||||||
|
|
||||||
|
var DefaultSocketHook SocketControl
|
||||||
|
|
||||||
|
func dialContextHooked(ctx context.Context, network string, destination netip.Addr, port string) (net.Conn, error) {
|
||||||
|
dialer := &net.Dialer{
|
||||||
|
Control: DefaultSocketHook,
|
||||||
|
}
|
||||||
|
|
||||||
|
conn, err := dialer.DialContext(ctx, network, net.JoinHostPort(destination.String(), port))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if t, ok := conn.(*net.TCPConn); ok {
|
||||||
|
t.SetKeepAlive(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
return conn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func listenPacketHooked(ctx context.Context, network, address string) (net.PacketConn, error) {
|
||||||
|
lc := &net.ListenConfig{
|
||||||
|
Control: DefaultSocketHook,
|
||||||
|
}
|
||||||
|
|
||||||
|
return lc.ListenPacket(ctx, network, address)
|
||||||
|
}
|
18
component/mmdb/patch_android.go
Normal file
18
component/mmdb/patch_android.go
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// +build android
|
||||||
|
|
||||||
|
package mmdb
|
||||||
|
|
||||||
|
import "github.com/oschwald/maxminddb-golang"
|
||||||
|
|
||||||
|
func InstallOverride(override *maxminddb.Reader) {
|
||||||
|
newReader := Reader{Reader: override}
|
||||||
|
switch override.Metadata.DatabaseType {
|
||||||
|
case "sing-geoip":
|
||||||
|
reader.databaseType = typeSing
|
||||||
|
case "Meta-geoip0":
|
||||||
|
reader.databaseType = typeMetaV0
|
||||||
|
default:
|
||||||
|
reader.databaseType = typeMaxmind
|
||||||
|
}
|
||||||
|
reader = newReader
|
||||||
|
}
|
16
component/process/patch_android.go
Normal file
16
component/process/patch_android.go
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// +build android
|
||||||
|
|
||||||
|
package process
|
||||||
|
|
||||||
|
import "github.com/metacubex/mihomo/constant"
|
||||||
|
|
||||||
|
type PackageNameResolver func(metadata *constant.Metadata) (string, error)
|
||||||
|
|
||||||
|
var DefaultPackageNameResolver PackageNameResolver
|
||||||
|
|
||||||
|
func FindPackageName(metadata *constant.Metadata) (string, error) {
|
||||||
|
if resolver := DefaultPackageNameResolver; resolver != nil {
|
||||||
|
return resolver(metadata)
|
||||||
|
}
|
||||||
|
return "", ErrPlatformNotSupport
|
||||||
|
}
|
|
@ -212,11 +212,16 @@ type RawDNS struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type RawFallbackFilter struct {
|
type RawFallbackFilter struct {
|
||||||
GeoIP bool `yaml:"geoip"`
|
GeoIP bool `yaml:"geoip" json:"geoip"`
|
||||||
GeoIPCode string `yaml:"geoip-code"`
|
GeoIPCode string `yaml:"geoip-code" json:"geoip-code"`
|
||||||
IPCIDR []string `yaml:"ipcidr"`
|
IPCIDR []string `yaml:"ipcidr" json:"ipcidr"`
|
||||||
Domain []string `yaml:"domain"`
|
Domain []string `yaml:"domain" json:"domain"`
|
||||||
GeoSite []string `yaml:"geosite"`
|
GeoSite []string `yaml:"geosite" json:"geosite"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RawClashForAndroid struct {
|
||||||
|
AppendSystemDNS bool `yaml:"append-system-dns" json:"append-system-dns"`
|
||||||
|
UiSubtitlePattern string `yaml:"ui-subtitle-pattern" json:"ui-subtitle-pattern"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RawTun struct {
|
type RawTun struct {
|
||||||
|
@ -317,6 +322,8 @@ type RawConfig struct {
|
||||||
SubRules map[string][]string `yaml:"sub-rules"`
|
SubRules map[string][]string `yaml:"sub-rules"`
|
||||||
RawTLS TLS `yaml:"tls"`
|
RawTLS TLS `yaml:"tls"`
|
||||||
Listeners []map[string]any `yaml:"listeners"`
|
Listeners []map[string]any `yaml:"listeners"`
|
||||||
|
|
||||||
|
ClashForAndroid RawClashForAndroid `yaml:"clash-for-android"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type GeoXUrl struct {
|
type GeoXUrl struct {
|
||||||
|
|
|
@ -147,6 +147,9 @@ type Metadata struct {
|
||||||
SpecialProxy string `json:"specialProxy"`
|
SpecialProxy string `json:"specialProxy"`
|
||||||
SpecialRules string `json:"specialRules"`
|
SpecialRules string `json:"specialRules"`
|
||||||
RemoteDst string `json:"remoteDestination"`
|
RemoteDst string `json:"remoteDestination"`
|
||||||
|
|
||||||
|
RawSrcAddr net.Addr `json:"-"`
|
||||||
|
RawDstAddr net.Addr `json:"-"`
|
||||||
// Only domain rule
|
// Only domain rule
|
||||||
SniffHost string `json:"sniffHost"`
|
SniffHost string `json:"sniffHost"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// +build !android
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
7
dns/patch_!android.go
Normal file
7
dns/patch_!android.go
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// +build !android
|
||||||
|
|
||||||
|
package dns
|
||||||
|
|
||||||
|
func UpdateIsolateHandler(resolver *Resolver, mapper *ResolverEnhancer) {
|
||||||
|
return
|
||||||
|
}
|
81
dns/patch_android.go
Normal file
81
dns/patch_android.go
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
// +build android
|
||||||
|
|
||||||
|
package dns
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
D "github.com/miekg/dns"
|
||||||
|
|
||||||
|
"github.com/metacubex/mihomo/common/cache"
|
||||||
|
"github.com/metacubex/mihomo/component/dhcp"
|
||||||
|
"github.com/metacubex/mihomo/component/resolver"
|
||||||
|
)
|
||||||
|
|
||||||
|
const SystemDNSPlaceholder = "system"
|
||||||
|
|
||||||
|
var systemResolver *Resolver
|
||||||
|
var isolateHandler handler
|
||||||
|
|
||||||
|
var _ dnsClient = (*dhcpClient)(nil)
|
||||||
|
|
||||||
|
type dhcpClient struct {
|
||||||
|
enable bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dhcpClient) Address() string {
|
||||||
|
return SystemDNSPlaceholder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dhcpClient) Exchange(m *D.Msg) (msg *D.Msg, err error) {
|
||||||
|
return d.ExchangeContext(context.Background(), m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *dhcpClient) ExchangeContext(ctx context.Context, m *D.Msg) (msg *D.Msg, err error) {
|
||||||
|
if s := systemResolver; s != nil {
|
||||||
|
return s.ExchangeContext(ctx, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, dhcp.ErrNotFound
|
||||||
|
}
|
||||||
|
|
||||||
|
func ServeDNSWithDefaultServer(msg *D.Msg) (*D.Msg, error) {
|
||||||
|
if h := isolateHandler; h != nil {
|
||||||
|
return handlerWithContext(context.Background(), h, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, D.ErrTime
|
||||||
|
}
|
||||||
|
|
||||||
|
func FlushCacheWithDefaultResolver() {
|
||||||
|
if r := resolver.DefaultResolver; r != nil {
|
||||||
|
r.(*Resolver).lruCache = cache.New[string, *D.Msg](cache.WithSize[string, *D.Msg](4096), cache.WithStale[string, *D.Msg](true))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateSystemDNS(addr []string) {
|
||||||
|
if len(addr) == 0 {
|
||||||
|
systemResolver = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ns := make([]NameServer, 0, len(addr))
|
||||||
|
for _, d := range addr {
|
||||||
|
ns = append(ns, NameServer{Addr: d})
|
||||||
|
}
|
||||||
|
|
||||||
|
systemResolver = NewResolver(Config{Main: ns})
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateIsolateHandler(resolver *Resolver, mapper *ResolverEnhancer) {
|
||||||
|
if resolver == nil {
|
||||||
|
isolateHandler = nil
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
isolateHandler = NewHandler(resolver, mapper)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDHCPClient(ifaceName string) *dhcpClient {
|
||||||
|
return &dhcpClient{enable: ifaceName == SystemDNSPlaceholder}
|
||||||
|
}
|
|
@ -49,6 +49,8 @@ func (s *Server) SetHandler(handler handler) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReCreateServer(addr string, resolver *Resolver, mapper *ResolverEnhancer) {
|
func ReCreateServer(addr string, resolver *Resolver, mapper *ResolverEnhancer) {
|
||||||
|
UpdateIsolateHandler(resolver, mapper)
|
||||||
|
|
||||||
if addr == address && resolver != nil {
|
if addr == address && resolver != nil {
|
||||||
handler := NewHandler(resolver, mapper)
|
handler := NewHandler(resolver, mapper)
|
||||||
server.SetHandler(handler)
|
server.SetHandler(handler)
|
||||||
|
|
9
listener/http/patch_android.go
Normal file
9
listener/http/patch_android.go
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// +build android
|
||||||
|
|
||||||
|
package http
|
||||||
|
|
||||||
|
import "net"
|
||||||
|
|
||||||
|
func (l *Listener) Listener() net.Listener {
|
||||||
|
return l.listener
|
||||||
|
}
|
27
rules/provider/patch_android.go
Normal file
27
rules/provider/patch_android.go
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// +build android
|
||||||
|
|
||||||
|
package provider
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
var (
|
||||||
|
suspended bool
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdatableProvider interface {
|
||||||
|
UpdatedAt() time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *ruleSetProvider) UpdatedAt() time.Time {
|
||||||
|
return f.Fetcher.UpdatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rp *ruleSetProvider) Close() error {
|
||||||
|
rp.Fetcher.Destroy()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Suspend(s bool) {
|
||||||
|
suspended = s
|
||||||
|
}
|
7
tunnel/statistic/patch_android.go
Normal file
7
tunnel/statistic/patch_android.go
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// +build android
|
||||||
|
|
||||||
|
package statistic
|
||||||
|
|
||||||
|
func (m *Manager) Total() (up, down int64) {
|
||||||
|
return m.uploadTotal.Load(), m.downloadTotal.Load()
|
||||||
|
}
|
Loading…
Reference in a new issue