|  | @@ -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;
 |