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

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: Add License info to multicast.js Created 7 years, 7 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
« 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/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 protocol_level =
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_, protocol_level, 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 protocol_level =
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_, protocol_level, 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 if (!is_connected())
646 return ERR_SOCKET_NOT_CONNECTED;
647
648 switch (group_address.size()) {
649 case kIPv4AddressSize: {
650 if (addr_family_ != AF_INET)
651 return ERR_ADDRESS_INVALID;
652 ip_mreq mreq;
653 mreq.imr_interface.s_addr = INADDR_ANY;
654 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize);
655 int rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP,
656 reinterpret_cast<const char*>(&mreq),
657 sizeof(mreq));
658 if (rv)
659 return MapSystemError(WSAGetLastError());
660 return OK;
661 }
662 case kIPv6AddressSize: {
663 if (addr_family_ != AF_INET6)
664 return ERR_ADDRESS_INVALID;
665 ipv6_mreq mreq;
666 mreq.ipv6mr_interface = 0; // 0 indicates default multicast interface.
667 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize);
668 int rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP,
669 reinterpret_cast<const char*>(&mreq),
670 sizeof(mreq));
671 if (rv)
672 return MapSystemError(WSAGetLastError());
673 return OK;
674 }
675 default:
676 NOTREACHED() << "Invalid address family";
677 return ERR_ADDRESS_INVALID;
678 }
679 }
680
681 int UDPSocketWin::LeaveGroup(
682 const IPAddressNumber& group_address) const {
683 DCHECK(CalledOnValidThread());
684 if (!is_connected())
685 return ERR_SOCKET_NOT_CONNECTED;
686
687 switch (group_address.size()) {
688 case kIPv4AddressSize: {
689 if (addr_family_ != AF_INET)
690 return ERR_ADDRESS_INVALID;
691 ip_mreq mreq;
692 mreq.imr_interface.s_addr = INADDR_ANY;
693 memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize);
694 int rv = setsockopt(socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP,
695 reinterpret_cast<const char*>(&mreq),
696 sizeof(mreq));
697 if (rv)
698 return MapSystemError(WSAGetLastError());
699 return OK;
700 }
701 case kIPv6AddressSize: {
702 if (addr_family_ != AF_INET6)
703 return ERR_ADDRESS_INVALID;
704 ipv6_mreq mreq;
705 mreq.ipv6mr_interface = 0; // 0 indicates default multicast interface.
706 memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize);
707 int rv = setsockopt(socket_, IPPROTO_IPV6, IP_DROP_MEMBERSHIP,
708 reinterpret_cast<const char*>(&mreq),
709 sizeof(mreq));
710 if (rv)
711 return MapSystemError(WSAGetLastError());
712 return OK;
713 }
714 default:
715 NOTREACHED() << "Invalid address family";
716 return ERR_ADDRESS_INVALID;
717 }
718 }
719
720 int UDPSocketWin::SetMulticastTimeToLive(int time_to_live) {
721 DCHECK(CalledOnValidThread());
722 if (is_connected())
723 return ERR_UNEXPECTED;
724
725 if (time_to_live < 0 || time_to_live > 255)
726 return ERR_INVALID_ARGUMENT;
727 multicast_time_to_live_ = time_to_live;
728 return OK;
729 }
730
731 int UDPSocketWin::SetMulticastLoopbackMode(bool loopback) {
732 DCHECK(CalledOnValidThread());
733 if (is_connected())
734 return ERR_UNEXPECTED;
735
736 if (loopback)
737 socket_options_ |= SOCKET_OPTION_MULTICAST_LOOP;
738 else
739 socket_options_ &= ~SOCKET_OPTION_MULTICAST_LOOP;
740 return OK;
741 }
742
617 } // namespace net 743 } // 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