Better pack UDP packets in one GSO write

This commit is contained in:
Tatsuhiro Tsujikawa 2022-05-16 21:20:40 +09:00
parent 9d159596a4
commit 0c77d6b943
2 changed files with 14 additions and 4 deletions

View File

@ -711,6 +711,8 @@ int Client::write_quic() {
std::array<nghttp3_vec, 16> vec; std::array<nghttp3_vec, 16> vec;
size_t pktcnt = 0; size_t pktcnt = 0;
auto max_udp_payload_size = ngtcp2_conn_get_max_udp_payload_size(quic.conn); auto max_udp_payload_size = ngtcp2_conn_get_max_udp_payload_size(quic.conn);
auto path_max_udp_payload_size =
ngtcp2_conn_get_path_max_udp_payload_size(quic.conn);
size_t max_pktcnt = size_t max_pktcnt =
#ifdef UDP_SEGMENT #ifdef UDP_SEGMENT
worker->config->no_udp_gso worker->config->no_udp_gso
@ -803,7 +805,9 @@ int Client::write_quic() {
if (pktcnt == 0) { if (pktcnt == 0) {
gso_size = nwrite; gso_size = nwrite;
} else if (static_cast<size_t>(nwrite) != gso_size) { } else if (static_cast<size_t>(nwrite) > gso_size ||
(gso_size > path_max_udp_payload_size &&
static_cast<size_t>(nwrite) != gso_size)) {
auto data = quic.tx.data.get(); auto data = quic.tx.data.get();
auto datalen = bufpos - quic.tx.data.get() - nwrite; auto datalen = bufpos - quic.tx.data.get() - nwrite;
rv = write_udp(ps.path.remote.addr, ps.path.remote.addrlen, data, datalen, rv = write_udp(ps.path.remote.addr, ps.path.remote.addrlen, data, datalen,
@ -825,7 +829,7 @@ int Client::write_quic() {
} }
// Assume that the path does not change. // Assume that the path does not change.
if (++pktcnt == max_pktcnt) { if (++pktcnt == max_pktcnt || static_cast<size_t>(nwrite) < gso_size) {
auto data = quic.tx.data.get(); auto data = quic.tx.data.get();
auto datalen = bufpos - quic.tx.data.get(); auto datalen = bufpos - quic.tx.data.get();
rv = write_udp(ps.path.remote.addr, ps.path.remote.addrlen, data, datalen, rv = write_udp(ps.path.remote.addr, ps.path.remote.addrlen, data, datalen,

View File

@ -706,6 +706,10 @@ int Http3Upstream::on_write() {
int Http3Upstream::write_streams() { int Http3Upstream::write_streams() {
std::array<nghttp3_vec, 16> vec; std::array<nghttp3_vec, 16> vec;
auto max_udp_payload_size = ngtcp2_conn_get_max_udp_payload_size(conn_); auto max_udp_payload_size = ngtcp2_conn_get_max_udp_payload_size(conn_);
#ifdef UDP_SEGMENT
auto path_max_udp_payload_size =
ngtcp2_conn_get_path_max_udp_payload_size(conn_);
#endif // UDP_SEGMENT
size_t max_pktcnt = size_t max_pktcnt =
std::min(static_cast<size_t>(64_k), ngtcp2_conn_get_send_quantum(conn_)) / std::min(static_cast<size_t>(64_k), ngtcp2_conn_get_send_quantum(conn_)) /
max_udp_payload_size; max_udp_payload_size;
@ -860,7 +864,9 @@ int Http3Upstream::write_streams() {
gso_size = nwrite; gso_size = nwrite;
} else if (!ngtcp2_path_eq(&prev_ps.path, &ps.path) || } else if (!ngtcp2_path_eq(&prev_ps.path, &ps.path) ||
prev_pi.ecn != pi.ecn || prev_pi.ecn != pi.ecn ||
static_cast<size_t>(nwrite) != gso_size) { static_cast<size_t>(nwrite) > gso_size ||
(gso_size > path_max_udp_payload_size &&
static_cast<size_t>(nwrite) != gso_size)) {
auto faddr = static_cast<UpstreamAddr *>(prev_ps.path.user_data); auto faddr = static_cast<UpstreamAddr *>(prev_ps.path.user_data);
auto data = tx_.data.get(); auto data = tx_.data.get();
auto datalen = bufpos - data - nwrite; auto datalen = bufpos - data - nwrite;
@ -902,7 +908,7 @@ int Http3Upstream::write_streams() {
return 0; return 0;
} }
if (++pktcnt == max_pktcnt) { if (++pktcnt == max_pktcnt || static_cast<size_t>(nwrite) < gso_size) {
auto faddr = static_cast<UpstreamAddr *>(ps.path.user_data); auto faddr = static_cast<UpstreamAddr *>(ps.path.user_data);
auto data = tx_.data.get(); auto data = tx_.data.get();
auto datalen = bufpos - data; auto datalen = bufpos - data;