Use absl::down_cast in quiche / quic

Upgrade absl to 20260107.0 so we have a version that supports absl::down_cast.
Upgrade rules_cc to 0.2.9 to match absl.

PiperOrigin-RevId: 865498655
diff --git a/MODULE.bazel b/MODULE.bazel
index 45db83d..87523ba 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -7,11 +7,11 @@
 # Last updated 2025-09-09
 bazel_dep(name = "bazel_skylib", version = "1.8.1")
 
-# Last updated 2025-09-09
-bazel_dep(name = "rules_cc", version = "0.2.4")
+# Last updated 2026-02-04
+bazel_dep(name = "rules_cc", version = "0.2.9")
 
-# Last updated 2025-12-15
-bazel_dep(name = "abseil-cpp", version = "20250814.1", repo_name = "com_google_absl")
+# Last updated 2026-02-04
+bazel_dep(name = "abseil-cpp", version = "20260107.0", repo_name = "com_google_absl")
 
 # Last updated 2025-05-29
 bazel_dep(name = "protobuf", version = "31.1", repo_name = "com_google_protobuf")
diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock
index 838e953..7116652 100644
--- a/MODULE.bazel.lock
+++ b/MODULE.bazel.lock
@@ -16,8 +16,8 @@
     "https://bcr.bazel.build/modules/abseil-cpp/20250127.0/MODULE.bazel": "d1086e248cda6576862b4b3fe9ad76a214e08c189af5b42557a6e1888812c5d5",
     "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1",
     "https://bcr.bazel.build/modules/abseil-cpp/20250512.0/MODULE.bazel": "c4d02dd22cd87458516655a45512060246ee2a4732f1fbe948a5bd9eb614e626",
-    "https://bcr.bazel.build/modules/abseil-cpp/20250814.0/MODULE.bazel": "c43c16ca2c432566cdb78913964497259903ebe8fb7d9b57b38e9f1425b427b8",
-    "https://bcr.bazel.build/modules/abseil-cpp/20250814.0/source.json": "b88bff599ceaf0f56c264c749b1606f8485cec3b8c38ba30f88a4df9af142861",
+    "https://bcr.bazel.build/modules/abseil-cpp/20260107.0/MODULE.bazel": "94bdc259eccc59d880d3ae55e35ff1f27a289618a023cb1ed87182e17887b7c3",
+    "https://bcr.bazel.build/modules/abseil-cpp/20260107.0/source.json": "cd3c69eebe331264c87283774631f39006cd25caf159f4e1dab74322ef5c4bb9",
     "https://bcr.bazel.build/modules/abseil-py/2.1.0/MODULE.bazel": "5ebe5bf853769c65707e5c28f216798f7a4b1042015e6a36e6d03094d94bec8a",
     "https://bcr.bazel.build/modules/abseil-py/2.1.0/source.json": "0e8fc4f088ce07099c1cd6594c20c7ddbb48b4b3c0849b7d94ba94be88ff042b",
     "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896",
@@ -208,7 +208,6 @@
     "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a",
     "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/source.json": "2ff292be6ef3340325ce8a045ecc326e92cbfab47c7cbab4bd85d28971b97ac4",
     "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa",
-    "https://bcr.bazel.build/modules/riegeli/0.0.0-20241218-3385e3c/MODULE.bazel": "14bbe297ac80b30b689bde824d823f53bd87cd504ec3f82de72a730e7b02d526",
     "https://bcr.bazel.build/modules/riegeli/0.0.0-20250706-c4d1f27/MODULE.bazel": "b8b7309fb00c6b545fafcdfc3bf8cba168a61d37d841b9d90bacf7e70ae6627c",
     "https://bcr.bazel.build/modules/riegeli/0.0.0-20250706-c4d1f27/source.json": "af3e2998bdf2f0ca3695816695c079f885d1e5b838e1d05ca82450aba4941762",
     "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8",
@@ -230,9 +229,8 @@
     "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e",
     "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
     "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513",
-    "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c",
-    "https://bcr.bazel.build/modules/rules_cc/0.2.4/MODULE.bazel": "1ff1223dfd24f3ecf8f028446d4a27608aa43c3f41e346d22838a4223980b8cc",
-    "https://bcr.bazel.build/modules/rules_cc/0.2.4/source.json": "2bd87ef9b41d4753eadf65175745737135cba0e70b479bdc204ef0c67404d0c4",
+    "https://bcr.bazel.build/modules/rules_cc/0.2.9/MODULE.bazel": "34263f1dca62ea664265438cef714d7db124c03e1ed55ebb4f1dc860164308d1",
+    "https://bcr.bazel.build/modules/rules_cc/0.2.9/source.json": "4e49b40effcbd14fbfb233eb929de42dfff7b66538b4ffda310ad501638e7986",
     "https://bcr.bazel.build/modules/rules_foreign_cc/0.10.1/MODULE.bazel": "b9527010e5fef060af92b6724edb3691970a5b1f76f74b21d39f7d433641be60",
     "https://bcr.bazel.build/modules/rules_foreign_cc/0.10.1/source.json": "9300e71df0cdde0952f10afff1401fa664e9fc5d9ae6204660ba1b158d90d6a6",
     "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6",
diff --git a/quiche/BUILD.bazel b/quiche/BUILD.bazel
index c7e28c9..476ceb9 100644
--- a/quiche/BUILD.bazel
+++ b/quiche/BUILD.bazel
@@ -130,6 +130,7 @@
         "@boringssl//:crypto",
         "@boringssl//:ssl",
         "@com_google_absl//absl/algorithm:container",
