Add rebinding support to quic_client_interop
gfe-relnote: n/a, test-only
PiperOrigin-RevId: 274829536
Change-Id: I90b36e2fe4b9505068cb6f249bd6a43c58bd8248
diff --git a/quic/tools/quic_client_interop_test_bin.cc b/quic/tools/quic_client_interop_test_bin.cc
index 2511141..03f8aa9 100644
--- a/quic/tools/quic_client_interop_test_bin.cc
+++ b/quic/tools/quic_client_interop_test_bin.cc
@@ -39,6 +39,8 @@
kRetry,
// An H3 transaction succeeded.
kHttp3,
+ // We switched to a different port and the server migrated to it.
+ kRebinding,
};
char MatrixLetter(Feature f) {
@@ -55,13 +57,16 @@
return '3';
case Feature::kRetry:
return 'S';
+ case Feature::kRebinding:
+ return 'B';
}
}
std::set<Feature> AttemptRequest(QuicSocketAddress addr,
std::string authority,
QuicServerId server_id,
- ParsedQuicVersionVector versions) {
+ ParsedQuicVersionVector versions,
+ bool attempt_rebind) {
std::set<Feature> features;
auto proof_verifier = std::make_unique<FakeProofVerifier>();
QuicEpollServer epoll_server;
@@ -129,6 +134,26 @@
if (client->latest_response_code() != -1) {
features.insert(Feature::kHttp3);
+
+ if (attempt_rebind) {
+ // Now make a second request after switching to a different client port.
+ if (client->ChangeEphemeralPort()) {
+ client->SendRequest(header_block, "", /*fin=*/true);
+
+ const QuicTime second_request_start_time = epoll_clock.Now();
+ while (client->WaitForEvents()) {
+ if (epoll_clock.Now() - second_request_start_time >=
+ request_timeout) {
+ // Rebinding does not work, retry without attempting it.
+ return AttemptRequest(addr, authority, server_id, versions,
+ /*attempt_rebind=*/false);
+ }
+ }
+ features.insert(Feature::kRebinding);
+ } else {
+ QUIC_LOG(ERROR) << "Failed to change ephemeral port";
+ }
+ }
}
if (connection != nullptr && connection->connected()) {
@@ -173,11 +198,13 @@
versions_with_negotiation.insert(versions_with_negotiation.begin(),
QuicVersionReservedForNegotiation());
auto supported_features =
- AttemptRequest(addr, authority, server_id, versions_with_negotiation);
+ AttemptRequest(addr, authority, server_id, versions_with_negotiation,
+ /*attempt_rebind=*/true);
if (!supported_features.empty()) {
supported_features.insert(Feature::kVersionNegotiation);
} else {
- supported_features = AttemptRequest(addr, authority, server_id, versions);
+ supported_features = AttemptRequest(addr, authority, server_id, versions,
+ /*attempt_rebind=*/true);
}
return supported_features;
}