@fails-components/webtransport 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,6 +19,7 @@
19
19
 
20
20
  #include "absl/strings/match.h"
21
21
  #include "absl/strings/string_view.h"
22
+ #include "absl/cleanup/cleanup.h"
22
23
  #include "openssl/x509.h"
23
24
  #include "quiche/quic/core/crypto/proof_verifier.h"
24
25
  #include "quiche/quic/core/http/quic_spdy_client_stream.h"
@@ -44,6 +45,42 @@ using spdy::Http2HeaderBlock;
44
45
  namespace quic
45
46
  {
46
47
 
48
+ // taken from libquiche
49
+ namespace
50
+ {
51
+
52
+ // For level-triggered I/O, we need to manually rearm the kSocketEventWritable
53
+ // listener whenever the socket gets blocked.
54
+ class LevelTriggeredPacketWriter : public QuicDefaultPacketWriter
55
+ {
56
+ public:
57
+ explicit LevelTriggeredPacketWriter(int fd, QuicEventLoop *event_loop)
58
+ : QuicDefaultPacketWriter(fd), event_loop_(event_loop)
59
+ {
60
+ QUICHE_DCHECK(!event_loop->SupportsEdgeTriggered());
61
+ }
62
+
63
+ WriteResult WritePacket(const char *buffer, size_t buf_len,
64
+ const QuicIpAddress &self_address,
65
+ const QuicSocketAddress &peer_address,
66
+ PerPacketOptions *options) override
67
+ {
68
+ WriteResult result = QuicDefaultPacketWriter::WritePacket(
69
+ buffer, buf_len, self_address, peer_address, options);
70
+ if (IsWriteBlockedStatus(result.status))
71
+ {
72
+ bool success = event_loop_->RearmSocket(fd(), kSocketEventWritable);
73
+ QUICHE_DCHECK(success);
74
+ }
75
+ return result;
76
+ }
77
+
78
+ private:
79
+ QuicEventLoop *event_loop_;
80
+ };
81
+
82
+ } // namespace
83
+
47
84
  // taken from chromium to behave like the browser
48
85
  // A version of WebTransportFingerprintProofVerifier that enforces
49
86
  // Chromium-specific policies.
@@ -168,7 +205,7 @@ namespace quic
168
205
 
169
206
  void Http3Client::SendRequest(const std::string &uri)
170
207
  {
171
- spdy::SpdyHeaderBlock headers;
208
+ spdy::Http2HeaderBlock headers;
172
209
  if (!PopulateHeaderBlockFromUrl(uri, &headers))
173
210
  {
174
211
  return;
@@ -178,7 +215,7 @@ namespace quic
178
215
 
179
216
  void Http3Client::SendRequestAndRstTogether(const std::string &uri)
180
217
  {
181
- spdy::SpdyHeaderBlock headers;
218
+ spdy::Http2HeaderBlock headers;
182
219
  if (!PopulateHeaderBlockFromUrl(uri, &headers))
183
220
  {
184
221
  return;
@@ -194,7 +231,7 @@ namespace quic
194
231
  }
195
232
 
196
233
  void Http3Client::GetOrCreateStreamAndSendRequest(
197
- const spdy::SpdyHeaderBlock *headers, absl::string_view body, bool fin)
234
+ const spdy::Http2HeaderBlock *headers, absl::string_view body, bool fin)
198
235
  {
199
236
  if (headers)
200
237
  {
@@ -206,8 +243,8 @@ namespace quic
206
243
  if (rv == QUIC_PENDING)
207
244
  {
208
245
  // May need to retry request if asynchronous rendezvous fails.
209
- std::unique_ptr<spdy::SpdyHeaderBlock> new_headers(
210
- new spdy::SpdyHeaderBlock(headers->Clone()));
246
+ std::unique_ptr<spdy::Http2HeaderBlock> new_headers(
247
+ new spdy::Http2HeaderBlock(headers->Clone()));
211
248
  push_promise_data_to_resend_ = std::make_unique<Http3ClientDataToResend>(
212
249
  std::move(new_headers), body, fin, this);
213
250
  return;
@@ -218,7 +255,7 @@ namespace quic
218
255
  bool hasheaders = false;
219
256
  if (headers != nullptr)
220
257
  {
221
- spdy_headers = std::make_shared<spdy::SpdyHeaderBlock>(headers->Clone());
258
+ spdy_headers = std::make_shared<spdy::Http2HeaderBlock>(headers->Clone());
222
259
  hasheaders = true;
223
260
  }
224
261
 
@@ -252,13 +289,13 @@ namespace quic
252
289
  });
253
290
  }
254
291
 
255
- void Http3Client::SendMessageAsync(const spdy::SpdyHeaderBlock &headers,
292
+ void Http3Client::SendMessageAsync(const spdy::Http2HeaderBlock &headers,
256
293
  absl::string_view body)
257
294
  {
258
295
  return SendMessageAsync(headers, body, /*fin=*/true);
259
296
  }
260
297
 
261
- void Http3Client::SendMessageAsync(const spdy::SpdyHeaderBlock &headers,
298
+ void Http3Client::SendMessageAsync(const spdy::Http2HeaderBlock &headers,
262
299
  absl::string_view body, bool fin)
263
300
  {
264
301
  // Always force creation of a stream for SendMessage.
@@ -444,6 +481,9 @@ namespace quic
444
481
  overflow_supported_ = api.EnableDroppedPacketCount(fd);
445
482
  api.EnableReceiveTimestamp(fd);
446
483
 
484
+ auto closer = absl::MakeCleanup([fd]
485
+ { QuicUdpSocketApi api;api.Destroy(fd); });
486
+
447
487
  QuicSocketAddress client_address;
448
488
  if (bind_to_address.IsInitialized())
449
489
  {
@@ -492,10 +532,13 @@ namespace quic
492
532
  }
493
533
  const int kEpollFlags = kSocketEventReadable | kSocketEventWritable; // there is no analogue to EPOLLET in libuv hopefully not a problem
494
534
 
495
- fd_address_map_[fd] = client_address;
496
- eventloop_->getQuicEventLoop()->RegisterSocket(fd, kEpollFlags, this);
497
- // eventloop_->SetNonblocking(fd); // eventuelly should be part of register socket.
498
- return true;
535
+ if (eventloop_->getQuicEventLoop()->RegisterSocket(fd, kEpollFlags, this))
536
+ {
537
+ fd_address_map_[fd] = client_address;
538
+ std::move(closer).Cancel();
539
+ return true;
540
+ }
541
+ return false;
499
542
  }
500
543
 
501
544
  void Http3Client::CleanUpUDPSocket(int fd)
@@ -651,8 +694,8 @@ namespace quic
651
694
  Http3WTSession *wtsessionobj =
652
695
  new Http3WTSession();
653
696
  wtsessionobj->init(
654
- static_cast<WebTransportSession *>(wtsession),
655
- eventloop_);
697
+ static_cast<WebTransportSession *>(wtsession),
698
+ eventloop_);
656
699
  eventloop_->informNewClientSession(this, wtsessionobj);
657
700
  auto visitor = std::make_unique<Http3WTSession::Visitor>(wtsessionobj);
658
701
  wtsession->SetVisitor(std::move(visitor));
@@ -667,7 +710,7 @@ namespace quic
667
710
 
668
711
  void Http3Client::openWTSessionInt(absl::string_view path)
669
712
  {
670
- spdy::SpdyHeaderBlock headers;
713
+ spdy::Http2HeaderBlock headers;
671
714
  headers[":scheme"] = "https";
672
715
  headers[":authority"] = "localhost";
673
716
  headers[":path"] = path;
@@ -691,7 +734,7 @@ namespace quic
691
734
  {
692
735
  QUICHE_DCHECK(initialized_);
693
736
  QUICHE_DCHECK(!connected());
694
- QuicPacketWriter *writer = new QuicDefaultPacketWriter(GetLatestFD());
737
+ QuicPacketWriter *writer = new LevelTriggeredPacketWriter(GetLatestFD(), eventloop_->getQuicEventLoop());
695
738
  ParsedQuicVersion mutual_version = UnsupportedQuicVersion();
696
739
  const bool can_reconnect_with_different_version =
697
740
  CanReconnectWithDifferentVersion(&mutual_version);
@@ -717,7 +760,7 @@ namespace quic
717
760
 
718
761
  session_ = std::make_unique<Http3ClientSession>(
719
762
  config_, client_supported_versions, new QuicConnection(newconnid, QuicSocketAddress(), server_address_, helper_.get(), alarm_factory_.get(), writer,
720
- /* owns_writer= */ false, Perspective::IS_CLIENT, client_supported_versions),
763
+ /* owns_writer= */ false, Perspective::IS_CLIENT, client_supported_versions, connection_id_generator_),
721
764
  server_id_, &crypto_config_,
722
765
  &push_promise_index_, false /*drop_response_body_*/, true /* enable_web_transport */);
723
766
 
@@ -888,22 +931,17 @@ namespace quic
888
931
  bool success =
889
932
  event_loop->ArtificiallyNotifyEvent(fd, kSocketEventReadable);
890
933
  QUICHE_DCHECK(success);
891
- }
934
+ }
892
935
  if (!event_loop->SupportsEdgeTriggered())
893
936
  {
894
937
  bool success = event_loop->RearmSocket(fd, kSocketEventReadable);
895
938
  QUICHE_DCHECK(success);
896
939
  }
897
940
  }
898
- bool writeblocked = false;
899
941
  if (connected() && (events & kSocketEventWritable))
900
942
  {
901
943
  writer_->SetWritable();
902
944
  session_->connection()->OnCanWrite();
903
- if (writer_->IsWriteBlocked())
904
- {
905
- writeblocked = true;
906
- }
907
945
  }
908
946
 
909
947
  if (handleConnecting())
@@ -912,16 +950,6 @@ namespace quic
912
950
  event_loop->ArtificiallyNotifyEvent(fd, kSocketEventReadable);
913
951
  QUICHE_DCHECK(success);
914
952
  }
915
- if (writer_->IsWriteBlocked())
916
- {
917
- writeblocked = true;
918
- }
919
- if (!event_loop->SupportsEdgeTriggered() && writeblocked)
920
- {
921
- bool success = event_loop->RearmSocket(fd, kSocketEventWritable);
922
- QUICHE_DCHECK(success);
923
-
924
- }
925
953
  }