+        "@com_google_absl//absl/base",
         "@com_google_absl//absl/base:core_headers",
         "@com_google_absl//absl/base:log_severity",
         "@com_google_absl//absl/base:nullability",
@@ -195,6 +196,7 @@
     deps = [
         ":quiche_core",
         "@boringssl//:crypto",
+        "@com_google_absl//absl/base",
         "@com_google_absl//absl/base:core_headers",
         "@com_google_absl//absl/container:flat_hash_map",
         "@com_google_absl//absl/container:flat_hash_set",
@@ -229,6 +231,7 @@
         ":quiche_tool_support",
         "@boringssl//:crypto",
         "@boringssl//:ssl",
+        "@com_google_absl//absl/base",
         "@com_google_absl//absl/base:core_headers",
         "@com_google_absl//absl/base:nullability",
         "@com_google_absl//absl/container:flat_hash_map",
@@ -383,6 +386,7 @@
         "@boringssl//:crypto",
         "@boringssl//:ssl",
         "@com_google_absl//absl/algorithm:container",
+        "@com_google_absl//absl/base",
         "@com_google_absl//absl/base:core_headers",
         "@com_google_absl//absl/base:nullability",
         "@com_google_absl//absl/cleanup",
@@ -445,6 +449,7 @@
         ":quiche_tool_support",
         "@boringssl//:crypto",
         "@com_google_absl//absl/algorithm:container",
+        "@com_google_absl//absl/base",
         "@com_google_absl//absl/base:core_headers",
         "@com_google_absl//absl/cleanup",
         "@com_google_absl//absl/container:flat_hash_map",
@@ -479,6 +484,7 @@
         "@boringssl//:crypto",
         "@boringssl//:ssl",
         "@com_google_absl//absl/algorithm:container",
+        "@com_google_absl//absl/base",
         "@com_google_absl//absl/base:core_headers",
         "@com_google_absl//absl/cleanup",
         "@com_google_absl//absl/container:flat_hash_map",
@@ -533,6 +539,7 @@
         ":quiche_core",
         ":quiche_test_support",
         ":quiche_tool_support",
+        "@com_google_absl//absl/base",
         "@com_google_absl//absl/base:nullability",
         "@com_google_absl//absl/functional:bind_front",
         "@com_google_absl//absl/hash",
diff --git a/quiche/quic/core/http/end_to_end_test.cc b/quiche/quic/core/http/end_to_end_test.cc
index 342980d..9e30120 100644
--- a/quiche/quic/core/http/end_to_end_test.cc
+++ b/quiche/quic/core/http/end_to_end_test.cc
@@ -18,7 +18,7 @@
 #include <utility>
 #include <vector>
 
-
+#include "absl/base/casts.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
 #include "absl/synchronization/notification.h"
@@ -477,7 +477,7 @@
       return nullptr;
     }
     EXPECT_EQ(1u, dispatcher->NumSessions());
-    return static_cast<QuicSpdySession*>(
+    return absl::down_cast<QuicSpdySession*>(
         QuicDispatcherPeer::GetFirstSessionIfAny(dispatcher));
   }
 
@@ -658,7 +658,7 @@
                                QuicDispatcherPeer::GetAlarmFactory(dispatcher),
                                std::make_unique<ServerDelegate>(dispatcher));
     if (stream_factory_ != nullptr) {
-      static_cast<QuicTestServer*>(server_thread_->server())
+      absl::down_cast<QuicTestServer*>(server_thread_->server())
           ->SetSpdyStreamFactory(stream_factory_);
     }
 
