|  | @@ -301,6 +301,27 @@ static void tcp_close ( struct tcp_connection *tcp, int rc ) {
 | 
		
	
		
			
			| 301 | 301 |   ***************************************************************************
 | 
		
	
		
			
			| 302 | 302 |   */
 | 
		
	
		
			
			| 303 | 303 |  
 | 
		
	
		
			
			|  | 304 | +/**
 | 
		
	
		
			
			|  | 305 | + * Calculate transmission window
 | 
		
	
		
			
			|  | 306 | + *
 | 
		
	
		
			
			|  | 307 | + * @v tcp		TCP connection
 | 
		
	
		
			
			|  | 308 | + * @ret len		Maximum length that can be sent in a single packet
 | 
		
	
		
			
			|  | 309 | + */
 | 
		
	
		
			
			|  | 310 | +static size_t tcp_xmit_win ( struct tcp_connection *tcp ) {
 | 
		
	
		
			
			|  | 311 | +	size_t len;
 | 
		
	
		
			
			|  | 312 | +
 | 
		
	
		
			
			|  | 313 | +	/* Not ready if we're not in a suitable connection state */
 | 
		
	
		
			
			|  | 314 | +	if ( ! TCP_CAN_SEND_DATA ( tcp->tcp_state ) )
 | 
		
	
		
			
			|  | 315 | +		return 0;
 | 
		
	
		
			
			|  | 316 | +
 | 
		
	
		
			
			|  | 317 | +	/* Length is the minimum of the receiver's window and the path MTU */
 | 
		
	
		
			
			|  | 318 | +	len = tcp->snd_win;
 | 
		
	
		
			
			|  | 319 | +	if ( len > TCP_PATH_MTU )
 | 
		
	
		
			
			|  | 320 | +		len = TCP_PATH_MTU;
 | 
		
	
		
			
			|  | 321 | +
 | 
		
	
		
			
			|  | 322 | +	return len;
 | 
		
	
		
			
			|  | 323 | +}
 | 
		
	
		
			
			|  | 324 | +
 | 
		
	
		
			
			| 304 | 325 |  /**
 | 
		
	
		
			
			| 305 | 326 |   * Process TCP transmit queue
 | 
		
	
		
			
			| 306 | 327 |   *
 | 
		
	
	
		
			
			|  | @@ -363,8 +384,8 @@ static int tcp_xmit ( struct tcp_connection *tcp, int force_send ) {
 | 
		
	
		
			
			| 363 | 384 |  	unsigned int flags;
 | 
		
	
		
			
			| 364 | 385 |  	size_t len = 0;
 | 
		
	
		
			
			| 365 | 386 |  	size_t seq_len;
 | 
		
	
		
			
			| 366 |  | -	size_t app_window;
 | 
		
	
		
			
			| 367 |  | -	size_t window;
 | 
		
	
		
			
			|  | 387 | +	size_t app_win;
 | 
		
	
		
			
			|  | 388 | +	size_t rcv_win;
 | 
		
	
		
			
			| 368 | 389 |  	int rc;
 | 
		
	
		
			
			| 369 | 390 |  
 | 
		
	
		
			
			| 370 | 391 |  	/* If retransmission timer is already running, do nothing */
 | 
		
	
	
		
			
			|  | @@ -375,7 +396,8 @@ static int tcp_xmit ( struct tcp_connection *tcp, int force_send ) {
 | 
		
	
		
			
			| 375 | 396 |  	 * lengths that we wish to transmit.
 | 
		
	
		
			
			| 376 | 397 |  	 */
 | 
		
	
		
			
			| 377 | 398 |  	if ( TCP_CAN_SEND_DATA ( tcp->tcp_state ) ) {
 | 
		
	
		
			
			| 378 |  | -		len = tcp_process_queue ( tcp, tcp->snd_win, NULL, 0 );
 | 
		
	
		
			
			|  | 399 | +		len = tcp_process_queue ( tcp, tcp_xmit_win ( tcp ),
 | 
		
	
		
			
			|  | 400 | +					  NULL, 0 );
 | 
		
	
		
			
			| 379 | 401 |  	}
 | 
		
	
		
			
			| 380 | 402 |  	seq_len = len;
 | 
		
	
		
			
			| 381 | 403 |  	flags = TCP_FLAGS_SENDING ( tcp->tcp_state );
 | 
		
	
	
		
			
			|  | @@ -410,13 +432,13 @@ static int tcp_xmit ( struct tcp_connection *tcp, int force_send ) {
 | 
		
	
		
			
			| 410 | 432 |  	tcp_process_queue ( tcp, len, iobuf, 0 );
 | 
		
	
		
			
			| 411 | 433 |  
 | 
		
	
		
			
			| 412 | 434 |  	/* Estimate window size */
 | 
		
	
		
			
			| 413 |  | -	window = ( ( freemem * 3 ) / 4 );
 | 
		
	
		
			
			| 414 |  | -	if ( window > TCP_MAX_WINDOW_SIZE )
 | 
		
	
		
			
			| 415 |  | -		window = TCP_MAX_WINDOW_SIZE;
 | 
		
	
		
			
			| 416 |  | -	app_window = xfer_window ( &tcp->xfer );
 | 
		
	
		
			
			| 417 |  | -	if ( window > app_window )
 | 
		
	
		
			
			| 418 |  | -		window = app_window;
 | 
		
	
		
			
			| 419 |  | -	window &= ~0x03; /* Keep everything dword-aligned */
 | 
		
	
		
			
			|  | 435 | +	rcv_win = ( ( freemem * 3 ) / 4 );
 | 
		
	
		
			
			|  | 436 | +	if ( rcv_win > TCP_MAX_WINDOW_SIZE )
 | 
		
	
		
			
			|  | 437 | +		rcv_win = TCP_MAX_WINDOW_SIZE;
 | 
		
	
		
			
			|  | 438 | +	app_win = xfer_window ( &tcp->xfer );
 | 
		
	
		
			
			|  | 439 | +	if ( rcv_win > app_win )
 | 
		
	
		
			
			|  | 440 | +		rcv_win = app_win;
 | 
		
	
		
			
			|  | 441 | +	rcv_win &= ~0x03; /* Keep everything dword-aligned */
 | 
		
	
		
			
			| 420 | 442 |  
 | 
		
	
		
			
			| 421 | 443 |  	/* Fill up the TCP header */
 | 
		
	
		
			
			| 422 | 444 |  	payload = iobuf->data;
 | 
		
	
	
		
			
			|  | @@ -434,7 +456,7 @@ static int tcp_xmit ( struct tcp_connection *tcp, int force_send ) {
 | 
		
	
		
			
			| 434 | 456 |  	tcphdr->ack = htonl ( tcp->rcv_ack );
 | 
		
	
		
			
			| 435 | 457 |  	tcphdr->hlen = ( ( payload - iobuf->data ) << 2 );
 | 
		
	
		
			
			| 436 | 458 |  	tcphdr->flags = flags;
 | 
		
	
		
			
			| 437 |  | -	tcphdr->win = htons ( window );
 | 
		
	
		
			
			|  | 459 | +	tcphdr->win = htons ( rcv_win );
 | 
		
	
		
			
			| 438 | 460 |  	tcphdr->csum = tcpip_chksum ( iobuf->data, iob_len ( iobuf ) );
 | 
		
	
		
			
			| 439 | 461 |  
 | 
		
	
		
			
			| 440 | 462 |  	/* Dump header */
 | 
		
	
	
		
			
			|  | @@ -910,10 +932,6 @@ static size_t tcp_xfer_window ( struct xfer_interface *xfer ) {
 | 
		
	
		
			
			| 910 | 932 |  	struct tcp_connection *tcp =
 | 
		
	
		
			
			| 911 | 933 |  		container_of ( xfer, struct tcp_connection, xfer );
 | 
		
	
		
			
			| 912 | 934 |  
 | 
		
	
		
			
			| 913 |  | -	/* Not ready if we're not in a suitable connection state */
 | 
		
	
		
			
			| 914 |  | -	if ( ! TCP_CAN_SEND_DATA ( tcp->tcp_state ) )
 | 
		
	
		
			
			| 915 |  | -		return 0;
 | 
		
	
		
			
			| 916 |  | -
 | 
		
	
		
			
			| 917 | 935 |  	/* Not ready if data queue is non-empty.  This imposes a limit
 | 
		
	
		
			
			| 918 | 936 |  	 * of only one unACKed packet in the TX queue at any time; we
 | 
		
	
		
			
			| 919 | 937 |  	 * do this to conserve memory usage.
 | 
		
	
	
		
			
			|  | @@ -922,7 +940,7 @@ static size_t tcp_xfer_window ( struct xfer_interface *xfer ) {
 | 
		
	
		
			
			| 922 | 940 |  		return 0;
 | 
		
	
		
			
			| 923 | 941 |  
 | 
		
	
		
			
			| 924 | 942 |  	/* Return TCP window length */
 | 
		
	
		
			
			| 925 |  | -	return tcp->snd_win;
 | 
		
	
		
			
			|  | 943 | +	return tcp_xmit_win ( tcp );
 | 
		
	
		
			
			| 926 | 944 |  }
 | 
		
	
		
			
			| 927 | 945 |  
 | 
		
	
		
			
			| 928 | 946 |  /**
 |