fix(handler/sni): add sniff deadline, log sniff errors, nil Router guard
- Set read deadline before/after sniffing.Sniff to prevent goroutine leak from slow clients (matches redirect/tcp and ss patterns) - Log sniff errors at Debug level instead of silently discarding them - Add nil Router check in dial closure to prevent NPE panic
This commit is contained in:
+13
-1
@@ -120,11 +120,23 @@ func (h *sniHandler) Handle(ctx context.Context, conn net.Conn, opts ...handler.
|
|||||||
return rate_limiter.ErrRateLimit
|
return rate_limiter.ErrRateLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if h.md.readTimeout > 0 {
|
||||||
|
conn.SetReadDeadline(time.Now().Add(h.md.readTimeout))
|
||||||
|
}
|
||||||
br := bufio.NewReader(conn)
|
br := bufio.NewReader(conn)
|
||||||
proto, _ := sniffing.Sniff(ctx, br)
|
proto, sniffErr := sniffing.Sniff(ctx, br)
|
||||||
|
if h.md.readTimeout > 0 {
|
||||||
|
conn.SetReadDeadline(time.Time{})
|
||||||
|
}
|
||||||
|
if sniffErr != nil {
|
||||||
|
log.Debugf("sniff: %v", sniffErr)
|
||||||
|
}
|
||||||
ro.Proto = proto
|
ro.Proto = proto
|
||||||
|
|
||||||
dial := func(ctx context.Context, network, address string) (net.Conn, error) {
|
dial := func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
|
if h.options.Router == nil {
|
||||||
|
return nil, errors.New("sni: router not available")
|
||||||
|
}
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
cc, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", address)
|
cc, err := h.options.Router.Dial(ictx.ContextWithBuffer(ctx, &buf), "tcp", address)
|
||||||
ro.Route = buf.String()
|
ro.Route = buf.String()
|
||||||
|
|||||||
Reference in New Issue
Block a user