nghttpx: Send ECN

This commit is contained in:
Tatsuhiro Tsujikawa 2021-11-05 23:23:00 +09:00
parent 7eb179069d
commit deae6c95b1
7 changed files with 61 additions and 29 deletions

View File

@ -712,6 +712,9 @@ int Http3Upstream::write_streams() {
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;
ngtcp2_pkt_info pi; ngtcp2_pkt_info pi;
#ifdef UDP_SEGMENT
ngtcp2_pkt_info prev_pi;
#endif // UDP_SEGMENT
uint8_t *bufpos = buf.data(); uint8_t *bufpos = buf.data();
ngtcp2_path_storage ps, prev_ps; ngtcp2_path_storage ps, prev_ps;
size_t pktcnt = 0; size_t pktcnt = 0;
@ -815,7 +818,8 @@ int Http3Upstream::write_streams() {
send_packet(static_cast<UpstreamAddr *>(prev_ps.path.user_data), send_packet(static_cast<UpstreamAddr *>(prev_ps.path.user_data),
prev_ps.path.remote.addr, prev_ps.path.remote.addrlen, prev_ps.path.remote.addr, prev_ps.path.remote.addrlen,
prev_ps.path.local.addr, prev_ps.path.local.addrlen, prev_ps.path.local.addr, prev_ps.path.local.addrlen,
buf.data(), bufpos - buf.data(), max_udp_payload_size); prev_pi, buf.data(), bufpos - buf.data(),
max_udp_payload_size);
reset_idle_timer(); reset_idle_timer();
} }
@ -832,17 +836,19 @@ int Http3Upstream::write_streams() {
#ifdef UDP_SEGMENT #ifdef UDP_SEGMENT
if (pktcnt == 0) { if (pktcnt == 0) {
ngtcp2_path_copy(&prev_ps.path, &ps.path); ngtcp2_path_copy(&prev_ps.path, &ps.path);
} else if (!ngtcp2_path_eq(&prev_ps.path, &ps.path)) { prev_pi = pi;
} else if (!ngtcp2_path_eq(&prev_ps.path, &ps.path) ||
prev_pi.ecn != pi.ecn) {
send_packet(static_cast<UpstreamAddr *>(prev_ps.path.user_data), send_packet(static_cast<UpstreamAddr *>(prev_ps.path.user_data),
prev_ps.path.remote.addr, prev_ps.path.remote.addrlen, prev_ps.path.remote.addr, prev_ps.path.remote.addrlen,
prev_ps.path.local.addr, prev_ps.path.local.addrlen, prev_ps.path.local.addr, prev_ps.path.local.addrlen, prev_pi,
buf.data(), bufpos - buf.data() - nwrite, buf.data(), bufpos - buf.data() - nwrite,
max_udp_payload_size); max_udp_payload_size);
send_packet(static_cast<UpstreamAddr *>(ps.path.user_data), send_packet(static_cast<UpstreamAddr *>(ps.path.user_data),
ps.path.remote.addr, ps.path.remote.addrlen, ps.path.remote.addr, ps.path.remote.addrlen,
ps.path.local.addr, ps.path.local.addrlen, bufpos - nwrite, ps.path.local.addr, ps.path.local.addrlen, pi,
nwrite, max_udp_payload_size); bufpos - nwrite, nwrite, max_udp_payload_size);
ngtcp2_conn_update_pkt_tx_time(conn_, ts); ngtcp2_conn_update_pkt_tx_time(conn_, ts);
reset_idle_timer(); reset_idle_timer();
@ -856,7 +862,7 @@ int Http3Upstream::write_streams() {
static_cast<size_t>(nwrite) < max_udp_payload_size) { static_cast<size_t>(nwrite) < max_udp_payload_size) {
send_packet(static_cast<UpstreamAddr *>(ps.path.user_data), send_packet(static_cast<UpstreamAddr *>(ps.path.user_data),
ps.path.remote.addr, ps.path.remote.addrlen, ps.path.remote.addr, ps.path.remote.addrlen,
ps.path.local.addr, ps.path.local.addrlen, buf.data(), ps.path.local.addr, ps.path.local.addrlen, pi, buf.data(),
bufpos - buf.data(), max_udp_payload_size); bufpos - buf.data(), max_udp_payload_size);
ngtcp2_conn_update_pkt_tx_time(conn_, ts); ngtcp2_conn_update_pkt_tx_time(conn_, ts);
@ -869,7 +875,7 @@ int Http3Upstream::write_streams() {
#else // !UDP_SEGMENT #else // !UDP_SEGMENT
send_packet(static_cast<UpstreamAddr *>(ps.path.user_data), send_packet(static_cast<UpstreamAddr *>(ps.path.user_data),
ps.path.remote.addr, ps.path.remote.addrlen, ps.path.local.addr, ps.path.remote.addr, ps.path.remote.addrlen, ps.path.local.addr,
ps.path.local.addrlen, buf.data(), bufpos - buf.data(), 0); ps.path.local.addrlen, pi, buf.data(), bufpos - buf.data(), 0);
if (++pktcnt == max_pktcnt) { if (++pktcnt == max_pktcnt) {
ngtcp2_conn_update_pkt_tx_time(conn_, ts); ngtcp2_conn_update_pkt_tx_time(conn_, ts);
@ -1411,7 +1417,7 @@ void Http3Upstream::on_handler_delete() {
send_packet(static_cast<UpstreamAddr *>(ps.path.user_data), send_packet(static_cast<UpstreamAddr *>(ps.path.user_data),
ps.path.remote.addr, ps.path.remote.addrlen, ps.path.local.addr, ps.path.remote.addr, ps.path.remote.addrlen, ps.path.local.addr,
ps.path.local.addrlen, conn_close_.data(), nwrite, 0); ps.path.local.addrlen, pi, conn_close_.data(), nwrite, 0);
} }
auto d = auto d =
@ -1716,10 +1722,10 @@ int Http3Upstream::on_read(const UpstreamAddr *faddr,
int Http3Upstream::send_packet(const UpstreamAddr *faddr, int Http3Upstream::send_packet(const UpstreamAddr *faddr,
const sockaddr *remote_sa, size_t remote_salen, const sockaddr *remote_sa, size_t remote_salen,
const sockaddr *local_sa, size_t local_salen, const sockaddr *local_sa, size_t local_salen,
const uint8_t *data, size_t datalen, const ngtcp2_pkt_info &pi, const uint8_t *data,
size_t gso_size) { size_t datalen, size_t gso_size) {
auto rv = quic_send_packet(faddr, remote_sa, remote_salen, local_sa, auto rv = quic_send_packet(faddr, remote_sa, remote_salen, local_sa,
local_salen, data, datalen, gso_size); local_salen, pi, data, datalen, gso_size);
switch (rv) { switch (rv) {
case 0: case 0:
return 0; return 0;
@ -1776,7 +1782,7 @@ int Http3Upstream::handle_error() {
send_packet(static_cast<UpstreamAddr *>(ps.path.user_data), send_packet(static_cast<UpstreamAddr *>(ps.path.user_data),
ps.path.remote.addr, ps.path.remote.addrlen, ps.path.local.addr, ps.path.remote.addr, ps.path.remote.addrlen, ps.path.local.addr,
ps.path.local.addrlen, conn_close_.data(), nwrite, 0); ps.path.local.addrlen, pi, conn_close_.data(), nwrite, 0);
return -1; return -1;
} }

View File

@ -151,8 +151,8 @@ public:
void idle_close(); void idle_close();
int send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa, int send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa,
size_t remote_salen, const sockaddr *local_sa, size_t remote_salen, const sockaddr *local_sa,
size_t local_salen, const uint8_t *data, size_t datalen, size_t local_salen, const ngtcp2_pkt_info &pi,
size_t gso_size); const uint8_t *data, size_t datalen, size_t gso_size);
void qlog_write(const void *data, size_t datalen, bool fin); void qlog_write(const void *data, size_t datalen, bool fin);
int open_qlog_file(const StringRef &dir, const ngtcp2_cid &scid) const; int open_qlog_file(const StringRef &dir, const ngtcp2_cid &scid) const;

View File

@ -57,8 +57,8 @@ ngtcp2_tstamp quic_timestamp() {
int quic_send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa, int quic_send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa,
size_t remote_salen, const sockaddr *local_sa, size_t remote_salen, const sockaddr *local_sa,
size_t local_salen, const uint8_t *data, size_t datalen, size_t local_salen, const ngtcp2_pkt_info &pi,
size_t gso_size) { const uint8_t *data, size_t datalen, size_t gso_size) {
iovec msg_iov = {const_cast<uint8_t *>(data), datalen}; iovec msg_iov = {const_cast<uint8_t *>(data), datalen};
msghdr msg{}; msghdr msg{};
msg.msg_name = const_cast<sockaddr *>(remote_sa); msg.msg_name = const_cast<sockaddr *>(remote_sa);
@ -123,6 +123,8 @@ int quic_send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa,
msg.msg_controllen = controllen; msg.msg_controllen = controllen;
util::fd_set_send_ecn(faddr->fd, local_sa->sa_family, pi.ecn);
ssize_t nwrite; ssize_t nwrite;
do { do {
@ -142,7 +144,8 @@ int quic_send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa,
LOG(INFO) << "QUIC sent packet: local=" LOG(INFO) << "QUIC sent packet: local="
<< util::to_numeric_addr(local_sa, local_salen) << util::to_numeric_addr(local_sa, local_salen)
<< " remote=" << util::to_numeric_addr(remote_sa, remote_salen) << " remote=" << util::to_numeric_addr(remote_sa, remote_salen)
<< " " << nwrite << " bytes"; << " ecn=" << log::hex << pi.ecn << log::dec << " " << nwrite
<< " bytes";
} }
return 0; return 0;

View File

@ -81,8 +81,8 @@ ngtcp2_tstamp quic_timestamp();
int quic_send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa, int quic_send_packet(const UpstreamAddr *faddr, const sockaddr *remote_sa,
size_t remote_salen, const sockaddr *local_sa, size_t remote_salen, const sockaddr *local_sa,
size_t local_salen, const uint8_t *data, size_t datalen, size_t local_salen, const ngtcp2_pkt_info &pi,
size_t gso_size); const uint8_t *data, size_t datalen, size_t gso_size);
int generate_quic_retry_connection_id(ngtcp2_cid &cid, size_t cidlen, int generate_quic_retry_connection_id(ngtcp2_cid &cid, size_t cidlen,
const uint8_t *server_id, uint8_t km_id, const uint8_t *server_id, uint8_t km_id,

View File

@ -491,8 +491,8 @@ int QUICConnectionHandler::send_retry(
buf.resize(nwrite); buf.resize(nwrite);
quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len, quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len,
&local_addr.su.sa, local_addr.len, buf.data(), buf.size(), &local_addr.su.sa, local_addr.len, ngtcp2_pkt_info{},
0); buf.data(), buf.size(), 0);
if (generate_quic_hashed_connection_id(idcid, remote_addr, local_addr, if (generate_quic_hashed_connection_id(idcid, remote_addr, local_addr,
idcid) != 0) { idcid) != 0) {
@ -541,8 +541,8 @@ int QUICConnectionHandler::send_version_negotiation(
} }
return quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len, return quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len,
&local_addr.su.sa, local_addr.len, buf.data(), nwrite, &local_addr.su.sa, local_addr.len, ngtcp2_pkt_info{},
0); buf.data(), nwrite, 0);
} }
int QUICConnectionHandler::send_stateless_reset(const UpstreamAddr *faddr, int QUICConnectionHandler::send_stateless_reset(const UpstreamAddr *faddr,
@ -604,8 +604,8 @@ int QUICConnectionHandler::send_stateless_reset(const UpstreamAddr *faddr,
} }
return quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len, return quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len,
&local_addr.su.sa, local_addr.len, buf.data(), nwrite, &local_addr.su.sa, local_addr.len, ngtcp2_pkt_info{},
0); buf.data(), nwrite, 0);
} }
int QUICConnectionHandler::send_connection_close( int QUICConnectionHandler::send_connection_close(
@ -630,8 +630,8 @@ int QUICConnectionHandler::send_connection_close(
} }
return quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len, return quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len,
&local_addr.su.sa, local_addr.len, buf.data(), nwrite, &local_addr.su.sa, local_addr.len, ngtcp2_pkt_info{},
0); buf.data(), nwrite, 0);
} }
void QUICConnectionHandler::add_connection_id(const ngtcp2_cid &cid, void QUICConnectionHandler::add_connection_id(const ngtcp2_cid &cid,
@ -726,8 +726,8 @@ int CloseWait::handle_packet(const UpstreamAddr *faddr,
} }
if (quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len, if (quic_send_packet(faddr, &remote_addr.su.sa, remote_addr.len,
&local_addr.su.sa, local_addr.len, pkt.data(), &local_addr.su.sa, local_addr.len, ngtcp2_pkt_info{},
pkt.size(), 0) != 0) { pkt.data(), pkt.size(), 0) != 0) {
return -1; return -1;
} }

View File

@ -1770,6 +1770,27 @@ int fd_set_recv_ecn(int fd, int family) {
return -1; return -1;
} }
int fd_set_send_ecn(int fd, int family, unsigned int ecn) {
switch (family) {
case AF_INET:
if (setsockopt(fd, IPPROTO_IP, IP_TOS, &ecn,
static_cast<socklen_t>(sizeof(ecn))) == -1) {
return -1;
}
return 0;
case AF_INET6:
if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &ecn,
static_cast<socklen_t>(sizeof(ecn))) == -1) {
return -1;
}
return 0;
}
return -1;
}
#endif // ENABLE_HTTP3 #endif // ENABLE_HTTP3
} // namespace util } // namespace util

View File

@ -922,6 +922,8 @@ int msghdr_get_local_addr(Address &dest, msghdr *msg, int family);
unsigned int msghdr_get_ecn(msghdr *msg, int family); unsigned int msghdr_get_ecn(msghdr *msg, int family);
int fd_set_recv_ecn(int fd, int family); int fd_set_recv_ecn(int fd, int family);
int fd_set_send_ecn(int fd, int family, unsigned int ecn);
#endif // ENABLE_HTTP3 #endif // ENABLE_HTTP3
} // namespace util } // namespace util