fix(proxy): keep bytes after PROXY UNKNOWN header

When a trusted upstream sends "PROXY UNKNOWN\r\n", parseProxyProtocolHeader
returned the raw connection and discarded whatever followed the header in
the same read. The TLS ClientHello usually arrives in that same segment, so
it was lost, the SNI extraction failed on the truncated stream, and the
connection was dropped. The 5s parsing read deadline was also left set on
this path.

Wrap the connection so the remaining buffered bytes are replayed ahead of
the socket, and clear the read deadline, matching the other header
branches.
This commit is contained in:
breken
2026-09-13 19:28:18 -07:00
parent 81e2a64e11
commit ba5c55f1a9
2 changed files with 81 additions and 2 deletions
+13 -2
View File
@@ -213,8 +213,19 @@ func (p *SNIProxy) parseProxyProtocolHeader(conn net.Conn) (*ProxyProtocolInfo,
if len(parts) != 6 || parts[0] != "PROXY" {
// Check for PROXY UNKNOWN
if len(parts) == 2 && parts[0] == "PROXY" && parts[1] == "UNKNOWN" {
// PROXY UNKNOWN - use original connection info
return nil, conn, nil
// PROXY UNKNOWN - use original connection info, but keep any
// bytes that arrived after the header (the TLS ClientHello).
if err := conn.SetReadDeadline(time.Time{}); err != nil {
return nil, conn, fmt.Errorf("failed to clear read deadline: %w", err)
}
if len(remainingData) == 0 {
return nil, conn, nil
}
wrappedConn := &proxyProtocolConn{
Conn: conn,
reader: io.MultiReader(bytes.NewReader(remainingData), conn),
}
return nil, wrappedConn, nil
}
// Invalid PROXY protocol, but might be regular TLS - treat as such
logger.Debug("Invalid PROXY protocol from trusted upstream %s, treating as regular TLS connection: %s", remoteHost, headerLine)