Make QuicConnection  generate a new flow label when flow label based
black hole avoidance is enabled, and added CODE_COUNTS for when the
flow label changes

PiperOrigin-RevId: 686993723
diff --git a/quiche/quic/core/quic_connection.cc b/quiche/quic/core/quic_connection.cc
index d6e2fa1..72bf8c9 100644
--- a/quiche/quic/core/quic_connection.cc
+++ b/quiche/quic/core/quic_connection.cc
@@ -1174,13 +1174,13 @@
                    last_flow_label_received_) {
       if (expect_peer_flow_label_change_) {
         expect_peer_flow_label_change_ = false;
+        QUIC_CODE_COUNT(quic_detected_expected_flow_label_change);
       } else if (header.packet_number > GetLargestReceivedPacket() + 1) {
         // This packet introduced a packet number gap and came with a new flow
         // label so the peer is RTO'ing. In response, send a different flow
         // label.
-        uint32_t flow_label;
-        random_generator_->RandBytes(&flow_label, sizeof(flow_label));
-        set_outgoing_flow_label(flow_label);
+        GenerateNewOutgoingFlowLabel();
+        QUIC_CODE_COUNT(quic_generated_new_flow_label_on_flow_label_change);
       }
       last_flow_label_received_ = last_received_packet_info_.flow_label;
     }
@@ -2926,6 +2926,12 @@
   return direct_peer_address_ != last_received_packet_info_.source_address;
 }
 
+void QuicConnection::GenerateNewOutgoingFlowLabel() {
+  uint32_t flow_label;
+  random_generator_->RandBytes(&flow_label, sizeof(flow_label));
+  set_outgoing_flow_label(flow_label);
+}
+
 bool QuicConnection::ProcessValidatedPacket(const QuicPacketHeader& header) {
   if (perspective_ == Perspective::IS_CLIENT && version().HasIetfQuicFrames() &&
       direct_peer_address_.IsInitialized() &&
@@ -4198,10 +4204,9 @@
                                               clock_->Now());
     }
     if (enable_black_hole_avoidance_via_flow_label_) {
-      uint32_t flow_label;
-      random_generator_->RandBytes(&flow_label, sizeof(flow_label));
-      set_outgoing_flow_label(flow_label);
+      GenerateNewOutgoingFlowLabel();
       expect_peer_flow_label_change_ = true;
+      QUIC_CODE_COUNT(quic_generated_new_flow_label_on_pto);
     }
   }
   if (default_enable_5rto_blackhole_detection_ &&
diff --git a/quiche/quic/core/quic_connection.h b/quiche/quic/core/quic_connection.h
index be9bcb6..693873b 100644
--- a/quiche/quic/core/quic_connection.h
+++ b/quiche/quic/core/quic_connection.h
@@ -1449,7 +1449,9 @@
   }
 
   void EnableBlackholeAvoidanceViaFlowLabel() {
+    GenerateNewOutgoingFlowLabel();
     enable_black_hole_avoidance_via_flow_label_ = true;
+    QUIC_CODE_COUNT(quic_black_hole_avoidance_via_flow_label_enabled);
   }
 
   bool enable_black_hole_avoidance_via_flow_label() const {
@@ -2149,6 +2151,8 @@
 
   bool PeerAddressChanged() const;
 
+  void GenerateNewOutgoingFlowLabel();
+
   QuicAlarm& ack_alarm() { return alarms_.ack_alarm(); }
   const QuicAlarm& ack_alarm() const { return alarms_.ack_alarm(); }
   QuicAlarm& retransmission_alarm() { return alarms_.retransmission_alarm(); }
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc
index 8d36e98..6aa7ef3 100644
--- a/quiche/quic/core/quic_connection_test.cc
+++ b/quiche/quic/core/quic_connection_test.cc
@@ -9996,8 +9996,11 @@
   EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
   connection_.SetFromConfig(config);
   EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
-  connection_.set_outgoing_flow_label(1);
+  EXPECT_EQ(0, connection_.outgoing_flow_label());
   connection_.EnableBlackholeAvoidanceViaFlowLabel();
+  static_cast<test::MockRandom*>(helper_->GetRandomGenerator())->ChangeValue();
+  const uint32_t flow_label = connection_.outgoing_flow_label();
+  EXPECT_NE(0, flow_label);
 
   QuicStreamId stream_id = 2;
   QuicPacketNumber last_packet;
@@ -10009,7 +10012,7 @@
   // Fire PTO and verify the flow label has changed.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
   connection_.GetRetransmissionAlarm()->Fire();
-  EXPECT_NE(1, connection_.outgoing_flow_label());
+  EXPECT_NE(flow_label, connection_.outgoing_flow_label());
 }
 
 TEST_P(QuicConnectionTest, NewReceiveNewFlowLabelWithGapChangesFlowLabel) {
@@ -10020,21 +10023,24 @@
   config.SetConnectionOptionsToSend(connection_options);
   EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
   connection_.SetFromConfig(config);
+  EXPECT_EQ(0, connection_.outgoing_flow_label());
   connection_.EnableBlackholeAvoidanceViaFlowLabel();
-  const uint32_t flow_label = 1;
-  connection_.set_outgoing_flow_label(flow_label);
+  static_cast<test::MockRandom*>(helper_->GetRandomGenerator())->ChangeValue();
+  const uint32_t flow_label = connection_.outgoing_flow_label();
+  EXPECT_NE(0, flow_label);
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
 
   // Receive the first packet to initialize the flow label.
   ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_INITIAL, 0);
