/** * 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; }
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; }