add GNetworkMonitor, for... monitoring the network
[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, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "gio.h"
22
23 /* hack */
24 #define GIO_COMPILATION
25 #include "gnetworkmonitorbase.h"
26
27 #include <string.h>
28
29 /* Test data; the GInetAddresses and GInetAddressMasks get filled in
30  * in main(). Each address in a TestAddress matches the mask in its
31  * corresponding TestMask, and none of them match any of the other
32  * masks. The addresses in unmatched don't match any of the masks.
33  */
34
35 typedef struct {
36   const char *string;
37   GInetAddress *address;
38 } TestAddress;
39
40 typedef struct {
41   const char *mask_string;
42   GInetAddressMask *mask;
43   TestAddress *addresses;
44 } TestMask;
45
46 TestAddress net127addrs[] = {
47   { "127.0.0.1", NULL },
48   { "127.0.0.2", NULL },
49   { "127.0.0.255", NULL },
50   { "127.0.1.0", NULL },
51   { "127.0.255.0", NULL },
52   { "127.0.255.0", NULL },
53   { "127.255.255.255", NULL },
54   { NULL, NULL }
55 };
56 TestMask net127 = { "127.0.0.0/8", NULL, net127addrs };
57
58 TestAddress net10addrs[] = {
59   { "10.0.0.1", NULL },
60   { "10.0.0.2", NULL },
61   { "10.0.0.255", NULL },
62   { NULL, NULL }
63 };
64 TestMask net10 = { "10.0.0.0/24", NULL, net10addrs };
65
66 TestAddress net192addrs[] = {
67   { "192.168.0.1", NULL },
68   { "192.168.0.2", NULL },
69   { "192.168.0.255", NULL },
70   { "192.168.1.0", NULL },
71   { "192.168.15.0", NULL },
72   { NULL, NULL }
73 };
74 TestMask net192 = { "192.168.0.0/20", NULL, net192addrs };
75
76 TestAddress netlocal6addrs[] = {
77   { "::1", NULL },
78   { NULL, NULL }
79 };
80 TestMask netlocal6 = { "::1/128", NULL, netlocal6addrs };
81
82 TestAddress netfe80addrs[] = {
83   { "fe80::", NULL },
84   { "fe80::1", NULL },
85   { "fe80::21b:77ff:fea2:972a", NULL },
86   { NULL, NULL }
87 };
88 TestMask netfe80 = { "fe80::/64", NULL, netfe80addrs };
89
90 TestAddress unmatched[] = {
91   { "10.0.1.0", NULL },
92   { "10.0.255.0", NULL },
93   { "10.255.255.255", NULL },
94   { "192.168.16.0", NULL },
95   { "192.168.255.0", NULL },
96   { "192.169.0.0", NULL },
97   { "192.255.255.255", NULL },
98   { "::2", NULL },
99   { "1::1", NULL },
100   { "fe80::1:0:0:0:0", NULL },
101   { "fe80:8000::0:0:0:0", NULL },
102   { NULL, NULL }
103 };
104
105 GInetAddressMask *ip4_default, *ip6_default;
106
107 static void
108 notify_handler (GObject    *object,
109                 GParamSpec *pspec,
110                 gpointer    user_data)
111 {
112   gboolean *emitted = user_data;
113
114   *emitted = TRUE;
115 }
116
117 static void
118 network_changed_handler (GNetworkMonitor *monitor,
119                          gboolean         available,
120                          gpointer         user_data)
121 {
122   gboolean *emitted = user_data;
123
124   *emitted = TRUE;
125 }
126
127 static void
128 assert_signals (GNetworkMonitor *monitor,
129                 gboolean         should_emit_notify,
130                 gboolean         should_emit_network_changed,
131                 gboolean         expected_network_available)
132 {
133   gboolean emitted_notify = FALSE, emitted_network_changed = FALSE;
134   guint h1, h2;
135
136   h1 = g_signal_connect (monitor, "notify::network-available",
137                          G_CALLBACK (notify_handler),
138                          &emitted_notify);
139   h2 = g_signal_connect (monitor, "network-changed",
140                          G_CALLBACK (network_changed_handler),
141                          &emitted_network_changed);
142
143   g_main_context_iteration (NULL, FALSE);
144
145   g_signal_handler_disconnect (monitor, h1);
146   g_signal_handler_disconnect (monitor, h2);
147
148   g_assert (emitted_notify == should_emit_notify);
149   g_assert (emitted_network_changed == should_emit_network_changed);
150
151   g_assert (g_network_monitor_get_network_available (monitor) == expected_network_available);
152 }
153
154 static void
155 run_tests (GNetworkMonitor *monitor,
156            TestAddress     *addresses,
157            gboolean         should_be_reachable)
158 {
159   GError *error = NULL;
160   int i;
161   gboolean reachable;
162   GSocketAddress *sockaddr;
163
164   for (i = 0; addresses[i].address; i++)
165     {
166       sockaddr = g_inet_socket_address_new (addresses[i].address, 0);
167       reachable = g_network_monitor_can_reach (monitor,
168                                                G_SOCKET_CONNECTABLE (sockaddr),
169                                                NULL, &error);
170       g_object_unref (sockaddr);
171       g_assert_cmpint (reachable, ==, should_be_reachable);
172       if (should_be_reachable)
173         g_assert_no_error (error);
174       else
175         {
176           g_assert (error != NULL);
177           g_clear_error (&error);
178         }
179     }
180 }
181
182 static void
183 test_default (void)
184 {
185   GNetworkMonitor *monitor;
186   GError *error = NULL;
187
188   monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL);
189   g_assert_no_error (error);
190
191   /* In the default configuration, all addresses are reachable */
192   run_tests (monitor, net127.addresses, TRUE);
193   run_tests (monitor, net10.addresses, TRUE);
194   run_tests (monitor, net192.addresses, TRUE);
195   run_tests (monitor, netlocal6.addresses, TRUE);
196   run_tests (monitor, netfe80.addresses, TRUE);
197   run_tests (monitor, unmatched, TRUE);
198
199   assert_signals (monitor, FALSE, FALSE, TRUE);
200 }
201
202 static void
203 test_remove_default (void)
204 {
205   GNetworkMonitor *monitor;
206   GError *error = NULL;
207
208   monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL);
209   g_assert_no_error (error);
210   assert_signals (monitor, FALSE, FALSE, TRUE);
211
212   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
213                                          ip4_default);
214   assert_signals (monitor, FALSE, TRUE, TRUE);
215   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
216                                          ip6_default);
217   assert_signals (monitor, TRUE, TRUE, FALSE);
218
219   /* Now nothing should be reachable */
220   run_tests (monitor, net127.addresses, FALSE);
221   run_tests (monitor, net10.addresses, FALSE);
222   run_tests (monitor, net192.addresses, FALSE);
223   run_tests (monitor, netlocal6.addresses, FALSE);
224   run_tests (monitor, netfe80.addresses, FALSE);
225   run_tests (monitor, unmatched, FALSE);
226 }
227
228 static void
229 test_add_networks (void)
230 {
231   GNetworkMonitor *monitor;
232   GError *error = NULL;
233
234   monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL);
235   g_assert_no_error (error);
236   assert_signals (monitor, FALSE, FALSE, TRUE);
237
238   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
239                                          ip4_default);
240   assert_signals (monitor, FALSE, TRUE, TRUE);
241   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
242                                          ip6_default);
243   assert_signals (monitor, TRUE, TRUE, FALSE);
244
245   /* Now add the masks one by one */
246
247   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
248                                       net127.mask);
249   assert_signals (monitor, FALSE, TRUE, FALSE);
250
251   run_tests (monitor, net127.addresses, TRUE);
252   run_tests (monitor, net10.addresses, FALSE);
253   run_tests (monitor, net192.addresses, FALSE);
254   run_tests (monitor, netlocal6.addresses, FALSE);
255   run_tests (monitor, netfe80.addresses, FALSE);
256   run_tests (monitor, unmatched, FALSE);
257
258   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
259                                       net10.mask);
260   assert_signals (monitor, FALSE, TRUE, FALSE);
261   run_tests (monitor, net127.addresses, TRUE);
262   run_tests (monitor, net10.addresses, TRUE);
263   run_tests (monitor, net192.addresses, FALSE);
264   run_tests (monitor, netlocal6.addresses, FALSE);
265   run_tests (monitor, netfe80.addresses, FALSE);
266   run_tests (monitor, unmatched, FALSE);
267
268   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
269                                       net192.mask);
270   assert_signals (monitor, FALSE, TRUE, FALSE);
271   run_tests (monitor, net127.addresses, TRUE);
272   run_tests (monitor, net10.addresses, TRUE);
273   run_tests (monitor, net192.addresses, TRUE);
274   run_tests (monitor, netlocal6.addresses, FALSE);
275   run_tests (monitor, netfe80.addresses, FALSE);
276   run_tests (monitor, unmatched, FALSE);
277
278   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
279                                       netlocal6.mask);
280   assert_signals (monitor, FALSE, TRUE, FALSE);
281   run_tests (monitor, net127.addresses, TRUE);
282   run_tests (monitor, net10.addresses, TRUE);
283   run_tests (monitor, net192.addresses, TRUE);
284   run_tests (monitor, netlocal6.addresses, TRUE);
285   run_tests (monitor, netfe80.addresses, FALSE);
286   run_tests (monitor, unmatched, FALSE);
287
288   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
289                                       netfe80.mask);
290   assert_signals (monitor, FALSE, TRUE, FALSE);
291   run_tests (monitor, net127.addresses, TRUE);
292   run_tests (monitor, net10.addresses, TRUE);
293   run_tests (monitor, net192.addresses, TRUE);
294   run_tests (monitor, netlocal6.addresses, TRUE);
295   run_tests (monitor, netfe80.addresses, TRUE);
296   run_tests (monitor, unmatched, FALSE);
297 }
298
299 static void
300 test_remove_networks (void)
301 {
302   GNetworkMonitor *monitor;
303   GError *error = NULL;
304
305   monitor = g_initable_new (G_TYPE_NETWORK_MONITOR_BASE, NULL, &error, NULL);
306   g_assert_no_error (error);
307   assert_signals (monitor, FALSE, FALSE, TRUE);
308
309   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
310                                          ip4_default);
311   assert_signals (monitor, FALSE, TRUE, TRUE);
312   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
313                                          ip6_default);
314   assert_signals (monitor, TRUE, TRUE, FALSE);
315
316   /* First add them */
317   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
318                                       net127.mask);
319   assert_signals (monitor, FALSE, TRUE, FALSE);
320   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
321                                       net10.mask);
322   assert_signals (monitor, FALSE, TRUE, FALSE);
323   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
324                                       net192.mask);
325   assert_signals (monitor, FALSE, TRUE, FALSE);
326   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
327                                       netlocal6.mask);
328   assert_signals (monitor, FALSE, TRUE, FALSE);
329   g_network_monitor_base_add_network (G_NETWORK_MONITOR_BASE (monitor),
330                                       netfe80.mask);
331   assert_signals (monitor, FALSE, TRUE, FALSE);
332
333   run_tests (monitor, net127.addresses, TRUE);
334   run_tests (monitor, net10.addresses, TRUE);
335   run_tests (monitor, net192.addresses, TRUE);
336   run_tests (monitor, netlocal6.addresses, TRUE);
337   run_tests (monitor, netfe80.addresses, TRUE);
338   run_tests (monitor, unmatched, FALSE);
339
340   /* Now remove them one by one */
341   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
342                                          net127.mask);
343   assert_signals (monitor, FALSE, TRUE, FALSE);
344   run_tests (monitor, net127.addresses, FALSE);
345   run_tests (monitor, net10.addresses, TRUE);
346   run_tests (monitor, net192.addresses, TRUE);
347   run_tests (monitor, netlocal6.addresses, TRUE);
348   run_tests (monitor, netfe80.addresses, TRUE);
349   run_tests (monitor, unmatched, FALSE);
350
351   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
352                                          net10.mask);
353   assert_signals (monitor, FALSE, TRUE, FALSE);
354   run_tests (monitor, net127.addresses, FALSE);
355   run_tests (monitor, net10.addresses, FALSE);
356   run_tests (monitor, net192.addresses, TRUE);
357   run_tests (monitor, netlocal6.addresses, TRUE);
358   run_tests (monitor, netfe80.addresses, TRUE);
359   run_tests (monitor, unmatched, FALSE);
360
361   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
362                                          net192.mask);
363   assert_signals (monitor, FALSE, TRUE, FALSE);
364   run_tests (monitor, net127.addresses, FALSE);
365   run_tests (monitor, net10.addresses, FALSE);
366   run_tests (monitor, net192.addresses, FALSE);
367   run_tests (monitor, netlocal6.addresses, TRUE);
368   run_tests (monitor, netfe80.addresses, TRUE);
369   run_tests (monitor, unmatched, FALSE);
370
371   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
372                                          netlocal6.mask);
373   assert_signals (monitor, FALSE, TRUE, FALSE);
374   run_tests (monitor, net127.addresses, FALSE);
375   run_tests (monitor, net10.addresses, FALSE);
376   run_tests (monitor, net192.addresses, FALSE);
377   run_tests (monitor, netlocal6.addresses, FALSE);
378   run_tests (monitor, netfe80.addresses, TRUE);
379   run_tests (monitor, unmatched, FALSE);
380
381   g_network_monitor_base_remove_network (G_NETWORK_MONITOR_BASE (monitor),
382                                          netfe80.mask);
383   assert_signals (monitor, FALSE, TRUE, FALSE);
384   run_tests (monitor, net127.addresses, FALSE);
385   run_tests (monitor, net10.addresses, FALSE);
386   run_tests (monitor, net192.addresses, FALSE);
387   run_tests (monitor, netlocal6.addresses, FALSE);
388   run_tests (monitor, netfe80.addresses, FALSE);
389   run_tests (monitor, unmatched, FALSE);
390 }
391
392
393 static void
394 init_test (TestMask *test)
395 {
396   GError *error = NULL;
397   int i;
398
399   test->mask = g_inet_address_mask_new_from_string (test->mask_string, &error);
400   g_assert_no_error (error);
401
402   for (i = 0; test->addresses[i].string; i++)
403     {
404       test->addresses[i].address = g_inet_address_new_from_string (test->addresses[i].string);
405       if (strchr (test->addresses[i].string, ':'))
406         g_assert_cmpint (g_inet_address_get_family (test->addresses[i].address), ==, G_SOCKET_FAMILY_IPV6);
407       else
408         g_assert_cmpint (g_inet_address_get_family (test->addresses[i].address), ==, G_SOCKET_FAMILY_IPV4);
409     }
410 }
411
412 static void
413 watch_network_changed (GNetworkMonitor *monitor,
414                        gboolean         available,
415                        gpointer         user_data)
416 {
417   g_print ("Network is %s\n", available ? "up" : "down");
418 }
419
420 static void
421 do_watch_network (void)
422 {
423   GNetworkMonitor *monitor = g_network_monitor_get_default ();
424   GMainLoop *loop;
425
426   g_print ("Monitoring via %s\n", g_type_name_from_instance ((GTypeInstance *) monitor));
427
428   g_signal_connect (monitor, "network-changed",
429                     G_CALLBACK (watch_network_changed), NULL);
430   watch_network_changed (monitor, g_network_monitor_get_network_available (monitor), NULL);
431
432   loop = g_main_loop_new (NULL, FALSE);
433   g_main_loop_run (loop);
434 }
435
436 int
437 main (int argc, char **argv)
438 {
439   g_type_init ();
440
441   if (argc == 2 && !strcmp (argv[1], "--watch"))
442     {
443       do_watch_network ();
444       return 0;
445     }
446
447   g_test_init (&argc, &argv, NULL);
448
449   init_test (&net127);
450   init_test (&net10);
451   init_test (&net192);
452   init_test (&netlocal6);
453   init_test (&netfe80);
454   ip4_default = g_inet_address_mask_new_from_string ("0.0.0.0/0", NULL);
455   ip6_default = g_inet_address_mask_new_from_string ("::/0", NULL);
456
457   g_test_add_func ("/network-monitor/default", test_default);
458   g_test_add_func ("/network-monitor/remove_default", test_remove_default);
459   g_test_add_func ("/network-monitor/add_networks", test_add_networks);
460   g_test_add_func ("/network-monitor/remove_networks", test_remove_networks);
461
462   return g_test_run ();
463 }