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

Unified Diff: net/udp/udp_socket_libevent.cc

Issue 12684008: Multicast socket API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix tests 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 side-by-side diff with in-line comments
Download patch
Index: net/udp/udp_socket_libevent.cc
diff --git a/net/udp/udp_socket_libevent.cc b/net/udp/udp_socket_libevent.cc
index 063da08c387963b60066b3d1459aa82b9703a970..a6e78bf7745164f5194c0027dce704203a0c0f1f 100644
--- a/net/udp/udp_socket_libevent.cc
+++ b/net/udp/udp_socket_libevent.cc
@@ -42,6 +42,8 @@ UDPSocketLibevent::UDPSocketLibevent(
const net::NetLog::Source& source)
: socket_(kInvalidSocket),
socket_options_(0),
+ multicast_time_to_live_(1),
+ multicast_loopback_mode_(true),
bind_type_(bind_type),
rand_int_cb_(rand_int_cb),
read_watcher_(this),
@@ -363,7 +365,8 @@ void UDPSocketLibevent::LogRead(int result,
}
int UDPSocketLibevent::CreateSocket(const IPEndPoint& address) {
- socket_ = socket(address.GetSockAddrFamily(), SOCK_DGRAM, 0);
+ sock_addr_family_ = address.GetSockAddrFamily();
+ socket_ = socket(sock_addr_family_, SOCK_DGRAM, 0);
if (socket_ == kInvalidSocket)
return MapSystemError(errno);
if (SetNonBlocking(socket_)) {
@@ -476,14 +479,25 @@ int UDPSocketLibevent::SetSocketOptions() {
// port.
rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEPORT, &true_value,
sizeof(true_value));
- if (rv < 0)
- return MapSystemError(errno);
mmenke 2013/04/12 21:07:41 Why get rid of this?
Bei Zhang 2013/04/15 22:30:26 I simply moved this out side of the #if to elimina
+#else
+ rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, &true_value,
+ sizeof(true_value));
mmenke 2013/04/12 21:07:41 I don't think we need to do this twice on platform
Bei Zhang 2013/04/15 22:30:26 Done.
#endif // defined(OS_MACOSX)
rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, &true_value,
sizeof(true_value));
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;
}
@@ -509,4 +523,104 @@ int UDPSocketLibevent::RandomBind(const IPEndPoint& address) {
return DoBind(IPEndPoint(ip, 0));
}
+int UDPSocketLibevent::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;
+ }
mmenke 2013/04/12 21:07:41 Braces are generally discouraged in single line if
Bei Zhang 2013/04/15 22:30:26 Done.
+ ip_mreq mreq;
+ memset(&mreq, 0, sizeof(mreq));
+ memcpy(&mreq.imr_multiaddr, &group_address[0], kIPv4AddressSize);
+ rv = setsockopt(socket_, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ &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_JOIN_GROUP,
+ &mreq, sizeof(mreq));
+ break;
+ }
+ }
+
+ return MapSystemError(rv);
+}
+
+int UDPSocketLibevent::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,
+ &mreq, sizeof(mreq));
mmenke 2013/04/12 21:07:41 Fix indent.
Bei Zhang 2013/04/15 22:30:26 Done.
+ 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_LEAVE_GROUP,
+ &mreq, sizeof(mreq));
mmenke 2013/04/12 21:07:41 Fix indent.
Bei Zhang 2013/04/15 22:30:26 Done.
+ break;
+ }
+ }
+
+ return MapSystemError(rv);
+}
+
+int UDPSocketLibevent::SetMulticastTimeToLive(int timeToLive) {
mmenke 2013/04/12 21:07:41 Rename, per comment in header.
Bei Zhang 2013/04/15 22:30:26 Done.
+ DCHECK(CalledOnValidThread());
+ if (timeToLive < 0 || timeToLive > 255) {
+ return ERR_INVALID_ARGUMENT;
+ }
+ if(is_connected()) {
mmenke 2013/04/12 21:07:41 Space after if.
Bei Zhang 2013/04/15 22:30:26 Done.
+ uint8 ttl = timeToLive;
+ int ip_family = sock_addr_family_ == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
+ return MapSystemError(setsockopt(socket_,
+ ip_family,
+ IP_MULTICAST_TTL,
+ &ttl, sizeof(ttl)));
+ } else {
+ multicast_time_to_live_ = timeToLive;
+ return OK;
+ }
+}
+
+int UDPSocketLibevent::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,
+ &loop, sizeof(loop)));
+ } else {
+ multicast_loopback_mode_ = loopback;
+ return OK;
+ }
+}
} // namespace net

Powered by Google App Engine
This is Rietveld 408576698