32#define TRANSPORTS_BUCKETS 127
34#define IDLE_TIMEOUT (pjsip_cfg()->tsx.td)
61 pjsip_tpselector selector = {
62 .type = PJSIP_TPSELECTOR_TRANSPORT,
73 pj_sockaddr_get_len(&monitored->
transport->key.rem_addr),
81 pj_thread_desc
desc = { 0 };
84 if (pj_thread_register(
"Asterisk Keepalive Thread",
desc, &
thread) != PJ_SUCCESS) {
85 ast_log(
LOG_ERROR,
"Could not register keepalive thread with PJLIB, keepalives will not occur.\n");
124 if (!pj_thread_is_registered()) {
126 pj_thread_desc *
desc;
130 ast_log(
LOG_ERROR,
"Could not get thread desc from thread-local storage.\n");
136 pj_thread_register(
"Transport Monitor", *
desc, &
thread);
159 char *obj_name = (
char *) data;
170 ast_log(
LOG_NOTICE,
"Shutting down transport '%s' since no request was received in %d seconds\n",
172 pjsip_transport_shutdown(monitored->
transport);
183 char *obj_name = (
char *) data;
193 pjsip_transport_shutdown(monitored->
transport);
206 pjsip_transport_dec_ref(monitored->
transport);
211 const pjsip_transport_state_info *
info)
216 if (PJSIP_TRANSPORT_IS_RELIABLE(transport)
222 case PJSIP_TP_STATE_CONNECTED:
229 pjsip_transport_add_ref(monitored->
transport);
233 if (
transport->dir == PJSIP_TP_DIR_INCOMING) {
245 case PJSIP_TP_STATE_SHUTDOWN:
246 case PJSIP_TP_STATE_DISCONNECTED:
273 key =
object->transport->obj_name;
288 const char *right_key = arg;
293 right_key = object_right->
transport->obj_name;
296 cmp = strcmp(object_left->
transport->obj_name, right_key);
303 cmp = strncmp(object_left->
transport->obj_name, right_key, strlen(right_key));
336 ast_log(
LOG_ERROR,
"Could not create thread for sending keepalive messages.\n");
367 .name = {
"idle monitor module", 19},
368 .priority = PJSIP_MOD_PRIORITY_TRANSPORT_LAYER + 3,
379 ast_log(
LOG_ERROR,
"Could not create container for transports to perform keepalive on.\n");
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdup(str)
A wrapper for strdup()
#define ao2_iterator_next(iter)
#define ao2_link(container, obj)
Add an object to a container.
@ AO2_ALLOC_OPT_LOCK_NOLOCK
@ AO2_ALLOC_OPT_LOCK_MUTEX
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
#define ao2_find(container, arg, flags)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#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.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ 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_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_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.
#define AST_PTHREADT_NULL
Asterisk module definitions.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
static pjsip_module idle_monitor_module
int ast_sip_initialize_transport_management(void)
static int idle_sched_init_pj_thread(void)
static void keepalive_transport_send_keepalive(struct monitored_transport *monitored)
static void * keepalive_transport_thread(void *data)
Thread which sends keepalives to all active connection-oriented transports.
static void monitored_transport_state_callback(pjsip_transport *transport, pjsip_transport_state state, const pjsip_transport_state_info *info)
Callback invoked when transport changes occur.
#define TRANSPORTS_BUCKETS
Number of buckets for monitored transports.
static struct ast_sched_context * sched
Scheduler context for timing out connections with no data received.
static AO2_GLOBAL_OBJ_STATIC(monitored_transports)
Global container of active transports.
static const pj_str_t keepalive_packet
The keep alive packet to send.
static int monitored_transport_hash_fn(const void *obj, int flags)
Hashing function for monitored transport.
static pj_bool_t idle_monitor_on_rx_request(pjsip_rx_data *rdata)
On incoming TCP connections, when we receive a SIP request, we mark that we have received a valid SIP...
static int idle_sched_cb(const void *data)
static unsigned int keepalive_interval
The global interval at which to send keepalives.
void ast_sip_destroy_transport_management(void)
static int idle_sched_cleanup(const void *data)
static pthread_t keepalive_thread
Thread keeping things alive.
static void keepalive_global_loaded(const char *object_type)
struct ast_sip_tpmgr_state_callback monitored_transport_reg
static struct ast_threadstorage desc_storage
static struct monitored_transport * get_monitored_transport_by_name(const char *obj_name)
static struct ast_sorcery_observer keepalive_global_observer
Observer which is used to update our interval when the global setting changes.
static int monitored_transport_cmp_fn(void *obj, void *arg, int flags)
Comparison function for monitored transport.
static void monitored_transport_destroy(void *obj)
Destructor for keepalive transport.
unsigned int ast_sip_get_keep_alive_interval(void)
Retrieve the system keep alive interval setting.
void ast_sip_unregister_service(pjsip_module *module)
int ast_sip_register_service(pjsip_module *module)
Register a SIP service in Asterisk.
void ast_sip_transport_state_register(struct ast_sip_tpmgr_state_callback *element)
Register a transport state notification callback element.
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
void ast_sip_transport_state_unregister(struct ast_sip_tpmgr_state_callback *element)
Unregister a transport state notification callback element.
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
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.
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_reload_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to reload persistent objects.
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Interface for a sorcery object type observer.
void(* loaded)(const char *object_type)
Callback for when an object type is loaded/reloaded.
Structure for transport to be monitored.
pjsip_transport * transport
The underlying PJSIP transport.
int sip_received
Non-zero if a PJSIP request was received.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
#define AST_THREADSTORAGE(name)
Define a thread storage variable.
#define ast_pthread_create(a, b, c, d)