sniffer.go 1.1 KB

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