From 072e7619346274925e0e9be73f45cc38508772fa Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Tue, 30 Mar 2021 17:43:17 +0800 Subject: [PATCH 1/7] revert: single bool --- app/dispatcher/default.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dispatcher/default.go b/app/dispatcher/default.go index b50df8d924bd..50ed61347191 100644 --- a/app/dispatcher/default.go +++ b/app/dispatcher/default.go @@ -268,7 +268,7 @@ func sniffer(ctx context.Context, cReader *cachedReader, metadataOnly bool) (Sni metaresult, metadataErr := sniffer.SniffMetadata(ctx) - if metadataOnly || metaresult != nil { + if metadataOnly { return metaresult, metadataErr } From e16909a605e67e1faa66e327148c7e653298db15 Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Tue, 30 Mar 2021 17:51:41 +0800 Subject: [PATCH 2/7] Update default.go --- app/dispatcher/default.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dispatcher/default.go b/app/dispatcher/default.go index 50ed61347191..49b0acc580c7 100644 --- a/app/dispatcher/default.go +++ b/app/dispatcher/default.go @@ -286,7 +286,7 @@ func sniffer(ctx context.Context, cReader *cachedReader, metadataOnly bool) (Sni cReader.Cache(payload) if !payload.IsEmpty() { - result, err := sniffer.Sniff(ctx, payload.Bytes()) + result, err := sniffer.Sniff(ctx, payload.Bytes(), metadataErr != nil) if err != common.ErrNoClue { return result, err } From 57145fea3b650bbe57eb0a35dc6dc03ff78fc38a Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Tue, 30 Mar 2021 18:00:56 +0800 Subject: [PATCH 3/7] Update sniffer.go --- app/dispatcher/sniffer.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/dispatcher/sniffer.go b/app/dispatcher/sniffer.go index 988d30792ea3..5735e2e38f43 100644 --- a/app/dispatcher/sniffer.go +++ b/app/dispatcher/sniffer.go @@ -14,7 +14,7 @@ type SniffResult interface { Domain() string } -type protocolSniffer func(context.Context, []byte) (SniffResult, error) +type protocolSniffer func(context.Context, []byte, bool) (SniffResult, error) type protocolSnifferWithMetadata struct { protocolSniffer protocolSniffer @@ -31,9 +31,9 @@ type Sniffer struct { func NewSniffer(ctx context.Context) *Sniffer { ret := &Sniffer{ sniffer: []protocolSnifferWithMetadata{ - {func(c context.Context, b []byte) (SniffResult, error) { return http.SniffHTTP(b) }, false}, - {func(c context.Context, b []byte) (SniffResult, error) { return tls.SniffTLS(b) }, false}, - {func(c context.Context, b []byte) (SniffResult, error) { return bittorrent.SniffBittorrent(b) }, false}, + {func(c context.Context, b []byte, s bool) (SniffResult, error) { return http.SniffHTTP(b, s) }, false}, + {func(c context.Context, b []byte, s bool) (SniffResult, error) { return tls.SniffTLS(b, s) }, false}, + {func(c context.Context, b []byte, s bool) (SniffResult, error) { return bittorrent.SniffBittorrent(b, s) }, false}, }, } if sniffer, err := newFakeDNSSniffer(ctx); err == nil { @@ -44,14 +44,14 @@ func NewSniffer(ctx context.Context) *Sniffer { var errUnknownContent = newError("unknown content") -func (s *Sniffer) Sniff(c context.Context, payload []byte) (SniffResult, error) { +func (s *Sniffer) Sniff(c context.Context, payload []byte, shouldSniffDomain bool) (SniffResult, error) { var pendingSniffer []protocolSnifferWithMetadata for _, si := range s.sniffer { s := si.protocolSniffer if si.metadataSniffer { continue } - result, err := s(c, payload) + result, err := s(c, payload, shouldSniffDomain) if err == common.ErrNoClue { pendingSniffer = append(pendingSniffer, si) continue @@ -78,7 +78,7 @@ func (s *Sniffer) SniffMetadata(c context.Context) (SniffResult, error) { pendingSniffer = append(pendingSniffer, si) continue } - result, err := s(c, nil) + result, err := s(c, nil, true) if err == common.ErrNoClue { pendingSniffer = append(pendingSniffer, si) continue From 723a7aebb08f297e0a7dc280d3ae61d53ef3199f Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Tue, 30 Mar 2021 18:05:03 +0800 Subject: [PATCH 4/7] Update fakednssniffer.go --- app/dispatcher/fakednssniffer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/dispatcher/fakednssniffer.go b/app/dispatcher/fakednssniffer.go index 7d26d975ffaa..5ebd21539cf6 100644 --- a/app/dispatcher/fakednssniffer.go +++ b/app/dispatcher/fakednssniffer.go @@ -23,7 +23,7 @@ func newFakeDNSSniffer(ctx context.Context) (protocolSnifferWithMetadata, error) errNotInit := newError("FakeDNSEngine is not initialized, but such a sniffer is used").AtError() return protocolSnifferWithMetadata{}, errNotInit } - return protocolSnifferWithMetadata{protocolSniffer: func(ctx context.Context, bytes []byte) (SniffResult, error) { + return protocolSnifferWithMetadata{protocolSniffer: func(ctx context.Context, bytes []byte, shouldSniffDomain bool) (SniffResult, error) { Target := session.OutboundFromContext(ctx).Target if Target.Network == net.Network_TCP || Target.Network == net.Network_UDP { domainFromFakeDNS := fakeDNSEngine.GetDomainFromFakeDNS(Target.Address) From 06cccabc9b56e00d5b1935feb125801032e51538 Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Tue, 30 Mar 2021 18:09:29 +0800 Subject: [PATCH 5/7] Update sniff.go --- common/protocol/http/sniff.go | 40 ++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/common/protocol/http/sniff.go b/common/protocol/http/sniff.go index ceedede24ff5..6125c5364c53 100644 --- a/common/protocol/http/sniff.go +++ b/common/protocol/http/sniff.go @@ -56,7 +56,7 @@ func beginWithHTTPMethod(b []byte) error { return errNotHTTPMethod } -func SniffHTTP(b []byte) (*SniffHeader, error) { +func SniffHTTP(b []byte, shouldSniffDomain bool) (*SniffHeader, error) { if err := beginWithHTTPMethod(b); err != nil { return nil, err } @@ -65,28 +65,30 @@ func SniffHTTP(b []byte) (*SniffHeader, error) { version: HTTP1, } - headers := bytes.Split(b, []byte{'\n'}) - for i := 1; i < len(headers); i++ { - header := headers[i] - if len(header) == 0 { - break - } - parts := bytes.SplitN(header, []byte{':'}, 2) - if len(parts) != 2 { - continue - } - key := strings.ToLower(string(parts[0])) - if key == "host" { - rawHost := strings.ToLower(string(bytes.TrimSpace(parts[1]))) - dest, err := ParseHost(rawHost, net.Port(80)) - if err != nil { - return nil, err + if shouldSniffDomain { + headers := bytes.Split(b, []byte{'\n'}) + for i := 1; i < len(headers); i++ { + header := headers[i] + if len(header) == 0 { + break + } + parts := bytes.SplitN(header, []byte{':'}, 2) + if len(parts) != 2 { + continue + } + key := strings.ToLower(string(parts[0])) + if key == "host" { + rawHost := strings.ToLower(string(bytes.TrimSpace(parts[1]))) + dest, err := ParseHost(rawHost, net.Port(80)) + if err != nil { + return nil, err + } + sh.host = dest.Address.String() } - sh.host = dest.Address.String() } } - if len(sh.host) > 0 { + if !shouldSniffDomain || len(sh.host) > 0 { return sh, nil } From 0d817edf8d4ec7be86b36d3dd72f0bf413a7e663 Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Tue, 30 Mar 2021 18:10:29 +0800 Subject: [PATCH 6/7] Update bittorrent.go --- common/protocol/bittorrent/bittorrent.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/protocol/bittorrent/bittorrent.go b/common/protocol/bittorrent/bittorrent.go index 0ffc56a3ee41..33ec147fd7f1 100644 --- a/common/protocol/bittorrent/bittorrent.go +++ b/common/protocol/bittorrent/bittorrent.go @@ -19,7 +19,7 @@ func (h *SniffHeader) Domain() string { var errNotBittorrent = errors.New("not bittorrent header") -func SniffBittorrent(b []byte) (*SniffHeader, error) { +func SniffBittorrent(b []byte, shouldSniffDomain bool) (*SniffHeader, error) { if len(b) < 20 { return nil, common.ErrNoClue } From f8982baa3c155fb757d99fbb79ad62ba7317593a Mon Sep 17 00:00:00 2001 From: rurirei <72071920+rurirei@users.noreply.github.com> Date: Tue, 30 Mar 2021 18:19:02 +0800 Subject: [PATCH 7/7] Update sniff.go --- common/protocol/tls/sniff.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/common/protocol/tls/sniff.go b/common/protocol/tls/sniff.go index f3806a059cc7..66561a0e8704 100644 --- a/common/protocol/tls/sniff.go +++ b/common/protocol/tls/sniff.go @@ -29,7 +29,7 @@ func IsValidTLSVersion(major, minor byte) bool { // ReadClientHello returns server name (if any) from TLS client hello message. // https://github.com/golang/go/blob/master/src/crypto/tls/handshake_messages.go#L300 -func ReadClientHello(data []byte, h *SniffHeader) error { +func ReadClientHello(shouldSniffDomain bool, data []byte, h *SniffHeader) error { if len(data) < 42 { return common.ErrNoClue } @@ -70,6 +70,10 @@ func ReadClientHello(data []byte, h *SniffHeader) error { return errNotClientHello } + if !shouldSniffDomain { + return nil + } + for len(data) != 0 { if len(data) < 4 { return errNotClientHello @@ -121,7 +125,7 @@ func ReadClientHello(data []byte, h *SniffHeader) error { return errNotTLS } -func SniffTLS(b []byte) (*SniffHeader, error) { +func SniffTLS(b []byte, shouldSniffDomain bool) (*SniffHeader, error) { if len(b) < 5 { return nil, common.ErrNoClue } @@ -138,7 +142,7 @@ func SniffTLS(b []byte) (*SniffHeader, error) { } h := &SniffHeader{} - err := ReadClientHello(b[5:5+headerLen], h) + err := ReadClientHello(shouldSniffDomain, b[5:5+headerLen], h) if err == nil { return h, nil }