github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/app/dispatcher/sniffer.go (about) 1 // +build !confonly 2 3 package dispatcher 4 5 import ( 6 "v2ray.com/core/common" 7 "v2ray.com/core/common/protocol/bittorrent" 8 "v2ray.com/core/common/protocol/http" 9 "v2ray.com/core/common/protocol/tls" 10 ) 11 12 type SniffResult interface { 13 Protocol() string 14 Domain() string 15 } 16 17 type protocolSniffer func([]byte) (SniffResult, error) 18 19 type Sniffer struct { 20 sniffer []protocolSniffer 21 } 22 23 func NewSniffer() *Sniffer { 24 return &Sniffer{ 25 sniffer: []protocolSniffer{ 26 func(b []byte) (SniffResult, error) { return http.SniffHTTP(b) }, 27 func(b []byte) (SniffResult, error) { return tls.SniffTLS(b) }, 28 func(b []byte) (SniffResult, error) { return bittorrent.SniffBittorrent(b) }, 29 }, 30 } 31 } 32 33 var errUnknownContent = newError("unknown content") 34 35 func (s *Sniffer) Sniff(payload []byte) (SniffResult, error) { 36 var pendingSniffer []protocolSniffer 37 for _, s := range s.sniffer { 38 result, err := s(payload) 39 if err == common.ErrNoClue { 40 pendingSniffer = append(pendingSniffer, s) 41 continue 42 } 43 44 if err == nil && result != nil { 45 return result, nil 46 } 47 } 48 49 if len(pendingSniffer) > 0 { 50 s.sniffer = pendingSniffer 51 return nil, common.ErrNoClue 52 } 53 54 return nil, errUnknownContent 55 }