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