|  | @@ -93,6 +93,8 @@ enum tcp_flags {
 | 
		
	
		
			
			| 93 | 93 |  	TCP_XFER_CLOSED = 0x0001,
 | 
		
	
		
			
			| 94 | 94 |  	/** TCP timestamps are enabled */
 | 
		
	
		
			
			| 95 | 95 |  	TCP_TS_ENABLED = 0x0002,
 | 
		
	
		
			
			|  | 96 | +	/** TCP acknowledgement is pending */
 | 
		
	
		
			
			|  | 97 | +	TCP_ACK_PENDING = 0x0004,
 | 
		
	
		
			
			| 96 | 98 |  };
 | 
		
	
		
			
			| 97 | 99 |  
 | 
		
	
		
			
			| 98 | 100 |  /**
 | 
		
	
	
		
			
			|  | @@ -396,7 +398,6 @@ static size_t tcp_process_queue ( struct tcp_connection *tcp, size_t max_len,
 | 
		
	
		
			
			| 396 | 398 |   * Transmit any outstanding data
 | 
		
	
		
			
			| 397 | 399 |   *
 | 
		
	
		
			
			| 398 | 400 |   * @v tcp		TCP connection
 | 
		
	
		
			
			| 399 |  | - * @v force_send	Force sending of packet
 | 
		
	
		
			
			| 400 | 401 |   * 
 | 
		
	
		
			
			| 401 | 402 |   * Transmits any outstanding data on the connection.
 | 
		
	
		
			
			| 402 | 403 |   *
 | 
		
	
	
		
			
			|  | @@ -404,7 +405,7 @@ static size_t tcp_process_queue ( struct tcp_connection *tcp, size_t max_len,
 | 
		
	
		
			
			| 404 | 405 |   * will have been started if necessary, and so the stack will
 | 
		
	
		
			
			| 405 | 406 |   * eventually attempt to retransmit the failed packet.
 | 
		
	
		
			
			| 406 | 407 |   */
 | 
		
	
		
			
			| 407 |  | -static int tcp_xmit ( struct tcp_connection *tcp, int force_send ) {
 | 
		
	
		
			
			|  | 408 | +static int tcp_xmit ( struct tcp_connection *tcp ) {
 | 
		
	
		
			
			| 408 | 409 |  	struct io_buffer *iobuf;
 | 
		
	
		
			
			| 409 | 410 |  	struct tcp_header *tcphdr;
 | 
		
	
		
			
			| 410 | 411 |  	struct tcp_mss_option *mssopt;
 | 
		
	
	
		
			
			|  | @@ -438,7 +439,7 @@ static int tcp_xmit ( struct tcp_connection *tcp, int force_send ) {
 | 
		
	
		
			
			| 438 | 439 |  	tcp->snd_sent = seq_len;
 | 
		
	
		
			
			| 439 | 440 |  
 | 
		
	
		
			
			| 440 | 441 |  	/* If we have nothing to transmit, stop now */
 | 
		
	
		
			
			| 441 |  | -	if ( ( seq_len == 0 ) && ! force_send )
 | 
		
	
		
			
			|  | 442 | +	if ( ( seq_len == 0 ) && ! ( tcp->flags & TCP_ACK_PENDING ) )
 | 
		
	
		
			
			| 442 | 443 |  		return 0;
 | 
		
	
		
			
			| 443 | 444 |  
 | 
		
	
		
			
			| 444 | 445 |  	/* If we are transmitting anything that requires
 | 
		
	
	
		
			
			|  | @@ -519,6 +520,9 @@ static int tcp_xmit ( struct tcp_connection *tcp, int force_send ) {
 | 
		
	
		
			
			| 519 | 520 |  		return rc;
 | 
		
	
		
			
			| 520 | 521 |  	}
 | 
		
	
		
			
			| 521 | 522 |  
 | 
		
	
		
			
			|  | 523 | +	/* Clear ACK-pending flag */
 | 
		
	
		
			
			|  | 524 | +	tcp->flags &= ~TCP_ACK_PENDING;
 | 
		
	
		
			
			|  | 525 | +
 | 
		
	
		
			
			| 522 | 526 |  	return 0;
 | 
		
	
		
			
			| 523 | 527 |  }
 | 
		
	
		
			
			| 524 | 528 |  
 | 
		
	
	
		
			
			|  | @@ -552,7 +556,7 @@ static void tcp_expired ( struct retry_timer *timer, int over ) {
 | 
		
	
		
			
			| 552 | 556 |  		tcp_close ( tcp, -ETIMEDOUT );
 | 
		
	
		
			
			| 553 | 557 |  	} else {
 | 
		
	
		
			
			| 554 | 558 |  		/* Otherwise, retransmit the packet */
 | 
		
	
		
			
			| 555 |  | -		tcp_xmit ( tcp, 0 );
 | 
		
	
		
			
			|  | 559 | +		tcp_xmit ( tcp );
 | 
		
	
		
			
			| 556 | 560 |  	}
 | 
		
	
		
			
			| 557 | 561 |  }
 | 
		
	
		
			
			| 558 | 562 |  
 | 
		
	
	
		
			
			|  | @@ -709,6 +713,7 @@ static void tcp_rx_seq ( struct tcp_connection *tcp, uint32_t seq_len ) {
 | 
		
	
		
			
			| 709 | 713 |  	} else {
 | 
		
	
		
			
			| 710 | 714 |  		tcp->rcv_win = 0;
 | 
		
	
		
			
			| 711 | 715 |  	}
 | 
		
	
		
			
			|  | 716 | +	tcp->flags |= TCP_ACK_PENDING;
 | 
		
	
		
			
			| 712 | 717 |  }
 | 
		
	
		
			
			| 713 | 718 |  
 | 
		
	
		
			
			| 714 | 719 |  /**
 | 
		
	
	
		
			
			|  | @@ -927,7 +932,6 @@ static int tcp_rx ( struct io_buffer *iobuf,
 | 
		
	
		
			
			| 927 | 932 |  	struct tcp_options options;
 | 
		
	
		
			
			| 928 | 933 |  	size_t hlen;
 | 
		
	
		
			
			| 929 | 934 |  	uint16_t csum;
 | 
		
	
		
			
			| 930 |  | -	uint32_t start_seq;
 | 
		
	
		
			
			| 931 | 935 |  	uint32_t seq;
 | 
		
	
		
			
			| 932 | 936 |  	uint32_t ack;
 | 
		
	
		
			
			| 933 | 937 |  	uint32_t win;
 | 
		
	
	
		
			
			|  | @@ -967,7 +971,7 @@ static int tcp_rx ( struct io_buffer *iobuf,
 | 
		
	
		
			
			| 967 | 971 |  	
 | 
		
	
		
			
			| 968 | 972 |  	/* Parse parameters from header and strip header */
 | 
		
	
		
			
			| 969 | 973 |  	tcp = tcp_demux ( ntohs ( tcphdr->dest ) );
 | 
		
	
		
			
			| 970 |  | -	start_seq = seq = ntohl ( tcphdr->seq );
 | 
		
	
		
			
			|  | 974 | +	seq = ntohl ( tcphdr->seq );
 | 
		
	
		
			
			| 971 | 975 |  	ack = ntohl ( tcphdr->ack );
 | 
		
	
		
			
			| 972 | 976 |  	win = ntohs ( tcphdr->win );
 | 
		
	
		
			
			| 973 | 977 |  	flags = tcphdr->flags;
 | 
		
	
	
		
			
			|  | @@ -1002,6 +1006,12 @@ static int tcp_rx ( struct io_buffer *iobuf,
 | 
		
	
		
			
			| 1002 | 1006 |  		}
 | 
		
	
		
			
			| 1003 | 1007 |  	}
 | 
		
	
		
			
			| 1004 | 1008 |  
 | 
		
	
		
			
			|  | 1009 | +	/* Force an ACK if this packet is out of order */
 | 
		
	
		
			
			|  | 1010 | +	if ( ( tcp->tcp_state & TCP_STATE_RCVD ( TCP_SYN ) ) &&
 | 
		
	
		
			
			|  | 1011 | +	     ( seq != tcp->rcv_ack ) ) {
 | 
		
	
		
			
			|  | 1012 | +		tcp->flags |= TCP_ACK_PENDING;
 | 
		
	
		
			
			|  | 1013 | +	}
 | 
		
	
		
			
			|  | 1014 | +
 | 
		
	
		
			
			| 1005 | 1015 |  	/* Handle SYN, if present */
 | 
		
	
		
			
			| 1006 | 1016 |  	if ( flags & TCP_SYN ) {
 | 
		
	
		
			
			| 1007 | 1017 |  		tcp_rx_syn ( tcp, seq, &options );
 | 
		
	
	
		
			
			|  | @@ -1031,19 +1041,8 @@ static int tcp_rx ( struct io_buffer *iobuf,
 | 
		
	
		
			
			| 1031 | 1041 |  	/* Dump out any state change as a result of the received packet */
 | 
		
	
		
			
			| 1032 | 1042 |  	tcp_dump_state ( tcp );
 | 
		
	
		
			
			| 1033 | 1043 |  
 | 
		
	
		
			
			| 1034 |  | -	/* Send out any pending data.  We force sending a reply if either
 | 
		
	
		
			
			| 1035 |  | -	 *
 | 
		
	
		
			
			| 1036 |  | -	 *  a) the peer is expecting an ACK (i.e. consumed sequence space), or
 | 
		
	
		
			
			| 1037 |  | -	 *  b) either end of the packet was outside the receive window
 | 
		
	
		
			
			| 1038 |  | -	 *
 | 
		
	
		
			
			| 1039 |  | -	 * Case (b) enables us to support TCP keepalives using
 | 
		
	
		
			
			| 1040 |  | -	 * zero-length packets, which we would otherwise ignore.  Note
 | 
		
	
		
			
			| 1041 |  | -	 * that for case (b), we need *only* consider zero-length
 | 
		
	
		
			
			| 1042 |  | -	 * packets, since non-zero-length packets will already be
 | 
		
	
		
			
			| 1043 |  | -	 * caught by case (a).
 | 
		
	
		
			
			| 1044 |  | -	 */
 | 
		
	
		
			
			| 1045 |  | -	tcp_xmit ( tcp, ( ( start_seq != seq ) ||
 | 
		
	
		
			
			| 1046 |  | -			  ( ( seq - tcp->rcv_ack ) > tcp->rcv_win ) ) );
 | 
		
	
		
			
			|  | 1044 | +	/* Send out any pending data */
 | 
		
	
		
			
			|  | 1045 | +	tcp_xmit ( tcp );
 | 
		
	
		
			
			| 1047 | 1046 |  
 | 
		
	
		
			
			| 1048 | 1047 |  	/* If this packet was the last we expect to receive, set up
 | 
		
	
		
			
			| 1049 | 1048 |  	 * timer to expire and cause the connection to be freed.
 | 
		
	
	
		
			
			|  | @@ -1087,7 +1086,7 @@ static void tcp_xfer_close ( struct tcp_connection *tcp, int rc ) {
 | 
		
	
		
			
			| 1087 | 1086 |  	tcp_close ( tcp, rc );
 | 
		
	
		
			
			| 1088 | 1087 |  
 | 
		
	
		
			
			| 1089 | 1088 |  	/* Transmit FIN, if possible */
 | 
		
	
		
			
			| 1090 |  | -	tcp_xmit ( tcp, 0 );
 | 
		
	
		
			
			|  | 1089 | +	tcp_xmit ( tcp );
 | 
		
	
		
			
			| 1091 | 1090 |  }
 | 
		
	
		
			
			| 1092 | 1091 |  
 | 
		
	
		
			
			| 1093 | 1092 |  /**
 | 
		
	
	
		
			
			|  | @@ -1125,7 +1124,7 @@ static int tcp_xfer_deliver ( struct tcp_connection *tcp,
 | 
		
	
		
			
			| 1125 | 1124 |  	list_add_tail ( &iobuf->list, &tcp->queue );
 | 
		
	
		
			
			| 1126 | 1125 |  
 | 
		
	
		
			
			| 1127 | 1126 |  	/* Transmit data, if possible */
 | 
		
	
		
			
			| 1128 |  | -	tcp_xmit ( tcp, 0 );
 | 
		
	
		
			
			|  | 1127 | +	tcp_xmit ( tcp );
 | 
		
	
		
			
			| 1129 | 1128 |  
 | 
		
	
		
			
			| 1130 | 1129 |  	return 0;
 | 
		
	
		
			
			| 1131 | 1130 |  }
 |