mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-03-06 02:22:56 +00:00
support allowing pidf-ful presence clients to share the same account and 'appear offline' without influencing each other =/ also refactor the contact generation string based on nat into a helper function
This commit is contained in:
parent
c4e350ab0c
commit
97a68c50d9
@ -745,6 +745,14 @@ typedef struct {
|
|||||||
char *route_uri;
|
char *route_uri;
|
||||||
} sofia_destination_t;
|
} sofia_destination_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char network_ip[80];
|
||||||
|
int network_port;
|
||||||
|
const char *is_nat;
|
||||||
|
int is_auto_nat;
|
||||||
|
} sofia_nat_parse_t;
|
||||||
|
|
||||||
|
|
||||||
#define sofia_test_pflag(obj, flag) ((obj)->pflags[flag] ? 1 : 0)
|
#define sofia_test_pflag(obj, flag) ((obj)->pflags[flag] ? 1 : 0)
|
||||||
#define sofia_set_pflag(obj, flag) (obj)->pflags[flag] = 1
|
#define sofia_set_pflag(obj, flag) (obj)->pflags[flag] = 1
|
||||||
#define sofia_set_pflag_locked(obj, flag) assert(obj->flag_mutex != NULL);\
|
#define sofia_set_pflag_locked(obj, flag) assert(obj->flag_mutex != NULL);\
|
||||||
@ -1040,3 +1048,4 @@ switch_status_t sofia_glue_sdp_map(const char *r_sdp, switch_event_t **fmtp, swi
|
|||||||
void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl);
|
void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl);
|
||||||
void sofia_glue_check_dtmf_type(private_object_t *tech_pvt);
|
void sofia_glue_check_dtmf_type(private_object_t *tech_pvt);
|
||||||
void sofia_glue_parse_rtp_bugs(uint32_t *flag_pole, const char *str);
|
void sofia_glue_parse_rtp_bugs(uint32_t *flag_pole, const char *str);
|
||||||
|
char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_nat_parse_t *np);
|
||||||
|
@ -6136,6 +6136,129 @@ void sofia_glue_parse_rtp_bugs(uint32_t *flag_pole, const char *str)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_nat_parse_t *np)
|
||||||
|
{
|
||||||
|
char *contact_str = NULL;
|
||||||
|
const char *contact_host, *contact_user;
|
||||||
|
sip_contact_t const *contact;
|
||||||
|
char *port;
|
||||||
|
const char *display = "\"user\"";
|
||||||
|
char new_port[25] = "";
|
||||||
|
sofia_nat_parse_t lnp = { { 0 } };
|
||||||
|
const char *ipv6;
|
||||||
|
sip_from_t const *from;
|
||||||
|
|
||||||
|
if (!sip || !sip->sip_contact || !sip->sip_contact->m_url) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
from = sip->sip_from;
|
||||||
|
contact = sip->sip_contact;
|
||||||
|
|
||||||
|
if (!np) {
|
||||||
|
np = &lnp;
|
||||||
|
}
|
||||||
|
|
||||||
|
sofia_glue_get_addr(nua_current_request(profile->nua), np->network_ip, sizeof(np->network_ip), &np->network_port);
|
||||||
|
|
||||||
|
if (sofia_glue_check_nat(profile, np->network_ip)) {
|
||||||
|
np->is_auto_nat = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
port = (char *) contact->m_url->url_port;
|
||||||
|
contact_host = sip->sip_contact->m_url->url_host;
|
||||||
|
contact_user = sip->sip_contact->m_url->url_user;
|
||||||
|
|
||||||
|
display = contact->m_display;
|
||||||
|
|
||||||
|
|
||||||
|
if (zstr(display)) {
|
||||||
|
if (from) {
|
||||||
|
display = from->a_display;
|
||||||
|
if (zstr(display)) {
|
||||||
|
display = "\"user\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
display = "\"user\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)) {
|
||||||
|
if (sip->sip_via) {
|
||||||
|
const char *v_port = sip->sip_via->v_port;
|
||||||
|
const char *v_host = sip->sip_via->v_host;
|
||||||
|
|
||||||
|
if (v_host && sip->sip_via->v_received) {
|
||||||
|
np->is_nat = "via received";
|
||||||
|
} else if (v_host && strcmp(np->network_ip, v_host)) {
|
||||||
|
np->is_nat = "via host";
|
||||||
|
} else if (v_port && atoi(v_port) != np->network_port) {
|
||||||
|
np->is_nat = "via port";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!np->is_nat && sip && sip->sip_via && sip->sip_via->v_port &&
|
||||||
|
atoi(sip->sip_via->v_port) == 5060 && np->network_port != 5060 ) {
|
||||||
|
np->is_nat = "via port";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!np->is_nat && profile->nat_acl_count) {
|
||||||
|
uint32_t x = 0;
|
||||||
|
int ok = 1;
|
||||||
|
char *last_acl = NULL;
|
||||||
|
|
||||||
|
if (!zstr(contact_host)) {
|
||||||
|
for (x = 0; x < profile->nat_acl_count; x++) {
|
||||||
|
last_acl = profile->nat_acl[x];
|
||||||
|
if (!(ok = switch_check_network_list_ip(contact_host, last_acl))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
np->is_nat = last_acl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (np->is_nat && profile->local_network && switch_check_network_list_ip(np->network_ip, profile->local_network)) {
|
||||||
|
if (profile->debug) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s is on local network, not seting NAT mode.\n", np->network_ip);
|
||||||
|
}
|
||||||
|
np->is_nat = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zstr(contact_host)) {
|
||||||
|
np->is_nat = "No contact host";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (np->is_nat) {
|
||||||
|
contact_host = np->network_ip;
|
||||||
|
switch_snprintf(new_port, sizeof(new_port), ":%d", np->network_port);
|
||||||
|
port = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (port) {
|
||||||
|
switch_snprintf(new_port, sizeof(new_port), ":%s", port);
|
||||||
|
}
|
||||||
|
|
||||||
|
ipv6 = strchr(contact_host, ':');
|
||||||
|
if (contact->m_url->url_params) {
|
||||||
|
contact_str = switch_mprintf("%s <sip:%s@%s%s%s%s;%s>%s",
|
||||||
|
display, contact->m_url->url_user,
|
||||||
|
ipv6 ? "[" : "",
|
||||||
|
contact_host, ipv6 ? "]" : "", new_port, contact->m_url->url_params, np->is_nat ? ";fs_nat=yes" : "");
|
||||||
|
} else {
|
||||||
|
contact_str = switch_mprintf("%s <sip:%s@%s%s%s%s>%s",
|
||||||
|
display,
|
||||||
|
contact->m_url->url_user, ipv6 ? "[" : "", contact_host, ipv6 ? "]" : "", new_port, np->is_nat ? ";fs_nat=yes" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return contact_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -289,7 +289,8 @@ void sofia_presence_cancel(void)
|
|||||||
|
|
||||||
if ((sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
|
if ((sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
|
||||||
"full_via,expires,user_agent,accept,profile_name,network_ip"
|
"full_via,expires,user_agent,accept,profile_name,network_ip"
|
||||||
",-1,'unavailable','unavailable' from sip_subscriptions where expires > -1 and event='presence' and hostname='%q'",
|
",-1,'unavailable','unavailable' from sip_subscriptions where version > -1 and "
|
||||||
|
"expires > -1 and event='presence' and hostname='%q'",
|
||||||
mod_sofia_globals.hostname))) {
|
mod_sofia_globals.hostname))) {
|
||||||
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
||||||
for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
|
for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
|
||||||
@ -322,7 +323,7 @@ void sofia_presence_establish_presence(sofia_profile_t *profile)
|
|||||||
|
|
||||||
if (sofia_glue_execute_sql_callback(profile, profile->ireg_mutex,
|
if (sofia_glue_execute_sql_callback(profile, profile->ireg_mutex,
|
||||||
"select sub_to_user,sub_to_host,'Online','unknown',proto from sip_subscriptions "
|
"select sub_to_user,sub_to_host,'Online','unknown',proto from sip_subscriptions "
|
||||||
"where expires > -1 and proto='ext' or proto='user' or proto='conf'",
|
"where expires > -1 and version > -1 and proto='ext' or proto='user' or proto='conf'",
|
||||||
sofia_presence_resub_callback, &h) != SWITCH_TRUE) {
|
sofia_presence_resub_callback, &h) != SWITCH_TRUE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -435,12 +436,12 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
|
|||||||
if (for_everyone) {
|
if (for_everyone) {
|
||||||
sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
|
sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
|
||||||
"full_via,expires,user_agent,accept,profile_name,network_ip"
|
"full_via,expires,user_agent,accept,profile_name,network_ip"
|
||||||
",'%q','%q' from sip_subscriptions where expires > -1 and event='message-summary' "
|
",'%q','%q' from sip_subscriptions where version > -1 and expires > -1 and event='message-summary' "
|
||||||
"and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%')", stream.data, host, user, host, host);
|
"and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%')", stream.data, host, user, host, host);
|
||||||
} else if (sub_call_id) {
|
} else if (sub_call_id) {
|
||||||
sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
|
sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
|
||||||
"full_via,expires,user_agent,accept,profile_name,network_ip"
|
"full_via,expires,user_agent,accept,profile_name,network_ip"
|
||||||
",'%q','%q' from sip_subscriptions where expires > -1 and event='message-summary' "
|
",'%q','%q' from sip_subscriptions where version > -1 and expires > -1 and event='message-summary' "
|
||||||
"and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%' and call_id='%q')",
|
"and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%' and call_id='%q')",
|
||||||
stream.data, host, user, host, host, sub_call_id);
|
stream.data, host, user, host, host, sub_call_id);
|
||||||
}
|
}
|
||||||
@ -545,7 +546,8 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
|
|||||||
"from sip_subscriptions left join sip_presence on "
|
"from sip_subscriptions left join sip_presence on "
|
||||||
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
|
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
|
||||||
"sip_subscriptions.profile_name=sip_presence.profile_name) "
|
"sip_subscriptions.profile_name=sip_presence.profile_name) "
|
||||||
"where sip_subscriptions.expires > -1 and sip_subscriptions.event='presence' and sip_subscriptions.full_from like '%%%q%%'",
|
"where sip_subscriptions.version > -1 and "
|
||||||
|
"sip_subscriptions.expires > -1 and sip_subscriptions.event='presence' and sip_subscriptions.full_from like '%%%q%%'",
|
||||||
switch_str_nil(status), switch_str_nil(rpid), from);
|
switch_str_nil(status), switch_str_nil(rpid), from);
|
||||||
} else {
|
} else {
|
||||||
sql = switch_mprintf("select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
|
sql = switch_mprintf("select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
|
||||||
@ -557,7 +559,8 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
|
|||||||
"from sip_subscriptions left join sip_presence on "
|
"from sip_subscriptions left join sip_presence on "
|
||||||
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
|
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
|
||||||
"sip_subscriptions.profile_name=sip_presence.profile_name) "
|
"sip_subscriptions.profile_name=sip_presence.profile_name) "
|
||||||
"where sip_subscriptions.expires > -1 and sip_subscriptions.event='presence'", switch_str_nil(status),
|
"where sip_subscriptions.version > -1 and "
|
||||||
|
"sip_subscriptions.expires > -1 and sip_subscriptions.event='presence'", switch_str_nil(status),
|
||||||
switch_str_nil(rpid));
|
switch_str_nil(rpid));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -833,7 +836,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
|
|||||||
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
|
"(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
|
||||||
"sip_subscriptions.profile_name=sip_presence.profile_name) "
|
"sip_subscriptions.profile_name=sip_presence.profile_name) "
|
||||||
|
|
||||||
"where sip_subscriptions.expires > -1 and "
|
"where sip_subscriptions.version > -1 and sip_subscriptions.expires > -1 and "
|
||||||
"(event='%q' or event='%q') and sub_to_user='%q' "
|
"(event='%q' or event='%q') and sub_to_user='%q' "
|
||||||
"and (sub_to_host='%q' or presence_hosts like '%%%q%%') "
|
"and (sub_to_host='%q' or presence_hosts like '%%%q%%') "
|
||||||
"and (sip_subscriptions.profile_name = '%q' or sip_subscriptions.presence_hosts != sip_subscriptions.sub_to_host) ",
|
"and (sip_subscriptions.profile_name = '%q' or sip_subscriptions.presence_hosts != sip_subscriptions.sub_to_host) ",
|
||||||
@ -2009,13 +2012,13 @@ static void sync_sla(sofia_profile_t *profile, const char *to_user, const char *
|
|||||||
if (unseize) {
|
if (unseize) {
|
||||||
sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event "
|
sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event "
|
||||||
"from sip_subscriptions "
|
"from sip_subscriptions "
|
||||||
"where expires > -1 and hostname='%q' "
|
"where version > -1 and expires > -1 and hostname='%q' "
|
||||||
"and sub_to_user='%q' and sub_to_host='%q' "
|
"and sub_to_user='%q' and sub_to_host='%q' "
|
||||||
"and (event='call-info' or event='line-seize')", mod_sofia_globals.hostname, to_user, to_host);
|
"and (event='call-info' or event='line-seize')", mod_sofia_globals.hostname, to_user, to_host);
|
||||||
} else {
|
} else {
|
||||||
sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event "
|
sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event "
|
||||||
"from sip_subscriptions "
|
"from sip_subscriptions "
|
||||||
"where expires > -1 and hostname='%q' "
|
"where version > -1 and expires > -1 and hostname='%q' "
|
||||||
"and sub_to_user='%q' and sub_to_host='%q' " "and (event='call-info')", mod_sofia_globals.hostname, to_user, to_host);
|
"and sub_to_user='%q' and sub_to_host='%q' " "and (event='call-info')", mod_sofia_globals.hostname, to_user, to_host);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2044,18 +2047,15 @@ static void sync_sla(sofia_profile_t *profile, const char *to_user, const char *
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void sofia_presence_handle_sip_i_subscribe(int status,
|
void sofia_presence_handle_sip_i_subscribe(int status,
|
||||||
char const *phrase,
|
char const *phrase,
|
||||||
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
|
nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
|
||||||
tagi_t tags[])
|
tagi_t tags[])
|
||||||
{
|
{
|
||||||
if (sip) {
|
|
||||||
long exp_abs, exp_delta;
|
long exp_abs, exp_delta;
|
||||||
char exp_delta_str[30] = "";
|
char exp_delta_str[30] = "";
|
||||||
sip_to_t const *to = sip->sip_to;
|
sip_to_t const *to;
|
||||||
sip_from_t const *from = sip->sip_from;
|
|
||||||
sip_contact_t const *contact = sip->sip_contact;
|
|
||||||
const char *from_user = NULL, *from_host = NULL;
|
const char *from_user = NULL, *from_host = NULL;
|
||||||
const char *to_user = NULL, *to_host = NULL;
|
const char *to_user = NULL, *to_host = NULL;
|
||||||
char *my_to_user = NULL;
|
char *my_to_user = NULL;
|
||||||
@ -2069,129 +2069,33 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
|||||||
char *full_via = NULL;
|
char *full_via = NULL;
|
||||||
char *full_agent = NULL;
|
char *full_agent = NULL;
|
||||||
char *sstr;
|
char *sstr;
|
||||||
const char *display = "\"user\"";
|
|
||||||
switch_event_t *sevent;
|
switch_event_t *sevent;
|
||||||
int sub_state;
|
int sub_state;
|
||||||
int sent_reply = 0;
|
int sent_reply = 0;
|
||||||
int network_port = 0;
|
sip_contact_t const *contact;
|
||||||
char network_ip[80];
|
|
||||||
const char *contact_host, *contact_user;
|
|
||||||
char *port;
|
|
||||||
char new_port[25] = "";
|
|
||||||
char *is_nat = NULL;
|
|
||||||
int is_auto_nat = 0;
|
|
||||||
const char *ipv6;
|
const char *ipv6;
|
||||||
|
const char *contact_host, *contact_user;
|
||||||
|
sofia_nat_parse_t np = { { 0 } };
|
||||||
|
|
||||||
if (!(contact && sip->sip_contact->m_url)) {
|
if (!sip) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
to = sip->sip_to;
|
||||||
|
contact = sip->sip_contact;
|
||||||
|
|
||||||
|
if (!(contact_str = sofia_glue_gen_contact_str(profile, sip, &np))) {
|
||||||
nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
|
nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
|
contact_host = sip->sip_contact->m_url->url_host;
|
||||||
|
contact_user = sip->sip_contact->m_url->url_user;
|
||||||
if (sofia_glue_check_nat(profile, network_ip)) {
|
|
||||||
is_auto_nat = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END());
|
tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END());
|
||||||
|
|
||||||
event = sip_header_as_string(profile->home, (void *) sip->sip_event);
|
event = sip_header_as_string(profile->home, (void *) sip->sip_event);
|
||||||
|
|
||||||
port = (char *) contact->m_url->url_port;
|
|
||||||
contact_host = sip->sip_contact->m_url->url_host;
|
|
||||||
contact_user = sip->sip_contact->m_url->url_user;
|
|
||||||
|
|
||||||
display = contact->m_display;
|
|
||||||
|
|
||||||
if (zstr(display)) {
|
|
||||||
if (from) {
|
|
||||||
display = from->a_display;
|
|
||||||
if (zstr(display)) {
|
|
||||||
display = "\"user\"";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
display = "\"user\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)) {
|
|
||||||
if (sip && sip->sip_via) {
|
|
||||||
const char *v_port = sip->sip_via->v_port;
|
|
||||||
const char *v_host = sip->sip_via->v_host;
|
|
||||||
|
|
||||||
if (v_host && sip->sip_via->v_received) {
|
|
||||||
is_nat = "via received";
|
|
||||||
} else if (v_host && strcmp(network_ip, v_host)) {
|
|
||||||
is_nat = "via host";
|
|
||||||
} else if (v_port && atoi(v_port) != network_port) {
|
|
||||||
is_nat = "via port";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_nat && sip && sip->sip_via && sip->sip_via->v_port &&
|
|
||||||
atoi(sip->sip_via->v_port) == 5060 && network_port != 5060 ) {
|
|
||||||
is_nat = "via port";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_nat && profile->nat_acl_count) {
|
|
||||||
uint32_t x = 0;
|
|
||||||
int ok = 1;
|
|
||||||
char *last_acl = NULL;
|
|
||||||
|
|
||||||
if (!zstr(contact_host)) {
|
|
||||||
for (x = 0; x < profile->nat_acl_count; x++) {
|
|
||||||
last_acl = profile->nat_acl[x];
|
|
||||||
if (!(ok = switch_check_network_list_ip(contact_host, last_acl))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ok) {
|
|
||||||
is_nat = last_acl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_nat && profile->local_network && switch_check_network_list_ip(network_ip, profile->local_network)) {
|
|
||||||
if (profile->debug) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s is on local network, not seting NAT mode.\n", network_ip);
|
|
||||||
}
|
|
||||||
is_nat = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zstr(contact_host)) {
|
|
||||||
is_nat = "No contact host";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_nat) {
|
|
||||||
contact_host = network_ip;
|
|
||||||
switch_snprintf(new_port, sizeof(new_port), ":%d", network_port);
|
|
||||||
port = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zstr(contact_host)) {
|
|
||||||
nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (port) {
|
|
||||||
switch_snprintf(new_port, sizeof(new_port), ":%s", port);
|
|
||||||
}
|
|
||||||
|
|
||||||
ipv6 = strchr(contact_host, ':');
|
|
||||||
if (contact->m_url->url_params) {
|
|
||||||
contact_str = switch_mprintf("%s <sip:%s@%s%s%s%s;%s>%s",
|
|
||||||
display, contact->m_url->url_user,
|
|
||||||
ipv6 ? "[" : "",
|
|
||||||
contact_host, ipv6 ? "]" : "", new_port, contact->m_url->url_params, is_nat ? ";fs_nat=yes" : "");
|
|
||||||
} else {
|
|
||||||
contact_str = switch_mprintf("%s <sip:%s@%s%s%s%s>%s",
|
|
||||||
display,
|
|
||||||
contact->m_url->url_user, ipv6 ? "[" : "", contact_host, ipv6 ? "]" : "", new_port, is_nat ? ";fs_nat=yes" : "");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* the following could be refactored back to the calling event handler in sofia.c XXX MTK */
|
/* the following could be refactored back to the calling event handler in sofia.c XXX MTK */
|
||||||
if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
|
if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
|
||||||
@ -2205,8 +2109,6 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (to) {
|
if (to) {
|
||||||
to_str = switch_mprintf("sip:%s@%s", to->a_url->url_user, to->a_url->url_host);
|
to_str = switch_mprintf("sip:%s@%s", to->a_url->url_user, to->a_url->url_host);
|
||||||
}
|
}
|
||||||
@ -2220,7 +2122,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
|||||||
to_host = profile->sub_domain;
|
to_host = profile->sub_domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sip && sip->sip_from) {
|
if (sip->sip_from) {
|
||||||
from_user = sip->sip_from->a_url->url_user;
|
from_user = sip->sip_from->a_url->url_user;
|
||||||
from_host = sip->sip_from->a_url->url_host;
|
from_host = sip->sip_from->a_url->url_host;
|
||||||
} else {
|
} else {
|
||||||
@ -2266,7 +2168,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
|||||||
full_from = sip_header_as_string(profile->home, (void *) sip->sip_from);
|
full_from = sip_header_as_string(profile->home, (void *) sip->sip_from);
|
||||||
full_via = sip_header_as_string(profile->home, (void *) sip->sip_via);
|
full_via = sip_header_as_string(profile->home, (void *) sip->sip_via);
|
||||||
|
|
||||||
if (sip && sip->sip_expires && sip->sip_expires->ex_delta > 31536000) {
|
if (sip->sip_expires && sip->sip_expires->ex_delta > 31536000) {
|
||||||
sip->sip_expires->ex_delta = 31536000;
|
sip->sip_expires->ex_delta = 31536000;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2307,7 +2209,7 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
|||||||
event, contact_str, call_id, full_from, full_via,
|
event, contact_str, call_id, full_from, full_via,
|
||||||
//sofia_test_pflag(profile, PFLAG_MULTIREG) ? switch_epoch_time_now(NULL) + exp_delta : exp_delta * -1,
|
//sofia_test_pflag(profile, PFLAG_MULTIREG) ? switch_epoch_time_now(NULL) + exp_delta : exp_delta * -1,
|
||||||
(long) switch_epoch_time_now(NULL) + (exp_delta * 2),
|
(long) switch_epoch_time_now(NULL) + (exp_delta * 2),
|
||||||
full_agent, accept, profile->name, mod_sofia_globals.hostname, network_port, network_ip);
|
full_agent, accept, profile->name, mod_sofia_globals.hostname, np.network_port, np.network_ip);
|
||||||
|
|
||||||
switch_assert(sql != NULL);
|
switch_assert(sql != NULL);
|
||||||
|
|
||||||
@ -2328,16 +2230,16 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
|||||||
char *contactstr = profile->url, *cs = NULL;
|
char *contactstr = profile->url, *cs = NULL;
|
||||||
char *p = NULL, *new_contactstr = NULL;
|
char *p = NULL, *new_contactstr = NULL;
|
||||||
|
|
||||||
if (is_nat) {
|
if (np.is_nat) {
|
||||||
char params[128] = "";
|
char params[128] = "";
|
||||||
if (contact->m_url->url_params) {
|
if (contact->m_url->url_params) {
|
||||||
switch_snprintf(params, sizeof(params), ";%s", contact->m_url->url_params);
|
switch_snprintf(params, sizeof(params), ";%s", contact->m_url->url_params);
|
||||||
}
|
}
|
||||||
ipv6 = strchr(network_ip, ':');
|
ipv6 = strchr(np.network_ip, ':');
|
||||||
sticky = switch_mprintf("sip:%s@%s%s%s:%d%s", contact_user, ipv6 ? "[" : "", network_ip, ipv6 ? "]" : "", network_port, params);
|
sticky = switch_mprintf("sip:%s@%s%s%s:%d%s", contact_user, ipv6 ? "[" : "", np.network_ip, ipv6 ? "]" : "", np.network_port, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_auto_nat) {
|
if (np.is_auto_nat) {
|
||||||
contactstr = profile->public_url;
|
contactstr = profile->public_url;
|
||||||
} else {
|
} else {
|
||||||
contactstr = profile->url;
|
contactstr = profile->url;
|
||||||
@ -2345,13 +2247,13 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
|||||||
|
|
||||||
|
|
||||||
if (switch_stristr("port=tcp", contact->m_url->url_params)) {
|
if (switch_stristr("port=tcp", contact->m_url->url_params)) {
|
||||||
if (is_auto_nat) {
|
if (np.is_auto_nat) {
|
||||||
cs = profile->tcp_public_contact;
|
cs = profile->tcp_public_contact;
|
||||||
} else {
|
} else {
|
||||||
cs = profile->tcp_contact;
|
cs = 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)) {
|
||||||
if (is_auto_nat) {
|
if (np.is_auto_nat) {
|
||||||
cs = profile->tls_public_contact;
|
cs = profile->tls_public_contact;
|
||||||
} else {
|
} else {
|
||||||
cs = profile->tls_contact;
|
cs = profile->tls_contact;
|
||||||
@ -2474,7 +2376,8 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
|||||||
if (!strcasecmp(event, "message-summary")) {
|
if (!strcasecmp(event, "message-summary")) {
|
||||||
if ((sql = switch_mprintf("select proto,sip_user,'%q',sub_to_user,sub_to_host,event,contact,call_id,full_from,"
|
if ((sql = switch_mprintf("select proto,sip_user,'%q',sub_to_user,sub_to_host,event,contact,call_id,full_from,"
|
||||||
"full_via,expires,user_agent,accept,profile_name,network_ip"
|
"full_via,expires,user_agent,accept,profile_name,network_ip"
|
||||||
" from sip_subscriptions where expires > -1 and event='message-summary' and sip_user='%q' "
|
" from sip_subscriptions where version > -1 and "
|
||||||
|
"expires > -1 and event='message-summary' and sip_user='%q' "
|
||||||
"and (sip_host='%q' or presence_hosts like '%%%q%%')", to_host, to_user, to_host, to_host))) {
|
"and (sip_host='%q' or presence_hosts like '%%%q%%')", to_host, to_user, to_host, to_host))) {
|
||||||
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_sub_reg_callback, profile);
|
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_sub_reg_callback, profile);
|
||||||
|
|
||||||
@ -2540,9 +2443,10 @@ void sofia_presence_handle_sip_i_subscribe(int status,
|
|||||||
if (!sent_reply) {
|
if (!sent_reply) {
|
||||||
nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
|
nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sofia_gateway_subscription_t *sofia_find_gateway_subscription(sofia_gateway_t *gateway_ptr, const char *event)
|
sofia_gateway_subscription_t *sofia_find_gateway_subscription(sofia_gateway_t *gateway_ptr, const char *event)
|
||||||
{
|
{
|
||||||
sofia_gateway_subscription_t *gw_sub_ptr;
|
sofia_gateway_subscription_t *gw_sub_ptr;
|
||||||
@ -2624,20 +2528,53 @@ void sofia_presence_handle_sip_r_subscribe(int status,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int sofia_counterpath_crutch(void *pArg, int argc, char **argv, char **columnNames)
|
||||||
|
{
|
||||||
|
nua_handle_t *nh;
|
||||||
|
sofia_profile_t *profile = (sofia_profile_t *) pArg;
|
||||||
|
char *call_id = argv[0];
|
||||||
|
char *pl = argv[1];
|
||||||
|
char *event_type = argv[2];
|
||||||
|
long exp_delta = atol(argv[3]);
|
||||||
|
|
||||||
|
if ((nh = nua_handle_by_call_id(profile->nua, call_id))) {
|
||||||
|
char sstr[128] = "", expstr[128] = "";
|
||||||
|
switch_snprintf(expstr, sizeof(expstr), "%d", exp_delta);
|
||||||
|
switch_snprintf(sstr, sizeof(sstr), "active;expires=%u", exp_delta);
|
||||||
|
nua_notify(nh,
|
||||||
|
NUTAG_WITH_THIS(profile->nua),
|
||||||
|
SIPTAG_EXPIRES_STR(expstr),
|
||||||
|
SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_EVENT_STR(event_type),
|
||||||
|
SIPTAG_CONTENT_TYPE_STR("application/pidf+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END());
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
|
void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
|
||||||
tagi_t tags[])
|
tagi_t tags[])
|
||||||
{
|
{
|
||||||
if (sip) {
|
|
||||||
sip_from_t const *from = sip->sip_from;
|
sip_from_t const *from;
|
||||||
char *from_user = NULL;
|
char *from_user = NULL;
|
||||||
char *from_host = NULL;
|
char *from_host = NULL;
|
||||||
char *rpid = "";
|
char *rpid = "";
|
||||||
sip_payload_t *payload = sip->sip_payload;
|
sip_payload_t *payload;
|
||||||
char *event_type = NULL;
|
char *event_type = NULL;
|
||||||
char etag[9] = "";
|
char etag[9] = "";
|
||||||
char expstr[30] = "";
|
char expstr[30] = "";
|
||||||
long exp = 0, exp_delta = 3600;
|
long exp = 0, exp_delta = 3600;
|
||||||
char *pd_dup = NULL;
|
char *pd_dup = NULL;
|
||||||
|
int count = 1;
|
||||||
|
char *contact_str;
|
||||||
|
int open = 1;
|
||||||
|
|
||||||
|
if (!sip) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
from = sip->sip_from;
|
||||||
|
payload = sip->sip_payload;
|
||||||
|
|
||||||
/* the following could instead be refactored back to the calling event handler in sofia.c XXX MTK */
|
/* the following could instead be refactored back to the calling event handler in sofia.c XXX MTK */
|
||||||
if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
|
if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
|
||||||
@ -2648,12 +2585,13 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
contact_str = sofia_glue_gen_contact_str(profile, sip, NULL);
|
||||||
|
|
||||||
if (from) {
|
if (from) {
|
||||||
from_user = (char *) from->a_url->url_user;
|
from_user = (char *) from->a_url->url_user;
|
||||||
from_host = (char *) from->a_url->url_host;
|
from_host = (char *) from->a_url->url_host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
exp_delta = (sip->sip_expires ? sip->sip_expires->ex_delta : 3600);
|
exp_delta = (sip->sip_expires ? sip->sip_expires->ex_delta : 3600);
|
||||||
if (profile->force_publish_expires) {
|
if (profile->force_publish_expires) {
|
||||||
exp_delta = profile->force_publish_expires;
|
exp_delta = profile->force_publish_expires;
|
||||||
@ -2670,7 +2608,6 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
|
|||||||
switch_event_t *event;
|
switch_event_t *event;
|
||||||
char *sql;
|
char *sql;
|
||||||
char *full_agent = NULL;
|
char *full_agent = NULL;
|
||||||
int count = 1;
|
|
||||||
|
|
||||||
pd_dup = strdup(payload->pl_data);
|
pd_dup = strdup(payload->pl_data);
|
||||||
|
|
||||||
@ -2698,10 +2635,21 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sofia_test_pflag(profile, PFLAG_MULTIREG) && !strcasecmp(open_closed, "closed")) {
|
if (!(open = !strcasecmp(open_closed, "open"))) {
|
||||||
|
sql = switch_mprintf("update sip_subscriptions set version = -1 where contact='%q'", contact_str);
|
||||||
|
} else {
|
||||||
|
sql = switch_mprintf("update sip_subscriptions set version = 0 where contact='%q'", contact_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
||||||
|
|
||||||
|
|
||||||
|
if (sofia_test_pflag(profile, PFLAG_MULTIREG) && !open) {
|
||||||
char buf[32] = "";
|
char buf[32] = "";
|
||||||
|
|
||||||
sql = switch_mprintf("select count(*) from sip_registrations where sip_user='%q' and orig_server_host='%q'", from_user, from_host);
|
sql = switch_mprintf("select count(*) from sip_registrations where "
|
||||||
|
"sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')", from_user, from_host, from_host);
|
||||||
|
|
||||||
sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf));
|
sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf));
|
||||||
switch_safe_free(sql);
|
switch_safe_free(sql);
|
||||||
count = atoi(buf);
|
count = atoi(buf);
|
||||||
@ -2710,6 +2658,8 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
|
|||||||
|
|
||||||
/* if (count > 1) let's not and say we did or all the clients who subscribe to their own presence will think they selves is offline */
|
/* if (count > 1) let's not and say we did or all the clients who subscribe to their own presence will think they selves is offline */
|
||||||
|
|
||||||
|
event_type = sip_header_as_string(profile->home, (void *) sip->sip_event);
|
||||||
|
|
||||||
if (count < 2) {
|
if (count < 2) {
|
||||||
if ((sql =
|
if ((sql =
|
||||||
switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' "
|
switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' "
|
||||||
@ -2726,8 +2676,14 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
|
|||||||
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} else if (contact_str) {
|
||||||
|
sql = switch_mprintf("select call_id,'%q','%q','%ld' from sip_subscriptions where sub_to_user='%q' and sub_to_host='%q' "
|
||||||
|
"and contact = '%q' ", payload->pl_data ? payload->pl_data : "", event_type, exp_delta,
|
||||||
|
from_user, from_host, contact_str);
|
||||||
|
sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_counterpath_crutch, profile);
|
||||||
|
switch_safe_free(sql);
|
||||||
|
}
|
||||||
|
|
||||||
event_type = sip_header_as_string(profile->home, (void *) sip->sip_event);
|
|
||||||
|
|
||||||
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
|
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
|
||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
|
||||||
@ -2739,7 +2695,6 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
|
|||||||
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", event_type);
|
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", event_type);
|
||||||
switch_event_fire(&event);
|
switch_event_fire(&event);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (event_type) {
|
if (event_type) {
|
||||||
su_free(profile->home, event_type);
|
su_free(profile->home, event_type);
|
||||||
@ -2762,7 +2717,8 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n
|
|||||||
switch_snprintf(expstr, sizeof(expstr), "%d", exp_delta);
|
switch_snprintf(expstr, sizeof(expstr), "%d", exp_delta);
|
||||||
switch_stun_random_string(etag, 8, NULL);
|
switch_stun_random_string(etag, 8, NULL);
|
||||||
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), SIPTAG_ETAG_STR(etag), SIPTAG_EXPIRES_STR(expstr), TAG_END());
|
nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), SIPTAG_ETAG_STR(etag), SIPTAG_EXPIRES_STR(expstr), TAG_END());
|
||||||
}
|
|
||||||
|
switch_safe_free(contact_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sofia_presence_set_hash_key(char *hash_key, int32_t len, sip_t const *sip)
|
void sofia_presence_set_hash_key(char *hash_key, int32_t len, sip_t const *sip)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user