|
|
@@ -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)
|
|
|
}
|
|
|
}
|
|
|
}
|