From 255afc7c25d84e7d37daec4007f8a554bf0968d5 Mon Sep 17 00:00:00 2001 From: Brian West Date: Mon, 10 Apr 2006 21:36:06 +0000 Subject: [PATCH] update git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1110 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- libs/srtp/crypto/Makefile | 2 +- src/mod/endpoints/mod_exosip/mod_exosip.c | 51 +++++++++++++++++++---- src/switch_rtp.c | 42 +++++++++++++------ 3 files changed, 73 insertions(+), 22 deletions(-) diff --git a/libs/srtp/crypto/Makefile b/libs/srtp/crypto/Makefile index d7ac61fb14..fe5ae96f33 100644 --- a/libs/srtp/crypto/Makefile +++ b/libs/srtp/crypto/Makefile @@ -12,7 +12,7 @@ CC = gcc INCDIR = -Iinclude -I$(srcdir)/include DEFS = -DHAVE_CONFIG_H CPPFLAGS= -CFLAGS = -Wall -O4 -fexpensive-optimizations -funroll-loops +CFLAGS = -fPIC -Wall -O4 -fexpensive-optimizations -funroll-loops LIBS = LDFLAGS = -L. COMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS) diff --git a/src/mod/endpoints/mod_exosip/mod_exosip.c b/src/mod/endpoints/mod_exosip/mod_exosip.c index 1ae9caf617..b133b69637 100644 --- a/src/mod/endpoints/mod_exosip/mod_exosip.c +++ b/src/mod/endpoints/mod_exosip/mod_exosip.c @@ -66,7 +66,8 @@ typedef enum { TFLAG_RTP = (1 << 7), TFLAG_BYE = (1 << 8), TFLAG_ANS = (1 << 9), - TFLAG_EARLY_MEDIA = (1 << 10) + TFLAG_EARLY_MEDIA = (1 << 10), + TFLAG_SECURE = (1 << 11) } TFLAGS; @@ -85,11 +86,11 @@ static struct { char *codec_order[SWITCH_MAX_CODECS]; int codec_order_last; switch_hash *call_hash; + switch_hash *srtp_hash; int running; int codec_ms; int dtmf_duration; unsigned int flags; - char *crypto_key; } globals; struct private_object { @@ -126,6 +127,7 @@ struct private_object { unsigned int out_digit_sofar; unsigned int out_digit_dur; uint16_t out_digit_seq; + char *realm; }; @@ -138,7 +140,6 @@ SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan) SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_extip, globals.extip) SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_ip, globals.ip) SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_string, globals.codec_string) -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_crypto_key, globals.crypto_key) static switch_status exosip_on_init(switch_core_session *session); static switch_status exosip_on_hangup(switch_core_session *session); @@ -281,7 +282,10 @@ static switch_status exosip_on_init(switch_core_session *session) ip = globals.extip; } } - snprintf(from_uri, sizeof(from_uri), "%s ", tech_pvt->caller_profile->caller_id_name, tech_pvt->caller_profile->caller_id_number, ip); + snprintf(from_uri, sizeof(from_uri), "%s ", + tech_pvt->caller_profile->caller_id_name, + tech_pvt->caller_profile->caller_id_number, + ip); /* Setup codec negotiation stuffs */ osip_rfc3264_init(&tech_pvt->sdp_config); @@ -450,6 +454,7 @@ static switch_status activate_rtp(struct private_object *tech_pvt) int bw, ms; switch_channel *channel; const char *err; + char *key = NULL; assert(tech_pvt != NULL); @@ -475,7 +480,18 @@ static switch_status activate_rtp(struct private_object *tech_pvt) tech_pvt->remote_sdp_audio_port, tech_pvt->read_codec.codec_interface->ianacode, ms); - + if (tech_pvt->realm) { + if (!(key = (char *) switch_core_hash_find(globals.srtp_hash, tech_pvt->realm))) { + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "undefined Realm %s\n", tech_pvt->realm); + switch_channel_hangup(channel); + switch_set_flag(tech_pvt, TFLAG_BYE); + switch_clear_flag(tech_pvt, TFLAG_IO); + return SWITCH_STATUS_FALSE; + } else { + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "using Realm %s\n", tech_pvt->realm); + } + } + tech_pvt->rtp_session = switch_rtp_new(tech_pvt->local_sdp_audio_ip, tech_pvt->local_sdp_audio_port, tech_pvt->remote_sdp_audio_ip, @@ -484,7 +500,7 @@ static switch_status activate_rtp(struct private_object *tech_pvt) tech_pvt->read_codec.implementation->encoded_bytes_per_frame, ms, 0, - globals.crypto_key, + key, &err, switch_core_session_get_pool(tech_pvt->session)); if (tech_pvt->rtp_session) { @@ -952,6 +968,23 @@ static switch_status exosip_outgoing_channel(switch_core_session *session, switc char name[128]; switch_caller_profile *caller_profile = NULL; + + if (*outbound_profile->destination_number == '!') { + char *p; + + outbound_profile->destination_number++; + + if ((p=strchr(outbound_profile->destination_number, '!'))) { + *p = '\0'; + p++; + tech_pvt->realm = switch_core_session_strdup(*new_session, outbound_profile->destination_number); + outbound_profile->destination_number = p; + if ((p = strchr(tech_pvt->realm, '!'))) { + *p = '\0'; + } + } + + } snprintf(name, sizeof(name), "Exosip/%s-%04x", outbound_profile->destination_number, rand() & 0xffff); switch_channel_set_name(channel, name); @@ -997,6 +1030,7 @@ SWITCH_MOD_DECLARE(switch_status) switch_module_load(const switch_loadable_modul } switch_core_hash_init(&globals.call_hash, module_pool); + switch_core_hash_init(&globals.srtp_hash, module_pool); /* connect my internal structure to the blank pointer passed to me */ *interface = &exosip_module_interface; @@ -1602,8 +1636,9 @@ static int config_exosip(int reload) set_global_ip(val); } else if (!strcmp(var, "dialplan")) { set_global_dialplan(val); - } else if (!strcmp(var, "crypto_key")) { - set_global_crypto_key(val); + } else if (!strncasecmp(var, "srtp:", 5)) { + char *name = var + 5; + switch_core_hash_insert_dup(globals.srtp_hash, name, val); } else if (!strcmp(var, "codec_prefs")) { set_global_codec_string(val); globals.codec_order_last = switch_separate_string(globals.codec_string, ',', globals.codec_order, SWITCH_MAX_CODECS); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 93fc8bc311..cf1b697e92 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -279,7 +279,7 @@ SWITCH_DECLARE(switch_status) switch_rtp_create(switch_rtp **new_rtp_session, switch_set_flag(rtp_session, SWITCH_RTP_FLAG_SECURE); crypto_policy_set_rtp_default(&policy.rtp); crypto_policy_set_rtcp_default(&policy.rtcp); - policy.ssrc.type = ssrc_specific; + policy.ssrc.type = ssrc_any_inbound; policy.ssrc.value = ssrc; policy.key = (uint8_t *) key; policy.next = NULL; @@ -338,8 +338,18 @@ SWITCH_DECLARE(switch_status) switch_rtp_create(switch_rtp **new_rtp_session, rtp_session->next_read = switch_time_now() + rtp_session->ms_per_packet; if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE)) { - srtp_create(&rtp_session->recv_ctx, &policy); - srtp_create(&rtp_session->send_ctx, &policy); + err_status_t stat; + + if ((stat = srtp_create(&rtp_session->recv_ctx, &policy))) { + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Error allocating srtp [%d]\n", stat); + *err = "Error"; + return SWITCH_STATUS_FALSE; + } + if ((stat = srtp_create(&rtp_session->send_ctx, &policy))) { + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "Error allocating srtp [%d]\n", stat); + *err = "Error"; + return SWITCH_STATUS_FALSE; + } } *new_rtp_session = rtp_session; @@ -458,30 +468,30 @@ static int rtp_common_read(switch_rtp *rtp_session, void *data, int *payload_typ bytes = sizeof(rtp_msg_t); status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock, 0, (void *)&rtp_session->recv_msg, &bytes); + if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_IO)) { + return -1; + } + if (bytes < 0) { return bytes; - } - - if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE)) { + } else if (bytes > 0 && switch_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE)) { int sbytes = (int)bytes; err_status_t stat; - stat = srtp_unprotect(rtp_session->recv_ctx, &rtp_session->recv_msg, &sbytes); + stat = srtp_unprotect(rtp_session->recv_ctx, &rtp_session->recv_msg.header, &sbytes); if (stat) { switch_console_printf(SWITCH_CHANNEL_CONSOLE, "error: srtp unprotection failed with code %d%s\n", stat, stat == err_status_replay_fail ? " (replay check failed)" : stat == err_status_auth_fail ? " (auth check failed)" : ""); - return -1; + switch_yield(1000); + continue; } bytes = sbytes; } if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) { - if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_IO)) { - return -1; - } - + if ((switch_time_now() - rtp_session->next_read) > 1000) { /* We're late! We're Late!*/ memset(&rtp_session->recv_msg, 0, 13); @@ -584,7 +594,13 @@ static int rtp_common_write(switch_rtp *rtp_session, void *data, uint32_t datale bytes = datalen + rtp_header_len; if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE)) { int sbytes = (int)bytes; - srtp_protect(rtp_session->send_ctx, &rtp_session->send_msg, &sbytes); + err_status_t stat; + + stat = srtp_protect(rtp_session->send_ctx, &rtp_session->send_msg.header, &sbytes); + if (stat) { + switch_console_printf(SWITCH_CHANNEL_CONSOLE, "error: srtp unprotection failed with code %d\n", stat); + } + bytes = sbytes; }