| 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/socket/udp_socket_win.h" | 5 #include "net/socket/udp_socket_win.h" |
| 6 | 6 |
| 7 #include <mstcpip.h> | 7 #include <mstcpip.h> |
| 8 | 8 |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 namespace { | 34 namespace { |
| 35 | 35 |
| 36 const int kBindRetries = 10; | 36 const int kBindRetries = 10; |
| 37 const int kPortStart = 1024; | 37 const int kPortStart = 1024; |
| 38 const int kPortEnd = 65535; | 38 const int kPortEnd = 65535; |
| 39 | 39 |
| 40 } // namespace | 40 } // namespace |
| 41 | 41 |
| 42 namespace net { | 42 namespace net { |
| 43 | 43 |
| 44 // This class encapsulates all the state that has to be preserved as long as | |
| 45 // there is a network IO operation in progress. If the owner UDPSocketWin | |
| 46 // is destroyed while an operation is in progress, the Core is detached and it | |
| 47 // lives until the operation completes and the OS doesn't reference any resource | |
| 48 // declared on this class anymore. | |
| 49 class UDPSocketWin::Core : public base::RefCounted<Core> { | |
| 50 public: | |
| 51 explicit Core(UDPSocketWin* socket); | |
| 52 | |
| 53 // Start watching for the end of a read or write operation. | |
| 54 void WatchForRead(); | |
| 55 void WatchForWrite(); | |
| 56 | |
| 57 // The UDPSocketWin is going away. | |
| 58 void Detach() { socket_ = NULL; } | |
| 59 | |
| 60 // The separate OVERLAPPED variables for asynchronous operation. | |
| 61 OVERLAPPED read_overlapped_; | |
| 62 OVERLAPPED write_overlapped_; | |
| 63 | |
| 64 // The buffers used in Read() and Write(). | |
| 65 scoped_refptr<IOBuffer> read_iobuffer_; | |
| 66 scoped_refptr<IOBuffer> write_iobuffer_; | |
| 67 | |
| 68 // The address storage passed to WSARecvFrom(). | |
| 69 SockaddrStorage recv_addr_storage_; | |
| 70 | |
| 71 private: | |
| 72 friend class base::RefCounted<Core>; | |
| 73 | |
| 74 class ReadDelegate : public base::win::ObjectWatcher::Delegate { | |
| 75 public: | |
| 76 explicit ReadDelegate(Core* core) : core_(core) {} | |
| 77 ~ReadDelegate() override {} | |
| 78 | |
| 79 // base::ObjectWatcher::Delegate methods: | |
| 80 void OnObjectSignaled(HANDLE object) override; | |
| 81 | |
| 82 private: | |
| 83 Core* const core_; | |
| 84 }; | |
| 85 | |
| 86 class WriteDelegate : public base::win::ObjectWatcher::Delegate { | |
| 87 public: | |
| 88 explicit WriteDelegate(Core* core) : core_(core) {} | |
| 89 ~WriteDelegate() override {} | |
| 90 | |
| 91 // base::ObjectWatcher::Delegate methods: | |
| 92 void OnObjectSignaled(HANDLE object) override; | |
| 93 | |
| 94 private: | |
| 95 Core* const core_; | |
| 96 }; | |
| 97 | |
| 98 ~Core(); | |
| 99 | |
| 100 // The socket that created this object. | |
| 101 UDPSocketWin* socket_; | |
| 102 | |
| 103 // |reader_| handles the signals from |read_watcher_|. | |
| 104 ReadDelegate reader_; | |
| 105 // |writer_| handles the signals from |write_watcher_|. | |
| 106 WriteDelegate writer_; | |
| 107 | |
| 108 // |read_watcher_| watches for events from Read(). | |
| 109 base::win::ObjectWatcher read_watcher_; | |
| 110 // |write_watcher_| watches for events from Write(); | |
| 111 base::win::ObjectWatcher write_watcher_; | |
| 112 | |
| 113 DISALLOW_COPY_AND_ASSIGN(Core); | |
| 114 }; | |
| 115 | |
| 116 UDPSocketWin::Core::Core(UDPSocketWin* socket) | |
| 117 : socket_(socket), | |
| 118 reader_(this), | |
| 119 writer_(this) { | |
| 120 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); | |
| 121 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); | |
| 122 | |
| 123 read_overlapped_.hEvent = WSACreateEvent(); | |
| 124 write_overlapped_.hEvent = WSACreateEvent(); | |
| 125 } | |
| 126 | |
| 127 UDPSocketWin::Core::~Core() { | |
| 128 // Make sure the message loop is not watching this object anymore. | |
| 129 read_watcher_.StopWatching(); | |
| 130 write_watcher_.StopWatching(); | |
| 131 | |
| 132 WSACloseEvent(read_overlapped_.hEvent); | |
| 133 memset(&read_overlapped_, 0xaf, sizeof(read_overlapped_)); | |
| 134 WSACloseEvent(write_overlapped_.hEvent); | |
| 135 memset(&write_overlapped_, 0xaf, sizeof(write_overlapped_)); | |
| 136 } | |
| 137 | |
| 138 void UDPSocketWin::Core::WatchForRead() { | |
| 139 // We grab an extra reference because there is an IO operation in progress. | |
| 140 // Balanced in ReadDelegate::OnObjectSignaled(). | |
| 141 AddRef(); | |
| 142 read_watcher_.StartWatchingOnce(read_overlapped_.hEvent, &reader_); | |
| 143 } | |
| 144 | |
| 145 void UDPSocketWin::Core::WatchForWrite() { | |
| 146 // We grab an extra reference because there is an IO operation in progress. | |
| 147 // Balanced in WriteDelegate::OnObjectSignaled(). | |
| 148 AddRef(); | |
| 149 write_watcher_.StartWatchingOnce(write_overlapped_.hEvent, &writer_); | |
| 150 } | |
| 151 | |
| 152 void UDPSocketWin::Core::ReadDelegate::OnObjectSignaled(HANDLE object) { | |
| 153 DCHECK_EQ(object, core_->read_overlapped_.hEvent); | |
| 154 if (core_->socket_) | |
| 155 core_->socket_->DidCompleteRead(); | |
| 156 | |
| 157 core_->Release(); | |
| 158 } | |
| 159 | |
| 160 void UDPSocketWin::Core::WriteDelegate::OnObjectSignaled(HANDLE object) { | |
| 161 DCHECK_EQ(object, core_->write_overlapped_.hEvent); | |
| 162 if (core_->socket_) | |
| 163 core_->socket_->DidCompleteWrite(); | |
| 164 | |
| 165 core_->Release(); | |
| 166 } | |
| 167 //----------------------------------------------------------------------------- | |
| 168 | |
| 169 QwaveAPI::QwaveAPI() : qwave_supported_(false) { | 44 QwaveAPI::QwaveAPI() : qwave_supported_(false) { |
| 170 HMODULE qwave = LoadLibrary(L"qwave.dll"); | 45 HMODULE qwave = LoadLibrary(L"qwave.dll"); |
| 171 if (!qwave) | 46 if (!qwave) |
| 172 return; | 47 return; |
| 173 create_handle_func_ = | 48 create_handle_func_ = |
| 174 (CreateHandleFn)GetProcAddress(qwave, "QOSCreateHandle"); | 49 (CreateHandleFn)GetProcAddress(qwave, "QOSCreateHandle"); |
| 175 close_handle_func_ = | 50 close_handle_func_ = |
| 176 (CloseHandleFn)GetProcAddress(qwave, "QOSCloseHandle"); | 51 (CloseHandleFn)GetProcAddress(qwave, "QOSCloseHandle"); |
| 177 add_socket_to_flow_func_ = | 52 add_socket_to_flow_func_ = |
| 178 (AddSocketToFlowFn)GetProcAddress(qwave, "QOSAddSocketToFlow"); | 53 (AddSocketToFlowFn)GetProcAddress(qwave, "QOSAddSocketToFlow"); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 248 net::NetLog* net_log, | 123 net::NetLog* net_log, |
| 249 const net::NetLogSource& source) | 124 const net::NetLogSource& source) |
| 250 : socket_(INVALID_SOCKET), | 125 : socket_(INVALID_SOCKET), |
| 251 addr_family_(0), | 126 addr_family_(0), |
| 252 is_connected_(false), | 127 is_connected_(false), |
| 253 socket_options_(SOCKET_OPTION_MULTICAST_LOOP), | 128 socket_options_(SOCKET_OPTION_MULTICAST_LOOP), |
| 254 multicast_interface_(0), | 129 multicast_interface_(0), |
| 255 multicast_time_to_live_(1), | 130 multicast_time_to_live_(1), |
| 256 bind_type_(bind_type), | 131 bind_type_(bind_type), |
| 257 rand_int_cb_(rand_int_cb), | 132 rand_int_cb_(rand_int_cb), |
| 258 use_non_blocking_io_(false), | |
| 259 read_iobuffer_len_(0), | 133 read_iobuffer_len_(0), |
| 260 write_iobuffer_len_(0), | 134 write_iobuffer_len_(0), |
| 261 recv_from_address_(NULL), | 135 recv_from_address_(NULL), |
| 262 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::UDP_SOCKET)), | 136 net_log_(NetLogWithSource::Make(net_log, NetLogSourceType::UDP_SOCKET)), |
| 263 qos_handle_(NULL), | 137 qos_handle_(NULL), |
| 264 qos_flow_id_(0) { | 138 qos_flow_id_(0) { |
| 265 EnsureWinsockInit(); | 139 EnsureWinsockInit(); |
| 266 net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE, | 140 net_log_.BeginEvent(NetLogEventType::SOCKET_ALIVE, |
| 267 source.ToEventParametersCallback()); | 141 source.ToEventParametersCallback()); |
| 268 if (bind_type == DatagramSocket::RANDOM_BIND) | 142 if (bind_type == DatagramSocket::RANDOM_BIND) |
| 269 DCHECK(!rand_int_cb.is_null()); | 143 DCHECK(!rand_int_cb.is_null()); |
| 270 } | 144 } |
| 271 | 145 |
| 272 UDPSocketWin::~UDPSocketWin() { | 146 UDPSocketWin::~UDPSocketWin() { |
| 273 Close(); | 147 Close(); |
| 274 net_log_.EndEvent(NetLogEventType::SOCKET_ALIVE); | 148 net_log_.EndEvent(NetLogEventType::SOCKET_ALIVE); |
| 275 } | 149 } |
| 276 | 150 |
| 277 int UDPSocketWin::Open(AddressFamily address_family) { | 151 int UDPSocketWin::Open(AddressFamily address_family) { |
| 278 DCHECK(CalledOnValidThread()); | 152 DCHECK(CalledOnValidThread()); |
| 279 DCHECK_EQ(socket_, INVALID_SOCKET); | 153 DCHECK_EQ(socket_, INVALID_SOCKET); |
| 280 | 154 |
| 281 addr_family_ = ConvertAddressFamily(address_family); | 155 addr_family_ = ConvertAddressFamily(address_family); |
| 282 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP); | 156 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP); |
| 283 if (socket_ == INVALID_SOCKET) | 157 if (socket_ == INVALID_SOCKET) |
| 284 return MapSystemError(WSAGetLastError()); | 158 return MapSystemError(WSAGetLastError()); |
| 285 if (!use_non_blocking_io_) { | 159 read_write_event_.Set(WSACreateEvent()); |
| 286 core_ = new Core(this); | 160 WSAEventSelect(socket_, read_write_event_.Get(), FD_READ | FD_WRITE); |
| 287 } else { | |
| 288 read_write_event_.Set(WSACreateEvent()); | |
| 289 WSAEventSelect(socket_, read_write_event_.Get(), FD_READ | FD_WRITE); | |
| 290 } | |
| 291 return OK; | 161 return OK; |
| 292 } | 162 } |
| 293 | 163 |
| 294 void UDPSocketWin::Close() { | 164 void UDPSocketWin::Close() { |
| 295 DCHECK(CalledOnValidThread()); | 165 DCHECK(CalledOnValidThread()); |
| 296 | 166 |
| 297 if (socket_ == INVALID_SOCKET) | 167 if (socket_ == INVALID_SOCKET) |
| 298 return; | 168 return; |
| 299 | 169 |
| 300 if (qos_handle_) { | 170 if (qos_handle_) { |
| 301 QwaveAPI::Get().CloseHandle(qos_handle_); | 171 QwaveAPI::Get().CloseHandle(qos_handle_); |
| 302 } | 172 } |
| 303 | 173 |
| 304 // Zero out any pending read/write callback state. | 174 // Zero out any pending read/write callback state. |
| 305 read_callback_.Reset(); | 175 read_callback_.Reset(); |
| 306 recv_from_address_ = NULL; | 176 recv_from_address_ = NULL; |
| 307 write_callback_.Reset(); | 177 write_callback_.Reset(); |
| 308 | 178 |
| 309 base::TimeTicks start_time = base::TimeTicks::Now(); | 179 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 310 closesocket(socket_); | 180 closesocket(socket_); |
| 311 UMA_HISTOGRAM_TIMES("Net.UDPSocketWinClose", | 181 UMA_HISTOGRAM_TIMES("Net.UDPSocketWinClose", |
| 312 base::TimeTicks::Now() - start_time); | 182 base::TimeTicks::Now() - start_time); |
| 313 socket_ = INVALID_SOCKET; | 183 socket_ = INVALID_SOCKET; |
| 314 addr_family_ = 0; | 184 addr_family_ = 0; |
| 315 is_connected_ = false; | 185 is_connected_ = false; |
| 316 | 186 |
| 317 read_write_watcher_.StopWatching(); | 187 read_write_watcher_.StopWatching(); |
| 318 read_write_event_.Close(); | 188 read_write_event_.Close(); |
| 319 | |
| 320 if (core_) { | |
| 321 core_->Detach(); | |
| 322 core_ = NULL; | |
| 323 } | |
| 324 } | 189 } |
| 325 | 190 |
| 326 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const { | 191 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const { |
| 327 DCHECK(CalledOnValidThread()); | 192 DCHECK(CalledOnValidThread()); |
| 328 DCHECK(address); | 193 DCHECK(address); |
| 329 if (!is_connected()) | 194 if (!is_connected()) |
| 330 return ERR_SOCKET_NOT_CONNECTED; | 195 return ERR_SOCKET_NOT_CONNECTED; |
| 331 | 196 |
| 332 // TODO(szym): Simplify. http://crbug.com/126152 | 197 // TODO(szym): Simplify. http://crbug.com/126152 |
| 333 if (!remote_address_.get()) { | 198 if (!remote_address_.get()) { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 int buf_len, | 244 int buf_len, |
| 380 IPEndPoint* address, | 245 IPEndPoint* address, |
| 381 const CompletionCallback& callback) { | 246 const CompletionCallback& callback) { |
| 382 DCHECK(CalledOnValidThread()); | 247 DCHECK(CalledOnValidThread()); |
| 383 DCHECK_NE(INVALID_SOCKET, socket_); | 248 DCHECK_NE(INVALID_SOCKET, socket_); |
| 384 CHECK(read_callback_.is_null()); | 249 CHECK(read_callback_.is_null()); |
| 385 DCHECK(!recv_from_address_); | 250 DCHECK(!recv_from_address_); |
| 386 DCHECK(!callback.is_null()); // Synchronous operation not supported. | 251 DCHECK(!callback.is_null()); // Synchronous operation not supported. |
| 387 DCHECK_GT(buf_len, 0); | 252 DCHECK_GT(buf_len, 0); |
| 388 | 253 |
| 389 int nread = core_ ? InternalRecvFromOverlapped(buf, buf_len, address) | 254 int nread = InternalRecvFromNonBlocking(buf, buf_len, address); |
| 390 : InternalRecvFromNonBlocking(buf, buf_len, address); | |
| 391 if (nread != ERR_IO_PENDING) | 255 if (nread != ERR_IO_PENDING) |
| 392 return nread; | 256 return nread; |
| 393 | 257 |
| 394 read_callback_ = callback; | 258 read_callback_ = callback; |
| 395 recv_from_address_ = address; | 259 recv_from_address_ = address; |
| 396 return ERR_IO_PENDING; | 260 return ERR_IO_PENDING; |
| 397 } | 261 } |
| 398 | 262 |
| 399 int UDPSocketWin::Write(IOBuffer* buf, | 263 int UDPSocketWin::Write(IOBuffer* buf, |
| 400 int buf_len, | 264 int buf_len, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 413 int buf_len, | 277 int buf_len, |
| 414 const IPEndPoint* address, | 278 const IPEndPoint* address, |
| 415 const CompletionCallback& callback) { | 279 const CompletionCallback& callback) { |
| 416 DCHECK(CalledOnValidThread()); | 280 DCHECK(CalledOnValidThread()); |
| 417 DCHECK_NE(INVALID_SOCKET, socket_); | 281 DCHECK_NE(INVALID_SOCKET, socket_); |
| 418 CHECK(write_callback_.is_null()); | 282 CHECK(write_callback_.is_null()); |
| 419 DCHECK(!callback.is_null()); // Synchronous operation not supported. | 283 DCHECK(!callback.is_null()); // Synchronous operation not supported. |
| 420 DCHECK_GT(buf_len, 0); | 284 DCHECK_GT(buf_len, 0); |
| 421 DCHECK(!send_to_address_.get()); | 285 DCHECK(!send_to_address_.get()); |
| 422 | 286 |
| 423 int nwrite = core_ ? InternalSendToOverlapped(buf, buf_len, address) | 287 int nwrite = InternalSendToNonBlocking(buf, buf_len, address); |
| 424 : InternalSendToNonBlocking(buf, buf_len, address); | |
| 425 if (nwrite != ERR_IO_PENDING) | 288 if (nwrite != ERR_IO_PENDING) |
| 426 return nwrite; | 289 return nwrite; |
| 427 | 290 |
| 428 if (address) | 291 if (address) |
| 429 send_to_address_.reset(new IPEndPoint(*address)); | 292 send_to_address_.reset(new IPEndPoint(*address)); |
| 430 write_callback_ = callback; | 293 write_callback_ = callback; |
| 431 return ERR_IO_PENDING; | 294 return ERR_IO_PENDING; |
| 432 } | 295 } |
| 433 | 296 |
| 434 int UDPSocketWin::Connect(const IPEndPoint& address) { | 297 int UDPSocketWin::Connect(const IPEndPoint& address) { |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 void UDPSocketWin::DoWriteCallback(int rv) { | 452 void UDPSocketWin::DoWriteCallback(int rv) { |
| 590 DCHECK_NE(rv, ERR_IO_PENDING); | 453 DCHECK_NE(rv, ERR_IO_PENDING); |
| 591 DCHECK(!write_callback_.is_null()); | 454 DCHECK(!write_callback_.is_null()); |
| 592 | 455 |
| 593 // since Run may result in Write being called, clear write_callback_ up front. | 456 // since Run may result in Write being called, clear write_callback_ up front. |
| 594 CompletionCallback c = write_callback_; | 457 CompletionCallback c = write_callback_; |
| 595 write_callback_.Reset(); | 458 write_callback_.Reset(); |
| 596 c.Run(rv); | 459 c.Run(rv); |
| 597 } | 460 } |
| 598 | 461 |
| 599 void UDPSocketWin::DidCompleteRead() { | |
| 600 DWORD num_bytes, flags; | |
| 601 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, | |
| 602 &num_bytes, FALSE, &flags); | |
| 603 WSAResetEvent(core_->read_overlapped_.hEvent); | |
| 604 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | |
| 605 // Convert address. | |
| 606 IPEndPoint address; | |
| 607 IPEndPoint* address_to_log = NULL; | |
| 608 if (result >= 0) { | |
| 609 if (address.FromSockAddr(core_->recv_addr_storage_.addr, | |
| 610 core_->recv_addr_storage_.addr_len)) { | |
| 611 if (recv_from_address_) | |
| 612 *recv_from_address_ = address; | |
| 613 address_to_log = &address; | |
| 614 } else { | |
| 615 result = ERR_ADDRESS_INVALID; | |
| 616 } | |
| 617 } | |
| 618 LogRead(result, core_->read_iobuffer_->data(), address_to_log); | |
| 619 core_->read_iobuffer_ = NULL; | |
| 620 recv_from_address_ = NULL; | |
| 621 DoReadCallback(result); | |
| 622 } | |
| 623 | |
| 624 void UDPSocketWin::DidCompleteWrite() { | |
| 625 DWORD num_bytes, flags; | |
| 626 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, | |
| 627 &num_bytes, FALSE, &flags); | |
| 628 WSAResetEvent(core_->write_overlapped_.hEvent); | |
| 629 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | |
| 630 LogWrite(result, core_->write_iobuffer_->data(), send_to_address_.get()); | |
| 631 | |
| 632 send_to_address_.reset(); | |
| 633 core_->write_iobuffer_ = NULL; | |
| 634 DoWriteCallback(result); | |
| 635 } | |
| 636 | |
| 637 void UDPSocketWin::OnObjectSignaled(HANDLE object) { | 462 void UDPSocketWin::OnObjectSignaled(HANDLE object) { |
| 638 DCHECK(object == read_write_event_.Get()); | 463 DCHECK(object == read_write_event_.Get()); |
| 639 WSANETWORKEVENTS network_events; | 464 WSANETWORKEVENTS network_events; |
| 640 int os_error = 0; | 465 int os_error = 0; |
| 641 int rv = | 466 int rv = |
| 642 WSAEnumNetworkEvents(socket_, read_write_event_.Get(), &network_events); | 467 WSAEnumNetworkEvents(socket_, read_write_event_.Get(), &network_events); |
| 643 if (rv == SOCKET_ERROR) { | 468 if (rv == SOCKET_ERROR) { |
| 644 os_error = WSAGetLastError(); | 469 os_error = WSAGetLastError(); |
| 645 rv = MapSystemError(os_error); | 470 rv = MapSystemError(os_error); |
| 646 if (read_iobuffer_) { | 471 if (read_iobuffer_) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 728 | 553 |
| 729 if (net_log_.IsCapturing()) { | 554 if (net_log_.IsCapturing()) { |
| 730 net_log_.AddEvent( | 555 net_log_.AddEvent( |
| 731 NetLogEventType::UDP_BYTES_SENT, | 556 NetLogEventType::UDP_BYTES_SENT, |
| 732 CreateNetLogUDPDataTranferCallback(result, bytes, address)); | 557 CreateNetLogUDPDataTranferCallback(result, bytes, address)); |
| 733 } | 558 } |
| 734 | 559 |
| 735 NetworkActivityMonitor::GetInstance()->IncrementBytesSent(result); | 560 NetworkActivityMonitor::GetInstance()->IncrementBytesSent(result); |
| 736 } | 561 } |
| 737 | 562 |
| 738 int UDPSocketWin::InternalRecvFromOverlapped(IOBuffer* buf, | |
| 739 int buf_len, | |
| 740 IPEndPoint* address) { | |
| 741 DCHECK(!core_->read_iobuffer_.get()); | |
| 742 SockaddrStorage& storage = core_->recv_addr_storage_; | |
| 743 storage.addr_len = sizeof(storage.addr_storage); | |
| 744 | |
| 745 WSABUF read_buffer; | |
| 746 read_buffer.buf = buf->data(); | |
| 747 read_buffer.len = buf_len; | |
| 748 | |
| 749 DWORD flags = 0; | |
| 750 DWORD num; | |
| 751 CHECK_NE(INVALID_SOCKET, socket_); | |
| 752 AssertEventNotSignaled(core_->read_overlapped_.hEvent); | |
| 753 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, storage.addr, | |
| 754 &storage.addr_len, &core_->read_overlapped_, NULL); | |
| 755 if (rv == 0) { | |
| 756 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { | |
| 757 int result = num; | |
| 758 // Convert address. | |
| 759 IPEndPoint address_storage; | |
| 760 IPEndPoint* address_to_log = NULL; | |
| 761 if (result >= 0) { | |
| 762 if (address_storage.FromSockAddr(core_->recv_addr_storage_.addr, | |
| 763 core_->recv_addr_storage_.addr_len)) { | |
| 764 if (address) | |
| 765 *address = address_storage; | |
| 766 address_to_log = &address_storage; | |
| 767 } else { | |
| 768 result = ERR_ADDRESS_INVALID; | |
| 769 } | |
| 770 } | |
| 771 LogRead(result, buf->data(), address_to_log); | |
| 772 return result; | |
| 773 } | |
| 774 } else { | |
| 775 int os_error = WSAGetLastError(); | |
| 776 if (os_error != WSA_IO_PENDING) { | |
| 777 int result = MapSystemError(os_error); | |
| 778 LogRead(result, NULL, NULL); | |
| 779 return result; | |
| 780 } | |
| 781 } | |
| 782 core_->WatchForRead(); | |
| 783 core_->read_iobuffer_ = buf; | |
| 784 return ERR_IO_PENDING; | |
| 785 } | |
| 786 | |
| 787 int UDPSocketWin::InternalSendToOverlapped(IOBuffer* buf, | |
| 788 int buf_len, | |
| 789 const IPEndPoint* address) { | |
| 790 DCHECK(!core_->write_iobuffer_.get()); | |
| 791 SockaddrStorage storage; | |
| 792 struct sockaddr* addr = storage.addr; | |
| 793 // Convert address. | |
| 794 if (!address) { | |
| 795 addr = NULL; | |
| 796 storage.addr_len = 0; | |
| 797 } else { | |
| 798 if (!address->ToSockAddr(addr, &storage.addr_len)) { | |
| 799 int result = ERR_ADDRESS_INVALID; | |
| 800 LogWrite(result, NULL, NULL); | |
| 801 return result; | |
| 802 } | |
| 803 } | |
| 804 | |
| 805 WSABUF write_buffer; | |
| 806 write_buffer.buf = buf->data(); | |
| 807 write_buffer.len = buf_len; | |
| 808 | |
| 809 DWORD flags = 0; | |
| 810 DWORD num; | |
| 811 AssertEventNotSignaled(core_->write_overlapped_.hEvent); | |
| 812 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, | |
| 813 addr, storage.addr_len, &core_->write_overlapped_, NULL); | |
| 814 if (rv == 0) { | |
| 815 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { | |
| 816 int result = num; | |
| 817 LogWrite(result, buf->data(), address); | |
| 818 return result; | |
| 819 } | |
| 820 } else { | |
| 821 int os_error = WSAGetLastError(); | |
| 822 if (os_error != WSA_IO_PENDING) { | |
| 823 int result = MapSystemError(os_error); | |
| 824 LogWrite(result, NULL, NULL); | |
| 825 return result; | |
| 826 } | |
| 827 } | |
| 828 | |
| 829 core_->WatchForWrite(); | |
| 830 core_->write_iobuffer_ = buf; | |
| 831 return ERR_IO_PENDING; | |
| 832 } | |
| 833 | |
| 834 int UDPSocketWin::InternalRecvFromNonBlocking(IOBuffer* buf, | 563 int UDPSocketWin::InternalRecvFromNonBlocking(IOBuffer* buf, |
| 835 int buf_len, | 564 int buf_len, |
| 836 IPEndPoint* address) { | 565 IPEndPoint* address) { |
| 837 DCHECK(!read_iobuffer_ || read_iobuffer_.get() == buf); | 566 DCHECK(!read_iobuffer_ || read_iobuffer_.get() == buf); |
| 838 SockaddrStorage storage; | 567 SockaddrStorage storage; |
| 839 storage.addr_len = sizeof(storage.addr_storage); | 568 storage.addr_len = sizeof(storage.addr_storage); |
| 840 | 569 |
| 841 CHECK_NE(INVALID_SOCKET, socket_); | 570 CHECK_NE(INVALID_SOCKET, socket_); |
| 842 int rv = recvfrom(socket_, buf->data(), buf_len, 0, storage.addr, | 571 int rv = recvfrom(socket_, buf->data(), buf_len, 0, storage.addr, |
| 843 &storage.addr_len); | 572 &storage.addr_len); |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1186 0, | 915 0, |
| 1187 NULL); | 916 NULL); |
| 1188 | 917 |
| 1189 return OK; | 918 return OK; |
| 1190 } | 919 } |
| 1191 | 920 |
| 1192 void UDPSocketWin::DetachFromThread() { | 921 void UDPSocketWin::DetachFromThread() { |
| 1193 base::NonThreadSafe::DetachFromThread(); | 922 base::NonThreadSafe::DetachFromThread(); |
| 1194 } | 923 } |
| 1195 | 924 |
| 1196 void UDPSocketWin::UseNonBlockingIO() { | |
| 1197 DCHECK(!core_); | |
| 1198 use_non_blocking_io_ = true; | |
| 1199 } | |
| 1200 | |
| 1201 } // namespace net | 925 } // namespace net |
| OLD | NEW |