• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "sdk/android/src/jni/android_network_monitor.h"
12 
13 #include "rtc_base/ip_address.h"
14 #include "rtc_base/logging.h"
15 #include "rtc_base/thread.h"
16 #include "sdk/android/native_unittests/application_context_provider.h"
17 #include "sdk/android/src/jni/jni_helpers.h"
18 #include "test/gtest.h"
19 #include "test/scoped_key_value_config.h"
20 
21 namespace webrtc {
22 namespace test {
23 static const uint32_t kTestIpv4Address = 0xC0A80011;  // 192.168.0.17
24 // The following two ipv6 addresses only diff by the last 64 bits.
25 static const char kTestIpv6Address1[] = "2a00:8a00:a000:1190:0000:0001:000:252";
26 static const char kTestIpv6Address2[] = "2a00:8a00:a000:1190:0000:0002:000:253";
27 
28 static const char kTestIfName1[] = "testlan0";
29 static const char kTestIfName1V4[] = "v4-testlan0";
30 static const char kTestIfName2[] = "testnet0";
31 
CreateNetworkInformation(const std::string & interface_name,jni::NetworkHandle network_handle,const rtc::IPAddress & ip_address)32 jni::NetworkInformation CreateNetworkInformation(
33     const std::string& interface_name,
34     jni::NetworkHandle network_handle,
35     const rtc::IPAddress& ip_address) {
36   jni::NetworkInformation net_info;
37   net_info.interface_name = interface_name;
38   net_info.handle = network_handle;
39   net_info.type = jni::NETWORK_WIFI;
40   net_info.ip_addresses.push_back(ip_address);
41   return net_info;
42 }
43 
GetIpAddressFromIpv6String(const std::string & str)44 rtc::IPAddress GetIpAddressFromIpv6String(const std::string& str) {
45   rtc::IPAddress ipv6;
46   RTC_CHECK(rtc::IPFromString(str, &ipv6));
47   return ipv6;
48 }
49 
50 class AndroidNetworkMonitorTest : public ::testing::Test {
51  public:
AndroidNetworkMonitorTest()52   AndroidNetworkMonitorTest() {
53     JNIEnv* env = AttachCurrentThreadIfNeeded();
54     ScopedJavaLocalRef<jobject> context = test::GetAppContextForTest(env);
55     network_monitor_ = std::make_unique<jni::AndroidNetworkMonitor>(
56         env, context, field_trials_);
57   }
58 
SetUp()59   void SetUp() override {
60     // Reset network monitor states.
61     network_monitor_->Stop();
62   }
63 
TearDown()64   void TearDown() override {
65     // The network monitor must be stopped, before it is destructed.
66     network_monitor_->Stop();
67   }
68 
Disconnect(jni::NetworkHandle handle)69   void Disconnect(jni::NetworkHandle handle) {
70     network_monitor_->OnNetworkDisconnected_n(handle);
71   }
72 
73  protected:
74   test::ScopedKeyValueConfig field_trials_;
75   rtc::AutoThread main_thread_;
76   std::unique_ptr<jni::AndroidNetworkMonitor> network_monitor_;
77 };
78 
TEST_F(AndroidNetworkMonitorTest,TestFindNetworkHandleUsingIpv4Address)79 TEST_F(AndroidNetworkMonitorTest, TestFindNetworkHandleUsingIpv4Address) {
80   jni::NetworkHandle ipv4_handle = 100;
81   rtc::IPAddress ipv4_address(kTestIpv4Address);
82   jni::NetworkInformation net_info =
83       CreateNetworkInformation(kTestIfName1, ipv4_handle, ipv4_address);
84   std::vector<jni::NetworkInformation> net_infos(1, net_info);
85   network_monitor_->SetNetworkInfos(net_infos);
86 
87   auto network_handle =
88       network_monitor_->FindNetworkHandleFromAddressOrName(ipv4_address, "");
89 
90   ASSERT_TRUE(network_handle.has_value());
91   EXPECT_EQ(ipv4_handle, *network_handle);
92 }
93 
TEST_F(AndroidNetworkMonitorTest,TestFindNetworkHandleUsingFullIpv6Address)94 TEST_F(AndroidNetworkMonitorTest, TestFindNetworkHandleUsingFullIpv6Address) {
95   jni::NetworkHandle ipv6_handle = 200;
96   rtc::IPAddress ipv6_address1 = GetIpAddressFromIpv6String(kTestIpv6Address1);
97   rtc::IPAddress ipv6_address2 = GetIpAddressFromIpv6String(kTestIpv6Address2);
98   // Set up an IPv6 network.
99   jni::NetworkInformation net_info =
100       CreateNetworkInformation(kTestIfName1, ipv6_handle, ipv6_address1);
101   std::vector<jni::NetworkInformation> net_infos(1, net_info);
102   network_monitor_->OnNetworkConnected_n(net_info);
103 
104   auto network_handle1 =
105       network_monitor_->FindNetworkHandleFromAddressOrName(ipv6_address1, "");
106   auto network_handle2 =
107       network_monitor_->FindNetworkHandleFromAddressOrName(ipv6_address2, "");
108 
109   ASSERT_TRUE(network_handle1.has_value());
110   EXPECT_EQ(ipv6_handle, *network_handle1);
111   EXPECT_TRUE(!network_handle2);
112 }
113 
TEST_F(AndroidNetworkMonitorTest,TestFindNetworkHandleIgnoringIpv6TemporaryPart)114 TEST_F(AndroidNetworkMonitorTest,
115        TestFindNetworkHandleIgnoringIpv6TemporaryPart) {
116   ScopedKeyValueConfig field_trials(
117       field_trials_,
118       "WebRTC-FindNetworkHandleWithoutIpv6TemporaryPart/Enabled/");
119   // Start() updates the states introduced by the field trial.
120   network_monitor_->Start();
121   jni::NetworkHandle ipv6_handle = 200;
122   rtc::IPAddress ipv6_address1 = GetIpAddressFromIpv6String(kTestIpv6Address1);
123   rtc::IPAddress ipv6_address2 = GetIpAddressFromIpv6String(kTestIpv6Address2);
124   // Set up an IPv6 network.
125   jni::NetworkInformation net_info =
126       CreateNetworkInformation(kTestIfName1, ipv6_handle, ipv6_address1);
127   std::vector<jni::NetworkInformation> net_infos(1, net_info);
128   network_monitor_->OnNetworkConnected_n(net_info);
129 
130   auto network_handle1 =
131       network_monitor_->FindNetworkHandleFromAddressOrName(ipv6_address1, "");
132   auto network_handle2 =
133       network_monitor_->FindNetworkHandleFromAddressOrName(ipv6_address2, "");
134 
135   ASSERT_TRUE(network_handle1.has_value());
136   EXPECT_EQ(ipv6_handle, *network_handle1);
137   ASSERT_TRUE(network_handle2.has_value());
138   EXPECT_EQ(ipv6_handle, *network_handle2);
139 }
140 
TEST_F(AndroidNetworkMonitorTest,TestFindNetworkHandleUsingIfName)141 TEST_F(AndroidNetworkMonitorTest, TestFindNetworkHandleUsingIfName) {
142   // Start() updates the states introduced by the field trial.
143   network_monitor_->Start();
144   jni::NetworkHandle ipv6_handle = 200;
145   rtc::IPAddress ipv6_address1 = GetIpAddressFromIpv6String(kTestIpv6Address1);
146 
147   // Set up an IPv6 network.
148   jni::NetworkInformation net_info =
149       CreateNetworkInformation(kTestIfName1, ipv6_handle, ipv6_address1);
150   std::vector<jni::NetworkInformation> net_infos(1, net_info);
151   network_monitor_->OnNetworkConnected_n(net_info);
152 
153   rtc::IPAddress ipv4_address(kTestIpv4Address);
154 
155   // Search using ip address only...
156   auto network_handle1 =
157       network_monitor_->FindNetworkHandleFromAddressOrName(ipv4_address, "");
158 
159   // Search using ip address AND if_name (for typical ipv4 over ipv6 tunnel).
160   auto network_handle2 = network_monitor_->FindNetworkHandleFromAddressOrName(
161       ipv4_address, kTestIfName1V4);
162 
163   ASSERT_FALSE(network_handle1.has_value());
164   ASSERT_TRUE(network_handle2.has_value());
165   EXPECT_EQ(ipv6_handle, *network_handle2);
166 }
167 
TEST_F(AndroidNetworkMonitorTest,TestUnderlyingVpnType)168 TEST_F(AndroidNetworkMonitorTest, TestUnderlyingVpnType) {
169   ScopedKeyValueConfig field_trials(field_trials_,
170                                     "WebRTC-BindUsingInterfaceName/Enabled/");
171   jni::NetworkHandle ipv4_handle = 100;
172   rtc::IPAddress ipv4_address(kTestIpv4Address);
173   jni::NetworkInformation net_info =
174       CreateNetworkInformation(kTestIfName1, ipv4_handle, ipv4_address);
175   net_info.type = jni::NETWORK_VPN;
176   net_info.underlying_type_for_vpn = jni::NETWORK_WIFI;
177   network_monitor_->OnNetworkConnected_n(net_info);
178 
179   EXPECT_EQ(rtc::ADAPTER_TYPE_WIFI,
180             network_monitor_->GetInterfaceInfo(kTestIfName1V4)
181                 .underlying_type_for_vpn);
182 }
183 
184 // Verify that Disconnect makes interface unavailable.
TEST_F(AndroidNetworkMonitorTest,Disconnect)185 TEST_F(AndroidNetworkMonitorTest, Disconnect) {
186   network_monitor_->Start();
187 
188   jni::NetworkHandle ipv4_handle = 100;
189   rtc::IPAddress ipv4_address(kTestIpv4Address);
190   jni::NetworkInformation net_info =
191       CreateNetworkInformation(kTestIfName1, ipv4_handle, ipv4_address);
192   net_info.type = jni::NETWORK_WIFI;
193   network_monitor_->OnNetworkConnected_n(net_info);
194 
195   EXPECT_TRUE(network_monitor_->GetInterfaceInfo(kTestIfName1).available);
196   EXPECT_TRUE(
197       network_monitor_
198           ->FindNetworkHandleFromAddressOrName(ipv4_address, kTestIfName1V4)
199           .has_value());
200   EXPECT_EQ(network_monitor_->GetInterfaceInfo(kTestIfName1V4).adapter_type,
201             rtc::ADAPTER_TYPE_WIFI);
202 
203   // Check that values are reset on disconnect().
204   Disconnect(ipv4_handle);
205   EXPECT_FALSE(network_monitor_->GetInterfaceInfo(kTestIfName1).available);
206   EXPECT_FALSE(
207       network_monitor_
208           ->FindNetworkHandleFromAddressOrName(ipv4_address, kTestIfName1V4)
209           .has_value());
210   EXPECT_EQ(network_monitor_->GetInterfaceInfo(kTestIfName1V4).adapter_type,
211             rtc::ADAPTER_TYPE_UNKNOWN);
212 }
213 
214 // Verify that Stop() resets all caches.
TEST_F(AndroidNetworkMonitorTest,Reset)215 TEST_F(AndroidNetworkMonitorTest, Reset) {
216   network_monitor_->Start();
217 
218   jni::NetworkHandle ipv4_handle = 100;
219   rtc::IPAddress ipv4_address(kTestIpv4Address);
220   jni::NetworkInformation net_info =
221       CreateNetworkInformation(kTestIfName1, ipv4_handle, ipv4_address);
222   net_info.type = jni::NETWORK_WIFI;
223   network_monitor_->OnNetworkConnected_n(net_info);
224 
225   EXPECT_TRUE(network_monitor_->GetInterfaceInfo(kTestIfName1).available);
226   EXPECT_TRUE(
227       network_monitor_
228           ->FindNetworkHandleFromAddressOrName(ipv4_address, kTestIfName1V4)
229           .has_value());
230   EXPECT_EQ(network_monitor_->GetInterfaceInfo(kTestIfName1V4).adapter_type,
231             rtc::ADAPTER_TYPE_WIFI);
232 
233   // Check that values are reset on Stop().
234   network_monitor_->Stop();
235   EXPECT_FALSE(network_monitor_->GetInterfaceInfo(kTestIfName1).available);
236   EXPECT_FALSE(
237       network_monitor_
238           ->FindNetworkHandleFromAddressOrName(ipv4_address, kTestIfName1V4)
239           .has_value());
240   EXPECT_EQ(network_monitor_->GetInterfaceInfo(kTestIfName1V4).adapter_type,
241             rtc::ADAPTER_TYPE_UNKNOWN);
242 }
243 
TEST_F(AndroidNetworkMonitorTest,DuplicateIfname)244 TEST_F(AndroidNetworkMonitorTest, DuplicateIfname) {
245   network_monitor_->Start();
246 
247   jni::NetworkHandle ipv4_handle = 100;
248   rtc::IPAddress ipv4_address(kTestIpv4Address);
249   jni::NetworkInformation net_info1 =
250       CreateNetworkInformation(kTestIfName1, ipv4_handle, ipv4_address);
251   net_info1.type = jni::NETWORK_WIFI;
252 
253   jni::NetworkHandle ipv6_handle = 101;
254   rtc::IPAddress ipv6_address = GetIpAddressFromIpv6String(kTestIpv6Address1);
255   jni::NetworkInformation net_info2 =
256       CreateNetworkInformation(kTestIfName1, ipv6_handle, ipv6_address);
257   net_info2.type = jni::NETWORK_UNKNOWN_CELLULAR;
258 
259   network_monitor_->OnNetworkConnected_n(net_info1);
260   network_monitor_->OnNetworkConnected_n(net_info2);
261 
262   // The last added.
263   EXPECT_TRUE(network_monitor_->GetInterfaceInfo(kTestIfName1).available);
264   EXPECT_EQ(network_monitor_->GetInterfaceInfo(kTestIfName1V4).adapter_type,
265             rtc::ADAPTER_TYPE_CELLULAR);
266 
267   // But both IP addresses are still searchable.
268   EXPECT_EQ(
269       *network_monitor_->FindNetworkHandleFromAddressOrName(ipv4_address, ""),
270       ipv4_handle);
271   EXPECT_EQ(
272       *network_monitor_->FindNetworkHandleFromAddressOrName(ipv6_address, ""),
273       ipv6_handle);
274 }
275 
TEST_F(AndroidNetworkMonitorTest,DuplicateIfnameDisconnectOwner)276 TEST_F(AndroidNetworkMonitorTest, DuplicateIfnameDisconnectOwner) {
277   network_monitor_->Start();
278 
279   jni::NetworkHandle ipv4_handle = 100;
280   rtc::IPAddress ipv4_address(kTestIpv4Address);
281   jni::NetworkInformation net_info1 =
282       CreateNetworkInformation(kTestIfName1, ipv4_handle, ipv4_address);
283   net_info1.type = jni::NETWORK_WIFI;
284 
285   jni::NetworkHandle ipv6_handle = 101;
286   rtc::IPAddress ipv6_address = GetIpAddressFromIpv6String(kTestIpv6Address1);
287   jni::NetworkInformation net_info2 =
288       CreateNetworkInformation(kTestIfName1, ipv6_handle, ipv6_address);
289   net_info2.type = jni::NETWORK_UNKNOWN_CELLULAR;
290 
291   network_monitor_->OnNetworkConnected_n(net_info1);
292   network_monitor_->OnNetworkConnected_n(net_info2);
293 
294   // The last added.
295   EXPECT_TRUE(network_monitor_->GetInterfaceInfo(kTestIfName1).available);
296   EXPECT_EQ(network_monitor_->GetInterfaceInfo(kTestIfName1V4).adapter_type,
297             rtc::ADAPTER_TYPE_CELLULAR);
298 
299   Disconnect(ipv6_handle);
300 
301   // We should now find ipv4_handle.
302   EXPECT_TRUE(network_monitor_->GetInterfaceInfo(kTestIfName1).available);
303   EXPECT_EQ(network_monitor_->GetInterfaceInfo(kTestIfName1V4).adapter_type,
304             rtc::ADAPTER_TYPE_WIFI);
305 }
306 
TEST_F(AndroidNetworkMonitorTest,DuplicateIfnameDisconnectNonOwner)307 TEST_F(AndroidNetworkMonitorTest, DuplicateIfnameDisconnectNonOwner) {
308   network_monitor_->Start();
309 
310   jni::NetworkHandle ipv4_handle = 100;
311   rtc::IPAddress ipv4_address(kTestIpv4Address);
312   jni::NetworkInformation net_info1 =
313       CreateNetworkInformation(kTestIfName1, ipv4_handle, ipv4_address);
314   net_info1.type = jni::NETWORK_WIFI;
315 
316   jni::NetworkHandle ipv6_handle = 101;
317   rtc::IPAddress ipv6_address = GetIpAddressFromIpv6String(kTestIpv6Address1);
318   jni::NetworkInformation net_info2 =
319       CreateNetworkInformation(kTestIfName1, ipv6_handle, ipv6_address);
320   net_info2.type = jni::NETWORK_UNKNOWN_CELLULAR;
321 
322   network_monitor_->OnNetworkConnected_n(net_info1);
323   network_monitor_->OnNetworkConnected_n(net_info2);
324 
325   // The last added.
326   EXPECT_TRUE(network_monitor_->GetInterfaceInfo(kTestIfName1).available);
327   EXPECT_EQ(network_monitor_->GetInterfaceInfo(kTestIfName1).adapter_type,
328             rtc::ADAPTER_TYPE_CELLULAR);
329 
330   Disconnect(ipv4_handle);
331 
332   // We should still find ipv6 network.
333   EXPECT_TRUE(network_monitor_->GetInterfaceInfo(kTestIfName1).available);
334   EXPECT_EQ(network_monitor_->GetInterfaceInfo(kTestIfName1V4).adapter_type,
335             rtc::ADAPTER_TYPE_CELLULAR);
336 }
337 
TEST_F(AndroidNetworkMonitorTest,ReconnectWithoutDisconnect)338 TEST_F(AndroidNetworkMonitorTest, ReconnectWithoutDisconnect) {
339   network_monitor_->Start();
340 
341   jni::NetworkHandle ipv4_handle = 100;
342   rtc::IPAddress ipv4_address(kTestIpv4Address);
343   jni::NetworkInformation net_info1 =
344       CreateNetworkInformation(kTestIfName1, ipv4_handle, ipv4_address);
345   net_info1.type = jni::NETWORK_WIFI;
346 
347   rtc::IPAddress ipv6_address = GetIpAddressFromIpv6String(kTestIpv6Address1);
348   jni::NetworkInformation net_info2 =
349       CreateNetworkInformation(kTestIfName2, ipv4_handle, ipv6_address);
350   net_info2.type = jni::NETWORK_UNKNOWN_CELLULAR;
351 
352   network_monitor_->OnNetworkConnected_n(net_info1);
353   network_monitor_->OnNetworkConnected_n(net_info2);
354 
355   // Only last one should still be there!
356   EXPECT_TRUE(network_monitor_->GetInterfaceInfo(kTestIfName2).available);
357   EXPECT_EQ(network_monitor_->GetInterfaceInfo(kTestIfName2).adapter_type,
358             rtc::ADAPTER_TYPE_CELLULAR);
359 
360   EXPECT_FALSE(network_monitor_->GetInterfaceInfo(kTestIfName1).available);
361   EXPECT_EQ(network_monitor_->GetInterfaceInfo(kTestIfName1).adapter_type,
362             rtc::ADAPTER_TYPE_UNKNOWN);
363 
364   Disconnect(ipv4_handle);
365 
366   // Should be empty!
367   EXPECT_FALSE(network_monitor_->GetInterfaceInfo(kTestIfName2).available);
368   EXPECT_EQ(network_monitor_->GetInterfaceInfo(kTestIfName2).adapter_type,
369             rtc::ADAPTER_TYPE_UNKNOWN);
370   EXPECT_FALSE(network_monitor_->GetInterfaceInfo(kTestIfName1).available);
371   EXPECT_EQ(network_monitor_->GetInterfaceInfo(kTestIfName1).adapter_type,
372             rtc::ADAPTER_TYPE_UNKNOWN);
373 }
374 
375 }  // namespace test
376 }  // namespace webrtc
377