Chromium Code Reviews| 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_win.h" | 5 #include "net/udp/udp_socket_win.h" |
| 6 | 6 |
| 7 #include <mstcpip.h> | 7 #include <mstcpip.h> |
| 8 | 8 |
| 9 #include "base/eintr_wrapper.h" | 9 #include "base/eintr_wrapper.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 87 closesocket(socket_); | 87 closesocket(socket_); |
| 88 socket_ = INVALID_SOCKET; | 88 socket_ = INVALID_SOCKET; |
| 89 } | 89 } |
| 90 | 90 |
| 91 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const { | 91 int UDPSocketWin::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 // TODO(szym): Simplify. http://crbug.com/126152 | |
| 97 if (!remote_address_.get()) { | 98 if (!remote_address_.get()) { |
| 98 struct sockaddr_storage addr_storage; | 99 SockaddrStorage storage; |
| 99 int addr_len = sizeof(addr_storage); | 100 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(WSAGetLastError()); | 101 return MapSystemError(WSAGetLastError()); |
| 103 scoped_ptr<IPEndPoint> address(new IPEndPoint()); | 102 scoped_ptr<IPEndPoint> address(new IPEndPoint()); |
| 104 if (!address->FromSockAddr(addr, addr_len)) | 103 if (!address->FromSockAddr(storage.addr, storage.addr_len)) |
| 105 return ERR_FAILED; | 104 return ERR_FAILED; |
| 106 remote_address_.reset(address.release()); | 105 remote_address_.reset(address.release()); |
| 107 } | 106 } |
| 108 | 107 |
| 109 *address = *remote_address_; | 108 *address = *remote_address_; |
| 110 return OK; | 109 return OK; |
| 111 } | 110 } |
| 112 | 111 |
| 113 int UDPSocketWin::GetLocalAddress(IPEndPoint* address) const { | 112 int UDPSocketWin::GetLocalAddress(IPEndPoint* address) const { |
| 114 DCHECK(CalledOnValidThread()); | 113 DCHECK(CalledOnValidThread()); |
| 115 DCHECK(address); | 114 DCHECK(address); |
| 116 if (!is_connected()) | 115 if (!is_connected()) |
| 117 return ERR_SOCKET_NOT_CONNECTED; | 116 return ERR_SOCKET_NOT_CONNECTED; |
| 118 | 117 |
| 118 // TODO(szym): Simplify. http://crbug.com/126152 | |
| 119 if (!local_address_.get()) { | 119 if (!local_address_.get()) { |
| 120 struct sockaddr_storage addr_storage; | 120 SockaddrStorage storage; |
| 121 socklen_t addr_len = sizeof(addr_storage); | 121 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(WSAGetLastError()); | 122 return MapSystemError(WSAGetLastError()); |
| 125 scoped_ptr<IPEndPoint> address(new IPEndPoint()); | 123 scoped_ptr<IPEndPoint> address(new IPEndPoint()); |
| 126 if (!address->FromSockAddr(addr, addr_len)) | 124 if (!address->FromSockAddr(storage.addr, storage.addr_len)) |
| 127 return ERR_FAILED; | 125 return ERR_FAILED; |
| 128 local_address_.reset(address.release()); | 126 local_address_.reset(address.release()); |
| 129 } | 127 } |
| 130 | 128 |
| 131 *address = *local_address_; | 129 *address = *local_address_; |
| 132 return OK; | 130 return OK; |
| 133 } | 131 } |
| 134 | 132 |
| 135 int UDPSocketWin::Read(IOBuffer* buf, | 133 int UDPSocketWin::Read(IOBuffer* buf, |
| 136 int buf_len, | 134 int buf_len, |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 211 if (rv < 0) | 209 if (rv < 0) |
| 212 return rv; | 210 return rv; |
| 213 | 211 |
| 214 if (bind_type_ == DatagramSocket::RANDOM_BIND) | 212 if (bind_type_ == DatagramSocket::RANDOM_BIND) |
| 215 rv = RandomBind(address); | 213 rv = RandomBind(address); |
| 216 // else connect() does the DatagramSocket::DEFAULT_BIND | 214 // else connect() does the DatagramSocket::DEFAULT_BIND |
| 217 | 215 |
| 218 if (rv < 0) | 216 if (rv < 0) |
| 219 return rv; | 217 return rv; |
| 220 | 218 |
| 221 struct sockaddr_storage addr_storage; | 219 SockaddrStorage storage; |
| 222 size_t addr_len = sizeof(addr_storage); | 220 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) |
| 223 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); | |
| 224 if (!address.ToSockAddr(addr, &addr_len)) | |
| 225 return ERR_FAILED; | 221 return ERR_FAILED; |
| 226 | 222 |
| 227 rv = connect(socket_, addr, addr_len); | 223 rv = connect(socket_, storage.addr, storage.addr_len); |
| 228 if (rv < 0) | 224 if (rv < 0) |
| 229 return MapSystemError(WSAGetLastError()); | 225 return MapSystemError(WSAGetLastError()); |
| 230 | 226 |
| 231 remote_address_.reset(new IPEndPoint(address)); | 227 remote_address_.reset(new IPEndPoint(address)); |
| 232 return rv; | 228 return rv; |
| 233 } | 229 } |
| 234 | 230 |
| 235 int UDPSocketWin::Bind(const IPEndPoint& address) { | 231 int UDPSocketWin::Bind(const IPEndPoint& address) { |
| 236 DCHECK(!is_connected()); | 232 DCHECK(!is_connected()); |
| 237 int rv = CreateSocket(address); | 233 int rv = CreateSocket(address); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 394 LogRead(result, NULL); | 390 LogRead(result, NULL); |
| 395 return result; | 391 return result; |
| 396 } | 392 } |
| 397 } | 393 } |
| 398 read_watcher_.StartWatching(read_overlapped_.hEvent, &read_delegate_); | 394 read_watcher_.StartWatching(read_overlapped_.hEvent, &read_delegate_); |
| 399 return ERR_IO_PENDING; | 395 return ERR_IO_PENDING; |
| 400 } | 396 } |
| 401 | 397 |
| 402 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len, | 398 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len, |
| 403 const IPEndPoint* address) { | 399 const IPEndPoint* address) { |
| 404 struct sockaddr_storage addr_storage; | 400 SockaddrStorage storage; |
| 405 size_t addr_len = sizeof(addr_storage); | 401 struct sockaddr* addr = storage.addr; |
| 406 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); | |
| 407 | |
| 408 // Convert address. | 402 // Convert address. |
| 409 if (!address) { | 403 if (!address) { |
| 410 addr = NULL; | 404 addr = NULL; |
|
eroman
2012/05/04 01:08:41
IMPORTANT: This translations scares me since there
szym
2012/05/04 02:38:29
This is the only exception to using storage.addr.
| |
| 411 addr_len = 0; | 405 storage.addr_len = 0; |
| 412 } else { | 406 } else { |
| 413 if (!address->ToSockAddr(addr, &addr_len)) { | 407 if (!address->ToSockAddr(storage.addr, &storage.addr_len)) { |
| 414 int result = ERR_FAILED; | 408 int result = ERR_FAILED; |
| 415 LogWrite(result, NULL, NULL); | 409 LogWrite(result, NULL, NULL); |
| 416 return result; | 410 return result; |
| 417 } | 411 } |
| 418 } | 412 } |
| 419 | 413 |
| 420 WSABUF write_buffer; | 414 WSABUF write_buffer; |
| 421 write_buffer.buf = buf->data(); | 415 write_buffer.buf = buf->data(); |
| 422 write_buffer.len = buf_len; | 416 write_buffer.len = buf_len; |
| 423 | 417 |
| 424 DWORD flags = 0; | 418 DWORD flags = 0; |
| 425 DWORD num; | 419 DWORD num; |
| 426 AssertEventNotSignaled(write_overlapped_.hEvent); | 420 AssertEventNotSignaled(write_overlapped_.hEvent); |
| 427 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, | 421 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, |
| 428 addr, addr_len, &write_overlapped_, NULL); | 422 addr, storage.addr_len, &write_overlapped_, NULL); |
| 429 if (rv == 0) { | 423 if (rv == 0) { |
| 430 if (ResetEventIfSignaled(write_overlapped_.hEvent)) { | 424 if (ResetEventIfSignaled(write_overlapped_.hEvent)) { |
| 431 int result = num; | 425 int result = num; |
| 432 LogWrite(result, buf->data(), address); | 426 LogWrite(result, buf->data(), address); |
| 433 return result; | 427 return result; |
| 434 } | 428 } |
| 435 } else { | 429 } else { |
| 436 int os_error = WSAGetLastError(); | 430 int os_error = WSAGetLastError(); |
| 437 if (os_error != WSA_IO_PENDING) { | 431 if (os_error != WSA_IO_PENDING) { |
| 438 int result = MapSystemError(os_error); | 432 int result = MapSystemError(os_error); |
| 439 LogWrite(result, NULL, NULL); | 433 LogWrite(result, NULL, NULL); |
| 440 return result; | 434 return result; |
| 441 } | 435 } |
| 442 } | 436 } |
| 443 | 437 |
| 444 write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_); | 438 write_watcher_.StartWatching(write_overlapped_.hEvent, &write_delegate_); |
| 445 return ERR_IO_PENDING; | 439 return ERR_IO_PENDING; |
| 446 } | 440 } |
| 447 | 441 |
| 448 int UDPSocketWin::DoBind(const IPEndPoint& address) { | 442 int UDPSocketWin::DoBind(const IPEndPoint& address) { |
| 449 struct sockaddr_storage addr_storage; | 443 SockaddrStorage storage; |
| 450 size_t addr_len = sizeof(addr_storage); | 444 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) |
| 451 struct sockaddr* addr = reinterpret_cast<struct sockaddr*>(&addr_storage); | |
| 452 if (!address.ToSockAddr(addr, &addr_len)) | |
| 453 return ERR_UNEXPECTED; | 445 return ERR_UNEXPECTED; |
| 454 int rv = bind(socket_, addr, addr_len); | 446 int rv = bind(socket_, storage.addr, storage.addr_len); |
| 455 return rv < 0 ? MapSystemError(WSAGetLastError()) : rv; | 447 return rv < 0 ? MapSystemError(WSAGetLastError()) : rv; |
| 456 } | 448 } |
| 457 | 449 |
| 458 int UDPSocketWin::RandomBind(const IPEndPoint& address) { | 450 int UDPSocketWin::RandomBind(const IPEndPoint& address) { |
| 459 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null()); | 451 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null()); |
| 460 | 452 |
| 461 // Construct IPAddressNumber of appropriate size (IPv4 or IPv6) of 0s. | 453 // Construct IPAddressNumber of appropriate size (IPv4 or IPv6) of 0s. |
| 462 IPAddressNumber ip(address.address().size()); | 454 IPAddressNumber ip(address.address().size()); |
| 463 | 455 |
| 464 for (int i = 0; i < kBindRetries; ++i) { | 456 for (int i = 0; i < kBindRetries; ++i) { |
| 465 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); | 457 int rv = DoBind(IPEndPoint(ip, rand_int_cb_.Run(kPortStart, kPortEnd))); |
| 466 if (rv == OK || rv != ERR_ADDRESS_IN_USE) | 458 if (rv == OK || rv != ERR_ADDRESS_IN_USE) |
| 467 return rv; | 459 return rv; |
| 468 } | 460 } |
| 469 return DoBind(IPEndPoint(ip, 0)); | 461 return DoBind(IPEndPoint(ip, 0)); |
| 470 } | 462 } |
| 471 | 463 |
| 472 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { | 464 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { |
| 473 const struct sockaddr* addr = | 465 const struct sockaddr* addr = |
| 474 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); | 466 reinterpret_cast<const struct sockaddr*>(&recv_addr_storage_); |
| 475 return address->FromSockAddr(addr, recv_addr_len_); | 467 return address->FromSockAddr(addr, recv_addr_len_); |
| 476 } | 468 } |
| 477 | 469 |
| 478 } // namespace net | 470 } // namespace net |
| OLD | NEW |