926
954
 
927
955
  void Http3Client::ProcessPacket(
@@ -943,7 +971,7 @@ namespace quic
943
971
  return response_headers_complete_;
944
972
  }
945
973
 
946
- const spdy::SpdyHeaderBlock *Http3Client::response_headers() const
974
+ const spdy::Http2HeaderBlock *Http3Client::response_headers() const
947
975
  {
948
976
  for (std::pair<QuicStreamId, QuicSpdyClientStream *> stream : open_streams_)
949
977
  {
@@ -956,7 +984,7 @@ namespace quic
956
984
  return &response_headers_;
957
985
  }
958
986
 
959
- const spdy::SpdyHeaderBlock *Http3Client::preliminary_headers() const
987
+ const spdy::Http2HeaderBlock *Http3Client::preliminary_headers() const
960
988
  {
961
989
  for (std::pair<QuicStreamId, QuicSpdyClientStream *> stream : open_streams_)
962
990
  {
@@ -971,7 +999,7 @@ namespace quic
971
999
  return &preliminary_headers_;
972
1000
  }
973
1001
 
974
- const spdy::SpdyHeaderBlock &Http3Client::response_trailers() const
1002
+ const spdy::Http2HeaderBlock &Http3Client::response_trailers() const
975
1003
  {
976
1004
  return response_trailers_;
977
1005
  }
@@ -1080,9 +1108,9 @@ namespace quic
1080
1108
  }
1081
1109
 
1082
1110
  bool Http3Client::CheckVary(
1083
- const spdy::SpdyHeaderBlock & /*client_request*/,
1084
- const spdy::SpdyHeaderBlock & /*promise_request*/,
1085
- const spdy::SpdyHeaderBlock & /*promise_response*/)
1111
+ const spdy::Http2HeaderBlock & /*client_request*/,
1112
+ const spdy::Http2HeaderBlock & /*promise_request*/,
1113
+ const spdy::Http2HeaderBlock & /*promise_response*/)
1086
1114
  {
1087
1115
  return true;
1088
1116
  }
