[Freeswitch-svn] [commit] r8893 - in freeswitch/trunk/src: . include mod/endpoints/mod_sofia
Freeswitch SVN
mikej at freeswitch.org
Thu Jul 3 14:50:15 EDT 2008
Author: mikej
Date: Thu Jul 3 14:50:15 2008
New Revision: 8893
Modified:
freeswitch/trunk/src/include/switch_utils.h
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia.c
freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c
freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_presence.c
freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_reg.c
freeswitch/trunk/src/switch_apr.c
freeswitch/trunk/src/switch_rtp.c
freeswitch/trunk/src/switch_utils.c
Log:
update
Modified: freeswitch/trunk/src/include/switch_utils.h
==============================================================================
--- freeswitch/trunk/src/include/switch_utils.h (original)
+++ freeswitch/trunk/src/include/switch_utils.h Thu Jul 3 14:50:15 2008
@@ -118,10 +118,44 @@
\brief find the char representation of an ip adress
\param buf the buffer to write the ip adress found into
\param len the length of the buf
- \param in the struct in_addr * to get the adress from
+ \param sa the struct sockaddr * to get the adress from
+ \param salen the length of sa
\return the ip adress string
*/
-SWITCH_DECLARE(char *) get_addr(char *buf, switch_size_t len, struct in_addr *in);
+SWITCH_DECLARE(char *) get_addr(char *buf, switch_size_t len, struct sockaddr *sa, socklen_t salen);
+
+/*!
+ \brief get the port number of an ip address
+ \param sa the struct sockaddr * to get the port from
+ \return the ip adress string
+*/
+SWITCH_DECLARE(unsigned short) get_port(struct sockaddr *sa);
+
+/*!
+ \brief flags to be used with switch_build_uri()
+ */
+enum switch_uri_flags {
+ SWITCH_URI_NUMERIC_HOST = 1,
+ SWITCH_URI_NUMERIC_PORT = 2,
+ SWITCH_URI_NO_SCOPE = 4,
+};
+
+/*!
+ \brief build a URI string from components
+ \param uri output string
+ \param size maximum size of output string (including trailing null)
+ \param scheme URI scheme
+ \param user user part or null if none
+ \param sa host address
+ \param flags logical OR-ed combination of flags from \ref switch_uri_flags
+ \return number of characters printed (not including the trailing null)
+ */
+SWITCH_DECLARE(int) switch_build_uri(char *uri,
+ switch_size_t size,
+ const char *scheme,
+ const char *user,
+ const switch_sockaddr_t *sa,
+ int flags);
#define SWITCH_STATUS_IS_BREAK(x) (x == SWITCH_STATUS_BREAK || x == 730035 || x == 35)
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Thu Jul 3 14:50:15 2008
@@ -926,7 +926,8 @@
char ref_to[128] = "";
if (!strstr(msg->string_arg, "sip:")) {
- switch_snprintf(ref_to, sizeof(ref_to), "sip:%s@%s", msg->string_arg, tech_pvt->profile->sipip);
+ const char *format = strchr(tech_pvt->profile->sipip, ':') ? "sip:%s@[%s]" : "sip:%s@%s";
+ switch_snprintf(ref_to, sizeof(ref_to), format, msg->string_arg, tech_pvt->profile->sipip);
} else {
switch_set_string(ref_to, msg->string_arg);
}
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 Thu Jul 3 14:50:15 2008
@@ -215,7 +215,8 @@
if (authorization) {
char network_ip[80];
- get_addr(network_ip, sizeof(network_ip), &((struct sockaddr_in *) msg_addrinfo(nua_current_request(nua))->ai_addr)->sin_addr);
+ su_addrinfo_t *addrinfo = msg_addrinfo(nua_current_request(nua));
+ get_addr(network_ip, sizeof(network_ip), addrinfo->ai_addr, addrinfo->ai_addrlen);
auth_res = sofia_reg_parse_auth(profile, authorization, sip,
(char *) sip->sip_request->rq_method_name, tech_pvt->key, strlen(tech_pvt->key), network_ip, NULL, 0,
REG_INVITE, NULL);
@@ -749,6 +750,7 @@
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
if ((gateway = switch_core_alloc(profile->pool, sizeof(*gateway)))) {
+ const char *sipip, *format;
char *register_str = "true", *scheme = "Digest",
*realm = NULL,
*username = NULL,
@@ -893,8 +895,11 @@
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,
+
+ sipip = profile->extsipip ? profile->extsipip : profile->sipip;
+ format = strchr(sipip, ':') ? "<sip:%s@[%s]:%d%s>" : "<sip:%s@%s:%d%s>";
+ gateway->register_contact = switch_core_sprintf(gateway->pool, format, extension,
+ sipip,
sofia_glue_transport_has_tls(gateway->register_transport) ? profile->tls_sip_port : profile->
sip_port, params);
@@ -1389,10 +1394,22 @@
profile->sipdomain = switch_core_strdup(profile->pool, profile->sipip);
}
if (profile->extsipip) {
- profile->url = switch_core_sprintf(profile->pool, "sip:mod_sofia@%s:%d", profile->extsipip, profile->sip_port);
+ char *ipv6 = strchr(profile->extsipip, ':');
+ profile->url = switch_core_sprintf(profile->pool,
+ "sip:mod_sofia@%s%s%s:%d",
+ ipv6 ? "[" : "",
+ profile->extsipip,
+ ipv6 ? "]" : "",
+ profile->sip_port);
profile->bindurl = switch_core_sprintf(profile->pool, "%s;maddr=%s", profile->url, profile->sipip);
} else {
- profile->url = switch_core_sprintf(profile->pool, "sip:mod_sofia@%s:%d", profile->sipip, profile->sip_port);
+ char *ipv6 = strchr(profile->sipip, ':');
+ profile->url = switch_core_sprintf(profile->pool,
+ "sip:mod_sofia@%s%s%s:%d",
+ ipv6 ? "[" : "",
+ profile->sipip,
+ ipv6 ? "]" : "",
+ profile->sip_port);
profile->bindurl = profile->url;
}
@@ -1410,12 +1427,37 @@
}
if (profile->extsipip) {
- profile->tls_url = switch_core_sprintf(profile->pool, "sip:mod_sofia@%s:%d", profile->extsipip, profile->tls_sip_port);
+ char *ipv6 = strchr(profile->extsipip, ':');
+ profile->tls_url =
+ switch_core_sprintf(profile->pool,
+ "sip:mod_sofia@%s%s%s:%d",
+ ipv6 ? "[" : "",
+ profile->extsipip, ipv6 ? "]" : "",
+ profile->tls_sip_port);
profile->tls_bindurl =
- switch_core_sprintf(profile->pool, "sips:mod_sofia@%s:%d;maddr=%s", profile->extsipip, profile->tls_sip_port, profile->sipip);
+ switch_core_sprintf(profile->pool,
+ "sips:mod_sofia@%s%s%s:%d;maddr=%s",
+ ipv6 ? "[" : "",
+ profile->extsipip,
+ ipv6 ? "]" : "",
+ profile->tls_sip_port,
+ profile->sipip);
} else {
- profile->tls_url = switch_core_sprintf(profile->pool, "sip:mod_sofia@%s:%d", profile->sipip, profile->tls_sip_port);
- profile->tls_bindurl = switch_core_sprintf(profile->pool, "sips:mod_sofia@%s:%d", profile->sipip, profile->tls_sip_port);
+ char *ipv6 = strchr(profile->sipip, ':');
+ profile->tls_url =
+ switch_core_sprintf(profile->pool,
+ "sip:mod_sofia@%s%s%s:%d",
+ ipv6 ? "[" : "",
+ profile->sipip,
+ ipv6 ? "]" : "",
+ profile->tls_sip_port);
+ profile->tls_bindurl =
+ switch_core_sprintf(profile->pool,
+ "sips:mod_sofia@%s%s%s:%d",
+ ipv6 ? "[" : "",
+ profile->sipip,
+ ipv6 ? "]" : "",
+ profile->tls_sip_port);
}
if (profile->tls_bind_params) {
@@ -2637,7 +2679,7 @@
return;
}
- get_addr(network_ip, sizeof(network_ip), &((struct sockaddr_in *) my_addrinfo->ai_addr)->sin_addr);
+ get_addr(network_ip, sizeof(network_ip), my_addrinfo->ai_addr, my_addrinfo->ai_addrlen);
network_port = ntohs(((struct sockaddr_in *) msg_addrinfo(nua_current_request(nua))->ai_addr)->sin_port);
if ((profile->pflags & PFLAG_AGGRESSIVE_NAT_DETECTION)) {
@@ -2754,9 +2796,17 @@
char tmp[35] = "";
sofia_transport_t transport = sofia_glue_url2transport(sip->sip_contact->m_url);
- tech_pvt->record_route = switch_core_session_sprintf(session, "sip:%s@%s:%d;transport=%s",
- sip->sip_contact->m_url->url_user, tech_pvt->remote_ip,
- tech_pvt->remote_port, sofia_glue_transport2str(transport));
+ const char *ipv6 = strchr(tech_pvt->remote_ip, ':');
+ tech_pvt->record_route =
+ switch_core_session_sprintf(session,
+ "sip:%s@%s%s%s:%d;transport=%s",
+ sip->sip_contact->m_url->url_user,
+ ipv6 ? "[" : "",
+ tech_pvt->remote_ip,
+ ipv6 ? "]" : "",
+ tech_pvt->remote_port,
+ sofia_glue_transport2str(transport));
+
switch_channel_set_variable(channel, "sip_received_ip", tech_pvt->remote_ip);
snprintf(tmp, sizeof(tmp), "%d", tech_pvt->remote_port);
switch_channel_set_variable(channel, "sip_received_port", tmp);
@@ -2871,6 +2921,7 @@
url_set_chanvars(session, sip->sip_to->a_url, sip_to);
if (switch_channel_get_variable(channel, "sip_to_uri")) {
+ const char *ipv6;
host = switch_channel_get_variable(channel, "sip_to_host");
user = switch_channel_get_variable(channel, "sip_to_user");
@@ -2887,7 +2938,14 @@
port = sofia_glue_transport_has_tls(transport) ? profile->tls_sip_port : profile->sip_port;
}
- tech_pvt->to_uri = switch_core_session_sprintf(session, "sip:%s@%s:%d;transport=%s", user, host, port, sofia_glue_transport2str(transport));
+ ipv6 = strchr(host, ':');
+ tech_pvt->to_uri =
+ switch_core_session_sprintf(session,
+ "sip:%s@%s%s%s:%d;transport=%s",
+ user, ipv6 ? "[" : "",
+ host, ipv6 ? "]" : "",
+ port,
+ sofia_glue_transport2str(transport));
if (profile->ndlb & PFLAG_NDLB_TO_IN_200_CONTACT) {
if (strchr(tech_pvt->to_uri, '>')) {
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/sofia_glue.c Thu Jul 3 14:50:15 2008
@@ -44,6 +44,7 @@
uint32_t v_port;
int use_cng = 1;
const char *val;
+ const char *family;
const char *pass_fmtp = switch_channel_get_variable(tech_pvt->channel, "sip_video_fmtp");
const char *ov_fmtp = switch_channel_get_variable(tech_pvt->channel, "sip_force_video_fmtp");
@@ -82,13 +83,14 @@
tech_pvt->session_id++;
+ family = strchr(ip, ':') ? "IP6" : "IP4";
switch_snprintf(buf, sizeof(buf),
"v=0\n"
- "o=FreeSWITCH %010u %010u IN IP4 %s\n"
+ "o=FreeSWITCH %010u %010u IN %s %s\n"
"s=FreeSWITCH\n"
- "c=IN IP4 %s\n" "t=0 0\n"
+ "c=IN %s %s\n" "t=0 0\n"
"a=%s\n"
- "m=audio %d RTP/%sAVP", tech_pvt->owner_id, tech_pvt->session_id, ip, ip, sr, port,
+ "m=audio %d RTP/%sAVP", tech_pvt->owner_id, tech_pvt->session_id, family, ip, family, ip, sr, port,
(!switch_strlen_zero(tech_pvt->local_crypto_key) && switch_test_flag(tech_pvt, TFLAG_SECURE)) ? "S" : "");
@@ -730,7 +732,8 @@
return SWITCH_STATUS_FALSE;
}
- if ((p = (char *) switch_stristr("c=IN IP4 ", tech_pvt->remote_sdp_str))) {
+ if ((p = (char *) switch_stristr("c=IN IP4 ", tech_pvt->remote_sdp_str)) ||
+ (p = (char *) switch_stristr("c=IN IP6 ", tech_pvt->remote_sdp_str))) {
ip_ptr = p + 9;
}
@@ -833,7 +836,8 @@
len = strlen(tech_pvt->local_sdp_str) + 384;
- if ((p = (char *) switch_stristr("c=IN IP4 ", tech_pvt->local_sdp_str))) {
+ if ((p = (char *) switch_stristr("c=IN IP4 ", tech_pvt->local_sdp_str)) ||
+ (p = (char *) switch_stristr("c=IN IP6 ", tech_pvt->local_sdp_str))) {
ip_ptr = p + 9;
}
@@ -956,11 +960,15 @@
check_decode(cid_num, session);
if (!tech_pvt->from_str) {
- tech_pvt->from_str = switch_core_session_sprintf(tech_pvt->session, "\"%s\" <sip:%s%s%s>",
- cid_name,
- cid_num,
- !switch_strlen_zero(cid_num) ? "@" : "",
- tech_pvt->profile->extsipip ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip);
+ const char* sipip = tech_pvt->profile->extsipip ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip;
+ const char* format = strchr(sipip, ':') ? "\"%s\" <sip:%s%s[%s]>" : "\"%s\" <sip:%s%s%s>";
+ tech_pvt->from_str =
+ switch_core_session_sprintf(tech_pvt->session,
+ format,
+ cid_name,
+ cid_num,
+ !switch_strlen_zero(cid_num) ? "@" : "",
+ sipip);
}
if ((alertbuf = switch_channel_get_variable(channel, "alert_info"))) {
@@ -1223,15 +1231,17 @@
private_object_t *tech_pvt = switch_core_session_get_private(session);
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_caller_profile_t *caller_profile;
+ const char *sipip, *format;
switch_assert(tech_pvt != NULL);
caller_profile = switch_channel_get_caller_profile(channel);
- if ((tech_pvt->from_str = switch_core_session_sprintf(session, "\"%s\" <sip:%s@%s>",
- caller_profile->caller_id_name,
- caller_profile->caller_id_number,
- tech_pvt->profile->extsipip ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip))) {
+ sipip = tech_pvt->profile->extsipip ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip;
+ format = strchr(sipip, ':') ? "\"%s\" <sip:%s@[%s]>" : "\"%s\" <sip:%s@%s>";
+ if ((tech_pvt->from_str = switch_core_session_sprintf(session, format,
+ caller_profile->caller_id_name,
+ caller_profile->caller_id_number, sipip))) {
const char *rep = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER);
@@ -1637,7 +1647,7 @@
}
if (!switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "AUDIO RTP [%s] %s:%d->%s:%d codec: %u ms: %d\n",
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "AUDIO RTP [%s] %s port %d -> %s port %d codec: %u ms: %d\n",
switch_channel_get_name(tech_pvt->channel),
tech_pvt->local_sdp_audio_ip,
tech_pvt->local_sdp_audio_port,
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 Thu Jul 3 14:50:15 2008
@@ -1203,13 +1203,14 @@
char *port;
char new_port[25] = "";
char *is_nat = NULL;
+ const char *ipv6;
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);
+ get_addr(network_ip, sizeof(network_ip), my_addrinfo->ai_addr, my_addrinfo->ai_addrlen);
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());
@@ -1279,11 +1280,25 @@
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",
- display, contact->m_url->url_user, contact_host, new_port, contact->m_url->url_params, is_nat ? ";nat" : "");
+ 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 ? ";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" : "");
+ 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 ? ";nat" : "");
}
@@ -1398,7 +1413,13 @@
char *sticky = NULL;
if (is_nat) {
- sticky = switch_mprintf("sip:%s@%s:%d", contact_user, network_ip, network_port);
+ const char *ipv6 = strchr(network_ip, ':');
+ sticky = switch_mprintf("sip:%s@%s%s%s:%d",
+ contact_user,
+ ipv6 ? "[" : "",
+ network_ip,
+ ipv6 ? "]" : "",
+ network_port);
}
nua_respond(nh, SIP_202_ACCEPTED, NUTAG_WITH_THIS(nua), SIPTAG_SUBSCRIPTION_STATE_STR(sstr), TAG_IF(sticky, NUTAG_PROXY(sticky)),
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 Thu Jul 3 14:50:15 2008
@@ -403,6 +403,7 @@
const char *rpid = "unknown";
const char *display = "\"user\"";
char network_ip[80];
+ char url_ip[80];
char *register_gateway = NULL;
int network_port;
const char *reg_desc = "Registered";
@@ -410,12 +411,15 @@
char *force_user;
char received_data[128] = "";
char *path_val = NULL;
-
+ su_addrinfo_t *my_addrinfo = msg_addrinfo(nua_current_request(nua));
+
/* 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);
- get_addr(network_ip, sizeof(network_ip), &((struct sockaddr_in *) msg_addrinfo(nua_current_request(nua))->ai_addr)->sin_addr);
- network_port = ntohs(((struct sockaddr_in *) msg_addrinfo(nua_current_request(nua))->ai_addr)->sin_port);
+ get_addr(network_ip, sizeof(network_ip), my_addrinfo->ai_addr,my_addrinfo->ai_addrlen);
+ network_port = get_port(my_addrinfo->ai_addr);
+
+ snprintf(url_ip, sizeof(url_ip), my_addrinfo->ai_addr->sa_family == AF_INET6 ? "[%s]" : "%s", network_ip);
expires = sip->sip_expires;
authorization = sip->sip_authorization;
@@ -466,7 +470,7 @@
} else {
reg_desc = "Registered(UDP-NAT)";
}
- contact_host = network_ip;
+ contact_host = url_ip;
switch_snprintf(new_port, sizeof(new_port), ":%d", network_port);
port = NULL;
} else {
@@ -501,7 +505,7 @@
}
if (is_nat && (profile->pflags & PFLAG_RECIEVED_IN_NAT_REG_CONTACT)) {
- switch_snprintf(received_data, sizeof(received_data), ";received=\"%s:%d\"", network_ip, network_port);
+ switch_snprintf(received_data, sizeof(received_data), ";received=\"%s:%d\"", url_ip, network_port);
}
if (contact->m_url->url_params) {
@@ -556,16 +560,16 @@
if ((v_contact_str = switch_event_get_header(*v_event, "sip-force-contact"))) {
if (*received_data && (profile->pflags & PFLAG_RECIEVED_IN_NAT_REG_CONTACT)) {
- switch_snprintf(received_data, sizeof(received_data), ";received=\"%s:%d\"", network_ip, network_port);
+ switch_snprintf(received_data, sizeof(received_data), ";received=\"%s:%d\"", url_ip, network_port);
}
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%s;fs_nat=yes>",
- display, contact->m_url->url_user, network_ip, network_port, contact->m_url->url_params, received_data);
+ display, contact->m_url->url_user, url_ip, network_port, contact->m_url->url_params, received_data);
} else {
- switch_snprintf(contact_str, sizeof(contact_str), "%s <sip:%s@%s:%d%s;fs_nat=yes>", display, contact->m_url->url_user, network_ip,
+ switch_snprintf(contact_str, sizeof(contact_str), "%s <sip:%s@%s:%d%s;fs_nat=yes>", display, contact->m_url->url_user, url_ip,
network_port, received_data);
}
if (strstr(v_contact_str, "tls")) {
@@ -762,8 +766,8 @@
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);
+ 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)) {
Modified: freeswitch/trunk/src/switch_apr.c
==============================================================================
--- freeswitch/trunk/src/switch_apr.c (original)
+++ freeswitch/trunk/src/switch_apr.c Thu Jul 3 14:50:15 2008
@@ -630,7 +630,7 @@
if (!in) {
return "";
}
- return get_addr(buf, len, &in->sa.sin.sin_addr);
+ return get_addr(buf, len, (struct sockaddr*)&in->sa, in->salen);
}
SWITCH_DECLARE(uint16_t) switch_sockaddr_get_port(switch_sockaddr_t *sa)
Modified: freeswitch/trunk/src/switch_rtp.c
==============================================================================
--- freeswitch/trunk/src/switch_rtp.c (original)
+++ freeswitch/trunk/src/switch_rtp.c Thu Jul 3 14:50:15 2008
@@ -121,7 +121,13 @@
};
struct switch_rtp {
- switch_socket_t *sock;
+ /*
+ * Two sockets are needed because we might be transcoding protocol families
+ * (e.g. receive over IPv4 and send over IPv6). In case the protocol
+ * families are equal, sock_input == sock_output and only one socket is
+ * used.
+ */
+ switch_socket_t *sock_input, *sock_output;
switch_sockaddr_t *local_addr;
rtp_msg_t send_msg;
@@ -220,7 +226,7 @@
packet = switch_stun_packet_build_header(SWITCH_STUN_BINDING_REQUEST, NULL, buf);
switch_stun_packet_attribute_add_username(packet, rtp_session->ice_user, 32);
bytes = switch_stun_packet_length(packet);
- switch_socket_sendto(rtp_session->sock, rtp_session->remote_addr, 0, (void *) packet, &bytes);
+ switch_socket_sendto(rtp_session->sock_output, rtp_session->remote_addr, 0, (void *) packet, &bytes);
rtp_session->stuncount = 25;
end:
@@ -296,7 +302,7 @@
remote_ip = switch_get_addr(ipbuf, sizeof(ipbuf), rtp_session->from_addr);
switch_stun_packet_attribute_add_binded_address(rpacket, (char *) remote_ip, switch_sockaddr_get_port(rtp_session->from_addr));
bytes = switch_stun_packet_length(rpacket);
- switch_socket_sendto(rtp_session->sock, rtp_session->from_addr, 0, (void *) rpacket, &bytes);
+ switch_socket_sendto(rtp_session->sock_output, rtp_session->from_addr, 0, (void *) rpacket, &bytes);
}
end:
@@ -440,11 +446,11 @@
goto done;
}
- if (rtp_session->sock) {
+ if (rtp_session->sock_input) {
switch_rtp_kill_socket(rtp_session);
}
- if (switch_socket_create(&new_sock, AF_INET, SOCK_DGRAM, 0, rtp_session->pool) != SWITCH_STATUS_SUCCESS) {
+ if (switch_socket_create(&new_sock, switch_sockaddr_get_family(rtp_session->local_addr), SOCK_DGRAM, 0, rtp_session->pool) != SWITCH_STATUS_SUCCESS) {
*err = "Socket Error!";
goto done;
}
@@ -483,12 +489,12 @@
#endif
- old_sock = rtp_session->sock;
- rtp_session->sock = new_sock;
+ old_sock = rtp_session->sock_input;
+ rtp_session->sock_input = new_sock;
new_sock = NULL;
if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_NOBLOCK)) {
- switch_socket_opt_set(rtp_session->sock, SWITCH_SO_NONBLOCK, TRUE);
+ switch_socket_opt_set(rtp_session->sock_input, SWITCH_SO_NONBLOCK, TRUE);
switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_NOBLOCK);
}
@@ -522,6 +528,7 @@
SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, const char **err)
{
switch_sockaddr_t *remote_addr;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
*err = "Success";
if (switch_sockaddr_info_get(&remote_addr, host, SWITCH_UNSPEC, port, 0, rtp_session->pool) != SWITCH_STATUS_SUCCESS || !remote_addr) {
@@ -530,11 +537,32 @@
}
switch_mutex_lock(rtp_session->write_mutex);
+
rtp_session->remote_addr = remote_addr;
rtp_session->remote_port = port;
+
+ if (rtp_session->sock_input &&
+ switch_sockaddr_get_family(rtp_session->remote_addr) ==
+ switch_sockaddr_get_family(rtp_session->local_addr)) {
+ rtp_session->sock_output = rtp_session->sock_input;
+ }
+ else {
+ if (rtp_session->sock_output &&
+ rtp_session->sock_output != rtp_session->sock_input) {
+ switch_socket_close(rtp_session->sock_output);
+ }
+ if ((status = switch_socket_create(&rtp_session->sock_output,
+ switch_sockaddr_get_family(rtp_session->remote_addr),
+ SOCK_DGRAM, 0, rtp_session->pool)) !=
+ SWITCH_STATUS_SUCCESS)
+ {
+ *err = "Socket Error!";
+ }
+ }
+
switch_mutex_unlock(rtp_session->write_mutex);
- return SWITCH_STATUS_SUCCESS;
+ return status;
}
SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_session,
@@ -829,9 +857,9 @@
switch_assert(rtp_session != NULL);
switch_mutex_lock(rtp_session->flag_mutex);
- if (rtp_session->sock) {
+ if (rtp_session->sock_input) {
switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_BREAK);
- switch_socket_sendto(rtp_session->sock, rtp_session->local_addr, 0, (void *) &o, &len);
+ switch_socket_sendto(rtp_session->sock_input, rtp_session->local_addr, 0, (void *) &o, &len);
}
switch_mutex_unlock(rtp_session->flag_mutex);
}
@@ -842,8 +870,11 @@
switch_mutex_lock(rtp_session->flag_mutex);
if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_IO)) {
switch_clear_flag(rtp_session, SWITCH_RTP_FLAG_IO);
- if (rtp_session->sock) {
- switch_socket_shutdown(rtp_session->sock, SWITCH_SHUTDOWN_READWRITE);
+ if (rtp_session->sock_input) {
+ switch_socket_shutdown(rtp_session->sock_input, SWITCH_SHUTDOWN_READWRITE);
+ }
+ if (rtp_session->sock_output && rtp_session->sock_output != rtp_session->sock_input) {
+ switch_socket_shutdown(rtp_session->sock_output, SWITCH_SHUTDOWN_READWRITE);
}
}
switch_mutex_unlock(rtp_session->flag_mutex);
@@ -858,7 +889,7 @@
}
switch_mutex_lock(rtp_session->flag_mutex);
- ret = (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_IO) && rtp_session->sock && rtp_session->remote_addr && rtp_session->ready == 2) ? 1 : 0;
+ ret = (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_IO) && rtp_session->sock_input && rtp_session->sock_output && rtp_session->remote_addr && rtp_session->ready == 2) ? 1 : 0;
switch_mutex_unlock(rtp_session->flag_mutex);
return ret;
@@ -899,10 +930,15 @@
stfu_n_destroy(&(*rtp_session)->jb);
}
- sock = (*rtp_session)->sock;
- (*rtp_session)->sock = NULL;
+ sock = (*rtp_session)->sock_input;
+ (*rtp_session)->sock_input = NULL;
switch_socket_close(sock);
+ if ( (*rtp_session)->sock_output != sock ) {
+ sock = (*rtp_session)->sock_output;
+ (*rtp_session)->sock_output = NULL;
+ switch_socket_close(sock);
+ }
if (switch_test_flag((*rtp_session), SWITCH_RTP_FLAG_VAD)) {
switch_rtp_disable_vad(*rtp_session);
@@ -932,7 +968,7 @@
SWITCH_DECLARE(switch_socket_t *) switch_rtp_get_rtp_socket(switch_rtp_t *rtp_session)
{
- return rtp_session->sock;
+ return rtp_session->sock_input;
}
SWITCH_DECLARE(void) switch_rtp_set_default_samples_per_interval(switch_rtp_t *rtp_session, uint16_t samples_per_interval)
@@ -1096,7 +1132,7 @@
int do_cng = 0;
bytes = sizeof(rtp_msg_t);
- status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock, 0, (void *) &rtp_session->recv_msg, &bytes);
+ status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, &bytes);
if (bytes < 0) {
ret = (int) bytes;
@@ -1184,7 +1220,7 @@
}
if (rtp_session->invalid_handler) {
- rtp_session->invalid_handler(rtp_session, rtp_session->sock, (void *) &rtp_session->recv_msg, bytes, rtp_session->from_addr);
+ rtp_session->invalid_handler(rtp_session, rtp_session->sock_input, (void *) &rtp_session->recv_msg, bytes, rtp_session->from_addr);
}
memset(data, 0, 2);
@@ -1783,7 +1819,7 @@
bytes = sbytes;
}
- if (switch_socket_sendto(rtp_session->sock, rtp_session->remote_addr, 0, (void *) send_msg, &bytes) != SWITCH_STATUS_SUCCESS) {
+ if (switch_socket_sendto(rtp_session->sock_output, rtp_session->remote_addr, 0, (void *) send_msg, &bytes) != SWITCH_STATUS_SUCCESS) {
rtp_session->seq--;
ret = -1;
goto end;
@@ -1889,7 +1925,7 @@
return 0;
}
bytes = frame->packetlen;
- if (switch_socket_sendto(rtp_session->sock, rtp_session->remote_addr, 0, frame->packet, &bytes) != SWITCH_STATUS_SUCCESS) {
+ if (switch_socket_sendto(rtp_session->sock_output, rtp_session->remote_addr, 0, frame->packet, &bytes) != SWITCH_STATUS_SUCCESS) {
return -1;
}
return (int) bytes;
@@ -1971,7 +2007,7 @@
bytes = sbytes;
}
- if (switch_socket_sendto(rtp_session->sock, rtp_session->remote_addr, 0, (void *) &rtp_session->write_msg, &bytes) != SWITCH_STATUS_SUCCESS) {
+ if (switch_socket_sendto(rtp_session->sock_output, rtp_session->remote_addr, 0, (void *) &rtp_session->write_msg, &bytes) != SWITCH_STATUS_SUCCESS) {
rtp_session->seq--;
ret = -1;
goto end;
Modified: freeswitch/trunk/src/switch_utils.c
==============================================================================
--- freeswitch/trunk/src/switch_utils.c (original)
+++ freeswitch/trunk/src/switch_utils.c Thu Jul 3 14:50:15 2008
@@ -757,7 +757,7 @@
goto doh;
}
- switch_copy_string(buf, get_addr(abuf, sizeof(abuf), &iface_out.sin_addr), len);
+ switch_copy_string(buf, get_addr(abuf, sizeof(abuf), (struct sockaddr*)&iface_out, sizeof(iface_out)), len);
status = SWITCH_STATUS_SUCCESS;
}
break;
@@ -768,17 +768,13 @@
memset(&remote, 0, sizeof(struct sockaddr_in6));
remote.sin6_family = AF_INET6;
- switch_inet_pton(AF_INET6, buf, &remote.sin6_addr);
+ switch_inet_pton(AF_INET6, base, &remote.sin6_addr);
remote.sin6_port = htons(4242);
memset(&iface_out, 0, sizeof(iface_out));
tmp_socket = socket(AF_INET6, SOCK_DGRAM, 0);
- if (setsockopt(tmp_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) == -1) {
- goto doh;
- }
-
- if (connect(tmp_socket, (struct sockaddr *) &remote, sizeof(struct sockaddr_in)) == -1) {
+ if (connect(tmp_socket, (struct sockaddr *) &remote, sizeof(remote)) == -1) {
goto doh;
}
@@ -1054,16 +1050,66 @@
#endif
-SWITCH_DECLARE(char *) get_addr(char *buf, switch_size_t len, struct in_addr *in)
+SWITCH_DECLARE(char *) get_addr(char *buf, switch_size_t len, struct sockaddr *sa, socklen_t salen)
{
switch_assert(buf);
*buf = '\0';
- if (in) {
- switch_inet_ntop(AF_INET, in, buf, len);
+ if (sa) {
+ getnameinfo(sa, salen, buf, len, NULL, 0, NI_NUMERICHOST);
}
return buf;
}
+SWITCH_DECLARE(unsigned short) get_port(struct sockaddr *sa)
+{
+ unsigned short port = 0;
+ if (sa) {
+ switch (sa->sa_family) {
+ case AF_INET:
+ port = ntohs(((struct sockaddr_in*)sa)->sin_port);
+ break;
+ case AF_INET6:
+ port = ntohs(((struct sockaddr_in6*)sa)->sin6_port);
+ break;
+ }
+ }
+ return port;
+}
+
+SWITCH_DECLARE(int) switch_build_uri(char *uri,
+ switch_size_t size,
+ const char *scheme,
+ const char *user,
+ const switch_sockaddr_t *sa,
+ int flags)
+{
+ char host[NI_MAXHOST], serv[NI_MAXSERV];
+ struct sockaddr_storage ss;
+ const struct sockaddr *addr;
+ const char *colon;
+
+ if (flags & SWITCH_URI_NO_SCOPE && sa->family == AF_INET6) {
+ memcpy(&ss, &sa->sa, sa->salen);
+ ((struct sockaddr_in6*) &ss)->sin6_scope_id = 0;
+ addr = (const struct sockaddr*) &ss;
+ } else {
+ addr = (const struct sockaddr*) &sa->sa;
+ }
+
+ if (getnameinfo(addr, sa->salen, host, sizeof(host), serv, sizeof(serv),
+ (flags & SWITCH_URI_NUMERIC_HOST) ? NI_NUMERICHOST : 0 |
+ (flags & SWITCH_URI_NUMERIC_PORT) ? NI_NUMERICSERV : 0) != 0) {
+ return 0;
+ }
+
+ colon = strchr(host, ':');
+
+ return switch_snprintf(uri, size, "%s:%s%s%s%s%s%s%s", scheme,
+ user ? user : "", user ? "@" : "",
+ colon ? "[" : "", host, colon ? "]" : "",
+ serv[0] ? ":" : "", serv[0] ? serv : "");
+}
+
SWITCH_DECLARE(char) switch_rfc2833_to_char(int event)
{
if (event > -1 && event < (int32_t) sizeof(RFC2833_CHARS)) {
More information about the Freeswitch-svn
mailing list