| OLD | NEW |
| 1 // Copyright (c) 2011 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/udp/udp_socket_libevent.h" | 5 #include "net/udp/udp_socket_libevent.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <netdb.h> | 9 #include <netdb.h> |
| 10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
| 11 | 11 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 socket_ = kInvalidSocket; | 88 socket_ = kInvalidSocket; |
| 89 } | 89 } |
| 90 | 90 |
| 91 int UDPSocketLibevent::GetPeerAddress(IPEndPoint* address) const { | 91 int UDPSocketLibevent::GetPeerAddress(IPEndPoint* address) const { |
| 92 DCHECK(CalledOnValidThread()); | 92 DCHECK(CalledOnValidThread()); |
| 93 DCHECK(address); | 93 DCHECK(address); |
| 94 if (!is_connected()) | 94 if (!is_connected()) |
| 95 return ERR_SOCKET_NOT_CONNECTED; | 95 return ERR_SOCKET_NOT_CONNECTED; |
| 96 | 96 |
| 97 if (!remote_address_.get()) { | 97 if (!remote_address_.get()) { |
| 98 struct sockaddr_storage addr_storage; | 98 SockaddrStorage storage; |
| 99 socklen_t addr_len = sizeof(addr_storage); | 99 if (getpeername(socket_, storage.addr, &storage.addr_len)) |
| 100 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); | |
| 101 if (getpeername(socket_, addr, &addr_len)) | |
| 102 return MapSystemError(errno); | 100 return MapSystemError(errno); |
| 103 scoped_ptr<IPEndPoint> address(new IPEndPoint()); | 101 scoped_ptr<IPEndPoint> address(new IPEndPoint()); |
| 104 if (!address->FromSockAddr(addr, addr_len)) | 102 if (!address->FromSockAddr(storage.addr, storage.addr_len)) |
| 105 return ERR_FAILED; | 103 return ERR_FAILED; |
| 106 remote_address_.reset(address.release()); | 104 remote_address_.reset(address.release()); |
| 107 } | 105 } |
| 108 | 106 |
| 109 *address = *remote_address_; | 107 *address = *remote_address_; |
| 110 return OK; | 108 return OK; |
| 111 } | 109 } |
| 112 | 110 |
| 113 int UDPSocketLibevent::GetLocalAddress(IPEndPoint* address) const { | 111 int UDPSocketLibevent::GetLocalAddress(IPEndPoint* address) const { |
| 114 DCHECK(CalledOnValidThread()); | 112 DCHECK(CalledOnValidThread()); |
| 115 DCHECK(address); | 113 DCHECK(address); |
| 116 if (!is_connected()) | 114 if (!is_connected()) |
| 117 return ERR_SOCKET_NOT_CONNECTED; | 115 return ERR_SOCKET_NOT_CONNECTED; |
| 118 | 116 |
| 119 if (!local_address_.get()) { | 117 if (!local_address_.get()) { |
| 120 struct sockaddr_storage addr_storage; | 118 SockaddrStorage storage; |
| 121 socklen_t addr_len = sizeof(addr_storage); | 119 if (getsockname(socket_, storage.addr, &storage.addr_len)) |
| 122 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); | |
| 123 if (getsockname(socket_, addr, &addr_len)) | |
| 124 return MapSystemError(errno); | 120 return MapSystemError(errno); |
| 125 scoped_ptr<IPEndPoint> address(new IPEndPoint()); | 121 scoped_ptr<IPEndPoint> address(new IPEndPoint()); |
| 126 if (!address->FromSockAddr(addr, addr_len)) | 122 if (!address->FromSockAddr(storage.addr, storage.addr_len)) |
| 127 return ERR_FAILED; | 123 return ERR_FAILED; |
| 128 local_address_.reset(address.release()); | 124 local_address_.reset(address.release()); |
| 129 } | 125 } |
| 130 | 126 |
| 131 *address = *local_address_; | 127 *address = *local_address_; |
| 132 return OK; | 128 return OK; |
| 133 } | 129 } |
| 134 | 130 |
| 135 int UDPSocketLibevent::Read(IOBuffer* buf, | 131 int UDPSocketLibevent::Read(IOBuffer* buf, |
| 136 int buf_len, | 132 int buf_len, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 if (rv < 0) | 229 if (rv < 0) |
| 234 return rv; | 230 return rv; |
| 235 | 231 |
| 236 if (bind_type_ == DatagramSocket::RANDOM_BIND) | 232 if (bind_type_ == DatagramSocket::RANDOM_BIND) |
| 237 rv = RandomBind(address); | 233 rv = RandomBind(address); |
| 238 // else connect() does the DatagramSocket::DEFAULT_BIND | 234 // else connect() does the DatagramSocket::DEFAULT_BIND |
| 239 | 235 |
| 240 if (rv < 0) | 236 if (rv < 0) |
| 241 return rv; | 237 return rv; |
| 242 | 238 |
| 243 struct sockaddr_storage addr_storage; | 239 SockaddrStorage storage; |
| 244 size_t addr_len = sizeof(addr_storage); | 240 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) |
| 245 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); | |
| 246 if (!address.ToSockAddr(addr, &addr_len)) | |
| 247 return ERR_FAILED; | 241 return ERR_FAILED; |
| 248 | 242 |
| 249 rv = HANDLE_EINTR(connect(socket_, addr, addr_len)); | 243 rv = HANDLE_EINTR(connect(socket_, storage.addr, storage.addr_len)); |
| 250 if (rv < 0) | 244 if (rv < 0) |
| 251 return MapSystemError(errno); | 245 return MapSystemError(errno); |
| 252 | 246 |
| 253 remote_address_.reset(new IPEndPoint(address)); | 247 remote_address_.reset(new IPEndPoint(address)); |
| 254 return rv; | 248 return rv; |
| 255 } | 249 } |
| 256 | 250 |
| 257 int UDPSocketLibevent::Bind(const IPEndPoint& address) { | 251 int UDPSocketLibevent::Bind(const IPEndPoint& address) { |
| 258 DCHECK(CalledOnValidThread()); | 252 DCHECK(CalledOnValidThread()); |
| 259 DCHECK(!is_connected()); | 253 DCHECK(!is_connected()); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 | 380 |
| 387 base::StatsCounter write_bytes("udp.write_bytes"); | 381 base::StatsCounter write_bytes("udp.write_bytes"); |
| 388 write_bytes.Add(result); | 382 write_bytes.Add(result); |
| 389 } | 383 } |
| 390 | 384 |
| 391 int UDPSocketLibevent::InternalRecvFrom(IOBuffer* buf, int buf_len, | 385 int UDPSocketLibevent::InternalRecvFrom(IOBuffer* buf, int buf_len, |
| 392 IPEndPoint* address) { | 386 IPEndPoint* address) { |
| 393 int bytes_transferred; | 387 int bytes_transferred; |
| 394 int flags = 0; | 388 int flags = 0; |
| 395 | 389 |
| 396 struct sockaddr_storage addr_storage; | 390 SockaddrStorage storage; |
| 397 socklen_t addr_len = sizeof(addr_storage); | |
| 398 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); | |
| 399 | 391 |
| 400 bytes_transferred = | 392 bytes_transferred = |
| 401 HANDLE_EINTR(recvfrom(socket_, | 393 HANDLE_EINTR(recvfrom(socket_, |
| 402 buf->data(), | 394 buf->data(), |
| 403 buf_len, | 395 buf_len, |
| 404 flags, | 396 flags, |
| 405 addr, | 397 storage.addr, |
| 406 &addr_len)); | 398 &storage.addr_len)); |
| 407 int result; | 399 int result; |
| 408 if (bytes_transferred >= 0) { | 400 if (bytes_transferred >= 0) { |
| 409 result = bytes_transferred; | 401 result = bytes_transferred; |
| 410 if (address && !address->FromSockAddr(addr, addr_len)) | 402 if (address && !address->FromSockAddr(storage.addr, storage.addr_len)) |
| 411 result = ERR_FAILED; | 403 result = ERR_FAILED; |
| 412 } else { | 404 } else { |
| 413 result = MapSystemError(errno); | 405 result = MapSystemError(errno); |
| 414 } | 406 } |
| 415 if (result != ERR_IO_PENDING) | 407 if (result != ERR_IO_PENDING) |
| 416 LogRead(result, buf->data(), addr_len, addr); | 408 LogRead(result, buf->data(), storage.addr_len, storage.addr); |
| 417 return result; | 409 return result; |
| 418 } | 410 } |
| 419 | 411 |
| 420 int UDPSocketLibevent::InternalSendTo(IOBuffer* buf, int buf_len, | 412 int UDPSocketLibevent::InternalSendTo(IOBuffer* buf, int buf_len, |
| 421 const IPEndPoint* address) { | 413 const IPEndPoint* address) { |
| 422 struct sockaddr_storage addr_storage; | 414 SockaddrStorage storage; |
| 423 size_t addr_len = sizeof(addr_storage); | 415 struct sockaddr* addr = storage.addr; |
| 424 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); | |
| 425 | |
| 426 if (!address) { | 416 if (!address) { |
| 427 addr = NULL; | 417 addr = NULL; |
| 428 addr_len = 0; | 418 storage.addr_len = 0; |
| 429 } else { | 419 } else { |
| 430 if (!address->ToSockAddr(addr, &addr_len)) { | 420 if (!address->ToSockAddr(storage.addr, &storage.addr_len)) { |
| 431 int result = ERR_FAILED; | 421 int result = ERR_FAILED; |
| 432 LogWrite(result, NULL, NULL); | 422 LogWrite(result, NULL, NULL); |
| 433 return result; | 423 return result; |
| 434 } | 424 } |
| 435 } | 425 } |
| 436 | 426 |
| 437 int result = HANDLE_EINTR(sendto(socket_, | 427 int result = HANDLE_EINTR(sendto(socket_, |
| 438 buf->data(), | 428 buf->data(), |
| 439 buf_len, | 429 buf_len, |
| 440 0, | 430 0, |
| 441 addr, | 431 addr, |
| 442 addr_len)); | 432 storage.addr_len)); |
| 443 if (result < 0) | 433 if (result < 0) |
| 444 result = MapSystemError(errno); | 434 result = MapSystemError(errno); |
| 445 if (result != ERR_IO_PENDING) | 435 if (result != ERR_IO_PENDING) |
| 446 LogWrite(result, buf->data(), address); | 436 LogWrite(result, buf->data(), address); |
| 447 return result; | 437 return result; |
| 448 } | 438 } |
| 449 | 439 |
| 450 int UDPSocketLibevent::DoBind(const IPEndPoint& address) { | 440 int UDPSocketLibevent::DoBind(const IPEndPoint& address) { |
| 451 struct sockaddr_storage addr_storage; | 441 SockaddrStorage storage; |
| 452 size_t addr_len = sizeof(addr_storage); | 442 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) |
| 453 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); | |
| 454 if (!address.ToSockAddr(addr, &addr_len)) | |
| 455 return ERR_UNEXPECTED; | 443 return ERR_UNEXPECTED; |
| 456 int rv = bind(socket_, addr, addr_len); | 444 int rv = bind(socket_, storage.addr, storage.addr_len); |
| 457 return rv < 0 ? MapSystemError(errno) : rv; | 445 return rv < 0 ? MapSystemError(errno) : rv; |
| 458 } | 446 } |
| 459 | 447 |
| 460 int UDPSocketLibevent::RandomBind(const IPEndPoint& address) { | 448 int UDPSocketLibevent::RandomBind(const IPEndPoint& address) { |
| 461 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null()); | 449 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null()); |
| 462 | 450 |
| 463 // Construct IPAddressNumber of appropriate size (IPv4 or IPv6) of 0s. | 451 // Construct IPAddressNumber of appropriate size (IPv4 or IPv6) of 0s. |
| 464 IPAddressNumber ip(address.address().size()); | 452 IPAddressNumber ip(address.address().size()); |
| 465 | 453 |
| 466 for (int i = 0; i < kBindRetries; ++i) { | 454 for (int i = 0; i < kBindRetries; ++i) { |
| 467 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); | 455 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); |
| 468 if (rv == OK || rv != ERR_ADDRESS_IN_USE) | 456 if (rv == OK || rv != ERR_ADDRESS_IN_USE) |
| 469 return rv; | 457 return rv; |
| 470 } | 458 } |
| 471 return DoBind(IPEndPoint(ip, 0)); | 459 return DoBind(IPEndPoint(ip, 0)); |
| 472 } | 460 } |
| 473 | 461 |
| 474 } // namespace net | 462 } // namespace net |
| OLD | NEW |