diff options
-rw-r--r-- | apps/app_queue.c | 13 | ||||
-rw-r--r-- | configs/samples/manager.conf.sample | 4 | ||||
-rw-r--r-- | contrib/ast-db-manage/config/versions/3772f8f828da_update_identify_by.py | 44 | ||||
-rw-r--r-- | main/asterisk.c | 350 | ||||
-rw-r--r-- | main/named_locks.c | 4 | ||||
-rw-r--r-- | main/taskprocessor.c | 8 | ||||
-rw-r--r-- | res/res_pjsip/config_global.c | 12 | ||||
-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 | ||||
-rw-r--r-- | res/res_pjsip_caller_id.c | 2 | ||||
-rw-r--r-- | res/res_pjsip_diversion.c | 2 | ||||
-rw-r--r-- | res/res_pjsip_mwi.c | 30 | ||||
-rw-r--r-- | res/res_pjsip_registrar.c | 4 | ||||
-rw-r--r-- | res/res_pjsip_registrar_expire.c | 4 |
15 files changed, 280 insertions, 380 deletions
diff --git a/apps/app_queue.c b/apps/app_queue.c index 7fd1c6c7d..e04942f68 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -4838,6 +4838,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte char tmpchan[256]; char *stuff; char *tech; + int failed = 0; ast_copy_string(tmpchan, ast_channel_call_forward(o->chan), sizeof(tmpchan)); ast_copy_string(forwarder, ast_channel_name(o->chan), sizeof(forwarder)); @@ -4950,14 +4951,20 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte if (ast_call(o->chan, stuff, 0)) { ast_log(LOG_NOTICE, "Forwarding failed to dial '%s/%s'\n", tech, stuff); - do_hang(o); - numnochan++; + failed = 1; } } - ast_channel_publish_dial(qe->chan, o->chan, stuff, NULL); ast_channel_publish_dial_forward(qe->chan, original, o->chan, NULL, "CANCEL", ast_channel_call_forward(original)); + if (o->chan) { + ast_channel_publish_dial(qe->chan, o->chan, stuff, NULL); + } + + if (failed) { + do_hang(o); + numnochan++; + } /* Hangup the original channel now, in case we needed it */ ast_hangup(winner); diff --git a/configs/samples/manager.conf.sample b/configs/samples/manager.conf.sample index aec2d07f1..0eb64c8ae 100644 --- a/configs/samples/manager.conf.sample +++ b/configs/samples/manager.conf.sample @@ -125,7 +125,9 @@ bindaddr = 0.0.0.0 ; ; all - All event classes below (including any we may have missed). ; system - General information about the system and ability to run system -; management commands, such as Shutdown, Restart, and Reload. +; management commands, such as Shutdown, Restart, and Reload. This +; class also includes dialplan manipulation actions such as +; DialplanExtensionAdd and DialplanExtensionRemove. ; call - Information about channels and ability to set information in a ; running channel. ; log - Logging information. Read-only. (Defined but not yet used.) diff --git a/contrib/ast-db-manage/config/versions/3772f8f828da_update_identify_by.py b/contrib/ast-db-manage/config/versions/3772f8f828da_update_identify_by.py new file mode 100644 index 000000000..92695b09f --- /dev/null +++ b/contrib/ast-db-manage/config/versions/3772f8f828da_update_identify_by.py @@ -0,0 +1,44 @@ +"""update_identify_by + +Revision ID: 3772f8f828da +Revises: c7a44a5a0851 +Create Date: 2016-08-11 10:47:29.211063 + +""" + +# revision identifiers, used by Alembic. +revision = '3772f8f828da' +down_revision = 'c7a44a5a0851' + +from alembic import op +import sqlalchemy as sa + + +def enum_update(table_name, column_name, enum_name, enum_values): + if op.get_context().bind.dialect.name != 'postgresql': + op.alter_column(table_name, column_name, + type_=sa.Enum(*enum_values, name=enum_name)) + return + + # Postgres requires a few more steps + tmp = enum_name + '_tmp' + + op.execute('ALTER TYPE ' + enum_name + ' RENAME TO ' + tmp) + + updated = sa.Enum(*enum_values, name=enum_name) + updated.create(op.get_bind(), checkfirst=False) + + op.execute('ALTER TABLE ' + table_name + ' ALTER COLUMN ' + column_name + + ' TYPE ' + enum_name + ' USING identify_by::text::' + enum_name) + + op.execute('DROP TYPE ' + tmp) + + +def upgrade(): + enum_update('ps_endpoints', 'identify_by', 'pjsip_identify_by_values', + ['username', 'auth_username']) + + +def downgrade(): + enum_update('ps_endpoints', 'identify_by', 'pjsip_identify_by_values', + ['username']) diff --git a/main/asterisk.c b/main/asterisk.c index 772c3dce9..d5ffacb19 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -4307,13 +4307,21 @@ int main(int argc, char *argv[]) return 0; } +static inline void check_init(int init_result, const char *name) +{ + if (init_result) { + printf("%s initialization failed.\n%s", name, term_quit()); + ast_run_atexits(0); + exit(init_result == -2 ? 2 : 1); + } +} + static void asterisk_daemon(int isroot, const char *runuser, const char *rungroup) { FILE *f; sigset_t sigs; int num; char *buf; - int moduleresult; /*!< Result from the module load subsystem */ char pbx_uuid[AST_UUID_STR_LEN]; /* This needs to remain as high up in the initial start up as possible. @@ -4404,15 +4412,8 @@ static void asterisk_daemon(int isroot, const char *runuser, const char *rungrou register_config_cli(); read_config_maps(); - if (astobj2_init()) { - printf("Failed: astobj2_init\n%s", term_quit()); - exit(1); - } - - if (ast_named_locks_init()) { - printf("Failed: ast_named_locks_init\n%s", term_quit()); - exit(1); - } + check_init(astobj2_init(), "AO2"); + check_init(ast_named_locks_init(), "Named Locks"); if (ast_opt_console) { if (el_hist == NULL || el == NULL) @@ -4425,10 +4426,7 @@ static void asterisk_daemon(int isroot, const char *runuser, const char *rungrou ast_xmldoc_load_documentation(); #endif - if (astdb_init()) { - printf("Failed: astdb_init\n%s", term_quit()); - exit(1); - } + check_init(astdb_init(), "ASTdb"); ast_uuid_init(); @@ -4445,89 +4443,27 @@ static void asterisk_daemon(int isroot, const char *runuser, const char *rungrou callerid_init(); ast_builtins_init(); - if (ast_utils_init()) { - printf("Failed: ast_utils_init\n%s", term_quit()); - exit(1); - } - - if (ast_tps_init()) { - printf("Failed: ast_tps_init\n%s", term_quit()); - exit(1); - } - - if (ast_fd_init()) { - printf("Failed: ast_fd_init\n%s", term_quit()); - exit(1); - } - - if (ast_pbx_init()) { - printf("Failed: ast_pbx_init\n%s", term_quit()); - exit(1); - } - + check_init(ast_utils_init(), "Utilities"); + check_init(ast_tps_init(), "Task Processor Core"); + check_init(ast_fd_init(), "File Descriptor Debugging"); + check_init(ast_pbx_init(), "ast_pbx_init"); #ifdef TEST_FRAMEWORK - if (ast_test_init()) { - printf("Failed: ast_test_init\n%s", term_quit()); - exit(1); - } + check_init(ast_test_init(), "Test Framework"); #endif - - if (ast_translate_init()) { - printf("Failed: ast_translate_init\n%s", term_quit()); - exit(1); - } + check_init(ast_translate_init(), "Translator Core"); ast_aoc_cli_init(); - if (ast_sorcery_init()) { - printf("Failed: ast_sorcery_init\n%s", term_quit()); - exit(1); - } - - if (ast_codec_init()) { - printf("Failed: ast_codec_init\n%s", term_quit()); - exit(1); - } - - if (ast_format_init()) { - printf("Failed: ast_format_init\n%s", term_quit()); - exit(1); - } - - if (ast_format_cache_init()) { - printf("Failed: ast_format_cache_init\n%s", term_quit()); - exit(1); - } - - if (ast_codec_builtin_init()) { - printf("Failed: ast_codec_builtin_init\n%s", term_quit()); - exit(1); - } - - if (aco_init()) { - printf("Failed: aco_init\n%s", term_quit()); - exit(1); - } - - if (ast_bucket_init()) { - printf("Failed: ast_bucket_init\n%s", term_quit()); - exit(1); - } - - if (stasis_init()) { - printf("Stasis initialization failed.\n%s", term_quit()); - exit(1); - } - - if (ast_stasis_system_init()) { - printf("Stasis system-level information initialization failed.\n%s", term_quit()); - exit(1); - } - - if (ast_endpoint_stasis_init()) { - printf("Endpoint initialization failed.\n%s", term_quit()); - exit(1); - } + check_init(ast_sorcery_init(), "Sorcery"); + check_init(ast_codec_init(), "Codecs"); + check_init(ast_format_init(), "Formats"); + check_init(ast_format_cache_init(), "Format Cache"); + check_init(ast_codec_builtin_init(), "Built-in Codecs"); + check_init(aco_init(), "Configuration Option Framework"); + check_init(ast_bucket_init(), "Bucket API"); + check_init(stasis_init(), "Stasis"); + check_init(ast_stasis_system_init(), "Stasis system-level information"); + check_init(ast_endpoint_stasis_init(), "Stasis Endpoint"); ast_makesocket(); /* GCC 4.9 gives a bogus "right-hand operand of comma expression has @@ -4551,210 +4487,58 @@ static void asterisk_daemon(int isroot, const char *runuser, const char *rungrou srand((unsigned int) getpid() + (unsigned int) time(NULL)); initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool)); - if (init_logger()) { /* Start logging subsystem */ - printf("Failed: init_logger\n%s", term_quit()); - exit(1); - } + check_init(init_logger(), "Logger"); threadstorage_init(); - if (ast_rtp_engine_init()) { - printf("Failed: ast_rtp_engine_init\n%s", term_quit()); - exit(1); - } + check_init(ast_rtp_engine_init(), "RTP Engine"); ast_autoservice_init(); - if (ast_timing_init()) { - printf("Failed: ast_timing_init\n%s", term_quit()); - exit(1); - } - - if (ast_ssl_init()) { - printf("Failed: ast_ssl_init\n%s", term_quit()); - exit(1); - } - - if (ast_pj_init()) { - printf("Failed: ast_pj_init\n%s", term_quit()); - exit(1); - } - - if (app_init()) { - printf("App core initialization failed.\n%s", term_quit()); - exit(1); - } - - if (devstate_init()) { - printf("Device state core initialization failed.\n%s", term_quit()); - exit(1); - } - - if (ast_msg_init()) { - printf("Failed: ast_msg_init\n%s", term_quit()); - exit(1); - } - - /* initialize the data retrieval API */ - if (ast_data_init()) { - printf("Failed: ast_data_init\n%s", term_quit()); - exit(1); - } - - if (ast_channels_init()) { - printf("Failed: ast_channels_init\n%s", term_quit()); - exit(1); - } - - if (ast_endpoint_init()) { - printf ("Failed: ast_endpoint_init\n%s", term_quit()); - exit(1); - } - - if (ast_pickup_init()) { - printf("Failed: ast_pickup_init\n%s", term_quit()); - exit(1); - } - - if (ast_bridging_init()) { - printf("Failed: ast_bridging_init\n%s", term_quit()); - exit(1); - } - - if (ast_parking_stasis_init()) { - printf("Failed: ast_parking_stasis_init\n%s", term_quit()); - exit(1); - } - - if (ast_device_state_engine_init()) { - printf("Failed: ast_device_state_engine_init\n%s", term_quit()); - exit(1); - } - - if (ast_presence_state_engine_init()) { - printf("Failed: ast_presence_state_engine_init\n%s", term_quit()); - exit(1); - } - - if ((moduleresult = load_modules(1))) { /* Load modules, pre-load only */ - printf("Failed: load_modules\n%s", term_quit()); - exit(moduleresult == -2 ? 2 : 1); - } - - if (ast_features_init()) { - printf("Failed: ast_features_init\n%s", term_quit()); - exit(1); - } - - if (dnsmgr_init()) { /* Initialize the DNS manager */ - printf("Failed: dnsmgr_init\n%s", term_quit()); - exit(1); - } - - if (ast_security_stasis_init()) { /* Initialize Security Stasis Topic and Events */ - printf("Failed: ast_security_stasis_init\n%s", term_quit()); - exit(1); - } - - if (ast_named_acl_init()) { /* Initialize the Named ACL system */ - printf("Failed: ast_named_acl_init\n%s", term_quit()); - exit(1); - } + check_init(ast_timing_init(), "Timing"); + check_init(ast_ssl_init(), "SSL"); + check_init(ast_pj_init(), "Embedded PJProject"); + check_init(app_init(), "App Core"); + check_init(devstate_init(), "Device State Core"); + check_init(ast_msg_init(), "Messaging API"); + check_init(ast_data_init(), "Data Retrieval API"); + check_init(ast_channels_init(), "Channel"); + check_init(ast_endpoint_init(), "Endpoints"); + check_init(ast_pickup_init(), "Call Pickup"); + check_init(ast_bridging_init(), "Bridging"); + check_init(ast_parking_stasis_init(), "Parking Core"); + check_init(ast_device_state_engine_init(), "Device State Engine"); + check_init(ast_presence_state_engine_init(), "Presence State Engine"); + check_init(load_modules(1), "Module Preload"); + check_init(ast_features_init(), "Call Features"); + check_init(dnsmgr_init(), "DNS manager"); + check_init(ast_security_stasis_init(), "Security Stasis Topic and Events"); + check_init(ast_named_acl_init(), "Named ACL system"); ast_http_init(); /* Start the HTTP server, if needed */ - if (ast_indications_init()) { - printf("Failed: ast_indications_init\n%s", term_quit()); - exit(1); - } - - if (ast_cdr_engine_init()) { - printf("Failed: ast_cdr_engine_init\n%s", term_quit()); - exit(1); - } + check_init(ast_indications_init(), "Indication Tone Handling"); + check_init(ast_cdr_engine_init(), "CDR Engine"); ast_dsp_init(); ast_udptl_init(); - if (ast_image_init()) { - printf("Failed: ast_image_init\n%s", term_quit()); - exit(1); - } - - if (ast_file_init()) { - printf("Failed: ast_file_init\n%s", term_quit()); - exit(1); - } - - if (load_pbx()) { - printf("Failed: load_pbx\n%s", term_quit()); - exit(1); - } - - if (load_pbx_builtins()) { - printf("Failed: load_pbx_builtins\n%s", term_quit()); - exit(1); - } - - if (load_pbx_functions_cli()) { - printf("Failed: load_pbx_functions_cli\n%s", term_quit()); - exit(1); - } - - if (load_pbx_variables()) { - printf("Failed: load_pbx_variables\n%s", term_quit()); - exit(1); - } - - if (load_pbx_switch()) { - printf("Failed: load_pbx_switch\n%s", term_quit()); - exit(1); - } - - if (load_pbx_app()) { - printf("Failed: load_pbx_app\n%s", term_quit()); - exit(1); - } - - if (load_pbx_hangup_handler()) { - printf("Failed: load_pbx_hangup_handler\n%s", term_quit()); - exit(1); - } - - if (ast_local_init()) { - printf("Failed: ast_local_init\n%s", term_quit()); - exit(1); - } - - if (ast_cel_engine_init()) { - printf("Failed: ast_cel_engine_init\n%s", term_quit()); - exit(1); - } - - if (init_manager()) { - printf("Failed: init_manager\n%s", term_quit()); - exit(1); - } - - if (ast_enum_init()) { - printf("Failed: ast_enum_init\n%s", term_quit()); - exit(1); - } - - if (ast_cc_init()) { - printf("Failed: ast_cc_init\n%s", term_quit()); - exit(1); - } - - if (ast_sounds_index_init()) { - printf("Failed: ast_sounds_index_init\n%s", term_quit()); - exit(1); - } - - if ((moduleresult = load_modules(0))) { /* Load modules */ - printf("%s", term_quit()); - exit(moduleresult == -2 ? 2 : 1); - } + check_init(ast_image_init(), "Image"); + check_init(ast_file_init(), "Generic File Format Support"); + check_init(load_pbx(), "load_pbx"); + check_init(load_pbx_builtins(), "Builtin PBX Applications"); + check_init(load_pbx_functions_cli(), "PBX Functions Support"); + check_init(load_pbx_variables(), "PBX Variables Support"); + check_init(load_pbx_switch(), "PBX Switch Support"); + check_init(load_pbx_app(), "PBX Application Support"); + check_init(load_pbx_hangup_handler(), "PBX Hangup Handler Support"); + check_init(ast_local_init(), "Local Proxy Channel Driver"); + check_init(ast_cel_engine_init(), "CEL Engine"); + check_init(init_manager(), "Asterisk Manager Interface"); + check_init(ast_enum_init(), "ENUM Support"); + check_init(ast_cc_init(), "Call Completion Supplementary Services"); + check_init(ast_sounds_index_init(), "Sounds Indexer"); + check_init(load_modules(0), "Module"); /* loads the cli_permissoins.conf file needed to implement cli restrictions. */ ast_cli_perms_init(0); diff --git a/main/named_locks.c b/main/named_locks.c index b977b553c..596048388 100644 --- a/main/named_locks.c +++ b/main/named_locks.c @@ -87,8 +87,8 @@ static void named_locks_shutdown(void) int ast_named_locks_init(void) { - named_locks = ao2_container_alloc_hash(0, 0, NAMED_LOCKS_BUCKETS, named_locks_hash, NULL, - named_locks_cmp); + named_locks = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, + NAMED_LOCKS_BUCKETS, named_locks_hash, NULL, named_locks_cmp); if (!named_locks) { return -1; } diff --git a/main/taskprocessor.c b/main/taskprocessor.c index 0c429cf3f..bbf282c27 100644 --- a/main/taskprocessor.c +++ b/main/taskprocessor.c @@ -608,7 +608,7 @@ int ast_taskprocessor_alert_set_levels(struct ast_taskprocessor *tps, long low_w tps_alert_add(tps, -1); } } else { - if (high_water <= tps->tps_queue_size) { + if (high_water < tps->tps_queue_size) { /* Update water mark alert immediately */ tps->high_water_alert = 1; tps_alert_add(tps, +1); @@ -883,11 +883,11 @@ static int taskprocessor_push(struct ast_taskprocessor *tps, struct tps_task *t) AST_LIST_INSERT_TAIL(&tps->tps_queue, t, list); previous_size = tps->tps_queue_size++; - if (previous_size >= tps->tps_queue_high) { + if (tps->tps_queue_high <= tps->tps_queue_size) { if (!tps->high_water_warned) { tps->high_water_warned = 1; - ast_log(LOG_WARNING, "The '%s' task processor queue reached %d scheduled tasks.\n", - tps->name, previous_size); + ast_log(LOG_WARNING, "The '%s' task processor queue reached %ld scheduled tasks.\n", + tps->name, tps->tps_queue_size); } if (!tps->high_water_alert) { tps->high_water_alert = 1; diff --git a/res/res_pjsip/config_global.c b/res/res_pjsip/config_global.c index 8a1b0d449..975c5eefe 100644 --- a/res/res_pjsip/config_global.c +++ b/res/res_pjsip/config_global.c @@ -118,6 +118,18 @@ static int global_apply(const struct ast_sorcery *sorcery, void *obj) struct global_config *cfg = obj; char max_forwards[10]; + if (ast_strlen_zero(cfg->debug)) { + ast_log(LOG_ERROR, + "Global option 'debug' can't be empty. Set it to a valid value or remove the entry to accept 'no' as the default\n"); + return -1; + } + + if (ast_strlen_zero(cfg->default_from_user)) { + ast_log(LOG_ERROR, + "Global option 'default_from_user' can't be empty. Set it to a valid value or remove the entry to accept 'asterisk' as the default\n"); + return -1; + } + snprintf(max_forwards, sizeof(max_forwards), "%u", cfg->max_forwards); ast_sip_add_global_request_header("Max-Forwards", max_forwards, 1); 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; } diff --git a/res/res_pjsip_caller_id.c b/res/res_pjsip_caller_id.c index efa1b89a8..4d9f09237 100644 --- a/res/res_pjsip_caller_id.c +++ b/res/res_pjsip_caller_id.c @@ -413,7 +413,7 @@ static pjsip_fromto_hdr *create_new_id_hdr(const pj_str_t *hdr_name, pjsip_fromt id_hdr = pjsip_from_hdr_create(tdata->pool); id_hdr->type = PJSIP_H_OTHER; pj_strdup(tdata->pool, &id_hdr->name, hdr_name); - id_hdr->sname.slen = 0; + id_hdr->sname = id_hdr->name; id_name_addr = pjsip_uri_clone(tdata->pool, base->uri); id_uri = pjsip_uri_get_uri(id_name_addr->uri); diff --git a/res/res_pjsip_diversion.c b/res/res_pjsip_diversion.c index 41e6c821a..99d18da44 100644 --- a/res/res_pjsip_diversion.c +++ b/res/res_pjsip_diversion.c @@ -305,7 +305,7 @@ static void add_diversion_header(pjsip_tx_data *tdata, struct ast_party_redirect hdr = pjsip_from_hdr_create(tdata->pool); hdr->type = PJSIP_H_OTHER; pj_strdup(tdata->pool, &hdr->name, &diversion_name); - hdr->sname.slen = 0; + hdr->sname = hdr->name; name_addr = pjsip_uri_clone(tdata->pool, base); uri = pjsip_uri_get_uri(name_addr->uri); diff --git a/res/res_pjsip_mwi.c b/res/res_pjsip_mwi.c index 9553cd732..fb6e6b8f6 100644 --- a/res/res_pjsip_mwi.c +++ b/res/res_pjsip_mwi.c @@ -748,7 +748,6 @@ static int endpoint_receives_unsolicited_mwi_for_mailbox(struct ast_sip_endpoint int ret = 0; mwi_subs = ao2_find(unsolicited_mwi, endpoint_id, OBJ_SEARCH_KEY | OBJ_MULTIPLE); - if (!mwi_subs) { return 0; } @@ -1089,7 +1088,7 @@ static void mwi_stasis_cb(void *userdata, struct stasis_subscription *sub, } } -/*! \note Called with the unsolicited_mwi conainer lock held. */ +/*! \note Called with the unsolicited_mwi container lock held. */ static int create_mwi_subscriptions_for_endpoint(void *obj, void *arg, int flags) { RAII_VAR(struct mwi_subscription *, aggregate_sub, NULL, ao2_cleanup); @@ -1212,7 +1211,8 @@ static void mwi_contact_added(const void *object) ao2_lock(unsolicited_mwi); - mwi_subs = ao2_find(unsolicited_mwi, endpoint_id, OBJ_SEARCH_KEY | OBJ_MULTIPLE | OBJ_NOLOCK | OBJ_UNLINK); + mwi_subs = ao2_find(unsolicited_mwi, endpoint_id, + OBJ_SEARCH_KEY | OBJ_MULTIPLE | OBJ_NOLOCK | OBJ_UNLINK); if (mwi_subs) { for (; (mwi_sub = ao2_iterator_next(mwi_subs)); ao2_cleanup(mwi_sub)) { unsubscribe(mwi_sub, NULL, 0); @@ -1288,17 +1288,19 @@ static int load_module(void) return AST_MODULE_LOAD_DECLINE; } - unsolicited_mwi = ao2_container_alloc(MWI_BUCKETS, mwi_sub_hash, mwi_sub_cmp); - if (!unsolicited_mwi) { - ast_sip_unregister_subscription_handler(&mwi_handler); - return AST_MODULE_LOAD_DECLINE; - } - if (mwi_serializer_pool_setup()) { ast_log(AST_LOG_WARNING, "Failed to create MWI serializer pool. The default SIP pool will be used for MWI\n"); } + unsolicited_mwi = ao2_container_alloc_hash(AO2_ALLOC_OPT_LOCK_MUTEX, 0, MWI_BUCKETS, + mwi_sub_hash, NULL, mwi_sub_cmp); + if (!unsolicited_mwi) { + mwi_serializer_pool_shutdown(); + ast_sip_unregister_subscription_handler(&mwi_handler); + return AST_MODULE_LOAD_DECLINE; + } create_mwi_subscriptions(); + ast_sorcery_observer_add(ast_sip_get_sorcery(), "contact", &mwi_contact_observer); ast_sorcery_observer_add(ast_sip_get_sorcery(), "global", &global_observer); ast_sorcery_reload_object(ast_sip_get_sorcery(), "global"); @@ -1316,13 +1318,19 @@ static int load_module(void) static int unload_module(void) { + ast_sorcery_observer_remove(ast_sip_get_sorcery(), "global", &global_observer); + ast_sorcery_observer_remove(ast_sip_get_sorcery(), "contact", &mwi_contact_observer); + ao2_callback(unsolicited_mwi, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe, NULL); ao2_ref(unsolicited_mwi, -1); + unsolicited_mwi = NULL; + mwi_serializer_pool_shutdown(); - ast_sorcery_observer_remove(ast_sip_get_sorcery(), "global", &global_observer); - ast_sorcery_observer_remove(ast_sip_get_sorcery(), "contact", &mwi_contact_observer); + ast_sip_unregister_subscription_handler(&mwi_handler); + ast_free(default_voicemail_extension); + default_voicemail_extension = NULL; return 0; } diff --git a/res/res_pjsip_registrar.c b/res/res_pjsip_registrar.c index aef0e164b..53209575f 100644 --- a/res/res_pjsip_registrar.c +++ b/res/res_pjsip_registrar.c @@ -525,12 +525,12 @@ static int register_aor(pjsip_rx_data *rdata, struct ao2_container *contacts = NULL; struct ast_named_lock *lock; - lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_RWLOCK, "aor", aor_name); + lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "aor", aor_name); if (!lock) { return PJ_TRUE; } - ao2_wrlock(lock); + ao2_lock(lock); contacts = ast_sip_location_retrieve_aor_contacts_nolock(aor); if (!contacts) { ao2_unlock(lock); diff --git a/res/res_pjsip_registrar_expire.c b/res/res_pjsip_registrar_expire.c index 0fddbda91..aeefc3fbc 100644 --- a/res/res_pjsip_registrar_expire.c +++ b/res/res_pjsip_registrar_expire.c @@ -44,7 +44,7 @@ static int expire_contact(void *obj, void *arg, int flags) struct ast_sip_contact *contact = obj; struct ast_named_lock *lock; - lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_RWLOCK, "aor", contact->aor); + lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_MUTEX, "aor", contact->aor); if (!lock) { return 0; } @@ -53,7 +53,7 @@ static int expire_contact(void *obj, void *arg, int flags) * We need to check the expiration again with the aor lock held * in case another thread is attempting to renew the contact. */ - ao2_wrlock(lock); + ao2_lock(lock); if (ast_tvdiff_ms(ast_tvnow(), contact->expiration_time) > 0) { ast_sip_location_delete_contact(contact); } |