@@ -1174,7 +1202,7 @@ namespace quic
1174
1202
  }
1175
1203
 
1176
1204
  Http3Client::Http3ClientDataToResend::Http3ClientDataToResend(
1177
- std::unique_ptr<spdy::SpdyHeaderBlock> headers, absl::string_view body,
1205
+ std::unique_ptr<spdy::Http2HeaderBlock> headers, absl::string_view body,
1178
1206
  bool fin, Http3Client *client)
1179
1207
  : headers_(std::move(headers)), body_(body), fin_(fin),
1180
1208
  client_(client) {}
@@ -1202,9 +1230,9 @@ namespace quic
1202
1230
  Http3Client::PerStreamState::PerStreamState(
1203
1231
  QuicRstStreamErrorCode stream_error, bool response_complete,
1204
1232
  bool response_headers_complete,
1205
- const spdy::SpdyHeaderBlock &response_headers,
1206
- const spdy::SpdyHeaderBlock &preliminary_headers,
1207
- const std::string &response, const spdy::SpdyHeaderBlock &response_trailers,
1233
+ const spdy::Http2HeaderBlock &response_headers,
1234
+ const spdy::Http2HeaderBlock &preliminary_headers,
1235
+ const std::string &response, const spdy::Http2HeaderBlock &response_trailers,
1208
1236
  uint64_t bytes_read, uint64_t bytes_written, int64_t response_body_size)
