hook gvariant vectors up to kdbus
[platform/upstream/glib.git] / gio / tests / network-monitor.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright 2011 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #include "gio.h"
20
21 /* hack */
22 #define GIO_COMPILATION
23 #include "gnetworkmonitorbase.h"
24
25 #include <string.h>
26
27 /* Test data; the GInetAddresses and GInetAddressMasks get filled in
28  * in main(). Each address in a TestAddress matches the mask in its
29  * corresponding TestMask, and none of them match any of the other
30  * masks. The addresses in unmatched don't match any of the masks.
31  */
32
33 typedef struct {
34   const char *string;
35   GInetAddress *address;
36 } TestAddress;
37
38 typedef struct {
39   const char *mask_string;
40   GInetAddressMask *mask;
41   TestAddress *addresses;
42 } TestMask;
43
44 TestAddress net127addrs[] = {
45   { "127.0.0.1", NULL },
46   { "127.0.0.2", NULL },
47   { "127.0.0.255", NULL },
48   { "127.0.1.0", NULL },
49   { "127.0.255.0", NULL },
50   { "127.0.255.0", NULL },
51   { "127.255.255.255", NULL },
52   { NULL, NULL }
53 };
54 TestMask net127 = { "127.0.0.0/8", NULL, net127addrs };
55
56 TestAddress net10addrs[] = {
57   { "10.0.0.1", NULL },
58   { "10.0.0.2", NULL },
59   { "10.0.0.255", NULL },
60   { NULL, NULL }
61 };
62 TestMask net10 = { "10.0.0.0/24", NULL, net10addrs };
63
64 TestAddress net192addrs[] = {
65   { "192.168.0.1", NULL },
66   { "192.168.0.2", NULL },
67   { "192.168.0.255", NULL },
68   { "192.168.1.0", NULL },
69   { "192.168.15.0", NULL },
70   { NULL, NULL }
71 };
72 TestMask net192 = { "192.168.0.0/20", NULL, net192addrs };
73
74 TestAddress netlocal6addrs[] = {
75   { "::1", NULL },
76   { NULL, NULL }
77 };
78 TestMask netlocal6 = { "::1/128", NULL, netlocal6addrs };
79
80 TestAddress netfe80addrs[] = {
81   { "fe80::", NULL },
82   { "fe80::1", NULL },
83   { "fe80::21b:77ff:fea2:972a", NULL },
84   { NULL, NULL }
85 };
86 TestMask netfe80 = { "fe80::/64", NULL, netfe80addrs };
87
88 TestAddress unmatched[] = {
89   { "10.0.1.0", NULL },
90   { "10.0.255.0", NULL },
91   { "10.255.255.255", NULL },
92   { "192.168.16.0", NULL },
93   { "192.168.255.0", NULL },
94   { "192.169.0.0", NULL },
95   { "192.255.255.255", NULL },
96   { "::2", NULL },
97   { "1::1", NULL },
98   { "fe80::1:0:0:0:0", NULL },
99   { "fe80:8000::0:0:0:0", NULL },
100   { NULL, NULL }
101 };
102
103 GInetAddressMask *ip4_default, *ip6_default;
104
105 static void
106 notify_handler (GObject    *object,
107                 GParamSpec *pspec,
108                 gpointer    user_data)
109 {
110   gboolean *emitted = user_data;
111
112   *emitted = TRUE;
113 }
114
115 static void
116 network_changed_handler (GNetworkMonitor *monitor,
117                          gboolean         available,
118                          gpointer         user_data)
119 {
120   gboolean *emitted = user_data;
121
122   *emitted = TRUE;
123 }
124
125 static void
126 assert_signals (GNetworkMonitor *monitor,
127                 gboolean         should_emit_notify,
128                 gboolean         should_emit_network_changed,
129                 gboolean         expected_network_available)
130 {
131   gboolean emitted_notify = FALSE, emitted_network_changed = FALSE;
132   guint h1, h2;
133
134   h1 = g_signal_connect (monitor, "notify::network-available",
135                          G_CALLBACK (notify_handler),
136                          &emitted_notify);
137   h2 = g_signal_connect (monitor, "network-changed",
138                          G_CALLBACK (network_changed_handler),
139                          &emitted_network_changed);
140
141   g_main_context_iteration (NULL, FALSE);
142
143   g_signal_handler_disconnect (monitor, h1);
144   g_signal_handler_disconnect (monitor, h2);
145
146   g_assert (emitted_notify == should_emit_notify);
147   g_assert (emitted_network_changed == should_emit_network_changed);
148
149   g_assert (g_network_monitor_get_network_available (monitor) == expected_network_available);
150 }
151
152 typedef struct {
153   GNetworkMonitor *monitor;
154   GMainLoop       *loop;
155   GSocketAddress  *sockaddr;
156   gboolean         should_be_reachable;
157 } CanReachData;
158
159 static void
160 reach_cb (GObject      *source,
161           GAsyncResult *res,
162           gpointer      user_data)
163 {
164   GError *error = NULL;
165   gboolean reachable;
166   CanReachData *data = user_data;
167
168   reachable = g_network_monitor_can_reach_finish (data->monitor, res, &error);
169
170   if (data->should_be_reachable)
171     g_assert_no_error (error);
172   else
173     {
174       g_assert (error != NULL);
175       g_clear_error (&error);
176     }
177   g_assert (reachable == data->should_be_reachable);
178
179   g_main_loop_quit (data->loop);
180 }
181
182 static gboolean
183 test_reach_async (gpointer user_data)
184 {
185   CanReachData *data = user_data;
186
187   g_network_monitor_can_reach_async (data->monitor,
188                                      G_SOCKET_CONNECTABLE (data->sockaddr),
189                                      NULL,
190                                      reach_cb,
191                                      data);
192   return G_SOURCE_REMOVE;
193 }
194
195 static void
196 run_tests (GNetworkMonitor *monitor,
197            TestAddress     *addresses,
198            gboolean         should_be_reachable)
199 {
200   GError *error = NULL;
201   int i;
202   gboolean reachable;
203   GSocketAddress *sockaddr;
204   CanReachData data;
205
206   data.monitor = monitor;
207   data.loop = g_main_loop_new (NULL, FALSE);
208
209   for (i = 0; addresses[i].address; i++)
210     {
211       sockaddr = g_inet_socket_address_new (addresses[i].address, 0);
212       reachable = g_network_monitor_can_reach (monitor,
213                                                G_SOCKET_CONNECTABLE (sockaddr),
214                                                NULL, &error);
215       data.sockaddr = sockaddr;
216       data.should_be_reachable = should_be_reachable;
217
218       g_idle_add (test_reach_async, &data);
219       g_main_loop_run (data.loop);
220
221       g_object_unref (sockaddr);
222       g_assert_cmpint (reachable, ==, should_be_reachable);
223       if (should_be_reachable)
224         g_assert_no_error (error);
225       else
226         {
227           g_assert (error != NULL);
228           g_clear_error (&error);
229         }
230     }
231
232   g_main_loop_unref (data.loop);
233 }
234
235 static void
236 test_default (void)
237 {
238   GNetworkMonitor *monitor, *m;
239   GError *error = NULL;
240
241   m = g_network_monitor_get_default ();
242   g_assert (G_IS_NETWORK_MONITOR (m));
243
244   monitor = g_initable_newv (G_TYPE_NETWORK_MONITOR_BASE, 0, NULL, NULL,  &error);
245   g_assert_no_error (error);
246
247   /* In the default configuration, all addresses are reachable */
248   run_tests (monitor, net127.addresses, TRUE);
249   run_tests (monitor, net10.addresses, TRUE);
250   run_tests (monitor, net192.addresses, TRUE);
251   run_tests (monitor, netlocal6.addresses, TRUE);
252   run_tests (monitor, netfe80.addresses, TRUE);
253   run_tests (monitor, unmatched, TRUE);
254
255   assert_signals (monitor, FALSE, FALSE, TRUE);
256
257   g_object_unref (monitor);
258 }
259
260 static void
261 test_remove_default (void)
262 {
263   GNetworkMonitor *monitor;
264   GError *error = NULL;
265
266   monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL);
267   g_assert_no_error (error);
268   assert_signals (monitor, FALSE, FALSE, TRUE);
269
270   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
271                                          ip4_default);
272   assert_signals (monitor, FALSE, TRUE, TRUE);
273   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
274                                          ip6_default);
275   assert_signals (monitor, TRUE, TRUE, FALSE);
276
277   /* Now nothing should be reachable */
278   run_tests (monitor, net127.addresses, FALSE);
279   run_tests (monitor, net10.addresses, FALSE);
280   run_tests (monitor, net192.addresses, FALSE);
281   run_tests (monitor, netlocal6.addresses, FALSE);
282   run_tests (monitor, netfe80.addresses, FALSE);
283   run_tests (monitor, unmatched, FALSE);
284
285   g_object_unref (monitor);
286 }
287
288 static void
289 test_add_networks (void)
290 {
291   GNetworkMonitor *monitor;
292   GError *error = NULL;
293
294   monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL);
295   g_assert_no_error (error);
296   assert_signals (monitor, FALSE, FALSE, TRUE);
297
298   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
299                                          ip4_default);
300   assert_signals (monitor, FALSE, TRUE, TRUE);
301   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
302                                          ip6_default);
303   assert_signals (monitor, TRUE, TRUE, FALSE);
304
305   /* Now add the masks one by one */
306
307   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
308                                       net127.mask);
309   assert_signals (monitor, FALSE, TRUE, FALSE);
310
311   run_tests (monitor, net127.addresses, TRUE);
312   run_tests (monitor, net10.addresses, FALSE);
313   run_tests (monitor, net192.addresses, FALSE);
314   run_tests (monitor, netlocal6.addresses, FALSE);
315   run_tests (monitor, netfe80.addresses, FALSE);
316   run_tests (monitor, unmatched, FALSE);
317
318   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
319                                       net10.mask);
320   assert_signals (monitor, FALSE, TRUE, FALSE);
321   run_tests (monitor, net127.addresses, TRUE);
322   run_tests (monitor, net10.addresses, TRUE);
323   run_tests (monitor, net192.addresses, FALSE);
324   run_tests (monitor, netlocal6.addresses, FALSE);
325   run_tests (monitor, netfe80.addresses, FALSE);
326   run_tests (monitor, unmatched, FALSE);
327
328   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
329                                       net192.mask);
330   assert_signals (monitor, FALSE, TRUE, FALSE);
331   run_tests (monitor, net127.addresses, TRUE);
332   run_tests (monitor, net10.addresses, TRUE);
333   run_tests (monitor, net192.addresses, TRUE);
334   run_tests (monitor, netlocal6.addresses, FALSE);
335   run_tests (monitor, netfe80.addresses, FALSE);
336   run_tests (monitor, unmatched, FALSE);
337
338   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
339                                       netlocal6.mask);
340   assert_signals (monitor, FALSE, TRUE, FALSE);
341   run_tests (monitor, net127.addresses, TRUE);
342   run_tests (monitor, net10.addresses, TRUE);
343   run_tests (monitor, net192.addresses, TRUE);
344   run_tests (monitor, netlocal6.addresses, TRUE);
345   run_tests (monitor, netfe80.addresses, FALSE);
346   run_tests (monitor, unmatched, FALSE);
347
348   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
349                                       netfe80.mask);
350   assert_signals (monitor, FALSE, TRUE, FALSE);
351   run_tests (monitor, net127.addresses, TRUE);
352   run_tests (monitor, net10.addresses, TRUE);
353   run_tests (monitor, net192.addresses, TRUE);
354   run_tests (monitor, netlocal6.addresses, TRUE);
355   run_tests (monitor, netfe80.addresses, TRUE);
356   run_tests (monitor, unmatched, FALSE);
357
358   g_object_unref (monitor);
359 }
360
361 static void
362 test_remove_networks (void)
363 {
364   GNetworkMonitor *monitor;
365   GError *error = NULL;
366
367   monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL);
368   g_assert_no_error (error);
369   assert_signals (monitor, FALSE, FALSE, TRUE);
370
371   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
372                                          ip4_default);
373   assert_signals (monitor, FALSE, TRUE, TRUE);
374   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
375                                          ip6_default);
376   assert_signals (monitor, TRUE, TRUE, FALSE);
377
378   /* First add them */
379   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
380                                       net127.mask);
381   assert_signals (monitor, FALSE, TRUE, FALSE);
382   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
383                                       net10.mask);
384   assert_signals (monitor, FALSE, TRUE, FALSE);
385   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
386                                       net192.mask);
387   assert_signals (monitor, FALSE, TRUE, FALSE);
388   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
389                                       netlocal6.mask);
390   assert_signals (monitor, FALSE, TRUE, FALSE);
391   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
392                                       netfe80.mask);
393   assert_signals (monitor, FALSE, TRUE, FALSE);
394
395   run_tests (monitor, net127.addresses, TRUE);
396   run_tests (monitor, net10.addresses, TRUE);
397   run_tests (monitor, net192.addresses, TRUE);
398   run_tests (monitor, netlocal6.addresses, TRUE);
399   run_tests (monitor, netfe80.addresses, TRUE);
400   run_tests (monitor, unmatched, FALSE);
401
402   /* Now remove them one by one */
403   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
404                                          net127.mask);
405   assert_signals (monitor, FALSE, TRUE, FALSE);
406   run_tests (monitor, net127.addresses, FALSE);
407   run_tests (monitor, net10.addresses, TRUE);
408   run_tests (monitor, net192.addresses, TRUE);
409   run_tests (monitor, netlocal6.addresses, TRUE);
410   run_tests (monitor, netfe80.addresses, TRUE);
411   run_tests (monitor, unmatched, FALSE);
412
413   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
414                                          net10.mask);
415   assert_signals (monitor, FALSE, TRUE, FALSE);
416   run_tests (monitor, net127.addresses, FALSE);
417   run_tests (monitor, net10.addresses, FALSE);
418   run_tests (monitor, net192.addresses, TRUE);
419   run_tests (monitor, netlocal6.addresses, TRUE);
420   run_tests (monitor, netfe80.addresses, TRUE);
421   run_tests (monitor, unmatched, FALSE);
422
423   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
424                                          net192.mask);
425   assert_signals (monitor, FALSE, TRUE, FALSE);
426   run_tests (monitor, net127.addresses, FALSE);
427   run_tests (monitor, net10.addresses, FALSE);
428   run_tests (monitor, net192.addresses, FALSE);
429   run_tests (monitor, netlocal6.addresses, TRUE);
430   run_tests (monitor, netfe80.addresses, TRUE);
431   run_tests (monitor, unmatched, FALSE);
432
433   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
434                                          netlocal6.mask);
435   assert_signals (monitor, FALSE, TRUE, FALSE);
436   run_tests (monitor, net127.addresses, FALSE);
437   run_tests (monitor, net10.addresses, FALSE);
438   run_tests (monitor, net192.addresses, FALSE);
439   run_tests (monitor, netlocal6.addresses, FALSE);
440   run_tests (monitor, netfe80.addresses, TRUE);
441   run_tests (monitor, unmatched, FALSE);
442
443   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
444                                          netfe80.mask);
445   assert_signals (monitor, FALSE, TRUE, FALSE);
446   run_tests (monitor, net127.addresses, FALSE);
447   run_tests (monitor, net10.addresses, FALSE);
448   run_tests (monitor, net192.addresses, FALSE);
449   run_tests (monitor, netlocal6.addresses, FALSE);
450   run_tests (monitor, netfe80.addresses, FALSE);
451   run_tests (monitor, unmatched, FALSE);
452
453   g_object_unref (monitor);
454 }
455
456
457 static void
458 init_test (TestMask *test)
459 {
460   GError *error = NULL;
461   int i;
462
463   test->mask = g_inet_address_mask_new_from_string (test->mask_string, &error);
464   g_assert_no_error (error);
465
466   for (i = 0; test->addresses[i].string; i++)
467     {
468       test->addresses[i].address = g_inet_address_new_from_string (test->addresses[i].string);
469       if (strchr (test->addresses[i].string, ':'))
470         g_assert_cmpint (g_inet_address_get_family (test->addresses[i].address), ==, G_SOCKET_FAMILY_IPV6);
471       else
472         g_assert_cmpint (g_inet_address_get_family (test->addresses[i].address), ==, G_SOCKET_FAMILY_IPV4);
473     }
474 }
475
476 static void
477 cleanup_test (TestMask *test)
478 {
479   int i;
480
481   g_object_unref (test->mask);
482   for (i = 0; test->addresses[i].string; i++)
483     g_object_unref (test->addresses[i].address);
484 }
485
486 static void
487 watch_network_changed (GNetworkMonitor *monitor,
488                        gboolean         available,
489                        gpointer         user_data)
490 {
491   g_print ("Network is %s\n", available ? "up" : "down");
492 }
493
494 static void
495 do_watch_network (void)
496 {
497   GNetworkMonitor *monitor = g_network_monitor_get_default ();
498   GMainLoop *loop;
499
500   g_print ("Monitoring via %s\n", g_type_name_from_instance ((GTypeInstance *) monitor));
501
502   g_signal_connect (monitor, "network-changed",
503                     G_CALLBACK (watch_network_changed), NULL);
504   watch_network_changed (monitor, g_network_monitor_get_network_available (monitor), NULL);
505
506   loop = g_main_loop_new (NULL, FALSE);
507   g_main_loop_run (loop);
508 }
509
510 int
511 main (int argc, char **argv)
512 {
513   int ret;
514
515   if (argc == 2 && !strcmp (argv[1], "--watch"))
516     {
517       do_watch_network ();
518       return 0;
519     }
520
521   g_test_init (&argc, &argv, NULL);
522
523   init_test (&net127);
524   init_test (&net10);
525   init_test (&net192);
526   init_test (&netlocal6);
527   init_test (&netfe80);
528   ip4_default = g_inet_address_mask_new_from_string ("0.0.0.0/0", NULL);
529   ip6_default = g_inet_address_mask_new_from_string ("::/0", NULL);
530
531   g_test_add_func ("/network-monitor/default", test_default);
532   g_test_add_func ("/network-monitor/remove_default", test_remove_default);
533   g_test_add_func ("/network-monitor/add_networks", test_add_networks);
534   g_test_add_func ("/network-monitor/remove_networks", test_remove_networks);
535
536   ret = g_test_run ();
537
538   cleanup_test (&net127);
539   cleanup_test (&net10);
540   cleanup_test (&net192);
541   cleanup_test (&netlocal6);
542   cleanup_test (&netfe80);
543   g_object_unref (ip4_default);
544   g_object_unref (ip6_default);
545
546   return ret;
547 }