From 0d0ecca30593004a98bb24ed5cc9f132becff02c Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Fri, 29 Apr 2016 16:24:33 +0200 Subject: [PATCH] presence_server: fix memory leaks --- coreapi/bellesip_sal/sal_impl.c | 101 +++++++++++++++++--------------- coreapi/callbacks.c | 19 +++--- coreapi/linphonecore.c | 2 +- coreapi/proxy.c | 1 + tester/presence_server_tester.c | 24 ++++---- 5 files changed, 81 insertions(+), 66 deletions(-) diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index 010921544..43926027b 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -239,57 +239,62 @@ static void process_request_event(void *ud, const belle_sip_request_event_t *eve ms_warning("Receiving request for null or terminated op [%p], ignored",op); return; } - }else if (strcmp("INVITE",method)==0) { + }else{ /*handle the case where we are receiving a request with to tag but it is not belonging to any dialog*/ - belle_sip_header_to_t *to = belle_sip_message_get_header_by_type(req, belle_sip_header_to_t); - if (belle_sip_header_to_get_tag(to) != NULL){ - ms_warning("Receiving INVITE with to-tag but no know dialog here. Rejecting."); - resp=belle_sip_response_create_from_request(req,481); + if (strcmp("INVITE",method)==0 || strcmp("NOTIFY",method)==0) { + belle_sip_header_to_t *to = belle_sip_message_get_header_by_type(req, belle_sip_header_to_t); + if (belle_sip_header_to_get_tag(to) != NULL){ + ms_warning("Receiving %s with to-tag but no know dialog here. Rejecting.", method); + resp=belle_sip_response_create_from_request(req,481); + belle_sip_provider_send_response(sal->prov,resp); + return; + } + } + + if (strcmp("INVITE",method)==0) { + op=sal_op_new(sal); + op->dir=SalOpDirIncoming; + sal_op_call_fill_cbs(op); + }else if ((strcmp("SUBSCRIBE",method)==0 || strcmp("NOTIFY",method)==0) && (evh=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Event"))!=NULL) { + op=sal_op_new(sal); + op->dir=SalOpDirIncoming; + if (strncmp(belle_sip_header_get_unparsed_value(evh),"presence",strlen("presence"))==0){ + sal_op_presence_fill_cbs(op); + }else + sal_op_subscribe_fill_cbs(op); + }else if (strcmp("MESSAGE",method)==0) { + op=sal_op_new(sal); + op->dir=SalOpDirIncoming; + sal_op_message_fill_cbs(op); + }else if (strcmp("OPTIONS",method)==0) { + resp=belle_sip_response_create_from_request(req,200); + belle_sip_provider_send_response(sal->prov,resp); + return; + }else if (strcmp("INFO",method)==0) { + resp=belle_sip_response_create_from_request(req,481);/*INFO out of call dialogs are not allowed*/ + belle_sip_provider_send_response(sal->prov,resp); + return; + }else if (strcmp("BYE",method)==0) { + resp=belle_sip_response_create_from_request(req,481);/*out of dialog BYE */ + belle_sip_provider_send_response(sal->prov,resp); + return; + }else if (strcmp("CANCEL",method)==0) { + resp=belle_sip_response_create_from_request(req,481);/*out of dialog CANCEL */ + belle_sip_provider_send_response(sal->prov,resp); + return; + }else if (sal->enable_test_features && strcmp("PUBLISH",method)==0) { + resp=belle_sip_response_create_from_request(req,200);/*out of dialog BYE */ + belle_sip_message_add_header((belle_sip_message_t*)resp,belle_sip_header_create("SIP-Etag","4441929FFFZQOA")); + belle_sip_provider_send_response(sal->prov,resp); + return; + }else { + ms_error("sal process_request_event not implemented yet for method [%s]",belle_sip_request_get_method(req)); + resp=belle_sip_response_create_from_request(req,405); + belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp) + ,BELLE_SIP_HEADER(belle_sip_header_allow_create("INVITE, CANCEL, ACK, BYE, SUBSCRIBE, NOTIFY, MESSAGE, OPTIONS, INFO"))); belle_sip_provider_send_response(sal->prov,resp); return; } - op=sal_op_new(sal); - op->dir=SalOpDirIncoming; - sal_op_call_fill_cbs(op); - }else if ((strcmp("SUBSCRIBE",method)==0 || strcmp("NOTIFY",method)==0) && (evh=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Event"))!=NULL) { - op=sal_op_new(sal); - op->dir=SalOpDirIncoming; - if (strncmp(belle_sip_header_get_unparsed_value(evh),"presence",strlen("presence"))==0){ - sal_op_presence_fill_cbs(op); - }else - sal_op_subscribe_fill_cbs(op); - }else if (strcmp("MESSAGE",method)==0) { - op=sal_op_new(sal); - op->dir=SalOpDirIncoming; - sal_op_message_fill_cbs(op); - }else if (strcmp("OPTIONS",method)==0) { - resp=belle_sip_response_create_from_request(req,200); - belle_sip_provider_send_response(sal->prov,resp); - return; - }else if (strcmp("INFO",method)==0) { - resp=belle_sip_response_create_from_request(req,481);/*INFO out of call dialogs are not allowed*/ - belle_sip_provider_send_response(sal->prov,resp); - return; - }else if (strcmp("BYE",method)==0) { - resp=belle_sip_response_create_from_request(req,481);/*out of dialog BYE */ - belle_sip_provider_send_response(sal->prov,resp); - return; - }else if (strcmp("CANCEL",method)==0) { - resp=belle_sip_response_create_from_request(req,481);/*out of dialog CANCEL */ - belle_sip_provider_send_response(sal->prov,resp); - return; - }else if (sal->enable_test_features && strcmp("PUBLISH",method)==0) { - resp=belle_sip_response_create_from_request(req,200);/*out of dialog BYE */ - belle_sip_message_add_header((belle_sip_message_t*)resp,belle_sip_header_create("SIP-Etag","4441929FFFZQOA")); - belle_sip_provider_send_response(sal->prov,resp); - return; - }else { - ms_error("sal process_request_event not implemented yet for method [%s]",belle_sip_request_get_method(req)); - resp=belle_sip_response_create_from_request(req,405); - belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp) - ,BELLE_SIP_HEADER(belle_sip_header_allow_create("INVITE, CANCEL, ACK, BYE, SUBSCRIBE, NOTIFY, MESSAGE, OPTIONS, INFO"))); - belle_sip_provider_send_response(sal->prov,resp); - return; } if (!op->base.from_address) { @@ -1010,7 +1015,7 @@ int sal_generate_uuid(char *uuid, size_t len) { sal_uuid_t uuid_struct; int i; int written; - + if (len==0) return -1; /*create an UUID as described in RFC4122, 4.4 */ belle_sip_random_bytes((unsigned char*)&uuid_struct, sizeof(sal_uuid_t)); diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 41b399e08..8f9f50690 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -495,7 +495,7 @@ static void process_call_accepted(LinphoneCore *lc, LinphoneCall *call, SalOp *o if (call->params->internal_call_update) call->params->internal_call_update = FALSE; - + #ifdef BUILD_UPNP if (call->upnp_session != NULL && rmd) { linphone_core_update_upnp_from_remote_media_description(call, rmd); @@ -511,12 +511,12 @@ static void process_call_accepted(LinphoneCore *lc, LinphoneCall *call, SalOp *o md = NULL; } if (md){ /*there is a valid SDP in the response, either offer or answer, and we're able to start/update the streams*/ - + /* Handle remote ICE attributes if any. */ if (call->ice_session != NULL && rmd) { linphone_call_update_ice_from_remote_media_description(call, rmd, FALSE); } - + switch (call->state){ case LinphoneCallResuming: linphone_core_notify_display_status(lc,_("Call resumed.")); @@ -1063,7 +1063,7 @@ static void refer_received(Sal *sal, SalOp *op, const char *referto){ LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); LinphoneAddress *refer_to_addr = linphone_address_new(referto); char method[20] = ""; - + if(refer_to_addr) { const char *tmp = linphone_address_get_method_param(refer_to_addr); if(tmp) strncpy(method, tmp, sizeof(method)); @@ -1131,7 +1131,7 @@ static void parse_presence_requested(SalOp *op, const char *content_type, const static void convert_presence_to_xml_requested(SalOp *op, SalPresenceModel *presence, const char *contact, char **content) { /*for backward compatibility because still used by notify. No loguer used for publish*/ - + if(linphone_presence_model_get_presentity((LinphonePresenceModel*)presence) == NULL) { LinphoneAddress * presentity = linphone_address_new(contact); linphone_presence_model_set_presentity((LinphonePresenceModel*)presence, presentity); @@ -1313,8 +1313,8 @@ static void subscribe_response(SalOp *op, SalSubscribeStatus status){ static void notify(SalOp *op, SalSubscribeStatus st, const char *eventname, SalBodyHandler *body_handler){ LinphoneEvent *lev=(LinphoneEvent*)sal_op_get_user_pointer(op); LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); - - if (lev==NULL) { + bool_t out_of_dialog = (lev==NULL); + if (out_of_dialog) { /*out of subscribe notify */ lev=linphone_event_new_with_out_of_dialog_op(lc,op,LinphoneSubscriptionOutgoing,eventname); } @@ -1328,6 +1328,11 @@ static void notify(SalOp *op, SalSubscribeStatus st, const char *eventname, SalB if (st!=SalSubscribeNone){ linphone_event_set_state(lev,linphone_subscription_state_from_sal(st)); } + + if (out_of_dialog) { + linphone_event_unref(lev); + } + } static void subscribe_received(SalOp *op, const char *eventname, const SalBodyHandler *body_handler){ diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index f179f0a03..6513675b4 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1705,7 +1705,7 @@ static void linphone_core_internal_notify_received(LinphoneCore *lc, LinphoneEve const MSList* friendLists = linphone_core_get_friends_lists(lc); while( friendLists != NULL ){ LinphoneFriendList* list = friendLists->data; - ms_warning("notify presence for list %p", list); + ms_message("notify presence for list %p", list); linphone_friend_list_notify_presence_received(list, lev, body); friendLists = friendLists->next; } diff --git a/coreapi/proxy.c b/coreapi/proxy.c index bc5845e0a..6cd24c61f 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -198,6 +198,7 @@ void _linphone_proxy_config_release_ops(LinphoneProxyConfig *cfg){ cfg->op=NULL; } if (cfg->long_term_event){ + linphone_event_terminate(cfg->long_term_event); linphone_event_unref(cfg->long_term_event); cfg->long_term_event=NULL; } diff --git a/tester/presence_server_tester.c b/tester/presence_server_tester.c index 0cf173a0d..a82f83898 100644 --- a/tester/presence_server_tester.c +++ b/tester/presence_server_tester.c @@ -66,6 +66,7 @@ static void simple(void) { BC_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivityDinner, int, "%d"); } + linphone_friend_unref(f); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } @@ -249,7 +250,7 @@ static void subscribe_with_late_publish(void) { BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePresenceActivityBreakfast, 0, int,"%i"); BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePresenceActivityAppointment, 1, int,"%i"); - + linphone_friend_unref(lf); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); } @@ -316,6 +317,7 @@ static void test_forked_subscribe_notify_publish(void) { /*wait for new status*/ BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphonePresenceActivityMeeting,1,3000)); + linphone_friend_unref(lf); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(marie2); linphone_core_manager_destroy(pauline); @@ -554,12 +556,12 @@ static void test_presence_list_subscription_expire_for_unknown(void) { linphone_core_remove_friend_list(laure->lc, linphone_core_get_default_friend_list(laure->lc)); linphone_core_add_friend_list(laure->lc, lfl); linphone_friend_list_update_subscriptions(lfl,NULL,FALSE); - linphone_friend_list_unref(lfl); /* wait for refresh*/ BC_ASSERT_FALSE(wait_for_until(laure->lc, NULL, &laure->stat.number_of_NotifyPresenceReceived, 1, 4000)); + linphone_friend_unref(lf); linphone_core_manager_destroy(laure); } @@ -583,8 +585,10 @@ static void test_presence_list_subscribe_with_error(bool_t io_error) { linphone_friend_list_set_rls_uri(lfl, rls_uri); lf = linphone_core_create_friend_with_address(laure->lc, pauline_identity); linphone_friend_list_add_friend(lfl, lf); + linphone_friend_unref(lf); lf = linphone_core_create_friend_with_address(laure->lc, "sip:michelle@sip.inexistentdomain.com"); linphone_friend_list_add_friend(lfl, lf); + linphone_friend_unref(lf); linphone_core_remove_friend_list(laure->lc, linphone_core_get_default_friend_list(laure->lc)); linphone_core_add_friend_list(laure->lc, lfl); linphone_friend_list_unref(lfl); @@ -712,14 +716,14 @@ static void long_term_presence_list(void) { test_t presence_server_tests[] = { TEST_NO_TAG("Simple", simple), TEST_NO_TAG("Fast activity change", fast_activity_change), - TEST_ONE_TAG("Subscriber no longer reachable using server",subscriber_no_longer_reachable, "presence"), - TEST_ONE_TAG("Subscribe with late publish", subscribe_with_late_publish, "LeaksMemory"), - TEST_ONE_TAG("Forked subscribe with late publish", test_forked_subscribe_notify_publish, "LeaksMemory"), - TEST_ONE_TAG("Presence list", test_presence_list, "LeaksMemory"), - TEST_ONE_TAG("Presence list without compression", test_presence_list_without_compression, "LeaksMemory"), - TEST_ONE_TAG("Presence list, subscription expiration for unknown contact",test_presence_list_subscription_expire_for_unknown, "LeaksMemory"), - TEST_ONE_TAG("Presence list, silent subscription expiration", presence_list_subscribe_dialog_expire, "LeaksMemory"), - TEST_ONE_TAG("Presence list, io error",presence_list_subscribe_io_error, "LeaksMemory"), + TEST_NO_TAG("Subscriber no longer reachable using server",subscriber_no_longer_reachable), + TEST_NO_TAG("Subscribe with late publish", subscribe_with_late_publish), + TEST_NO_TAG("Forked subscribe with late publish", test_forked_subscribe_notify_publish), + TEST_NO_TAG("Presence list", test_presence_list), + TEST_NO_TAG("Presence list without compression", test_presence_list_without_compression), + TEST_NO_TAG("Presence list, subscription expiration for unknown contact",test_presence_list_subscription_expire_for_unknown), + TEST_NO_TAG("Presence list, silent subscription expiration", presence_list_subscribe_dialog_expire), + TEST_NO_TAG("Presence list, io error",presence_list_subscribe_io_error), TEST_NO_TAG("Long term presence existing friend",long_term_presence_existing_friend), TEST_NO_TAG("Long term presence inexistent friend",long_term_presence_inexistent_friend), TEST_NO_TAG("Long term presence list",long_term_presence_list),