Imported Upstream version 0.1.17
[platform/upstream/libnice.git] / tests / test-pseudotcp-fin.c
1 /*
2  * This file is part of the Nice GLib ICE library.
3  *
4  * © 2014, 2015 Collabora Ltd.
5  *  Contact: Philip Withnall
6  *
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/
11  *
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
15  * License.
16  *
17  * The Original Code is the Nice GLib ICE library.
18  *
19  * The Initial Developers of the Original Code are Collabora Ltd and Nokia
20  * Corporation. All Rights Reserved.
21  *
22  * Contributors:
23  *   Philip Withnall, Collabora Ltd.
24  *
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.
34  */
35
36 #ifdef HAVE_CONFIG_H
37 # include "config.h"
38 #endif
39
40 #include <locale.h>
41 #include <string.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <errno.h>
45 #include <arpa/inet.h>
46
47 #include "pseudotcp.h"
48
49
50 typedef struct {
51   PseudoTcpSocket *left;  /* owned */
52   PseudoTcpSocket *right;  /* owned */
53
54   guint32 left_current_time;
55   guint32 right_current_time;
56
57   /* Data sent and received by each socket. */
58   GQueue/*<owned GBytes>*/ *left_sent;  /* owned */
59   GQueue/*<owned GBytes>*/ *right_sent;  /* owned */
60 } Data;
61
62 /* NOTE: Must match the on-the-wire flag values from pseudotcp.c. */
63 typedef enum {
64   FLAG_NONE = 0,
65   FLAG_FIN = 1 << 0,
66   FLAG_SYN = 1 << 1,
67   FLAG_RST = 1 << 2,
68 } SegmentFlags;
69
70 typedef void (*TestFunc) (Data *data, const void *next_funcs);
71
72
73 static void
74 data_clear (Data *data)
75 {
76   if (data->left != NULL)
77     g_object_unref (data->left);
78   if (data->right != NULL)
79     g_object_unref (data->right);
80
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);
85 }
86
87
88 static gchar *
89 segment_flags_to_string (SegmentFlags flags)
90 {
91   GString *str = g_string_new (NULL);
92
93   if (flags & FLAG_SYN)
94     g_string_append (str, "SYN,");
95   if (flags & FLAG_FIN)
96     g_string_append (str, "FIN,");
97   if (flags & FLAG_RST)
98     g_string_append (str, "RST,");
99
100   /* Strip the trailing comma. */
101   if (str->len > 0)
102     g_string_truncate (str, str->len - 1);
103
104   if (str->len == 0)
105     g_string_append (str, "0");
106
107   return g_string_free (str, FALSE);
108 }
109
110 static gchar *
111 segment_to_string (guint32 seq, guint32 ack, SegmentFlags flags)
112 {
113   gchar *ctl, *out;
114
115   ctl = segment_flags_to_string (flags);
116   out = g_strdup_printf ("<SEQ=%u><ACK=%u><CTL=%s>", seq, ack, ctl);
117   g_free (ctl);
118
119   return out;
120 }
121
122 static gchar *
123 segment_bytes_to_string (const guint8 *bytes)
124 {
125   union {
126     const guint8 *u8;
127     const guint32 *u32;
128   } b;
129   guint32 seq, ack;
130   guint8 flags;
131
132   b.u8 = bytes;
133
134   seq = ntohl (b.u32[1]);
135   ack = ntohl (b.u32[2]);
136   flags = b.u8[13];
137
138   return segment_to_string (seq, ack, flags);
139 }
140
141
142 static void
143 opened (PseudoTcpSocket *sock, gpointer data)
144 {
145   g_debug ("Socket %p opened", sock);
146 }
147
148 static void
149 readable (PseudoTcpSocket *sock, gpointer data)
150 {
151   g_debug ("Socket %p readable", sock);
152 }
153
154 static void
155 writable (PseudoTcpSocket *sock, gpointer data)
156 {
157   g_debug ("Socket %p writeable", sock);
158 }
159
160 static void
161 closed (PseudoTcpSocket *sock, guint32 err, gpointer data)
162 {
163   g_debug ("Socket %p closed: %s", sock, strerror (err));
164 }
165
166 static PseudoTcpWriteResult
167 write_packet (PseudoTcpSocket *sock, const gchar *buffer, guint32 len,
168     gpointer user_data)
169 {
170   Data *data = user_data;
171   gchar *str;  /* owned */
172   GQueue/*<owned GBytes>*/ *queue;  /* unowned */
173   GBytes *segment;  /* owned */
174
175   /* Debug output. */
176   str = segment_bytes_to_string ((const guint8 *) buffer);
177   g_debug ("%p sent: %s", sock, str);
178   g_free (str);
179
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;
185   else
186     g_assert_not_reached ();
187
188   segment = g_bytes_new (buffer, len);
189   g_queue_push_tail (queue, segment);
190
191   return WR_SUCCESS;
192 }
193
194
195 static void
196 create_sockets (Data *data, gboolean support_fin_ack)
197 {
198   PseudoTcpCallbacks cbs = {
199     data, opened, readable, writable, closed, write_packet
200   };
201
202   data->left = g_object_new (PSEUDO_TCP_SOCKET_TYPE,
203       "conversation", 0,
204       "callbacks", &cbs,
205       "support-fin-ack", support_fin_ack,
206       NULL);
207   data->right = g_object_new (PSEUDO_TCP_SOCKET_TYPE,
208       "conversation", 0,
209       "callbacks", &cbs,
210       "support-fin-ack", support_fin_ack,
211       NULL);
212
213   g_debug ("Left: %p, right: %p", data->left, data->right);
214
215   /* Control the socket clocks precisely. */
216   pseudo_tcp_socket_set_time (data->left, 1);
217   pseudo_tcp_socket_set_time (data->right, 1);
218
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);
222
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);
225
226   data->left_sent = g_queue_new ();
227   data->right_sent = g_queue_new ();
228 }
229
230 static void
231 expect_segment (PseudoTcpSocket *socket, GQueue/*<owned GBytes>*/ *queue,
232     guint32 seq, guint32 ack, guint32 len, SegmentFlags flags)
233 {
234   GBytes *bytes;  /* unowned */
235   union {
236     const guint8 *u8;
237     const guint32 *u32;
238   } b;
239   gsize size;
240   gchar *str;
241
242   str = segment_to_string (seq, ack, flags);
243   g_debug ("%p expect: %s", socket, str);
244   g_free (str);
245
246   /* Grab the segment. */
247   bytes = g_queue_peek_head (queue);
248   g_assert (bytes != NULL);
249
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);
253
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);
258 }
259
260 static void
261 expect_syn_sent (Data *data)
262 {
263   expect_segment (data->left, data->left_sent, 0, 0, 7, FLAG_SYN);
264 }
265
266 static void
267 expect_syn_received (Data *data)
268 {
269   expect_segment (data->right, data->right_sent, 0, 7, 7, FLAG_SYN);
270 }
271
272 static void
273 assert_empty_queues (Data *data)
274 {
275   g_assert_cmpuint (g_queue_get_length (data->left_sent), ==, 0);
276   g_assert_cmpuint (g_queue_get_length (data->right_sent), ==, 0);
277 }
278
279 /* Return whether the socket accepted the packet. */
280 static gboolean
281 forward_segment (GQueue/*<owned GBytes>*/ *from, PseudoTcpSocket *to)
282 {
283   GBytes *segment;  /* owned */
284   const guint8 *b;
285   gsize size;
286   gboolean retval;
287
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);
293
294   return retval;
295 }
296
297 static void
298 forward_segment_ltr (Data *data)
299 {
300   g_assert (forward_segment (data->left_sent, data->right));
301 }
302
303 static void
304 forward_segment_rtl (Data *data)
305 {
306   g_assert (forward_segment (data->right_sent, data->left));
307 }
308
309 static void
310 duplicate_segment (GQueue/*<owned GBytes>*/ *queue)
311 {
312   GBytes *segment;  /* unowned */
313
314   segment = g_queue_peek_head (queue);
315   g_assert (segment != NULL);
316   g_queue_push_head (queue, g_bytes_ref (segment));
317 }
318
319 static void
320 drop_segment (PseudoTcpSocket *socket, GQueue/*<owned GBytes>*/ *queue)
321 {
322   GBytes *segment;  /* owned */
323   gchar *str;
324
325   segment = g_queue_pop_head (queue);
326   g_assert (segment != NULL);
327
328   str = segment_bytes_to_string (g_bytes_get_data (segment, NULL));
329   g_debug ("%p drop: %s", socket, str);
330   g_free (str);
331
332   g_bytes_unref (segment);
333 }
334
335 /* Swap the order of the head-most two segments in the @queue. */
336 static void
337 reorder_segments (PseudoTcpSocket *socket, GQueue/*<owned GBytes>*/ *queue)
338 {
339   GBytes *segment1, *segment2;  /* unowned */
340   gchar *str;
341
342   segment1 = g_queue_pop_head (queue);
343   g_assert (segment1 != NULL);
344   segment2 = g_queue_pop_head (queue);
345   g_assert (segment2 != NULL);
346
347   str = segment_bytes_to_string (g_bytes_get_data (segment1, NULL));
348   g_debug ("%p reorder: %s", socket, str);
349   g_free (str);
350   str = segment_bytes_to_string (g_bytes_get_data (segment2, NULL));
351   g_debug ("%p after:   %s", socket, str);
352   g_free (str);
353
354   g_queue_push_head (queue, segment1);
355   g_queue_push_head (queue, segment2);
356 }
357
358 static void
359 expect_socket_state (PseudoTcpSocket *socket, PseudoTcpState expected_state)
360 {
361   PseudoTcpState state;
362
363   g_object_get (socket, "state", &state, NULL);
364   g_assert_cmpuint (state, ==, expected_state);
365 }
366
367 static void
368 expect_sockets_connected (Data *data)
369 {
370   expect_socket_state (data->left, PSEUDO_TCP_ESTABLISHED);
371   expect_socket_state (data->right, PSEUDO_TCP_ESTABLISHED);
372 }
373
374 static void
375 expect_sockets_closed (Data *data)
376 {
377   guint8 buf[100];
378
379   expect_socket_state (data->left, PSEUDO_TCP_CLOSED);
380   expect_socket_state (data->right, PSEUDO_TCP_CLOSED);
381
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);
385
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);
389 }
390
391 static void
392 increment_time (PseudoTcpSocket *socket, guint32 *counter, guint32 increment)
393 {
394   g_debug ("Incrementing %p time by %u from %u to %u", socket, increment,
395       *counter, *counter + increment);
396   *counter = *counter + increment;
397
398   pseudo_tcp_socket_set_time (socket, *counter);
399   pseudo_tcp_socket_notify_clock (socket);
400 }
401
402 static void
403 increment_time_both (Data *data, guint32 increment)
404 {
405   increment_time (data->left, &data->left_current_time, increment);
406   increment_time (data->right, &data->right_current_time, increment);
407 }
408
409 static void
410 expect_fin (PseudoTcpSocket *socket, GQueue/*<owned GBytes>*/ *queue,
411     guint32 seq, guint32 ack)
412 {
413   expect_segment (socket, queue, seq, ack, 0, FLAG_FIN);
414 }
415
416 static void
417 expect_rst (PseudoTcpSocket *socket, GQueue/*<owned GBytes>*/ *queue,
418     guint32 seq, guint32 ack)
419 {
420   expect_segment (socket, queue, seq, ack, 0, FLAG_RST);
421 }
422
423 static void
424 expect_ack (PseudoTcpSocket *socket, GQueue/*<owned GBytes>*/ *queue,
425     guint32 seq, guint32 ack)
426 {
427   expect_segment (socket, queue, seq, ack, 0, FLAG_NONE);
428 }
429
430 static void
431 expect_data (PseudoTcpSocket *socket, GQueue/*<owned GBytes>*/ *queue,
432     guint32 seq, guint32 ack, guint32 len)
433 {
434   expect_segment (socket, queue, seq, ack, len, FLAG_NONE);
435 }
436
437 static void
438 close_socket (PseudoTcpSocket *socket)
439 {
440   guint8 buf[100];
441
442   pseudo_tcp_socket_close (socket, FALSE);
443
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);
447 }
448
449 /* Helper to create a socket pair and perform the SYN handshake. */
450 static void
451 establish_connection (Data *data)
452 {
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);
463
464   assert_empty_queues (data);
465 }
466
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). */
469 static void
470 close_lhs (Data *data)
471 {
472   pseudo_tcp_socket_close (data->left, FALSE);
473
474   expect_fin (data->left, data->left_sent, 7, 7);
475   forward_segment_ltr (data);
476
477   expect_ack (data->right, data->right_sent, 7, 8);
478   forward_segment_rtl (data);
479 }
480
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). */
483 static void
484 close_rhs (Data *data)
485 {
486   pseudo_tcp_socket_close (data->right, FALSE);
487
488   expect_fin (data->right, data->right_sent, 7, 8);
489   forward_segment_rtl (data);
490
491   increment_time_both (data, 10);  /* TIME-WAIT */
492   expect_ack (data->left, data->left_sent, 8, 8);
493   forward_segment_ltr (data);
494 }
495
496 /* Check that establishing a connection then immediately closing it works, using
497  * normal handshakes (FIN, ACK, FIN, ACK). See: RFC 793, Figure 13. */
498 static void
499 pseudotcp_close_normal (void)
500 {
501   Data data = { 0, };
502   guint8 buf[100];
503
504   /* Establish a connection. */
505   establish_connection (&data);
506
507   /* Close it. Verify that sending fails. */
508   close_socket (data.left);
509
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);
514
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);
518
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);
525
526   data_clear (&data);
527 }
528
529 /* Check that establishing a connection then immediately closing it works, using
530  * simultaneous handshakes (FIN, FIN, ACK, ACK). See: RFC 793, Figure 14. */
531 static void
532 pseudotcp_close_simultaneous (void)
533 {
534   Data data = { 0, };
535
536   /* Establish a connection. */
537   establish_connection (&data);
538
539   /* Close both sides simultaneously. Verify that sending fails. */
540   close_socket (data.left);
541   close_socket (data.right);
542
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);
547
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);
552
553   increment_time_both (&data, 10);  /* TIME-WAIT */
554   expect_sockets_closed (&data);
555
556   data_clear (&data);
557 }
558
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. */
566 static void
567 pseudotcp_close_skew1 (void)
568 {
569   Data data = { 0, };
570
571   /* Establish a connection. */
572   establish_connection (&data);
573
574   /* Close both sides simultaneously. Verify that sending fails. */
575   close_socket (data.left);
576   close_socket (data.right);
577
578   expect_fin (data.left, data.left_sent, 7, 7);
579
580   expect_fin (data.right, data.right_sent, 7, 7);
581   forward_segment_rtl (&data);
582
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);
587
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);
592
593   increment_time_both (&data, 10);  /* TIME-WAIT */
594   expect_sockets_closed (&data);
595
596   data_clear (&data);
597 }
598
599 /* Same as pseudotcp_close_skew1() but with the packets reordered in a
600  * different way. */
601 static void
602 pseudotcp_close_skew2 (void)
603 {
604   Data data = { 0, };
605
606   /* Establish a connection. */
607   establish_connection (&data);
608
609   /* Close both sides simultaneously. Verify that sending fails. */
610   close_socket (data.left);
611   close_socket (data.right);
612
613   expect_fin (data.right, data.right_sent, 7, 7);
614
615   expect_fin (data.left, data.left_sent, 7, 7);
616   forward_segment_ltr (&data);
617
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);
622
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);
627
628   increment_time_both (&data, 10);  /* TIME-WAIT */
629   expect_sockets_closed (&data);
630
631   data_clear (&data);
632 }
633
634 /* Check that closing a connection recovers from the initial FIN segment being
635  * dropped. Based on: RFC 793, Figure 13. */
636 static void
637 pseudotcp_close_normal_recovery1 (void)
638 {
639   Data data = { 0, };
640
641   /* Establish a connection. */
642   establish_connection (&data);
643
644   /* Close the LHS and drop the FIN segment. */
645   close_socket (data.left);
646
647   expect_fin (data.left, data.left_sent, 7, 7);
648   drop_segment (data.left, data.left_sent);
649
650   increment_time_both (&data, 1100);  /* retransmit timeout */
651
652   expect_fin (data.left, data.left_sent, 7, 7);
653   forward_segment_ltr (&data);
654
655   expect_ack (data.right, data.right_sent, 7, 8);
656   forward_segment_rtl (&data);
657
658   /* Close the RHS. */
659   close_rhs (&data);
660
661   expect_sockets_closed (&data);
662
663   data_clear (&data);
664 }
665
666 /* Check that closing a connection recovers from the initial ACK segment being
667  * dropped. Based on: RFC 793, Figure 13. */
668 static void
669 pseudotcp_close_normal_recovery2 (void)
670 {
671   Data data = { 0, };
672
673   /* Establish a connection. */
674   establish_connection (&data);
675
676   /* Close the LHS and drop the ACK segment. The LHS should retransmit the
677    * FIN. */
678   close_socket (data.left);
679
680   expect_fin (data.left, data.left_sent, 7, 7);
681   forward_segment_ltr (&data);
682
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);
690
691   /* Close the RHS. */
692   close_rhs (&data);
693
694   expect_sockets_closed (&data);
695
696   data_clear (&data);
697 }
698
699 /* Check that closing a connection recovers from the second FIN segment being
700  * dropped. Based on: RFC 793, Figure 13. */
701 static void
702 pseudotcp_close_normal_recovery3 (void)
703 {
704   Data data = { 0, };
705
706   /* Establish a connection. */
707   establish_connection (&data);
708
709   /* Close the LHS. */
710   close_lhs (&data);
711
712   /* Close the RHS and drop the FIN segment. */
713   close_socket (data.right);
714
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);
720
721   increment_time_both (&data, 10);  /* TIME-WAIT */
722   expect_ack (data.left, data.left_sent, 8, 8);
723   forward_segment_ltr (&data);
724
725   expect_sockets_closed (&data);
726
727   data_clear (&data);
728 }
729
730 /* Check that closing a connection recovers from the second ACK segment being
731  * dropped. Based on: RFC 793, Figure 13. */
732 static void
733 pseudotcp_close_normal_recovery4 (void)
734 {
735   Data data = { 0, };
736
737   /* Establish a connection. */
738   establish_connection (&data);
739
740   /* Close the LHS. */
741   close_lhs (&data);
742
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);
747
748   expect_fin (data.right, data.right_sent, 7, 8);
749   forward_segment_rtl (&data);
750
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);
759
760   expect_sockets_closed (&data);
761
762   data_clear (&data);
763 }
764
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. */
767 static void
768 pseudotcp_close_normal_recovery_data (void)
769 {
770   Data data = { 0, };
771
772   /* Establish a connection. */
773   establish_connection (&data);
774
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);
779
780   assert_empty_queues(&data);
781
782   /* Close the LHS. */
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);
786
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);
790
791   expect_socket_state (data.right, PSEUDO_TCP_ESTABLISHED);
792   expect_ack (data.right, data.right_sent, 7, 7);
793   forward_segment_rtl (&data);
794
795   expect_socket_state (data.left, PSEUDO_TCP_FIN_WAIT_1);
796
797   assert_empty_queues(&data);
798
799   /* Close the RHS. */
800   close_socket (data.right);
801
802   expect_socket_state (data.right, PSEUDO_TCP_FIN_WAIT_1);
803
804   expect_fin (data.right, data.right_sent, 7, 7);
805   forward_segment_rtl (&data);
806
807   expect_socket_state (data.left, PSEUDO_TCP_CLOSING);
808
809   expect_ack (data.left, data.left_sent, 11, 8);
810   forward_segment_ltr (&data);
811
812   expect_socket_state (data.right, PSEUDO_TCP_FIN_WAIT_2);
813
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);
817
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);
821
822   increment_time_both (&data, 100);  /* Delayed ACK */
823
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);
827
828   increment_time_both (&data, 10);  /* TIME-WAIT */
829
830   expect_sockets_closed (&data);
831
832   data_clear (&data);
833 }
834
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. */
838 static void
839 pseudotcp_close_simultaneous_recovery1 (void)
840 {
841   Data data = { 0, };
842
843   /* Establish a connection. */
844   establish_connection (&data);
845
846   /* Close both sides simultaneously and drop the FINs. */
847   close_socket (data.left);
848   close_socket (data.right);
849
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);
854
855   increment_time_both (&data, 1200);  /* retransmit timeout */
856
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);
861
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);
866
867   increment_time_both (&data, 10);  /* TIME-WAIT */
868   expect_sockets_closed (&data);
869
870   data_clear (&data);
871 }
872
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. */
876 static void
877 pseudotcp_close_simultaneous_recovery2 (void)
878 {
879   Data data = { 0, };
880
881   /* Establish a connection. */
882   establish_connection (&data);
883
884   /* Close both sides simultaneously and forward the FINs. */
885   close_socket (data.left);
886   close_socket (data.right);
887
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);
892
893   /* Drop the ACKs. */
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);
898
899   increment_time_both (&data, 1200);  /* retransmit timeout */
900
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);
905
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);
910
911   increment_time_both (&data, 10);  /* TIME-WAIT */
912
913   expect_sockets_closed (&data);
914
915   data_clear (&data);
916 }
917
918 /* Check that closing a connection ignores a duplicate FIN segment.
919  * Based on: RFC 793, Figure 13. */
920 static void
921 pseudotcp_close_duplicate_fin (void)
922 {
923   Data data = { 0, };
924
925   /* Establish a connection. */
926   establish_connection (&data);
927
928   /* Close the LHS. */
929   close_lhs (&data);
930
931   /* Close the RHS and duplicate the FIN segment. */
932   close_socket (data.right);
933
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);
938
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);
942
943   expect_sockets_closed (&data);
944
945   data_clear (&data);
946 }
947
948 /* Check that closing a connection ignores a duplicate ACK segment.
949  * Based on: RFC 793, Figure 13. */
950 static void
951 pseudotcp_close_duplicate_ack (void)
952 {
953   Data data = { 0, };
954
955   /* Establish a connection. */
956   establish_connection (&data);
957
958   /* Close the LHS. */
959   close_lhs (&data);
960
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);
964
965   expect_fin (data.right, data.right_sent, 7, 8);
966   forward_segment_rtl (&data);
967
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));
975
976   expect_sockets_closed (&data);
977
978   data_clear (&data);
979 }
980
981 /* Check that forcefully closing a connection by sending a RST segment works.
982  * See: RFC 1122, §4.2.2.13. */
983 static void
984 pseudotcp_close_rst (void)
985 {
986   Data data = { 0, };
987   guint8 buf[100];
988
989   /* Establish a connection. */
990   establish_connection (&data);
991
992   /* Close the LHS. */
993   pseudo_tcp_socket_close (data.left, TRUE);
994
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);
998
999   expect_rst (data.left, data.left_sent, 7, 7);
1000   g_assert (!forward_segment (data.left_sent, data.right));
1001
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);
1006
1007   expect_sockets_closed (&data);
1008
1009   data_clear (&data);
1010 }
1011
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. */
1014 static void
1015 pseudotcp_close_pending_received (void)
1016 {
1017   Data data = { 0, };
1018   guint8 buf[100];
1019
1020   /* Establish a connection. */
1021   establish_connection (&data);
1022
1023   /* Send some data from RHS to LHS. Do *not* read the data from the LHS receive
1024    * buffer. */
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);
1028
1029   /* Close the LHS. */
1030   g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.left), ==, 3);
1031   close_socket (data.left);
1032
1033   expect_rst (data.left, data.left_sent, 7, 10);
1034   g_assert (!forward_segment (data.left_sent, data.right));
1035
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);
1040
1041   expect_sockets_closed (&data);
1042
1043   data_clear (&data);
1044 }
1045
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. */
1048 static void
1049 pseudotcp_close_rst_afterwards (void)
1050 {
1051   Data data = { 0, };
1052   guint8 buf[100];
1053
1054   /* Establish a connection. */
1055   establish_connection (&data);
1056
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);
1061
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 */
1064
1065   assert_empty_queues(&data);
1066
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));
1071
1072   expect_rst (data.left, data.left_sent, 7, 7);
1073   g_assert (!forward_segment (data.left_sent, data.right));
1074
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);
1079
1080   expect_sockets_closed (&data);
1081
1082   data_clear (&data);
1083 }
1084
1085 /* Check that two pseudo-TCP sockets interact correctly even if FIN–ACK support
1086  * is disabled on one of them. */
1087 static void
1088 pseudotcp_compatibility (void)
1089 {
1090   Data data = { 0, };
1091   guint8 buf[100];
1092   guint64 timeout;
1093
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);
1107
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));
1111
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);
1115
1116   expect_data (data.left, data.left_sent, 4, 4, 3);
1117   forward_segment_ltr (&data);
1118
1119   increment_time_both (&data, 100);
1120
1121   expect_ack (data.right, data.right_sent, 4, 7);
1122   forward_segment_rtl (&data);
1123
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);
1127
1128   g_assert (!pseudo_tcp_socket_get_next_clock (data.left, &timeout));
1129
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);
1134
1135   pseudo_tcp_socket_close (data.right, FALSE);
1136
1137   g_assert (!pseudo_tcp_socket_get_next_clock (data.right, &timeout));
1138
1139   expect_sockets_closed (&data);
1140
1141   data_clear (&data);
1142 }
1143
1144
1145 /* Check that after receiving a FIN, queued data can still be read */
1146 static void
1147 pseudotcp_close_recv_queued (void)
1148 {
1149   Data data = { 0, };
1150   guint8 buf[100];
1151
1152   /* Establish a connection. */
1153   establish_connection (&data);
1154
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), >,
1158       0);
1159   g_assert_cmpint (pseudo_tcp_socket_get_available_send_space (data.left), >,
1160       0);
1161
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);
1165
1166   increment_time_both (&data, 100);  /* Delayed ACK */
1167   expect_ack (data.right, data.right_sent, 7, 10);
1168   forward_segment_rtl (&data);
1169
1170   close_socket (data.left);
1171   expect_fin (data.left, data.left_sent, 10, 7);
1172   forward_segment_ltr (&data);
1173
1174   expect_socket_state (data.left, PSEUDO_TCP_FIN_WAIT_1);
1175   expect_socket_state (data.right, PSEUDO_TCP_CLOSE_WAIT);
1176
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), ==,
1179       0);
1180
1181   expect_ack (data.right, data.right_sent, 7, 11);
1182   forward_segment_rtl (&data);
1183
1184   expect_socket_state (data.left, PSEUDO_TCP_FIN_WAIT_2);
1185
1186
1187   g_assert_cmpint (pseudo_tcp_socket_get_available_bytes (data.right), ==, 3);
1188
1189   g_assert_cmpint (pseudo_tcp_socket_get_available_send_space (data.right), >,
1190       0);
1191
1192   /* Check that the data can be read */
1193   g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, 3);
1194
1195   /* Now the socket should be empty */
1196   g_assert_cmpint (pseudo_tcp_socket_recv (data.right, (char *) buf, sizeof (buf)), ==, 0);
1197
1198   data_clear (&data);
1199 }
1200
1201 int
1202 main (int argc, char *argv[])
1203 {
1204   setlocale (LC_ALL, "");
1205   g_test_init (&argc, &argv, NULL);
1206   pseudo_tcp_set_debug_level (PSEUDO_TCP_DEBUG_VERBOSE);
1207
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.
1211    *
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
1215    * permutations:
1216    *  • SF, RF, RA
1217    *  • SF, RA, RF
1218    *  • RF, SF, RA
1219    * Other permutations are disallowed because SF must come before RA.
1220    *
1221    * The permutations of one peer’s (1) behaviour with a second (2) can then be
1222    * considered:
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.
1229    *
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);
1240
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);
1261
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);
1268
1269   g_test_add_func ("/pseudotcp/close/recv-queued",
1270       pseudotcp_close_recv_queued);
1271
1272   g_test_add_func ("/pseudotcp/compatibility",
1273       pseudotcp_compatibility);
1274
1275   g_test_run ();
1276
1277   return 0;
1278 }