tls interop

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7268 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2008-01-17 17:37:49 +00:00
parent 2f6f99583f
commit 4181b2bc87
5 changed files with 116 additions and 85 deletions

View File

@ -1628,7 +1628,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
nchannel = switch_core_session_get_channel(nsession);
if (!strncasecmp(profile_name, "gateway", 7)) {
char *gw;
char *gw, *params;
sofia_gateway_t *gateway_ptr = NULL;
if (!(gw = strchr(profile_name, '/'))) {
@ -1653,19 +1653,55 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
goto error;
}
tech_pvt->transport = gateway_ptr->register_transport;
/*
* Handle params, strip them off the destination and add them to the
* invite contact.
*
* TODO:
* - Add parameters back to destination url?
*/
if ((params = strchr(dest, ';'))) {
char *tp_param;
*params++ = '\0';
if ((tp_param = (char *)switch_stristr("port=", params))) {
tp_param += 5;
tech_pvt->transport = sofia_glue_str2transport(tp_param);
if (tech_pvt->transport == SOFIA_TRANSPORT_UNKNOWN) {
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
goto error;
}
}
}
if (tech_pvt->transport != gateway_ptr->register_transport) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "You are trying to use a different transport type for this gateway (overriding the register-transport), this is unsupported!\n");
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
goto error;
}
profile = gateway_ptr->profile;
tech_pvt->gateway_name = switch_core_session_strdup(nsession, gateway_ptr->name);
switch_channel_set_variable(nchannel, "sip_gateway_name", gateway_ptr->name);
if (!switch_test_flag(gateway_ptr, REG_FLAG_CALLERID)) {
tech_pvt->gateway_from_str = switch_core_session_strdup(nsession, gateway_ptr->register_from);
}
if (!strchr(dest, '@')) {
tech_pvt->dest = switch_core_session_sprintf(nsession, "sip:%s@%s", dest, gateway_ptr->register_proxy + 4);
} else {
tech_pvt->dest = switch_core_session_sprintf(nsession, "sip:%s", dest);
}
tech_pvt->invite_contact = switch_core_session_strdup(nsession, gateway_ptr->register_contact);
if (params) {
tech_pvt->invite_contact = switch_core_session_sprintf(nsession, "%s;%s", gateway_ptr->register_contact, params);
} else {
tech_pvt->invite_contact = switch_core_session_strdup(nsession, gateway_ptr->register_contact);
}
} else {
if (!(dest = strchr(profile_name, '/'))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid URL\n");
@ -1729,7 +1765,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
}
}
switch_channel_set_variable(nchannel, "sip_destination_url", tech_pvt->dest);
caller_profile = switch_caller_profile_clone(nsession, outbound_profile);
caller_profile->destination_number = switch_core_strdup(caller_profile->pool, dest);
switch_channel_set_caller_profile(nchannel, caller_profile);

View File

