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.1 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#include <gio/gcredentialsprivate.h>
22#ifdef G_OS_UNIX
23#include <errno.h>
24#include <sys/wait.h>
25#include <string.h>
26#include <stdlib.h>
27#include <gio/gnetworking.h>
28#include <gio/gunixconnection.h>
29#endif
30
31#include "gnetworkingprivate.h"
32
33static gboolean ipv6_supported;
34
35typedef struct {
36 GSocket *server;
37 GSocket *client;
38 GSocketFamily family;
39 GThread *thread;
40 GMainLoop *loop;
41 GCancellable *cancellable; /* to shut down dgram echo server thread */
42} IPTestData;
43
44static gpointer
45echo_server_dgram_thread (gpointer user_data)
46{
47 IPTestData *data = user_data;
48 GSocketAddress *sa;
49 GCancellable *cancellable = data->cancellable;
50 GSocket *sock;
51 GError *error = NULL;
52 gssize nread, nwrote;
53 gchar buf[128];
54
55 sock = data->server;
56
57 while (TRUE)
58 {
59 nread = g_socket_receive_from (socket: sock, address: &sa, buffer: buf, size: sizeof (buf), cancellable, error: &error);
60 if (error && g_error_matches (error, G_IO_ERROR, code: G_IO_ERROR_CANCELLED))
61 break;
62 g_assert_no_error (error);
63 g_assert_cmpint (nread, >=, 0);
64
65 nwrote = g_socket_send_to (socket: sock, address: sa, buffer: buf, size: nread, cancellable, error: &error);
66 if (error && g_error_matches (error, G_IO_ERROR, code: G_IO_ERROR_CANCELLED))
67 break;
68 g_assert_no_error (error);
69 g_assert_cmpint (nwrote, ==, nread);
70
71 g_object_unref (object: sa);
72 }
73
74 g_clear_error (err: &error);
75
76 return NULL;
77}
78
79static gpointer
80echo_server_thread (gpointer user_data)
81{
82 IPTestData *data = user_data;
83 GSocket *sock;
84 GError *error = NULL;
85 gssize nread, nwrote;
86 gchar buf[128];
87
88 sock = g_socket_accept (socket: data->server, NULL, error: &error);
89 g_assert_no_error (error);
90
91 while (TRUE)
92 {
93 nread = g_socket_receive (socket: sock, buffer: buf, size: sizeof (buf), NULL, error: &error);
94 g_assert_no_error (error);
95 g_assert_cmpint (nread, >=, 0);
96
97 if (nread == 0)
98 break;
99
100 nwrote = g_socket_send (socket: sock, buffer: buf, size: nread, NULL, error: &error);
101 g_assert_no_error (error);
102 g_assert_cmpint (nwrote, ==, nread);
103 }
104
105 g_socket_close (socket: sock, error: &error);
106 g_assert_no_error (error);
107 g_object_unref (object: sock);
108 return NULL;
109}
110
111static IPTestData *
112create_server_full (GSocketFamily family,
113 GSocketType socket_type,
114 GThreadFunc server_thread,
115 gboolean v4mapped,
116 GError **error)
117{
118 IPTestData *data;
119 GSocket *server;
120 GSocketAddress *addr;
121 GInetAddress *iaddr;
122
123 data = g_slice_new (IPTestData);
124 data->family = family;
125
126 data->server = server = g_socket_new (family,
127 type: socket_type,
128 protocol: G_SOCKET_PROTOCOL_DEFAULT,
129 error);
130 if (server == NULL)
131 goto error;
132
133 g_assert_cmpint (g_socket_get_family (server), ==, family);
134 g_assert_cmpint (g_socket_get_socket_type (server), ==, socket_type);
135 g_assert_cmpint (g_socket_get_protocol (server), ==, G_SOCKET_PROTOCOL_DEFAULT);
136
137 g_socket_set_blocking (socket: server, TRUE);
138
139#if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY)
140 if (v4mapped)
141 {
142 g_socket_set_option (socket: data->server, IPPROTO_IPV6, IPV6_V6ONLY, FALSE, NULL);
143 if (!g_socket_speaks_ipv4 (socket: data->server))
144 {
145 g_set_error_literal (err: error, G_IO_ERROR, code: G_IO_ERROR_NOT_SUPPORTED,
146 message: "IPv6-only server cannot speak IPv4");
147 goto error;
148 }
149 }
150#endif
151
152 if (v4mapped)
153 iaddr = g_inet_address_new_any (family);
154 else
155 iaddr = g_inet_address_new_loopback (family);
156 addr = g_inet_socket_address_new (address: iaddr, port: 0);
157 g_object_unref (object: iaddr);
158
159 g_assert_cmpint (g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)), ==, 0);
160 if (!g_socket_bind (socket: server, address: addr, TRUE, error))
161 {
162 g_object_unref (object: addr);
163 goto error;
164 }
165 g_object_unref (object: addr);
166
167 addr = g_socket_get_local_address (socket: server, error);
168 if (addr == NULL)
169 goto error;
170 g_assert_cmpint (g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)), !=, 0);
171 g_object_unref (object: addr);
172
173 if (socket_type == G_SOCKET_TYPE_STREAM)
174 {
175 if (!g_socket_listen (socket: server, error))
176 goto error;
177 }
178 else
179 {
180 data->cancellable = g_cancellable_new ();
181 }
182
183 data->thread = g_thread_new (name: "server", func: server_thread, data);
184
185 return data;
186
187error:
188 g_clear_object (&data->server);
189 g_slice_free (IPTestData, data);
190
191 return NULL;
192}
193
194static IPTestData *
195create_server (GSocketFamily family,
196 GThreadFunc server_thread,
197 gboolean v4mapped,
198 GError **error)
199{
200 return create_server_full (family, socket_type: G_SOCKET_TYPE_STREAM, server_thread, v4mapped, error);
201}
202
203static const gchar *testbuf = "0123456789abcdef";
204
205static gboolean
206test_ip_async_read_ready (GSocket *client,
207 GIOCondition cond,
208 gpointer user_data)
209{
210 IPTestData *data = user_data;
211 GError *error = NULL;
212 gssize len;
213 gchar buf[128];
214
215 g_assert_cmpint (cond, ==, G_IO_IN);
216
217 len = g_socket_receive (socket: client, buffer: buf, size: sizeof (buf), NULL, error: &error);
218 g_assert_no_error (error);
219 g_assert_cmpint (len, ==, strlen (testbuf) + 1);
220
221 g_assert_cmpstr (testbuf, ==, buf);
222
223 g_main_loop_quit (loop: data->loop);
224
225 return FALSE;
226}
227
228static gboolean
229test_ip_async_write_ready (GSocket *client,
230 GIOCondition cond,
231 gpointer user_data)
232{
233 IPTestData *data = user_data;
234 GError *error = NULL;
235 GSource *source;
236 gssize len;
237
238 g_assert_cmpint (cond, ==, G_IO_OUT);
239
240 len = g_socket_send (socket: client, buffer: testbuf, size: strlen (s: testbuf) + 1, NULL, error: &error);
241 g_assert_no_error (error);
242 g_assert_cmpint (len, ==, strlen (testbuf) + 1);
243
244 source = g_socket_create_source (socket: client, condition: G_IO_IN, NULL);
245 g_source_set_callback (source, func: (GSourceFunc)test_ip_async_read_ready,
246 data, NULL);
247 g_source_attach (source, NULL);
248 g_source_unref (source);
249
250 return FALSE;
251}
252
253static gboolean
254test_ip_async_timed_out (GSocket *client,
255 GIOCondition cond,
256 gpointer user_data)
257{
258 IPTestData *data = user_data;
259 GError *error = NULL;
260 GSource *source;
261 gssize len;
262 gchar buf[128];
263
264 if (data->family == G_SOCKET_FAMILY_IPV4)
265 {
266 g_assert_cmpint (cond, ==, G_IO_IN);
267 len = g_socket_receive (socket: client, buffer: buf, size: sizeof (buf), NULL, error: &error);
268 g_assert_cmpint (len, ==, -1);
269 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
270 g_clear_error (err: &error);
271 }
272
273 source = g_socket_create_source (socket: client, condition: G_IO_OUT, NULL);
274 g_source_set_callback (source, func: (GSourceFunc)test_ip_async_write_ready,
275 data, NULL);
276 g_source_attach (source, NULL);
277 g_source_unref (source);
278
279 return FALSE;
280}
281
282static gboolean
283test_ip_async_connected (GSocket *client,
284 GIOCondition cond,
285 gpointer user_data)
286{
287 IPTestData *data = user_data;
288 GError *error = NULL;
289 GSource *source;
290 gssize len;
291 gchar buf[128];
292
293 g_socket_check_connect_result (socket: client, error: &error);
294 g_assert_no_error (error);
295 /* We do this after the check_connect_result, since that will give a
296 * more useful assertion in case of error.
297 */
298 g_assert_cmpint (cond, ==, G_IO_OUT);
299
300 g_assert (g_socket_is_connected (client));
301
302 /* This adds 1 second to "make check", so let's just only do it once. */
303 if (data->family == G_SOCKET_FAMILY_IPV4)
304 {
305 len = g_socket_receive (socket: client, buffer: buf, size: sizeof (buf), NULL, error: &error);
306 g_assert_cmpint (len, ==, -1);
307 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
308 g_clear_error (err: &error);
309
310 source = g_socket_create_source (socket: client, condition: G_IO_IN, NULL);
311 g_source_set_callback (source, func: (GSourceFunc)test_ip_async_timed_out,
312 data, NULL);
313 g_source_attach (source, NULL);
314 g_source_unref (source);
315 }
316 else
317 test_ip_async_timed_out (client, cond: 0, user_data: data);
318
319 return FALSE;
320}
321
322static gboolean
323idle_test_ip_async_connected (gpointer user_data)
324{
325 IPTestData *data = user_data;
326
327 return test_ip_async_connected (client: data->client, cond: G_IO_OUT, user_data: data);
328}
329
330static void
331test_ip_async (GSocketFamily family)
332{
333 IPTestData *data;
334 GError *error = NULL;
335 GSocket *client;
336 GSocketAddress *addr;
337 GSource *source;
338 gssize len;
339 gchar buf[128];
340
341 data = create_server (family, server_thread: echo_server_thread, FALSE, error: &error);
342 if (error != NULL)
343 {
344 gchar *message = g_strdup_printf (format: "Failed to create server: %s", error->message);
345 g_test_skip (msg: message);
346 g_free (mem: message);
347 g_clear_error (err: &error);
348 return;
349 }
350 g_assert_nonnull (data);
351
352 addr = g_socket_get_local_address (socket: data->server, error: &error);
353 g_assert_no_error (error);
354
355 client = g_socket_new (family,
356 type: G_SOCKET_TYPE_STREAM,
357 protocol: G_SOCKET_PROTOCOL_DEFAULT,
358 error: &error);
359 g_assert_no_error (error);
360 data->client = client;
361
362 g_assert_cmpint (g_socket_get_family (client), ==, family);
363 g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
364 g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
365
366 g_socket_set_blocking (socket: client, FALSE);
367 g_socket_set_timeout (socket: client, timeout: 1);
368
369 if (g_socket_connect (socket: client, address: addr, NULL, error: &error))
370 {
371 g_assert_no_error (error);
372 g_idle_add (function: idle_test_ip_async_connected, data);
373 }
374 else
375 {
376 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PENDING);
377 g_clear_error (err: &error);
378 source = g_socket_create_source (socket: client, condition: G_IO_OUT, NULL);
379 g_source_set_callback (source, func: (GSourceFunc)test_ip_async_connected,
380 data, NULL);
381 g_source_attach (source, NULL);
382 g_source_unref (source);
383 }
384 g_object_unref (object: addr);
385
386 data->loop = g_main_loop_new (NULL, TRUE);
387 g_main_loop_run (loop: data->loop);
388 g_main_loop_unref (loop: data->loop);
389
390 g_socket_shutdown (socket: client, FALSE, TRUE, error: &error);
391 g_assert_no_error (error);
392
393 g_thread_join (thread: data->thread);
394
395 if (family == G_SOCKET_FAMILY_IPV4)
396 {
397 /* Test that reading on a remote-closed socket gets back 0 bytes. */
398 len = g_socket_receive_with_blocking (socket: client, buffer: buf, size: sizeof (buf),
399 TRUE, NULL, error: &error);
400 g_assert_no_error (error);
401 g_assert_cmpint (len, ==, 0);
402 }
403 else
404 {
405 /* Test that writing to a remote-closed socket gets back CONNECTION_CLOSED. */
406 len = g_socket_send_with_blocking (socket: client, buffer: testbuf, size: strlen (s: testbuf) + 1,
407 TRUE, NULL, error: &error);
408 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED);
409 g_assert_cmpint (len, ==, -1);
410 g_clear_error (err: &error);
411 }
412
413 g_socket_close (socket: client, error: &error);
414 g_assert_no_error (error);
415 g_socket_close (socket: data->server, error: &error);
416 g_assert_no_error (error);
417
418 g_object_unref (object: data->server);
419 g_object_unref (object: client);
420
421 g_slice_free (IPTestData, data);
422}
423
424static void
425test_ipv4_async (void)
426{
427 test_ip_async (family: G_SOCKET_FAMILY_IPV4);
428}
429
430static void
431test_ipv6_async (void)
432{
433 if (!ipv6_supported)
434 {
435 g_test_skip (msg: "No support for IPv6");
436 return;
437 }
438
439 test_ip_async (family: G_SOCKET_FAMILY_IPV6);
440}
441
442static const gchar testbuf2[] = "0123456789abcdefghijklmnopqrstuvwxyz";
443
444static void
445test_ip_sync (GSocketFamily family)
446{
447 IPTestData *data;
448 GError *error = NULL;
449 GSocket *client;
450 GSocketAddress *addr;
451 gssize len;
452 gchar buf[128];
453
454 data = create_server (family, server_thread: echo_server_thread, FALSE, error: &error);
455 if (error != NULL)
456 {
457 gchar *message = g_strdup_printf (format: "Failed to create server: %s", error->message);
458 g_test_skip (msg: message);
459 g_free (mem: message);
460 g_clear_error (err: &error);
461 return;
462 }
463
464 addr = g_socket_get_local_address (socket: data->server, error: &error);
465 g_assert_no_error (error);
466
467 client = g_socket_new (family,
468 type: G_SOCKET_TYPE_STREAM,
469 protocol: G_SOCKET_PROTOCOL_DEFAULT,
470 error: &error);
471 g_assert_no_error (error);
472
473 g_assert_cmpint (g_socket_get_family (client), ==, family);
474 g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
475 g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
476
477 g_socket_set_blocking (socket: client, TRUE);
478 g_socket_set_timeout (socket: client, timeout: 1);
479
480 g_socket_connect (socket: client, address: addr, NULL, error: &error);
481 g_assert_no_error (error);
482 g_assert (g_socket_is_connected (client));
483 g_object_unref (object: addr);
484
485 /* This adds 1 second to "make check", so let's just only do it once. */
486 if (family == G_SOCKET_FAMILY_IPV4)
487 {
488 len = g_socket_receive (socket: client, buffer: buf, size: sizeof (buf), NULL, error: &error);
489 g_assert_cmpint (len, ==, -1);
490 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
491 g_clear_error (err: &error);
492 }
493
494 len = g_socket_send (socket: client, buffer: testbuf, size: strlen (s: testbuf) + 1, NULL, error: &error);
495 g_assert_no_error (error);
496 g_assert_cmpint (len, ==, strlen (testbuf) + 1);
497
498 len = g_socket_receive (socket: client, buffer: buf, size: sizeof (buf), NULL, error: &error);
499 g_assert_no_error (error);
500 g_assert_cmpint (len, ==, strlen (testbuf) + 1);
501
502 g_assert_cmpstr (testbuf, ==, buf);
503
504 {
505 GOutputVector v[7] = { { NULL, }, };
506
507 v[0].buffer = testbuf2 + 0;
508 v[0].size = 3;
509 v[1].buffer = testbuf2 + 3;
510 v[1].size = 5;
511 v[2].buffer = testbuf2 + 3 + 5;
512 v[2].size = 0;
513 v[3].buffer = testbuf2 + 3 + 5;
514 v[3].size = 6;
515 v[4].buffer = testbuf2 + 3 + 5 + 6;
516 v[4].size = 2;
517 v[5].buffer = testbuf2 + 3 + 5 + 6 + 2;
518 v[5].size = 1;
519 v[6].buffer = testbuf2 + 3 + 5 + 6 + 2 + 1;
520 v[6].size = strlen (s: testbuf2) - (3 + 5 + 6 + 2 + 1);
521
522 len = g_socket_send_message (socket: client, NULL, vectors: v, G_N_ELEMENTS (v), NULL, num_messages: 0, flags: 0, NULL, error: &error);
523 g_assert_no_error (error);
524 g_assert_cmpint (len, ==, strlen (testbuf2));
525
526 memset (s: buf, c: 0, n: sizeof (buf));
527 len = g_socket_receive (socket: client, buffer: buf, size: sizeof (buf), NULL, error: &error);
528 g_assert_no_error (error);
529 g_assert_cmpint (len, ==, strlen (testbuf2));
530 g_assert_cmpstr (testbuf2, ==, buf);
531 }
532
533 g_socket_shutdown (socket: client, FALSE, TRUE, error: &error);
534 g_assert_no_error (error);
535
536 g_thread_join (thread: data->thread);
537
538 if (family == G_SOCKET_FAMILY_IPV4)
539 {
540 /* Test that reading on a remote-closed socket gets back 0 bytes. */
541 len = g_socket_receive (socket: client, buffer: buf, size: sizeof (buf), NULL, error: &error);
542 g_assert_no_error (error);
543 g_assert_cmpint (len, ==, 0);
544 }
545 else
546 {
547 /* Test that writing to a remote-closed socket gets back CONNECTION_CLOSED. */
548 len = g_socket_send (socket: client, buffer: testbuf, size: strlen (s: testbuf) + 1, NULL, error: &error);
549 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED);
550 g_assert_cmpint (len, ==, -1);
551 g_clear_error (err: &error);
552 }
553
554 g_socket_close (socket: client, error: &error);
555 g_assert_no_error (error);
556 g_socket_close (socket: data->server, error: &error);
557 g_assert_no_error (error);
558
559 g_object_unref (object: data->server);
560 g_object_unref (object: client);
561
562 g_slice_free (IPTestData, data);
563}
564
565static void
566test_ipv4_sync (void)
567{
568 test_ip_sync (family: G_SOCKET_FAMILY_IPV4);
569}
570
571static void
572test_ipv6_sync (void)
573{
574 if (!ipv6_supported)
575 {
576 g_test_skip (msg: "No support for IPv6");
577 return;
578 }
579
580 test_ip_sync (family: G_SOCKET_FAMILY_IPV6);
581}
582
583static void
584test_ip_sync_dgram (GSocketFamily family)
585{
586 IPTestData *data;
587 GError *error = NULL;
588 GSocket *client;
589 GSocketAddress *dest_addr;
590 gssize len;
591 gchar buf[128];
592
593 data = create_server_full (family, socket_type: G_SOCKET_TYPE_DATAGRAM,
594 server_thread: echo_server_dgram_thread, FALSE, error: &error);
595 if (error != NULL)
596 {
597 gchar *message = g_strdup_printf (format: "Failed to create server: %s", error->message);
598 g_test_skip (msg: message);
599 g_free (mem: message);
600 g_clear_error (err: &error);
601 return;
602 }
603
604 dest_addr = g_socket_get_local_address (socket: data->server, error: &error);
605
606 client = g_socket_new (family,
607 type: G_SOCKET_TYPE_DATAGRAM,
608 protocol: G_SOCKET_PROTOCOL_DEFAULT,
609 error: &error);
610 g_assert_no_error (error);
611
612 g_assert_cmpint (g_socket_get_family (client), ==, family);
613 g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_DATAGRAM);
614 g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
615
616 g_socket_set_blocking (socket: client, TRUE);
617 g_socket_set_timeout (socket: client, timeout: 1);
618
619 len = g_socket_send_to (socket: client, address: dest_addr, buffer: testbuf, size: strlen (s: testbuf) + 1, NULL, error: &error);
620 g_assert_no_error (error);
621 g_assert_cmpint (len, ==, strlen (testbuf) + 1);
622
623 len = g_socket_receive_from (socket: client, NULL, buffer: buf, size: sizeof (buf), NULL, error: &error);
624 g_assert_no_error (error);
625 g_assert_cmpint (len, ==, strlen (testbuf) + 1);
626
627 g_assert_cmpstr (testbuf, ==, buf);
628
629 {
630 GOutputMessage m[3] = { { NULL, }, };
631 GInputMessage im[3] = { { NULL, }, };
632 GOutputVector v[7] = { { NULL, }, };
633 GInputVector iv[7] = { { NULL, }, };
634
635 v[0].buffer = testbuf2 + 0;
636 v[0].size = 3;
637 v[1].buffer = testbuf2 + 3;
638 v[1].size = 5;
639 v[2].buffer = testbuf2 + 3 + 5;
640 v[2].size = 0;
641 v[3].buffer = testbuf2 + 3 + 5;
642 v[3].size = 6;
643 v[4].buffer = testbuf2 + 3 + 5 + 6;
644 v[4].size = 2;
645 v[5].buffer = testbuf2 + 3 + 5 + 6 + 2;
646 v[5].size = 1;
647 v[6].buffer = testbuf2 + 3 + 5 + 6 + 2 + 1;
648 v[6].size = strlen (s: testbuf2) - (3 + 5 + 6 + 2 + 1);
649
650 iv[0].buffer = buf + 0;
651 iv[0].size = 3;
652 iv[1].buffer = buf + 3;
653 iv[1].size = 5;
654 iv[2].buffer = buf + 3 + 5;
655 iv[2].size = 0;
656 iv[3].buffer = buf + 3 + 5;
657 iv[3].size = 6;
658 iv[4].buffer = buf + 3 + 5 + 6;
659 iv[4].size = 2;
660 iv[5].buffer = buf + 3 + 5 + 6 + 2;
661 iv[5].size = 1;
662 iv[6].buffer = buf + 3 + 5 + 6 + 2 + 1;
663 iv[6].size = sizeof (buf) - (3 + 5 + 6 + 2 + 1);
664
665 len = g_socket_send_message (socket: client, address: dest_addr, vectors: v, G_N_ELEMENTS (v), NULL, num_messages: 0, flags: 0, NULL, error: &error);
666 g_assert_no_error (error);
667 g_assert_cmpint (len, ==, strlen (testbuf2));
668
669 memset (s: buf, c: 0, n: sizeof (buf));
670 len = g_socket_receive_from (socket: client, NULL, buffer: buf, size: sizeof (buf), NULL, error: &error);
671 g_assert_no_error (error);
672 g_assert_cmpint (len, ==, strlen (testbuf2));
673 g_assert_cmpstr (testbuf2, ==, buf);
674
675 m[0].vectors = &v[0];
676 m[0].num_vectors = 1;
677 m[0].address = dest_addr;
678 m[1].vectors = &v[0];
679 m[1].num_vectors = 6;
680 m[1].address = dest_addr;
681 m[2].vectors = &v[6];
682 m[2].num_vectors = 1;
683 m[2].address = dest_addr;
684
685 len = g_socket_send_messages (socket: client, messages: m, G_N_ELEMENTS (m), flags: 0, NULL, error: &error);
686 g_assert_no_error (error);
687 g_assert_cmpint (len, ==, G_N_ELEMENTS (m));
688 g_assert_cmpint (m[0].bytes_sent, ==, 3);
689 g_assert_cmpint (m[1].bytes_sent, ==, 17);
690 g_assert_cmpint (m[2].bytes_sent, ==, v[6].size);
691
692 memset (s: buf, c: 0, n: sizeof (buf));
693 len = g_socket_receive_from (socket: client, NULL, buffer: buf, size: sizeof (buf), NULL, error: &error);
694 g_assert_no_error (error);
695 g_assert_cmpint (len, ==, 3);
696
697 memset (s: buf, c: 0, n: sizeof (buf));
698 len = g_socket_receive_from (socket: client, NULL, buffer: buf, size: sizeof (buf), NULL, error: &error);
699 g_assert_no_error (error);
700 /* v[0].size + v[1].size + v[2].size + v[3].size + v[4].size + v[5].size */
701 g_assert_cmpint (len, ==, 17);
702 g_assert (memcmp (testbuf2, buf, 17) == 0);
703
704 memset (s: buf, c: 0, n: sizeof (buf));
705 len = g_socket_receive_from (socket: client, NULL, buffer: buf, size: sizeof (buf), NULL, error: &error);
706 g_assert_no_error (error);
707 g_assert_cmpint (len, ==, v[6].size);
708 g_assert_cmpstr (buf, ==, v[6].buffer);
709
710 /* reset since we're re-using the message structs */
711 m[0].bytes_sent = 0;
712 m[1].bytes_sent = 0;
713 m[2].bytes_sent = 0;
714
715 /* now try receiving multiple messages */
716 len = g_socket_send_messages (socket: client, messages: m, G_N_ELEMENTS (m), flags: 0, NULL, error: &error);
717 g_assert_no_error (error);
718 g_assert_cmpint (len, ==, G_N_ELEMENTS (m));
719 g_assert_cmpint (m[0].bytes_sent, ==, 3);
720 g_assert_cmpint (m[1].bytes_sent, ==, 17);
721 g_assert_cmpint (m[2].bytes_sent, ==, v[6].size);
722
723 im[0].vectors = &iv[0];
724 im[0].num_vectors = 1;
725 im[1].vectors = &iv[0];
726 im[1].num_vectors = 6;
727 im[2].vectors = &iv[6];
728 im[2].num_vectors = 1;
729
730 memset (s: buf, c: 0, n: sizeof (buf));
731 len = g_socket_receive_messages (socket: client, messages: im, G_N_ELEMENTS (im), flags: 0,
732 NULL, error: &error);
733 g_assert_no_error (error);
734 g_assert_cmpint (len, ==, G_N_ELEMENTS (im));
735
736 g_assert_cmpuint (im[0].bytes_received, ==, 3);
737 /* v[0].size + v[1].size + v[2].size + v[3].size + v[4].size + v[5].size */
738 g_assert_cmpuint (im[1].bytes_received, ==, 17);
739 g_assert_cmpuint (im[2].bytes_received, ==, v[6].size);
740
741 /* reset since we're re-using the message structs */
742 m[0].bytes_sent = 0;
743 m[1].bytes_sent = 0;
744 m[2].bytes_sent = 0;
745
746 /* now try to generate an early return by omitting the destination address on [1] */
747 m[1].address = NULL;
748 len = g_socket_send_messages (socket: client, messages: m, G_N_ELEMENTS (m), flags: 0, NULL, error: &error);
749 g_assert_no_error (error);
750 g_assert_cmpint (len, ==, 1);
751
752 g_assert_cmpint (m[0].bytes_sent, ==, 3);
753 g_assert_cmpint (m[1].bytes_sent, ==, 0);
754 g_assert_cmpint (m[2].bytes_sent, ==, 0);
755
756 /* reset since we're re-using the message structs */
757 m[0].bytes_sent = 0;
758 m[1].bytes_sent = 0;
759 m[2].bytes_sent = 0;
760
761 /* now try to generate an error by omitting all destination addresses */
762 m[0].address = NULL;
763 m[1].address = NULL;
764 m[2].address = NULL;
765 len = g_socket_send_messages (socket: client, messages: m, G_N_ELEMENTS (m), flags: 0, NULL, error: &error);
766 /* This error code may vary between platforms and over time; it is not guaranteed API: */
767#ifndef G_OS_WIN32
768 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_FAILED);
769#else
770 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_CONNECTED);
771#endif
772 g_clear_error (err: &error);
773 g_assert_cmpint (len, ==, -1);
774
775 g_assert_cmpint (m[0].bytes_sent, ==, 0);
776 g_assert_cmpint (m[1].bytes_sent, ==, 0);
777 g_assert_cmpint (m[2].bytes_sent, ==, 0);
778
779 len = g_socket_receive_from (socket: client, NULL, buffer: buf, size: sizeof (buf), NULL, error: &error);
780 g_assert_cmpint (len, ==, 3);
781 }
782
783 g_cancellable_cancel (cancellable: data->cancellable);
784
785 g_thread_join (thread: data->thread);
786
787 g_socket_close (socket: client, error: &error);
788 g_assert_no_error (error);
789 g_socket_close (socket: data->server, error: &error);
790 g_assert_no_error (error);
791
792 g_object_unref (object: data->server);
793 g_object_unref (object: data->cancellable);
794 g_object_unref (object: client);
795 g_object_unref (object: dest_addr);
796
797 g_slice_free (IPTestData, data);
798}
799
800static void
801test_ipv4_sync_dgram (void)
802{
803 test_ip_sync_dgram (family: G_SOCKET_FAMILY_IPV4);
804}
805
806static void
807test_ipv6_sync_dgram (void)
808{
809 if (!ipv6_supported)
810 {
811 g_test_skip (msg: "No support for IPv6");
812 return;
813 }
814
815 test_ip_sync_dgram (family: G_SOCKET_FAMILY_IPV6);
816}
817
818static gpointer
819cancellable_thread_cb (gpointer data)
820{
821 GCancellable *cancellable = data;
822
823 g_usleep (microseconds: 0.1 * G_USEC_PER_SEC);
824 g_cancellable_cancel (cancellable);
825 g_object_unref (object: cancellable);
826
827 return NULL;
828}
829
830static void
831test_ip_sync_dgram_timeouts (GSocketFamily family)
832{
833 GError *error = NULL;
834 GSocket *client = NULL;
835 GCancellable *cancellable = NULL;
836 GThread *cancellable_thread = NULL;
837 gssize len;
838#ifdef G_OS_WIN32
839 GInetAddress *iaddr;
840 GSocketAddress *addr;
841#endif
842
843 client = g_socket_new (family,
844 type: G_SOCKET_TYPE_DATAGRAM,
845 protocol: G_SOCKET_PROTOCOL_DEFAULT,
846 error: &error);
847 g_assert_no_error (error);
848
849 g_assert_cmpint (g_socket_get_family (client), ==, family);
850 g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_DATAGRAM);
851 g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
852
853#ifdef G_OS_WIN32
854 /* Winsock can't recv() on unbound udp socket */
855 iaddr = g_inet_address_new_loopback (family);
856 addr = g_inet_socket_address_new (iaddr, 0);
857 g_object_unref (iaddr);
858 g_socket_bind (client, addr, TRUE, &error);
859 g_object_unref (addr);
860 g_assert_no_error (error);
861#endif
862
863 /* No overall timeout: test the per-operation timeouts instead. */
864 g_socket_set_timeout (socket: client, timeout: 0);
865
866 cancellable = g_cancellable_new ();
867
868 /* Check for timeouts when no server is running. */
869 {
870 gint64 start_time;
871 GInputMessage im = { NULL, };
872 GInputVector iv = { NULL, };
873 guint8 buf[128];
874
875 iv.buffer = buf;
876 iv.size = sizeof (buf);
877
878 im.vectors = &iv;
879 im.num_vectors = 1;
880
881 memset (s: buf, c: 0, n: sizeof (buf));
882
883 /* Try a non-blocking read. */
884 g_socket_set_blocking (socket: client, FALSE);
885 len = g_socket_receive_messages (socket: client, messages: &im, num_messages: 1, flags: 0 /* flags */,
886 NULL, error: &error);
887 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
888 g_assert_cmpint (len, ==, -1);
889 g_clear_error (err: &error);
890
891 /* Try a timeout read. Can’t really validate the time taken more than
892 * checking it’s positive. */
893 g_socket_set_timeout (socket: client, timeout: 1);
894 g_socket_set_blocking (socket: client, TRUE);
895 start_time = g_get_monotonic_time ();
896 len = g_socket_receive_messages (socket: client, messages: &im, num_messages: 1, flags: 0 /* flags */,
897 NULL, error: &error);
898 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
899 g_assert_cmpint (len, ==, -1);
900 g_assert_cmpint (g_get_monotonic_time () - start_time, >, 0);
901 g_clear_error (err: &error);
902
903 /* Try a blocking read, cancelled from another thread. */
904 g_socket_set_timeout (socket: client, timeout: 0);
905 cancellable_thread = g_thread_new (name: "cancellable",
906 func: cancellable_thread_cb,
907 g_object_ref (cancellable));
908
909 start_time = g_get_monotonic_time ();
910 len = g_socket_receive_messages (socket: client, messages: &im, num_messages: 1, flags: 0 /* flags */,
911 cancellable, error: &error);
912 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
913 g_assert_cmpint (len, ==, -1);
914 g_assert_cmpint (g_get_monotonic_time () - start_time, >, 0);
915 g_clear_error (err: &error);
916
917 g_thread_join (thread: cancellable_thread);
918 }
919
920 g_socket_close (socket: client, error: &error);
921 g_assert_no_error (error);
922
923 g_object_unref (object: client);
924 g_object_unref (object: cancellable);
925}
926
927static void
928test_ipv4_sync_dgram_timeouts (void)
929{
930 test_ip_sync_dgram_timeouts (family: G_SOCKET_FAMILY_IPV4);
931}
932
933static void
934test_ipv6_sync_dgram_timeouts (void)
935{
936 if (!ipv6_supported)
937 {
938 g_test_skip (msg: "No support for IPv6");
939 return;
940 }
941
942 test_ip_sync_dgram_timeouts (family: G_SOCKET_FAMILY_IPV6);
943}
944
945static gpointer
946graceful_server_thread (gpointer user_data)
947{
948 IPTestData *data = user_data;
949 GSocket *sock;
950 GError *error = NULL;
951 gssize len;
952
953 sock = g_socket_accept (socket: data->server, NULL, error: &error);
954 g_assert_no_error (error);
955
956 len = g_socket_send (socket: sock, buffer: testbuf, size: strlen (s: testbuf) + 1, NULL, error: &error);
957 g_assert_no_error (error);
958 g_assert_cmpint (len, ==, strlen (testbuf) + 1);
959
960 return sock;
961}
962
963static void
964test_close_graceful (void)
965{
966 GSocketFamily family = G_SOCKET_FAMILY_IPV4;
967 IPTestData *data;
968 GError *error = NULL;
969 GSocket *client, *server;
970 GSocketAddress *addr;
971 gssize len;
972 gchar buf[128];
973
974 data = create_server (family, server_thread: graceful_server_thread, FALSE, error: &error);
975 if (error != NULL)
976 {
977 gchar *message = g_strdup_printf (format: "Failed to create server: %s", error->message);
978 g_test_skip (msg: message);
979 g_free (mem: message);
980 g_clear_error (err: &error);
981 return;
982 }
983
984 addr = g_socket_get_local_address (socket: data->server, error: &error);
985 g_assert_no_error (error);
986
987 client = g_socket_new (family,
988 type: G_SOCKET_TYPE_STREAM,
989 protocol: G_SOCKET_PROTOCOL_DEFAULT,
990 error: &error);
991 g_assert_no_error (error);
992
993 g_assert_cmpint (g_socket_get_family (client), ==, family);
994 g_assert_cmpint (g_socket_get_socket_type (client), ==, G_SOCKET_TYPE_STREAM);
995 g_assert_cmpint (g_socket_get_protocol (client), ==, G_SOCKET_PROTOCOL_DEFAULT);
996
997 g_socket_set_blocking (socket: client, TRUE);
998 g_socket_set_timeout (socket: client, timeout: 1);
999
1000 g_socket_connect (socket: client, address: addr, NULL, error: &error);
1001 g_assert_no_error (error);
1002 g_assert (g_socket_is_connected (client));
1003 g_object_unref (object: addr);
1004
1005 server = g_thread_join (thread: data->thread);
1006
1007 /* similar to g_tcp_connection_set_graceful_disconnect(), but explicit */
1008 g_socket_shutdown (socket: server, FALSE, TRUE, error: &error);
1009 g_assert_no_error (error);
1010
1011 /* we must timeout */
1012 g_socket_condition_wait (socket: client, condition: G_IO_HUP, NULL, error: &error);
1013 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
1014 g_clear_error (err: &error);
1015
1016 /* check that the remaining data is received */
1017 len = g_socket_receive (socket: client, buffer: buf, size: strlen (s: testbuf) + 1, NULL, error: &error);
1018 g_assert_no_error (error);
1019 g_assert_cmpint (len, ==, strlen (testbuf) + 1);
1020
1021 /* and only then the connection is closed */
1022 len = g_socket_receive (socket: client, buffer: buf, size: sizeof (buf), NULL, error: &error);
1023 g_assert_no_error (error);
1024 g_assert_cmpint (len, ==, 0);
1025
1026 g_socket_close (socket: server, error: &error);
1027 g_assert_no_error (error);
1028
1029 g_socket_close (socket: client, error: &error);
1030 g_assert_no_error (error);
1031
1032 g_object_unref (object: server);
1033 g_object_unref (object: data->server);
1034 g_object_unref (object: client);
1035
1036 g_slice_free (IPTestData, data);
1037}
1038
1039#if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY)
1040static gpointer
1041v4mapped_server_thread (gpointer user_data)
1042{
1043 IPTestData *data = user_data;
1044 GSocket *sock;
1045 GError *error = NULL;
1046 GSocketAddress *addr;
1047
1048 sock = g_socket_accept (socket: data->server, NULL, error: &error);
1049 g_assert_no_error (error);
1050
1051 g_assert_cmpint (g_socket_get_family (sock), ==, G_SOCKET_FAMILY_IPV6);
1052
1053 addr = g_socket_get_local_address (socket: sock, error: &error);
1054 g_assert_no_error (error);
1055 g_assert_cmpint (g_socket_address_get_family (addr), ==, G_SOCKET_FAMILY_IPV4);
1056 g_object_unref (object: addr);
1057
1058 addr = g_socket_get_remote_address (socket: sock, error: &error);
1059 g_assert_no_error (error);
1060 g_assert_cmpint (g_socket_address_get_family (addr), ==, G_SOCKET_FAMILY_IPV4);
1061 g_object_unref (object: addr);
1062
1063 g_socket_close (socket: sock, error: &error);
1064 g_assert_no_error (error);
1065 g_object_unref (object: sock);
1066 return NULL;
1067}
1068
1069static void
1070test_ipv6_v4mapped (void)
1071{
1072 IPTestData *data;
1073 GError *error = NULL;
1074 GSocket *client;
1075 GSocketAddress *addr, *v4addr;
1076 GInetAddress *iaddr;
1077
1078 if (!ipv6_supported)
1079 {
1080 g_test_skip (msg: "No support for IPv6");
1081 return;
1082 }
1083
1084 data = create_server (family: G_SOCKET_FAMILY_IPV6, server_thread: v4mapped_server_thread, TRUE, error: &error);
1085 if (error != NULL)
1086 {
1087 gchar *message = g_strdup_printf (format: "Failed to create server: %s", error->message);
1088 g_test_skip (msg: message);
1089 g_free (mem: message);
1090 g_clear_error (err: &error);
1091 return;
1092 }
1093
1094 client = g_socket_new (family: G_SOCKET_FAMILY_IPV4,
1095 type: G_SOCKET_TYPE_STREAM,
1096 protocol: G_SOCKET_PROTOCOL_DEFAULT,
1097 error: &error);
1098 g_assert_no_error (error);
1099
1100 g_socket_set_blocking (socket: client, TRUE);
1101 g_socket_set_timeout (socket: client, timeout: 1);
1102
1103 addr = g_socket_get_local_address (socket: data->server, error: &error);
1104 g_assert_no_error (error);
1105 iaddr = g_inet_address_new_loopback (family: G_SOCKET_FAMILY_IPV4);
1106 v4addr = g_inet_socket_address_new (address: iaddr, port: g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)));
1107 g_object_unref (object: iaddr);
1108 g_object_unref (object: addr);
1109
1110 g_socket_connect (socket: client, address: v4addr, NULL, error: &error);
1111 g_assert_no_error (error);
1112 g_assert (g_socket_is_connected (client));
1113
1114 g_thread_join (thread: data->thread);
1115
1116 g_socket_close (socket: client, error: &error);
1117 g_assert_no_error (error);
1118 g_socket_close (socket: data->server, error: &error);
1119 g_assert_no_error (error);
1120
1121 g_object_unref (object: data->server);
1122 g_object_unref (object: client);
1123 g_object_unref (object: v4addr);
1124
1125 g_slice_free (IPTestData, data);
1126}
1127#endif
1128
1129static void
1130test_timed_wait (void)
1131{
1132 IPTestData *data;
1133 GError *error = NULL;
1134 GSocket *client;
1135 GSocketAddress *addr;
1136 gint64 start_time;
1137 gint poll_duration;
1138
1139 if (!g_test_thorough ())
1140 {
1141 g_test_skip (msg: "Not running timing heavy test");
1142 return;
1143 }
1144
1145 data = create_server (family: G_SOCKET_FAMILY_IPV4, server_thread: echo_server_thread, FALSE, error: &error);
1146 if (error != NULL)
1147 {
1148 gchar *message = g_strdup_printf (format: "Failed to create server: %s", error->message);
1149 g_test_skip (msg: message);
1150 g_free (mem: message);
1151 g_clear_error (err: &error);
1152 return;
1153 }
1154
1155 addr = g_socket_get_local_address (socket: data->server, error: &error);
1156 g_assert_no_error (error);
1157
1158 client = g_socket_new (family: G_SOCKET_FAMILY_IPV4,
1159 type: G_SOCKET_TYPE_STREAM,
1160 protocol: G_SOCKET_PROTOCOL_DEFAULT,
1161 error: &error);
1162 g_assert_no_error (error);
1163
1164 g_socket_set_blocking (socket: client, TRUE);
1165 g_socket_set_timeout (socket: client, timeout: 1);
1166
1167 g_socket_connect (socket: client, address: addr, NULL, error: &error);
1168 g_assert_no_error (error);
1169 g_object_unref (object: addr);
1170
1171 start_time = g_get_monotonic_time ();
1172 g_socket_condition_timed_wait (socket: client, condition: G_IO_IN, timeout_us: 100000 /* 100 ms */,
1173 NULL, error: &error);
1174 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
1175 g_clear_error (err: &error);
1176 poll_duration = g_get_monotonic_time () - start_time;
1177
1178 g_assert_cmpint (poll_duration, >=, 98000);
1179 g_assert_cmpint (poll_duration, <, 112000);
1180
1181 g_socket_close (socket: client, error: &error);
1182 g_assert_no_error (error);
1183
1184 g_thread_join (thread: data->thread);
1185
1186 g_socket_close (socket: data->server, error: &error);
1187 g_assert_no_error (error);
1188
1189 g_object_unref (object: data->server);
1190 g_object_unref (object: client);
1191
1192 g_slice_free (IPTestData, data);
1193}
1194
1195static int
1196duplicate_fd (int fd)
1197{
1198#ifdef G_OS_WIN32
1199 HANDLE newfd;
1200
1201 if (!DuplicateHandle (GetCurrentProcess (),
1202 (HANDLE)fd,
1203 GetCurrentProcess (),
1204 &newfd,
1205 0,
1206 FALSE,
1207 DUPLICATE_SAME_ACCESS))
1208 {
1209 return -1;
1210 }
1211
1212 return (int)newfd;
1213#else
1214 return dup (fd: fd);
1215#endif
1216}
1217
1218static void
1219test_fd_reuse (void)
1220{
1221 IPTestData *data;
1222 GError *error = NULL;
1223 GSocket *client;
1224 GSocket *client2;
1225 GSocketAddress *addr;
1226 int fd;
1227 gssize len;
1228 gchar buf[128];
1229
1230 g_test_bug (bug_uri_snippet: "741707");
1231
1232 data = create_server (family: G_SOCKET_FAMILY_IPV4, server_thread: echo_server_thread, FALSE, error: &error);
1233 if (error != NULL)
1234 {
1235 gchar *message = g_strdup_printf (format: "Failed to create server: %s", error->message);
1236 g_test_skip (msg: message);
1237 g_free (mem: message);
1238 g_clear_error (err: &error);
1239 return;
1240 }
1241
1242 addr = g_socket_get_local_address (socket: data->server, error: &error);
1243 g_assert_no_error (error);
1244
1245 client = g_socket_new (family: G_SOCKET_FAMILY_IPV4,
1246 type: G_SOCKET_TYPE_STREAM,
1247 protocol: G_SOCKET_PROTOCOL_DEFAULT,
1248 error: &error);
1249 g_assert_no_error (error);
1250
1251 g_socket_set_blocking (socket: client, TRUE);
1252 g_socket_set_timeout (socket: client, timeout: 1);
1253
1254 g_socket_connect (socket: client, address: addr, NULL, error: &error);
1255 g_assert_no_error (error);
1256 g_assert (g_socket_is_connected (client));
1257 g_object_unref (object: addr);
1258
1259 /* we have to dup otherwise the fd gets closed twice on unref */
1260 fd = duplicate_fd (fd: g_socket_get_fd (socket: client));
1261 client2 = g_socket_new_from_fd (fd, error: &error);
1262 g_assert_no_error (error);
1263
1264 g_assert_cmpint (g_socket_get_family (client2), ==, g_socket_get_family (client));
1265 g_assert_cmpint (g_socket_get_socket_type (client2), ==, g_socket_get_socket_type (client));
1266 g_assert_cmpint (g_socket_get_protocol (client2), ==, G_SOCKET_PROTOCOL_TCP);
1267
1268 len = g_socket_send (socket: client2, buffer: testbuf, size: strlen (s: testbuf) + 1, NULL, error: &error);
1269 g_assert_no_error (error);
1270 g_assert_cmpint (len, ==, strlen (testbuf) + 1);
1271
1272 len = g_socket_receive (socket: client2, buffer: buf, size: sizeof (buf), NULL, error: &error);
1273 g_assert_no_error (error);
1274 g_assert_cmpint (len, ==, strlen (testbuf) + 1);
1275
1276 g_assert_cmpstr (testbuf, ==, buf);
1277
1278 g_socket_shutdown (socket: client, FALSE, TRUE, error: &error);
1279 g_assert_no_error (error);
1280 /* The semantics of dup()+shutdown() are ambiguous; this call will succeed
1281 * on Linux, but return ENOTCONN on OS X.
1282 */
1283 g_socket_shutdown (socket: client2, FALSE, TRUE, NULL);
1284
1285 g_thread_join (thread: data->thread);
1286
1287 g_socket_close (socket: client, error: &error);
1288 g_assert_no_error (error);
1289 g_socket_close (socket: client2, error: &error);
1290 g_assert_no_error (error);
1291 g_socket_close (socket: data->server, error: &error);
1292 g_assert_no_error (error);
1293
1294 g_assert_cmpint (g_socket_get_fd (client), ==, -1);
1295 g_assert_cmpint (g_socket_get_fd (client2), ==, -1);
1296 g_assert_cmpint (g_socket_get_fd (data->server), ==, -1);
1297
1298 g_object_unref (object: data->server);
1299 g_object_unref (object: client);
1300 g_object_unref (object: client2);
1301
1302 g_slice_free (IPTestData, data);
1303}
1304
1305static void
1306test_sockaddr (void)
1307{
1308 struct sockaddr_in6 sin6, gsin6;
1309 GSocketAddress *saddr;
1310 GInetSocketAddress *isaddr;
1311 GInetAddress *iaddr;
1312 GError *error = NULL;
1313
1314 memset (s: &sin6, c: 0, n: sizeof (sin6));
1315 sin6.sin6_family = AF_INET6;
1316 sin6.sin6_addr = in6addr_loopback;
1317 sin6.sin6_port = g_htons (42);
1318 sin6.sin6_scope_id = 17;
1319 sin6.sin6_flowinfo = 1729;
1320
1321 saddr = g_socket_address_new_from_native (native: &sin6, len: sizeof (sin6));
1322 g_assert (G_IS_INET_SOCKET_ADDRESS (saddr));
1323
1324 isaddr = G_INET_SOCKET_ADDRESS (saddr);
1325 iaddr = g_inet_socket_address_get_address (address: isaddr);
1326 g_assert_cmpint (g_inet_address_get_family (iaddr), ==, G_SOCKET_FAMILY_IPV6);
1327 g_assert (g_inet_address_get_is_loopback (iaddr));
1328
1329 g_assert_cmpint (g_inet_socket_address_get_port (isaddr), ==, 42);
1330 g_assert_cmpint (g_inet_socket_address_get_scope_id (isaddr), ==, 17);
1331 g_assert_cmpint (g_inet_socket_address_get_flowinfo (isaddr), ==, 1729);
1332
1333 g_socket_address_to_native (address: saddr, dest: &gsin6, destlen: sizeof (gsin6), error: &error);
1334 g_assert_no_error (error);
1335
1336 g_assert (memcmp (&sin6.sin6_addr, &gsin6.sin6_addr, sizeof (struct in6_addr)) == 0);
1337 g_assert_cmpint (sin6.sin6_port, ==, gsin6.sin6_port);
1338 g_assert_cmpint (sin6.sin6_scope_id, ==, gsin6.sin6_scope_id);
1339 g_assert_cmpint (sin6.sin6_flowinfo, ==, gsin6.sin6_flowinfo);
1340
1341 g_object_unref (object: saddr);
1342}
1343
1344#ifdef G_OS_UNIX
1345static void
1346test_unix_from_fd (void)
1347{
1348 gint fd;
1349 GError *error;
1350 GSocket *s;
1351
1352 fd = socket (AF_UNIX, SOCK_STREAM, protocol: 0);
1353 g_assert_cmpint (fd, !=, -1);
1354
1355 error = NULL;
1356 s = g_socket_new_from_fd (fd, error: &error);
1357 g_assert_no_error (error);
1358 g_assert_cmpint (g_socket_get_family (s), ==, G_SOCKET_FAMILY_UNIX);
1359 g_assert_cmpint (g_socket_get_socket_type (s), ==, G_SOCKET_TYPE_STREAM);
1360 g_assert_cmpint (g_socket_get_protocol (s), ==, G_SOCKET_PROTOCOL_DEFAULT);
1361 g_object_unref (object: s);
1362}
1363
1364static void
1365test_unix_connection (void)
1366{
1367 gint fd;
1368 GError *error;
1369 GSocket *s;
1370 GSocketConnection *c;
1371
1372 fd = socket (AF_UNIX, SOCK_STREAM, protocol: 0);
1373 g_assert_cmpint (fd, !=, -1);
1374
1375 error = NULL;
1376 s = g_socket_new_from_fd (fd, error: &error);
1377 g_assert_no_error (error);
1378 c = g_socket_connection_factory_create_connection (socket: s);
1379 g_assert (G_IS_UNIX_CONNECTION (c));
1380 g_object_unref (object: c);
1381 g_object_unref (object: s);
1382}
1383
1384static GSocketConnection *
1385create_connection_for_fd (int fd)
1386{
1387 GError *err = NULL;
1388 GSocket *socket;
1389 GSocketConnection *connection;
1390
1391 socket = g_socket_new_from_fd (fd, error: &err);
1392 g_assert_no_error (err);
1393 g_assert (G_IS_SOCKET (socket));
1394 connection = g_socket_connection_factory_create_connection (socket);
1395 g_assert (G_IS_UNIX_CONNECTION (connection));
1396 g_object_unref (object: socket);
1397 return connection;
1398}
1399
1400#define TEST_DATA "failure to say failure to say 'i love gnome-panel!'."
1401
1402static void
1403test_unix_connection_ancillary_data (void)
1404{
1405 GError *err = NULL;
1406 gint pv[2], sv[3];
1407 gint status, fd, len;
1408 char buffer[1024];
1409 pid_t pid;
1410
1411 status = pipe (pipedes: pv);
1412 g_assert_cmpint (status, ==, 0);
1413
1414 status = socketpair (PF_UNIX, SOCK_STREAM, protocol: 0, fds: sv);
1415 g_assert_cmpint (status, ==, 0);
1416
1417 pid = fork ();
1418 g_assert_cmpint (pid, >=, 0);
1419
1420 /* Child: close its copy of the write end of the pipe, receive it
1421 * again from the parent over the socket, and write some text to it.
1422 *
1423 * Parent: send the write end of the pipe (still open for the
1424 * parent) over the socket, close it, and read some text from the
1425 * read end of the pipe.
1426 */
1427 if (pid == 0)
1428 {
1429 GSocketConnection *connection;
1430
1431 close (fd: sv[1]);
1432 connection = create_connection_for_fd (fd: sv[0]);
1433
1434 status = close (fd: pv[1]);
1435 g_assert_cmpint (status, ==, 0);
1436
1437 err = NULL;
1438 fd = g_unix_connection_receive_fd (G_UNIX_CONNECTION (connection), NULL,
1439 error: &err);
1440 g_assert_no_error (err);
1441 g_assert_cmpint (fd, >, -1);
1442 g_object_unref (object: connection);
1443
1444 do
1445 len = write (fd: fd, TEST_DATA, n: sizeof (TEST_DATA));
1446 while (len == -1 && errno == EINTR);
1447 g_assert_cmpint (len, ==, sizeof (TEST_DATA));
1448 exit (status: 0);
1449 }
1450 else
1451 {
1452 GSocketConnection *connection;
1453
1454 close (fd: sv[0]);
1455 connection = create_connection_for_fd (fd: sv[1]);
1456
1457 err = NULL;
1458 g_unix_connection_send_fd (G_UNIX_CONNECTION (connection), fd: pv[1], NULL,
1459 error: &err);
1460 g_assert_no_error (err);
1461 g_object_unref (object: connection);
1462
1463 status = close (fd: pv[1]);
1464 g_assert_cmpint (status, ==, 0);
1465
1466 memset (s: buffer, c: 0xff, n: sizeof buffer);
1467 do
1468 len = read (fd: pv[0], buf: buffer, nbytes: sizeof buffer);
1469 while (len == -1 && errno == EINTR);
1470
1471 g_assert_cmpint (len, ==, sizeof (TEST_DATA));
1472 g_assert_cmpstr (buffer, ==, TEST_DATA);
1473
1474 waitpid (pid: pid, stat_loc: &status, options: 0);
1475 g_assert (WIFEXITED (status));
1476 g_assert_cmpint (WEXITSTATUS (status), ==, 0);
1477 }
1478
1479 /* TODO: add test for g_unix_connection_send_credentials() and
1480 * g_unix_connection_receive_credentials().
1481 */
1482}
1483
1484static gboolean
1485postmortem_source_cb (GSocket *socket,
1486 GIOCondition condition,
1487 gpointer user_data)
1488{
1489 gboolean *been_here = user_data;
1490
1491 g_assert_cmpint (condition, ==, G_IO_NVAL);
1492
1493 *been_here = TRUE;
1494 return FALSE;
1495}
1496
1497static void
1498test_source_postmortem (void)
1499{
1500 GMainContext *context;
1501 GSocket *socket;
1502 GSource *source;
1503 GError *error = NULL;
1504 gboolean callback_visited = FALSE;
1505
1506 socket = g_socket_new (family: G_SOCKET_FAMILY_UNIX, type: G_SOCKET_TYPE_STREAM, protocol: G_SOCKET_PROTOCOL_DEFAULT, error: &error);
1507 g_assert_no_error (error);
1508
1509 context = g_main_context_new ();
1510
1511 source = g_socket_create_source (socket, condition: G_IO_IN, NULL);
1512 g_source_set_callback (source, func: (GSourceFunc) postmortem_source_cb,
1513 data: &callback_visited, NULL);
1514 g_source_attach (source, context);
1515 g_source_unref (source);
1516
1517 g_socket_close (socket, error: &error);
1518 g_assert_no_error (error);
1519 g_object_unref (object: socket);
1520
1521 /* Test that, after a socket is closed, its source callback should be called
1522 * exactly once. */
1523 g_main_context_iteration (context, FALSE);
1524 g_assert (callback_visited);
1525 g_assert (!g_main_context_pending (context));
1526
1527 g_main_context_unref (context);
1528}
1529
1530#endif /* G_OS_UNIX */
1531
1532static void
1533test_reuse_tcp (void)
1534{
1535 GSocket *sock1, *sock2;
1536 GError *error = NULL;
1537 GInetAddress *iaddr;
1538 GSocketAddress *addr;
1539
1540 sock1 = g_socket_new (family: G_SOCKET_FAMILY_IPV4,
1541 type: G_SOCKET_TYPE_STREAM,
1542 protocol: G_SOCKET_PROTOCOL_DEFAULT,
1543 error: &error);
1544 g_assert_no_error (error);
1545
1546 iaddr = g_inet_address_new_loopback (family: G_SOCKET_FAMILY_IPV4);
1547 addr = g_inet_socket_address_new (address: iaddr, port: 0);
1548 g_object_unref (object: iaddr);
1549 g_socket_bind (socket: sock1, address: addr, TRUE, error: &error);
1550 g_object_unref (object: addr);
1551 g_assert_no_error (error);
1552
1553 g_socket_listen (socket: sock1, error: &error);
1554 g_assert_no_error (error);
1555
1556 sock2 = g_socket_new (family: G_SOCKET_FAMILY_IPV4,
1557 type: G_SOCKET_TYPE_STREAM,
1558 protocol: G_SOCKET_PROTOCOL_DEFAULT,
1559 error: &error);
1560 g_assert_no_error (error);
1561
1562 addr = g_socket_get_local_address (socket: sock1, error: &error);
1563 g_assert_no_error (error);
1564 g_socket_bind (socket: sock2, address: addr, TRUE, error: &error);
1565 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_ADDRESS_IN_USE);
1566 g_clear_error (err: &error);
1567 g_object_unref (object: addr);
1568
1569 g_object_unref (object: sock1);
1570 g_object_unref (object: sock2);
1571}
1572
1573static void
1574test_reuse_udp (void)
1575{
1576 GSocket *sock1, *sock2;
1577 GError *error = NULL;
1578 GInetAddress *iaddr;
1579 GSocketAddress *addr;
1580
1581 sock1 = g_socket_new (family: G_SOCKET_FAMILY_IPV4,
1582 type: G_SOCKET_TYPE_DATAGRAM,
1583 protocol: G_SOCKET_PROTOCOL_DEFAULT,
1584 error: &error);
1585 g_assert_no_error (error);
1586
1587 iaddr = g_inet_address_new_loopback (family: G_SOCKET_FAMILY_IPV4);
1588 addr = g_inet_socket_address_new (address: iaddr, port: 0);
1589 g_object_unref (object: iaddr);
1590 g_socket_bind (socket: sock1, address: addr, TRUE, error: &error);
1591 g_object_unref (object: addr);
1592 g_assert_no_error (error);
1593
1594 sock2 = g_socket_new (family: G_SOCKET_FAMILY_IPV4,
1595 type: G_SOCKET_TYPE_DATAGRAM,
1596 protocol: G_SOCKET_PROTOCOL_DEFAULT,
1597 error: &error);
1598 g_assert_no_error (error);
1599
1600 addr = g_socket_get_local_address (socket: sock1, error: &error);
1601 g_assert_no_error (error);
1602 g_socket_bind (socket: sock2, address: addr, TRUE, error: &error);
1603 g_object_unref (object: addr);
1604 g_assert_no_error (error);
1605
1606 g_object_unref (object: sock1);
1607 g_object_unref (object: sock2);
1608}
1609
1610static void
1611test_get_available (gconstpointer user_data)
1612{
1613 GSocketType socket_type = GPOINTER_TO_UINT (user_data);
1614 GError *err = NULL;
1615 GSocket *listener, *server, *client;
1616 GInetAddress *addr;
1617 GSocketAddress *saddr, *boundaddr;
1618 gchar data[] = "0123456789abcdef";
1619 gchar buf[34];
1620 gssize nread;
1621
1622 listener = g_socket_new (family: G_SOCKET_FAMILY_IPV4,
1623 type: socket_type,
1624 protocol: G_SOCKET_PROTOCOL_DEFAULT,
1625 error: &err);
1626 g_assert_no_error (err);
1627 g_assert (G_IS_SOCKET (listener));
1628
1629 client = g_socket_new (family: G_SOCKET_FAMILY_IPV4,
1630 type: socket_type,
1631 protocol: G_SOCKET_PROTOCOL_DEFAULT,
1632 error: &err);
1633 g_assert_no_error (err);
1634 g_assert (G_IS_SOCKET (client));
1635
1636 if (socket_type == G_SOCKET_TYPE_STREAM)
1637 {
1638 g_socket_set_option (socket: client, IPPROTO_TCP, TCP_NODELAY, TRUE, error: &err);
1639 g_assert_no_error (err);
1640 }
1641
1642 addr = g_inet_address_new_any (family: G_SOCKET_FAMILY_IPV4);
1643 saddr = g_inet_socket_address_new (address: addr, port: 0);
1644
1645 g_socket_bind (socket: listener, address: saddr, TRUE, error: &err);
1646 g_assert_no_error (err);
1647 g_object_unref (object: saddr);
1648 g_object_unref (object: addr);
1649
1650 boundaddr = g_socket_get_local_address (socket: listener, error: &err);
1651 g_assert_no_error (err);
1652
1653 addr = g_inet_address_new_loopback (family: G_SOCKET_FAMILY_IPV4);
1654 saddr = g_inet_socket_address_new (address: addr, port: g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (boundaddr)));
1655 g_object_unref (object: addr);
1656 g_object_unref (object: boundaddr);
1657
1658 if (socket_type == G_SOCKET_TYPE_STREAM)
1659 {
1660 g_socket_listen (socket: listener, error: &err);
1661 g_assert_no_error (err);
1662 g_socket_connect (socket: client, address: saddr, NULL, error: &err);
1663 g_assert_no_error (err);
1664
1665 server = g_socket_accept (socket: listener, NULL, error: &err);
1666 g_assert_no_error (err);
1667 g_socket_set_blocking (socket: server, FALSE);
1668 g_object_unref (object: listener);
1669 }
1670 else
1671 server = listener;
1672
1673 g_socket_send_to (socket: client, address: saddr, buffer: data, size: sizeof (data), NULL, error: &err);
1674 g_assert_no_error (err);
1675
1676 while (!g_socket_condition_wait (socket: server, condition: G_IO_IN, NULL, NULL))
1677 ;
1678 g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data));
1679
1680 g_socket_send_to (socket: client, address: saddr, buffer: data, size: sizeof (data), NULL, error: &err);
1681 g_assert_no_error (err);
1682
1683 /* We need to wait until the data has actually been copied into the
1684 * server socket's buffers, but g_socket_condition_wait() won't help
1685 * here since the socket is definitely already readable. So there's
1686 * a race condition in checking its available bytes. In the TCP
1687 * case, we poll for a bit until the new data shows up. In the UDP
1688 * case, there's not much we can do, but at least the failure mode
1689 * is passes-when-it-shouldn't, not fails-when-it-shouldn't.
1690 */
1691 if (socket_type == G_SOCKET_TYPE_STREAM)
1692 {
1693 int tries;
1694
1695 for (tries = 0; tries < 100; tries++)
1696 {
1697 if (g_socket_get_available_bytes (socket: server) > sizeof (data))
1698 break;
1699 g_usleep (microseconds: 100000);
1700 }
1701
1702 g_assert_cmpint (g_socket_get_available_bytes (server), ==, 2 * sizeof (data));
1703 }
1704 else
1705 {
1706 g_usleep (microseconds: 100000);
1707 g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data));
1708 }
1709
1710 g_assert_cmpint (sizeof (buf), >=, 2 * sizeof (data));
1711 nread = g_socket_receive (socket: server, buffer: buf, size: sizeof (buf), NULL, error: &err);
1712 g_assert_no_error (err);
1713
1714 if (socket_type == G_SOCKET_TYPE_STREAM)
1715 {
1716 g_assert_cmpint (nread, ==, 2 * sizeof (data));
1717 g_assert_cmpint (g_socket_get_available_bytes (server), ==, 0);
1718 }
1719 else
1720 {
1721 g_assert_cmpint (nread, ==, sizeof (data));
1722 g_assert_cmpint (g_socket_get_available_bytes (server), ==, sizeof (data));
1723 }
1724
1725 nread = g_socket_receive (socket: server, buffer: buf, size: sizeof (buf), NULL, error: &err);
1726 if (socket_type == G_SOCKET_TYPE_STREAM)
1727 {
1728 g_assert_cmpint (nread, ==, -1);
1729 g_assert_error (err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
1730 g_clear_error (err: &err);
1731 }
1732 else
1733 {
1734 g_assert_cmpint (nread, ==, sizeof (data));
1735 g_assert_no_error (err);
1736 }
1737
1738 g_assert_cmpint (g_socket_get_available_bytes (server), ==, 0);
1739
1740 g_socket_close (socket: server, error: &err);
1741 g_assert_no_error (err);
1742
1743 g_object_unref (object: saddr);
1744 g_object_unref (object: server);
1745 g_object_unref (object: client);
1746}
1747
1748typedef struct {
1749 GInputStream *is;
1750 GOutputStream *os;
1751 const guint8 *write_data;
1752 guint8 *read_data;
1753} TestReadWriteData;
1754
1755static gpointer
1756test_read_write_write_thread (gpointer user_data)
1757{
1758 TestReadWriteData *data = user_data;
1759 gsize bytes_written;
1760 GError *error = NULL;
1761 gboolean res;
1762
1763 res = g_output_stream_write_all (stream: data->os, buffer: data->write_data, count: 1024, bytes_written: &bytes_written, NULL, error: &error);
1764 g_assert_true (res);
1765 g_assert_no_error (error);
1766 g_assert_cmpint (bytes_written, ==, 1024);
1767
1768 return NULL;
1769}
1770
1771static gpointer
1772test_read_write_read_thread (gpointer user_data)
1773{
1774 TestReadWriteData *data = user_data;
1775 gsize bytes_read;
1776 GError *error = NULL;
1777 gboolean res;
1778
1779 res = g_input_stream_read_all (stream: data->is, buffer: data->read_data, count: 1024, bytes_read: &bytes_read, NULL, error: &error);
1780 g_assert_true (res);
1781 g_assert_no_error (error);
1782 g_assert_cmpint (bytes_read, ==, 1024);
1783
1784 return NULL;
1785}
1786
1787static gpointer
1788test_read_write_writev_thread (gpointer user_data)
1789{
1790 TestReadWriteData *data = user_data;
1791 gsize bytes_written;
1792 GError *error = NULL;
1793 gboolean res;
1794 GOutputVector vectors[3];
1795
1796 vectors[0].buffer = data->write_data;
1797 vectors[0].size = 256;
1798 vectors[1].buffer = data->write_data + 256;
1799 vectors[1].size = 256;
1800 vectors[2].buffer = data->write_data + 512;
1801 vectors[2].size = 512;
1802
1803 res = g_output_stream_writev_all (stream: data->os, vectors, G_N_ELEMENTS (vectors), bytes_written: &bytes_written, NULL, error: &error);
1804 g_assert_true (res);
1805 g_assert_no_error (error);
1806 g_assert_cmpint (bytes_written, ==, 1024);
1807
1808 return NULL;
1809}
1810
1811/* test if normal read/write/writev via the GSocket*Streams works on TCP sockets */
1812static void
1813test_read_write (gconstpointer user_data)
1814{
1815 gboolean writev = GPOINTER_TO_INT (user_data);
1816 GError *err = NULL;
1817 GSocket *listener, *server, *client;
1818 GInetAddress *addr;
1819 GSocketAddress *saddr, *boundaddr;
1820 TestReadWriteData data;
1821 guint8 data_write[1024], data_read[1024];
1822 GSocketConnection *server_stream, *client_stream;
1823 GThread *write_thread, *read_thread;
1824 guint i;
1825
1826 listener = g_socket_new (family: G_SOCKET_FAMILY_IPV4,
1827 type: G_SOCKET_TYPE_STREAM,
1828 protocol: G_SOCKET_PROTOCOL_DEFAULT,
1829 error: &err);
1830 g_assert_no_error (err);
1831 g_assert (G_IS_SOCKET (listener));
1832
1833 client = g_socket_new (family: G_SOCKET_FAMILY_IPV4,
1834 type: G_SOCKET_TYPE_STREAM,
1835 protocol: G_SOCKET_PROTOCOL_DEFAULT,
1836 error: &err);
1837 g_assert_no_error (err);
1838 g_assert (G_IS_SOCKET (client));
1839
1840 addr = g_inet_address_new_any (family: G_SOCKET_FAMILY_IPV4);
1841 saddr = g_inet_socket_address_new (address: addr, port: 0);
1842
1843 g_socket_bind (socket: listener, address: saddr, TRUE, error: &err);
1844 g_assert_no_error (err);
1845 g_object_unref (object: saddr);
1846 g_object_unref (object: addr);
1847
1848 boundaddr = g_socket_get_local_address (socket: listener, error: &err);
1849 g_assert_no_error (err);
1850
1851 g_socket_listen (socket: listener, error: &err);
1852 g_assert_no_error (err);
1853
1854 addr = g_inet_address_new_loopback (family: G_SOCKET_FAMILY_IPV4);
1855 saddr = g_inet_socket_address_new (address: addr, port: g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (boundaddr)));
1856 g_object_unref (object: addr);
1857 g_object_unref (object: boundaddr);
1858
1859 g_socket_connect (socket: client, address: saddr, NULL, error: &err);
1860 g_assert_no_error (err);
1861
1862 server = g_socket_accept (socket: listener, NULL, error: &err);
1863 g_assert_no_error (err);
1864 g_socket_set_blocking (socket: server, FALSE);
1865 g_object_unref (object: listener);
1866
1867 server_stream = g_socket_connection_factory_create_connection (socket: server);
1868 g_assert_nonnull (server_stream);
1869 client_stream = g_socket_connection_factory_create_connection (socket: client);
1870 g_assert_nonnull (client_stream);
1871
1872 for (i = 0; i < sizeof (data_write); i++)
1873 data_write[i] = i;
1874
1875 data.is = g_io_stream_get_input_stream (G_IO_STREAM (server_stream));
1876 data.os = g_io_stream_get_output_stream (G_IO_STREAM (client_stream));
1877 data.read_data = data_read;
1878 data.write_data = data_write;
1879
1880 if (writev)
1881 write_thread = g_thread_new (name: "writer", func: test_read_write_writev_thread, data: &data);
1882 else
1883 write_thread = g_thread_new (name: "writer", func: test_read_write_write_thread, data: &data);
1884 read_thread = g_thread_new (name: "reader", func: test_read_write_read_thread, data: &data);
1885
1886 g_thread_join (thread: write_thread);
1887 g_thread_join (thread: read_thread);
1888
1889 g_assert_cmpmem (data_write, sizeof data_write, data_read, sizeof data_read);
1890
1891 g_socket_close (socket: server, error: &err);
1892 g_assert_no_error (err);
1893
1894 g_object_unref (object: server_stream);
1895 g_object_unref (object: client_stream);
1896
1897 g_object_unref (object: saddr);
1898 g_object_unref (object: server);
1899 g_object_unref (object: client);
1900}
1901
1902#ifdef SO_NOSIGPIPE
1903static void
1904test_nosigpipe (void)
1905{
1906 GSocket *sock;
1907 GError *error = NULL;
1908 gint value;
1909
1910 sock = g_socket_new (AF_INET,
1911 G_SOCKET_TYPE_STREAM,
1912 G_SOCKET_PROTOCOL_DEFAULT,
1913 &error);
1914 g_assert_no_error (error);
1915
1916 g_socket_get_option (sock, SOL_SOCKET, SO_NOSIGPIPE, &value, &error);
1917 g_assert_no_error (error);
1918 g_assert_true (value);
1919
1920 g_object_unref (sock);
1921}
1922#endif
1923
1924#if G_CREDENTIALS_SUPPORTED
1925static gpointer client_setup_thread (gpointer user_data);
1926
1927static void
1928test_credentials_tcp_client (void)
1929{
1930 const GSocketFamily family = G_SOCKET_FAMILY_IPV4;
1931 IPTestData *data;
1932 GError *error = NULL;
1933 GSocket *client;
1934 GSocketAddress *addr;
1935 GCredentials *creds;
1936
1937 data = create_server (family, server_thread: echo_server_thread, FALSE, error: &error);
1938 if (error != NULL)
1939 {
1940 gchar *message = g_strdup_printf (format: "Failed to create server: %s", error->message);
1941 g_test_skip (msg: message);
1942 g_free (mem: message);
1943 g_clear_error (err: &error);
1944 return;
1945 }
1946
1947 addr = g_socket_get_local_address (socket: data->server, error: &error);
1948 g_assert_no_error (error);
1949
1950 client = g_socket_new (family,
1951 type: G_SOCKET_TYPE_STREAM,
1952 protocol: G_SOCKET_PROTOCOL_DEFAULT,
1953 error: &error);
1954 g_assert_no_error (error);
1955
1956 g_socket_set_blocking (socket: client, TRUE);
1957 g_socket_set_timeout (socket: client, timeout: 1);
1958
1959 g_socket_connect (socket: client, address: addr, NULL, error: &error);
1960 g_assert_no_error (error);
1961 g_object_unref (object: addr);
1962
1963 creds = g_socket_get_credentials (socket: client, error: &error);
1964 if (creds != NULL)
1965 {
1966 gchar *str = g_credentials_to_string (credentials: creds);
1967 g_print (format: "Supported on this OS: %s\n", str);
1968 g_free (mem: str);
1969 g_clear_object (&creds);
1970 }
1971 else
1972 {
1973 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1974 g_print (format: "Unsupported on this OS: %s\n", error->message);
1975 g_clear_error (err: &error);
1976 }
1977
1978 g_socket_close (socket: client, error: &error);
1979 g_assert_no_error (error);
1980
1981 g_thread_join (thread: data->thread);
1982
1983 g_socket_close (socket: data->server, error: &error);
1984 g_assert_no_error (error);
1985
1986 g_object_unref (object: data->server);
1987 g_object_unref (object: client);
1988
1989 g_slice_free (IPTestData, data);
1990}
1991
1992static void
1993test_credentials_tcp_server (void)
1994{
1995 const GSocketFamily family = G_SOCKET_FAMILY_IPV4;
1996 IPTestData *data;
1997 GSocket *server;
1998 GError *error = NULL;
1999 GSocketAddress *addr = NULL;
2000 GInetAddress *iaddr = NULL;
2001 GSocket *sock = NULL;
2002 GCredentials *creds;
2003
2004 data = g_slice_new0 (IPTestData);
2005 data->family = family;
2006 data->server = server = g_socket_new (family,
2007 type: G_SOCKET_TYPE_STREAM,
2008 protocol: G_SOCKET_PROTOCOL_DEFAULT,
2009 error: &error);
2010 if (error != NULL)
2011 goto skip;
2012
2013 g_socket_set_blocking (socket: server, TRUE);
2014
2015 iaddr = g_inet_address_new_loopback (family);
2016 addr = g_inet_socket_address_new (address: iaddr, port: 0);
2017
2018 if (!g_socket_bind (socket: server, address: addr, TRUE, error: &error))
2019 goto skip;
2020
2021 if (!g_socket_listen (socket: server, error: &error))
2022 goto skip;
2023
2024 data->thread = g_thread_new (name: "client", func: client_setup_thread, data);
2025
2026 sock = g_socket_accept (socket: server, NULL, error: &error);
2027 g_assert_no_error (error);
2028
2029 creds = g_socket_get_credentials (socket: sock, error: &error);
2030 if (creds != NULL)
2031 {
2032 gchar *str = g_credentials_to_string (credentials: creds);
2033 g_print (format: "Supported on this OS: %s\n", str);
2034 g_free (mem: str);
2035 g_clear_object (&creds);
2036 }
2037 else
2038 {
2039 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
2040 g_print (format: "Unsupported on this OS: %s\n", error->message);
2041 g_clear_error (err: &error);
2042 }
2043
2044 goto beach;
2045
2046skip:
2047 {
2048 gchar *message = g_strdup_printf (format: "Failed to create server: %s", error->message);
2049 g_test_skip (msg: message);
2050 g_free (mem: message);
2051
2052 goto beach;
2053 }
2054beach:
2055 {
2056 g_clear_error (err: &error);
2057
2058 g_clear_object (&sock);
2059 g_clear_object (&addr);
2060 g_clear_object (&iaddr);
2061
2062 g_clear_pointer (&data->thread, g_thread_join);
2063 g_clear_object (&data->server);
2064 g_clear_object (&data->client);
2065
2066 g_slice_free (IPTestData, data);
2067 }
2068}
2069
2070static gpointer
2071client_setup_thread (gpointer user_data)
2072{
2073 IPTestData *data = user_data;
2074 GSocketAddress *addr;
2075 GSocket *client;
2076 GError *error = NULL;
2077
2078 addr = g_socket_get_local_address (socket: data->server, error: &error);
2079 g_assert_no_error (error);
2080
2081 data->client = client = g_socket_new (family: data->family,
2082 type: G_SOCKET_TYPE_STREAM,
2083 protocol: G_SOCKET_PROTOCOL_DEFAULT,
2084 error: &error);
2085 g_assert_no_error (error);
2086
2087 g_socket_set_blocking (socket: client, TRUE);
2088 g_socket_set_timeout (socket: client, timeout: 1);
2089
2090 g_socket_connect (socket: client, address: addr, NULL, error: &error);
2091 g_assert_no_error (error);
2092
2093 g_object_unref (object: addr);
2094
2095 return NULL;
2096}
2097
2098#ifdef G_OS_UNIX
2099static void
2100test_credentials_unix_socketpair (void)
2101{
2102 gint fds[2];
2103 gint status;
2104 GSocket *sock;
2105 GError *error = NULL;
2106 GCredentials *creds;
2107
2108 status = socketpair (PF_UNIX, SOCK_STREAM, protocol: 0, fds: fds);
2109 g_assert_cmpint (status, ==, 0);
2110
2111 sock = g_socket_new_from_fd (fd: fds[0], error: &error);
2112
2113 creds = g_socket_get_credentials (socket: sock, error: &error);
2114 if (creds != NULL)
2115 {
2116 gchar *str = g_credentials_to_string (credentials: creds);
2117 g_print (format: "Supported on this OS: %s\n", str);
2118 g_free (mem: str);
2119 g_clear_object (&creds);
2120 }
2121 else
2122 {
2123 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
2124 g_print (format: "Unsupported on this OS: %s\n", error->message);
2125 g_clear_error (err: &error);
2126 }
2127
2128 g_object_unref (object: sock);
2129 close (fd: fds[1]);
2130}
2131#endif
2132#endif
2133
2134int
2135main (int argc,
2136 char *argv[])
2137{
2138 GSocket *sock;
2139 GError *error = NULL;
2140
2141 g_test_init (argc: &argc, argv: &argv, NULL);
2142 g_test_bug_base (uri_pattern: "https://bugzilla.gnome.org/");
2143
2144 sock = g_socket_new (family: G_SOCKET_FAMILY_IPV6,
2145 type: G_SOCKET_TYPE_STREAM,
2146 protocol: G_SOCKET_PROTOCOL_DEFAULT,
2147 error: &error);
2148 if (sock != NULL)
2149 {
2150 ipv6_supported = TRUE;
2151 g_object_unref (object: sock);
2152 }
2153 else
2154 {
2155 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
2156 g_clear_error (err: &error);
2157 }
2158
2159 g_test_add_func (testpath: "/socket/ipv4_sync", test_func: test_ipv4_sync);
2160 g_test_add_func (testpath: "/socket/ipv4_async", test_func: test_ipv4_async);
2161 g_test_add_func (testpath: "/socket/ipv6_sync", test_func: test_ipv6_sync);
2162 g_test_add_func (testpath: "/socket/ipv6_async", test_func: test_ipv6_async);
2163 g_test_add_func (testpath: "/socket/ipv4_sync/datagram", test_func: test_ipv4_sync_dgram);
2164 g_test_add_func (testpath: "/socket/ipv4_sync/datagram/timeouts", test_func: test_ipv4_sync_dgram_timeouts);
2165 g_test_add_func (testpath: "/socket/ipv6_sync/datagram", test_func: test_ipv6_sync_dgram);
2166 g_test_add_func (testpath: "/socket/ipv6_sync/datagram/timeouts", test_func: test_ipv6_sync_dgram_timeouts);
2167#if defined (IPPROTO_IPV6) && defined (IPV6_V6ONLY)
2168 g_test_add_func (testpath: "/socket/ipv6_v4mapped", test_func: test_ipv6_v4mapped);
2169#endif
2170 g_test_add_func (testpath: "/socket/close_graceful", test_func: test_close_graceful);
2171 g_test_add_func (testpath: "/socket/timed_wait", test_func: test_timed_wait);
2172 g_test_add_func (testpath: "/socket/fd_reuse", test_func: test_fd_reuse);
2173 g_test_add_func (testpath: "/socket/address", test_func: test_sockaddr);
2174#ifdef G_OS_UNIX
2175 g_test_add_func (testpath: "/socket/unix-from-fd", test_func: test_unix_from_fd);
2176 g_test_add_func (testpath: "/socket/unix-connection", test_func: test_unix_connection);
2177 g_test_add_func (testpath: "/socket/unix-connection-ancillary-data", test_func: test_unix_connection_ancillary_data);
2178 g_test_add_func (testpath: "/socket/source-postmortem", test_func: test_source_postmortem);
2179#endif
2180 g_test_add_func (testpath: "/socket/reuse/tcp", test_func: test_reuse_tcp);
2181 g_test_add_func (testpath: "/socket/reuse/udp", test_func: test_reuse_udp);
2182 g_test_add_data_func (testpath: "/socket/get_available/datagram", GUINT_TO_POINTER (G_SOCKET_TYPE_DATAGRAM),
2183 test_func: test_get_available);
2184 g_test_add_data_func (testpath: "/socket/get_available/stream", GUINT_TO_POINTER (G_SOCKET_TYPE_STREAM),
2185 test_func: test_get_available);
2186 g_test_add_data_func (testpath: "/socket/read_write", GUINT_TO_POINTER (FALSE),
2187 test_func: test_read_write);
2188 g_test_add_data_func (testpath: "/socket/read_writev", GUINT_TO_POINTER (TRUE),
2189 test_func: test_read_write);
2190#ifdef SO_NOSIGPIPE
2191 g_test_add_func ("/socket/nosigpipe", test_nosigpipe);
2192#endif
2193#if G_CREDENTIALS_SUPPORTED
2194 g_test_add_func (testpath: "/socket/credentials/tcp_client", test_func: test_credentials_tcp_client);
2195 g_test_add_func (testpath: "/socket/credentials/tcp_server", test_func: test_credentials_tcp_server);
2196#ifdef G_OS_UNIX
2197 g_test_add_func (testpath: "/socket/credentials/unix_socketpair", test_func: test_credentials_unix_socketpair);
2198#endif
2199#endif
2200
2201 return g_test_run();
2202}
2203

source code of gtk/subprojects/glib/gio/tests/socket.c