diff --git a/src/h2load.cc b/src/h2load.cc index 1ab52c0b..3fa09ab1 100644 --- a/src/h2load.cc +++ b/src/h2load.cc @@ -106,6 +106,7 @@ Config::Config() max_concurrent_streams(1), window_bits(30), connection_window_bits(30), + max_frame_size(16_k), rate(0), rate_period(1.0), duration(0.0), @@ -2109,6 +2110,11 @@ Options: http/1.1 is used, this specifies the number of HTTP pipelining requests in-flight. Default: 1 + -f, --max-frame-size= + Maximum frame size that the local endpoint is willing to + receive. + Default: )" + << util::utos_unit(config.max_frame_size) << R"( -w, --window-bits= Sets the stream level initial window size to (2**)-1. For QUIC, is capped to 26 (roughly 64MiB). @@ -2301,6 +2307,7 @@ int main(int argc, char **argv) { {"threads", required_argument, nullptr, 't'}, {"max-concurrent-streams", required_argument, nullptr, 'm'}, {"window-bits", required_argument, nullptr, 'w'}, + {"max-frame-size", required_argument, nullptr, 'f'}, {"connection-window-bits", required_argument, nullptr, 'W'}, {"input-file", required_argument, nullptr, 'i'}, {"header", required_argument, nullptr, 'H'}, @@ -2332,7 +2339,7 @@ int main(int argc, char **argv) { {nullptr, 0, nullptr, 0}}; int option_index = 0; auto c = getopt_long(argc, argv, - "hvW:c:d:m:n:p:t:w:H:i:r:T:N:D:B:", long_options, + "hvW:c:d:m:n:p:t:w:f:H:i:r:T:N:D:B:", long_options, &option_index); if (c == -1) { break; @@ -2378,6 +2385,24 @@ int main(int argc, char **argv) { } break; } + case 'f': { + auto n = util::parse_uint_with_unit(optarg); + if (n == -1) { + std::cerr << "--max-frame-size: bad option value: " << optarg + << std::endl; + exit(EXIT_FAILURE); + } + if (static_cast(n) < 16_k) { + std::cerr << "--max-frame-size: minimum 16384" << std::endl; + exit(EXIT_FAILURE); + } + if (static_cast(n) > 16_m - 1) { + std::cerr << "--max-frame-size: maximum 16777215" << std::endl; + exit(EXIT_FAILURE); + } + config.max_frame_size = n; + break; + } case 'H': { char *header = optarg; // Skip first possible ':' in the header name diff --git a/src/h2load.h b/src/h2load.h index 590a6cd2..f1083a1d 100644 --- a/src/h2load.h +++ b/src/h2load.h @@ -95,6 +95,7 @@ struct Config { ssize_t max_concurrent_streams; size_t window_bits; size_t connection_window_bits; + size_t max_frame_size; // rate at which connections should be made size_t rate; ev_tstamp rate_period; diff --git a/src/h2load_http2_session.cc b/src/h2load_http2_session.cc index 06c474c0..9cafa0e3 100644 --- a/src/h2load_http2_session.cc +++ b/src/h2load_http2_session.cc @@ -215,7 +215,7 @@ void Http2Session::on_connect() { nghttp2_option_del(opt); - std::array iv; + std::array iv; size_t niv = 2; iv[0].settings_id = NGHTTP2_SETTINGS_ENABLE_PUSH; iv[0].value = 0; @@ -227,6 +227,11 @@ void Http2Session::on_connect() { iv[niv].value = config->header_table_size; ++niv; } + if (config->max_frame_size != 16_k) { + iv[niv].settings_id = NGHTTP2_SETTINGS_MAX_FRAME_SIZE; + iv[niv].value = config->max_frame_size; + ++niv; + } rv = nghttp2_submit_settings(session_, NGHTTP2_FLAG_NONE, iv.data(), niv);