Exemple #1
0
/**
 * Create a message.
 *
 * @relatesalso msg_s
 *
 * @param mc    message class
 * @param flags message control flags
 */
msg_t *msg_create(msg_mclass_t const *mc, int flags)
{
  msg_t *msg = su_home_new(sizeof(*msg) + mc->mc_msize);

  if (msg) {
    if ((flags & MSG_FLG_THRDSAFE) &&
	su_home_threadsafe(msg->m_home) < 0) {
      su_home_unref(msg->m_home);
      return NULL;
    }

    msg->m_refs++;
    msg->m_tail = &msg->m_chain;
    msg->m_addrinfo.ai_addrlen = sizeof(msg->m_addr);
    msg->m_addrinfo.ai_addr = &msg->m_addr->su_sa;
    msg->m_maxsize = 0;

    flags &= MSG_FLG_USERMASK;

    msg->m_class = mc;
    msg->m_oflags = flags;
    msg->m_object = (void *)(msg + 1);
    msg->m_object->msg_size = mc->mc_msize;
    msg->m_object->msg_flags = mc->mc_flags | flags;
    msg->m_object->msg_common->h_class = (void *)mc;
  }

  return msg;
}
nth_engine_t *nth_engine_create(su_root_t *root,
				tag_type_t tag, tag_value_t value, ...)
{
  nth_engine_t *he;
  ta_list ta;

  if ((he = su_home_new(sizeof(*he)))) {
    he->he_root = root;
    he->he_mflags = MSG_DO_CANONIC;
    he->he_mclass = http_default_mclass();
    he->he_expires = 32000;

    ta_start(ta, tag, value);

    if (hc_htable_resize(he->he_home, he->he_clients, 0) < 0 ||
	he_create_tports(he, ta_args(ta)) < 0 ||
	he_timer_init(he) < 0 || nth_engine_set_params(he, ta_tags(ta)) < 0) {
      nth_engine_destroy(he), he = NULL;
    }

    ta_end(ta);
  }

  return he;
}
static apt_bool_t mrcp_unirtsp_session_create(rtsp_server_t *rtsp_server, rtsp_server_session_t *rtsp_session)
{
	mrcp_unirtsp_agent_t *agent = rtsp_server_object_get(rtsp_server);
	const apt_str_t *session_id;
	mrcp_unirtsp_session_t *session;
	mrcp_session_t* mrcp_session = agent->sig_agent->create_server_session(agent->sig_agent);
	if(!mrcp_session) {
		return FALSE;
	}
	session_id = rtsp_server_session_id_get(rtsp_session);
	if(session_id) {
		mrcp_session->id = *session_id;
	}
	mrcp_session->response_vtable = &session_response_vtable;
	mrcp_session->event_vtable = NULL;

	session = apr_palloc(mrcp_session->pool,sizeof(mrcp_unirtsp_session_t));
	session->mrcp_session = mrcp_session;
	mrcp_session->obj = session;
	
	session->home = su_home_new(sizeof(*session->home));

	rtsp_server_session_object_set(rtsp_session,session);
	session->rtsp_session = rtsp_session;
	return TRUE;
}
static apt_bool_t mrcp_unirtsp_session_create(mrcp_session_t *mrcp_session, const mrcp_sig_settings_t *settings)
{
	mrcp_unirtsp_agent_t *agent = mrcp_session->signaling_agent->obj;
	mrcp_unirtsp_session_t *session;
	mrcp_session->request_vtable = &session_request_vtable;

	session = apr_palloc(mrcp_session->pool,sizeof(mrcp_unirtsp_session_t));
	session->home = su_home_new(sizeof(*session->home));
	session->rtsp_settings = settings;
	session->mrcp_message = NULL;
	session->mrcp_session = mrcp_session;
	mrcp_session->obj = session;
	
	session->rtsp_session = rtsp_client_session_create(
									agent->rtsp_client,
									session->rtsp_settings->server_ip,
									session->rtsp_settings->server_port,
									session->rtsp_settings->resource_location);
	if(!session->rtsp_session) {
		su_home_unref(session->home);
		return FALSE;
	}
	rtsp_client_session_object_set(session->rtsp_session,session);
	return TRUE;
}
Exemple #5
0
/* SDP Initialization */
int janus_sdp_init() {
	home = su_home_new(sizeof(su_home_t));
	if(su_home_init(home) < 0) {
		JANUS_PRINT("Ops, error setting up sofia-sdp?\n");
		return -1;
	}
	return 0;
}
Exemple #6
0
/* SDP Initialization */
int janus_sdp_init(void) {
	home = su_home_new(sizeof(su_home_t));
	if(su_home_init(home) < 0) {
		JANUS_LOG(LOG_FATAL, "Ops, error setting up sofia-sdp?\n");
		return -1;
	}
	return 0;
}
Exemple #7
0
static void
ssc_media_init (SscMedia *object)
{
  SscMedia *self = SSC_MEDIA (object);

  self->sm_home = su_home_new(sizeof (*self->sm_home));

  g_debug("%s:%d", __func__, __LINE__);
}
static void etsi_setup(void)
{
  nua = s2_nua_setup("ETSI",
                     NUTAG_OUTBOUND("no-options-keepalive, no-validate"),
		     TAG_END());

  soa = soa_create(NULL, s2base->root, NULL);

  fail_if(!soa);

  soa_set_params(soa,
		 SOATAG_USER_SDP_STR("m=audio 5008 RTP/AVP 8 0" CRLF
				     "m=video 5010 RTP/AVP 34" CRLF),
		 TAG_END());

  d1 = su_home_new(sizeof *d1); fail_if(!d1);
  d2 = su_home_new(sizeof *d2); fail_if(!d2);
}
Exemple #9
0
static
tls_t *tls_create(int type)
{
  tls_t *tls = su_home_new(sizeof(*tls));

  if (tls)
    tls->type = type == tls_master ? tls_master : tls_slave;

  return tls;
}
/**Allocate an authentication module instance.
 *
 * The function auth_mod_alloc() allocates an authentication module object.
 *
 */
