Example #1
0
int nghttp2_bufs_add(nghttp2_bufs *bufs, const void *data, size_t len)
{
  int rv;
  size_t nwrite;
  nghttp2_buf *buf;
  const uint8_t *p;

  if(bufs_avail(bufs) < (ssize_t)len) {
    return NGHTTP2_ERR_BUFFER_ERROR;
  }

  p = (const uint8_t *)data;

  while(len) {
    buf = &bufs->cur->buf;

    nwrite = nghttp2_min((size_t)nghttp2_buf_avail(buf), len);
    if(nwrite == 0) {
      rv = bufs_alloc_chain(bufs);
      if(rv != 0) {
        return rv;
      }
      continue;
    }

    buf->last = nghttp2_cpymem(buf->last, p, nwrite);
    p += len;
    len -= nwrite;
  }

  return 0;
}
Example #2
0
/*
 *   local_window_size
 *   ^  *
 *   |  *    recv_window_size
 *   |  *  * ^
 *   |  *  * |
 *  0+++++++++
 *   |  *  *   \
 *   |  *  *   | This rage is hidden in flow control.  But it must be
 *   v  *  *   / kept in order to restore it when window size is enlarged.
 *   recv_reduction
 *   (+ for negative direction)
 *
 *   recv_window_size could be negative if we decrease
 *   local_window_size more than recv_window_size:
 *
 *   local_window_size
 *   ^  *
 *   |  *
 *   |  *
 *   0++++++++
 *   |  *    ^ recv_window_size (negative)
 *   |  *    |
 *   v  *  *
 *   recv_reduction
 */
int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
                                     int32_t *recv_window_size_ptr,
                                     int32_t *recv_reduction_ptr,
                                     int32_t *delta_ptr) {
  if (*delta_ptr > 0) {
    int32_t recv_reduction_delta;
    int32_t delta;
    int32_t new_recv_window_size =
        nghttp2_max(0, *recv_window_size_ptr) - *delta_ptr;

    if (new_recv_window_size >= 0) {
      *recv_window_size_ptr = new_recv_window_size;
      return 0;
    }

    delta = -new_recv_window_size;

    /* The delta size is strictly more than received bytes. Increase
       local_window_size by that difference |delta|. */
    if (*local_window_size_ptr > NGHTTP2_MAX_WINDOW_SIZE - delta) {
      return NGHTTP2_ERR_FLOW_CONTROL;
    }
    *local_window_size_ptr += delta;
    /* If there is recv_reduction due to earlier window_size
       reduction, we have to adjust it too. */
    recv_reduction_delta = nghttp2_min(*recv_reduction_ptr, delta);
    *recv_reduction_ptr -= recv_reduction_delta;
    if (*recv_window_size_ptr < 0) {
      *recv_window_size_ptr += recv_reduction_delta;
    } else {
      /* If *recv_window_size_ptr > 0, then those bytes are going to
         be returned to the remote peer (by WINDOW_UPDATE with the
         adjusted *delta_ptr), so it is effectively 0 now.  We set to
         *recv_reduction_delta, because caller does not take into
         account it in *delta_ptr. */
      *recv_window_size_ptr = recv_reduction_delta;
    }
    /* recv_reduction_delta must be paied from *delta_ptr, since it
       was added in window size reduction (see below). */
    *delta_ptr -= recv_reduction_delta;

    return 0;
  }

  if (*local_window_size_ptr + *delta_ptr < 0 ||
      *recv_window_size_ptr < INT32_MIN - *delta_ptr ||
      *recv_reduction_ptr > INT32_MAX + *delta_ptr) {
    return NGHTTP2_ERR_FLOW_CONTROL;
  }
  /* Decreasing local window size. Note that we achieve this without
     noticing to the remote peer. To do this, we cut
     recv_window_size by -delta. This means that we don't send
     WINDOW_UPDATE for -delta bytes. */
  *local_window_size_ptr += *delta_ptr;
  *recv_window_size_ptr += *delta_ptr;
  *recv_reduction_ptr -= *delta_ptr;
  *delta_ptr = 0;

  return 0;
}
Example #3
0
int nghttp2_bufs_add(nghttp2_bufs *bufs, const void *data, size_t len) {
  int rv;
  size_t nwrite;
  nghttp2_buf *buf;
  const uint8_t *p;

  // h1994st:
  if (!bufs->random_enabled && bufs_avail(bufs) < len) {
    return NGHTTP2_ERR_BUFFER_ERROR;
  }

  p = data;

  while (len) {
    buf = &bufs->cur->buf;

    nwrite = nghttp2_min(nghttp2_buf_avail(buf), len);
    if (nwrite == 0) {
      rv = bufs_alloc_chain(bufs);
      if (rv != 0) {
        return rv;
      }
      continue;
    }

    buf->last = nghttp2_cpymem(buf->last, p, nwrite);
    p += nwrite;
    len -= nwrite;
  }

  return 0;
}
Example #4
0
int nghttp2_increase_local_window_size(int32_t *local_window_size_ptr,
                                       int32_t *recv_window_size_ptr,
                                       int32_t *recv_reduction_ptr,
                                       int32_t *delta_ptr) {
  int32_t recv_reduction_delta;
  int32_t delta;

  delta = *delta_ptr;

  assert(delta >= 0);

  /* The delta size is strictly more than received bytes. Increase
     local_window_size by that difference |delta|. */
  if (*local_window_size_ptr > NGHTTP2_MAX_WINDOW_SIZE - delta) {
    return NGHTTP2_ERR_FLOW_CONTROL;
  }

  *local_window_size_ptr += delta;
  /* If there is recv_reduction due to earlier window_size
     reduction, we have to adjust it too. */
  recv_reduction_delta = nghttp2_min(*recv_reduction_ptr, delta);
  *recv_reduction_ptr -= recv_reduction_delta;

  *recv_window_size_ptr += recv_reduction_delta;

  /* recv_reduction_delta must be paid from *delta_ptr, since it was
     added in window size reduction (see below). */
  *delta_ptr -= recv_reduction_delta;

  return 0;
}
Example #5
0
static ssize_t data_feed_recv_callback(nghttp2_session *session, uint8_t *data,
                                       size_t len, int flags, void *user_data) {
  data_feed *df = ((my_user_data *)user_data)->df;
  size_t avail = (size_t)(df->datalimit - df->datamark);
  size_t wlen = nghttp2_min(avail, len);
  (void)session;
  (void)flags;

  memcpy(data, df->datamark, wlen);
  df->datamark += wlen;
  return (ssize_t)wlen;
}
Example #6
0
int nghttp2_buffer_reserve(nghttp2_buffer *buffer, size_t len)
{
  if(len > buffer->max_capacity) {
    return NGHTTP2_ERR_BUFFER_ERROR;
  }
  if(buffer->capacity < len) {
    uint8_t *new_buf;
    size_t new_cap = buffer->capacity == 0 ? 8 : buffer->capacity * 3 / 2;
    new_cap = nghttp2_min(buffer->max_capacity, nghttp2_max(new_cap, len));
    new_buf = realloc(buffer->buf, new_cap);
    if(new_buf == NULL) {
      return NGHTTP2_ERR_NOMEM;
    }
    buffer->buf = new_buf;
    buffer->capacity = new_cap;
  }
  return 0;
}