diff options
-rw-r--r-- | configs/samples/res_config_sqlite.conf.sample | 2 | ||||
-rw-r--r-- | include/asterisk/res_pjsip_session.h | 7 | ||||
-rw-r--r-- | main/cdr.c | 48 | ||||
-rw-r--r-- | res/res_pjsip.c | 23 | ||||
-rw-r--r-- | res/res_pjsip/include/res_pjsip_private.h | 26 | ||||
-rw-r--r-- | res/res_pjsip/pjsip_configuration.c | 18 | ||||
-rw-r--r-- | res/res_pjsip/pjsip_message_filter.c | 24 | ||||
-rw-r--r-- | res/res_pjsip/pjsip_session.c | 121 | ||||
-rw-r--r-- | res/res_pjsip_session.c | 70 |
9 files changed, 213 insertions, 126 deletions
diff --git a/configs/samples/res_config_sqlite.conf.sample b/configs/samples/res_config_sqlite.conf.sample index 04e6ae2e7..2d14d46a3 100644 --- a/configs/samples/res_config_sqlite.conf.sample +++ b/configs/samples/res_config_sqlite.conf.sample @@ -8,4 +8,4 @@ dbfile => /var/lib/asterisk/sqlite.db ; extconfig.conf, the value given here is used. If cdr_table is omitted, CDR ; support is simply disabled. config_table => ast_config -cdr_table => ast_cdr +; cdr_table => ast_cdr diff --git a/include/asterisk/res_pjsip_session.h b/include/asterisk/res_pjsip_session.h index d275c256e..7d6b30229 100644 --- a/include/asterisk/res_pjsip_session.h +++ b/include/asterisk/res_pjsip_session.h @@ -544,6 +544,13 @@ int ast_sip_session_register_supplement(struct ast_sip_session_supplement *suppl void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement); /*! + * \brief Add supplements to a SIP session + * + * \param session The session to initialize + */ +int ast_sip_session_add_supplements(struct ast_sip_session *session); + +/*! * \brief Alternative for ast_datastore_alloc() * * There are two major differences between this and ast_datastore_alloc() diff --git a/main/cdr.c b/main/cdr.c index f313f0b63..ff0e4760e 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -754,11 +754,7 @@ static void free_variables(struct varshead *headp) */ static void cdr_object_snapshot_copy(struct cdr_object_snapshot *dst, struct cdr_object_snapshot *src) { - if (dst->snapshot) { - ao2_t_ref(dst->snapshot, -1, "release old snapshot during copy"); - } - dst->snapshot = src->snapshot; - ao2_t_ref(dst->snapshot, +1, "bump new snapshot during copy"); + ao2_t_replace(dst->snapshot, src->snapshot, "CDR snapshot copy"); strcpy(dst->userfield, src->userfield); dst->flags = src->flags; copy_variables(&dst->variables, &src->variables); @@ -788,11 +784,11 @@ static int cdr_object_channel_hash_fn(const void *obj, const int flags) const struct cdr_object *cdr; const char *key; - switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) { - case OBJ_KEY: + switch (flags & OBJ_SEARCH_MASK) { + case OBJ_SEARCH_KEY: key = obj; break; - case OBJ_POINTER: + case OBJ_SEARCH_OBJECT: cdr = obj; key = cdr->uniqueid; break; @@ -813,14 +809,14 @@ static int cdr_object_channel_cmp_fn(void *obj, void *arg, int flags) const char *right_key = arg; int cmp; - switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) { - case OBJ_POINTER: + switch (flags & OBJ_SEARCH_MASK) { + case OBJ_SEARCH_OBJECT: right_key = right->uniqueid; /* Fall through */ - case OBJ_KEY: + case OBJ_SEARCH_KEY: cmp = strcmp(left->uniqueid, right_key); break; - case OBJ_PARTIAL_KEY: + case OBJ_SEARCH_PARTIAL_KEY: /* * We could also use a partial key struct containing a length * so strlen() does not get called for every comparison instead. @@ -1361,11 +1357,7 @@ static void cdr_object_swap_snapshot(struct cdr_object_snapshot *old_snapshot, struct ast_channel_snapshot *new_snapshot) { cdr_object_update_cid(old_snapshot, new_snapshot); - if (old_snapshot->snapshot) { - ao2_t_ref(old_snapshot->snapshot, -1, "Drop ref for swap"); - } - ao2_t_ref(new_snapshot, +1, "Bump ref for swap"); - old_snapshot->snapshot = new_snapshot; + ao2_t_replace(old_snapshot->snapshot, new_snapshot, "Swap CDR shapshot"); } /* BASE METHOD IMPLEMENTATIONS */ @@ -1575,7 +1567,7 @@ static enum process_bridge_enter_results single_state_process_bridge_enter(struc !success && (channel_id = ao2_iterator_next(&it_cdrs)); ao2_ref(channel_id, -1)) { RAII_VAR(struct cdr_object *, cand_cdr_master, - ao2_find(active_cdrs_by_channel, channel_id, OBJ_KEY), + ao2_find(active_cdrs_by_channel, channel_id, OBJ_SEARCH_KEY), ao2_cleanup); struct cdr_object *cand_cdr; @@ -1723,7 +1715,7 @@ static enum process_bridge_enter_results dial_state_process_bridge_enter(struct !success && (channel_id = ao2_iterator_next(&it_cdrs)); ao2_ref(channel_id, -1)) { RAII_VAR(struct cdr_object *, cand_cdr_master, - ao2_find(active_cdrs_by_channel, channel_id, OBJ_KEY), + ao2_find(active_cdrs_by_channel, channel_id, OBJ_SEARCH_KEY), ao2_cleanup); struct cdr_object *cand_cdr; @@ -1963,9 +1955,9 @@ static void handle_dial_message(void *data, struct stasis_subscription *sub, str /* Figure out who is running this show */ if (caller) { - cdr = ao2_find(active_cdrs_by_channel, caller->uniqueid, OBJ_KEY); + cdr = ao2_find(active_cdrs_by_channel, caller->uniqueid, OBJ_SEARCH_KEY); } else { - cdr = ao2_find(active_cdrs_by_channel, peer->uniqueid, OBJ_KEY); + cdr = ao2_find(active_cdrs_by_channel, peer->uniqueid, OBJ_SEARCH_KEY); } if (!cdr) { @@ -2119,7 +2111,7 @@ static void handle_channel_cache_message(void *data, struct stasis_subscription /* Handle Party A */ if (!cdr) { - cdr = ao2_find(active_cdrs_by_channel, uniqueid, OBJ_KEY); + cdr = ao2_find(active_cdrs_by_channel, uniqueid, OBJ_SEARCH_KEY); } if (!cdr) { ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", name); @@ -2225,7 +2217,7 @@ static void handle_bridge_leave_message(void *data, struct stasis_subscription * RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup); RAII_VAR(struct cdr_object *, cdr, - ao2_find(active_cdrs_by_channel, channel->uniqueid, OBJ_KEY), + ao2_find(active_cdrs_by_channel, channel->uniqueid, OBJ_SEARCH_KEY), ao2_cleanup); struct cdr_object *it_cdr; struct bridge_leave_data leave_data = { @@ -2382,7 +2374,7 @@ static void handle_bridge_pairings(struct cdr_object *cdr, struct ast_bridge_sna it_channels = ao2_iterator_init(bridge->channels, 0); while ((channel_id = ao2_iterator_next(&it_channels))) { RAII_VAR(struct cdr_object *, cand_cdr, - ao2_find(active_cdrs_by_channel, channel_id, OBJ_KEY), + ao2_find(active_cdrs_by_channel, channel_id, OBJ_SEARCH_KEY), ao2_cleanup); if (!cand_cdr) { @@ -2528,7 +2520,7 @@ static void handle_bridge_enter_message(void *data, struct stasis_subscription * struct ast_bridge_snapshot *bridge = update->bridge; struct ast_channel_snapshot *channel = update->channel; RAII_VAR(struct cdr_object *, cdr, - ao2_find(active_cdrs_by_channel, channel->uniqueid, OBJ_KEY), + ao2_find(active_cdrs_by_channel, channel->uniqueid, OBJ_SEARCH_KEY), ao2_cleanup); RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup); @@ -2596,7 +2588,7 @@ static void handle_parked_call_message(void *data, struct stasis_subscription *s (unsigned int)stasis_message_timestamp(message)->tv_sec, (unsigned int)stasis_message_timestamp(message)->tv_usec); - cdr = ao2_find(active_cdrs_by_channel, channel->uniqueid, OBJ_KEY); + cdr = ao2_find(active_cdrs_by_channel, channel->uniqueid, OBJ_SEARCH_KEY); if (!cdr) { ast_log(AST_LOG_WARNING, "No CDR for channel %s\n", channel->name); ast_assert(0); @@ -4246,8 +4238,8 @@ int ast_cdr_engine_init(void) stasis_message_router_add(stasis_router, ast_parked_call_type(), handle_parked_call_message, NULL); stasis_message_router_add(stasis_router, cdr_sync_message_type(), handle_cdr_sync_message, NULL); - active_cdrs_by_channel = ao2_container_alloc(NUM_CDR_BUCKETS, - cdr_object_channel_hash_fn, cdr_object_channel_cmp_fn); + active_cdrs_by_channel = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, + NUM_CDR_BUCKETS, cdr_object_channel_hash_fn, NULL, cdr_object_channel_cmp_fn); if (!active_cdrs_by_channel) { return -1; } diff --git a/res/res_pjsip.c b/res/res_pjsip.c index 4d5c5cb83..844d8a1cc 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -3476,7 +3476,7 @@ int ast_sip_create_request(const char *method, struct pjsip_dialog *dlg, AST_RWLIST_HEAD_STATIC(supplements, ast_sip_supplement); -int ast_sip_register_supplement(struct ast_sip_supplement *supplement) +void internal_sip_register_supplement(struct ast_sip_supplement *supplement) { struct ast_sip_supplement *iter; int inserted = 0; @@ -3494,22 +3494,39 @@ int ast_sip_register_supplement(struct ast_sip_supplement *supplement) if (!inserted) { AST_RWLIST_INSERT_TAIL(&supplements, supplement, next); } +} + +int ast_sip_register_supplement(struct ast_sip_supplement *supplement) +{ + internal_sip_register_supplement(supplement); ast_module_ref(ast_module_info->self); + return 0; } -void ast_sip_unregister_supplement(struct ast_sip_supplement *supplement) +int internal_sip_unregister_supplement(struct ast_sip_supplement *supplement) { struct ast_sip_supplement *iter; SCOPED_LOCK(lock, &supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK); + int res = -1; + AST_RWLIST_TRAVERSE_SAFE_BEGIN(&supplements, iter, next) { if (supplement == iter) { AST_RWLIST_REMOVE_CURRENT(next); - ast_module_unref(ast_module_info->self); + res = 0; break; } } AST_RWLIST_TRAVERSE_SAFE_END; + + return res; +} + +void ast_sip_unregister_supplement(struct ast_sip_supplement *supplement) +{ + if (!internal_sip_unregister_supplement(supplement)) { + ast_module_unref(ast_module_info->self); + } } static int send_in_dialog_request(pjsip_tx_data *tdata, struct pjsip_dialog *dlg) diff --git a/res/res_pjsip/include/res_pjsip_private.h b/res/res_pjsip/include/res_pjsip_private.h index 9fd7aed97..5ce3c6faf 100644 --- a/res/res_pjsip/include/res_pjsip_private.h +++ b/res/res_pjsip/include/res_pjsip_private.h @@ -328,6 +328,18 @@ int internal_sip_unregister_service(pjsip_module *module); /*! * \internal + * \brief Used by res_pjsip.so to register a supplement without adding a self reference + */ +void internal_sip_register_supplement(struct ast_sip_supplement *supplement); + +/*! + * \internal + * \brief Used by res_pjsip.so to unregister a supplement without removing a self reference + */ +int internal_sip_unregister_supplement(struct ast_sip_supplement *supplement); + +/*! + * \internal * \brief Used by res_pjsip.so to register an endpoint formatter without adding a self reference */ void internal_sip_register_endpoint_formatter(struct ast_sip_endpoint_formatter *obj); @@ -338,6 +350,20 @@ void internal_sip_register_endpoint_formatter(struct ast_sip_endpoint_formatter */ int internal_sip_unregister_endpoint_formatter(struct ast_sip_endpoint_formatter *obj); +struct ast_sip_session_supplement; + +/*! + * \internal + * \brief Used by res_pjsip.so to register a session supplement without adding a self reference + */ +void internal_sip_session_register_supplement(struct ast_sip_session_supplement *supplement); + +/*! + * \internal + * \brief Used by res_pjsip.so to unregister a session supplement without removing a self reference + */ +int internal_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement); + /*! * \internal * \brief Finds or creates contact_status for a contact diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index 437476631..a39102305 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -1314,6 +1314,14 @@ static struct ast_endpoint *persistent_endpoint_find_or_create(const struct ast_ ast_endpoint_set_state(persistent->endpoint, AST_ENDPOINT_OFFLINE); ao2_link_flags(persistent_endpoints, persistent, OBJ_NOLOCK); + } else if (strcmp(persistent->aors, endpoint->aors)) { + char *new_aors = ast_strdup(endpoint->aors); + + /* make sure we don't NULL persistent->aors if allocation fails. */ + if (new_aors) { + ast_free(persistent->aors); + persistent->aors = new_aors; + } } ao2_ref(persistent->endpoint, +1); @@ -1790,20 +1798,12 @@ static struct ast_cli_entry cli_commands[] = { struct ast_sip_cli_formatter_entry *channel_formatter; struct ast_sip_cli_formatter_entry *endpoint_formatter; -static int on_load_endpoint(void *obj, void *arg, int flags) -{ - return sip_endpoint_apply_handler(sip_sorcery, obj); -} - static void load_all_endpoints(void) { struct ao2_container *endpoints; endpoints = ast_sorcery_retrieve_by_fields(sip_sorcery, "endpoint", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL); - if (endpoints) { - ao2_callback(endpoints, OBJ_NODATA, on_load_endpoint, NULL); - ao2_ref(endpoints, -1); - } + ao2_cleanup(endpoints); } int ast_res_pjsip_initialize_configuration(void) diff --git a/res/res_pjsip/pjsip_message_filter.c b/res/res_pjsip/pjsip_message_filter.c index d2f9b9562..978aeb070 100644 --- a/res/res_pjsip/pjsip_message_filter.c +++ b/res/res_pjsip/pjsip_message_filter.c @@ -505,32 +505,24 @@ static pj_bool_t filter_on_rx_message(pjsip_rx_data *rdata) void ast_res_pjsip_cleanup_message_filter(void) { - ast_sip_unregister_service(&filter_module_tsx); - ast_sip_unregister_service(&filter_module_transport); - ast_sip_unregister_supplement(&filter_supplement); - ast_sip_session_unregister_supplement(&filter_session_supplement); + internal_sip_unregister_service(&filter_module_tsx); + internal_sip_unregister_service(&filter_module_transport); + internal_sip_unregister_supplement(&filter_supplement); + internal_sip_session_unregister_supplement(&filter_session_supplement); } int ast_res_pjsip_init_message_filter(void) { - if (ast_sip_session_register_supplement(&filter_session_supplement)) { - ast_log(LOG_ERROR, "Could not register message filter session supplement for outgoing requests\n"); - return -1; - } - - if (ast_sip_register_supplement(&filter_supplement)) { - ast_log(LOG_ERROR, "Could not register message filter supplement for outgoing requests\n"); - ast_res_pjsip_cleanup_message_filter(); - return -1; - } + internal_sip_session_register_supplement(&filter_session_supplement); + internal_sip_register_supplement(&filter_supplement); - if (ast_sip_register_service(&filter_module_transport)) { + if (internal_sip_register_service(&filter_module_transport)) { ast_log(LOG_ERROR, "Could not register message filter module for incoming and outgoing requests\n"); ast_res_pjsip_cleanup_message_filter(); return -1; } - if (ast_sip_register_service(&filter_module_tsx)) { + if (internal_sip_register_service(&filter_module_tsx)) { ast_log(LOG_ERROR, "Could not register message filter module for incoming and outgoing requests\n"); ast_res_pjsip_cleanup_message_filter(); return -1; diff --git a/res/res_pjsip/pjsip_session.c b/res/res_pjsip/pjsip_session.c new file mode 100644 index 000000000..cea72436a --- /dev/null +++ b/res/res_pjsip/pjsip_session.c @@ -0,0 +1,121 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2017, CFWare, LLC + * + * Corey Farrell <git@cfware.com> + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +#include "asterisk.h" + +#include <pjsip.h> +#include <pjsip_ua.h> +#include <pjlib.h> + +#include "asterisk/res_pjsip.h" +#include "asterisk/res_pjsip_session.h" +#include "include/res_pjsip_private.h" +#include "asterisk/linkedlists.h" +#include "asterisk/lock.h" +#include "asterisk/module.h" + + +AST_RWLIST_HEAD_STATIC(session_supplements, ast_sip_session_supplement); + +void internal_sip_session_register_supplement(struct ast_sip_session_supplement *supplement) +{ + struct ast_sip_session_supplement *iter; + int inserted = 0; + SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK); + + if (!supplement->response_priority) { + supplement->response_priority = AST_SIP_SESSION_BEFORE_MEDIA; + } + + AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) { + if (iter->priority > supplement->priority) { + AST_RWLIST_INSERT_BEFORE_CURRENT(supplement, next); + inserted = 1; + break; + } + } + AST_RWLIST_TRAVERSE_SAFE_END; + + if (!inserted) { + AST_RWLIST_INSERT_TAIL(&session_supplements, supplement, next); + } +} + +int ast_sip_session_register_supplement(struct ast_sip_session_supplement *supplement) +{ + internal_sip_session_register_supplement(supplement); + ast_module_ref(AST_MODULE_SELF); + + return 0; +} + +int internal_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement) +{ + struct ast_sip_session_supplement *iter; + int res = -1; + SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK); + + AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) { + if (supplement == iter) { + AST_RWLIST_REMOVE_CURRENT(next); + res = 0; + break; + } + } + AST_RWLIST_TRAVERSE_SAFE_END; + + return res; +} + +void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement) +{ + if (!internal_sip_session_unregister_supplement(supplement)) { + ast_module_unref(AST_MODULE_SELF); + } +} + +static struct ast_sip_session_supplement *supplement_dup(const struct ast_sip_session_supplement *src) +{ + struct ast_sip_session_supplement *dst = ast_calloc(1, sizeof(*dst)); + + if (!dst) { + return NULL; + } + /* Will need to revisit if shallow copy becomes an issue */ + *dst = *src; + + return dst; +} + +int ast_sip_session_add_supplements(struct ast_sip_session *session) +{ + struct ast_sip_session_supplement *iter; + SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK); + + AST_RWLIST_TRAVERSE(&session_supplements, iter, next) { + struct ast_sip_session_supplement *copy = supplement_dup(iter); + + if (!copy) { + return -1; + } + AST_LIST_INSERT_TAIL(&session->supplements, copy, next); + } + + return 0; +} + diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c index 496c4763a..f84d60e14 100644 --- a/res/res_pjsip_session.c +++ b/res/res_pjsip_session.c @@ -396,59 +396,6 @@ static int handle_negotiated_sdp(struct ast_sip_session *session, const pjmedia_ return -1; } -AST_RWLIST_HEAD_STATIC(session_supplements, ast_sip_session_supplement); - -int ast_sip_session_register_supplement(struct ast_sip_session_supplement *supplement) -{ - struct ast_sip_session_supplement *iter; - int inserted = 0; - SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK); - - if (!supplement->response_priority) { - supplement->response_priority = AST_SIP_SESSION_BEFORE_MEDIA; - } - - AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) { - if (iter->priority > supplement->priority) { - AST_RWLIST_INSERT_BEFORE_CURRENT(supplement, next); - inserted = 1; - break; - } - } - AST_RWLIST_TRAVERSE_SAFE_END; - - if (!inserted) { - AST_RWLIST_INSERT_TAIL(&session_supplements, supplement, next); - } - ast_module_ref(ast_module_info->self); - return 0; -} - -void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement) -{ - struct ast_sip_session_supplement *iter; - SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK); - AST_RWLIST_TRAVERSE_SAFE_BEGIN(&session_supplements, iter, next) { - if (supplement == iter) { - AST_RWLIST_REMOVE_CURRENT(next); - ast_module_unref(ast_module_info->self); - break; - } - } - AST_RWLIST_TRAVERSE_SAFE_END; -} - -static struct ast_sip_session_supplement *supplement_dup(const struct ast_sip_session_supplement *src) -{ - struct ast_sip_session_supplement *dst = ast_calloc(1, sizeof(*dst)); - if (!dst) { - return NULL; - } - /* Will need to revisit if shallow copy becomes an issue */ - *dst = *src; - return dst; -} - #define DATASTORE_BUCKETS 53 #define MEDIA_BUCKETS 7 @@ -1380,21 +1327,6 @@ static void session_destructor(void *obj) ast_test_suite_event_notify("SESSION_DESTROYED", "Endpoint: %s", endpoint_name); } -static int add_supplements(struct ast_sip_session *session) -{ - struct ast_sip_session_supplement *iter; - SCOPED_LOCK(lock, &session_supplements, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK); - - AST_RWLIST_TRAVERSE(&session_supplements, iter, next) { - struct ast_sip_session_supplement *copy = supplement_dup(iter); - if (!copy) { - return -1; - } - AST_LIST_INSERT_TAIL(&session->supplements, copy, next); - } - return 0; -} - static int add_session_media(void *obj, void *arg, int flags) { struct sdp_handler_list *handler_list = obj; @@ -1523,7 +1455,7 @@ struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint, session->dtmf = endpoint->dtmf; - if (add_supplements(session)) { + if (ast_sip_session_add_supplements(session)) { /* Release the ref held by session->inv_session */ ao2_ref(session, -1); return NULL; |