chore: add force-dns-mapping in sniffer

This commit is contained in:
wwqgtxx 2022-10-14 07:46:33 +08:00
parent b9ef713dd7
commit 0da49bd92b
6 changed files with 54 additions and 49 deletions

View file

@ -3,19 +3,18 @@ package sniffer
import (
"errors"
"fmt"
"github.com/Dreamacro/clash/common/cache"
"github.com/Dreamacro/clash/constant/sniffer"
"net"
"net/netip"
"strconv"
"sync"
"time"
"github.com/Dreamacro/clash/component/trie"
CN "github.com/Dreamacro/clash/common/net"
"github.com/Dreamacro/clash/common/cache"
N "github.com/Dreamacro/clash/common/net"
"github.com/Dreamacro/clash/common/utils"
"github.com/Dreamacro/clash/component/trie"
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/constant/sniffer"
"github.com/Dreamacro/clash/log"
)
@ -25,30 +24,29 @@ var (
ErrNoClue = errors.New("not enough information for making a decision")
)
var Dispatcher SnifferDispatcher
var Dispatcher *SnifferDispatcher
type (
SnifferDispatcher struct {
enable bool
type SnifferDispatcher struct {
enable bool
sniffers []sniffer.Sniffer
sniffers []sniffer.Sniffer
foreDomain *trie.DomainTrie[bool]
skipSNI *trie.DomainTrie[bool]
portRanges *[]utils.Range[uint16]
skipList *cache.LruCache[string, uint8]
rwMux sync.RWMutex
}
)
forceDomain *trie.DomainTrie[bool]
skipSNI *trie.DomainTrie[bool]
portRanges *[]utils.Range[uint16]
skipList *cache.LruCache[string, uint8]
rwMux sync.RWMutex
forceDnsMapping bool
}
func (sd *SnifferDispatcher) TCPSniff(conn net.Conn, metadata *C.Metadata) {
bufConn, ok := conn.(*CN.BufferedConn)
bufConn, ok := conn.(*N.BufferedConn)
if !ok {
return
}
if metadata.Host == "" || sd.foreDomain.Search(metadata.Host) != nil {
if metadata.Host == "" || sd.forceDomain.Search(metadata.Host) != nil || (metadata.DNSMode == C.DNSMapping && sd.forceDnsMapping) {
port, err := strconv.ParseUint(metadata.DstPort, 10, 16)
if err != nil {
log.Debugln("[Sniffer] Dst port is error")
@ -114,7 +112,7 @@ func (sd *SnifferDispatcher) Enable() bool {
return sd.enable
}
func (sd *SnifferDispatcher) sniffDomain(conn *CN.BufferedConn, metadata *C.Metadata) (string, error) {
func (sd *SnifferDispatcher) sniffDomain(conn *N.BufferedConn, metadata *C.Metadata) (string, error) {
for _, s := range sd.sniffers {
if s.SupportNetwork() == C.TCP {
_ = conn.SetReadDeadline(time.Now().Add(1 * time.Second))
@ -177,13 +175,14 @@ func NewCloseSnifferDispatcher() (*SnifferDispatcher, error) {
}
func NewSnifferDispatcher(needSniffer []sniffer.Type, forceDomain *trie.DomainTrie[bool],
skipSNI *trie.DomainTrie[bool], ports *[]utils.Range[uint16]) (*SnifferDispatcher, error) {
skipSNI *trie.DomainTrie[bool], ports *[]utils.Range[uint16], forceDnsMapping bool) (*SnifferDispatcher, error) {
dispatcher := SnifferDispatcher{
enable: true,
foreDomain: forceDomain,
skipSNI: skipSNI,
portRanges: ports,
skipList: cache.NewLRUCache[string, uint8](cache.WithSize[string, uint8](128), cache.WithAge[string, uint8](600)),
enable: true,
forceDomain: forceDomain,
skipSNI: skipSNI,
portRanges: ports,
skipList: cache.NewLRUCache[string, uint8](cache.WithSize[string, uint8](128), cache.WithAge[string, uint8](600)),
forceDnsMapping: forceDnsMapping,
}
for _, snifferName := range needSniffer {

View file

@ -4,9 +4,10 @@ import (
"bytes"
"errors"
"fmt"
C "github.com/Dreamacro/clash/constant"
"net"
"strings"
C "github.com/Dreamacro/clash/constant"
)
var (

View file

@ -195,12 +195,13 @@ type IPTables struct {
}
type Sniffer struct {
Enable bool
Sniffers []sniffer.Type
Reverses *trie.DomainTrie[bool]
ForceDomain *trie.DomainTrie[bool]
SkipDomain *trie.DomainTrie[bool]
Ports *[]utils.Range[uint16]
Enable bool
Sniffers []sniffer.Type
Reverses *trie.DomainTrie[bool]
ForceDomain *trie.DomainTrie[bool]
SkipDomain *trie.DomainTrie[bool]
Ports *[]utils.Range[uint16]
ForceDnsMapping bool
}
// Experimental config
@ -325,11 +326,12 @@ type RawGeoXUrl struct {
}
type RawSniffer struct {
Enable bool `yaml:"enable" json:"enable"`
Sniffing []string `yaml:"sniffing" json:"sniffing"`
ForceDomain []string `yaml:"force-domain" json:"force-domain"`
SkipDomain []string `yaml:"skip-domain" json:"skip-domain"`
Ports []string `yaml:"port-whitelist" json:"port-whitelist"`
Enable bool `yaml:"enable" json:"enable"`
Sniffing []string `yaml:"sniffing" json:"sniffing"`
ForceDomain []string `yaml:"force-domain" json:"force-domain"`
SkipDomain []string `yaml:"skip-domain" json:"skip-domain"`
Ports []string `yaml:"port-whitelist" json:"port-whitelist"`
ForceDnsMapping bool `yaml:"force-dns-mapping" json:"force-dns-mapping"`
}
// EBpf config
@ -419,11 +421,12 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
},
},
Sniffer: RawSniffer{
Enable: false,
Sniffing: []string{},
ForceDomain: []string{},
SkipDomain: []string{},
Ports: []string{},
Enable: false,
Sniffing: []string{},
ForceDomain: []string{},
SkipDomain: []string{},
Ports: []string{},
ForceDnsMapping: true,
},
Profile: Profile{
StoreSelected: true,
@ -1173,7 +1176,8 @@ func parseTun(rawTun RawTun, general *General, dnsCfg *DNS) (*Tun, error) {
func parseSniffer(snifferRaw RawSniffer) (*Sniffer, error) {
sniffer := &Sniffer{
Enable: snifferRaw.Enable,
Enable: snifferRaw.Enable,
ForceDnsMapping: snifferRaw.ForceDnsMapping,
}
var ports []utils.Range[uint16]

View file

@ -1,10 +1,11 @@
package context
import (
CN "github.com/Dreamacro/clash/common/net"
"net"
N "github.com/Dreamacro/clash/common/net"
C "github.com/Dreamacro/clash/constant"
"github.com/gofrs/uuid"
)
@ -20,7 +21,7 @@ func NewConnContext(conn net.Conn, metadata *C.Metadata) *ConnContext {
return &ConnContext{
id: id,
metadata: metadata,
conn: CN.NewBufferedConn(conn),
conn: N.NewBufferedConn(conn),
}
}

View file

@ -265,7 +265,7 @@ func updateTun(tun *config.Tun) {
func updateSniffer(sniffer *config.Sniffer) {
if sniffer.Enable {
dispatcher, err := SNI.NewSnifferDispatcher(sniffer.Sniffers, sniffer.ForceDomain, sniffer.SkipDomain, sniffer.Ports)
dispatcher, err := SNI.NewSnifferDispatcher(sniffer.Sniffers, sniffer.ForceDomain, sniffer.SkipDomain, sniffer.Ports, sniffer.ForceDnsMapping)
if err != nil {
log.Warnln("initial sniffer failed, err:%v", err)
}

View file

@ -107,7 +107,7 @@ func UpdateProxies(newProxies map[string]C.Proxy, newProviders map[string]provid
func UpdateSniffer(dispatcher *sniffer.SnifferDispatcher) {
configMux.Lock()
sniffer.Dispatcher = *dispatcher
sniffer.Dispatcher = dispatcher
sniffingEnable = true
configMux.Unlock()
}