From 604a902e2c7e0317aecaa3666124079c75a31573 Mon Sep 17 00:00:00 2001 From: Chris O'Haver Date: Sat, 29 Apr 2023 05:52:00 -0400 Subject: [PATCH] plugin/forward: Continue waiting after receiving malformed responses (#6014) * forward: continue waiting after malformed responses Signed-off-by: Chris O'Haver * add test Signed-off-by: Chris O'Haver * fix test Signed-off-by: Chris O'Haver * clean up Signed-off-by: Chris O'Haver * clean up Signed-off-by: Chris O'Haver * move test to /test/. Add build tag. Signed-off-by: Chris O'Haver * install libpcap-dev for e2e tests Signed-off-by: Chris O'Haver * sudo the test Signed-off-by: Chris O'Haver * remove stray err check Signed-off-by: Chris O'Haver * disable the test Signed-off-by: Chris O'Haver * use -exec flag to run test binary as root Signed-off-by: Chris O'Haver * run new test by itself in a new workflow Signed-off-by: Chris O'Haver * fix test name Signed-off-by: Chris O'Haver * only for udp Signed-off-by: Chris O'Haver * remove libpcap test workflow action Signed-off-by: Chris O'Haver * remove test, since it cant run in ci Signed-off-by: Chris O'Haver * and remove gopacket package Signed-off-by: Chris O'Haver --------- Signed-off-by: Chris O'Haver --- plugin/pkg/proxy/connect.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/plugin/pkg/proxy/connect.go b/plugin/pkg/proxy/connect.go index 29274d92d..b60a1a237 100644 --- a/plugin/pkg/proxy/connect.go +++ b/plugin/pkg/proxy/connect.go @@ -7,6 +7,7 @@ package proxy import ( "context" "io" + "net" "strconv" "sync/atomic" "time" @@ -117,11 +118,20 @@ func (p *Proxy) Connect(ctx context.Context, state request.Request, opts Options for { ret, err = pc.c.ReadMsg() if err != nil { - pc.c.Close() // not giving it back + // For UDP, if the error is not a network error keep waiting for a valid response to prevent malformed + // spoofs from blocking the upstream response. + // In the case this is a legitimate malformed response from the upstream, this will result in a timeout. + if proto == "udp" { + if _, ok := err.(net.Error); !ok { + continue + } + } + pc.c.Close() // connection closed by peer, close the persistent connection if err == io.EOF && cached { return nil, ErrCachedClosed } - // recovery the origin Id after upstream. + + // recover the origin Id after upstream. if ret != nil { ret.Id = originId }