|
@@ -726,40 +726,44 @@ static int tcp_rx_ack ( struct tcp_connection *tcp, uint32_t ack,
|
726
|
726
|
size_t len;
|
727
|
727
|
unsigned int acked_flags;
|
728
|
728
|
|
729
|
|
- /* Determine acknowledged flags and data length */
|
730
|
|
- len = ack_len;
|
731
|
|
- acked_flags = ( TCP_FLAGS_SENDING ( tcp->tcp_state ) &
|
732
|
|
- ( TCP_SYN | TCP_FIN ) );
|
733
|
|
- if ( acked_flags )
|
734
|
|
- len--;
|
735
|
|
-
|
736
|
|
- /* Stop retransmission timer if necessary */
|
737
|
|
- if ( ack_len == 0 ) {
|
738
|
|
- /* Duplicate ACK (or just a packet that isn't
|
739
|
|
- * intending to ACK any new data). If the
|
740
|
|
- * retransmission timer is running, leave it running
|
741
|
|
- * so that we don't immediately retransmit and cause a
|
742
|
|
- * sorceror's apprentice syndrome.
|
743
|
|
- */
|
744
|
|
- } else if ( ack_len <= tcp->snd_sent ) {
|
745
|
|
- /* ACK of new data. Stop the retransmission timer. */
|
746
|
|
- stop_timer ( &tcp->timer );
|
747
|
|
- } else {
|
748
|
|
- /* Out-of-range (or old duplicate) ACK. Leave the
|
749
|
|
- * timer running, as for the ack_len==0 case, to
|
750
|
|
- * handle old duplicate ACKs.
|
751
|
|
- */
|
|
729
|
+ /* Check for out-of-range or old duplicate ACKs */
|
|
730
|
+ if ( ack_len > tcp->snd_sent ) {
|
752
|
731
|
DBGC ( tcp, "TCP %p received ACK for %08x..%08zx, "
|
753
|
732
|
"sent only %08x..%08x\n", tcp, tcp->snd_seq,
|
754
|
733
|
( tcp->snd_seq + ack_len ), tcp->snd_seq,
|
755
|
734
|
( tcp->snd_seq + tcp->snd_sent ) );
|
756
|
|
- /* Send RST if an out-of-range ACK is received on a
|
757
|
|
- * not-yet-established connection.
|
758
|
|
- */
|
759
|
|
- if ( ! TCP_HAS_BEEN_ESTABLISHED ( tcp->tcp_state ) )
|
|
735
|
+
|
|
736
|
+ if ( TCP_HAS_BEEN_ESTABLISHED ( tcp->tcp_state ) ) {
|
|
737
|
+ /* Just ignore what might be old duplicate ACKs */
|
|
738
|
+ return 0;
|
|
739
|
+ } else {
|
|
740
|
+ /* Send RST if an out-of-range ACK is received
|
|
741
|
+ * on a not-yet-established connection, as per
|
|
742
|
+ * RFC 793.
|
|
743
|
+ */
|
760
|
744
|
return -EINVAL;
|
|
745
|
+ }
|
761
|
746
|
}
|
762
|
747
|
|
|
748
|
+ /* Ignore ACKs that don't actually acknowledge any new data.
|
|
749
|
+ * (In particular, do not stop the retransmission timer; this
|
|
750
|
+ * avoids creating a sorceror's apprentice syndrome when a
|
|
751
|
+ * duplicate ACK is received and we still have data in our
|
|
752
|
+ * transmit queue.)
|
|
753
|
+ */
|
|
754
|
+ if ( ack_len == 0 )
|
|
755
|
+ return 0;
|
|
756
|
+
|
|
757
|
+ /* Stop the retransmission timer */
|
|
758
|
+ stop_timer ( &tcp->timer );
|
|
759
|
+
|
|
760
|
+ /* Determine acknowledged flags and data length */
|
|
761
|
+ len = ack_len;
|
|
762
|
+ acked_flags = ( TCP_FLAGS_SENDING ( tcp->tcp_state ) &
|
|
763
|
+ ( TCP_SYN | TCP_FIN ) );
|
|
764
|
+ if ( acked_flags )
|
|
765
|
+ len--;
|
|
766
|
+
|
763
|
767
|
/* Update SEQ and sent counters, and window size */
|
764
|
768
|
tcp->snd_seq = ack;
|
765
|
769
|
tcp->snd_sent = 0;
|