Skip to content

Commit cffe9b2

Browse files
committed
quic: getting application working, fixing bugs
1 parent d0a91fe commit cffe9b2

File tree

6 files changed

+61
-28
lines changed

6 files changed

+61
-28
lines changed

src/quic/application.cc

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include "ngtcp2/ngtcp2.h"
12
#if HAVE_OPENSSL && NODE_OPENSSL_HAS_QUIC
23

34
#include "application.h"
@@ -95,6 +96,20 @@ Maybe<Session::Application_Options> Session::Application_Options::From(
9596
return Just<Application_Options>(options);
9697
}
9798

99+
// ============================================================================
100+
101+
std::string Session::Application::StreamData::ToString() const {
102+
DebugIndentScope indent;
103+
auto prefix = indent.Prefix();
104+
std::string res("{");
105+
res += prefix + "count: " + std::to_string(count);
106+
res += prefix + "remaining: " + std::to_string(remaining);
107+
res += prefix + "id: " + std::to_string(id);
108+
res += prefix + "fin: " + std::to_string(fin);
109+
res += indent.Close();
110+
return res;
111+
}
112+
98113
Session::Application::Application(Session* session, const Options& options)
99114
: session_(session) {}
100115

@@ -251,13 +266,15 @@ void Session::Application::SendPendingData() {
251266
};
252267

