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