Implement sending and receiving DRAIN_WEBTRANSPORT_SESSION
PiperOrigin-RevId: 540692201
diff --git a/quiche/common/capsule.cc b/quiche/common/capsule.cc
index 4c5ad5a..66d4a66 100644
--- a/quiche/common/capsule.cc
+++ b/quiche/common/capsule.cc
@@ -36,6 +36,8 @@
return "LEGACY_DATAGRAM_WITHOUT_CONTEXT";
case CapsuleType::CLOSE_WEBTRANSPORT_SESSION:
return "CLOSE_WEBTRANSPORT_SESSION";
+ case CapsuleType::DRAIN_WEBTRANSPORT_SESSION:
+ return "DRAIN_WEBTRANSPORT_SESSION";
case CapsuleType::ADDRESS_REQUEST:
return "ADDRESS_REQUEST";
case CapsuleType::ADDRESS_ASSIGN:
@@ -129,6 +131,10 @@
",error_message=\"", error_message, "\")");
}
+std::string DrainWebTransportSessionCapsule::ToString() const {
+ return "DRAIN_WEBTRANSPORT_SESSION()";
+}
+
std::string AddressRequestCapsule::ToString() const {
std::string rv = "ADDRESS_REQUEST[";
for (auto requested_address : requested_addresses) {
@@ -293,6 +299,8 @@
WireUint32(capsule.close_web_transport_session_capsule().error_code),
WireBytes(
capsule.close_web_transport_session_capsule().error_message));
+ case CapsuleType::DRAIN_WEBTRANSPORT_SESSION:
+ return SerializeCapsuleFields(capsule.capsule_type(), allocator);
case CapsuleType::ADDRESS_REQUEST:
return SerializeCapsuleFields(
capsule.capsule_type(), allocator,
@@ -414,6 +422,8 @@
capsule.error_message = reader.ReadRemainingPayload();
return Capsule(std::move(capsule));
}
+ case CapsuleType::DRAIN_WEBTRANSPORT_SESSION:
+ return Capsule(DrainWebTransportSessionCapsule());
case CapsuleType::ADDRESS_REQUEST: {
AddressRequestCapsule capsule;
while (!reader.IsDoneReading()) {
diff --git a/quiche/common/capsule.h b/quiche/common/capsule.h
index 08bde5b..7220ee4 100644
--- a/quiche/common/capsule.h
+++ b/quiche/common/capsule.h
@@ -13,6 +13,7 @@
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
+#include "quiche/common/platform/api/quiche_export.h"
#include "quiche/common/platform/api/quiche_logging.h"
#include "quiche/common/quiche_buffer_allocator.h"
#include "quiche/common/quiche_ip_address.h"
@@ -29,6 +30,7 @@
// <https://datatracker.ietf.org/doc/draft-ietf-webtrans-http3/>
CLOSE_WEBTRANSPORT_SESSION = 0x2843,
+ DRAIN_WEBTRANSPORT_SESSION = 0x78ae,
// draft-ietf-masque-connect-ip-03.
ADDRESS_ASSIGN = 0x1ECA6A00,
@@ -106,6 +108,13 @@
error_message == other.error_message;
}
};
+struct QUICHE_EXPORT DrainWebTransportSessionCapsule {
+ std::string ToString() const;
+ CapsuleType capsule_type() const {
+ return CapsuleType::DRAIN_WEBTRANSPORT_SESSION;
+ }
+ bool operator==(const DrainWebTransportSessionCapsule&) const { return true; }
+};
// MASQUE CONNECT-IP.
struct QUICHE_EXPORT PrefixWithId {
@@ -320,7 +329,8 @@
private:
absl::variant<DatagramCapsule, LegacyDatagramCapsule,
LegacyDatagramWithoutContextCapsule,
- CloseWebTransportSessionCapsule, AddressRequestCapsule,
+ CloseWebTransportSessionCapsule,
+ DrainWebTransportSessionCapsule, AddressRequestCapsule,
AddressAssignCapsule, RouteAdvertisementCapsule,
WebTransportStreamDataCapsule, WebTransportResetStreamCapsule,
WebTransportStopSendingCapsule, WebTransportMaxStreamsCapsule,
diff --git a/quiche/common/capsule_test.cc b/quiche/common/capsule_test.cc
index 5ed4d1a..ae55aaf 100644
--- a/quiche/common/capsule_test.cc
+++ b/quiche/common/capsule_test.cc
@@ -136,6 +136,20 @@
TestSerialization(expected_capsule, capsule_fragment);
}
+TEST_F(CapsuleTest, DrainWebTransportStreamCapsule) {
+ std::string capsule_fragment = absl::HexStringToBytes(
+ "800078ae" // DRAIN_WEBTRANSPORT_STREAM capsule type
+ "00" // capsule length
+ );
+ Capsule expected_capsule = Capsule(DrainWebTransportSessionCapsule());
+ {
+ EXPECT_CALL(visitor_, OnCapsule(expected_capsule));
+ ASSERT_TRUE(capsule_parser_.IngestCapsuleFragment(capsule_fragment));
+ }
+ ValidateParserIsEmpty();
+ TestSerialization(expected_capsule, capsule_fragment);
+}
+
TEST_F(CapsuleTest, AddressAssignCapsule) {
std::string capsule_fragment = absl::HexStringToBytes(
"9ECA6A00" // ADDRESS_ASSIGN capsule type
diff --git a/quiche/common/wire_serialization.h b/quiche/common/wire_serialization.h
index 89a54f2..7cc2596 100644
--- a/quiche/common/wire_serialization.h
+++ b/quiche/common/wire_serialization.h
@@ -347,6 +347,10 @@
QUICHE_RETURN_IF_ERROR(SerializeIntoWriterCore(writer, argno, data1));
return SerializeIntoWriterCore(writer, argno + 1, rest...);
}
+
+inline absl::Status SerializeIntoWriterCore(QuicheDataWriter&, int) {
+ return absl::OkStatus();
+}
} // namespace wire_serialization_internal
// SerializeIntoWriter(writer, d1, d2, ... dN) serializes all of supplied data
@@ -369,6 +373,7 @@
size_t ComputeLengthOnWire(T1 data1, Ts... rest) {
return data1.GetLengthOnWire() + ComputeLengthOnWire(rest...);
}
+inline size_t ComputeLengthOnWire() { return 0; }
// SerializeIntoBuffer(allocator, d1, d2, ... dN) computes the length required
// to store the supplied data, allocates the buffer of appropriate size using
diff --git a/quiche/common/wire_serialization_test.cc b/quiche/common/wire_serialization_test.cc
index b1dea91..9abdda9 100644
--- a/quiche/common/wire_serialization_test.cc
+++ b/quiche/common/wire_serialization_test.cc
@@ -252,5 +252,7 @@
#endif
}
+TEST(SerializationTest, Empty) { ExpectEncodingHex("nothing", ""); }
+
} // namespace
} // namespace quiche::test