[Freeswitch-svn] [commit] r8511 - freeswitch/trunk/src/mod/endpoints/mod_sofia
Freeswitch SVN
anthm at freeswitch.org
Wed May 21 17:49:27 EDT 2008
Author: anthm
Date: Wed May 21 17:49:27 2008
New Revision: 8511
Modified:
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c
freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c
Log:
swatting at NAT
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.h Wed May 21 17:49:27 2008
@@ -556,7 +556,7 @@
switch_call_cause_t sofia_glue_sip_cause_to_freeswitch(int status);
void sofia_glue_do_xfer_invite(switch_core_session_t *session);
uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip,
- sofia_regtype_t regtype, char *key, uint32_t keylen, switch_event_t **v_event);
+ sofia_regtype_t regtype, char *key, uint32_t keylen, switch_event_t **v_event, const char *is_nat);
extern switch_endpoint_interface_t *sofia_endpoint_interface;
void sofia_presence_set_chat_hash(private_object_t *tech_pvt, sip_t const *sip);
switch_status_t sofia_on_hangup(switch_core_session_t *session);
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c Wed May 21 17:49:27 2008
@@ -2670,7 +2670,9 @@
const char *port = sip->sip_via->v_port;
const char *host = sip->sip_via->v_host;
- if (host && strcmp(network_ip, host)) {
+ if (host && sip->sip_via->v_received) {
+ is_nat = "via received";
+ } else if (host && strcmp(network_ip, host)) {
is_nat = "via host";
} else if (port && atoi(port) != network_port) {
is_nat = "via port";
@@ -2737,7 +2739,7 @@
if (!strcmp(network_ip, profile->sipip) && network_port == profile->sip_port) {
calling_myself++;
} else {
- if (sofia_reg_handle_register(nua, profile, nh, sip, REG_INVITE, key, sizeof(key), &v_event)) {
+ if (sofia_reg_handle_register(nua, profile, nh, sip, REG_INVITE, key, sizeof(key), &v_event, NULL)) {
if (v_event) {
switch_event_destroy(&v_event);
}
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c Wed May 21 17:49:27 2008
@@ -1136,7 +1136,7 @@
char *sub_to_user = argv[0];
char *sub_to_host = argv[1];
char *event = "message-summary";
- char *contact = argv[2];
+ char *contact, *o_contact = argv[2];
char *body = argv[3];
char *id = NULL;
nua_handle_t *nh;
@@ -1145,7 +1145,7 @@
id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
- contact = sofia_glue_get_url_from_contact(contact, 0);
+ contact = sofia_glue_get_url_from_contact(o_contact, 1);
nh = nua_handle(h->profile->nua, NULL,
NUTAG_URL(contact),
@@ -1156,8 +1156,10 @@
nua_notify(nh,
NUTAG_NEWSUB(1),
+ TAG_IF(strstr(o_contact, ";nat"), NUTAG_PROXY(contact)),
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(id);
return 0;
@@ -1189,40 +1191,97 @@
switch_event_t *sevent;
int sub_state;
int sent_reply = 0;
+ su_addrinfo_t *my_addrinfo = msg_addrinfo(nua_current_request(nua));
+ int network_port = 0;
+ char network_ip[80];
+ const char *contact_host, *contact_user;
+ char *port;
+ char new_port[25] = "";
+ char *is_nat = NULL;
+
+ if (!(contact && sip->sip_contact->m_url)) {
+ nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
+ return;
+ }
+
+ get_addr(network_ip, sizeof(network_ip), &((struct sockaddr_in *) my_addrinfo->ai_addr)->sin_addr);
+ network_port = ntohs(((struct sockaddr_in *) msg_addrinfo(nua_current_request(nua))->ai_addr)->sin_port);
tl_gets(tags,
NUTAG_SUBSTATE_REF(sub_state), TAG_END());
event = sip_header_as_string(profile->home, (void *) sip->sip_event);
- if (contact) {
- char *port = (char *) contact->m_url->url_port;
- char new_port[25] = "";
-
- display = contact->m_display;
-
- if (switch_strlen_zero(display)) {
- if (from) {
- display = from->a_display;
- if (switch_strlen_zero(display)) {
- display = "\"user\"";
- }
+ 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 (switch_strlen_zero(display)) {
+ if (from) {
+ display = from->a_display;
+ if (switch_strlen_zero(display)) {
+ display = "\"user\"";
}
- } else {
- display = "\"user\"";
}
-
- if (port) {
- switch_snprintf(new_port, sizeof(new_port), ":%s", port);
+ } else {
+ display = "\"user\"";
+ }
+
+ if ((profile->pflags & PFLAG_AGGRESSIVE_NAT_DETECTION)) {
+ if (sip && sip->sip_via) {
+ const char *port = sip->sip_via->v_port;
+ const char *host = sip->sip_via->v_host;
+
+ if (host && sip->sip_via->v_received) {
+ is_nat = "via received";
+ } else if (host && strcmp(network_ip, host)) {
+ is_nat = "via host";
+ } else if (port && atoi(port) != network_port) {
+ is_nat = "via port";
+ }
}
+ }
- if (contact->m_url->url_params) {
- contact_str = switch_mprintf("%s <sip:%s@%s%s;%s>",
- display, contact->m_url->url_user, contact->m_url->url_host, new_port, contact->m_url->url_params);
- } else {
- contact_str = switch_mprintf("%s <sip:%s@%s%s>", display, contact->m_url->url_user, contact->m_url->url_host, new_port);
+ if (!is_nat && profile->nat_acl_count) {
+ uint32_t x = 0;
+ int ok = 1;
+ char *last_acl = NULL;
+
+ if (!switch_strlen_zero(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) {
+ contact_host = network_ip;
+ switch_snprintf(new_port, sizeof(new_port), ":%d", network_port);
+ port = NULL;
+ }
+
+
+ if (port) {
+ switch_snprintf(new_port, sizeof(new_port), ":%s", port);
+ }
+
+ if (contact->m_url->url_params) {
+ contact_str = switch_mprintf("%s <sip:%s@%s%s;%s>%s",
+ display, contact->m_url->url_user, contact_host, new_port, contact->m_url->url_params, is_nat ? ";nat" : "");
+ } else {
+ contact_str = switch_mprintf("%s <sip:%s@%s%s>%s", display, contact->m_url->url_user, contact_host, new_port, is_nat ? ";nat" : "");
+ }
+
if (to) {
to_str = switch_mprintf("sip:%s@%s", to->a_url->url_user, to->a_url->url_host); //, to->a_url->url_port);
@@ -1336,14 +1395,25 @@
switch_mutex_unlock(profile->ireg_mutex);
+
if (status < 200) {
- nua_respond(nh, SIP_202_ACCEPTED,
+ char *sticky = NULL;
+
+ if (is_nat) {
+ sticky = switch_mprintf("sip:%s@%s:%d", contact_user, network_ip, network_port);
+ }
+
+ nua_respond(nh, SIP_202_ACCEPTED,
NUTAG_WITH_THIS(nua),
SIPTAG_SUBSCRIPTION_STATE_STR(sstr),
+ TAG_IF(sticky, NUTAG_PROXY(sticky)),
//SIPTAG_FROM(sip->sip_to),
//SIPTAG_TO(sip->sip_from),
//SIPTAG_CONTACT_STR(contact_str),
TAG_END());
+
+ switch_safe_free(sticky);
+
}
sent_reply++;
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c Wed May 21 17:49:27 2008
@@ -333,7 +333,7 @@
if (now) {
- switch_snprintf(sql, sizeof(sql), "select * from sip_registrations where status like '%%NATHACK%%'");
+ switch_snprintf(sql, sizeof(sql), "select * from sip_registrations where status like '%%AUTO-NAT%%'");
sofia_glue_execute_sql_callback(profile,
SWITCH_TRUE,
NULL,
@@ -414,7 +414,7 @@
}
uint8_t sofia_reg_handle_register(nua_t * nua, sofia_profile_t *profile, nua_handle_t * nh, sip_t const *sip, sofia_regtype_t regtype, char *key,
- uint32_t keylen, switch_event_t **v_event)
+ uint32_t keylen, switch_event_t **v_event, const char *is_nat)
{
sip_to_t const *to = NULL;
sip_expires_t const *expires = NULL;
@@ -466,7 +466,15 @@
const char *port = contact->m_url->url_port;
char new_port[25] = "";
display = contact->m_display;
-
+ const char *contact_host = contact->m_url->url_host;
+
+ if (is_nat) {
+ reg_desc = "Registered(AUTO-NAT)";
+ contact_host = network_ip;
+ switch_snprintf(new_port, sizeof(new_port), ":%d", network_port);
+ port = NULL;
+ }
+
if (switch_strlen_zero(display)) {
if (to) {
display = to->a_display;
@@ -481,10 +489,10 @@
}
if (contact->m_url->url_params) {
- switch_snprintf(contact_str, sizeof(contact_str), "%s <sip:%s@%s%s;%s>",
- display, contact->m_url->url_user, contact->m_url->url_host, new_port, contact->m_url->url_params);
+ switch_snprintf(contact_str, sizeof(contact_str), "%s <sip:%s@%s%s;%s>%s",
+ display, contact->m_url->url_user, contact_host, new_port, contact->m_url->url_params, is_nat ? ";nat" : "");
} else {
- switch_snprintf(contact_str, sizeof(contact_str), "%s <sip:%s@%s%s>", display, contact->m_url->url_user, contact->m_url->url_host, new_port);
+ switch_snprintf(contact_str, sizeof(contact_str), "%s <sip:%s@%s%s>%s", display, contact->m_url->url_user, contact_host, new_port, is_nat ? ";nat" : "");
}
}
@@ -537,7 +545,7 @@
if (strstr(v_contact_str, "tls")) {
reg_desc = "Registered(TLSHACK)";
} else {
- reg_desc = "Registered(NATHACK)";
+ reg_desc = "Registered(AUTO-NAT)";
exptime = 20;
}
nat_hack = 1;
@@ -609,8 +617,6 @@
sql = switch_mprintf("insert into sip_registrations values ('%q', '%q','%q','%q','%q', '%q', %ld, '%q')", call_id,
to_user, to_host, contact_str, reg_desc,
rpid, (long) switch_timestamp(NULL) + (long) exptime * 2, agent);
-
-
if (sql) {
sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
}
@@ -747,6 +753,7 @@
su_addrinfo_t *my_addrinfo = msg_addrinfo(nua_current_request(nua));
sofia_regtype_t type = REG_REGISTER;
int network_port = 0;
+ char *is_nat = NULL;
get_addr(network_ip, sizeof(network_ip), &((struct sockaddr_in *) my_addrinfo->ai_addr)->sin_addr);
network_port = ntohs(((struct sockaddr_in *) msg_addrinfo(nua_current_request(nua))->ai_addr)->sin_port);
@@ -765,6 +772,45 @@
goto end;
}
+ if ((profile->pflags & PFLAG_AGGRESSIVE_NAT_DETECTION)) {
+ if (sip && sip->sip_via) {
+ const char *port = sip->sip_via->v_port;
+ const char *host = sip->sip_via->v_host;
+
+ if (host && sip->sip_via->v_received) {
+ is_nat = "via received";
+ } else if (host && strcmp(network_ip, host)) {
+ is_nat = "via host";
+ } else if (port && atoi(port) != network_port) {
+ is_nat = "via port";
+ }
+ }
+ }
+
+ if (!is_nat && profile->nat_acl_count) {
+ uint32_t x = 0;
+ int ok = 1;
+ char *last_acl = NULL;
+ const char *contact_host = NULL;
+
+ if (sip && sip->sip_contact && sip->sip_contact->m_url) {
+ contact_host = sip->sip_contact->m_url->url_host;
+ }
+
+ if (!switch_strlen_zero(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 (profile->reg_acl_count) {
uint32_t x = 0;
int ok = 1;
@@ -796,7 +842,7 @@
goto end;
}
- sofia_reg_handle_register(nua, profile, nh, sip, type, key, sizeof(key), &v_event);
+ sofia_reg_handle_register(nua, profile, nh, sip, type, key, sizeof(key), &v_event, is_nat);
if (v_event) {
switch_event_fire(&v_event);
More information about the Freeswitch-svn
mailing list