diff --git a/app/dispatcher/impl/default.go b/app/dispatcher/impl/default.go index e02a84c36..9485373e6 100644 --- a/app/dispatcher/impl/default.go +++ b/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) } } }