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