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