提交 1dd780e6 authored 作者: Michael Jerris's avatar Michael Jerris

merge sip nat improvements from branches/brian

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@13594 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 b28bd6b9
...@@ -394,6 +394,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) ...@@ -394,6 +394,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) { if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) {
nua_bye(tech_pvt->nh, nua_bye(tech_pvt->nh,
SIPTAG_REASON_STR(reason), SIPTAG_REASON_STR(reason),
TAG_IF(!switch_strlen_zero(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
TAG_IF(!switch_strlen_zero(bye_headers), SIPTAG_HEADER_STR(bye_headers)), TAG_IF(!switch_strlen_zero(bye_headers), SIPTAG_HEADER_STR(bye_headers)),
TAG_END()); TAG_END());
} }
...@@ -407,7 +408,6 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session) ...@@ -407,7 +408,6 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
nua_cancel(tech_pvt->nh, nua_cancel(tech_pvt->nh,
SIPTAG_REASON_STR(reason), SIPTAG_REASON_STR(reason),
TAG_IF(!switch_strlen_zero(bye_headers), SIPTAG_HEADER_STR(bye_headers)), TAG_IF(!switch_strlen_zero(bye_headers), SIPTAG_HEADER_STR(bye_headers)),
TAG_IF(!switch_strlen_zero(bye_headers), SIPTAG_HEADER_STR(bye_headers)),
TAG_END()); TAG_END());
} }
} else { } else {
...@@ -2694,6 +2694,8 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session ...@@ -2694,6 +2694,8 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session
} }
} }
sofia_glue_get_user_host(switch_core_session_strdup(nsession, tech_pvt->dest), NULL, &tech_pvt->remote_ip);
if (dest_to) { if (dest_to) {
if (strchr(dest_to, '@')) { if (strchr(dest_to, '@')) {
tech_pvt->dest_to = switch_core_session_sprintf(nsession, "sip:%s", dest_to); tech_pvt->dest_to = switch_core_session_sprintf(nsession, "sip:%s", dest_to);
...@@ -3217,6 +3219,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) ...@@ -3217,6 +3219,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)
mod_sofia_globals.running = 1; mod_sofia_globals.running = 1;
switch_mutex_unlock(mod_sofia_globals.mutex); switch_mutex_unlock(mod_sofia_globals.mutex);
mod_sofia_globals.auto_nat = (switch_core_get_variable("nat_type") ? 1 : 0);
switch_queue_create(&mod_sofia_globals.presence_queue, SOFIA_QUEUE_SIZE, mod_sofia_globals.pool); switch_queue_create(&mod_sofia_globals.presence_queue, SOFIA_QUEUE_SIZE, mod_sofia_globals.pool);
switch_queue_create(&mod_sofia_globals.mwi_queue, SOFIA_QUEUE_SIZE, mod_sofia_globals.pool); switch_queue_create(&mod_sofia_globals.mwi_queue, SOFIA_QUEUE_SIZE, mod_sofia_globals.pool);
......
...@@ -192,6 +192,7 @@ typedef enum { ...@@ -192,6 +192,7 @@ typedef enum {
PFLAG_MESSAGE_QUERY_ON_REGISTER, PFLAG_MESSAGE_QUERY_ON_REGISTER,
PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE, PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE,
PFLAG_PROXY_FOLLOW_REDIRECT, PFLAG_PROXY_FOLLOW_REDIRECT,
PFLAG_AUTO_NAT,
/* No new flags below this line */ /* No new flags below this line */
PFLAG_MAX PFLAG_MAX
} PFLAGS; } PFLAGS;
...@@ -272,6 +273,7 @@ struct mod_sofia_globals { ...@@ -272,6 +273,7 @@ struct mod_sofia_globals {
char guess_mask_str[16]; char guess_mask_str[16];
int debug_presence; int debug_presence;
int auto_restart; int auto_restart;
int auto_nat;
}; };
extern struct mod_sofia_globals mod_sofia_globals; extern struct mod_sofia_globals mod_sofia_globals;
...@@ -408,9 +410,13 @@ struct sofia_profile { ...@@ -408,9 +410,13 @@ struct sofia_profile {
char *extsipip; char *extsipip;
char *username; char *username;
char *url; char *url;
char *public_url;
char *bindurl; char *bindurl;
char *tls_url; char *tls_url;
char *tls_public_url;
char *tls_bindurl; char *tls_bindurl;
char *tcp_public_contact;
char *tls_public_contact;
char *tcp_contact; char *tcp_contact;
char *tls_contact; char *tls_contact;
char *sla_contact; char *sla_contact;
...@@ -430,8 +436,8 @@ struct sofia_profile { ...@@ -430,8 +436,8 @@ struct sofia_profile {
sofia_cid_type_t cid_type; sofia_cid_type_t cid_type;
sofia_dtmf_t dtmf_type; sofia_dtmf_t dtmf_type;
int auto_restart; int auto_restart;
int sip_port; switch_port_t sip_port;
int tls_sip_port; switch_port_t tls_sip_port;
int tls_version; int tls_version;
char *codec_string; char *codec_string;
int running; int running;
...@@ -489,6 +495,7 @@ struct sofia_profile { ...@@ -489,6 +495,7 @@ struct sofia_profile {
uint32_t timer_t2; uint32_t timer_t2;
uint32_t timer_t4; uint32_t timer_t4;
char *contact_user; char *contact_user;
char *local_network;
}; };
struct private_object { struct private_object {
...@@ -613,6 +620,7 @@ struct private_object { ...@@ -613,6 +620,7 @@ struct private_object {
switch_rtp_bug_flag_t rtp_bugs; switch_rtp_bug_flag_t rtp_bugs;
switch_codec_implementation_t read_impl; switch_codec_implementation_t read_impl;
switch_codec_implementation_t write_impl; switch_codec_implementation_t write_impl;
char *user_via;
}; };
struct callback_t { struct callback_t {
...@@ -822,7 +830,9 @@ sofia_transport_t sofia_glue_str2transport(const char *str); ...@@ -822,7 +830,9 @@ sofia_transport_t sofia_glue_str2transport(const char *str);
const char *sofia_glue_transport2str(const sofia_transport_t tp); const char *sofia_glue_transport2str(const sofia_transport_t tp);
char * sofia_glue_find_parameter(const char *str, const char *param); char * sofia_glue_find_parameter(const char *str, const char *param);
char *sofia_glue_create_via(switch_core_session_t *session, const char *ip, switch_port_t port, sofia_transport_t transport);
char *sofia_glue_create_external_via(switch_core_session_t *session, sofia_profile_t *profile, sofia_transport_t transport);
int sofia_glue_check_nat(sofia_profile_t *profile, const char *network_ip);
int sofia_glue_transport_has_tls(const sofia_transport_t tp); 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); const char *sofia_glue_get_unknown_header(sip_t const *sip, const char *name);
switch_status_t sofia_glue_build_crypto(private_object_t *tech_pvt, int index, switch_rtp_crypto_key_type_t type, switch_rtp_crypto_direction_t direction); switch_status_t sofia_glue_build_crypto(private_object_t *tech_pvt, int index, switch_rtp_crypto_key_type_t type, switch_rtp_crypto_direction_t direction);
...@@ -835,7 +845,7 @@ switch_status_t sofia_glue_tech_set_video_codec(private_object_t *tech_pvt, int ...@@ -835,7 +845,7 @@ switch_status_t sofia_glue_tech_set_video_codec(private_object_t *tech_pvt, int
const char *sofia_glue_strip_proto(const char *uri); const char *sofia_glue_strip_proto(const char *uri);
switch_status_t reconfig_sofia(sofia_profile_t *profile); switch_status_t reconfig_sofia(sofia_profile_t *profile);
void sofia_glue_del_gateway(sofia_gateway_t *gp); void sofia_glue_del_gateway(sofia_gateway_t *gp);
void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const char *host, const char *contact, const char *user_agent); void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const char *host, const char *contact, const char *user_agent, const char *network_ip);
void sofia_glue_restart_all_profiles(void); void sofia_glue_restart_all_profiles(void);
void sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly); void sofia_glue_toggle_hold(private_object_t *tech_pvt, int sendonly);
const char * sofia_state_string(int state); const char * sofia_state_string(int state);
...@@ -877,3 +887,4 @@ int sofia_get_loglevel(const char *name); ...@@ -877,3 +887,4 @@ int sofia_get_loglevel(const char *name);
sofia_cid_type_t sofia_cid_name2type(const char *name); sofia_cid_type_t sofia_cid_name2type(const char *name);
void sofia_glue_tech_set_local_sdp(private_object_t *tech_pvt, const char *sdp_str, switch_bool_t dup); void sofia_glue_tech_set_local_sdp(private_object_t *tech_pvt, const char *sdp_str, switch_bool_t dup);
void sofia_glue_set_rtp_stats(private_object_t *tech_pvt); void sofia_glue_set_rtp_stats(private_object_t *tech_pvt);
void sofia_glue_get_addr(msg_t *msg, char *buf, size_t buflen, int *port);
...@@ -375,11 +375,11 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event) ...@@ -375,11 +375,11 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
} }
if (for_everyone) { if (for_everyone) {
sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,'%q' " sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q' "
"from sip_registrations where sip_user='%q' and sip_host='%q'", "from sip_registrations where sip_user='%q' and sip_host='%q'",
stream.data, user, host); stream.data, user, host);
} else if (call_id) { } else if (call_id) {
sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,'%q' " sql = switch_mprintf("select sip_user,sip_host,contact,profile_name,network_ip,'%q' "
"from sip_registrations where sip_user='%q' and sip_host='%q' and call_id='%q'", "from sip_registrations where sip_user='%q' and sip_host='%q' and call_id='%q'",
stream.data, user, host, call_id); stream.data, user, host, call_id);
} }
...@@ -1401,13 +1401,14 @@ static int sofia_presence_mwi_callback2(void *pArg, int argc, char **argv, char ...@@ -1401,13 +1401,14 @@ static int sofia_presence_mwi_callback2(void *pArg, int argc, char **argv, char
char *event = "message-summary"; char *event = "message-summary";
char *contact, *o_contact = argv[2]; char *contact, *o_contact = argv[2];
char *profile_name = argv[3]; char *profile_name = argv[3];
char *body = argv[4]; char *network_ip = argv[4];
char *body = argv[5];
char *id = NULL; char *id = NULL;
nua_handle_t *nh; nua_handle_t *nh;
struct mwi_helper *h = (struct mwi_helper *) pArg; struct mwi_helper *h = (struct mwi_helper *) pArg;
sofia_profile_t *ext_profile = NULL, *profile = h->profile; sofia_profile_t *ext_profile = NULL, *profile = h->profile;
char *route = NULL, *route_uri = NULL; char *route = NULL, *route_uri = NULL, *user_via = NULL;
char *p; char *p, *contact_str;
if (profile_name && strcasecmp(profile_name, h->profile->name)) { if (profile_name && strcasecmp(profile_name, h->profile->name)) {
if ((ext_profile = sofia_glue_find_profile(profile_name))) { if ((ext_profile = sofia_glue_find_profile(profile_name))) {
...@@ -1415,9 +1416,41 @@ static int sofia_presence_mwi_callback2(void *pArg, int argc, char **argv, char ...@@ -1415,9 +1416,41 @@ static int sofia_presence_mwi_callback2(void *pArg, int argc, char **argv, char
} }
} }
id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
contact = sofia_glue_get_url_from_contact(o_contact, 1); contact = sofia_glue_get_url_from_contact(o_contact, 1);
if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && profile->local_network &&
!switch_check_network_list_ip(network_ip, profile->local_network)) {
char *ptr = NULL;
const char *transport_str = NULL;
id = switch_mprintf("sip:%s@%s", sub_to_user, profile->extsipip);
if ((ptr = sofia_glue_find_parameter(o_contact, "transport="))) {
sofia_transport_t transport = sofia_glue_str2transport(ptr);
transport_str = sofia_glue_transport2str(transport);
switch (transport) {
case SOFIA_TRANSPORT_TCP:
contact_str = profile->tcp_public_contact;
break;
case SOFIA_TRANSPORT_TCP_TLS:
contact_str = profile->tls_public_contact;
break;
default:
contact_str = profile->public_url;
break;
}
user_via = sofia_glue_create_external_via(NULL, profile, transport);
} else {
user_via = sofia_glue_create_external_via(NULL, profile, SOFIA_TRANSPORT_UDP);
contact_str = profile->public_url;
}
} else {
contact_str = profile->url;
id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
}
if ((route = strstr(contact, ";fs_path=")) && (route = strdup(route + 9))) { if ((route = strstr(contact, ";fs_path=")) && (route = strdup(route + 9))) {
for (p = route; p && *p ; p++) { for (p = route; p && *p ; p++) {
...@@ -1455,17 +1488,24 @@ static int sofia_presence_mwi_callback2(void *pArg, int argc, char **argv, char ...@@ -1455,17 +1488,24 @@ static int sofia_presence_mwi_callback2(void *pArg, int argc, char **argv, char
} }
} }
nh = nua_handle(profile->nua, NULL, NUTAG_URL(contact), SIPTAG_FROM_STR(id), SIPTAG_TO_STR(id), SIPTAG_CONTACT_STR(h->profile->url), TAG_END()); nh = nua_handle(profile->nua, NULL, NUTAG_URL(contact),
SIPTAG_FROM_STR(id), SIPTAG_TO_STR(id),
SIPTAG_CONTACT_STR(contact_str), TAG_END());
nua_handle_bind(nh, &mod_sofia_globals.destroy_private); nua_handle_bind(nh, &mod_sofia_globals.destroy_private);
nua_notify(nh, nua_notify(nh,
NUTAG_NEWSUB(1), NUTAG_NEWSUB(1),
TAG_IF(route_uri, NUTAG_PROXY(route_uri)), TAG_IF(route_uri, NUTAG_PROXY(route_uri)),
SIPTAG_EVENT_STR(event), SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"), SIPTAG_PAYLOAD_STR(body), TAG_END()); TAG_IF(user_via, SIPTAG_VIA_STR(user_via)),
SIPTAG_EVENT_STR(event),
SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"),
SIPTAG_PAYLOAD_STR(body), TAG_END());
switch_safe_free(contact); switch_safe_free(contact);
switch_safe_free(id); switch_safe_free(id);
switch_safe_free(route); switch_safe_free(route);
switch_safe_free(user_via);
if (ext_profile) { if (ext_profile) {
sofia_glue_release_profile(ext_profile); sofia_glue_release_profile(ext_profile);
} }
...@@ -1501,13 +1541,13 @@ void sofia_presence_handle_sip_i_subscribe(int status, ...@@ -1501,13 +1541,13 @@ void sofia_presence_handle_sip_i_subscribe(int status,
switch_event_t *sevent; switch_event_t *sevent;
int sub_state; int sub_state;
int sent_reply = 0; int sent_reply = 0;
su_addrinfo_t *my_addrinfo = msg_addrinfo(nua_current_request(nua));
int network_port = 0; int network_port = 0;
char network_ip[80]; char network_ip[80];
const char *contact_host, *contact_user; const char *contact_host, *contact_user;
char *port; char *port;
char new_port[25] = ""; char new_port[25] = "";
char *is_nat = NULL; char *is_nat = NULL;
int is_auto_nat = 0;
const char *ipv6; const char *ipv6;
if (!(contact && sip->sip_contact->m_url)) { if (!(contact && sip->sip_contact->m_url)) {
...@@ -1515,8 +1555,12 @@ void sofia_presence_handle_sip_i_subscribe(int status, ...@@ -1515,8 +1555,12 @@ void sofia_presence_handle_sip_i_subscribe(int status,
return; return;
} }
get_addr(network_ip, sizeof(network_ip), my_addrinfo->ai_addr, my_addrinfo->ai_addrlen); sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
network_port = ntohs(((struct sockaddr_in *) msg_addrinfo(nua_current_request(nua))->ai_addr)->sin_port);
if (sofia_test_pflag(profile, PFLAG_AUTO_NAT) && profile->local_network &&
!switch_check_network_list_ip(network_ip, profile->local_network)) {
is_auto_nat = 1;
}
tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END()); tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END());
...@@ -1777,19 +1821,35 @@ void sofia_presence_handle_sip_i_subscribe(int status, ...@@ -1777,19 +1821,35 @@ void sofia_presence_handle_sip_i_subscribe(int status,
network_port, network_port,
params); params);
} }
if (is_auto_nat) {
contactstr = profile->public_url;
} else {
contactstr = profile->url;
}
if (switch_stristr("port=tcp", contact->m_url->url_params)) { if (switch_stristr("port=tcp", contact->m_url->url_params)) {
contactstr = profile->tcp_contact; if (is_auto_nat) {
contactstr = profile->tcp_public_contact;
} else {
contactstr = profile->tcp_contact;
}
} else if (switch_stristr("port=tls", contact->m_url->url_params)) { } else if (switch_stristr("port=tls", contact->m_url->url_params)) {
contactstr = profile->tls_contact; if (is_auto_nat) {
contactstr = profile->tls_contact;
} else {
contactstr = profile->tls_public_contact;
}
} }
if (nh && nh->nh_ds && nh->nh_ds->ds_usage) { if (nh && nh->nh_ds && nh->nh_ds->ds_usage) {
nua_dialog_usage_set_refresh_range(nh->nh_ds->ds_usage, exp_delta + SUB_OVERLAP, exp_delta + SUB_OVERLAP); nua_dialog_usage_set_refresh_range(nh->nh_ds->ds_usage, exp_delta + SUB_OVERLAP, exp_delta + SUB_OVERLAP);
} }
nua_respond(nh, SIP_202_ACCEPTED, SIPTAG_CONTACT_STR(contactstr), NUTAG_WITH_THIS(nua), nua_respond(nh, SIP_202_ACCEPTED,
SIPTAG_CONTACT_STR(contactstr),
NUTAG_WITH_THIS(nua),
SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_SUBSCRIPTION_STATE_STR(sstr),
SIPTAG_EXPIRES_STR(exp_delta_str), SIPTAG_EXPIRES_STR(exp_delta_str),
TAG_IF(sticky, NUTAG_PROXY(sticky)), TAG_END()); TAG_IF(sticky, NUTAG_PROXY(sticky)), TAG_END());
......
...@@ -402,11 +402,13 @@ int sofia_sub_del_callback(void *pArg, int argc, char **argv, char **columnNames ...@@ -402,11 +402,13 @@ int sofia_sub_del_callback(void *pArg, int argc, char **argv, char **columnNames
return 0; return 0;
} }
void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const char *host, const char *contact, const char *user_agent) void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const char *host, const char *contact, const char *user_agent, const char *network_ip)
{ {
const char *event = "check-sync"; const char *event = "check-sync";
nua_handle_t *nh; nua_handle_t *nh;
char *contact_url = NULL; char *contact_url = NULL;
char *contact_str = NULL;
char *user_via = NULL;
char *id = NULL; char *id = NULL;
if (switch_stristr("snom", user_agent)) { if (switch_stristr("snom", user_agent)) {
...@@ -417,22 +419,52 @@ void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const cha ...@@ -417,22 +419,52 @@ void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const cha
if ((contact_url = sofia_glue_get_url_from_contact((char *)contact, 1))) { if ((contact_url = sofia_glue_get_url_from_contact((char *)contact, 1))) {
char *p; char *p;
id = switch_mprintf("sip:%s@%s", user, host); id = switch_mprintf("sip:%s@%s", user, network_ip);
if ((p = strstr(contact_url, ";fs_"))) { if ((p = strstr(contact_url, ";fs_"))) {
*p = '\0'; *p = '\0';
} }
if (sofia_glue_check_nat(profile, network_ip)) {
char *ptr = NULL;
const char *transport_str = NULL;
if ((ptr = sofia_glue_find_parameter(contact_url, "transport="))) {
sofia_transport_t transport = sofia_glue_str2transport(ptr);
transport_str = sofia_glue_transport2str(transport);
switch (transport) {
case SOFIA_TRANSPORT_TCP:
contact_str = profile->tcp_public_contact;
break;
case SOFIA_TRANSPORT_TCP_TLS:
contact_str = profile->tls_public_contact;
break;
default:
contact_str = profile->public_url;
break;
}
user_via = sofia_glue_create_external_via(NULL, profile, transport);
} else {
user_via = sofia_glue_create_external_via(NULL, profile, SOFIA_TRANSPORT_UDP);
contact_str = profile->public_url;
}
} else {
contact_str = profile->url;
}
nh = nua_handle(profile->nua, NULL, nh = nua_handle(profile->nua, NULL,
NUTAG_URL(contact_url), NUTAG_URL(contact_url),
SIPTAG_FROM_STR(id), SIPTAG_FROM_STR(id),
SIPTAG_TO_STR(id), SIPTAG_TO_STR(id),
SIPTAG_CONTACT_STR(profile->url), SIPTAG_CONTACT_STR(contact_str),
TAG_END()); TAG_END());
nua_handle_bind(nh, &mod_sofia_globals.destroy_private); nua_handle_bind(nh, &mod_sofia_globals.destroy_private);
nua_notify(nh, nua_notify(nh,
NUTAG_NEWSUB(1), NUTAG_NEWSUB(1),
TAG_IF(user_via, SIPTAG_VIA_STR(user_via)),
SIPTAG_EVENT_STR(event), SIPTAG_EVENT_STR(event),
SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"), SIPTAG_CONTENT_TYPE_STR("application/simple-message-summary"),
SIPTAG_PAYLOAD_STR(""), SIPTAG_PAYLOAD_STR(""),
...@@ -442,6 +474,7 @@ void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const cha ...@@ -442,6 +474,7 @@ void sofia_reg_send_reboot(sofia_profile_t *profile, const char *user, const cha
free(contact_url); free(contact_url);
} }
switch_safe_free(user_via);
switch_safe_free(id); switch_safe_free(id);
} }
...@@ -462,8 +495,8 @@ int sofia_reg_del_callback(void *pArg, int argc, char **argv, char **columnNames ...@@ -462,8 +495,8 @@ int sofia_reg_del_callback(void *pArg, int argc, char **argv, char **columnNames
switch_event_t *s_event; switch_event_t *s_event;
sofia_profile_t *profile = (sofia_profile_t *) pArg; sofia_profile_t *profile = (sofia_profile_t *) pArg;
if (argc > 11 && atoi(argv[11]) == 1) { if (argc > 12 && atoi(argv[12]) == 1) {
sofia_reg_send_reboot(profile, argv[1], argv[2], argv[3], argv[7]); sofia_reg_send_reboot(profile, argv[1], argv[2], argv[3], argv[7], argv[11]);
} }
if (argc >= 3) { if (argc >= 3) {
...@@ -508,7 +541,8 @@ void sofia_reg_expire_call_id(sofia_profile_t *profile, const char *call_id, int ...@@ -508,7 +541,8 @@ void sofia_reg_expire_call_id(sofia_profile_t *profile, const char *call_id, int
switch_snprintf(sqlextra, sizeof(sqlextra), " or (sip_user='%s' and sip_host='%s')", user, host); switch_snprintf(sqlextra, sizeof(sqlextra), " or (sip_user='%s' and sip_host='%s')", user, host);
} }
switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid,expires,user_agent,server_user,server_host,profile_name" switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid,expires"
",user_agent,server_user,server_host,profile_name,network_ip"
",%d from sip_registrations where call_id='%s' %s", ",%d from sip_registrations where call_id='%s' %s",
reboot, call_id, sqlextra); reboot, call_id, sqlextra);
...@@ -548,10 +582,12 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot) ...@@ -548,10 +582,12 @@ void sofia_reg_check_expire(sofia_profile_t *profile, time_t now, int reboot)
switch_mutex_lock(profile->ireg_mutex); switch_mutex_lock(profile->ireg_mutex);
if (now) { if (now) {
switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid,expires,user_agent,server_user,server_host,profile_name" switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid,expires"
",user_agent,server_user,server_host,profile_name,network_ip"
",%d from sip_registrations where expires > 0 and expires <= %ld", reboot, (long) now); ",%d from sip_registrations where expires > 0 and expires <= %ld", reboot, (long) now);
} else { } else {
switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid,expires,user_agent,server_user,server_host,profile_name" switch_snprintf(sql, sizeof(sql), "select call_id,sip_user,sip_host,contact,status,rpid,expires"
",user_agent,server_user,server_host,profile_name,network_ip"
",%d from sip_registrations where expires > 0", reboot); ",%d from sip_registrations where expires > 0", reboot);
} }
...@@ -725,19 +761,17 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand ...@@ -725,19 +761,17 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
char *force_user; char *force_user;
char received_data[128] = ""; char received_data[128] = "";
char *path_val = NULL; char *path_val = NULL;
su_addrinfo_t *my_addrinfo = msg_addrinfo(nua_current_request(nua));
switch_event_t *auth_params = NULL; switch_event_t *auth_params = NULL;
int r = 0; int r = 0;
/* all callers must confirm that sip, sip->sip_request and sip->sip_contact are not NULL */ /* all callers must confirm that sip, sip->sip_request and sip->sip_contact are not NULL */
switch_assert(sip != NULL && sip->sip_contact != NULL && sip->sip_request != NULL); switch_assert(sip != NULL && sip->sip_contact != NULL && sip->sip_request != NULL);
get_addr(network_ip, sizeof(network_ip), my_addrinfo->ai_addr,my_addrinfo->ai_addrlen); sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
network_port = get_port(my_addrinfo->ai_addr);
snprintf(network_port_c, sizeof(network_port_c), "%d", network_port); snprintf(network_port_c, sizeof(network_port_c), "%d", network_port);
snprintf(url_ip, sizeof(url_ip), my_addrinfo->ai_addr->sa_family == AF_INET6 ? "[%s]" : "%s", network_ip); snprintf(url_ip, sizeof(url_ip), (msg_addrinfo(nua_current_request(nua)))->ai_addr->sa_family == AF_INET6 ? "[%s]" : "%s", network_ip);
expires = sip->sip_expires; expires = sip->sip_expires;
authorization = sip->sip_authorization; authorization = sip->sip_authorization;
...@@ -1249,15 +1283,11 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h ...@@ -1249,15 +1283,11 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
char key[128] = ""; char key[128] = "";
switch_event_t *v_event = NULL; switch_event_t *v_event = NULL;
char network_ip[80]; char network_ip[80];
su_addrinfo_t *my_addrinfo = msg_addrinfo(nua_current_request(nua));
sofia_regtype_t type = REG_REGISTER; sofia_regtype_t type = REG_REGISTER;
int network_port = 0; int network_port = 0;
char *is_nat = NULL; char *is_nat = NULL;
sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
get_addr(network_ip, sizeof(network_ip), my_addrinfo->ai_addr, my_addrinfo->ai_addrlen);
network_port = get_port(msg_addrinfo(nua_current_request(nua))->ai_addr);
if (!(sip->sip_contact && sip->sip_contact->m_url)) { if (!(sip->sip_contact && sip->sip_contact->m_url)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO CONTACT!\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO CONTACT!\n");
......
...@@ -76,6 +76,10 @@ void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const ...@@ -76,6 +76,10 @@ void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const
struct sla_helper sh = { { 0 } }; struct sla_helper sh = { { 0 } };
char *contact_str = strip_uri(full_contact); char *contact_str = strip_uri(full_contact);
sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url); sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url);
char network_ip[80];
int network_port = 0;
sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
sql = switch_mprintf("select call_id from sip_shared_appearance_dialogs where hostname='%q' and profile_name='%q' and contact_str='%q'", sql = switch_mprintf("select call_id from sip_shared_appearance_dialogs where hostname='%q' and profile_name='%q' and contact_str='%q'",
mod_sofia_globals.hostname, profile->name, contact_str); mod_sofia_globals.hostname, profile->name, contact_str);
...@@ -99,8 +103,13 @@ void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const ...@@ -99,8 +103,13 @@ void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const
nua_handle_bind(nh, &mod_sofia_globals.keep_private); nua_handle_bind(nh, &mod_sofia_globals.keep_private);
switch_snprintf(exp_str, sizeof(exp_str), "%ld", exptime + 30); switch_snprintf(exp_str, sizeof(exp_str), "%ld", exptime + 30);
switch_snprintf(my_contact, sizeof(my_contact), "<%s;transport=%s>;expires=%s", profile->sla_contact, sofia_glue_transport2str(transport), exp_str); if (sofia_glue_check_nat(profile, network_ip)) {
switch_snprintf(my_contact, sizeof(my_contact), "<sip:%s@%s;transport=%s>;expires=%s", profile->sla_contact,
profile->extsipip, sofia_glue_transport2str(transport), exp_str);
} else {
switch_snprintf(my_contact, sizeof(my_contact), "<sip:%s@%s;transport=%s>;expires=%s", profile->sla_contact,
profile->sipip, sofia_glue_transport2str(transport), exp_str);
}
nua_subscribe(nh, nua_subscribe(nh,
SIPTAG_TO(sip->sip_to), SIPTAG_TO(sip->sip_to),
SIPTAG_FROM(sip->sip_to), SIPTAG_FROM(sip->sip_to),
...@@ -125,8 +134,11 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia ...@@ -125,8 +134,11 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia
char *sql = NULL; char *sql = NULL;
char *route_uri = NULL; char *route_uri = NULL;
char *sla_contact = NULL; char *sla_contact = NULL;
char network_ip[80];
int network_port = 0;
sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url); sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url);
sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
/* /*
* XXX MTK FIXME - we don't look at the tag to see if NUTAG_SUBSTATE(nua_substate_terminated) or * XXX MTK FIXME - we don't look at the tag to see if NUTAG_SUBSTATE(nua_substate_terminated) or
* a Subscription-State header with state "terminated" and/or expiration of 0. So we never forget * a Subscription-State header with state "terminated" and/or expiration of 0. So we never forget
...@@ -141,8 +153,9 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia ...@@ -141,8 +153,9 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia
* so we do what openser's pua_bla does and... * so we do what openser's pua_bla does and...
*/ */
/* We always store the AOR as the sipip and not the request so SLA works with NAT inside out */
aor = switch_mprintf("sip:%s@%s;transport=%s", sip->sip_contact->m_url->url_user, aor = switch_mprintf("sip:%s@%s;transport=%s", sip->sip_contact->m_url->url_user,
sip->sip_from->a_url->url_host, sofia_glue_transport2str(transport)); profile->sipip, sofia_glue_transport2str(transport));
/* /*
* ok, and now that we HAVE the AOR, we REALLY should go check in the XML config and see if this particular * ok, and now that we HAVE the AOR, we REALLY should go check in the XML config and see if this particular
...@@ -163,9 +176,9 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia ...@@ -163,9 +176,9 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia
} }
if ((sql = if ((sql =
switch_mprintf("insert into sip_shared_appearance_subscriptions (subscriber, call_id, aor, profile_name, hostname, contact_str) " switch_mprintf("insert into sip_shared_appearance_subscriptions (subscriber, call_id, aor, profile_name, hostname, contact_str, network_ip) "
"values ('%q','%q','%q','%q','%q','%q')", "values ('%q','%q','%q','%q','%q','%q','%q')",
subscriber, sip->sip_call_id->i_id, aor, profile->name, mod_sofia_globals.hostname, contact_str))) { subscriber, sip->sip_call_id->i_id, aor, profile->name, mod_sofia_globals.hostname, contact_str, network_ip))) {
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
} }
...@@ -187,8 +200,11 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia ...@@ -187,8 +200,11 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia
*p++ = '\0'; *p++ = '\0';
} }
} }
if (sofia_glue_check_nat(profile, network_ip)) {
sla_contact = switch_mprintf("<%s;transport=%s>", profile->sla_contact, sofia_glue_transport2str(transport)); sla_contact = switch_mprintf("<sip:%s@%s;transport=%s>", profile->sla_contact, profile->extsipip, sofia_glue_transport2str(transport));
} else {
sla_contact = switch_mprintf("<sip:%s@%s;transport=%s>", profile->sla_contact, profile->sipip, sofia_glue_transport2str(transport));
}
nua_respond(nh, SIP_202_ACCEPTED, SIPTAG_CONTACT_STR(sla_contact), NUTAG_WITH_THIS(nua), nua_respond(nh, SIP_202_ACCEPTED, SIPTAG_CONTACT_STR(sla_contact), NUTAG_WITH_THIS(nua),
TAG_IF(route_uri, NUTAG_PROXY(route_uri)), TAG_IF(route_uri, NUTAG_PROXY(route_uri)),
...@@ -276,8 +292,9 @@ void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_han ...@@ -276,8 +292,9 @@ void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_han
} }
/* calculate the AOR we're trying to tell people about. should probably double-check before derferencing XXX MTK */ /* calculate the AOR we're trying to tell people about. should probably double-check before derferencing XXX MTK */
/* We always store the AOR as the sipip and not the request so SLA works with NAT inside out */
aor = switch_mprintf("sip:%s@%s;transport=%s", sip->sip_to->a_url->url_user, aor = switch_mprintf("sip:%s@%s;transport=%s", sip->sip_to->a_url->url_user,
sip->sip_to->a_url->url_host, sofia_glue_transport2str(transport)); profile->sipip, sofia_glue_transport2str(transport));
/* this isn't sufficient because on things like the polycom, the subscriber is the 'main' ext number, but the /* this isn't sufficient because on things like the polycom, the subscriber is the 'main' ext number, but the
* 'main' ext number isn't in ANY of the headers they send us in the notify. of course. * 'main' ext number isn't in ANY of the headers they send us in the notify. of course.
...@@ -290,10 +307,9 @@ void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_han ...@@ -290,10 +307,9 @@ void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_han
sip->sip_contact->m_url->url_host, sofia_glue_transport2str(transport)); sip->sip_contact->m_url->url_host, sofia_glue_transport2str(transport));
if (sip->sip_payload && sip->sip_payload->pl_data) { if (sip->sip_payload && sip->sip_payload->pl_data) {
sql = switch_mprintf("select subscriber,call_id,aor,profile_name,hostname,contact_str from sip_shared_appearance_subscriptions where " sql = switch_mprintf("select subscriber,call_id,aor,profile_name,hostname,contact_str,network_ip from sip_shared_appearance_subscriptions where "
"aor='%q' and subscriber<>'%q' and profile_name='%q' and hostname='%q'", "aor='%q' and profile_name='%q' and hostname='%q'",
aor, contact, profile->name, mod_sofia_globals.hostname); aor, profile->name, mod_sofia_globals.hostname);
helper.profile = profile; helper.profile = profile;
helper.payload = sip->sip_payload->pl_data; /* could just send the WHOLE payload. you'd get the type that way. */ helper.payload = sip->sip_payload->pl_data; /* could just send the WHOLE payload. you'd get the type that way. */
...@@ -316,10 +332,11 @@ static int sofia_sla_sub_callback(void *pArg, int argc, char **argv, char **colu ...@@ -316,10 +332,11 @@ static int sofia_sla_sub_callback(void *pArg, int argc, char **argv, char **colu
/* char *profile_name = argv[3]; */ /* char *profile_name = argv[3]; */
/* char *hostname = argv[4]; */ /* char *hostname = argv[4]; */
char *contact_str = argv[5]; char *contact_str = argv[5];
char *network_ip = argv[6];
nua_handle_t *nh; nua_handle_t *nh;
char *route_uri = NULL; char *route_uri = NULL;
char *xml_fixup = NULL;
char *fixup = NULL;
nh = nua_handle_by_call_id(helper->profile->nua, call_id); /* that's all you need to find the subscription's nh */ nh = nua_handle_by_call_id(helper->profile->nua, call_id); /* that's all you need to find the subscription's nh */
if (nh) { if (nh) {
...@@ -343,13 +360,27 @@ static int sofia_sla_sub_callback(void *pArg, int argc, char **argv, char **colu ...@@ -343,13 +360,27 @@ static int sofia_sla_sub_callback(void *pArg, int argc, char **argv, char **colu
} }
} }
if (sofia_test_pflag(helper->profile, PFLAG_AUTO_NAT)) {
if (sofia_glue_check_nat(helper->profile, network_ip)) {
fixup = switch_string_replace(helper->payload, helper->profile->sipip, helper->profile->extsipip);
} else {
fixup = switch_string_replace(helper->payload, helper->profile->extsipip, helper->profile->sipip);
}
xml_fixup = fixup;
} else {
xml_fixup = helper->payload;
}
nua_notify(nh, nua_notify(nh,
SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=300"), /* XXX MTK FIXME - this is totally fake calculation */ SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=300"), /* XXX MTK FIXME - this is totally fake calculation */
TAG_IF(route_uri, NUTAG_PROXY(route_uri)), TAG_IF(route_uri, NUTAG_PROXY(route_uri)),
SIPTAG_CONTENT_TYPE_STR("application/dialog-info+xml"), /* could've just kept the type from the payload */ SIPTAG_CONTENT_TYPE_STR("application/dialog-info+xml"), /* could've just kept the type from the payload */
SIPTAG_PAYLOAD_STR(helper->payload), SIPTAG_PAYLOAD_STR(xml_fixup),
TAG_END()); TAG_END());
switch_safe_free(route_uri); switch_safe_free(route_uri);
if (fixup && fixup != helper->payload) {
free(fixup);
}
} }
return 0; return 0;
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论