Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
mediastreamer2
Commits
c640bc4a
Commit
c640bc4a
authored
Jul 11, 2012
by
Ghislain MARY
Browse files
Handle triggered checks when receiving ICE connectivity checks.
parent
e4178775
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
119 additions
and
47 deletions
+119
-47
src/ice.c
src/ice.c
+119
-47
No files found.
src/ice.c
View file @
c640bc4a
...
...
@@ -61,8 +61,15 @@ typedef struct _CheckList_RtpSession_Time {
uint64_t
time
;
}
CheckList_RtpSession_Time
;
typedef
struct
_LocalCandidate_RemoteCandidate
{
IceCandidate
*
local
;
IceCandidate
*
remote
;
}
LocalCandidate_RemoteCandidate
;
static
int
ice_compare_transport_addresses
(
const
IceTransportAddress
*
ta1
,
const
IceTransportAddress
*
ta2
);
static
int
ice_compare_pair_priorities
(
const
IceCandidatePair
*
p1
,
const
IceCandidatePair
*
p2
);
static
void
ice_pair_set_state
(
IceCandidatePair
*
pair
,
IceCandidatePairState
state
);
static
void
ice_compute_candidate_foundation
(
IceCandidate
*
candidate
,
IceCheckList
*
cl
);
static
void
ice_set_credentials
(
char
**
ufrag
,
char
**
pwd
,
const
char
*
ufrag_str
,
const
char
*
pwd_str
);
...
...
@@ -181,6 +188,44 @@ IceCheckList * ice_check_list_new(void)
return
cl
;
}
static
void
ice_compute_pair_priority
(
IceCandidatePair
*
pair
,
IceRole
*
role
)
{
/* Use formula defined in 5.7.2 to compute pair priority. */
uint64_t
G
;
uint64_t
D
;
switch
(
*
role
)
{
case
IR_Controlling
:
G
=
pair
->
local
->
priority
;
D
=
pair
->
remote
->
priority
;
break
;
case
IR_Controlled
:
G
=
pair
->
remote
->
priority
;
D
=
pair
->
local
->
priority
;
break
;
}
pair
->
priority
=
(
MIN
(
G
,
D
)
<<
32
)
|
(
MAX
(
G
,
D
)
<<
1
)
|
(
G
>
D
?
1
:
0
);
}
static
IceCandidatePair
*
ice_pair_new
(
IceCheckList
*
cl
,
IceCandidate
*
local_candidate
,
IceCandidate
*
remote_candidate
)
{
IceCandidatePair
*
pair
=
ms_new
(
IceCandidatePair
,
1
);
pair
->
local
=
local_candidate
;
pair
->
remote
=
remote_candidate
;
ice_pair_set_state
(
pair
,
ICP_Frozen
);
pair
->
is_default
=
FALSE
;
pair
->
is_nominated
=
FALSE
;
if
((
pair
->
local
->
is_default
==
TRUE
)
&&
(
pair
->
remote
->
is_default
==
TRUE
))
pair
->
is_default
=
TRUE
;
else
pair
->
is_default
=
FALSE
;
memset
(
&
pair
->
transactionID
,
0
,
sizeof
(
pair
->
transactionID
));
pair
->
rto
=
ICE_DEFAULT_RTO_DURATION
;
pair
->
retransmissions
=
0
;
pair
->
role
=
cl
->
session
->
role
;
ice_compute_pair_priority
(
pair
,
&
cl
->
session
->
role
);
// TODO: Handle is_valid.
return
pair
;
}
static
void
ice_free_pair_foundation
(
IcePairFoundation
*
foundation
)
{
ms_free
(
foundation
);
...
...
@@ -297,25 +342,6 @@ const char * ice_session_remote_pwd(IceSession *session)
return
session
->
remote_pwd
;
}
static
void
ice_compute_pair_priority
(
IceCandidatePair
*
pair
,
IceRole
*
role
)
{
/* Use formula defined in 5.7.2 to compute pair priority. */
uint64_t
G
;
uint64_t
D
;
switch
(
*
role
)
{
case
IR_Controlling
:
G
=
pair
->
local
->
priority
;
D
=
pair
->
remote
->
priority
;
break
;
case
IR_Controlled
:
G
=
pair
->
remote
->
priority
;
D
=
pair
->
local
->
priority
;
break
;
}
pair
->
priority
=
(
MIN
(
G
,
D
)
<<
32
)
|
(
MAX
(
G
,
D
)
<<
1
)
|
(
G
>
D
?
1
:
0
);
}
static
void
ice_check_list_compute_pair_priorities
(
IceCheckList
*
cl
)
{
ms_list_for_each2
(
cl
->
pairs
,
(
void
(
*
)(
void
*
,
void
*
))
ice_compute_pair_priority
,
&
cl
->
session
->
role
);
...
...
@@ -599,6 +625,13 @@ static int ice_check_received_binding_request_role_conflict(IceCheckList *cl, Rt
return
0
;
}
static
void
ice_fill_transport_address
(
IceTransportAddress
*
taddr
,
const
char
*
ip
,
int
port
)
{
memset
(
taddr
,
0
,
sizeof
(
IceTransportAddress
));
strncpy
(
taddr
->
ip
,
ip
,
sizeof
(
taddr
->
ip
));
taddr
->
port
=
port
;
}
static
int
ice_find_candidate_from_foundation
(
IceCandidate
*
candidate
,
const
char
*
foundation
)
{
return
!
((
strlen
(
candidate
->
foundation
)
==
strlen
(
foundation
))
&&
(
strcmp
(
candidate
->
foundation
,
foundation
)
==
0
));
...
...
@@ -616,42 +649,94 @@ static void ice_generate_arbitrary_foundation(char *foundation, int len, MSList
}
while
(
elem
!=
NULL
);
}
static
IceCandidate
*
ice_learn_peer_reflexive_candidate
(
IceCheckList
*
cl
,
const
StunMessage
*
msg
,
const
Stun
Address
4
*
remote_addr
,
const
char
*
src6host
)
static
IceCandidate
*
ice_learn_peer_reflexive_candidate
(
IceCheckList
*
cl
,
const
StunMessage
*
msg
,
const
IceTransport
Address
*
taddr
)
{
char
foundation
[
32
];
IceTransportAddress
taddr
;
IceCandidate
*
candidate
=
NULL
;
MSList
*
elem
;
uint16_t
componentID
=
1
;
// TODO: Set the component ID according to the port on which the binding request was received
memset
(
&
taddr
,
0
,
sizeof
(
taddr
));
strncpy
(
taddr
.
ip
,
src6host
,
sizeof
(
taddr
.
ip
));
taddr
.
port
=
remote_addr
->
port
;
elem
=
ms_list_find_custom
(
cl
->
remote_candidates
,
(
MSCompareFunc
)
ice_find_candidate_from_transport_address
,
&
taddr
);
elem
=
ms_list_find_custom
(
cl
->
remote_candidates
,
(
MSCompareFunc
)
ice_find_candidate_from_transport_address
,
taddr
);
if
(
elem
==
NULL
)
{
ms_message
(
"ice: Learned peer reflexive candidate %s:%d"
,
taddr
.
ip
,
taddr
.
port
);
ms_message
(
"ice: Learned peer reflexive candidate %s:%d"
,
taddr
->
ip
,
taddr
->
port
);
/* Add peer reflexive candidate to the remote candidates list. */
memset
(
foundation
,
'\0'
,
sizeof
(
foundation
));
ice_generate_arbitrary_foundation
(
foundation
,
sizeof
(
foundation
),
cl
->
remote_candidates
);
candidate
=
ice_add_remote_candidate
(
cl
,
"prflx"
,
taddr
.
ip
,
taddr
.
port
,
componentID
,
msg
->
priority
.
priority
,
foundation
);
candidate
=
ice_add_remote_candidate
(
cl
,
"prflx"
,
taddr
->
ip
,
taddr
->
port
,
componentID
,
msg
->
priority
.
priority
,
foundation
);
}
return
candidate
;
}
static
int
ice_find_pair_from_candidates
(
IceCandidatePair
*
pair
,
LocalCandidate_RemoteCandidate
*
candidates
)
{
return
!
((
pair
->
local
==
candidates
->
local
)
&&
(
pair
->
remote
==
candidates
->
remote
));
}
/* Trigger checks as defined in 7.2.1.4. */
static
void
ice_trigger_connectivity_check_on_binding_request
(
IceCheckList
*
cl
,
RtpSession
*
rtp_session
,
IceCandidate
*
prflx_candidate
,
const
IceTransportAddress
*
remote_taddr
)
{
IceTransportAddress
local_taddr
;
LocalCandidate_RemoteCandidate
candidates
;
MSList
*
elem
;
IceCandidatePair
*
pair
;
ice_fill_transport_address
(
&
local_taddr
,
"192.168.0.147"
,
rtp_session
->
rtp
.
loc_port
);
// TODO: Get local IP address
elem
=
ms_list_find_custom
(
cl
->
local_candidates
,
(
MSCompareFunc
)
ice_find_candidate_from_transport_address
,
&
local_taddr
);
if
(
elem
==
NULL
)
{
ms_error
(
"Local candidate %s:%d not found!"
,
local_taddr
.
ip
,
local_taddr
.
port
);
return
;
}
candidates
.
local
=
(
IceCandidate
*
)
elem
->
data
;
if
(
prflx_candidate
!=
NULL
)
{
candidates
.
remote
=
prflx_candidate
;
}
else
{
elem
=
ms_list_find_custom
(
cl
->
remote_candidates
,
(
MSCompareFunc
)
ice_find_candidate_from_transport_address
,
remote_taddr
);
if
(
elem
==
NULL
)
{
ms_error
(
"Remote candidate %s:%d not found!"
,
remote_taddr
->
ip
,
remote_taddr
->
port
);
return
;
}
candidates
.
remote
=
(
IceCandidate
*
)
elem
->
data
;
}
elem
=
ms_list_find_custom
(
cl
->
pairs
,
(
MSCompareFunc
)
ice_find_pair_from_candidates
,
&
candidates
);
if
(
elem
==
NULL
)
{
/* The pair is not in the check list yet. */
ms_message
(
"ice: Add new candidate pair in the check list"
);
pair
=
ice_pair_new
(
cl
,
candidates
.
local
,
candidates
.
remote
);
cl
->
pairs
=
ms_list_insert_sorted
(
cl
->
pairs
,
pair
,
(
MSCompareFunc
)
ice_compare_pair_priorities
);
/* Set the state of the pair to Waiting and trigger a check. */
pair
->
transmission_time
=
cl
->
session
->
ticker
->
time
;
ice_pair_set_state
(
pair
,
ICP_Waiting
);
}
else
{
/* The pair has been found in the check list. */
pair
=
(
IceCandidatePair
*
)
elem
->
data
;
switch
(
pair
->
state
)
{
case
ICP_Waiting
:
case
ICP_Frozen
:
case
ICP_InProgress
:
case
ICP_Failed
:
ice_pair_set_state
(
pair
,
ICP_Waiting
);
// TODO: Trigger check
break
;
case
ICP_Succeeded
:
/* Nothing to be done. */
break
;
}
}
}
static
void
ice_handle_received_binding_request
(
IceCheckList
*
cl
,
RtpSession
*
rtp_session
,
const
StunMessage
*
msg
,
const
StunAddress4
*
remote_addr
,
mblk_t
*
mp
,
const
char
*
src6host
)
{
IceCandidate
*
candidate
;
IceTransportAddress
taddr
;
IceCandidate
*
prflx_candidate
;
if
(
ice_check_received_binding_request_attributes
(
rtp_session
,
msg
,
remote_addr
)
<
0
)
return
;
if
(
ice_check_received_binding_request_integrity
(
cl
,
rtp_session
,
msg
,
remote_addr
,
mp
)
<
0
)
return
;
if
(
ice_check_received_binding_request_username
(
cl
,
rtp_session
,
msg
,
remote_addr
)
<
0
)
return
;
if
(
ice_check_received_binding_request_role_conflict
(
cl
,
rtp_session
,
msg
,
remote_addr
)
<
0
)
return
;
candidate
=
ice_learn_peer_reflexive_candidate
(
cl
,
msg
,
remote_addr
,
src6host
);
if
(
candidate
!=
NULL
)
{
// TODO: Trigger checks and update nominated flag
}
ice_fill_transport_address
(
&
taddr
,
src6host
,
remote_addr
->
port
);
prflx_candidate
=
ice_learn_peer_reflexive_candidate
(
cl
,
msg
,
&
taddr
);
ice_trigger_connectivity_check_on_binding_request
(
cl
,
rtp_session
,
prflx_candidate
,
&
taddr
);
ice_send_binding_response
(
rtp_session
,
msg
,
remote_addr
);
}
...
...
@@ -1031,20 +1116,7 @@ static void ice_form_candidate_pairs(IceCheckList *cl)
local_candidate
=
(
IceCandidate
*
)
local_list
->
data
;
remote_candidate
=
(
IceCandidate
*
)
remote_list
->
data
;
if
(
local_candidate
->
componentID
==
remote_candidate
->
componentID
)
{
pair
=
ms_new
(
IceCandidatePair
,
1
);
pair
->
local
=
local_candidate
;
pair
->
remote
=
remote_candidate
;
ice_pair_set_state
(
pair
,
ICP_Frozen
);
pair
->
is_default
=
FALSE
;
pair
->
is_nominated
=
FALSE
;
if
((
pair
->
local
->
is_default
==
TRUE
)
&&
(
pair
->
remote
->
is_default
==
TRUE
))
pair
->
is_default
=
TRUE
;
else
pair
->
is_default
=
FALSE
;
memset
(
&
pair
->
transactionID
,
0
,
sizeof
(
pair
->
transactionID
));
pair
->
rto
=
ICE_DEFAULT_RTO_DURATION
;
pair
->
retransmissions
=
0
;
pair
->
role
=
cl
->
session
->
role
;
ice_compute_pair_priority
(
pair
,
&
cl
->
session
->
role
);
// TODO: Handle is_valid.
pair
=
ice_pair_new
(
cl
,
local_candidate
,
remote_candidate
);
cl
->
pairs
=
ms_list_insert_sorted
(
cl
->
pairs
,
pair
,
(
MSCompareFunc
)
ice_compare_pair_priorities
);
}
remote_list
=
ms_list_next
(
remote_list
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment