From b35df101ee162831573fd9b11515e34ed71638db Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 9 Mar 2018 17:42:22 +0100 Subject: [PATCH 1/3] Started multi routes but currently crashes... --- coreapi/linphonecore.c | 15 +++++++++----- coreapi/private_structs.h | 2 +- coreapi/proxy.c | 36 +++++++++++++++++++++------------ include/linphone/proxy_config.h | 8 ++++++++ 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 2027b4101..56024b2c5 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -3421,11 +3421,16 @@ LinphoneCall * linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall * system. */ static bctbx_list_t *make_routes_for_proxy(LinphoneProxyConfig *proxy, const LinphoneAddress *dest){ - bctbx_list_t *ret=NULL; - const char *local_route=linphone_proxy_config_get_route(proxy); - const LinphoneAddress *srv_route=linphone_proxy_config_get_service_route(proxy); - if (local_route){ - ret=bctbx_list_append(ret,sal_address_new(local_route)); + bctbx_list_t *ret = NULL; + const bctbx_list_t *proxy_routes = linphone_proxy_config_get_routes(proxy); + bctbx_list_t *proxy_routes_iterator = (bctbx_list_t *)proxy_routes; + const LinphoneAddress *srv_route = linphone_proxy_config_get_service_route(proxy); + while (proxy_routes_iterator) { + const char *local_route = (const char *)bctbx_list_get_data(proxy_routes_iterator); + if (local_route) { + ret = bctbx_list_append(ret, sal_address_new(local_route)); + } + proxy_routes_iterator = bctbx_list_next(proxy_routes_iterator); } if (srv_route){ ret=bctbx_list_append(ret,sal_address_clone(L_GET_PRIVATE_FROM_C_OBJECT(srv_route)->getInternalAddress())); diff --git a/coreapi/private_structs.h b/coreapi/private_structs.h index 13e0bcce5..3bcfc4d78 100644 --- a/coreapi/private_structs.h +++ b/coreapi/private_structs.h @@ -90,7 +90,7 @@ struct _LinphoneProxyConfig LinphoneAddress* identity_address; LinphoneAddress *contact_address; LinphoneAddress *contact_address_without_params; - char *reg_route; + bctbx_list_t *reg_routes; char *quality_reporting_collector; char *realm; char *contact_params; diff --git a/coreapi/proxy.c b/coreapi/proxy.c index 127d9bb93..dad8307e5 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -113,7 +113,7 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *cf const char *dial_prefix = lc ? lp_config_get_default_string(lc->config,"proxy","dial_prefix",NULL) : NULL; const char *identity = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_identity", NULL) : NULL; const char *proxy = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_proxy", NULL) : NULL; - const char *route = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_route", NULL) : NULL; + const char *route = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_route", NULL) : NULL; //TODO return list instead of string const char *realm = lc ? lp_config_get_default_string(lc->config, "proxy", "realm", NULL) : NULL; const char *quality_reporting_collector = lc ? lp_config_get_default_string(lc->config, "proxy", "quality_reporting_collector", NULL) : NULL; const char *contact_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_parameters", NULL) : NULL; @@ -130,7 +130,7 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *cf cfg->identity_address = identity ? linphone_address_new(identity) : NULL; cfg->reg_identity = cfg->identity_address ? linphone_address_as_string(cfg->identity_address) : NULL; cfg->reg_proxy = proxy ? ms_strdup(proxy) : NULL; - cfg->reg_route = route ? ms_strdup(route) : NULL; + cfg->reg_routes = route ? bctbx_list_append(cfg->reg_routes, ms_strdup(route)) : NULL; //TODO get list directly cfg->realm = realm ? ms_strdup(realm) : NULL; cfg->quality_reporting_enabled = lc ? !!lp_config_get_default_int(lc->config, "proxy", "quality_reporting_enabled", 0) : 0; cfg->quality_reporting_collector = quality_reporting_collector ? ms_strdup(quality_reporting_collector) : NULL; @@ -183,13 +183,18 @@ bool_t linphone_proxy_config_compute_publish_params_hash(LinphoneProxyConfig * c char hash[33]; char saved; unsigned long long previous_hash[2]; + bctbx_list_t *routes_iterator = cfg->reg_routes; previous_hash[0] = cfg->previous_publish_config_hash[0]; previous_hash[1] = cfg->previous_publish_config_hash[1]; source = ms_strcat_printf(source, "%i",cfg->privacy); source=append_linphone_address(cfg->identity_address, source); source=append_string(cfg->reg_proxy,source); - source=append_string(cfg->reg_route,source); + while (routes_iterator) { + const char *route = (const char *)bctbx_list_get_data(routes_iterator); + source=append_string(route,source); + routes_iterator = bctbx_list_next(routes_iterator); + } source=append_string(cfg->realm,source); source = ms_strcat_printf(source, "%i",cfg->publish_expires); source = ms_strcat_printf(source, "%i",cfg->publish); @@ -235,7 +240,7 @@ void _linphone_proxy_config_destroy(LinphoneProxyConfig *cfg){ if (cfg->reg_proxy!=NULL) ms_free(cfg->reg_proxy); if (cfg->reg_identity!=NULL) ms_free(cfg->reg_identity); if (cfg->identity_address!=NULL) linphone_address_unref(cfg->identity_address); - if (cfg->reg_route!=NULL) ms_free(cfg->reg_route); + if (cfg->reg_routes!=NULL) bctbx_list_free_with_data(cfg->reg_routes, ms_free); if (cfg->quality_reporting_collector!=NULL) ms_free(cfg->quality_reporting_collector); if (cfg->ssctx!=NULL) sip_setup_context_free(cfg->ssctx); if (cfg->realm!=NULL) ms_free(cfg->realm); @@ -348,9 +353,9 @@ const char *linphone_proxy_config_get_domain(const LinphoneProxyConfig *cfg){ LinphoneStatus linphone_proxy_config_set_route(LinphoneProxyConfig *cfg, const char *route) { - if (cfg->reg_route!=NULL){ - ms_free(cfg->reg_route); - cfg->reg_route=NULL; + if (cfg->reg_routes!=NULL){ + bctbx_list_free_with_data(cfg->reg_routes, ms_free); + cfg->reg_routes=NULL; } if (route!=NULL && route[0] !='\0'){ SalAddress *addr; @@ -362,7 +367,7 @@ LinphoneStatus linphone_proxy_config_set_route(LinphoneProxyConfig *cfg, const c addr=sal_address_new(tmp); if (addr!=NULL){ sal_address_destroy(addr); - cfg->reg_route=tmp; + cfg->reg_routes = bctbx_list_append(cfg->reg_routes, tmp); return 0; }else{ ms_free(tmp); @@ -934,8 +939,13 @@ void _linphone_proxy_config_unpublish(LinphoneProxyConfig *obj) { } } -const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *cfg){ - return cfg->reg_route; +const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *cfg) { + if (cfg->reg_routes) return (const char *)bctbx_list_get_data(cfg->reg_routes); + return NULL; +} + +const bctbx_list_t* linphone_proxy_config_get_routes(const LinphoneProxyConfig *cfg) { + return cfg->reg_routes; } const LinphoneAddress *linphone_proxy_config_get_identity_address(const LinphoneProxyConfig *cfg){ @@ -1116,8 +1126,8 @@ void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyC if (cfg->reg_proxy!=NULL){ lp_config_set_string(config,key,"reg_proxy",cfg->reg_proxy); } - if (cfg->reg_route!=NULL){ - lp_config_set_string(config,key,"reg_route",cfg->reg_route); + if (cfg->reg_routes != NULL) { + lp_config_set_string_list(config, key, "reg_route", cfg->reg_routes); } if (cfg->reg_identity!=NULL){ lp_config_set_string(config,key,"reg_identity",cfg->reg_identity); @@ -1187,7 +1197,7 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore* lc CONFIGURE_STRING_VALUE(cfg,config,key,identity,"reg_identity") CONFIGURE_STRING_VALUE(cfg,config,key,server_addr,"reg_proxy") - CONFIGURE_STRING_VALUE(cfg,config,key,route,"reg_route") + cfg->reg_routes = linphone_config_get_string_list(config, key, "reg_route", NULL); CONFIGURE_STRING_VALUE(cfg,config,key,realm,"realm") diff --git a/include/linphone/proxy_config.h b/include/linphone/proxy_config.h index ec9368a34..13ef5d294 100644 --- a/include/linphone/proxy_config.h +++ b/include/linphone/proxy_config.h @@ -257,9 +257,17 @@ LINPHONE_PUBLIC void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, c /** * @return the route set for this proxy configuration. + * @deprecated Use linphone_proxy_config_get_routes() instead. **/ LINPHONE_PUBLIC const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *cfg); +/** + * Gets the list of the routes set for this proxy config. + * @param[in] cfg #LinphoneProxyConfig object. + * @return \bctbx_list{const char *} the list of routes. + */ +LINPHONE_PUBLIC const bctbx_list_t* linphone_proxy_config_get_routes(const LinphoneProxyConfig *cfg); + /** * @return the SIP identity that belongs to this proxy configuration. **/ From 9b0c21cc233f85b79364acdd9762536f50b2be92 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 13 Mar 2018 15:03:20 +0100 Subject: [PATCH 2/3] Fixed multi routes crash --- coreapi/proxy.c | 37 ++++++++++++++++++++++++++++++--- include/linphone/proxy_config.h | 10 +++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/coreapi/proxy.c b/coreapi/proxy.c index dad8307e5..067b95790 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -353,9 +353,9 @@ const char *linphone_proxy_config_get_domain(const LinphoneProxyConfig *cfg){ LinphoneStatus linphone_proxy_config_set_route(LinphoneProxyConfig *cfg, const char *route) { - if (cfg->reg_routes!=NULL){ + if (cfg->reg_routes != NULL) { bctbx_list_free_with_data(cfg->reg_routes, ms_free); - cfg->reg_routes=NULL; + cfg->reg_routes = NULL; } if (route!=NULL && route[0] !='\0'){ SalAddress *addr; @@ -378,6 +378,37 @@ LinphoneStatus linphone_proxy_config_set_route(LinphoneProxyConfig *cfg, const c } } +LinphoneStatus linphone_proxy_config_set_routes(LinphoneProxyConfig *cfg, const bctbx_list_t *routes) { + if (cfg->reg_routes != NULL) { + bctbx_list_free_with_data(cfg->reg_routes, ms_free); + cfg->reg_routes = NULL; + } + bctbx_list_t *iterator = (bctbx_list_t *)routes; + while (iterator != NULL) { + char *route = (char *)bctbx_list_get_data(iterator); + if (route != NULL && route[0] !='\0') { + SalAddress *addr; + char *tmp; + /*try to prepend 'sip:' */ + if (strstr(route,"sip:") == NULL && strstr(route,"sips:") == NULL) { + tmp = ms_strdup_printf("sip:%s",route); + } else { + tmp = ms_strdup(route); + } + addr = sal_address_new(tmp); + if (addr != NULL) { + sal_address_destroy(addr); + cfg->reg_routes = bctbx_list_append(cfg->reg_routes, tmp); + } else { + ms_free(tmp); + return -1; + } + } + iterator = bctbx_list_next(iterator); + } + return 0; +} + bool_t linphone_proxy_config_check(LinphoneCore *lc, LinphoneProxyConfig *cfg){ if (cfg->reg_proxy==NULL) return FALSE; @@ -1197,7 +1228,7 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore* lc CONFIGURE_STRING_VALUE(cfg,config,key,identity,"reg_identity") CONFIGURE_STRING_VALUE(cfg,config,key,server_addr,"reg_proxy") - cfg->reg_routes = linphone_config_get_string_list(config, key, "reg_route", NULL); + linphone_proxy_config_set_routes(cfg, linphone_config_get_string_list(config, key, "reg_route", NULL)); CONFIGURE_STRING_VALUE(cfg,config,key,realm,"realm") diff --git a/include/linphone/proxy_config.h b/include/linphone/proxy_config.h index 13ef5d294..edaa9d8c8 100644 --- a/include/linphone/proxy_config.h +++ b/include/linphone/proxy_config.h @@ -99,6 +99,16 @@ LINPHONE_PUBLIC LinphoneStatus linphone_proxy_config_set_identity_address(Linpho **/ LINPHONE_PUBLIC LinphoneStatus linphone_proxy_config_set_route(LinphoneProxyConfig *cfg, const char *route); +/** + * Sets a list of SIP route. + * When a route is set, all outgoing calls will go to the route's destination if this proxy + * is the default one (see linphone_core_set_default_proxy() ). + * @param[in] cfg the #LinphoneProxyConfig + * @param[in] routes A \bctbx_list{const char *} of routes + * @return -1 if routes are invalid, 0 otherwise. +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_proxy_config_set_routes(LinphoneProxyConfig *cfg, const bctbx_list_t *routes); + /** * Sets the registration expiration time in seconds. **/ From c80f9f65c0f59bb9de4d9d037fdd0f3a088c922c Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 13 Mar 2018 17:16:11 +0100 Subject: [PATCH 3/3] Added test for single route --- tester/proxy_config_tester.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/tester/proxy_config_tester.c b/tester/proxy_config_tester.c index a2bf63066..a07c0217f 100644 --- a/tester/proxy_config_tester.c +++ b/tester/proxy_config_tester.c @@ -243,12 +243,36 @@ static void load_dynamic_proxy_config(void) { } +static void single_route(void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); + LinphoneProxyConfig *marie_cfg = linphone_core_get_default_proxy_config(marie->lc); + BC_ASSERT_PTR_NOT_NULL(marie_cfg); + + const bctbx_list_t *routes = linphone_proxy_config_get_routes(marie_cfg); + BC_ASSERT_PTR_NOT_NULL(routes); + BC_ASSERT_EQUAL(bctbx_list_size(routes), 1, int, "%d"); + const char *route = (const char *)bctbx_list_get_data(routes); + BC_ASSERT_STRING_EQUAL(linphone_proxy_config_get_route(marie_cfg), "sip:sip.example.org;transport=tcp;lr"); + BC_ASSERT_STRING_EQUAL(route, "sip:sip.example.org;transport=tcp;lr"); + + linphone_proxy_config_set_route(marie_cfg, "sip.linphone.org"); + routes = linphone_proxy_config_get_routes(marie_cfg); + BC_ASSERT_PTR_NOT_NULL(routes); + BC_ASSERT_EQUAL(bctbx_list_size(routes), 1, int, "%d"); + route = (const char *)bctbx_list_get_data(routes); + BC_ASSERT_STRING_EQUAL(linphone_proxy_config_get_route(marie_cfg), "sip:sip.linphone.org"); + BC_ASSERT_STRING_EQUAL(route, "sip:sip.linphone.org"); + + linphone_core_manager_destroy(marie); +} + test_t proxy_config_tests[] = { TEST_NO_TAG("Phone normalization without proxy", phone_normalization_without_proxy), TEST_NO_TAG("Phone normalization with proxy", phone_normalization_with_proxy), TEST_NO_TAG("Phone normalization with dial escape plus", phone_normalization_with_dial_escape_plus), TEST_NO_TAG("SIP URI normalization", sip_uri_normalization), - TEST_NO_TAG("Load new default value for proxy config", load_dynamic_proxy_config) + TEST_NO_TAG("Load new default value for proxy config", load_dynamic_proxy_config), + TEST_NO_TAG("Single route", single_route) }; test_suite_t proxy_config_test_suite = {"Proxy config", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,