1 /* GNet GInetAddr unit test (deterministic, computation-based tests only)
2  * Copyright (C) 2002 David Helder
3  * Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program 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
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 
20 #include "config.h"
21 #include "gnetcheck.h"
22 
23 #ifdef HAVE_VALGRIND
24 #include <valgrind/valgrind.h>
25 #endif
26 
27 #include <string.h>
28 #include <stdio.h>
29 
30 /*** IPv4 tests */
31 
GNET_START_TEST(test_inetaddr_ipv4)32 GNET_START_TEST (test_inetaddr_ipv4)
33 {
34   GInetAddr* inetaddr;
35   GInetAddr* inetaddr2;
36   gchar* cname;
37   gchar* cname2;
38   gchar bytes[GNET_INETADDR_MAX_LEN];
39 
40   /* new (canonical, IPv4) */
41   inetaddr = gnet_inetaddr_new ("141.213.11.124", 23);
42   fail_unless (inetaddr != NULL);
43 
44   /* get_port */
45   fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 23);
46 
47   /* set_port */
48   gnet_inetaddr_set_port (inetaddr, 42);
49   fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 42);
50 
51   /* get_canonical_name */
52   cname = gnet_inetaddr_get_canonical_name (inetaddr);
53   fail_unless (cname != NULL);
54   fail_unless_equals_string (cname, "141.213.11.124");
55   g_free (cname);
56 
57   /* clone */
58   inetaddr2 = gnet_inetaddr_clone (inetaddr);
59   fail_unless (inetaddr2 != NULL);
60   cname2 = gnet_inetaddr_get_canonical_name (inetaddr2);
61   fail_unless (cname2 != NULL);
62   fail_unless_equals_string (cname2, "141.213.11.124");
63   fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr2), 42);
64   g_free(cname2);
65 
66   /* equal, noport_equal */
67   fail_unless (gnet_inetaddr_equal (inetaddr, inetaddr2));
68   fail_unless (gnet_inetaddr_noport_equal (inetaddr, inetaddr2));
69   gnet_inetaddr_set_port (inetaddr2, 23);
70   fail_if (gnet_inetaddr_equal (inetaddr, inetaddr2));
71   fail_unless (gnet_inetaddr_noport_equal (inetaddr, inetaddr2));
72 
73   /* hash */
74   fail_unless_equals_int (gnet_inetaddr_hash (inetaddr), 2379549526u);
75   /* hash port */
76   fail_unless (gnet_inetaddr_hash (inetaddr) != gnet_inetaddr_hash (inetaddr2));
77 
78   gnet_inetaddr_delete (inetaddr);
79   gnet_inetaddr_delete (inetaddr2);
80 
81   /* bytes */
82   inetaddr = gnet_inetaddr_new_bytes ("\x8d\xd5\xb\x7c", 4);
83   fail_unless (inetaddr != NULL);
84 
85   cname = gnet_inetaddr_get_canonical_name (inetaddr);
86   fail_unless (cname != NULL);
87   fail_unless_equals_string ("141.213.11.124", cname);
88   g_free (cname);
89 
90   fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 0);
91   gnet_inetaddr_set_port (inetaddr, 2345);
92   fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 2345);
93 
94   fail_unless_equals_int (gnet_inetaddr_get_length (inetaddr), 4);
95 
96   gnet_inetaddr_set_bytes (inetaddr, "\x7c\xb\xd5\x8d", 4);
97   cname = gnet_inetaddr_get_canonical_name (inetaddr);
98   fail_unless (cname != NULL);
99   fail_unless_equals_string ("124.11.213.141", cname);
100   fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 2345);
101   g_free (cname);
102 
103   fail_unless_equals_int (gnet_inetaddr_get_length (inetaddr), 4);
104 
105   gnet_inetaddr_get_bytes (inetaddr, bytes);
106   fail_unless (memcmp(bytes, "\x7c\xb\xd5\x8d", 4) == 0);
107 
108 #ifdef HAVE_IPV6
109 
110   /* IPv4 -> IPv6 via set_bytes */
111   gnet_inetaddr_set_bytes (inetaddr, "\x3f\xfe\x0b\x00" "\x0c\x18\x1f\xff"
112 			   "\0\0\0\0"         "\0\0\0\x6f", 16);
113   cname = gnet_inetaddr_get_canonical_name (inetaddr);
114   fail_unless (cname != NULL);
115   fail_unless (!strcasecmp("3ffe:b00:c18:1fff::6f", cname));
116   g_free (cname);
117   fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 2345);
118   fail_unless_equals_int (gnet_inetaddr_get_length (inetaddr), 16);
119 
120   gnet_inetaddr_get_bytes (inetaddr, bytes);
121   fail_unless (!memcmp(bytes, "\x3f\xfe\x0b\x00\x0c\x18\x1f\xff\0\0\0\0\0\0\0\x6f", 16));
122 
123 #endif
124 
125   gnet_inetaddr_delete (inetaddr);
126 }
127 GNET_END_TEST;
128 
129 #define IS_TEST(S,A,F) do {                                     \
130   GInetAddr* _inetaddr;                                         \
131   gchar* _cname;                                                \
132   _inetaddr = gnet_inetaddr_new_nonblock (A, 0);                \
133   fail_unless (_inetaddr != NULL);                              \
134   _cname = gnet_inetaddr_get_canonical_name (_inetaddr);        \
135   fail_unless (_cname != NULL);                                 \
136   fail_unless_equals_string (_cname, (A));                      \
137   fail_unless (F (_inetaddr));                                  \
138   g_free (_cname);                                              \
139   gnet_inetaddr_delete (_inetaddr);                             \
140 } while (0)
141 
GNET_START_TEST(test_inetaddr_is_ipv4)142 GNET_START_TEST (test_inetaddr_is_ipv4)
143 {
144   /* IPv4 */
145   IS_TEST ("IPv4", "141.213.11.124", 	     	  gnet_inetaddr_is_ipv4);
146 
147   /* IPv4 Loopback */
148   IS_TEST ("IPv4 Loopback",  "127.0.0.1",     	  gnet_inetaddr_is_loopback);
149   IS_TEST ("IPv4 Loopback2", "127.23.42.129", 	  gnet_inetaddr_is_loopback);
150   IS_TEST ("IPv4 !Loopback", "128.23.42.129", 	  !gnet_inetaddr_is_loopback);
151 
152   /* IPv4 Multicast */
153   IS_TEST ("IPv4 Multicast",   "224.0.0.0",       gnet_inetaddr_is_multicast);
154   IS_TEST ("IPv4 Multicast2",  "224.0.0.1",       gnet_inetaddr_is_multicast);
155   IS_TEST ("IPv4 Multicast3",  "239.255.255.255", gnet_inetaddr_is_multicast);
156   IS_TEST ("IPv4 !Multicast",  "223.255.255.255", !gnet_inetaddr_is_multicast);
157   IS_TEST ("IPv4 !Multicast2", "240.0.0.0", 	  !gnet_inetaddr_is_multicast);
158 
159   /* IPv4 Private */
160   IS_TEST ("IPv4 Private",   	"10.0.0.0", 	   gnet_inetaddr_is_private);
161   IS_TEST ("IPv4 Private2",   	"10.255.255.255",  gnet_inetaddr_is_private);
162   IS_TEST ("IPv4 !Private",   	"9.255.255.255",   !gnet_inetaddr_is_private);
163   IS_TEST ("IPv4 !Private2",   	"11.0.0.0", 	   !gnet_inetaddr_is_private);
164   IS_TEST ("IPv4 Private3",   	"172.16.0.0", 	   gnet_inetaddr_is_private);
165   IS_TEST ("IPv4 Private4",   	"172.31.255.255",  gnet_inetaddr_is_private);
166   IS_TEST ("IPv4 !Private3",   	"172.15.255.255",  !gnet_inetaddr_is_private);
167   IS_TEST ("IPv4 !Private4",   	"172.32.0.0",      !gnet_inetaddr_is_private);
168   IS_TEST ("IPv4 Private5",   	"192.168.0.0", 	   gnet_inetaddr_is_private);
169   IS_TEST ("IPv4 Private6",   	"192.168.255.255", gnet_inetaddr_is_private);
170   IS_TEST ("IPv4 !Private5",   	"192.167.255.255", !gnet_inetaddr_is_private);
171   IS_TEST ("IPv4 !Private6",   	"192.169.0.0",     !gnet_inetaddr_is_private);
172 
173 
174   /* IPv4 Reserved */
175   IS_TEST ("IPv4 Reserved",   	"0.0.0.0", 	   gnet_inetaddr_is_reserved);
176   IS_TEST ("IPv4 Reserved2",   	"0.0.255.255", 	   gnet_inetaddr_is_reserved);
177   IS_TEST ("IPv4 !Reserved2",   "1.0.0.0", 	   !gnet_inetaddr_is_reserved);
178   IS_TEST ("IPv4 Reserved3",   	"240.0.0.0", 	   gnet_inetaddr_is_reserved);
179   IS_TEST ("IPv4 Reserved4",   	"247.255.255.255", gnet_inetaddr_is_reserved);
180   IS_TEST ("IPv4 !Reserved3",   "239.255.255.255", !gnet_inetaddr_is_reserved);
181   IS_TEST ("IPv4 !Reserved4",   "248.0.0.0", 	   !gnet_inetaddr_is_reserved);
182 
183   /* Internet */
184   IS_TEST ("Internet1", "141.213.11.124", 	   gnet_inetaddr_is_internet);
185 }
186 GNET_END_TEST;
187 
188 #if HAVE_IPV6
189 
GNET_START_TEST(test_inetaddr_is_ipv6)190 GNET_START_TEST (test_inetaddr_is_ipv6)
191 {
192   /* IPv6 */
193   IS_TEST ("!IPv4", "3ffe:b00:c18:1fff::6f", 	  !gnet_inetaddr_is_ipv4);
194   IS_TEST ("IPv6", "3ffe:b00:c18:1fff::6f",  	  gnet_inetaddr_is_ipv6);
195   IS_TEST ("!IPv6", "141.213.11.124", 	     	  !gnet_inetaddr_is_ipv6);
196 
197   /* IPv6 Loopback */
198   IS_TEST ("IPv6 Loopback",   "::1", 	      	  gnet_inetaddr_is_loopback);
199   IS_TEST ("IPv6 !Loopback",  "::",           	  !gnet_inetaddr_is_loopback);
200   IS_TEST ("IPv6 !Loopback2", "::201",        	  !gnet_inetaddr_is_loopback);
201 
202   /* IPv6 Multicast */
203   IS_TEST ("IPv6 Multicast",   "ffff::1",         gnet_inetaddr_is_multicast);
204   IS_TEST ("IPv6 !Multicast",  "feff::1",         !gnet_inetaddr_is_multicast);
205 
206   /* IPv6 Broadcast */
207   IS_TEST ("IPv6 Broadcast",   "255.255.255.255", gnet_inetaddr_is_broadcast);
208   IS_TEST ("IPv6 !Broadcast",  "255.255.255.254", !gnet_inetaddr_is_broadcast);
209 
210   /* IPv6 Private */
211   IS_TEST ("IPv6 Private",   	"fe80::",     	   gnet_inetaddr_is_private);
212   IS_TEST ("IPv6 Private2",   	"fecf:ffff::",     gnet_inetaddr_is_private);
213   IS_TEST ("IPv6 !Private",   	"fe7f:ffff::",     !gnet_inetaddr_is_private);
214   IS_TEST ("IPv6 !Private2",   	"ff00::",          !gnet_inetaddr_is_private);
215 
216   /* IPv6 Reserved */
217   IS_TEST ("IPv6 Reserved",   	"::",     	   gnet_inetaddr_is_reserved);
218   IS_TEST ("IPv6 !Reserved",   	"1::",     	   !gnet_inetaddr_is_reserved);
219 
220   /* Internet */
221   IS_TEST ("Internet2", "3ffe:b00:c18:1fff::6f",   gnet_inetaddr_is_internet);
222   IS_TEST ("!Internet1",  "255.255.255.255",       !gnet_inetaddr_is_internet);
223   IS_TEST ("!Internet2",  "ffff::1",     	   !gnet_inetaddr_is_internet);
224 }
225 GNET_END_TEST;
226 
227 #endif /* HAVE_IPV6 */
228 
229 
230 /*** IPv6 tests ***/
231 
232 #if HAVE_IPV6
GNET_START_TEST(test_inetaddr_ipv6)233 GNET_START_TEST (test_inetaddr_ipv6)
234 {
235   GInetAddr* inetaddr;
236   GInetAddr* inetaddr2;
237   gchar* cname;
238   gchar* cname2;
239 
240   /* new (canonical, IPv6) */
241   inetaddr = gnet_inetaddr_new ("3ffe:b00:c18:1fff::6f", 23);
242   fail_unless (inetaddr != NULL);
243 
244   /* get_port */
245   fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 23);
246 
247   /* set_port */
248   gnet_inetaddr_set_port (inetaddr, 42);
249   fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 42);
250 
251   /* get_canonical_name */
252   cname = gnet_inetaddr_get_canonical_name (inetaddr);
253   fail_unless (cname != NULL);
254   fail_unless (!strcasecmp(cname, "3ffe:b00:c18:1fff::6f"));
255   g_free (cname);
256 
257   /* clone */
258   inetaddr2 = gnet_inetaddr_clone (inetaddr);
259   fail_unless (inetaddr != NULL);
260   cname2 = gnet_inetaddr_get_canonical_name (inetaddr2);
261   fail_unless (cname2 != NULL);
262   fail_unless (!strcasecmp(cname2, "3ffe:b00:c18:1fff::6f"));
263   fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr2), 42);
264   g_free(cname2);
265 
266   /* equal, noport_equal */
267   fail_unless (gnet_inetaddr_equal (inetaddr, inetaddr2));
268   fail_unless (gnet_inetaddr_noport_equal (inetaddr, inetaddr2));
269   gnet_inetaddr_set_port (inetaddr2, 23);
270   fail_if (gnet_inetaddr_equal (inetaddr, inetaddr2));
271   fail_unless (gnet_inetaddr_noport_equal (inetaddr, inetaddr2));
272 
273   /* hash */
274   fail_unless_equals_int (gnet_inetaddr_hash (inetaddr), 870716602u);
275   /* hash port */
276   fail_unless (gnet_inetaddr_hash (inetaddr) != gnet_inetaddr_hash (inetaddr2));
277 
278   gnet_inetaddr_delete (inetaddr);
279   gnet_inetaddr_delete (inetaddr2);
280 
281   /* bytes */
282   inetaddr = gnet_inetaddr_new_bytes ("\x3f\xfe\x0b\x00" "\x0c\x18\x1f\xff"
283 				      "\0\0\0\0"         "\0\0\0\x6f", 16);
284   fail_unless (inetaddr != NULL);
285   cname = gnet_inetaddr_get_canonical_name (inetaddr);
286   fail_unless (cname != NULL);
287   fail_unless (!strcasecmp("3ffe:b00:c18:1fff::6f", cname));
288   fail_unless_equals_int (gnet_inetaddr_get_port (inetaddr), 0);
289   gnet_inetaddr_delete (inetaddr);
290   g_free (cname);
291 }
292 GNET_END_TEST;
293 #endif /* HAVE_IPV6 */
294 
GNET_START_TEST(test_inetaddr_is_internet_domainname)295 GNET_START_TEST (test_inetaddr_is_internet_domainname)
296 {
297   fail_unless (gnet_inetaddr_is_internet_domainname ("speak.eecs.umich.edu"));
298   fail_unless (gnet_inetaddr_is_internet_domainname ("141.213.11.124"));
299   fail_if (gnet_inetaddr_is_internet_domainname ("localhost"));
300   fail_if (gnet_inetaddr_is_internet_domainname ("localhost.localdomain"));
301   fail_if (gnet_inetaddr_is_internet_domainname ("speak"));
302 }
303 GNET_END_TEST;
304 
305 static void
lookup_list_cb(GList * list,gpointer data)306 lookup_list_cb (GList * list, gpointer data)
307 {
308   gboolean *p_called = (gboolean *) data;
309   GList *l;
310 
311   *p_called = TRUE;
312 
313   /* g_print ("%d results\n", g_list_length (list)); */
314 
315   fail_unless (list != NULL);
316   for (l = list; l != NULL; l = l->next) {
317     GInetAddr *ia;
318     gchar *name;
319 
320     ia = (GInetAddr *) l->data;
321     name = gnet_inetaddr_get_canonical_name (ia);
322     fail_unless (name != NULL);
323     fail_unless_equals_int (gnet_inetaddr_get_port (ia), 80);
324     g_free (name);
325   }
326 
327   g_list_foreach (list, (GFunc) gnet_inetaddr_unref, NULL);
328   g_list_free (list);
329 }
330 
331 static void
lookup_list_cb_do_nothing(GList * list,gpointer data)332 lookup_list_cb_do_nothing (GList * list, gpointer data)
333 {
334   g_list_foreach (list, (GFunc) gnet_inetaddr_unref, NULL);
335   g_list_free (list);
336 }
337 
338 static gboolean
do_nothing_timeout(gpointer foo)339 do_nothing_timeout (gpointer foo)
340 {
341   return FALSE; /* don't call again */
342 }
343 
344 static void
destroy_notify(gpointer data)345 destroy_notify (gpointer data)
346 {
347   gboolean *p_bool = (gboolean *) data;
348 
349   *p_bool = TRUE;
350 }
351 
352 static void
do_test_inetaddr_list_async(const gchar * hostname)353 do_test_inetaddr_list_async (const gchar * hostname)
354 {
355   GInetAddrNewListAsyncID list_async_id;
356   GMainContext *ctx;
357   gboolean called, destroyed;
358   gint id;
359 
360   /* g_print ("list async: looking up %s ... ", hostname); */
361 
362   /* list async (default main context) */
363   called = FALSE;
364   list_async_id = gnet_inetaddr_new_list_async (hostname, 80,
365       lookup_list_cb, &called);
366   id = g_timeout_add (5 * 1000, (GSourceFunc) do_nothing_timeout, NULL);
367   g_main_context_iteration (NULL, TRUE);
368   fail_unless (called);
369   g_source_remove (id);
370 
371   /* list async + cancel (default main context) */
372   called = FALSE;
373   list_async_id = gnet_inetaddr_new_list_async (hostname, 80,
374       lookup_list_cb, &called);
375   fail_unless (list_async_id != NULL);
376   gnet_inetaddr_new_list_async_cancel (list_async_id);
377   while (g_main_context_iteration (NULL, FALSE)) {
378     ;
379   }
380   fail_unless (!called);
381 
382   /* list async (destroy notify) */
383   destroyed = FALSE;
384   list_async_id = gnet_inetaddr_new_list_async_full (hostname, 80,
385       lookup_list_cb_do_nothing, &destroyed, destroy_notify, NULL,
386       G_PRIORITY_HIGH);
387   fail_unless (list_async_id != NULL);
388   g_main_context_iteration (NULL, TRUE);
389   fail_unless (destroyed);
390 
391   /* list async + cancel (destroy notify; thread unlikely to start) */
392   destroyed = FALSE;
393   list_async_id = gnet_inetaddr_new_list_async_full (hostname, 80,
394       lookup_list_cb_do_nothing, &destroyed, destroy_notify, NULL,
395       G_PRIORITY_HIGH);
396   fail_unless (list_async_id != NULL);
397   gnet_inetaddr_new_list_async_cancel (list_async_id);
398   /* give thread a chance to execute and act on the cancelled flag */
399   g_usleep (1 * G_USEC_PER_SEC);
400   fail_unless (destroyed);
401 
402   /* list async + cancel (destroy notify II) */
403   destroyed = FALSE;
404   list_async_id = gnet_inetaddr_new_list_async_full (hostname, 80,
405       lookup_list_cb_do_nothing, &destroyed, destroy_notify, NULL,
406       G_PRIORITY_HIGH);
407   fail_unless (list_async_id != NULL);
408   /* give thread a chance to execute and block before we cancel it */
409   g_usleep (1 * G_USEC_PER_SEC);
410   gnet_inetaddr_new_list_async_cancel (list_async_id);
411   fail_unless (destroyed);
412 
413   /* list async + cancel (destroy notify III) */
414   destroyed = FALSE;
415   list_async_id = gnet_inetaddr_new_list_async_full (hostname, 80,
416       lookup_list_cb_do_nothing, &destroyed, destroy_notify, NULL,
417       G_PRIORITY_HIGH);
418   fail_unless (list_async_id != NULL);
419   /* give thread a chance to execute and block and be done before cancelling */
420   g_usleep (3 * G_USEC_PER_SEC);
421   gnet_inetaddr_new_list_async_cancel (list_async_id);
422   fail_unless (destroyed);
423 
424   /* list async (custom main context) */
425   called = FALSE;
426   ctx = g_main_context_new ();
427   list_async_id = gnet_inetaddr_new_list_async_full (hostname, 80,
428       lookup_list_cb, &called, (GDestroyNotify) NULL, ctx,
429       G_PRIORITY_HIGH);
430   /* give thread a chance to execute and block and be done */
431   g_usleep (3 * G_USEC_PER_SEC);
432   fail_unless (!called);
433   /* there shouldn't be anyhing pending in the default context */
434   fail_unless (!g_main_context_pending (NULL));
435   /* but there should be something pending in OUR context now */
436   fail_unless (g_main_context_pending (ctx));
437   fail_unless (!called);
438   /* let's iterate it and dispatch the callback */
439   fail_unless (g_main_context_iteration (ctx, FALSE));
440   fail_unless (called);
441   g_main_context_unref (ctx);
442 }
443 
GNET_START_TEST(test_inetaddr_list_async)444 GNET_START_TEST (test_inetaddr_list_async)
445 {
446   do_test_inetaddr_list_async ("localhost");
447 /* FIXME: these might not work right yet because of the timings in the test
448 #ifdef GNET_ENABLE_NETWORK_TESTS
449   do_test_inetaddr_list_async ("www.google.com");
450   do_test_inetaddr_list_async ("www.heise.de");
451 #endif
452 */
453 #ifdef HAVE_VALGRIND
454   if (RUNNING_ON_VALGRIND) {
455     g_print ("Sleeping for a while to let cancelled threads finish ...\n");
456     /* sleep a while to give any cancelled threads a chance to quit, otherwise
457      * valgrind will think the threads were leaked */
458     g_usleep (60 * G_USEC_PER_SEC);
459   }
460 #endif
461 }
462 GNET_END_TEST;
463 
464 static void
lookup_name_cb(GInetAddr * ia,gpointer data)465 lookup_name_cb (GInetAddr * ia, gpointer data)
466 {
467   gboolean *p_called = (gboolean *) data;
468   gchar *name;
469 
470   *p_called = TRUE;
471 
472   fail_unless (ia != NULL);
473 
474   name = gnet_inetaddr_get_canonical_name (ia);
475   fail_unless (name != NULL);
476   fail_unless_equals_int (gnet_inetaddr_get_port (ia), 80);
477   g_free (name);
478 
479   gnet_inetaddr_unref (ia);
480 }
481 
482 static void
lookup_name_cb_do_nothing(GInetAddr * ia,gpointer data)483 lookup_name_cb_do_nothing (GInetAddr * ia, gpointer data)
484 {
485   gnet_inetaddr_unref (ia);
486 }
487 
488 static void
do_test_inetaddr_name_async(const gchar * hostname)489 do_test_inetaddr_name_async (const gchar * hostname)
490 {
491   GInetAddrNewAsyncID async_id;
492   GMainContext *ctx;
493   gboolean called, destroyed;
494   gint id;
495 
496   /* name async (default main context) */
497   called = FALSE;
498   async_id = gnet_inetaddr_new_async (hostname, 80, lookup_name_cb, &called);
499   fail_unless (async_id != NULL);
500   id = g_timeout_add (5 * 1000, (GSourceFunc) do_nothing_timeout, NULL);
501   g_main_context_iteration (NULL, TRUE);
502   fail_unless (called);
503   g_source_remove (id);
504 
505   /* name async + cancel (default main context) */
506   called = FALSE;
507   async_id = gnet_inetaddr_new_async (hostname, 80, lookup_name_cb, &called);
508   fail_unless (async_id != NULL);
509   gnet_inetaddr_new_async_cancel (async_id);
510   while (g_main_context_iteration (NULL, FALSE)) { ; }
511   fail_unless (!called);
512 
513   /* name async (destroy notify) */
514   destroyed = FALSE;
515   async_id = gnet_inetaddr_new_async_full (hostname, 80,
516       lookup_name_cb_do_nothing, &destroyed, destroy_notify, NULL,
517       G_PRIORITY_HIGH);
518   fail_unless (async_id != NULL);
519   g_main_context_iteration (NULL, TRUE);
520   fail_unless (destroyed);
521 
522   /* name async + cancel (destroy notify; thread unlikely to start) */
523   destroyed = FALSE;
524   async_id = gnet_inetaddr_new_async_full (hostname, 80,
525       lookup_name_cb_do_nothing, &destroyed, destroy_notify, NULL,
526       G_PRIORITY_HIGH);
527   fail_unless (async_id != NULL);
528   gnet_inetaddr_new_async_cancel (async_id);
529   /* give thread a chance to execute and act on the cancelled flag */
530   g_usleep (1 * G_USEC_PER_SEC);
531   fail_unless (destroyed);
532 
533   /* name async + cancel (destroy notify II) */
534   destroyed = FALSE;
535   async_id = gnet_inetaddr_new_async_full (hostname, 80,
536       lookup_name_cb_do_nothing, &destroyed, destroy_notify, NULL,
537       G_PRIORITY_HIGH);
538   fail_unless (async_id != NULL);
539   /* give thread a chance to execute and block before we cancel it */
540   g_usleep (1 * G_USEC_PER_SEC);
541   gnet_inetaddr_new_async_cancel (async_id);
542   fail_unless (destroyed);
543 
544   /* name async + cancel (destroy notify III) */
545   destroyed = FALSE;
546   async_id = gnet_inetaddr_new_async_full (hostname, 80,
547       lookup_name_cb_do_nothing, &destroyed, destroy_notify, NULL,
548       G_PRIORITY_HIGH);
549   fail_unless (async_id != NULL);
550   /* give thread a chance to execute and block and be done before cancelling */
551   g_usleep (3 * G_USEC_PER_SEC);
552   gnet_inetaddr_new_async_cancel (async_id);
553   fail_unless (destroyed);
554 
555   /* name async (custom main context) */
556   called = FALSE;
557   ctx = g_main_context_new ();
558   async_id = gnet_inetaddr_new_async_full (hostname, 80, lookup_name_cb,
559       &called, (GDestroyNotify) NULL, ctx, G_PRIORITY_HIGH);
560   /* give thread a chance to execute and block and be done */
561   g_usleep (3 * G_USEC_PER_SEC);
562   fail_unless (!called);
563   /* there shouldn't be anyhing pending in the default context */
564   fail_unless (!g_main_context_pending (NULL));
565   /* but there should be something pending in OUR context now */
566   fail_unless (g_main_context_pending (ctx));
567   fail_unless (!called);
568   /* let's iterate it and dispatch the callback */
569   fail_unless (g_main_context_iteration (ctx, FALSE));
570   fail_unless (called);
571   g_main_context_unref (ctx);
572 }
573 
GNET_START_TEST(test_inetaddr_name_async)574 GNET_START_TEST (test_inetaddr_name_async)
575 {
576   do_test_inetaddr_name_async ("localhost");
577 
578 /* FIXME: these might not work right yet because of the timings in the test
579 #ifdef GNET_ENABLE_NETWORK_TESTS
580   do_test_inetaddr_name_async ("www.google.com");
581 #endif
582 */
583 #ifdef HAVE_VALGRIND
584   if (RUNNING_ON_VALGRIND) {
585     g_print ("Sleeping for a while to let cancelled threads finish ...\n");
586     /* sleep a while to give any cancelled threads a chance to quit, otherwise
587      * valgrind will think the threads were leaked */
588     g_usleep (60 * G_USEC_PER_SEC);
589   }
590 #endif
591 }
592 GNET_END_TEST;
593 
594 static void
reverse_lookup_func(gchar * hostname,gpointer data)595 reverse_lookup_func (gchar * hostname, gpointer data)
596 {
597   /* should never be called, since we don't iterate the default main context */
598   g_assert_not_reached ();
599 }
600 
601 static void
do_test_inetaddr_reverse_async_ipv4_cancel(const gchar * ip_string)602 do_test_inetaddr_reverse_async_ipv4_cancel (const gchar * ip_string)
603 {
604   GInetAddrGetNameAsyncID async_id;
605   GInetAddr *ia;
606 
607   g_print ("Starting reverse lookup for %s ...", ip_string);
608   fflush (stdout);
609   ia = gnet_inetaddr_new_nonblock (ip_string, 80);
610   fail_unless (ia != NULL);
611 
612   ASSERT_CRITICAL (gnet_inetaddr_get_name_async (ia, NULL, NULL));
613 
614   async_id = gnet_inetaddr_get_name_async (ia, reverse_lookup_func, NULL);
615   fail_unless (async_id != NULL);
616   gnet_inetaddr_delete (ia);
617 
618   g_usleep (g_random_int_range (0, G_USEC_PER_SEC * 2));
619   gnet_inetaddr_get_name_async_cancel (async_id);
620   g_print (" cancelled.\n");
621 }
622 
GNET_START_TEST(test_inetaddr_reverse_async_ipv4_cancel)623 GNET_START_TEST (test_inetaddr_reverse_async_ipv4_cancel)
624 {
625   ASSERT_CRITICAL (
626       gnet_inetaddr_get_name_async (NULL, reverse_lookup_func, NULL)
627   );
628 
629   do_test_inetaddr_reverse_async_ipv4_cancel ("127.0.0.1");
630 
631 #ifdef GNET_ENABLE_NETWORK_TESTS
632   {
633     gint i;
634 
635     for (i = 0; i < 10; ++i) {
636 
637       if (i == 1) {
638         do_test_inetaddr_reverse_async_ipv4_cancel ("217.155.155.155");
639       } else if (i == 2) {
640         do_test_inetaddr_reverse_async_ipv4_cancel ("91.189.93.3");
641       } else {
642         gchar *ip_string;
643 
644         ip_string = g_strdup_printf ("%u.%u.%u.%u",
645             g_random_int_range (4, 250), g_random_int_range (0, 255),
646             g_random_int_range (0, 255), g_random_int_range (0, 255));
647         do_test_inetaddr_reverse_async_ipv4_cancel (ip_string);
648         g_free (ip_string);
649       }
650     }
651   }
652 #endif
653 
654 #ifdef HAVE_VALGRIND
655   if (RUNNING_ON_VALGRIND) {
656     g_print ("Sleeping for a while to let cancelled threads finish ...\n");
657     /* sleep a while to give any cancelled threads a chance to quit, otherwise
658      * valgrind will think the threads were leaked */
659     g_usleep (60 * G_USEC_PER_SEC);
660   }
661 #endif
662 }
663 GNET_END_TEST;
664 
665 static GInetAddr *current_ia; /* NULL */
666 
667 static void
lookup_reverse_cb(gchar * hostname,gpointer data)668 lookup_reverse_cb (gchar * hostname, gpointer data)
669 {
670   gboolean *p_called = (gboolean *) data;
671 
672   *p_called = TRUE;
673 
674   fail_unless (hostname != NULL);
675 
676   g_free (hostname);
677 }
678 
679 static void
lookup_reverse_cb_do_nothing(gchar * hostname,gpointer data)680 lookup_reverse_cb_do_nothing (gchar * hostname, gpointer data)
681 {
682   if (current_ia != NULL && hostname != NULL) {
683     gchar *can_name;
684 
685     can_name = gnet_inetaddr_get_canonical_name (current_ia);
686     g_print ("%s --> %s\n", can_name, hostname);
687     g_free (can_name);
688   }
689 
690   g_free (hostname);
691 }
692 
693 static void
do_test_inetaddr_reverse_async(const gchar * hostname)694 do_test_inetaddr_reverse_async (const gchar * hostname)
695 {
696   GInetAddrGetNameAsyncID async_id;
697   GMainContext *ctx;
698   GInetAddr *ia;
699   gboolean called, destroyed;
700   gchar *ip_string;
701   gint id;
702 
703   /* we assume the given host has a 1:1 IP<->hostname mapping */
704   ia = gnet_inetaddr_new (hostname, 80);
705   fail_unless (ia != NULL);
706   ip_string = gnet_inetaddr_get_canonical_name (ia);
707   fail_unless (ip_string != NULL);
708   gnet_inetaddr_unref (ia);
709   ia = NULL;
710 
711   g_print ("%s --> %s\n", hostname, ip_string);
712 
713   ia = gnet_inetaddr_new_nonblock (ip_string, 80);
714   fail_unless (ia != NULL);
715   current_ia = ia;
716 
717   /* name async (default main context) */
718   called = FALSE;
719   async_id = gnet_inetaddr_get_name_async (ia, lookup_reverse_cb, &called);
720   fail_unless (async_id != NULL);
721   id = g_timeout_add (10 * 1000, (GSourceFunc) do_nothing_timeout, NULL);
722   g_main_context_iteration (NULL, TRUE);
723   fail_unless (called);
724   g_source_remove (id);
725 
726   /* name async + cancel (default main context) */
727   called = FALSE;
728   async_id = gnet_inetaddr_get_name_async (ia, lookup_reverse_cb, &called);
729   fail_unless (async_id != NULL);
730   gnet_inetaddr_get_name_async_cancel (async_id);
731   while (g_main_context_iteration (NULL, FALSE)) { ; }
732   fail_unless (!called);
733 
734   /* name async (destroy notify) */
735   destroyed = FALSE;
736   async_id = gnet_inetaddr_get_name_async_full (ia,
737       lookup_reverse_cb_do_nothing, &destroyed, destroy_notify, NULL,
738       G_PRIORITY_HIGH);
739   fail_unless (async_id != NULL);
740   g_main_context_iteration (NULL, TRUE);
741   fail_unless (destroyed);
742 
743   /* name async + cancel (destroy notify; thread unlikely to start) */
744   destroyed = FALSE;
745   async_id = gnet_inetaddr_get_name_async_full (ia,
746       lookup_reverse_cb_do_nothing, &destroyed, destroy_notify, NULL,
747       G_PRIORITY_HIGH);
748   fail_unless (async_id != NULL);
749   gnet_inetaddr_get_name_async_cancel (async_id);
750   /* give thread a chance to execute and act on the cancelled flag */
751   g_usleep (1 * G_USEC_PER_SEC);
752   fail_unless (destroyed);
753 
754   /* name async + cancel (destroy notify II) */
755   destroyed = FALSE;
756   async_id = gnet_inetaddr_get_name_async_full (ia,
757       lookup_reverse_cb_do_nothing, &destroyed, destroy_notify, NULL,
758       G_PRIORITY_HIGH);
759   fail_unless (async_id != NULL);
760   /* give thread a chance to execute and block before we cancel it */
761   g_usleep (1 * G_USEC_PER_SEC);
762   gnet_inetaddr_get_name_async_cancel (async_id);
763   fail_unless (destroyed);
764 
765   /* name async + cancel (destroy notify III) */
766   destroyed = FALSE;
767   async_id = gnet_inetaddr_get_name_async_full (ia,
768       lookup_reverse_cb_do_nothing, &destroyed, destroy_notify, NULL,
769       G_PRIORITY_HIGH);
770   fail_unless (async_id != NULL);
771   /* give thread a chance to execute and block and be done before cancelling */
772   g_usleep (3 * G_USEC_PER_SEC);
773   gnet_inetaddr_get_name_async_cancel (async_id);
774   fail_unless (destroyed);
775 
776   /* name async (custom main context) */
777   called = FALSE;
778   ctx = g_main_context_new ();
779   async_id = gnet_inetaddr_get_name_async_full (ia, lookup_reverse_cb,
780       &called, (GDestroyNotify) NULL, ctx, G_PRIORITY_HIGH);
781   /* give thread a chance to execute and block and be done */
782   g_usleep (10 * G_USEC_PER_SEC);
783   fail_unless (!called);
784   /* there shouldn't be anyhing pending in the default context */
785   fail_unless (!g_main_context_pending (NULL));
786   /* but there should be something pending in OUR context now */
787   fail_unless (g_main_context_pending (ctx));
788   fail_unless (!called);
789   /* let's iterate it and dispatch the callback */
790   fail_unless (g_main_context_iteration (ctx, FALSE));
791   fail_unless (called);
792   g_main_context_unref (ctx);
793 
794   g_free (ip_string);
795   gnet_inetaddr_unref (ia);
796   current_ia = NULL;
797 }
798 
GNET_START_TEST(test_inetaddr_reverse_async)799 GNET_START_TEST (test_inetaddr_reverse_async)
800 {
801   do_test_inetaddr_reverse_async ("localhost");
802 
803 #ifdef GNET_ENABLE_NETWORK_TESTS
804   do_test_inetaddr_reverse_async ("gabe.freedesktop.org");
805 #endif
806 
807 #ifdef HAVE_VALGRIND
808   if (RUNNING_ON_VALGRIND) {
809     g_print ("Sleeping for a while to let cancelled threads finish ...\n");
810     /* sleep a while to give any cancelled threads a chance to quit, otherwise
811      * valgrind will think the threads were leaked */
812     g_usleep (60 * G_USEC_PER_SEC);
813   }
814 #endif
815 }
816 GNET_END_TEST;
817 
818 static Suite *
gnetinetaddr_suite(void)819 gnetinetaddr_suite (void)
820 {
821   Suite *s = suite_create ("GInetAddr");
822   TCase *tc_chain = tcase_create ("inetaddr");
823 
824   tcase_set_timeout (tc_chain, 0);
825 
826   suite_add_tcase (s, tc_chain);
827   tcase_add_test (tc_chain, test_inetaddr_is_internet_domainname);
828   tcase_add_test (tc_chain, test_inetaddr_ipv4);
829   tcase_add_test (tc_chain, test_inetaddr_is_ipv4);
830   tcase_add_test (tc_chain, test_inetaddr_list_async);
831   tcase_add_test (tc_chain, test_inetaddr_name_async);
832   tcase_add_test (tc_chain, test_inetaddr_reverse_async);
833   tcase_add_test (tc_chain, test_inetaddr_reverse_async_ipv4_cancel);
834 #if HAVE_IPV6
835   tcase_add_test (tc_chain, test_inetaddr_ipv6);
836   tcase_add_test (tc_chain, test_inetaddr_is_ipv6);
837 #endif
838 
839 
840   return s;
841 }
842 
843 GNET_CHECK_MAIN (gnetinetaddr);
844 
845