Browse Source

refactor peeking strategy

Darien Raymond 8 years ago
parent
commit
93d913b959
1 changed files with 25 additions and 16 deletions
  1. 25 16
      app/dispatcher/impl/default.go

+ 25 - 16
app/dispatcher/impl/default.go

@@ -4,6 +4,7 @@ package impl
 
 import (
 	"context"
+
 	"time"
 
 	"v2ray.com/core/app"
@@ -81,6 +82,26 @@ func (d *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin
 	return outbound, nil
 }
 
+func trySnif(sniferList []proxyman.KnownProtocols, b []byte) (string, error) {
+	for _, protocol := range sniferList {
+		var f func([]byte) (string, error)
+		switch protocol {
+		case proxyman.KnownProtocols_HTTP:
+			f = SniffHTTP
+		case proxyman.KnownProtocols_TLS:
+			f = SniffTLS
+		default:
+			panic("Unsupported protocol")
+		}
+
+		domain, err := f(b)
+		if err != ErrMoreData {
+			return domain, err
+		}
+	}
+	return "", ErrMoreData
+}
+
 func snifer(ctx context.Context, sniferList []proxyman.KnownProtocols, outbound ray.OutboundRay) (string, error) {
 	payload := buf.New()
 	defer payload.Release()
@@ -90,27 +111,14 @@ func snifer(ctx context.Context, sniferList []proxyman.KnownProtocols, outbound
 		select {
 		case <-ctx.Done():
 			return "", ctx.Err()
-		case <-time.After(time.Millisecond * 100):
+		default:
 			totalAttempt++
 			if totalAttempt > 5 {
 				return "", errSniffingTimeout
 			}
 			outbound.OutboundInput().Peek(payload)
-			if payload.IsEmpty() {
-				continue
-			}
-			for _, protocol := range sniferList {
-				var f func([]byte) (string, error)
-				switch protocol {
-				case proxyman.KnownProtocols_HTTP:
-					f = SniffHTTP
-				case proxyman.KnownProtocols_TLS:
-					f = SniffTLS
-				default:
-					panic("Unsupported protocol")
-				}
-
-				domain, err := f(payload.Bytes())
+			if !payload.IsEmpty() {
+				domain, err := trySnif(sniferList, payload.Bytes())
 				if err != ErrMoreData {
 					return domain, err
 				}
@@ -118,6 +126,7 @@ func snifer(ctx context.Context, sniferList []proxyman.KnownProtocols, outbound
 			if payload.IsFull() {
 				return "", ErrInvalidData
 			}
+			time.Sleep(time.Millisecond * 100)
 		}
 	}
 }