Пример #1
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);
  }
}
Пример #2
0
static su_duration_t
nua_dialog_usage_get_max_defer(nua_dialog_usage_t *du)
{
  nua_handle_t const *nh = (nua_handle_t *)du->du_dialog->ds_owner;
  nua_t const *nua = nh->nh_nua;

  if (nua->nua_prefs->ngp_deferrable_timers)
    return su_root_get_max_defer(nua->nua_root);
  else
    return 0;
}
Пример #3
0
/** Main function for clone thread.
 *
 * @internal
 */
static void *su_pthread_port_clone_main(void *varg)
{
  struct clone_args *arg = (struct clone_args *)varg;
  su_task_r task;
  int zap = 1;

#if SU_HAVE_WINSOCK
  su_init();
#endif

  task->sut_port = arg->create();

  if (task->sut_port) {
    task->sut_root = su_salloc(su_port_home(task->sut_port),
			       sizeof *task->sut_root);
    if (task->sut_root) {

      task->sut_root->sur_threading = 1;	/* By default */

      SU_TASK_COPY(task->sut_root->sur_parent, su_root_task(arg->parent),
		   su_pthread_port_clone_main);
      SU_TASK_COPY(task->sut_root->sur_task, task,
		   su_pthread_port_clone_main);

      if (su_msg_create(arg->clone,
			task,
			su_root_task(arg->parent),
			su_pthread_port_clone_break,
			0) == 0) {
	task->sut_root->sur_magic = arg->magic;
	task->sut_root->sur_deinit = arg->deinit;

	su_root_set_max_defer(task->sut_root, 
			      su_root_get_max_defer(arg->parent));

	if (arg->init(task->sut_root, arg->magic) == 0) {
	  su_pthread_port_return_to_parent(arg, 0), arg = NULL;

	  su_root_run(task->sut_root); /* Do the work */

	  /* Cleanup */
	  if (task->sut_port->sup_waiting_parent) {
	    struct su_pthread_port_waiting_parent *mom;

	    mom = task->sut_port->sup_waiting_parent;
	    pthread_mutex_lock(mom->mutex);
	    mom->waiting = 0;
	    pthread_cond_signal(mom->cv);
	    pthread_mutex_unlock(mom->mutex);

	    pthread_mutex_lock(mom->deinit);
	    su_port_getmsgs(task->sut_port);
	    pthread_mutex_unlock(mom->deinit);
	  }
	  else
	    zap = 0;
	}
	else
	  su_msg_destroy(arg->clone);

	su_root_destroy(task->sut_root);
      }
    }

    task->sut_port->sup_base->sup_vtable->
      su_port_decref(task->sut_port, zap,
		     "su_pthread_port_clone_main");
  }

#if SU_HAVE_WINSOCK
  su_deinit();
#endif

  if (arg)
    su_pthread_port_return_to_parent(arg, -1);

  return NULL;			/* Exit from thread */
}