From 7553aa6492f1df0106ca42bbfb9cea49c5dd656e Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 25 Apr 2014 23:10:12 +0200 Subject: [PATCH] - linphone now puts Route headers in requests (except register) for outbound proxy configurations, according to RFC3261 This behavior can be reverted by putting [sip]->use_no_initial_route=1 in the configuration file. - accept presence NOTIFY without bodies, instead of replying 415 - remove belle-sip warning at start due to stack not created early enough. --- coreapi/bellesip_sal/sal_impl.c | 12 +++++++++-- coreapi/bellesip_sal/sal_impl.h | 1 + coreapi/bellesip_sal/sal_op_impl.c | 17 +++++++++++++++- coreapi/bellesip_sal/sal_op_presence.c | 28 +++++++++++--------------- coreapi/linphonecore.c | 1 + include/sal/sal.h | 1 + 6 files changed, 41 insertions(+), 19 deletions(-) diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index 5bc256bea..a35d85822 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -424,14 +424,18 @@ Sal * sal_init(){ belle_sip_listener_callbacks_t listener_callbacks; Sal * sal=ms_new0(Sal,1); sal->auto_contacts=TRUE; + + /*first create the stack, which initializes the belle-sip object's pool for this thread*/ + belle_sip_set_log_handler(_belle_sip_log); + sal->stack = belle_sip_stack_new(NULL); + sal->user_agent=belle_sip_header_user_agent_new(); #if defined(PACKAGE_NAME) && defined(LINPHONE_VERSION) belle_sip_header_user_agent_add_product(sal->user_agent, PACKAGE_NAME "/" LINPHONE_VERSION); #endif sal_append_stack_string_to_user_agent(sal); belle_sip_object_ref(sal->user_agent); - belle_sip_set_log_handler(_belle_sip_log); - sal->stack = belle_sip_stack_new(NULL); + sal->prov = belle_sip_stack_create_provider(sal->stack,NULL); sal_nat_helper_enable(sal,TRUE); memset(&listener_callbacks,0,sizeof(listener_callbacks)); @@ -938,6 +942,10 @@ void sal_enable_test_features(Sal*ctx, bool_t enabled){ ctx->enable_test_features=enabled; } +void sal_use_no_initial_route(Sal *ctx, bool_t enabled){ + ctx->no_initial_route=enabled; +} + SalResolverContext * sal_resolve_a(Sal* sal, const char *name, int port, int family, SalResolverCallback cb, void *data){ return (SalResolverContext*)belle_sip_stack_resolve_a(sal->stack,name,port,family,(belle_sip_resolver_callback_t)cb,data); } diff --git a/coreapi/bellesip_sal/sal_impl.h b/coreapi/bellesip_sal/sal_impl.h index c203c9cb1..b6e18d76a 100644 --- a/coreapi/bellesip_sal/sal_impl.h +++ b/coreapi/bellesip_sal/sal_impl.h @@ -47,6 +47,7 @@ struct Sal{ bool_t use_dates; bool_t auto_contacts; bool_t enable_test_features; + bool_t no_initial_route; }; typedef enum SalOpState { diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index 251420977..1b90487e0 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -122,15 +122,25 @@ belle_sip_header_t * sal_make_supported_header(Sal *sal){ return belle_sip_header_create("Supported","replaces, outbound"); } +static void add_initial_route_set(belle_sip_request_t *request, const MSList *list){ + for (;list!=NULL;list=list->next){ + SalAddress *addr=(SalAddress*)list->data; + belle_sip_header_route_t *route=belle_sip_header_route_create((belle_sip_header_address_t*)addr); + belle_sip_uri_t *uri=belle_sip_header_address_get_uri((belle_sip_header_address_t*)route); + belle_sip_uri_set_lr_param(uri,1); + belle_sip_message_add_header((belle_sip_message_t*)request,(belle_sip_header_t*)route); + } +} + belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) { belle_sip_header_from_t* from_header; belle_sip_header_to_t* to_header; belle_sip_provider_t* prov=op->base.root->prov; belle_sip_request_t *req; belle_sip_uri_t* req_uri; + const MSList *elem=sal_op_get_route_addresses(op); char token[10]; - if (strcmp("REGISTER",method)==0 || op->privacy==SalPrivacyNone) { from_header = belle_sip_header_from_create(BELLE_SIP_HEADER_ADDRESS(sal_op_get_from_address(op)) ,belle_sip_random_token(token,sizeof(token))); @@ -157,6 +167,11 @@ belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) { belle_sip_header_p_preferred_identity_t* p_preferred_identity=belle_sip_header_p_preferred_identity_create(BELLE_SIP_HEADER_ADDRESS(sal_op_get_from_address(op))); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(p_preferred_identity)); } + + if (elem && strcmp(method,"REGISTER")!=0 && !op->base.root->no_initial_route){ + add_initial_route_set(req,elem); + } + if (strcmp("REGISTER",method)!=0 && op->privacy!=SalPrivacyNone ){ belle_sip_header_privacy_t* privacy_header=belle_sip_header_privacy_new(); if (op->privacy&SalPrivacyCritical) diff --git a/coreapi/bellesip_sal/sal_op_presence.c b/coreapi/bellesip_sal/sal_op_presence.c index ca526fd5d..3be52c051 100644 --- a/coreapi/bellesip_sal/sal_op_presence.c +++ b/coreapi/bellesip_sal/sal_op_presence.c @@ -164,6 +164,8 @@ static SalPresenceModel * process_presence_notification(SalOp *op, belle_sip_req return NULL; if (belle_sip_header_content_length_get_content_length(content_length) == 0) return NULL; + + if (body==NULL) return NULL; op->base.root->callbacks.parse_presence_requested(op, belle_sip_header_content_type_get_type(content_type), @@ -183,28 +185,22 @@ static void handle_notify(SalOp *op, belle_sip_request_t *req){ if (strcmp("NOTIFY",belle_sip_request_get_method(req))==0) { SalPresenceModel *presence_model = NULL; const char* body = belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)); - if (body==NULL){ - ms_error("No body in NOTIFY received from [%s]",sal_op_get_from(op)); - resp = sal_op_create_response_from_request(op, req, 415); - belle_sip_server_transaction_send_response(server_transaction,resp); - return; + if (!subscription_state_header || strcasecmp(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,belle_sip_header_subscription_state_get_state(subscription_state_header)) ==0) { + sub_state=SalSubscribeTerminated; + ms_message("Outgoing subscription terminated by remote [%s]",sal_op_get_to(op)); + } else { + sub_state=SalSubscribeActive; } presence_model = process_presence_notification(op, req); - if (presence_model != NULL) { + if (presence_model != NULL || body==NULL) { /* Presence notification body parsed successfully. */ - if (!subscription_state_header || strcasecmp(BELLE_SIP_SUBSCRIPTION_STATE_TERMINATED,belle_sip_header_subscription_state_get_state(subscription_state_header)) ==0) { - sub_state=SalSubscribeTerminated; - ms_message("Outgoing subscription terminated by remote [%s]",sal_op_get_to(op)); - } else { - sub_state=SalSubscribeActive; - } + resp = sal_op_create_response_from_request(op, req, 200); /*create first because the op may be destroyed by notify_presence */ op->base.root->callbacks.notify_presence(op, sub_state, presence_model, NULL); - - } else { + } else if (body){ /* Formatting error in presence notification body. */ - ms_error("Wrongly formatted presence notification received"); - resp = sal_op_create_response_from_request(op, req, 400); + ms_warning("Wrongly formatted presence document."); + resp = sal_op_create_response_from_request(op, req, 488); } belle_sip_server_transaction_send_response(server_transaction,resp); } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index dc69310a3..c31d1c181 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -662,6 +662,7 @@ static void sip_config_read(LinphoneCore *lc) sal_use_session_timers(lc->sal,200); } + sal_use_no_initial_route(lc->sal,lp_config_get_int(lc->config,"sip","use_no_initial_route",0)); sal_use_rport(lc->sal,lp_config_get_int(lc->config,"sip","use_rport",1)); ipv6=lp_config_get_int(lc->config,"sip","use_ipv6",-1); diff --git a/include/sal/sal.h b/include/sal/sal.h index 0d5cea3cc..2d7e4eec8 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -530,6 +530,7 @@ void sal_verify_server_cn(Sal *ctx, bool_t verify); void sal_set_uuid(Sal*ctx, const char *uuid); int sal_create_uuid(Sal*ctx, char *uuid, size_t len); void sal_enable_test_features(Sal*ctx, bool_t enabled); +void sal_use_no_initial_route(Sal *ctx, bool_t enabled); int sal_iterate(Sal *sal); MSList * sal_get_pending_auths(Sal *sal);