2 * This file is part of the Nice GLib ICE library.
4 * © 2014, 2015 Collabora Ltd.
5 * Contact: Philip Withnall
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
17 * The Original Code is the Nice GLib ICE library.
19 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
20 * Corporation. All Rights Reserved.
23 * Philip Withnall, Collabora Ltd.
25 * Alternatively, the contents of this file may be used under the terms of the
26 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
27 * case the provisions of LGPL are applicable instead of those above. If you
28 * wish to allow use of your version of this file only under the terms of the
29 * LGPL and not to allow others to use your version of this file under the
30 * MPL, indicate your decision by deleting the provisions above and replace
31 * them with the notice and other provisions required by the LGPL. If you do
32 * not delete the provisions above, a recipient may use your version of this
33 * file under either the MPL or the LGPL.
45 #include <arpa/inet.h>
47 #include "pseudotcp.h"
51 PseudoTcpSocket *left; /* owned */
52 PseudoTcpSocket *right; /* owned */
54 guint32 left_current_time;
55 guint32 right_current_time;
57 /* Data sent and received by each socket. */
58 GQueue/*<owned GBytes>*/ *left_sent; /* owned */
59 GQueue/*<owned GBytes>*/ *right_sent; /* owned */
62 /* NOTE: Must match the on-the-wire flag values from pseudotcp.c. */
70 typedef void (*TestFunc) (Data *data, const void *next_funcs);
74 data_clear (Data *data)
76 if (data->left != NULL)
77 g_object_unref (data->left);
78 if (data->right != NULL)
79 g_object_unref (data->right);
81 if (data->left_sent != NULL)
82 g_queue_free_full (data->left_sent, (GDestroyNotify) g_bytes_unref);
83 if (data->right_sent != NULL)
84 g_queue_free_full (data->right_sent, (GDestroyNotify) g_bytes_unref);
89 segment_flags_to_string (SegmentFlags flags)
91 GString *str = g_string_new (NULL);
94 g_string_append (str, "SYN,");
96 g_string_append (str, "FIN,");
98 g_string_append (str, "RST,");
100 /* Strip the trailing comma. */
102 g_string_truncate (str, str->len - 1);
105 g_string_append (str, "0");
107 return g_string_free (str, FALSE);
111 segment_to_string (guint32 seq, guint32 ack, SegmentFlags flags)
115 ctl = segment_flags_to_string (flags);
116 out = g_strdup_printf ("<SEQ=%u><ACK=%u><CTL=%s>", seq, ack, ctl);
123 segment_bytes_to_string (const guint8 *bytes)
134 seq = ntohl (b.u32[1]);
135 ack = ntohl (b.u32[2]);
138 return segment_to_string (seq, ack, flags);
143 opened (PseudoTcpSocket *sock, gpointer data)
145 g_debug ("Socket %p opened", sock);
149 readable (PseudoTcpSocket *sock, gpointer data)
151 g_debug ("Socket %p readable", sock);
155 writable (PseudoTcpSocket *sock, gpointer data)
157 g_debug ("Socket %p writeable", sock);
161 closed (PseudoTcpSocket *sock, guint32 err, gpointer data)
163 g_debug ("Socket %p closed: %s", sock, strerror (err));
166 static PseudoTcpWriteResult
167 write_packet (PseudoTcpSocket *sock, const gchar *buffer, guint32 len,
170 Data *data = user_data;
171 gchar *str; /* owned */
172 GQueue/*<owned GBytes>*/ *queue; /* unowned */
173 GBytes *segment; /* owned */
176 str = segment_bytes_to_string ((const guint8 *) buffer);
177 g_debug ("%p sent: %s", sock, str);
180 /* One of the sockets has outputted a packet. */
181 if (sock == data->left)
182 queue = data->left_sent;
183 else if (sock == data->right)
184 queue = data->right_sent;
186 g_assert_not_reached ();
188 segment = g_bytes_new (buffer, len);
189 g_queue_push_tail (queue, segment);
196 create_sockets (Data *data, gboolean support_fin_ack)
198 PseudoTcpCallbacks cbs = {
199 data, opened, readable, writable, closed, write_packet
202 data->left = g_object_new (PSEUDO_TCP_SOCKET_TYPE,
205 "support-fin-ack", support_fin_ack,
207 data->right = g_object_new (PSEUDO_TCP_SOCKET_TYPE,
210 "support-fin-ack", support_fin_ack,
213 g_debug ("Left: %p, right: %p", data->left, data->right);
215 /* Control the socket clocks precisely. */
216 pseudo_tcp_socket_set_time (data->left, 1);
217 pseudo_tcp_socket_set_time (data->right, 1);
219 /* Sanity check the socket state. */
220 g_assert_cmpint (pseudo_tcp_socket_send (data->left, "foo", 3), ==, -1);
221 g_assert_cmpint (pseudo_tcp_socket_get_error (data->left), ==, ENOTCONN);
223 g_assert_cmpint (pseudo_tcp_socket_send (data->right, "foo", 3), ==, -1);
224 g_assert_cmpint (pseudo_tcp_socket_get_error (data->right), ==, ENOTCONN);
226 data->left_sent = g_queue_new ();
227 data->right_sent = g_queue_new ();
231 expect_segment (PseudoTcpSocket *socket, GQueue/*<owned GBytes>*/ *queue,
232 guint32 seq, guint32 ack, guint32 len, SegmentFlags flags)
234 GBytes *bytes; /* unowned */
242 str = segment_to_string (seq, ack, flags);
243 g_debug ("%p expect: %s", socket, str);
246 /* Grab the segment. */
247 bytes = g_queue_peek_head (queue);
248 g_assert (bytes != NULL);
250 b.u8 = g_bytes_get_data (bytes, &size);
251 g_assert_cmpuint (size, >=, 24); /* minimum packet size */
252 g_assert_cmpuint (size - 24, ==, len);
254 /* Check the segment’s fields. */
255 g_assert_cmpuint (ntohl (b.u32[1]), ==, seq);
256 g_assert_cmpuint (ntohl (b.u32[2]), ==, ack);
257 g_assert_cmpuint (b.u8[13], ==, flags);
261 expect_syn_sent (Data *data)
263 expect_segment (data->left, data->left_sent, 0, 0, 7, FLAG_SYN);
267 expect_syn_received (Data *data)
269 expect_segment (data->right, data->right_sent, 0, 7, 7, FLAG_SYN);
273 assert_empty_queues (Data *data)
275 g_assert_cmpuint (g_queue_get_length (data->left_sent), ==, 0);
276 g_assert_cmpuint (g_queue_get_length (data->right_sent), ==, 0);
279 /* Return whether the socket accepted the packet. */
281 forward_segment (GQueue/*<owned GBytes>*/ *from, PseudoTcpSocket *to)
283 GBytes *segment; /* owned */
288 segment = g_queue_pop_head (from);
289 g_assert (segment != NULL);
290 b = g_bytes_get_data (segment, &size);
291 retval = pseudo_tcp_socket_notify_packet (to, (const gchar *) b, size);
292 g_bytes_unref (segment);
298 forward_segment_ltr (Data *data)
300 g_assert (forward_segment (data->left_sent, data->right));
304 forward_segment_rtl (Data *data)
306 g_assert (forward_segment (data->right_sent, data->left));
310 duplicate_segment (GQueue/*<owned GBytes>*/ *queue)
312 GBytes *segment; /* unowned */
314 segment = g_queue_peek_head (queue);
315 g_assert (segment != NULL);
316 g_queue_push_head (queue, g_bytes_ref (segment));
320 drop_segment (PseudoTcpSocket *socket, GQueue/*<owned GBytes>*/ *queue)
322 GBytes *segment; /* owned */
325 segment = g_queue_pop_head (queue);
326 g_assert (segment != NULL);
328 str = segment_bytes_to_string (g_bytes_get_data (segment, NULL));
329 g_debug ("%p drop: %s", socket, str);
332 g_bytes_unref (segment);
335 /* Swap the order of the head-most two segments in the @queue. */
337 reorder_segments (PseudoTcpSocket *socket, GQueue/*<owned GBytes>*/ *queue)
339 GBytes *segment1, *segment2; /* unowned */
342 segment1 = g_queue_pop_head (queue);
343 g_assert (segment1 != NULL);
344 segment2 = g_queue_pop_head (queue);
345 g_assert (segment2 != NULL);
347 str = segment_bytes_to_string (g_bytes_get_data (segment1, NULL));
348 g_debug ("%p reorder: %s", socket, str);
350 str = segment_bytes_to_string (g_bytes_get_data (segment2, NULL));
351 g_debug ("%p after: %s", socket, str);
354 g_queue_push_head (queue, segment1);
355 g_queue_push_head (queue, segment2);
359 expect_socket_state (PseudoTcpSocket *socket, PseudoTcpState expected_state)
361 PseudoTcpState state;
363 g_object_get (socket, "state", &state, NULL);
364 g_assert_cmpuint (state, ==, expected_state);
368 expect_sockets_connected (Data *data)
370 expect_socket_state (data->left, PSEUDO_TCP_ESTABLISHED);
371 expect_socket_state (data->right, PSEUDO_TCP_ESTABLISHED);
375 expect_sockets_closed (Data *data)
379 expect_socket_state (data->left, PSEUDO_TCP_CLOSED);
380 expect_socket_state (data->right, PSEUDO_TCP_CLOSED);
382 g_assert_cmpint (pseudo_tcp_socket_send (data->left, "foo", 3), ==, -1);
383 g_assert_cmpint (pseudo_tcp_socket_get_error (data->left), ==, EPIPE);
384 g_assert_cmpint (pseudo_tcp_socket_recv (data->left, (char *) buf, sizeof (buf)), ==, 0);
386 g_assert_cmpint (pseudo_tcp_socket_send (data->right, "foo", 3), ==, -1);
387 g_assert_cmpint (pseudo_tcp_socket_get_error (data->right), ==, EPIPE);
388 g_assert_cmpint (pseudo_tcp_socket_recv (data->right, (char *) buf, sizeof (buf)), ==, 0);
392 increment_time (PseudoTcpSocket *socket, guint32 *counter, guint32 increment)
394 g_debug ("Incrementing %p time by %u from %u to %u", socket, increment,
395 *counter, *counter + increment);
396 *counter = *counter + increment;
398 pseudo_tcp_socket_set_time (socket, *counter);
399 pseudo_tcp_socket_notify_clock (socket);
403 increment_time_both (Data *data, guint32 increment)
405 increment_time (data->left, &data->left_current_time, increment);
406 increment_time (data->right, &data->right_current_time, increment);
410 expect_fin (PseudoTcpSocket *socket, GQueue/*<owned GBytes>*/ *queue,
411 guint32 seq, guint32 ack)
413 expect_segment (socket, queue, seq, ack, 0, FLAG_FIN);
417 expect_rst (PseudoTcpSocket *socket, GQueue/*<owned GBytes>*/ *queue,
418 guint32 seq, guint32 ack)
420 expect_segment (socket, queue, seq, ack, 0, FLAG_RST);
424 expect_ack (PseudoTcpSocket *socket, GQueue/*<owned GBytes>*/ *queue,
425 guint32 seq, guint32 ack)
427 expect_segment (socket, queue, seq, ack, 0, FLAG_NONE);
431 expect_data (PseudoTcpSocket *socket, GQueue/*<owned GBytes>*/ *queue,
432 guint32 seq, guint32 ack, guint32 len)
434 expect_segment (socket, queue, seq, ack, len, FLAG_NONE);
438 close_socket (PseudoTcpSocket *socket)
442 pseudo_tcp_socket_close (socket, FALSE);
444 g_assert_cmpint (pseudo_tcp_socket_send (socket, "foo", 3), ==, -1);
445 g_assert_cmpint (pseudo_tcp_socket_get_error (socket), ==, EPIPE);
446 g_assert_cmpint (pseudo_tcp_socket_recv (socket, (char *) buf, sizeof (buf)), ==, 0);
449 /* Helper to create a socket pair and perform the SYN handshake. */
451 establish_connection (Data *data)
453 create_sockets (data, TRUE);
454 pseudo_tcp_socket_connect (data->left);
455 expect_syn_sent (data);
456 forward_segment_ltr (data);
457 expect_syn_received (data);
458 forward_segment_rtl (data);
459 increment_time_both (data, 110);
460 expect_ack (data->left, data->left_sent, 7, 7);
461 forward_segment_ltr (data);
462 expect_sockets_connected (data);
464 assert_empty_queues (data);
467 /* Helper to close the LHS of a socket pair which has not transmitted any
468 * data (i.e. perform the first half of the FIN handshake). */
470 close_lhs (Data *data)
472 pseudo_tcp_socket_close (data->left, FALSE);
474 expect_fin (data->left, data->left_sent, 7, 7);
475 forward_segment_ltr (data);
477 expect_ack (data->right, data->right_sent, 7, 8);
478 forward_segment_rtl (data);
481 /* Helper to close the RHS of a socket pair which has not transmitted any
482 * data (i.e. perform the second half of the FIN handshake). */
484 close_rhs (Data *data)
486 pseudo_tcp_socket_close (data->right, FALSE);
488 expect_fin (data->right, data->right_sent, 7, 8);
489 forward_segment_rtl (data);
491 increment_time_both (data, 10); /* TIME-WAIT */
492 expect_ack (data->left, data->left_sent, 8, 8);
493 forward_segment_ltr (data);
496 /* Check that establishing a connection then immediately closing it works, using
497 * normal handshakes (FIN, ACK, FIN, ACK). See: RFC 793, Figure 13. */
499 pseudotcp_close_normal (void)
504 /* Establish a connection. */
505 establish_connection (&data);
507 /* Close it. Verify that sending fails. */
508 close_socket (data.left);
510 expect_fin (data.left, data.left_sent, 7, 7);
511 forward_segment_ltr (&data);
512 expect_ack (data.right, data.right_sent, 7, 8);
513 forward_segment_rtl (&data);
515 /* Check the RHS is closed. */
516 g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, 0);
517 close_socket (data.right);
519 expect_fin (data.right, data.right_sent, 7, 8);
520 forward_segment_rtl (&data);
521 increment_time_both (&data, 10); /* TIME-WAIT */
522 expect_ack (data.left, data.left_sent, 8, 8);
523 forward_segment_ltr (&data);
524 expect_sockets_closed (&data);
529 /* Check that establishing a connection then immediately closing it works, using
530 * simultaneous handshakes (FIN, FIN, ACK, ACK). See: RFC 793, Figure 14. */
532 pseudotcp_close_simultaneous (void)
536 /* Establish a connection. */
537 establish_connection (&data);
539 /* Close both sides simultaneously. Verify that sending fails. */
540 close_socket (data.left);
541 close_socket (data.right);
543 expect_fin (data.left, data.left_sent, 7, 7);
544 expect_fin (data.right, data.right_sent, 7, 7);
545 forward_segment_ltr (&data);
546 forward_segment_rtl (&data);
548 expect_ack (data.left, data.left_sent, 8, 8);
549 expect_ack (data.right, data.right_sent, 8, 8);
550 forward_segment_ltr (&data);
551 forward_segment_rtl (&data);
553 increment_time_both (&data, 10); /* TIME-WAIT */
554 expect_sockets_closed (&data);
559 /* Check that establishing a connection then immediately closing it works, using
560 * skewed handshakes. The segments are reordered so that the FIN and ACK from
561 * the LHS arrive at the RHS in reverse order. The RHS sees the ACK has a higher
562 * sequence number than the bytes it’s seen so far (as it hasn’t seen the LHS
563 * FIN at that point) and thus emits two sequential ACKs: one from before
564 * receiving the FIN (fast retransmit), and one from after.
565 * See: RFC 793, Figure 14. */
567 pseudotcp_close_skew1 (void)
571 /* Establish a connection. */
572 establish_connection (&data);
574 /* Close both sides simultaneously. Verify that sending fails. */
575 close_socket (data.left);
576 close_socket (data.right);
578 expect_fin (data.left, data.left_sent, 7, 7);
580 expect_fin (data.right, data.right_sent, 7, 7);
581 forward_segment_rtl (&data);
583 reorder_segments (data.left, data.left_sent);
584 expect_ack (data.left, data.left_sent, 8, 8);
585 forward_segment_ltr (&data);
586 forward_segment_ltr (&data);
588 expect_ack (data.right, data.right_sent, 8, 7);
589 forward_segment_rtl (&data);
590 expect_ack (data.right, data.right_sent, 8, 8);
591 forward_segment_rtl (&data);
593 increment_time_both (&data, 10); /* TIME-WAIT */
594 expect_sockets_closed (&data);
599 /* Same as pseudotcp_close_skew1() but with the packets reordered in a
602 pseudotcp_close_skew2 (void)
606 /* Establish a connection. */
607 establish_connection (&data);
609 /* Close both sides simultaneously. Verify that sending fails. */
610 close_socket (data.left);
611 close_socket (data.right);
613 expect_fin (data.right, data.right_sent, 7, 7);
615 expect_fin (data.left, data.left_sent, 7, 7);
616 forward_segment_ltr (&data);
618 reorder_segments (data.right, data.right_sent);
619 expect_ack (data.right, data.right_sent, 8, 8);
620 forward_segment_rtl (&data);
621 forward_segment_rtl (&data);
623 expect_ack (data.left, data.left_sent, 8, 7);
624 forward_segment_ltr (&data);
625 expect_ack (data.left, data.left_sent, 8, 8);
626 forward_segment_ltr (&data);
628 increment_time_both (&data, 10); /* TIME-WAIT */
629 expect_sockets_closed (&data);
634 /* Check that closing a connection recovers from the initial FIN segment being
635 * dropped. Based on: RFC 793, Figure 13. */
637 pseudotcp_close_normal_recovery1 (void)
641 /* Establish a connection. */
642 establish_connection (&data);
644 /* Close the LHS and drop the FIN segment. */
645 close_socket (data.left);
647 expect_fin (data.left, data.left_sent, 7, 7);
648 drop_segment (data.left, data.left_sent);
650 increment_time_both (&data, 1100); /* retransmit timeout */
652 expect_fin (data.left, data.left_sent, 7, 7);
653 forward_segment_ltr (&data);
655 expect_ack (data.right, data.right_sent, 7, 8);
656 forward_segment_rtl (&data);
661 expect_sockets_closed (&data);
666 /* Check that closing a connection recovers from the initial ACK segment being
667 * dropped. Based on: RFC 793, Figure 13. */
669 pseudotcp_close_normal_recovery2 (void)
673 /* Establish a connection. */
674 establish_connection (&data);
676 /* Close the LHS and drop the ACK segment. The LHS should retransmit the
678 close_socket (data.left);
680 expect_fin (data.left, data.left_sent, 7, 7);
681 forward_segment_ltr (&data);
683 expect_ack (data.right, data.right_sent, 7, 8);
684 drop_segment (data.right, data.right_sent);
685 increment_time_both (&data, 1100); /* retransmit timeout */
686 expect_fin (data.left, data.left_sent, 7, 7);
687 forward_segment_ltr (&data);
688 expect_ack (data.right, data.right_sent, 7, 8);
689 forward_segment_rtl (&data);
694 expect_sockets_closed (&data);
699 /* Check that closing a connection recovers from the second FIN segment being
700 * dropped. Based on: RFC 793, Figure 13. */
702 pseudotcp_close_normal_recovery3 (void)
706 /* Establish a connection. */
707 establish_connection (&data);
712 /* Close the RHS and drop the FIN segment. */
713 close_socket (data.right);
715 expect_fin (data.right, data.right_sent, 7, 8);
716 drop_segment (data.right, data.right_sent);
717 increment_time_both (&data, 300); /* retransmit timeout */
718 expect_fin (data.right, data.right_sent, 7, 8);
719 forward_segment_rtl (&data);
721 increment_time_both (&data, 10); /* TIME-WAIT */
722 expect_ack (data.left, data.left_sent, 8, 8);
723 forward_segment_ltr (&data);
725 expect_sockets_closed (&data);
730 /* Check that closing a connection recovers from the second ACK segment being
731 * dropped. Based on: RFC 793, Figure 13. */
733 pseudotcp_close_normal_recovery4 (void)
737 /* Establish a connection. */
738 establish_connection (&data);
743 /* Close the RHS and drop the ACK segment. The RHS should retransmit the
744 * FIN. The timers for the two peers are manipulated separately so the LHS
745 * doesn’t exceed its TIME-WAIT while waiting for the retransmit. */
746 close_socket (data.right);
748 expect_fin (data.right, data.right_sent, 7, 8);
749 forward_segment_rtl (&data);
751 expect_ack (data.left, data.left_sent, 8, 8);
752 drop_segment (data.left, data.left_sent);
753 increment_time (data.right, &data.right_current_time, 300); /* retransmit timeout */
754 expect_fin (data.right, data.right_sent, 7, 8);
755 forward_segment_rtl (&data);
756 increment_time (data.left, &data.left_current_time, 10); /* TIME-WAIT */
757 expect_ack (data.left, data.left_sent, 8, 8);
758 forward_segment_ltr (&data);
760 expect_sockets_closed (&data);
765 /* Check that closing a connection recovers from a data segment being dropped
766 * immediately before the first FIN is sent. Based on: RFC 793, Figure 13. */
768 pseudotcp_close_normal_recovery_data (void)
772 /* Establish a connection. */
773 establish_connection (&data);
775 /* Send some data from LHS to RHS, but drop the segment. */
776 g_assert_cmpint (pseudo_tcp_socket_send (data.left, "foo", 3), ==, 3);
777 expect_data (data.left, data.left_sent, 7, 7, 3);
778 drop_segment (data.left, data.left_sent);
780 assert_empty_queues(&data);
783 g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.left), ==, 0);
784 g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.right), ==, 0);
785 close_socket (data.left);
787 expect_socket_state (data.left, PSEUDO_TCP_FIN_WAIT_1);
788 expect_fin (data.left, data.left_sent, 10, 7);
789 forward_segment_ltr (&data);
791 expect_socket_state (data.right, PSEUDO_TCP_ESTABLISHED);
792 expect_ack (data.right, data.right_sent, 7, 7);
793 forward_segment_rtl (&data);
795 expect_socket_state (data.left, PSEUDO_TCP_FIN_WAIT_1);
797 assert_empty_queues(&data);
800 close_socket (data.right);
802 expect_socket_state (data.right, PSEUDO_TCP_FIN_WAIT_1);
804 expect_fin (data.right, data.right_sent, 7, 7);
805 forward_segment_rtl (&data);
807 expect_socket_state (data.left, PSEUDO_TCP_CLOSING);
809 expect_ack (data.left, data.left_sent, 11, 8);
810 forward_segment_ltr (&data);
812 expect_socket_state (data.right, PSEUDO_TCP_FIN_WAIT_2);
814 expect_data (data.right, data.right_sent, 8, 7, 0);
815 forward_segment_rtl (&data);
816 expect_socket_state (data.left, PSEUDO_TCP_CLOSING);
818 expect_data (data.left, data.left_sent, 7, 8, 3);
819 forward_segment_ltr (&data);
820 expect_socket_state (data.right, PSEUDO_TCP_TIME_WAIT);
822 increment_time_both (&data, 100); /* Delayed ACK */
824 expect_ack (data.right, data.right_sent, 8, 11);
825 forward_segment_rtl (&data);
826 expect_socket_state (data.left, PSEUDO_TCP_TIME_WAIT);
828 increment_time_both (&data, 10); /* TIME-WAIT */
830 expect_sockets_closed (&data);
835 /* Check that if both FIN segments from a simultaneous FIN handshake are
836 * dropped, the handshake recovers and completes successfully.
837 * See: RFC 793, Figure 14. */
839 pseudotcp_close_simultaneous_recovery1 (void)
843 /* Establish a connection. */
844 establish_connection (&data);
846 /* Close both sides simultaneously and drop the FINs. */
847 close_socket (data.left);
848 close_socket (data.right);
850 expect_fin (data.left, data.left_sent, 7, 7);
851 expect_fin (data.right, data.right_sent, 7, 7);
852 drop_segment (data.left, data.left_sent);
853 drop_segment (data.right, data.right_sent);
855 increment_time_both (&data, 1200); /* retransmit timeout */
857 expect_fin (data.left, data.left_sent, 7, 7);
858 expect_fin (data.right, data.right_sent, 7, 7);
859 forward_segment_ltr (&data);
860 forward_segment_rtl (&data);
862 expect_ack (data.left, data.left_sent, 8, 8);
863 expect_ack (data.right, data.right_sent, 8, 8);
864 forward_segment_ltr (&data);
865 forward_segment_rtl (&data);
867 increment_time_both (&data, 10); /* TIME-WAIT */
868 expect_sockets_closed (&data);
873 /* Check that if both ACK segments from a simultaneous FIN handshake are
874 * dropped, the handshake recovers and completes successfully.
875 * See: RFC 793, Figure 14. */
877 pseudotcp_close_simultaneous_recovery2 (void)
881 /* Establish a connection. */
882 establish_connection (&data);
884 /* Close both sides simultaneously and forward the FINs. */
885 close_socket (data.left);
886 close_socket (data.right);
888 expect_fin (data.left, data.left_sent, 7, 7);
889 expect_fin (data.right, data.right_sent, 7, 7);
890 forward_segment_ltr (&data);
891 forward_segment_rtl (&data);
894 expect_ack (data.left, data.left_sent, 8, 8);
895 expect_ack (data.right, data.right_sent, 8, 8);
896 drop_segment (data.left, data.left_sent);
897 drop_segment (data.right, data.right_sent);
899 increment_time_both (&data, 1200); /* retransmit timeout */
901 expect_fin (data.left, data.left_sent, 7, 8);
902 expect_fin (data.right, data.right_sent, 7, 8);
903 forward_segment_ltr (&data);
904 forward_segment_rtl (&data);
906 expect_ack (data.left, data.left_sent, 8, 8);
907 expect_ack (data.right, data.right_sent, 8, 8);
908 forward_segment_ltr (&data);
909 forward_segment_rtl (&data);
911 increment_time_both (&data, 10); /* TIME-WAIT */
913 expect_sockets_closed (&data);
918 /* Check that closing a connection ignores a duplicate FIN segment.
919 * Based on: RFC 793, Figure 13. */
921 pseudotcp_close_duplicate_fin (void)
925 /* Establish a connection. */
926 establish_connection (&data);
931 /* Close the RHS and duplicate the FIN segment. */
932 close_socket (data.right);
934 expect_fin (data.right, data.right_sent, 7, 8);
935 duplicate_segment (data.right_sent);
936 forward_segment_rtl (&data);
937 forward_segment_rtl (&data);
939 increment_time (data.left, &data.left_current_time, 10); /* TIME-WAIT */
940 expect_ack (data.left, data.left_sent, 8, 8);
941 forward_segment_ltr (&data);
943 expect_sockets_closed (&data);
948 /* Check that closing a connection ignores a duplicate ACK segment.
949 * Based on: RFC 793, Figure 13. */
951 pseudotcp_close_duplicate_ack (void)
955 /* Establish a connection. */
956 establish_connection (&data);
961 /* Close the RHS and duplicate the ACK segment. The RHS should reject the
962 * duplicate with a RST segment. The LHS should then reject the RST. */
963 close_socket (data.right);
965 expect_fin (data.right, data.right_sent, 7, 8);
966 forward_segment_rtl (&data);
968 increment_time (data.left, &data.left_current_time, 10); /* TIME-WAIT */
969 expect_ack (data.left, data.left_sent, 8, 8);
970 duplicate_segment (data.left_sent);
971 forward_segment_ltr (&data);
972 g_assert (!forward_segment (data.left_sent, data.right));
973 expect_rst (data.right, data.right_sent, 8, 8);
974 g_assert (!forward_segment (data.right_sent, data.left));
976 expect_sockets_closed (&data);
981 /* Check that forcefully closing a connection by sending a RST segment works.
982 * See: RFC 1122, §4.2.2.13. */
984 pseudotcp_close_rst (void)
989 /* Establish a connection. */
990 establish_connection (&data);
993 pseudo_tcp_socket_close (data.left, TRUE);
995 g_assert_cmpint (pseudo_tcp_socket_send (data.left, "foo", 3), ==, -1);
996 g_assert_cmpint (pseudo_tcp_socket_get_error (data.left), ==, EPIPE);
997 g_assert_cmpint (pseudo_tcp_socket_recv (data.left, (char *) buf, sizeof (buf)), ==, 0);
999 expect_rst (data.left, data.left_sent, 7, 7);
1000 g_assert (!forward_segment (data.left_sent, data.right));
1002 /* Check the RHS is closed. */
1003 g_assert_cmpint (pseudo_tcp_socket_send (data.right, "foo", 3), ==, -1);
1004 g_assert_cmpint (pseudo_tcp_socket_get_error (data.right), ==, EPIPE);
1005 g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, 0);
1007 expect_sockets_closed (&data);
1012 /* Check that an RST is sent if a connection is closed with pending data in the
1013 * local receive buffer. See: RFC 1122, §4.2.2.13. */
1015 pseudotcp_close_pending_received (void)
1020 /* Establish a connection. */
1021 establish_connection (&data);
1023 /* Send some data from RHS to LHS. Do *not* read the data from the LHS receive
1025 g_assert_cmpint (pseudo_tcp_socket_send (data.right, "foo", 3), ==, 3);
1026 expect_data (data.right, data.right_sent, 7, 7, 3);
1027 forward_segment_rtl (&data);
1029 /* Close the LHS. */
1030 g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.left), ==, 3);
1031 close_socket (data.left);
1033 expect_rst (data.left, data.left_sent, 7, 10);
1034 g_assert (!forward_segment (data.left_sent, data.right));
1036 /* Check the RHS is closed. */
1037 g_assert_cmpint (pseudo_tcp_socket_send (data.right, "foo", 3), ==, -1);
1038 g_assert_cmpint (pseudo_tcp_socket_get_error (data.right), ==, EPIPE);
1039 g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, 0);
1041 expect_sockets_closed (&data);
1046 /* Check that an RST is sent if data is received on a socket after close() has
1047 * been called. See: RFC 1122, §4.2.2.13. */
1049 pseudotcp_close_rst_afterwards (void)
1054 /* Establish a connection. */
1055 establish_connection (&data);
1057 /* Close the LHS. */
1058 g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.left), ==, 0);
1059 pseudo_tcp_socket_close (data.left, TRUE);
1060 close_socket (data.left);
1062 expect_rst (data.left, data.left_sent, 7, 7);
1063 drop_segment (data.left, data.left_sent); /* just to get it out of the way */
1065 assert_empty_queues(&data);
1067 /* Send some data from RHS to LHS, which should result in an RST. */
1068 g_assert_cmpint (pseudo_tcp_socket_send (data.right, "foo", 3), ==, 3);
1069 expect_data (data.right, data.right_sent, 7, 7, 3);
1070 g_assert (!forward_segment (data.right_sent, data.left));
1072 expect_rst (data.left, data.left_sent, 7, 7);
1073 g_assert (!forward_segment (data.left_sent, data.right));
1075 /* Check the RHS is closed. */
1076 g_assert_cmpint (pseudo_tcp_socket_send (data.right, "foo", 3), ==, -1);
1077 g_assert_cmpint (pseudo_tcp_socket_get_error (data.right), ==, EPIPE);
1078 g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, 0);
1080 expect_sockets_closed (&data);
1085 /* Check that two pseudo-TCP sockets interact correctly even if FIN–ACK support
1086 * is disabled on one of them. */
1088 pseudotcp_compatibility (void)
1094 /* Establish a connection. Note the sequence numbers should start at 4 this
1095 * time, rather than the 7 in other tests, because the FIN–ACK option should
1096 * not be being sent. */
1097 create_sockets (&data, FALSE);
1098 pseudo_tcp_socket_connect (data.left);
1099 expect_segment (data.left, data.left_sent, 0, 0, 4, FLAG_SYN);
1100 forward_segment_ltr (&data);
1101 expect_segment (data.right, data.right_sent, 0, 4, 4, FLAG_SYN);
1102 forward_segment_rtl (&data);
1103 increment_time_both (&data, 110);
1104 expect_ack (data.left, data.left_sent, 4, 4);
1105 forward_segment_ltr (&data);
1106 expect_sockets_connected (&data);
1108 /* Close it. Sending shouldn’t fail. */
1109 pseudo_tcp_socket_close (data.left, FALSE);
1110 g_assert (!pseudo_tcp_socket_is_closed (data.left));
1112 g_assert_cmpint (pseudo_tcp_socket_send (data.left, "foo", 3), ==, 3);
1113 g_assert_cmpint (pseudo_tcp_socket_recv (data.left, (char *) buf, sizeof (buf)), ==, -1);
1114 g_assert_cmpint (pseudo_tcp_socket_get_error (data.left), ==, EWOULDBLOCK);
1116 expect_data (data.left, data.left_sent, 4, 4, 3);
1117 forward_segment_ltr (&data);
1119 increment_time_both (&data, 100);
1121 expect_ack (data.right, data.right_sent, 4, 7);
1122 forward_segment_rtl (&data);
1124 /* Advance the timers; now the LHS should be closed, as the RHS has ACKed all
1125 * outstanding data. */
1126 increment_time_both (&data, 50);
1128 g_assert (!pseudo_tcp_socket_get_next_clock (data.left, &timeout));
1130 /* Check the RHS can be closed after receiving the data just sent. */
1131 g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, 3);
1132 g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, -1);
1133 g_assert_cmpint (pseudo_tcp_socket_get_error (data.right), ==, EWOULDBLOCK);
1135 pseudo_tcp_socket_close (data.right, FALSE);
1137 g_assert (!pseudo_tcp_socket_get_next_clock (data.right, &timeout));
1139 expect_sockets_closed (&data);
1145 /* Check that after receiving a FIN, queued data can still be read */
1147 pseudotcp_close_recv_queued (void)
1152 /* Establish a connection. */
1153 establish_connection (&data);
1155 g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.left), ==, 0);
1156 g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.right), ==, 0);
1157 g_assert_cmpint (pseudo_tcp_socket_get_available_send_space (data.right), >,
1159 g_assert_cmpint (pseudo_tcp_socket_get_available_send_space (data.left), >,
1162 g_assert_cmpint (pseudo_tcp_socket_send (data.left, "foo", 3), ==, 3);
1163 expect_data (data.left, data.left_sent, 7, 7, 3);
1164 forward_segment_ltr (&data);
1166 increment_time_both (&data, 100); /* Delayed ACK */
1167 expect_ack (data.right, data.right_sent, 7, 10);
1168 forward_segment_rtl (&data);
1170 close_socket (data.left);
1171 expect_fin (data.left, data.left_sent, 10, 7);
1172 forward_segment_ltr (&data);
1174 expect_socket_state (data.left, PSEUDO_TCP_FIN_WAIT_1);
1175 expect_socket_state (data.right, PSEUDO_TCP_CLOSE_WAIT);
1177 g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.left), ==, 0);
1178 g_assert_cmpint (pseudo_tcp_socket_get_available_send_space (data.left), ==,
1181 expect_ack (data.right, data.right_sent, 7, 11);
1182 forward_segment_rtl (&data);
1184 expect_socket_state (data.left, PSEUDO_TCP_FIN_WAIT_2);
1187 g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.right), ==, 3);
1189 g_assert_cmpint (pseudo_tcp_socket_get_available_send_space (data.right), >,
1192 /* Check that the data can be read */
1193 g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, 3);
1195 /* Now the socket should be empty */
1196 g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, 0);
1202 main (int argc, char *argv[])
1204 setlocale (LC_ALL, "");
1205 g_test_init (&argc, &argv, NULL);
1206 pseudo_tcp_set_debug_level (PSEUDO_TCP_DEBUG_VERBOSE);
1208 /* There are four possible scenarios for the FIN handshake, if the possibility
1209 * of dropped or duplicated segments is ignored (but reordered segments are
1210 * allowed: normal, simultaneous, and two types of skew.
1212 * These can be generated by considering the events happening at a single peer
1213 * during connection closure: sending the FIN (SF), receiving a FIN and
1214 * sending a FIN-ACK (RF), receiving a FIN-ACK (RA). These have the following
1219 * Other permutations are disallowed because SF must come before RA.
1221 * The permutations of one peer’s (1) behaviour with a second (2) can then be
1223 * • 1: SF, RF, RA; 2: SF, RF, RA (simultaneous)
1224 * • 1: SF, RF, RA; 2: SF, RA, RF (skew 1)
1225 * • 1: SF, RF, RA; 2: RF, SF, RA (skew 2)
1226 * • 1: SF, RA, RF; 2: RF, SF, RA (normal)
1227 * Other permutations are disallowed because SF on one peer must come before
1228 * RF on the other; similarly RF on one must come before RA on the other.
1230 * Thus, the following unit tests provably cover all possible scenarios where
1231 * segments can be reordered but not dropped or duplicated. */
1232 g_test_add_func ("/pseudotcp/close/normal",
1233 pseudotcp_close_normal);
1234 g_test_add_func ("/pseudotcp/close/simultaneous",
1235 pseudotcp_close_simultaneous);
1236 g_test_add_func ("/pseudotcp/close/skew1",
1237 pseudotcp_close_skew1);
1238 g_test_add_func ("/pseudotcp/close/skew2",
1239 pseudotcp_close_skew2);
1241 /* An arbitrary (less methodical) selection of unit tests for dropped and
1242 * duplicated packets. */
1243 g_test_add_func ("/pseudotcp/close/normal/recovery1",
1244 pseudotcp_close_normal_recovery1);
1245 g_test_add_func ("/pseudotcp/close/normal/recovery2",
1246 pseudotcp_close_normal_recovery2);
1247 g_test_add_func ("/pseudotcp/close/normal/recovery3",
1248 pseudotcp_close_normal_recovery3);
1249 g_test_add_func ("/pseudotcp/close/normal/recovery4",
1250 pseudotcp_close_normal_recovery4);
1251 g_test_add_func ("/pseudotcp/close/normal/recovery-data",
1252 pseudotcp_close_normal_recovery_data);
1253 g_test_add_func ("/pseudotcp/close/simultaneous/recovery1",
1254 pseudotcp_close_simultaneous_recovery1);
1255 g_test_add_func ("/pseudotcp/close/simultaneous/recovery2",
1256 pseudotcp_close_simultaneous_recovery2);
1257 g_test_add_func ("/pseudotcp/close/duplicate-fin",
1258 pseudotcp_close_duplicate_fin);
1259 g_test_add_func ("/pseudotcp/close/duplicate-ack",
1260 pseudotcp_close_duplicate_ack);
1262 g_test_add_func ("/pseudotcp/close/rst",
1263 pseudotcp_close_rst);
1264 g_test_add_func ("/pseudotcp/close/pending-received",
1265 pseudotcp_close_pending_received);
1266 g_test_add_func ("/pseudotcp/close/rst-afterwards",
1267 pseudotcp_close_rst_afterwards);
1269 g_test_add_func ("/pseudotcp/close/recv-queued",
1270 pseudotcp_close_recv_queued);
1272 g_test_add_func ("/pseudotcp/compatibility",
1273 pseudotcp_compatibility);