@ -196,6 +196,14 @@ typedef enum {
REG_STATE_LAST
} reg_state_t;
typedef enum {
SOFIA_TRANSPORT_UNKNOWN = 0,
SOFIA_TRANSPORT_UDP,
SOFIA_TRANSPORT_TCP,
SOFIA_TRANSPORT_TCP_TLS,
SOFIA_TRANSPORT_SCTP
} sofia_transport_t;
struct sofia_gateway {
sofia_private_t *sofia_private;
nua_handle_t *nh;
@ -212,6 +220,7 @@ struct sofia_gateway {
char *register_context;
char *expires_str;
char *register_url;
sofia_transport_t register_transport;
uint32_t freq;
time_t expires;
time_t retry;
@ -358,6 +367,7 @@ struct private_object {
switch_payload_t bte;
switch_payload_t cng_pt;
switch_payload_t bcng_pt;
sofia_transport_t transport;
nua_handle_t *nh;
nua_handle_t *nh2;
sip_contact_t *contact;
@ -401,14 +411,6 @@ typedef enum {
AUTH_STALE,
} auth_res_t;
typedef enum {
SOFIA_TRANSPORT_UNKNOWN = 0,
SOFIA_TRANSPORT_UDP,
SOFIA_TRANSPORT_TCP,
SOFIA_TRANSPORT_TCP_TLS,
SOFIA_TRANSPORT_SCTP,
} sofia_transport_t;
#define sofia_test_pflag(obj, flag) ((obj)->pflags & flag)
#define sofia_set_pflag(obj, flag) (obj)->pflags |= (flag)
#define sofia_set_pflag_locked(obj, flag) assert(obj->flag_mutex != NULL);\
@ -568,8 +570,10 @@ void sofia_reg_release_gateway__(const char *file, const char *func, int line, s
*/
sofia_transport_t sofia_glue_via2transport(const sip_via_t *via);
sofia_transport_t sofia_glue_url2transport(const url_t *url);
sofia_transport_t sofia_glue_str2transport(const char *str);
const char *sofia_glue_transport2str(const sofia_transport_t tp);
char * sofia_glue_find_parameter(const char *str, const char *param);
int sofia_glue_transport_has_tls(const sofia_transport_t tp);
const char *sofia_glue_get_unknown_header(sip_t const *sip, const char *name);

View File

@ -664,8 +664,9 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
*register_proxy = NULL,
*contact_params = NULL,
*params = NULL,
*register_transport = "udp";
*register_transport = NULL;
gateway->register_transport = SOFIA_TRANSPORT_UDP;
gateway->pool = profile->pool;
gateway->profile = profile;
gateway->name = switch_core_strdup(gateway->pool, name);
@ -707,12 +708,14 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
} else if (!strcmp(var, "contact-params")) {
contact_params = val;
} else if (!strcmp(var, "register-transport")) {
if (!strcasecmp(val, "udp") || !strcasecmp(val, "tcp")) {
register_transport = val;
} else {
sofia_transport_t transport = sofia_glue_str2transport(val);
if (transport == SOFIA_TRANSPORT_UNKNOWN || (!sofia_test_pflag(profile, PFLAG_TLS) && sofia_glue_transport_has_tls(transport))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: unsupported transport\n");
goto skip;
}
gateway->register_transport = transport;
}
}
@ -767,6 +770,7 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
if (switch_true(caller_id_in_from)) {
switch_set_flag(gateway, REG_FLAG_CALLERID);
}
register_transport = (char *)sofia_glue_transport2str(gateway->register_transport);
if (contact_params) {
if (*contact_params == ';') {
params = switch_core_sprintf(gateway->pool, "%s&transport=%s", contact_params, register_transport);
@ -777,10 +781,11 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
params = switch_core_sprintf(gateway->pool, ";transport=%s", register_transport);
}
gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s;transport=%s", register_proxy,register_transport);
gateway->register_url = switch_core_sprintf(gateway->pool, "sip:%s;transport=%s", register_proxy, register_transport);
gateway->register_from = switch_core_sprintf(gateway->pool, "<sip:%s@%s;transport=%s>", from_user, from_domain, register_transport);
gateway->register_contact = switch_core_sprintf(gateway->pool, "<sip:%s@%s:%d%s>", extension,
profile->extsipip ? profile->extsipip : profile->sipip, profile->sip_port, params);
profile->extsipip ? profile->extsipip : profile->sipip,
sofia_glue_transport_has_tls(gateway->register_transport) ? profile->tls_sip_port : profile->sip_port, params);
if (!strncasecmp(proxy, "sip:", 4)) {
gateway->register_proxy = switch_core_strdup(gateway->pool, proxy);

View File

@ -509,24 +509,40 @@ switch_status_t sofia_glue_tech_choose_video_port(private_object_t *tech_pvt)
return SWITCH_STATUS_SUCCESS;
}
static sofia_transport_t sofia_glue_str2transport(const char *str)
sofia_transport_t sofia_glue_str2transport(const char *str)
{
if (!strcasecmp(str, "udp")) {
if (!strncasecmp(str, "udp", 3)) {
return SOFIA_TRANSPORT_UDP;
}
else if (!strcasecmp(str, "tcp")) {
else if (!strncasecmp(str, "tcp", 3)) {
return SOFIA_TRANSPORT_TCP;
}
else if (!strcasecmp(str, "sctp")) {
else if (!strncasecmp(str, "sctp", 4)) {
return SOFIA_TRANSPORT_SCTP;
}
else if (!strcasecmp(str, "tls")) {
else if (!strncasecmp(str, "tls", 3)) {
return SOFIA_TRANSPORT_TCP_TLS;
}
return SOFIA_TRANSPORT_UNKNOWN;
}
char * sofia_glue_find_parameter(const char *str, const char *param)
{
char *ptr = NULL;
ptr = (char *)str;
while(ptr) {
if (!strncasecmp(ptr, param, strlen(param)))
return ptr;
if ((ptr = strchr(ptr, ';')))
ptr++;
}
return NULL;
}
sofia_transport_t sofia_glue_url2transport(const url_t *url)
{
char *ptr = NULL;
@ -539,29 +555,8 @@ sofia_transport_t sofia_glue_url2transport(const url_t *url)
tls++;
}
ptr = (char *)url->url_params;
while(ptr) {
if (!strncasecmp(ptr, "transport=", 10)) {
ptr += 10;
if (!strncasecmp(ptr, "udp", 3)) {
return SOFIA_TRANSPORT_UDP;
}
else if (!strncasecmp(ptr, "tcp", 3)) {
return SOFIA_TRANSPORT_TCP;
}
else if (!strncasecmp(ptr, "tls", 3)) {
return SOFIA_TRANSPORT_TCP_TLS;
}
else if (!strncasecmp(ptr, "sctp", 4)) {
return SOFIA_TRANSPORT_SCTP;
}
break;
}
if ((ptr = strchr(ptr, ';')))
ptr++;
if ((ptr = sofia_glue_find_parameter(url->url_params, "transport="))) {
return sofia_glue_str2transport(ptr + 10);
}
return (tls) ? SOFIA_TRANSPORT_TCP_TLS : SOFIA_TRANSPORT_UDP;
@ -713,7 +708,6 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
if (!tech_pvt->nh) {
char *d_url = NULL, *url = NULL;
sofia_private_t *sofia_private;
sofia_transport_t transport = SOFIA_TRANSPORT_UDP;
char *invite_contact = NULL, *to_str, *use_from_str, *from_str, *url_str;
const char *t_var;
char *rpid_domain = "cluecon.com", *p;
@ -752,28 +746,35 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
rpid_domain = "cluecon.com";
}
if ((p = (char *)switch_stristr("port=", url))) {
p += 5;
transport = sofia_glue_str2transport( p );
} else {
if ((t_var = switch_channel_get_variable(channel, "sip_transport"))) {
transport = sofia_glue_str2transport(t_var);
/*
* Ignore transport chanvar and uri parameter for gateway connections
* since all of them have been already taken care of in mod_sofia.c:sofia_outgoing_channel()
*/
if (switch_strlen_zero(tech_pvt->gateway_name)) {
if ((p = (char *)switch_stristr("port=", url))) {
p += 5;
tech_pvt->transport = sofia_glue_str2transport( p );
} else {
if ((t_var = switch_channel_get_variable(channel, "sip_transport"))) {
tech_pvt->transport = sofia_glue_str2transport(t_var);
}
}
if (tech_pvt->transport == SOFIA_TRANSPORT_UNKNOWN) {
tech_pvt->transport = SOFIA_TRANSPORT_UDP;
}
}
if (transport == SOFIA_TRANSPORT_UNKNOWN) {
transport = SOFIA_TRANSPORT_UDP;
}
if (switch_strlen_zero(tech_pvt->invite_contact)) {
if (sofia_glue_transport_has_tls(transport))
if (switch_strlen_zero(tech_pvt->invite_contact))
{
if (sofia_glue_transport_has_tls(tech_pvt->transport))
tech_pvt->invite_contact = tech_pvt->profile->tls_url;
else
tech_pvt->invite_contact = tech_pvt->profile->url;
}
url_str = sofia_overcome_sip_uri_weakness(session, url, transport, SWITCH_TRUE);
invite_contact = sofia_overcome_sip_uri_weakness(session, tech_pvt->invite_contact, transport, SWITCH_FALSE);
url_str = sofia_overcome_sip_uri_weakness(session, url, tech_pvt->transport, SWITCH_TRUE);
invite_contact = sofia_overcome_sip_uri_weakness(session, tech_pvt->invite_contact, tech_pvt->transport, SWITCH_FALSE);
from_str = sofia_overcome_sip_uri_weakness(session, use_from_str, 0, SWITCH_FALSE);
to_str = sofia_overcome_sip_uri_weakness(session, tech_pvt->dest_to, 0, SWITCH_FALSE);

View File

@ -343,7 +343,7 @@ uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t *profile, nua_han
char network_ip[80];
char *register_gateway = NULL;
int network_port;
int cd = 0;
const char *reg_desc = "Registered";
const char *call_id = NULL;
char *force_user;
@ -431,34 +431,19 @@ uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t *profile, nua_han
}
if ((v_contact_str = switch_event_get_header(*v_event, "sip-force-contact"))) {
if (!strcasecmp(v_contact_str, "nat-connectile-dysfunction") || !strcasecmp(v_contact_str, "NDLB-connectile-dysfunction")) {
if (!strcasecmp(v_contact_str, "nat-connectile-dysfunction") ||
!strcasecmp(v_contact_str, "NDLB-connectile-dysfunction") || !strcasecmp(v_contact_str, "NDLB-tls-connectile-dysfunction")) {
if (contact->m_url->url_params) {
switch_snprintf(contact_str, sizeof(contact_str), "%s <sip:%s@%s:%d;%s>",
display, contact->m_url->url_user, network_ip, network_port, contact->m_url->url_params);
} else {
switch_snprintf(contact_str, sizeof(contact_str), "%s <sip:%s@%s:%d>", display, contact->m_url->url_user, network_ip, network_port);
}
cd = 1;
exptime = 20;
} else if (!strcasecmp(v_contact_str, "NDLB-tls-connectile-dysfunction")) {
const char *pt = contact->m_url->url_port;
int port;
if (!pt) {
pt = "5060";
}
port = atoi(pt);
if (port > 0) {
port++;
if (contact->m_url->url_params) {
switch_snprintf(contact_str, sizeof(contact_str), "%s <sip:%s@%s:%d;%s>",
display, contact->m_url->url_user, contact->m_url->url_host, port, contact->m_url->url_params);
} else {
switch_snprintf(contact_str, sizeof(contact_str), "%s <sip:%s@%s:%d>",
display, contact->m_url->url_user, contact->m_url->url_host, port);
}
if (strstr(v_contact_str, "tls")) {
reg_desc = "Registered(TLSHACK)";
} else {
reg_desc = "Registered(NATHACK)";
exptime = 20;
}
} else {
char *p;
@ -524,7 +509,7 @@ uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t *profile, nua_han
switch_safe_free(sql);
sql = switch_mprintf("insert into sip_registrations values ('%q', '%q','%q','%q','%q', '%q', %ld, '%q')", call_id,
to_user, to_host, contact_str, cd ? "Registered(NATHACK)" : "Registered",
to_user, to_host, contact_str, reg_desc,
rpid, (long) switch_timestamp(NULL) + (long) exptime * 2, agent);