Index: net/udp/udp_socket_libevent.cc |
diff --git a/net/udp/udp_socket_libevent.cc b/net/udp/udp_socket_libevent.cc |
index 9b1a9957189d968c3fed617ba02aa3ee7d13cb98..373edae24708f9c35045a60c347895b12f61e8ec 100644 |
--- a/net/udp/udp_socket_libevent.cc |
+++ b/net/udp/udp_socket_libevent.cc |
@@ -317,20 +317,26 @@ int UDPSocketLibevent::Bind(const IPEndPoint& address) { |
int UDPSocketLibevent::SetReceiveBufferSize(int32 size) { |
DCHECK(CalledOnValidThread()); |
- int rv = setsockopt(socket_, SOL_SOCKET, SO_RCVBUF, |
- reinterpret_cast<const char*>(&size), sizeof(size)); |
- int last_error = errno; |
- DCHECK(!rv) << "Could not set socket receive buffer size: " << last_error; |
- return rv == 0 ? OK : MapSystemError(last_error); |
+ if (is_connected()) { |
+ int result = SetReceiveBufferSizeInternal(size); |
+ if (result != OK) |
+ return result; |
+ } |
+ socket_options_ |= SOCKET_OPTION_RCVBUF_SIZE; |
+ rcvbuf_size_ = size; |
+ return OK; |
} |
int UDPSocketLibevent::SetSendBufferSize(int32 size) { |
DCHECK(CalledOnValidThread()); |
- int rv = setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, |
- reinterpret_cast<const char*>(&size), sizeof(size)); |
- int last_error = errno; |
- DCHECK(!rv) << "Could not set socket send buffer size: " << last_error; |
- return rv == 0 ? OK : MapSystemError(last_error); |
+ if (is_connected()) { |
+ int result = SetSendBufferSizeInternal(size); |
+ if (result != OK) |
+ return result; |
+ } |
+ socket_options_ |= SOCKET_OPTION_SNDBUF_SIZE; |
+ sndbuf_size_ = size; |
+ return OK; |
} |
void UDPSocketLibevent::AllowAddressReuse() { |
@@ -340,11 +346,18 @@ void UDPSocketLibevent::AllowAddressReuse() { |
socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS; |
} |
-void UDPSocketLibevent::AllowBroadcast() { |
+int UDPSocketLibevent::SetBroadcast(bool broadcast) { |
DCHECK(CalledOnValidThread()); |
- DCHECK(!is_connected()); |
- |
- socket_options_ |= SOCKET_OPTION_BROADCAST; |
+ if (is_connected()) { |
+ int result = SetBroadcastInternal(broadcast); |
+ if (result != OK) |
+ return result; |
+ } |
+ if (broadcast) |
+ socket_options_ |= SOCKET_OPTION_BROADCAST; |
+ else |
+ socket_options_ &= ~SOCKET_OPTION_BROADCAST; |
+ return OK; |
} |
void UDPSocketLibevent::ReadWatcher::OnFileCanReadWithoutBlocking(int) { |
@@ -516,29 +529,17 @@ int UDPSocketLibevent::InternalSendTo(IOBuffer* buf, int buf_len, |
} |
int UDPSocketLibevent::SetSocketOptions() { |
- int true_value = 1; |
+ DCHECK(CalledOnValidThread()); |
if (socket_options_ & SOCKET_OPTION_REUSE_ADDRESS) { |
- int rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, &true_value, |
- sizeof(true_value)); |
- if (rv < 0) |
- return MapSystemError(errno); |
+ int rv = AllowAddressReuseInternal(); |
+ if (rv != OK) |
+ return rv; |
} |
if (socket_options_ & SOCKET_OPTION_BROADCAST) { |
- int rv; |
-#if defined(OS_MACOSX) |
- // SO_REUSEPORT on OSX permits multiple processes to each receive |
- // UDP multicast or broadcast datagrams destined for the bound |
- // port. |
- rv = setsockopt(socket_, SOL_SOCKET, SO_REUSEPORT, &true_value, |
- sizeof(true_value)); |
-#else |
- rv = setsockopt(socket_, SOL_SOCKET, SO_BROADCAST, &true_value, |
- sizeof(true_value)); |
-#endif // defined(OS_MACOSX) |
- if (rv < 0) |
- return MapSystemError(errno); |
+ int rv = SetBroadcastInternal(true); |
+ if (rv != OK) |
+ return rv; |
} |
- |
if (!(socket_options_ & SOCKET_OPTION_MULTICAST_LOOP)) { |
int rv; |
if (addr_family_ == AF_INET) { |
@@ -553,6 +554,17 @@ int UDPSocketLibevent::SetSocketOptions() { |
if (rv < 0) |
return MapSystemError(errno); |
} |
+ if (socket_options_ & SOCKET_OPTION_RCVBUF_SIZE) { |
+ int rv = SetReceiveBufferSizeInternal(rcvbuf_size_); |
+ if (rv != OK) |
+ return rv; |
+ } |
+ if (socket_options_ & SOCKET_OPTION_SNDBUF_SIZE) { |
+ int rv = SetSendBufferSizeInternal(sndbuf_size_); |
+ if (rv != OK) |
+ return rv; |
+ } |
+ |
if (multicast_time_to_live_ != IP_DEFAULT_MULTICAST_TTL) { |
int rv; |
if (addr_family_ == AF_INET) { |
@@ -605,6 +617,51 @@ int UDPSocketLibevent::SetSocketOptions() { |
return OK; |
} |
+int UDPSocketLibevent::AllowAddressReuseInternal() { |
+ DCHECK(CalledOnValidThread()); |
+ DCHECK(is_connected()); |
+ int opt_value = 1; |
+ int rv = setsockopt( |
+ socket_, SOL_SOCKET, SO_REUSEADDR, &opt_value, sizeof(opt_value)); |
+ return rv == 0 ? OK : MapSystemError(errno); |
+} |
+ |
+int UDPSocketLibevent::SetBroadcastInternal(bool broadcast) { |
+ DCHECK(CalledOnValidThread()); |
+ DCHECK(is_connected()); |
+ int opt_value = broadcast ? 1 : 0; |
+#if defined(OS_MACOSX) |
+ // SO_REUSEPORT on OSX permits multiple processes to each receive |
+ // UDP multicast or broadcast datagrams destined for the bound port. |
+ const int kOptName = SO_REUSEPORT; |
+#else |
+ const int kOptName = SO_BROADCAST; |
+#endif |
+ int rv = setsockopt( |
+ socket_, SOL_SOCKET, kOptName, &opt_value, sizeof(opt_value)); |
+ return rv == 0 ? OK : MapSystemError(errno); |
+} |
+ |
+int UDPSocketLibevent::SetReceiveBufferSizeInternal(int32 size) { |
+ DCHECK(CalledOnValidThread()); |
+ DCHECK(is_connected()); |
+ int rv = setsockopt( |
+ socket_, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); |
+ int last_error = errno; |
+ DCHECK(!rv) << "Could not set socket receive buffer size: " << last_error; |
+ return rv == 0 ? OK : MapSystemError(last_error); |
+} |
+ |
+int UDPSocketLibevent::SetSendBufferSizeInternal(int32 size) { |
+ DCHECK(CalledOnValidThread()); |
+ DCHECK(is_connected()); |
+ int rv = setsockopt( |
+ socket_, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); |
+ int last_error = errno; |
+ DCHECK(!rv) << "Could not set socket send buffer size: " << last_error; |
+ return rv == 0 ? OK : MapSystemError(last_error); |
+} |
+ |
int UDPSocketLibevent::DoBind(const IPEndPoint& address) { |
SockaddrStorage storage; |
if (!address.ToSockAddr(storage.addr, &storage.addr_len)) |