@@ -366,9 +366,18 @@ static int tcp_estab_state (_tcp_Socket **sp, const in_Header *ip,
366
366
len = tcp_process_data (s , tcp , len , & flags );
367
367
if (len < 0 )
368
368
{
369
- TCP_SEND (s ); /* An out-of-order or missing segment; do fast ACK */
369
+ /* An out-of-order or missing segment; do fast ACK.
370
+ * Three should be enough. If those get dropped,
371
+ * retransmitter will send more eventually.
372
+ */
373
+ if (s -> dup_acks < 3 )
374
+ {
375
+ TCP_SEND (s );
376
+ ++ s -> dup_acks ;
377
+ }
370
378
return (1 );
371
379
}
380
+ s -> dup_acks = 0 ;
372
381
373
382
if (s -> state != tcp_StateCLOSWT &&
374
383
(flags & tcp_FlagFIN ) &&
@@ -402,6 +411,14 @@ static int tcp_estab_state (_tcp_Socket **sp, const in_Header *ip,
402
411
}
403
412
}
404
413
414
+ /* Send fast-ACK after retransmission.
415
+ */
416
+ if (len > 0 && s -> missed_seq [0 ] != s -> missed_seq [1 ])
417
+ {
418
+ TCP_SEND (s );
419
+ return (0 );
420
+ }
421
+
405
422
/* Peer ACKed some of our data, continue sending more.
406
423
*/
407
424
if (ldiff > 0 && s -> tx_datalen > (unsigned long )s -> send_una )
@@ -848,7 +865,7 @@ copy_in_order (_tcp_Socket *s, const BYTE *data, unsigned len)
848
865
* Handle any new data that increments the 'recv_next' index.
849
866
* 'ldiff >= 0'.
850
867
*/
851
- static void
868
+ static int
852
869
data_in_order (_tcp_Socket * s , const BYTE * data , unsigned len , unsigned diff )
853
870
{
854
871
/* Skip data before recv_next. We must be left with some data or
@@ -893,6 +910,11 @@ data_in_order (_tcp_Socket *s, const BYTE *data, unsigned len, unsigned diff)
893
910
*/
894
911
copy_in_order (s , data + ms_end , len - ms_end );
895
912
}
913
+
914
+ /* Send fast-ACK to notify peer that we caught up.
915
+ */
916
+ s -> dup_acks = 0 ;
917
+ len = -1 ;
896
918
}
897
919
898
920
TRACE_FILE ("data_in_order (%u): edges %lu/%lu, recv.next %lu\n" ,
@@ -901,6 +923,8 @@ data_in_order (_tcp_Socket *s, const BYTE *data, unsigned len, unsigned diff)
901
923
902
924
TRACE_FILE ("data_in_order (%u): new data now ends at %u\n" ,
903
925
__LINE__ , s -> rx_datalen );
926
+
927
+ return (len );
904
928
}
905
929
906
930
/*
@@ -1092,7 +1116,7 @@ static int tcp_process_data (_tcp_Socket *s, const tcp_Header *tcp,
1092
1116
1093
1117
if (ldiff >= 0 )
1094
1118
{
1095
- data_in_order (s , data , len , ldiff );
1119
+ len = data_in_order (s , data , len , ldiff );
1096
1120
s -> unhappy = (s -> tx_datalen > 0 );
1097
1121
return (len );
1098
1122
}
0 commit comments