Chore: merge branch 'with-tun' into plus-pro

This commit is contained in:
yaling888
2022-04-10 05:57:06 +08:00
66 changed files with 2807 additions and 334 deletions

View File

@@ -0,0 +1,54 @@
package statistic
import (
"errors"
"github.com/Dreamacro/clash/common/snifer/tls"
"github.com/Dreamacro/clash/component/resolver"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/log"
"go.uber.org/atomic"
)
type sniffing struct {
C.Conn
metadata *C.Metadata
totalWrite *atomic.Uint64
}
func (r *sniffing) Read(b []byte) (int, error) {
return r.Conn.Read(b)
}
func (r *sniffing) Write(b []byte) (int, error) {
if r.totalWrite.Load() < 128 && r.metadata.Host == "" && (r.metadata.DstPort == "443" || r.metadata.DstPort == "8443" || r.metadata.DstPort == "993" || r.metadata.DstPort == "465" || r.metadata.DstPort == "995") {
header, err := tls.SniffTLS(b)
if err != nil {
// log.Errorln("Expect no error but actually %s %s:%s:%s", err.Error(), tt.Metadata.Host, tt.Metadata.DstIP.String(), tt.Metadata.DstPort)
} else {
resolver.InsertHostByIP(r.metadata.DstIP, header.Domain())
log.Warnln("use sni update host: %s ip: %s", header.Domain(), r.metadata.DstIP.String())
r.Conn.Close()
return 0, errors.New("sni update, break current link to avoid leaks")
}
}
n, err := r.Conn.Write(b)
r.totalWrite.Add(uint64(n))
return n, err
}
func (r *sniffing) Close() error {
return r.Conn.Close()
}
func NewSniffing(conn C.Conn, metadata *C.Metadata) C.Conn {
return &sniffing{
Conn: conn,
metadata: metadata,
totalWrite: atomic.NewUint64(0),
}
}

View File

@@ -57,7 +57,7 @@ func (tt *tcpTracker) Close() error {
return tt.Conn.Close()
}
func NewTCPTracker(conn C.Conn, manager *Manager, metadata *C.Metadata, rule C.Rule) *tcpTracker {
func NewTCPTracker(conn C.Conn, manager *Manager, metadata *C.Metadata, rule C.Rule) C.Conn {
uuid, _ := uuid.NewV4()
t := &tcpTracker{
@@ -80,7 +80,7 @@ func NewTCPTracker(conn C.Conn, manager *Manager, metadata *C.Metadata, rule C.R
}
manager.Join(t)
return t
return NewSniffing(t, metadata)
}
type udpTracker struct {

View File

@@ -27,6 +27,7 @@ var (
udpQueue = make(chan *inbound.PacketAdapter, 200)
natTable = nat.New()
rules []C.Rule
rewrites C.RewriteRule
proxies = make(map[string]C.Proxy)
providers map[string]provider.ProxyProvider
configMux sync.RWMutex
@@ -36,6 +37,9 @@ var (
// default timeout for UDP session
udpTimeout = 60 * time.Second
// MitmOutbound mitm proxy adapter
MitmOutbound C.ProxyAdapter
)
func init() {
@@ -92,6 +96,18 @@ func SetMode(m TunnelMode) {
mode = m
}
// Rewrites return all rewrites
func Rewrites() C.RewriteRule {
return rewrites
}
// UpdateRewrites handle update rewrites
func UpdateRewrites(newRewrites C.RewriteRule) {
configMux.Lock()
rewrites = newRewrites
configMux.Unlock()
}
// processUDP starts a loop to handle udp packet
func processUDP() {
queue := udpQueue
@@ -143,7 +159,7 @@ func preHandleMetadata(metadata *C.Metadata) error {
metadata.DNSMode = C.DNSFakeIP
} else if node := resolver.DefaultHosts.Search(host); node != nil {
// redir-host should lookup the hosts
metadata.DstIP = node.Data.(net.IP)
metadata.DstIP = node.Data.AsSlice()
}
} else if resolver.IsFakeIP(metadata.DstIP) {
return fmt.Errorf("fake DNS record %s missing", metadata.DstIP)
@@ -286,14 +302,24 @@ func handleTCPConn(connCtx C.ConnContext) {
return
}
ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTCPTimeout)
defer cancel()
if MitmOutbound != nil && metadata.Type != C.MITM {
if remoteConn, err1 := MitmOutbound.DialContext(ctx, metadata); err1 == nil {
remoteConn = statistic.NewSniffing(remoteConn, metadata)
defer remoteConn.Close()
handleSocket(connCtx, remoteConn)
return
}
}
proxy, rule, err := resolveMetadata(connCtx, metadata)
if err != nil {
log.Warnln("[Metadata] parse failed: %s", err.Error())
return
}
ctx, cancel := context.WithTimeout(context.Background(), C.DefaultTCPTimeout)
defer cancel()
remoteConn, err := proxy.DialContext(ctx, metadata.Pure())
if err != nil {
if rule == nil {
@@ -333,8 +359,7 @@ func match(metadata *C.Metadata) (C.Proxy, C.Rule, error) {
var resolved bool
if node := resolver.DefaultHosts.Search(metadata.Host); node != nil {
ip := node.Data.(net.IP)
metadata.DstIP = ip
metadata.DstIP = node.Data.AsSlice()
resolved = true
}
@@ -388,8 +413,7 @@ func matchScript(metadata *C.Metadata) (C.Proxy, error) {
defer configMux.RUnlock()
if node := resolver.DefaultHosts.Search(metadata.Host); node != nil {
ip := node.Data.(net.IP)
metadata.DstIP = ip
metadata.DstIP = node.Data.AsSlice()
}
adapter, err := S.CallPyMainFunction(metadata)