Example #1
0
/**
 * Creates a new operation object and stores it the list of
 * active operations for 'cli'.
 */
ssc_oper_t *ssc_oper_create(ssc_t *ssc,
                            sip_method_t method,
                            char const *name,
                            char const *address,
                            tag_type_t tag, tag_value_t value, ...)
{
    ssc_oper_t *op, *old;

    ta_list ta;

    enter;

    for (old = ssc->ssc_operations; old; old = old->op_next)
        if (!old->op_persistent)
            break;

    if (address) {
        int have_url = 1;
        sip_to_t *to;

        to = sip_to_make(ssc->ssc_home, address);

        if (to == NULL) {
            printf("%s: %s: invalid address: %s\n", ssc->ssc_name, name, address);
            return NULL;
        }

        /* Try to make sense out of the URL */
        if (url_sanitize(to->a_url) < 0) {
            printf("%s: %s: invalid address\n", ssc->ssc_name, name);
            return NULL;
        }

        if (!(op = su_zalloc(ssc->ssc_home, sizeof(*op)))) {
            printf("%s: %s: cannot create handle\n", ssc->ssc_name, name);
            return NULL;
        }

        op->op_next = ssc->ssc_operations;
        op->op_prev_state = -1;
        op->op_ssc = ssc;
        ssc->ssc_operations = op;

        if (method == sip_method_register)
            have_url = 0;

        ta_start(ta, tag, value);

        op->op_handle = nua_handle(ssc->ssc_nua, op,
                                   TAG_IF(have_url, NUTAG_URL(to->a_url)),
                                   SIPTAG_TO(to),
                                   ta_tags(ta));

        ta_end(ta);

        op->op_ident = sip_header_as_string(ssc->ssc_home, (sip_header_t *)to);

        ssc_oper_assign(op, method, name);

        if (!op->op_persistent) {
            ssc_oper_t *old_next;
            for (; old; old = old_next) {      /* Clean old handles */
                old_next = old->op_next;
                if (!old->op_persistent && !old->op_callstate)
                    ssc_oper_destroy(ssc, old);
            }
        }

        su_free(ssc->ssc_home, to);
    }
    else if (method || name)
        ssc_oper_assign(op = old, method, name);
    else
        return old;

    if (!op) {
        if (address)
            printf("%s: %s: invalid destination\n", ssc->ssc_name, name);
        else
            printf("%s: %s: no destination\n", ssc->ssc_name, name);
        return NULL;
    }

    return op;
}
Example #2
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;
}