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/callback.h" | 9 #include "base/callback.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 | 99 |
100 // |read_watcher_| watches for events from Read(). | 100 // |read_watcher_| watches for events from Read(). |
101 base::win::ObjectWatcher read_watcher_; | 101 base::win::ObjectWatcher read_watcher_; |
102 // |write_watcher_| watches for events from Write(); | 102 // |write_watcher_| watches for events from Write(); |
103 base::win::ObjectWatcher write_watcher_; | 103 base::win::ObjectWatcher write_watcher_; |
104 | 104 |
105 DISALLOW_COPY_AND_ASSIGN(Core); | 105 DISALLOW_COPY_AND_ASSIGN(Core); |
106 }; | 106 }; |
107 | 107 |
108 UDPSocketWin::Core::Core(UDPSocketWin* socket) | 108 UDPSocketWin::Core::Core(UDPSocketWin* socket) |
109 : socket_(socket), | 109 : socket_(socket), reader_(this), writer_(this) { |
110 reader_(this), | |
111 writer_(this) { | |
112 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); | 110 memset(&read_overlapped_, 0, sizeof(read_overlapped_)); |
113 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); | 111 memset(&write_overlapped_, 0, sizeof(write_overlapped_)); |
114 | 112 |
115 read_overlapped_.hEvent = WSACreateEvent(); | 113 read_overlapped_.hEvent = WSACreateEvent(); |
116 write_overlapped_.hEvent = WSACreateEvent(); | 114 write_overlapped_.hEvent = WSACreateEvent(); |
117 } | 115 } |
118 | 116 |
119 UDPSocketWin::Core::~Core() { | 117 UDPSocketWin::Core::~Core() { |
120 // Make sure the message loop is not watching this object anymore. | 118 // Make sure the message loop is not watching this object anymore. |
121 read_watcher_.StopWatching(); | 119 read_watcher_.StopWatching(); |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 addr_family_ = addr_family; | 381 addr_family_ = addr_family; |
384 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP); | 382 socket_ = CreatePlatformSocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP); |
385 if (socket_ == INVALID_SOCKET) | 383 if (socket_ == INVALID_SOCKET) |
386 return MapSystemError(WSAGetLastError()); | 384 return MapSystemError(WSAGetLastError()); |
387 core_ = new Core(this); | 385 core_ = new Core(this); |
388 return OK; | 386 return OK; |
389 } | 387 } |
390 | 388 |
391 int UDPSocketWin::SetReceiveBufferSize(int32 size) { | 389 int UDPSocketWin::SetReceiveBufferSize(int32 size) { |
392 DCHECK(CalledOnValidThread()); | 390 DCHECK(CalledOnValidThread()); |
393 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, | 391 int rv = setsockopt(socket_, |
394 reinterpret_cast<const char*>(&size), sizeof(size)); | 392 SOL_SOCKET, |
| 393 SO_RCVBUF, |
| 394 reinterpret_cast<const char*>(&size), |
| 395 sizeof(size)); |
395 if (rv != 0) | 396 if (rv != 0) |
396 return MapSystemError(WSAGetLastError()); | 397 return MapSystemError(WSAGetLastError()); |
397 | 398 |
398 // According to documentation, setsockopt may succeed, but we need to check | 399 // According to documentation, setsockopt may succeed, but we need to check |
399 // the results via getsockopt to be sure it works on Windows. | 400 // the results via getsockopt to be sure it works on Windows. |
400 int32 actual_size = 0; | 401 int32 actual_size = 0; |
401 int option_size = sizeof(actual_size); | 402 int option_size = sizeof(actual_size); |
402 rv = getsockopt(socket_, SOL_SOCKET, SO_RCVBUF, | 403 rv = getsockopt(socket_, |
403 reinterpret_cast<char*>(&actual_size), &option_size); | 404 SOL_SOCKET, |
| 405 SO_RCVBUF, |
| 406 reinterpret_cast<char*>(&actual_size), |
| 407 &option_size); |
404 if (rv != 0) | 408 if (rv != 0) |
405 return MapSystemError(WSAGetLastError()); | 409 return MapSystemError(WSAGetLastError()); |
406 if (actual_size >= size) | 410 if (actual_size >= size) |
407 return OK; | 411 return OK; |
408 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableReceiveBuffer", | 412 UMA_HISTOGRAM_CUSTOM_COUNTS( |
409 actual_size, 1000, 1000000, 50); | 413 "Net.SocketUnchangeableReceiveBuffer", actual_size, 1000, 1000000, 50); |
410 return ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE; | 414 return ERR_SOCKET_RECEIVE_BUFFER_SIZE_UNCHANGEABLE; |
411 } | 415 } |
412 | 416 |
413 int UDPSocketWin::SetSendBufferSize(int32 size) { | 417 int UDPSocketWin::SetSendBufferSize(int32 size) { |
414 DCHECK(CalledOnValidThread()); | 418 DCHECK(CalledOnValidThread()); |
415 int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, | 419 int rv = setsockopt(socket_, |
416 reinterpret_cast<const char*>(&size), sizeof(size)); | 420 SOL_SOCKET, |
| 421 SO_SNDBUF, |
| 422 reinterpret_cast<const char*>(&size), |
| 423 sizeof(size)); |
417 if (rv != 0) | 424 if (rv != 0) |
418 return MapSystemError(WSAGetLastError()); | 425 return MapSystemError(WSAGetLastError()); |
419 // According to documentation, setsockopt may succeed, but we need to check | 426 // According to documentation, setsockopt may succeed, but we need to check |
420 // the results via getsockopt to be sure it works on Windows. | 427 // the results via getsockopt to be sure it works on Windows. |
421 int32 actual_size = 0; | 428 int32 actual_size = 0; |
422 int option_size = sizeof(actual_size); | 429 int option_size = sizeof(actual_size); |
423 rv = getsockopt(socket_, SOL_SOCKET, SO_SNDBUF, | 430 rv = getsockopt(socket_, |
424 reinterpret_cast<char*>(&actual_size), &option_size); | 431 SOL_SOCKET, |
| 432 SO_SNDBUF, |
| 433 reinterpret_cast<char*>(&actual_size), |
| 434 &option_size); |
425 if (rv != 0) | 435 if (rv != 0) |
426 return MapSystemError(WSAGetLastError()); | 436 return MapSystemError(WSAGetLastError()); |
427 if (actual_size >= size) | 437 if (actual_size >= size) |
428 return OK; | 438 return OK; |
429 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.SocketUnchangeableSendBuffer", | 439 UMA_HISTOGRAM_CUSTOM_COUNTS( |
430 actual_size, 1000, 1000000, 50); | 440 "Net.SocketUnchangeableSendBuffer", actual_size, 1000, 1000000, 50); |
431 return ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE; | 441 return ERR_SOCKET_SEND_BUFFER_SIZE_UNCHANGEABLE; |
432 } | 442 } |
433 | 443 |
434 void UDPSocketWin::AllowAddressReuse() { | 444 void UDPSocketWin::AllowAddressReuse() { |
435 DCHECK(CalledOnValidThread()); | 445 DCHECK(CalledOnValidThread()); |
436 DCHECK(!is_connected()); | 446 DCHECK(!is_connected()); |
437 | 447 |
438 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS; | 448 socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS; |
439 } | 449 } |
440 | 450 |
(...skipping 19 matching lines...) Expand all Loading... |
460 DCHECK(!write_callback_.is_null()); | 470 DCHECK(!write_callback_.is_null()); |
461 | 471 |
462 // since Run may result in Write being called, clear write_callback_ up front. | 472 // since Run may result in Write being called, clear write_callback_ up front. |
463 CompletionCallback c = write_callback_; | 473 CompletionCallback c = write_callback_; |
464 write_callback_.Reset(); | 474 write_callback_.Reset(); |
465 c.Run(rv); | 475 c.Run(rv); |
466 } | 476 } |
467 | 477 |
468 void UDPSocketWin::DidCompleteRead() { | 478 void UDPSocketWin::DidCompleteRead() { |
469 DWORD num_bytes, flags; | 479 DWORD num_bytes, flags; |
470 BOOL ok = WSAGetOverlappedResult(socket_, &core_->read_overlapped_, | 480 BOOL ok = WSAGetOverlappedResult( |
471 &num_bytes, FALSE, &flags); | 481 socket_, &core_->read_overlapped_, &num_bytes, FALSE, &flags); |
472 WSAResetEvent(core_->read_overlapped_.hEvent); | 482 WSAResetEvent(core_->read_overlapped_.hEvent); |
473 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | 483 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); |
474 // Convert address. | 484 // Convert address. |
475 if (recv_from_address_ && result >= 0) { | 485 if (recv_from_address_ && result >= 0) { |
476 if (!ReceiveAddressToIPEndpoint(recv_from_address_)) | 486 if (!ReceiveAddressToIPEndpoint(recv_from_address_)) |
477 result = ERR_ADDRESS_INVALID; | 487 result = ERR_ADDRESS_INVALID; |
478 } | 488 } |
479 LogRead(result, core_->read_iobuffer_->data()); | 489 LogRead(result, core_->read_iobuffer_->data()); |
480 core_->read_iobuffer_ = NULL; | 490 core_->read_iobuffer_ = NULL; |
481 recv_from_address_ = NULL; | 491 recv_from_address_ = NULL; |
482 DoReadCallback(result); | 492 DoReadCallback(result); |
483 } | 493 } |
484 | 494 |
485 void UDPSocketWin::LogRead(int result, const char* bytes) const { | 495 void UDPSocketWin::LogRead(int result, const char* bytes) const { |
486 if (result < 0) { | 496 if (result < 0) { |
487 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); | 497 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_RECEIVE_ERROR, result); |
488 return; | 498 return; |
489 } | 499 } |
490 | 500 |
491 if (net_log_.IsLogging()) { | 501 if (net_log_.IsLogging()) { |
492 // Get address for logging, if |address| is NULL. | 502 // Get address for logging, if |address| is NULL. |
493 IPEndPoint address; | 503 IPEndPoint address; |
494 bool is_address_valid = ReceiveAddressToIPEndpoint(&address); | 504 bool is_address_valid = ReceiveAddressToIPEndpoint(&address); |
495 net_log_.AddEvent( | 505 net_log_.AddEvent(NetLog::TYPE_UDP_BYTES_RECEIVED, |
496 NetLog::TYPE_UDP_BYTES_RECEIVED, | 506 CreateNetLogUDPDataTranferCallback( |
497 CreateNetLogUDPDataTranferCallback( | 507 result, bytes, is_address_valid ? &address : NULL)); |
498 result, bytes, | |
499 is_address_valid ? &address : NULL)); | |
500 } | 508 } |
501 | 509 |
502 base::StatsCounter read_bytes("udp.read_bytes"); | 510 base::StatsCounter read_bytes("udp.read_bytes"); |
503 read_bytes.Add(result); | 511 read_bytes.Add(result); |
504 } | 512 } |
505 | 513 |
506 void UDPSocketWin::DidCompleteWrite() { | 514 void UDPSocketWin::DidCompleteWrite() { |
507 DWORD num_bytes, flags; | 515 DWORD num_bytes, flags; |
508 BOOL ok = WSAGetOverlappedResult(socket_, &core_->write_overlapped_, | 516 BOOL ok = WSAGetOverlappedResult( |
509 &num_bytes, FALSE, &flags); | 517 socket_, &core_->write_overlapped_, &num_bytes, FALSE, &flags); |
510 WSAResetEvent(core_->write_overlapped_.hEvent); | 518 WSAResetEvent(core_->write_overlapped_.hEvent); |
511 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); | 519 int result = ok ? num_bytes : MapSystemError(WSAGetLastError()); |
512 LogWrite(result, core_->write_iobuffer_->data(), send_to_address_.get()); | 520 LogWrite(result, core_->write_iobuffer_->data(), send_to_address_.get()); |
513 | 521 |
514 send_to_address_.reset(); | 522 send_to_address_.reset(); |
515 core_->write_iobuffer_ = NULL; | 523 core_->write_iobuffer_ = NULL; |
516 DoWriteCallback(result); | 524 DoWriteCallback(result); |
517 } | 525 } |
518 | 526 |
519 void UDPSocketWin::LogWrite(int result, | 527 void UDPSocketWin::LogWrite(int result, |
520 const char* bytes, | 528 const char* bytes, |
521 const IPEndPoint* address) const { | 529 const IPEndPoint* address) const { |
522 if (result < 0) { | 530 if (result < 0) { |
523 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result); | 531 net_log_.AddEventWithNetErrorCode(NetLog::TYPE_UDP_SEND_ERROR, result); |
524 return; | 532 return; |
525 } | 533 } |
526 | 534 |
527 if (net_log_.IsLogging()) { | 535 if (net_log_.IsLogging()) { |
528 net_log_.AddEvent( | 536 net_log_.AddEvent( |
529 NetLog::TYPE_UDP_BYTES_SENT, | 537 NetLog::TYPE_UDP_BYTES_SENT, |
530 CreateNetLogUDPDataTranferCallback(result, bytes, address)); | 538 CreateNetLogUDPDataTranferCallback(result, bytes, address)); |
531 } | 539 } |
532 | 540 |
533 base::StatsCounter write_bytes("udp.write_bytes"); | 541 base::StatsCounter write_bytes("udp.write_bytes"); |
534 write_bytes.Add(result); | 542 write_bytes.Add(result); |
535 } | 543 } |
536 | 544 |
537 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, int buf_len, | 545 int UDPSocketWin::InternalRecvFrom(IOBuffer* buf, |
| 546 int buf_len, |
538 IPEndPoint* address) { | 547 IPEndPoint* address) { |
539 DCHECK(!core_->read_iobuffer_); | 548 DCHECK(!core_->read_iobuffer_); |
540 SockaddrStorage& storage = core_->recv_addr_storage_; | 549 SockaddrStorage& storage = core_->recv_addr_storage_; |
541 storage.addr_len = sizeof(storage.addr_storage); | 550 storage.addr_len = sizeof(storage.addr_storage); |
542 | 551 |
543 WSABUF read_buffer; | 552 WSABUF read_buffer; |
544 read_buffer.buf = buf->data(); | 553 read_buffer.buf = buf->data(); |
545 read_buffer.len = buf_len; | 554 read_buffer.len = buf_len; |
546 | 555 |
547 DWORD flags = 0; | 556 DWORD flags = 0; |
548 DWORD num; | 557 DWORD num; |
549 CHECK_NE(INVALID_SOCKET, socket_); | 558 CHECK_NE(INVALID_SOCKET, socket_); |
550 AssertEventNotSignaled(core_->read_overlapped_.hEvent); | 559 AssertEventNotSignaled(core_->read_overlapped_.hEvent); |
551 int rv = WSARecvFrom(socket_, &read_buffer, 1, &num, &flags, storage.addr, | 560 int rv = WSARecvFrom(socket_, |
552 &storage.addr_len, &core_->read_overlapped_, NULL); | 561 &read_buffer, |
| 562 1, |
| 563 &num, |
| 564 &flags, |
| 565 storage.addr, |
| 566 &storage.addr_len, |
| 567 &core_->read_overlapped_, |
| 568 NULL); |
553 if (rv == 0) { | 569 if (rv == 0) { |
554 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { | 570 if (ResetEventIfSignaled(core_->read_overlapped_.hEvent)) { |
555 int result = num; | 571 int result = num; |
556 // Convert address. | 572 // Convert address. |
557 if (address && result >= 0) { | 573 if (address && result >= 0) { |
558 if (!ReceiveAddressToIPEndpoint(address)) | 574 if (!ReceiveAddressToIPEndpoint(address)) |
559 result = ERR_ADDRESS_INVALID; | 575 result = ERR_ADDRESS_INVALID; |
560 } | 576 } |
561 LogRead(result, buf->data()); | 577 LogRead(result, buf->data()); |
562 return result; | 578 return result; |
563 } | 579 } |
564 } else { | 580 } else { |
565 int os_error = WSAGetLastError(); | 581 int os_error = WSAGetLastError(); |
566 if (os_error != WSA_IO_PENDING) { | 582 if (os_error != WSA_IO_PENDING) { |
567 int result = MapSystemError(os_error); | 583 int result = MapSystemError(os_error); |
568 LogRead(result, NULL); | 584 LogRead(result, NULL); |
569 return result; | 585 return result; |
570 } | 586 } |
571 } | 587 } |
572 core_->WatchForRead(); | 588 core_->WatchForRead(); |
573 core_->read_iobuffer_ = buf; | 589 core_->read_iobuffer_ = buf; |
574 return ERR_IO_PENDING; | 590 return ERR_IO_PENDING; |
575 } | 591 } |
576 | 592 |
577 int UDPSocketWin::InternalSendTo(IOBuffer* buf, int buf_len, | 593 int UDPSocketWin::InternalSendTo(IOBuffer* buf, |
| 594 int buf_len, |
578 const IPEndPoint* address) { | 595 const IPEndPoint* address) { |
579 DCHECK(!core_->write_iobuffer_); | 596 DCHECK(!core_->write_iobuffer_); |
580 SockaddrStorage storage; | 597 SockaddrStorage storage; |
581 struct sockaddr* addr = storage.addr; | 598 struct sockaddr* addr = storage.addr; |
582 // Convert address. | 599 // Convert address. |
583 if (!address) { | 600 if (!address) { |
584 addr = NULL; | 601 addr = NULL; |
585 storage.addr_len = 0; | 602 storage.addr_len = 0; |
586 } else { | 603 } else { |
587 if (!address->ToSockAddr(addr, &storage.addr_len)) { | 604 if (!address->ToSockAddr(addr, &storage.addr_len)) { |
588 int result = ERR_ADDRESS_INVALID; | 605 int result = ERR_ADDRESS_INVALID; |
589 LogWrite(result, NULL, NULL); | 606 LogWrite(result, NULL, NULL); |
590 return result; | 607 return result; |
591 } | 608 } |
592 } | 609 } |
593 | 610 |
594 WSABUF write_buffer; | 611 WSABUF write_buffer; |
595 write_buffer.buf = buf->data(); | 612 write_buffer.buf = buf->data(); |
596 write_buffer.len = buf_len; | 613 write_buffer.len = buf_len; |
597 | 614 |
598 DWORD flags = 0; | 615 DWORD flags = 0; |
599 DWORD num; | 616 DWORD num; |
600 AssertEventNotSignaled(core_->write_overlapped_.hEvent); | 617 AssertEventNotSignaled(core_->write_overlapped_.hEvent); |
601 int rv = WSASendTo(socket_, &write_buffer, 1, &num, flags, | 618 int rv = WSASendTo(socket_, |
602 addr, storage.addr_len, &core_->write_overlapped_, NULL); | 619 &write_buffer, |
| 620 1, |
| 621 &num, |
| 622 flags, |
| 623 addr, |
| 624 storage.addr_len, |
| 625 &core_->write_overlapped_, |
| 626 NULL); |
603 if (rv == 0) { | 627 if (rv == 0) { |
604 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { | 628 if (ResetEventIfSignaled(core_->write_overlapped_.hEvent)) { |
605 int result = num; | 629 int result = num; |
606 LogWrite(result, buf->data(), address); | 630 LogWrite(result, buf->data(), address); |
607 return result; | 631 return result; |
608 } | 632 } |
609 } else { | 633 } else { |
610 int os_error = WSAGetLastError(); | 634 int os_error = WSAGetLastError(); |
611 if (os_error != WSA_IO_PENDING) { | 635 if (os_error != WSA_IO_PENDING) { |
612 int result = MapSystemError(os_error); | 636 int result = MapSystemError(os_error); |
613 LogWrite(result, NULL, NULL); | 637 LogWrite(result, NULL, NULL); |
614 return result; | 638 return result; |
615 } | 639 } |
616 } | 640 } |
617 | 641 |
618 core_->WatchForWrite(); | 642 core_->WatchForWrite(); |
619 core_->write_iobuffer_ = buf; | 643 core_->write_iobuffer_ = buf; |
620 return ERR_IO_PENDING; | 644 return ERR_IO_PENDING; |
621 } | 645 } |
622 | 646 |
623 int UDPSocketWin::SetSocketOptions() { | 647 int UDPSocketWin::SetSocketOptions() { |
624 BOOL true_value = 1; | 648 BOOL true_value = 1; |
625 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) { | 649 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) { |
626 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, | 650 int rv = setsockopt(socket_, |
| 651 SOL_SOCKET, |
| 652 SO_REUSEADDR, |
627 reinterpret_cast<const char*>(&true_value), | 653 reinterpret_cast<const char*>(&true_value), |
628 sizeof(true_value)); | 654 sizeof(true_value)); |
629 if (rv < 0) | 655 if (rv < 0) |
630 return MapSystemError(WSAGetLastError()); | 656 return MapSystemError(WSAGetLastError()); |
631 } | 657 } |
632 if (socket_options_ & SOCKET_OPTION_BROADCAST) { | 658 if (socket_options_ & SOCKET_OPTION_BROADCAST) { |
633 int rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, | 659 int rv = setsockopt(socket_, |
| 660 SOL_SOCKET, |
| 661 SO_BROADCAST, |
634 reinterpret_cast<const char*>(&true_value), | 662 reinterpret_cast<const char*>(&true_value), |
635 sizeof(true_value)); | 663 sizeof(true_value)); |
636 if (rv < 0) | 664 if (rv < 0) |
637 return MapSystemError(WSAGetLastError()); | 665 return MapSystemError(WSAGetLastError()); |
638 } | 666 } |
639 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) { | 667 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) { |
640 DWORD loop = 0; | 668 DWORD loop = 0; |
641 int protocol_level = | 669 int protocol_level = addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
642 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; | |
643 int option = | 670 int option = |
644 addr_family_ == AF_INET ? IP_MULTICAST_LOOP: IPV6_MULTICAST_LOOP; | 671 addr_family_ == AF_INET ? IP_MULTICAST_LOOP : IPV6_MULTICAST_LOOP; |
645 int rv = setsockopt(socket_, protocol_level, option, | 672 int rv = setsockopt(socket_, |
646 reinterpret_cast<const char*>(&loop), sizeof(loop)); | 673 protocol_level, |
| 674 option, |
| 675 reinterpret_cast<const char*>(&loop), |
| 676 sizeof(loop)); |
647 if (rv < 0) | 677 if (rv < 0) |
648 return MapSystemError(WSAGetLastError()); | 678 return MapSystemError(WSAGetLastError()); |
649 } | 679 } |
650 if (multicast_time_to_live_ != 1) { | 680 if (multicast_time_to_live_ != 1) { |
651 DWORD hops = multicast_time_to_live_; | 681 DWORD hops = multicast_time_to_live_; |
652 int protocol_level = | 682 int protocol_level = addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
653 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; | |
654 int option = | 683 int option = |
655 addr_family_ == AF_INET ? IP_MULTICAST_TTL: IPV6_MULTICAST_HOPS; | 684 addr_family_ == AF_INET ? IP_MULTICAST_TTL : IPV6_MULTICAST_HOPS; |
656 int rv = setsockopt(socket_, protocol_level, option, | 685 int rv = setsockopt(socket_, |
657 reinterpret_cast<const char*>(&hops), sizeof(hops)); | 686 protocol_level, |
| 687 option, |
| 688 reinterpret_cast<const char*>(&hops), |
| 689 sizeof(hops)); |
658 if (rv < 0) | 690 if (rv < 0) |
659 return MapSystemError(WSAGetLastError()); | 691 return MapSystemError(WSAGetLastError()); |
660 } | 692 } |
661 if (multicast_interface_ != 0) { | 693 if (multicast_interface_ != 0) { |
662 switch (addr_family_) { | 694 switch (addr_family_) { |
663 case AF_INET: { | 695 case AF_INET: { |
664 in_addr address; | 696 in_addr address; |
665 address.s_addr = htonl(multicast_interface_); | 697 address.s_addr = htonl(multicast_interface_); |
666 int rv = setsockopt(socket_, IPPROTO_IP, IP_MULTICAST_IF, | 698 int rv = setsockopt(socket_, |
| 699 IPPROTO_IP, |
| 700 IP_MULTICAST_IF, |
667 reinterpret_cast<const char*>(&address), | 701 reinterpret_cast<const char*>(&address), |
668 sizeof(address)); | 702 sizeof(address)); |
669 if (rv) | 703 if (rv) |
670 return MapSystemError(WSAGetLastError()); | 704 return MapSystemError(WSAGetLastError()); |
671 break; | 705 break; |
672 } | 706 } |
673 case AF_INET6: { | 707 case AF_INET6: { |
674 uint32 interface_index = multicast_interface_; | 708 uint32 interface_index = multicast_interface_; |
675 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_MULTICAST_IF, | 709 int rv = setsockopt(socket_, |
| 710 IPPROTO_IPV6, |
| 711 IPV6_MULTICAST_IF, |
676 reinterpret_cast<const char*>(&interface_index), | 712 reinterpret_cast<const char*>(&interface_index), |
677 sizeof(interface_index)); | 713 sizeof(interface_index)); |
678 if (rv) | 714 if (rv) |
679 return MapSystemError(WSAGetLastError()); | 715 return MapSystemError(WSAGetLastError()); |
680 break; | 716 break; |
681 } | 717 } |
682 default: | 718 default: |
683 NOTREACHED() << "Invalid address family"; | 719 NOTREACHED() << "Invalid address family"; |
684 return ERR_ADDRESS_INVALID; | 720 return ERR_ADDRESS_INVALID; |
685 } | 721 } |
(...skipping 18 matching lines...) Expand all Loading... |
704 // page "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE" for the gory details. | 740 // page "Using SO_REUSEADDR and SO_EXCLUSIVEADDRUSE" for the gory details. |
705 if (last_error == WSAEACCES || last_error == WSAEADDRNOTAVAIL) | 741 if (last_error == WSAEACCES || last_error == WSAEADDRNOTAVAIL) |
706 return ERR_ADDRESS_IN_USE; | 742 return ERR_ADDRESS_IN_USE; |
707 return MapSystemError(last_error); | 743 return MapSystemError(last_error); |
708 } | 744 } |
709 | 745 |
710 int UDPSocketWin::RandomBind(const IPAddressNumber& address) { | 746 int UDPSocketWin::RandomBind(const IPAddressNumber& address) { |
711 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null()); | 747 DCHECK(bind_type_ == DatagramSocket::RANDOM_BIND && !rand_int_cb_.is_null()); |
712 | 748 |
713 for (int i = 0; i < kBindRetries; ++i) { | 749 for (int i = 0; i < kBindRetries; ++i) { |
714 int rv = DoBind(IPEndPoint(address, | 750 int rv = |
715 rand_int_cb_.Run(kPortStart, kPortEnd))); | 751 DoBind(IPEndPoint(address, rand_int_cb_.Run(kPortStart, kPortEnd))); |
716 if (rv == OK || rv != ERR_ADDRESS_IN_USE) | 752 if (rv == OK || rv != ERR_ADDRESS_IN_USE) |
717 return rv; | 753 return rv; |
718 } | 754 } |
719 return DoBind(IPEndPoint(address, 0)); | 755 return DoBind(IPEndPoint(address, 0)); |
720 } | 756 } |
721 | 757 |
722 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { | 758 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { |
723 SockaddrStorage& storage = core_->recv_addr_storage_; | 759 SockaddrStorage& storage = core_->recv_addr_storage_; |
724 return address->FromSockAddr(storage.addr, storage.addr_len); | 760 return address->FromSockAddr(storage.addr, storage.addr_len); |
725 } | 761 } |
726 | 762 |
727 int UDPSocketWin::JoinGroup( | 763 int UDPSocketWin::JoinGroup(const IPAddressNumber& group_address) const { |
728 const IPAddressNumber& group_address) const { | |
729 DCHECK(CalledOnValidThread()); | 764 DCHECK(CalledOnValidThread()); |
730 if (!is_connected()) | 765 if (!is_connected()) |
731 return ERR_SOCKET_NOT_CONNECTED; | 766 return ERR_SOCKET_NOT_CONNECTED; |
732 | 767 |
733 switch (group_address.size()) { | 768 switch (group_address.size()) { |
734 case kIPv4AddressSize: { | 769 case kIPv4AddressSize: { |
735 if (addr_family_ != AF_INET) | 770 if (addr_family_ != AF_INET) |
736 return ERR_ADDRESS_INVALID; | 771 return ERR_ADDRESS_INVALID; |
737 ip_mreq mreq; | 772 ip_mreq mreq; |
738 mreq.imr_interface.s_addr = htonl(multicast_interface_); | 773 mreq.imr_interface.s_addr = htonl(multicast_interface_); |
739 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); | 774 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); |
740 int rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP, | 775 int rv = setsockopt(socket_, |
| 776 IPPROTO_IP, |
| 777 IP_ADD_MEMBERSHIP, |
741 reinterpret_cast<const char*>(&mreq), | 778 reinterpret_cast<const char*>(&mreq), |
742 sizeof(mreq)); | 779 sizeof(mreq)); |
743 if (rv) | 780 if (rv) |
744 return MapSystemError(WSAGetLastError()); | 781 return MapSystemError(WSAGetLastError()); |
745 return OK; | 782 return OK; |
746 } | 783 } |
747 case kIPv6AddressSize: { | 784 case kIPv6AddressSize: { |
748 if (addr_family_ != AF_INET6) | 785 if (addr_family_ != AF_INET6) |
749 return ERR_ADDRESS_INVALID; | 786 return ERR_ADDRESS_INVALID; |
750 ipv6_mreq mreq; | 787 ipv6_mreq mreq; |
751 mreq.ipv6mr_interface = multicast_interface_; | 788 mreq.ipv6mr_interface = multicast_interface_; |
752 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); | 789 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); |
753 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, | 790 int rv = setsockopt(socket_, |
| 791 IPPROTO_IPV6, |
| 792 IPV6_ADD_MEMBERSHIP, |
754 reinterpret_cast<const char*>(&mreq), | 793 reinterpret_cast<const char*>(&mreq), |
755 sizeof(mreq)); | 794 sizeof(mreq)); |
756 if (rv) | 795 if (rv) |
757 return MapSystemError(WSAGetLastError()); | 796 return MapSystemError(WSAGetLastError()); |
758 return OK; | 797 return OK; |
759 } | 798 } |
760 default: | 799 default: |
761 NOTREACHED() << "Invalid address family"; | 800 NOTREACHED() << "Invalid address family"; |
762 return ERR_ADDRESS_INVALID; | 801 return ERR_ADDRESS_INVALID; |
763 } | 802 } |
764 } | 803 } |
765 | 804 |
766 int UDPSocketWin::LeaveGroup( | 805 int UDPSocketWin::LeaveGroup(const IPAddressNumber& group_address) const { |
767 const IPAddressNumber& group_address) const { | |
768 DCHECK(CalledOnValidThread()); | 806 DCHECK(CalledOnValidThread()); |
769 if (!is_connected()) | 807 if (!is_connected()) |
770 return ERR_SOCKET_NOT_CONNECTED; | 808 return ERR_SOCKET_NOT_CONNECTED; |
771 | 809 |
772 switch (group_address.size()) { | 810 switch (group_address.size()) { |
773 case kIPv4AddressSize: { | 811 case kIPv4AddressSize: { |
774 if (addr_family_ != AF_INET) | 812 if (addr_family_ != AF_INET) |
775 return ERR_ADDRESS_INVALID; | 813 return ERR_ADDRESS_INVALID; |
776 ip_mreq mreq; | 814 ip_mreq mreq; |
777 mreq.imr_interface.s_addr = htonl(multicast_interface_); | 815 mreq.imr_interface.s_addr = htonl(multicast_interface_); |
778 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); | 816 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); |
779 int rv = setsockopt(socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP, | 817 int rv = setsockopt(socket_, |
780 reinterpret_cast<const char*>(&mreq), sizeof(mreq)); | 818 IPPROTO_IP, |
| 819 IP_DROP_MEMBERSHIP, |
| 820 reinterpret_cast<const char*>(&mreq), |
| 821 sizeof(mreq)); |
781 if (rv) | 822 if (rv) |
782 return MapSystemError(WSAGetLastError()); | 823 return MapSystemError(WSAGetLastError()); |
783 return OK; | 824 return OK; |
784 } | 825 } |
785 case kIPv6AddressSize: { | 826 case kIPv6AddressSize: { |
786 if (addr_family_ != AF_INET6) | 827 if (addr_family_ != AF_INET6) |
787 return ERR_ADDRESS_INVALID; | 828 return ERR_ADDRESS_INVALID; |
788 ipv6_mreq mreq; | 829 ipv6_mreq mreq; |
789 mreq.ipv6mr_interface = multicast_interface_; | 830 mreq.ipv6mr_interface = multicast_interface_; |
790 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); | 831 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); |
791 int rv = setsockopt(socket_, IPPROTO_IPV6, IP_DROP_MEMBERSHIP, | 832 int rv = setsockopt(socket_, |
792 reinterpret_cast<const char*>(&mreq), sizeof(mreq)); | 833 IPPROTO_IPV6, |
| 834 IP_DROP_MEMBERSHIP, |
| 835 reinterpret_cast<const char*>(&mreq), |
| 836 sizeof(mreq)); |
793 if (rv) | 837 if (rv) |
794 return MapSystemError(WSAGetLastError()); | 838 return MapSystemError(WSAGetLastError()); |
795 return OK; | 839 return OK; |
796 } | 840 } |
797 default: | 841 default: |
798 NOTREACHED() << "Invalid address family"; | 842 NOTREACHED() << "Invalid address family"; |
799 return ERR_ADDRESS_INVALID; | 843 return ERR_ADDRESS_INVALID; |
800 } | 844 } |
801 } | 845 } |
802 | 846 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 // Note: setsockopt(IP_TOS) does not work on windows XP and later. | 879 // Note: setsockopt(IP_TOS) does not work on windows XP and later. |
836 int UDPSocketWin::SetDiffServCodePoint(DiffServCodePoint dscp) { | 880 int UDPSocketWin::SetDiffServCodePoint(DiffServCodePoint dscp) { |
837 return ERR_NOT_IMPLEMENTED; | 881 return ERR_NOT_IMPLEMENTED; |
838 } | 882 } |
839 | 883 |
840 void UDPSocketWin::DetachFromThread() { | 884 void UDPSocketWin::DetachFromThread() { |
841 base::NonThreadSafe::DetachFromThread(); | 885 base::NonThreadSafe::DetachFromThread(); |
842 } | 886 } |
843 | 887 |
844 } // namespace net | 888 } // namespace net |
OLD | NEW |