h2load: Add --max-udp-payload-size option

This commit is contained in:
Tatsuhiro Tsujikawa 2021-09-07 14:42:35 +09:00
parent 1657a425c1
commit 7ea57eaa18
3 changed files with 38 additions and 13 deletions

View File

@ -124,7 +124,8 @@ Config::Config()
base_uri_unix(false),
unix_addr{},
rps(0.),
no_udp_gso(false) {}
no_udp_gso(false),
max_udp_payload_size(0) {}
Config::~Config() {
if (addrs) {
@ -2247,6 +2248,8 @@ Options:
<< config.groups << R"(
--no-udp-gso
Disable UDP GSO.
--max-udp-payload-size=<SIZE>
Specify the maximum outgoing UDP datagram payload size.
-v, --verbose
Output debug information.
--version Display version information and exit.
@ -2312,6 +2315,7 @@ int main(int argc, char **argv) {
{"tls13-ciphers", required_argument, &flag, 14},
{"no-udp-gso", no_argument, &flag, 15},
{"qlog-file-base", required_argument, &flag, 16},
{"max-udp-payload-size", required_argument, &flag, 17},
{nullptr, 0, nullptr, 0}};
int option_index = 0;
auto c = getopt_long(argc, argv,
@ -2578,6 +2582,22 @@ int main(int argc, char **argv) {
// --qlog-file-base
qlog_base = optarg;
break;
case 17: {
// --max-udp-payload-size
auto n = util::parse_uint_with_unit(optarg);
if (n == -1) {
std::cerr << "--max-udp-payload-size: bad option value: " << optarg
<< std::endl;
exit(EXIT_FAILURE);
}
if (n > 64_k) {
std::cerr << "--max-udp-payload-size: must not exceed 65536"
<< std::endl;
exit(EXIT_FAILURE);
}
config.max_udp_payload_size = n;
break;
}
}
break;
default:

View File

@ -133,6 +133,8 @@ struct Config {
double rps;
// Disables GSO for UDP connections.
bool no_udp_gso;
// The maximum UDP datagram payload size to send.
size_t max_udp_payload_size;
Config();
~Config();
@ -336,7 +338,6 @@ struct Client {
ev_timer pkt_timer;
ngtcp2_conn *conn;
quic::Error last_error;
size_t max_pktlen;
bool close_requested;
FILE *qlog_file;
} quic;

View File

@ -305,8 +305,6 @@ int Client::quic_init(const sockaddr *local_addr, socklen_t local_addrlen,
SSL_set_quic_use_legacy_codepoint(ssl, 0);
}
quic.max_pktlen = NGTCP2_MAX_UDP_PAYLOAD_SIZE;
auto callbacks = ngtcp2_callbacks{
ngtcp2_crypto_client_initial_cb,
nullptr, // recv_client_initial
@ -373,6 +371,10 @@ int Client::quic_init(const sockaddr *local_addr, socklen_t local_addrlen,
}
settings.qlog.write = qlog_write_cb;
}
if (config->max_udp_payload_size) {
settings.max_udp_payload_size = config->max_udp_payload_size;
settings.no_udp_payload_size_shaping = 1;
}
ngtcp2_transport_params params;
ngtcp2_transport_params_default(&params);
@ -424,7 +426,7 @@ void Client::quic_close_connection() {
return;
}
std::array<uint8_t, 1500> buf;
std::array<uint8_t, NGTCP2_MAX_UDP_PAYLOAD_SIZE> buf;
ngtcp2_ssize nwrite;
ngtcp2_path_storage ps;
ngtcp2_path_storage_zero(&ps);
@ -434,12 +436,12 @@ void Client::quic_close_connection() {
return;
case quic::ErrorType::Transport:
nwrite = ngtcp2_conn_write_connection_close(
quic.conn, &ps.path, nullptr, buf.data(), quic.max_pktlen,
quic.conn, &ps.path, nullptr, buf.data(), buf.size(),
quic.last_error.code, timestamp(worker->loop));
break;
case quic::ErrorType::Application:
nwrite = ngtcp2_conn_write_application_close(
quic.conn, &ps.path, nullptr, buf.data(), quic.max_pktlen,
quic.conn, &ps.path, nullptr, buf.data(), buf.size(),
quic.last_error.code, timestamp(worker->loop));
break;
default:
@ -575,12 +577,14 @@ int Client::write_quic() {
std::array<nghttp3_vec, 16> vec;
size_t pktcnt = 0;
auto max_udp_payload_size =
ngtcp2_conn_get_path_max_udp_payload_size(quic.conn);
size_t max_pktcnt =
#ifdef UDP_SEGMENT
worker->config->no_udp_gso
? 1
: std::min(static_cast<size_t>(10),
static_cast<size_t>(64_k / quic.max_pktlen));
static_cast<size_t>(64_k / max_udp_payload_size));
#else // !UDP_SEGMENT
1;
#endif // !UDP_SEGMENT
@ -614,8 +618,8 @@ int Client::write_quic() {
}
auto nwrite = ngtcp2_conn_writev_stream(
quic.conn, &ps.path, nullptr, bufpos, quic.max_pktlen, &ndatalen, flags,
stream_id, reinterpret_cast<const ngtcp2_vec *>(v), vcnt,
quic.conn, &ps.path, nullptr, bufpos, max_udp_payload_size, &ndatalen,
flags, stream_id, reinterpret_cast<const ngtcp2_vec *>(v), vcnt,
timestamp(worker->loop));
if (nwrite < 0) {
switch (nwrite) {
@ -650,7 +654,7 @@ int Client::write_quic() {
if (nwrite == 0) {
if (bufpos - buf.data()) {
write_udp(ps.path.remote.addr, ps.path.remote.addrlen, buf.data(),
bufpos - buf.data(), quic.max_pktlen);
bufpos - buf.data(), max_udp_payload_size);
}
return 0;
}
@ -659,9 +663,9 @@ int Client::write_quic() {
// Assume that the path does not change.
if (++pktcnt == max_pktcnt ||
static_cast<size_t>(nwrite) < quic.max_pktlen) {
static_cast<size_t>(nwrite) < max_udp_payload_size) {
write_udp(ps.path.remote.addr, ps.path.remote.addrlen, buf.data(),
bufpos - buf.data(), quic.max_pktlen);
bufpos - buf.data(), max_udp_payload_size);
signal_write();
return 0;
}