Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
quic: update quic impl to use latest ngtcp2/nghttp3
  • Loading branch information
jasnell committed Dec 27, 2023
commit 8ce48d6e5cc8915b08c95da0b78fb7b85149387d
26 changes: 13 additions & 13 deletions src/quic/application.cc
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ BaseObjectPtr<Packet> Session::Application::CreateStreamDataPacket() {
return Packet::Create(env(),
session_->endpoint_.get(),
session_->remote_address_,
ngtcp2_conn_get_max_udp_payload_size(*session_),
ngtcp2_conn_get_max_tx_udp_payload_size(*session_),
"stream data");
}

Expand Down Expand Up @@ -291,18 +291,18 @@ ssize_t Session::Application::WriteVStream(PathStorage* path,
uint32_t flags = NGTCP2_WRITE_STREAM_FLAG_NONE;
if (stream_data.remaining > 0) flags |= NGTCP2_WRITE_STREAM_FLAG_MORE;
if (stream_data.fin) flags |= NGTCP2_WRITE_STREAM_FLAG_FIN;
ssize_t ret =
ngtcp2_conn_writev_stream(*session_,
&path->path,
nullptr,
buf,
ngtcp2_conn_get_max_udp_payload_size(*session_),
ndatalen,
flags,
stream_data.id,
stream_data.buf,
stream_data.count,
uv_hrtime());
ssize_t ret = ngtcp2_conn_writev_stream(
*session_,
&path->path,
nullptr,
buf,
ngtcp2_conn_get_max_tx_udp_payload_size(*session_),
ndatalen,
flags,
stream_data.id,
stream_data.buf,
stream_data.count,
uv_hrtime());
return ret;
}

Expand Down
5 changes: 2 additions & 3 deletions src/quic/bindingdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ class Endpoint;
class Packet;

enum class Side {
CLIENT = NGTCP2_CRYPTO_SIDE_CLIENT,
SERVER = NGTCP2_CRYPTO_SIDE_SERVER,
CLIENT,
SERVER,
};

