2323#define UDX_STREAM_SHOULD_READ (UDX_STREAM_ENDED_REMOTE | UDX_STREAM_DEAD)
2424#define UDX_STREAM_READ 0
2525
26- #define UDX_STREAM_SHOULD_END (UDX_STREAM_ENDING | UDX_STREAM_ENDED | UDX_STREAM_DEAD)
27- #define UDX_STREAM_END UDX_STREAM_ENDING
28-
29- #define UDX_STREAM_SHOULD_END_REMOTE (UDX_STREAM_ENDED_REMOTE | UDX_STREAM_DEAD | UDX_STREAM_ENDING_REMOTE)
30- #define UDX_STREAM_END_REMOTE UDX_STREAM_ENDING_REMOTE
31-
3226#define UDX_HEADER_DATA_OR_END (UDX_HEADER_DATA | UDX_HEADER_END)
3327
3428#define UDX_DEFAULT_TTL 64
4640#define UDX_CONG_MAX_CWND 65536
4741#define UDX_RTO_MAX_MS 30000
4842#define UDX_RTT_MAX_MS 30000
49- #define UDX_DEFAULT_RWND_MAX (4 * 1024 * 1024) // arbitrary, ~175 1500 mtu packets, @20ms latency = 416 mbits/sec
43+ #define UDX_TIME_WAIT_MS 30000 // 30 seconds
44+ #define UDX_DEFAULT_RWND_MAX (4 * 1024 * 1024) // 4mb. 139 mbit/s at 240ms latency
5045
5146#define UDX_HIGH_WATERMARK 262144
5247
@@ -599,8 +594,6 @@ close_stream (udx_stream_t *stream, int err) {
599594 stream -> status |= UDX_STREAM_CLOSED ;
600595 stream -> status &= ~UDX_STREAM_CONNECTED ;
601596
602- debug_printf ("closing stream local_id=%u \n" , stream -> local_id );
603-
604597 udx_t * udx = stream -> udx ;
605598 udx_socket_t * socket = stream -> socket ;
606599
@@ -840,6 +833,25 @@ udx_zwp_timeout (uv_timer_t *timer) {
840833 update_poll (stream -> socket );
841834}
842835
836+ static void
837+ udx_timewait_timeout (uv_timer_t * timer ) {
838+ udx_stream_t * stream = timer -> data ;
839+ udx_socket_t * socket = stream -> socket ;
840+
841+ close_stream (stream , 0 );
842+
843+ update_poll (socket );
844+ }
845+
846+ static void
847+ time_wait_stream (udx_stream_t * stream ) {
848+ stream -> status |= UDX_STREAM_TIME_WAIT ;
849+ uv_timer_stop (& stream -> zwp_timer );
850+ uv_timer_stop (& stream -> tlp_timer );
851+ uv_timer_stop (& stream -> rack_reo_timer );
852+ uv_timer_start (& stream -> rto_timer , udx_timewait_timeout , stream -> timewait_timeout_ms , 0 );
853+ }
854+
843855static void
844856udx_rto_timeout (uv_timer_t * timer ) {
845857 udx_stream_t * stream = timer -> data ;
@@ -1081,11 +1093,14 @@ ack_packet (udx_stream_t *stream, uint32_t seq, int sack) {
10811093
10821094 free (pkt );
10831095
1084- // TODO: the end condition needs work here to be more "stateless"
1085- // ie if the remote has acked all our writes, then instead of waiting for retransmits, we should
1086- // clear those and mark as local ended NOW.
1087- if ((stream -> status & UDX_STREAM_SHOULD_END ) == UDX_STREAM_END && stream -> inflight_queue .len == 0 && stream -> retransmit_queue .len == 0 && stream -> write_queue .len == 0 ) {
1096+ const int UDX_STREAM_SHOULD_END = UDX_STREAM_ENDING | UDX_STREAM_ENDED | UDX_STREAM_DEAD ;
1097+
1098+ if ((stream -> status & UDX_STREAM_SHOULD_END ) == UDX_STREAM_ENDING && stream -> inflight_queue .len == 0 && stream -> retransmit_queue .len == 0 && stream -> write_queue .len == 0 ) {
10881099 stream -> status |= UDX_STREAM_ENDED ;
1100+ // received the final ack, and we are the passive side (no TIME_WAIT)
1101+ if ((stream -> status & (UDX_STREAM_ENDED_REMOTE | UDX_STREAM_NEED_TIME_WAIT )) == UDX_STREAM_ENDED_REMOTE ) {
1102+ close_stream (stream , 0 );
1103+ }
10891104 return 2 ;
10901105 }
10911106
@@ -1399,24 +1414,28 @@ process_packet (udx_socket_t *socket, char *buf, ssize_t buf_len, struct sockadd
13991414 }
14001415
14011416 if (a == 0 || a == 1 ) continue ;
1402- if (a == 2 ) { // it ended, so ack that and trigger close
1403- // TODO: make this work as well, if the ack packet is lost, ie
1404- // have some internal (capped) queue of "gracefully closed" streams (TIME_WAIT)
1417+ if (a == 2 ) {
14051418
14061419 if (stream -> status & UDX_STREAM_DEAD ) {
14071420 return 1 ;
14081421 }
14091422
1410- if ((stream -> status & UDX_STREAM_ALL_ENDED ) == UDX_STREAM_ALL_ENDED ) {
1411- close_stream (stream , 0 );
1412- return 1 ;
1413- }
1414-
14151423 if (stream -> remote_acked == stream -> seq ) {
14161424 uv_timer_stop (& stream -> rto_timer );
14171425 uv_timer_stop (& stream -> tlp_timer );
14181426 }
14191427
1428+ if ((stream -> status & UDX_STREAM_ALL_ENDED ) == UDX_STREAM_ALL_ENDED ) {
1429+ if (stream -> status & UDX_STREAM_NEED_TIME_WAIT ) {
1430+ // CLOSING -> TIME_WAIT
1431+ time_wait_stream (stream );
1432+ return 1 ;
1433+ } else {
1434+ close_stream (stream , 0 );
1435+ return 1 ;
1436+ }
1437+ }
1438+
14201439 // send a final state packet to make sure we've acked the end packet
14211440 stream -> write_wanted |= UDX_STREAM_WRITE_WANT_STATE ;
14221441 update_poll (stream -> socket );
@@ -1640,8 +1659,10 @@ send_stream_packets (udx_socket_t *socket, udx_stream_t *stream) {
16401659 return false;
16411660 }
16421661
1662+ const int UDX_STREAM_SHOULD_END_REMOTE = UDX_STREAM_ENDED_REMOTE | UDX_STREAM_DEAD | UDX_STREAM_ENDING_REMOTE ;
1663+
16431664 // if this ACK packet acks the remote's END packet, advance from ENDING_REMOTE -> ENDED_REMOTE
1644- if ((stream -> status & UDX_STREAM_SHOULD_END_REMOTE ) == UDX_STREAM_END_REMOTE && seq_compare (stream -> remote_ended , stream -> ack ) <= 0 ) {
1665+ if ((stream -> status & UDX_STREAM_SHOULD_END_REMOTE ) == UDX_STREAM_ENDING_REMOTE && seq_compare (stream -> remote_ended , stream -> ack ) <= 0 ) {
16451666 stream -> status |= UDX_STREAM_ENDED_REMOTE ;
16461667 if (stream -> on_read != NULL ) {
16471668 uv_buf_t b = uv_buf_init (NULL , 0 );
@@ -1655,9 +1676,16 @@ send_stream_packets (udx_socket_t *socket, udx_stream_t *stream) {
16551676 stream -> write_wanted &= ~UDX_STREAM_WRITE_WANT_STATE ;
16561677
16571678 if ((stream -> status & UDX_STREAM_ALL_ENDED ) == UDX_STREAM_ALL_ENDED ) {
1679+
16581680 assert (stream -> retransmit_queue .len == 0 );
16591681 assert (stream -> write_queue .len == 0 );
1660- close_stream (stream , 0 );
1682+
1683+ if (stream -> status & UDX_STREAM_NEED_TIME_WAIT ) {
1684+ // FIN_WAIT -> TIME_WAIT
1685+ time_wait_stream (stream );
1686+ } else {
1687+ close_stream (stream , 0 );
1688+ }
16611689 return true;
16621690 }
16631691 }
@@ -2344,6 +2372,8 @@ udx_stream_init (udx_t *udx, udx_stream_t *stream, uint32_t local_id, udx_stream
23442372 stream -> send_wl2 = 0 ;
23452373 stream -> remote_acked = 0 ;
23462374
2375+ stream -> timewait_timeout_ms = UDX_TIME_WAIT_MS ;
2376+
23472377 stream -> srtt = 0 ;
23482378 stream -> rttvar = 0 ;
23492379 stream -> rto = 1000 ;
@@ -2455,6 +2485,18 @@ udx_stream_set_ack (udx_stream_t *stream, uint32_t ack) {
24552485 return 0 ;
24562486}
24572487
2488+ int
2489+ udx_stream_get_timewait_timeout_ms (udx_stream_t * stream , uint32_t * timeout_ms ) {
2490+ * timeout_ms = stream -> timewait_timeout_ms ;
2491+ return 0 ;
2492+ }
2493+
2494+ int
2495+ udx_stream_set_timewait_timeout_ms (udx_stream_t * stream , uint32_t timeout_ms ) {
2496+ stream -> timewait_timeout_ms = timeout_ms ;
2497+ return 0 ;
2498+ }
2499+
24582500int
24592501udx_stream_get_rwnd_max (udx_stream_t * stream , uint32_t * size ) {
24602502 * size = stream -> recv_rwnd_max ;
@@ -2766,6 +2808,11 @@ udx_stream_write_end (udx_stream_write_t *req, udx_stream_t *stream, const uv_bu
27662808
27672809 stream -> status |= UDX_STREAM_ENDING ;
27682810
2811+ // only the 'active' closer must enter TIME_WAIT
2812+ if ((stream -> status & UDX_STREAM_ENDED_REMOTE ) == 0 ) {
2813+ stream -> status |= UDX_STREAM_NEED_TIME_WAIT ;
2814+ }
2815+
27692816 if (bufs_len > 0 ) {
27702817 req -> nwbufs = bufs_len ;
27712818 _udx_stream_write (req , stream , bufs , bufs_len , ack_cb , true);
0 commit comments