1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef NET_THIRD_PARTY_QUICHE_OVERRIDES_QUICHE_PLATFORM_IMPL_QUICHE_UDP_SOCKET_PLATFORM_IMPL_H_
6 #define NET_THIRD_PARTY_QUICHE_OVERRIDES_QUICHE_PLATFORM_IMPL_QUICHE_UDP_SOCKET_PLATFORM_IMPL_H_
7 
8 #include <sys/socket.h>
9 #include <unistd.h>
10 
11 #include <cstddef>
12 #include <cstdint>
13 
14 namespace quiche {
15 
16 namespace {
17 
18 inline constexpr uint8_t kEcnMask = 0x03;
19 
20 }  // namespace
21 
22 const size_t kCmsgSpaceForGooglePacketHeaderImpl = 0;
23 
GetGooglePacketHeadersFromControlMessageImpl(struct::cmsghdr * cmsg,char ** packet_headers,size_t * packet_headers_len)24 inline bool GetGooglePacketHeadersFromControlMessageImpl(
25     struct ::cmsghdr* cmsg,
26     char** packet_headers,
27     size_t* packet_headers_len) {
28   return false;
29 }
30 
SetGoogleSocketOptionsImpl(int fd)31 inline void SetGoogleSocketOptionsImpl(int fd) {}
32 
33 // Reads the current DSCP bits on the socket and adds the ECN field requested
34 // in |ecn_codepoint|. Sets |type| to be the correct cmsg_type to use in sendmsg
35 // to set the TOS byte, and writes a correctly formulated struct representing
36 // the TOS byte in |value|. (Some platforms deviate from the POSIX standard of
37 // IP_TOS/IPV6_TCLASS and an int).
38 // Returns 0 on success and an error code on failure.
GetEcnCmsgArgsPreserveDscpImpl(const int fd,const int address_family,uint8_t ecn_codepoint,int & type,void * value,socklen_t & value_len)39 inline int GetEcnCmsgArgsPreserveDscpImpl(const int fd,
40                                           const int address_family,
41                                           uint8_t ecn_codepoint,
42                                           int& type,
43                                           void* value,
44                                           socklen_t& value_len) {
45   // Return if the calling function did not provide a valid address family
46   // or ECN codepoint.
47   if ((address_family != AF_INET && address_family != AF_INET6) ||
48       (ecn_codepoint & kEcnMask) != ecn_codepoint) {
49     return -EINVAL;
50   }
51   if (value_len < sizeof(int)) {
52     return -EINVAL;
53   }
54   int* arg = static_cast<int*>(value);
55   if (getsockopt(fd, (address_family == AF_INET) ? IPPROTO_IP : IPPROTO_IPV6,
56                  (address_family == AF_INET) ? IP_TOS : IPV6_TCLASS, arg,
57                  &value_len) != 0) {
58     return -1 * errno;
59   }
60   *arg &= static_cast<int>(~kEcnMask);
61   *arg |= static_cast<int>(ecn_codepoint);
62   type = (address_family == AF_INET) ? IP_TOS : IPV6_TCLASS;
63   return 0;
64 }
65 
66 }  // namespace quiche
67 
68 #endif  // NET_THIRD_PARTY_QUICHE_OVERRIDES_QUICHE_PLATFORM_IMPL_QUICHE_UDP_SOCKET_PLATFORM_IMPL_H_
69