Fixing logic for using android_setsocknetwork() with bind().

If android_setsocknetwork() is available, and it fails, then bind()
should *not* be called, and an error should be returned.

If it succeeds, then bind should be called, but with an "any" address.

This is to prevent cases where sockets are sent with a source address
that doesn't match the network interface they're sent on. See bug below.

This CL also changes "NetworkBinderResults" to an enum class, and
renames it to "NetworkBinderResult".

BUG=webrtc:7026

Review-Url: https://codereview.webrtc.org/2646863005
Cr-Commit-Position: refs/heads/master@{#16597}
This commit is contained in:
deadbeef
2017-02-13 15:41:59 -08:00
committed by Commit bot
parent 06b7e5ce1f
commit c874d1296a
6 changed files with 101 additions and 30 deletions

View File

@ -236,8 +236,9 @@ void AndroidNetworkMonitor::Stop() {
// The implementation is largely taken from UDPSocketPosix::BindToNetwork in
// https://cs.chromium.org/chromium/src/net/udp/udp_socket_posix.cc
int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd,
const rtc::IPAddress& address) {
rtc::NetworkBindingResult AndroidNetworkMonitor::BindSocketToNetwork(
int socket_fd,
const rtc::IPAddress& address) {
RTC_CHECK(thread_checker_.CalledOnValidThread());
// Android prior to Lollipop didn't have support for binding sockets to
// networks. In that case it should not have reached here because
@ -246,12 +247,12 @@ int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd,
if (android_sdk_int_ < SDK_VERSION_LOLLIPOP) {
LOG(LS_ERROR) << "BindSocketToNetwork is not supported in Android SDK "
<< android_sdk_int_;
return rtc::NETWORK_BIND_NOT_IMPLEMENTED;
return rtc::NetworkBindingResult::NOT_IMPLEMENTED;
}
auto iter = network_handle_by_address_.find(address);
if (iter == network_handle_by_address_.end()) {
return rtc::NETWORK_BIND_ADDRESS_NOT_FOUND;
return rtc::NetworkBindingResult::ADDRESS_NOT_FOUND;
}
NetworkHandle network_handle = iter->second;
@ -271,7 +272,7 @@ int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd,
void* lib = dlopen(android_native_lib_path.c_str(), RTLD_NOW);
if (lib == nullptr) {
LOG(LS_ERROR) << "Library " << android_native_lib_path << " not found!";
return rtc::NETWORK_BIND_NOT_IMPLEMENTED;
return rtc::NetworkBindingResult::NOT_IMPLEMENTED;
}
marshmallowSetNetworkForSocket =
reinterpret_cast<MarshmallowSetNetworkForSocket>(
@ -279,7 +280,7 @@ int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd,
}
if (!marshmallowSetNetworkForSocket) {
LOG(LS_ERROR) << "Symbol marshmallowSetNetworkForSocket is not found";
return rtc::NETWORK_BIND_NOT_IMPLEMENTED;
return rtc::NetworkBindingResult::NOT_IMPLEMENTED;
}
rv = marshmallowSetNetworkForSocket(network_handle, socket_fd);
} else {
@ -300,7 +301,7 @@ int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd,
void* lib = dlopen(net_library_path.c_str(), RTLD_NOW | RTLD_NOLOAD);
if (lib == nullptr) {
LOG(LS_ERROR) << "Library " << net_library_path << " not found!";
return rtc::NETWORK_BIND_NOT_IMPLEMENTED;
return rtc::NetworkBindingResult::NOT_IMPLEMENTED;
}
lollipopSetNetworkForSocket =
reinterpret_cast<LollipopSetNetworkForSocket>(
@ -308,7 +309,7 @@ int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd,
}
if (!lollipopSetNetworkForSocket) {
LOG(LS_ERROR) << "Symbol lollipopSetNetworkForSocket is not found ";
return rtc::NETWORK_BIND_NOT_IMPLEMENTED;
return rtc::NetworkBindingResult::NOT_IMPLEMENTED;
}
rv = lollipopSetNetworkForSocket(network_handle, socket_fd);
}
@ -317,12 +318,12 @@ int AndroidNetworkMonitor::BindSocketToNetwork(int socket_fd,
// ERR_NETWORK_CHANGED, rather than MapSystemError(ENONET) which gives back
// the less descriptive ERR_FAILED.
if (rv == 0) {
return rtc::NETWORK_BIND_SUCCESS;
return rtc::NetworkBindingResult::SUCCESS;
}
if (rv == ENONET) {
return rtc::NETWORK_BIND_NETWORK_CHANGED;
return rtc::NetworkBindingResult::NETWORK_CHANGED;
}
return rtc::NETWORK_BIND_FAILURE;
return rtc::NetworkBindingResult::FAILURE;
}
void AndroidNetworkMonitor::OnNetworkConnected(

View File

@ -58,8 +58,9 @@ class AndroidNetworkMonitor : public rtc::NetworkMonitorBase,
void Start() override;
void Stop() override;
int BindSocketToNetwork(int socket_fd,
const rtc::IPAddress& address) override;
rtc::NetworkBindingResult BindSocketToNetwork(
int socket_fd,
const rtc::IPAddress& address) override;
rtc::AdapterType GetAdapterType(const std::string& if_name) override;
void OnNetworkConnected(const NetworkInformation& network_info);
void OnNetworkDisconnected(NetworkHandle network_handle);