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