Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(383)

Side by Side Diff: net/udp/udp_socket_win.cc

Issue 861963002: UDP: Windows implementation using non-blocking IO (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix build Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/udp/udp_socket_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/udp/udp_socket_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698