diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index 51b7d23a5..92686da46 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -741,7 +741,7 @@ void sal_op_set_manual_refresher_mode(SalOp *op, bool_t enabled){ bool_t sal_op_is_ipv6(SalOp *op){ belle_sip_transaction_t *tr=NULL; belle_sip_header_address_t *contact; - belle_sip_request_t *req; + if (op->refresher) tr=(belle_sip_transaction_t *)belle_sip_refresher_get_transaction(op->refresher); @@ -750,17 +750,29 @@ bool_t sal_op_is_ipv6(SalOp *op){ tr=(belle_sip_transaction_t *)op->pending_client_trans; if (tr==NULL) tr=(belle_sip_transaction_t *)op->pending_server_trans; - + if (tr==NULL){ ms_error("Unable to determine IP version from signaling operation."); return FALSE; } - req=belle_sip_transaction_get_request(tr); - contact=(belle_sip_header_address_t*)belle_sip_message_get_header_by_type(req,belle_sip_header_contact_t); - if (!contact){ - ms_error("Unable to determine IP version from signaling operation, no contact header found."); + + + if (op->refresher) { + belle_sip_response_t *resp = belle_sip_transaction_get_response(tr); + belle_sip_header_via_t *via = resp ?belle_sip_message_get_header_by_type(resp,belle_sip_header_via_t):NULL; + if (!via){ + ms_error("Unable to determine IP version from signaling operation, no via header found."); + return FALSE; + } + return strchr(belle_sip_header_via_get_host(via),':') != NULL; + } else { + belle_sip_request_t *req = belle_sip_transaction_get_request(tr); + contact=(belle_sip_header_address_t*)belle_sip_message_get_header_by_type(req,belle_sip_header_contact_t); + if (!contact){ + ms_error("Unable to determine IP version from signaling operation, no contact header found."); + } + return sal_address_is_ipv6((SalAddress*)contact); } - return sal_address_is_ipv6((SalAddress*)contact); } bool_t sal_op_is_idle(SalOp *op){ diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 1cc34c2a6..2ef760ab3 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1202,10 +1202,12 @@ void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, S }else if (call->params->media_encryption != LinphoneMediaEncryptionZRTP){ call->params->media_encryption = LinphoneMediaEncryptionNone; } - if (!sal_media_description_has_ipv6(md)){ + + /*in case of nat64, even ipv4 addresses are reachable from v6. Should be enhanced to manage stream by stream connectivity (I.E v6 or v4)*/ + /*if (!sal_media_description_has_ipv6(md)){ ms_message("The remote SDP doesn't seem to offer any IPv6 connectivity, so disabling IPv6 for this call."); call->af = AF_INET; - } + }*/ linphone_call_fix_call_parameters(call, md); } diff --git a/tester/call_tester.c b/tester/call_tester.c index 98a67def3..643fd5031 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -6326,10 +6326,40 @@ static void call_with_zrtp_configured_callee_side(void) { linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); - - } + +static void v6_call_over_nat_64(void){ + 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_nat64_rc"); + pauline = linphone_core_manager_new("pauline_nat64_rc"); + + linphone_core_set_user_agent(pauline->lc, "Natted Linphone", NULL); + linphone_core_set_user_agent(marie->lc, "Natted Linphone", NULL); + + BC_ASSERT_TRUE(wait_for_until(pauline->lc, NULL, &pauline->stat.number_of_LinphoneRegistrationOk, 1, 2000)); + BC_ASSERT_TRUE(wait_for_until(pauline->lc, NULL, &marie->stat.number_of_LinphoneRegistrationOk, 1, 2000)); + + + BC_ASSERT_TRUE(call(marie,pauline)); + + liblinphone_tester_check_rtcp(marie,pauline); + end_call(marie,pauline); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + liblinphonetester_ipv6=liblinphonetester_ipv6_save; /*this test nee v6*/ + + }else ms_warning("Test skipped, no ipv6 nat64 available"); +} + + test_t call_tests[] = { TEST_NO_TAG("Early declined call", early_declined_call), TEST_NO_TAG("Call declined", call_declined), @@ -6343,6 +6373,7 @@ test_t call_tests[] = { TEST_NO_TAG("Call with http proxy", call_with_http_proxy), TEST_NO_TAG("Call with timeouted bye", call_with_timeouted_bye), TEST_NO_TAG("Direct call over IPv6", direct_call_over_ipv6), + TEST_NO_TAG("IPv6 call over NAT64", v6_call_over_nat_64), TEST_NO_TAG("Outbound call with multiple proxy possible", call_outbound_with_multiple_proxy), TEST_NO_TAG("Audio call recording", audio_call_recording_test), #if 0 /* not yet activated because not implemented */ diff --git a/tester/liblinphone_tester.h b/tester/liblinphone_tester.h index b02861d6a..7dea47ed1 100644 --- a/tester/liblinphone_tester.h +++ b/tester/liblinphone_tester.h @@ -70,6 +70,7 @@ extern test_suite_t complex_sip_call_test_suite; extern int manager_count; extern int liblinphone_tester_ipv6_available(void); +extern int liblinphone_tester_ipv4_available(void); /** * @brief Tells the tester whether or not to clean the accounts it has created between runs. diff --git a/tester/rcfiles/marie_nat64_rc b/tester/rcfiles/marie_nat64_rc new file mode 100644 index 000000000..a59516c72 --- /dev/null +++ b/tester/rcfiles/marie_nat64_rc @@ -0,0 +1,55 @@ +[sip] +sip_port=-1 +sip_tcp_port=-1 +sip_tls_port=-1 +default_proxy=0 +ping_with_options=0 +use_ipv6=1 +composing_idle_timeout=1 +store_ha1_passwd=0 #used for sipp + +[auth_info_0] +username=marie +userid=marie +passwd=secret +realm=sip.example.org + + +[proxy_0] +reg_proxy=sipv4.example.org;transport=tcp +reg_route=sipv4.example.org;transport=tcp;lr +reg_identity="Super Marie" +reg_expires=3600 +reg_sendregister=1 +publish=0 +dial_escape_plus=0 + +[friend_0] +url="Paupoche" +pol=accept +subscribe=0 + + +[rtp] +audio_rtp_port=18070-28000 +video_rtp_port=28070-38000 +text_rtp_port=39000-49000 + +[video] +display=0 +capture=0 +show_local=0 +size=qcif +enabled=0 +self_view=0 +automatically_initiate=0 +automatically_accept=0 +device=StaticImage: Static picture + +[sound] +echocancellation=0 #to not overload cpu in case of VG + +[net] +dns_srv_enabled=0 #no srv needed in general +stun_server=stun.linphone.org + diff --git a/tester/rcfiles/pauline_nat64_rc b/tester/rcfiles/pauline_nat64_rc new file mode 100644 index 000000000..b2255c3c6 --- /dev/null +++ b/tester/rcfiles/pauline_nat64_rc @@ -0,0 +1,51 @@ +[sip] +sip_port=-1 +sip_tcp_port=-1 +sip_tls_port=-1 +default_proxy=0 +ping_with_options=0 +use_ipv6=1 +composing_idle_timeout=1 + +[auth_info_0] +username=pauline +userid=pauline +passwd=secret +realm=sip.example.org + + +[proxy_0] +reg_proxy=sipv4.example.org;transport=tls +reg_route=sipv4.example.org;transport=tls +reg_identity=sip:pauline@sip.example.org +reg_expires=3600 +reg_sendregister=1 +publish=0 +dial_escape_plus=0 + +#[friend_0] +#url="Mariette" +#pol=accept +#subscribe=0 + +[rtp] +audio_rtp_port=18070-28000 +video_rtp_port=39072-49000 + +[video] +display=0 +capture=0 +show_local=0 +size=qcif +enabled=0 +self_view=0 +automatically_initiate=0 +automatically_accept=0 +device=StaticImage: Static picture + +[sound] +echocancellation=0 #to not overload cpu in case of VG + +[net] +dns_srv_enabled=0 #no srv needed in general +stun_server=stun.linphone.org diff --git a/tester/tester.c b/tester/tester.c index 928cff4a2..9accb8719 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -451,6 +451,25 @@ int liblinphone_tester_ipv6_available(void){ return FALSE; } +int liblinphone_tester_ipv4_available(void){ + struct addrinfo *ai=bctbx_ip_address_to_addrinfo(AF_INET,SOCK_STREAM,"212.27.40.240",53); + if (ai){ + struct sockaddr_storage ss; + struct addrinfo src; + socklen_t slen=sizeof(ss); + char localip[128]; + int port=0; + belle_sip_get_src_addr_for(ai->ai_addr,(socklen_t)ai->ai_addrlen,(struct sockaddr*) &ss,&slen,4444); + src.ai_addr=(struct sockaddr*) &ss; + src.ai_addrlen=slen; + bctbx_addrinfo_to_ip_address(&src,localip, sizeof(localip),&port); + freeaddrinfo(ai); + return strcmp(localip,"127.0.0.1")!=0; + } + return FALSE; +} + + void liblinphone_tester_keep_accounts( int keep ){ liblinphone_tester_keep_accounts_flag = keep; } diff --git a/tester/tester_hosts b/tester/tester_hosts index 638e4eb6d..6416ddebc 100644 --- a/tester/tester_hosts +++ b/tester/tester_hosts @@ -1,3 +1,4 @@ 94.23.19.176 sip2.linphone.org sip.example.org sipopen.example.org auth.example.org auth1.example.org auth2.example.org altname.linphone.org sip.wildcard1.linphone.org altname.wildcard2.linphone.org 2001:41d0:2:14b0::1 sip2.linphone.org sip.example.org sipopen.example.org auth.example.org auth1.example.org auth2.example.org altname.linphone.org sip.wildcard1.linphone.org altname.wildcard2.linphone.org 188.165.46.90 tunnel.wildcard2.linphone.org +64:ff9b::94.23.19.176 sipv4.example.org