auth_mod_t *auth_mod_alloc(auth_scheme_t *scheme,
                           tag_type_t tag, tag_value_t value, ...)
{
    auth_mod_t *am = NULL;

    if ((am = su_home_new(scheme->asch_size))) {
        am->am_scheme = scheme;
        su_home_destructor(am->am_home, auth_call_scheme_destructor);
    }

    return am;
}
void s2_dialog_setup(void)
{
    nua = s2_nua_setup("simple",
                       SIPTAG_ORGANIZATION_STR("Pussy Galore's Flying Circus"),
                       NUTAG_OUTBOUND("no-options-keepalive, no-validate"),
                       TAG_END());

    dialog = su_home_new(sizeof *dialog);
    fail_if(!dialog);

    s2_register_setup();
}
Exemple #12
0
/** Create a resolver cache object.
 *
 * @param n initial size of cache
 */
sres_cache_t *sres_cache_new(int n)
{
  sres_cache_t *cache = su_home_new(sizeof *cache);

  if (cache) {
    su_home_threadsafe(cache->cache_home);
    if (sres_htable_resize(cache->cache_home, cache->cache_hash, n) < 0 ||
	sres_heap_resize(cache->cache_home, &cache->cache_heap, 0) < 0)
      su_home_unref(cache->cache_home), cache = NULL;
  }

  return cache;
}
/** Create a port using epoll() or poll().
 */
