working mo better

This commit is contained in:
Anthony Minessale 2013-01-24 23:08:40 -06:00
parent 5c90322e8c
commit 668f4a6207
10 changed files with 305 additions and 122 deletions

View File

@ -2053,8 +2053,8 @@ const sipdns_tports[SIPDNS_TRANSPORTS] = {
{ "tcp", "5060", "_sip._tcp.", "SIP+D2T" },
{ "sctp", "5060", "_sip._sctp.", "SIP+D2S" },
{ "tls", "5061", "_sips._tcp.", "SIPS+D2T" },
{ "ws", "80", "_sips._ws.", "SIP+D2W" },
{ "wss", "443", "_sips._wss.", "SIPS+D2W" },
{ "ws", "5066", "_sips._ws.", "SIP+D2W" },
{ "wss", "5067", "_sips._wss.", "SIPS+D2W" },
};
static char const * const tports_sip[] =
@ -2064,7 +2064,7 @@ static char const * const tports_sip[] =
static char const * const tports_sips[] =
{
"tls", "ws", NULL
"tls", "wss", "ws", NULL
};
static tport_stack_class_t nta_agent_class[1] =

View File

@ -1346,11 +1346,13 @@ extern tport_vtable_t const tport_udp_vtable;
extern tport_vtable_t const tport_tcp_vtable;
extern tport_vtable_t const tport_tls_vtable;
extern tport_vtable_t const tport_ws_vtable;
extern tport_vtable_t const tport_wss_vtable;
extern tport_vtable_t const tport_sctp_vtable;
extern tport_vtable_t const tport_udp_client_vtable;
extern tport_vtable_t const tport_tcp_client_vtable;
extern tport_vtable_t const tport_sctp_client_vtable;
extern tport_vtable_t const tport_ws_client_vtable;
extern tport_vtable_t const tport_wss_client_vtable;
extern tport_vtable_t const tport_tls_client_vtable;
extern tport_vtable_t const tport_http_connect_vtable;
extern tport_vtable_t const tport_threadpool_vtable;
@ -1363,6 +1365,8 @@ tport_vtable_t const *tport_vtables[TPORT_NUMBER_OF_TYPES + 1] =
&tport_http_connect_vtable,
&tport_ws_client_vtable,
&tport_ws_vtable,
&tport_wss_client_vtable,
&tport_wss_vtable,
#endif
#if HAVE_TLS
&tport_tls_client_vtable,

View File

