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

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

Issue 12684008: Multicast socket API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix windows build Created 7 years, 8 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 | Annotate | Revision Log
« net/udp/udp_socket_unittest.cc ('K') | « 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/callback.h" 9 #include "base/callback.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 core_->Release(); 156 core_->Release();
157 } 157 }
158 158
159 //----------------------------------------------------------------------------- 159 //-----------------------------------------------------------------------------
160 160
161 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type, 161 UDPSocketWin::UDPSocketWin(DatagramSocket::BindType bind_type,
162 const RandIntCallback& rand_int_cb, 162 const RandIntCallback& rand_int_cb,
163 net::NetLog* net_log, 163 net::NetLog* net_log,
164 const net::NetLog::Source& source) 164 const net::NetLog::Source& source)
165 : socket_(INVALID_SOCKET), 165 : socket_(INVALID_SOCKET),
166 socket_options_(0), 166 addr_family_(0),
167 socket_options_(SOCKET_OPTION_MULTICAST_LOOP),
168 multicast_time_to_live_(1),
167 bind_type_(bind_type), 169 bind_type_(bind_type),
168 rand_int_cb_(rand_int_cb), 170 rand_int_cb_(rand_int_cb),
169 recv_from_address_(NULL), 171 recv_from_address_(NULL),
170 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) { 172 net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_UDP_SOCKET)) {
171 EnsureWinsockInit(); 173 EnsureWinsockInit();
172 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE, 174 net_log_.BeginEvent(NetLog::TYPE_SOCKET_ALIVE,
173 source.ToEventParametersCallback()); 175 source.ToEventParametersCallback());
174 if (bind_type == DatagramSocket::RANDOM_BIND) 176 if (bind_type == DatagramSocket::RANDOM_BIND)
175 DCHECK(!rand_int_cb.is_null()); 177 DCHECK(!rand_int_cb.is_null());
176 } 178 }
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 if (rv < 0) 350 if (rv < 0)
349 return rv; 351 return rv;
350 rv = DoBind(address); 352 rv = DoBind(address);
351 if (rv < 0) 353 if (rv < 0)
352 return rv; 354 return rv;
353 local_address_.reset(); 355 local_address_.reset();
354 return rv; 356 return rv;
355 } 357 }
356 358
357 int UDPSocketWin::CreateSocket(const IPEndPoint& address) { 359 int UDPSocketWin::CreateSocket(const IPEndPoint& address) {
358 socket_ = WSASocket(address.GetSockAddrFamily(), SOCK_DGRAM, IPPROTO_UDP, 360 addr_family_ = address.GetSockAddrFamily();
361 socket_ = WSASocket(addr_family_, SOCK_DGRAM, IPPROTO_UDP,
359 NULL, 0, WSA_FLAG_OVERLAPPED); 362 NULL, 0, WSA_FLAG_OVERLAPPED);
360 if (socket_ == INVALID_SOCKET) 363 if (socket_ == INVALID_SOCKET)
361 return MapSystemError(WSAGetLastError()); 364 return MapSystemError(WSAGetLastError());
362 core_ = new Core(this); 365 core_ = new Core(this);
363 return OK; 366 return OK;
364 } 367 }
365 368
366 bool UDPSocketWin::SetReceiveBufferSize(int32 size) { 369 bool UDPSocketWin::SetReceiveBufferSize(int32 size) {
367 DCHECK(CalledOnValidThread()); 370 DCHECK(CalledOnValidThread());
368 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, 371 int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF,
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 return ERR_IO_PENDING; 571 return ERR_IO_PENDING;
569 } 572 }
570 573
571 int UDPSocketWin::SetSocketOptions() { 574 int UDPSocketWin::SetSocketOptions() {
572 BOOL true_value = 1; 575 BOOL true_value = 1;
573 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) { 576 if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) {
574 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, 577 int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR,
575 reinterpret_cast<const char*>(&true_value), 578 reinterpret_cast<const char*>(&true_value),
576 sizeof(true_value)); 579 sizeof(true_value));
577 if (rv < 0) 580 if (rv < 0)
578 return MapSystemError(errno); 581 return MapSystemError(WSAGetLastError());
579 } 582 }
580 if (socket_options_ & SOCKET_OPTION_BROADCAST) { 583 if (socket_options_ & SOCKET_OPTION_BROADCAST) {
581 int rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, 584 int rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST,
582 reinterpret_cast<const char*>(&true_value), 585 reinterpret_cast<const char*>(&true_value),
583 sizeof(true_value)); 586 sizeof(true_value));
584 if (rv < 0) 587 if (rv < 0)
585 return MapSystemError(errno); 588 return MapSystemError(WSAGetLastError());
589 }
590 if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) {
591 DWORD loop = 0;
592 int ip_family =
593 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
594 int option =
595 addr_family_ == AF_INET ? IP_MULTICAST_LOOP: IPV6_MULTICAST_LOOP;
596 int rv = setsockopt(socket_, ip_family, option,
597 reinterpret_cast<const char*>(&loop), sizeof(loop));
598 if (rv < 0)
599 return MapSystemError(WSAGetLastError());
600 }
601 if (multicast_time_to_live_ != 1) {
602 DWORD hops = multicast_time_to_live_;
603 int ip_family =
604 addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
605 int option =
606 addr_family_ == AF_INET ? IP_MULTICAST_TTL: IPV6_MULTICAST_HOPS;
607 int rv = setsockopt(socket_, ip_family, option,
608 reinterpret_cast<const char*>(&hops), sizeof(hops));
609 if (rv < 0)
610 return MapSystemError(WSAGetLastError());
586 } 611 }
587 return OK; 612 return OK;
588 } 613 }
589 614
590 int UDPSocketWin::DoBind(const IPEndPoint& address) { 615 int UDPSocketWin::DoBind(const IPEndPoint& address) {
591 SockaddrStorage storage; 616 SockaddrStorage storage;
592 if (!address.ToSockAddr(storage.addr, &storage.addr_len)) 617 if (!address.ToSockAddr(storage.addr, &storage.addr_len))
593 return ERR_UNEXPECTED; 618 return ERR_UNEXPECTED;
594 int rv = bind(socket_, storage.addr, storage.addr_len); 619 int rv = bind(socket_, storage.addr, storage.addr_len);
595 return rv < 0 ? MapSystemError(WSAGetLastError()) : rv; 620 return rv < 0 ? MapSystemError(WSAGetLastError()) : rv;
(...skipping 11 matching lines...) Expand all
607 return rv; 632 return rv;
608 } 633 }
609 return DoBind(IPEndPoint(ip, 0)); 634 return DoBind(IPEndPoint(ip, 0));
610 } 635 }
611 636
612 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { 637 bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const {
613 SockaddrStorage& storage = core_->recv_addr_storage_; 638 SockaddrStorage& storage = core_->recv_addr_storage_;
614 return address->FromSockAddr(storage.addr, storage.addr_len); 639 return address->FromSockAddr(storage.addr, storage.addr_len);
615 } 640 }
616 641
642 int UDPSocketWin::JoinGroup(
643 const IPAddressNumber& group_address) const {
644 DCHECK(CalledOnValidThread());
645 DCHECK(is_connected());
646 switch (group_address.size()) {
647 case kIPv4AddressSize: {
648 if (addr_family_ != AF_INET)
649 return ERR_ADDRESS_INVALID;
650 ip_mreq mreq;
651 mreq.imr_interface.s_addr = INADDR_ANY;
652 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize);
653 int rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP,
654 reinterpret_cast<const char*>(&mreq),
655 sizeof(mreq));
656 if (rv)
657 return MapSystemError(WSAGetLastError());
658 return OK;
659 }
660 case kIPv6AddressSize: {
661 if (addr_family_ != AF_INET6)
662 return ERR_ADDRESS_INVALID;
663 ipv6_mreq mreq;
664 mreq.ipv6mr_interface = 0; // 0 indicates default multicast interface.
665 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize);
666 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
667 reinterpret_cast<const char*>(&mreq),
668 sizeof(mreq));
669 if (rv)
670 return MapSystemError(WSAGetLastError());
671 return OK;
672 }
673 default:
674 NOTREACHED() << "Invalid address family";
675 return ERR_ADDRESS_INVALID;
676 }
677 }
678
679 int UDPSocketWin::LeaveGroup(
680 const IPAddressNumber& group_address) const {
681 DCHECK(CalledOnValidThread());
682 DCHECK(is_connected());
683 switch (group_address.size()) {
684 case kIPv4AddressSize: {
685 if (addr_family_ != AF_INET)
686 return ERR_ADDRESS_INVALID;
687 ip_mreq mreq;
688 mreq.imr_interface.s_addr = INADDR_ANY;
689 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize);
690 int rv = setsockopt(socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP,
691 reinterpret_cast<const char*>(&mreq),
692 sizeof(mreq));
693 if (rv)
694 return MapSystemError(WSAGetLastError());
695 return OK;
696 }
697 case kIPv6AddressSize: {
698 if (addr_family_ != AF_INET6)
699 return ERR_ADDRESS_INVALID;
700 ipv6_mreq mreq;
701 mreq.ipv6mr_interface = 0; // 0 indicates default multicast interface.
702 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize);
703 int rv = setsockopt(socket_, IPPROTO_IPV6, IP_DROP_MEMBERSHIP,
704 reinterpret_cast<const char*>(&mreq),
705 sizeof(mreq));
706 if (rv)
707 return MapSystemError(WSAGetLastError());
708 return OK;
709 }
710 default:
711 NOTREACHED() << "Invalid address family";
712 return ERR_ADDRESS_INVALID;
713 }
714 }
715
716 int UDPSocketWin::SetMulticastTimeToLive(int time_to_live) {
717 DCHECK(CalledOnValidThread());
718 DCHECK(!is_connected());
719 if (time_to_live < 0 || time_to_live > 255)
720 return ERR_INVALID_ARGUMENT;
721 multicast_time_to_live_ = time_to_live;
722 return OK;
723 }
724
725 int UDPSocketWin::SetMulticastLoopbackMode(bool loopback) {
726 DCHECK(CalledOnValidThread());
727 DCHECK(!is_connected());
728 if (loopback)
729 socket_options_ |= SOCKET_OPTION_MULTICAST_LOOP;
730 else
731 socket_options_ &= ~SOCKET_OPTION_MULTICAST_LOOP;
732 return OK;
733 }
734
617 } // namespace net 735 } // namespace net
OLDNEW
« net/udp/udp_socket_unittest.cc ('K') | « net/udp/udp_socket_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698