1209
1237
  : stream_error(stream_error),
1210
1238
  response_complete(response_complete),
@@ -1220,7 +1248,7 @@ namespace quic
1220
1248
  Http3Client::PerStreamState::~PerStreamState() = default;
1221
1249
 
1222
1250
  bool Http3Client::PopulateHeaderBlockFromUrl(
1223
- const std::string &uri, spdy::SpdyHeaderBlock *headers)
1251
+ const std::string &uri, spdy::Http2HeaderBlock *headers)
1224
1252
  {
1225
1253
  std::string url;
1226
1254
  if (absl::StartsWith(uri, "https://") || absl::StartsWith(uri, "http://"))
@@ -1271,8 +1299,7 @@ namespace quic
1271
1299
  latest_created_stream_ = nullptr;
1272
1300
  }
1273
1301
 
1274
- Http3ClientJS::Http3ClientJS(const Napi::CallbackInfo &info) :
1275
- Napi::ObjectWrap<Http3ClientJS>(info)
1302
+ Http3ClientJS::Http3ClientJS(const Napi::CallbackInfo &info) : Napi::ObjectWrap<Http3ClientJS>(info)
1276
1303
  {
1277
1304
 
1278
1305
  std::string port = "443";
@@ -1289,39 +1316,41 @@ namespace quic
1289
1316
  if (!lobj.IsEmpty())
1290
1317
  {
1291
1318
 
1292
- if (lobj.Has( "allowPooling") && !(lobj).Get("allowPooling").IsEmpty())
1319
+ if (lobj.Has("allowPooling") && !(lobj).Get("allowPooling").IsEmpty())
1293
1320
  {
1294
1321
  Napi::Value poolValue = (lobj).Get("allowPooling");
1295
1322
  allowPooling = poolValue.As<Napi::Boolean>().Value();
1296
1323
  }
1297
1324
 
1298
- if (lobj.Has( "forceIpv6") && !(lobj).Get("forceIpv6").IsEmpty())
1325
+ if (lobj.Has("forceIpv6") && !(lobj).Get("forceIpv6").IsEmpty())
1299
1326
  {
1300
1327
  Napi::Value ipv6Value = (lobj).Get("forceIpv6");
1301
1328
  forceipv6 = ipv6Value.As<Napi::Boolean>().Value();
1302
1329
  }
1303
1330
 
1304
- if (lobj.Has( "port") && !(lobj).Get("port").IsEmpty())
1331
+ if (lobj.Has("port") && !(lobj).Get("port").IsEmpty())
1305
1332
  {
1306
1333
  Napi::Value portValue = (lobj).Get("port");
1307
1334
  port = portValue.ToString().Utf8Value();
1308
1335
  }
1309
- else {
1336
+ else
1337
+ {
1310
1338
  Napi::Error::New(env, "no port specified").ThrowAsJavaScriptException();
1311
- return ;
1339
+ return;
1312
1340
  }
1313
1341
 
1314
- if (lobj.Has( "hostname") && !(lobj).Get("hostname").IsEmpty())
1342
+ if (lobj.Has("hostname") && !(lobj).Get("hostname").IsEmpty())
1315
1343
  {
1316
1344
  Napi::Value hostnameValue = (lobj).Get("hostname");
1317
1345
  hostname = hostnameValue.ToString().Utf8Value();
1318
1346
  }
1319
- else {
1347
+ else
1348
+ {
1320
1349
  Napi::Error::New(env, "no hostname specified").ThrowAsJavaScriptException();
1321
- return ;
1350
+ return;
1322
1351
  }
1323
1352
 
1324
- if (lobj.Has( "serverCertificateHashes") && !(lobj).Get("serverCertificateHashes").IsEmpty())
1353
+ if (lobj.Has("serverCertificateHashes") && !(lobj).Get("serverCertificateHashes").IsEmpty())
1325
1354
  {
1326
1355
  Napi::Value hashValue = (lobj).Get("serverCertificateHashes");
1327
1356
  if (hashValue.IsArray())
@@ -1341,40 +1370,45 @@ namespace quic
1341
1370
  size_t len = bufferlocal.As<Napi::Buffer<char>>().Length();
1342
1371
  curhash.value = std::string(buffer, len);
1343
1372
  }
1344
- else {
1373
+ else
1374
+ {
1345
1375
  Napi::Error::New(env, "serverCertificateHashes wrong format").ThrowAsJavaScriptException();
1346
- return ;
1376
+ return;
1347
1377
  }
1348
1378
  if (hashobj.Has("algorithm") && !(hashobj).Get("algorithm").IsEmpty())
1349
1379
  {
1350
1380
  Napi::Value algorithmValue = (hashobj).Get("algorithm");
1351
1381
  curhash.algorithm = algorithmValue.ToString().Utf8Value();
1352
1382
  }
1353
- else {
1383
+ else
1384
+ {
1354
1385
  Napi::Error::New(env, "serverCertificateHashes wrong format").ThrowAsJavaScriptException();
1355
- return ;
1386
+ return;
1356
1387
  }
1357
- if (curhash.algorithm.compare(WebTransportHash::kSha256) != 0) {
1388
+ if (curhash.algorithm.compare(WebTransportHash::kSha256) != 0)
1389
+ {
1358
1390
  Napi::Error::New(env, "serverCertificateHashes unknown algorithm").ThrowAsJavaScriptException();
1359
- return ;
1391
+ return;
1360
1392
  }
1361
1393
  serverCertificateHashes.push_back(curhash);
1362
1394
  }
1363
1395
  }
1364
- else {
1396
+ else
1397
+ {
1365
1398
  Napi::Error::New(env, "serverCertificateHashes is not an array").ThrowAsJavaScriptException();
1366
- return ;
1399
+ return;
1367
1400
  }
1368
1401
  }
1369
1402
 
1370
- if (lobj.Has( "localPort") && !(lobj).Get("localPort").IsEmpty())
1403
+ if (lobj.Has("localPort") && !(lobj).Get("localPort").IsEmpty())
1371
1404
  {
1372
1405
  Napi::Value localPortValue = (lobj).Get("localPort");
1373
1406
  if (localPortValue.IsNumber())
1374
1407
  local_port = localPortValue.As<Napi::Number>().Int32Value();
1375
- else {
1408
+ else
1409
+ {
1376
1410
  Napi::Error::New(env, "localPort is not a number").ThrowAsJavaScriptException();
1377
- return ;
1411
+ return;
1378
1412
  }
1379
1413
  }
1380
1414
  }
@@ -1391,7 +1425,7 @@ namespace quic
1391
1425
  else
1392
1426
  {
1393
1427
  Napi::Error::New(env, "No eventloop arguments passed to Http3Client").ThrowAsJavaScriptException();
1394
- return ;
1428
+ return;
1395
1429
  }
1396
1430
 
1397
1431
  std::unique_ptr<QuicConnectionHelperInterface> helper =
@@ -1409,13 +1443,14 @@ namespace quic
1409
1443
  if (!verifier->AddFingerprint(*cur))
1410
1444
  {
1411
1445
  Napi::Error::New(env, "serverCertificateHashes is not valid fingerprint").ThrowAsJavaScriptException();
1412
- return ;
1446
+ return;
1413
1447
  }
1414
1448
  }
1415
1449
  }
1416
- else {
1450
+ else
1451
+ {
1417
1452
  Napi::Error::New(env, "No supported verification method included").ThrowAsJavaScriptException();
1418
- return ;
1453
+ return;
1419
1454
  }
1420
1455
 
1421
1456
  std::unique_ptr<Http3SessionCache> cache;
@@ -1442,7 +1477,7 @@ namespace quic
1442
1477
  << gai_strerror(result);
1443
1478
  info_list = nullptr;
1444
1479
  Napi::Error::New(env, "URL host lookup failed").ThrowAsJavaScriptException();
1445
- return ;
1480
+ return;
1446
1481
  }
1447
1482
 
1448
1483
  QUICHE_CHECK(info_list != nullptr);
@@ -1450,7 +1485,7 @@ namespace quic
1450
1485
  freeaddrinfo(info_list);
1451
1486
 
1452
1487
  client_ = std::make_unique<Http3Client>(eventloop, address, hostname, local_port,
1453
- std::move(verifier), std::move(cache), std::move(helper));
1488
+ std::move(verifier), std::move(cache), std::move(helper));
1454
1489
  client_->SetUserAgentID("fails-components/webtransport");
1455
1490
 
1456
1491
  client_->setJS(this);
@@ -1462,11 +1497,10 @@ namespace quic
1462
1497
  client_->Connect();
1463
1498
  };
1464
1499
  client_->eventloop_->Schedule(task);
1465
- return ;
1500
+ return;
1466
1501
  }
