nalika / rpms / grub2

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