From 73052e573219725eb437cdd56c6f9d21c84a0f6f Mon Sep 17 00:00:00 2001 From: Richard Mudgett Date: Thu, 4 Aug 2016 18:03:56 -0500 Subject: location.c: Misc fixes and cleanups. * Eliminated most RAII_VAR() usage. * Added several missing allocation failure checks. * Made ast_sip_for_each_contact() allocate the wrapper ao2 object without a lock as it is not needed. Change-Id: Ie20913365156c95dd79e5d471cfd25e99ae880bc --- res/res_pjsip/location.c | 132 +++++++++++++++++++++++++++++------------------ 1 file changed, 81 insertions(+), 51 deletions(-) (limited to 'res/res_pjsip') diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c index 9c08ccee6..67ea204af 100644 --- a/res/res_pjsip/location.c +++ b/res/res_pjsip/location.c @@ -173,16 +173,15 @@ static int contact_link_static(void *obj, void *arg, int flags) struct ast_sip_contact *ast_sip_location_retrieve_first_aor_contact(const struct ast_sip_aor *aor) { - RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup); - struct ast_sip_contact *contact; + struct ao2_container *contacts; + struct ast_sip_contact *contact = NULL; contacts = ast_sip_location_retrieve_aor_contacts(aor); - if (!contacts || (ao2_container_count(contacts) == 0)) { - return NULL; + if (contacts && ao2_container_count(contacts)) { + /* Get the first AOR contact in the container. */ + contact = ao2_callback(contacts, 0, NULL, NULL); } - - /* Get the first AOR contact in the container. */ - contact = ao2_callback(contacts, 0, NULL, NULL); + ao2_cleanup(contacts); return contact; } @@ -315,14 +314,16 @@ int ast_sip_location_add_contact_nolock(struct ast_sip_aor *aor, const char *uri const char *via_addr, int via_port, const char *call_id, struct ast_sip_endpoint *endpoint) { + struct ast_sip_contact *contact; + int res; char name[MAX_OBJECT_FIELD * 2 + 3]; - RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup); char hash[33]; ast_md5_hash(hash, uri); snprintf(name, sizeof(name), "%s;@%s", ast_sorcery_object_get_id(aor), hash); - if (!(contact = ast_sorcery_alloc(ast_sip_get_sorcery(), "contact", name))) { + contact = ast_sorcery_alloc(ast_sip_get_sorcery(), "contact", name); + if (!contact) { return -1; } @@ -362,7 +363,9 @@ int ast_sip_location_add_contact_nolock(struct ast_sip_aor *aor, const char *uri ast_string_field_set(contact, endpoint_name, ast_sorcery_object_get_id(endpoint)); } - return ast_sorcery_create(ast_sip_get_sorcery(), contact); + res = ast_sorcery_create(ast_sip_get_sorcery(), contact); + ao2_ref(contact, -1); + return res; } int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri, @@ -603,7 +606,9 @@ static int voicemail_extension_to_str(const void *obj, const intptr_t *args, cha int ast_sip_for_each_aor(const char *aors, ao2_callback_fn on_aor, void *arg) { - char *copy, *name; + char *copy; + char *name; + int res; if (!on_aor || ast_strlen_zero(aors)) { return 0; @@ -611,15 +616,15 @@ int ast_sip_for_each_aor(const char *aors, ao2_callback_fn on_aor, void *arg) copy = ast_strdupa(aors); while ((name = ast_strip(strsep(©, ",")))) { - RAII_VAR(struct ast_sip_aor *, aor, - ast_sip_location_retrieve_aor(name), ao2_cleanup); - - if (!aor) { - continue; - } + struct ast_sip_aor *aor; - if (on_aor(aor, arg, 0)) { - return -1; + aor = ast_sip_location_retrieve_aor(name); + if (aor) { + res = on_aor(aor, arg, 0); + ao2_ref(aor, -1); + if (res) { + return -1; + } } } return 0; @@ -628,15 +633,16 @@ int ast_sip_for_each_aor(const char *aors, ao2_callback_fn on_aor, void *arg) static void contact_wrapper_destroy(void *obj) { struct ast_sip_contact_wrapper *wrapper = obj; + ast_free(wrapper->aor_id); ast_free(wrapper->contact_id); - ao2_ref(wrapper->contact, -1); + ao2_cleanup(wrapper->contact); } int ast_sip_for_each_contact(const struct ast_sip_aor *aor, ao2_callback_fn on_contact, void *arg) { - RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup); + struct ao2_container *contacts; struct ao2_iterator i; int res = 0; void *object = NULL; @@ -652,7 +658,8 @@ int ast_sip_for_each_contact(const struct ast_sip_aor *aor, RAII_VAR(struct ast_sip_contact_wrapper *, wrapper, NULL, ao2_cleanup); const char *aor_id = ast_sorcery_object_get_id(aor); - wrapper = ao2_alloc(sizeof(struct ast_sip_contact_wrapper), contact_wrapper_destroy); + wrapper = ao2_alloc_options(sizeof(struct ast_sip_contact_wrapper), + contact_wrapper_destroy, AO2_ALLOC_OPT_LOCK_NOLOCK); if (!wrapper) { res = -1; break; @@ -676,6 +683,7 @@ int ast_sip_for_each_contact(const struct ast_sip_aor *aor, } } ao2_iterator_destroy(&i); + ao2_ref(contacts, -1); return res; } @@ -691,10 +699,11 @@ int ast_sip_contact_to_str(void *object, void *arg, int flags) static int sip_aor_to_ami(const struct ast_sip_aor *aor, struct ast_str **buf) { - RAII_VAR(struct ast_variable *, objset, ast_sorcery_objectset_create2( - ast_sip_get_sorcery(), aor, AST_HANDLER_ONLY_STRING), ast_variables_destroy); + struct ast_variable *objset; struct ast_variable *i; + objset = ast_sorcery_objectset_create2(ast_sip_get_sorcery(), aor, + AST_HANDLER_ONLY_STRING); if (!objset) { return -1; } @@ -706,6 +715,7 @@ static int sip_aor_to_ami(const struct ast_sip_aor *aor, struct ast_str **buf) for (i = objset; i; i = i->next) { char *camel = ast_to_camel_case(i->name); + if (strcmp(camel, "Contact") == 0) { ast_free(camel); camel = NULL; @@ -714,23 +724,28 @@ static int sip_aor_to_ami(const struct ast_sip_aor *aor, struct ast_str **buf) ast_free(camel); } + ast_variables_destroy(objset); return 0; } static int contacts_to_str(const void *obj, const intptr_t *args, char **buf) { const struct ast_sip_aor *aor = obj; - RAII_VAR(struct ast_str *, str, ast_str_create(MAX_OBJECT_FIELD), ast_free); + struct ast_str *str; + + str = ast_str_create(MAX_OBJECT_FIELD); + if (!str) { + *buf = NULL; + return -1; + } ast_sip_for_each_contact(aor, ast_sip_contact_to_str, &str); ast_str_truncate(str, -1); *buf = ast_strdup(ast_str_buffer(str)); - if (!*buf) { - return -1; - } + ast_free(str); - return 0; + return *buf ? 0 : -1; } static int format_ami_aor_handler(void *obj, void *arg, int flags) @@ -738,17 +753,20 @@ static int format_ami_aor_handler(void *obj, void *arg, int flags) struct ast_sip_aor *aor = obj; struct ast_sip_ami *ami = arg; const struct ast_sip_endpoint *endpoint = ami->arg; - RAII_VAR(struct ast_str *, buf, - ast_sip_create_ami_event("AorDetail", ami), ast_free); - + struct ast_str *buf; + struct ao2_container *contacts; int total_contacts; int num_permanent; - RAII_VAR(struct ao2_container *, contacts, - ast_sip_location_retrieve_aor_contacts(aor), ao2_cleanup); + buf = ast_sip_create_ami_event("AorDetail", ami); if (!buf) { return -1; } + contacts = ast_sip_location_retrieve_aor_contacts(aor); + if (!contacts) { + ast_free(buf); + return -1; + } sip_aor_to_ami(aor, &buf); total_contacts = ao2_container_count(contacts); @@ -764,6 +782,8 @@ static int format_ami_aor_handler(void *obj, void *arg, int flags) astman_append(ami->s, "%s\r\n", ast_str_buffer(buf)); ami->count++; + ast_free(buf); + ao2_ref(contacts, -1); return 0; } @@ -781,7 +801,7 @@ struct ast_sip_endpoint_formatter endpoint_aor_formatter = { static struct ao2_container *cli_aor_get_container(const char *regex) { - RAII_VAR(struct ao2_container *, container, NULL, ao2_cleanup); + struct ao2_container *container; struct ao2_container *s_container; container = ast_sorcery_retrieve_by_regex(ast_sip_get_sorcery(), "aor", regex); @@ -789,16 +809,15 @@ static struct ao2_container *cli_aor_get_container(const char *regex) return NULL; } + /* Create a sorted container of aors. */ s_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, ast_sorcery_object_id_sort, ast_sorcery_object_id_compare); - if (!s_container) { - return NULL; - } - - if (ao2_container_dup(s_container, container, 0)) { + if (s_container + && ao2_container_dup(s_container, container, 0)) { ao2_ref(s_container, -1); - return NULL; + s_container = NULL; } + ao2_ref(container, -1); return s_container; } @@ -900,7 +919,7 @@ static struct ao2_container *cli_contact_get_container(const char *regex) struct ao2_container *child_container; regex_t regexbuf; - parent_container = cli_aor_get_container(""); + parent_container = cli_aor_get_container(""); if (!parent_container) { return NULL; } @@ -927,9 +946,17 @@ static struct ao2_container *cli_contact_get_container(const char *regex) static void *cli_contact_retrieve_by_id(const char *id) { - RAII_VAR(struct ao2_container *, container, cli_contact_get_container(""), ao2_cleanup); + struct ao2_container *container; + void *obj; - return ao2_find(container, id, OBJ_KEY | OBJ_NOLOCK); + container = cli_contact_get_container(""); + if (!container) { + return NULL; + } + + obj = ao2_find(container, id, OBJ_SEARCH_KEY); + ao2_ref(container, -1); + return obj; } static int cli_contact_print_header(void *obj, void *arg, int flags) @@ -956,14 +983,13 @@ static int cli_contact_print_body(void *obj, void *arg, int flags) int flexwidth; const char *contact_id = ast_sorcery_object_get_id(contact); const char *hash_start = contact_id + strlen(contact->aor) + 2; - - RAII_VAR(struct ast_sip_contact_status *, status, - ast_sorcery_retrieve_by_id( ast_sip_get_sorcery(), CONTACT_STATUS, contact_id), - ao2_cleanup); + struct ast_sip_contact_status *status; ast_assert(contact->uri != NULL); ast_assert(context->output_buffer != NULL); + status = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), CONTACT_STATUS, contact_id); + indent = CLI_INDENT_TO_SPACES(context->indent_level); flexwidth = CLI_LAST_TABSTOP - indent - 9 - strlen(contact->aor) + 1; @@ -977,6 +1003,7 @@ static int cli_contact_print_body(void *obj, void *arg, int flags) ast_sip_get_contact_short_status_label(status ? status->status : UNKNOWN), (status && (status->status != UNKNOWN) ? ((long long) status->rtt) / 1000.0 : NAN)); + ao2_cleanup(status); return 0; } @@ -1000,8 +1027,6 @@ static const char *cli_aor_get_id(const void *obj) static int cli_aor_print_header(void *obj, void *arg, int flags) { struct ast_sip_cli_context *context = arg; - RAII_VAR(struct ast_sip_cli_formatter_entry *, formatter_entry, NULL, ao2_cleanup); - int indent = CLI_INDENT_TO_SPACES(context->indent_level); int filler = CLI_LAST_TABSTOP - indent - 7; @@ -1012,10 +1037,13 @@ static int cli_aor_print_header(void *obj, void *arg, int flags) indent, "Aor", filler, filler, CLI_HEADER_FILLER); if (context->recurse) { + struct ast_sip_cli_formatter_entry *formatter_entry; + context->indent_level++; formatter_entry = ast_sip_lookup_cli_formatter("contact"); if (formatter_entry) { formatter_entry->print_header(NULL, context, 0); + ao2_ref(formatter_entry, -1); } context->indent_level--; } @@ -1027,7 +1055,6 @@ static int cli_aor_print_body(void *obj, void *arg, int flags) { struct ast_sip_aor *aor = obj; struct ast_sip_cli_context *context = arg; - RAII_VAR(struct ast_sip_cli_formatter_entry *, formatter_entry, NULL, ao2_cleanup); int indent; int flexwidth; @@ -1045,11 +1072,14 @@ static int cli_aor_print_body(void *obj, void *arg, int flags) ast_sorcery_object_get_id(aor), aor->max_contacts); if (context->recurse) { + struct ast_sip_cli_formatter_entry *formatter_entry; + context->indent_level++; formatter_entry = ast_sip_lookup_cli_formatter("contact"); if (formatter_entry) { formatter_entry->iterate(aor, formatter_entry->print_body, context); + ao2_ref(formatter_entry, -1); } context->indent_level--; -- cgit v1.2.3