@@ -1053,7 +1053,7 @@
 
   QuicConfig PauseServerAndGetLastNegotiatedConfigFromDispatcher() {
     server_thread_->Pause();
-    QuicSimpleDispatcher* dispatcher = static_cast<QuicSimpleDispatcher*>(
+    QuicSimpleDispatcher* dispatcher = absl::down_cast<QuicSimpleDispatcher*>(
         QuicServerPeer::GetDispatcher(server_thread_->server()));
     std::optional<QuicConfig> config = dispatcher->last_negotiated_config();
     if (!config.has_value()) {
@@ -2385,7 +2385,7 @@
   client_->Disconnect();
 
   QuicClientSessionCache* session_cache =
-      static_cast<QuicClientSessionCache*>(
+      absl::down_cast<QuicClientSessionCache*>(
           client_crypto_config->session_cache());
   ASSERT_TRUE(
       !QuicClientSessionCachePeer::GetToken(session_cache, server_id).empty());
diff --git a/quiche/quic/core/http/quic_receive_control_stream_test.cc b/quiche/quic/core/http/quic_receive_control_stream_test.cc
index 6b5ac4f..7b8cd98 100644
--- a/quiche/quic/core/http/quic_receive_control_stream_test.cc
+++ b/quiche/quic/core/http/quic_receive_control_stream_test.cc
@@ -92,7 +92,7 @@
         session_(connection_) {
     EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
     session_.Initialize();
-    EXPECT_CALL(static_cast<const MockQuicCryptoStream&>(
+    EXPECT_CALL(absl::down_cast<const MockQuicCryptoStream&>(
                     *session_.GetCryptoStream()),
                 encryption_established())
         .WillRepeatedly(testing::Return(true));
diff --git a/quiche/quic/core/http/quic_server_session_base_test.cc b/quiche/quic/core/http/quic_server_session_base_test.cc
index bcb0242..12ce32d 100644
--- a/quiche/quic/core/http/quic_server_session_base_test.cc
+++ b/quiche/quic/core/http/quic_server_session_base_test.cc
@@ -668,7 +668,7 @@
       QuicTime::Delta::FromSeconds(kNumSecondsPerHour + 1));
 
   QuicCryptoServerStreamBase* crypto_stream =
-      static_cast<QuicCryptoServerStreamBase*>(
+      absl::down_cast<QuicCryptoServerStreamBase*>(
           QuicSessionPeer::GetMutableCryptoStream(session_.get()));
 
   // No effect if no CachedNetworkParameters provided.
@@ -804,7 +804,7 @@
   }
 
   FakeProofSource* GetFakeProofSource() const {
-    return static_cast<FakeProofSource*>(
+    return absl::down_cast<FakeProofSource*>(
         crypto_config_peer_.GetProofSource());
   }
 
diff --git a/quiche/quic/core/http/quic_spdy_session.cc b/quiche/quic/core/http/quic_spdy_session.cc
index 227294c..23395ff 100644
--- a/quiche/quic/core/http/quic_spdy_session.cc
+++ b/quiche/quic/core/http/quic_spdy_session.cc
@@ -13,8 +13,8 @@
 #include <string>
 #include <utility>
 
-
 #include "absl/base/attributes.h"
+#include "absl/base/casts.h"
 #include "absl/strings/numbers.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
@@ -864,7 +864,7 @@
               stream->version().transport_version, stream->id())) {
         return true;
       }
-      QuicSpdyStream* spdy_stream = static_cast<QuicSpdyStream*>(stream);
+      QuicSpdyStream* spdy_stream = absl::down_cast<QuicSpdyStream*>(stream);
       WebTransportHttp3* web_transport = spdy_stream->web_transport();
       if (web_transport == nullptr) {
         return true;
@@ -981,7 +981,7 @@
         ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
     return nullptr;
   }
-  return static_cast<QuicSpdyStream*>(stream);
+  return absl::down_cast<QuicSpdyStream*>(stream);
 }
 
 void QuicSpdySession::OnNewEncryptionKeyAvailable(
@@ -1858,7 +1858,7 @@
   stream_id64 *= kHttpDatagramStreamIdDivisor;
   QuicStreamId stream_id = static_cast<QuicStreamId>(stream_id64);
   QuicSpdyStream* stream =
-      static_cast<QuicSpdyStream*>(GetActiveStream(stream_id));
+      absl::down_cast<QuicSpdyStream*>(GetActiveStream(stream_id));
   if (stream == nullptr) {
     QUIC_DLOG(INFO) << "Received HTTP/3 datagram for unknown stream ID "
                     << stream_id;
diff --git a/quiche/quic/core/http/web_transport_http3.cc b/quiche/quic/core/http/web_transport_http3.cc
index bfb5e4a..4044796 100644
--- a/quiche/quic/core/http/web_transport_http3.cc
+++ b/quiche/quic/core/http/web_transport_http3.cc
@@ -11,8 +11,8 @@
 #include <utility>
 #include <vector>
 
-
 #include "absl/algorithm/container.h"
+#include "absl/base/casts.h"
 #include "absl/status/statusor.h"
 #include "absl/strings/string_view.h"
 #include "quiche/quic/core/http/quic_spdy_session.h"
@@ -222,7 +222,7 @@
       // receieved and the time the client has polled for them.
       continue;
     }
-    return static_cast<WebTransportHttp3UnidirectionalStream*>(stream)
+    return absl::down_cast<WebTransportHttp3UnidirectionalStream*>(stream)
         ->interface();
   }
   return nullptr;
@@ -264,9 +264,9 @@
   const bool bidi = QuicUtils::IsBidirectionalStreamId(
       id, ParsedQuicVersion::RFCv1());  // Assume IETF QUIC for WebTransport
   if (bidi) {
-    return static_cast<QuicSpdyStream*>(stream)->web_transport_stream();
+    return absl::down_cast<QuicSpdyStream*>(stream)->web_transport_stream();
   } else {
-    return static_cast<WebTransportHttp3UnidirectionalStream*>(stream)
+    return absl::down_cast<WebTransportHttp3UnidirectionalStream*>(stream)
         ->interface();
   }
 }
diff --git a/quiche/quic/core/qpack/qpack_receive_stream_test.cc b/quiche/quic/core/qpack/qpack_receive_stream_test.cc
index 78e657b..9e1cb7b 100644
--- a/quiche/quic/core/qpack/qpack_receive_stream_test.cc
+++ b/quiche/quic/core/qpack/qpack_receive_stream_test.cc
@@ -58,7 +58,7 @@
         session_(connection_) {
     EXPECT_CALL(session_, OnCongestionWindowChange(_)).Times(AnyNumber());
     session_.Initialize();
-    EXPECT_CALL(static_cast<const MockQuicCryptoStream&>(
+    EXPECT_CALL(absl::down_cast<const MockQuicCryptoStream&>(
                     *session_.GetCryptoStream()),
                 encryption_established())
         .WillRepeatedly(testing::Return(true));
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc
index 88223d3..e7b0832 100644
--- a/quiche/quic/core/quic_connection_test.cc
+++ b/quiche/quic/core/quic_connection_test.cc
@@ -543,7 +543,7 @@
 
  private:
   TestPacketWriter* writer() {
-    return static_cast<TestPacketWriter*>(QuicConnection::writer());
+    return absl::down_cast<TestPacketWriter*>(QuicConnection::writer());
   }
 
   SimpleDataProducer producer_;
diff --git a/quiche/quic/core/quic_crypto_server_stream_test.cc b/quiche/quic/core/quic_crypto_server_stream_test.cc
index 41795ef..18a9763 100644
--- a/quiche/quic/core/quic_crypto_server_stream_test.cc
+++ b/quiche/quic/core/quic_crypto_server_stream_test.cc
@@ -354,7 +354,7 @@
         crypto_config_peer_(&server_crypto_config_) {}
 
   FakeProofSource* GetFakeProofSource() const {
-    return static_cast<FakeProofSource*>(
+    return absl::down_cast<FakeProofSource*>(
         crypto_config_peer_.GetProofSource());
   }
 
diff --git a/quiche/quic/core/quic_dispatcher_test.cc b/quiche/quic/core/quic_dispatcher_test.cc
index 635587c..ecd9e2a 100644
--- a/quiche/quic/core/quic_dispatcher_test.cc
+++ b/quiche/quic/core/quic_dispatcher_test.cc
@@ -15,7 +15,6 @@
 #include <utility>
 #include <vector>
 
-
 #include "absl/base/macros.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
diff --git a/quiche/quic/core/quic_packet_creator_test.cc b/quiche/quic/core/quic_packet_creator_test.cc
index 6fa7218..62e7c6d 100644
--- a/quiche/quic/core/quic_packet_creator_test.cc
+++ b/quiche/quic/core/quic_packet_creator_test.cc
@@ -2618,7 +2618,7 @@
       SimpleDataProducer* producer)
       : QuicPacketCreator(connection_id, framer, random_generator, delegate),
         ack_frame_(InitAckFrame(1)),
-        delegate_(static_cast<MockDelegate*>(delegate)),
+        delegate_(absl::down_cast<MockDelegate*>(delegate)),
         producer_(producer) {}
 
   bool ConsumeRetransmittableControlFrame(const QuicFrame& frame,
diff --git a/quiche/quic/masque/masque_server_session.cc b/quiche/quic/masque/masque_server_session.cc
index 35eab91..cbed99a 100644
--- a/quiche/quic/masque/masque_server_session.cc
+++ b/quiche/quic/masque/masque_server_session.cc
@@ -22,8 +22,8 @@
 #include <utility>
 #include <vector>
 
-
 #include "absl/algorithm/container.h"
+#include "absl/base/casts.h"
 #include "absl/cleanup/cleanup.h"
 #include "absl/strings/escaping.h"
 #include "absl/strings/numbers.h"
@@ -508,7 +508,7 @@
   }
 
   if (protocol == "connect-ip") {
-    QuicSpdyStream* stream = static_cast<QuicSpdyStream*>(
+    QuicSpdyStream* stream = absl::down_cast<QuicSpdyStream*>(
         GetActiveStream(request_handler->stream_id()));
     if (stream == nullptr) {
       QUIC_BUG(bad masque server stream type)
@@ -648,7 +648,7 @@
     use_ipv6 = target_server_address.host().AddressFamilyToInt() == AF_INET6;
   }
 
-  QuicSpdyStream* stream = static_cast<QuicSpdyStream*>(
+  QuicSpdyStream* stream = absl::down_cast<QuicSpdyStream*>(
       GetActiveStream(request_handler->stream_id()));
   if (stream == nullptr) {
     QUIC_BUG(bad masque server stream type)
diff --git a/quiche/quic/moqt/moqt_parser.cc b/quiche/quic/moqt/moqt_parser.cc
index 9891815..a55455d 100644
--- a/quiche/quic/moqt/moqt_parser.cc
+++ b/quiche/quic/moqt/moqt_parser.cc
@@ -15,7 +15,7 @@
 #include <variant>
 #include <vector>
 
-
+#include "absl/base/casts.h"
 #include "absl/cleanup/cleanup.h"
 #include "absl/container/fixed_array.h"
 #include "absl/strings/str_cat.h"
diff --git a/quiche/quic/moqt/moqt_session.cc b/quiche/quic/moqt/moqt_session.cc
index 2e90a54..d42810e 100644
--- a/quiche/quic/moqt/moqt_session.cc
+++ b/quiche/quic/moqt/moqt_session.cc
@@ -14,7 +14,7 @@
 #include <variant>
 #include <vector>
 
-
+#include "absl/base/casts.h"
 #include "absl/base/nullability.h"
 #include "absl/container/btree_map.h"
 #include "absl/container/flat_hash_map.h"
@@ -565,7 +565,7 @@
           fetch_task.release();
           return;
         }
-        auto* subscribe = static_cast<SubscribeRemoteTrack*>(track);
+        auto* subscribe = absl::down_cast<SubscribeRemoteTrack*>(track);
         RemoteTrackByName(track->full_track_name());
         subscribe->OnJoiningFetchReady(std::move(fetch_task));
       },
@@ -1062,7 +1062,8 @@
                     << "request_id = " << message.request_id << " "
                     << track->full_track_name();
   }
-  SubscribeRemoteTrack* subscribe = static_cast<SubscribeRemoteTrack*>(track);
+  SubscribeRemoteTrack* subscribe =
+      absl::down_cast<SubscribeRemoteTrack*>(track);
   subscribe->OnObjectOrOk();
   auto [it, success] =
       session_->subscribe_by_alias_.try_emplace(message.track_alias, subscribe);
@@ -1151,13 +1152,14 @@
                     << ", error = " << static_cast<uint64_t>(message.error_code)
                     << " (" << message.reason_phrase << ")";
     if (track->is_fetch()) {
-      UpstreamFetch* fetch = static_cast<UpstreamFetch*>(track);
+      UpstreamFetch* fetch = absl::down_cast<UpstreamFetch*>(track);
       absl::Status status =
           RequestErrorCodeToStatus(message.error_code, message.reason_phrase);
       fetch->OnFetchResult(Location(0, 0), MoqtDeliveryOrder::kAscending,
                            status, nullptr);
     } else {
-      SubscribeRemoteTrack* subscribe = static_cast<SubscribeRemoteTrack*>(track);
+      SubscribeRemoteTrack* subscribe =
+          absl::down_cast<SubscribeRemoteTrack*>(track);
       // Delete the by-name entry at this point prevents Subscribe() from
       // throwing an error due to a duplicate track name. The other entries for
       // this subscribe will be deleted after calling Subscribe().
@@ -1220,7 +1222,7 @@
   if (it == session_->upstream_by_id_.end()) {
     return;
   }
-  auto* subscribe = static_cast<SubscribeRemoteTrack*>(it->second.get());
+  auto* subscribe = absl::down_cast<SubscribeRemoteTrack*>(it->second.get());
   QUIC_DLOG(INFO) << ENDPOINT << "Received a PUBLISH_DONE for "
                   << it->second->full_track_name();
   subscribe->OnPublishDone(
@@ -1261,7 +1263,7 @@
       message.track_namespace, message.parameters,
       [&](std::optional<MoqtRequestErrorInfo> error) {
         MoqtSession* session =
-            static_cast<MoqtSession*>(session_weakptr.GetIfAvailable());
+            absl::down_cast<MoqtSession*>(session_weakptr.GetIfAvailable());
         if (session == nullptr) {
           return;
         }
@@ -1548,7 +1550,7 @@
   }
   QUIC_DLOG(INFO) << ENDPOINT << "Received the FETCH_OK for request_id = "
                   << message.request_id << " " << track->full_track_name();
-  UpstreamFetch* fetch = static_cast<UpstreamFetch*>(track);
+  UpstreamFetch* fetch = absl::down_cast<UpstreamFetch*>(track);
   fetch->OnFetchResult(
       message.end_location, message.group_order, absl::OkStatus(),
       [=, session = session_]() { session->CancelFetch(message.request_id); });
@@ -1644,7 +1646,8 @@
         no_more_objects_ = true;
       }
     }
-    SubscribeRemoteTrack* subscribe = static_cast<SubscribeRemoteTrack*>(track);
+    SubscribeRemoteTrack* subscribe =
+        absl::down_cast<SubscribeRemoteTrack*>(track);
     subscribe->OnObjectOrOk();
     if (subscribe->visitor() != nullptr) {
       PublishedObjectMetadata metadata;
@@ -1660,7 +1663,7 @@
     }
   } else {  // FETCH
     track->OnObjectOrOk();
-    UpstreamFetch* fetch = static_cast<UpstreamFetch*>(track);
+    UpstreamFetch* fetch = absl::down_cast<UpstreamFetch*>(track);
     if (!fetch->LocationIsValid(Location(message.group_id, message.object_id),
                                 message.object_status, end_of_message)) {
       // TODO(martinduke): in https://github.com/moq-wg/moq-transport/pull/1409
@@ -1708,7 +1711,7 @@
   }
   // It's a subscribe.
   SubscribeRemoteTrack* subscribe =
-      static_cast<SubscribeRemoteTrack*>(track_.GetIfAvailable());
+      absl::down_cast<SubscribeRemoteTrack*>(track_.GetIfAvailable());
   if (subscribe == nullptr) {
     return;
   }
@@ -1728,7 +1731,7 @@
         << "Requesting object, track in unexpected state";
     return;
   }
-  UpstreamFetch* fetch = static_cast<UpstreamFetch*>(track);
+  UpstreamFetch* fetch = absl::down_cast<UpstreamFetch*>(track);
   UpstreamFetch::UpstreamFetchTask* task = fetch->task();
   if (task == nullptr) {
     return;
@@ -1796,7 +1799,7 @@
         << "Fetch pointer is null";
     return;
   }
-  UpstreamFetch* fetch = static_cast<UpstreamFetch*>(it->second.get());
+  UpstreamFetch* fetch = absl::down_cast<UpstreamFetch*>(it->second.get());
   if (!knew_track_alias) {
     // If the task already exists (FETCH_OK has arrived), the callback will
     // immediately execute to read the first object. Otherwise, it will only
@@ -1973,7 +1976,7 @@
           continue;
         }
         OutgoingDataStream* stream =
-            static_cast<OutgoingDataStream*>(raw_stream->visitor());
+            absl::down_cast<OutgoingDataStream*>(raw_stream->visitor());
         stream->CreateAndSetAlarm(session_->callbacks_.clock->ApproximateNow() +
                                   delivery_timeout());
       }
@@ -2004,7 +2007,7 @@
   }
 
   OutgoingDataStream* stream =
-      static_cast<OutgoingDataStream*>(raw_stream->visitor());
+      absl::down_cast<OutgoingDataStream*>(raw_stream->visitor());
   stream->SendObjects(*this);
 }
 
@@ -2036,7 +2039,7 @@
     return;
   }
   OutgoingDataStream* stream =
-      static_cast<OutgoingDataStream*>(raw_stream->visitor());
+      absl::down_cast<OutgoingDataStream*>(raw_stream->visitor());
   stream->Fin(location);
 }
 
@@ -2388,13 +2391,13 @@
 
 void MoqtSession::OnMalformedTrack(RemoteTrack* track) {
   if (!track->is_fetch()) {
-    static_cast<SubscribeRemoteTrack*>(track)->visitor()->OnMalformedTrack(
+    absl::down_cast<SubscribeRemoteTrack*>(track)->visitor()->OnMalformedTrack(
         track->full_track_name());
     Unsubscribe(track->full_track_name());
     return;
   }
   UpstreamFetch::UpstreamFetchTask* task =
-      static_cast<UpstreamFetch*>(track)->task();
+      absl::down_cast<UpstreamFetch*>(track)->task();
   if (task != nullptr) {
     task->OnStreamAndFetchClosed(kResetCodeMalformedTrack,
                                  "Malformed track received");
@@ -2435,7 +2438,7 @@
       continue;
     }
     DestroySubscription(
-        static_cast<SubscribeRemoteTrack*>(upstream->second.get()));
+        absl::down_cast<SubscribeRemoteTrack*>(upstream->second.get()));
   }
 }
 