su_port_t *su_poll_port_create(void)
{
  su_port_t *self = su_home_new(sizeof *self);

  if (!self)
    return self;

  if (su_home_destructor(su_port_home(self), su_poll_port_deinit) < 0)
    return su_home_unref(su_port_home(self)), NULL;

  self->sup_multishot = SU_ENABLE_MULTISHOT_POLL;

  if (su_socket_port_init(self->sup_base, su_poll_port_vtable) < 0)
    return su_home_unref(su_port_home(self)), NULL;

  return self;
}
static apt_bool_t mrcp_sofia_session_create(mrcp_session_t *session, mrcp_sig_settings_t *settings)
{
	mrcp_sofia_agent_t *sofia_agent = mrcp_sofia_agent_get(session);
	mrcp_sofia_session_t *sofia_session;
	session->request_vtable = &session_request_vtable;

	if(!sofia_agent->nua) {
		return FALSE;
	}

	sofia_session = apr_palloc(session->pool,sizeof(mrcp_sofia_session_t));
	sofia_session->mutex = NULL;
	sofia_session->home = su_home_new(sizeof(*sofia_session->home));
	sofia_session->session = session;
	sofia_session->sip_settings = settings;
	sofia_session->terminate_requested = FALSE;
	sofia_session->descriptor = NULL;
	session->obj = sofia_session;

	if(settings->user_name && settings->user_name != '\0') {
		sofia_session->sip_to_str = apr_psprintf(session->pool,"sip:%s@%s:%hu",
										settings->user_name,
										settings->server_ip,
										settings->server_port);
	}
	else {
		sofia_session->sip_to_str = apr_psprintf(session->pool,"sip:%s:%hu",
										settings->server_ip,
										settings->server_port);
	}

	sofia_session->nh = nua_handle(
				sofia_agent->nua,
				sofia_session,
				SIPTAG_TO_STR(sofia_session->sip_to_str),
				SIPTAG_FROM_STR(sofia_agent->sip_from_str),
				SIPTAG_CONTACT_STR(sofia_agent->sip_contact_str),
				TAG_IF(settings->feature_tags,SIPTAG_ACCEPT_CONTACT_STR(settings->feature_tags)),
				TAG_END());
	sofia_session->nua_state = nua_callstate_init;

	apr_thread_mutex_create(&sofia_session->mutex,APR_THREAD_MUTEX_DEFAULT,session->pool);
	return TRUE;
}
END_TEST

