예제 #1
0
파일: reliable.c 프로젝트: angelol/iOpenVPN
/* grab a free buffer, fail if buffer clogged by unacknowledged low packet IDs */
struct buffer *
reliable_get_buf_output_sequenced (struct reliable *rel)
{
  struct gc_arena gc = gc_new ();
  int i;
  packet_id_type min_id = 0;
  bool min_id_defined = false;
  struct buffer *ret = NULL;

  /* find minimum active packet_id */
  for (i = 0; i < rel->size; ++i)
    {
      const struct reliable_entry *e = &rel->array[i];
      if (e->active)
	{
	  if (!min_id_defined || e->packet_id < min_id)
	    {
	      min_id_defined = true;
	      min_id = e->packet_id;
	    }
	}
    }

  if (!min_id_defined || (int)(rel->packet_id - min_id) < rel->size)
    {
      ret = reliable_get_buf (rel);
    }
  else
    {
      dmsg (D_REL_LOW, "ACK output sequence broken: %s", reliable_print_ids (rel, &gc));
    }
  gc_free (&gc);
  return ret;
}
예제 #2
0
파일: reliable.c 프로젝트: angelol/iOpenVPN
/* if we return BIG_TIMEOUT, nothing to wait for */
interval_t
reliable_send_timeout (const struct reliable *rel)
{
  struct gc_arena gc = gc_new ();
  interval_t ret = BIG_TIMEOUT;
  int i;
  const time_t local_now = now;

  for (i = 0; i < rel->size; ++i)
    {
      const struct reliable_entry *e = &rel->array[i];
      if (e->active)
	{
	  if (e->next_try <= local_now)
	    {
	      ret = 0;
	      break;
	    }
	  else
	    {
	      ret = min_int (ret, e->next_try - local_now);
	    }
	}
    }

  dmsg (D_REL_DEBUG, "ACK reliable_send_timeout %d %s",
       (int) ret,
       reliable_print_ids (rel, &gc));

  gc_free (&gc);
  return ret;
}
예제 #3
0
파일: reliable.c 프로젝트: neuhalje/openvpn
/* return true if reliable_send would return a non-NULL result */
bool
reliable_can_send(const struct reliable *rel)
{
    struct gc_arena gc = gc_new();
    int i;
    int n_active = 0, n_current = 0;
    for (i = 0; i < rel->size; ++i)
    {
        const struct reliable_entry *e = &rel->array[i];
        if (e->active)
        {
            ++n_active;
            if (now >= e->next_try)
            {
                ++n_current;
            }
        }
    }
    dmsg(D_REL_DEBUG, "ACK reliable_can_send active=%d current=%d : %s",
         n_active,
         n_current,
         reliable_print_ids(rel, &gc));

    gc_free(&gc);
    return n_current > 0 && !rel->hold;
}
예제 #4
0
파일: reliable.c 프로젝트: angelol/iOpenVPN
/* true if at least one free buffer available */
bool
reliable_can_get (const struct reliable *rel)
{
  struct gc_arena gc = gc_new ();
  int i;
  for (i = 0; i < rel->size; ++i)
    {
      const struct reliable_entry *e = &rel->array[i];
      if (!e->active)
	return true;
    }
  dmsg (D_REL_LOW, "ACK no free receive buffer available: %s", reliable_print_ids (rel, &gc));
  gc_free (&gc);
  return false;
}
/* make sure that incoming packet ID won't deadlock the receive buffer */
bool
reliable_wont_break_sequentiality (const struct reliable *rel, packet_id_type id)
{
  struct gc_arena gc = gc_new ();

  const int ret = reliable_pid_in_range2 (id, rel->packet_id, rel->size);

  if (!ret)
    {
      dmsg (D_REL_LOW, "ACK " packet_id_format " breaks sequentiality: %s",
	   (packet_id_print_type)id, reliable_print_ids (rel, &gc));
    }

  dmsg (D_REL_DEBUG, "ACK RWBS rel->size=%d rel->packet_id=%08x id=%08x ret=%d\n", rel->size, rel->packet_id, id, ret);

  gc_free (&gc);
  return ret;
}
예제 #6
0
파일: reliable.c 프로젝트: angelol/iOpenVPN
/* make sure that incoming packet ID won't deadlock the receive buffer */
bool
reliable_wont_break_sequentiality (const struct reliable *rel, packet_id_type id)
{
  struct gc_arena gc = gc_new ();
  int ret;

  if ((int)id < (int)rel->packet_id + rel->size)
    {
      ret = true;
    }
  else
    {
      dmsg (D_REL_LOW, "ACK " packet_id_format " breaks sequentiality: %s",
	   (packet_id_print_type)id, reliable_print_ids (rel, &gc));
      ret = false;
    }
  gc_free (&gc);
  return ret;
}
예제 #7
0
파일: reliable.c 프로젝트: angelol/iOpenVPN
/* make sure that incoming packet ID isn't a replay */
bool
reliable_not_replay (const struct reliable *rel, packet_id_type id)
{
  struct gc_arena gc = gc_new ();
  int i;
  if (id < rel->packet_id)
    goto bad;
  for (i = 0; i < rel->size; ++i)
    {
      const struct reliable_entry *e = &rel->array[i];
      if (e->active && e->packet_id == id)
	goto bad;
    }
  gc_free (&gc);
  return true;

 bad:
  dmsg (D_REL_DEBUG, "ACK " packet_id_format " is a replay: %s", (packet_id_print_type)id, reliable_print_ids (rel, &gc));
  gc_free (&gc);
  return false;
}