diff --git a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c index 647d0dddf1..397cd86516 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c +++ b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp_parse.c @@ -1387,7 +1387,9 @@ void sdp_media_transport(sdp_media_t *m, char const *s) else if (su_casematch(s, "RTP/SAVP")) m->m_proto = sdp_proto_srtp, m->m_proto_name = "RTP/SAVP"; else if (su_casematch(s, "RTP/SAVPF")) - m->m_proto = sdp_proto_extended_srtp, m->m_proto_name = "RTP/SAVPF"; + m->m_proto = sdp_proto_extended_srtp, m->m_proto_name = "RTP/SAVPF"; + else if (su_casematch(s, "UDP/TLS/RTP/SAVPF")) + m->m_proto = sdp_proto_extended_srtp, m->m_proto_name = "UDP/TLS/RTP/SAVPF"; else if (su_casematch(s, "udptl")) /* Lower case - be compatible with people living by T.38 examples */ m->m_proto = sdp_proto_udptl, m->m_proto_name = "udptl"; diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c index afbf80923d..f66dcc3016 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/ws.c +++ b/libs/sofia-sip/libsofia-sip-ua/tport/ws.c @@ -3,11 +3,17 @@ #define SHA1_HASH_SIZE 20 struct globals_s globals; -#ifndef PTHREAD +#ifndef WSS_STANDALONE + void init_ssl(void) { SSL_library_init(); } +void deinit_ssl(void) +{ + return; +} + #else static unsigned long pthreads_thread_id(void); static void pthreads_locking_callback(int mode, int type, const char *file, int line); @@ -68,23 +74,24 @@ static unsigned long pthreads_thread_id(void) 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); + + OpenSSL_add_all_algorithms(); /* load & register cryptos */ + SSL_load_error_strings(); /* load all error messages */ + globals.ssl_method = TLSv1_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(); - } @@ -215,7 +222,7 @@ int ws_handshake(wsh_t *wsh) if (wsh->sock == ws_sock_invalid) { return -3; } - + 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")) { @@ -272,7 +279,7 @@ int ws_handshake(wsh_t *wsh) //printf("ERR:\n%s\n", respond); - send(wsh->sock, respond, strlen(respond), 0); + ws_raw_write(wsh, respond, strlen(respond)); ws_close(wsh, WS_NONE); @@ -300,7 +307,7 @@ ssize_t ws_raw_read(wsh_t *wsh, void *data, size_t bytes) } while (r == -1 && (errno == EAGAIN || errno == EINTR) && x < 100); //if (r<0) { - //printf("READ FAIL: %s\n", strerror(errno)); + // printf("READ FAIL: %s\n", strerror(errno)); //} return r; @@ -334,6 +341,10 @@ int ws_init(wsh_t *wsh, ws_socket_t sock, size_t buflen, SSL_CTX *ssl_ctx, int c memset(wsh, 0, sizeof(*wsh)); wsh->sock = sock; + if (!ssl_ctx) { + ssl_ctx = globals.ssl_ctx; + } + if (close_sock) { wsh->close_sock = 1; } @@ -352,13 +363,16 @@ int ws_init(wsh_t *wsh, ws_socket_t sock, size_t buflen, SSL_CTX *ssl_ctx, int c if (wsh->secure) { int code; + wsh->ssl = SSL_new(ssl_ctx); + assert(wsh->ssl); + 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) { diff --git a/libs/sofia-sip/libsofia-sip-ua/tport/ws.h b/libs/sofia-sip/libsofia-sip-ua/tport/ws.h index 2b4d139097..5d36b7615e 100644 --- a/libs/sofia-sip/libsofia-sip-ua/tport/ws.h +++ b/libs/sofia-sip/libsofia-sip-ua/tport/ws.h @@ -1,6 +1,8 @@ #ifndef _WS_H #define _WS_H +//#define WSS_STANDALONE 1 + #define MAXLEN 0x10000 #define WEBSOCKET_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" #define B64BUFFLEN 1024 diff --git a/src/include/switch_types.h b/src/include/switch_types.h index fdd2bafc21..c1e2604da8 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1297,6 +1297,7 @@ typedef enum { CF_AUTOFLUSH_DURING_BRIDGE, CF_RTP_NOTIMER_DURING_BRIDGE, CF_WEBRTC, + CF_WEBRTC_MOZ, CF_ICE, CF_DTLS, /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */ diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 028f852fd1..7d204b5257 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -663,6 +663,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) if (switch_channel_test_flag(channel, CF_CONFERENCE)) { tech_pvt->reply_contact = switch_core_session_sprintf(session, "%s;isfocus", tech_pvt->reply_contact); } + //switch_core_media_set_local_sdp if(sofia_test_flag(tech_pvt, TFLAG_3PCC_INVITE)) { // SNARK: complete hack to get final ack sent when a 3pcc invite has been passed from the other leg in bypass_media mode. @@ -688,7 +689,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) } if (sofia_test_flag(tech_pvt, TFLAG_ANS) || switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { - return SWITCH_STATUS_SUCCESS; + printf("BALLZ %d\n", __LINE__);return SWITCH_STATUS_SUCCESS; } @@ -702,7 +703,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { switch_core_media_patch_sdp(tech_pvt->session); if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_FALSE; + printf("BALLZ %d\n", __LINE__);return SWITCH_STATUS_FALSE; } } } else { @@ -721,7 +722,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { switch_core_media_patch_sdp(tech_pvt->session); if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_FALSE; + printf("BALLZ %d\n", __LINE__);return SWITCH_STATUS_FALSE; } } } @@ -776,7 +777,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "3PCC-PROXY, Done waiting for ACK\n"); - return SWITCH_STATUS_SUCCESS; + printf("BALLZ %d\n", __LINE__);return SWITCH_STATUS_SUCCESS; } if ((is_proxy && !b_sdp) || sofia_test_flag(tech_pvt, TFLAG_LATE_NEGOTIATION) || @@ -799,14 +800,14 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) //switch_mutex_lock(tech_pvt->sofia_mutex); //nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END()); //switch_mutex_unlock(tech_pvt->sofia_mutex); - return SWITCH_STATUS_FALSE; + printf("BALLZ %d\n", __LINE__);return SWITCH_STATUS_FALSE; } } } if ((status = switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0)) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - return status; + printf("BALLZ %d\n", __LINE__);return status; } switch_core_media_gen_local_sdp(session, NULL, 0, NULL, 0); diff --git a/src/mod/endpoints/mod_sofia/sofia_media.c b/src/mod/endpoints/mod_sofia/sofia_media.c index 2d8cc97e25..ff6f3ae1c7 100644 --- a/src/mod/endpoints/mod_sofia/sofia_media.c +++ b/src/mod/endpoints/mod_sofia/sofia_media.c @@ -77,20 +77,20 @@ switch_status_t sofia_media_tech_media(private_object_t *tech_pvt, const char *r switch_assert(r_sdp != NULL); if (zstr(r_sdp)) { - return SWITCH_STATUS_FALSE; + printf("BALLZ %d\n", __LINE__);return SWITCH_STATUS_FALSE; } if ((match = sofia_media_negotiate_sdp(tech_pvt->session, r_sdp))) { if (switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_FALSE; + printf("BALLZ %d\n", __LINE__);return SWITCH_STATUS_FALSE; } if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { - return SWITCH_STATUS_FALSE; + printf("BALLZ %d\n", __LINE__);return SWITCH_STATUS_FALSE; } switch_channel_set_variable(tech_pvt->channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "EARLY MEDIA"); sofia_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA); switch_channel_mark_pre_answered(tech_pvt->channel); - return SWITCH_STATUS_SUCCESS; + printf("BALLZ %d\n", __LINE__);return SWITCH_STATUS_SUCCESS; } diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 9750f4f3af..29a6853b48 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -1804,7 +1804,7 @@ static void generate_local_fingerprint(switch_media_handle_t *smh, switch_media_ //? -static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_media_t *m) +static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_session_t *sdp, sdp_media_t *m) { switch_rtp_engine_t *engine = &smh->engines[type]; sdp_attribute_t *attr; @@ -1814,8 +1814,13 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_ engine->ice_in.chosen[1] = 0; engine->ice_in.cand_idx = 0; + if (m) { + attr = m->m_attributes; + } else { + attr = sdp->sdp_attributes; + } - for (attr = m->m_attributes; attr; attr = attr->a_next) { + for (; attr; attr = attr->a_next) { char *data; char *fields[15]; int argc = 0, j = 0; @@ -2187,6 +2192,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_core_media_find_zrtp_hash(session, sdp); switch_core_media_pass_zrtp_hash(session); + check_ice(smh, SWITCH_MEDIA_TYPE_AUDIO, sdp, NULL); + for (m = sdp->sdp_media; m; m = m->m_next) { sdp_connection_t *connection; switch_core_session_t *other_session; @@ -2199,6 +2206,10 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_core_session_set_ice(session); } + if (m->m_proto_name && !strcasecmp(m->m_proto_name, "UDP/TLS/RTP/SAVPF")) { + switch_channel_set_flag(session->channel, CF_WEBRTC_MOZ); + } + if (m->m_proto == sdp_proto_srtp || m->m_proto == sdp_proto_extended_srtp) { if (m->m_type == sdp_media_audio) { got_savp++; @@ -2633,7 +2644,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s if (match) { if (switch_core_media_set_codec(session, 1, smh->mparams->codec_flags) == SWITCH_STATUS_SUCCESS) { got_audio = 1; - check_ice(smh, SWITCH_MEDIA_TYPE_AUDIO, m); + check_ice(smh, SWITCH_MEDIA_TYPE_AUDIO, sdp, m); } else { match = 0; } @@ -2810,8 +2821,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s switch_channel_set_variable(session->channel, "sip_video_recv_pt", tmp); if (!match && vmatch) match = 1; - check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, m); - + check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, sdp, m); + check_ice(smh, SWITCH_MEDIA_TYPE_VIDEO, sdp, NULL); break; } else { vmatch = 0; @@ -3753,23 +3764,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi } - if (!zstr(a_engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls()) { - dtls_type_t xtype, dtype = switch_channel_direction(smh->session->channel) == SWITCH_CALL_DIRECTION_INBOUND ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER; - - - xtype = DTLS_TYPE_RTP; - if (a_engine->rtcp_mux > 0) xtype |= DTLS_TYPE_RTCP; - switch_rtp_add_dtls(a_engine->rtp_session, &a_engine->local_dtls_fingerprint, &a_engine->remote_dtls_fingerprint, dtype | xtype); - - if (a_engine->rtcp_mux < 1) { - xtype = DTLS_TYPE_RTCP; - switch_rtp_add_dtls(a_engine->rtp_session, &a_engine->local_dtls_fingerprint, &a_engine->remote_dtls_fingerprint, dtype | xtype); - } - - } - - if (a_engine->ice_in.cands[a_engine->ice_in.chosen[0]][0].ready) { gen_ice(session, SWITCH_MEDIA_TYPE_AUDIO, NULL, 0); @@ -3843,6 +3838,24 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi } + if (!zstr(a_engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls()) { + dtls_type_t xtype, dtype = switch_channel_direction(smh->session->channel) == SWITCH_CALL_DIRECTION_INBOUND ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER; + + + xtype = DTLS_TYPE_RTP; + if (a_engine->rtcp_mux > 0) xtype |= DTLS_TYPE_RTCP; + + switch_rtp_add_dtls(a_engine->rtp_session, &a_engine->local_dtls_fingerprint, &a_engine->remote_dtls_fingerprint, dtype | xtype); + + if (a_engine->rtcp_mux < 1) { + xtype = DTLS_TYPE_RTCP; + switch_rtp_add_dtls(a_engine->rtp_session, &a_engine->local_dtls_fingerprint, &a_engine->remote_dtls_fingerprint, dtype | xtype); + } + + } + + + if ((val = switch_channel_get_variable(session->channel, "jitterbuffer_msec")) || (val = smh->mparams->jb_msec)) { int jb_msec = atoi(val); int maxlen = 0, max_drift = 0; @@ -4179,7 +4192,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi if ((val = switch_channel_get_variable(session->channel, "rtcp_video_interval_msec")) || (val = smh->mparams->rtcp_video_interval_msec)) { const char *rport = switch_channel_get_variable(session->channel, "sip_remote_video_rtcp_port"); - switch_port_t remote_port = 0; + switch_port_t remote_port = v_engine->remote_rtcp_port; if (rport) { remote_port = (switch_port_t)atoi(rport); } @@ -4198,21 +4211,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi } - if (!zstr(v_engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls()) { - dtls_type_t xtype, - dtype = switch_channel_direction(smh->session->channel) == SWITCH_CALL_DIRECTION_INBOUND ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER; - xtype = DTLS_TYPE_RTP; - if (v_engine->rtcp_mux > 0) xtype |= DTLS_TYPE_RTCP; - - switch_rtp_add_dtls(v_engine->rtp_session, &v_engine->local_dtls_fingerprint, &v_engine->remote_dtls_fingerprint, dtype | xtype); - - if (v_engine->rtcp_mux < 1) { - xtype = DTLS_TYPE_RTCP; - switch_rtp_add_dtls(v_engine->rtp_session, &v_engine->local_dtls_fingerprint, &v_engine->remote_dtls_fingerprint, dtype | xtype); - } - } - - if (v_engine->ice_in.cands[v_engine->ice_in.chosen[1]][1].ready) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating VIDEO RTCP ICE\n"); switch_rtp_activate_ice(v_engine->rtp_session, @@ -4236,7 +4234,20 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi } - + + if (!zstr(v_engine->local_dtls_fingerprint.str) && switch_rtp_has_dtls()) { + dtls_type_t xtype, + dtype = switch_channel_direction(smh->session->channel) == SWITCH_CALL_DIRECTION_INBOUND ? DTLS_TYPE_CLIENT : DTLS_TYPE_SERVER; + xtype = DTLS_TYPE_RTP; + if (v_engine->rtcp_mux > 0) xtype |= DTLS_TYPE_RTCP; + + switch_rtp_add_dtls(v_engine->rtp_session, &v_engine->local_dtls_fingerprint, &v_engine->remote_dtls_fingerprint, dtype | xtype); + + if (v_engine->rtcp_mux < 1) { + xtype = DTLS_TYPE_RTCP; + switch_rtp_add_dtls(v_engine->rtp_session, &v_engine->local_dtls_fingerprint, &v_engine->remote_dtls_fingerprint, dtype | xtype); + } + } if ((val = switch_channel_get_variable(session->channel, "rtp_manual_video_rtp_bugs"))) { @@ -4293,6 +4304,26 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi } +static const char *get_media_profile_name(switch_core_session_t *session, int secure) +{ + switch_assert(session); + + if (switch_channel_test_flag(session->channel, CF_WEBRTC)) { + if (switch_channel_test_flag(session->channel, CF_WEBRTC_MOZ)) { + return "UDP/TLS/RTP/SAVPF"; + } else { + return "RTP/SAVPF"; + } + } + + if ((!secure && switch_channel_test_flag(session->channel, CF_SECURE)) || secure) { + return "RTP/SAVP"; + } + + return "RTP/AVP"; + +} + //? static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, switch_port_t port, const char *family, const char *ip, @@ -4315,9 +4346,10 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; - switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "m=audio %d RTP/%sAVP%s", - port, secure ? "S" : "", switch_channel_test_flag(session->channel, CF_WEBRTC) ? "F" : ""); - + //switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "m=audio %d RTP/%sAVP%s", + //port, secure ? "S" : "", switch_channel_test_flag(session->channel, CF_WEBRTC) ? "F" : ""); + + switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "m=audio %d %s", port, get_media_profile_name(session, secure)); for (i = 0; i < smh->mparams->num_codecs; i++) { @@ -4477,9 +4509,11 @@ static void generate_m(switch_core_session_t *session, char *buf, size_t buflen, switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ssrc:%u mslabel:%s\n", a_engine->ssrc, smh->msid); switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ssrc:%u label:%sa0\n", a_engine->ssrc, smh->msid); + switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ice-ufrag:%s\n", ice_out->ufrag); switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=ice-pwd:%s\n", ice_out->pwd); + switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ host generation 0\n", tmp1, ice_out->cands[0][0].transport, c1, ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port @@ -4850,18 +4884,28 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess "%s", username, smh->owner_id, smh->session_id, family, ip, username, family, ip, srbuf); + if (switch_channel_test_flag(smh->session->channel, CF_ICE)) { gen_ice(session, SWITCH_MEDIA_TYPE_AUDIO, ip, port); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=msid-semantic: WMS %s\n", smh->msid); } + if (a_engine->codec_params.rm_encoding) { + /* switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=audio %d RTP/%sAVP%s", port, ((!zstr(local_audio_crypto_key) || switch_channel_test_flag(session->channel, CF_DTLS)) && switch_channel_test_flag(session->channel, CF_SECURE)) ? "S" : "", switch_channel_test_flag(session->channel, CF_WEBRTC) ? "F" : ""); + */ - + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=audio %d %s", port, + get_media_profile_name(session, + ((!zstr(local_audio_crypto_key) || switch_channel_test_flag(session->channel, CF_DTLS)) && + switch_channel_test_flag(session->channel, CF_SECURE)) + )); + + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), " %d", a_engine->codec_params.pt); if ((smh->mparams->dtmf_type == DTMF_2833 || switch_media_handle_test_media_flag(smh, SCMF_LIBERAL_DTMF) || @@ -4960,15 +5004,17 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess ice_out = &a_engine->ice_out; - switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u cname:%s\n", a_engine->ssrc, smh->cname); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u msid:%s a0\n", a_engine->ssrc, smh->msid); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u mslabel:%s\n", a_engine->ssrc, smh->msid); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u label:%sa0\n", a_engine->ssrc, smh->msid); + + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-ufrag:%s\n", ice_out->ufrag); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-pwd:%s\n", ice_out->pwd); + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ host generation 0\n", tmp1, ice_out->cands[0][0].transport, c1, ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port @@ -5122,12 +5168,19 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess if (switch_channel_test_flag(smh->session->channel, CF_ICE)) { gen_ice(session, SWITCH_MEDIA_TYPE_VIDEO, ip, v_port); } - + /* switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=video %d RTP/%sAVP%s", v_port, ((!zstr(local_video_crypto_key) || switch_channel_test_flag(session->channel, CF_DTLS)) && switch_channel_test_flag(session->channel, CF_SECURE)) ? "S" : "", switch_channel_test_flag(session->channel, CF_WEBRTC) ? "F" : ""); + */ + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=video %d %s", + v_port, get_media_profile_name(session, + (!zstr(local_video_crypto_key) || switch_channel_test_flag(session->channel, CF_DTLS)) + && switch_channel_test_flag(session->channel, CF_SECURE))); + + /*****************************/ if (v_engine->codec_params.rm_encoding) { @@ -5283,14 +5336,18 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess ice_out = &v_engine->ice_out; + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u cname:%s\n", v_engine->ssrc, smh->cname); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u msid:%s v0\n", v_engine->ssrc, smh->msid); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u mslabel:%s\n", v_engine->ssrc, smh->msid); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u label:%sv0\n", v_engine->ssrc, smh->msid); + + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-ufrag:%s\n", ice_out->ufrag); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-pwd:%s\n", ice_out->pwd); + switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ host generation 0\n", tmp1, ice_out->cands[0][0].transport, c1, ice_out->cands[0][0].con_addr, ice_out->cands[0][0].con_port diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 427a447c5e..fa0838ea21 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -177,6 +177,7 @@ typedef struct { uint8_t sending; uint8_t ready; uint8_t rready; + int missed_count; } switch_rtp_ice_t; struct switch_rtp; @@ -678,12 +679,9 @@ static switch_status_t ice_out(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice) if (ice == &rtp_session->rtcp_ice) { sock_output = rtp_session->rtcp_sock_output; - //remote_addr = rtp_session->rtcp_remote_addr; } - - switch_assert(rtp_session != NULL); switch_assert(ice->ice_user != NULL); @@ -775,6 +773,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d int xlen = 0; int ok = 1; uint32_t *pri = NULL; + int is_rtcp = ice == &rtp_session->rtcp_ice; if (!switch_rtp_ready(rtp_session) || zstr(ice->user_ice) || zstr(ice->ice_user)) { return; @@ -800,8 +799,6 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d } - - #if 0 if (ice->sending && (packet->header.type == SWITCH_STUN_BINDING_RESPONSE || packet->header.type == SWITCH_STUN_BINDING_ERROR_RESPONSE)) { ice->sending = 0; @@ -847,19 +844,23 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d ok = !strcmp(ice->user_ice, username); } - if (ice->type == ICE_VANILLA) { + if ((ice->type & ICE_VANILLA)) { if (!ok && ice == &rtp_session->ice && pri && *pri == rtp_session->rtcp_ice.ice_params->cands[rtp_session->rtcp_ice.ice_params->chosen[1]][1].priority) { ice = &rtp_session->rtcp_ice; ok = 1; } - if (!ok) { + if (ok) { + ice->missed_count = 0; + } else { uint32_t elapsed = (unsigned int) ((switch_micro_time_now() - rtp_session->last_stun) / 1000); switch_rtp_ice_t *icep[2] = { &rtp_session->ice, &rtp_session->rtcp_ice }; switch_port_t port = 0; char *host = NULL; + ice->missed_count++; + if (elapsed > 20000 && pri) { int i, j; uint32_t old; @@ -936,7 +937,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d } - if (ok) { + if (ok || ice->missed_count > 1) { if ((packet->header.type == SWITCH_STUN_BINDING_RESPONSE)) { if (rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) { rtp_session->ice.rready = 1; @@ -953,7 +954,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d switch_sockaddr_t *from_addr = rtp_session->from_addr; switch_socket_t *sock_output = rtp_session->sock_output; - if (ice == &rtp_session->rtcp_ice && !rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) { + if (is_rtcp && !rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) { from_addr = rtp_session->rtcp_from_addr; sock_output = rtp_session->rtcp_sock_output; } @@ -968,7 +969,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d } remote_ip = switch_get_addr(ipbuf, sizeof(ipbuf), from_addr); - switch_stun_packet_attribute_add_binded_address(rpacket, (char *) remote_ip, switch_sockaddr_get_port(from_addr)); + switch_stun_packet_attribute_add_xor_binded_address(rpacket, (char *) remote_ip, switch_sockaddr_get_port(from_addr)); if ((ice->type & ICE_VANILLA)) { switch_stun_packet_attribute_add_integrity(rpacket, ice->pass); @@ -988,7 +989,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d port = switch_sockaddr_get_port(from_addr); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, - "Auto Changing stun/rtp/dtls port to %s:%u\n", host, port); + "Auto Changing stun/%s/dtls port to %s:%u\n", is_rtcp ? "rtcp" : "rtp", host, port); ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr = switch_core_strdup(rtp_session->pool, host); ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port = port; @@ -1001,8 +1002,15 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d switch_sockaddr_info_get(&rtp_session->dtls->remote_addr, host, SWITCH_UNSPEC, port, 0, rtp_session->pool); } - if (ice == &rtp_session->rtcp_ice && !rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX] && rtp_session->rtcp_dtls) { - switch_sockaddr_info_get(&rtp_session->rtcp_dtls->remote_addr, host, SWITCH_UNSPEC, port, 0, rtp_session->pool); + if (is_rtcp && !rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) { + + switch_sockaddr_info_get(&rtp_session->rtcp_remote_addr, host, SWITCH_UNSPEC, port, 0, rtp_session->pool); + if (rtp_session->rtcp_dtls) { + //switch_sockaddr_info_get(&rtp_session->rtcp_dtls->remote_addr, host, SWITCH_UNSPEC, port, 0, rtp_session->pool); + rtp_session->rtcp_dtls->remote_addr = rtp_session->rtcp_remote_addr; + rtp_session->rtcp_dtls->sock_output = rtp_session->rtcp_sock_output; + } + } } @@ -2179,6 +2187,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d { switch_dtls_t *dtls; int ret; + const char *kind = ""; #ifndef HAVE_OPENSSL_DTLS_SRTP return SWITCH_STATUS_FALSE; @@ -2192,8 +2201,16 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_CRIT, "INVALID TYPE!\n"); } + if ((type & DTLS_TYPE_RTP) && (type & DTLS_TYPE_RTCP)) { + kind = "RTP/RTCP"; + } else if ((type & DTLS_TYPE_RTP)) { + kind = "RTP"; + } else { + kind = "RTCP"; + } + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, - "Activate %s DTLS %s\n", rtp_type(rtp_session), (type & DTLS_TYPE_SERVER) ? "server" : "client"); + "Activate %s %s DTLS %s\n", kind, rtp_type(rtp_session), (type & DTLS_TYPE_SERVER) ? "server" : "client"); if (((type & DTLS_TYPE_RTP) && rtp_session->dtls) || ((type & DTLS_TYPE_RTCP) && rtp_session->rtcp_dtls)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "DTLS ALREADY INIT\n"); @@ -2395,7 +2412,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess case SWITCH_RTP_CRYPTO_RECV: policy->ssrc.type = ssrc_any_inbound; - if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] && idx == 0) { + if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] && idx == 0 && rtp_session->recv_ctx[idx]) { rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV_RESET] = 1; } else { if ((stat = srtp_create(&rtp_session->recv_ctx[idx], policy))) { @@ -2403,8 +2420,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess } if (status == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "Activating %s Secure RTP RECV\n", - rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "Video" : "Audio"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "Activating %s Secure %s RECV\n", + rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "Video" : "Audio", idx ? "RTCP" : "RTP"); rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] = 1; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error allocating srtp [%d]\n", stat); @@ -2417,7 +2434,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess //policy->ssrc.type = ssrc_specific; //policy->ssrc.value = rtp_session->ssrc; - if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND] && idx == 0) { + if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND] && idx == 0 && rtp_session->send_ctx[idx]) { rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND_RESET] = 1; } else { if ((stat = srtp_create(&rtp_session->send_ctx[idx], policy))) { @@ -2425,8 +2442,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess } if (status == SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "Activating %s Secure RTP SEND\n", - rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "Video" : "Audio"); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "Activating %s Secure %s SEND\n", + rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "Video" : "Audio", idx ? "RTCP" : "RTP"); rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND] = 1; } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error allocating SRTP [%d]\n", stat); @@ -3041,8 +3058,8 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_sessio return SWITCH_STATUS_FALSE; } - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_NOTICE, "Activating %s ICE: %s %s:%d\n", - rtp_type(rtp_session), ice_user, host, port); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_NOTICE, "Activating %s %s ICE: %s %s:%d\n", + proto == IPR_RTP ? "RTP" : "RTCP", rtp_type(rtp_session), ice_user, host, port); if (ice->ice_user) { @@ -3679,6 +3696,13 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t } if (rtp_session->dtls) { + + if (rtp_session->rtcp_dtls && rtp_session->rtcp_dtls != rtp_session->dtls) { + rtp_session->rtcp_dtls->bytes = 0; + rtp_session->rtcp_dtls->data = NULL; + do_dtls(rtp_session, rtp_session->rtcp_dtls); + } + rtp_session->dtls->bytes = 0; if (*bytes) { @@ -4002,10 +4026,12 @@ static switch_status_t process_rtcp_packet(switch_rtp_t *rtp_session, switch_siz } + + static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t *bytes, switch_frame_flag_t *flags) { switch_status_t status = SWITCH_STATUS_FALSE; - + if (!rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP]) { return SWITCH_STATUS_FALSE; } @@ -4019,21 +4045,30 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t *bytes = 0; } - if (rtp_session->rtcp_dtls) { char *b = (char *) &rtp_session->rtcp_recv_msg; //printf("RECV2 %d %ld\n", *b, *bytes); - - if ((*b >= 20) && (*b <= 64)) { + + + if (*b == 0 || *b == 1) { + if (rtp_session->rtcp_ice.ice_user) { + handle_ice(rtp_session, &rtp_session->rtcp_ice, (void *) &rtp_session->rtcp_recv_msg, *bytes); + } + *bytes = 0; + } + + + if (*bytes && (*b >= 20) && (*b <= 64)) { rtp_session->rtcp_dtls->bytes = *bytes; rtp_session->rtcp_dtls->data = (void *) &rtp_session->rtcp_recv_msg; } else { rtp_session->rtcp_dtls->bytes = 0; rtp_session->rtcp_dtls->data = NULL; } - + do_dtls(rtp_session, rtp_session->rtcp_dtls); + if (rtp_session->rtcp_dtls->bytes) { *bytes = 0; @@ -4327,7 +4362,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ - if (bytes && rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP]) { + if (rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP]) { rtcp_poll_status = SWITCH_STATUS_FALSE; if (rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX] && has_rtcp) {