Beispiel #1
0
/**@internal Set refresh in range min..max seconds in the future. */
void nua_dialog_usage_set_refresh_range(nua_dialog_usage_t *du,
					unsigned min, unsigned max)
{
  su_duration_t max_defer = nua_dialog_usage_get_max_defer(du);
  unsigned delta;
  int make_deferrable = 0;

  if (max <= min) {
    max = min;
    delta = min * 1000;
  }
  else if (max_defer > 0 && (int)(max - min) >= max_defer / 1000) {
    delta = su_randint(min * 1000, max * 1000 - (max_defer + 999));
    make_deferrable = 1;
  }
  else
    delta = su_randint(min * 1000, max * 1000);

  SU_DEBUG_7(("nua(): refresh %s in %.3f seconds (in [%u..%u]%s)\n",
	      nua_dialog_usage_name(du), 1e-3 * delta, min, max,
	      make_deferrable? ", deferrable" : ""));

  delta += delta == 0;

  nua_dialog_usage_set_refresh_timer(du, delta, make_deferrable);
}
Beispiel #2
0
/**@internal Set refresh in range min..max seconds in the future. */
void nua_dialog_usage_set_refresh_range(nua_dialog_usage_t *du,
					unsigned min, unsigned max)
{
  sip_time_t now = sip_now(), target;
  unsigned delta;

  if (max < min)
    max = min;

  if (min != max)
    delta = su_randint(min, max);
  else
    delta = min;

  if (now + delta >= now)
    target = now + delta;
  else
    target = SIP_TIME_MAX;

  SU_DEBUG_7(("nua(): refresh %s after %lu seconds (in [%u..%u])\n",
	      nua_dialog_usage_name(du), target - now, min, max));

  du->du_refquested = now;

  du->du_refresh = target;
}
Beispiel #3
0
/** Receive datagram.
 *
 * @retval -1 error
 * @retval 0  end-of-stream
 * @retval 1  normal receive (should never happen)
 * @retval 2  incomplete recv, call me again (should never happen)
 * @retval 3  STUN keepalive, ignore
 */
int tport_recv_dgram(tport_t *self)
{
  msg_t *msg;
  ssize_t n, veclen, N;
  su_addrinfo_t *ai;
  su_sockaddr_t *from;
  socklen_t fromlen;
  msg_iovec_t iovec[msg_n_fragments] = {{ 0 }};
  uint8_t sample[1];

  /* Simulate packet loss */
  if (self->tp_params->tpp_drop &&
      (unsigned)su_randint(0, 1000) < self->tp_params->tpp_drop) {
    su_recv(self->tp_socket, sample, 1, 0);
    SU_DEBUG_3(("tport(%p): simulated packet loss!\n", (void *)self));
    return 0;
  }

  assert(self->tp_msg == NULL);

#if nomore
  /* We used to resize the buffer, but it fragments the memory */
  N = 65535;
#else
  N = (ssize_t)su_getmsgsize(self->tp_socket);
  if (N == -1) {
    int err = su_errno();
    SU_DEBUG_1(("%s(%p): su_getmsgsize(): %s (%d)\n", __func__, (void *)self,
		su_strerror(err), err));
    return -1;
  }
  if (N == 0) {
    su_recv(self->tp_socket, sample, 1, 0);
    SU_DEBUG_3(("tport(%p): zero length packet", (void *)self));
    return 0;
  }
#endif

  veclen = tport_recv_iovec(self, &self->tp_msg, iovec, N, 1);
  if (veclen == -1)
    return -1;

  msg = self->tp_msg;

  ai = msg_addrinfo(msg);
  from = (su_sockaddr_t *)ai->ai_addr, fromlen = (socklen_t)(ai->ai_addrlen);

  n = su_vrecv(self->tp_socket, iovec, veclen, 0, from, &fromlen);

  ai->ai_addrlen = fromlen;

  if (n == SOCKET_ERROR) {
    int error = su_errno();
    msg_destroy(msg); self->tp_msg = NULL;
    su_seterrno(error);

    if (su_is_blocking(error))
      return 0;
    else
      return -1;
  }
  else if (n <= 1) {
    SU_DEBUG_1(("%s(%p): runt of "MOD_ZD" bytes\n",
		"tport_recv_dgram", (void *)self, n));
    msg_destroy(msg), self->tp_msg = NULL;
    return 0;
  }

  tport_recv_bytes(self, n, n);

  SU_CANONIZE_SOCKADDR(from);

  if (self->tp_master->mr_dump_file)
    tport_dump_iovec(self, msg, n, iovec, veclen, "recv", "from");

  *sample = *((uint8_t *)iovec[0].mv_base);

  /* Commit received data into buffer. This may relocate iovec contents */
  msg_recv_commit(msg, n, 1);

  if ((sample[0] & 0xf8) == 0xf8)
    /* SigComp */
    return tport_recv_comp_dgram(self, self->tp_comp, &self->tp_msg,
				 from, fromlen);
#if HAVE_SOFIA_STUN
  else if (sample[0] == 0 || sample[0] == 1)
    /* STUN request or response */
    return tport_recv_stun_dgram(self, &self->tp_msg, from, fromlen);
#endif
  else
    return 0;
}