diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index 4b12a653f..84957f36a 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -115,10 +115,11 @@ int sal_op_send_request(SalOp* op, belle_sip_request_t* request) { belle_sip_client_transaction_t* client_transaction; belle_sip_provider_t* prov=op->base.root->prov; belle_sip_header_route_t* route_header; + MSList* iterator; if (!op->dialog) { /*don't put route header if dialog is in confirmed state*/ - if (sal_op_get_route_address(op)) { - route_header = belle_sip_header_route_create(BELLE_SIP_HEADER_ADDRESS(sal_op_get_route_address(op))); + for(iterator=(MSList*)sal_op_get_route_addresses(op);iterator!=NULL;iterator=iterator->next) { + route_header = belle_sip_header_route_create(BELLE_SIP_HEADER_ADDRESS(iterator->data)); belle_sip_message_add_header(BELLE_SIP_MESSAGE(request),BELLE_SIP_HEADER(route_header)); } } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 763f59058..4b3d1ea50 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2461,9 +2461,25 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const if (linphone_core_get_route(lc)) { sal_op_set_route(call->op,linphone_core_get_route(lc)); - } else if (proxy && linphone_proxy_config_get_service_route(proxy)) { + } +/* +* rfc3608 +6.1. Procedures at the UA + + /.../ + For example, some devices will use locally-configured + explicit loose routing to reach a next-hop proxy, and others will use + a default outbound-proxy routing rule. However, for the result to + function, the combination MUST provide valid routing in the local + environment. In general, the service route set is appended to any + locally configured route needed to egress the access proxy chain. + Systems designers must match the service routing policy of their + nodes with the basic SIP routing policy in order to get a workable + system. +*/ + if (proxy && linphone_proxy_config_get_service_route(proxy)) { /*set service route*/ - sal_op_set_route_address(call->op,linphone_proxy_config_get_service_route(proxy)); + sal_op_add_route_address(call->op,linphone_proxy_config_get_service_route(proxy)); } /*else, no route*/ diff --git a/coreapi/sal.c b/coreapi/sal.c index 5809b2617..3a9806a9d 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -273,16 +273,34 @@ void sal_op_set_contact(SalOp *op, const char *contact){ } void sal_op_set_route(SalOp *op, const char *route){ - SET_PARAM(op,route); + char* route_string=(void *)0; + SalOpBase* op_base = (SalOpBase*)op; + if (op_base->route_addresses) { + ms_list_for_each(op_base->route_addresses,(void (*)(void *))sal_address_destroy); + op_base->route_addresses=ms_list_free(op_base->route_addresses); + } + if (route) { + op_base->route_addresses=ms_list_append(NULL,NULL); + assign_address((SalAddress**)&(op_base->route_addresses->data),route); + route_string=sal_address_as_string((SalAddress*)op_base->route_addresses->data); \ + } + assign_string(&op_base->route,route_string); \ + if(route_string) ortp_free(route_string); } -const SalAddress* sal_op_get_route_address(const SalOp *op) { - return ((SalOpBase*)op)->route_address; +const MSList* sal_op_get_route_addresses(const SalOp *op) { + return ((SalOpBase*)op)->route_addresses; } void sal_op_set_route_address(SalOp *op, const SalAddress *address){ char* address_string=sal_address_as_string(address); /*can probably be optimized*/ sal_op_set_route(op,address_string); ms_free(address_string); } +void sal_op_add_route_address(SalOp *op, const SalAddress *address){ + SalOpBase* op_base = (SalOpBase*)op; + if (op_base->route_addresses) { + op_base->route_addresses=ms_list_append(op_base->route_addresses,(void*)address); + } +} void sal_op_set_from(SalOp *op, const char *from){ SET_PARAM(op,from); } diff --git a/coreapi/sal.h b/coreapi/sal.h index 281397143..2918dbe92 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -215,7 +215,7 @@ void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_ typedef struct SalOpBase{ Sal *root; char *route; /*or request-uri for REGISTER*/ - SalAddress* route_address; + MSList* route_addresses; /*list of SalAddress* */ char *contact; SalAddress* contact_address; char *from; @@ -391,6 +391,7 @@ void sal_op_set_contact(SalOp *op, const char *contact); void sal_op_set_contact_address(SalOp *op, const SalAddress* address); void sal_op_set_route(SalOp *op, const char *route); void sal_op_set_route_address(SalOp *op, const SalAddress* address); +void sal_op_add_route_address(SalOp *op, const SalAddress* address); void sal_op_set_from(SalOp *op, const char *from); void sal_op_set_from_address(SalOp *op, const SalAddress *from); void sal_op_set_to(SalOp *op, const char *to); @@ -407,7 +408,7 @@ const SalAddress *sal_op_get_to_address(const SalOp *op); const char *sal_op_get_contact(const SalOp *op); const SalAddress *sal_op_get_contact_address(const SalOp *op); const char *sal_op_get_route(const SalOp *op); -const SalAddress* sal_op_get_route_address(const SalOp *op); +const MSList* sal_op_get_route_addresses(const SalOp *op); const char *sal_op_get_proxy(const SalOp *op); /*for incoming requests, returns the origin of the packet as a sip uri*/ const char *sal_op_get_network_origin(const SalOp *op);