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