From bb73dc304246c8b971493887ae2ebb96bc0a7a46 Mon Sep 17 00:00:00 2001 From: Yannick Dylla <17772145+ydylla@users.noreply.github.com> Date: Sun, 2 Jun 2024 22:24:49 +0200 Subject: [PATCH] fix: skip already seen routes after a match This is done to be backwards compatible with the old matching behavior see https://github.com/mholt/caddy-l4/pull/192#issuecomment-2143681952 --- layer4/routes.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/layer4/routes.go b/layer4/routes.go index 97f55bd..c1d002a 100644 --- a/layer4/routes.go +++ b/layer4/routes.go @@ -101,6 +101,7 @@ func (routes RouteList) Provision(ctx caddy.Context) error { func (routes RouteList) Compile(logger *zap.Logger, matchingTimeout time.Duration, next NextHandler) Handler { return HandlerFunc(func(cx *Connection) error { deadline := time.Now().Add(matchingTimeout) + lastMatchedRouteIdx := -1 router: // timeout matching to protect against malicious or very slow clients err := cx.Conn.SetReadDeadline(deadline) @@ -127,7 +128,14 @@ func (routes RouteList) Compile(logger *zap.Logger, matchingTimeout time.Duratio } } - for _, route := range routes { + for i, route := range routes { + // After a match continue with the routes after the matched one, instead of starting at the beginning. + // This is done for backwards compatibility with configs written before the "Non blocking matchers & matching timeout" rewrite. + // See https://github.com/mholt/caddy-l4/pull/192 and https://github.com/mholt/caddy-l4/pull/192#issuecomment-2143681952. + if i <= lastMatchedRouteIdx { + continue + } + // A route must match at least one of the matcher sets matched, err := route.matcherSets.AnyMatch(cx) if errors.Is(err, ErrConsumedAllPrefetchedBytes) { @@ -138,6 +146,8 @@ func (routes RouteList) Compile(logger *zap.Logger, matchingTimeout time.Duratio return nil } if matched { + lastMatchedRouteIdx = i + // remove deadline after we matched err = cx.Conn.SetReadDeadline(time.Time{}) if err != nil {