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 |