Support VPN adapter type in WebRTC Android.

The VPN adapter type is not effectively supported in WebRTC Android for
1) the network monitor may not obtain the VPN adapter type from the OS,
e.g. via NetworkInfo.getType, 2) and VPN adapter type is replaced
by the adapter type of an underlying network by the network monitor in
the current implementation. Specifically, WebRTC Android would
previously classify VPNs as either type ADAPTER_TYPE_UNKNOWN, or the
type of the currently active network (which we assume the VPN is
using).

In this CL, VPNs are classified as ADAPTER_TYPE_VPN whenever possible,
and the underlying network type, if available from the VPN, is
separately stored and used to prioritize ICE candidates in network path
selection.

This allows ADAPTER_TYPE_VPN to be used in networkIgnoreMask to ignore
VPNs when gathering ICE candidates.

Bug: webrtc:9168
Change-Id: I9513c76a114ba967437b699e71223a4a2f13f34a
Reviewed-on: https://webrtc-review.googlesource.com/70960
Commit-Queue: Qingsi Wang <qingsi@google.com>
Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org>
Reviewed-by: Sami Kalliomäki <sakal@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23061}
This commit is contained in:
Qingsi Wang
2018-04-27 14:25:37 -07:00
committed by Commit Bot
parent e80689fcab
commit de2ed7dc18
8 changed files with 225 additions and 47 deletions

View File

@ -60,6 +60,9 @@ static NetworkType GetNetworkTypeFromJava(
if (enum_name == "CONNECTION_BLUETOOTH") {
return NetworkType::NETWORK_BLUETOOTH;
}
if (enum_name == "CONNECTION_VPN") {
return NetworkType::NETWORK_VPN;
}
if (enum_name == "CONNECTION_NONE") {
return NetworkType::NETWORK_NONE;
}
@ -80,6 +83,7 @@ static rtc::AdapterType AdapterTypeFromNetworkType(NetworkType network_type) {
case NETWORK_2G:
case NETWORK_UNKNOWN_CELLULAR:
return rtc::ADAPTER_TYPE_CELLULAR;
case NETWORK_VPN:
case NETWORK_BLUETOOTH:
// There is no corresponding mapping for bluetooth networks.
// Map it to VPN for now.
@ -123,6 +127,9 @@ static NetworkInformation GetNetworkInformationFromJava(
Java_NetworkInformation_getHandle(jni, j_network_info));
network_info.type = GetNetworkTypeFromJava(
jni, Java_NetworkInformation_getConnectionType(jni, j_network_info));
network_info.underlying_type_for_vpn = GetNetworkTypeFromJava(
jni, Java_NetworkInformation_getUnderlyingConnectionTypeForVpn(
jni, j_network_info));
ScopedJavaLocalRef<jobjectArray> j_ip_addresses =
Java_NetworkInformation_getIpAddresses(jni, j_network_info);
network_info.ip_addresses = JavaToNativeVector<rtc::IPAddress>(
@ -147,7 +154,11 @@ NetworkInformation& NetworkInformation::operator=(NetworkInformation&&) =
std::string NetworkInformation::ToString() const {
std::stringstream ss;
ss << "NetInfo[name " << interface_name << "; handle " << handle << "; type "
<< type << "; address";
<< type;
if (type == NETWORK_VPN) {
ss << "; underlying_type_for_vpn " << underlying_type_for_vpn;
}
ss << "; address";
for (const rtc::IPAddress address : ip_addresses) {
ss << " " << address.ToString();
}
@ -316,6 +327,10 @@ void AndroidNetworkMonitor::OnNetworkConnected_w(
RTC_LOG(LS_INFO) << "Network connected: " << network_info.ToString();
adapter_type_by_name_[network_info.interface_name] =
AdapterTypeFromNetworkType(network_info.type);
if (network_info.type == NETWORK_VPN) {
vpn_underlying_adapter_type_by_name_[network_info.interface_name] =
AdapterTypeFromNetworkType(network_info.underlying_type_for_vpn);
}
network_info_by_handle_[network_info.handle] = network_info;
for (const rtc::IPAddress& address : network_info.ip_addresses) {
network_handle_by_address_[address] = network_info.handle;
@ -363,6 +378,15 @@ rtc::AdapterType AndroidNetworkMonitor::GetAdapterType(
return type;
}
rtc::AdapterType AndroidNetworkMonitor::GetVpnUnderlyingAdapterType(
const std::string& if_name) {
auto iter = vpn_underlying_adapter_type_by_name_.find(if_name);
rtc::AdapterType type = (iter == vpn_underlying_adapter_type_by_name_.end())
? rtc::ADAPTER_TYPE_UNKNOWN
: iter->second;
return type;
}
AndroidNetworkMonitorFactory::AndroidNetworkMonitorFactory()
: j_application_context_(nullptr) {}

View File

@ -35,6 +35,7 @@ enum NetworkType {
NETWORK_2G,
NETWORK_UNKNOWN_CELLULAR,
NETWORK_BLUETOOTH,
NETWORK_VPN,
NETWORK_NONE
};
@ -44,6 +45,7 @@ struct NetworkInformation {
std::string interface_name;
NetworkHandle handle;
NetworkType type;
NetworkType underlying_type_for_vpn;
std::vector<rtc::IPAddress> ip_addresses;
NetworkInformation();
@ -73,6 +75,8 @@ class AndroidNetworkMonitor : public rtc::NetworkMonitorBase,
int socket_fd,
const rtc::IPAddress& address) override;
rtc::AdapterType GetAdapterType(const std::string& if_name) override;
rtc::AdapterType GetVpnUnderlyingAdapterType(
const std::string& if_name) override;
void OnNetworkConnected(const NetworkInformation& network_info);
void OnNetworkDisconnected(NetworkHandle network_handle);
// Always expected to be called on the network thread.
@ -100,6 +104,7 @@ class AndroidNetworkMonitor : public rtc::NetworkMonitorBase,
rtc::ThreadChecker thread_checker_;
bool started_ = false;
std::map<std::string, rtc::AdapterType> adapter_type_by_name_;
std::map<std::string, rtc::AdapterType> vpn_underlying_adapter_type_by_name_;
std::map<rtc::IPAddress, NetworkHandle> network_handle_by_address_;
std::map<NetworkHandle, NetworkInformation> network_info_by_handle_;
};