| Index: net/tools/quic/quic_dispatcher.cc
|
| diff --git a/net/tools/quic/quic_dispatcher.cc b/net/tools/quic/quic_dispatcher.cc
|
| index 9431130d19ce188dfce18818197ad500f8d56156..6157941c9c032b1fe6d788209377297b42a5450e 100644
|
| --- a/net/tools/quic/quic_dispatcher.cc
|
| +++ b/net/tools/quic/quic_dispatcher.cc
|
| @@ -279,6 +279,16 @@ bool QuicDispatcher::OnUnauthenticatedPublicHeader(
|
| return false;
|
| }
|
|
|
| + // Check if we are buffering packets for this connection ID
|
| + if (FLAGS_enable_async_get_proof &&
|
| + (temporarily_buffered_connections_.find(connection_id) !=
|
| + temporarily_buffered_connections_.end())) {
|
| + // This packet was received while the a CHLO for the same connection ID was
|
| + // being processed. Buffer it.
|
| + BufferEarlyPacket(connection_id);
|
| + return false;
|
| + }
|
| +
|
| if (!OnUnauthenticatedUnknownPublicHeader(header)) {
|
| return false;
|
| }
|
| @@ -358,8 +368,8 @@ void QuicDispatcher::ProcessUnauthenticatedHeaderFate(
|
| break;
|
| }
|
| case kFateTimeWait:
|
| - // MaybeRejectStatelessly might have already added the connection to
|
| - // time wait, in which case it should not be added again.
|
| + // MaybeRejectStatelessly or OnExpiredPackets might have already added the
|
| + // connection to time wait, in which case it should not be added again.
|
| if (!FLAGS_quic_use_cheap_stateless_rejects ||
|
| !time_wait_list_manager_->IsConnectionIdInTimeWait(connection_id)) {
|
| // Add this connection_id to the time-wait state, to safely reject
|
| @@ -374,10 +384,20 @@ void QuicDispatcher::ProcessUnauthenticatedHeaderFate(
|
| time_wait_list_manager_->ProcessPacket(
|
| current_server_address_, current_client_address_, connection_id,
|
| packet_number, *current_packet_);
|
| +
|
| + if (FLAGS_enable_async_get_proof) {
|
| + // Any packets which were buffered while the stateless rejector logic
|
| + // was running should be discarded. Do not inform the time wait list
|
| + // manager, which should already have a made a decision about sending a
|
| + // reject based on the CHLO alone.
|
| + buffered_packets_.DiscardPackets(connection_id);
|
| + }
|
| +
|
| break;
|
| case kFateBuffer:
|
| - // This packet is a non-CHLO packet which has arrived out of order.
|
| - // Buffer it.
|
| + // This packet is a non-CHLO packet which has arrived before the
|
| + // corresponding CHLO, *or* this packet was received while the
|
| + // corresponding CHLO was being processed. Buffer it.
|
| BufferEarlyPacket(connection_id);
|
| break;
|
| case kFateDrop:
|
| @@ -790,16 +810,24 @@ class StatelessRejectorProcessDoneCallback
|
| QuicPacketNumber packet_number,
|
| QuicVersion first_version)
|
| : dispatcher_(dispatcher),
|
| + current_client_address_(dispatcher->current_client_address_),
|
| + current_server_address_(dispatcher->current_server_address_),
|
| + current_packet_(
|
| + dispatcher->current_packet_->Clone()), // Note: copies the packet
|
| packet_number_(packet_number),
|
| first_version_(first_version) {}
|
|
|
| void Run(std::unique_ptr<StatelessRejector> rejector) override {
|
| - dispatcher_->OnStatelessRejectorProcessDone(std::move(rejector),
|
| - packet_number_, first_version_);
|
| + dispatcher_->OnStatelessRejectorProcessDone(
|
| + std::move(rejector), current_client_address_, current_server_address_,
|
| + std::move(current_packet_), packet_number_, first_version_);
|
| }
|
|
|
| private:
|
| QuicDispatcher* dispatcher_;
|
| + IPEndPoint current_client_address_;
|
| + IPEndPoint current_server_address_;
|
| + std::unique_ptr<QuicReceivedPacket> current_packet_;
|
| QuicPacketNumber packet_number_;
|
| QuicVersion first_version_;
|
| };
|
| @@ -861,6 +889,23 @@ void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id,
|
| return;
|
| }
|
|
|
| + // If we were able to make a decision about this CHLO based purely on the
|
| + // information available in OnChlo, just invoke the done callback immediately.
|
| + if (rejector->state() != StatelessRejector::UNKNOWN) {
|
| + ProcessStatelessRejectorState(std::move(rejector), header.packet_number,
|
| + header.public_header.versions.front());
|
| + return;
|
| + }
|
| +
|
| + // Insert into set of connection IDs to buffer
|
| + if (FLAGS_enable_async_get_proof) {
|
| + const bool ok =
|
| + temporarily_buffered_connections_.insert(connection_id).second;
|
| + QUIC_BUG_IF(!ok)
|
| + << "Processing multiple stateless rejections for connection ID "
|
| + << connection_id;
|
| + }
|
| +
|
| // Continue stateless rejector processing
|
| std::unique_ptr<StatelessRejectorProcessDoneCallback> cb(
|
| new StatelessRejectorProcessDoneCallback(
|
| @@ -870,6 +915,43 @@ void QuicDispatcher::MaybeRejectStatelessly(QuicConnectionId connection_id,
|
|
|
| void QuicDispatcher::OnStatelessRejectorProcessDone(
|
| std::unique_ptr<StatelessRejector> rejector,
|
| + const IPEndPoint& current_client_address,
|
| + const IPEndPoint& current_server_address,
|
| + std::unique_ptr<QuicReceivedPacket> current_packet,
|
| + QuicPacketNumber packet_number,
|
| + QuicVersion first_version) {
|
| + if (FLAGS_enable_async_get_proof) {
|
| + // Stop buffering packets on this connection
|
| + const auto num_erased =
|
| + temporarily_buffered_connections_.erase(rejector->connection_id());
|
| + QUIC_BUG_IF(num_erased != 1) << "Completing stateless rejection logic for "
|
| + "non-buffered connection ID "
|
| + << rejector->connection_id();
|
| +
|
| + // If this connection has gone into time-wait during the async processing,
|
| + // don't proceed.
|
| + if (time_wait_list_manager_->IsConnectionIdInTimeWait(
|
| + rejector->connection_id())) {
|
| + time_wait_list_manager_->ProcessPacket(
|
| + current_server_address, current_client_address,
|
| + rejector->connection_id(), packet_number, *current_packet);
|
| + return;
|
| + }
|
| + }
|
| +
|
| + // Reset current_* to correspond to the packet which initiated the stateless
|
| + // reject logic.
|
| + current_client_address_ = current_client_address;
|
| + current_server_address_ = current_server_address;
|
| + current_packet_ = current_packet.get();
|
| + current_connection_id_ = rejector->connection_id();
|
| +
|
| + ProcessStatelessRejectorState(std::move(rejector), packet_number,
|
| + first_version);
|
| +}
|
| +
|
| +void QuicDispatcher::ProcessStatelessRejectorState(
|
| + std::unique_ptr<StatelessRejector> rejector,
|
| QuicPacketNumber packet_number,
|
| QuicVersion first_version) {
|
| QuicPacketFate fate;
|
|
|