@ -263,6 +263,10 @@ int tls_verify_cb(int ok, X509_STORE_CTX *store)
return ok;
}
void tls_init(void) {
ONCE_INIT(tls_init_once);
}
static
int tls_init_context(tls_t *tls, tls_issues_t const *ti)
{

View File

@ -93,6 +93,7 @@ ssize_t tls_write(tls_t *tls, void *buf, size_t size);
int tls_want_write(tls_t *tls, int events);
int tls_events(tls_t const *tls, int flags);
void tls_init(void);
SOFIA_END_DECLS

View File

@ -36,6 +36,7 @@
#include "tport_internal.h"
#include "tport_ws.h"
#include "tport_tls.h"
#if HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
@ -65,18 +66,27 @@ static char const __func__[] = "tport_type_ws";
#include <sofia-sip/http.h>
#include <sofia-sip/http_header.h>
static int tport_ws_init_primary_secure(tport_primary_t *pri,
tp_name_t tpn[1],
su_addrinfo_t *ai,
tagi_t const *tags,
char const **return_culprit);
static int tport_ws_setsndbuf(int socket, int atleast);
static void tport_ws_deinit_primary(tport_primary_t *pri);
tport_vtable_t const tport_ws_vtable =
{
/* vtp_name */ "ws",
/* vtp_public */ tport_type_local,
/* vtp_pri_size */ sizeof (tport_primary_t),
/* vtp_pri_size */ sizeof (tport_ws_primary_t),
/* vtp_init_primary */ tport_ws_init_primary,
/* vtp_deinit_primary */ NULL,
/* vtp_deinit_primary */ tport_ws_deinit_primary,
/* vtp_wakeup_pri */ tport_accept,
/* vtp_connect */ NULL,
/* vtp_secondary_size */ sizeof (tport_ws_t),
/* vtp_init_secondary */ tport_ws_init_secondary,
/* vtp_deinit_secondary */ NULL,
/* vtp_deinit_secondary */ tport_ws_deinit_secondary,
/* vtp_shutdown */ NULL,
/* vtp_set_events */ NULL,
/* vtp_wakeup */ NULL,
@ -94,9 +104,9 @@ tport_vtable_t const tport_ws_client_vtable =
{
/* vtp_name */ "ws",
/* vtp_public */ tport_type_client,
/* vtp_pri_size */ sizeof (tport_primary_t),
/* vtp_pri_size */ sizeof (tport_ws_primary_t),
/* vtp_init_primary */ tport_ws_init_client,
/* vtp_deinit_primary */ NULL,
/* vtp_deinit_primary */ tport_ws_deinit_primary,
/* vtp_wakeup_pri */ NULL,
/* vtp_connect */ NULL,
/* vtp_secondary_size */ sizeof (tport_ws_t),
@ -115,8 +125,64 @@ tport_vtable_t const tport_ws_client_vtable =
/* vtp_secondary_timer */ tport_ws_timer,
};
static int tport_ws_setsndbuf(int socket, int atleast);
tport_vtable_t const tport_wss_vtable =
{
/* vtp_name */ "wss",
/* vtp_public */ tport_type_local,
/* vtp_pri_size */ sizeof (tport_ws_primary_t),
/* vtp_init_primary */ tport_ws_init_primary_secure,
/* vtp_deinit_primary */ tport_ws_deinit_primary,
/* vtp_wakeup_pri */ tport_accept,
/* vtp_connect */ NULL,
/* vtp_secondary_size */ sizeof (tport_ws_t),
/* vtp_init_secondary */ tport_ws_init_secondary,
/* vtp_deinit_secondary */ tport_ws_deinit_secondary,
/* vtp_shutdown */ NULL,
/* vtp_set_events */ NULL,
/* vtp_wakeup */ NULL,
/* vtp_recv */ tport_recv_stream_ws,
/* vtp_send */ tport_send_stream_ws,
/* vtp_deliver */ NULL,
/* vtp_prepare */ NULL,
/* vtp_keepalive */ NULL,
/* vtp_stun_response */ NULL,
/* vtp_next_secondary_timer*/ tport_ws_next_timer,
/* vtp_secondary_timer */ tport_ws_timer,
};
tport_vtable_t const tport_wss_client_vtable =
{
/* vtp_name */ "wss",
/* vtp_public */ tport_type_client,
/* vtp_pri_size */ sizeof (tport_ws_primary_t),
/* vtp_init_primary */ tport_ws_init_client,
/* vtp_deinit_primary */ tport_ws_deinit_primary,
/* vtp_wakeup_pri */ NULL,
/* vtp_connect */ NULL,
/* vtp_secondary_size */ sizeof (tport_ws_t),
/* vtp_init_secondary */ tport_ws_init_secondary,
/* vtp_deinit_secondary */ NULL,
/* vtp_shutdown */ NULL,
/* vtp_set_events */ NULL,
/* vtp_wakeup */ NULL,
/* vtp_recv */ tport_recv_stream_ws,
/* vtp_send */ tport_send_stream_ws,
/* vtp_deliver */ NULL,
/* vtp_prepare */ NULL,
/* vtp_keepalive */ NULL,
/* vtp_stun_response */ NULL,
/* vtp_next_secondary_timer*/ tport_ws_next_timer,
/* vtp_secondary_timer */ tport_ws_timer,
};
static void tport_ws_deinit_primary(tport_primary_t *pri)
{
tport_ws_primary_t *wspri = (tport_ws_primary_t *)pri;
if ( wspri->ssl_ctx ) {
SSL_CTX_free(wspri->ssl_ctx), wspri->ssl_ctx = NULL;
}
}
/** Receive from stream.
*
@ -134,11 +200,12 @@ int tport_recv_stream_ws(tport_t *self)
msg_iovec_t iovec[msg_n_fragments] = {{ 0 }};
tport_ws_t *wstp = (tport_ws_t *)self;
wsh_t *ws = wstp->ws;
tport_ws_primary_t *wspri = (tport_ws_primary_t *)self->tp_pri;
uint8_t *data;
ws_opcode_t oc;
if ( !wstp->ws_initialized ) {
ws_init(ws, self->tp_socket, 65336, wstp->ws_secure);
ws_init(ws, self->tp_socket, 65336, wstp->ws_secure ? wspri->ssl_ctx : NULL);
wstp->ws_initialized = 1;
self->tp_pre_framed = 1;
return 1;
@ -155,7 +222,7 @@ int tport_recv_stream_ws(tport_t *self)
err = su_errno();
SU_DEBUG_1(("%s(%p): su_getmsgsize(): %s (%d)\n", __func__, (void *)self,
su_strerror(err), err));
return -1;
return 0;;
}
veclen = tport_recv_iovec(self, &self->tp_msg, iovec, N, 0);
@ -271,6 +338,36 @@ ssize_t tport_send_stream_ws(tport_t const *self, msg_t *msg,
return size;
}
static int tport_ws_init_primary_secure(tport_primary_t *pri,
tp_name_t tpn[1],
su_addrinfo_t *ai,
tagi_t const *tags,
char const **return_culprit)
{
tport_ws_primary_t *wspri = (tport_ws_primary_t *)pri;
const char *cert = "/ssl.pem";
const char *key = "/ssl.pem";
init_ssl();
// OpenSSL_add_all_algorithms(); /* load & register cryptos */
// SSL_load_error_strings(); /* load all error messages */
wspri->ssl_method = SSLv23_server_method(); /* create server instance */
wspri->ssl_ctx = SSL_CTX_new(wspri->ssl_method); /* create context */
wspri->ws_secure = 1;
if ( !wspri->ssl_ctx ) return -1;
/* set the local certificate from CertFile */
SSL_CTX_use_certificate_file(wspri->ssl_ctx, cert, SSL_FILETYPE_PEM);
/* set the private key from KeyFile */
SSL_CTX_use_PrivateKey_file(wspri->ssl_ctx, key, SSL_FILETYPE_PEM);
/* verify private key */
if ( !SSL_CTX_check_private_key(wspri->ssl_ctx) ) {
return -1;
}
return tport_ws_init_primary(pri, tpn, ai, tags, return_culprit);
}
int tport_ws_init_primary(tport_primary_t *pri,
tp_name_t tpn[1],
@ -305,6 +402,8 @@ int tport_ws_init_secondary(tport_t *self, int socket, int accepted,
char const **return_reason)
{
int one = 1;
tport_ws_primary_t *wspri = (tport_ws_primary_t *)self->tp_pri;
tport_ws_t *wstp = (tport_ws_t *)self;
self->tp_has_connection = 1;
@ -314,9 +413,21 @@ int tport_ws_init_secondary(tport_t *self, int socket, int accepted,
if (!accepted)
tport_ws_setsndbuf(socket, 64 * 1024);
if ( wspri->ws_secure ) wstp->ws_secure = 1;
return 0;
}
static void tport_ws_deinit_secondary(tport_t *self)
{
tport_ws_t *wstp = (tport_ws_t *)self;
if (wstp->ws_initialized ) {
ws_close(wstp->ws, WS_NONE);
wstp->ws_initialized = 0;
}
}
static int tport_ws_setsndbuf(int socket, int atleast)
{
#if SU_HAVE_WINSOCK2

View File

@ -62,6 +62,14 @@ typedef struct tport_ws_s {
unsigned:0;
} tport_ws_t;
typedef struct tport_ws_primary_s {
tport_primary_t wspri_pri[1];
SSL_CTX *ssl_ctx;
const SSL_METHOD *ssl_method;
unsigned ws_secure:1;
unsigned :0;
} tport_ws_primary_t;
int tport_recv_stream_ws(tport_t *self);
ssize_t tport_send_stream_ws(tport_t const *self, msg_t *msg,
msg_iovec_t iov[], size_t iovused);
@ -82,6 +90,7 @@ int tport_ws_init_secondary(tport_t *self, int socket, int accepted,
int tport_ws_next_timer(tport_t *self, su_time_t *, char const **);
void tport_ws_timer(tport_t *self, su_time_t);
static void tport_ws_deinit_secondary(tport_t *self);
SOFIA_END_DECLS

View File

@ -1,10 +1,13 @@
#include "ws.h"
#include <pthread.h>
#define SHA1_HASH_SIZE 20
struct globals_s globals;
#ifndef PTHREAD
void ssl_init() {}
void init_ssl(void)
{
SSL_library_init();
}
#else
static unsigned long pthreads_thread_id(void);
static void pthreads_locking_callback(int mode, int type, const char *file, int line);
@ -67,18 +70,18 @@ void init_ssl(void) {
SSL_library_init();
// OpenSSL_add_all_algorithms(); /* load & register cryptos */
// SSL_load_error_strings(); /* load all error messages */
globals.ssl_method = SSLv23_server_method(); /* create server instance */
globals.ssl_ctx = SSL_CTX_new(globals.ssl_method); /* create context */
assert(globals.ssl_ctx);
//globals.ssl_method = SSLv23_server_method(); /* create server instance */
//globals.ssl_ctx = SSL_CTX_new(globals.ssl_method); /* create context */
//assert(globals.ssl_ctx);
/* set the local certificate from CertFile */
SSL_CTX_use_certificate_file(globals.ssl_ctx, globals.cert, SSL_FILETYPE_PEM);
//SSL_CTX_use_certificate_file(globals.ssl_ctx, globals.cert, SSL_FILETYPE_PEM);
/* set the private key from KeyFile */
SSL_CTX_use_PrivateKey_file(globals.ssl_ctx, globals.key, SSL_FILETYPE_PEM);
//SSL_CTX_use_PrivateKey_file(globals.ssl_ctx, globals.key, SSL_FILETYPE_PEM);
/* verify private key */
if ( !SSL_CTX_check_private_key(globals.ssl_ctx) ) {
abort();
}
//if ( !SSL_CTX_check_private_key(globals.ssl_ctx) ) {
// abort();
//}
thread_setup();
@ -213,12 +216,6 @@ int ws_handshake(wsh_t *wsh)
return -3;
}
if (wsh->secure) {
wsh->ssl = SSL_new(globals.ssl_ctx);
SSL_set_fd(wsh->ssl, wsh->sock);
SSL_accept(wsh->ssl);
}
while((bytes = ws_raw_read(wsh, wsh->buffer + wsh->datalen, wsh->buflen - wsh->datalen)) > 0) {
wsh->datalen += bytes;
if (strstr(wsh->buffer, "\r\n\r\n") || strstr(wsh->buffer, "\n\n")) {
@ -288,7 +285,11 @@ ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes)
ssize_t r;
if (wsh->ssl) {
return SSL_read(wsh->ssl, data, bytes);
do {
r = SSL_read(wsh->ssl, data, bytes);
} while (r == -1 && SSL_get_error(wsh->ssl, r) == SSL_ERROR_WANT_READ);
return r;
}
do {
@ -307,7 +308,11 @@ ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes)
size_t r;
if (wsh->ssl) {
return SSL_write(wsh->ssl, data, bytes);
do {
r = SSL_write(wsh->ssl, data, bytes);
} while (r == -1 && SSL_get_error(wsh->ssl, r) == SSL_ERROR_WANT_WRITE);
return r;
}
do {
@ -321,7 +326,7 @@ ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes)
return r;
}
int ws_init(wsh_t *wsh, ws_socket_t sock, size_t buflen, int secure)
int ws_init(wsh_t *wsh, ws_socket_t sock, size_t buflen, SSL_CTX *ssl_ctx)
{
memset(wsh, 0, sizeof(*wsh));
wsh->sock = sock;
@ -331,13 +336,24 @@ int ws_init(wsh_t *wsh, ws_socket_t sock, size_t buflen, int secure)
}
wsh->buflen = buflen;
wsh->secure = secure;
wsh->secure = ssl_ctx ? 1 : 0;
if (!wsh->buffer) {
wsh->buffer = malloc(wsh->buflen);
assert(wsh->buffer);
}
if (wsh->secure) {
int code;
wsh->ssl = SSL_new(ssl_ctx);
SSL_set_fd(wsh->ssl, wsh->sock);
do {
code = SSL_accept(wsh->ssl);
} while (code == -1 && SSL_get_error(wsh->ssl, code) == SSL_ERROR_WANT_READ);
}
while (!wsh->down && !wsh->handshake) {
ws_handshake(wsh);
}
@ -368,6 +384,11 @@ ssize_t ws_close(wsh_t *wsh, int16_t reason)
if (wsh->ssl) {
int code;
do {
code = SSL_shutdown(wsh->ssl);
} while (code == -1 && SSL_get_error(wsh->ssl, code) == SSL_ERROR_WANT_READ);
SSL_free(wsh->ssl);
wsh->ssl = NULL;
}

View File

@ -68,7 +68,7 @@ ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes);
ssize_t ws_raw_write(wsh_t *wsh, void *data, size_t bytes);
ssize_t ws_read_frame(wsh_t *wsh, ws_opcode_t *oc, uint8_t **data);
ssize_t ws_write_frame(wsh_t *wsh, ws_opcode_t oc, void *data, size_t bytes);
int ws_init(wsh_t *wsh, ws_socket_t sock, size_t buflen, int secure);
int ws_init(wsh_t *wsh, ws_socket_t sock, size_t buflen, SSL_CTX *ssl_ctx);
ssize_t ws_close(wsh_t *wsh, int16_t reason);
void init_ssl(void);
void deinit_ssl(void);

View File

@ -1109,10 +1109,21 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
const char *agent = "unknown";
const char *pres_on_reg = NULL;
int send_pres = 0;
int is_tls = 0, is_tcp = 0, is_ws = 0;
int is_tls = 0, is_tcp = 0, is_ws = 0, is_wss = 0;
char expbuf[35] = "";
time_t reg_time = switch_epoch_time_now(NULL);
const char *vproto = NULL;
const char *proto = "sip";
if (sip && sip->sip_via && (vproto = sip->sip_via->v_protocol)) {
if (!strcasecmp(vproto, "sip/2.0/ws")) {
is_ws = 1;
is_nat++;
} else if (!strcasecmp(vproto, "sip/2.0/wss")) {
is_wss = 1;
is_nat++;
}
}
if (v_event && *v_event) pres_on_reg = switch_event_get_header(*v_event, "send-presence-on-register");
@ -1177,24 +1188,28 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
const char *contact_host = contact->m_url->url_host;
char *path_encoded = NULL;
int path_encoded_len = 0;
const char *proto = "sip";
if (switch_stristr("transport=tls", sip->sip_contact->m_url->url_params)) {
is_tls += 1;
is_nat++;
}
if (switch_stristr("transport=ws", sip->sip_contact->m_url->url_params)) {
if (!is_wss && !is_ws && switch_stristr("transport=ws", sip->sip_contact->m_url->url_params)) {
is_nat++;
is_ws += 1;
}
if (sip->sip_contact->m_url->url_type == url_sips && !switch_stristr("transport=ws", sip->sip_contact->m_url->url_params)) {
if (sip->sip_contact->m_url->url_type == url_sips) {
proto = "sips";
is_tls += 2;
is_nat++;
}
if (is_wss) {
proto = "sips";
}
if (switch_stristr("transport=tcp", sip->sip_contact->m_url->url_params)) {
is_tcp = 1;
is_nat++;
@ -1209,6 +1224,8 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
reg_desc = "Registered(TCP-NAT)";
} else if (is_ws) {
reg_desc = "Registered(WS-NAT)";
} else if (is_wss) {
reg_desc = "Registered(WSS-NAT)";
} else {
reg_desc = "Registered(UDP-NAT)";
}
@ -1243,10 +1260,10 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
} else if (is_nat) {
char my_contact_str[1024];
if (sip->sip_contact->m_url->url_params) {
switch_snprintf(my_contact_str, sizeof(my_contact_str), "sip:%s@%s:%d;%s",
switch_snprintf(my_contact_str, sizeof(my_contact_str), "%s:%s@%s:%d;%s", proto,
contact->m_url->url_user, url_ip, network_port, sip->sip_contact->m_url->url_params);
} else {
switch_snprintf(my_contact_str, sizeof(my_contact_str), "sip:%s@%s:%d", contact->m_url->url_user, url_ip, network_port);
switch_snprintf(my_contact_str, sizeof(my_contact_str), "%s:%s@%s:%d", proto, contact->m_url->url_user, url_ip, network_port);
}
path_encoded_len = (int)(strlen(my_contact_str) * 3) + 1;
@ -1388,7 +1405,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
size_t path_encoded_len;
char my_contact_str[1024];
switch_snprintf(my_contact_str, sizeof(my_contact_str), "sip:%s@%s:%d", contact->m_url->url_user, url_ip, network_port);
switch_snprintf(my_contact_str, sizeof(my_contact_str), "%s:%s@%s:%d", proto, contact->m_url->url_user, url_ip, network_port);
path_encoded_len = (strlen(my_contact_str) * 3) + 1;
if (!switch_stristr("fs_path=", contact_str)) {
@ -1414,10 +1431,11 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
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, url_ip, network_port, contact->m_url->url_params, received_data);
switch_snprintf(contact_str, sizeof(contact_str), "%s <%s:%s@%s:%d;%s%s;fs_nat=yes>",
display, proto, 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, url_ip,
switch_snprintf(contact_str, sizeof(contact_str), "%s <%s:%s@%s:%d%s;fs_nat=yes>", display, proto,
contact->m_url->url_user, url_ip,
network_port, received_data);
}
if (switch_stristr(v_contact_str, "transport=tls")) {
@ -1623,7 +1641,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
switch_find_local_ip(guess_ip4, sizeof(guess_ip4), NULL, AF_INET);
contact = sofia_glue_get_url_from_contact(contact_str, 1);
url = switch_mprintf("sofia/%q/sip:%q", profile->name, sofia_glue_strip_proto(contact));
url = switch_mprintf("sofia/%q/%s:%q", profile->name, proto, sofia_glue_strip_proto(contact));
switch_core_add_registration(to_user, reg_host, call_id, url, (long) reg_time + (long) exptime + 60,
network_ip, network_port_c, is_tls ? "tls" : is_tcp ? "tcp" : "udp", reg_meta);
@ -1773,7 +1791,7 @@ uint8_t sofia_reg_handle_register(nua_t *nua, sofia_profile_t *profile, nua_hand
(reg_count == 1 && sofia_test_pflag(profile, PFLAG_MESSAGE_QUERY_ON_FIRST_REGISTER))) && debounce_ok) {
if (switch_event_create(&s_mwi_event, SWITCH_EVENT_MESSAGE_QUERY) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(s_mwi_event, SWITCH_STACK_BOTTOM, "Message-Account", "sip:%s@%s", mwi_user, mwi_host);
switch_event_add_header(s_mwi_event, SWITCH_STACK_BOTTOM, "Message-Account", "%s:%s@%s", proto, mwi_user, mwi_host);
switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Sofia-Profile", profile->name);
switch_event_add_header_string(s_mwi_event, SWITCH_STACK_BOTTOM, "VM-Call-ID", call_id);
}

View File

@ -1977,6 +1977,10 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
int total_codecs;
switch_rtp_engine_t *a_engine, *v_engine;
switch_media_handle_t *smh;
uint32_t near_rate = 0;
const switch_codec_implementation_t *mimp = NULL, *near_match = NULL;
int codec_ms = 0;
switch_assert(session);
@ -2353,11 +2357,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
for (map = m->m_rtpmaps; map; map = map->rm_next) {
int32_t i;
uint32_t near_rate = 0;
const switch_codec_implementation_t *mimp = NULL, *near_match = NULL;
const char *rm_encoding;
uint32_t map_bit_rate = 0;
int codec_ms = 0;
switch_codec_fmtp_t codec_fmtp = { 0 };
if (x++ < skip) {
@ -2411,9 +2412,12 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
}
if (zstr(map->rm_fmtp)) {
if (!strcasecmp(map->rm_encoding, "ilbc") || !strcasecmp(map->rm_encoding, "isac")) {
if (!strcasecmp(map->rm_encoding, "ilbc")) {
codec_ms = 30;
map_bit_rate = 13330;
} else if (!strcasecmp(map->rm_encoding, "isac")) {
codec_ms = 30;
map_bit_rate = 32000;
}
} else {
if ((switch_core_codec_parse_fmtp(map->rm_encoding, map->rm_fmtp, map->rm_rate, &codec_fmtp)) == SWITCH_STATUS_SUCCESS) {
@ -2450,7 +2454,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
match = 0;
}
if (match && map->rm_rate && codec_rate && map->rm_rate != codec_rate && (!strcasecmp(map->rm_encoding, "pcma") || !strcasecmp(map->rm_encoding, "pcmu"))) {
if (match && map->rm_rate && codec_rate && map->rm_rate != codec_rate && (!strcasecmp(map->rm_encoding, "pcma") ||
!strcasecmp(map->rm_encoding, "pcmu"))) {
/* if the sampling rate is specified and doesn't match, this is not a codec match for G.711 */
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "sampling rates have to match for G.711\n");
match = 0;
@ -2474,6 +2479,17 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
}
}
if (!match && greedy) {
skip++;
continue;
}
if (match && mimp) {
break;
}
}
if (!match && near_match) {
const switch_codec_implementation_t *search[1];
char *prefs[1];
@ -2503,11 +2519,6 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
}
if (!match && greedy) {
skip++;
continue;
}
if (mimp) {
char tmp[50];
const char *mirror = switch_channel_get_variable(session->channel, "rtp_mirror_remote_audio_codec_payload");
@ -2551,7 +2562,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
match = 0;
}
}
}
if (!best_te && (switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) || switch_channel_test_flag(session->channel, CF_LIBERAL_DTMF))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
@ -6335,9 +6347,12 @@ static void add_audio_codec(sdp_rtpmap_t *map, int ptime, char *buf, switch_size
}
if (zstr(map->rm_fmtp)) {
if (!strcasecmp(map->rm_encoding, "ilbc") || !strcasecmp(map->rm_encoding, "isac")) {
if (!strcasecmp(map->rm_encoding, "ilbc")) {
ptime = codec_ms = 30;
map_bit_rate = 13330;
} else if (!strcasecmp(map->rm_encoding, "isac")) {
ptime = codec_ms = 30;
map_bit_rate = 32000;
}
} else {
if ((switch_core_codec_parse_fmtp(map->rm_encoding, map->rm_fmtp, map->rm_rate, &codec_fmtp)) == SWITCH_STATUS_SUCCESS) {