START_TEST(subscribe_6_1_4)
{
    nua_handle_t *nh;
    struct message *response;
    struct event *notify, *event;

    S2_CASE("6.1.4", "Subscription terminated by notifier, re-established",
            "NUA sends SUBSCRIBE, waits for NOTIFY, "
            "gets NOTIFY terminating the subscription,");

    nh = nua_handle(nua, NULL, SIPTAG_TO(s2sip->aor), TAG_END());
    nua_subscribe(nh, SIPTAG_EVENT_STR(event_type), TAG_END());
    notify = subscription_by_nua(nh, nua_substate_embryonic, TAG_END());
    s2_free_event(notify);

    fail_if(s2_sip_request_to(dialog, SIP_METHOD_NOTIFY, NULL,
                              SIPTAG_EVENT_STR(event_type),
                              SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=deactivated"),
                              TAG_END()));
    event = s2_wait_for_event(nua_i_notify, 200);
    fail_if(!event);
    fail_unless(s2_check_substate(event, nua_substate_embryonic));
    s2_free_event(event);
    response = s2_sip_wait_for_response(200, SIP_METHOD_NOTIFY);
    fail_if(!response);
    s2_sip_free_message(response);

    su_home_unref((void *)dialog), dialog = su_home_new(sizeof *dialog);
    fail_if(!dialog);

    s2_nua_fast_forward(5, s2base->root);
    /* nua re-establishes the subscription */
    notify = subscription_by_nua(nh, nua_substate_embryonic, TAG_END());
    s2_free_event(notify);

    /* Unsubscribe with nua_subscribe() Expires: 0 */
    nua_subscribe(nh, SIPTAG_EVENT_STR(event_type), SIPTAG_EXPIRES_STR("0"), TAG_END());
    notify = subscription_by_nua(nh, nua_substate_active, TAG_END());
    s2_free_event(notify);

    nua_handle_destroy(nh);
}
nua_t *s2_nua_setup(char const *label,
		    tag_type_t tag, tag_value_t value, ...)
{
  ta_list ta;

  s2_setup(label);

  s2 = su_home_new(sizeof *s2);

  s2_dns_setup(s2base->root);

  s2_setup_logs(0);
  s2_sip_setup("example.org", NULL, TAG_END());
  assert(s2sip->contact);

  s2_dns_domain("example.org", 1,
		"s2", 1, s2sip->udp.contact->m_url,
		"s2", 1, s2sip->tcp.contact->m_url,
		NULL);

  /* enable/disable multithreading */
  su_root_threading(s2base->root, s2_nua_thread);

  ta_start(ta, tag, value);
  s2->nua =
    nua_create(s2base->root,
	       s2_nua_callback,
	       s2,
	       SIPTAG_FROM_STR("Alice <sip:[email protected]>"),
	       /* NUTAG_PROXY((url_string_t *)s2sip->contact->m_url), */
	       /* Use internal DNS server */
	       NUTAG_PROXY("sip:example.org"),
	       /* Force sresolv to use localhost and s2dns as DNS server */
#if HAVE_WIN32
	       SRESTAG_RESOLV_CONF("NUL"),
#else
	       SRESTAG_RESOLV_CONF("/dev/null"),
#endif
	       ta_tags(ta));
  ta_end(ta);

  return s2->nua;
}
static mrcp_sofia_session_t* mrcp_sofia_session_create(mrcp_sofia_agent_t *sofia_agent, nua_handle_t *nh)
{
	mrcp_sofia_session_t *sofia_session;
	mrcp_session_t* session = sofia_agent->sig_agent->create_server_session(sofia_agent->sig_agent);
	if(!session) {
		return NULL;
	}
	session->response_vtable = &session_response_vtable;
	session->event_vtable = NULL;

	sofia_session = apr_palloc(session->pool,sizeof(mrcp_sofia_session_t));
	sofia_session->home = su_home_new(sizeof(*sofia_session->home));
	sofia_session->session = session;
	session->obj = sofia_session;
	
	nua_handle_bind(nh, sofia_session);
	sofia_session->nh = nh;
	return sofia_session;
}
static apt_bool_t mrcp_sofia_session_create(mrcp_session_t *session)
{
	mrcp_sofia_agent_t *sofia_agent = session->signaling_agent->obj;
	mrcp_sofia_session_t *sofia_session;
	session->request_vtable = &session_request_vtable;

	sofia_session = apr_palloc(session->pool,sizeof(mrcp_sofia_session_t));
	sofia_session->home = su_home_new(sizeof(*sofia_session->home));
	sofia_session->session = session;
	sofia_session->terminate_requested = FALSE;
	session->obj = sofia_session;
	
	sofia_session->nh = nua_handle(
				sofia_agent->nua,
				sofia_session,
				SIPTAG_TO_STR(sofia_agent->sip_to_str),
				SIPTAG_FROM_STR(sofia_agent->sip_from_str),
				SIPTAG_CONTACT_STR(sofia_agent->sip_contact_str),
				TAG_END());
	return TRUE;
}
static void invite_setup(void)
{
    dialog = su_home_new(sizeof *dialog);

    fail_unless(dialog != NULL);

    s2_nta_setup("NTA", NULL, TAG_END());

    fail_unless(s2sip->udp.contact != NULL);

    s2_nta_agent_setup(URL_STRING_MAKE("sip:0.0.0.0:*"), NULL, NULL,
                       NTATAG_UA(1),
                       TAG_END());

    leg = nta_leg_tcreate(s2->nta, NULL, NULL,
                          SIPTAG_FROM_STR("<sip:[email protected]>"),
                          SIPTAG_TO_STR("<sip:test2.3.1.example.org>"),
                          TAG_END());

    fail_unless(leg != NULL);
}
/** Create a port using /dev/poll or poll().
 */
su_port_t *su_devpoll_port_create(void)
{
  su_port_t *self;
  int devpoll = open("/dev/poll", O_RDWR);

  if (devpoll == -1) {
    /* Fallback to poll() */
    SU_DEBUG_3(("%s(): open(\"%s\") => %u: %s\n",
		"su_devpoll_port_create", "/dev/poll",
		errno, strerror(errno)));
    return su_poll_port_create();
  }

  self = su_home_new(sizeof *self);
  if (!self) {
    close(devpoll);
    return self;
  }

  if (su_home_destructor(su_port_home(self), su_devpoll_port_deinit) < 0 ||
      !(self->sup_indices =
	su_zalloc(su_port_home(self),
		  (sizeof self->sup_indices[0]) *
		  (self->sup_size_indices = 64)))) {
    su_home_unref(su_port_home(self));
    close(devpoll);
    return NULL;
  }

  self->sup_devpoll = devpoll;
  self->sup_multishot = SU_ENABLE_MULTISHOT_POLL;

  if (su_socket_port_init(self->sup_base, su_devpoll_port_vtable) < 0)
    return su_home_unref(su_port_home(self)), NULL;

  SU_DEBUG_9(("%s(%p): devpoll_create() => %u: %s\n",
	      "su_port_create", (void *)self, self->sup_devpoll, "OK"));

  return self;
}
Exemple #21
0
/**Clone a su_home_t object.
 *
 * Clone a secondary home object used to collect multiple memoryf
 * allocations under one handle. The memory is freed either when the cloned
 * home is destroyed or when the parent home is destroyed.
 *
 * An independent
 * home object is created if NULL is passed as @a parent argument.
 *
 * @param parent  a parent object (may be NULL)
 * @param size    size of home object
 *
 * The memory home object allocated with su_home_clone() can be freed with
 * su_home_unref().
 *
 * @return
 * This function returns a pointer to an su_home_t object, or NULL upon
 * an error.
 */
