git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8893 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Michael Jerris 2008-07-03 18:50:15 +00:00
parent 11cedd5fcb
commit 1d46f922e2
9 changed files with 290 additions and 80 deletions

View File

@ -118,10 +118,44 @@ SWITCH_DECLARE(switch_status_t) switch_find_local_ip(_Out_opt_bytecapcount_(len)
\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)

View File

@ -926,7 +926,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
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);
}

View File

@ -215,7 +215,8 @@ void sofia_event_callback(nua_event_t event,
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 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
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 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag)
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 @@ switch_status_t config_sofia(int reload, char *profile_name)
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 @@ switch_status_t config_sofia(int reload, char *profile_name)
}
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 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
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 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
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 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
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 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
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, '>')) {

View File

@ -44,6 +44,7 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32
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 @@ void sofia_glue_set_local_sdp(private_object_t *tech_pvt, const char *ip, uint32
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 @@ switch_status_t sofia_glue_tech_proxy_remote_addr(private_object_t *tech_pvt)
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 @@ void sofia_glue_tech_patch_sdp(private_object_t *tech_pvt)
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 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
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 @@ void sofia_glue_do_xfer_invite(switch_core_session_t *session)
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 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
}
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,

View File

@ -1203,13 +1203,14 @@ void sofia_presence_handle_sip_i_subscribe(int status,
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 @@ void sofia_presence_handle_sip_i_subscribe(int status,
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 @@ void sofia_presence_handle_sip_i_subscribe(int status,
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)),

View File

@ -403,6 +403,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
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 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
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 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
} 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 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
}
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 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
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 @@ void sofia_reg_handle_sip_i_register(nua_t *nua, sofia_profile_t *profile, nua_h
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)) {

View File

@ -630,7 +630,7 @@ SWITCH_DECLARE(const char *) switch_get_addr(char *buf, switch_size_t len, switc
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)

View File

@ -121,7 +121,13 @@ struct switch_rtp_rfc2833_data {
};
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 @@ static switch_status_t ice_out(switch_rtp_t *rtp_session)
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 @@ static void handle_ice(switch_rtp_t *rtp_session, void *data, switch_size_t len)
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 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_s
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 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_s
#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(void) switch_rtp_set_max_missed_packets(switch_rtp_t *rtp_session
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_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_
}
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_DECLARE(void) switch_rtp_break(switch_rtp_t *rtp_session)
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_DECLARE(void) switch_rtp_kill_socket(switch_rtp_t *rtp_session)
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_DECLARE(uint8_t) switch_rtp_ready(switch_rtp_t *rtp_session)
}
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 @@ SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp_t **rtp_session)
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(void) switch_rtp_destroy(switch_rtp_t **rtp_session)
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 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
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 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
}
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 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
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 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra
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 @@ SWITCH_DECLARE(int) switch_rtp_write_manual(switch_rtp_t *rtp_session,
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;

View File

@ -757,7 +757,7 @@ SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int fam
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 @@ SWITCH_DECLARE(switch_status_t) switch_find_local_ip(char *buf, int len, int fam
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 @@ static const char *switch_inet_ntop6(unsigned char const *src, char *dst, size_t
#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)) {