MILESTONE: working inbound calls

This commit is contained in:
Anthony Minessale 2013-01-13 20:12:23 -06:00
parent cb076e6b28
commit 7510bccd6c
7 changed files with 238 additions and 178 deletions

View File

@ -220,9 +220,10 @@ SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp_t **rtp_session);
\return SWITCH_STATUS_SUCCESS \return SWITCH_STATUS_SUCCESS
*/ */
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_session, char *login, char *rlogin, SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_session, char *login, char *rlogin,
const char *password, switch_core_media_ice_type_t type, uint32_t priority); const char *password, const char *rpassword, switch_core_media_ice_type_t type, uint32_t priority);
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp_ice(switch_rtp_t *rtp_session, char *login, char *rlogin, SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp_ice(switch_rtp_t *rtp_session, char *login, char *rlogin,
const char *password, switch_core_media_ice_type_t type, uint32_t priority); const char *password, const char *rpassword,
switch_core_media_ice_type_t type, uint32_t priority);
/*! /*!
\brief Activate sending RTCP Sender Reports (SR's) \brief Activate sending RTCP Sender Reports (SR's)

View File

@ -262,6 +262,7 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip,
\param end pointer to the end of the buffer \param end pointer to the end of the buffer
\return true or false depending on if there are any more attributes \return true or false depending on if there are any more attributes
*/ */
#define switch_stun_packet_next_attribute(attribute, end) (attribute && (attribute = (switch_stun_packet_attribute_t *) (attribute->value + switch_stun_attribute_padded_length(attribute))) && ((void *)attribute < end) && attribute->type && ((void *)(attribute + switch_stun_attribute_padded_length(attribute)) < end)) #define switch_stun_packet_next_attribute(attribute, end) (attribute && (attribute = (switch_stun_packet_attribute_t *) (attribute->value + switch_stun_attribute_padded_length(attribute))) && ((void *)attribute < end) && attribute->type && ((void *)(attribute + switch_stun_attribute_padded_length(attribute)) < end))
#define switch_stun_packet_next_attribute_hbo(attribute, end) (attribute && (attribute = (switch_stun_packet_attribute_t *) (attribute->value + switch_stun_attribute_padded_length_hbo(attribute))) && ((void *)attribute < end) && attribute->type && ((void *)(attribute + switch_stun_attribute_padded_length_hbo(attribute)) < end)) #define switch_stun_packet_next_attribute_hbo(attribute, end) (attribute && (attribute = (switch_stun_packet_attribute_t *) (attribute->value + switch_stun_attribute_padded_length_hbo(attribute))) && ((void *)attribute < end) && attribute->type && ((void *)(attribute + switch_stun_attribute_padded_length_hbo(attribute)) < end))

View File

@ -817,13 +817,14 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) { if (sofia_media_activate_rtp(tech_pvt) != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
} }
if (tech_pvt->nh) { if (tech_pvt->nh) {
if (tech_pvt->mparams.local_sdp_str) { if (tech_pvt->mparams.local_sdp_str) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Local SDP %s:\n%s\n", switch_channel_get_name(channel), switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Local SDP %s:\n%s\n", switch_channel_get_name(channel),
tech_pvt->mparams.local_sdp_str); tech_pvt->mparams.local_sdp_str);
} }
} }
} }
if (sofia_test_flag(tech_pvt, TFLAG_NAT) || if (sofia_test_flag(tech_pvt, TFLAG_NAT) ||

View File

@ -1228,6 +1228,7 @@ SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload)
switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_FALSE); switch_network_list_add_cidr(rfc_list, "10.0.0.0/8", SWITCH_FALSE);
switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_FALSE); switch_network_list_add_cidr(rfc_list, "172.16.0.0/12", SWITCH_FALSE);
switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_FALSE); switch_network_list_add_cidr(rfc_list, "192.168.0.0/16", SWITCH_FALSE);
switch_network_list_add_cidr(rfc_list, "169.254.0.0/16", SWITCH_FALSE);
switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list); switch_core_hash_insert(IP_LIST.hash, tmp_name, rfc_list);
tmp_name = "nat.auto"; tmp_name = "nat.auto";

View File

