3901cff14d50fb1be972cc49013eddddbc63ba60
[platform/upstream/glib.git] / gio / tests / socket.c
1 /* GLib testing framework examples and tests
2  *
3  * Copyright (C) 2008-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/gio.h>
20
21 #ifdef G_OS_UNIX
22 #include <errno.h>
23 #include <sys/wait.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <gio/gnetworking.h>
27 #include <gio/gunixconnection.h>
28 #endif
29
30 #include "gnetworkingprivate.h"
31
32 static gboolean ipv6_supported;
33
34 typedef struct {
35   GSocket *server;
36   GSocket *client;
37   GSocketFamily family;
38   GThread *thread;
39   GMainLoop *loop;
40 } IPTestData;
41
42 static gpointer
43 echo_server_thread (gpointer user_data)
44 {
45   IPTestData *data = user_data;
46   GSocket *sock;
47   GError *error = NULL;
48   gssize nread, nwrote;
49   gchar buf[128];
50
51   sock = g_socket_accept (data->server, NULL, &error);
52   g_assert_no_error (error);
53
54   while (TRUE)
55     {
56       nread = g_socket_receive (sock, buf, sizeof (buf), NULL, &error);
57       g_assert_no_error (error);
58       g_assert_cmpint (nread, >=, 0);
59
60       if (nread == 0)
61         break;
62
63       nwrote = g_socket_send (sock, buf, nread, NULL, &error);
64       g_assert_no_error (error);
65       g_assert_cmpint (nwrote, ==, nread);
66     }
67
68   g_socket_close (sock, &error);
69   g_assert_no_error (error);
70   g_object_unref (sock);
71   return NULL;
72 }
73
74 static IPTestData *
75 create_server (GSocketFamily family,
76                GThreadFunc   server_thread,
77                gboolean      v4mapped)
78 {
79   IPTestData *data;
80   GSocket *server;
81   GError *error = NULL;
82   GSocketAddress *addr;
83   GInetAddress *iaddr;
84
85   data = g_slice_new (IPTestData);
86   data->family = family;
87
88   data->server = server = g_socket_new (family,
89                                         G_SOCKET_TYPE_STREAM,
90                                         G_SOCKET_PROTOCOL_DEFAULT,
91                                         &error);
92   g_assert_no_error (error);
93
94   g_assert_cmpint (g_socket_get_family (server), ==, family);
95   g_assert_cmpint (g_socket_get_socket_type (server), ==, G_SOCKET_TYPE_STREAM);
96   g_assert_cmpint (g_socket_get_protocol (server), ==, G_SOCKET_PROTOCOL_DEFAULT);
97
98   g_socket_set_blocking (server, TRUE);
99
100 #if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY)
101   if (v4mapped)
102     {
103       g_socket_set_option (data->server, IPPROTO_IPV6, IPV6_V6ONLY, FALSE, NULL);
104       if (! g_socket_speaks_ipv4 (data->server))
105         {
106           g_object_unref (data->server);
107           g_slice_free (IPTestData, data);
108           return NULL;
109         }
110     }
111 #endif
112
113   if (v4mapped)
114     iaddr = g_inet_address_new_any (family);
115   else
116     iaddr = g_inet_address_new_loopback (family);
117   addr = g_inet_socket_address_new (iaddr, 0);
118   g_object_unref (iaddr);
119
120   g_assert_cmpint (g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)), ==, 0);
121   g_socket_bind (server, addr, TRUE, &error);
122   g_assert_no_error (error);
123   g_object_unref (addr);
124
125   addr = g_socket_get_local_address (server, &error);
126   g_assert_no_error (error);
127   g_assert_cmpint (g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)), !=, 0);
128   g_object_unref (addr);
129
130   g_socket_listen (server, &error);
131   g_assert_no_error (error);
132
133   data->thread = g_thread_new ("server", server_thread, data);
134
135   return data;
136 }
137
138 static const gchar *testbuf = "0123456789abcdef";
139
140 static gboolean
141 test_ip_async_read_ready (GSocket      *client,
142                           GIOCondition  cond,
143                           gpointer      user_data)
144 {
145   IPTestData *data = user_data;
146   GError *error = NULL;
147   gssize len;
148   gchar buf[128];
149
150   g_assert_cmpint (cond, ==, G_IO_IN);
151
152   len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
153   g_assert_no_error (error);
154   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
155
156   g_assert_cmpstr (testbuf, ==, buf);
157
158   g_main_loop_quit (data->loop);
159
160   return FALSE;
161 }
162
163 static gboolean
164 test_ip_async_write_ready (GSocket      *client,
165                            GIOCondition  cond,
166                            gpointer      user_data)
167 {
168   IPTestData *data = user_data;
169   GError *error = NULL;
170   GSource *source;
171   gssize len;
172
173   g_assert_cmpint (cond, ==, G_IO_OUT);
174
175   len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error);
176   g_assert_no_error (error);
177   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
178
179   source = g_socket_create_source (client, G_IO_IN, NULL);
180   g_source_set_callback (source, (GSourceFunc)test_ip_async_read_ready,
181                          data, NULL);
182   g_source_attach (source, NULL);
183   g_source_unref (source);
184
185   return FALSE;
186 }
187
188 static gboolean
189 test_ip_async_timed_out (GSocket      *client,
190                          GIOCondition  cond,
191                          gpointer      user_data)
192 {
193   IPTestData *data = user_data;
194   GError *error = NULL;
195   GSource *source;
196   gssize len;
197   gchar buf[128];
198
199   if (data->family == G_SOCKET_FAMILY_IPV4)
200     {
201       g_assert_cmpint (cond, ==, G_IO_IN);
202       len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
203       g_assert_cmpint (len, ==, -1);
204       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
205       g_clear_error (&error);
206     }
207
208   source = g_socket_create_source (client, G_IO_OUT, NULL);
209   g_source_set_callback (source, (GSourceFunc)test_ip_async_write_ready,
210                          data, NULL);
211   g_source_attach (source, NULL);
212   g_source_unref (source);
213
214   return FALSE;
215 }
216
217 static gboolean
218 test_ip_async_connected (GSocket      *client,
219                          GIOCondition  cond,
220                          gpointer      user_data)
221 {
222   IPTestData *data = user_data;
223   GError *error = NULL;
224   GSource *source;
225   gssize len;
226   gchar buf[128];
227
228   g_socket_check_connect_result (client, &error);
229   g_assert_no_error (error);
230   /* We do this after the check_connect_result, since that will give a
231    * more useful assertion in case of error.
232    */
233   g_assert_cmpint (cond, ==, G_IO_OUT);
234
235   g_assert (g_socket_is_connected (client));
236
237   /* This adds 1 second to "make check", so let's just only do it once. */
238   if (data->family == G_SOCKET_FAMILY_IPV4)
239     {
240       len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
241       g_assert_cmpint (len, ==, -1);
242       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
243       g_clear_error (&error);
244
245       source = g_socket_create_source (client, G_IO_IN, NULL);
246       g_source_set_callback (source, (GSourceFunc)test_ip_async_timed_out,
247                              data, NULL);
248       g_source_attach (source, NULL);
249       g_source_unref (source);
250     }
251   else
252     test_ip_async_timed_out (client, 0, data);
253
254   return FALSE;
255 }
256
257 static gboolean
258 idle_test_ip_async_connected (gpointer user_data)
259 {
260   IPTestData *data = user_data;
261
262   return test_ip_async_connected (data->client, G_IO_OUT, data);
263 }
264
265 static void
266 test_ip_async (GSocketFamily family)
267 {
268   IPTestData *data;
269   GError *error = NULL;
270   GSocket *client;
271   GSocketAddress *addr;
272   GSource *source;
273   gssize len;
274   gchar buf[128];
275
276   data = create_server (family, echo_server_thread, FALSE);
277   addr = g_socket_get_local_address (data->server, &error);
278
279   client = g_socket_new (family,
280                          G_SOCKET_TYPE_STREAM,
281                          G_SOCKET_PROTOCOL_DEFAULT,
282                          &error);
283   g_assert_no_error (error);
284   data->client = client;
285
286   g_assert_cmpint (g_socket_get_family (client), ==, family);
287   g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
288   g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
289
290   g_socket_set_blocking (client, FALSE);
291   g_socket_set_timeout (client, 1);
292
293   if (g_socket_connect (client, addr, NULL, &error))
294     {
295       g_assert_no_error (error);
296       g_idle_add (idle_test_ip_async_connected, data);
297     }
298   else
299     {
300       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PENDING);
301       g_clear_error (&error);
302       source = g_socket_create_source (client, G_IO_OUT, NULL);
303       g_source_set_callback (source, (GSourceFunc)test_ip_async_connected,
304                              data, NULL);
305       g_source_attach (source, NULL);
306       g_source_unref (source);
307     }
308   g_object_unref (addr);
309
310   data->loop = g_main_loop_new (NULL, TRUE);
311   g_main_loop_run (data->loop);
312   g_main_loop_unref (data->loop);
313
314   g_socket_shutdown (client, FALSE, TRUE, &error);
315   g_assert_no_error (error);
316
317   g_thread_join (data->thread);
318
319   len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
320   g_assert_no_error (error);
321   g_assert_cmpint (len, ==, 0);
322
323   g_socket_close (client, &error);
324   g_assert_no_error (error);
325   g_socket_close (data->server, &error);
326   g_assert_no_error (error);
327
328   g_object_unref (data->server);
329   g_object_unref (client);
330
331   g_slice_free (IPTestData, data);
332 }
333
334 static void
335 test_ipv4_async (void)
336 {
337   test_ip_async (G_SOCKET_FAMILY_IPV4);
338 }
339
340 static void
341 test_ipv6_async (void)
342 {
343   if (!ipv6_supported)
344     {
345       g_test_skip ("No support for IPv6");
346       return;
347     }
348
349   test_ip_async (G_SOCKET_FAMILY_IPV6);
350 }
351
352 static void
353 test_ip_sync (GSocketFamily family)
354 {
355   IPTestData *data;
356   GError *error = NULL;
357   GSocket *client;
358   GSocketAddress *addr;
359   gssize len;
360   gchar buf[128];
361
362   data = create_server (family, echo_server_thread, FALSE);
363   addr = g_socket_get_local_address (data->server, &error);
364
365   client = g_socket_new (family,
366                          G_SOCKET_TYPE_STREAM,
367                          G_SOCKET_PROTOCOL_DEFAULT,
368                          &error);
369   g_assert_no_error (error);
370
371   g_assert_cmpint (g_socket_get_family (client), ==, family);
372   g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
373   g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
374
375   g_socket_set_blocking (client, TRUE);
376   g_socket_set_timeout (client, 1);
377
378   g_socket_connect (client, addr, NULL, &error);
379   g_assert_no_error (error);
380   g_assert (g_socket_is_connected (client));
381   g_object_unref (addr);
382
383   /* This adds 1 second to "make check", so let's just only do it once. */
384   if (family == G_SOCKET_FAMILY_IPV4)
385     {
386       len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
387       g_assert_cmpint (len, ==, -1);
388       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
389       g_clear_error (&error);
390     }
391
392   len = g_socket_send (client, testbuf, strlen (testbuf) + 1, NULL, &error);
393   g_assert_no_error (error);
394   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
395   
396   len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
397   g_assert_no_error (error);
398   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
399
400   g_assert_cmpstr (testbuf, ==, buf);
401
402   g_socket_shutdown (client, FALSE, TRUE, &error);
403   g_assert_no_error (error);
404
405   g_thread_join (data->thread);
406
407   len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
408   g_assert_no_error (error);
409   g_assert_cmpint (len, ==, 0);
410
411   g_socket_close (client, &error);
412   g_assert_no_error (error);
413   g_socket_close (data->server, &error);
414   g_assert_no_error (error);
415
416   g_object_unref (data->server);
417   g_object_unref (client);
418
419   g_slice_free (IPTestData, data);
420 }
421
422 static void
423 test_ipv4_sync (void)
424 {
425   test_ip_sync (G_SOCKET_FAMILY_IPV4);
426 }
427
428 static void
429 test_ipv6_sync (void)
430 {
431   if (!ipv6_supported)
432     {
433       g_test_skip ("No support for IPv6");
434       return;
435     }
436
437   test_ip_sync (G_SOCKET_FAMILY_IPV6);
438 }
439
440 static gpointer
441 graceful_server_thread (gpointer user_data)
442 {
443   IPTestData *data = user_data;
444   GSocket *sock;
445   GError *error = NULL;
446   gssize len;
447
448   sock = g_socket_accept (data->server, NULL, &error);
449   g_assert_no_error (error);
450
451   len = g_socket_send (sock, testbuf, strlen (testbuf) + 1, NULL, &error);
452   g_assert_no_error (error);
453   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
454
455   return sock;
456 }
457
458 static void
459 test_close_graceful (void)
460 {
461   GSocketFamily family = G_SOCKET_FAMILY_IPV4;
462   IPTestData *data;
463   GError *error = NULL;
464   GSocket *client, *server;
465   GSocketAddress *addr;
466   gssize len;
467   gchar buf[128];
468
469   data = create_server (family, graceful_server_thread, FALSE);
470   addr = g_socket_get_local_address (data->server, &error);
471
472   client = g_socket_new (family,
473                          G_SOCKET_TYPE_STREAM,
474                          G_SOCKET_PROTOCOL_DEFAULT,
475                          &error);
476   g_assert_no_error (error);
477
478   g_assert_cmpint (g_socket_get_family (client), ==, family);
479   g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
480   g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
481
482   g_socket_set_blocking (client, TRUE);
483   g_socket_set_timeout (client, 1);
484
485   g_socket_connect (client, addr, NULL, &error);
486   g_assert_no_error (error);
487   g_assert (g_socket_is_connected (client));
488   g_object_unref (addr);
489
490   server = g_thread_join (data->thread);
491
492   /* similar to g_tcp_connection_set_graceful_disconnect(), but explicit */
493   g_socket_shutdown (server, FALSE, TRUE, &error);
494   g_assert_no_error (error);
495
496   /* we must timeout */
497   g_socket_condition_wait (client, G_IO_HUP, NULL, &error);
498   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
499   g_clear_error (&error);
500
501   /* check that the remaining data is received */
502   len = g_socket_receive (client, buf, strlen (testbuf) + 1, NULL, &error);
503   g_assert_no_error (error);
504   g_assert_cmpint (len, ==, strlen (testbuf) + 1);
505
506   /* and only then the connection is closed */
507   len = g_socket_receive (client, buf, sizeof (buf), NULL, &error);
508   g_assert_no_error (error);
509   g_assert_cmpint (len, ==, 0);
510
511   g_socket_close (server, &error);
512   g_assert_no_error (error);
513
514   g_socket_close (client, &error);
515   g_assert_no_error (error);
516
517   g_object_unref (server);
518   g_object_unref (data->server);
519   g_object_unref (client);
520
521   g_slice_free (IPTestData, data);
522 }
523
524 #if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY)
525 static gpointer
526 v4mapped_server_thread (gpointer user_data)
527 {
528   IPTestData *data = user_data;
529   GSocket *sock;
530   GError *error = NULL;
531   GSocketAddress *addr;
532
533   sock = g_socket_accept (data->server, NULL, &error);
534   g_assert_no_error (error);
535
536   g_assert_cmpint (g_socket_get_family (sock), ==, G_SOCKET_FAMILY_IPV6);
537
538   addr = g_socket_get_local_address (sock, &error);
539   g_assert_no_error (error);
540   g_assert_cmpint (g_socket_address_get_family (addr), ==, G_SOCKET_FAMILY_IPV4);
541   g_object_unref (addr);
542
543   addr = g_socket_get_remote_address (sock, &error);
544   g_assert_no_error (error);
545   g_assert_cmpint (g_socket_address_get_family (addr), ==, G_SOCKET_FAMILY_IPV4);
546   g_object_unref (addr);
547
548   g_socket_close (sock, &error);
549   g_assert_no_error (error);
550   g_object_unref (sock);
551   return NULL;
552 }
553
554 static void
555 test_ipv6_v4mapped (void)
556 {
557   IPTestData *data;
558   GError *error = NULL;
559   GSocket *client;
560   GSocketAddress *addr, *v4addr;
561   GInetAddress *iaddr;
562
563   if (!ipv6_supported)
564     {
565       g_test_skip ("No support for IPv6");
566       return;
567     }
568
569   data = create_server (G_SOCKET_FAMILY_IPV6, v4mapped_server_thread, TRUE);
570
571   if (data == NULL)
572     {
573       g_test_message ("Test not run: not supported by the OS");
574       return;
575     }
576
577   client = g_socket_new (G_SOCKET_FAMILY_IPV4,
578                          G_SOCKET_TYPE_STREAM,
579                          G_SOCKET_PROTOCOL_DEFAULT,
580                          &error);
581   g_assert_no_error (error);
582
583   g_socket_set_blocking (client, TRUE);
584   g_socket_set_timeout (client, 1);
585
586   addr = g_socket_get_local_address (data->server, &error);
587   iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
588   v4addr = g_inet_socket_address_new (iaddr, g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)));
589   g_object_unref (iaddr);
590   g_object_unref (addr);
591
592   g_socket_connect (client, v4addr, NULL, &error);
593   g_assert_no_error (error);
594   g_assert (g_socket_is_connected (client));
595
596   g_thread_join (data->thread);
597
598   g_socket_close (client, &error);
599   g_assert_no_error (error);
600   g_socket_close (data->server, &error);
601   g_assert_no_error (error);
602
603   g_object_unref (data->server);
604   g_object_unref (client);
605   g_object_unref (v4addr);
606
607   g_slice_free (IPTestData, data);
608 }
609 #endif
610
611 static void
612 test_timed_wait (void)
613 {
614   IPTestData *data;
615   GError *error = NULL;
616   GSocket *client;
617   GSocketAddress *addr;
618   gint64 start_time;
619   gint poll_duration;
620
621   data = create_server (G_SOCKET_FAMILY_IPV4, echo_server_thread, FALSE);
622   addr = g_socket_get_local_address (data->server, &error);
623
624   client = g_socket_new (G_SOCKET_FAMILY_IPV4,
625                          G_SOCKET_TYPE_STREAM,
626                          G_SOCKET_PROTOCOL_DEFAULT,
627                          &error);
628   g_assert_no_error (error);
629
630   g_socket_set_blocking (client, TRUE);
631   g_socket_set_timeout (client, 1);
632
633   g_socket_connect (client, addr, NULL, &error);
634   g_assert_no_error (error);
635   g_object_unref (addr);
636
637   start_time = g_get_monotonic_time ();
638   g_socket_condition_timed_wait (client, G_IO_IN, 100000 /* 100 ms */,
639                                  NULL, &error);
640   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
641   g_clear_error (&error);
642   poll_duration = g_get_monotonic_time () - start_time;
643
644   g_assert_cmpint (poll_duration, >=, 98000);
645   g_assert_cmpint (poll_duration, <, 112000);
646
647   g_socket_close (client, &error);
648   g_assert_no_error (error);
649
650   g_thread_join (data->thread);
651
652   g_socket_close (data->server, &error);
653   g_assert_no_error (error);
654
655   g_object_unref (data->server);
656   g_object_unref (client);
657
658   g_slice_free (IPTestData, data);
659 }
660
661 static void
662 test_sockaddr (void)
663 {
664   struct sockaddr_in6 sin6, gsin6;
665   GSocketAddress *saddr;
666   GInetSocketAddress *isaddr;
667   GInetAddress *iaddr;
668   GError *error = NULL;
669
670   memset (&sin6, 0, sizeof (sin6));
671   sin6.sin6_family = AF_INET6;
672   sin6.sin6_addr = in6addr_loopback;
673   sin6.sin6_port = g_htons (42);
674   sin6.sin6_scope_id = 17;
675   sin6.sin6_flowinfo = 1729;
676
677   saddr = g_socket_address_new_from_native (&sin6, sizeof (sin6));
678   g_assert (G_IS_INET_SOCKET_ADDRESS (saddr));
679
680   isaddr = G_INET_SOCKET_ADDRESS (saddr);
681   iaddr = g_inet_socket_address_get_address (isaddr);
682   g_assert_cmpint (g_inet_address_get_family (iaddr), ==, G_SOCKET_FAMILY_IPV6);
683   g_assert (g_inet_address_get_is_loopback (iaddr));
684
685   g_assert_cmpint (g_inet_socket_address_get_port (isaddr), ==, 42);
686   g_assert_cmpint (g_inet_socket_address_get_scope_id (isaddr), ==, 17);
687   g_assert_cmpint (g_inet_socket_address_get_flowinfo (isaddr), ==, 1729);
688
689   g_socket_address_to_native (saddr, &gsin6, sizeof (gsin6), &error);
690   g_assert_no_error (error);
691
692   g_assert (memcmp (&sin6.sin6_addr, &gsin6.sin6_addr, sizeof (struct in6_addr)) == 0);
693   g_assert_cmpint (sin6.sin6_port, ==, gsin6.sin6_port);
694   g_assert_cmpint (sin6.sin6_scope_id, ==, gsin6.sin6_scope_id);
695   g_assert_cmpint (sin6.sin6_flowinfo, ==, gsin6.sin6_flowinfo);
696
697   g_object_unref (saddr);
698 }
699
700 #ifdef G_OS_UNIX
701 static void
702 test_unix_from_fd (void)
703 {
704   gint fd;
705   GError *error;
706   GSocket *s;
707
708   fd = socket (AF_UNIX, SOCK_STREAM, 0);
709   g_assert_cmpint (fd, !=, -1);
710
711   error = NULL;
712   s = g_socket_new_from_fd (fd, &error);
713   g_assert_no_error (error);
714   g_assert_cmpint (g_socket_get_family (s), ==, G_SOCKET_FAMILY_UNIX);
715   g_assert_cmpint (g_socket_get_socket_type (s), ==, G_SOCKET_TYPE_STREAM);
716   g_assert_cmpint (g_socket_get_protocol (s), ==, G_SOCKET_PROTOCOL_DEFAULT);
717   g_object_unref (s);
718 }
719
720 static void
721 test_unix_connection (void)
722 {
723   gint fd;
724   GError *error;
725   GSocket *s;
726   GSocketConnection *c;
727
728   fd = socket (AF_UNIX, SOCK_STREAM, 0);
729   g_assert_cmpint (fd, !=, -1);
730
731   error = NULL;
732   s = g_socket_new_from_fd (fd, &error);
733   g_assert_no_error (error);
734   c = g_socket_connection_factory_create_connection (s);
735   g_assert (G_IS_UNIX_CONNECTION (c));
736   g_object_unref (c);
737   g_object_unref (s);
738 }
739
740 static GSocketConnection *
741 create_connection_for_fd (int fd)
742 {
743   GError *err = NULL;
744   GSocket *socket;
745   GSocketConnection *connection;
746
747   socket = g_socket_new_from_fd (fd, &err);
748   g_assert_no_error (err);
749   g_assert (G_IS_SOCKET (socket));
750   connection = g_socket_connection_factory_create_connection (socket);
751   g_assert (G_IS_UNIX_CONNECTION (connection));
752   g_object_unref (socket);
753   return connection;
754 }
755
756 #define TEST_DATA "failure to say failure to say 'i love gnome-panel!'."
757
758 static void
759 test_unix_connection_ancillary_data (void)
760 {
761   GError *err = NULL;
762   gint pv[2], sv[3];
763   gint status, fd, len;
764   char buffer[1024];
765   pid_t pid;
766
767   status = pipe (pv);
768   g_assert_cmpint (status, ==, 0);
769
770   status = socketpair (PF_UNIX, SOCK_STREAM, 0, sv);
771   g_assert_cmpint (status, ==, 0);
772
773   pid = fork ();
774   g_assert_cmpint (pid, >=, 0);
775
776   /* Child: close its copy of the write end of the pipe, receive it
777    * again from the parent over the socket, and write some text to it.
778    *
779    * Parent: send the write end of the pipe (still open for the
780    * parent) over the socket, close it, and read some text from the
781    * read end of the pipe.
782    */
783   if (pid == 0)
784     {
785       GSocketConnection *connection;
786
787       close (sv[1]);
788       connection = create_connection_for_fd (sv[0]);
789
790       status = close (pv[1]);
791       g_assert_cmpint (status, ==, 0);
792
793       err = NULL;
794       fd = g_unix_connection_receive_fd (G_UNIX_CONNECTION (connection), NULL,
795                                          &err);
796       g_assert_no_error (err);
797       g_assert_cmpint (fd, >, -1);
798       g_object_unref (connection);
799
800       do
801         len = write (fd, TEST_DATA, sizeof (TEST_DATA));
802       while (len == -1 && errno == EINTR);
803       g_assert_cmpint (len, ==, sizeof (TEST_DATA));
804       exit (0);
805     }
806   else
807     {
808       GSocketConnection *connection;
809
810       close (sv[0]);
811       connection = create_connection_for_fd (sv[1]);
812
813       err = NULL;
814       g_unix_connection_send_fd (G_UNIX_CONNECTION (connection), pv[1], NULL,
815                                  &err);
816       g_assert_no_error (err);
817       g_object_unref (connection);
818
819       status = close (pv[1]);
820       g_assert_cmpint (status, ==, 0);
821
822       memset (buffer, 0xff, sizeof buffer);
823       do
824         len = read (pv[0], buffer, sizeof buffer);
825       while (len == -1 && errno == EINTR);
826
827       g_assert_cmpint (len, ==, sizeof (TEST_DATA));
828       g_assert_cmpstr (buffer, ==, TEST_DATA);
829
830       waitpid (pid, &status, 0);
831       g_assert (WIFEXITED (status));
832       g_assert_cmpint (WEXITSTATUS (status), ==, 0);
833     }
834
835   /* TODO: add test for g_unix_connection_send_credentials() and
836    * g_unix_connection_receive_credentials().
837    */
838 }
839 #endif /* G_OS_UNIX */
840
841 static void
842 test_reuse_tcp (void)
843 {
844   GSocket *sock1, *sock2;
845   GError *error = NULL;
846   GInetAddress *iaddr;
847   GSocketAddress *addr;
848
849   sock1 = g_socket_new (G_SOCKET_FAMILY_IPV4,
850                         G_SOCKET_TYPE_STREAM,
851                         G_SOCKET_PROTOCOL_DEFAULT,
852                         &error);
853   g_assert_no_error (error);
854
855   iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
856   addr = g_inet_socket_address_new (iaddr, 0);
857   g_object_unref (iaddr);
858   g_socket_bind (sock1, addr, TRUE, &error);
859   g_object_unref (addr);
860   g_assert_no_error (error);
861
862   g_socket_listen (sock1, &error);
863   g_assert_no_error (error);
864
865   sock2 = g_socket_new (G_SOCKET_FAMILY_IPV4,
866                         G_SOCKET_TYPE_STREAM,
867                         G_SOCKET_PROTOCOL_DEFAULT,
868                         &error);
869   g_assert_no_error (error);
870
871   addr = g_socket_get_local_address (sock1, &error);
872   g_assert_no_error (error);
873   g_socket_bind (sock2, addr, TRUE, &error);
874   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_ADDRESS_IN_USE);
875   g_clear_error (&error);
876   g_object_unref (addr);
877
878   g_object_unref (sock1);
879   g_object_unref (sock2);
880 }
881
882 static void
883 test_reuse_udp (void)
884 {
885   GSocket *sock1, *sock2;
886   GError *error = NULL;
887   GInetAddress *iaddr;
888   GSocketAddress *addr;
889
890   sock1 = g_socket_new (G_SOCKET_FAMILY_IPV4,
891                         G_SOCKET_TYPE_DATAGRAM,
892                         G_SOCKET_PROTOCOL_DEFAULT,
893                         &error);
894   g_assert_no_error (error);
895
896   iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
897   addr = g_inet_socket_address_new (iaddr, 0);
898   g_object_unref (iaddr);
899   g_socket_bind (sock1, addr, TRUE, &error);
900   g_object_unref (addr);
901   g_assert_no_error (error);
902
903   sock2 = g_socket_new (G_SOCKET_FAMILY_IPV4,
904                         G_SOCKET_TYPE_DATAGRAM,
905                         G_SOCKET_PROTOCOL_DEFAULT,
906                         &error);
907   g_assert_no_error (error);
908
909   addr = g_socket_get_local_address (sock1, &error);
910   g_assert_no_error (error);
911   g_socket_bind (sock2, addr, TRUE, &error);
912   g_object_unref (addr);
913   g_assert_no_error (error);
914
915   g_object_unref (sock1);
916   g_object_unref (sock2);
917 }
918
919 static void
920 test_get_available (gconstpointer user_data)
921 {
922   GSocketType socket_type = GPOINTER_TO_UINT (user_data);
923   GError *err = NULL;
924   GSocket *listener, *server, *client;
925   GInetAddress *addr;
926   GSocketAddress *saddr;
927   gchar data[] = "0123456789abcdef";
928   gchar buf[34];
929   gssize nread;
930
931   listener = g_socket_new (G_SOCKET_FAMILY_IPV4,
932                            socket_type,
933                            G_SOCKET_PROTOCOL_DEFAULT,
934                            &err);
935   g_assert_no_error (err);
936   g_assert (G_IS_SOCKET (listener));
937
938   client = g_socket_new (G_SOCKET_FAMILY_IPV4,
939                          socket_type,
940                          G_SOCKET_PROTOCOL_DEFAULT,
941                          &err);
942   g_assert_no_error (err);
943   g_assert (G_IS_SOCKET (client));
944
945   if (socket_type == G_SOCKET_TYPE_STREAM)
946     {
947       g_socket_set_option (client, IPPROTO_TCP, TCP_NODELAY, TRUE, &err);
948       g_assert_no_error (err);
949     }
950
951   addr = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
952   saddr = g_inet_socket_address_new (addr, 0);
953
954   g_socket_bind (listener, saddr, TRUE, &err);
955   g_assert_no_error (err);
956   g_object_unref (saddr);
957   g_object_unref (addr);
958
959   saddr = g_socket_get_local_address (listener, &err);
960   g_assert_no_error (err);
961
962   if (socket_type == G_SOCKET_TYPE_STREAM)
963     {
964       g_socket_listen (listener, &err);
965       g_assert_no_error (err);
966       g_socket_connect (client, saddr, NULL, &err);
967       g_assert_no_error (err);
968
969       server = g_socket_accept (listener, NULL, &err);
970       g_assert_no_error (err);
971       g_socket_set_blocking (server, FALSE);
972       g_object_unref (listener);
973     }
974   else
975     server = listener;
976
977   g_socket_send_to (client, saddr, data, sizeof (data), NULL, &err);
978   g_assert_no_error (err);
979
980   while (!g_socket_condition_wait (server, G_IO_IN, NULL, NULL))
981     ;
982   g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data));
983
984   g_socket_send_to (client, saddr, data, sizeof (data), NULL, &err);
985   g_assert_no_error (err);
986
987   /* We need to wait until the data has actually been copied into the
988    * server socket's buffers, but g_socket_condition_wait() won't help
989    * here since the socket is definitely already readable. So there's
990    * a race condition in checking its available bytes. In the TCP
991    * case, we poll for a bit until the new data shows up. In the UDP
992    * case, there's not much we can do, but at least the failure mode
993    * is passes-when-it-shouldn't, not fails-when-it-shouldn't.
994    */
995   if (socket_type == G_SOCKET_TYPE_STREAM)
996     {
997       int tries;
998
999       for (tries = 0; tries < 100; tries++)
1000         {
1001           if (g_socket_get_available_bytes (server) > sizeof (data))
1002             break;
1003           g_usleep (100000);
1004         }
1005
1006       g_assert_cmpint (g_socket_get_available_bytes (server), ==, 2 * sizeof (data));
1007     }
1008   else
1009     {
1010       g_usleep (100000);
1011       g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data));
1012     }
1013
1014   g_assert_cmpint (sizeof (buf), >=, 2 * sizeof (data));
1015   nread = g_socket_receive (server, buf, sizeof (buf), NULL, &err);
1016   g_assert_no_error (err);
1017
1018   if (socket_type == G_SOCKET_TYPE_STREAM)
1019     {
1020       g_assert_cmpint (nread, ==, 2 * sizeof (data));
1021       g_assert_cmpint (g_socket_get_available_bytes (server), ==, 0);
1022     }
1023   else
1024     {
1025       g_assert_cmpint (nread, ==, sizeof (data));
1026       g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data));
1027     }
1028
1029   nread = g_socket_receive (server, buf, sizeof (buf), NULL, &err);
1030   if (socket_type == G_SOCKET_TYPE_STREAM)
1031     {
1032       g_assert_cmpint (nread, ==, -1);
1033       g_assert_error (err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
1034       g_clear_error (&err);
1035     }
1036   else
1037     {
1038       g_assert_cmpint (nread, ==, sizeof (data));
1039       g_assert_no_error (err);
1040     }
1041
1042   g_assert_cmpint (g_socket_get_available_bytes (server), ==, 0);
1043
1044   g_socket_close (server, &err);
1045   g_assert_no_error (err);
1046
1047   g_object_unref (saddr);
1048   g_object_unref (server);
1049   g_object_unref (client);
1050 }
1051
1052 int
1053 main (int   argc,
1054       char *argv[])
1055 {
1056   GSocket *sock;
1057   GError *error = NULL;
1058
1059   g_test_init (&argc, &argv, NULL);
1060
1061   sock = g_socket_new (G_SOCKET_FAMILY_IPV6,
1062                        G_SOCKET_TYPE_STREAM,
1063                        G_SOCKET_PROTOCOL_DEFAULT,
1064                        &error);
1065   if (sock != NULL)
1066     {
1067       ipv6_supported = TRUE;
1068       g_object_unref (sock);
1069     }
1070   else
1071     {
1072       g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1073       g_clear_error (&error);
1074     }
1075
1076   g_test_add_func ("/socket/ipv4_sync", test_ipv4_sync);
1077   g_test_add_func ("/socket/ipv4_async", test_ipv4_async);
1078   g_test_add_func ("/socket/ipv6_sync", test_ipv6_sync);
1079   g_test_add_func ("/socket/ipv6_async", test_ipv6_async);
1080 #if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY)
1081   g_test_add_func ("/socket/ipv6_v4mapped", test_ipv6_v4mapped);
1082 #endif
1083   g_test_add_func ("/socket/close_graceful", test_close_graceful);
1084   g_test_add_func ("/socket/timed_wait", test_timed_wait);
1085   g_test_add_func ("/socket/address", test_sockaddr);
1086 #ifdef G_OS_UNIX
1087   g_test_add_func ("/socket/unix-from-fd", test_unix_from_fd);
1088   g_test_add_func ("/socket/unix-connection", test_unix_connection);
1089   g_test_add_func ("/socket/unix-connection-ancillary-data", test_unix_connection_ancillary_data);
1090 #endif
1091   g_test_add_func ("/socket/reuse/tcp", test_reuse_tcp);
1092   g_test_add_func ("/socket/reuse/udp", test_reuse_udp);
1093   g_test_add_data_func ("/socket/get_available/datagram", GUINT_TO_POINTER (G_SOCKET_TYPE_DATAGRAM),
1094                         test_get_available);
1095   g_test_add_data_func ("/socket/get_available/stream", GUINT_TO_POINTER (G_SOCKET_TYPE_STREAM),
1096                         test_get_available);
1097
1098   return g_test_run();
1099 }
1100