1467
1502
 
1468
-
1469
- void Http3ClientJS::openWTSession(const Napi::CallbackInfo& info)
1503
+ void Http3ClientJS::openWTSession(const Napi::CallbackInfo &info)
1470
1504
  {
1471
1505
  Http3Client *obj = getObj();
1472
1506
  // got the object we can now start the server
@@ -1480,13 +1514,14 @@ namespace quic
1480
1514
  };
1481
1515
  obj->eventloop_->Schedule(task);
1482
1516
  }
1483
- else {
1517
+ else
1518
+ {
1484
1519
  Napi::Error::New(info.Env(), "openWTSession without path").ThrowAsJavaScriptException();
1485
- return ;
1520
+ return;
1486
1521
  }
1487
1522
  }
1488
1523
 
1489
- void Http3ClientJS::closeClient(const Napi::CallbackInfo& info)
1524
+ void Http3ClientJS::closeClient(const Napi::CallbackInfo &info)
1490
1525
  {
1491
1526
  Http3Client *obj = getObj();
1492
1527
  // got the object we can now start the server
@@ -1494,8 +1529,8 @@ namespace quic
1494
1529
  {
1495
1530
  if (!obj->closeClientInt())
1496
1531
  {
1497
- printf( "closeClientInt failed for Http3Client");
1498
- return ;
1532
+ printf("closeClientInt failed for Http3Client");
1533
+ return;
1499
1534
  }
1500
1535
  };
1501
1536
  obj->eventloop_->Schedule(task);
package/src/http3client.h CHANGED
@@ -29,6 +29,7 @@
29
29
  #include "quiche/quic/core/quic_packet_reader.h"
30
30
  #include "quiche/quic/platform/api/quic_socket_address.h"
31
31
  #include "quiche/quic/core/proto/cached_network_parameters_proto.h"
32
+ #include "quiche/quic/core/deterministic_connection_id_generator.h"
32
33
  #include "quiche/quic/core/quic_framer.h"
33
34
  #include "quiche/quic/core/quic_packet_creator.h"
34
35
  #include "quiche/quic/core/quic_packets.h"
@@ -133,12 +134,12 @@ namespace quic
133
134
 
134
135
  // Sends a request containing |headers| and |body| and returns the number of
135
136
  // bytes sent (the size of the serialized request headers and body).
136
- void SendMessageAsync(const spdy::SpdyHeaderBlock &headers,
137
+ void SendMessageAsync(const spdy::Http2HeaderBlock &headers,
137
138
  absl::string_view body);
138
139
  // Sends a request containing |headers| and |body| with the fin bit set to
139
140
  // |fin| and returns the number of bytes sent (the size of the serialized
140
141
  // request headers and body).
141
- void SendMessageAsync(const spdy::SpdyHeaderBlock &headers,
142
+ void SendMessageAsync(const spdy::Http2HeaderBlock &headers,
142
143
  absl::string_view body, bool fin);
143
144
 
144
145
  void SendConnectivityProbing();
@@ -173,14 +174,14 @@ namespace quic
173
174
  // is received. 2) returns state of the oldest active stream which have
174
175
  // received partial response (if any).
175
176
  // Group 1.
176
- const spdy::SpdyHeaderBlock &response_trailers() const;
177
+ const spdy::Http2HeaderBlock &response_trailers() const;
177
178
  bool response_complete() const;
178
179
  int64_t response_body_size() const;
179
180
  const std::string &response_body() const;
180
181
  // Group 2.
181
182
  bool response_headers_complete() const;
182
- const spdy::SpdyHeaderBlock *response_headers() const;
183
- const spdy::SpdyHeaderBlock *preliminary_headers() const;
183
+ const spdy::Http2HeaderBlock *response_headers() const;
184
+ const spdy::Http2HeaderBlock *preliminary_headers() const;
184
185
  int64_t response_size() const;
185
186
  size_t bytes_read() const;
186
187
  size_t bytes_written() const;
@@ -221,9 +222,9 @@ namespace quic
221
222
  const std::string &response_body);
222
223
 
223
224
  // From QuicClientPushPromiseIndex::Delegate
224
- bool CheckVary(const spdy::SpdyHeaderBlock &client_request,
225
- const spdy::SpdyHeaderBlock &promise_request,
226
- const spdy::SpdyHeaderBlock &promise_response) override;
225
+ bool CheckVary(const spdy::Http2HeaderBlock &client_request,
226
+ const spdy::Http2HeaderBlock &promise_request,
227
+ const spdy::Http2HeaderBlock &promise_response) override;
227
228
  void OnRendezvousResult(QuicSpdyStream *) override;
228
229
 
229
230
  // Returns nullptr if the maximum number of streams have already been created.
@@ -235,7 +236,7 @@ namespace quic
235
236
  // stores the request in case it needs to be resent. If |headers| is
236
237
  // null, only the body will be sent on the stream.
237
238
  void GetOrCreateStreamAndSendRequest(
238
- const spdy::SpdyHeaderBlock *headers, absl::string_view body, bool fin);
239
+ const spdy::Http2HeaderBlock *headers, absl::string_view body, bool fin);
239
240
 
240
241
  QuicRstStreamErrorCode stream_error() { return stream_error_; }
241
242
  QuicErrorCode connection_error() const;
@@ -272,7 +273,7 @@ namespace quic
272
273
  // request. If |uri| is a relative URL, the QuicServerId will be
273
274
  // use to specify the authority.
274
275
  bool PopulateHeaderBlockFromUrl(const std::string &uri,
275
- spdy::SpdyHeaderBlock *headers);
276
+ spdy::Http2HeaderBlock *headers);
276
277
 
