Index: net/udp/udp_socket_win.cc |
diff --git a/net/udp/udp_socket_win.cc b/net/udp/udp_socket_win.cc |
index 5c6da9fc47c154dfd9e40ad682e980512eb19002..f86ddcd24e69d8746db43b323a5df35902c626ba 100644 |
--- a/net/udp/udp_socket_win.cc |
+++ b/net/udp/udp_socket_win.cc |
@@ -355,7 +355,8 @@ int UDPSocketWin::Bind(const IPEndPoint& address) { |
} |
int UDPSocketWin::CreateSocket(const IPEndPoint& address) { |
- socket_ = WSASocket(address.GetSockAddrFamily(), SOCK_DGRAM, IPPROTO_UDP, |
+ sock_addr_family_ = address.GetSockAddrFamily(); |
+ socket_ = WSASocket(sock_addr_family_, SOCK_DGRAM, IPPROTO_UDP, |
NULL, 0, WSA_FLAG_OVERLAPPED); |
if (socket_ == INVALID_SOCKET) |
return MapSystemError(WSAGetLastError()); |
@@ -584,6 +585,16 @@ int UDPSocketWin::SetSocketOptions() { |
if (rv < 0) |
return MapSystemError(errno); |
} |
+ if (multicast_time_to_live_ != 1) { |
+ int rv = SetMulticastTimeToLive(multicast_time_to_live_); |
+ if (rv != OK) |
+ return rv; |
+ } |
+ if (!multicast_loopback_mode_) { |
+ int rv = SetMulticastLoopbackMode(multicast_loopback_mode_); |
+ if (rv != OK) |
+ return rv; |
+ } |
return OK; |
} |
@@ -614,4 +625,109 @@ bool UDPSocketWin::ReceiveAddressToIPEndpoint(IPEndPoint* address) const { |
return address->FromSockAddr(storage.addr, storage.addr_len); |
} |
+ |
+int UDPSocketWin::JoinGroup( |
+ const net::IPAddressNumber& group_address) const { |
+ DCHECK(CalledOnValidThread()); |
+ DCHECK(is_connected()); |
+ int rv = -1; |
+ switch(group_address.size()) { |
mmenke
2013/04/12 21:07:41
Space after switch.
Bei Zhang
2013/04/15 22:30:26
Done.
|
+ case kIPv4AddressSize: { |
+ if (sock_addr_family_ != AF_INET) { |
+ return ERR_ADDRESS_INVALID; |
+ } |
+ ip_mreq mreq; |
+ memset(&mreq, 0, sizeof(mreq)); |
+ memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); |
+ rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP, |
+ reinterpret_cast<const char*>(&mreq), |
+ sizeof(mreq)); |
+ break; |
+ } |
+ case kIPv6AddressSize: { |
+ if (sock_addr_family_ != AF_INET6) { |
+ return ERR_ADDRESS_INVALID; |
+ } |
+ ipv6_mreq mreq; |
+ memset(&mreq, 0, sizeof(mreq)); |
+ memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); |
+ rv = setsockopt(socket_, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, |
+ reinterpret_cast<const char*>(&mreq), |
+ sizeof(mreq)); |
+ break; |
+ } |
+ } |
+ return MapSystemError(rv); |
+} |
+ |
+int UDPSocketWin::LeaveGroup( |
+ const net::IPAddressNumber& group_address) const { |
+ DCHECK(CalledOnValidThread()); |
+ DCHECK(is_connected()); |
+ int rv = -1; |
+ switch(group_address.size()) { |
+ case kIPv4AddressSize: { |
+ if (sock_addr_family_ != AF_INET) { |
+ return ERR_ADDRESS_INVALID; |
+ } |
+ ip_mreq mreq; |
+ memset(&mreq, 0, sizeof(mreq)); |
+ memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize); |
+ rv = setsockopt(socket_, IPPROTO_IP, IP_DROP_MEMBERSHIP, |
+ reinterpret_cast<const char*>(&mreq), |
+ sizeof(mreq)); |
+ break; |
+ } |
+ case kIPv6AddressSize: { |
+ if (sock_addr_family_ != AF_INET6) { |
+ return ERR_ADDRESS_INVALID; |
+ } |
+ ipv6_mreq mreq; |
+ memset(&mreq, 0, sizeof(mreq)); |
+ memcpy(&mreq.ipv6mr_multiaddr, &group_address[0], kIPv6AddressSize); |
+ rv = setsockopt(socket_, IPPROTO_IPV6, IP_DROP_MEMBERSHIP, |
+ reinterpret_cast<const char*>(&mreq), |
+ sizeof(mreq)); |
+ break; |
+ } |
+ } |
+ return MapSystemError(rv); |
+} |
+ |
+int UDPSocketWin::SetMulticastTimeToLive(int timeToLive) { |
mmenke
2013/04/12 21:07:41
time_to_live
Bei Zhang
2013/04/15 22:30:26
Done.
|
+ DCHECK(CalledOnValidThread()); |
+ if(is_connected()) { |
mmenke
2013/04/12 21:07:41
Space after if
Bei Zhang
2013/04/15 22:30:26
Done.
|
+ if (timeToLive < 0 || timeToLive > 255) { |
+ return ERR_INVALID_ARGUMENT; |
+ } |
+ uint8 ttl = timeToLive; |
+ int ip_family = sock_addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
+ return MapSystemError(setsockopt(socket_, |
+ ip_family, |
+ IP_MULTICAST_TTL, |
+ reinterpret_cast<const char*>(&ttl), |
+ sizeof(ttl))); |
+ } else { |
+ multicast_time_to_live_ = timeToLive; |
+ return OK; |
+ } |
+ |
mmenke
2013/04/12 21:07:41
Remove blank line.
Bei Zhang
2013/04/15 22:30:26
Done.
|
+} |
+ |
+int UDPSocketWin::SetMulticastLoopbackMode(bool loopback) { |
+ DCHECK(CalledOnValidThread()); |
+ if(is_connected()) { |
mmenke
2013/04/12 21:07:41
Space after if
Bei Zhang
2013/04/15 22:30:26
Done.
|
+ uint8 loop = loopback; |
+ int ip_family = sock_addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6; |
+ return MapSystemError(setsockopt(socket_, |
+ ip_family, |
+ IP_MULTICAST_LOOP, |
+ reinterpret_cast<const char*>(&loop), |
+ sizeof(loop))); |
mmenke
2013/04/12 21:07:41
4-space indent.
Bei Zhang
2013/04/15 22:30:26
Done.
|
+ } else { |
+ multicast_loopback_mode_ = loopback; |
+ return OK; |
+ } |
+} |
+ |
} // namespace net |