summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Brown2007-01-13 18:36:17 +0100
committerMichael Brown2007-01-13 18:36:17 +0100
commit526d314266f1648ae79d8cdd380edb371fb69e4b (patch)
tree5284562a3282e8bd7b2652b33563c764fa48cb10
parentI prefer IMAGE_XXX to XXX_IMAGE. (diff)
downloadipxe-526d314266f1648ae79d8cdd380edb371fb69e4b.tar.gz
ipxe-526d314266f1648ae79d8cdd380edb371fb69e4b.tar.xz
ipxe-526d314266f1648ae79d8cdd380edb371fb69e4b.zip
Advertise a larger MSS to improve TCP performance.
-rw-r--r--src/include/gpxe/tcp.h24
-rw-r--r--src/net/tcp.c11
2 files changed, 33 insertions, 2 deletions
diff --git a/src/include/gpxe/tcp.h b/src/include/gpxe/tcp.h
index f9cd41390..c8988cf52 100644
--- a/src/include/gpxe/tcp.h
+++ b/src/include/gpxe/tcp.h
@@ -27,6 +27,18 @@ struct tcp_header {
uint16_t urg; /* Urgent pointer */
};
+/**
+ * TCP MSS option
+ */
+struct tcp_mss_option {
+ uint8_t kind;
+ uint8_t length;
+ uint16_t mss;
+};
+
+/** Code for the TCP MSS option */
+#define TCP_OPTION_MSS 2
+
/*
* TCP flags
*/
@@ -212,7 +224,17 @@ struct tcp_header {
* guess an arbitrary number that is empirically as large as possible
* while avoiding retransmissions due to dropped packets.
*/
-#define TCP_WINDOW_SIZE 2048
+#define TCP_WINDOW_SIZE 4096
+
+/**
+ * Advertised TCP MSS
+ *
+ * We currently hardcode this to a reasonable value and hope that the
+ * sender uses path MTU discovery. The alternative is breaking the
+ * abstraction layer so that we can find out the MTU from the IP layer
+ * (which would have to find out from the net device layer).
+ */
+#define TCP_MSS 1460
/** TCP maximum segment lifetime
*
diff --git a/src/net/tcp.c b/src/net/tcp.c
index f50c776a5..6496239f4 100644
--- a/src/net/tcp.c
+++ b/src/net/tcp.c
@@ -229,6 +229,8 @@ static int tcp_senddata_conn ( struct tcp_connection *conn, int force_send ) {
struct tcp_application *app = conn->app;
struct pk_buff *pkb;
struct tcp_header *tcphdr;
+ struct tcp_mss_option *mssopt;
+ void *payload;
unsigned int flags;
size_t len;
size_t seq_len;
@@ -289,13 +291,20 @@ static int tcp_senddata_conn ( struct tcp_connection *conn, int force_send ) {
start_timer ( &conn->timer );
/* Fill up the TCP header */
+ payload = pkb->data;
+ if ( flags & TCP_SYN ) {
+ mssopt = pkb_push ( pkb, sizeof ( *mssopt ) );
+ mssopt->kind = TCP_OPTION_MSS;
+ mssopt->length = sizeof ( *mssopt );
+ mssopt->mss = htons ( TCP_MSS );
+ }
tcphdr = pkb_push ( pkb, sizeof ( *tcphdr ) );
memset ( tcphdr, 0, sizeof ( *tcphdr ) );
tcphdr->src = conn->local_port;
tcphdr->dest = conn->peer.st_port;
tcphdr->seq = htonl ( conn->snd_seq );
tcphdr->ack = htonl ( conn->rcv_ack );
- tcphdr->hlen = ( ( sizeof ( *tcphdr ) / 4 ) << 4 );
+ tcphdr->hlen = ( ( payload - pkb->data ) << 2 );
tcphdr->flags = flags;
tcphdr->win = htons ( TCP_WINDOW_SIZE );
tcphdr->csum = tcpip_chksum ( pkb->data, pkb_len ( pkb ) );