Esempio n. 1
0
void nua_stack_deinit(su_root_t *root, nua_t *nua)
{
  enter;

  su_timer_destroy(nua->nua_shutdown_timer), nua->nua_shutdown_timer = NULL;
  nta_agent_destroy(nua->nua_nta), nua->nua_nta = NULL;
}
Esempio n. 2
0
	void SipDialog::cancelSessionTimer() {
		assert( NULL != m_timerSessionRefresh ) ;
		su_timer_destroy( m_timerSessionRefresh ) ;
		m_timerSessionRefresh = NULL ;
		m_refresher = no_refresher ;
		m_nSessionExpiresSecs = 0 ;
	}
Esempio n. 3
0
/** Start OPTIONS keepalive or contact validation process */
void outbound_start_keepalive(outbound_t *ob,
			      nta_outgoing_t *register_transaction)
{
  unsigned interval = 0;
  int need_to_validate, udp;

  if (!ob)
    return;

  udp = ob->ob_via && ob->ob_via->v_protocol == sip_transport_udp;

  if (/* ob->ob_prefs.natify && */
      /* On UDP, use OPTIONS keepalive by default */
      (udp ? ob->ob_prefs.okeepalive != 0
       /* Otherwise, only if requested */
       : ob->ob_prefs.okeepalive > 0))
    interval = ob->ob_prefs.interval;
  need_to_validate = ob->ob_prefs.validate && !ob->ob_validated;

  if (!register_transaction ||
      !(need_to_validate || interval != 0)) {
    outbound_stop_keepalive(ob);
    return;
  }

  if (ob->ob_keepalive.timer)
    su_timer_destroy(ob->ob_keepalive.timer), ob->ob_keepalive.timer = NULL;

  if (interval) {
    su_duration_t max_defer;

    max_defer = su_root_get_max_defer(ob->ob_root);
    if ((su_duration_t)interval >= max_defer) {
      interval -= max_defer - 100;
    }

    ob->ob_keepalive.timer =
      su_timer_create(su_root_task(ob->ob_root), interval);

    su_timer_deferrable(ob->ob_keepalive.timer, 1);
  }

  ob->ob_keepalive.interval = interval;

  if (!ob->ob_validated && ob->ob_keepalive.sipstun
      && 0 /* Stun is disabled for now */) {
    nta_tport_keepalive(register_transaction);
  }
  else {
    if (register_transaction) {
      msg_t *msg = nta_outgoing_getrequest(register_transaction);
      sip_t const *register_request = sip_object(msg);
      create_keepalive_message(ob, register_request);
      msg_destroy(msg);
    }

    keepalive_options(ob);
  }
}
void
end_test(struct tester *tester, su_timer_t *t, struct timing *ti)
{
  printf("ending test\n");
  su_timer_destroy(t);
  su_timer_reset(tester->t);
  su_timer_reset(tester->t1);
  su_root_break(tester->root);
}
Esempio n. 5
0
/** Request restarted by timer */
static void
nua_client_restart_after(su_root_magic_t *magic,
			 su_timer_t *timer,
			 nua_client_request_t *cr)
{
  cr->cr_waiting = 0;
  su_timer_destroy(cr->cr_timer), cr->cr_timer = NULL;
  nua_client_restart_request(cr, cr->cr_terminating, NULL);
  nua_client_request_unref(cr);
}
Esempio n. 6
0
/** @internal Shut down stack. */
void nua_stack_shutdown(nua_t *nua)
{
  nua_handle_t *nh, *nh_next;
  int busy = 0;
  sip_time_t now = sip_now();
  int status;
  char const *phrase;

  enter;

  if (!nua->nua_shutdown)
    nua->nua_shutdown = now;

  for (nh = nua->nua_handles; nh; nh = nh_next) {
    nua_dialog_state_t *ds = nh->nh_ds;

    nh_next = nh->nh_next;

    busy += nua_dialog_repeat_shutdown(nh, ds);

    if (nh->nh_soa) {
      soa_destroy(nh->nh_soa), nh->nh_soa = NULL;
    }

    if (nua_client_request_pending(ds->ds_cr))
      busy++;

    if (nh_notifier_shutdown(nh, NULL, NEATAG_REASON("noresource"), TAG_END()))
      busy++;
  }

  if (!busy)
    SET_STATUS(200, "Shutdown successful");
  else if (now == nua->nua_shutdown)
    SET_STATUS(100, "Shutdown started");
  else if (now - nua->nua_shutdown < 30)
    SET_STATUS(101, "Shutdown in progress");
  else
    SET_STATUS(500, "Shutdown timeout");

  if (status >= 200) {
    for (nh = nua->nua_handles; nh; nh = nh_next) {
      nh_next = nh->nh_next;
      while (nh->nh_ds && nh->nh_ds->ds_usage) {
	nua_dialog_usage_remove(nh, nh->nh_ds, nh->nh_ds->ds_usage, NULL, NULL);
      }
    }
    su_timer_destroy(nua->nua_timer), nua->nua_timer = NULL;
    nta_agent_destroy(nua->nua_nta), nua->nua_nta = NULL;
  }

  nua_stack_event(nua, NULL, NULL, nua_r_shutdown, status, phrase, NULL);
}
Esempio n. 7
0
void outbound_unref(outbound_t *ob)
{
  if (ob->ob_keepalive.timer)
    su_timer_destroy(ob->ob_keepalive.timer), ob->ob_keepalive.timer = NULL;

  if (ob->ob_keepalive.orq)
    nta_outgoing_destroy(ob->ob_keepalive.orq), ob->ob_keepalive.orq = NULL;

  if (ob->ob_keepalive.msg)
    msg_destroy(ob->ob_keepalive.msg), ob->ob_keepalive.msg = NULL;

  su_home_unref(ob->ob_home);
}
Esempio n. 8
0
void outbound_stop_keepalive(outbound_t *ob)
{
  if (!ob)
    return;

  ob->ob_keepalive.interval = 0;

  if (ob->ob_keepalive.timer)
    su_timer_destroy(ob->ob_keepalive.timer), ob->ob_keepalive.timer = NULL;

  if (ob->ob_keepalive.orq)
    nta_outgoing_destroy(ob->ob_keepalive.orq), ob->ob_keepalive.orq = NULL;

  if (ob->ob_keepalive.msg)
    msg_destroy(ob->ob_keepalive.msg), ob->ob_keepalive.msg = NULL;
}
Esempio n. 9
0
void nth_engine_destroy(nth_engine_t * he)
{
  if (he) {
    size_t i;
    hc_htable_t *hct = he->he_clients;

    for (i = 0; i < hct->hct_size; i++)
      hc_free(hct->hct_table[i]);

    tport_destroy(he->he_tports);

    su_timer_destroy(he->he_timer), he->he_timer = NULL;

    su_home_unref(he->he_home);
  }
}
Esempio n. 10
0
int
nua_client_request_remove(nua_client_request_t *cr)
{
  int retval = 0;
  int in_queue = cr->cr_prev != NULL;

  if (in_queue) {
    if ((*cr->cr_prev = cr->cr_next))
      cr->cr_next->cr_prev = cr->cr_prev;
  }
  cr->cr_prev = NULL, cr->cr_next = NULL;

  if (cr->cr_timer) {
    su_timer_destroy(cr->cr_timer), cr->cr_timer = NULL;
    retval = nua_client_request_unref(cr);
  }

  if (!in_queue)
    return retval;

  return nua_client_request_unref(cr);
}
Esempio n. 11
0
void server_destroy(server_t *srv)
{
  tport_destroy(srv->srv_tports);
  su_timer_destroy(srv->srv_timer);
  su_home_unref(srv->srv_home);
}
Esempio n. 12
0
int nua_base_client_check_restart(nua_client_request_t *cr,
				  int status,
				  char const *phrase,
				  sip_t const *sip)
{
  nua_handle_t *nh = cr->cr_owner;
  nta_outgoing_t *orq;
#if 0
  if (status == 302 || status == 305) {
    sip_route_t r[1];

    if (!can_redirect(sip->sip_contact, cr->cr_method))
      return 0;

    switch (status) {
    case 302:
      if (nua_dialog_zap(nh, nh->nh_ds) == 0 &&
	  nua_client_set_target(cr, sip->sip_contact->m_url) >= 0)
	return nua_client_restart(cr, 100, "Redirected");
      break;

    case 305:
      sip_route_init(r);
      *r->r_url = *sip->sip_contact->m_url;
      if (nua_dialog_zap(nh, nh->nh_ds) == 0 &&
	  sip_add_dup(cr->cr_msg, cr->cr_sip, (sip_header_t *)r) >= 0)
	return nua_client_restart(cr, 100, "Redirected via a proxy");
      break;

    default:
      break;
    }
  }
#endif

  if (status == 423) {
    unsigned my_expires = 0;

    if (cr->cr_sip->sip_expires)
      my_expires = cr->cr_sip->sip_expires->ex_delta;

    if (sip->sip_min_expires &&
	sip->sip_min_expires->me_delta > my_expires) {
      sip_expires_t ex[1];
      sip_expires_init(ex);
      ex->ex_delta = sip->sip_min_expires->me_delta;

      if (sip_add_dup(cr->cr_msg, NULL, (sip_header_t *)ex) < 0)
	return 0;

      return nua_client_restart(cr, 100, "Re-Negotiating Expiration");
    }
  }

  if ((status == 401 && sip->sip_www_authenticate) ||
      (status == 407 && sip->sip_proxy_authenticate)) {
    int server = 0, proxy = 0;

    if (sip->sip_www_authenticate)
      server = auc_challenge(&nh->nh_auth, nh->nh_home,
			     sip->sip_www_authenticate,
			     sip_authorization_class);

    if (sip->sip_proxy_authenticate)
      proxy = auc_challenge(&nh->nh_auth, nh->nh_home,
			    sip->sip_proxy_authenticate,
			    sip_proxy_authorization_class);

    if (server >= 0 && proxy >= 0) {
      int invalid = cr->cr_challenged && server + proxy == 0;

      cr->cr_challenged = 1;

      if (invalid) {
	/* Bad username/password */
	SU_DEBUG_7(("nua(%p): bad credentials, clearing them\n", (void *)nh));
	auc_clear_credentials(&nh->nh_auth, NULL, NULL);
      }
      else if (auc_has_authorization(&nh->nh_auth))
	return nua_client_restart(cr, 100, "Request Authorized by Cache");

      orq = cr->cr_orq, cr->cr_orq = NULL;

      cr->cr_waiting = cr->cr_wait_for_cred = 1;
      nua_client_report(cr, status, phrase, NULL, orq, NULL);
      nta_outgoing_destroy(orq);
      cr->cr_status = 0, cr->cr_phrase = NULL;
      nua_client_request_unref(cr);

      return 1;
    }
  }

  if (0 && 500 <= status && status < 600 &&
      sip->sip_retry_after &&
      sip->sip_retry_after->af_delta < 32) {
    su_timer_t *timer;
    char phrase[18];		/* Retry After XXXX\0 */

    timer = su_timer_create(su_root_task(nh->nh_nua->nua_root), 0);

    if (su_timer_set_interval(timer, nua_client_restart_after, cr,
			      sip->sip_retry_after->af_delta * 1000) < 0) {
      su_timer_destroy(timer);
      return 0; /* Too bad */
    }

    cr->cr_timer = timer;	/* This takes over cr reference from orq */

    snprintf(phrase, sizeof phrase, "Retry After %u",
	     (unsigned)sip->sip_retry_after->af_delta);

    orq = cr->cr_orq, cr->cr_orq = NULL;
    cr->cr_waiting = 1;
    nua_client_report(cr, 100, phrase, NULL, orq, NULL);
    nta_outgoing_destroy(orq);
    cr->cr_status = 0, cr->cr_phrase = NULL;

    return 1;
  }

  return 0;  /* This was a final response that cannot be restarted. */
}
/*
 * test su_timer functionality:
 *
 * Create a timer, executing print_stamp() in every 20 ms
 */
