diff --git a/linphone/coreapi/linphonecore.c b/linphone/coreapi/linphonecore.c index a06e57c64..4a1073db0 100644 --- a/linphone/coreapi/linphonecore.c +++ b/linphone/coreapi/linphonecore.c @@ -108,19 +108,18 @@ static void discover_mtu(LinphoneCore *lc, const char *remote){ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, const osip_from_t *from, const osip_to_t *to) { LinphoneCall *call=ms_new0(LinphoneCall,1); - char localip[LINPHONE_IPADDR_SIZE]; char *fromstr=NULL,*tostr=NULL; call->dir=LinphoneCallOutgoing; call->cid=-1; call->did=-1; call->tid=-1; call->core=lc; - linphone_core_get_local_ip(lc,to->url->host,localip); + linphone_core_get_local_ip(lc,to->url->host,call->localip); osip_from_to_str(from,&fromstr); osip_to_to_str(to,&tostr); linphone_call_init_common(call,fromstr,tostr); call->sdpctx=sdp_handler_create_context(&linphone_sdphandler, - call->audio_params.natd_port>0 ? call->audio_params.natd_addr : localip, + call->audio_params.natd_port>0 ? call->audio_params.natd_addr : call->localip, from->url->username,NULL); sdp_context_set_user_pointer(call->sdpctx,(void*)call); discover_mtu(lc,to->url->host); @@ -128,9 +127,7 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, const osip_f } -LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, const char *from, const char *to, int cid, int did, int tid) -{ - char localip[LINPHONE_IPADDR_SIZE]; +LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, const char *from, const char *to, int cid, int did, int tid){ LinphoneCall *call=ms_new0(LinphoneCall,1); osip_from_t *me= linphone_core_get_primary_contact_parsed(lc); osip_from_t *from_url=NULL; @@ -141,10 +138,10 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, const char *from, co call->core=lc; osip_from_init(&from_url); osip_from_parse(from_url, from); - linphone_core_get_local_ip(lc,from_url->url->host,localip); + linphone_core_get_local_ip(lc,from_url->url->host,call->localip); linphone_call_init_common(call, osip_strdup(from), osip_strdup(to)); call->sdpctx=sdp_handler_create_context(&linphone_sdphandler, - call->audio_params.natd_port>0 ? call->audio_params.natd_addr : localip, + call->audio_params.natd_port>0 ? call->audio_params.natd_addr : call->localip, me->url->username,NULL); sdp_context_set_user_pointer(call->sdpctx,(void*)call); discover_mtu(lc,from_url->url->host); @@ -1277,6 +1274,34 @@ void linphone_set_sdp(osip_message_t *sip, const char *sdpmesg){ osip_message_set_content_length(sip,clen); } +LinphoneProxyConfig * linphone_core_goes_through_known_proxy(LinphoneCore *lc, const char *uri){ + const MSList *elem; + LinphoneProxyConfig *found_cfg=NULL; + osip_from_t *parsed_uri; + osip_from_init(&parsed_uri); + osip_from_parse(parsed_uri,uri); + for (elem=linphone_core_get_proxy_config_list(lc);elem!=NULL;elem=elem->next){ + LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data; + const char *domain=linphone_proxy_config_get_domain(cfg); + if (domain!=NULL && strcmp(domain,parsed_uri->url->host)==0){ + found_cfg=cfg; + break; + } + } + osip_from_free(parsed_uri); + return found_cfg; +} + +static void fix_contact(osip_message_t *msg, const char *localip){ + osip_contact_t *ctt=NULL; + + osip_message_get_contact(msg,0,&ctt); + if (ctt!=NULL){ + osip_free(ctt->url->host); + ctt->url->host=osip_strdup(localip); + } +} + int linphone_core_invite(LinphoneCore *lc, const char *url) { char *barmsg; @@ -1324,6 +1349,11 @@ int linphone_core_invite(LinphoneCore *lc, const char *url) osip_from_parse(parsed_url2,from); lc->call=linphone_call_new_outgoing(lc,parsed_url2,real_parsed_url); + /*try to be best-effort in giving real local or routable contact address, + except when the user choosed to override the ipaddress */ + if (linphone_core_get_firewall_policy(lc)!=LINPHONE_POLICY_USE_NAT_ADDRESS) + fix_contact(invite,lc->call->localip); + barmsg=ortp_strdup_printf("%s %s", _("Contacting"), real_url); lc->vtable.display_status(lc,barmsg); ms_free(barmsg); diff --git a/linphone/coreapi/linphonecore.h b/linphone/coreapi/linphonecore.h index cb8fbbd64..bf0be2383 100644 --- a/linphone/coreapi/linphonecore.h +++ b/linphone/coreapi/linphonecore.h @@ -185,11 +185,12 @@ typedef struct _LinphoneCall int cid; /*call id */ int did; /*dialog id */ int tid; /*last transaction id*/ + char localip[LINPHONE_IPADDR_SIZE]; /* our best guess for local ipaddress for this call */ struct _sdp_context *sdpctx; time_t start_time; /*time at which the call was initiated*/ time_t media_start_time; /*time at which it was accepted, media streams established*/ LCState state; - bool_t auth_pending; + bool_t auth_pending; } LinphoneCall; LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, const osip_from_t *from, const osip_to_t *to); @@ -298,6 +299,8 @@ typedef struct _LinphoneProxyConfig char *type; struct _SipSetupContext *ssctx; int auth_failures; + char *contact_addr; /* our IP address as seen by the proxy, read from via 's received= parameter*/ + int contact_port; /*our IP port as seen by the proxy, read from via's rport= parameter */ bool_t commit; bool_t reg_sendregister; bool_t registered; diff --git a/linphone/coreapi/private.h b/linphone/coreapi/private.h index dd349750d..88067899b 100644 --- a/linphone/coreapi/private.h +++ b/linphone/coreapi/private.h @@ -133,5 +133,7 @@ void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call); void linphone_core_write_friends_config(LinphoneCore* lc); void linphone_proxy_config_update(LinphoneProxyConfig *cfg); +void linphone_proxy_config_get_contact(LinphoneProxyConfig *cfg, const char **ip, int *port); + #endif /* _PRIVATE_H */ diff --git a/linphone/coreapi/proxy.c b/linphone/coreapi/proxy.c index eef862f19..eea60409e 100644 --- a/linphone/coreapi/proxy.c +++ b/linphone/coreapi/proxy.c @@ -54,12 +54,32 @@ void linphone_proxy_config_destroy(LinphoneProxyConfig *obj){ if (obj->ssctx!=NULL) sip_setup_context_free(obj->ssctx); if (obj->realm!=NULL) ms_free(obj->realm); if (obj->type!=NULL) ms_free(obj->type); + if (obj->contact_addr!=NULL) ms_free(obj->contact_addr); } bool_t linphone_proxy_config_is_registered(const LinphoneProxyConfig *obj){ return obj->registered; } +void linphone_proxy_config_get_contact(LinphoneProxyConfig *cfg, const char **ip, int *port){ + if (cfg->registered){ + *ip=cfg->contact_addr; + *port=cfg->contact_port; + }else{ + *ip=NULL; + *port=0; + } +} + +static void update_contact(LinphoneProxyConfig *cfg, const char *ip, const char *port){ + if (cfg->contact_addr){ + ms_free(cfg->contact_addr); + } + cfg->contact_addr=ms_strdup(ip); + cfg->contact_port=atoi(port); + if (cfg->contact_port==0) cfg->contact_port=5060; +} + bool_t linphone_proxy_config_register_again_with_updated_contact(LinphoneProxyConfig *obj, osip_message_t *orig_request, osip_message_t *last_answer){ osip_message_t *msg; const char *rport,*received; @@ -108,6 +128,7 @@ bool_t linphone_proxy_config_register_again_with_updated_contact(LinphoneProxyCo ctt->url->port=osip_strdup(rport); eXosip_register_send_register(obj->rid,msg); eXosip_unlock(); + update_contact(obj,received,rport); ms_message("Resending new register with updated contact %s:%s",received,rport); return TRUE; }