diff --git a/configure.ac b/configure.ac index cd9f90903..69a1ed745 100644 --- a/configure.ac +++ b/configure.ac @@ -1057,9 +1057,10 @@ else fi AM_CONDITIONAL(HAVE_DOXYGEN, test "$DOXYGEN" != "false") -AC_CHECK_PROG([SIPP],[sipp], [true], [false]) +AC_PATH_PROG([SIPP],[sipp],[false]) if test "x$SIPP" != "xfalse" ; then AC_DEFINE(HAVE_SIPP,1,[defined when SIPP is available]) + AC_DEFINE_UNQUOTED(SIPP_COMMAND,"$SIPP",[defined when SIPP is available]) fi AC_CONFIG_FILES([ diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index c23e4132e..81a967fe9 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -622,7 +622,12 @@ static int sal_add_listen_port(Sal *ctx, SalAddress* addr, bool_t is_tunneled){ if (lp) { belle_sip_listening_point_set_keep_alive(lp,ctx->keep_alive); result = belle_sip_provider_add_listening_point(ctx->prov,lp); - if (sal_address_get_transport(addr)==SalTransportTLS) set_tls_properties(ctx); + if (sal_address_get_transport(addr)==SalTransportTLS) { + belle_sip_tls_listening_point_t *tls_lp = (belle_sip_tls_listening_point_t *)lp; + belle_sip_tls_listening_point_set_http_proxy_host(tls_lp,ctx->http_proxy_host); + belle_sip_tls_listening_point_set_http_proxy_port(tls_lp,ctx->http_proxy_port); + set_tls_properties(ctx); + } } else { return -1; } @@ -1190,3 +1195,34 @@ int sal_enable_pending_trans_checking(Sal *sal, bool_t value) { sal->pending_trans_checking = value; return 0; } +void sal_set_http_proxy_host(Sal *sal, const char *host) { + belle_sip_tls_listening_point_t *lp=(belle_sip_tls_listening_point_t *)belle_sip_provider_get_listening_point(sal->prov,"TLS"); + if (sal->http_proxy_host) ms_free (sal->http_proxy_host); + if (host) + sal->http_proxy_host = ms_strdup(host); + else + sal->http_proxy_host = NULL; + + if (lp){ + belle_sip_tls_listening_point_set_http_proxy_host(lp,sal->http_proxy_host); + belle_sip_tls_listening_point_set_http_proxy_port(lp,sal->http_proxy_host); + } +} + +void sal_set_http_proxy_port(Sal *sal, int port) { + belle_sip_tls_listening_point_t *lp=(belle_sip_tls_listening_point_t *)belle_sip_provider_get_listening_point(sal->prov,"TLS"); + sal->http_proxy_port=port; + if (lp){ + belle_sip_tls_listening_point_set_http_proxy_port(lp,sal->http_proxy_port); + } + +} +const char *sal_get_http_proxy_host(const Sal *sal) { + return sal->http_proxy_host; +} + +int sal_get_http_proxy_port(const Sal *sal) { + return sal->http_proxy_port; +} + + diff --git a/coreapi/bellesip_sal/sal_impl.h b/coreapi/bellesip_sal/sal_impl.h index b75be9156..6e72b68c9 100644 --- a/coreapi/bellesip_sal/sal_impl.h +++ b/coreapi/bellesip_sal/sal_impl.h @@ -52,6 +52,8 @@ struct Sal{ bool_t enable_sip_update; /*true by default*/ SalOpSDPHandling default_sdp_handling; bool_t pending_trans_checking; /*testing purpose*/ + char *http_proxy_host; + int http_proxy_port; }; typedef enum SalOpState { diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 0c7e80566..4b11d7dac 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2193,7 +2193,10 @@ int _linphone_core_apply_transports(LinphoneCore *lc){ sal_unlisten_ports(sal); listening_address = lp_config_get_string(lc->config,"sip","bind_address",anyaddr); - + if (linphone_core_get_http_proxy_host(lc)) { + sal_set_http_proxy_host(sal, linphone_core_get_http_proxy_host(lc)); + sal_set_http_proxy_port(sal,linphone_core_get_http_proxy_port(lc)); + } if (lc->tunnel && linphone_tunnel_sip_enabled(lc->tunnel) && linphone_tunnel_get_activated(lc->tunnel)){ if (sal_listen_port(sal,anyaddr,tr->udp_port,SalTransportUDP,TRUE)!=0){ transport_error(lc,"udp+tunnel",tr->udp_port); @@ -7286,3 +7289,23 @@ LINPHONE_PUBLIC const char *linphone_core_log_collection_upload_state_to_string( bool_t linphone_core_realtime_text_enabled(LinphoneCore *lc) { return lc->text_conf.enabled; } +void linphone_core_set_http_proxy_host(LinphoneCore *lc, const char *host) { + lp_config_set_string(lc->config,"sip","http_proxy_host",host); + if (lc->sal) { + sal_set_http_proxy_host(lc->sal,host); + sal_set_http_proxy_port(lc->sal,linphone_core_get_http_proxy_port(lc)); /*to make sure default value is set*/ + } +} + +void linphone_core_set_http_proxy_port(LinphoneCore *lc, int port) { + lp_config_set_int(lc->config,"sip","http_proxy_port",port); + if (lc->sal) + sal_set_http_proxy_port(lc->sal,port); +} +const char *linphone_core_get_http_proxy_host(const LinphoneCore *lc) { + return lp_config_get_string(lc->config,"sip","http_proxy_host",NULL); +} + +int linphone_core_get_http_proxy_port(const LinphoneCore *lc) { + return lp_config_get_int(lc->config,"sip","http_proxy_port",3128); +} diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 93350eaee..af425c55a 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -4124,6 +4124,34 @@ LINPHONE_PUBLIC const char * linphone_core_get_video_preset(const LinphoneCore * */ LINPHONE_PUBLIC bool_t linphone_core_realtime_text_enabled(LinphoneCore *lc); +/** + * Set http proxy address to be used for signaling during next channel connection. Use #linphone_core_set_network_reachable FASLE/TRUE to force channel restart. + * @param[in] lc LinphoneCore object + * @param[in] hostname of IP adress of the http proxy (can be NULL to disable). + */ +LINPHONE_PUBLIC void linphone_core_set_http_proxy_host(LinphoneCore *lc, const char *host) ; + +/** + * Set http proxy port to be used for signaling. + * @param[in] lc LinphoneCore object + * @param[in] port of the http proxy. + */ +LINPHONE_PUBLIC void linphone_core_set_http_proxy_port(LinphoneCore *lc, int port) ; + +/** + * Get http proxy address to be used for signaling. + * @param[in] lc LinphoneCore object + * @return hostname of IP adress of the http proxy (can be NULL to disable). + */ +LINPHONE_PUBLIC const char *linphone_core_get_http_proxy_host(const LinphoneCore *lc); + +/** + * Get http proxy port to be used for signaling. + * @param[in] lc LinphoneCore object + * @return port of the http proxy. + */ +LINPHONE_PUBLIC int linphone_core_get_http_proxy_port(const LinphoneCore *lc); + #ifdef __cplusplus } #endif diff --git a/include/sal/sal.h b/include/sal/sal.h index a96498a95..72c47d2dd 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -842,6 +842,12 @@ void sal_end_background_task(unsigned long id); void sal_op_cnx_ip_to_0000_if_sendonly_enable(SalOp *sal,bool_t yesno); bool_t sal_op_cnx_ip_to_0000_if_sendonly_enabled(SalOp *sal); +void sal_set_http_proxy_host(Sal *sal, const char *host) ; +void sal_set_http_proxy_port(Sal *sal, int port) ; +const char *sal_get_http_proxy_host(const Sal *sal); +int sal_get_http_proxy_port(const Sal *sal); + + #endif diff --git a/tester/CMakeLists.txt b/tester/CMakeLists.txt index 76c4ecf7b..9d053e4c0 100644 --- a/tester/CMakeLists.txt +++ b/tester/CMakeLists.txt @@ -51,6 +51,7 @@ set(SOURCE_FILES find_program(SIPP_PROGRAM NAMES sipp sipp.exe) if(SIPP_PROGRAM) add_definitions(-DHAVE_SIPP=1) + add_definitions(-DSIPP_COMMAND="${SIPP_PROGRAM}") else() message(WARNING "Could not find sipp!") endif() diff --git a/tester/call_tester.c b/tester/call_tester.c index bc12e2892..40668c589 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -2421,7 +2421,7 @@ static void call_with_mkv_file_player(void) { char *recordpath; bool_t call_ok; #if !defined(__arm__) && !defined(__arm64__) && !TARGET_IPHONE_SIMULATOR && !defined(ANDROID) - double similar; + double similar=0.0; const double threshold = 0.9; #define DO_AUDIO_CMP #endif @@ -4890,6 +4890,36 @@ static void call_logs_sqlite_storage() { #endif + +static void call_with_http_proxy(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_rc"); + bool_t call_ok; + LinphoneCall *marie_call; + LinphoneAddress *contact_addr; + struct hostent *he = gethostbyname("sip.linphone.org"); + + if (!transport_supported(LinphoneTransportTls)) { + ms_message("Test skipped because no tls support"); + goto end; + } + + linphone_core_set_http_proxy_host(pauline->lc,"sip.linphone.org"); + linphone_core_set_network_reachable(pauline->lc, FALSE); /*to make sure channel is restarted*/ + linphone_core_set_network_reachable(pauline->lc, TRUE); + + BC_ASSERT_TRUE((call_ok=call(pauline,marie))); + if (!call_ok) goto end; + + marie_call = linphone_core_get_current_call(marie->lc); + contact_addr = linphone_address_new(linphone_call_get_remote_contact(marie_call)); + BC_ASSERT_STRING_EQUAL(linphone_address_get_domain(contact_addr),inet_ntoa(*((struct in_addr **)he->h_addr_list)[0])); + linphone_address_destroy(contact_addr); +end: + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + +} test_t call_tests[] = { { "Early declined call", early_declined_call }, { "Call declined", call_declined }, @@ -4899,6 +4929,7 @@ test_t call_tests[] = { { "Cancelled ringing call", cancelled_ringing_call }, { "Call busy when calling self", call_busy_when_calling_self}, { "Simple call", simple_call }, + { "Call with http proxy", call_with_http_proxy }, { "Call with timeouted bye", call_with_timeouted_bye }, { "Direct call over IPv6", direct_call_over_ipv6}, { "Outbound call with multiple proxy possible", call_outbound_with_multiple_proxy }, diff --git a/tester/complex_sip_call_tester.c b/tester/complex_sip_call_tester.c index 9681e6c88..16e4417da 100644 --- a/tester/complex_sip_call_tester.c +++ b/tester/complex_sip_call_tester.c @@ -49,6 +49,7 @@ void check_rtcp(LinphoneCall *call) { } static FILE *sip_start(const char *senario, const char* dest_username, LinphoneAddress* dest_addres) { +#if HAVE_SIPP char *dest; char *command; FILE *file; @@ -57,15 +58,17 @@ static FILE *sip_start(const char *senario, const char* dest_username, LinphoneA dest = ms_strdup_printf("%s:%i",linphone_address_get_domain(dest_addres),linphone_address_get_port(dest_addres)); else dest = ms_strdup_printf("%s",linphone_address_get_domain(dest_addres)); - //until errors logs are handled correctly and stop breaks output, they will be DISABLED - command = ms_strdup_printf("sipp -sf %s -s %s %s -trace_err -trace_msg -rtp_echo -m 1 -d 1000 2>/dev/null",senario,dest_username,dest); + command = ms_strdup_printf(SIPP_COMMAND" -sf %s -s %s %s -trace_err -trace_msg -rtp_echo -m 1 -d 1000",senario,dest_username,dest); ms_message("Starting sipp commad [%s]",command); file = popen(command, "r"); ms_free(command); ms_free(dest); return file; +#else + return NULL; +#endif } /*static void dest_server_server_resolved(void *data, const char *name, struct addrinfo *ai_list) { *(struct addrinfo **)data =ai_list;