From e291396644248a677f86d5bfd8b8df5c19308abf Mon Sep 17 00:00:00 2001 From: yang-g Date: Mon, 17 Jun 2019 22:59:55 -0700 Subject: [PATCH] Cap deadline to 99999999 seconds on wire --- src/core/lib/transport/timeout_encoding.cc | 7 +++++++ src/core/lib/transport/timeout_encoding.h | 5 +++-- test/core/transport/timeout_encoding_test.cc | 3 +++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/core/lib/transport/timeout_encoding.cc b/src/core/lib/transport/timeout_encoding.cc index fe22c15fa6d..26d4b4a426f 100644 --- a/src/core/lib/transport/timeout_encoding.cc +++ b/src/core/lib/transport/timeout_encoding.cc @@ -44,6 +44,9 @@ static int64_t round_up_to_three_sig_figs(int64_t x) { /* encode our minimum viable timeout value */ static void enc_tiny(char* buffer) { memcpy(buffer, "1n", 3); } +/* encode our maximum timeout value, about 1157 days */ +static void enc_huge(char* buffer) { memcpy(buffer, "99999999S", 10); } + static void enc_ext(char* buffer, int64_t value, char ext) { int n = int64_ttoa(value, buffer); buffer[n] = ext; @@ -51,6 +54,7 @@ static void enc_ext(char* buffer, int64_t value, char ext) { } static void enc_seconds(char* buffer, int64_t sec) { + sec = round_up_to_three_sig_figs(sec); if (sec % 3600 == 0) { enc_ext(buffer, sec / 3600, 'H'); } else if (sec % 60 == 0) { @@ -74,10 +78,13 @@ static void enc_millis(char* buffer, int64_t x) { } void grpc_http2_encode_timeout(grpc_millis timeout, char* buffer) { + const grpc_millis kMaxTimeout = 99999999000; if (timeout <= 0) { enc_tiny(buffer); } else if (timeout < 1000 * GPR_MS_PER_SEC) { enc_millis(buffer, timeout); + } else if (timeout >= kMaxTimeout) { + enc_huge(buffer); } else { enc_seconds(buffer, timeout / GPR_MS_PER_SEC + (timeout % GPR_MS_PER_SEC != 0)); diff --git a/src/core/lib/transport/timeout_encoding.h b/src/core/lib/transport/timeout_encoding.h index cc0d37452fd..c87ff39d491 100644 --- a/src/core/lib/transport/timeout_encoding.h +++ b/src/core/lib/transport/timeout_encoding.h @@ -27,10 +27,11 @@ #include "src/core/lib/gpr/string.h" #include "src/core/lib/iomgr/exec_ctx.h" -#define GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE (GPR_LTOA_MIN_BUFSIZE + 1) +#define GRPC_HTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE 10 /* Encode/decode timeouts to the GRPC over HTTP/2 format; - encoding may round up arbitrarily */ + encoding may round up arbitrarily. If the timeout is larger than about 1157 + days, it will be capped and "99999999S" will be sent on the wire. */ void grpc_http2_encode_timeout(grpc_millis timeout, char* buffer); int grpc_http2_decode_timeout(const grpc_slice& text, grpc_millis* timeout); diff --git a/test/core/transport/timeout_encoding_test.cc b/test/core/transport/timeout_encoding_test.cc index 22e68fe5540..61c3061d0c1 100644 --- a/test/core/transport/timeout_encoding_test.cc +++ b/test/core/transport/timeout_encoding_test.cc @@ -62,6 +62,9 @@ void test_encoding(void) { assert_encodes_as(20 * 60 * GPR_MS_PER_SEC, "20M"); assert_encodes_as(60 * 60 * GPR_MS_PER_SEC, "1H"); assert_encodes_as(10 * 60 * 60 * GPR_MS_PER_SEC, "10H"); + assert_encodes_as(60 * 60 * GPR_MS_PER_SEC - 100, "1H"); + assert_encodes_as(100 * 60 * 60 * GPR_MS_PER_SEC, "100H"); + assert_encodes_as(100000000000, "99999999S"); } static void assert_decodes_as(const char* buffer, grpc_millis expected) {