35 .name = {
"Request Distributor", 19},
36 .priority = PJSIP_MOD_PRIORITY_TSX_LAYER - 6,
44#define DEFAULT_SUSPECTS_BUCKETS 53
60#define DISTRIBUTOR_POOL_SIZE 31
89 tdata_name = pj_pool_alloc(tdata->pool, strlen(
name) + 1);
90 strcpy(tdata_name,
name);
113 pjsip_transaction *tsx;
115 pjsip_tsx_create_key(rdata->tp_info.pool, &tsx_key, PJSIP_ROLE_UAC,
116 &rdata->msg_info.cseq->method, rdata);
118 tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE);
120 ast_debug(1,
"Could not find transaction for %s.\n",
121 pjsip_rx_data_get_info(rdata));
124 ast_debug(3,
"Found transaction %s for %s.\n",
125 tsx->obj_name, pjsip_rx_data_get_info(rdata));
128 const char *serializer_name;
134 ast_debug(3,
"Found serializer %s on transaction %s\n",
135 serializer_name, tsx->obj_name);
140#ifdef HAVE_PJ_TRANSACTION_GRP_LOCK
141 pj_grp_lock_release(tsx->grp_lock);
143 pj_mutex_unlock(tsx->mutex);
159#define DIALOG_ASSOCIATIONS_BUCKETS 251
184 hash = hash * 33 ^ *pos++;
216 const pjsip_dialog *
dlg;
217 const char buf[
sizeof(pjsip_dialog *)];
226 key.dlg =
object->dlg;
240 const pjsip_dialog *right_key = arg;
245 right_key = object_right->
dlg;
248 if (object_left->
dlg == right_key) {
339 pjsip_transaction *tsx;
342 pj_str_t *remote_tag;
344 if (!rdata->msg_info.msg) {
348 if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
349 local_tag = &rdata->msg_info.to->tag;
350 remote_tag = &rdata->msg_info.from->tag;
352 local_tag = &rdata->msg_info.from->tag;
353 remote_tag = &rdata->msg_info.to->tag;
361 if (rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG ||
362 pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_cancel_method) ||
363 rdata->msg_info.to->tag.slen != 0) {
364 dlg = pjsip_ua_find_dialog(&rdata->msg_info.cid->id, local_tag,
365 remote_tag, PJ_FALSE);
376 if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
381 pjsip_tsx_create_key(rdata->tp_info.pool, &tsx_key, PJSIP_ROLE_UAS,
382 pjsip_get_invite_method(), rdata);
384 pjsip_tsx_create_key(rdata->tp_info.pool, &tsx_key, PJSIP_ROLE_UAC,
385 &rdata->msg_info.cseq->method, rdata);
388 tsx = pjsip_tsx_layer_find_tsx(&tsx_key, PJ_TRUE);
390 ast_debug(3,
"Could not find matching transaction for %s\n",
391 pjsip_rx_data_get_info(rdata));
395 dlg = pjsip_tsx_get_dlg(tsx);
397#ifdef HAVE_PJ_TRANSACTION_GRP_LOCK
398 pj_grp_lock_release(tsx->grp_lock);
400 pj_mutex_unlock(tsx->mutex);
448 pj_str_t *remote_tag;
451 if (!rdata->msg_info.msg) {
455 if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
456 remote_tag = &rdata->msg_info.from->tag;
458 remote_tag = &rdata->msg_info.to->tag;
468 ast_debug(3,
"Calculated serializer %s to use for %s\n",
477 .name = {
"Endpoint Identifier", 19},
478 .priority = PJSIP_MOD_PRIORITY_TSX_LAYER - 3,
487 pjsip_rx_data *clone;
499 ast_debug(3,
"Searching for serializer associated with dialog %s for %s\n",
500 dlg->obj_name, pjsip_rx_data_get_info(rdata));
507 ast_debug(3,
"Found serializer %s associated with dialog %s\n",
515 }
else if (rdata->msg_info.msg->type == PJSIP_RESPONSE_MSG) {
516 ast_debug(3,
"No dialog serializer for %s. Using request transaction as basis.\n",
517 pjsip_rx_data_get_info(rdata));
527 }
else if (!pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_cancel_method)
528 || !pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_bye_method)) {
547 switch (rdata->tp_info.transport->key.type) {
548 case PJSIP_TRANSPORT_UDP6:
549 case PJSIP_TRANSPORT_UDP:
550 ast_debug(3,
"Taskprocessor overload alert: Ignoring '%s'.\n",
551 pjsip_rx_data_get_info(rdata));
554 ast_debug(3,
"Taskprocessor overload on non-udp transport. Received:'%s'. "
555 "Responding with a 503.\n", pjsip_rx_data_get_info(rdata));
568 if (pjsip_rx_data_clone(rdata, 0, &clone) != PJ_SUCCESS) {
583 pjsip_rx_data_free_cloned(clone);
657static void log_failed_request(pjsip_rx_data *rdata,
char *msg,
unsigned int count,
unsigned int period)
659 char from_buf[PJSIP_MAX_URL_SIZE];
660 char callid_buf[PJSIP_MAX_URL_SIZE];
661 char method_buf[PJSIP_MAX_URL_SIZE];
663 pjsip_uri_print(PJSIP_URI_IN_FROMTO_HDR, rdata->msg_info.from->uri, from_buf, PJSIP_MAX_URL_SIZE);
664 ast_copy_pj_str(callid_buf, &rdata->msg_info.cid->id, PJSIP_MAX_URL_SIZE);
665 ast_copy_pj_str(method_buf, &rdata->msg_info.msg->line.req.method.name, PJSIP_MAX_URL_SIZE);
668 " after %u tries in %.3f ms\n",
669 method_buf, from_buf,
670 pj_sockaddr_print(&rdata->pkt_info.src_addr, src_addr_buf,
sizeof(src_addr_buf), 3),
671 callid_buf, msg, count, period / 1000.0);
673 ast_log(
LOG_NOTICE,
"Request '%s' from '%s' failed for '%s' (callid: %s) - %s\n",
674 method_buf, from_buf,
675 pj_sockaddr_print(&rdata->pkt_info.src_addr, src_addr_buf,
sizeof(src_addr_buf), 3),
707 ast_debug(1,
"Endpoint '%s' not allowed by ACL\n",
719 int is_ack = rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD;
761 pjsip_uri *from = rdata->msg_info.from->uri;
786 strcpy(unid->
src_name, rdata->pkt_info.src_name);
811 memset(&addr, 0,
sizeof(addr));
825 pjsip_sip_uri *sip_uri;
828 if (!contact || contact->star) {
833 if (!PJSIP_URI_SCHEME_IS_SIP(contact->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact->uri)) {
837 sip_uri = pjsip_uri_get_uri(contact->uri);
844 int num_contact_addrs;
848 pjsip_contact_hdr *contact = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
854 while ((contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next))) {
856 if (num_contact_addrs <= 0) {
859 for (i = 0; i < num_contact_addrs; ++i) {
880 int is_ack = rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD;
889 pjsip_tx_data *tdata;
898 pjsip_tx_data_dec_ref(tdata);
914 pjsip_tx_data_dec_ref(tdata);
920 pjsip_tx_data_dec_ref(tdata);
924 pjsip_tx_data_dec_ref(tdata);
935 .name = {
"Request Authenticator", 21},
936 .priority = PJSIP_MOD_PRIORITY_APPLICATION - 2,
942 static pjsip_process_rdata_param param = {
944 .idx_after_start = 1,
946 pj_bool_t handled = PJ_FALSE;
947 pjsip_rx_data *rdata = data;
948 int is_request = rdata->msg_info.msg->type == PJSIP_REQUEST_MSG;
949 int is_ack = is_request ? rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD : 0;
953 if (!handled && is_request && !is_ack) {
962 pjsip_rx_data_free_cloned(rdata);
979 const char *right_key = arg;
987 cmp = strcmp(object_left->
src_name, right_key);
990 cmp = strncmp(object_left->
src_name, right_key, strlen(right_key));
1003 const char *right_key = arg;
1008 right_key = object_right->
src_name;
1011 if (strcmp(object_left->
src_name, right_key) == 0) {
1016 if (strncmp(object_left->
src_name, right_key, strlen(right_key)) == 0) {
1038 key =
object->src_name;
1096 "%*s: <IP Address%*.*s> <Count> <Age(sec)>\n",
1118 flexwidth, flexwidth,
1126 .
command =
"pjsip show unidentified_requests",
1127 .
usage =
"Usage: pjsip show unidentified_requests\n"
1128 " Show the PJSIP Unidentified Requests\n"),
1139 if (ms > (*maxage) * 2 * 1000) {
1148 unsigned int maxage;
1166 char *identifier_order;
1170 if (identifier_order) {
1171 char *identify_method;
1177 if (!strcmp(identify_method,
"auth_username")) {
Access Control of various sorts.
enum ast_acl_sense ast_apply_acl(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
Apply a set of rules to a given IP address.
int ast_acl_list_is_empty(struct ast_acl_list *acl_list)
Determines if an ACL is empty or if it contains entries.
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
Copy all object references in the src container into the dest container.
@ AO2_ALLOC_OPT_LOCK_NOLOCK
@ AO2_ALLOC_OPT_LOCK_RWLOCK
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
#define ao2_unlink(container, obj)
Remove an object from a container.
#define ao2_unlink_flags(container, obj, flags)
Remove an object from a container.
int() ao2_callback_fn(void *obj, void *arg, int flags)
Type of a generic callback function.
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
#define ao2_find(container, arg, flags)
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_alloc_options(data_size, destructor_fn, options)
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
@ OBJ_SEARCH_PARTIAL_KEY
The arg parameter is a partial search key similar to OBJ_SEARCH_KEY.
@ OBJ_SEARCH_OBJECT
The arg parameter is an object of the same type.
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
@ OBJ_SEARCH_MASK
Search option field mask.
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
#define ao2_alloc(data_size, destructor_fn)
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CLI_DEFINE(fn, txt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
enum ast_sip_taskprocessor_overload_trigger ast_sip_get_taskprocessor_overload_trigger(void)
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct ast_flags ast_options
@ AST_OPT_FLAG_FULLY_BOOTED
struct ast_sip_endpoint * ast_sip_dialog_get_endpoint(pjsip_dialog *dlg)
Get the endpoint associated with this dialog.
struct ast_taskprocessor * ast_sip_get_distributor_serializer(pjsip_rx_data *rdata)
Determine the distributor serializer for the SIP message.
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
struct ast_taskprocessor * ast_sip_create_serializer(const char *name)
Create a new serializer for SIP tasks.
void ast_sip_dialog_set_endpoint(pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint)
Set an endpoint on a SIP dialog so in-dialog requests do not undergo endpoint lookup.
void ast_sip_dialog_set_serializer(pjsip_dialog *dlg, struct ast_taskprocessor *serializer)
Set a serializer on a SIP dialog so requests and responses are automatically serialized.
char * strsep(char **str, const char *delims)
#define ast_debug(level,...)
Log a DEBUG message.
int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, int flags, int family)
Parses a string with an IPv4 or IPv6 address and place results into an array.
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
#define AST_SOCKADDR_BUFLEN
struct ast_sip_auth * ast_sip_get_artificial_auth(void)
Retrieves a reference to the artificial auth.
static int dialog_associations_hash(const void *obj, int flags)
static int cli_unid_iterate(void *container, ao2_callback_fn callback, void *args)
static int cli_unid_print_header(void *obj, void *arg, int flags)
static struct ast_sorcery_observer global_observer
Observer which is used to update our interval and default_realm when the global setting changes.
static int prune_task(const void *data)
static pjsip_module distributor_mod
static void distributor_pool_shutdown(void)
static int distribute(void *data)
static struct ao2_container * unidentified_requests
static struct ast_cli_entry cli_commands[]
static unsigned int unidentified_prune_interval
static enum ast_sip_taskprocessor_overload_trigger overload_trigger
static AO2_GLOBAL_OBJ_STATIC(artificial_auth)
struct ast_sip_endpoint * ast_sip_get_artificial_endpoint(void)
Retrieves a reference to the artificial endpoint.
static unsigned int unidentified_period
static void global_loaded(const char *object_type)
static pjsip_module auth_mod
#define DIALOG_ASSOCIATIONS_BUCKETS
static int extract_contact_addr(pjsip_contact_hdr *contact, struct ast_sockaddr **addrs)
static int expire_requests(void *object, void *arg, int flags)
static int apply_endpoint_acl(pjsip_rx_data *rdata, struct ast_sip_endpoint *endpoint)
static void check_endpoint(pjsip_rx_data *rdata, struct unidentified_request *unid, const char *name)
static pjsip_module endpoint_mod
static int buf_hash(const char *pos, size_t len)
static int buf_hash_add(const char *pos, size_t len, int hash)
struct ast_sched_context * prune_context
static void apply_acls(pjsip_rx_data *rdata)
static int clean_task(const void *data)
static pj_bool_t endpoint_lookup(pjsip_rx_data *rdata)
static pjsip_dialog * find_dialog(pjsip_rx_data *rdata)
static pj_status_t record_serializer(pjsip_tx_data *tdata)
static struct ao2_container * cli_unid_get_container(const char *regex)
struct ast_sip_endpoint * ast_pjsip_rdata_get_endpoint(pjsip_rx_data *rdata)
Get the looked-up endpoint on an out-of dialog request or response.
int ast_sip_initialize_distributor(void)
static int pjstr_hash_add(pj_str_t *str, int hash)
#define DISTRIBUTOR_POOL_SIZE
static int cli_unid_print_body(void *obj, void *arg, int flags)
static int suspects_hash(const void *obj, int flags)
static struct ast_sip_endpoint * artificial_endpoint
static int apply_endpoint_contact_acl(pjsip_rx_data *rdata, struct ast_sip_endpoint *endpoint)
static void * cli_unid_retrieve_by_id(const char *id)
static int suspects_compare(void *obj, void *arg, int flags)
static int suspects_sort(const void *obj, const void *arg, int flags)
static pj_bool_t authenticate(pjsip_rx_data *rdata)
static int create_artificial_endpoint(void)
static int dialog_associations_cmp(void *obj, void *arg, int flags)
void ast_sip_destroy_distributor(void)
static void log_failed_request(pjsip_rx_data *rdata, char *msg, unsigned int count, unsigned int period)
static int create_artificial_auth(void)
static const char * cli_unid_get_id(const void *obj)
struct ast_sip_cli_formatter_entry * unid_formatter
static pj_bool_t distributor(pjsip_rx_data *rdata)
static int pjstr_hash(pj_str_t *str)
static int using_auth_username
static unsigned int unidentified_count
static struct ast_sip_auth * alloc_artificial_auth(char *default_realm)
static struct ast_taskprocessor * distributor_pool[DISTRIBUTOR_POOL_SIZE]
static struct ast_taskprocessor * find_request_serializer(pjsip_rx_data *rdata)
static int distributor_pool_setup(void)
#define DEFAULT_SUSPECTS_BUCKETS
static struct ao2_container * dialog_associations
struct ao2_container * container
const pj_str_t * ast_sip_pjsip_uri_get_username(pjsip_uri *uri)
Get the user portion of the pjsip_uri.
void ast_sip_unregister_service(pjsip_module *module)
char * ast_sip_get_endpoint_identifier_order(void)
Retrieve the global endpoint_identifier_order setting.
int ast_sip_requires_authentication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
Determine if an incoming request requires authentication.
void ast_sip_report_auth_success(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
Send a security event notification for when authentication succeeds.
int ast_sip_register_service(pjsip_module *module)
Register a SIP service in Asterisk.
int ast_sip_is_allowed_uri(pjsip_uri *uri)
Check whether a pjsip_uri is allowed or not.
void ast_sip_report_auth_challenge_sent(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pjsip_tx_data *tdata)
Send a security event notification for when an authentication challenge is sent.
enum ast_sip_check_auth_result ast_sip_check_authentication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pjsip_tx_data *tdata)
Method to determine authentication status of an incoming request.
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
struct ast_sip_endpoint * ast_sip_identify_endpoint(pjsip_rx_data *rdata)
Determine the endpoint that has sent a SIP message.
void ast_sip_report_invalid_endpoint(const char *name, pjsip_rx_data *rdata)
Send a security event notification for when an invalid endpoint is requested.
void ast_sip_get_default_realm(char *realm, size_t size)
Retrieve the global default realm.
#define AST_SIP_AUTH_MAX_REALM_LENGTH
@ AST_SIP_AUTH_TYPE_ARTIFICIAL
void ast_sip_report_auth_failed_challenge_response(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
Send a security event notification for when a challenge response has failed.
#define SIP_SORCERY_AUTH_TYPE
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
@ AST_SIP_AUTHENTICATION_CHALLENGE
@ AST_SIP_AUTHENTICATION_ERROR
@ AST_SIP_AUTHENTICATION_SUCCESS
@ AST_SIP_AUTHENTICATION_FAILED
void ast_sip_report_failed_acl(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, const char *name)
Send a security event notification for when an ACL check fails.
void ast_sip_get_unidentified_request_thresholds(unsigned int *count, unsigned int *period, unsigned int *prune_interval)
Retrieve the unidentified request security event thresholds.
static char default_realm[AST_SIP_AUTH_MAX_REALM_LENGTH+1]
int ast_sip_unregister_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Unregisters a CLI formatter.
#define CLI_HEADER_FILLER
char * ast_sip_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define CLI_INDENT_TO_SPACES(x)
int ast_sip_register_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Registers a CLI formatter.
ast_sip_taskprocessor_overload_trigger
@ TASKPROCESSOR_OVERLOAD_TRIGGER_GLOBAL
@ TASKPROCESSOR_OVERLOAD_TRIGGER_PJSIP_ONLY
void ast_sched_clean_by_callback(struct ast_sched_context *con, ast_sched_cb match, ast_sched_cb cleanup_cb)
Clean all scheduled events with matching callback.
void ast_sched_context_destroy(struct ast_sched_context *c)
destroys a schedule context
int ast_sched_start_thread(struct ast_sched_context *con)
Start a thread for processing scheduler entries.
int ast_sched_add_variable(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data, int variable) attribute_warn_unused_result
Adds a scheduled event with rescheduling support.
struct ast_sched_context * ast_sched_context_create(void)
Create a scheduler context.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
void ast_sorcery_observer_remove(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Remove an observer from a specific object type.
int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Add an observer to a specific object type.
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to reload persistent objects.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
static force_inline int attribute_pure ast_str_hash_restrict(unsigned int hash)
Restrict hash value range.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
descriptor for a cli entry.
const ast_string_field realm
const ast_string_field auth_user
const ast_string_field auth_pass
enum ast_sip_auth_type type
CLI Formatter Context passed to all formatters.
CLI Formatter Registry Entry.
int(* iterate)(void *container, ao2_callback_fn callback, void *args)
ao2_callback_fn * print_header
void *(* retrieve_by_id)(const char *id)
const char *(* get_id)(const void *obj)
ao2_callback_fn * print_body
struct ao2_container *(* get_container)(const char *regex)
An entity with which Asterisk communicates.
struct ast_sip_auth_vector inbound_auths
struct ast_acl_list * contact_acl
struct ast_acl_list * acl
Socket address structure.
Interface for a sorcery object type observer.
void(* loaded)(const char *object_type)
Callback for when an object type is loaded/reloaded.
A ast_taskprocessor structure is a singleton by name.
struct ast_sip_endpoint * endpoint
struct ast_taskprocessor * serializer
struct timeval first_seen
An API for managing task processing threads that can be shared across modules.
struct ast_taskprocessor * ast_taskprocessor_get(const char *name, enum ast_tps_options create)
Get a reference to a taskprocessor with the specified name and create the taskprocessor if necessary.
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
@ TPS_REF_IF_EXISTS
return a reference to a taskprocessor ONLY if it already exists
unsigned int ast_taskprocessor_alert_get(void)
Get the current taskprocessor high water alert count.
unsigned int ast_taskprocessor_get_subsystem_alert(const char *subsystem)
Get the current taskprocessor high water alert count by subsystem.
void ast_taskprocessor_build_name(char *buf, unsigned int size, const char *format,...)
Build a taskprocessor name with a sequence number on the end.
const char * ast_taskprocessor_name(struct ast_taskprocessor *tps)
Return the name of the taskprocessor singleton.
#define AST_TASKPROCESSOR_MAX_NAME
Suggested maximum taskprocessor name length (less null terminator).
struct ast_taskprocessor * ast_threadpool_serializer_get_current(void)
Get the threadpool serializer currently associated with this thread.
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
#define ast_test_flag(p, flag)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.