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 |