Skip to content
This repository has been archived by the owner on Aug 11, 2020. It is now read-only.

Commit

Permalink
quic: pass local address in to QuicSession
Browse files Browse the repository at this point in the history
To set up support for supporting multiple endpoints, the
QuicSession needs to know the local endpoint directly rather
than relying on the QuicSocket to provide it.

PR-URL: #223
Reviewed-By: Anna Henningsen <[email protected]>
  • Loading branch information
jasnell committed Dec 13, 2019
1 parent f0906cd commit 5ae5c74
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 63 deletions.
2 changes: 1 addition & 1 deletion src/js_udp_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ void JSUDPWrap::EmitReceived(const FunctionCallbackInfo<Value>& args) {
data += avail;
len -= avail;
wrap->listener()->OnRecv(
avail, buf, reinterpret_cast<sockaddr*>(&addr), flags);
nullptr, avail, buf, reinterpret_cast<sockaddr*>(&addr), flags);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/node_quic_default_application.cc
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ bool DefaultApplication::SendStreamData(QuicStream* stream) {

Debug(stream, "Sending %" PRIu64 " bytes in serialized packet", nwrite);
dest.Realloc(nwrite);
if (!Session()->SendPacket(std::move(dest), &path))
if (!Session()->SendPacket(std::move(dest), path))
return false;

if (IsEmpty(v, c)) {
Expand Down
2 changes: 1 addition & 1 deletion src/node_quic_http3_application.cc
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ bool Http3Application::SendPendingData() {

Debug(Session(), "Sending %" PRIu64 " bytes in serialized packet", nwrite);
dest.Realloc(nwrite);
if (!Session()->SendPacket(std::move(dest), &path))
if (!Session()->SendPacket(std::move(dest), path))
return false;

if (fin)
Expand Down
81 changes: 61 additions & 20 deletions src/node_quic_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1173,7 +1173,8 @@ QuicSession::QuicSession(
QuicSessionConfig* config,
Local<Object> wrap,
const ngtcp2_cid* rcid,
const struct sockaddr* addr,
const SocketAddress& local_addr,
const struct sockaddr* remote_addr,
const ngtcp2_cid* dcid,
const ngtcp2_cid* ocid,
uint32_t version,
Expand All @@ -1193,14 +1194,22 @@ QuicSession::QuicSession(
options,
QUIC_PREFERRED_ADDRESS_ACCEPT, // Not used on server sessions
initial_connection_close) {
InitServer(config, addr, dcid, ocid, version, qlog);
InitServer(
config,
local_addr,
remote_addr,
dcid,
ocid,
version,
qlog);
}

// Client QuicSession Constructor
QuicSession::QuicSession(
QuicSocket* socket,
v8::Local<v8::Object> wrap,
const struct sockaddr* addr,
const SocketAddress& local_addr,
const struct sockaddr* remote_addr,
SecureContext* context,
Local<Value> early_transport_params,
Local<Value> session_ticket,
Expand All @@ -1221,7 +1230,13 @@ QuicSession::QuicSession(
nullptr, // rcid only used on the server
options,
select_preferred_address_policy) {
CHECK(InitClient(addr, early_transport_params, session_ticket, dcid, qlog));
CHECK(InitClient(
local_addr,
remote_addr,
early_transport_params,
session_ticket,
dcid,
qlog));
}

// QuicSession is an abstract base class that defines the code used by both
Expand Down Expand Up @@ -1753,7 +1768,7 @@ void QuicSession::PathValidation(
Debug(this,
"Path validation succeeded. Updating local and remote addresses");
SetLocalAddress(&path->local);
remote_address_.Update(path->remote.addr, path->remote.addrlen);
UpdateEndpoint(*path);
IncrementStat(
1, &session_stats_,
&session_stats::path_validation_success_count);
Expand Down Expand Up @@ -1814,6 +1829,7 @@ bool QuicSession::ReceiveRetry() {
bool QuicSession::Receive(
ssize_t nread,
const uint8_t* data,
const SocketAddress& local_addr,
const struct sockaddr* remote_addr,
unsigned int flags) {
if (IsFlagSet(QUICSESSION_FLAG_DESTROYED)) {
Expand Down Expand Up @@ -1858,7 +1874,7 @@ bool QuicSession::Receive(
// packet to the next so we have to look at the addr on
// every packet.
remote_address_ = remote_addr;
QuicPath path(Socket()->GetLocalAddress(), &remote_address_);
QuicPath path(local_addr, remote_address_);

{
// These are within a scope to ensure that the InternalCallbackScope
Expand Down Expand Up @@ -2191,10 +2207,9 @@ bool QuicSession::SelectPreferredAddress(

bool QuicSession::SendPacket(
MallocedBuffer<uint8_t> buf,
ngtcp2_path_storage* path) {
const ngtcp2_path_storage& path) {
sendbuf_.Push(std::move(buf));
// TODO(@jasnell): Update the local endpoint also?
remote_address_.Update(path->path.remote.addr, path->path.remote.addrlen);
UpdateEndpoint(path.path);
return SendPacket("stream data");
}

Expand Down Expand Up @@ -2242,7 +2257,13 @@ bool QuicSession::SendPacket(const char* diagnostic_label) {
Debug(this, "There are %" PRIu64 " bytes in txbuf_ to send", txbuf_.Length());
session_stats_.session_sent_at = uv_hrtime();
ScheduleRetransmit();
Debug(this, "Sending to %s:%d from %s:%d",
remote_address_.GetAddress().c_str(),
remote_address_.GetPort(),
local_address_.GetAddress().c_str(),
local_address_.GetPort());
int err = Socket()->SendPacket(
local_address_,
remote_address_,
&txbuf_,
BaseObjectPtr<QuicSession>(this),
Expand Down Expand Up @@ -2611,14 +2632,20 @@ bool QuicSession::WritePackets(const char* diagnostic_label) {
}

data.Realloc(nwrite);
remote_address_.Update(path.path.remote.addr, path.path.remote.addrlen);
UpdateEndpoint(path.path);
sendbuf_.Push(std::move(data));
UpdateDataStats();

if (!SendPacket(diagnostic_label))
return false;
}
}

void QuicSession::UpdateEndpoint(const ngtcp2_path& path) {
remote_address_.Update(path.remote.addr, path.remote.addrlen);
local_address_.Update(path.local.addr, path.local.addrlen);
}

bool QuicSession::SubmitInformation(
int64_t stream_id,
v8::Local<v8::Array> headers) {
Expand Down Expand Up @@ -2692,7 +2719,8 @@ BaseObjectPtr<QuicSession> QuicSession::CreateServer(
QuicSocket* socket,
QuicSessionConfig* config,
const ngtcp2_cid* rcid,
const struct sockaddr* addr,
const SocketAddress& local_addr,
const struct sockaddr* remote_addr,
const ngtcp2_cid* dcid,
const ngtcp2_cid* ocid,
uint32_t version,
Expand All @@ -2712,7 +2740,8 @@ BaseObjectPtr<QuicSession> QuicSession::CreateServer(
config,
obj,
rcid,
addr,
local_addr,
remote_addr,
dcid,
ocid,
version,
Expand All @@ -2727,7 +2756,8 @@ BaseObjectPtr<QuicSession> QuicSession::CreateServer(

void QuicSession::InitServer(
QuicSessionConfig* config,
const struct sockaddr* addr,
const SocketAddress& local_addr,
const struct sockaddr* remote_addr,
const ngtcp2_cid* dcid,
const ngtcp2_cid* ocid,
uint32_t version,
Expand All @@ -2738,8 +2768,9 @@ void QuicSession::InitServer(
ExtendMaxStreamsBidi(DEFAULT_MAX_STREAMS_BIDI);
ExtendMaxStreamsUni(DEFAULT_MAX_STREAMS_UNI);

remote_address_ = addr;
max_pktlen_ = GetMaxPktLen(addr);
local_address_ = local_addr;
remote_address_ = remote_addr;
max_pktlen_ = GetMaxPktLen(remote_addr);

config->SetOriginalConnectionID(ocid);
config->GenerateStatelessResetToken();
Expand All @@ -2749,7 +2780,7 @@ void QuicSession::InitServer(
EntropySource(scid_.data, NGTCP2_SV_SCIDLEN);
scid_.datalen = NGTCP2_SV_SCIDLEN;

QuicPath path(Socket()->GetLocalAddress(), &remote_address_);
QuicPath path(local_addr, remote_address_);

// NOLINTNEXTLINE(readability/pointer_notation)
if (qlog == QlogMode::kEnabled) config->SetQlog({ *ocid, OnQlogWrite });
Expand Down Expand Up @@ -2838,6 +2869,7 @@ BaseObjectPtr<QuicSession> QuicSession::CreateClient(
MakeDetachedBaseObject<QuicSession>(
socket,
obj,
*socket->GetLocalAddress(),
addr,
context,
early_transport_params,
Expand All @@ -2854,15 +2886,22 @@ BaseObjectPtr<QuicSession> QuicSession::CreateClient(
}

bool QuicSession::InitClient(
const struct sockaddr* addr,
const SocketAddress& local_addr,
const struct sockaddr* remote_addr,
Local<Value> early_transport_params,
Local<Value> session_ticket,
Local<Value> dcid_value,
QlogMode qlog) {
CHECK_NULL(connection_);

remote_address_ = addr;
max_pktlen_ = GetMaxPktLen(addr);
local_address_ = local_addr;
remote_address_ = remote_addr;
Debug(this, "Initializing connection from %s:%d to %s:%d",
local_address_.GetAddress().c_str(),
local_address_.GetPort(),
remote_address_.GetAddress().c_str(),
remote_address_.GetPort());
max_pktlen_ = GetMaxPktLen(remote_addr);

QuicSessionConfig config(env());
max_crypto_buffer_ = config.GetMaxCryptoBuffer();
Expand All @@ -2885,7 +2924,7 @@ bool QuicSession::InitClient(
EntropySource(dcid.data, dcid.datalen);
}

QuicPath path(Socket()->GetLocalAddress(), &remote_address_);
QuicPath path(local_address_, remote_address_);

if (qlog == QlogMode::kEnabled) config.SetQlog({ dcid, OnQlogWrite });

Expand All @@ -2902,6 +2941,8 @@ bool QuicSession::InitClient(
&alloc_info_,
static_cast<QuicSession*>(this)), 0);

auto n = ngtcp2_conn_get_remote_addr(conn);

connection_.reset(conn);

InitializeTLS(this);
Expand Down
22 changes: 16 additions & 6 deletions src/node_quic_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,8 @@ class QuicSession : public AsyncWrap,
QuicSocket* socket,
QuicSessionConfig* config,
const ngtcp2_cid* rcid,
const struct sockaddr* addr,
const SocketAddress& local_addr,
const struct sockaddr* remote_addr,
const ngtcp2_cid* dcid,
const ngtcp2_cid* ocid,
uint32_t version,
Expand Down Expand Up @@ -638,7 +639,8 @@ class QuicSession : public AsyncWrap,
QuicSessionConfig* config,
v8::Local<v8::Object> wrap,
const ngtcp2_cid* rcid,
const struct sockaddr* addr,
const SocketAddress& local_addr,
const struct sockaddr* remote_addr,
const ngtcp2_cid* dcid,
const ngtcp2_cid* ocid,
uint32_t version,
Expand All @@ -651,7 +653,8 @@ class QuicSession : public AsyncWrap,
QuicSession(
QuicSocket* socket,
v8::Local<v8::Object> wrap,
const struct sockaddr* addr,
const SocketAddress& local_addr,
const struct sockaddr* remote_addr,
crypto::SecureContext* context,
v8::Local<v8::Value> early_transport_params,
v8::Local<v8::Value> session_ticket,
Expand Down Expand Up @@ -804,6 +807,7 @@ class QuicSession : public AsyncWrap,
bool Receive(
ssize_t nread,
const uint8_t* data,
const SocketAddress& local_addr,
const struct sockaddr* remote_addr,
unsigned int flags);

Expand All @@ -824,7 +828,9 @@ class QuicSession : public AsyncWrap,
// Causes pending QuicStream data to be serialized and sent
bool SendStreamData(QuicStream* stream);

bool SendPacket(MallocedBuffer<uint8_t> buf, ngtcp2_path_storage* path);
bool SendPacket(
MallocedBuffer<uint8_t> buf,
const ngtcp2_path_storage& path);

inline uint64_t GetMaxDataLeft();

Expand Down Expand Up @@ -986,15 +992,17 @@ class QuicSession : public AsyncWrap,
// Initialize the QuicSession as a server
void InitServer(
QuicSessionConfig* config,
const struct sockaddr* addr,
const SocketAddress& local_addr,
const struct sockaddr* remote_addr,
const ngtcp2_cid* dcid,
const ngtcp2_cid* ocid,
uint32_t version,
QlogMode qlog);

// Initialize the QuicSession as a client
bool InitClient(
const struct sockaddr* addr,
const SocketAddress& local_addr,
const struct sockaddr* remote_addr,
v8::Local<v8::Value> early_transport_params,
v8::Local<v8::Value> session_ticket,
v8::Local<v8::Value> dcid,
Expand Down Expand Up @@ -1040,6 +1048,7 @@ class QuicSession : public AsyncWrap,
bool WritePackets(const char* diagnostic_label = nullptr);
void UpdateRecoveryStats();
void UpdateDataStats();
void UpdateEndpoint(const ngtcp2_path& path);

void VersionNegotiation(
const ngtcp2_pkt_hd* hd,
Expand Down Expand Up @@ -1303,6 +1312,7 @@ class QuicSession : public AsyncWrap,
uint64_t{NGTCP2_NO_ERROR}
};
ConnectionPointer connection_;
SocketAddress local_address_;
SocketAddress remote_address_;
uint32_t flags_ = 0;
uint64_t initial_connection_close_ = NGTCP2_NO_ERROR;
Expand Down
Loading

0 comments on commit 5ae5c74

Please sign in to comment.