Merge commit from fork

Add configurable resource limits to prevent potential DoS vectors
via connection/stream exhaustion on gRPC, HTTPS, and HTTPS/3 servers.

New configuration plugins:
- grpc_server: configure max_streams, max_connections
- https: configure max_connections
- https3: configure max_streams

Changes:
- Use netutil.LimitListener for connection limiting
- Use gRPC MaxConcurrentStreams and message size limits
- Add QUIC MaxIncomingStreams for HTTPS/3 stream limiting
- Set secure defaults: 256 max streams, 200 max connections
- Setting any limit to 0 means unbounded/fallback to previous impl

Defaults are applied automatically when plugins are omitted from
config.

Includes tests and integration tests.

Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
This commit is contained in:
Ville Vesilehto
2025-12-18 05:08:59 +02:00
committed by GitHub
parent 0fb05f225c
commit 0d8cbb1a6b
24 changed files with 1689 additions and 24 deletions

View File

@@ -156,12 +156,29 @@ func (s *ServerQUIC) serveQUICConnection(conn *quic.Conn) {
return
}
// Use a bounded worker pool
s.streamProcessPool <- struct{}{} // Acquire a worker slot, may block
go func(st *quic.Stream, cn *quic.Conn) {
defer func() { <-s.streamProcessPool }() // Release worker slot
s.serveQUICStream(st, cn)
}(stream, conn)
// Use a bounded worker pool with context cancellation
select {
case s.streamProcessPool <- struct{}{}:
// Got worker slot immediately
go func(st *quic.Stream, cn *quic.Conn) {
defer func() { <-s.streamProcessPool }() // Release worker slot
s.serveQUICStream(st, cn)
}(stream, conn)
default:
// Worker pool full, check for context cancellation
go func(st *quic.Stream, cn *quic.Conn) {
select {
case s.streamProcessPool <- struct{}{}:
// Got worker slot after waiting
defer func() { <-s.streamProcessPool }() // Release worker slot
s.serveQUICStream(st, cn)
case <-conn.Context().Done():
// Connection context was cancelled while waiting
st.Close()
return
}
}(stream, conn)
}
}
}