QGrpcHttp2Channel: add reconnect backoff and connect timeout
QtGrpc reconnected immediately after every connection failure, with no
delay between attempts. A flapping or malicious server could therefore
drive the client into an unbounded, tight reconnect loop, exhausting
file descriptors, CPU, and network bandwidth (availability / DoS).
Add QGrpcChannelOptions::setInitialReconnectBackoff() and
setMaximumReconnectBackoff() to rate-limit reconnection attempts with
exponential backoff and jitter, and setConnectTimeout() to bound
how long a single attempt may hang before it is aborted. Defaults match
the gRPC specification: 1 s initial, 120 s maximum, 20 s connect
timeout. The backoff resets once the server acknowledges the connection
via the HTTP/2 SETTINGS frame.
QT_GRPC_INITIAL_RECONNECT_BACKOFF_MS,
QT_GRPC_MAXIMUM_RECONNECT_BACKOFF_MS, and
QT_GRPC_CONNECT_TIMEOUT_MS provide global fallbacks.
Move QGrpcChannelOptionsPrivate into a new header. We don't want to
expose the tri-state with the env-var since this is not channel agnostic
and is kept reserved for our own h2channel implementation.
Backport to older branches manually: The env var approach will get
picked back manually, since it's the easiest to avoid conflict hell.
[ChangeLog][QtGrpc][QGrpcChannelOptions] Added
setInitialReconnectBackoff(), setMaximumReconnectBackoff(), and
setConnectTimeout() to rate-limit reconnection attempts after
a connection failure. The defaults (1 s, 120 s, and 20 s) match the
gRPC specification. The environment variables
QT_GRPC_INITIAL_RECONNECT_BACKOFF_MS,
QT_GRPC_MAXIMUM_RECONNECT_BACKOFF_MS, and
QT_GRPC_CONNECT_TIMEOUT_MS provide global overrides.
Fixes: QTBUG-147829
Change-Id: I9f7c6daa8305c69e2b3065abe139ee3ca746286c
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Mate Barany <mate.barany@qt.io>