mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-21 01:20:07 +08:00
Merge branch 'Alpha' into Meta
This commit is contained in:
commit
e27d7c010f
8
.github/genReleaseNote.sh
vendored
8
.github/genReleaseNote.sh
vendored
@ -18,15 +18,15 @@ if [ -z "$version_range" ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "## What's Changed" > release.md
|
echo "## What's Changed" > release.md
|
||||||
git log --pretty=format:"* %s by @%an" --grep="^feat" -i $version_range | sort -f | uniq >> release.md
|
git log --pretty=format:"* %h %s by @%an" --grep="^feat" -i $version_range | sort -f | uniq >> release.md
|
||||||
echo "" >> release.md
|
echo "" >> release.md
|
||||||
|
|
||||||
echo "## BUG & Fix" >> release.md
|
echo "## BUG & Fix" >> release.md
|
||||||
git log --pretty=format:"* %s by @%an" --grep="^fix" -i $version_range | sort -f | uniq >> release.md
|
git log --pretty=format:"* %h %s by @%an" --grep="^fix" -i $version_range | sort -f | uniq >> release.md
|
||||||
echo "" >> release.md
|
echo "" >> release.md
|
||||||
|
|
||||||
echo "## Maintenance" >> release.md
|
echo "## Maintenance" >> release.md
|
||||||
git log --pretty=format:"* %s by @%an" --grep="^chore\|^docs\|^refactor" -i $version_range | sort -f | uniq >> release.md
|
git log --pretty=format:"* %h %s by @%an" --grep="^chore\|^docs\|^refactor" -i $version_range | sort -f | uniq >> release.md
|
||||||
echo "" >> release.md
|
echo "" >> release.md
|
||||||
|
|
||||||
echo "**Full Changelog**: https://github.com/MetaCubeX/Clash.Meta/compare/$version_range" >> release.md
|
echo "**Full Changelog**: https://github.com/MetaCubeX/mihomo/compare/$version_range" >> release.md
|
||||||
|
|||||||
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@ -141,6 +141,12 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
go test ./...
|
go test ./...
|
||||||
|
|
||||||
|
- name: Update UA
|
||||||
|
run: |
|
||||||
|
sudo apt-get install ca-certificates
|
||||||
|
sudo update-ca-certificates
|
||||||
|
cp -f /etc/ssl/certs/ca-certificates.crt component/ca/ca-certificates.crt
|
||||||
|
|
||||||
- name: Build core
|
- name: Build core
|
||||||
env:
|
env:
|
||||||
GOOS: ${{matrix.jobs.goos}}
|
GOOS: ${{matrix.jobs.goos}}
|
||||||
|
|||||||
@ -188,7 +188,8 @@ func NewWireGuard(option WireGuardOption) (*WireGuard, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(option.Peers) > 0 {
|
if len(option.Peers) > 0 {
|
||||||
for i, peer := range option.Peers {
|
for i := range option.Peers {
|
||||||
|
peer := &option.Peers[i] // we need modify option here
|
||||||
bytes, err := base64.StdEncoding.DecodeString(peer.PublicKey)
|
bytes, err := base64.StdEncoding.DecodeString(peer.PublicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, E.Cause(err, "decode public key for peer ", i)
|
return nil, E.Cause(err, "decode public key for peer ", i)
|
||||||
|
|||||||
@ -43,7 +43,7 @@ func (t *TypedValue[T]) Swap(new T) T {
|
|||||||
if old == nil {
|
if old == nil {
|
||||||
return DefaultValue[T]()
|
return DefaultValue[T]()
|
||||||
}
|
}
|
||||||
return old.(T)
|
return old.(tValue[T]).value
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TypedValue[T]) CompareAndSwap(old, new T) bool {
|
func (t *TypedValue[T]) CompareAndSwap(old, new T) bool {
|
||||||
|
|||||||
0
component/ca/ca-certificates.crt
Normal file
0
component/ca/ca-certificates.crt
Normal file
@ -5,10 +5,12 @@ import (
|
|||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
|
_ "embed"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
@ -18,6 +20,11 @@ var globalCertPool *x509.CertPool
|
|||||||
var mutex sync.RWMutex
|
var mutex sync.RWMutex
|
||||||
var errNotMatch = errors.New("certificate fingerprints do not match")
|
var errNotMatch = errors.New("certificate fingerprints do not match")
|
||||||
|
|
||||||
|
//go:embed ca-certificates.crt
|
||||||
|
var _CaCertificates []byte
|
||||||
|
var DisableEmbedCa, _ = strconv.ParseBool(os.Getenv("DISABLE_EMBED_CA"))
|
||||||
|
var DisableSystemCa, _ = strconv.ParseBool(os.Getenv("DISABLE_SYSTEM_CA"))
|
||||||
|
|
||||||
func AddCertificate(certificate string) error {
|
func AddCertificate(certificate string) error {
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
defer mutex.Unlock()
|
defer mutex.Unlock()
|
||||||
@ -34,13 +41,20 @@ func AddCertificate(certificate string) error {
|
|||||||
|
|
||||||
func initializeCertPool() {
|
func initializeCertPool() {
|
||||||
var err error
|
var err error
|
||||||
globalCertPool, err = x509.SystemCertPool()
|
if DisableSystemCa {
|
||||||
if err != nil {
|
|
||||||
globalCertPool = x509.NewCertPool()
|
globalCertPool = x509.NewCertPool()
|
||||||
|
} else {
|
||||||
|
globalCertPool, err = x509.SystemCertPool()
|
||||||
|
if err != nil {
|
||||||
|
globalCertPool = x509.NewCertPool()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for _, cert := range trustCerts {
|
for _, cert := range trustCerts {
|
||||||
globalCertPool.AddCert(cert)
|
globalCertPool.AddCert(cert)
|
||||||
}
|
}
|
||||||
|
if !DisableEmbedCa {
|
||||||
|
globalCertPool.AppendCertsFromPEM(_CaCertificates)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ResetCertificate() {
|
func ResetCertificate() {
|
||||||
|
|||||||
@ -213,11 +213,7 @@ func ResolveIP(ctx context.Context, host string) (netip.Addr, error) {
|
|||||||
// ResolveIPv4ProxyServerHost proxies server host only
|
// ResolveIPv4ProxyServerHost proxies server host only
|
||||||
func ResolveIPv4ProxyServerHost(ctx context.Context, host string) (netip.Addr, error) {
|
func ResolveIPv4ProxyServerHost(ctx context.Context, host string) (netip.Addr, error) {
|
||||||
if ProxyServerHostResolver != nil {
|
if ProxyServerHostResolver != nil {
|
||||||
if ip, err := ResolveIPv4WithResolver(ctx, host, ProxyServerHostResolver); err != nil {
|
return ResolveIPv4WithResolver(ctx, host, ProxyServerHostResolver)
|
||||||
return ResolveIPv4(ctx, host)
|
|
||||||
} else {
|
|
||||||
return ip, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ResolveIPv4(ctx, host)
|
return ResolveIPv4(ctx, host)
|
||||||
}
|
}
|
||||||
@ -225,11 +221,7 @@ func ResolveIPv4ProxyServerHost(ctx context.Context, host string) (netip.Addr, e
|
|||||||
// ResolveIPv6ProxyServerHost proxies server host only
|
// ResolveIPv6ProxyServerHost proxies server host only
|
||||||
func ResolveIPv6ProxyServerHost(ctx context.Context, host string) (netip.Addr, error) {
|
func ResolveIPv6ProxyServerHost(ctx context.Context, host string) (netip.Addr, error) {
|
||||||
if ProxyServerHostResolver != nil {
|
if ProxyServerHostResolver != nil {
|
||||||
if ip, err := ResolveIPv6WithResolver(ctx, host, ProxyServerHostResolver); err != nil {
|
return ResolveIPv6WithResolver(ctx, host, ProxyServerHostResolver)
|
||||||
return ResolveIPv6(ctx, host)
|
|
||||||
} else {
|
|
||||||
return ip, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ResolveIPv6(ctx, host)
|
return ResolveIPv6(ctx, host)
|
||||||
}
|
}
|
||||||
@ -237,11 +229,7 @@ func ResolveIPv6ProxyServerHost(ctx context.Context, host string) (netip.Addr, e
|
|||||||
// ResolveProxyServerHost proxies server host only
|
// ResolveProxyServerHost proxies server host only
|
||||||
func ResolveProxyServerHost(ctx context.Context, host string) (netip.Addr, error) {
|
func ResolveProxyServerHost(ctx context.Context, host string) (netip.Addr, error) {
|
||||||
if ProxyServerHostResolver != nil {
|
if ProxyServerHostResolver != nil {
|
||||||
if ip, err := ResolveIPWithResolver(ctx, host, ProxyServerHostResolver); err != nil {
|
return ResolveIPWithResolver(ctx, host, ProxyServerHostResolver)
|
||||||
return ResolveIP(ctx, host)
|
|
||||||
} else {
|
|
||||||
return ip, err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ResolveIP(ctx, host)
|
return ResolveIP(ctx, host)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -482,6 +482,11 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
|
|||||||
"www.msftconnecttest.com",
|
"www.msftconnecttest.com",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Experimental: Experimental{
|
||||||
|
// https://github.com/quic-go/quic-go/issues/4178
|
||||||
|
// Quic-go currently cannot automatically fall back on platforms that do not support ecn, so this feature is turned off by default.
|
||||||
|
QUICGoDisableECN: true,
|
||||||
|
},
|
||||||
Sniffer: RawSniffer{
|
Sniffer: RawSniffer{
|
||||||
Enable: false,
|
Enable: false,
|
||||||
Sniffing: []string{},
|
Sniffing: []string{},
|
||||||
@ -916,7 +921,7 @@ func parseRules(rulesConfig []string, proxies map[string]C.Proxy, subRules map[s
|
|||||||
|
|
||||||
l := len(rule)
|
l := len(rule)
|
||||||
|
|
||||||
if ruleName == "NOT" || ruleName == "OR" || ruleName == "AND" || ruleName == "SUB-RULE" {
|
if ruleName == "NOT" || ruleName == "OR" || ruleName == "AND" || ruleName == "SUB-RULE" || ruleName == "DOMAIN-REGEX" {
|
||||||
target = rule[l-1]
|
target = rule[l-1]
|
||||||
payload = strings.Join(rule[1:l-1], ",")
|
payload = strings.Join(rule[1:l-1], ",")
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -173,6 +173,7 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
|
|||||||
closed: false,
|
closed: false,
|
||||||
options: options,
|
options: options,
|
||||||
handler: handler,
|
handler: handler,
|
||||||
|
tunName: tunName,
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -279,7 +280,6 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
|
|||||||
|
|
||||||
func (l *Listener) FlushDefaultInterface() {
|
func (l *Listener) FlushDefaultInterface() {
|
||||||
if l.options.AutoDetectInterface {
|
if l.options.AutoDetectInterface {
|
||||||
targetInterface := dialer.DefaultInterface.Load()
|
|
||||||
for _, destination := range []netip.Addr{netip.IPv4Unspecified(), netip.IPv6Unspecified(), netip.MustParseAddr("1.1.1.1")} {
|
for _, destination := range []netip.Addr{netip.IPv4Unspecified(), netip.IPv6Unspecified(), netip.MustParseAddr("1.1.1.1")} {
|
||||||
autoDetectInterfaceName := l.defaultInterfaceMonitor.DefaultInterfaceName(destination)
|
autoDetectInterfaceName := l.defaultInterfaceMonitor.DefaultInterfaceName(destination)
|
||||||
if autoDetectInterfaceName == l.tunName {
|
if autoDetectInterfaceName == l.tunName {
|
||||||
@ -287,17 +287,16 @@ func (l *Listener) FlushDefaultInterface() {
|
|||||||
} else if autoDetectInterfaceName == "" || autoDetectInterfaceName == "<nil>" {
|
} else if autoDetectInterfaceName == "" || autoDetectInterfaceName == "<nil>" {
|
||||||
log.Warnln("[TUN] Auto detect interface by %s get empty name.", destination.String())
|
log.Warnln("[TUN] Auto detect interface by %s get empty name.", destination.String())
|
||||||
} else {
|
} else {
|
||||||
targetInterface = autoDetectInterfaceName
|
if old := dialer.DefaultInterface.Swap(autoDetectInterfaceName); old != autoDetectInterfaceName {
|
||||||
if old := dialer.DefaultInterface.Load(); old != targetInterface {
|
log.Warnln("[TUN] default interface changed by monitor, %s => %s", old, autoDetectInterfaceName)
|
||||||
log.Warnln("[TUN] default interface changed by monitor, %s => %s", old, targetInterface)
|
|
||||||
|
|
||||||
dialer.DefaultInterface.Store(targetInterface)
|
|
||||||
|
|
||||||
iface.FlushCache()
|
iface.FlushCache()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if dialer.DefaultInterface.CompareAndSwap("", "<invalid>") {
|
||||||
|
log.Warnln("[TUN] Auto detect interface failed, set '<invalid>' to DefaultInterface to avoid lookback")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,9 +2,10 @@ package provider
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
C "github.com/metacubex/mihomo/constant"
|
C "github.com/metacubex/mihomo/constant"
|
||||||
"github.com/metacubex/mihomo/log"
|
"github.com/metacubex/mihomo/log"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type classicalStrategy struct {
|
type classicalStrategy struct {
|
||||||
@ -76,7 +77,7 @@ func ruleParse(ruleRaw string) (string, string, []string) {
|
|||||||
} else if len(item) == 2 {
|
} else if len(item) == 2 {
|
||||||
return item[0], item[1], nil
|
return item[0], item[1], nil
|
||||||
} else if len(item) > 2 {
|
} else if len(item) > 2 {
|
||||||
if item[0] == "NOT" || item[0] == "OR" || item[0] == "AND" || item[0] == "SUB-RULE" {
|
if item[0] == "NOT" || item[0] == "OR" || item[0] == "AND" || item[0] == "SUB-RULE" || item[0] == "DOMAIN-REGEX" {
|
||||||
return item[0], strings.Join(item[1:len(item)], ","), nil
|
return item[0], strings.Join(item[1:len(item)], ","), nil
|
||||||
} else {
|
} else {
|
||||||
return item[0], item[1], item[2:]
|
return item[0], item[1], item[2:]
|
||||||
|
|||||||
@ -596,7 +596,7 @@ func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) {
|
|||||||
defer configMux.RUnlock()
|
defer configMux.RUnlock()
|
||||||
var (
|
var (
|
||||||
resolved bool
|
resolved bool
|
||||||
attemptProcessLookup = true
|
attemptProcessLookup = metadata.Type != C.INNER
|
||||||
)
|
)
|
||||||
|
|
||||||
if node, ok := resolver.DefaultHosts.Search(metadata.Host, false); ok {
|
if node, ok := resolver.DefaultHosts.Search(metadata.Host, false); ok {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user