diff --git a/quiche/quic/moqt/moqt_session_test.cc b/quiche/quic/moqt/moqt_session_test.cc
index fd8f33c..17022d3 100644
--- a/quiche/quic/moqt/moqt_session_test.cc
+++ b/quiche/quic/moqt/moqt_session_test.cc
@@ -13,6 +13,7 @@
 #include <utility>
 #include <variant>
 
+#include "absl/base/casts.h"
 #include "absl/status/status.h"
 #include "absl/strings/match.h"
 #include "absl/strings/string_view.h"
@@ -3203,7 +3204,7 @@
   std::unique_ptr<MoqtFetchTask> fetch_task =
       MoqtSessionPeer::CreateUpstreamFetch(&session, &stream);
   UpstreamFetch::UpstreamFetchTask* task =
-      static_cast<UpstreamFetch::UpstreamFetchTask*>(fetch_task.get());
+      absl::down_cast<UpstreamFetch::UpstreamFetchTask*>(fetch_task.get());
   ASSERT_NE(task, nullptr);
   EXPECT_FALSE(task->HasObject());
   bool object_ready = false;
@@ -3356,8 +3357,9 @@
   subscription->OnNewObjectAvailable(Location(0, 0), 0,
                                      kDefaultPublisherPriority,
                                      MoqtForwardingPreference::kSubgroup);