-  EXPECT_EQ(1, connection_.outgoing_flow_label());
+  EXPECT_EQ(flow_label, connection_.outgoing_flow_label());
 
   // Receive the second packet with the same flow label
   ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_INITIAL, flow_label);
-  EXPECT_EQ(1, connection_.outgoing_flow_label());
+  EXPECT_EQ(flow_label, connection_.outgoing_flow_label());
 
   // Receive a packet with gap and a new flow label and verify the outgoing
   // flow label has changed.
+  static_cast<test::MockRandom*>(helper_->GetRandomGenerator())->ChangeValue();
   ProcessDataPacketAtLevel(4, !kHasStopWaiting, ENCRYPTION_INITIAL,
                            flow_label + 1);
   EXPECT_NE(flow_label, connection_.outgoing_flow_label());
@@ -10049,18 +10055,20 @@
   config.SetConnectionOptionsToSend(connection_options);
   EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
   connection_.SetFromConfig(config);
+  EXPECT_EQ(0, connection_.outgoing_flow_label());
   connection_.EnableBlackholeAvoidanceViaFlowLabel();
-  const uint32_t flow_label = 1;
-  connection_.set_outgoing_flow_label(flow_label);
+  static_cast<test::MockRandom*>(helper_->GetRandomGenerator())->ChangeValue();
+  const uint32_t flow_label = connection_.outgoing_flow_label();
+  EXPECT_NE(0, flow_label);
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(AnyNumber());
 
   // Receive the first packet to initialize the flow label.
   ProcessDataPacketAtLevel(1, !kHasStopWaiting, ENCRYPTION_INITIAL, 0);
-  EXPECT_EQ(1, connection_.outgoing_flow_label());
+  EXPECT_EQ(flow_label, connection_.outgoing_flow_label());
 
   // Receive the second packet with the same flow label
   ProcessDataPacketAtLevel(2, !kHasStopWaiting, ENCRYPTION_INITIAL, flow_label);
-  EXPECT_EQ(1, connection_.outgoing_flow_label());
+  EXPECT_EQ(flow_label, connection_.outgoing_flow_label());
 
   // Receive a packet with no gap and a new flow label and verify the outgoing
   // flow label has not changed.