Provide default QUICHE implementation for GetEcnCmsgArgsPreserveDscpImpl(). This will prevent failures when quic_support_ect1 is enabled, since the current code will return uninitialized values.

Protected by FLAGS_quic_restart_flag_quic_support_ect1.

PiperOrigin-RevId: 595134398
diff --git a/quiche/common/platform/default/quiche_platform_impl/quiche_udp_socket_platform_impl.h b/quiche/common/platform/default/quiche_platform_impl/quiche_udp_socket_platform_impl.h
index e79ac22..28664e9 100644
--- a/quiche/common/platform/default/quiche_platform_impl/quiche_udp_socket_platform_impl.h
+++ b/quiche/common/platform/default/quiche_platform_impl/quiche_udp_socket_platform_impl.h
@@ -5,6 +5,8 @@
 #ifndef QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_UDP_SOCKET_PLATFORM_IMPL_H_
 #define QUICHE_COMMON_PLATFORM_DEFAULT_QUICHE_PLATFORM_IMPL_QUICHE_UDP_SOCKET_PLATFORM_IMPL_H_
 
+#include <errno.h>
+#include <netinet/in.h>
 #include <sys/socket.h>
 #include <unistd.h>
 
@@ -15,6 +17,8 @@
 
 constexpr size_t kCmsgSpaceForGooglePacketHeaderImpl = 0;
 
+constexpr uint8_t kQuichePlatformImplEcnMask = 0x03;
+
 inline bool GetGooglePacketHeadersFromControlMessageImpl(
     struct ::cmsghdr* /*cmsg*/, char** /*packet_headers*/,
     size_t* /*packet_headers_len*/) {
@@ -23,12 +27,28 @@
 
 inline void SetGoogleSocketOptionsImpl(int /*fd*/) {}
 
-inline int GetEcnCmsgArgsPreserveDscpImpl(const int /*fd*/,
-                                          const int /*address_family*/,
-                                          uint8_t /*ecn_codepoint*/,
-                                          int& /*type*/, void* /*value*/,
-                                          socklen_t& /*value_len*/) {
-  // TODO(b/273081493): implement this.
+// The default implementation assigns ECN correctly given Linux socket APIs.
+// TODO(b/273081493): Implement Windows socket API calls.
+inline int GetEcnCmsgArgsPreserveDscpImpl(const int fd,
+                                          const int address_family,
+                                          uint8_t ecn_codepoint, int& type,
+                                          void* value, socklen_t& value_len) {
+  if ((address_family != AF_INET && address_family != AF_INET6) ||
+      (ecn_codepoint & kQuichePlatformImplEcnMask) != ecn_codepoint) {
+    return -EINVAL;
+  }
+  if (value_len < sizeof(int)) {
+    return -EINVAL;
+  }
+  int* arg = static_cast<int*>(value);
+  if (getsockopt(fd, (address_family == AF_INET) ? IPPROTO_IP : IPPROTO_IPV6,
+                 (address_family == AF_INET) ? IP_TOS : IPV6_TCLASS, arg,
+                 &value_len) != 0) {
+    return -1 * errno;
+  }
+  *arg &= static_cast<int>(~kQuichePlatformImplEcnMask);
+  *arg |= static_cast<int>(ecn_codepoint);
+  type = (address_family == AF_INET) ? IP_TOS : IPV6_TCLASS;
   return 0;
 }
 
diff --git a/quiche/quic/core/quic_flags_list.h b/quiche/quic/core/quic_flags_list.h
index 79a1e21..8808af3 100644
--- a/quiche/quic/core/quic_flags_list.h
+++ b/quiche/quic/core/quic_flags_list.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2023 The Chromium Authors. All rights reserved.
+// Copyright (c) 2024 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.