david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

Limit xmit window to one MTU. (Path MTU discovery not yet

implemented; should be done at some point.)
This commit is contained in:
Michael Brown 2007-07-08 14:33:53 +01:00
parent 3e1dd0772a
commit edded7546e
2 changed files with 42 additions and 16 deletions

View File

@ -237,6 +237,14 @@ struct tcp_mss_option {
*/
#define TCP_MAX_WINDOW_SIZE ( 65536 - 4 )
/**
* Path MTU
*
* We really ought to implement Path MTU discovery. Until we do,
* anything with a path MTU greater than this may fail.
*/
#define TCP_PATH_MTU 1460
/**
* Advertised TCP MSS
*

View File

@ -301,6 +301,27 @@ static void tcp_close ( struct tcp_connection *tcp, int rc ) {
***************************************************************************
*/
/**
* Calculate transmission window
*
* @v tcp TCP connection
* @ret len Maximum length that can be sent in a single packet
*/
static size_t tcp_xmit_win ( struct tcp_connection *tcp ) {
size_t len;
/* Not ready if we're not in a suitable connection state */
if ( ! TCP_CAN_SEND_DATA ( tcp->tcp_state ) )
return 0;
/* Length is the minimum of the receiver's window and the path MTU */
len = tcp->snd_win;
if ( len > TCP_PATH_MTU )
len = TCP_PATH_MTU;
return len;
}
/**
* Process TCP transmit queue
*
@ -363,8 +384,8 @@ static int tcp_xmit ( struct tcp_connection *tcp, int force_send ) {
unsigned int flags;
size_t len = 0;
size_t seq_len;
size_t app_window;
size_t window;
size_t app_win;
size_t rcv_win;
int rc;
/* If retransmission timer is already running, do nothing */
@ -375,7 +396,8 @@ static int tcp_xmit ( struct tcp_connection *tcp, int force_send ) {
* lengths that we wish to transmit.
*/
if ( TCP_CAN_SEND_DATA ( tcp->tcp_state ) ) {
len = tcp_process_queue ( tcp, tcp->snd_win, NULL, 0 );
len = tcp_process_queue ( tcp, tcp_xmit_win ( tcp ),
NULL, 0 );
}
seq_len = len;
flags = TCP_FLAGS_SENDING ( tcp->tcp_state );
@ -410,13 +432,13 @@ static int tcp_xmit ( struct tcp_connection *tcp, int force_send ) {
tcp_process_queue ( tcp, len, iobuf, 0 );
/* Estimate window size */
window = ( ( freemem * 3 ) / 4 );
if ( window > TCP_MAX_WINDOW_SIZE )
window = TCP_MAX_WINDOW_SIZE;
app_window = xfer_window ( &tcp->xfer );
if ( window > app_window )
window = app_window;
window &= ~0x03; /* Keep everything dword-aligned */
rcv_win = ( ( freemem * 3 ) / 4 );
if ( rcv_win > TCP_MAX_WINDOW_SIZE )
rcv_win = TCP_MAX_WINDOW_SIZE;
app_win = xfer_window ( &tcp->xfer );
if ( rcv_win > app_win )
rcv_win = app_win;
rcv_win &= ~0x03; /* Keep everything dword-aligned */
/* Fill up the TCP header */
payload = iobuf->data;
@ -434,7 +456,7 @@ static int tcp_xmit ( struct tcp_connection *tcp, int force_send ) {
tcphdr->ack = htonl ( tcp->rcv_ack );
tcphdr->hlen = ( ( payload - iobuf->data ) << 2 );
tcphdr->flags = flags;
tcphdr->win = htons ( window );
tcphdr->win = htons ( rcv_win );
tcphdr->csum = tcpip_chksum ( iobuf->data, iob_len ( iobuf ) );
/* Dump header */
@ -910,10 +932,6 @@ static size_t tcp_xfer_window ( struct xfer_interface *xfer ) {
struct tcp_connection *tcp =
container_of ( xfer, struct tcp_connection, xfer );
/* Not ready if we're not in a suitable connection state */
if ( ! TCP_CAN_SEND_DATA ( tcp->tcp_state ) )
return 0;
/* Not ready if data queue is non-empty. This imposes a limit
* of only one unACKed packet in the TX queue at any time; we
* do this to conserve memory usage.
@ -922,7 +940,7 @@ static size_t tcp_xfer_window ( struct xfer_interface *xfer ) {
return 0;
/* Return TCP window length */
return tcp->snd_win;
return tcp_xmit_win ( tcp );
}
/**