feat: better config for sniffer
This commit is contained in:
52
component/sniffer/base_sniffer.go
Normal file
52
component/sniffer/base_sniffer.go
Normal file
@ -0,0 +1,52 @@
|
||||
package sniffer
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Dreamacro/clash/common/utils"
|
||||
"github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/constant/sniffer"
|
||||
)
|
||||
|
||||
type SnifferConfig struct {
|
||||
Ports []utils.Range[uint16]
|
||||
}
|
||||
|
||||
type BaseSniffer struct {
|
||||
ports []utils.Range[uint16]
|
||||
supportNetworkType constant.NetWork
|
||||
}
|
||||
|
||||
// Protocol implements sniffer.Sniffer
|
||||
func (*BaseSniffer) Protocol() string {
|
||||
return "unknown"
|
||||
}
|
||||
|
||||
// SniffTCP implements sniffer.Sniffer
|
||||
func (*BaseSniffer) SniffTCP(bytes []byte) (string, error) {
|
||||
return "", errors.New("TODO")
|
||||
}
|
||||
|
||||
// SupportNetwork implements sniffer.Sniffer
|
||||
func (bs *BaseSniffer) SupportNetwork() constant.NetWork {
|
||||
return bs.supportNetworkType
|
||||
}
|
||||
|
||||
// SupportPort implements sniffer.Sniffer
|
||||
func (bs *BaseSniffer) SupportPort(port uint16) bool {
|
||||
for _, portRange := range bs.ports {
|
||||
if portRange.Contains(port) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func NewBaseSniffer(ports []utils.Range[uint16], networkType constant.NetWork) *BaseSniffer {
|
||||
return &BaseSniffer{
|
||||
ports: ports,
|
||||
supportNetworkType: networkType,
|
||||
}
|
||||
}
|
||||
|
||||
var _ sniffer.Sniffer = (*BaseSniffer)(nil)
|
@ -11,7 +11,6 @@ import (
|
||||
|
||||
"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"
|
||||
@ -33,7 +32,6 @@ type SnifferDispatcher struct {
|
||||
|
||||
forceDomain *trie.DomainTrie[struct{}]
|
||||
skipSNI *trie.DomainTrie[struct{}]
|
||||
portRanges *[]utils.Range[uint16]
|
||||
skipList *cache.LruCache[string, uint8]
|
||||
rwMux sync.RWMutex
|
||||
|
||||
@ -55,10 +53,12 @@ func (sd *SnifferDispatcher) TCPSniff(conn net.Conn, metadata *C.Metadata) {
|
||||
}
|
||||
|
||||
inWhitelist := false
|
||||
for _, portRange := range *sd.portRanges {
|
||||
if portRange.Contains(uint16(port)) {
|
||||
inWhitelist = true
|
||||
break
|
||||
for _, sniffer := range sd.sniffers {
|
||||
if sniffer.SupportNetwork() == C.TCP || sniffer.SupportNetwork() == C.ALLNet {
|
||||
inWhitelist = sniffer.SupportPort(uint16(port))
|
||||
if inWhitelist {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,21 +182,20 @@ func NewCloseSnifferDispatcher() (*SnifferDispatcher, error) {
|
||||
return &dispatcher, nil
|
||||
}
|
||||
|
||||
func NewSnifferDispatcher(needSniffer []sniffer.Type, forceDomain *trie.DomainTrie[struct{}],
|
||||
skipSNI *trie.DomainTrie[struct{}], ports *[]utils.Range[uint16],
|
||||
func NewSnifferDispatcher(snifferConfig map[sniffer.Type]SnifferConfig, forceDomain *trie.DomainTrie[struct{}],
|
||||
skipSNI *trie.DomainTrie[struct{}],
|
||||
forceDnsMapping bool, parsePureIp bool) (*SnifferDispatcher, error) {
|
||||
dispatcher := SnifferDispatcher{
|
||||
enable: true,
|
||||
forceDomain: forceDomain,
|
||||
skipSNI: skipSNI,
|
||||
portRanges: ports,
|
||||
skipList: cache.New[string, uint8](cache.WithSize[string, uint8](128), cache.WithAge[string, uint8](600)),
|
||||
forceDnsMapping: forceDnsMapping,
|
||||
parsePureIp: parsePureIp,
|
||||
}
|
||||
|
||||
for _, snifferName := range needSniffer {
|
||||
s, err := NewSniffer(snifferName)
|
||||
for snifferName, config := range snifferConfig {
|
||||
s, err := NewSniffer(snifferName, config)
|
||||
if err != nil {
|
||||
log.Errorln("Sniffer name[%s] is error", snifferName)
|
||||
return &SnifferDispatcher{enable: false}, err
|
||||
@ -208,12 +207,12 @@ func NewSnifferDispatcher(needSniffer []sniffer.Type, forceDomain *trie.DomainTr
|
||||
return &dispatcher, nil
|
||||
}
|
||||
|
||||
func NewSniffer(name sniffer.Type) (sniffer.Sniffer, error) {
|
||||
func NewSniffer(name sniffer.Type, snifferConfig SnifferConfig) (sniffer.Sniffer, error) {
|
||||
switch name {
|
||||
case sniffer.TLS:
|
||||
return &TLSSniffer{}, nil
|
||||
return NewTLSSniffer(snifferConfig)
|
||||
case sniffer.HTTP:
|
||||
return &HTTPSniffer{}, nil
|
||||
return NewHTTPSniffer(snifferConfig)
|
||||
default:
|
||||
return nil, ErrorUnsupportedSniffer
|
||||
}
|
||||
|
@ -7,7 +7,9 @@ import (
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/Dreamacro/clash/common/utils"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/constant/sniffer"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -24,10 +26,25 @@ const (
|
||||
)
|
||||
|
||||
type HTTPSniffer struct {
|
||||
*BaseSniffer
|
||||
version version
|
||||
host string
|
||||
}
|
||||
|
||||
var _ sniffer.Sniffer = (*HTTPSniffer)(nil)
|
||||
|
||||
func NewHTTPSniffer(snifferConfig SnifferConfig) (*HTTPSniffer, error) {
|
||||
ports := make([]utils.Range[uint16], 0)
|
||||
if len(snifferConfig.Ports) == 0 {
|
||||
ports = append(ports, *utils.NewRange[uint16](80, 80))
|
||||
} else {
|
||||
ports = append(ports, snifferConfig.Ports...)
|
||||
}
|
||||
return &HTTPSniffer{
|
||||
BaseSniffer: NewBaseSniffer(ports, C.TCP),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (http *HTTPSniffer) Protocol() string {
|
||||
switch http.version {
|
||||
case HTTP1:
|
||||
|
@ -5,7 +5,9 @@ import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/Dreamacro/clash/common/utils"
|
||||
C "github.com/Dreamacro/clash/constant"
|
||||
"github.com/Dreamacro/clash/constant/sniffer"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -13,7 +15,22 @@ var (
|
||||
errNotClientHello = errors.New("not client hello")
|
||||
)
|
||||
|
||||
var _ sniffer.Sniffer = (*TLSSniffer)(nil)
|
||||
|
||||
type TLSSniffer struct {
|
||||
*BaseSniffer
|
||||
}
|
||||
|
||||
func NewTLSSniffer(snifferConfig SnifferConfig) (*TLSSniffer, error) {
|
||||
ports := make([]utils.Range[uint16], 0)
|
||||
if len(snifferConfig.Ports) == 0 {
|
||||
ports = append(ports, *utils.NewRange[uint16](443, 443))
|
||||
} else {
|
||||
ports = append(ports, snifferConfig.Ports...)
|
||||
}
|
||||
return &TLSSniffer{
|
||||
BaseSniffer: NewBaseSniffer(ports, C.TCP),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (tls *TLSSniffer) Protocol() string {
|
||||
|
Reference in New Issue
Block a user