-  auto* delivery_alarm = static_cast<quic::test::MockAlarmFactory::TestAlarm*>(
-      MoqtSessionPeer::GetAlarm(stream_visitor.get()));
+  auto* delivery_alarm =
+      absl::down_cast<quic::test::MockAlarmFactory::TestAlarm*>(
+          MoqtSessionPeer::GetAlarm(stream_visitor.get()));
   EXPECT_CALL(data_mock, ResetWithUserCode(kResetCodeDeliveryTimeout))
       .WillOnce([&](webtransport::StreamErrorCode /*error*/) {
         stream_visitor.reset();
@@ -3409,8 +3411,9 @@
 
   EXPECT_CALL(data_mock, Writev(_, _)).WillOnce(Return(absl::OkStatus()));
   subscription->OnNewFinAvailable(Location(0, 0), 0);
-  auto* delivery_alarm = static_cast<quic::test::MockAlarmFactory::TestAlarm*>(
-      MoqtSessionPeer::GetAlarm(stream_visitor.get()));
+  auto* delivery_alarm =
+      absl::down_cast<quic::test::MockAlarmFactory::TestAlarm*>(
+          MoqtSessionPeer::GetAlarm(stream_visitor.get()));
   EXPECT_CALL(data_mock, ResetWithUserCode(kResetCodeDeliveryTimeout))
       .WillOnce([&](webtransport::StreamErrorCode /*error*/) {
         stream_visitor.reset();
@@ -3493,8 +3496,9 @@
                                      MoqtForwardingPreference::kSubgroup);
 
   // Group 1 should start the timer on the Group 0 stream.
-  auto* delivery_alarm = static_cast<quic::test::MockAlarmFactory::TestAlarm*>(
-      MoqtSessionPeer::GetAlarm(stream_visitor1.get()));
+  auto* delivery_alarm =
+      absl::down_cast<quic::test::MockAlarmFactory::TestAlarm*>(
+          MoqtSessionPeer::GetAlarm(stream_visitor1.get()));
   EXPECT_CALL(data_mock1, ResetWithUserCode(kResetCodeDeliveryTimeout))
       .WillOnce([&](webtransport::StreamErrorCode /*error*/) {
         stream_visitor1.reset();
@@ -3586,8 +3590,9 @@
       127, std::nullopt, VersionSpecificParameters()));
   session_.GoAway("");
   // GoAway timer fires.
-  auto* goaway_alarm = static_cast<quic::test::MockAlarmFactory::TestAlarm*>(
-      MoqtSessionPeer::GetGoAwayTimeoutAlarm(&session_));
+  auto* goaway_alarm =
+      absl::down_cast<quic::test::MockAlarmFactory::TestAlarm*>(
+          MoqtSessionPeer::GetGoAwayTimeoutAlarm(&session_));
   EXPECT_CALL(mock_session_,
               CloseSession(static_cast<webtransport::SessionErrorCode>(
                                MoqtError::kGoawayTimeout),
@@ -3795,7 +3800,7 @@
       MoqtPublishDone(0, PublishDoneCode::kTrackEnded, kNumStreams + 1, "foo"));
   EXPECT_FALSE(track->all_streams_closed());
   auto* publish_done_alarm =
-      static_cast<quic::test::MockAlarmFactory::TestAlarm*>(
+      absl::down_cast<quic::test::MockAlarmFactory::TestAlarm*>(
           MoqtSessionPeer::GetPublishDoneAlarm(track));
   EXPECT_CALL(remote_track_visitor_, OnPublishDone(_));
   publish_done_alarm->Fire();
diff --git a/quiche/quic/moqt/test_tools/moqt_session_peer.h b/quiche/quic/moqt/test_tools/moqt_session_peer.h
index dfad53b..1fa97e5 100644
--- a/quiche/quic/moqt/test_tools/moqt_session_peer.h
+++ b/quiche/quic/moqt/test_tools/moqt_session_peer.h
@@ -10,7 +10,7 @@
 #include <optional>
 #include <utility>
 
-
+#include "absl/base/casts.h"
 #include "absl/status/status.h"
 #include "absl/strings/string_view.h"
 #include "quiche/quic/core/quic_alarm.h"
@@ -119,7 +119,7 @@
   static bool InSubscriptionWindow(MoqtObjectListener* subscription,
                                    Location sequence) {
     std::optional<SubscriptionFilter> filter =
-        static_cast<MoqtSession::PublishedSubscription*>(subscription)
+        absl::down_cast<MoqtSession::PublishedSubscription*>(subscription)
             ->parameters_.subscription_filter;
     return (!filter.has_value() || filter->InWindow(sequence));
   }
@@ -199,7 +199,7 @@
                  task = std::move(fetch_task);
                }));
     QUICHE_DCHECK(success);
-    UpstreamFetch* fetch = static_cast<UpstreamFetch*>(it->second.get());
+    UpstreamFetch* fetch = absl::down_cast<UpstreamFetch*>(it->second.get());
     // Initialize the fetch task
     fetch->OnFetchResult(
         Location{4, 10}, order, absl::OkStatus(),
@@ -208,7 +208,7 @@
         });
     ;
     auto mock_session =
-        static_cast<webtransport::test::MockSession*>(session->session());
+        absl::down_cast<webtransport::test::MockSession*>(session->session());
     EXPECT_CALL(*mock_session, AcceptIncomingUnidirectionalStream())
         .WillOnce(testing::Return(stream))
         .WillOnce(testing::Return(nullptr));
@@ -225,7 +225,7 @@
   }
 
   static quic::QuicAlarm* GetAlarm(webtransport::StreamVisitor* visitor) {
-    return static_cast<MoqtSession::OutgoingDataStream*>(visitor)
+    return absl::down_cast<MoqtSession::OutgoingDataStream*>(visitor)
         ->delivery_timeout_alarm_.get();
   }
 
