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..0d645e905d0bc4e0a8620a3f021b04808db5a638 100644 |
--- a/net/udp/udp_socket_libevent.cc |
+++ b/net/udp/udp_socket_libevent.cc |
@@ -317,34 +317,70 @@ 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() { |
+int UDPSocketLibevent::AllowAddressReuse() { |
DCHECK(CalledOnValidThread()); |
- DCHECK(!is_connected()); |
- |
+ if (is_connected()) { |
+ int result = SetAddressReuseInternal(true); |
+ if (result != OK) |
+ return result; |
+ } |
socket_options_ |= SOCKET_OPTION_REUSE_ADDRESS; |
+ return OK; |
} |
-void UDPSocketLibevent::AllowBroadcast() { |
+int UDPSocketLibevent::DisallowAddressReuse() { |
DCHECK(CalledOnValidThread()); |
- DCHECK(!is_connected()); |
+ if (is_connected()) { |
+ int result = SetAddressReuseInternal(false); |
+ if (result != OK) |
+ return result; |
+ } |
+ socket_options_ &= ~SOCKET_OPTION_REUSE_ADDRESS; |
+ return OK; |
+} |
+int UDPSocketLibevent::AllowBroadcast() { |
+ DCHECK(CalledOnValidThread()); |
+ if (is_connected()) { |
+ int result = SetBroadcastInternal(true); |
+ if (result != OK) |
+ return result; |
+ } |
socket_options_ |= SOCKET_OPTION_BROADCAST; |
+ return OK; |
+} |
+ |
+int UDPSocketLibevent::DisallowBroadcast() { |
+ DCHECK(CalledOnValidThread()); |
+ if (is_connected()) { |
+ int result = SetBroadcastInternal(false); |
+ if (result != OK) |
+ return result; |
+ } |
+ socket_options_ &= ~SOCKET_OPTION_BROADCAST; |
+ return OK; |
} |
void UDPSocketLibevent::ReadWatcher::OnFileCanReadWithoutBlocking(int) { |
@@ -516,29 +552,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 = SetAddressReuseInternal(true); |
+ 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 +577,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 +640,52 @@ int UDPSocketLibevent::SetSocketOptions() { |
return OK; |
} |
+int UDPSocketLibevent::SetAddressReuseInternal(bool address_reuse) { |
+ DCHECK(CalledOnValidThread()); |
+ DCHECK(is_connected()); |
+ int opt_value = address_reuse ? 1 : 0; |
+ 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, |
+ 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); |
+} |
+ |
+int UDPSocketLibevent::SetSendBufferSizeInternal(int32 size) { |
+ DCHECK(CalledOnValidThread()); |
+ DCHECK(is_connected()); |
+ 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); |
+} |
+ |
int UDPSocketLibevent::DoBind(const IPEndPoint& address) { |
SockaddrStorage storage; |
if (!address.ToSockAddr(storage.addr, &storage.addr_len)) |