15a2072
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
15a2072
From: Josef Bacik <jbacik@fb.com>
15a2072
Date: Wed, 12 Aug 2015 08:57:55 -0700
15a2072
Subject: [PATCH] tcp: add window scaling support
15a2072
15a2072
Sometimes we have to provision boxes across regions, such as California to
15a2072
Sweden.  The http server has a 10 minute timeout, so if we can't get our 250mb
15a2072
image transferred fast enough our provisioning fails, which is not ideal.  So
15a2072
add tcp window scaling on open connections and set the window size to 1mb.  With
15a2072
this change we're able to get higher sustained transfers between regions and can
15a2072
transfer our image in well below 10 minutes.  Without this patch we'd time out
15a2072
every time halfway through the transfer.  Thanks,
15a2072
15a2072
Signed-off-by: Josef Bacik <jbacik@fb.com>
15a2072
---
15a2072
 grub-core/net/tcp.c | 42 +++++++++++++++++++++++++++++-------------
15a2072
 1 file changed, 29 insertions(+), 13 deletions(-)
15a2072
15a2072
diff --git a/grub-core/net/tcp.c b/grub-core/net/tcp.c
15a2072
index e8ad34b84d4..7d4b822626d 100644
15a2072
--- a/grub-core/net/tcp.c
15a2072
+++ b/grub-core/net/tcp.c
15a2072
@@ -106,6 +106,18 @@ struct tcphdr
15a2072
   grub_uint16_t urgent;
15a2072
 } GRUB_PACKED;
15a2072
 
15a2072
+struct tcp_scale_opt {
15a2072
+  grub_uint8_t kind;
15a2072
+  grub_uint8_t length;
15a2072
+  grub_uint8_t scale;
15a2072
+} GRUB_PACKED;
15a2072
+
15a2072
+struct tcp_synhdr {
15a2072
+  struct tcphdr tcphdr;
15a2072
+  struct tcp_scale_opt scale_opt;
15a2072
+  grub_uint8_t padding;
15a2072
+};
15a2072
+
15a2072
 struct tcp_pseudohdr
15a2072
 {
15a2072
   grub_uint32_t src;
15a2072
@@ -566,7 +578,7 @@ grub_net_tcp_open (char *server,
15a2072
   grub_net_tcp_socket_t socket;
15a2072
   static grub_uint16_t in_port = 21550;
15a2072
   struct grub_net_buff *nb;
15a2072
-  struct tcphdr *tcph;
15a2072
+  struct tcp_synhdr *tcph;
15a2072
   int i;
15a2072
   grub_uint8_t *nbd;
15a2072
   grub_net_link_level_address_t ll_target_addr;
15a2072
@@ -635,20 +647,24 @@ grub_net_tcp_open (char *server,
15a2072
     }
15a2072
 
15a2072
   tcph = (void *) nb->data;
15a2072
+  grub_memset(tcph, 0, sizeof (*tcph));
15a2072
   socket->my_start_seq = grub_get_time_ms ();
15a2072
   socket->my_cur_seq = socket->my_start_seq + 1;
15a2072
-  socket->my_window = 8192;
15a2072
-  tcph->seqnr = grub_cpu_to_be32 (socket->my_start_seq);
15a2072
-  tcph->ack = grub_cpu_to_be32_compile_time (0);
15a2072
-  tcph->flags = grub_cpu_to_be16_compile_time ((5 << 12) | TCP_SYN);
15a2072
-  tcph->window = grub_cpu_to_be16 (socket->my_window);
15a2072
-  tcph->urgent = 0;
15a2072
-  tcph->src = grub_cpu_to_be16 (socket->in_port);
15a2072
-  tcph->dst = grub_cpu_to_be16 (socket->out_port);
15a2072
-  tcph->checksum = 0;
15a2072
-  tcph->checksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_TCP,
15a2072
-						   &socket->inf->address,
15a2072
-						   &socket->out_nla);
15a2072
+  socket->my_window = 32768;
15a2072
+  tcph->tcphdr.seqnr = grub_cpu_to_be32 (socket->my_start_seq);
15a2072
+  tcph->tcphdr.ack = grub_cpu_to_be32_compile_time (0);
15a2072
+  tcph->tcphdr.flags = grub_cpu_to_be16_compile_time ((6 << 12) | TCP_SYN);
15a2072
+  tcph->tcphdr.window = grub_cpu_to_be16 (socket->my_window);
15a2072
+  tcph->tcphdr.urgent = 0;
15a2072
+  tcph->tcphdr.src = grub_cpu_to_be16 (socket->in_port);
15a2072
+  tcph->tcphdr.dst = grub_cpu_to_be16 (socket->out_port);
15a2072
+  tcph->tcphdr.checksum = 0;
15a2072
+  tcph->scale_opt.kind = 3;
15a2072
+  tcph->scale_opt.length = 3;
15a2072
+  tcph->scale_opt.scale = 5;
15a2072
+  tcph->tcphdr.checksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_TCP,
15a2072
+							  &socket->inf->address,
15a2072
+							  &socket->out_nla);
15a2072
 
15a2072
   tcp_socket_register (socket);
15a2072