@@ -240,18 +240,18 @@
 
   static quic::QuicTimeDelta GetDeliveryTimeout(
       MoqtObjectListener* subscription) {
-    return static_cast<MoqtSession::PublishedSubscription*>(subscription)
+    return absl::down_cast<MoqtSession::PublishedSubscription*>(subscription)
         ->delivery_timeout();
   }
   static void SetDeliveryTimeout(MoqtObjectListener* subscription,
                                  quic::QuicTimeDelta timeout) {
-    static_cast<MoqtSession::PublishedSubscription*>(subscription)
+    absl::down_cast<MoqtSession::PublishedSubscription*>(subscription)
         ->parameters_.delivery_timeout = timeout;
   }
 
   static bool SubgroupHasBeenReset(MoqtObjectListener* subscription,
                                    DataStreamIndex index) {
-    return static_cast<MoqtSession::PublishedSubscription*>(subscription)
+    return absl::down_cast<MoqtSession::PublishedSubscription*>(subscription)
         ->reset_subgroups()
         .contains(index);
   }
diff --git a/quiche/quic/moqt/test_tools/moqt_simulator.cc b/quiche/quic/moqt/test_tools/moqt_simulator.cc
index 4df183f..1b0d796 100644
--- a/quiche/quic/moqt/test_tools/moqt_simulator.cc
+++ b/quiche/quic/moqt/test_tools/moqt_simulator.cc
@@ -17,7 +17,7 @@
 #include <vector>
 
 #include "absl/algorithm/container.h"
