Commit 9951583b authored by Ghislain MARY's avatar Ghislain MARY

Check for ICE mismatch.

parent 97187262
......@@ -184,11 +184,13 @@ typedef struct _IceCheckList {
MSList *check_list; /**< List of IceCandidatePair structures */
MSList *valid_list; /**< List of IceValidCandidatePair structures */
MSList *foundations; /**< List of IcePairFoundation structures */
MSList *componentIDs; /**< List of uint16_t */
MSList *local_componentIDs; /**< List of uint16_t */
MSList *remote_componentIDs; /**< List of uint16_t */
IceCheckListState state; /**< Global state of the ICE check list */
uint64_t ta_time; /**< Time when the Ta timer has been processed for the last time */
uint64_t keepalive_time; /**< Time when the last keepalive packet has been sent for this stream */
uint32_t foundation_generator; /**< Autoincremented integer to generate unique foundation values */
bool_t mismatch; /**< Boolean value telling whether there was a mismatch during the answer/offer process */
} IceCheckList;
......@@ -384,6 +386,14 @@ MS2_PUBLIC const char * ice_check_list_remote_ufrag(const IceCheckList *cl);
*/
MS2_PUBLIC const char * ice_check_list_remote_pwd(const IceCheckList *cl);
/**
* Get the mismatch property of an ICE check list.
*
* @param cl A pointer to a check list
* @return TRUE if there was a mismatch for the check list, FALSE otherwise
*/
MS2_PUBLIC bool_t ice_check_list_is_mismatch(const IceCheckList *cl);
/**
* Set the remote credentials of an ICE check list.
*
......@@ -522,6 +532,15 @@ MS2_PUBLIC void ice_session_eliminate_redundant_candidates(IceSession *session);
*/
MS2_PUBLIC void ice_session_choose_default_candidates(IceSession *session);
/**
* Choose the default remote candidates of an ICE session.
*
* This function SHOULD not be used. Instead, the default remote candidates MUST be defined as default
* when creating them with ice_add_remote_candidate().
* However, this function is used by mediastream for testing purpose.
*/
void ice_session_choose_default_remote_candidates(IceSession *session);
/**
* Pair the local and the remote candidates for an ICE session and start sending connectivity checks.
*
......@@ -529,6 +548,13 @@ MS2_PUBLIC void ice_session_choose_default_candidates(IceSession *session);
*/
MS2_PUBLIC void ice_session_start_connectivity_checks(IceSession *session);
/**
* Check whether all the ICE check lists of the session includes a default candidate for each component ID in its remote candidates list.
*
* @param session A pointer to a session
*/
MS2_PUBLIC void ice_session_check_mismatch(IceSession *session);
/**
* Core ICE check list processing.
*
......
......@@ -210,11 +210,12 @@ static void ice_check_list_init(IceCheckList *cl)
cl->session = NULL;
cl->remote_ufrag = cl->remote_pwd = NULL;
cl->local_candidates = cl->remote_candidates = cl->pairs = cl->triggered_checks_queue = cl->check_list = cl->valid_list = NULL;
cl->componentIDs = cl->foundations = NULL;
cl->local_componentIDs = cl->remote_componentIDs = cl->foundations = NULL;
cl->state = ICL_Running;
cl->ta_time = 0;
cl->keepalive_time = 0;
cl->foundation_generator = 1;
cl->mismatch = FALSE;
}
IceCheckList * ice_check_list_new(void)
......@@ -297,7 +298,8 @@ void ice_check_list_destroy(IceCheckList *cl)
ms_list_for_each(cl->remote_candidates, (void (*)(void*))ice_free_candidate);
ms_list_for_each(cl->local_candidates, (void (*)(void*))ice_free_candidate);
ms_list_free(cl->foundations);
ms_list_free(cl->componentIDs);
ms_list_free(cl->local_componentIDs);
ms_list_free(cl->remote_componentIDs);
ms_list_free(cl->valid_list);
ms_list_free(cl->check_list);
ms_list_free(cl->triggered_checks_queue);
......@@ -491,6 +493,11 @@ static bool_t ice_check_list_is_frozen(const IceCheckList *cl)
return (elem == NULL);
}
bool_t ice_check_list_is_mismatch(const IceCheckList *cl)
{
return cl->mismatch;
}
/******************************************************************************
* SESSION ACCESSORS *
......@@ -582,6 +589,30 @@ void ice_session_add_check_list(IceSession *session, IceCheckList *cl)
cl->session = session;
}
static int ice_find_default_candidate_from_componentID(const IceCandidate *candidate, const uint16_t *componentID)
{
return !((candidate->is_default == TRUE) && (candidate->componentID == *componentID));
}
static void ice_find_default_remote_candidate_for_componentID(const uint16_t *componentID, IceCheckList *cl)
{
MSList *elem = ms_list_find_custom(cl->remote_candidates, (MSCompareFunc)ice_find_default_candidate_from_componentID, componentID);
if (elem == NULL) {
cl->mismatch = TRUE;
cl->state = ICL_Failed;
}
}
static void ice_check_list_check_mismatch(IceCheckList *cl)
{
ms_list_for_each2(cl->remote_componentIDs, (void (*)(void*,void*))ice_find_default_remote_candidate_for_componentID, cl);
}
void ice_session_check_mismatch(IceSession *session)
{
ms_list_for_each(session->streams, (void (*)(void*))ice_check_list_check_mismatch);
}
/******************************************************************************
* STUN PACKETS HANDLING *
......@@ -807,7 +838,7 @@ static void ice_send_keepalive_packets(IceCheckList *cl, const RtpSession *rtp_s
CheckList_RtpSession cr;
cr.cl = cl;
cr.rtp_session = rtp_session;
ms_list_for_each2(cl->componentIDs, (void (*)(void*,void*))ice_send_keepalive_packet_for_componentID, &cr);
ms_list_for_each2(cl->local_componentIDs, (void (*)(void*,void*))ice_send_keepalive_packet_for_componentID, &cr);
}
static int ice_find_candidate_from_transport_address(const IceCandidate *candidate, const IceTransportAddress *taddr)
......@@ -1407,11 +1438,11 @@ static int ice_find_componentID(const uint16_t *cid1, const uint16_t *cid2)
return !(*cid1 == *cid2);
}
static void ice_add_componentID(IceCheckList *cl, uint16_t *componentID)
static void ice_add_componentID(MSList **list, uint16_t *componentID)
{
MSList *elem = ms_list_find_custom(cl->componentIDs, (MSCompareFunc)ice_find_componentID, componentID);
MSList *elem = ms_list_find_custom(*list, (MSCompareFunc)ice_find_componentID, componentID);
if (elem == NULL) {
cl->componentIDs = ms_list_append(cl->componentIDs, componentID);
*list = ms_list_append(*list, componentID);
}
}
......@@ -1422,7 +1453,7 @@ IceCandidate * ice_add_local_candidate(IceCheckList* cl, const char* type, const
if (candidate->base == NULL) candidate->base = base;
ice_compute_candidate_priority(candidate);
ice_add_componentID(cl, &candidate->componentID);
ice_add_componentID(&cl->local_componentIDs, &candidate->componentID);
return candidate;
}
......@@ -1436,6 +1467,7 @@ IceCandidate * ice_add_remote_candidate(IceCheckList *cl, const char *type, cons
else candidate->priority = priority;
strncpy(candidate->foundation, foundation, sizeof(candidate->foundation) - 1);
candidate->is_default = is_default;
ice_add_componentID(&cl->remote_componentIDs, &candidate->componentID);
return candidate;
}
......@@ -1607,7 +1639,6 @@ static void ice_choose_local_or_remote_default_candidates(IceCheckList *cl, MSLi
static void ice_check_list_choose_default_candidates(IceCheckList *cl)
{
ice_choose_local_or_remote_default_candidates(cl, cl->local_candidates);
ice_choose_local_or_remote_default_candidates(cl, cl->remote_candidates);
}
void ice_session_choose_default_candidates(IceSession *session)
......@@ -1615,6 +1646,16 @@ void ice_session_choose_default_candidates(IceSession *session)
ms_list_for_each(session->streams, (void (*)(void*))ice_check_list_choose_default_candidates);
}
static void ice_check_list_choose_default_remote_candidates(IceCheckList *cl)
{
ice_choose_local_or_remote_default_candidates(cl, cl->remote_candidates);
}
void ice_session_choose_default_remote_candidates(IceSession *session)
{
ms_list_for_each(session->streams, (void (*)(void*))ice_check_list_choose_default_remote_candidates);
}
/******************************************************************************
* FORM CANDIDATES PAIRS *
......@@ -1951,7 +1992,7 @@ static void ice_conclude_processing(IceCheckList *cl, RtpSession *rtp_session)
cb.cl = cl;
cb.result = TRUE;
ms_list_for_each2(cl->componentIDs, (void (*)(void*,void*))ice_find_nominated_valid_pair_for_componentID, &cb);
ms_list_for_each2(cl->local_componentIDs, (void (*)(void*,void*))ice_find_nominated_valid_pair_for_componentID, &cb);
if (cb.result == TRUE) {
if (cl->state != ICL_Completed) {
cl->state = ICL_Completed;
......@@ -2144,7 +2185,7 @@ static void ice_set_base_for_srflx_candidate_with_componentID(uint16_t *componen
static void ice_check_list_set_base_for_srflx_candidates(IceCheckList *cl)
{
ms_list_for_each2(cl->componentIDs, (void (*)(void*,void*))ice_set_base_for_srflx_candidate_with_componentID, cl);
ms_list_for_each2(cl->local_componentIDs, (void (*)(void*,void*))ice_set_base_for_srflx_candidate_with_componentID, cl);
}
void ice_session_set_base_for_srflx_candidates(IceSession *session)
......@@ -2173,7 +2214,7 @@ static MSList * ice_get_valid_pairs(const IceCheckList *cl)
cm.cl = cl;
cm.list = &valid_pairs;
ms_list_for_each2(cl->componentIDs, (void (*)(void*,void*))ice_get_valid_pair_for_componentID, &cm);
ms_list_for_each2(cl->local_componentIDs, (void (*)(void*,void*))ice_get_valid_pair_for_componentID, &cm);
return valid_pairs;
}
......@@ -2342,5 +2383,5 @@ static void ice_dump_componentID(const uint16_t *componentID)
void ice_dump_componentIDs(const IceCheckList* cl)
{
ms_debug("Component IDs:");
ms_list_for_each(cl->componentIDs, (void (*)(void*))ice_dump_componentID);
ms_list_for_each(cl->local_componentIDs, (void (*)(void*))ice_dump_componentID);
}
......@@ -626,8 +626,8 @@ void setup_media_streams(MediastreamDatas* args) {
candidate=&args->ice_remote_candidates[c];
memset(foundation, '\0', sizeof(foundation));
snprintf(foundation, sizeof(foundation) - 1, "%u", c + 1);
ice_add_remote_candidate(args->audio->ice_check_list,candidate->type,candidate->ip,candidate->port,1,0,foundation);
ice_add_remote_candidate(args->audio->ice_check_list,candidate->type,candidate->ip,candidate->port+1,2,0,foundation);
ice_add_remote_candidate(args->audio->ice_check_list,candidate->type,candidate->ip,candidate->port,1,0,foundation,FALSE);
ice_add_remote_candidate(args->audio->ice_check_list,candidate->type,candidate->ip,candidate->port+1,2,0,foundation,FALSE);
}
}
......@@ -727,6 +727,7 @@ void setup_media_streams(MediastreamDatas* args) {
ice_session_set_base_for_srflx_candidates(args->ice_session);
ice_session_compute_candidates_foundations(args->ice_session);
ice_session_choose_default_candidates(args->ice_session);
ice_session_choose_default_remote_candidates(args->ice_session);
ice_session_start_connectivity_checks(args->ice_session);
OrtpNetworkSimulatorParams params={0};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment