| 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 |