-
+#include "absl/base/casts.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/str_format.h"
 #include "absl/strings/str_join.h"
diff --git a/quiche/quic/moqt/tools/moqt_relay_test.cc b/quiche/quic/moqt/tools/moqt_relay_test.cc
index 66df0d8..83210cb 100644
--- a/quiche/quic/moqt/tools/moqt_relay_test.cc
+++ b/quiche/quic/moqt/tools/moqt_relay_test.cc
@@ -11,7 +11,7 @@
 #include <string>
 #include <utility>
 
-
+#include "absl/base/casts.h"
 #include "absl/strings/string_view.h"
 #include "quiche/quic/core/io/quic_event_loop.h"
 #include "quiche/quic/core/quic_time.h"
@@ -185,7 +185,7 @@
   relay_.publisher()->AddNamespaceSubscriber(foo, &relay_probe);
   upstream_.publisher()->AddNamespaceSubscriber(foo, &upstream_probe);
   MoqtSession* upstream_session =
-      static_cast<MoqtSession*>(upstream_.last_server_session);
+      absl::down_cast<MoqtSession*>(upstream_.last_server_session);
   // Downstream publishes a namespace. It's stored in relay_ but upstream_
   // hasn't been notified.
   downstream_.client_session()->PublishNamespace(
diff --git a/quiche/quic/qbone/qbone_client.cc b/quiche/quic/qbone/qbone_client.cc
index 94a62e1..9f3739a 100644
--- a/quiche/quic/qbone/qbone_client.cc
+++ b/quiche/quic/qbone/qbone_client.cc
@@ -7,7 +7,7 @@
 #include <memory>
 #include <utility>
 
-
+#include "absl/base/casts.h"
 #include "absl/strings/string_view.h"
 #include "quiche/quic/core/io/quic_event_loop.h"
 #include "quiche/quic/core/quic_bandwidth.h"
@@ -50,7 +50,7 @@
 QboneClient::~QboneClient() { ResetSession(); }
 
 QboneClientSession* QboneClient::qbone_session() {
-  return static_cast<QboneClientSession*>(QuicClientBase::session());
+  return absl::down_cast<QboneClientSession*>(QuicClientBase::session());
 }
 
 void QboneClient::ProcessPacketFromNetwork(absl::string_view packet) {
diff --git a/quiche/quic/test_tools/quic_spdy_session_peer.cc b/quiche/quic/test_tools/quic_spdy_session_peer.cc
index 9ef123b..b7b4650 100644
--- a/quiche/quic/test_tools/quic_spdy_session_peer.cc
+++ b/quiche/quic/test_tools/quic_spdy_session_peer.cc
@@ -6,7 +6,7 @@
 
 #include <utility>
 
-
+#include "absl/base/casts.h"
 #include "quiche/quic/core/http/quic_spdy_session.h"
 #include "quiche/quic/core/qpack/qpack_receive_stream.h"
 #include "quiche/quic/core/quic_utils.h"
@@ -32,7 +32,7 @@
         QuicUtils::GetHeadersStreamId(session->transport_version())) {
       it.second.reset(headers_stream);
       session->headers_stream_ =
-          static_cast<QuicHeadersStream*>(it.second.get());
+          absl::down_cast<QuicHeadersStream*>(it.second.get());
       break;
     }
   }
