| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "content/browser/renderer_host/p2p_socket_host_posix.h" | 5 #include "content/browser/renderer_host/p2p_socket_host_posix.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <net/if.h> | 8 #include <net/if.h> |
| 9 #include <netinet/in.h> | 9 #include <netinet/in.h> |
| 10 #include <sys/ioctl.h> | 10 #include <sys/ioctl.h> |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 } | 64 } |
| 65 | 65 |
| 66 ptr++; | 66 ptr++; |
| 67 } | 67 } |
| 68 | 68 |
| 69 close(fd); | 69 close(fd); |
| 70 | 70 |
| 71 return found; | 71 return found; |
| 72 } | 72 } |
| 73 | 73 |
| 74 bool SocketAddressToSockAddr(const P2PSocketAddress& address, | |
| 75 sockaddr_in* addr) { | |
| 76 // TODO(sergeyu): Add IPv6 support. | |
| 77 if (address.address.size() != 4) { | |
| 78 return false; | |
| 79 } | |
| 80 | |
| 81 addr->sin_family = AF_INET; | |
| 82 memcpy(&addr->sin_addr, &address.address[0], 4); | |
| 83 addr->sin_port = htons(address.port); | |
| 84 return true; | |
| 85 } | |
| 86 | |
| 87 bool SockAddrToSocketAddress(sockaddr_in* addr, | |
| 88 P2PSocketAddress* address) { | |
| 89 if (addr->sin_family != AF_INET) { | |
| 90 LOG(ERROR) << "SockAddrToSocketAddress: only IPv4 addresses are supported"; | |
| 91 // TODO(sergeyu): Add IPv6 support. | |
| 92 return false; | |
| 93 } | |
| 94 | |
| 95 address->address.resize(4); | |
| 96 memcpy(&address->address[0], &addr->sin_addr, 4); | |
| 97 address->port = ntohs(addr->sin_port); | |
| 98 | |
| 99 return true; | |
| 100 } | |
| 101 | |
| 102 } // namespace | 74 } // namespace |
| 103 | 75 |
| 104 P2PSocketHostPosix::P2PSocketHostPosix( | 76 P2PSocketHostPosix::P2PSocketHostPosix( |
| 105 P2PSocketsHost* host, int routing_id, int id) | 77 P2PSocketsHost* host, int routing_id, int id) |
| 106 : P2PSocketHost(host, routing_id, id), | 78 : P2PSocketHost(host, routing_id, id), |
| 107 state_(STATE_UNINITIALIZED), socket_(0), read_watcher_(this) { | 79 state_(STATE_UNINITIALIZED), socket_(0), read_watcher_(this) { |
| 108 } | 80 } |
| 109 | 81 |
| 110 P2PSocketHostPosix::~P2PSocketHostPosix() { | 82 P2PSocketHostPosix::~P2PSocketHostPosix() { |
| 111 if (state_ == STATE_OPEN) { | 83 if (state_ == STATE_OPEN) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 socklen_t addrlen = sizeof(addr); | 126 socklen_t addrlen = sizeof(addr); |
| 155 result = getsockname(socket_, reinterpret_cast<sockaddr*>(&addr), | 127 result = getsockname(socket_, reinterpret_cast<sockaddr*>(&addr), |
| 156 &addrlen); | 128 &addrlen); |
| 157 if (result < 0) { | 129 if (result < 0) { |
| 158 LOG(ERROR) << "P2PSocket::Init(): unable to get local addr: " | 130 LOG(ERROR) << "P2PSocket::Init(): unable to get local addr: " |
| 159 << result; | 131 << result; |
| 160 OnError(); | 132 OnError(); |
| 161 return false; | 133 return false; |
| 162 } | 134 } |
| 163 | 135 |
| 164 P2PSocketAddress address; | 136 net::IPEndPoint address; |
| 165 if (!SockAddrToSocketAddress(&addr, &address)) { | 137 if (!address.FromSockAddr(reinterpret_cast<sockaddr*>(&addr), addrlen)) { |
| 166 OnError(); | 138 OnError(); |
| 167 return false; | 139 return false; |
| 168 } | 140 } |
| 169 | 141 |
| 170 VLOG(1) << "getsockname() returned " | 142 VLOG(1) << "getsockname() returned " |
| 171 << net::NetAddressToString( | 143 << address.ToString(); |
| 172 reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) | |
| 173 << ":" << address.port; | |
| 174 | 144 |
| 175 state_ = STATE_OPEN; | 145 state_ = STATE_OPEN; |
| 176 | 146 |
| 177 host_->Send(new P2PMsg_OnSocketCreated(routing_id_, id_, address)); | 147 host_->Send(new P2PMsg_OnSocketCreated(routing_id_, id_, address)); |
| 178 | 148 |
| 179 return true; | 149 return true; |
| 180 } | 150 } |
| 181 | 151 |
| 182 void P2PSocketHostPosix::OnError() { | 152 void P2PSocketHostPosix::OnError() { |
| 183 if (socket_ > 0) | 153 if (socket_ > 0) |
| 184 close(socket_); | 154 close(socket_); |
| 185 socket_ = 0; | 155 socket_ = 0; |
| 186 | 156 |
| 187 if (state_ == STATE_UNINITIALIZED || state_ == STATE_OPEN) | 157 if (state_ == STATE_UNINITIALIZED || state_ == STATE_OPEN) |
| 188 host_->Send(new P2PMsg_OnError(routing_id_, id_)); | 158 host_->Send(new P2PMsg_OnError(routing_id_, id_)); |
| 189 | 159 |
| 190 state_ = STATE_ERROR; | 160 state_ = STATE_ERROR; |
| 191 } | 161 } |
| 192 | 162 |
| 193 void P2PSocketHostPosix::DidCompleteRead() { | 163 void P2PSocketHostPosix::DidCompleteRead() { |
| 194 if (state_ != STATE_OPEN) | 164 if (state_ != STATE_OPEN) |
| 195 return; | 165 return; |
| 196 | 166 |
| 197 std::vector<char> data; | 167 std::vector<char> data; |
| 198 data.resize(4096); | 168 data.resize(4096); |
| 199 sockaddr_in addr; | 169 sockaddr_storage addr_storage; |
| 200 socklen_t addr_len = sizeof(addr); | 170 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage); |
| 201 int result = recvfrom(socket_, &data[0], data.size(), 0, | 171 socklen_t addr_len = sizeof(addr_storage); |
| 202 reinterpret_cast<sockaddr*>(&addr), &addr_len); | 172 int result = recvfrom(socket_, &data[0], data.size(), 0, addr, &addr_len); |
| 203 if (result > 0) { | 173 if (result > 0) { |
| 204 data.resize(result); | 174 data.resize(result); |
| 205 VLOG(2) << "received " << result << " bytes from " | 175 |
| 206 << net::NetAddressToString( | 176 net::IPEndPoint address; |
| 207 reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) | 177 if (!address.FromSockAddr(addr, addr_len) || |
| 208 << ":" << ntohs(addr.sin_port); | 178 address.GetFamily() != AF_INET) { |
| 209 P2PSocketAddress address; | 179 // We should never receive IPv6 packet on IPv4 packet. |
| 210 if (!SockAddrToSocketAddress(&addr, &address)) { | |
| 211 // Address conversion fails only if we receive a non-IPv4 | |
| 212 // packet, which should never happen because the socket is IPv4. | |
| 213 NOTREACHED(); | 180 NOTREACHED(); |
| 214 return; | 181 return; |
| 215 } | 182 } |
| 216 | 183 |
| 184 VLOG(2) << "received " << result << " bytes from " |
| 185 << address.ToString(); |
| 186 |
| 217 host_->Send(new P2PMsg_OnDataReceived(routing_id_, id_, | 187 host_->Send(new P2PMsg_OnDataReceived(routing_id_, id_, |
| 218 address, data)); | 188 address, data)); |
| 219 } else if (result < 0) { | 189 } else if (result < 0) { |
| 220 LOG(ERROR) << "recvfrom() returned error: " << result; | 190 LOG(ERROR) << "recvfrom() returned error: " << result; |
| 221 OnError(); | 191 OnError(); |
| 222 } | 192 } |
| 223 } | 193 } |
| 224 | 194 |
| 225 void P2PSocketHostPosix::Send(const P2PSocketAddress& socket_address, | 195 void P2PSocketHostPosix::Send(const net::IPEndPoint& socket_address, |
| 226 const std::vector<char>& data) { | 196 const std::vector<char>& data) { |
| 227 sockaddr_in addr; | 197 sockaddr_storage addr_storage; |
| 228 SocketAddressToSockAddr(socket_address, &addr); | 198 sockaddr* addr = reinterpret_cast<sockaddr*>(&addr_storage); |
| 229 int result = sendto(socket_, &data[0], data.size(), 0, | 199 size_t addr_len = sizeof(addr_storage); |
| 230 reinterpret_cast<sockaddr*>(&addr), sizeof(addr)); | 200 socket_address.ToSockAddr(addr, &addr_len); |
| 201 int result = sendto(socket_, &data[0], data.size(), 0, addr, addr_len); |
| 231 if (result < 0) { | 202 if (result < 0) { |
| 232 LOG(ERROR) << "Send failed."; | 203 LOG(ERROR) << "Send failed."; |
| 233 } else { | 204 } else { |
| 234 VLOG(2) << "Sent " << result << " bytes to " | 205 VLOG(2) << "Sent " << result << " bytes to " |
| 235 << net::NetAddressToString( | 206 << socket_address.ToString(); |
| 236 reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) | |
| 237 << ":" << ntohs(addr.sin_port); | |
| 238 } | 207 } |
| 239 } | 208 } |
| 240 | 209 |
| 241 // static | 210 // static |
| 242 P2PSocketHost* P2PSocketHost::Create( | 211 P2PSocketHost* P2PSocketHost::Create( |
| 243 P2PSocketsHost* host, int routing_id, int id, P2PSocketType type) { | 212 P2PSocketsHost* host, int routing_id, int id, P2PSocketType type) { |
| 244 switch (type) { | 213 switch (type) { |
| 245 case P2P_SOCKET_UDP: | 214 case P2P_SOCKET_UDP: |
| 246 return new P2PSocketHostPosix(host, routing_id, id); | 215 return new P2PSocketHostPosix(host, routing_id, id); |
| 247 | 216 |
| 248 case P2P_SOCKET_TCP_SERVER: | 217 case P2P_SOCKET_TCP_SERVER: |
| 249 // TODO(sergeyu): Implement TCP sockets support. | 218 // TODO(sergeyu): Implement TCP sockets support. |
| 250 return NULL; | 219 return NULL; |
| 251 | 220 |
| 252 case P2P_SOCKET_TCP_CLIENT: | 221 case P2P_SOCKET_TCP_CLIENT: |
| 253 return NULL; | 222 return NULL; |
| 254 } | 223 } |
| 255 | 224 |
| 256 NOTREACHED(); | 225 NOTREACHED(); |
| 257 return NULL; | 226 return NULL; |
| 258 } | 227 } |
| OLD | NEW |