OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/tools/quic/quic_socket_utils.h" | 5 #include "net/tools/quic/quic_socket_utils.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <linux/net_tstamp.h> | 8 #include <linux/net_tstamp.h> |
9 #include <netinet/in.h> | 9 #include <netinet/in.h> |
10 #include <string.h> | 10 #include <string.h> |
11 #include <sys/socket.h> | 11 #include <sys/socket.h> |
12 #include <sys/uio.h> | 12 #include <sys/uio.h> |
13 #include <string> | 13 #include <string> |
14 | 14 |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "net/quic/core/quic_bug_tracker.h" | 16 #include "net/quic/core/quic_bug_tracker.h" |
17 #include "net/quic/core/quic_flags.h" | 17 #include "net/quic/core/quic_flags.h" |
18 #include "net/quic/core/quic_protocol.h" | 18 #include "net/quic/core/quic_protocol.h" |
19 | 19 |
20 #ifndef SO_RXQ_OVFL | 20 #ifndef SO_RXQ_OVFL |
21 #define SO_RXQ_OVFL 40 | 21 #define SO_RXQ_OVFL 40 |
22 #endif | 22 #endif |
23 | 23 |
24 namespace net { | 24 namespace net { |
25 | 25 |
26 // static | 26 // static |
27 void QuicSocketUtils::GetAddressAndTimestampFromMsghdr( | 27 void QuicSocketUtils::GetAddressAndTimestampFromMsghdr( |
28 struct msghdr* hdr, | 28 struct msghdr* hdr, |
29 IPAddress* address, | 29 IPAddress* address, |
30 QuicTime* timestamp, | 30 QuicWallTime* walltimestamp) { |
31 QuicWallTime* walltimestamp, | |
32 bool latched_walltimestamps) { | |
33 if (hdr->msg_controllen > 0) { | 31 if (hdr->msg_controllen > 0) { |
34 for (cmsghdr* cmsg = CMSG_FIRSTHDR(hdr); cmsg != nullptr; | 32 for (cmsghdr* cmsg = CMSG_FIRSTHDR(hdr); cmsg != nullptr; |
35 cmsg = CMSG_NXTHDR(hdr, cmsg)) { | 33 cmsg = CMSG_NXTHDR(hdr, cmsg)) { |
36 const uint8_t* addr_data = nullptr; | 34 const uint8_t* addr_data = nullptr; |
37 int len = 0; | 35 int len = 0; |
38 if (cmsg->cmsg_type == IPV6_PKTINFO) { | 36 if (cmsg->cmsg_type == IPV6_PKTINFO) { |
39 in6_pktinfo* info = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg)); | 37 in6_pktinfo* info = reinterpret_cast<in6_pktinfo*>(CMSG_DATA(cmsg)); |
40 addr_data = reinterpret_cast<const uint8_t*>(&info->ipi6_addr); | 38 addr_data = reinterpret_cast<const uint8_t*>(&info->ipi6_addr); |
41 len = sizeof(in6_addr); | 39 len = sizeof(in6_addr); |
42 *address = IPAddress(addr_data, len); | 40 *address = IPAddress(addr_data, len); |
43 } else if (cmsg->cmsg_type == IP_PKTINFO) { | 41 } else if (cmsg->cmsg_type == IP_PKTINFO) { |
44 in_pktinfo* info = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg)); | 42 in_pktinfo* info = reinterpret_cast<in_pktinfo*>(CMSG_DATA(cmsg)); |
45 addr_data = reinterpret_cast<const uint8_t*>(&info->ipi_addr); | 43 addr_data = reinterpret_cast<const uint8_t*>(&info->ipi_addr); |
46 len = sizeof(in_addr); | 44 len = sizeof(in_addr); |
47 *address = IPAddress(addr_data, len); | 45 *address = IPAddress(addr_data, len); |
48 } else if (cmsg->cmsg_level == SOL_SOCKET && | 46 } else if (cmsg->cmsg_level == SOL_SOCKET && |
49 cmsg->cmsg_type == SO_TIMESTAMPING) { | 47 cmsg->cmsg_type == SO_TIMESTAMPING) { |
50 LinuxTimestamping* lts = | 48 LinuxTimestamping* lts = |
51 reinterpret_cast<LinuxTimestamping*>(CMSG_DATA(cmsg)); | 49 reinterpret_cast<LinuxTimestamping*>(CMSG_DATA(cmsg)); |
52 timespec* ts = <s->systime; | 50 timespec* ts = <s->systime; |
53 int64_t usec = (static_cast<int64_t>(ts->tv_sec) * 1000 * 1000) + | 51 int64_t usec = (static_cast<int64_t>(ts->tv_sec) * 1000 * 1000) + |
54 (static_cast<int64_t>(ts->tv_nsec) / 1000); | 52 (static_cast<int64_t>(ts->tv_nsec) / 1000); |
55 if (latched_walltimestamps) { | 53 *walltimestamp = QuicWallTime::FromUNIXMicroseconds(usec); |
56 *walltimestamp = QuicWallTime::FromUNIXMicroseconds(usec); | |
57 } else { | |
58 *timestamp = | |
59 QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(usec); | |
60 } | |
61 } | 54 } |
62 } | 55 } |
63 } | 56 } |
64 } | 57 } |
65 | 58 |
66 // static | 59 // static |
67 bool QuicSocketUtils::GetOverflowFromMsghdr(struct msghdr* hdr, | 60 bool QuicSocketUtils::GetOverflowFromMsghdr(struct msghdr* hdr, |
68 QuicPacketCount* dropped_packets) { | 61 QuicPacketCount* dropped_packets) { |
69 if (hdr->msg_controllen > 0) { | 62 if (hdr->msg_controllen > 0) { |
70 struct cmsghdr* cmsg; | 63 struct cmsghdr* cmsg; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 } | 108 } |
116 return true; | 109 return true; |
117 } | 110 } |
118 | 111 |
119 // static | 112 // static |
120 int QuicSocketUtils::ReadPacket(int fd, | 113 int QuicSocketUtils::ReadPacket(int fd, |
121 char* buffer, | 114 char* buffer, |
122 size_t buf_len, | 115 size_t buf_len, |
123 QuicPacketCount* dropped_packets, | 116 QuicPacketCount* dropped_packets, |
124 IPAddress* self_address, | 117 IPAddress* self_address, |
125 QuicTime* timestamp, | |
126 QuicWallTime* walltimestamp, | 118 QuicWallTime* walltimestamp, |
127 bool latched_walltimestamps, | |
128 IPEndPoint* peer_address) { | 119 IPEndPoint* peer_address) { |
129 DCHECK(peer_address != nullptr); | 120 DCHECK(peer_address != nullptr); |
130 char cbuf[kSpaceForCmsg]; | 121 char cbuf[kSpaceForCmsg]; |
131 memset(cbuf, 0, arraysize(cbuf)); | 122 memset(cbuf, 0, arraysize(cbuf)); |
132 | 123 |
133 iovec iov = {buffer, buf_len}; | 124 iovec iov = {buffer, buf_len}; |
134 struct sockaddr_storage raw_address; | 125 struct sockaddr_storage raw_address; |
135 msghdr hdr; | 126 msghdr hdr; |
136 | 127 |
137 hdr.msg_name = &raw_address; | 128 hdr.msg_name = &raw_address; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 IPAddress stack_address; | 160 IPAddress stack_address; |
170 if (self_address == nullptr) { | 161 if (self_address == nullptr) { |
171 self_address = &stack_address; | 162 self_address = &stack_address; |
172 } | 163 } |
173 | 164 |
174 QuicWallTime stack_walltimestamp = QuicWallTime::FromUNIXMicroseconds(0); | 165 QuicWallTime stack_walltimestamp = QuicWallTime::FromUNIXMicroseconds(0); |
175 if (walltimestamp == nullptr) { | 166 if (walltimestamp == nullptr) { |
176 walltimestamp = &stack_walltimestamp; | 167 walltimestamp = &stack_walltimestamp; |
177 } | 168 } |
178 | 169 |
179 QuicTime stack_timestamp = QuicTime::Zero(); | 170 GetAddressAndTimestampFromMsghdr(&hdr, self_address, walltimestamp); |
180 if (timestamp == nullptr) { | |
181 timestamp = &stack_timestamp; | |
182 } | |
183 | |
184 GetAddressAndTimestampFromMsghdr(&hdr, self_address, timestamp, walltimestamp, | |
185 latched_walltimestamps); | |
186 | 171 |
187 if (raw_address.ss_family == AF_INET) { | 172 if (raw_address.ss_family == AF_INET) { |
188 CHECK(peer_address->FromSockAddr( | 173 CHECK(peer_address->FromSockAddr( |
189 reinterpret_cast<const sockaddr*>(&raw_address), | 174 reinterpret_cast<const sockaddr*>(&raw_address), |
190 sizeof(struct sockaddr_in))); | 175 sizeof(struct sockaddr_in))); |
191 } else if (raw_address.ss_family == AF_INET6) { | 176 } else if (raw_address.ss_family == AF_INET6) { |
192 CHECK(peer_address->FromSockAddr( | 177 CHECK(peer_address->FromSockAddr( |
193 reinterpret_cast<const sockaddr*>(&raw_address), | 178 reinterpret_cast<const sockaddr*>(&raw_address), |
194 sizeof(struct sockaddr_in6))); | 179 sizeof(struct sockaddr_in6))); |
195 } | 180 } |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 rc = SetGetSoftwareReceiveTimestamp(fd); | 294 rc = SetGetSoftwareReceiveTimestamp(fd); |
310 if (rc < 0) { | 295 if (rc < 0) { |
311 LOG(WARNING) << "SO_TIMESTAMPING not supported; using fallback: " | 296 LOG(WARNING) << "SO_TIMESTAMPING not supported; using fallback: " |
312 << strerror(errno); | 297 << strerror(errno); |
313 } | 298 } |
314 | 299 |
315 return fd; | 300 return fd; |
316 } | 301 } |
317 | 302 |
318 } // namespace net | 303 } // namespace net |
OLD | NEW |