@ -90,10 +90,7 @@ typedef struct codec_params_s {
} codec_params_t; } codec_params_t;
typedef struct ice_s { typedef struct icand_s {
char *cand_acl[SWITCH_MAX_CAND_ACL];
int cand_acl_count;
char *foundation; char *foundation;
int component_id; int component_id;
char *transport; char *transport;
@ -104,12 +101,18 @@ typedef struct ice_s {
char *raddr; char *raddr;
switch_port_t rport; switch_port_t rport;
char *generation; char *generation;
uint8_t ready;
} icand_t;
typedef struct ice_s {
icand_t cands[2];
char *ufrag; char *ufrag;
char *pwd; char *pwd;
char *options; char *options;
uint8_t ready;
} ice_t; } ice_t;
@ -145,6 +148,9 @@ typedef struct switch_rtp_engine_s {
codec_params_t codec_params; codec_params_t codec_params;
uint32_t timestamp_send; uint32_t timestamp_send;
char *cand_acl[SWITCH_MAX_CAND_ACL];
int cand_acl_count;
ice_t ice_in; ice_t ice_in;
ice_t ice_out; ice_t ice_out;
@ -1720,8 +1726,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_add_ice_acl(switch_core_sessio
engine = &smh->engines[type]; engine = &smh->engines[type];
if (engine->ice_in.cand_acl_count < SWITCH_MAX_CAND_ACL) { if (engine->cand_acl_count < SWITCH_MAX_CAND_ACL) {
engine->ice_in.cand_acl[engine->ice_in.cand_acl_count++] = switch_core_session_strdup(session, acl_name); engine->cand_acl[engine->cand_acl_count++] = switch_core_session_strdup(session, acl_name);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
@ -1759,18 +1765,18 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_
{ {
switch_rtp_engine_t *engine = &smh->engines[type]; switch_rtp_engine_t *engine = &smh->engines[type];
sdp_attribute_t *attr; sdp_attribute_t *attr;
int i = 0;
for (attr = m->m_attributes; attr; attr = attr->a_next) { for (attr = m->m_attributes; attr; attr = attr->a_next) {
char *data; char *data;
char *fields[15]; char *fields[15];
int argc = 0, i = 0, j = 0; int argc = 0, j = 0;
int cid = 0;
if (zstr(attr->a_name)) { if (zstr(attr->a_name)) {
continue; continue;
} }
printf("ICE [%s] [%s]\n", attr->a_name, attr->a_value);
if (!strcasecmp(attr->a_name, "ice-ufrag")) { if (!strcasecmp(attr->a_name, "ice-ufrag")) {
engine->ice_in.ufrag = switch_core_session_strdup(smh->session, attr->a_value); engine->ice_in.ufrag = switch_core_session_strdup(smh->session, attr->a_value);
} else if (!strcasecmp(attr->a_name, "ice-pwd")) { } else if (!strcasecmp(attr->a_name, "ice-pwd")) {
@ -1779,7 +1785,7 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_
engine->ice_in.options = switch_core_session_strdup(smh->session, attr->a_value); engine->ice_in.options = switch_core_session_strdup(smh->session, attr->a_value);
} else if (!strcasecmp(attr->a_name, "candidate")) { } else if (!strcasecmp(attr->a_name, "candidate")) {
if (!engine->ice_in.cand_acl_count) { if (!engine->cand_acl_count) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "NO candidate ACL defined, skipping candidate check.\n"); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_WARNING, "NO candidate ACL defined, skipping candidate check.\n");
return; return;
} }
@ -1798,62 +1804,63 @@ static void check_ice(switch_media_handle_t *smh, switch_media_type_t type, sdp_
continue; continue;
} }
cid = atoi(fields[1]) - 1;
printf("BAH %d [%s]\n", argc, data);
//del me
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
printf("CAND %d [%s]\n", i, fields[i]); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG1, "CAND %d [%s]\n", i, fields[i]);
} }
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG, switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_DEBUG,
"Checking Candidate proto: %s type: %s addr: %s\n", fields[2], fields[7], fields[4]); "Checking Candidate cid: %d proto: %s type: %s addr: %s\n", cid+1, fields[2], fields[7], fields[4]);
if (cid < 2 && !engine->ice_in.cands[cid].ready) {
for (i = 0; i < engine->ice_in.cand_acl_count; i++) { for (i = 0; i < engine->cand_acl_count; i++) {
if (switch_check_network_list_ip(fields[4], engine->ice_in.cand_acl[i])) { if (switch_check_network_list_ip(fields[4], engine->cand_acl[i])) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_NOTICE, switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(smh->session), SWITCH_LOG_NOTICE,
"Choose Candidate proto: %s type: %s addr: %s\n", fields[2], fields[7], fields[4]); "Choose Candidate cid: %d proto: %s type: %s addr: %s\n", cid+1, fields[2], fields[7], fields[4]);
engine->ice_in.foundation = switch_core_session_strdup(smh->session, fields[0]); engine->ice_in.cands[cid].foundation = switch_core_session_strdup(smh->session, fields[0]);
engine->ice_in.component_id = atoi(fields[1]); engine->ice_in.cands[cid].component_id = atoi(fields[1]);
engine->ice_in.transport = switch_core_session_strdup(smh->session, fields[2]); engine->ice_in.cands[cid].transport = switch_core_session_strdup(smh->session, fields[2]);
engine->ice_in.priority = atoi(fields[3]); engine->ice_in.cands[cid].priority = atol(fields[3]);
engine->ice_in.con_addr = switch_core_session_strdup(smh->session, fields[4]); engine->ice_in.cands[cid].con_addr = switch_core_session_strdup(smh->session, fields[4]);
engine->ice_in.con_port = atoi(fields[5]); engine->ice_in.cands[cid].con_port = atoi(fields[5]);
j = 6; j = 6;
while(j < argc && fields[j+1]) { while(j < argc && fields[j+1]) {
if (!strcasecmp(fields[j], "typ")) { if (!strcasecmp(fields[j], "typ")) {
engine->ice_in.cand_type = switch_core_session_strdup(smh->session, fields[j+1]); engine->ice_in.cands[cid].cand_type = switch_core_session_strdup(smh->session, fields[j+1]);
} else if (!strcasecmp(fields[j], "raddr")) { } else if (!strcasecmp(fields[j], "raddr")) {
engine->ice_in.raddr = switch_core_session_strdup(smh->session, fields[j+1]); engine->ice_in.cands[cid].raddr = switch_core_session_strdup(smh->session, fields[j+1]);
} else if (!strcasecmp(fields[j], "rport")) { } else if (!strcasecmp(fields[j], "rport")) {
engine->ice_in.rport = atoi(fields[j+1]); engine->ice_in.cands[cid].rport = atoi(fields[j+1]);
} else if (!strcasecmp(fields[j], "generation")) { } else if (!strcasecmp(fields[j], "generation")) {
engine->ice_in.generation = switch_core_session_strdup(smh->session, fields[j+1]); engine->ice_in.cands[cid].generation = switch_core_session_strdup(smh->session, fields[j+1]);
} }
j += 2; j += 2;
} }
engine->ice_in.ready++; engine->ice_in.cands[cid].ready++;
break; break;
}
} }
} }
} }
} }
if (engine->ice_in.ready) { for (i = 0; i < 2; i++) {
if (zstr(engine->ice_in.ufrag) || zstr(engine->ice_in.pwd)) { if (engine->ice_in.cands[i].ready) {
engine->ice_in.ready = 0; if (zstr(engine->ice_in.ufrag) || zstr(engine->ice_in.pwd)) {
engine->ice_in.cands[i].ready = 0;
}
} }
} }
@ -3194,29 +3201,29 @@ static void gen_ice(switch_core_session_t *session, switch_media_type_t type, co
engine->ice_out.pwd = switch_core_session_strdup(session, tmp); engine->ice_out.pwd = switch_core_session_strdup(session, tmp);
} }
if (!engine->ice_out.foundation) { if (!engine->ice_out.cands[0].foundation) {
tmp[10] = '\0'; tmp[10] = '\0';
switch_stun_random_string(tmp, 10, "0123456789"); switch_stun_random_string(tmp, 10, "0123456789");
engine->ice_out.foundation = switch_core_session_strdup(session, tmp); engine->ice_out.cands[0].foundation = switch_core_session_strdup(session, tmp);
} }
engine->ice_out.transport = "udp"; engine->ice_out.cands[0].transport = "udp";
if (!engine->ice_out.component_id) { if (!engine->ice_out.cands[0].component_id) {
engine->ice_out.component_id = 1; engine->ice_out.cands[0].component_id = 1;
engine->ice_out.priority = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - engine->ice_out.component_id); engine->ice_out.cands[0].priority = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - engine->ice_out.cands[0].component_id);
} }
if (ip) { if (ip) {
engine->ice_out.con_addr = switch_core_session_strdup(session, ip); engine->ice_out.cands[0].con_addr = switch_core_session_strdup(session, ip);
} }
if (port) { if (port) {
engine->ice_out.con_port = port; engine->ice_out.cands[0].con_port = port;
} }
engine->ice_out.generation = "0"; engine->ice_out.cands[0].generation = "0";
//add rport stuff later //add rport stuff later
engine->ice_out.ready = 1; engine->ice_out.cands[0].ready = 1;
} }
@ -3686,44 +3693,45 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
switch_rtp_set_ssrc(a_engine->rtp_session, a_engine->ssrc); switch_rtp_set_ssrc(a_engine->rtp_session, a_engine->ssrc);
printf("xxxxxxWTF %d %d\n", a_engine->ice_out.ready , a_engine->ice_in.ready); if (a_engine->ice_in.cands[0].ready) {
if (a_engine->ice_in.ready) {
gen_ice(session, SWITCH_MEDIA_TYPE_AUDIO, "", 0); gen_ice(session, SWITCH_MEDIA_TYPE_AUDIO, "", 0);
switch_rtp_activate_ice(a_engine->rtp_session, switch_rtp_activate_ice(a_engine->rtp_session,
a_engine->ice_in.ufrag, a_engine->ice_in.ufrag,
a_engine->ice_out.ufrag, a_engine->ice_out.ufrag,
a_engine->ice_out.pwd,
a_engine->ice_in.pwd, a_engine->ice_in.pwd,
#ifdef GOOGLE_ICE #ifdef GOOGLE_ICE
ICE_GOOGLE_JINGLE, ICE_GOOGLE_JINGLE,
0 0
#else #else
ICE_VANILLA | ICE_CONTROLLED, ICE_VANILLA | ICE_CONTROLLED,
a_engine->ice_out.priority a_engine->ice_in.cands[0].priority
#endif #endif
); );
if (a_engine->ice_in.cands[1].ready) {
switch_rtp_activate_rtcp_ice(a_engine->rtp_session,
switch_rtp_activate_rtcp_ice(a_engine->rtp_session, a_engine->ice_in.ufrag,
a_engine->ice_in.ufrag, a_engine->ice_out.ufrag,
a_engine->ice_out.ufrag, a_engine->ice_out.pwd,
a_engine->ice_in.pwd, a_engine->ice_in.pwd,
#ifdef GOOGLE_ICE #ifdef GOOGLE_ICE
ICE_GOOGLE_JINGLE, ICE_GOOGLE_JINGLE,
0 0
#else #else
ICE_VANILLA | ICE_CONTROLLED, ICE_VANILLA | ICE_CONTROLLED,
a_engine->ice_out.priority -1 a_engine->ice_in.cands[1].priority
#endif #endif
); );
}
}
}
video: video:
@ -4269,6 +4277,11 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO]; a_engine = &smh->engines[SWITCH_MEDIA_TYPE_AUDIO];
v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO];
if (a_engine->ice_out.cands[0].ready) {
verbose_sdp = 1;
}
fmtp_out = a_engine->codec_params.fmtp_out; fmtp_out = a_engine->codec_params.fmtp_out;
username = smh->mparams->sdp_username; username = smh->mparams->sdp_username;
@ -4413,58 +4426,6 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "\n"); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "\n");
// if (smh->mparams->rtcp_audio_interval_msec) {
// switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp:%d IN %s %s\n", port + 1, family, ip);
//}
//switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u\n", a_engine->ssrc);
if (a_engine->ice_out.ready) {
char tmp1[11] = "";
char tmp2[11] = "";
uint32_t c1 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 1);
uint32_t c2 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 2);
uint32_t c3 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 1);
uint32_t c4 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 2);
tmp1[10] = '\0';
tmp2[10] = '\0';
switch_stun_random_string(tmp1, 10, "0123456789");
switch_stun_random_string(tmp2, 10, "0123456789");
ice_out = &a_engine->ice_out;
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ host generation 0\n",
tmp1, ice_out->transport, c1,
ice_out->con_addr, ice_out->con_port
);
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ srflx generation 0\n",
tmp2, ice_out->transport, c3,
ice_out->con_addr, ice_out->con_port
);
#if 1
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\n",
tmp1, ice_out->transport, c2,
ice_out->con_addr, ice_out->con_port + 1
);
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx generation 0\n",
tmp2, ice_out->transport, c4,
ice_out->con_addr, ice_out->con_port + 1
);
#endif
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);
#ifdef GOOGLE_ICE
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-options:google-ice\n");
#endif
}
rate = a_engine->codec_params.rm_rate; rate = a_engine->codec_params.rm_rate;
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%d\n", a_engine->codec_params.agreed_pt, a_engine->codec_params.rm_encoding, rate); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtpmap:%d %s/%d\n", a_engine->codec_params.agreed_pt, a_engine->codec_params.rm_encoding, rate);
@ -4511,6 +4472,64 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=%s\n", sr); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=%s\n", sr);
} }
// if (smh->mparams->rtcp_audio_interval_msec) {
// switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp:%d IN %s %s\n", port + 1, family, ip);
//}
//switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ssrc:%u\n", a_engine->ssrc);
if (a_engine->ice_out.cands[0].ready) {
char tmp1[11] = "";
char tmp2[11] = "";
uint32_t c1 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 1);
uint32_t c2 = (2^24)*126 + (2^8)*65535 + (2^0)*(256 - 2);
uint32_t c3 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 1);
uint32_t c4 = (2^24)*126 + (2^8)*65534 + (2^0)*(256 - 2);
tmp1[10] = '\0';
tmp2[10] = '\0';
switch_stun_random_string(tmp1, 10, "0123456789");
switch_stun_random_string(tmp2, 10, "0123456789");
ice_out = &a_engine->ice_out;
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].transport, c1,
ice_out->cands[0].con_addr, ice_out->cands[0].con_port
);
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 1 %s %u %s %d typ srflx generation 0\n",
tmp2, ice_out->cands[0].transport, c3,
ice_out->cands[0].con_addr, ice_out->cands[0].con_port
);
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ host generation 0\n",
tmp1, ice_out->cands[0].transport, c2,
ice_out->cands[0].con_addr, ice_out->cands[0].con_port + 1
);
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s 2 %s %u %s %d typ srflx generation 0\n",
tmp2, ice_out->cands[0].transport, c4,
ice_out->cands[0].con_addr, ice_out->cands[0].con_port + 1
);
#ifdef GOOGLE_ICE
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-options:google-ice\n");
#endif
}
if (!zstr(local_audio_crypto_key) && switch_channel_test_flag(session->channel, CF_SECURE)) { if (!zstr(local_audio_crypto_key) && switch_channel_test_flag(session->channel, CF_SECURE)) {
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=crypto:%s\n", local_audio_crypto_key); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=crypto:%s\n", local_audio_crypto_key);
//switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=encryption:optional\n"); //switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=encryption:optional\n");
@ -4640,6 +4659,8 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "\n"); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "\n");
// if (smh->mparams->rtcp_audio_interval_msec) { // if (smh->mparams->rtcp_audio_interval_msec) {
// switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp:%d IN %s %s\n", v_port + 1, family, ip); // switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=rtcp:%d IN %s %s\n", v_port + 1, family, ip);
//} //}
@ -4648,18 +4669,10 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
const char *of; const char *of;
if (v_engine->ice_out.ready) { if (v_engine->ice_out.cands[0].ready) {
ice_out = &v_engine->ice_out; ice_out = &v_engine->ice_out;
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=candidate:%s %d %s %u %s %d typ host generation 0\n",
ice_out->foundation, ice_out->component_id, ice_out->transport, ice_out->priority,
ice_out->con_addr, ice_out->con_port
);
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-ufrag:%s\n", ice_out->ufrag); // VID CANDS HERE
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-pwd:%s\n", ice_out->pwd);
#ifdef GOOGLE_ICE
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=ice-options:google-ice\n");
#endif
} }
@ -4744,8 +4757,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
//switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\n"); //switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\n");
} }
if (local_sdp_video_zrtp_hash) { if (local_sdp_video_zrtp_hash) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Adding video a=zrtp-hash:%s\n", local_sdp_video_zrtp_hash); switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Adding video a=zrtp-hash:%s\n", local_sdp_video_zrtp_hash);
switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=zrtp-hash:%s\n", local_sdp_video_zrtp_hash); switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "a=zrtp-hash:%s\n", local_sdp_video_zrtp_hash);

