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