All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrei Borzenkov <arvidjaar@gmail.com>
To: Josef Bacik <jbacik@fb.com>, grub-devel@gnu.org, kernel-team@fb.com
Subject: Re: [PATCH v3] tcp: add window scaling and RTTM support
Date: Sat, 13 Feb 2016 18:40:18 +0300	[thread overview]
Message-ID: <56BF4E62.1040508@gmail.com> (raw)
In-Reply-To: <1454351457-496174-1-git-send-email-jbacik@fb.com>

01.02.2016 21:30, Josef Bacik пишет:
...

> @@ -745,6 +817,7 @@ grub_net_recv_tcp_packet (struct grub_net_buff *nb,
>  {
>    struct tcphdr *tcph;
>    grub_net_tcp_socket_t sock;
> +  grub_uint32_t tsecr = 0;
>    grub_err_t err;
>  
>    /* Ignore broadcast.  */
> @@ -771,6 +844,38 @@ grub_net_recv_tcp_packet (struct grub_net_buff *nb,
>        return GRUB_ERR_NONE;
>      }
>  

Still no proper boundary check.

> +  /* If the packet is large enough to have the timestamp opt then lets look for
> +     the tsecr value. */
> +  if ((grub_be_to_cpu16 (tcph->flags >> 12) * sizeof (grub_uint32_t)) >=
> +      ALIGN_UP (sizeof (struct tcphdr) + sizeof (struct tcp_timestamp_opt), 4))
> +    {
> +      struct tcp_opt_hdr *opt;
> +      grub_size_t remaining = nb->tail - nb->data;
> +
> +      opt = (struct tcp_opt_hdr *)(tcph + 1);
> +      while (remaining > 0)
> +	{
> +	  grub_uint8_t len = 1;
> +	  if (opt->kind == 8 || opt->kind == 0)
> +	    break;
> +	  if (opt->kind > 1)

Here (we only can ensure opt->kind here)

> +	    len = opt->length;
> +	  if (len > remaining)
> +	    len = remaining;
> +	  remaining -= len;
> +	  opt = (struct tcp_opt_hdr *)((grub_uint8_t *)opt + len);
> +	}
> +
> +      /* Ok we definitely have the timestamp option. */
> +      if (opt->kind == 8)
> +	{
> +	  struct tcp_timestamp_opt *timestamp;
> +
> +	  timestamp = (struct tcp_timestamp_opt *)opt;
> +	  tsecr = grub_be_to_cpu32 (timestamp->tsval);

And of course here (there is no length check at all when we break out of
loop).

> +	}
> +    }
> +
>    FOR_TCP_SOCKETS (sock)
>    {
>      if (!(grub_be_to_cpu16 (tcph->dst) == sock->in_port
> @@ -805,6 +910,9 @@ grub_net_recv_tcp_packet (struct grub_net_buff *nb,
>  	sock->their_start_seq = grub_be_to_cpu32 (tcph->seqnr);
>  	sock->their_cur_seq = sock->their_start_seq + 1;
>  	sock->established = 1;
> +	sock->timestamp_supported = 0;
> +	if (tsecr)
> +	  sock->timestamp_supported = 1;
>        }
>  
>      if (grub_be_to_cpu16 (tcph->flags) & TCP_RST)
> @@ -906,6 +1014,8 @@ grub_net_recv_tcp_packet (struct grub_net_buff *nb,
>  	      return err;
>  	    }
>  
> +	  /* We only update the tsecr when we advance the window. */
> +	  sock->cur_tsecr = tsecr;

You intended to check that tsecr >= cur_tsecr.

>  	  sock->their_cur_seq += (nb_top->tail - nb_top->data);
>  	  if (grub_be_to_cpu16 (tcph->flags) & TCP_FIN)
>  	    {
> @@ -999,3 +1109,63 @@ grub_net_tcp_unstall (grub_net_tcp_socket_t sock)
>    sock->i_stall = 0;
>    ack (sock);
>  }
> +
> +static const char *
> +window_get_env (struct grub_env_var *var __attribute__ ((unused)),
> +		const char *val __attribute__ ((unused)))
> +{
> +  return grub_net_tcp_window_size;
> +}
> +

Oh, that's really redundant as is, string is stored as variable value
anyway, no need to duplicate it, just return from window_set_env.

> +static char *
> +window_set_env (struct grub_env_var *var __attribute__ ((unused)),
> +		const char *val)
> +{
> +  grub_uint32_t ret;
> +
> +  if (val == NULL)
> +    return NULL;
> +
> +  grub_error_push ();
> +  ret = (grub_uint32_t) grub_strtoul (val, 0, 0);
> +  if (grub_errno != GRUB_ERR_NONE)
> +    {
> +      grub_printf ("Invalid number for window size '%s'.\n", val);
> +      grub_errno = GRUB_ERR_NONE;
> +      grub_error_pop ();

You just lost proper error return from grub_strtoul. Just return NULL
here without any push/pop and error from strtoul will be correctly
propagated and printed when set command completes.

> +      return NULL;
> +    }
> +  grub_error_pop ();
> +
> +  /* A window size greater than 1gib is invalid. */
> +  if (ret > 1024 * 1024 * 1024)
> +    {
> +      grub_printf ("TCP window size must be <= 1gib.\n");

Please use grub_error to set grub_errno and error string;
GRUB_ERR_BAD_ARGUMENT looks suitable here.

> +      return NULL;
> +    }
> +  grub_net_tcp_window_size = grub_strdup (val);
> +  tcp_window_size = ret;
> +  tcp_window_scale = 0;
> +
> +  /* The window size is only 16 bits long, so we have to scale it down to fit in
> +     the header and calculate the scale along the way. */
> +  while (tcp_window_size > 65535)
> +    {
> +      tcp_window_size >>= 1;
> +      tcp_window_scale += 1;
> +    }
> +
> +  return grub_net_tcp_window_size;
> +}
> +
> +/* We set the default window size to 1mib. */
> +#define DEFAULT_TCP_WINDOW_SIZE "1048576"

Well ... I'm still unsure we should do it by default.

> +
> +void
> +grub_net_tcp_init (void)
> +{
> +  grub_register_variable_hook ("net_tcp_window_size", window_get_env,
> +			       window_set_env);
> +  grub_env_export ("net_tcp_window_size");
> +  grub_env_set ("net_tcp_window_size", DEFAULT_TCP_WINDOW_SIZE);
> +}
> diff --git a/include/grub/net.h b/include/grub/net.h
> index 4571b72..fa3d286 100644
> --- a/include/grub/net.h
> +++ b/include/grub/net.h
> @@ -551,6 +551,8 @@ grub_net_add_dns_server (const struct grub_net_network_level_address *s);
>  void
>  grub_net_remove_dns_server (const struct grub_net_network_level_address *s);
>  
> +void
> +grub_net_tcp_init (void);
>  
>  extern char *grub_net_default_server;
>  
> 



  reply	other threads:[~2016-02-13 15:40 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-01 18:30 [PATCH v3] tcp: add window scaling and RTTM support Josef Bacik
2016-02-13 15:40 ` Andrei Borzenkov [this message]
2016-02-18 19:20   ` Josef Bacik
2016-02-22  8:00     ` Andrei Borzenkov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=56BF4E62.1040508@gmail.com \
    --to=arvidjaar@gmail.com \
    --cc=grub-devel@gnu.org \
    --cc=jbacik@fb.com \
    --cc=kernel-team@fb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.