View File

@ -55,7 +55,7 @@
#define WRITE_DEC(rtp_session) switch_mutex_unlock(rtp_session->write_mutex); rtp_session->writing-- #define WRITE_DEC(rtp_session) switch_mutex_unlock(rtp_session->write_mutex); rtp_session->writing--
#define RTP_DEFAULT_STUNCOUNT 100;
#define rtp_header_len 12 #define rtp_header_len 12
#define RTP_START_PORT 16384 #define RTP_START_PORT 16384
#define RTP_END_PORT 32768 #define RTP_END_PORT 32768
@ -164,6 +164,7 @@ typedef struct {
char *ice_user; char *ice_user;
char *user_ice; char *user_ice;
char *pass; char *pass;
char *rpass;
uint32_t stuncount; uint32_t stuncount;
uint32_t funny_stun; uint32_t funny_stun;
uint32_t default_stuncount; uint32_t default_stuncount;
@ -677,7 +678,7 @@ static switch_status_t ice_out(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice)
switch_stun_packet_attribute_add_controlling(packet); switch_stun_packet_attribute_add_controlling(packet);
} }
switch_stun_packet_attribute_add_integrity(packet, ice->pass); switch_stun_packet_attribute_add_integrity(packet, ice->rpass);
switch_stun_packet_attribute_add_fingerprint(packet); switch_stun_packet_attribute_add_fingerprint(packet);
@ -715,6 +716,8 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
char username[33] = { 0 }; char username[33] = { 0 };
unsigned char buf[512] = { 0 }; unsigned char buf[512] = { 0 };
switch_size_t cpylen = len; switch_size_t cpylen = len;
int xlen = 0;
int ok = 1;
if (!switch_rtp_ready(rtp_session) || zstr(ice->user_ice) || zstr(ice->ice_user)) { if (!switch_rtp_ready(rtp_session) || zstr(ice->user_ice) || zstr(ice->ice_user)) {
return; return;
@ -727,23 +730,19 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
goto end; goto end;
} }
if (cpylen > sizeof(buf)) {
if (cpylen > 512) { cpylen = sizeof(buf);
cpylen = 512;
} }
memcpy(buf, data, cpylen); memcpy(buf, data, cpylen);
packet = switch_stun_packet_parse(buf, sizeof(buf)); packet = switch_stun_packet_parse(buf, cpylen);
if (!packet) { if (!packet) {
switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session"); switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session");
//int sbytes = (int) cpylen;
//int stat;
//if ((stat = srtp_unprotect(rtp_session->recv_ctx, buf, &sbytes)) || !(packet = switch_stun_packet_parse(buf, sizeof(buf)))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid STUN/ICE packet received\n");
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid STUN/ICE packet received\n"); goto end;
goto end;
//}
} }
#if 0 #if 0
@ -762,8 +761,6 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
switch_stun_packet_first_attribute(packet, attr); switch_stun_packet_first_attribute(packet, attr);
do { do {
switch (attr->type) { switch (attr->type) {
case SWITCH_STUN_ATTR_MAPPED_ADDRESS: case SWITCH_STUN_ATTR_MAPPED_ADDRESS:
@ -778,27 +775,41 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
switch_stun_packet_attribute_get_username(attr, username, 32); switch_stun_packet_attribute_get_username(attr, username, 32);
} }
break; break;
case SWITCH_STUN_ATTR_PRIORITY:
{
uint32_t *val = (uint32_t *) attr->value;
ok = *val == ice->priority;
}
break;
} }
} while (switch_stun_packet_next_attribute(attr, end_buf));
if ((packet->header.type == SWITCH_STUN_BINDING_REQUEST)) { if (!switch_stun_packet_next_attribute(attr, end_buf)) {
//if ((packet->header.type == SWITCH_STUN_BINDING_REQUEST) && !strcmp(ice->user_ice, username)) { break;
}
xlen += 4 + switch_stun_attribute_padded_length(attr);
} while (xlen <= packet->header.length);
if (ice->type == ICE_GOOGLE_JINGLE && ok) {
ok = !strcmp(ice->user_ice, username);
}
if ((packet->header.type == SWITCH_STUN_BINDING_REQUEST) && ok) {
uint8_t stunbuf[512]; uint8_t stunbuf[512];
switch_stun_packet_t *rpacket; switch_stun_packet_t *rpacket;
const char *remote_ip; const char *remote_ip;
switch_size_t bytes; switch_size_t bytes;
char ipbuf[25]; char ipbuf[25];
//int rtcp = 0;
switch_sockaddr_t *from_addr = rtp_session->from_addr; switch_sockaddr_t *from_addr = rtp_session->from_addr;
switch_socket_t *sock_output = rtp_session->sock_output; switch_socket_t *sock_output = rtp_session->sock_output;
if (ice == &rtp_session->rtcp_ice) { if (ice == &rtp_session->rtcp_ice) {
//rtcp = 1;
from_addr = rtp_session->rtcp_from_addr; from_addr = rtp_session->rtcp_from_addr;
sock_output = rtp_session->rtcp_sock_output; sock_output = rtp_session->rtcp_sock_output;
} }
printf("STUN REQ\n");
rtp_session->ice.ready = 1;
memset(stunbuf, 0, sizeof(stunbuf)); memset(stunbuf, 0, sizeof(stunbuf));
rpacket = switch_stun_packet_build_header(SWITCH_STUN_BINDING_RESPONSE, packet->header.id, stunbuf); rpacket = switch_stun_packet_build_header(SWITCH_STUN_BINDING_RESPONSE, packet->header.id, stunbuf);
@ -811,11 +822,18 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
switch_stun_packet_attribute_add_binded_address(rpacket, (char *) remote_ip, switch_sockaddr_get_port(from_addr)); switch_stun_packet_attribute_add_binded_address(rpacket, (char *) remote_ip, switch_sockaddr_get_port(from_addr));
if ((ice->type & ICE_VANILLA)) { if ((ice->type & ICE_VANILLA)) {
//if (!(ice->type && ICE_CONTROLLED)) {
// switch_stun_packet_attribute_add_use_candidate(rpacket);
// switch_stun_packet_attribute_add_priority(rpacket, ice->priority);
//}
switch_stun_packet_attribute_add_integrity(rpacket, ice->pass); switch_stun_packet_attribute_add_integrity(rpacket, ice->pass);
switch_stun_packet_attribute_add_fingerprint(rpacket); switch_stun_packet_attribute_add_fingerprint(rpacket);
} }
rtp_session->ice.ready = 1;
bytes = switch_stun_packet_length(rpacket); bytes = switch_stun_packet_length(rpacket);
switch_socket_sendto(sock_output, from_addr, 0, (void *) rpacket, &bytes); switch_socket_sendto(sock_output, from_addr, 0, (void *) rpacket, &bytes);
@ -1074,7 +1092,7 @@ static uint8_t get_next_write_ts(switch_rtp_t *rtp_session, uint32_t timestamp)
static int check_srtp_and_ice(switch_rtp_t *rtp_session) static int check_srtp_and_ice(switch_rtp_t *rtp_session)
{ {
int ret = 0; int ret = 0;
int rtcp_ok = 1;
if (rtp_session->flags[SWITCH_RTP_FLAG_AUTO_CNG] && rtp_session->send_msg.header.ts && if (rtp_session->flags[SWITCH_RTP_FLAG_AUTO_CNG] && rtp_session->send_msg.header.ts &&
@ -1094,7 +1112,11 @@ static int check_srtp_and_ice(switch_rtp_t *rtp_session)
} }
} }
if (rtp_session->rtcp_sock_output && if (rtp_session->rtcp_ice.ice_user && !rtp_session->rtcp_ice.ready) {
rtcp_ok = 0;
}
if (rtp_session->rtcp_sock_output && rtcp_ok &&
rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP] && !rtp_session->flags[SWITCH_RTP_FLAG_RTCP_PASSTHRU] && rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP] && !rtp_session->flags[SWITCH_RTP_FLAG_RTCP_PASSTHRU] &&
rtp_session->rtcp_interval && (rtp_session->stats.read_count % rtp_session->rtcp_interval) == 0) { rtp_session->rtcp_interval && (rtp_session->stats.read_count % rtp_session->rtcp_interval) == 0) {
struct switch_rtcp_senderinfo *sr = (struct switch_rtcp_senderinfo*) rtp_session->rtcp_send_msg.body; struct switch_rtcp_senderinfo *sr = (struct switch_rtcp_senderinfo*) rtp_session->rtcp_send_msg.body;
@ -2422,7 +2444,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_sessi
} }
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_session, char *login, char *rlogin, SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_session, char *login, char *rlogin,
const char *password, switch_core_media_ice_type_t type, uint32_t priority) const char *password, const char *rpassword, switch_core_media_ice_type_t type, uint32_t priority)
{ {
char ice_user[80]; char ice_user[80];
char user_ice[80]; char user_ice[80];
@ -2439,12 +2461,18 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_sessio
rtp_session->ice.user_ice = switch_core_strdup(rtp_session->pool, user_ice); rtp_session->ice.user_ice = switch_core_strdup(rtp_session->pool, user_ice);
rtp_session->ice.type = type; rtp_session->ice.type = type;
rtp_session->ice.priority = priority; rtp_session->ice.priority = priority;
rtp_session->ice.pass = "";
rtp_session->ice.rpass = "";
if (password) { if (password) {
rtp_session->ice.pass = switch_core_strdup(rtp_session->pool, password); rtp_session->ice.pass = switch_core_strdup(rtp_session->pool, password);
} }
if (rpassword) {
rtp_session->ice.rpass = switch_core_strdup(rtp_session->pool, rpassword);
}
rtp_session->ice.default_stuncount = 25; rtp_session->ice.default_stuncount = RTP_DEFAULT_STUNCOUNT;
rtp_session->ice.stuncount = 0; rtp_session->ice.stuncount = 0;
if (rtp_session->ice.ice_user) { if (rtp_session->ice.ice_user) {
@ -2458,7 +2486,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_sessio
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp_ice(switch_rtp_t *rtp_session, char *login, char *rlogin, SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp_ice(switch_rtp_t *rtp_session, char *login, char *rlogin,
const char *password, switch_core_media_ice_type_t type, uint32_t priority) const char *password, const char *rpassword, switch_core_media_ice_type_t type, uint32_t priority)
{ {
char ice_user[80]; char ice_user[80];
char user_ice[80]; char user_ice[80];
@ -2475,11 +2503,18 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp_ice(switch_rtp_t *rtp_s
rtp_session->rtcp_ice.user_ice = switch_core_strdup(rtp_session->pool, user_ice); rtp_session->rtcp_ice.user_ice = switch_core_strdup(rtp_session->pool, user_ice);
rtp_session->rtcp_ice.type = type; rtp_session->rtcp_ice.type = type;
rtp_session->rtcp_ice.priority = priority; rtp_session->rtcp_ice.priority = priority;
rtp_session->rtcp_ice.pass = "";
rtp_session->rtcp_ice.rpass = "";
if (password) { if (password) {
rtp_session->rtcp_ice.pass = switch_core_strdup(rtp_session->pool, password); rtp_session->rtcp_ice.pass = switch_core_strdup(rtp_session->pool, password);
} }
rtp_session->rtcp_ice.default_stuncount = 25;
if (rpassword) {
rtp_session->rtcp_ice.rpass = switch_core_strdup(rtp_session->pool, rpassword);
}
rtp_session->rtcp_ice.default_stuncount = RTP_DEFAULT_STUNCOUNT;
rtp_session->rtcp_ice.stuncount = 0; rtp_session->rtcp_ice.stuncount = 0;
if (rtp_session->rtcp_ice.ice_user) { if (rtp_session->rtcp_ice.ice_user) {

View File

@ -120,6 +120,7 @@ SWITCH_DECLARE(switch_stun_packet_t *) switch_stun_packet_parse(uint8_t *buf, ui
switch_stun_packet_attribute_t *attr; switch_stun_packet_attribute_t *attr;
uint32_t bytes_left = len; uint32_t bytes_left = len;
void *end_buf = buf + len; void *end_buf = buf + len;
int xlen = 0;
if (len < SWITCH_STUN_PACKET_MIN_LEN) { if (len < SWITCH_STUN_PACKET_MIN_LEN) {
return NULL; return NULL;
@ -128,7 +129,8 @@ SWITCH_DECLARE(switch_stun_packet_t *) switch_stun_packet_parse(uint8_t *buf, ui
packet = (switch_stun_packet_t *) buf; packet = (switch_stun_packet_t *) buf;
packet->header.type = ntohs(packet->header.type); packet->header.type = ntohs(packet->header.type);
packet->header.length = ntohs(packet->header.length); packet->header.length = ntohs(packet->header.length);
bytes_left -= packet->header.length + 20; bytes_left -= 20;
/* /*
* Check packet type (RFC3489(bis?) values) * Check packet type (RFC3489(bis?) values)
@ -182,12 +184,13 @@ SWITCH_DECLARE(switch_stun_packet_t *) switch_stun_packet_parse(uint8_t *buf, ui
attr->type = ntohs(attr->type); attr->type = ntohs(attr->type);
bytes_left -= 4; /* attribute header consumed */ bytes_left -= 4; /* attribute header consumed */
if (!attr->length || switch_stun_attribute_padded_length(attr) > bytes_left) { if (switch_stun_attribute_padded_length(attr) > bytes_left) {
/* /*
* Note we simply don't "break" here out of the loop anymore because * Note we simply don't "break" here out of the loop anymore because
* we don't want the upper layers to have to deal with attributes without a value * we don't want the upper layers to have to deal with attributes without a value
* (or worse: invalid length) * (or worse: invalid length)
*/ */
return NULL;
} }
/* /*
@ -202,6 +205,12 @@ SWITCH_DECLARE(switch_stun_packet_t *) switch_stun_packet_parse(uint8_t *buf, ui
case SWITCH_STUN_ATTR_REFLECTED_FROM: case SWITCH_STUN_ATTR_REFLECTED_FROM:
case SWITCH_STUN_ATTR_ALTERNATE_SERVER: case SWITCH_STUN_ATTR_ALTERNATE_SERVER:
case SWITCH_STUN_ATTR_DESTINATION_ADDRESS: case SWITCH_STUN_ATTR_DESTINATION_ADDRESS:
case SWITCH_STUN_ATTR_PRIORITY:
{
uint32_t *u = (uint32_t *)attr->value;
*u = ntohl(*u);
}
break;
case SWITCH_STUN_ATTR_SOURCE_ADDRESS2: case SWITCH_STUN_ATTR_SOURCE_ADDRESS2:
{ {
switch_stun_ip_t *ip; switch_stun_ip_t *ip;
@ -279,16 +288,18 @@ SWITCH_DECLARE(switch_stun_packet_t *) switch_stun_packet_parse(uint8_t *buf, ui
break; break;
default: default:
/* Mandatory attribute range? => invalid */
//if (attr->type <= 0x7FFF) {
// return NULL;
//}
break; break;
} }
bytes_left -= switch_stun_attribute_padded_length(attr); /* attribute value consumed, substract padded length */ bytes_left -= switch_stun_attribute_padded_length(attr); /* attribute value consumed, substract padded length */
xlen += 4 + switch_stun_attribute_padded_length(attr);
} while (bytes_left >= SWITCH_STUN_ATTRIBUTE_MIN_LEN && switch_stun_packet_next_attribute(attr, end_buf)); attr = (switch_stun_packet_attribute_t *) (attr->value + switch_stun_attribute_padded_length(attr));
if ((void *)attr > end_buf) {
break;
}
} while (xlen < packet->header.length);
if ((uint32_t) (packet->header.length + 20) > (uint32_t) (len - bytes_left)) { if ((uint32_t) (packet->header.length + 20) > (uint32_t) (len - bytes_left)) {
/* /*
* the packet length is longer than the length of all attributes? * the packet length is longer than the length of all attributes?
@ -296,10 +307,11 @@ SWITCH_DECLARE(switch_stun_packet_t *) switch_stun_packet_parse(uint8_t *buf, ui
*/ */
packet->header.length = (uint16_t) ((len - bytes_left) - 20); packet->header.length = (uint16_t) ((len - bytes_left) - 20);
} }
return packet; return packet;
} }
SWITCH_DECLARE(const char *) switch_stun_value_to_name(int32_t type, uint32_t value) SWITCH_DECLARE(const char *) switch_stun_value_to_name(int32_t type, uint32_t value)
{ {
uint32_t x = 0; uint32_t x = 0;
@ -460,16 +472,13 @@ SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_xor_binded_address(swit
SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_priority(switch_stun_packet_t *packet, uint32_t priority) SWITCH_DECLARE(uint8_t) switch_stun_packet_attribute_add_priority(switch_stun_packet_t *packet, uint32_t priority)
{ {
switch_stun_packet_attribute_t *attribute; switch_stun_packet_attribute_t *attribute;
uint32_t *lame;
priority = htonl(priority); priority = htonl(priority);
attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length)); attribute = (switch_stun_packet_attribute_t *) ((uint8_t *) & packet->first_attribute + ntohs(packet->header.length));
attribute->type = htons(SWITCH_STUN_ATTR_PRIORITY); attribute->type = htons(SWITCH_STUN_ATTR_PRIORITY);
attribute->length = htons(4); attribute->length = htons(4);
memcpy(attribute->value, &priority, 4); memcpy(attribute->value, &priority, 4);
lame = (uint32_t *) attribute->value;
printf("FUCKER2 %u %u\n", *lame, priority);
packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length; packet->header.length += htons(sizeof(switch_stun_packet_attribute_t)) + attribute->length;
return 1; return 1;
} }