void *su_home_clone(su_home_t *parent, isize_t size)
{
  su_home_t *home;

  assert(size >= sizeof (*home));

  if (size < sizeof (*home))
    return (void)(errno = EINVAL), NULL;
  else if (size > INT_MAX)
    return (void)(errno = ENOMEM), NULL;

  if (parent) {
    su_block_t *sub = MEMLOCK(parent);
    home = sub_alloc(parent, sub, size, (enum sub_zero)2);
    UNLOCK(parent);
  }
  else {
    home = su_home_new(size);
  }

  return home;
}
Exemple #22
0
/**
 * Create an su_home_t object.
 *
 * Creates a home object. A home object is used to collect multiple memory
 * allocations, so that they all can be freed by calling su_home_unref().
 *
 * @return This function returns a pointer to an #su_home_t object, or
 * NULL upon an error.
 */
su_home_t *su_home_create(void)
{
  return su_home_new(sizeof(su_home_t));
}
server_t *server_create(url_t const *url,
			tag_type_t tag, tag_value_t value, ...)
{
  server_t *srv;
  msg_mclass_t const *mclass = NULL;
  tp_name_t tpn[1] = {{ NULL }};
  su_root_t *root = NULL;
  http_server_t const *server = NULL;
  int persistent = 0;
  char const *server_str = SERVER_VERSION;
  ta_list ta;

  ta_start(ta, tag, value);
  tl_gets(ta_args(ta),
	  NTHTAG_ROOT_REF(root),
	  NTHTAG_MCLASS_REF(mclass),
	  TPTAG_REUSE_REF(persistent),
	  HTTPTAG_SERVER_REF(server),
	  HTTPTAG_SERVER_STR_REF(server_str),
	  TAG_END());

  if (!root || !url ||
      (url->url_type != url_http && url->url_type != url_https)
      || !(srv = su_home_new(sizeof(*srv)))) {
    ta_end(ta);
    return NULL;
  }

  tpn->tpn_proto = url_tport_default((enum url_type_e)url->url_type);
  tpn->tpn_canon = url->url_host;
  tpn->tpn_host =  url->url_host;
  tpn->tpn_port = url_port(url);

  srv->srv_tports = tport_tcreate(srv, nth_server_class, root,
				  TPTAG_IDLE(600000),
				  TPTAG_TIMEOUT(300000),
				  ta_tags(ta));

  srv->srv_persistent = persistent;
  srv->srv_max_bodylen = 1 << 30; /* 1 GB */

  if (tport_tbind(srv->srv_tports, tpn, http_tports,
		  TAG_END()) >= 0 ||
      tport_tbind(srv->srv_tports, tpn, http_no_tls_tports,
		  TAG_END()) >= 0) {
    srv->srv_root = root;
    srv->srv_mclass = mclass ? mclass : http_default_mclass();
    srv->srv_mflags = MSG_DO_CANONIC;

    if (server)
      srv->srv_server = http_server_dup(srv->srv_home, server);
    else
      srv->srv_server = http_server_make(srv->srv_home, server_str);

    tport_get_params(srv->srv_tports,
		     TPTAG_QUEUESIZE_REF(srv->srv_queuesize),
		     TAG_END());
  }
  else {
    SU_DEBUG_1(("nth_server_create: cannot bind transports "
		URL_FORMAT_STRING "\n",
		URL_PRINT_ARGS(url)));
    server_destroy(srv), srv = NULL;
  }

  ta_end(ta);

  return srv;
}
Exemple #24
0
switch_status_t sip_dig_function(_In_opt_z_ const char *cmd, _In_opt_ switch_core_session_t *session, _In_ switch_stream_handle_t *stream)