enum class EndpointLabel {
Expand Down Expand Up @@ -119,7 +119,6 @@ constexpr size_t kMaxVectorCount = 16;
V(alpn, "alpn") \
V(application_options, "application") \
V(bbr, "bbr") \
V(bbr2, "bbr2") \
V(ca, "ca") \
V(certs, "certs") \
V(cc_algorithm, "cc") \
Expand Down
24 changes: 12 additions & 12 deletions src/quic/data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,15 @@ std::string TypeName(QuicError::Type type) {
} // namespace

QuicError::QuicError(const std::string_view reason)
: reason_(reason), ptr_(&error_) {}
: reason_(reason), error_(), ptr_(&error_) {
ngtcp2_ccerr_default(&error_);
}

QuicError::QuicError(const ngtcp2_connection_close_error* ptr)
QuicError::QuicError(const ngtcp2_ccerr* ptr)
: reason_(reinterpret_cast<const char*>(ptr->reason), ptr->reasonlen),
ptr_(ptr) {}

QuicError::QuicError(const ngtcp2_connection_close_error& error)
QuicError::QuicError(const ngtcp2_ccerr& error)
: reason_(reinterpret_cast<const char*>(error.reason), error.reasonlen),
error_(error),
ptr_(&error_) {}
Expand Down Expand Up @@ -175,11 +177,11 @@ const std::string_view QuicError::reason() const {
return reason_;
}

QuicError::operator const ngtcp2_connection_close_error&() const {
QuicError::operator const ngtcp2_ccerr&() const {
return *ptr_;
}

QuicError::operator const ngtcp2_connection_close_error*() const {
QuicError::operator const ngtcp2_ccerr*() const {
return ptr_;
}

Expand Down Expand Up @@ -212,15 +214,15 @@ void QuicError::MemoryInfo(MemoryTracker* tracker) const {
QuicError QuicError::ForTransport(error_code code,
const std::string_view reason) {
QuicError error(reason);
ngtcp2_connection_close_error_set_transport_error(
ngtcp2_ccerr_set_transport_error(
&error.error_, code, error.reason_c_str(), reason.length());
return error;
}

QuicError QuicError::ForApplication(error_code code,
const std::string_view reason) {
QuicError error(reason);
ngtcp2_connection_close_error_set_application_error(
ngtcp2_ccerr_set_application_error(
&error.error_, code, error.reason_c_str(), reason.length());
return error;
}
Expand All @@ -235,22 +237,20 @@ QuicError QuicError::ForIdleClose(const std::string_view reason) {

QuicError QuicError::ForNgtcp2Error(int code, const std::string_view reason) {
QuicError error(reason);
ngtcp2_connection_close_error_set_transport_error_liberr(
ngtcp2_ccerr_set_liberr(
&error.error_, code, error.reason_c_str(), reason.length());
return error;
}

QuicError QuicError::ForTlsAlert(int code, const std::string_view reason) {
QuicError error(reason);
ngtcp2_connection_close_error_set_transport_error_tls_alert(
ngtcp2_ccerr_set_tls_alert(
&error.error_, code, error.reason_c_str(), reason.length());
return error;
}

QuicError QuicError::FromConnectionClose(ngtcp2_conn* session) {
QuicError error;
ngtcp2_conn_get_connection_close_error(session, &error.error_);
return error;
return QuicError(ngtcp2_conn_get_ccerr(session));
}

QuicError QuicError::TRANSPORT_NO_ERROR =
Expand Down
25 changes: 12 additions & 13 deletions src/quic/data.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,29 +71,28 @@ class QuicError final : public MemoryRetainer {
static constexpr error_code QUIC_APP_NO_ERROR = 65280;

enum class Type {
TRANSPORT = NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_TRANSPORT,
APPLICATION = NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_APPLICATION,
VERSION_NEGOTIATION =
NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_TRANSPORT_VERSION_NEGOTIATION,
IDLE_CLOSE = NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_TRANSPORT_IDLE_CLOSE,
TRANSPORT = NGTCP2_CCERR_TYPE_TRANSPORT,
APPLICATION = NGTCP2_CCERR_TYPE_APPLICATION,
VERSION_NEGOTIATION = NGTCP2_CCERR_TYPE_VERSION_NEGOTIATION,
IDLE_CLOSE = NGTCP2_CCERR_TYPE_IDLE_CLOSE,
};

static constexpr error_code QUIC_ERROR_TYPE_TRANSPORT =
NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_TRANSPORT;
NGTCP2_CCERR_TYPE_TRANSPORT;
static constexpr error_code QUIC_ERROR_TYPE_APPLICATION =
NGTCP2_CONNECTION_CLOSE_ERROR_CODE_TYPE_APPLICATION;
NGTCP2_CCERR_TYPE_APPLICATION;

explicit QuicError(const std::string_view reason = "");
explicit QuicError(const ngtcp2_connection_close_error* ptr);
explicit QuicError(const ngtcp2_connection_close_error& error);
explicit QuicError(const ngtcp2_ccerr* ptr);
explicit QuicError(const ngtcp2_ccerr& error);

Type type() const;
error_code code() const;
const std::string_view reason() const;
uint64_t frame_type() const;

operator const ngtcp2_connection_close_error&() const;
operator const ngtcp2_connection_close_error*() const;
operator const ngtcp2_ccerr&() const;
operator const ngtcp2_ccerr*() const;

// Returns false if the QuicError uses a no_error code with type
// transport or application.
Expand Down Expand Up @@ -130,8 +129,8 @@ class QuicError final : public MemoryRetainer {
const uint8_t* reason_c_str() const;

std::string reason_;
ngtcp2_connection_close_error error_ = ngtcp2_connection_close_error();
const ngtcp2_connection_close_error* ptr_ = nullptr;
ngtcp2_ccerr error_;
const ngtcp2_ccerr* ptr_ = nullptr;
};

} // namespace quic
Expand Down
27 changes: 15 additions & 12 deletions src/quic/endpoint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ namespace quic {
#define ENDPOINT_CC(V) \
V(RENO, reno) \
V(CUBIC, cubic) \
V(BBR, bbr) \
V(BBR2, bbr2)
V(BBR, bbr)

struct Endpoint::State {
#define V(_, name, type) type name;
Expand Down Expand Up @@ -427,11 +426,15 @@ int Endpoint::UDP::Bind(const Endpoint::Options& options) {
}

void Endpoint::UDP::Ref() {
if (!is_closed()) uv_ref(reinterpret_cast<uv_handle_t*>(&impl_->handle_));
if (!is_closed_or_closing()) {
uv_ref(reinterpret_cast<uv_handle_t*>(&impl_->handle_));
}
}

void Endpoint::UDP::Unref() {
if (!is_closed()) uv_unref(reinterpret_cast<uv_handle_t*>(&impl_->handle_));
if (!is_closed_or_closing()) {
uv_unref(reinterpret_cast<uv_handle_t*>(&impl_->handle_));
}
}

int Endpoint::UDP::Start() {
Expand Down Expand Up @@ -476,7 +479,7 @@ Endpoint::UDP::operator bool() const {
}

SocketAddress Endpoint::UDP::local_address() const {
DCHECK(!is_closed() && is_bound());
DCHECK(!is_closed_or_closing() && is_bound());
return SocketAddress::FromSockName(impl_->handle_);
}

Expand Down Expand Up @@ -1012,7 +1015,7 @@ void Endpoint::Receive(const uv_buf_t& buf,

if (options_.validate_address) {
// If there is no token, generate and send one.
if (hd.token.len == 0) {
if (hd.tokenlen == 0) {
SendRetry(PathDescriptor{
version,
dcid,
Expand All @@ -1027,9 +1030,9 @@ void Endpoint::Receive(const uv_buf_t& buf,

// We have two kinds of tokens, each prefixed with a different magic
// byte.
switch (hd.token.base[0]) {
switch (hd.token[0]) {
case RetryToken::kTokenMagic: {
RetryToken token(hd.token.base, hd.token.len);
RetryToken token(hd.token, hd.tokenlen);
auto ocid = token.Validate(
version,
remote_address,
Expand All @@ -1055,7 +1058,7 @@ void Endpoint::Receive(const uv_buf_t& buf,
break;
}
case RegularToken::kTokenMagic: {
RegularToken token(hd.token.base, hd.token.len);
RegularToken token(hd.token, hd.tokenlen);
if (!token.Validate(
version,
remote_address,
Expand All @@ -1072,8 +1075,8 @@ void Endpoint::Receive(const uv_buf_t& buf,
// if a retry is sent.
return true;
}
hd.token.base = nullptr;
hd.token.len = 0;
hd.token = nullptr;
hd.tokenlen = 0;
break;
}
default: {
Expand All @@ -1093,7 +1096,7 @@ void Endpoint::Receive(const uv_buf_t& buf,
// so we don't have to do this dance again for this endpoint
// instance.
addrLRU_.Upsert(remote_address)->validated = true;
} else if (hd.token.len > 0) {
} else if (hd.tokenlen > 0) {
// If validation is turned off and there is a token, that's weird.
// The peer should only have a token if we sent it to them and we
// wouldn't have sent it unless validation was turned on. Let's
Expand Down
7 changes: 3 additions & 4 deletions src/quic/endpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ class Endpoint final : public AsyncWrap, public Packet::Listener {
static constexpr auto QUIC_CC_ALGO_RENO = NGTCP2_CC_ALGO_RENO;
static constexpr auto QUIC_CC_ALGO_CUBIC = NGTCP2_CC_ALGO_CUBIC;
static constexpr auto QUIC_CC_ALGO_BBR = NGTCP2_CC_ALGO_BBR;
static constexpr auto QUIC_CC_ALGO_BBR2 = NGTCP2_CC_ALGO_BBR2;

// Endpoint configuration options
struct Options final : public MemoryRetainer {
Expand Down Expand Up @@ -131,9 +130,9 @@ class Endpoint final : public AsyncWrap, public Packet::Listener {
#endif // DEBUG

// There are several common congestion control algorithms that ngtcp2 uses
// to determine how it manages the flow control window: RENO, CUBIC, BBR,
// and BBR2. The details of how each works is not relevant here. The choice
// of which to use by default is arbitrary and we can choose whichever we'd
// to determine how it manages the flow control window: RENO, CUBIC, and
// BBR. The details of how each works is not relevant here. The choice of
// which to use by default is arbitrary and we can choose whichever we'd
// like. Additional performance profiling will be needed to determine which
// is the better of the two for our needs.
ngtcp2_cc_algo cc_algorithm = NGTCP2_CC_ALGO_CUBIC;
Expand Down
27 changes: 15 additions & 12 deletions src/quic/preferredaddress.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,22 @@ std::optional<const PreferredAddress::AddressInfo> get_address_info(
if (!paddr.ipv4_present) return std::nullopt;
PreferredAddress::AddressInfo address;
address.family = FAMILY;
address.port = paddr.ipv4_port;
address.port = paddr.ipv4.sin_port;
if (uv_inet_ntop(
FAMILY, paddr.ipv4_addr, address.host, sizeof(address.host)) == 0) {
FAMILY, &paddr.ipv4.sin_addr, address.host, sizeof(address.host)) ==
0) {
address.address = address.host;
}
return address;
} else {
if (!paddr.ipv6_present) return std::nullopt;
PreferredAddress::AddressInfo address;
address.family = FAMILY;
address.port = paddr.ipv6_port;
if (uv_inet_ntop(
FAMILY, paddr.ipv6_addr, address.host, sizeof(address.host)) == 0) {
address.port = paddr.ipv6.sin6_port;
if (uv_inet_ntop(FAMILY,
&paddr.ipv6.sin6_addr,
address.host,
sizeof(address.host)) == 0) {
address.address = address.host;
}
return address;
Expand All @@ -50,20 +53,20 @@ std::optional<const PreferredAddress::AddressInfo> get_address_info(
template <int FAMILY>
void copy_to_transport_params(ngtcp2_transport_params* params,
const sockaddr* addr) {
params->preferred_address_present = true;
params->preferred_addr_present = true;
if constexpr (FAMILY == AF_INET) {
const sockaddr_in* src = reinterpret_cast<const sockaddr_in*>(addr);
params->preferred_address.ipv4_port = SocketAddress::GetPort(addr);
memcpy(params->preferred_address.ipv4_addr,
params->preferred_addr.ipv4.sin_port = SocketAddress::GetPort(addr);
memcpy(&params->preferred_addr.ipv4.sin_addr,
&src->sin_addr,
sizeof(params->preferred_address.ipv4_addr));
sizeof(params->preferred_addr.ipv4.sin_addr));
} else {
DCHECK_EQ(FAMILY, AF_INET6);
const sockaddr_in6* src = reinterpret_cast<const sockaddr_in6*>(addr);
params->preferred_address.ipv6_port = SocketAddress::GetPort(addr);
memcpy(params->preferred_address.ipv6_addr,
params->preferred_addr.ipv6.sin6_port = SocketAddress::GetPort(addr);
memcpy(&params->preferred_addr.ipv6.sin6_addr,
&src->sin6_addr,
sizeof(params->preferred_address.ipv4_addr));
sizeof(params->preferred_addr.ipv4.sin_addr));
}
UNREACHABLE();
}
Expand Down
Loading