From 469bd11f392797027b68e9d22f8f59a547886515 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 19 Sep 2011 15:48:57 +0100 Subject: [PATCH] [tcp] Allow sufficient headroom for TCP headers TCP currently neglects to allow sufficient space for its own headers when allocating I/O buffers. This problem is masked by the fact that the maximum link-layer header size (802.11) is substantially larger than the common Ethernet link-layer header. Fix by allowing sufficient space for any TCP headers, as well as the network-layer and link-layer headers. Reported-by: Scott K Logan Debugged-by: Scott K Logan Tested-by: Scott K Logan Signed-off-by: Michael Brown --- src/include/ipxe/tcp.h | 10 ++++++++++ src/net/tcp.c | 8 ++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/include/ipxe/tcp.h b/src/include/ipxe/tcp.h index 197712b1..7084af60 100644 --- a/src/include/ipxe/tcp.h +++ b/src/include/ipxe/tcp.h @@ -308,6 +308,16 @@ struct tcp_options { */ #define TCP_MSL ( 2 * 60 * TICKS_PER_SEC ) +/** + * TCP maximum header length + * + */ +#define TCP_MAX_HEADER_LEN \ + ( MAX_LL_NET_HEADER_LEN + \ + sizeof ( struct tcp_header ) + \ + sizeof ( struct tcp_mss_option ) + \ + sizeof ( struct tcp_timestamp_padded_option ) ) + /** * Compare TCP sequence numbers * diff --git a/src/net/tcp.c b/src/net/tcp.c index 4df1aed5..0a7924a7 100644 --- a/src/net/tcp.c +++ b/src/net/tcp.c @@ -509,14 +509,14 @@ static int tcp_xmit ( struct tcp_connection *tcp ) { start_timer ( &tcp->timer ); /* Allocate I/O buffer */ - iobuf = alloc_iob ( len + MAX_LL_NET_HEADER_LEN ); + iobuf = alloc_iob ( len + TCP_MAX_HEADER_LEN ); if ( ! iobuf ) { DBGC ( tcp, "TCP %p could not allocate iobuf for %08x..%08x " "%08x\n", tcp, tcp->snd_seq, ( tcp->snd_seq + seq_len ), tcp->rcv_ack ); return -ENOMEM; } - iob_reserve ( iobuf, MAX_LL_NET_HEADER_LEN ); + iob_reserve ( iobuf, TCP_MAX_HEADER_LEN ); /* Fill data payload from transmit queue */ tcp_process_tx_queue ( tcp, len, iobuf, 0 ); @@ -653,14 +653,14 @@ static int tcp_xmit_reset ( struct tcp_connection *tcp, int rc; /* Allocate space for dataless TX buffer */ - iobuf = alloc_iob ( MAX_LL_NET_HEADER_LEN ); + iobuf = alloc_iob ( TCP_MAX_HEADER_LEN ); if ( ! iobuf ) { DBGC ( tcp, "TCP %p could not allocate iobuf for RST " "%08x..%08x %08x\n", tcp, ntohl ( in_tcphdr->ack ), ntohl ( in_tcphdr->ack ), ntohl ( in_tcphdr->seq ) ); return -ENOMEM; } - iob_reserve ( iobuf, MAX_LL_NET_HEADER_LEN ); + iob_reserve ( iobuf, TCP_MAX_HEADER_LEN ); /* Construct RST response */ tcphdr = iob_push ( iobuf, sizeof ( *tcphdr ) );