diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c index af69be30334a4139acef676f4112b64594cea51a..5806b997d7e68fc13131a7cb4bf2f47508bcd27f 100644 --- a/apps/app_chanspy.c +++ b/apps/app_chanspy.c @@ -557,13 +557,14 @@ static void publish_chanspy_message(struct ast_channel *spyer, RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref); RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); + struct stasis_message_type *type = start ? ast_channel_chanspy_start_type(): ast_channel_chanspy_stop_type(); if (!spyer) { ast_log(AST_LOG_WARNING, "Attempt to publish ChanSpy message for NULL spyer channel\n"); return; } blob = ast_json_null(); - if (!blob) { + if (!blob || !type) { return; } @@ -582,9 +583,7 @@ static void publish_chanspy_message(struct ast_channel *spyer, } } - message = stasis_message_create( - start ? ast_channel_chanspy_start_type(): ast_channel_chanspy_stop_type(), - payload); + message = stasis_message_create(type, payload); if (!message) { return; } diff --git a/apps/app_forkcdr.c b/apps/app_forkcdr.c index 932e862e1ad3c2b6aa9319052ce6c02a6c13d088..bbd15881a5e0147d0ab7def527aec12b615ac70d 100644 --- a/apps/app_forkcdr.c +++ b/apps/app_forkcdr.c @@ -136,7 +136,7 @@ static void forkcdr_callback(void *data, struct stasis_subscription *sub, struct static int forkcdr_exec(struct ast_channel *chan, const char *data) { RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); - RAII_VAR(struct fork_cdr_message_payload *, payload, ao2_alloc(sizeof(*payload), NULL), ao2_cleanup); + RAII_VAR(struct fork_cdr_message_payload *, payload, NULL, ao2_cleanup); RAII_VAR(struct stasis_message_router *, router, ast_cdr_message_router(), ao2_cleanup); char *parse; @@ -153,6 +153,13 @@ static int forkcdr_exec(struct ast_channel *chan, const char *data) ast_app_parse_options(forkcdr_exec_options, &flags, NULL, args.options); } + if (!forkcdr_message_type()) { + ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: no message type\n", + ast_channel_name(chan)); + return -1; + } + + payload = ao2_alloc(sizeof(*payload), NULL); if (!payload) { return -1; } diff --git a/apps/app_queue.c b/apps/app_queue.c index b0c81df38ab5ff024d7ab4a5a64045b92fc28335..012f04a710032d3758223607ce08493c223e88c8 100644 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -2066,6 +2066,10 @@ static void queue_publish_multi_channel_snapshot_blob(struct stasis_topic *topic RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); + if (!type) { + return; + } + payload = ast_multi_channel_blob_create(blob); if (!payload) { return; @@ -2122,7 +2126,7 @@ static void queue_publish_member_blob(struct stasis_message_type *type, struct a RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); - if (!blob) { + if (!blob || !type) { return; } diff --git a/configs/samples/stasis.conf.sample b/configs/samples/stasis.conf.sample new file mode 100644 index 0000000000000000000000000000000000000000..3aac230cbb7580b5fb9441e089d25d0487935872 --- /dev/null +++ b/configs/samples/stasis.conf.sample @@ -0,0 +1,122 @@ +[declined_message_types] +; This config section contains the names of message types that should be prevented +; from being created. By default, all message types are allowed to be created. +; +; Using this functionality requires knowledge of the names of internal stasis +; message types which is generally the same as the name of the accessor function. +; +; Use of this functionality may break more complex functionality in Asterisk +; such as CEL, CDR, transfers, etc. and will likely cause related messages in ARI +; and AMI to go missing. +; decline=stasis_app_recording_snapshot_type +; decline=stasis_app_playback_snapshot_type +; decline=stasis_test_message_type +; decline=confbridge_start_type +; decline=confbridge_end_type +; decline=confbridge_join_type +; decline=confbridge_leave_type +; decline=confbridge_start_record_type +; decline=confbridge_stop_record_type +; decline=confbridge_mute_type +; decline=confbridge_unmute_type +; decline=confbridge_talking_type +; decline=cel_generic_type +; decline=ast_bridge_snapshot_type +; decline=ast_bridge_merge_message_type +; decline=ast_channel_entered_bridge_type +; decline=ast_channel_left_bridge_type +; decline=ast_blind_transfer_type +; decline=ast_attended_transfer_type +; decline=ast_endpoint_snapshot_type +; decline=ast_endpoint_state_type +; decline=ast_device_state_message_type +; decline=ast_test_suite_message_type +; decline=ast_mwi_state_type +; decline=ast_mwi_vm_app_type +; decline=ast_format_register_type +; decline=ast_format_unregister_type +; decline=ast_manager_get_generic_type +; decline=ast_parked_call_type +; decline=ast_channel_snapshot_type +; decline=ast_channel_dial_type +; decline=ast_channel_varset_type +; decline=ast_channel_hangup_request_type +; decline=ast_channel_dtmf_begin_type +; decline=ast_channel_dtmf_end_type +; decline=ast_channel_hold_type +; decline=ast_channel_unhold_type +; decline=ast_channel_chanspy_start_type +; decline=ast_channel_chanspy_stop_type +; decline=ast_channel_fax_type +; decline=ast_channel_hangup_handler_type +; decline=ast_channel_moh_start_type +; decline=ast_channel_moh_stop_type +; decline=ast_channel_monitor_start_type +; decline=ast_channel_monitor_stop_type +; decline=ast_channel_agent_login_type +; decline=ast_channel_agent_logoff_type +; decline=ast_channel_talking_start +; decline=ast_channel_talking_stop +; decline=ast_security_event_type +; decline=ast_named_acl_change_type +; decline=ast_local_bridge_type +; decline=ast_local_optimization_begin_type +; decline=ast_local_optimization_end_type +; decline=stasis_subscription_change_type +; decline=ast_multi_user_event_type +; decline=stasis_cache_clear_type +; decline=stasis_cache_update_type +; decline=ast_network_change_type +; decline=ast_system_registry_type +; decline=ast_cc_available_type +; decline=ast_cc_offertimerstart_type +; decline=ast_cc_requested_type +; decline=ast_cc_requestacknowledged_type +; decline=ast_cc_callerstopmonitoring_type +; decline=ast_cc_callerstartmonitoring_type +; decline=ast_cc_callerrecalling_type +; decline=ast_cc_recallcomplete_type +; decline=ast_cc_failure_type +; decline=ast_cc_monitorfailed_type +; decline=ast_presence_state_message_type +; decline=ast_rtp_rtcp_sent_type +; decline=ast_rtp_rtcp_received_type +; decline=ast_call_pickup_type +; decline=aoc_s_type +; decline=aoc_d_type +; decline=aoc_e_type +; decline=dahdichannel_type +; decline=mcid_type +; decline=session_timeout_type +; decline=cdr_read_message_type +; decline=cdr_write_message_type +; decline=cdr_prop_write_message_type +; decline=corosync_ping_message_type +; decline=agi_exec_start_type +; decline=agi_exec_end_type +; decline=agi_async_start_type +; decline=agi_async_exec_type +; decline=agi_async_end_type +; decline=queue_caller_join_type +; decline=queue_caller_leave_type +; decline=queue_caller_abandon_type +; decline=queue_member_status_type +; decline=queue_member_added_type +; decline=queue_member_removed_type +; decline=queue_member_pause_type +; decline=queue_member_penalty_type +; decline=queue_member_ringinuse_type +; decline=queue_agent_called_type +; decline=queue_agent_connect_type +; decline=queue_agent_complete_type +; decline=queue_agent_dump_type +; decline=queue_agent_ringnoanswer_type +; decline=meetme_join_type +; decline=meetme_leave_type +; decline=meetme_end_type +; decline=meetme_mute_type +; decline=meetme_talking_type +; decline=meetme_talk_request_type +; decline=appcdr_message_type +; decline=forkcdr_message_type +; decline=cdr_sync_message_type diff --git a/funcs/func_cdr.c b/funcs/func_cdr.c index 44ecf4d6b4106a2d553d6c9f2d15ce3725d958a7..c9fce23d2d0b629d0626a4ac947daf2019555c73 100644 --- a/funcs/func_cdr.c +++ b/funcs/func_cdr.c @@ -437,8 +437,7 @@ static int cdr_read(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len) { RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); - RAII_VAR(struct cdr_func_payload *, payload, - ao2_alloc(sizeof(*payload), NULL), ao2_cleanup); + RAII_VAR(struct cdr_func_payload *, payload, NULL, ao2_cleanup); struct cdr_func_data output = { 0, }; if (!chan) { @@ -446,6 +445,13 @@ static int cdr_read(struct ast_channel *chan, const char *cmd, char *parse, return -1; } + if (!cdr_read_message_type()) { + ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n", + ast_channel_name(chan)); + return -1; + } + + payload = ao2_alloc(sizeof(*payload), NULL); if (!payload) { return -1; } @@ -489,8 +495,7 @@ static int cdr_write(struct ast_channel *chan, const char *cmd, char *parse, const char *value) { RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); - RAII_VAR(struct cdr_func_payload *, payload, - ao2_alloc(sizeof(*payload), NULL), ao2_cleanup); + RAII_VAR(struct cdr_func_payload *, payload, NULL, ao2_cleanup); RAII_VAR(struct stasis_message_router *, router, ast_cdr_message_router(), ao2_cleanup); @@ -505,6 +510,13 @@ static int cdr_write(struct ast_channel *chan, const char *cmd, char *parse, return -1; } + if (!cdr_write_message_type()) { + ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n", + ast_channel_name(chan)); + return -1; + } + + payload = ao2_alloc(sizeof(*payload), NULL); if (!payload) { return -1; } @@ -543,6 +555,13 @@ static int cdr_prop_write(struct ast_channel *chan, const char *cmd, char *parse return -1; } + if (!cdr_write_message_type()) { + ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n", + ast_channel_name(chan)); + return -1; + } + + payload = ao2_alloc(sizeof(*payload), NULL); if (!payload) { return -1; } diff --git a/include/asterisk/stasis.h b/include/asterisk/stasis.h index 4c4052c144f80b1e512578f0384f897ed5891266..b8dc4c84576475b2005e7e6f7e3b09a56d099f4f 100644 --- a/include/asterisk/stasis.h +++ b/include/asterisk/stasis.h @@ -273,6 +273,15 @@ struct stasis_message_vtable { struct stasis_message *message); }; +/*! + * \brief Return code for Stasis message type creation attempts + */ +enum stasis_message_type_result { + STASIS_MESSAGE_TYPE_ERROR = -1, /*!< Message type was not created due to allocation failure */ + STASIS_MESSAGE_TYPE_SUCCESS, /*!< Message type was created successfully */ + STASIS_MESSAGE_TYPE_DECLINED, /*!< Message type was not created due to configuration */ +}; + /*! * \brief Create a new message type. * @@ -281,12 +290,15 @@ struct stasis_message_vtable { * * \param name Name of the new type. * \param vtable Virtual table of message methods. May be \c NULL. - * \return Pointer to the new type. - * \return \c NULL on error. + * \param[out] result The location where the new message type will be placed + * + * \note Stasis message type creation may be declined if the message type is disabled + * + * \returns A stasis_message_type_result enum * \since 12 */ -struct stasis_message_type *stasis_message_type_create(const char *name, - struct stasis_message_vtable *vtable); +enum stasis_message_type_result stasis_message_type_create(const char *name, + struct stasis_message_vtable *vtable, struct stasis_message_type **result); /*! * \brief Gets the name of a given message type @@ -297,6 +309,16 @@ struct stasis_message_type *stasis_message_type_create(const char *name, */ const char *stasis_message_type_name(const struct stasis_message_type *type); +/*! + * \brief Check whether a message type is declined + * + * \param name The name of the message type to check + * + * \retval zero The message type is not declined + * \retval non-zero The message type is declined + */ +int stasis_message_type_declined(const char *name); + /*! * \brief Create a new message. * @@ -1184,9 +1206,8 @@ void stasis_log_bad_type_access(const char *name); #define STASIS_MESSAGE_TYPE_INIT(name) \ ({ \ ast_assert(_priv_ ## name == NULL); \ - _priv_ ## name = stasis_message_type_create(#name, \ - &_priv_ ## name ## _v); \ - _priv_ ## name ? 0 : -1; \ + stasis_message_type_create(#name, \ + &_priv_ ## name ## _v, &_priv_ ## name) == STASIS_MESSAGE_TYPE_ERROR ? 1 : 0; \ }) /*! diff --git a/main/app.c b/main/app.c index fa7c3ece138a4f04d1407463179d1a49d6592943..89889c65f21617cdce61e780384b9d9d5839a18d 100644 --- a/main/app.c +++ b/main/app.c @@ -3104,6 +3104,10 @@ static struct stasis_message *mwi_state_create_message( struct ast_mwi_state *mwi_state; struct stasis_message *message; + if (!ast_mwi_state_type()) { + return NULL; + } + mwi_state = ast_mwi_create(mailbox, context); if (!mwi_state) { return NULL; @@ -3247,6 +3251,10 @@ struct stasis_message *ast_mwi_blob_create(struct ast_mwi_state *mwi_state, ast_assert(blob != NULL); + if (!message_type) { + return NULL; + } + obj = ao2_alloc(sizeof(*obj), mwi_blob_dtor); if (!obj) { return NULL; diff --git a/main/bridge.c b/main/bridge.c index 63086e16ee022a2efffb25d66d0588abf259dfdd..462676ca844e437a430a116ff65c5c25e72cd7bb 100644 --- a/main/bridge.c +++ b/main/bridge.c @@ -615,6 +615,10 @@ static struct stasis_message *create_bridge_snapshot_message(struct ast_bridge * { RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup); + if (!ast_bridge_snapshot_type()) { + return NULL; + } + ast_bridge_lock(bridge); snapshot = ast_bridge_snapshot_create(bridge); ast_bridge_unlock(bridge); diff --git a/main/ccss.c b/main/ccss.c index 9fcabfefd6fbc5c528de1cb50b278f179f0d8750..3626f3d38b9cb21bacd6a3f0d5823cf5792773d3 100644 --- a/main/ccss.c +++ b/main/ccss.c @@ -1032,8 +1032,15 @@ static int cc_publish(struct stasis_message_type *message_type, int core_id, str RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); + if (!message_type) { + return -1; + } + blob = ast_json_pack("{s: i}", "core_id", core_id); + if (!blob) { + return -1; + } if (extras) { ast_json_object_update(blob, extras); diff --git a/main/cdr.c b/main/cdr.c index 17fa8a25fafb00e3a7ae1d2cb492e56c01ecf40d..2aaef88626c753d48442fc7d602d919f79f7e647 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -4198,7 +4198,7 @@ int ast_cdr_engine_init(void) void ast_cdr_engine_term(void) { RAII_VAR(struct module_config *, mod_cfg, ao2_global_obj_ref(module_configs), ao2_cleanup); - RAII_VAR(void *, payload, ao2_alloc(sizeof(*payload), NULL), ao2_cleanup); + RAII_VAR(void *, payload, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); /* Since this is called explicitly during process shutdown, we might not have ever @@ -4208,16 +4208,19 @@ void ast_cdr_engine_term(void) return; } - /* Make sure we have the needed items */ - if (!stasis_router || !payload) { - return; - } + if (cdr_sync_message_type()) { + /* Make sure we have the needed items */ + payload = ao2_alloc(sizeof(*payload), NULL); + if (!stasis_router || !payload) { + return; + } - ast_debug(1, "CDR Engine termination request received; waiting on messages...\n"); + ast_debug(1, "CDR Engine termination request received; waiting on messages...\n"); - message = stasis_message_create(cdr_sync_message_type(), payload); - if (message) { - stasis_message_router_publish_sync(stasis_router, message); + message = stasis_message_create(cdr_sync_message_type(), payload); + if (message) { + stasis_message_router_publish_sync(stasis_router, message); + } } if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) { diff --git a/main/channel.c b/main/channel.c index 6a252a6991cab4899de431459e74d3048cd35c26..23799d9be810a62e7db622d950a9b144440935d9 100644 --- a/main/channel.c +++ b/main/channel.c @@ -678,6 +678,11 @@ int ast_str2cause(const char *name) static struct stasis_message *create_channel_snapshot_message(struct ast_channel *channel) { RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); + + if (!ast_channel_snapshot_type()) { + return NULL; + } + ast_channel_lock(channel); snapshot = ast_channel_snapshot_create(channel); ast_channel_unlock(channel); diff --git a/main/core_local.c b/main/core_local.c index e1b66d0a736d04c277927dccd9f49a5df70e2aa9..54915ecfe2fecd0437bb1a2c7e1db5d6382633a3 100644 --- a/main/core_local.c +++ b/main/core_local.c @@ -357,6 +357,10 @@ static void local_optimization_started_cb(struct ast_unreal_pvt *base, struct as RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); struct local_pvt *p = (struct local_pvt *)base; + if (!ast_local_optimization_begin_type()) { + return; + } + json_object = ast_json_pack("{s: i, s: i}", "dest", dest, "id", id); @@ -395,6 +399,10 @@ static void local_optimization_finished_cb(struct ast_unreal_pvt *base, int succ RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); struct local_pvt *p = (struct local_pvt *)base; + if (!ast_local_optimization_end_type()) { + return; + } + json_object = ast_json_pack("{s: i, s: i}", "success", success, "id", id); if (!json_object) { @@ -501,6 +509,10 @@ static void publish_local_bridge_message(struct local_pvt *p) struct ast_channel *owner; struct ast_channel *chan; + if (!ast_local_bridge_type()) { + return; + } + ast_unreal_lock_all(&p->base, &chan, &owner); blob = ast_json_pack("{s: s, s: s, s: b}", diff --git a/main/devicestate.c b/main/devicestate.c index c4a57dd685788fcf3a677aa75aeda8b1a9aed07e..7f9136da39a63ca4d0cc1e48e5ce1131a4fc9791 100644 --- a/main/devicestate.c +++ b/main/devicestate.c @@ -721,6 +721,10 @@ int ast_publish_device_state_full( ast_assert(!ast_strlen_zero(device)); + if (!ast_device_state_message_type()) { + return -1; + } + device_state = device_state_alloc(device, state, cachable, eid); if (!device_state) { return -1; @@ -807,6 +811,10 @@ static struct stasis_message *device_state_aggregate_calc(struct stasis_cache_en struct ast_devstate_aggregate aggregate; int idx; + if (!ast_device_state_message_type()) { + return NULL; + } + /* Determine the new aggregate device state. */ ast_devstate_aggregate_init(&aggregate); snapshot = stasis_cache_entry_get_local(entry); diff --git a/main/endpoints.c b/main/endpoints.c index 07687eecc5066f515f6b1fe009870aa3d54b2968..cc2eccc705ee6b1eff3e3d8cc78b269b1d90b2dc 100644 --- a/main/endpoints.c +++ b/main/endpoints.c @@ -174,6 +174,10 @@ static void endpoint_publish_snapshot(struct ast_endpoint *endpoint) ast_assert(endpoint != NULL); ast_assert(endpoint->topics != NULL); + if (!ast_endpoint_snapshot_type()) { + return; + } + snapshot = ast_endpoint_snapshot_create(endpoint); if (!snapshot) { return; @@ -349,6 +353,11 @@ struct ast_endpoint *ast_endpoint_create(const char *tech, const char *resource) static struct stasis_message *create_endpoint_snapshot_message(struct ast_endpoint *endpoint) { RAII_VAR(struct ast_endpoint_snapshot *, snapshot, NULL, ao2_cleanup); + + if (!ast_endpoint_snapshot_type()) { + return NULL; + } + snapshot = ast_endpoint_snapshot_create(endpoint); if (!snapshot) { return NULL; diff --git a/main/file.c b/main/file.c index fa4c63bd95a624f3d2dae306d91884c83f81c3dc..59d39df8fd598bcc8e7e652a6716a455d51e0d2e 100644 --- a/main/file.c +++ b/main/file.c @@ -97,6 +97,10 @@ static int publish_format_update(const struct ast_format_def *f, struct stasis_m RAII_VAR(struct ast_json_payload *, json_payload, NULL, ao2_cleanup); RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref); + if (!type) { + return -1; + } + json_object = ast_json_pack("{s: s, s: o}", "format", f->name, "extensions", json_array_from_list(f->exts, "|")); diff --git a/main/loader.c b/main/loader.c index b4eef13c284eba8b7064960ed1a50e29c8dd04a6..ac17ddc9e78a4d946de8e586512234e60f09b793 100644 --- a/main/loader.c +++ b/main/loader.c @@ -803,6 +803,10 @@ static void publish_reload_message(const char *name, enum ast_module_reload_resu RAII_VAR(struct ast_json *, event_object, NULL, ast_json_unref); char res_buffer[8]; + if (!ast_manager_get_generic_type()) { + return; + } + snprintf(res_buffer, sizeof(res_buffer), "%u", result); event_object = ast_json_pack("{s: s, s: s}", "Module", S_OR(name, "All"), diff --git a/main/manager.c b/main/manager.c index 7fa083ca9bf7d4022d1e52904de0aee9ec01f8fc..b4e927ffb8e20166a878898f72d30a3f4ef42675 100644 --- a/main/manager.c +++ b/main/manager.c @@ -1519,7 +1519,7 @@ void ast_manager_publish_event(const char *type, int class_type, struct ast_json RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); - if (!obj) { + if (!obj || !ast_manager_get_generic_type()) { return; } diff --git a/main/named_acl.c b/main/named_acl.c index f0b5c2894703b5dfaabbef2f58795da2327f9e62..deda260b7dbb2560476a99ccef0cca2224e00cc1 100644 --- a/main/named_acl.c +++ b/main/named_acl.c @@ -380,7 +380,7 @@ static int publish_acl_change(const char *name) RAII_VAR(struct ast_json_payload *, json_payload, NULL, ao2_cleanup); RAII_VAR(struct ast_json *, json_object, ast_json_object_create(), ast_json_unref); - if (!json_object) { + if (!json_object || !ast_named_acl_change_type()) { goto publish_failure; } diff --git a/main/pickup.c b/main/pickup.c index 5be0c03abecfc29112a1966879d3ac74884ec575..125ec9359cfcea9311380d3ce2fb633a617a84c4 100644 --- a/main/pickup.c +++ b/main/pickup.c @@ -282,6 +282,10 @@ static int send_call_pickup_stasis_message(struct ast_channel *picking_up, struc RAII_VAR(struct ast_multi_channel_blob *, pickup_payload, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); + if (!ast_call_pickup_type()) { + return -1; + } + if (!(pickup_payload = ast_multi_channel_blob_create(ast_json_null()))) { return -1; } diff --git a/main/presencestate.c b/main/presencestate.c index db947df3414ca8c0321114da6c1c530e18329923..07df7429d9510208e2a27704d01add3227ed8e1e 100644 --- a/main/presencestate.c +++ b/main/presencestate.c @@ -263,8 +263,13 @@ static void presence_state_event(const char *provider, const char *message) { RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); - RAII_VAR(struct ast_presence_state_message *, presence_state, presence_state_alloc(provider, state, subtype, message), ao2_cleanup); + RAII_VAR(struct ast_presence_state_message *, presence_state, NULL, ao2_cleanup); + if (!ast_presence_state_message_type()) { + return; + } + + presence_state = presence_state_alloc(provider, state, subtype, message); if (!presence_state) { return; } diff --git a/main/rtp_engine.c b/main/rtp_engine.c index 52be8b90e28549d3c2a1cbe9dea6a4c7a19e92cf..0c624ab61627f2111a3b7236705e7fab687208ea 100644 --- a/main/rtp_engine.c +++ b/main/rtp_engine.c @@ -1996,6 +1996,10 @@ void ast_rtp_publish_rtcp_message(struct ast_rtp_instance *rtp, RAII_VAR(struct rtcp_message_payload *, payload, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); + if (!message_type) { + return; + } + payload = ao2_alloc(sizeof(*payload), rtcp_message_payload_dtor); if (!payload || !report) { return; diff --git a/main/security_events.c b/main/security_events.c index f4dc6fc6d8a6aef26312503e7c0f0dc6f988cb0f..00a70fbec541b9f74ad05febc375a5088493ad7d 100644 --- a/main/security_events.c +++ b/main/security_events.c @@ -1127,8 +1127,11 @@ static int handle_security_event(const struct ast_security_event_common *sec) const struct ast_security_event_ie_type *ies; unsigned int i; - json_object = alloc_security_event_json_object(sec); + if (!ast_security_event_type()) { + return -1; + } + json_object = alloc_security_event_json_object(sec); if (!json_object) { return -1; } diff --git a/main/stasis.c b/main/stasis.c index 594ec5e99c9641ea0e29269f4ea419219cf3a5a7..d8e0e5afc8762efc30604e28f02d8bc6bffc266e 100644 --- a/main/stasis.c +++ b/main/stasis.c @@ -41,6 +41,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$"); #include "asterisk/stasis_channels.h" #include "asterisk/stasis_bridges.h" #include "asterisk/stasis_endpoints.h" +#include "asterisk/config_options.h" /*** DOCUMENTATION <managerEvent language="en_US" name="UserEvent"> @@ -60,6 +61,135 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$"); </see-also> </managerEventInstance> </managerEvent> + <configInfo name="stasis" language="en_US"> + <configFile name="stasis.conf"> + <configObject name="declined_message_types"> + <synopsis>Stasis message types for which to decline creation.</synopsis> + <configOption name="decline"> + <synopsis>The message type to decline.</synopsis> + <description> + <para>This configuration option defines the name of the Stasis + message type that Asterisk is forbidden from creating and can be + specified as many times as necessary to achieve the desired result.</para> + <enumlist> + <enum name="stasis_app_recording_snapshot_type" /> + <enum name="stasis_app_playback_snapshot_type" /> + <enum name="stasis_test_message_type" /> + <enum name="confbridge_start_type" /> + <enum name="confbridge_end_type" /> + <enum name="confbridge_join_type" /> + <enum name="confbridge_leave_type" /> + <enum name="confbridge_start_record_type" /> + <enum name="confbridge_stop_record_type" /> + <enum name="confbridge_mute_type" /> + <enum name="confbridge_unmute_type" /> + <enum name="confbridge_talking_type" /> + <enum name="cel_generic_type" /> + <enum name="ast_bridge_snapshot_type" /> + <enum name="ast_bridge_merge_message_type" /> + <enum name="ast_channel_entered_bridge_type" /> + <enum name="ast_channel_left_bridge_type" /> + <enum name="ast_blind_transfer_type" /> + <enum name="ast_attended_transfer_type" /> + <enum name="ast_endpoint_snapshot_type" /> + <enum name="ast_endpoint_state_type" /> + <enum name="ast_device_state_message_type" /> + <enum name="ast_test_suite_message_type" /> + <enum name="ast_mwi_state_type" /> + <enum name="ast_mwi_vm_app_type" /> + <enum name="ast_format_register_type" /> + <enum name="ast_format_unregister_type" /> + <enum name="ast_manager_get_generic_type" /> + <enum name="ast_parked_call_type" /> + <enum name="ast_channel_snapshot_type" /> + <enum name="ast_channel_dial_type" /> + <enum name="ast_channel_varset_type" /> + <enum name="ast_channel_hangup_request_type" /> + <enum name="ast_channel_dtmf_begin_type" /> + <enum name="ast_channel_dtmf_end_type" /> + <enum name="ast_channel_hold_type" /> + <enum name="ast_channel_unhold_type" /> + <enum name="ast_channel_chanspy_start_type" /> + <enum name="ast_channel_chanspy_stop_type" /> + <enum name="ast_channel_fax_type" /> + <enum name="ast_channel_hangup_handler_type" /> + <enum name="ast_channel_moh_start_type" /> + <enum name="ast_channel_moh_stop_type" /> + <enum name="ast_channel_monitor_start_type" /> + <enum name="ast_channel_monitor_stop_type" /> + <enum name="ast_channel_agent_login_type" /> + <enum name="ast_channel_agent_logoff_type" /> + <enum name="ast_channel_talking_start" /> + <enum name="ast_channel_talking_stop" /> + <enum name="ast_security_event_type" /> + <enum name="ast_named_acl_change_type" /> + <enum name="ast_local_bridge_type" /> + <enum name="ast_local_optimization_begin_type" /> + <enum name="ast_local_optimization_end_type" /> + <enum name="stasis_subscription_change_type" /> + <enum name="ast_multi_user_event_type" /> + <enum name="stasis_cache_clear_type" /> + <enum name="stasis_cache_update_type" /> + <enum name="ast_network_change_type" /> + <enum name="ast_system_registry_type" /> + <enum name="ast_cc_available_type" /> + <enum name="ast_cc_offertimerstart_type" /> + <enum name="ast_cc_requested_type" /> + <enum name="ast_cc_requestacknowledged_type" /> + <enum name="ast_cc_callerstopmonitoring_type" /> + <enum name="ast_cc_callerstartmonitoring_type" /> + <enum name="ast_cc_callerrecalling_type" /> + <enum name="ast_cc_recallcomplete_type" /> + <enum name="ast_cc_failure_type" /> + <enum name="ast_cc_monitorfailed_type" /> + <enum name="ast_presence_state_message_type" /> + <enum name="ast_rtp_rtcp_sent_type" /> + <enum name="ast_rtp_rtcp_received_type" /> + <enum name="ast_call_pickup_type" /> + <enum name="aoc_s_type" /> + <enum name="aoc_d_type" /> + <enum name="aoc_e_type" /> + <enum name="dahdichannel_type" /> + <enum name="mcid_type" /> + <enum name="session_timeout_type" /> + <enum name="cdr_read_message_type" /> + <enum name="cdr_write_message_type" /> + <enum name="cdr_prop_write_message_type" /> + <enum name="corosync_ping_message_type" /> + <enum name="agi_exec_start_type" /> + <enum name="agi_exec_end_type" /> + <enum name="agi_async_start_type" /> + <enum name="agi_async_exec_type" /> + <enum name="agi_async_end_type" /> + <enum name="queue_caller_join_type" /> + <enum name="queue_caller_leave_type" /> + <enum name="queue_caller_abandon_type" /> + <enum name="queue_member_status_type" /> + <enum name="queue_member_added_type" /> + <enum name="queue_member_removed_type" /> + <enum name="queue_member_pause_type" /> + <enum name="queue_member_penalty_type" /> + <enum name="queue_member_ringinuse_type" /> + <enum name="queue_agent_called_type" /> + <enum name="queue_agent_connect_type" /> + <enum name="queue_agent_complete_type" /> + <enum name="queue_agent_dump_type" /> + <enum name="queue_agent_ringnoanswer_type" /> + <enum name="meetme_join_type" /> + <enum name="meetme_leave_type" /> + <enum name="meetme_end_type" /> + <enum name="meetme_mute_type" /> + <enum name="meetme_talking_type" /> + <enum name="meetme_talk_request_type" /> + <enum name="appcdr_message_type" /> + <enum name="forkcdr_message_type" /> + <enum name="cdr_sync_message_type" /> + </enumlist> + </description> + </configOption> + </configObject> + </configFile> + </configInfo> ***/ /*! @@ -801,6 +931,10 @@ static void send_subscription_subscribe(struct stasis_topic *topic, struct stasi /* This assumes that we have already unsubscribed */ ast_assert(stasis_subscription_is_subscribed(sub)); + if (!stasis_subscription_change_type()) { + return; + } + change = subscription_change_alloc(topic, sub->uniqueid, "Subscribe"); if (!change) { return; @@ -826,6 +960,10 @@ static void send_subscription_unsubscribe(struct stasis_topic *topic, /* This assumes that we have already unsubscribed */ ast_assert(!stasis_subscription_is_subscribed(sub)); + if (!stasis_subscription_change_type()) { + return; + } + change = subscription_change_alloc(topic, sub->uniqueid, "Unsubscribe"); if (!change) { return; @@ -1066,6 +1204,10 @@ void ast_multi_object_blob_single_channel_publish(struct ast_channel *chan, RAII_VAR(struct ast_channel_snapshot *, channel_snapshot, NULL, ao2_cleanup); RAII_VAR(struct ast_multi_object_blob *, multi, NULL, ao2_cleanup); + if (!type) { + return; + } + multi = ast_multi_object_blob_create(blob); if (!multi) { return; @@ -1215,6 +1357,113 @@ static struct ast_manager_event_blob *multi_user_event_to_ami( ast_str_buffer(body)); } +/*! \brief A structure to hold global configuration-related options */ +struct stasis_declined_config { + /*! The list of message types to decline */ + struct ao2_container *declined; +}; + + +struct stasis_config { + struct stasis_declined_config *declined_message_types; +}; + +/*! \brief An aco_type structure to link the "declined_message_types" category to the stasis_declined_config type */ +static struct aco_type declined_option = { + .type = ACO_GLOBAL, + .name = "declined_message_types", + .item_offset = offsetof(struct stasis_config, declined_message_types), + .category_match = ACO_WHITELIST, + .category = "^declined_message_types$", +}; + +struct aco_type *declined_options[] = ACO_TYPES(&declined_option); + +struct aco_file stasis_conf = { + .filename = "stasis.conf", + .types = ACO_TYPES(&declined_option), +}; + +/*! \brief A global object container that will contain the stasis_config that gets swapped out on reloads */ +static AO2_GLOBAL_OBJ_STATIC(globals); + +static void *stasis_config_alloc(void); + +/*! \brief Register information about the configs being processed by this module */ +CONFIG_INFO_CORE("stasis", cfg_info, globals, stasis_config_alloc, + .files = ACO_FILES(&stasis_conf), +); + +static void stasis_declined_config_destructor(void *obj) +{ + struct stasis_declined_config *declined = obj; + ao2_cleanup(declined->declined); +} + +static void stasis_config_destructor(void *obj) +{ + struct stasis_config *cfg = obj; + ao2_cleanup(cfg->declined_message_types); +} + +static void *stasis_config_alloc(void) +{ + struct stasis_config *cfg; + + if (!(cfg = ao2_alloc(sizeof(*cfg), stasis_config_destructor))) { + return NULL; + } + + /* Allocate/initialize memory */ + cfg->declined_message_types = ao2_alloc(sizeof(*cfg->declined_message_types), stasis_declined_config_destructor); + if (!cfg->declined_message_types) { + goto error; + } + + cfg->declined_message_types->declined = ast_str_container_alloc(13); + if (!cfg->declined_message_types->declined) { + goto error; + } + + return cfg; +error: + ao2_ref(cfg, -1); + return NULL; +} + +int stasis_message_type_declined(const char *name) +{ + RAII_VAR(struct stasis_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup); + char *name_in_declined; + int res; + + if (!cfg || !cfg->declined_message_types) { + return 0; + } + + name_in_declined = ao2_find(cfg->declined_message_types->declined, name, OBJ_SEARCH_KEY); + res = name_in_declined ? 1 : 0; + ao2_cleanup(name_in_declined); + if (res) { + ast_log(LOG_NOTICE, "Declining to allocate Stasis message type '%s' due to configuration\n", name); + } + return res; +} + +static int declined_handler(const struct aco_option *opt, struct ast_variable *var, void *obj) +{ + struct stasis_declined_config *declined = obj; + + if (ast_strlen_zero(var->value)) { + return 0; + } + + if (ast_str_container_add(declined->declined, var->value)) { + return -1; + } + + return 0; +} /*! * @{ \brief Define multi user event message type(s). @@ -1232,6 +1481,8 @@ static void stasis_cleanup(void) { STASIS_MESSAGE_TYPE_CLEANUP(stasis_subscription_change_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_multi_user_event_type); + aco_info_destroy(&cfg_info); + ao2_global_obj_release(globals); } int stasis_init(void) @@ -1241,6 +1492,24 @@ int stasis_init(void) /* Be sure the types are cleaned up after the message bus */ ast_register_cleanup(stasis_cleanup); + if (aco_info_init(&cfg_info)) { + return -1; + } + + aco_option_register_custom(&cfg_info, "decline", ACO_EXACT, declined_options, "", declined_handler, 0); + + if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) { + RAII_VAR(struct stasis_config *, stasis_cfg, stasis_config_alloc(), ao2_cleanup); + + if (aco_set_defaults(&declined_option, "declined_message_types", stasis_cfg->declined_message_types)) { + ast_log(LOG_ERROR, "Failed to load stasis.conf and failed to initialize defaults.\n"); + return -1; + } + + ast_log(LOG_NOTICE, "Could not load stasis config; using defaults\n"); + ao2_global_obj_replace_unref(globals, stasis_cfg); + } + cache_init = stasis_cache_init(); if (cache_init != 0) { return -1; diff --git a/main/stasis_bridges.c b/main/stasis_bridges.c index c5df5f4f9300a98dd31ac7ec5eb62e4287759340..56f7605f7580c1ea2e62791a0ee1cbe8e63a589f 100644 --- a/main/stasis_bridges.c +++ b/main/stasis_bridges.c @@ -267,6 +267,10 @@ void ast_bridge_publish_state(struct ast_bridge *bridge) RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); + if (!ast_bridge_snapshot_type()) { + return; + } + ast_assert(bridge != NULL); snapshot = ast_bridge_snapshot_create(bridge); @@ -358,6 +362,10 @@ void ast_bridge_publish_merge(struct ast_bridge *to, struct ast_bridge *from) RAII_VAR(struct ast_bridge_merge_message *, merge_msg, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); + if (!ast_bridge_merge_message_type()) { + return; + } + ast_assert(to != NULL); ast_assert(from != NULL); @@ -394,6 +402,10 @@ struct stasis_message *ast_bridge_blob_create( RAII_VAR(struct ast_bridge_blob *, obj, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); + if (!message_type) { + return NULL; + } + obj = ao2_alloc(sizeof(*obj), bridge_blob_dtor); if (!obj) { return NULL; @@ -958,6 +970,10 @@ void ast_bridge_publish_attended_transfer_fail(int is_external, enum ast_transfe RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); + if (!ast_attended_transfer_type()) { + return; + } + transfer_msg = attended_transfer_message_create(is_external, result, transferee, target); if (!transfer_msg) { return; @@ -980,6 +996,10 @@ void ast_bridge_publish_attended_transfer_bridge_merge(int is_external, enum ast RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); + if (!ast_attended_transfer_type()) { + return; + } + transfer_msg = attended_transfer_message_create(is_external, result, transferee, target); if (!transfer_msg) { return; @@ -1004,6 +1024,10 @@ void ast_bridge_publish_attended_transfer_threeway(int is_external, enum ast_tra RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); + if (!ast_attended_transfer_type()) { + return; + } + transfer_msg = attended_transfer_message_create(is_external, result, transferee, target); if (!transfer_msg) { return; @@ -1037,6 +1061,10 @@ void ast_bridge_publish_attended_transfer_app(int is_external, enum ast_transfer RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); + if (!ast_attended_transfer_type()) { + return; + } + transfer_msg = attended_transfer_message_create(is_external, result, transferee, target); if (!transfer_msg) { return; @@ -1061,6 +1089,10 @@ void ast_bridge_publish_attended_transfer_link(int is_external, enum ast_transfe RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); int i; + if (!ast_attended_transfer_type()) { + return; + } + transfer_msg = attended_transfer_message_create(is_external, result, transferee, target); if (!transfer_msg) { return; diff --git a/main/stasis_cache.c b/main/stasis_cache.c index 8b4304e5f4f3f1a8b61627820c09e161750db198..c492307d63aef631cf15ca299b31e177f5fa0e39 100644 --- a/main/stasis_cache.c +++ b/main/stasis_cache.c @@ -185,10 +185,13 @@ static struct stasis_cache_entry *cache_entry_create(struct stasis_message_type struct stasis_cache_entry *entry; int is_remote; - ast_assert(type != NULL); ast_assert(id != NULL); ast_assert(snapshot != NULL); + if (!type) { + return NULL; + } + entry = ao2_alloc_options(sizeof(*entry), cache_entry_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK); if (!entry) { @@ -550,9 +553,12 @@ struct ao2_container *stasis_cache_get_all(struct stasis_cache *cache, struct st ast_assert(cache != NULL); ast_assert(cache->entries != NULL); - ast_assert(type != NULL); ast_assert(id != NULL); + if (!type) { + return NULL; + } + found = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, NULL, NULL); if (!found) { return NULL; @@ -619,9 +625,12 @@ struct stasis_message *stasis_cache_get_by_eid(struct stasis_cache *cache, struc ast_assert(cache != NULL); ast_assert(cache->entries != NULL); - ast_assert(type != NULL); ast_assert(id != NULL); + if (!type) { + return NULL; + } + ao2_rdlock(cache->entries); cached_entry = cache_find(cache->entries, type, id); @@ -752,6 +761,10 @@ static struct stasis_message *update_create(struct stasis_message *old_snapshot, ast_assert(old_snapshot != NULL || new_snapshot != NULL); + if (!stasis_cache_update_type()) { + return NULL; + } + update = ao2_alloc_options(sizeof(*update), stasis_cache_update_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK); if (!update) { diff --git a/main/stasis_channels.c b/main/stasis_channels.c index a1e7ad20949d638f8b40e51373aada48901990b5..d7fbc98ab94f7adf3fcc2a5c1b19b2b8d4210d0d 100644 --- a/main/stasis_channels.c +++ b/main/stasis_channels.c @@ -304,6 +304,10 @@ void ast_channel_publish_dial_forward(struct ast_channel *caller, struct ast_cha RAII_VAR(struct ast_channel_snapshot *, peer_snapshot, NULL, ao2_cleanup); RAII_VAR(struct ast_channel_snapshot *, forwarded_snapshot, NULL, ao2_cleanup); + if (!ast_channel_dial_type()) { + return; + } + ast_assert(peer != NULL); blob = ast_json_pack("{s: s, s: s, s: s}", "dialstatus", S_OR(dialstatus, ""), @@ -405,9 +409,15 @@ struct stasis_message *ast_channel_blob_create_from_cache(const char *channel_id struct ast_json *blob) { RAII_VAR(struct ast_channel_snapshot *, snapshot, - ast_channel_snapshot_get_latest(channel_id), + NULL, ao2_cleanup); + if (!type) { + return NULL; + } + + snapshot = ast_channel_snapshot_get_latest(channel_id); + return create_channel_blob_message(snapshot, type, blob); } @@ -416,6 +426,10 @@ struct stasis_message *ast_channel_blob_create(struct ast_channel *chan, { RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); + if (!type) { + return NULL; + } + if (chan) { snapshot = ast_channel_snapshot_create(chan); } @@ -644,6 +658,10 @@ void ast_channel_publish_snapshot(struct ast_channel *chan) RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); + if (!ast_channel_snapshot_type()) { + return; + } + if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_SNAPSHOT_STAGE)) { return; } @@ -793,6 +811,10 @@ void ast_publish_channel_state(struct ast_channel *chan) RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); + if (!ast_channel_snapshot_type()) { + return; + } + ast_assert(chan != NULL); if (!chan) { return; diff --git a/main/stasis_endpoints.c b/main/stasis_endpoints.c index e3f5a3f15e57b8ade9ecb921f57ed7300951c6cb..73746817725cdbd19911dd0ffadb05b94d1710cc 100644 --- a/main/stasis_endpoints.c +++ b/main/stasis_endpoints.c @@ -150,6 +150,9 @@ struct stasis_message *ast_endpoint_blob_create(struct ast_endpoint *endpoint, RAII_VAR(struct ast_endpoint_blob *, obj, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); + if (!type) { + return NULL; + } if (!blob) { blob = ast_json_null(); } diff --git a/main/stasis_message.c b/main/stasis_message.c index 70c4085390cfa49b347e7a9ddcf4aaafb3802d1d..c797cdfa0509e6cf6c2b1201d695e2f8124cc502 100644 --- a/main/stasis_message.c +++ b/main/stasis_message.c @@ -50,14 +50,20 @@ static void message_type_dtor(void *obj) type->name = NULL; } -struct stasis_message_type *stasis_message_type_create(const char *name, - struct stasis_message_vtable *vtable) +int stasis_message_type_create(const char *name, + struct stasis_message_vtable *vtable, + struct stasis_message_type **result) { struct stasis_message_type *type; + /* Check for declination */ + if (name && stasis_message_type_declined(name)) { + return STASIS_MESSAGE_TYPE_DECLINED; + } + type = ao2_t_alloc(sizeof(*type), message_type_dtor, name); if (!type) { - return NULL; + return STASIS_MESSAGE_TYPE_ERROR; } if (!vtable) { /* Null object pattern, FTW! */ @@ -67,11 +73,12 @@ struct stasis_message_type *stasis_message_type_create(const char *name, type->name = ast_strdup(name); if (!type->name) { ao2_cleanup(type); - return NULL; + return STASIS_MESSAGE_TYPE_ERROR; } type->vtable = vtable; + *result = type; - return type; + return STASIS_MESSAGE_TYPE_SUCCESS; } const char *stasis_message_type_name(const struct stasis_message_type *type) diff --git a/main/stasis_system.c b/main/stasis_system.c index 2428a96c0767f37b53685dd93d933d6bfd67b0ec..e232b8e8a3d1cb4d53dad18da0ecde808c730ab0 100644 --- a/main/stasis_system.c +++ b/main/stasis_system.c @@ -122,6 +122,10 @@ void ast_system_publish_registry(const char *channeltype, const char *username, RAII_VAR(struct ast_json_payload *, payload, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); + if (!ast_system_registry_type()) { + return; + } + registry = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s}", "type", "registry", "channeltype", channeltype, diff --git a/main/test.c b/main/test.c index fe8fe153205ed30b07f732ac4157cb2a54f227e4..c144d3eb405242ab0dc0d5bfe57569c78b393959 100644 --- a/main/test.c +++ b/main/test.c @@ -1015,15 +1015,22 @@ struct ast_json *ast_test_suite_get_blob(struct ast_test_suite_message_payload * void __ast_test_suite_event_notify(const char *file, const char *func, int line, const char *state, const char *fmt, ...) { RAII_VAR(struct ast_test_suite_message_payload *, payload, - ao2_alloc(sizeof(*payload), test_suite_message_payload_dtor), + NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); - RAII_VAR(struct ast_str *, buf, ast_str_create(128), ast_free); + RAII_VAR(struct ast_str *, buf, NULL, ast_free); va_list ap; + if (!ast_test_suite_message_type()) { + return; + } + + buf = ast_str_create(128); if (!buf) { return; } + + payload = ao2_alloc(sizeof(*payload), test_suite_message_payload_dtor); if (!payload) { return; } diff --git a/pbx/pbx_realtime.c b/pbx/pbx_realtime.c index 641e30d95efd1a8ddd6c9832012ea1dd2c65c7f4..de62851e0feed250b3d945573827b0651343dea6 100644 --- a/pbx/pbx_realtime.c +++ b/pbx/pbx_realtime.c @@ -333,9 +333,11 @@ static int realtime_exec(struct ast_channel *chan, const char *context, const ch term_color(tmp1, app, COLOR_BRCYAN, 0, sizeof(tmp1)), term_color(tmp2, ast_channel_name(chan), COLOR_BRMAGENTA, 0, sizeof(tmp2)), term_color(tmp3, S_OR(appdata, ""), COLOR_BRMAGENTA, 0, sizeof(tmp3))); - ast_channel_lock(chan); - snapshot = ast_channel_snapshot_create(chan); - ast_channel_unlock(chan); + if (ast_channel_snapshot_type()) { + ast_channel_lock(chan); + snapshot = ast_channel_snapshot_create(chan); + ast_channel_unlock(chan); + } if (snapshot) { /* pbx_exec sets application name and data, but we don't want to log * every exec. Just update the snapshot here instead. diff --git a/res/parking/parking_manager.c b/res/parking/parking_manager.c index 20f8c4e1c80ad89d66fb58ebe7c48f69f701f86a..73b5ff49546fbacef04d1db6ba6696547d9fe99e 100644 --- a/res/parking/parking_manager.c +++ b/res/parking/parking_manager.c @@ -579,6 +579,10 @@ void publish_parked_call_failure(struct ast_channel *parkee) RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); + if (!ast_parked_call_type()) { + return; + } + payload = parked_call_payload_from_failure(parkee); if (!payload) { return; @@ -597,6 +601,10 @@ void publish_parked_call(struct parked_user *pu, enum ast_parked_call_event_type RAII_VAR(struct ast_parked_call_payload *, payload, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); + if (!ast_parked_call_type()) { + return; + } + payload = parked_call_payload_from_parked_user(pu, event_type); if (!payload) { return; diff --git a/res/res_corosync.c b/res/res_corosync.c index 1df9ed841165835993ffbbea630277e1d5f93458..58290c7ccf3d00cbe2ec11b79c9c9f9692a1376b 100644 --- a/res/res_corosync.c +++ b/res/res_corosync.c @@ -117,6 +117,10 @@ static void publish_corosync_ping_to_stasis(struct ast_event *event) ast_assert(ast_event_get_type(event) == AST_EVENT_PING); ast_assert(event != NULL); + if (!corosync_ping_message_type()) { + return; + } + payload = ao2_t_alloc(sizeof(*payload), corosync_ping_payload_dtor, "Create ping payload"); if (!payload) { return; diff --git a/res/res_stasis.c b/res/res_stasis.c index 7d5373153f2edef6662d94ac48d856a0f83cae16..7b5d16f1abd789683aa85539a84511314a313c5a 100644 --- a/res/res_stasis.c +++ b/res/res_stasis.c @@ -1357,6 +1357,10 @@ enum stasis_app_user_event_res stasis_app_user_event(const char *app_name, return STASIS_APP_USER_APP_NOT_FOUND; } + if (!ast_multi_user_event_type()) { + return res; + } + blob = json_variables; if (!blob) { blob = ast_json_pack("{}"); diff --git a/res/res_stasis_snoop.c b/res/res_stasis_snoop.c index af31046fca25f9231c51c6d922ab1f923418f4ad..72f8519230670ecee4abba5b2fe466ea5db2e9cd 100644 --- a/res/res_stasis_snoop.c +++ b/res/res_stasis_snoop.c @@ -111,9 +111,10 @@ static void publish_chanspy_message(struct stasis_app_snoop *snoop, int start) RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); RAII_VAR(struct ast_channel_snapshot *, snoop_snapshot, NULL, ao2_cleanup); RAII_VAR(struct ast_channel_snapshot *, spyee_snapshot, NULL, ao2_cleanup); + struct stasis_message_type *type = start ? ast_channel_chanspy_start_type(): ast_channel_chanspy_stop_type(); blob = ast_json_null(); - if (!blob) { + if (!blob || !type) { return; } @@ -133,9 +134,7 @@ static void publish_chanspy_message(struct stasis_app_snoop *snoop, int start) ast_multi_channel_blob_add_channel(payload, "spyee_channel", spyee_snapshot); } - message = stasis_message_create( - start ? ast_channel_chanspy_start_type(): ast_channel_chanspy_stop_type(), - payload); + message = stasis_message_create(type, payload); if (!message) { return; } diff --git a/res/res_stasis_test.c b/res/res_stasis_test.c index cec8e20c639bfcf30c0b6bf28bfed3aff3d1720f..9860b0ebd7f39dc2319628cacb0ea4d653becc6c 100644 --- a/res/res_stasis_test.c +++ b/res/res_stasis_test.c @@ -251,6 +251,10 @@ struct stasis_message *stasis_test_message_create(void) { RAII_VAR(void *, data, NULL, ao2_cleanup); + if (!stasis_test_message_type()) { + return NULL; + } + /* We just need the unique pointer; don't care what's in it */ data = ao2_alloc(1, NULL); if (!data) { diff --git a/res/res_stun_monitor.c b/res/res_stun_monitor.c index 1bda4b9ff9ff657de077e1b5f29400ee4d54c1d8..4cdc2fdca79292f4ca2e926649a39bc57b2c4829 100644 --- a/res/res_stun_monitor.c +++ b/res/res_stun_monitor.c @@ -157,10 +157,15 @@ static int stun_monitor_request(const void *blarg) if (args.external_addr_known) { RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); RAII_VAR(struct ast_json_payload *, json_payload, NULL, ao2_cleanup); - RAII_VAR(struct ast_json *, json_object, ast_json_object_create(), ast_json_unref); + RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref); + + if (!ast_network_change_type()) { + goto publish_failure; + } /* This json_object doesn't actually contain anything yet. We have to reference something * for stasis, and this is useful for if we want to ever add data for any reason. */ + json_object = ast_json_object_create(); if (!json_object) { goto publish_failure; } diff --git a/tests/test_stasis.c b/tests/test_stasis.c index 4c042c05be47df4cf0064fb03498910a14a2f80b..ba82e83adb06aa625d949bbb9834071d252f8ceb 100644 --- a/tests/test_stasis.c +++ b/tests/test_stasis.c @@ -84,8 +84,8 @@ AST_TEST_DEFINE(message_type) break; } - ast_test_validate(test, NULL == stasis_message_type_create(NULL, NULL)); - uut = stasis_message_type_create("SomeMessage", NULL); + ast_test_validate(test, stasis_message_type_create(NULL, NULL, NULL) == STASIS_MESSAGE_TYPE_ERROR); + ast_test_validate(test, stasis_message_type_create("SomeMessage", NULL, &uut) == STASIS_MESSAGE_TYPE_SUCCESS); ast_test_validate(test, 0 == strcmp(stasis_message_type_name(uut), "SomeMessage")); return AST_TEST_PASS; @@ -116,7 +116,7 @@ AST_TEST_DEFINE(message) memset(&foreign_eid, 0xFF, sizeof(foreign_eid)); - type = stasis_message_type_create("SomeMessage", NULL); + ast_test_validate(test, stasis_message_type_create("SomeMessage", NULL, &type) == STASIS_MESSAGE_TYPE_SUCCESS); ast_test_validate(test, NULL == stasis_message_create_full(NULL, NULL, NULL)); ast_test_validate(test, NULL == stasis_message_create_full(type, NULL, NULL)); @@ -395,7 +395,7 @@ AST_TEST_DEFINE(publish) test_data = ao2_alloc(1, NULL); ast_test_validate(test, NULL != test_data); - test_message_type = stasis_message_type_create("TestMessage", NULL); + ast_test_validate(test, stasis_message_type_create("TestMessage", NULL, &test_message_type) == STASIS_MESSAGE_TYPE_SUCCESS); test_message = stasis_message_create(test_message_type, test_data); stasis_publish(topic, test_message); @@ -442,7 +442,7 @@ AST_TEST_DEFINE(publish_sync) test_data = ao2_alloc(1, NULL); ast_test_validate(test, NULL != test_data); - test_message_type = stasis_message_type_create("TestMessage", NULL); + ast_test_validate(test, stasis_message_type_create("TestMessage", NULL, &test_message_type) == STASIS_MESSAGE_TYPE_SUCCESS); test_message = stasis_message_create(test_message_type, test_data); stasis_publish_sync(uut, test_message); @@ -490,7 +490,7 @@ AST_TEST_DEFINE(unsubscribe_stops_messages) test_data = ao2_alloc(1, NULL); ast_test_validate(test, NULL != test_data); - test_message_type = stasis_message_type_create("TestMessage", NULL); + ast_test_validate(test, stasis_message_type_create("TestMessage", NULL, &test_message_type) == STASIS_MESSAGE_TYPE_SUCCESS); test_message = stasis_message_create(test_message_type, test_data); stasis_publish(topic, test_message); @@ -554,7 +554,7 @@ AST_TEST_DEFINE(forward) test_data = ao2_alloc(1, NULL); ast_test_validate(test, NULL != test_data); - test_message_type = stasis_message_type_create("TestMessage", NULL); + ast_test_validate(test, stasis_message_type_create("TestMessage", NULL, &test_message_type) == STASIS_MESSAGE_TYPE_SUCCESS); test_message = stasis_message_create(test_message_type, test_data); stasis_publish(topic, test_message); @@ -604,7 +604,7 @@ AST_TEST_DEFINE(interleaving) break; } - test_message_type = stasis_message_type_create("test", NULL); + ast_test_validate(test, stasis_message_type_create("test", NULL, &test_message_type) == STASIS_MESSAGE_TYPE_SUCCESS); ast_test_validate(test, NULL != test_message_type); test_data = ao2_alloc(1, NULL); @@ -796,7 +796,7 @@ AST_TEST_DEFINE(cache_filter) break; } - non_cache_type = stasis_message_type_create("NonCacheable", NULL); + ast_test_validate(test, stasis_message_type_create("NonCacheable", NULL, &non_cache_type) == STASIS_MESSAGE_TYPE_SUCCESS); ast_test_validate(test, NULL != non_cache_type); topic = stasis_topic_create("SomeTopic"); ast_test_validate(test, NULL != topic); @@ -847,7 +847,7 @@ AST_TEST_DEFINE(cache) break; } - cache_type = stasis_message_type_create("Cacheable", NULL); + ast_test_validate(test, stasis_message_type_create("Cacheable", NULL, &cache_type) == STASIS_MESSAGE_TYPE_SUCCESS); ast_test_validate(test, NULL != cache_type); topic = stasis_topic_create("SomeTopic"); ast_test_validate(test, NULL != topic); @@ -948,7 +948,7 @@ AST_TEST_DEFINE(cache_dump) break; } - cache_type = stasis_message_type_create("Cacheable", NULL); + ast_test_validate(test, stasis_message_type_create("Cacheable", NULL, &cache_type) == STASIS_MESSAGE_TYPE_SUCCESS); ast_test_validate(test, NULL != cache_type); topic = stasis_topic_create("SomeTopic"); ast_test_validate(test, NULL != topic); @@ -1071,7 +1071,7 @@ AST_TEST_DEFINE(cache_eid_aggregate) memset(&foreign_eid1, 0xAA, sizeof(foreign_eid1)); memset(&foreign_eid2, 0xBB, sizeof(foreign_eid2)); - cache_type = stasis_message_type_create("Cacheable", NULL); + ast_test_validate(test, stasis_message_type_create("Cacheable", NULL, &cache_type) == STASIS_MESSAGE_TYPE_SUCCESS); ast_test_validate(test, NULL != cache_type); topic = stasis_topic_create("SomeTopic"); @@ -1331,11 +1331,11 @@ AST_TEST_DEFINE(router) consumer3 = consumer_create(1); ast_test_validate(test, NULL != consumer3); - test_message_type1 = stasis_message_type_create("TestMessage1", NULL); + ast_test_validate(test, stasis_message_type_create("TestMessage1", NULL, &test_message_type1) == STASIS_MESSAGE_TYPE_SUCCESS); ast_test_validate(test, NULL != test_message_type1); - test_message_type2 = stasis_message_type_create("TestMessage2", NULL); + ast_test_validate(test, stasis_message_type_create("TestMessage2", NULL, &test_message_type2) == STASIS_MESSAGE_TYPE_SUCCESS); ast_test_validate(test, NULL != test_message_type2); - test_message_type3 = stasis_message_type_create("TestMessage3", NULL); + ast_test_validate(test, stasis_message_type_create("TestMessage3", NULL, &test_message_type3) == STASIS_MESSAGE_TYPE_SUCCESS); ast_test_validate(test, NULL != test_message_type3); uut = stasis_message_router_create(topic); @@ -1448,11 +1448,11 @@ AST_TEST_DEFINE(router_cache_updates) consumer3 = consumer_create(1); ast_test_validate(test, NULL != consumer3); - test_message_type1 = stasis_message_type_create("Cache1", NULL); + ast_test_validate(test, stasis_message_type_create("Cache1", NULL, &test_message_type1) == STASIS_MESSAGE_TYPE_SUCCESS); ast_test_validate(test, NULL != test_message_type1); - test_message_type2 = stasis_message_type_create("Cache2", NULL); + ast_test_validate(test, stasis_message_type_create("Cache2", NULL, &test_message_type2) == STASIS_MESSAGE_TYPE_SUCCESS); ast_test_validate(test, NULL != test_message_type2); - test_message_type3 = stasis_message_type_create("NonCache", NULL); + ast_test_validate(test, stasis_message_type_create("NonCache", NULL, &test_message_type3) == STASIS_MESSAGE_TYPE_SUCCESS); ast_test_validate(test, NULL != test_message_type3); uut = stasis_message_router_create( @@ -1535,7 +1535,7 @@ AST_TEST_DEFINE(no_to_json) ast_test_validate(test, NULL == actual); /* Test message with NULL to_json function */ - type = stasis_message_type_create("SomeMessage", NULL); + ast_test_validate(test, stasis_message_type_create("SomeMessage", NULL, &type) == STASIS_MESSAGE_TYPE_SUCCESS); data = ao2_alloc(strlen(expected) + 1, NULL); strcpy(data, expected); @@ -1568,7 +1568,7 @@ AST_TEST_DEFINE(to_json) break; } - type = stasis_message_type_create("SomeMessage", &fake_vtable); + ast_test_validate(test, stasis_message_type_create("SomeMessage", &fake_vtable, &type) == STASIS_MESSAGE_TYPE_SUCCESS); data = ao2_alloc(strlen(expected_text) + 1, NULL); strcpy(data, expected_text); @@ -1606,7 +1606,7 @@ AST_TEST_DEFINE(no_to_ami) ast_test_validate(test, NULL == actual); /* Test message with NULL to_ami function */ - type = stasis_message_type_create("SomeMessage", NULL); + ast_test_validate(test, stasis_message_type_create("SomeMessage", NULL, &type) == STASIS_MESSAGE_TYPE_SUCCESS); data = ao2_alloc(strlen(expected) + 1, NULL); strcpy(data, expected); @@ -1639,7 +1639,7 @@ AST_TEST_DEFINE(to_ami) break; } - type = stasis_message_type_create("SomeMessage", &fake_vtable); + ast_test_validate(test, stasis_message_type_create("SomeMessage", &fake_vtable, &type) == STASIS_MESSAGE_TYPE_SUCCESS); data = ao2_alloc(strlen(expected_text) + 1, NULL); strcpy(data, expected_text); diff --git a/tests/test_stasis_channels.c b/tests/test_stasis_channels.c index 89240130ce8a8bbc528467ad3ce67d20e0961a58..4c4bc665e202e64b16426aef9e51cfdc88323b88 100644 --- a/tests/test_stasis_channels.c +++ b/tests/test_stasis_channels.c @@ -71,7 +71,7 @@ AST_TEST_DEFINE(channel_blob_create) break; } - type = stasis_message_type_create("test-type", NULL); + ast_test_validate(test, stasis_message_type_create("test-type", NULL, &type) == STASIS_MESSAGE_TYPE_SUCCESS); chan = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, NULL, 0, "TEST/Alice"); ast_channel_unlock(chan); json = ast_json_pack("{s: s}", @@ -126,7 +126,7 @@ AST_TEST_DEFINE(null_blob) break; } - type = stasis_message_type_create("test-type", NULL); + ast_test_validate(test, stasis_message_type_create("test-type", NULL, &type) == STASIS_MESSAGE_TYPE_SUCCESS); chan = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, NULL, 0, "TEST/Alice"); ast_channel_unlock(chan); json = ast_json_pack("{s: s}",