diff --git a/quiche/quic/test_tools/quic_test_client.cc b/quiche/quic/test_tools/quic_test_client.cc
index 5160675..feb51b1 100644
--- a/quiche/quic/test_tools/quic_test_client.cc
+++ b/quiche/quic/test_tools/quic_test_client.cc
@@ -234,13 +234,13 @@
 
 MockableQuicClientDefaultNetworkHelper*
 MockableQuicClient::mockable_network_helper() {
-  return static_cast<MockableQuicClientDefaultNetworkHelper*>(
+  return absl::down_cast<MockableQuicClientDefaultNetworkHelper*>(
       default_network_helper());
 }
 
 const MockableQuicClientDefaultNetworkHelper*
 MockableQuicClient::mockable_network_helper() const {
-  return static_cast<const MockableQuicClientDefaultNetworkHelper*>(
+  return absl::down_cast<const MockableQuicClientDefaultNetworkHelper*>(
       default_network_helper());
 }
 
@@ -739,7 +739,7 @@
     latest_created_stream_ = nullptr;
   }
   QuicSpdyClientStream* client_stream =
-      static_cast<QuicSpdyClientStream*>(stream);
+      absl::down_cast<QuicSpdyClientStream*>(stream);
   QuicStreamId id = client_stream->id();
   closed_stream_states_.insert(std::make_pair(
       id,
diff --git a/quiche/quic/tools/quic_spdy_client_base.cc b/quiche/quic/tools/quic_spdy_client_base.cc
index f8401fe..ad66ba4 100644
--- a/quiche/quic/tools/quic_spdy_client_base.cc
+++ b/quiche/quic/tools/quic_spdy_client_base.cc
@@ -10,7 +10,7 @@
 #include <utility>
 #include <vector>
 
-
+#include "absl/base/casts.h"
 #include "absl/strings/numbers.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
@@ -38,16 +38,15 @@
       store_response_(false),
       latest_response_code_(-1) {}
 
-QuicSpdyClientBase::~QuicSpdyClientBase() {
-  ResetSession();
-}
+QuicSpdyClientBase::~QuicSpdyClientBase() { ResetSession(); }
 
 QuicSpdyClientSession* QuicSpdyClientBase::client_session() {
-  return static_cast<QuicSpdyClientSession*>(QuicClientBase::session());
+  return absl::down_cast<QuicSpdyClientSession*>(QuicClientBase::session());
 }
 
 const QuicSpdyClientSession* QuicSpdyClientBase::client_session() const {
-  return static_cast<const QuicSpdyClientSession*>(QuicClientBase::session());
+  return absl::down_cast<const QuicSpdyClientSession*>(
+      QuicClientBase::session());
 }
 
 void QuicSpdyClientBase::InitializeSession() {