277
278
  QuicSpdyClientStream *latest_created_stream()
278
279
  {
@@ -300,7 +301,7 @@ namespace quic
300
301
  {
301
302
  public:
302
303
  Http3ClientDataToResend(
303
- std::unique_ptr<spdy::SpdyHeaderBlock> headers, absl::string_view body,
304
+ std::unique_ptr<spdy::Http2HeaderBlock> headers, absl::string_view body,
304
305
  bool fin, Http3Client *client);
305
306
 
306
307
  ~Http3ClientDataToResend();
@@ -320,10 +321,10 @@ namespace quic
320
321
  PerStreamState(const PerStreamState &other);
321
322
  PerStreamState(QuicRstStreamErrorCode stream_error, bool response_complete,
322
323
  bool response_headers_complete,
323
- const spdy::SpdyHeaderBlock &response_headers,
324
- const spdy::SpdyHeaderBlock &preliminary_headers,
324
+ const spdy::Http2HeaderBlock &response_headers,
325
+ const spdy::Http2HeaderBlock &preliminary_headers,
325
326
  const std::string &response,
326
- const spdy::SpdyHeaderBlock &response_trailers,
327
+ const spdy::Http2HeaderBlock &response_trailers,
327
328
  uint64_t bytes_read, uint64_t bytes_written,
328
329
  int64_t response_body_size);
329
330
  ~PerStreamState();
@@ -331,10 +332,10 @@ namespace quic
331
332
  QuicRstStreamErrorCode stream_error;
332
333
  bool response_complete;
333
334
  bool response_headers_complete;
334
- spdy::SpdyHeaderBlock response_headers;
335
- spdy::SpdyHeaderBlock preliminary_headers;
335
+ spdy::Http2HeaderBlock response_headers;
336
+ spdy::Http2HeaderBlock preliminary_headers;
336
337
  std::string response;
337
- spdy::SpdyHeaderBlock response_trailers;
338
+ spdy::Http2HeaderBlock response_trailers;
338
339
  uint64_t bytes_read;
339
340
  uint64_t bytes_written;
340
341
  int64_t response_body_size;
@@ -353,6 +354,8 @@ namespace quic
353
354
  // Returns true if the corresponding of this client has active requests.
354
355
  bool HasActiveRequests();
355
356
 
357
+ ConnectionIdGeneratorInterface &connection_id_generator();
358
+
356
359
  // Actually clean up |fd|.
357
360
  void CleanUpUDPSocketImpl(QuicUdpSocketFd fd);
358
361
 
@@ -396,11 +399,11 @@ namespace quic
396
399
 
397
400
  bool response_complete_;
398
401
  bool response_headers_complete_;
399
- mutable spdy::SpdyHeaderBlock preliminary_headers_;
400
- mutable spdy::SpdyHeaderBlock response_headers_;
402
+ mutable spdy::Http2HeaderBlock preliminary_headers_;
403
+ mutable spdy::Http2HeaderBlock response_headers_;
401
404
 
402
405
  // Parsed response trailers (if present), copied from the stream in OnClose.
403
- spdy::SpdyHeaderBlock response_trailers_;
406
+ spdy::Http2HeaderBlock response_trailers_;
404
407
 
405
408
  spdy::SpdyPriority priority_;
406
409
  std::string response_;
@@ -541,6 +544,9 @@ namespace quic
541
544
  // space than allowed on the stack.
542
545
  std::unique_ptr<QuicPacketReader> packet_reader_;
543
546
 
547
+ DeterministicConnectionIdGenerator connection_id_generator_{
548
+ kQuicDefaultConnectionIdLength};
549
+
544
550
  Http3EventLoop *eventloop_;
545
551
  // connection workflow
546
552
  bool wait_for_encryption_;
@@ -23,14 +23,16 @@ Http3Dispatcher::Http3Dispatcher(
23
23
  std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
24
24
  std::unique_ptr<QuicAlarmFactory> alarm_factory,
25
25
  Http3ServerBackend* http3_server_backend,
26
- uint8_t expected_server_connection_id_length)
26
+ uint8_t expected_server_connection_id_length,
27
+ ConnectionIdGeneratorInterface& generator)
27
28
  : QuicDispatcher(config,
28
29
  crypto_config,
29
30
  version_manager,
30
31
  std::move(helper),
31
32
  std::move(session_helper),
32
33
  std::move(alarm_factory),
33
- expected_server_connection_id_length),
34
+ expected_server_connection_id_length,
35
+ generator),
34
36
  http3_server_backend_(http3_server_backend) {}
35
37
 
36
38
  Http3Dispatcher::~Http3Dispatcher() = default;
@@ -47,7 +49,7 @@ std::unique_ptr<QuicSession> Http3Dispatcher::CreateQuicSession(
47
49
  new QuicConnection(connection_id, self_address, peer_address, helper(),
48
50
  alarm_factory(), writer(),
49
51
  /* owns_writer= */ false, Perspective::IS_SERVER,
50
- ParsedQuicVersionVector{version});
52
+ ParsedQuicVersionVector{version}, connection_id_generator());
51
53
 
52
54
  auto session = std::make_unique<Http3ServerSession>(
53
55
  config(), GetSupportedVersions(), connection, this, session_helper(),
@@ -30,7 +30,8 @@ namespace quic
30
30
  std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
31
31
  std::unique_ptr<QuicAlarmFactory> alarm_factory,
32
32
  Http3ServerBackend *http3_server_backend,
33
- uint8_t expected_server_connection_id_length);
33
+ uint8_t expected_server_connection_id_length,
34
+ ConnectionIdGeneratorInterface& generator);
34
35
 
35
36
  ~Http3Dispatcher() override;
36
37