diff --git a/coreapi/bellesip_sal/sal_address_impl.c b/coreapi/bellesip_sal/sal_address_impl.c index 540aa701b..c7f004bef 100644 --- a/coreapi/bellesip_sal/sal_address_impl.c +++ b/coreapi/bellesip_sal/sal_address_impl.c @@ -83,14 +83,22 @@ int sal_address_get_port_int(const SalAddress *addr){ return -1; } SalTransport sal_address_get_transport(const SalAddress* addr){ - belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr); - belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr); - if (uri && belle_sip_uri_get_transport_param(uri)) { - return sal_transport_parse(belle_sip_uri_get_transport_param(uri)); - } else + const char *transport=sal_address_get_transport_name(addr); + if (transport) + return sal_transport_parse(transport); + else return SalTransportUDP; }; +const char* sal_address_get_transport_name(const SalAddress* addr){ + belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr); + belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr); + if (uri) { + return belle_sip_uri_get_transport_param(uri); + } + return NULL; +} + void sal_address_set_display_name(SalAddress *addr, const char *display_name){ belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr); belle_sip_header_address_set_displayname(header_addr,display_name); @@ -132,8 +140,11 @@ void sal_address_set_param(SalAddress *addr,const char* name,const char* value){ belle_sip_parameters_set_parameter(parameters,name,value); return ; } + void sal_address_set_transport(SalAddress* addr,SalTransport transport){ SAL_ADDRESS_SET(addr,transport_param,sal_transport_to_string(transport)); } - +void sal_address_set_transport_name(SalAddress* addr,const char *transport){ + SAL_ADDRESS_SET(addr,transport_param,transport); +} diff --git a/coreapi/chat.c b/coreapi/chat.c index c12bb3398..54a15526b 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -65,11 +65,11 @@ void linphone_chat_room_destroy(LinphoneChatRoom *cr){ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage* msg){ - const char *route=NULL; - const char *identity=linphone_core_find_best_identity(cr->lc,cr->peer_url,&route); + MSList *routes=NULL; SalOp *op=NULL; LinphoneCall *call; char* content_type; + const char *identity=NULL; time_t t=time(NULL); if (lp_config_get_int(cr->lc->config,"sip","chat_use_call_dialogs",0)){ @@ -82,14 +82,19 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM ms_message("send SIP message through the existing call."); op = call->op; call->pending_message=msg; + identity=linphone_core_find_best_identity(cr->lc,linphone_call_get_remote_address(call)); } } } msg->time=t; if (op==NULL){ + LinphoneProxyConfig *proxy=linphone_core_lookup_known_proxy(cr->lc,cr->peer_url,&routes); + if (proxy){ + identity=linphone_proxy_config_get_identity(proxy); + }else identity=linphone_core_get_primary_contact(cr->lc); /*sending out of calls*/ op = sal_op_new(cr->lc->sal); - sal_op_set_route(op,route); + linphone_transfer_routes_to_op(routes,op); sal_op_set_user_pointer(op, msg); /*if out of call, directly store msg*/ if (msg->custom_headers){ sal_op_set_custom_header(op,msg->custom_headers); diff --git a/coreapi/friend.c b/coreapi/friend.c index 2a857de2d..19dd16f01 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -109,13 +109,14 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){ const char *route=NULL; const char *from=NULL; LinphoneProxyConfig *cfg; + MSList *routes=NULL; friend=linphone_address_as_string(fr->uri); - cfg=linphone_core_lookup_known_proxy(fr->lc,linphone_friend_get_address(fr)); + cfg=linphone_core_lookup_known_proxy(fr->lc,linphone_friend_get_address(fr),&routes); if (cfg!=NULL){ - route=linphone_proxy_config_get_route(cfg); from=linphone_proxy_config_get_identity(cfg); }else from=linphone_core_get_primary_contact(fr->lc); + if (fr->outsub==NULL){ /* people for which we don't have yet an answer should appear as offline */ fr->status=LinphoneStatusOffline; @@ -133,6 +134,7 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){ sal_op_set_contact(fr->outsub,sal_op_get_contact(cfg->op)); else sal_op_set_contact(fr->outsub,NULL); + linphone_transfer_routes_to_op(routes,fr->outsub); sal_subscribe_presence(fr->outsub,from,friend); fr->subscribe_active=TRUE; ms_free(friend); diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 1f8a288b0..c512dc3fd 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -219,20 +219,25 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall * PayloadType *pt; SalMediaDescription *old_md=call->localdesc; int i; - const char *me=linphone_core_get_identity(lc); - LinphoneAddress *addr=linphone_address_new(me); - const char *username=linphone_address_get_username (addr); + const char *me; SalMediaDescription *md=sal_media_description_new(); + LinphoneAddress *addr; bool_t keep_srtp_keys=lp_config_get_int(lc->config,"sip","keep_srtp_keys",0); linphone_core_adapt_to_network(lc,call->ping_time,&call->params); + if (call->dest_proxy) + me=linphone_proxy_config_get_identity(call->dest_proxy); + else + me=linphone_core_get_identity(lc); + addr=linphone_address_new(me); + md->session_id=(old_md ? old_md->session_id : (rand() & 0xfff)); md->session_ver=(old_md ? (old_md->session_ver+1) : (rand() & 0xfff)); md->n_total_streams=(old_md ? old_md->n_total_streams : 1); md->n_active_streams=1; strncpy(md->addr,call->localip,sizeof(md->addr)); - strncpy(md->username,username,sizeof(md->username)); + strncpy(md->username,linphone_address_get_username(addr),sizeof(md->username)); if (call->params.down_bw) md->bandwidth=call->params.down_bw; @@ -523,7 +528,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro from_str=linphone_address_as_string_uri_only(from); sal_op_set_route(call->ping_op,sal_op_get_network_origin(op)); sal_op_set_user_pointer(call->ping_op,call); - sal_ping(call->ping_op,linphone_core_find_best_identity(lc,from,NULL),from_str); + sal_ping(call->ping_op,linphone_core_find_best_identity(lc,from),from_str); ms_free(from_str); } } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 9d9e69059..44d8052d6 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -66,6 +66,7 @@ static void linphone_core_free_hooks(LinphoneCore *lc); #include "enum.h" + const char *linphone_core_get_nat_address_resolved(LinphoneCore *lc); static void toggle_video_preview(LinphoneCore *lc, bool_t val); @@ -2003,7 +2004,7 @@ static void linphone_core_grab_buddy_infos(LinphoneCore *lc, LinphoneProxyConfig for(elem=linphone_core_get_friend_list(lc);elem!=NULL;elem=elem->next){ LinphoneFriend *lf=(LinphoneFriend*)elem->data; if (lf->info==NULL){ - if (linphone_core_lookup_known_proxy(lc,lf->uri)==cfg){ + if (linphone_core_lookup_known_proxy(lc,lf->uri,NULL)==cfg){ if (linphone_address_get_username(lf->uri)!=NULL){ BuddyLookupRequest *req; char *tmp=linphone_address_as_string_uri_only(lf->uri); @@ -2295,7 +2296,53 @@ void linphone_core_notify_refer_state(LinphoneCore *lc, LinphoneCall *referer, L } } -LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const LinphoneAddress *uri){ +/* returns the ideal route set for making an operation through this proxy. + * The list must be freed as well as the SalAddress content*/ + + /* +* 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. +*/ + +static MSList *make_routes_for_proxy(LinphoneProxyConfig *proxy, const LinphoneAddress *addr){ + MSList *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=ms_list_append(ret,sal_address_new(local_route)); + } + if (srv_route){ + ret=ms_list_append(ret,sal_address_clone((SalAddress*)srv_route)); + } + if (ret==NULL){ + /*still no route, so try to build a route from proxy transport + identity host, + *in order to force using the transport required for this proxy, if any.*/ + SalAddress *proxy_addr=sal_address_new(linphone_proxy_config_get_addr(proxy)); + const char *transport=sal_address_get_transport_name(proxy_addr); + sal_address_destroy(proxy_addr); + if (transport){ + SalAddress *route=sal_address_new(NULL); + sal_address_set_domain(route,sal_address_get_domain((SalAddress*)addr)); + sal_address_set_port_int(route,sal_address_get_port_int((SalAddress*)addr)); + sal_address_set_transport_name(route,transport); + ret=ms_list_append(ret,route); + } + } + return ret; +} + +LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const LinphoneAddress *uri, MSList **routes){ const MSList *elem; LinphoneProxyConfig *found_cfg=NULL; LinphoneProxyConfig *default_cfg=lc->default_proxy; @@ -2303,8 +2350,10 @@ LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const L /*always prefer the default proxy if it is matching the destination uri*/ if (default_cfg){ const char *domain=linphone_proxy_config_get_domain(default_cfg); - if (strcmp(domain,linphone_address_get_domain(uri))==0) - return default_cfg; + if (strcmp(domain,linphone_address_get_domain(uri))==0){ + found_cfg=default_cfg; + goto end; + } } /*otherwise iterate through the other proxy config and return the first matching*/ @@ -2313,18 +2362,34 @@ LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const L const char *domain=linphone_proxy_config_get_domain(cfg); if (domain!=NULL && strcmp(domain,linphone_address_get_domain(uri))==0){ found_cfg=cfg; - break; + goto end; } } +end: + if (found_cfg!=NULL && found_cfg!=default_cfg){ + ms_message("Overriding default proxy setting for this call/message/subscribe operation."); + }; + + /*if route argument is given, fill adequate route set for this proxy.*/ + if (routes){ + if (found_cfg){ + *routes=make_routes_for_proxy(found_cfg,uri); + }else if (default_cfg){ + /*if the default proxy config has a locally configured route, we should use it*/ + const char *route=linphone_proxy_config_get_route(default_cfg); + if (route) + *routes=ms_list_append(*routes,sal_address_new(route)); + } + } + return found_cfg; } -const char *linphone_core_find_best_identity(LinphoneCore *lc, const LinphoneAddress *to, const char **route){ - LinphoneProxyConfig *cfg=linphone_core_lookup_known_proxy(lc,to); +const char *linphone_core_find_best_identity(LinphoneCore *lc, const LinphoneAddress *to){ + LinphoneProxyConfig *cfg=linphone_core_lookup_known_proxy(lc,to,NULL); if (cfg==NULL) linphone_core_get_default_proxy (lc,&cfg); if (cfg!=NULL){ - if (route) *route=linphone_proxy_config_get_route(cfg); return linphone_proxy_config_get_identity (cfg); } return linphone_core_get_primary_contact (lc); @@ -2474,6 +2539,15 @@ LinphoneCall * linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddr return call; } +void linphone_transfer_routes_to_op(MSList *routes, SalOp *op){ + MSList *it; + for(it=routes;it!=NULL;it=it->next){ + SalAddress *addr=(SalAddress*)it->data; + sal_op_add_route_address(op,addr); + sal_address_destroy(addr); + } + ms_list_free(routes); +} /** * Initiates an outgoing call given a destination LinphoneAddress @@ -2493,12 +2567,11 @@ LinphoneCall * linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddr LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const LinphoneAddress *addr, const LinphoneCallParams *params) { const char *from=NULL; - LinphoneProxyConfig *proxy=NULL,*dest_proxy=NULL; + LinphoneProxyConfig *proxy=NULL; LinphoneAddress *parsed_url2=NULL; - SalAddress *route=NULL; - SalAddress *proxy_addr=NULL; char *real_url=NULL; LinphoneCall *call; + MSList *routes=NULL; bool_t defer = FALSE; linphone_core_preempt_sound_resources(lc); @@ -2510,18 +2583,10 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const } linphone_core_get_default_proxy(lc,&proxy); - real_url=linphone_address_as_string(addr); - dest_proxy=linphone_core_lookup_known_proxy(lc,addr); + proxy=linphone_core_lookup_known_proxy(lc,addr,&routes); - if (proxy!=dest_proxy && dest_proxy!=NULL) { - ms_message("Overriding default proxy setting for this call:"); - ms_message("The used identity will be %s",linphone_proxy_config_get_identity(dest_proxy)); - } - - if (dest_proxy!=NULL) - from=linphone_proxy_config_get_identity(dest_proxy); - else if (proxy!=NULL) + if (proxy!=NULL) from=linphone_proxy_config_get_identity(proxy); /* if no proxy or no identity defined for this proxy, default to primary contact*/ @@ -2530,64 +2595,9 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const parsed_url2=linphone_address_new(from); call=linphone_call_new_outgoing(lc,parsed_url2,linphone_address_clone(addr),params); - call->dest_proxy=dest_proxy; - - if (linphone_core_get_route(lc)) { - sal_op_set_route(call->op,linphone_core_get_route(lc)); - } - -/* -* 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_add_route_address(call->op,linphone_proxy_config_get_service_route(proxy)); - } /*else, no route*/ - - if (!sal_op_get_route(call->op)) { - /*still no route, so try to build a route from proxy transport + identity host*/ - route=sal_address_new(NULL); - /*first, get domain and port from requerst uri*/ - sal_address_set_domain(route,sal_address_get_domain((SalAddress*)addr)); - sal_address_set_port_int(route,sal_address_get_port_int((SalAddress*)addr)); - /*next get transport either from request uri or from proxy if any*/ - if (sal_address_get_transport((SalAddress*)addr)) { - sal_address_set_transport(route,sal_address_get_transport((SalAddress*)addr)); - } else { - LinphoneProxyConfig* chosen_proxy=NULL; - - if (dest_proxy) - chosen_proxy=dest_proxy; - else if (proxy) - chosen_proxy=proxy; - else - chosen_proxy=NULL; - - if (chosen_proxy) - proxy_addr=sal_address_new(linphone_proxy_config_get_addr(chosen_proxy)); - - if (proxy_addr && sal_address_get_transport(proxy_addr)) - sal_address_set_transport(route,sal_address_get_transport(proxy_addr)); - else if (proxy_addr && linphone_proxy_config_guess_transport(chosen_proxy) && !sal_address_get_transport((SalAddress*)route)) { - /*compatibility mode*/ - sal_address_set_transport((SalAddress*)route,sal_transport_parse(linphone_proxy_config_guess_transport(chosen_proxy))); - } - } - sal_op_add_route_address(call->op,route); - } - + call->dest_proxy=proxy; + linphone_transfer_routes_to_op(routes,call->op); + if(linphone_core_add_call(lc,call)!= 0) { ms_warning("we had a problem in adding the call into the invite ... weird"); @@ -3119,7 +3129,7 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call, linphone_core_get_default_proxy(lc,&cfg); call->dest_proxy=cfg; - call->dest_proxy=linphone_core_lookup_known_proxy(lc,call->log->to); + call->dest_proxy=linphone_core_lookup_known_proxy(lc,call->log->to,NULL); if (cfg!=call->dest_proxy && call->dest_proxy!=NULL) { ms_message("Overriding default proxy setting for this call:"); diff --git a/coreapi/presence.c b/coreapi/presence.c index 4643d7d9f..8c93b28f7 100644 --- a/coreapi/presence.c +++ b/coreapi/presence.c @@ -64,7 +64,7 @@ void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){ tmp=linphone_address_as_string(uri); ms_message("Receiving new subscription from %s.",from); - cfg=linphone_core_lookup_known_proxy(lc,uri); + cfg=linphone_core_lookup_known_proxy(lc,uri,NULL); if (cfg!=NULL){ if (cfg->op){ if (sal_op_get_contact(cfg->op)) { @@ -73,6 +73,7 @@ void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){ } } } + /* check if we answer to this subscription */ if (linphone_find_friend(lc->friends,uri,&lf)!=NULL){ lf->insub=op; diff --git a/coreapi/private.h b/coreapi/private.h index 19e84f9dc..10cd8757b 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -240,10 +240,7 @@ void linphone_proxy_config_write_all_to_config_file(LinphoneCore *lc); * Can be NULL * */ const LinphoneAddress* linphone_proxy_config_get_service_route(const LinphoneProxyConfig* cfg); -/* - *guess the transport if only one trasport is configured at core level (for backward compatibility) - * */ -const char* linphone_proxy_config_guess_transport(const LinphoneProxyConfig *obj); + int linphone_online_status_to_eXosip(LinphoneOnlineStatus os); void linphone_friend_close_subscriptions(LinphoneFriend *lf); @@ -318,8 +315,9 @@ LinphoneFriend * linphone_friend_new_from_config_file(struct _LinphoneCore *lc, void linphone_proxy_config_update(LinphoneProxyConfig *cfg); void linphone_proxy_config_get_contact(LinphoneProxyConfig *cfg, const char **ip, int *port); -LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const LinphoneAddress *uri); -const char *linphone_core_find_best_identity(LinphoneCore *lc, const LinphoneAddress *to, const char **route); +LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const LinphoneAddress *uri, MSList **routes); +void linphone_transfer_routes_to_op(MSList *routes, SalOp *op); +const char *linphone_core_find_best_identity(LinphoneCore *lc, const LinphoneAddress *to); int linphone_core_get_local_ip_for(int type, const char *dest, char *result); LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(struct _LpConfig *config, int index); diff --git a/coreapi/proxy.c b/coreapi/proxy.c index 7104174cc..ab638ee05 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -346,35 +346,8 @@ LinphoneAddress *guess_contact_for_register(LinphoneProxyConfig *obj){ } return ret; } -/*use for compatibility with linphone supporting only 1 transport at a time*/ -const char* linphone_proxy_config_guess_transport(const LinphoneProxyConfig *obj) { - LCSipTransports transports; - const char* transport_name; - unsigned char transports_count=0; - linphone_core_get_sip_transports(obj->lc,&transports); - if (transports.udp_port>0) { - transports_count++; - transport_name="udp"; - } - if (transports.tcp_port>0) { - transports_count++; - transport_name="tcp"; - } - if (transports.tls_port>0) { - transports_count++; - transport_name="tls"; - } - if (transports.dtls_port>0) { - transports_count++; - transport_name="dtls"; - } - if (transports_count==1) { - return transport_name; - } else { - /*cannot guess transport*/ - return NULL; - } -} + + static void linphone_proxy_config_register(LinphoneProxyConfig *obj){ if (obj->reg_sendregister){ LinphoneAddress* proxy=linphone_address_new(obj->reg_proxy); @@ -383,10 +356,6 @@ static void linphone_proxy_config_register(LinphoneProxyConfig *obj){ char *contact; #else LinphoneAddress *contact; - - if (linphone_proxy_config_guess_transport(obj) && !sal_address_get_transport((SalAddress*)proxy)) { - sal_address_set_transport((SalAddress*)proxy,sal_transport_parse(linphone_proxy_config_guess_transport(obj))); - } #endif proxy_string=linphone_address_as_string_uri_only(proxy); linphone_address_destroy(proxy); diff --git a/include/sal/sal.h b/include/sal/sal.h index f48edbde3..0f78a4c8d 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -84,6 +84,7 @@ const char *sal_address_get_domain(const SalAddress *addr); const char * sal_address_get_port(const SalAddress *addr); int sal_address_get_port_int(const SalAddress *addr); SalTransport sal_address_get_transport(const SalAddress* addr); +const char* sal_address_get_transport_name(const SalAddress* addr); void sal_address_set_display_name(SalAddress *addr, const char *display_name); void sal_address_set_username(SalAddress *addr, const char *username); @@ -96,7 +97,7 @@ char *sal_address_as_string_uri_only(const SalAddress *u); void sal_address_destroy(SalAddress *u); void sal_address_set_param(SalAddress *u,const char* name,const char* value); void sal_address_set_transport(SalAddress* addr,SalTransport transport); - +void sal_address_set_transport_name(SalAddress* addr,const char* transport); Sal * sal_init(); void sal_uninit(Sal* sal);