{
	int exitcode = 0;
	int o_sctp = 1, o_tls_sctp = 1, o_verbatim = 1;
	int family = 0, multiple = 0;
	char const *dnsserver = NULL;
	char const *string;
	url_t *uri = NULL;

	char const *host;
	char const *port;
	char *transport = NULL, tport[32];
	int argc;
	char *argv_[25] = { 0 };
	char *mycmd = NULL;
	char **argv;
	struct dig dig[1] = {{ NULL }};
	su_home_t *home = NULL;
	int xml = 0;

	home = su_home_new(sizeof(*home));

	argv = argv_;
	argv++;

	if (!cmd) {
		{usage(1);}
	}

	mycmd = strdup(cmd);

	argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv_) / sizeof(argv_[0])) - 1);
	argv = argv_;


	if (!argv[1]) {
		{usage(1);}
	}
	
	if (!strcasecmp(argv[1], "xml")) {
		switch_event_add_header_string(stream->param_event, SWITCH_STACK_BOTTOM, "xml", "true");
		argv++;
		xml++;
	}

	argv[0] = "sofia_dig";


	//if (su_init() != 0)
	//return -1;

	while (argv[1] && argv[1][0] == '-') {
		if (strcmp(argv[1], "-v") == 0)
			o_verbatim++;
		else if (strcmp(argv[1], "-6") == 0)
			dig->ip6 = ++family;
		else if (strcmp(argv[1], "-4") == 0)
			dig->ip4 = ++family;
		else if (strncmp(argv[1], "-p", 2) == 0) {
			char const *proto;

			if (argv[1][2] == '=')
				proto = argv[1] + 3;
			else if (argv[1][2])
				proto = argv[1] + 2;
			else
				proto = argv++[2];

			if (proto == NULL)
				{usage(2);}

			if (prepare_transport(dig, proto) < 0) {
				goto fail;
			}
		}
		else if (strcmp(argv[1], "--udp") == 0)
			prepare_transport(dig, "udp");
		else if (strcmp(argv[1], "--tcp") == 0)
			prepare_transport(dig, "tcp");
		else if (strcmp(argv[1], "--tls") == 0)
			prepare_transport(dig, "tls");
		else if (strcmp(argv[1], "--sctp") == 0)
			prepare_transport(dig, "sctp");
		else if (strcmp(argv[1], "--tls-sctp") == 0)
			prepare_transport(dig, "tls-sctp");
		else if (strcmp(argv[1], "--tls-udp") == 0)
			prepare_transport(dig, "tls-udp");
		else if (strcmp(argv[1], "--no-sctp") == 0)
			o_sctp = 0, o_tls_sctp = 0;
		else if (strcmp(argv[1], "--help") == 0)
			{usage(0);}
		else if (strcmp(argv[1], "-h") == 0)
			{usage(0);}
		else if (strcmp(argv[1], "-?") == 0)
			{usage(0);}
		else if (strcmp(argv++[1], "-") == 0)
			break;
		else
			{usage(2);}
		argv++;
	}


	if (xml) {
		stream->write_function(stream, "%s", "<routes>\n");
	} else {
		stream->write_function(stream, "%10s\t%10s\t%10s\t%10s\t%10s\n", "Preference", "Weight", "Transport", "Port", "Address");
		stream->write_function(stream, "================================================================================\n");
	}

	if (!family)
		dig->ip4 = 1, dig->ip6 = 2;

	if (argv[1] && argv[1][0] == '@')
		dnsserver = argv++[1] + 1;



	if (!argv[1])
		{usage(2);}


	multiple = argv[1] && argv[2];

	if (!count_transports(dig, NULL, NULL)) {
		prepare_transport(dig, "udp");
		prepare_transport(dig, "tcp");
		if (o_sctp)
			prepare_transport(dig, "sctp");
		prepare_transport(dig, "tls");
		if (o_tls_sctp)
			prepare_transport(dig, "tls-sctp");
	}

	dig->sres = sres_resolver_new(getenv("SRESOLV_CONF"));
	if (!dig->sres)
		{usage(1);}
	
	for (; (string = argv[1]); argv++) {
		if (multiple)
			stream->write_function(stream, "%s", string);

		uri = url_hdup(home, (void *)string);

		if (uri && uri->url_type == url_unknown)
			url_sanitize(uri);

		if (uri && uri->url_type == url_any)
			continue;

		if (!uri || (uri->url_type != url_sip && uri->url_type != url_sips)) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: invalid uri\n", string);
			exitcode = 1;
			continue;
		}

		port = url_port(uri);
		if (port && !port[0]) port = NULL;
		if (url_param(uri->url_params, "transport=", tport, sizeof tport) > 0)
			transport = tport;

		host = uri->url_host;

		if (host_is_ip_address(host)) {
			if (transport) {
				print_result(host, port, transport, 1.0, 1, stream);
			}
			else if (uri->url_type == url_sips) {
				print_result(host, port, "tls", 1.0, 1, stream);
			}
			else {
				print_result(host, port, "udp", 1.0, 1, stream);
				print_result(host, port, "tcp", 1.0, 2, stream);
			}
			continue;
		}

		if (!host_is_domain(host)) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s: invalid host\n", string);
			exitcode = 1;
			continue;
		}

		dig->sips = uri->url_type == url_sips;
		dig->preference = 1;

		if (!port && !transport && dig_naptr(dig, host, 1.0, stream))
			continue /* resolved naptr */;
		else if (!port && dig_all_srvs(dig, transport, host, 1.0, stream))
			continue /* resolved srv */;
		else if (dig_addr(dig, transport, host, port, 1.0, stream))
			continue /* resolved a/aaaa */;

		stream->write_function(stream, "-ERR: %s: not found\n", string);
		exitcode = 1;
	}

	if (xml) {
		stream->write_function(stream, "%s", "</routes>\n");
	}


 fail:
	su_home_unref(home);
	sres_resolver_unref(dig->sres);
	switch_safe_free(mycmd);

	return SWITCH_STATUS_SUCCESS;
}
/** Test basic memory home operations  */
static int test_alloc(void)
{
  exhome_t *h0, *h1, *h2, *h3;
  su_home_t home[1] = { SU_HOME_INIT(home) };
  su_home_t home0[1];
  enum { N = 40 };
  void *m0[N], *m1[N], *m;
  char *c, *c0, *p0, *p1;
  int i;
  enum { destructed_once = 1 };
  int d0, d1a, d1, d2, d3;

  BEGIN();

  /* su_home_init() was not initializing suh_locks */
  memset(home0, 0xff, sizeof home0);
  TEST(su_home_init(home0), 0);
  TEST_VOID(su_home_deinit(home0));

  TEST_1(h0 = su_home_new(sizeof(*h0)));
  TEST_1(h1 = su_home_clone(h0->home, sizeof(*h1)));

  d0 = d1a = d1 = d2 = d3 = 0;
  h0->p = &d0; h1->p = &d1a;
  TEST(su_home_destructor(h0->home, exdestructor), 0);
  TEST(su_home_destructor(h1->home, exdestructor), 0);

  TEST_1(h2 = su_home_ref(h0->home));
  su_home_unref(h0->home);
  TEST(d0, 0);

  for (i = 0; i < 128; i++)
    TEST_1(su_alloc(h0->home, 16));

  for (i = 0; i < 128; i++)
    TEST_1(su_alloc(h1->home, 16));

  su_home_unref(h1->home);
  TEST(d1a, destructed_once);

  TEST_1(h1 = su_home_clone(h0->home, sizeof(*h1)));
  TEST(su_home_destructor(h1->home, exdestructor), 0);
  h1->p = &d1;

  for (i = 0; i < 128; i++)
    TEST_1(su_alloc(h1->home, 16));

  for (i = 0; i < 128; i++)
    TEST_1(su_alloc(h2->home, 16));

  su_home_unref(h2->home); /* Should call destructor of cloned home, too */

  TEST(d0, destructed_once);
  TEST(d1, destructed_once);

  TEST_1(h0 = su_home_new(sizeof(*h0)));
  TEST_1(h1 = su_home_clone(h0->home, sizeof(*h1)));
  TEST_1(h2 = su_home_clone(h1->home, sizeof(*h2)));
  TEST_1(h3 = su_home_clone(h2->home, sizeof(*h3)));

  TEST(su_home_threadsafe(h0->home), 0);

  for (i = 0; i < N; i++) {
    TEST_1(m0[i] = su_zalloc(h3->home, 20));
    TEST_1(m1[i] = su_zalloc(h2->home, 20));
  }

  TEST_1(m = su_zalloc(h2->home, 20));

  TEST_1(su_in_home(h2->home, m));
  TEST_1(!su_in_home(h2->home, (char *)m + 1));
  TEST_1(!su_in_home(h2->home, (void *)(intptr_t)su_in_home));
  TEST_1(!su_in_home(h3->home, m));
  TEST_1(!su_in_home(NULL, m));
  TEST_1(!su_in_home(h3->home, NULL));

  TEST(su_home_move(home, NULL), 0);
  TEST(su_home_move(NULL, home), 0);
  TEST(su_home_move(home, h3->home), 0);
  TEST(su_home_move(h2->home, h3->home), 0);
  TEST(su_home_move(h1->home, h2->home), 0);

  su_home_preload(home, 1, 1024 + 2 * 8);

  TEST_1(c = su_zalloc(home, 64)); p0 = c; p1 = c + 1024;
  c0 = c;
  TEST_P(c = su_realloc(home, c0, 127), c0);

  TEST_1(c = c0 = su_zalloc(home, 1024 - 128));
  TEST_1(p0 <= c); TEST_1(c < p1);
  TEST_P(c = su_realloc(home, c, 128), c0);
  TEST_P(c = su_realloc(home, c, 1023 - 128), c0);
  TEST_P(c = su_realloc(home, c, 1024 - 128), c0);
  TEST_1(c = su_realloc(home, c, 1024));
  TEST_1(c = su_realloc(home, c, 2 * 1024));

  TEST_P(c = su_realloc(home, p0, 126), p0);
  TEST_1(c = su_realloc(home, p0, 1024));
  TEST_P(c = su_realloc(home, c, 0), NULL);

  su_home_check(home);
  su_home_deinit(home);

  su_home_check(h2->home);
  su_home_zap(h2->home);
  su_home_check(h0->home);
  su_home_zap(h0->home);

  {
    su_home_t h1[1];

    memset(h1, 0, sizeof h1);

    TEST(su_home_init(h1), 0);
    TEST(su_home_threadsafe(h1), 0);

    TEST_1(su_home_ref(h1));
    TEST_1(su_home_ref(h1));

    TEST(su_home_destructor(h1, test_destructor), 0);

    TEST_1(!su_home_unref(h1));
    TEST_1(!su_home_unref(h1));
    TEST_1(su_home_unref(h1));
    TEST(h1->suh_size, 13);
  }

  /* Test su_home_parent() */
  TEST_1(h0 = su_home_new(sizeof *h0));
  TEST_1(h1 = su_home_clone(h0->home, sizeof *h1));
  TEST_1(h2 = su_home_clone(h1->home, sizeof *h2));
  TEST_1(h3 = su_home_clone(h2->home, sizeof *h3));

  TEST_P(su_home_parent(h0->home), NULL);
  TEST_P(su_home_parent(h1->home), h0);
  TEST_P(su_home_parent(h2->home), h1);
  TEST_P(su_home_parent(h3->home), h2);
  TEST(su_home_move(h0->home, h1->home), 0);
  TEST_P(su_home_parent(h2->home), h0);
  TEST_P(su_home_parent(h3->home), h2);
  TEST(su_home_move(h0->home, h2->home), 0);
  TEST_P(su_home_parent(h3->home), h0);

  su_home_move(NULL, h0->home);

  TEST_P(su_home_parent(h0->home), NULL);
  TEST_P(su_home_parent(h1->home), NULL);
  TEST_P(su_home_parent(h2->home), NULL);
  TEST_P(su_home_parent(h3->home), NULL);

  su_home_unref(h0->home);
  su_home_unref(h1->home);
  su_home_unref(h2->home);
  su_home_unref(h3->home);

  END();
}