Advertise a larger MSS to improve TCP performance.
authorMichael Brown <mcb30@etherboot.org>
Sat, 13 Jan 2007 17:36:17 +0000 (17:36 +0000)
committerMichael Brown <mcb30@etherboot.org>
Sat, 13 Jan 2007 17:36:17 +0000 (17:36 +0000)
src/include/gpxe/tcp.h
src/net/tcp.c

index f9cd413..c8988cf 100644 (file)
@@ -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
  *
index f50c776..6496239 100644 (file)
@@ -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 ) );