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