int main(int argc, char *argv[])
{
  su_root_t *root;
  su_timer_t *t, *t1, *t_end;
  su_timer_t **timers;
  su_duration_t interval = 60;
  char *argv0 = argv[0];
  char *s;
  int use_t1 = 0;
  su_time_t now, started;
  intptr_t i, N = 500;
  GSource *source;

  struct timing timing[1] = {{ 0 }};
  struct tester tester[1] = {{ 0 }};

  while (argv[1] && argv[1][0] == '-') {
    char *o = argv[1] + 1;
    while (*o) {
      if (*o == '1')
	o++, use_t1 = 1;
      else if (*o == 'r')
	o++, timing->t_run = 1;
      else if (*o == 'N') {
	if (o[1])
	  N = strtoul(o + 1, &o, 0);
	else if (argv[2])
	  N = strtoul(argv++[2], &o, 0);
	break;
      }
      else
	break;

    }
    if (*o)
      usage(argv0);
    argv++;
  }

  if (argv[1]) {
    interval = strtoul(argv[1], &s, 10);

    if (interval == 0 || s == argv[1])
      usage(argv0);
  }

  su_init(); atexit(su_deinit);

  tester->root = root = su_glib_root_create(tester);

  source = su_root_gsource(tester->root);
  g_source_attach(source, NULL /*g_main_context_default ()*/);

  su_msg_create(intr_msg,
		su_root_task(root),
		su_root_task(root),
		test_break, 0);

  signal(SIGINT, intr_handler);
#if HAVE_SIGPIPE
  signal(SIGPIPE, intr_handler);
  signal(SIGQUIT, intr_handler);
  signal(SIGHUP, intr_handler);
#endif

  t = su_timer_create(su_root_task(root), interval);
  t1 = su_timer_create(su_root_task(root), 1);
  t_end = su_timer_create(su_root_task(root), 20 * interval);

  if (t == NULL || t1 == NULL || t_end == NULL)
    su_perror("su_timer_create"), exit(1);

  tester->t = t, tester->t1 = t1;

  timing->t_prev = su_now();

  if (timing->t_run)
    su_timer_run(t, print_stamp, timing);
  else
    su_timer_set(t, print_stamp, timing);

  if (use_t1)
    su_timer_set(t1, print_X, NULL);

  su_timer_set(t_end, end_test, NULL);

  su_root_run(root);

  su_msg_destroy(intr_msg);

  su_timer_destroy(t);
  su_timer_destroy(t1);

  if (timing->t_times != 10) {
    fprintf(stderr, "%s: t expired %d times (expecting 10)\n",
	    argv0, timing->t_times);
    return 1;
  }

  /* Insert timers in order */
  timers = calloc(N, sizeof *timers);
  if (!timers) { perror("calloc"); exit(1); }

  now = started = su_now();

  for (i = 0; i < N; i++) {
    t = su_timer_create(su_root_task(root), 1000);
    if (!t) { perror("su_timer_create"); exit(1); }
    if (++now.tv_usec == 0) ++now.tv_sec;
    su_timer_set_at(t, increment, (void *)i, now);
    timers[i] = t;
  }

  tester->sentinel = (void*)(i - 1);

  su_root_run(root);

  printf("Processing %u timers took %f millisec (%f expected)\n",
	 (unsigned)i, su_time_diff(su_now(), started) * 1000, (double)i / 1000);

  for (i = 0; i < N; i++) {
    su_timer_destroy(timers[i]);
  }

  su_root_destroy(root);

  su_deinit();

  return 0;
}
Esempio n. 14
0
/**Update registered socket.
 *
 * @retval 0 if success
 * @retval -1 upon failure
 */
