diff options
Diffstat (limited to 'res/res_pjsip')
-rw-r--r-- | res/res_pjsip/location.c | 140 | ||||
-rw-r--r-- | res/res_pjsip/pjsip_configuration.c | 40 | ||||
-rw-r--r-- | res/res_pjsip/pjsip_distributor.c | 3 |
3 files changed, 113 insertions, 70 deletions
diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c index 9c08ccee6..d8f0c58b5 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; } @@ -214,12 +213,12 @@ struct ao2_container *ast_sip_location_retrieve_aor_contacts(const struct ast_si struct ao2_container *contacts; struct ast_named_lock *lock; - lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_RWLOCK, "aor", ast_sorcery_object_get_id(aor)); + lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "aor", ast_sorcery_object_get_id(aor)); if (!lock) { return NULL; } - ao2_wrlock(lock); + ao2_lock(lock); contacts = ast_sip_location_retrieve_aor_contacts_nolock(aor); ao2_unlock(lock); ast_named_lock_put(lock); @@ -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, @@ -373,12 +376,12 @@ int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri, int res; struct ast_named_lock *lock; - lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_RWLOCK, "aor", ast_sorcery_object_get_id(aor)); + lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "aor", ast_sorcery_object_get_id(aor)); if (!lock) { return -1; } - ao2_wrlock(lock); + ao2_lock(lock); res = ast_sip_location_add_contact_nolock(aor, uri, expiration_time, path_info, user_agent, via_addr, via_port, call_id, endpoint); @@ -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--; diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index 48d011067..9e757e230 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -169,7 +169,6 @@ static int persistent_endpoint_update_state(void *obj, void *arg, int flags) contact_status = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), CONTACT_STATUS, contact_id); - if (contact_status && contact_status->status != UNAVAILABLE) { state = AST_ENDPOINT_ONLINE; } @@ -299,7 +298,8 @@ static void endpoint_deleted_observer(const void *object) { const struct ast_sip_endpoint *endpoint = object; - ao2_find(persistent_endpoints, ast_endpoint_get_resource(endpoint->persistent), OBJ_SEARCH_KEY | OBJ_UNLINK | OBJ_NODATA); + ao2_find(persistent_endpoints, ast_endpoint_get_resource(endpoint->persistent), + OBJ_SEARCH_KEY | OBJ_UNLINK | OBJ_NODATA); } static const struct ast_sorcery_observer endpoint_observers = { @@ -1227,16 +1227,16 @@ static void persistent_endpoint_destroy(void *obj) int ast_sip_persistent_endpoint_update_state(const char *endpoint_name, enum ast_endpoint_state state) { - RAII_VAR(struct sip_persistent_endpoint *, persistent, NULL, ao2_cleanup); - SCOPED_AO2LOCK(lock, persistent_endpoints); + struct sip_persistent_endpoint *persistent; - if (!(persistent = ao2_find(persistent_endpoints, endpoint_name, OBJ_KEY | OBJ_NOLOCK))) { - return -1; + ao2_lock(persistent_endpoints); + persistent = ao2_find(persistent_endpoints, endpoint_name, OBJ_SEARCH_KEY | OBJ_NOLOCK); + if (persistent) { + endpoint_update_state(persistent->endpoint, state); + ao2_ref(persistent, -1); } - - endpoint_update_state(persistent->endpoint, state); - - return 0; + ao2_unlock(persistent_endpoints); + return persistent ? 0 : -1; } /*! \brief Internal function which finds (or creates) persistent endpoint information */ @@ -1245,16 +1245,25 @@ static struct ast_endpoint *persistent_endpoint_find_or_create(const struct ast_ RAII_VAR(struct sip_persistent_endpoint *, persistent, NULL, ao2_cleanup); SCOPED_AO2LOCK(lock, persistent_endpoints); - if (!(persistent = ao2_find(persistent_endpoints, ast_sorcery_object_get_id(endpoint), OBJ_KEY | OBJ_NOLOCK))) { - if (!(persistent = ao2_alloc(sizeof(*persistent), persistent_endpoint_destroy))) { + persistent = ao2_find(persistent_endpoints, ast_sorcery_object_get_id(endpoint), + OBJ_SEARCH_KEY | OBJ_NOLOCK); + if (!persistent) { + persistent = ao2_alloc_options(sizeof(*persistent), persistent_endpoint_destroy, + AO2_ALLOC_OPT_LOCK_NOLOCK); + if (!persistent) { return NULL; } - if (!(persistent->endpoint = ast_endpoint_create("PJSIP", ast_sorcery_object_get_id(endpoint)))) { + persistent->endpoint = ast_endpoint_create("PJSIP", + ast_sorcery_object_get_id(endpoint)); + if (!persistent->endpoint) { return NULL; } persistent->aors = ast_strdup(endpoint->aors); + if (!persistent->aors) { + return NULL; + } ast_endpoint_set_state(persistent->endpoint, AST_ENDPOINT_UNKNOWN); @@ -1760,7 +1769,9 @@ int ast_res_pjsip_initialize_configuration(const struct ast_module_info *ast_mod return -1; } - if (!(persistent_endpoints = ao2_container_alloc(PERSISTENT_BUCKETS, persistent_endpoint_hash, persistent_endpoint_cmp))) { + persistent_endpoints = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, + PERSISTENT_BUCKETS, persistent_endpoint_hash, NULL, persistent_endpoint_cmp); + if (!persistent_endpoints) { return -1; } @@ -1981,6 +1992,7 @@ void ast_res_pjsip_destroy_configuration(void) ast_sip_unregister_cli_formatter(endpoint_formatter); ast_sip_destroy_cli(); ao2_cleanup(persistent_endpoints); + persistent_endpoints = NULL; } int ast_res_pjsip_reload_configuration(void) diff --git a/res/res_pjsip/pjsip_distributor.c b/res/res_pjsip/pjsip_distributor.c index e8ed89361..8a9119639 100644 --- a/res/res_pjsip/pjsip_distributor.c +++ b/res/res_pjsip/pjsip_distributor.c @@ -965,7 +965,7 @@ static int clean_task(const void *data) static void global_loaded(const char *object_type) { char *identifier_order = ast_sip_get_endpoint_identifier_order(); - char *io_copy = ast_strdupa(identifier_order); + char *io_copy = identifier_order ? ast_strdupa(identifier_order) : NULL; char *identify_method; ast_free(identifier_order); @@ -982,6 +982,7 @@ static void global_loaded(const char *object_type) /* Clean out the old task, if any */ ast_sched_clean_by_callback(prune_context, prune_task, clean_task); + /* Have to do something with the return value to shut up the stupid compiler. */ if (ast_sched_add_variable(prune_context, unidentified_prune_interval * 1000, prune_task, NULL, 1) < 0) { return; } |