mirror of
https://github.com/XTLS/Xray-core.git
synced 2024-12-24 14:39:49 +00:00
56 lines
1.2 KiB
Go
56 lines
1.2 KiB
Go
|
// +build !confonly
|
||
|
|
||
|
package dispatcher
|
||
|
|
||
|
import (
|
||
|
"github.com/xtls/xray-core/v1/common"
|
||
|
"github.com/xtls/xray-core/v1/common/protocol/bittorrent"
|
||
|
"github.com/xtls/xray-core/v1/common/protocol/http"
|
||
|
"github.com/xtls/xray-core/v1/common/protocol/tls"
|
||
|
)
|
||
|
|
||
|
type SniffResult interface {
|
||
|
Protocol() string
|
||
|
Domain() string
|
||
|
}
|
||
|
|
||
|
type protocolSniffer func([]byte) (SniffResult, error)
|
||
|
|
||
|
type Sniffer struct {
|
||
|
sniffer []protocolSniffer
|
||
|
}
|
||
|
|
||
|
func NewSniffer() *Sniffer {
|
||
|
return &Sniffer{
|
||
|
sniffer: []protocolSniffer{
|
||
|
func(b []byte) (SniffResult, error) { return http.SniffHTTP(b) },
|
||
|
func(b []byte) (SniffResult, error) { return tls.SniffTLS(b) },
|
||
|
func(b []byte) (SniffResult, error) { return bittorrent.SniffBittorrent(b) },
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var errUnknownContent = newError("unknown content")
|
||
|
|
||
|
func (s *Sniffer) Sniff(payload []byte) (SniffResult, error) {
|
||
|
var pendingSniffer []protocolSniffer
|
||
|
for _, s := range s.sniffer {
|
||
|
result, err := s(payload)
|
||
|
if err == common.ErrNoClue {
|
||
|
pendingSniffer = append(pendingSniffer, s)
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
if err == nil && result != nil {
|
||
|
return result, nil
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if len(pendingSniffer) > 0 {
|
||
|
s.sniffer = pendingSniffer
|
||
|
return nil, common.ErrNoClue
|
||
|
}
|
||
|
|
||
|
return nil, errUnknownContent
|
||
|
}
|