Branch data Line data Source code
1 : : /* GIO - GLib Input, Output and Streaming Library
2 : : *
3 : : * Copyright 2011 Red Hat, Inc.
4 : : *
5 : : * SPDX-License-Identifier: LGPL-2.1-or-later
6 : : *
7 : : * This library is free software; you can redistribute it and/or
8 : : * modify it under the terms of the GNU Lesser General Public
9 : : * License as published by the Free Software Foundation; either
10 : : * version 2.1 of the License, or (at your option) any later version.
11 : : *
12 : : * This library is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 : : * Lesser General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU Lesser General
18 : : * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 : : */
20 : :
21 : : #include "config.h"
22 : :
23 : : #include "gio.h"
24 : :
25 : : /* hack */
26 : : #define GIO_COMPILATION
27 : : #include "gnetworkmonitorbase.h"
28 : :
29 : : #include <string.h>
30 : :
31 : : /* Test data; the GInetAddresses and GInetAddressMasks get filled in
32 : : * in main(). Each address in a TestAddress matches the mask in its
33 : : * corresponding TestMask, and none of them match any of the other
34 : : * masks. The addresses in unmatched don't match any of the masks.
35 : : */
36 : :
37 : : typedef struct {
38 : : const char *string;
39 : : GInetAddress *address;
40 : : } TestAddress;
41 : :
42 : : typedef struct {
43 : : const char *mask_string;
44 : : GInetAddressMask *mask;
45 : : TestAddress *addresses;
46 : : } TestMask;
47 : :
48 : : TestAddress net127addrs[] = {
49 : : { "127.0.0.1", NULL },
50 : : { "127.0.0.2", NULL },
51 : : { "127.0.0.255", NULL },
52 : : { "127.0.1.0", NULL },
53 : : { "127.0.255.0", NULL },
54 : : { "127.0.255.0", NULL },
55 : : { "127.255.255.255", NULL },
56 : : { NULL, NULL }
57 : : };
58 : : TestMask net127 = { "127.0.0.0/8", NULL, net127addrs };
59 : :
60 : : TestAddress net10addrs[] = {
61 : : { "10.0.0.1", NULL },
62 : : { "10.0.0.2", NULL },
63 : : { "10.0.0.255", NULL },
64 : : { NULL, NULL }
65 : : };
66 : : TestMask net10 = { "10.0.0.0/24", NULL, net10addrs };
67 : :
68 : : TestAddress net192addrs[] = {
69 : : { "192.168.0.1", NULL },
70 : : { "192.168.0.2", NULL },
71 : : { "192.168.0.255", NULL },
72 : : { "192.168.1.0", NULL },
73 : : { "192.168.15.0", NULL },
74 : : { NULL, NULL }
75 : : };
76 : : TestMask net192 = { "192.168.0.0/20", NULL, net192addrs };
77 : :
78 : : TestAddress netlocal6addrs[] = {
79 : : { "::1", NULL },
80 : : { NULL, NULL }
81 : : };
82 : : TestMask netlocal6 = { "::1/128", NULL, netlocal6addrs };
83 : :
84 : : TestAddress netfe80addrs[] = {
85 : : { "fe80::", NULL },
86 : : { "fe80::1", NULL },
87 : : { "fe80::21b:77ff:fea2:972a", NULL },
88 : : { NULL, NULL }
89 : : };
90 : : TestMask netfe80 = { "fe80::/64", NULL, netfe80addrs };
91 : :
92 : : TestAddress unmatched[] = {
93 : : { "10.0.1.0", NULL },
94 : : { "10.0.255.0", NULL },
95 : : { "10.255.255.255", NULL },
96 : : { "192.168.16.0", NULL },
97 : : { "192.168.255.0", NULL },
98 : : { "192.169.0.0", NULL },
99 : : { "192.255.255.255", NULL },
100 : : { "::2", NULL },
101 : : { "1::1", NULL },
102 : : { "fe80::1:0:0:0:0", NULL },
103 : : { "fe80:8000::0:0:0:0", NULL },
104 : : { NULL, NULL }
105 : : };
106 : :
107 : : GInetAddressMask *ip4_default, *ip6_default;
108 : :
109 : : static void
110 : 6 : notify_handler (GObject *object,
111 : : GParamSpec *pspec,
112 : : gpointer user_data)
113 : : {
114 : 6 : gboolean *emitted = user_data;
115 : :
116 : 6 : *emitted = TRUE;
117 : 6 : }
118 : :
119 : : static void
120 : 42 : network_changed_handler (GNetworkMonitor *monitor,
121 : : gboolean available,
122 : : gpointer user_data)
123 : : {
124 : 42 : gboolean *emitted = user_data;
125 : :
126 : 42 : *emitted = TRUE;
127 : 42 : }
128 : :
129 : : static void
130 : 50 : assert_signals (GNetworkMonitor *monitor,
131 : : gboolean should_emit_notify,
132 : : gboolean should_emit_network_changed,
133 : : gboolean expected_network_available)
134 : : {
135 : 50 : gboolean emitted_notify = FALSE, emitted_network_changed = FALSE;
136 : : guint h1, h2;
137 : :
138 : 50 : h1 = g_signal_connect (monitor, "notify::network-available",
139 : : G_CALLBACK (notify_handler),
140 : : &emitted_notify);
141 : 50 : h2 = g_signal_connect (monitor, "network-changed",
142 : : G_CALLBACK (network_changed_handler),
143 : : &emitted_network_changed);
144 : :
145 : 50 : g_main_context_iteration (NULL, FALSE);
146 : :
147 : 50 : g_signal_handler_disconnect (monitor, h1);
148 : 50 : g_signal_handler_disconnect (monitor, h2);
149 : :
150 : 50 : g_assert (emitted_notify == should_emit_notify);
151 : 50 : g_assert (emitted_network_changed == should_emit_network_changed);
152 : :
153 : 50 : g_assert (g_network_monitor_get_network_available (monitor) == expected_network_available);
154 : 50 : }
155 : :
156 : : typedef struct {
157 : : GNetworkMonitor *monitor;
158 : : GMainLoop *loop;
159 : : GSocketAddress *sockaddr;
160 : : gboolean should_be_reachable;
161 : : } CanReachData;
162 : :
163 : : static void
164 : 494 : reach_cb (GObject *source,
165 : : GAsyncResult *res,
166 : : gpointer user_data)
167 : : {
168 : 494 : GError *error = NULL;
169 : : gboolean reachable;
170 : 494 : CanReachData *data = user_data;
171 : :
172 : 494 : reachable = g_network_monitor_can_reach_finish (data->monitor, res, &error);
173 : :
174 : 494 : if (data->should_be_reachable)
175 : 266 : g_assert_no_error (error);
176 : : else
177 : : {
178 : 228 : g_assert (error != NULL);
179 : 228 : g_clear_error (&error);
180 : : }
181 : 494 : g_assert (reachable == data->should_be_reachable);
182 : :
183 : 494 : g_main_loop_quit (data->loop);
184 : 494 : }
185 : :
186 : : static gboolean
187 : 494 : test_reach_async (gpointer user_data)
188 : : {
189 : 494 : CanReachData *data = user_data;
190 : :
191 : 741 : g_network_monitor_can_reach_async (data->monitor,
192 : 494 : G_SOCKET_CONNECTABLE (data->sockaddr),
193 : : NULL,
194 : : reach_cb,
195 : 247 : data);
196 : 494 : return G_SOURCE_REMOVE;
197 : : }
198 : :
199 : : static void
200 : 156 : run_tests (GNetworkMonitor *monitor,
201 : : TestAddress *addresses,
202 : : gboolean should_be_reachable)
203 : : {
204 : 156 : GError *error = NULL;
205 : : int i;
206 : : gboolean reachable;
207 : : GSocketAddress *sockaddr;
208 : : CanReachData data;
209 : :
210 : 156 : data.monitor = monitor;
211 : 156 : data.loop = g_main_loop_new (NULL, FALSE);
212 : :
213 : 650 : for (i = 0; addresses[i].address; i++)
214 : : {
215 : 494 : sockaddr = g_inet_socket_address_new (addresses[i].address, 0);
216 : 741 : reachable = g_network_monitor_can_reach (monitor,
217 : 494 : G_SOCKET_CONNECTABLE (sockaddr),
218 : : NULL, &error);
219 : 494 : data.sockaddr = sockaddr;
220 : 494 : data.should_be_reachable = should_be_reachable;
221 : :
222 : 494 : g_idle_add (test_reach_async, &data);
223 : 494 : g_main_loop_run (data.loop);
224 : :
225 : 494 : g_object_unref (sockaddr);
226 : 494 : g_assert_cmpint (reachable, ==, should_be_reachable);
227 : 494 : if (should_be_reachable)
228 : 266 : g_assert_no_error (error);
229 : : else
230 : : {
231 : 228 : g_assert (error != NULL);
232 : 228 : g_clear_error (&error);
233 : : }
234 : 247 : }
235 : :
236 : 156 : g_main_loop_unref (data.loop);
237 : 156 : }
238 : :
239 : : static void
240 : 2 : test_default (void)
241 : : {
242 : : GNetworkMonitor *monitor, *m;
243 : 2 : GError *error = NULL;
244 : :
245 : 2 : m = g_network_monitor_get_default ();
246 : 3 : g_assert (G_IS_NETWORK_MONITOR (m));
247 : :
248 : 2 : monitor = g_object_new (G_TYPE_NETWORK_MONITOR_BASE, NULL);
249 : 2 : g_initable_init (G_INITABLE (monitor), NULL, &error);
250 : 2 : g_assert_no_error (error);
251 : :
252 : : /* In the default configuration, all addresses are reachable */
253 : 2 : run_tests (monitor, net127.addresses, TRUE);
254 : 2 : run_tests (monitor, net10.addresses, TRUE);
255 : 2 : run_tests (monitor, net192.addresses, TRUE);
256 : 2 : run_tests (monitor, netlocal6.addresses, TRUE);
257 : 2 : run_tests (monitor, netfe80.addresses, TRUE);
258 : 2 : run_tests (monitor, unmatched, TRUE);
259 : :
260 : 2 : assert_signals (monitor, FALSE, FALSE, TRUE);
261 : :
262 : 2 : g_object_unref (monitor);
263 : 2 : }
264 : :
265 : : static void
266 : 2 : test_remove_default (void)
267 : : {
268 : : GNetworkMonitor *monitor;
269 : 2 : GError *error = NULL;
270 : :
271 : 2 : monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL);
272 : 2 : g_assert_no_error (error);
273 : 2 : assert_signals (monitor, FALSE, FALSE, TRUE);
274 : :
275 : 3 : g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
276 : 1 : ip4_default);
277 : 2 : assert_signals (monitor, FALSE, TRUE, TRUE);
278 : 3 : g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
279 : 1 : ip6_default);
280 : 2 : assert_signals (monitor, TRUE, TRUE, FALSE);
281 : :
282 : : /* Now nothing should be reachable */
283 : 2 : run_tests (monitor, net127.addresses, FALSE);
284 : 2 : run_tests (monitor, net10.addresses, FALSE);
285 : 2 : run_tests (monitor, net192.addresses, FALSE);
286 : 2 : run_tests (monitor, netlocal6.addresses, FALSE);
287 : 2 : run_tests (monitor, netfe80.addresses, FALSE);
288 : 2 : run_tests (monitor, unmatched, FALSE);
289 : :
290 : 2 : g_object_unref (monitor);
291 : 2 : }
292 : :
293 : : static void
294 : 2 : test_add_networks (void)
295 : : {
296 : : GNetworkMonitor *monitor;
297 : 2 : GError *error = NULL;
298 : :
299 : 2 : monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL);
300 : 2 : g_assert_no_error (error);
301 : 2 : assert_signals (monitor, FALSE, FALSE, TRUE);
302 : :
303 : 3 : g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
304 : 1 : ip4_default);
305 : 2 : assert_signals (monitor, FALSE, TRUE, TRUE);
306 : 3 : g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
307 : 1 : ip6_default);
308 : 2 : assert_signals (monitor, TRUE, TRUE, FALSE);
309 : :
310 : : /* Now add the masks one by one */
311 : :
312 : 3 : g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
313 : 1 : net127.mask);
314 : 2 : assert_signals (monitor, FALSE, TRUE, FALSE);
315 : :
316 : 2 : run_tests (monitor, net127.addresses, TRUE);
317 : 2 : run_tests (monitor, net10.addresses, FALSE);
318 : 2 : run_tests (monitor, net192.addresses, FALSE);
319 : 2 : run_tests (monitor, netlocal6.addresses, FALSE);
320 : 2 : run_tests (monitor, netfe80.addresses, FALSE);
321 : 2 : run_tests (monitor, unmatched, FALSE);
322 : :
323 : 3 : g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
324 : 1 : net10.mask);
325 : 2 : assert_signals (monitor, FALSE, TRUE, FALSE);
326 : 2 : run_tests (monitor, net127.addresses, TRUE);
327 : 2 : run_tests (monitor, net10.addresses, TRUE);
328 : 2 : run_tests (monitor, net192.addresses, FALSE);
329 : 2 : run_tests (monitor, netlocal6.addresses, FALSE);
330 : 2 : run_tests (monitor, netfe80.addresses, FALSE);
331 : 2 : run_tests (monitor, unmatched, FALSE);
332 : :
333 : 3 : g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
334 : 1 : net192.mask);
335 : 2 : assert_signals (monitor, FALSE, TRUE, FALSE);
336 : 2 : run_tests (monitor, net127.addresses, TRUE);
337 : 2 : run_tests (monitor, net10.addresses, TRUE);
338 : 2 : run_tests (monitor, net192.addresses, TRUE);
339 : 2 : run_tests (monitor, netlocal6.addresses, FALSE);
340 : 2 : run_tests (monitor, netfe80.addresses, FALSE);
341 : 2 : run_tests (monitor, unmatched, FALSE);
342 : :
343 : 3 : g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
344 : 1 : netlocal6.mask);
345 : 2 : assert_signals (monitor, FALSE, TRUE, FALSE);
346 : 2 : run_tests (monitor, net127.addresses, TRUE);
347 : 2 : run_tests (monitor, net10.addresses, TRUE);
348 : 2 : run_tests (monitor, net192.addresses, TRUE);
349 : 2 : run_tests (monitor, netlocal6.addresses, TRUE);
350 : 2 : run_tests (monitor, netfe80.addresses, FALSE);
351 : 2 : run_tests (monitor, unmatched, FALSE);
352 : :
353 : 3 : g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
354 : 1 : netfe80.mask);
355 : 2 : assert_signals (monitor, FALSE, TRUE, FALSE);
356 : 2 : run_tests (monitor, net127.addresses, TRUE);
357 : 2 : run_tests (monitor, net10.addresses, TRUE);
358 : 2 : run_tests (monitor, net192.addresses, TRUE);
359 : 2 : run_tests (monitor, netlocal6.addresses, TRUE);
360 : 2 : run_tests (monitor, netfe80.addresses, TRUE);
361 : 2 : run_tests (monitor, unmatched, FALSE);
362 : :
363 : 2 : g_object_unref (monitor);
364 : 2 : }
365 : :
366 : : static void
367 : 2 : test_remove_networks (void)
368 : : {
369 : : GNetworkMonitor *monitor;
370 : 2 : GError *error = NULL;
371 : :
372 : 2 : monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL);
373 : 2 : g_assert_no_error (error);
374 : 2 : assert_signals (monitor, FALSE, FALSE, TRUE);
375 : :
376 : 3 : g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
377 : 1 : ip4_default);
378 : 2 : assert_signals (monitor, FALSE, TRUE, TRUE);
379 : 3 : g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
380 : 1 : ip6_default);
381 : 2 : assert_signals (monitor, TRUE, TRUE, FALSE);
382 : :
383 : : /* First add them */
384 : 3 : g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
385 : 1 : net127.mask);
386 : 2 : assert_signals (monitor, FALSE, TRUE, FALSE);
387 : 3 : g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
388 : 1 : net10.mask);
389 : 2 : assert_signals (monitor, FALSE, TRUE, FALSE);
390 : 3 : g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
391 : 1 : net192.mask);
392 : 2 : assert_signals (monitor, FALSE, TRUE, FALSE);
393 : 3 : g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
394 : 1 : netlocal6.mask);
395 : 2 : assert_signals (monitor, FALSE, TRUE, FALSE);
396 : 3 : g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
397 : 1 : netfe80.mask);
398 : 2 : assert_signals (monitor, FALSE, TRUE, FALSE);
399 : :
400 : 2 : run_tests (monitor, net127.addresses, TRUE);
401 : 2 : run_tests (monitor, net10.addresses, TRUE);
402 : 2 : run_tests (monitor, net192.addresses, TRUE);
403 : 2 : run_tests (monitor, netlocal6.addresses, TRUE);
404 : 2 : run_tests (monitor, netfe80.addresses, TRUE);
405 : 2 : run_tests (monitor, unmatched, FALSE);
406 : :
407 : : /* Now remove them one by one */
408 : 3 : g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
409 : 1 : net127.mask);
410 : 2 : assert_signals (monitor, FALSE, TRUE, FALSE);
411 : 2 : run_tests (monitor, net127.addresses, FALSE);
412 : 2 : run_tests (monitor, net10.addresses, TRUE);
413 : 2 : run_tests (monitor, net192.addresses, TRUE);
414 : 2 : run_tests (monitor, netlocal6.addresses, TRUE);
415 : 2 : run_tests (monitor, netfe80.addresses, TRUE);
416 : 2 : run_tests (monitor, unmatched, FALSE);
417 : :
418 : 3 : g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
419 : 1 : net10.mask);
420 : 2 : assert_signals (monitor, FALSE, TRUE, FALSE);
421 : 2 : run_tests (monitor, net127.addresses, FALSE);
422 : 2 : run_tests (monitor, net10.addresses, FALSE);
423 : 2 : run_tests (monitor, net192.addresses, TRUE);
424 : 2 : run_tests (monitor, netlocal6.addresses, TRUE);
425 : 2 : run_tests (monitor, netfe80.addresses, TRUE);
426 : 2 : run_tests (monitor, unmatched, FALSE);
427 : :
428 : 3 : g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
429 : 1 : net192.mask);
430 : 2 : assert_signals (monitor, FALSE, TRUE, FALSE);
431 : 2 : run_tests (monitor, net127.addresses, FALSE);
432 : 2 : run_tests (monitor, net10.addresses, FALSE);
433 : 2 : run_tests (monitor, net192.addresses, FALSE);
434 : 2 : run_tests (monitor, netlocal6.addresses, TRUE);
435 : 2 : run_tests (monitor, netfe80.addresses, TRUE);
436 : 2 : run_tests (monitor, unmatched, FALSE);
437 : :
438 : 3 : g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
439 : 1 : netlocal6.mask);
440 : 2 : assert_signals (monitor, FALSE, TRUE, FALSE);
441 : 2 : run_tests (monitor, net127.addresses, FALSE);
442 : 2 : run_tests (monitor, net10.addresses, FALSE);
443 : 2 : run_tests (monitor, net192.addresses, FALSE);
444 : 2 : run_tests (monitor, netlocal6.addresses, FALSE);
445 : 2 : run_tests (monitor, netfe80.addresses, TRUE);
446 : 2 : run_tests (monitor, unmatched, FALSE);
447 : :
448 : 3 : g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
449 : 1 : netfe80.mask);
450 : 2 : assert_signals (monitor, FALSE, TRUE, FALSE);
451 : 2 : run_tests (monitor, net127.addresses, FALSE);
452 : 2 : run_tests (monitor, net10.addresses, FALSE);
453 : 2 : run_tests (monitor, net192.addresses, FALSE);
454 : 2 : run_tests (monitor, netlocal6.addresses, FALSE);
455 : 2 : run_tests (monitor, netfe80.addresses, FALSE);
456 : 2 : run_tests (monitor, unmatched, FALSE);
457 : :
458 : 2 : g_object_unref (monitor);
459 : 2 : }
460 : :
461 : :
462 : : static void
463 : 10 : init_test (TestMask *test)
464 : : {
465 : 10 : GError *error = NULL;
466 : : int i;
467 : :
468 : 10 : test->mask = g_inet_address_mask_new_from_string (test->mask_string, &error);
469 : 10 : g_assert_no_error (error);
470 : :
471 : 48 : for (i = 0; test->addresses[i].string; i++)
472 : : {
473 : 38 : test->addresses[i].address = g_inet_address_new_from_string (test->addresses[i].string);
474 : 38 : if (strchr (test->addresses[i].string, ':'))
475 : 8 : g_assert_cmpint (g_inet_address_get_family (test->addresses[i].address), ==, G_SOCKET_FAMILY_IPV6);
476 : : else
477 : 30 : g_assert_cmpint (g_inet_address_get_family (test->addresses[i].address), ==, G_SOCKET_FAMILY_IPV4);
478 : 19 : }
479 : 10 : }
480 : :
481 : : static void
482 : 10 : cleanup_test (TestMask *test)
483 : : {
484 : : int i;
485 : :
486 : 10 : g_object_unref (test->mask);
487 : 48 : for (i = 0; test->addresses[i].string; i++)
488 : 38 : g_object_unref (test->addresses[i].address);
489 : 10 : }
490 : :
491 : : static void
492 : 0 : watch_network_changed (GNetworkMonitor *monitor,
493 : : gboolean available,
494 : : gpointer user_data)
495 : : {
496 : 0 : g_print ("Network is %s\n", available ? "up" : "down");
497 : 0 : }
498 : :
499 : : static void
500 : 0 : watch_connectivity_changed (GNetworkMonitor *monitor,
501 : : GParamSpec *pspec,
502 : : gpointer user_data)
503 : : {
504 : 0 : g_print ("Connectivity is %d\n", g_network_monitor_get_connectivity (monitor));
505 : 0 : }
506 : :
507 : : static void
508 : 0 : watch_metered_changed (GNetworkMonitor *monitor,
509 : : GParamSpec *pspec,
510 : : gpointer user_data)
511 : : {
512 : 0 : g_print ("Metered is %d\n", g_network_monitor_get_network_metered (monitor));
513 : 0 : }
514 : :
515 : : static void
516 : 0 : do_watch_network (void)
517 : : {
518 : 0 : GNetworkMonitor *monitor = g_network_monitor_get_default ();
519 : : GMainLoop *loop;
520 : :
521 : 0 : g_print ("Monitoring via %s\n", g_type_name_from_instance ((GTypeInstance *) monitor));
522 : :
523 : 0 : g_signal_connect (monitor, "network-changed",
524 : : G_CALLBACK (watch_network_changed), NULL);
525 : 0 : g_signal_connect (monitor, "notify::connectivity",
526 : : G_CALLBACK (watch_connectivity_changed), NULL);
527 : 0 : g_signal_connect (monitor, "notify::network-metered",
528 : : G_CALLBACK (watch_metered_changed), NULL);
529 : 0 : watch_network_changed (monitor, g_network_monitor_get_network_available (monitor), NULL);
530 : 0 : watch_connectivity_changed (monitor, NULL, NULL);
531 : 0 : watch_metered_changed (monitor, NULL, NULL);
532 : :
533 : 0 : loop = g_main_loop_new (NULL, FALSE);
534 : 0 : g_main_loop_run (loop);
535 : 0 : }
536 : :
537 : : #ifdef HAVE_NETLINK
538 : : static void
539 : 2 : can_reach_loopback_cb (GObject *source,
540 : : GAsyncResult *result,
541 : : gpointer user_data)
542 : : {
543 : 2 : GMainLoop *loop = user_data;
544 : 2 : GError *error = NULL;
545 : : gboolean reachable;
546 : :
547 : 2 : reachable = g_network_monitor_can_reach_finish (G_NETWORK_MONITOR (source),
548 : : result, &error);
549 : 2 : g_assert_no_error (error);
550 : 2 : g_assert_true (reachable);
551 : 2 : g_main_loop_quit (loop);
552 : 2 : }
553 : :
554 : : /* Assert that @address is reachable both synchronously and asynchronously (the
555 : : * async path runs the route lookup on a worker thread). */
556 : : static void
557 : 2 : assert_netlink_can_reach (GNetworkMonitor *monitor,
558 : : const char *address)
559 : : {
560 : : GSocketAddress *sockaddr;
561 : : GMainLoop *loop;
562 : 2 : GError *error = NULL;
563 : : gboolean reachable;
564 : :
565 : 2 : sockaddr = g_inet_socket_address_new_from_string (address, 0);
566 : :
567 : 2 : reachable = g_network_monitor_can_reach (monitor, G_SOCKET_CONNECTABLE (sockaddr),
568 : : NULL, &error);
569 : 2 : g_assert_no_error (error);
570 : 2 : g_assert_true (reachable);
571 : :
572 : 2 : loop = g_main_loop_new (NULL, FALSE);
573 : 2 : g_network_monitor_can_reach_async (monitor, G_SOCKET_CONNECTABLE (sockaddr),
574 : : NULL, can_reach_loopback_cb, loop);
575 : 2 : g_main_loop_run (loop);
576 : 2 : g_main_loop_unref (loop);
577 : :
578 : 2 : g_object_unref (sockaddr);
579 : 2 : }
580 : : #endif
581 : :
582 : : /* The netlink backend (forced via GIO_USE_NETWORK_MONITOR in main()) resolves
583 : : * reachability with a per-destination route lookup. A loopback address always
584 : : * has a route, so it must be reachable. Skipped if netlink was not built, or if
585 : : * the backend couldn't be selected (e.g. no PF_NETLINK). */
586 : : static void
587 : 2 : test_netlink_can_reach_loopback (void)
588 : : {
589 : : #ifndef HAVE_NETLINK
590 : 1 : g_test_skip ("Netlink is unavailable");
591 : : #else
592 : 1 : GNetworkMonitor *monitor = g_network_monitor_get_default ();
593 : :
594 : 1 : if (g_strcmp0 (G_OBJECT_TYPE_NAME (monitor), "GNetworkMonitorNetlink") != 0)
595 : : {
596 : 0 : g_test_skip ("netlink backend unavailable");
597 : 0 : return;
598 : : }
599 : :
600 : 1 : assert_netlink_can_reach (monitor, "127.0.0.1");
601 : : #endif
602 : 1 : }
603 : :
604 : : static void
605 : 2 : test_netlink_can_reach_loopback6 (void)
606 : : {
607 : : #ifndef HAVE_NETLINK
608 : 1 : g_test_skip ("Netlink is unavailable");
609 : : #else
610 : 1 : GNetworkMonitor *monitor = g_network_monitor_get_default ();
611 : :
612 : 1 : if (g_strcmp0 (G_OBJECT_TYPE_NAME (monitor), "GNetworkMonitorNetlink") != 0)
613 : : {
614 : 0 : g_test_skip ("netlink backend unavailable");
615 : 0 : return;
616 : : }
617 : :
618 : 1 : assert_netlink_can_reach (monitor, "::1");
619 : : #endif
620 : 1 : }
621 : :
622 : : int
623 : 2 : main (int argc, char **argv)
624 : : {
625 : : int ret;
626 : :
627 : 2 : if (argc == 2 && !strcmp (argv[1], "--watch"))
628 : : {
629 : 0 : do_watch_network ();
630 : 0 : return 0;
631 : : }
632 : :
633 : 2 : g_test_init (&argc, &argv, NULL);
634 : :
635 : : /* GNetworkMonitor will resolve addresses through a proxy if one is set and a
636 : : * GIO module is available to handle it. In these tests we deliberately
637 : : * change the idea of a reachable network to exclude the proxy, which will
638 : : * lead to negative results. We're not trying to test the proxy-resolving
639 : : * functionality (that would be for e.g. glib-networking's testsuite), so
640 : : * let's just use the dummy proxy resolver, which always pretends the
641 : : * passed-in URL is directly resolvable.
642 : : */
643 : 2 : g_setenv ("GIO_USE_PROXY_RESOLVER", "dummy", TRUE);
644 : :
645 : : #ifdef HAVE_NETLINK
646 : : /* Force the netlink backend so test_netlink_can_reach_loopback exercises it.
647 : : * The other tests use the base class directly and are backend-agnostic. */
648 : 1 : g_setenv ("GIO_USE_NETWORK_MONITOR", "netlink", TRUE);
649 : : #endif
650 : :
651 : 2 : init_test (&net127);
652 : 2 : init_test (&net10);
653 : 2 : init_test (&net192);
654 : 2 : init_test (&netlocal6);
655 : 2 : init_test (&netfe80);
656 : 2 : ip4_default = g_inet_address_mask_new_from_string ("0.0.0.0/0", NULL);
657 : 2 : ip6_default = g_inet_address_mask_new_from_string ("::/0", NULL);
658 : :
659 : 2 : g_test_add_func ("/network-monitor/default", test_default);
660 : 2 : g_test_add_func ("/network-monitor/remove_default", test_remove_default);
661 : 2 : g_test_add_func ("/network-monitor/add_networks", test_add_networks);
662 : 2 : g_test_add_func ("/network-monitor/remove_networks", test_remove_networks);
663 : 2 : g_test_add_func ("/network-monitor/netlink/can-reach-loopback", test_netlink_can_reach_loopback);
664 : 2 : g_test_add_func ("/network-monitor/netlink/can-reach-loopback6", test_netlink_can_reach_loopback6);
665 : :
666 : 2 : ret = g_test_run ();
667 : :
668 : 2 : cleanup_test (&net127);
669 : 2 : cleanup_test (&net10);
670 : 2 : cleanup_test (&net192);
671 : 2 : cleanup_test (&netlocal6);
672 : 2 : cleanup_test (&netfe80);
673 : 2 : g_object_unref (ip4_default);
674 : 2 : g_object_unref (ip6_default);
675 : :
676 : 2 : return ret;
677 : 1 : }
|