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