static int sres_sofia_update(sres_sofia_t *srs,
			     su_socket_t new_socket,
			     su_socket_t old_socket)
{
  char const *what = NULL;
  su_wait_t wait[1];
  sres_sofia_register_t *reg = NULL;
  sres_sofia_register_t *old_reg = NULL;
  int i, index = -1, error = 0;
  int N = SRES_MAX_NAMESERVERS;

  SU_DEBUG_9(("sres_sofia_update(%p, %d, %d)\n",
	      (void *)srs, (int)new_socket, (int)old_socket));

  if (srs == NULL)
    return 0;

  if (srs->srs_root == NULL)
    return -1;

  if (old_socket == new_socket) {
    if (old_socket == INVALID_SOCKET) {
      sres_resolver_set_async(srs->srs_resolver, sres_sofia_update, NULL, 0);
      /* Destroy srs */
      for (i = 0; i < N; i++) {
	if (!srs->srs_reg[i].reg_index)
	  continue;
	su_root_deregister(srs->srs_root, srs->srs_reg[i].reg_index);
	memset(&srs->srs_reg[i], 0, sizeof(srs->srs_reg[i]));
      }
      su_timer_destroy(srs->srs_timer), srs->srs_timer = NULL;
      su_free(NULL, srs);
    }
    return 0;
  }

  if (old_socket != INVALID_SOCKET)
    for (i = 0; i < N; i++)
      if ((srs->srs_reg + i)->reg_socket == old_socket) {
	old_reg = srs->srs_reg + i;
	break;
      }

  if (new_socket != INVALID_SOCKET) {
    if (old_reg == NULL) {
      for (i = 0; i < N; i++) {
	if (!(srs->srs_reg + i)->reg_ptr)
	  break;
      }
      if (i > N)
	return su_seterrno(ENOMEM);

      reg = srs->srs_reg + i;
    }
    else
      reg = old_reg;
  }

  if (reg) {
    if (su_wait_create(wait, new_socket, SU_WAIT_IN | SU_WAIT_ERR) == -1) {
      reg = NULL;
      what = "su_wait_create";
      error = su_errno();
    }

    if (reg)
      index = su_root_register(srs->srs_root, wait, sres_sofia_poll, reg, 0);

    if (index < 0) {
      reg = NULL;
      what = "su_root_register";
      error = su_errno();
      su_wait_destroy(wait);
    }
  }

  if (old_reg) {
    if (old_socket == srs->srs_socket)
      srs->srs_socket = INVALID_SOCKET;
    su_root_deregister(srs->srs_root, old_reg->reg_index);
    memset(old_reg, 0, sizeof *old_reg);
  }

  if (reg) {
    srs->srs_socket = new_socket;

    reg->reg_ptr = srs;
    reg->reg_socket = new_socket;
    reg->reg_index = index;
  }

  if (!what)
    return 0;		/* success */

  SU_DEBUG_3(("sres: %s: %s\n", what, su_strerror(error)));

  return su_seterrno(error);
}
Esempio n. 15
0
/** @internal Remove dialog usage.
 *
 * Zap dialog state (leg, tag and route) if no usages remain.
*/
static void
nua_dialog_usage_remove_at(nua_owner_t *own,
			   nua_dialog_state_t *ds,
			   nua_dialog_usage_t **at,
			   nua_client_request_t *cr0,
			   nua_server_request_t *sr0)
{
  if (*at) {
    nua_dialog_usage_t *du = *at;
    sip_event_t const *o = NULL;
    nua_client_request_t *cr, *cr_next;
    nua_server_request_t *sr, *sr_next;

    *at = du->du_next;

    o = du->du_event;

    SU_DEBUG_5(("nua(%p): removing %s usage%s%s\n",
		(void *)own, nua_dialog_usage_name(du),
		o ? " with event " : "", o ? o->o_type :""));
    du->du_class->usage_remove(own, ds, du, cr0, sr0);

    /* Clean reference to saved client request */
    if (du->du_cr)
      nua_client_bind(du->du_cr, NULL);

    /* Clean references from queued client requests */
    for (cr = ds->ds_cr; cr; cr = cr_next) {
      cr_next = cr->cr_next;
      if (cr->cr_usage == du)
	cr->cr_usage = NULL;
    }

    /* Clean references from queued server requests */
    for (sr = ds->ds_sr; sr; sr = sr_next) {
      sr_next = sr->sr_next;
      if (sr->sr_usage == du) {
	sr->sr_usage = NULL;
	if (sr != sr0)
	  nua_server_request_destroy(sr);
      }
    }

    if (du->du_refresh_timer)
      su_timer_destroy(du->du_refresh_timer);

    su_home_unref(own);
    su_free(own, du);
  }

  /* Zap dialog if there are no more usages */
  if (ds->ds_terminating)
    ;
  else if (ds->ds_usage == NULL) {
    nua_dialog_remove(own, ds, NULL);
    ds->ds_has_events = 0;
    return;
  }
  else {
    nua_dialog_log_usage(own, ds);
  }
}