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/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/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
254 net::NetLog* net_log, | 254 net::NetLog* net_log, |
255 const net::NetLog::Source& source) | 255 const net::NetLog::Source& source) |
256 : socket_(INVALID_SOCKET), | 256 : socket_(INVALID_SOCKET), |
257 addr_family_(0), | 257 addr_family_(0), |
258 is_connected_(false), | 258 is_connected_(false), |
259 socket_options_(SOCKET_OPTION_MULTICAST_LOOP), | 259 socket_options_(SOCKET_OPTION_MULTICAST_LOOP), |
260 multicast_interface_(0), | 260 multicast_interface_(0), |
261 multicast_time_to_live_(1), | 261 multicast_time_to_live_(1), |
262 bind_type_(bind_type), | 262 bind_type_(bind_type), |
263 rand_int_cb_(rand_int_cb), | 263 rand_int_cb_(rand_int_cb), |
264 use_non_blocking_io_(true), | |
rvargas (doing something else)
2015/02/03 03:11:41
false
Alpha Left Google
2015/02/03 23:24:45
Done.
| |
265 read_iobuffer_len_(0), | |
266 write_iobuffer_len_(0), | |
264 recv_from_address_(NULL), | 267 recv_from_address_(NULL), |
265 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)), | 268 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)), |
266 qos_handle_(NULL), | 269 qos_handle_(NULL), |
267 qos_flow_id_(0) { | 270 qos_flow_id_(0) { |
268 EnsureWinsockInit(); | 271 EnsureWinsockInit(); |
269 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, | 272 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, |
270 source.ToEventParametersCallback()); | 273 source.ToEventParametersCallback()); |
271 if (bind_type == DatagramSocket::RANDOM_BIND) | 274 if (bind_type == DatagramSocket::RANDOM_BIND) |
272 DCHECK(!rand_int_cb.is_null()); | 275 DCHECK(!rand_int_cb.is_null()); |
273 } | 276 } |
274 | 277 |
275 UDPSocketWin::~UDPSocketWin() { | 278 UDPSocketWin::~UDPSocketWin() { |
276 Close(); | 279 Close(); |
277 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); | 280 net_log_.EndEvent(NetLog::TYPE_SOCKET_ALIVE); |
278 } | 281 } |
279 | 282 |
280 int UDPSocketWin::Open(AddressFamily address_family) { | 283 int UDPSocketWin::Open(AddressFamily address_family) { |
281 DCHECK(CalledOnValidThread()); | 284 DCHECK(CalledOnValidThread()); |
282 DCHECK_EQ(socket_, INVALID_SOCKET); | 285 DCHECK_EQ(socket_, INVALID_SOCKET); |
283 | 286 |
284 addr_family_ = ConvertAddressFamily(address_family); | 287 addr_family_ = ConvertAddressFamily(address_family); |
285 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP); | 288 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP); |
286 if (socket_ == INVALID_SOCKET) | 289 if (socket_ == INVALID_SOCKET) |
287 return MapSystemError(WSAGetLastError()); | 290 return MapSystemError(WSAGetLastError()); |
288 core_ = new Core(this); | 291 if (!use_non_blocking_io_ || SetNonBlocking(socket_)) { |
rvargas (doing something else)
2015/02/03 03:11:41
Failure to set non blocking must be accounted for
Alpha Left Google
2015/02/03 23:24:46
guiwei pointed out that WSAEventSelect already set
| |
292 core_ = new Core(this); | |
293 } else { | |
294 read_write_event_.Set(WSACreateEvent()); | |
295 WSAEventSelect(socket_, read_write_event_.Get(), FD_READ | FD_WRITE); | |
296 } | |
289 return OK; | 297 return OK; |
290 } | 298 } |
291 | 299 |
292 void UDPSocketWin::Close() { | 300 void UDPSocketWin::Close() { |
293 DCHECK(CalledOnValidThread()); | 301 DCHECK(CalledOnValidThread()); |
294 | 302 |
295 if (socket_ == INVALID_SOCKET) | 303 if (socket_ == INVALID_SOCKET) |
296 return; | 304 return; |
297 | 305 |
298 if (qos_handle_) { | 306 if (qos_handle_) { |
299 QwaveAPI::Get().CloseHandle(qos_handle_); | 307 QwaveAPI::Get().CloseHandle(qos_handle_); |
300 } | 308 } |
301 | 309 |
302 // Zero out any pending read/write callback state. | 310 // Zero out any pending read/write callback state. |
303 read_callback_.Reset(); | 311 read_callback_.Reset(); |
304 recv_from_address_ = NULL; | 312 recv_from_address_ = NULL; |
305 write_callback_.Reset(); | 313 write_callback_.Reset(); |
306 | 314 |
315 read_write_watcher_.StopWatching(); | |
316 read_write_event_.Close(); | |
rvargas (doing something else)
2015/02/03 03:11:41
must be called after closesocket (or it may race t
Alpha Left Google
2015/02/03 23:24:46
Done.
| |
317 | |
307 base::TimeTicks start_time = base::TimeTicks::Now(); | 318 base::TimeTicks start_time = base::TimeTicks::Now(); |
308 closesocket(socket_); | 319 closesocket(socket_); |
309 UMA_HISTOGRAM_TIMES("Net.UDPSocketWinClose", | 320 UMA_HISTOGRAM_TIMES("Net.UDPSocketWinClose", |
310 base::TimeTicks::Now() - start_time); | 321 base::TimeTicks::Now() - start_time); |
311 socket_ = INVALID_SOCKET; | 322 socket_ = INVALID_SOCKET; |
312 addr_family_ = 0; | 323 addr_family_ = 0; |
313 is_connected_ = false; | 324 is_connected_ = false; |
314 | 325 |
315 core_->Detach(); | 326 if (core_) { |
316 core_ = NULL; | 327 core_->Detach(); |
328 core_ = NULL; | |
329 } | |
317 } | 330 } |
318 | 331 |
319 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const { | 332 int UDPSocketWin::GetPeerAddress(IPEndPoint* address) const { |
320 DCHECK(CalledOnValidThread()); | 333 DCHECK(CalledOnValidThread()); |
321 DCHECK(address); | 334 DCHECK(address); |
322 if (!is_connected()) | 335 if (!is_connected()) |
323 return ERR_SOCKET_NOT_CONNECTED; | 336 return ERR_SOCKET_NOT_CONNECTED; |
324 | 337 |
325 // TODO(szym): Simplify. http://crbug.com/126152 | 338 // TODO(szym): Simplify. http://crbug.com/126152 |
326 if (!remote_address_.get()) { | 339 if (!remote_address_.get()) { |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
370 int buf_len, | 383 int buf_len, |
371 IPEndPoint* address, | 384 IPEndPoint* address, |
372 const CompletionCallback& callback) { | 385 const CompletionCallback& callback) { |
373 DCHECK(CalledOnValidThread()); | 386 DCHECK(CalledOnValidThread()); |
374 DCHECK_NE(INVALID_SOCKET, socket_); | 387 DCHECK_NE(INVALID_SOCKET, socket_); |
375 CHECK(read_callback_.is_null()); | 388 CHECK(read_callback_.is_null()); |
376 DCHECK(!recv_from_address_); | 389 DCHECK(!recv_from_address_); |
377 DCHECK(!callback.is_null()); // Synchronous operation not supported. | 390 DCHECK(!callback.is_null()); // Synchronous operation not supported. |
378 DCHECK_GT(buf_len, 0); | 391 DCHECK_GT(buf_len, 0); |
379 | 392 |
380 int nread = InternalRecvFrom(buf, buf_len, address); | 393 int nread = core_ ? InternalRecvFromOverlapped(buf, buf_len, address) |
394 : InternalRecvFromNonBlocking(buf, buf_len, address); | |
381 if (nread != ERR_IO_PENDING) | 395 if (nread != ERR_IO_PENDING) |
382 return nread; | 396 return nread; |
383 | 397 |
384 read_callback_ = callback; | 398 read_callback_ = callback; |
385 recv_from_address_ = address; | 399 recv_from_address_ = address; |
386 return ERR_IO_PENDING; | 400 return ERR_IO_PENDING; |
387 } | 401 } |
388 | 402 |
389 int UDPSocketWin::Write(IOBuffer* buf, | 403 int UDPSocketWin::Write(IOBuffer* buf, |
390 int buf_len, | 404 int buf_len, |
(...skipping 12 matching lines...) Expand all Loading... | |
403 int buf_len, | 417 int buf_len, |
404 const IPEndPoint* address, | 418 const IPEndPoint* address, |
405 const CompletionCallback& callback) { | 419 const CompletionCallback& callback) { |
406 DCHECK(CalledOnValidThread()); | 420 DCHECK(CalledOnValidThread()); |
407 DCHECK_NE(INVALID_SOCKET, socket_); | 421 DCHECK_NE(INVALID_SOCKET, socket_); |
408 CHECK(write_callback_.is_null()); | 422 CHECK(write_callback_.is_null()); |
409 DCHECK(!callback.is_null()); // Synchronous operation not supported. | 423 DCHECK(!callback.is_null()); // Synchronous operation not supported. |
410 DCHECK_GT(buf_len, 0); | 424 DCHECK_GT(buf_len, 0); |
411 DCHECK(!send_to_address_.get()); | 425 DCHECK(!send_to_address_.get()); |
412 | 426 |
413 int nwrite = InternalSendTo(buf, buf_len, address); | 427 int nwrite = core_ ? InternalSendToOverlapped(buf, buf_len, address) |
428 : InternalSendToNonBlocking(buf, buf_len, address); | |
414 if (nwrite != ERR_IO_PENDING) | 429 if (nwrite != ERR_IO_PENDING) |
415 return nwrite; | 430 return nwrite; |
416 | 431 |
417 if (address) | 432 if (address) |
418 send_to_address_.reset(new IPEndPoint(*address)); | 433 send_to_address_.reset(new IPEndPoint(*address)); |
419 write_callback_ = callback; | 434 write_callback_ = callback; |
420 return ERR_IO_PENDING; | 435 return ERR_IO_PENDING; |
421 } | 436 } |
422 | 437 |
423 int UDPSocketWin::Connect(const IPEndPoint& address) { | 438 int UDPSocketWin::Connect(const IPEndPoint& address) { |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
566 c.Run(rv); | 581 c.Run(rv); |
567 } | 582 } |
568 | 583 |
569 void UDPSocketWin::DidCompleteRead() { | 584 void UDPSocketWin::DidCompleteRead() { |
570 DWORD num_bytes, flags; | 585 DWORD num_bytes, flags; |
571 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, | 586 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, |
572 &num_bytes, FALSE, &flags); | 587 &num_bytes, FALSE, &flags); |
573 WSAResetEvent(core_->read_overlapped_.hEvent); | 588 WSAResetEvent(core_->read_overlapped_.hEvent); |
574 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | 589 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); |
575 // Convert address. | 590 // Convert address. |
576 if (recv_from_address_ && result >= 0) { | 591 IPEndPoint address; |
577 if (!ReceiveAddressToIPEndpoint(recv_from_address_)) | 592 IPEndPoint* address_to_log = NULL; |
593 if (result >= 0) { | |
594 if (address.FromSockAddr(core_->recv_addr_storage_.addr, | |
595 core_->recv_addr_storage_.addr_len)) { | |
596 if (recv_from_address_) { | |
rvargas (doing something else)
2015/02/03 20:55:30
nit: no {}
Alpha Left Google
2015/02/03 23:24:45
Done.
| |
597 *recv_from_address_ = address; | |
598 } | |
599 address_to_log = &address; | |
600 } else { | |
578 result = ERR_ADDRESS_INVALID; | 601 result = ERR_ADDRESS_INVALID; |
602 } | |
579 } | 603 } |
580 LogRead(result, core_->read_iobuffer_->data()); | 604 LogRead(result, core_->read_iobuffer_->data(), address_to_log); |
581 core_->read_iobuffer_ = NULL; | 605 core_->read_iobuffer_ = NULL; |
582 recv_from_address_ = NULL; | 606 recv_from_address_ = NULL; |
583 DoReadCallback(result); | 607 DoReadCallback(result); |
584 } | 608 } |
585 | 609 |
586 void UDPSocketWin::LogRead(int result, const char* bytes) const { | 610 void UDPSocketWin::DidCompleteWrite() { |
611 DWORD num_bytes, flags; | |
612 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, | |
613 &num_bytes, FALSE, &flags); | |
614 WSAResetEvent(core_->write_overlapped_.hEvent); | |
615 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | |
616 LogWrite(result, core_->write_iobuffer_->data(), send_to_address_.get()); | |
617 | |
618 send_to_address_.reset(); | |
619 core_->write_iobuffer_ = NULL; | |
620 DoWriteCallback(result); | |
621 } | |
622 | |
623 void UDPSocketWin::OnObjectSignaled(HANDLE object) { | |
624 DCHECK(object == read_write_event_.Get()); | |
625 WSANETWORKEVENTS network_events; | |
626 int os_error = 0; | |
627 int rv = | |
628 WSAEnumNetworkEvents(socket_, read_write_event_.Get(), &network_events); | |
629 if (rv == SOCKET_ERROR) { | |
630 os_error = WSAGetLastError(); | |
631 rv = MapSystemError(os_error); | |
632 if (read_iobuffer_) { | |
633 read_iobuffer_ = NULL; | |
634 read_iobuffer_len_ = 0; | |
635 recv_from_address_ = NULL; | |
636 DoReadCallback(rv); | |
637 } | |
638 if (write_iobuffer_) { | |
639 write_iobuffer_ = NULL; | |
640 write_iobuffer_len_ = 0; | |
641 send_to_address_.reset(); | |
642 DoWriteCallback(rv); | |
643 } | |
644 return; | |
645 } | |
646 if ((network_events.lNetworkEvents & FD_READ) && read_iobuffer_) { | |
647 OnReadSignaled(); | |
648 } | |
649 if ((network_events.lNetworkEvents & FD_WRITE) && write_iobuffer_) { | |
650 OnWriteSignaled(); | |
651 } | |
652 | |
653 // There's still pending read / write. Watch for further events. | |
654 if (read_iobuffer_ || write_iobuffer_) { | |
655 WatchForReadWrite(); | |
656 } | |
657 } | |
658 | |
659 void UDPSocketWin::OnReadSignaled() { | |
660 DCHECK(read_iobuffer_); | |
rvargas (doing something else)
2015/02/03 03:11:41
Either both methods dcheck the buffer or not. (I h
Alpha Left Google
2015/02/03 23:24:45
Yeah this DCHECK should be removed since line 646
| |
661 int rv = InternalRecvFromNonBlocking(read_iobuffer_.get(), read_iobuffer_len_, | |
662 recv_from_address_); | |
663 if (rv == ERR_IO_PENDING) | |
664 return; | |
665 read_iobuffer_ = NULL; | |
666 read_iobuffer_len_ = 0; | |
667 recv_from_address_ = NULL; | |
668 DoReadCallback(rv); | |
669 } | |
670 | |
671 void UDPSocketWin::OnWriteSignaled() { | |
672 int rv = InternalSendToNonBlocking(write_iobuffer_.get(), write_iobuffer_len_, | |
673 send_to_address_.get()); | |
674 if (rv == ERR_IO_PENDING) | |
675 return; | |
676 write_iobuffer_ = NULL; | |
677 write_iobuffer_len_ = 0; | |
678 send_to_address_.reset(); | |
679 DoWriteCallback(rv); | |
680 } | |
681 | |
682 void UDPSocketWin::WatchForReadWrite() { | |
683 if (read_write_watcher_.GetWatchedObject() != NULL) { | |
rvargas (doing something else)
2015/02/03 03:11:41
When would this be the case? (red flag: checking a
Alpha Left Google
2015/02/03 23:24:46
For example both write and read got WSA_IO_PENDING
rvargas (doing something else)
2015/02/03 23:54:33
The code from the object watcher is quite old... a
| |
684 DCHECK(read_write_watcher_.GetWatchedObject() == read_write_event_.Get()); | |
685 return; | |
686 } | |
687 read_write_watcher_.StartWatching(read_write_event_.Get(), this); | |
688 } | |
689 | |
690 void UDPSocketWin::LogRead(int result, | |
691 const char* bytes, | |
692 const IPEndPoint* address) const { | |
587 if (result < 0) { | 693 if (result < 0) { |
588 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); | 694 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); |
589 return; | 695 return; |
590 } | 696 } |
591 | 697 |
592 if (net_log_.IsLogging()) { | 698 if (net_log_.IsLogging()) { |
593 // Get address for logging, if |address| is NULL. | |
594 IPEndPoint address; | |
595 bool is_address_valid = ReceiveAddressToIPEndpoint(&address); | |
596 net_log_.AddEvent( | 699 net_log_.AddEvent( |
597 NetLog::TYPE_UDP_BYTES_RECEIVED, | 700 NetLog::TYPE_UDP_BYTES_RECEIVED, |
598 CreateNetLogUDPDataTranferCallback( | 701 CreateNetLogUDPDataTranferCallback(result, bytes, address)); |
599 result, bytes, | |
600 is_address_valid ? &address : NULL)); | |
601 } | 702 } |
602 | 703 |
603 base::StatsCounter read_bytes("udp.read_bytes"); | 704 base::StatsCounter read_bytes("udp.read_bytes"); |
604 read_bytes.Add(result); | 705 read_bytes.Add(result); |
605 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(result); | 706 NetworkActivityMonitor::GetInstance()->IncrementBytesReceived(result); |
606 } | 707 } |
607 | 708 |
608 void UDPSocketWin::DidCompleteWrite() { | |
609 DWORD num_bytes, flags; | |
610 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, | |
611 &num_bytes, FALSE, &flags); | |
612 WSAResetEvent(core_->write_overlapped_.hEvent); | |
613 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | |
614 LogWrite(result, core_->write_iobuffer_->data(), send_to_address_.get()); | |
615 | |
616 send_to_address_.reset(); | |
617 core_->write_iobuffer_ = NULL; | |
618 DoWriteCallback(result); | |
619 } | |
620 | |
621 void UDPSocketWin::LogWrite(int result, | 709 void UDPSocketWin::LogWrite(int result, |
622 const char* bytes, | 710 const char* bytes, |
623 const IPEndPoint* address) const { | 711 const IPEndPoint* address) const { |
624 if (result < 0) { | 712 if (result < 0) { |
625 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result); | 713 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result); |
626 return; | 714 return; |
627 } | 715 } |
628 | 716 |
629 if (net_log_.IsLogging()) { | 717 if (net_log_.IsLogging()) { |
630 net_log_.AddEvent( | 718 net_log_.AddEvent( |
631 NetLog::TYPE_UDP_BYTES_SENT, | 719 NetLog::TYPE_UDP_BYTES_SENT, |
632 CreateNetLogUDPDataTranferCallback(result, bytes, address)); | 720 CreateNetLogUDPDataTranferCallback(result, bytes, address)); |
633 } | 721 } |
634 | 722 |
635 base::StatsCounter write_bytes("udp.write_bytes"); | 723 base::StatsCounter write_bytes("udp.write_bytes"); |
636 write_bytes.Add(result); | 724 write_bytes.Add(result); |
637 NetworkActivityMonitor::GetInstance()->IncrementBytesSent(result); | 725 NetworkActivityMonitor::GetInstance()->IncrementBytesSent(result); |
638 } | 726 } |
639 | 727 |
640 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len, | 728 int UDPSocketWin::InternalRecvFromOverlapped(IOBuffer* buf, |
641 IPEndPoint* address) { | 729 int buf_len, |
730 IPEndPoint* address) { | |
642 DCHECK(!core_->read_iobuffer_.get()); | 731 DCHECK(!core_->read_iobuffer_.get()); |
643 SockaddrStorage& storage = core_->recv_addr_storage_; | 732 SockaddrStorage& storage = core_->recv_addr_storage_; |
644 storage.addr_len = sizeof(storage.addr_storage); | 733 storage.addr_len = sizeof(storage.addr_storage); |
645 | 734 |
646 WSABUF read_buffer; | 735 WSABUF read_buffer; |
647 read_buffer.buf = buf->data(); | 736 read_buffer.buf = buf->data(); |
648 read_buffer.len = buf_len; | 737 read_buffer.len = buf_len; |
649 | 738 |
650 DWORD flags = 0; | 739 DWORD flags = 0; |
651 DWORD num; | 740 DWORD num; |
652 CHECK_NE(INVALID_SOCKET, socket_); | 741 CHECK_NE(INVALID_SOCKET, socket_); |
653 AssertEventNotSignaled(core_->read_overlapped_.hEvent); | 742 AssertEventNotSignaled(core_->read_overlapped_.hEvent); |
654 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, storage.addr, | 743 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, storage.addr, |
655 &storage.addr_len, &core_->read_overlapped_, NULL); | 744 &storage.addr_len, &core_->read_overlapped_, NULL); |
656 if (rv == 0) { | 745 if (rv == 0) { |
657 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { | 746 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { |
658 int result = num; | 747 int result = num; |
659 // Convert address. | 748 // Convert address. |
660 if (address && result >= 0) { | 749 IPEndPoint address_storage; |
661 if (!ReceiveAddressToIPEndpoint(address)) | 750 IPEndPoint* address_to_log = NULL; |
751 if (result >= 0) { | |
752 if (address_storage.FromSockAddr(core_->recv_addr_storage_.addr, | |
753 core_->recv_addr_storage_.addr_len)) { | |
754 if (address) | |
755 *address = address_storage; | |
756 address_to_log = &address_storage; | |
757 } else { | |
662 result = ERR_ADDRESS_INVALID; | 758 result = ERR_ADDRESS_INVALID; |
759 } | |
663 } | 760 } |
664 LogRead(result, buf->data()); | 761 LogRead(result, buf->data(), address_to_log); |
665 return result; | 762 return result; |
666 } | 763 } |
667 } else { | 764 } else { |
668 int os_error = WSAGetLastError(); | 765 int os_error = WSAGetLastError(); |
669 if (os_error != WSA_IO_PENDING) { | 766 if (os_error != WSA_IO_PENDING) { |
670 int result = MapSystemError(os_error); | 767 int result = MapSystemError(os_error); |
671 LogRead(result, NULL); | 768 LogRead(result, NULL, NULL); |
672 return result; | 769 return result; |
673 } | 770 } |
674 } | 771 } |
675 core_->WatchForRead(); | 772 core_->WatchForRead(); |
676 core_->read_iobuffer_ = buf; | 773 core_->read_iobuffer_ = buf; |
677 return ERR_IO_PENDING; | 774 return ERR_IO_PENDING; |
678 } | 775 } |
679 | 776 |
680 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len, | 777 int UDPSocketWin::InternalSendToOverlapped(IOBuffer* buf, |
681 const IPEndPoint* address) { | 778 int buf_len, |
779 const IPEndPoint* address) { | |
682 DCHECK(!core_->write_iobuffer_.get()); | 780 DCHECK(!core_->write_iobuffer_.get()); |
683 SockaddrStorage storage; | 781 SockaddrStorage storage; |
684 struct sockaddr* addr = storage.addr; | 782 struct sockaddr* addr = storage.addr; |
685 // Convert address. | 783 // Convert address. |
686 if (!address) { | 784 if (!address) { |
687 addr = NULL; | 785 addr = NULL; |
688 storage.addr_len = 0; | 786 storage.addr_len = 0; |
689 } else { | 787 } else { |
690 if (!address->ToSockAddr(addr, &storage.addr_len)) { | 788 if (!address->ToSockAddr(addr, &storage.addr_len)) { |
691 int result = ERR_ADDRESS_INVALID; | 789 int result = ERR_ADDRESS_INVALID; |
(...skipping 24 matching lines...) Expand all Loading... | |
716 LogWrite(result, NULL, NULL); | 814 LogWrite(result, NULL, NULL); |
717 return result; | 815 return result; |
718 } | 816 } |
719 } | 817 } |
720 | 818 |
721 core_->WatchForWrite(); | 819 core_->WatchForWrite(); |
722 core_->write_iobuffer_ = buf; | 820 core_->write_iobuffer_ = buf; |
723 return ERR_IO_PENDING; | 821 return ERR_IO_PENDING; |
724 } | 822 } |
725 | 823 |
824 int UDPSocketWin::InternalRecvFromNonBlocking(IOBuffer* buf, | |
825 int buf_len, | |
826 IPEndPoint* address) { | |
827 SockaddrStorage storage; | |
828 storage.addr_len = sizeof(storage.addr_storage); | |
829 | |
830 CHECK_NE(INVALID_SOCKET, socket_); | |
831 int rv = recvfrom(socket_, buf->data(), buf_len, 0, storage.addr, | |
832 &storage.addr_len); | |
833 if (rv == SOCKET_ERROR) { | |
834 int os_error = WSAGetLastError(); | |
835 if (os_error == WSAEWOULDBLOCK) { | |
836 read_iobuffer_ = buf; | |
837 read_iobuffer_len_ = buf_len; | |
838 WatchForReadWrite(); | |
839 return ERR_IO_PENDING; | |
840 } | |
841 rv = MapSystemError(os_error); | |
842 LogRead(rv, NULL, NULL); | |
843 return rv; | |
844 } | |
845 IPEndPoint address_storage; | |
846 IPEndPoint* address_to_log = NULL; | |
847 if (rv >= 0) { | |
848 if (address_storage.FromSockAddr(storage.addr, storage.addr_len)) { | |
849 if (address) | |
850 *address = address_storage; | |
851 address_to_log = &address_storage; | |
852 } else { | |
853 rv = ERR_ADDRESS_INVALID; | |
854 } | |
855 } | |
856 LogRead(rv, buf->data(), address_to_log); | |
857 return rv; | |
858 } | |
859 | |
860 int UDPSocketWin::InternalSendToNonBlocking(IOBuffer* buf, | |
861 int buf_len, | |
862 const IPEndPoint* address) { | |
863 SockaddrStorage storage; | |
864 struct sockaddr* addr = storage.addr; | |
865 // Convert address. | |
866 if (address) { | |
867 if (!address->ToSockAddr(addr, &storage.addr_len)) { | |
868 int result = ERR_ADDRESS_INVALID; | |
869 LogWrite(result, NULL, NULL); | |
870 return result; | |
871 } | |
872 } else { | |
873 addr = NULL; | |
874 storage.addr_len = 0; | |
875 } | |
876 | |
877 int rv = sendto(socket_, buf->data(), buf_len, 0, addr, storage.addr_len); | |
878 if (rv == SOCKET_ERROR) { | |
879 int os_error = WSAGetLastError(); | |
880 if (os_error == WSAEWOULDBLOCK) { | |
881 write_iobuffer_ = buf; | |
882 write_iobuffer_len_ = buf_len; | |
883 WatchForReadWrite(); | |
884 return ERR_IO_PENDING; | |
885 } | |
886 rv = MapSystemError(os_error); | |
887 LogWrite(rv, NULL, NULL); | |
888 return rv; | |
889 } | |
890 LogWrite(rv, buf->data(), address); | |
891 return rv; | |
892 } | |
893 | |
726 int UDPSocketWin::SetMulticastOptions() { | 894 int UDPSocketWin::SetMulticastOptions() { |
727 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) { | 895 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) { |
728 DWORD loop = 0; | 896 DWORD loop = 0; |
729 int protocol_level = | 897 int protocol_level = |
730 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; | 898 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
731 int option = | 899 int option = |
732 addr_family_ == AF_INET ? IP_MULTICAST_LOOP: IPV6_MULTICAST_LOOP; | 900 addr_family_ == AF_INET ? IP_MULTICAST_LOOP: IPV6_MULTICAST_LOOP; |
733 int rv = setsockopt(socket_, protocol_level, option, | 901 int rv = setsockopt(socket_, protocol_level, option, |
734 reinterpret_cast<const char*>(&loop), sizeof(loop)); | 902 reinterpret_cast<const char*>(&loop), sizeof(loop)); |
735 if (rv < 0) | 903 if (rv < 0) |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
800 | 968 |
801 for (int i = 0; i < kBindRetries; ++i) { | 969 for (int i = 0; i < kBindRetries; ++i) { |
802 int rv = DoBind(IPEndPoint( | 970 int rv = DoBind(IPEndPoint( |
803 address, static_cast<uint16>(rand_int_cb_.Run(kPortStart, kPortEnd)))); | 971 address, static_cast<uint16>(rand_int_cb_.Run(kPortStart, kPortEnd)))); |
804 if (rv == OK || rv != ERR_ADDRESS_IN_USE) | 972 if (rv == OK || rv != ERR_ADDRESS_IN_USE) |
805 return rv; | 973 return rv; |
806 } | 974 } |
807 return DoBind(IPEndPoint(address, 0)); | 975 return DoBind(IPEndPoint(address, 0)); |
808 } | 976 } |
809 | 977 |
810 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { | |
811 SockaddrStorage& storage = core_->recv_addr_storage_; | |
812 return address->FromSockAddr(storage.addr, storage.addr_len); | |
813 } | |
814 | |
815 int UDPSocketWin::JoinGroup( | 978 int UDPSocketWin::JoinGroup( |
816 const IPAddressNumber& group_address) const { | 979 const IPAddressNumber& group_address) const { |
817 DCHECK(CalledOnValidThread()); | 980 DCHECK(CalledOnValidThread()); |
818 if (!is_connected()) | 981 if (!is_connected()) |
819 return ERR_SOCKET_NOT_CONNECTED; | 982 return ERR_SOCKET_NOT_CONNECTED; |
820 | 983 |
821 switch (group_address.size()) { | 984 switch (group_address.size()) { |
822 case kIPv4AddressSize: { | 985 case kIPv4AddressSize: { |
823 if (addr_family_ != AF_INET) | 986 if (addr_family_ != AF_INET) |
824 return ERR_ADDRESS_INVALID; | 987 return ERR_ADDRESS_INVALID; |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1009 0, | 1172 0, |
1010 NULL); | 1173 NULL); |
1011 | 1174 |
1012 return OK; | 1175 return OK; |
1013 } | 1176 } |
1014 | 1177 |
1015 void UDPSocketWin::DetachFromThread() { | 1178 void UDPSocketWin::DetachFromThread() { |
1016 base::NonThreadSafe::DetachFromThread(); | 1179 base::NonThreadSafe::DetachFromThread(); |
1017 } | 1180 } |
1018 | 1181 |
1182 void UDPSocketWin::UseNonBlockingIO() { | |
1183 if (core_) | |
1184 return; | |
rvargas (doing something else)
2015/02/03 03:11:41
This looks like a serious issue. The data from the
Alpha Left Google
2015/02/03 23:24:46
I'll return a boolean with this call.
| |
1185 use_non_blocking_io_ = true; | |
1186 } | |
1187 | |
1019 } // namespace net | 1188 } // namespace net |
OLD | NEW |