| 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 <netinet/in.h> | 8 #include <netinet/in.h> |
| 9 #include <string.h> | 9 #include <string.h> |
| 10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
| 11 #include <sys/uio.h> | 11 #include <sys/uio.h> |
| 12 #include <string> | 12 #include <string> |
| 13 | 13 |
| 14 #include "base/basictypes.h" | 14 #include "base/basictypes.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "net/quic/quic_protocol.h" | 16 #include "net/quic/quic_protocol.h" |
| 17 | 17 |
| 18 #ifndef SO_RXQ_OVFL | 18 #ifndef SO_RXQ_OVFL |
| 19 #define SO_RXQ_OVFL 40 | 19 #define SO_RXQ_OVFL 40 |
| 20 #endif | 20 #endif |
| 21 | 21 |
| 22 namespace net { | 22 namespace net { |
| 23 namespace tools { | 23 namespace tools { |
| 24 | 24 |
| 25 // static | 25 // static |
| 26 IPAddressNumber QuicSocketUtils::GetAddressFromMsghdr(struct msghdr *hdr) { | 26 IPAddressNumber QuicSocketUtils::GetAddressFromMsghdr(struct msghdr *hdr) { |
| 27 if (hdr->msg_controllen > 0) { | 27 if (hdr->msg_controllen > 0) { |
| 28 for (cmsghdr* cmsg = CMSG_FIRSTHDR(hdr); | 28 for (cmsghdr* cmsg = CMSG_FIRSTHDR(hdr); |
| 29 cmsg != NULL; | 29 cmsg != nullptr; |
| 30 cmsg = CMSG_NXTHDR(hdr, cmsg)) { | 30 cmsg = CMSG_NXTHDR(hdr, cmsg)) { |
| 31 const uint8* addr_data = NULL; | 31 const uint8* addr_data = nullptr; |
| 32 int len = 0; | 32 int len = 0; |
| 33 if (cmsg->cmsg_type == IPV6_PKTINFO) { | 33 if (cmsg->cmsg_type == IPV6_PKTINFO) { |
| 34 in6_pktinfo* info = reinterpret_cast<in6_pktinfo*>CMSG_DATA(cmsg); | 34 in6_pktinfo* info = reinterpret_cast<in6_pktinfo*>CMSG_DATA(cmsg); |
| 35 in6_addr addr = info->ipi6_addr; | 35 in6_addr addr = info->ipi6_addr; |
| 36 addr_data = reinterpret_cast<const uint8*>(&addr); | 36 addr_data = reinterpret_cast<const uint8*>(&addr); |
| 37 len = sizeof(addr); | 37 len = sizeof(addr); |
| 38 } else if (cmsg->cmsg_type == IP_PKTINFO) { | 38 } else if (cmsg->cmsg_type == IP_PKTINFO) { |
| 39 in_pktinfo* info = reinterpret_cast<in_pktinfo*>CMSG_DATA(cmsg); | 39 in_pktinfo* info = reinterpret_cast<in_pktinfo*>CMSG_DATA(cmsg); |
| 40 in_addr addr = info->ipi_addr; | 40 in_addr addr = info->ipi_addr; |
| 41 addr_data = reinterpret_cast<const uint8*>(&addr); | 41 addr_data = reinterpret_cast<const uint8*>(&addr); |
| 42 len = sizeof(addr); | 42 len = sizeof(addr); |
| 43 } else { | 43 } else { |
| 44 continue; | 44 continue; |
| 45 } | 45 } |
| 46 return IPAddressNumber(addr_data, addr_data + len); | 46 return IPAddressNumber(addr_data, addr_data + len); |
| 47 } | 47 } |
| 48 } | 48 } |
| 49 DCHECK(false) << "Unable to get address from msghdr"; | 49 DCHECK(false) << "Unable to get address from msghdr"; |
| 50 return IPAddressNumber(); | 50 return IPAddressNumber(); |
| 51 } | 51 } |
| 52 | 52 |
| 53 // static | 53 // static |
| 54 bool QuicSocketUtils::GetOverflowFromMsghdr(struct msghdr *hdr, | 54 bool QuicSocketUtils::GetOverflowFromMsghdr(struct msghdr *hdr, |
| 55 uint32 *dropped_packets) { | 55 uint32 *dropped_packets) { |
| 56 if (hdr->msg_controllen > 0) { | 56 if (hdr->msg_controllen > 0) { |
| 57 struct cmsghdr *cmsg; | 57 struct cmsghdr *cmsg; |
| 58 for (cmsg = CMSG_FIRSTHDR(hdr); | 58 for (cmsg = CMSG_FIRSTHDR(hdr); |
| 59 cmsg != NULL; | 59 cmsg != nullptr; |
| 60 cmsg = CMSG_NXTHDR(hdr, cmsg)) { | 60 cmsg = CMSG_NXTHDR(hdr, cmsg)) { |
| 61 if (cmsg->cmsg_type == SO_RXQ_OVFL) { | 61 if (cmsg->cmsg_type == SO_RXQ_OVFL) { |
| 62 *dropped_packets = *(reinterpret_cast<int*>CMSG_DATA(cmsg)); | 62 *dropped_packets = *(reinterpret_cast<int*>CMSG_DATA(cmsg)); |
| 63 return true; | 63 return true; |
| 64 } | 64 } |
| 65 } | 65 } |
| 66 } | 66 } |
| 67 return false; | 67 return false; |
| 68 } | 68 } |
| 69 | 69 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 95 return false; | 95 return false; |
| 96 } | 96 } |
| 97 return true; | 97 return true; |
| 98 } | 98 } |
| 99 | 99 |
| 100 // static | 100 // static |
| 101 int QuicSocketUtils::ReadPacket(int fd, char* buffer, size_t buf_len, | 101 int QuicSocketUtils::ReadPacket(int fd, char* buffer, size_t buf_len, |
| 102 uint32* dropped_packets, | 102 uint32* dropped_packets, |
| 103 IPAddressNumber* self_address, | 103 IPAddressNumber* self_address, |
| 104 IPEndPoint* peer_address) { | 104 IPEndPoint* peer_address) { |
| 105 CHECK(peer_address != NULL); | 105 CHECK(peer_address != nullptr); |
| 106 const int kSpaceForOverflowAndIp = | 106 const int kSpaceForOverflowAndIp = |
| 107 CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(in6_pktinfo)); | 107 CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(in6_pktinfo)); |
| 108 char cbuf[kSpaceForOverflowAndIp]; | 108 char cbuf[kSpaceForOverflowAndIp]; |
| 109 memset(cbuf, 0, arraysize(cbuf)); | 109 memset(cbuf, 0, arraysize(cbuf)); |
| 110 | 110 |
| 111 iovec iov = {buffer, buf_len}; | 111 iovec iov = {buffer, buf_len}; |
| 112 struct sockaddr_storage raw_address; | 112 struct sockaddr_storage raw_address; |
| 113 msghdr hdr; | 113 msghdr hdr; |
| 114 | 114 |
| 115 hdr.msg_name = &raw_address; | 115 hdr.msg_name = &raw_address; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 127 | 127 |
| 128 // Return before setting dropped packets: if we get EAGAIN, it will | 128 // Return before setting dropped packets: if we get EAGAIN, it will |
| 129 // be 0. | 129 // be 0. |
| 130 if (bytes_read < 0 && errno != 0) { | 130 if (bytes_read < 0 && errno != 0) { |
| 131 if (errno != EAGAIN) { | 131 if (errno != EAGAIN) { |
| 132 LOG(ERROR) << "Error reading " << strerror(errno); | 132 LOG(ERROR) << "Error reading " << strerror(errno); |
| 133 } | 133 } |
| 134 return -1; | 134 return -1; |
| 135 } | 135 } |
| 136 | 136 |
| 137 if (dropped_packets != NULL) { | 137 if (dropped_packets != nullptr) { |
| 138 GetOverflowFromMsghdr(&hdr, dropped_packets); | 138 GetOverflowFromMsghdr(&hdr, dropped_packets); |
| 139 } | 139 } |
| 140 if (self_address != NULL) { | 140 if (self_address != nullptr) { |
| 141 *self_address = QuicSocketUtils::GetAddressFromMsghdr(&hdr); | 141 *self_address = QuicSocketUtils::GetAddressFromMsghdr(&hdr); |
| 142 } | 142 } |
| 143 | 143 |
| 144 if (raw_address.ss_family == AF_INET) { | 144 if (raw_address.ss_family == AF_INET) { |
| 145 CHECK(peer_address->FromSockAddr( | 145 CHECK(peer_address->FromSockAddr( |
| 146 reinterpret_cast<const sockaddr*>(&raw_address), | 146 reinterpret_cast<const sockaddr*>(&raw_address), |
| 147 sizeof(struct sockaddr_in))); | 147 sizeof(struct sockaddr_in))); |
| 148 } else if (raw_address.ss_family == AF_INET6) { | 148 } else if (raw_address.ss_family == AF_INET6) { |
| 149 CHECK(peer_address->FromSockAddr( | 149 CHECK(peer_address->FromSockAddr( |
| 150 reinterpret_cast<const sockaddr*>(&raw_address), | 150 reinterpret_cast<const sockaddr*>(&raw_address), |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 int rc = sendmsg(fd, &hdr, 0); | 216 int rc = sendmsg(fd, &hdr, 0); |
| 217 if (rc >= 0) { | 217 if (rc >= 0) { |
| 218 return WriteResult(WRITE_STATUS_OK, rc); | 218 return WriteResult(WRITE_STATUS_OK, rc); |
| 219 } | 219 } |
| 220 return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK) ? | 220 return WriteResult((errno == EAGAIN || errno == EWOULDBLOCK) ? |
| 221 WRITE_STATUS_BLOCKED : WRITE_STATUS_ERROR, errno); | 221 WRITE_STATUS_BLOCKED : WRITE_STATUS_ERROR, errno); |
| 222 } | 222 } |
| 223 | 223 |
| 224 } // namespace tools | 224 } // namespace tools |
| 225 } // namespace net | 225 } // namespace net |
| OLD | NEW |