253268
for (;;) {
254-
ssize_t ndatalen;
269+
ssize_t ndatalen = 0;
255270
StreamData stream_data;
256271

257272
err = GetStreamData(&stream_data);
258273

259274
if (err < 0) {
260275
session_->last_error_ = QuicError::ForNgtcp2Error(NGTCP2_ERR_INTERNAL);
276+
Debug(session_, "Application failed to get stream data with error %s",
277+
session_->last_error_);
261278
return session_->Close(Session::CloseMethod::SILENT);
262279
}
263280

@@ -270,13 +287,19 @@ void Session::Application::SendPendingData() {
270287
pos = ngtcp2_vec(*packet).base;
271288
}
272289

290+
Debug(session_, "Application using stream data: %s", stream_data);
291+
DCHECK_NOT_NULL(pos);
292+
DCHECK_NOT_NULL(stream_data.buf);
273293
ssize_t nwrite = WriteVStream(&path, pos, &ndatalen, stream_data);
294+
Debug(session_, "Application accepted %zu bytes", ndatalen);
274295

275296
if (nwrite <= 0) {
276297
switch (nwrite) {
277-
case 0:
298+
case 0: {
299+
Debug(session_, "Congestion limited. Sending nothing.");
278300
if (stream_data.id >= 0) ResumeStream(stream_data.id);
279301
return congestionLimited(std::move(packet));
302+
}
280303
case NGTCP2_ERR_STREAM_DATA_BLOCKED: {
281304
session().StreamDataBlocked(stream_data.id);
282305
if (session().max_data_left() == 0) {
@@ -287,6 +310,8 @@ void Session::Application::SendPendingData() {
287310
continue;
288311
}
289312
case NGTCP2_ERR_STREAM_SHUT_WR: {
313+
Debug(session_, "Stream %" PRIi64 " is closed for writing",
314+
stream_data.id);
290315
// Indicates that the writable side of the stream has been closed
291316
// locally or the stream is being reset. In either case, we can't send
292317
// any stream data!
@@ -299,6 +324,7 @@ void Session::Application::SendPendingData() {
299324
continue;
300325
}
301326
case NGTCP2_ERR_WRITE_MORE: {
327+
Debug(session_, "Application should write more to packet");
302328
CHECK_GT(ndatalen, 0);
303329
if (!StreamCommit(&stream_data, ndatalen)) return session_->Close();
304330
pos += ndatalen;
@@ -308,6 +334,8 @@ void Session::Application::SendPendingData() {
308334

309335
packet->Done(UV_ECANCELED);
310336
session_->last_error_ = QuicError::ForNgtcp2Error(nwrite);
337+
Debug(session_, "Application failed to write stream data with error %s",
338+
session_->last_error_);
311339
return session_->Close(Session::CloseMethod::SILENT);
312340
}
313341

@@ -322,9 +350,10 @@ void Session::Application::SendPendingData() {
322350

323351
if (stream_data.id >= 0 && ndatalen < 0) ResumeStream(stream_data.id);
324352

353+
Debug(session_, "Packet ready to send with %zu bytes", nwrite);
325354
packet->Truncate(nwrite);
326-
session_->Send(std::move(packet), path);
327-
355+
session_->Send(packet, path);
356+
packet = nullptr;
328357
pos = nullptr;
329358

330359
if (++packetSendCount == maxPacketCount) {
@@ -343,10 +372,12 @@ ssize_t Session::Application::WriteVStream(PathStorage* path,
343372
uint32_t flags = NGTCP2_WRITE_STREAM_FLAG_NONE;
344373
if (stream_data.remaining > 0) flags |= NGTCP2_WRITE_STREAM_FLAG_MORE;
345374
if (stream_data.fin) flags |= NGTCP2_WRITE_STREAM_FLAG_FIN;
375+
ngtcp2_pkt_info pi;
376+
346377
ssize_t ret = ngtcp2_conn_writev_stream(
347378
*session_,
348379
&path->path,
349-
nullptr,
380+
&pi,
350381
buf,
351382
ngtcp2_conn_get_max_tx_udp_payload_size(*session_),
352383
ndatalen,

src/quic/application.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ struct Session::Application::StreamData final {
151151
BaseObjectPtr<Stream> stream;
152152

153153
inline operator nghttp3_vec() const { return {data[0].base, data[0].len}; }
154+
155+
std::string ToString() const;
154156
};
155157

156158
} // namespace quic

src/quic/cid.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,16 @@ class RandomCIDFactory : public CID::Factory {
114114
return CID(start, length_hint);
115115
}
116116

117-
void GenerateInto(ngtcp2_cid* cid,
118-
size_t length_hint = CID::kMaxLength) const override {
117+
CID GenerateInto(ngtcp2_cid* cid,
118+
size_t length_hint = CID::kMaxLength) const override {
119119
DCHECK_GE(length_hint, CID::kMinLength);
120120
DCHECK_LE(length_hint, CID::kMaxLength);
121121
Mutex::ScopedLock lock(mutex_);
122122
maybe_refresh_pool(length_hint);
123123
auto start = pool_ + pos_;
124124
pos_ += length_hint;
125125
ngtcp2_cid_init(cid, start, length_hint);
126+
return CID(cid);
126127
}
127128

128129
private:

src/quic/cid.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,9 @@ class CID::Factory {
111111
virtual CID Generate(size_t length_hint = CID::kMaxLength) const = 0;
112112

113113
// Generate a new CID into the given ngtcp2_cid. This variation of
114-
// Generate should be used far less commonly. It is provided largely
115-
// for a couple of internal cases.
116-
virtual void GenerateInto(ngtcp2_cid* cid,
117-
size_t length_hint = CID::kMaxLength) const = 0;
114+
// Generate should be used far less commonly.
115+
virtual CID GenerateInto(ngtcp2_cid* cid,
116+
size_t length_hint = CID::kMaxLength) const = 0;
118117

119118
// The default random CID generator instance.
120119
static const Factory& random();

src/quic/endpoint.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,7 @@ void Endpoint::Receive(const uv_buf_t& buf,
12361236
// identifies us. config.dcid should equal scid. config.scid should *not*
12371237
// equal dcid.
12381238
DCHECK(config.dcid == scid);
1239-
DCHECK(config.scid != dcid);
1239+
DCHECK(config.scid == dcid);
12401240

12411241
const auto is_remote_address_validated = ([&] {
12421242
auto info = addrLRU_.Peek(remote_address);

src/quic/session.cc

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,7 +1406,7 @@ void Session::DatagramReceived(const uint8_t* data,
14061406
bool Session::GenerateNewConnectionId(ngtcp2_cid* cid,
14071407
size_t len,
14081408
uint8_t* token) {
1409-
CID cid_ = config_.options.cid_factory->Generate(len);
1409+
CID cid_ = config_.options.cid_factory->GenerateInto(cid, len);
14101410
Debug(this, "Generated new connection id %s", cid_);
14111411
StatelessResetToken new_token(
14121412
token, endpoint_->options().reset_token_secret, cid_);
@@ -1416,10 +1416,11 @@ bool Session::GenerateNewConnectionId(ngtcp2_cid* cid,
14161416
}
14171417

14181418
bool Session::HandshakeCompleted() {
1419+
Debug(this, "Session handshake completed");
1420+
14191421
if (state_->handshake_completed) return false;
1420-
state_->handshake_completed = true;
1422+
state_->handshake_completed = 1;
14211423

1422-
Debug(this, "Session handshake completed");
14231424
STAT_RECORD_TIMESTAMP(Stats, handshake_completed_at);
14241425

14251426
if (!tls_session().early_data_was_accepted())
@@ -2012,17 +2013,17 @@ struct Session::Impl {
20122013
void* user_data) {
20132014
auto session = Impl::From(conn, user_data);
20142015
if (UNLIKELY(session->is_destroyed())) return NGTCP2_ERR_CALLBACK_FAILURE;
2016+
CHECK(!session->is_server());
2017+
2018+
if (level != NGTCP2_ENCRYPTION_LEVEL_1RTT) return NGTCP2_SUCCESS;
20152019

20162020
Debug(session,
20172021
"Receiving RX key for level %d for dcid %s",
20182022
to_string(level),
20192023
session->config().dcid);
20202024

2021-
if (!session->is_server() && (level == NGTCP2_ENCRYPTION_LEVEL_0RTT ||
2022-
level == NGTCP2_ENCRYPTION_LEVEL_1RTT)) {
2023-
if (!session->application().Start()) return NGTCP2_ERR_CALLBACK_FAILURE;
2024-
}
2025-
return NGTCP2_SUCCESS;
2025+
return session->application().Start() ?
2026+
NGTCP2_SUCCESS : NGTCP2_ERR_CALLBACK_FAILURE;
20262027
}
20272028

20282029
static int on_receive_stateless_reset(ngtcp2_conn* conn,
@@ -2071,17 +2072,16 @@ struct Session::Impl {
20712072
void* user_data) {
20722073
auto session = Impl::From(conn, user_data);
20732074
if (UNLIKELY(session->is_destroyed())) return NGTCP2_ERR_CALLBACK_FAILURE;
2075+
CHECK(session->is_server());
2076+
2077+
if (level != NGTCP2_ENCRYPTION_LEVEL_1RTT) return NGTCP2_SUCCESS;
20742078

20752079
Debug(session,
20762080
"Receiving TX key for level %d for dcid %s",
20772081
to_string(level),
20782082
session->config().dcid);
2079-
2080-
if (session->is_server() && (level == NGTCP2_ENCRYPTION_LEVEL_0RTT ||
2081-
level == NGTCP2_ENCRYPTION_LEVEL_1RTT)) {
2082-
if (!session->application().Start()) return NGTCP2_ERR_CALLBACK_FAILURE;
2083-
}
2084-
return NGTCP2_SUCCESS;
2083+
return session->application().Start() ?
2084+
NGTCP2_SUCCESS : NGTCP2_ERR_CALLBACK_FAILURE;
20852085
}
20862086

20872087
static int on_receive_version_negotiation(ngtcp2_conn* conn,
@@ -2206,7 +2206,7 @@ struct Session::Impl {
22062206
on_stream_stop_sending,
22072207
ngtcp2_crypto_version_negotiation_cb,
22082208
on_receive_rx_key,
2209-
on_receive_tx_key,
2209+
nullptr,
22102210
on_early_data_rejected};
22112211

22122212
static constexpr ngtcp2_callbacks SERVER = {
@@ -2247,7 +2247,7 @@ struct Session::Impl {
22472247
ngtcp2_crypto_get_path_challenge_data_cb,
22482248
on_stream_stop_sending,
22492249
ngtcp2_crypto_version_negotiation_cb,
2250-
on_receive_rx_key,
2250+
nullptr,
22512251
on_receive_tx_key,
22522252
on_early_data_rejected};
22532253
};

0 commit comments

Comments
 (0)