|  | @@ -391,6 +391,25 @@ static size_t tcp_xmit_win ( struct tcp_connection *tcp ) {
 | 
		
	
		
			
			| 391 | 391 |  	return len;
 | 
		
	
		
			
			| 392 | 392 |  }
 | 
		
	
		
			
			| 393 | 393 |  
 | 
		
	
		
			
			|  | 394 | +/**
 | 
		
	
		
			
			|  | 395 | + * Check data-transfer flow control window
 | 
		
	
		
			
			|  | 396 | + *
 | 
		
	
		
			
			|  | 397 | + * @v tcp		TCP connection
 | 
		
	
		
			
			|  | 398 | + * @ret len		Length of window
 | 
		
	
		
			
			|  | 399 | + */
 | 
		
	
		
			
			|  | 400 | +static size_t tcp_xfer_window ( struct tcp_connection *tcp ) {
 | 
		
	
		
			
			|  | 401 | +
 | 
		
	
		
			
			|  | 402 | +	/* Not ready if data queue is non-empty.  This imposes a limit
 | 
		
	
		
			
			|  | 403 | +	 * of only one unACKed packet in the TX queue at any time; we
 | 
		
	
		
			
			|  | 404 | +	 * do this to conserve memory usage.
 | 
		
	
		
			
			|  | 405 | +	 */
 | 
		
	
		
			
			|  | 406 | +	if ( ! list_empty ( &tcp->tx_queue ) )
 | 
		
	
		
			
			|  | 407 | +		return 0;
 | 
		
	
		
			
			|  | 408 | +
 | 
		
	
		
			
			|  | 409 | +	/* Return TCP window length */
 | 
		
	
		
			
			|  | 410 | +	return tcp_xmit_win ( tcp );
 | 
		
	
		
			
			|  | 411 | +}
 | 
		
	
		
			
			|  | 412 | +
 | 
		
	
		
			
			| 394 | 413 |  /**
 | 
		
	
		
			
			| 395 | 414 |   * Process TCP transmit queue
 | 
		
	
		
			
			| 396 | 415 |   *
 | 
		
	
	
		
			
			|  | @@ -1084,6 +1103,7 @@ static int tcp_rx ( struct io_buffer *iobuf,
 | 
		
	
		
			
			| 1084 | 1103 |  	unsigned int flags;
 | 
		
	
		
			
			| 1085 | 1104 |  	size_t len;
 | 
		
	
		
			
			| 1086 | 1105 |  	uint32_t seq_len;
 | 
		
	
		
			
			|  | 1106 | +	size_t old_xfer_window;
 | 
		
	
		
			
			| 1087 | 1107 |  	int rc;
 | 
		
	
		
			
			| 1088 | 1108 |  
 | 
		
	
		
			
			| 1089 | 1109 |  	/* Sanity check packet */
 | 
		
	
	
		
			
			|  | @@ -1145,6 +1165,9 @@ static int tcp_rx ( struct io_buffer *iobuf,
 | 
		
	
		
			
			| 1145 | 1165 |  		goto discard;
 | 
		
	
		
			
			| 1146 | 1166 |  	}
 | 
		
	
		
			
			| 1147 | 1167 |  
 | 
		
	
		
			
			|  | 1168 | +	/* Record old data-transfer window */
 | 
		
	
		
			
			|  | 1169 | +	old_xfer_window = tcp_xfer_window ( tcp );
 | 
		
	
		
			
			|  | 1170 | +
 | 
		
	
		
			
			| 1148 | 1171 |  	/* Handle ACK, if present */
 | 
		
	
		
			
			| 1149 | 1172 |  	if ( flags & TCP_ACK ) {
 | 
		
	
		
			
			| 1150 | 1173 |  		if ( ( rc = tcp_rx_ack ( tcp, ack, win ) ) != 0 ) {
 | 
		
	
	
		
			
			|  | @@ -1191,6 +1214,10 @@ static int tcp_rx ( struct io_buffer *iobuf,
 | 
		
	
		
			
			| 1191 | 1214 |  		start_timer_fixed ( &tcp->wait, ( 2 * TCP_MSL ) );
 | 
		
	
		
			
			| 1192 | 1215 |  	}
 | 
		
	
		
			
			| 1193 | 1216 |  
 | 
		
	
		
			
			|  | 1217 | +	/* Notify application if window has changed */
 | 
		
	
		
			
			|  | 1218 | +	if ( tcp_xfer_window ( tcp ) != old_xfer_window )
 | 
		
	
		
			
			|  | 1219 | +		xfer_window_changed ( &tcp->xfer );
 | 
		
	
		
			
			|  | 1220 | +
 | 
		
	
		
			
			| 1194 | 1221 |  	return 0;
 | 
		
	
		
			
			| 1195 | 1222 |  
 | 
		
	
		
			
			| 1196 | 1223 |   discard:
 | 
		
	
	
		
			
			|  | @@ -1256,25 +1283,6 @@ static void tcp_xfer_close ( struct tcp_connection *tcp, int rc ) {
 | 
		
	
		
			
			| 1256 | 1283 |  	tcp_xmit ( tcp );
 | 
		
	
		
			
			| 1257 | 1284 |  }
 | 
		
	
		
			
			| 1258 | 1285 |  
 | 
		
	
		
			
			| 1259 |  | -/**
 | 
		
	
		
			
			| 1260 |  | - * Check flow control window
 | 
		
	
		
			
			| 1261 |  | - *
 | 
		
	
		
			
			| 1262 |  | - * @v tcp		TCP connection
 | 
		
	
		
			
			| 1263 |  | - * @ret len		Length of window
 | 
		
	
		
			
			| 1264 |  | - */
 | 
		
	
		
			
			| 1265 |  | -static size_t tcp_xfer_window ( struct tcp_connection *tcp ) {
 | 
		
	
		
			
			| 1266 |  | -
 | 
		
	
		
			
			| 1267 |  | -	/* Not ready if data queue is non-empty.  This imposes a limit
 | 
		
	
		
			
			| 1268 |  | -	 * of only one unACKed packet in the TX queue at any time; we
 | 
		
	
		
			
			| 1269 |  | -	 * do this to conserve memory usage.
 | 
		
	
		
			
			| 1270 |  | -	 */
 | 
		
	
		
			
			| 1271 |  | -	if ( ! list_empty ( &tcp->tx_queue ) )
 | 
		
	
		
			
			| 1272 |  | -		return 0;
 | 
		
	
		
			
			| 1273 |  | -
 | 
		
	
		
			
			| 1274 |  | -	/* Return TCP window length */
 | 
		
	
		
			
			| 1275 |  | -	return tcp_xmit_win ( tcp );
 | 
		
	
		
			
			| 1276 |  | -}
 | 
		
	
		
			
			| 1277 |  | -
 | 
		
	
		
			
			| 1278 | 1286 |  /**
 | 
		
	
		
			
			| 1279 | 1287 |   * Deliver datagram as I/O buffer
 | 
		
	
		
			
			| 1280 | 1288 |   *
 |