Commit 78cb7617 authored by Ghislain MARY's avatar Ghislain MARY

Handle IPv6 for ICE and TURN.

parent b6a7b358
This diff is collapsed.
......@@ -220,20 +220,16 @@ static void stun_server_resolved(LinphoneNatPolicy *policy, const char *name, st
void linphone_nat_policy_resolve_stun_server(LinphoneNatPolicy *policy) {
const char *service = NULL;
/*
* WARNING: stun server resolution only done in IPv4.
* TODO: use IPv6 resolution if linphone_core_ipv6_enabled()==TRUE and use V4Mapped addresses for ICE gathering.
*/
if (linphone_nat_policy_stun_server_activated(policy)
&& (policy->lc->sal != NULL)
&& !policy->stun_resolver_context) {
if (linphone_nat_policy_stun_server_activated(policy) && (policy->lc->sal != NULL) && !policy->stun_resolver_context) {
char host[NI_MAXHOST];
int port = 3478;
linphone_parse_host_port(policy->stun_server, host, sizeof(host), &port);
if (linphone_nat_policy_turn_enabled(policy)) service = "turn";
else if (linphone_nat_policy_stun_enabled(policy)) service = "stun";
if (service != NULL) {
policy->stun_resolver_context = sal_resolve(policy->lc->sal, service, "udp", host, port, AF_INET, (SalResolverCallback)stun_server_resolved, policy);
int family = AF_INET;
if (linphone_core_ipv6_enabled(policy->lc) == TRUE) family = AF_INET6;
policy->stun_resolver_context = sal_resolve(policy->lc->sal, service, "udp", host, port, family, (SalResolverCallback)stun_server_resolved, policy);
}
}
}
......
......@@ -1232,15 +1232,30 @@ void _call_with_ice_base(LinphoneCoreManager* pauline,LinphoneCoreManager* marie
end_call(pauline, marie);
}
static void _call_with_ice(bool_t caller_with_ice, bool_t callee_with_ice, bool_t random_ports, bool_t forced_relay) {
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
static void _call_with_ice(bool_t caller_with_ice, bool_t callee_with_ice, bool_t random_ports, bool_t forced_relay, bool_t ipv6) {
LinphoneCoreManager* marie = linphone_core_manager_new2("marie_rc", FALSE);
LinphoneCoreManager* pauline = linphone_core_manager_new2(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc", FALSE);
if (ipv6) {
linphone_core_enable_ipv6(marie->lc, TRUE);
linphone_core_enable_ipv6(pauline->lc, TRUE);
}
linphone_core_manager_start(marie, TRUE);
linphone_core_manager_start(pauline, TRUE);
_call_with_ice_base(pauline,marie,caller_with_ice,callee_with_ice,random_ports,forced_relay);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void call_with_ice(void){
_call_with_ice(TRUE,TRUE,FALSE,FALSE);
_call_with_ice(TRUE,TRUE,FALSE,FALSE,FALSE);
}
static void call_with_ice_ipv6(void) {
if (liblinphone_tester_ipv6_available()) {
_call_with_ice(TRUE, TRUE, FALSE, FALSE, TRUE);
} else {
ms_warning("Test skipped, no ipv6 available");
}
}
/*ICE is not expected to work in this case, however this should not crash*/
......@@ -1264,19 +1279,19 @@ static void call_with_ice_no_sdp(void){
}
static void call_with_ice_random_ports(void){
_call_with_ice(TRUE,TRUE,TRUE,FALSE);
_call_with_ice(TRUE,TRUE,TRUE,FALSE,FALSE);
}
static void call_with_ice_forced_relay(void) {
_call_with_ice(TRUE, TRUE, TRUE, TRUE);
_call_with_ice(TRUE, TRUE, TRUE, TRUE, FALSE);
}
static void ice_to_not_ice(void){
_call_with_ice(TRUE,FALSE,FALSE,FALSE);
_call_with_ice(TRUE,FALSE,FALSE,FALSE,FALSE);
}
static void not_ice_to_ice(void){
_call_with_ice(FALSE,TRUE,FALSE,FALSE);
_call_with_ice(FALSE,TRUE,FALSE,FALSE,FALSE);
}
static void ice_added_by_reinvite(void){
......@@ -1311,15 +1326,11 @@ static void ice_added_by_reinvite(void){
linphone_call_params_destroy(params);
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallUpdatedByRemote,1));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2));
BC_ASSERT_TRUE(check_ice(marie, pauline, LinphoneIceStateHostConnection));
/*wait for the ICE reINVITE*/
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,3));
BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,3));
BC_ASSERT_TRUE(check_ice(marie, pauline, LinphoneIceStateHostConnection));
end_call(pauline, marie);
......@@ -4189,10 +4200,10 @@ static void _call_with_network_switch(bool_t use_ice, bool_t with_socket_refresh
wait_for_until(marie->lc, pauline->lc, NULL, 0, 2000);
if (use_ice) {
BC_ASSERT_TRUE(check_ice(pauline,marie,LinphoneIceStateHostConnection));
/*wait for ICE reINVITE to complete*/
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 2));
BC_ASSERT_TRUE(check_ice(pauline,marie,LinphoneIceStateHostConnection));
}
/*marie looses the network and reconnects*/
......@@ -4279,10 +4290,10 @@ static void call_with_sip_and_rtp_independant_switches(void){
wait_for_until(marie->lc, pauline->lc, NULL, 0, 2000);
if (use_ice) {
BC_ASSERT_TRUE(check_ice(pauline,marie,LinphoneIceStateHostConnection));
/*wait for ICE reINVITE to complete*/
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 2));
BC_ASSERT_TRUE(check_ice(pauline,marie,LinphoneIceStateHostConnection));
}
/*marie looses the SIP network and reconnects*/
linphone_core_set_sip_network_reachable(marie->lc, FALSE);
......@@ -4799,17 +4810,19 @@ static void v6_call_over_nat_64(void){
}
static void call_with_ice_in_ipv4_with_v6_enabled(void) {
if (liblinphone_tester_ipv4_available() && liblinphone_tester_ipv6_available()){
bool_t liblinphonetester_ipv6_save=liblinphonetester_ipv6; /*this test nee v6*/
LinphoneCoreManager* marie = linphone_core_manager_new("marie_v4proxy_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_v4proxy_rc");
liblinphonetester_ipv6=TRUE;
_call_with_ice_base(pauline,marie,TRUE,TRUE,TRUE,FALSE);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
liblinphonetester_ipv6=liblinphonetester_ipv6_save; /*this test nee v6*/
LinphoneCoreManager* marie;
LinphoneCoreManager* pauline;
if (liblinphone_tester_ipv4_available() && liblinphone_tester_ipv6_available()){
bool_t liblinphonetester_ipv6_save=liblinphonetester_ipv6; /*this test nee v6*/
liblinphonetester_ipv6=TRUE;
marie = linphone_core_manager_new("marie_v4proxy_rc");
pauline = linphone_core_manager_new("pauline_v4proxy_rc");
_call_with_ice_base(pauline,marie,TRUE,TRUE,TRUE,FALSE);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
liblinphonetester_ipv6=liblinphonetester_ipv6_save; /*this test nee v6*/
} else ms_warning("Test skipped, need both ipv6 and v4 available");
}
......@@ -4873,6 +4886,7 @@ test_t call_tests[] = {
TEST_NO_TAG("Call rejected without 403 because of wrong credential", call_rejected_without_403_because_wrong_credentials),
TEST_NO_TAG("Call rejected without 403 because of wrong credential and no auth req cb", call_rejected_without_403_because_wrong_credentials_no_auth_req_cb),
TEST_ONE_TAG("Call with ICE", call_with_ice, "ICE"),
TEST_ONE_TAG("Call with ICE IPv6", call_with_ice_ipv6, "ICE"),
TEST_ONE_TAG("Call with ICE without SDP", call_with_ice_no_sdp, "ICE"),
TEST_ONE_TAG("Call with ICE (random ports)", call_with_ice_random_ports, "ICE"),
TEST_ONE_TAG("Call with ICE (forced relay)", call_with_ice_forced_relay, "ICE"),
......
......@@ -886,11 +886,11 @@ static void _call_with_ice_video(LinphoneVideoPolicy caller_policy, LinphoneVide
BC_ASSERT_TRUE(call_ok = call(pauline, marie));
if (!call_ok) goto end;
BC_ASSERT_TRUE(check_ice(pauline, marie, LinphoneIceStateHostConnection));
/* Wait for ICE reINVITEs to complete. */
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2)
&& wait_for(pauline->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 2));
BC_ASSERT_TRUE(check_ice(pauline, marie, LinphoneIceStateHostConnection));
check_nb_media_starts(pauline, marie, nb_media_starts, nb_media_starts);
nb_media_starts++;
......
......@@ -121,7 +121,7 @@ static void check_turn_context_statistics(MSTurnContext *turn_context, bool_t fo
}
}
static void ice_turn_call_base(bool_t video_enabled, bool_t forced_relay, bool_t caller_turn_enabled, bool_t callee_turn_enabled, bool_t rtcp_mux_enabled) {
static void ice_turn_call_base(bool_t video_enabled, bool_t forced_relay, bool_t caller_turn_enabled, bool_t callee_turn_enabled, bool_t rtcp_mux_enabled, bool_t ipv6) {
LinphoneCoreManager *marie;
LinphoneCoreManager *pauline;
LinphoneCall *lcall;
......@@ -129,11 +129,16 @@ static void ice_turn_call_base(bool_t video_enabled, bool_t forced_relay, bool_t
LinphoneMediaDirection expected_video_dir = LinphoneMediaDirectionInactive;
bctbx_list_t *lcs = NULL;
marie = linphone_core_manager_new("marie_rc");
marie = linphone_core_manager_new2("marie_rc", FALSE);
lcs = bctbx_list_append(lcs, marie->lc);
pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
pauline = linphone_core_manager_new2(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc", FALSE);
lcs = bctbx_list_append(lcs, pauline->lc);
if (ipv6) {
linphone_core_enable_ipv6(marie->lc, TRUE);
linphone_core_enable_ipv6(pauline->lc, TRUE);
}
configure_nat_policy(marie->lc, caller_turn_enabled);
configure_nat_policy(pauline->lc, callee_turn_enabled);
if (forced_relay == TRUE) {
......@@ -148,6 +153,9 @@ static void ice_turn_call_base(bool_t video_enabled, bool_t forced_relay, bool_t
lp_config_set_int(linphone_core_get_config(pauline->lc), "rtp", "rtcp_mux", 1);
}
linphone_core_manager_start(marie, TRUE);
linphone_core_manager_start(pauline, TRUE);
if (video_enabled) {
#ifdef VIDEO_ENABLED
video_call_base_2(marie, pauline, FALSE, LinphoneMediaEncryptionNone, TRUE, TRUE);
......@@ -184,31 +192,39 @@ static void ice_turn_call_base(bool_t video_enabled, bool_t forced_relay, bool_t
}
static void basic_ice_turn_call(void) {
ice_turn_call_base(FALSE, FALSE, TRUE, TRUE, FALSE);
ice_turn_call_base(FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
}
static void basic_ipv6_ice_turn_call(void) {
if (liblinphone_tester_ipv6_available()) {
ice_turn_call_base(FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
} else {
ms_warning("Test skipped, no ipv6 available");
}
}
#ifdef VIDEO_ENABLED
static void video_ice_turn_call(void) {
ice_turn_call_base(TRUE, FALSE, TRUE, TRUE, FALSE);
ice_turn_call_base(TRUE, FALSE, TRUE, TRUE, FALSE, FALSE);
}
#endif
static void relayed_ice_turn_call(void) {
ice_turn_call_base(FALSE, TRUE, TRUE, TRUE, FALSE);
ice_turn_call_base(FALSE, TRUE, TRUE, TRUE, FALSE, FALSE);
}
#ifdef VIDEO_ENABLED
static void relayed_video_ice_turn_call(void) {
ice_turn_call_base(TRUE, TRUE, TRUE, TRUE, FALSE);
ice_turn_call_base(TRUE, TRUE, TRUE, TRUE, FALSE, FALSE);
}
#endif
static void relayed_ice_turn_call_with_rtcp_mux(void) {
ice_turn_call_base(FALSE, TRUE, TRUE, TRUE, TRUE);
ice_turn_call_base(FALSE, TRUE, TRUE, TRUE, TRUE, FALSE);
}
static void relayed_ice_turn_to_ice_stun_call(void) {
ice_turn_call_base(FALSE, TRUE, TRUE, FALSE, FALSE);
ice_turn_call_base(FALSE, TRUE, TRUE, FALSE, FALSE, FALSE);
}
......@@ -216,6 +232,7 @@ test_t stun_tests[] = {
TEST_ONE_TAG("Basic Stun test (Ping/public IP)", linphone_stun_test_grab_ip, "STUN"),
TEST_ONE_TAG("STUN encode", linphone_stun_test_encode, "STUN"),
TEST_TWO_TAGS("Basic ICE+TURN call", basic_ice_turn_call, "ICE", "TURN"),
TEST_TWO_TAGS("Basic IPv6 ICE+TURN call", basic_ipv6_ice_turn_call, "ICE", "TURN"),
#ifdef VIDEO_ENABLED
TEST_TWO_TAGS("Video ICE+TURN call", video_ice_turn_call, "ICE", "TURN"),
TEST_TWO_TAGS("Relayed video ICE+TURN call", relayed_video_ice_turn_call, "ICE", "TURN"),
......
......@@ -666,20 +666,33 @@ static void check_ice_from_rtp(LinphoneCall *c1, LinphoneCall *c2, LinphoneStrea
return;
}
if (linphone_call_get_audio_stats(c1)->ice_state == LinphoneIceStateHostConnection && media_stream_started(ms)) {
char ip[16];
char port[8];
getnameinfo((const struct sockaddr *)&c1->audiostream->ms.sessions.rtp_session->rtp.gs.rem_addr
, c1->audiostream->ms.sessions.rtp_session->rtp.gs.rem_addrlen
, ip
, sizeof(ip)
, port
, sizeof(port)
, NI_NUMERICHOST|NI_NUMERICSERV);
BC_ASSERT_STRING_EQUAL(ip, c2->media_localip);
struct sockaddr_storage remaddr;
socklen_t remaddrlen = sizeof(remaddr);
char ip[NI_MAXHOST] = { 0 };
int port = 0;
SalMediaDescription *result_desc;
char *expected_addr = NULL;
const LinphoneCallParams *cp1 = linphone_call_get_current_params(c1);
const LinphoneCallParams *cp2 = linphone_call_get_current_params(c2);
if (cp1->update_call_when_ice_completed && cp2->update_call_when_ice_completed) {
memset(&remaddr, 0, remaddrlen);
result_desc = sal_call_get_final_media_description(c2->op);
expected_addr = result_desc->streams[0].rtp_addr;
if (expected_addr[0] == '\0') expected_addr = result_desc->addr;
if ((strchr(expected_addr, ':') == NULL) && (c1->audiostream->ms.sessions.rtp_session->rtp.gs.rem_addr.ss_family == AF_INET6)) {
bctbx_sockaddr_ipv6_to_ipv4((struct sockaddr *)&c1->audiostream->ms.sessions.rtp_session->rtp.gs.rem_addr, (struct sockaddr *)&remaddr, &remaddrlen);
} else {
memcpy(&remaddr, &c1->audiostream->ms.sessions.rtp_session->rtp.gs.rem_addr, c1->audiostream->ms.sessions.rtp_session->rtp.gs.rem_addrlen);
}
bctbx_sockaddr_to_ip_address((struct sockaddr *)&remaddr, remaddrlen, ip, sizeof(ip), &port);
BC_ASSERT_STRING_EQUAL(ip, expected_addr);
}
}
}
bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee, LinphoneIceState state) {
LinphoneCall *c1,*c2;
bool_t audio_success=FALSE;
......
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