41#define ACTIVE_TRANSPORTS_BUCKETS 127
88 case PJSIP_TP_STATE_CONNECTED:
91 case PJSIP_TP_STATE_DISCONNECTED:
92 name =
"DISCONNECTED";
94 case PJSIP_TP_STATE_SHUTDOWN:
97 case PJSIP_TP_STATE_DESTROY:
124 ast_debug(3,
"Transport %s(%s,%s) RefCnt: %ld : state:MONITOR_DESTROYED\n",
128 pjsip_transport_dec_ref(monitored->
transport);
156 ast_debug(3,
"Transport %s(%s,%s) RefCnt: %ld : running callback %p(%p)\n",
159 pj_atomic_get(monitored->
transport->ref_cnt), notifier->
cb, notifier->
data);
160 notifier->
cb(notifier->
data);
163 ast_debug(3,
"Transport %s(%s,%s) RefCnt: %ld : ignored not matching %s\n",
166 pj_atomic_get(monitored->
transport->ref_cnt), transport->obj_name);
174 pj_uint32_t verify_status)
183 if (pj_ssl_cert_get_verify_status_strings(verify_status,
status, &count) != PJ_SUCCESS) {
184 ast_log(
LOG_ERROR,
"Error retrieving certificate verification result(s)\n");
189 for (i = 0; i < count; ++i) {
190 ast_log(
log_level,
_A_,
"Transport '%s' to remote '%.*s' - %s - %s\n", transport->factory->info,
191 (
int)pj_strlen(&transport->remote_name.host), pj_strbuf(&transport->remote_name.host),
192 transport_remote_ipaddr_port,
202 ast_debug(3,
"Verify certificate name: local = %.*s, remote = %.*s\n",
203 (
unsigned int)pj_strlen(local), pj_strbuf(local),
204 (
unsigned int)pj_strlen(remote), pj_strbuf(remote));
206 if (!pj_stricmp(remote, local)) {
210 if (pj_strnicmp2(remote,
"*.", 2)) {
214 p = pj_strchr(local,
'.');
219 size = pj_strbuf(local) + pj_strlen(local) - ++p;
221 return size == pj_strlen(remote) - 2 ?
222 !pj_memcmp(pj_strbuf(remote) + 2, p, size) : 0;
229 for (i = 0; i < remote->subj_alt_name.cnt; ++i) {
234 if (remote->subj_alt_name.entry[i].type == PJ_SSL_CERT_NAME_DNS
244 const pjsip_tls_state_info *state_info)
246 pj_uint32_t verify_status;
249 if (
transport->dir == PJSIP_TP_DIR_INCOMING) {
266 verify_status = state_info->ssl_sock_info->verify_status;
274 if (
state->allow_wildcard_certs &&
275 (verify_status & PJ_SSL_CERT_EIDENTITY_NOT_MATCH)) {
277 state_info->ssl_sock_info->remote_cert_info)) {
279 verify_status &= ~PJ_SSL_CERT_EIDENTITY_NOT_MATCH;
283 if (
state->verify_server && verify_status != PJ_SSL_CERT_ESUCCESS) {
294 pjsip_transport_state
state,
const pjsip_transport_state_info *
info)
300 if (PJSIP_TRANSPORT_IS_RELIABLE(transport)
305 ast_debug(3,
"Transport %s(%s,%s): RefCnt: %ld state:%s\n",
309 case PJSIP_TP_STATE_CONNECTED:
310 if (PJSIP_TRANSPORT_IS_SECURE(
transport) &&
329 pjsip_transport_add_ref(monitored->
transport);
330 ast_debug(3,
"Transport %s(%s,%s): RefCnt: %ld state:MONITOR_CREATED\n",
333 pj_atomic_get(monitored->
transport->ref_cnt));
338 case PJSIP_TP_STATE_DISCONNECTED:
344 case PJSIP_TP_STATE_SHUTDOWN:
355 case PJSIP_TP_STATE_DESTROY:
403 if (notifier->
cb == cb_data->
cb && (!cb_data->
data
407 ast_debug(3,
"Transport %s(%s,%s) RefCnt: %ld : Unregistered monitor %p(%p)\n",
410 pj_atomic_get(monitored->
transport->ref_cnt), notifier->
cb, notifier->
data);
534 ast_debug(3,
"Transport %s(%s) RefCnt: %ld : Monitor registration failed %p(%p)\n",
536 pj_atomic_get(monitored->
transport->ref_cnt),
cb, ao2_data);
539 ast_debug(3,
"Transport %s(%s,%s) RefCnt: %ld : Registered monitor %p(%p)\n",
542 pj_atomic_get(monitored->
transport->ref_cnt),
cb, ao2_data);
565 if (element == tpmgr_notifier) {
580 regex_t
regex = { 0, };
589 e->
command =
"pjsip show transport-monitors";
590 e->
usage =
"Usage: pjsip show transport-monitors [ like <pattern> ]\n"
591 " Show pjsip transport monitors\n";
597 if (
a->argc != 3 &&
a->argc != 5) {
603 if (strcasecmp(
a->argv[3],
"like")) {
606 regrc = regcomp(&
regex,
a->argv[4], REG_EXTENDED | REG_ICASE | REG_NOSUB);
609 regerror(regrc, &
regex, err, 256);
610 ast_cli(
a->fd,
"PJSIP Transport Monitor: Error: %s\n", err);
618 transport_monitor_sort_fn,
NULL);
619 if (!sorted_monitors) {
620 ast_cli(
a->fd,
"PJSIP Transport Monitor: Unable to allocate temporary container\n");
626 ast_cli(
a->fd,
"PJSIP Transport Monitor: Unable to get transports\n");
635 ast_cli(
a->fd,
"PJSIP Transport Monitors: Unable to sort temporary container\n");
640 ast_cli(
a->fd,
"PJSIP Transport Monitors:\n\n");
643 "<Remote Host...................................> <State.....> <Direction> <RefCnt> <Monitors> <ObjName............>\n");
649 if (using_regex && regexec(&
regex, monitored->
key, 0,
NULL, 0) == REG_NOMATCH) {
653 if (monitored->
transport->is_destroying) {
654 state =
"DESTROYING";
655 }
else if (monitored->
transport->is_shutdown) {
661 ast_cli(
a->fd,
" %-46.46s %-10s %-9s %6ld %8zu %s\n",
663 monitored->
transport->dir == PJSIP_TP_DIR_OUTGOING ?
"Outgoing" :
"Incoming",
664 pj_atomic_get(monitored->
transport->ref_cnt),
668 ast_cli(
a->fd,
"\nTotal Transport Monitors: %d\n\n", container_count);
709 transport_monitor_cmp_fn);
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdup(str)
A wrapper for strdup()
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.
#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_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ao2_unlink(container, obj)
Remove an object from 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)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a red-black tree 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.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
@ 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.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
#define ast_debug(level,...)
Log a DEBUG message.
A set of macros to manage forward-linked lists.
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
#define AST_RWLIST_HEAD(name, type)
Defines a structure to be used to hold a read/write list of specified type.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
#define AST_LIST_REMOVE(head, elm, field)
Removes a specific entry from a list.
static struct ast_cli_entry cli_commands[]
AO2_STRING_FIELD_SORT_FN(transport_monitor, key)
Sort function for struct transport_monitor.
static struct @455 transport_state_list
static void verify_log_result(int log_level, const pjsip_transport *transport, pj_uint32_t verify_status)
void ast_sip_transport_state_register(struct ast_sip_tpmgr_state_callback *element)
Register a transport state notification callback element.
enum ast_transport_monitor_reg ast_sip_transport_monitor_register_key(const char *transport_key, ast_transport_monitor_shutdown_cb cb, void *ao2_data)
Register a reliable transport shutdown monitor callback.
AO2_STRING_FIELD_HASH_FN(transport_monitor, key)
Hashing function for struct transport_monitor.
enum ast_transport_monitor_reg ast_sip_transport_monitor_register_replace(pjsip_transport *transport, ast_transport_monitor_shutdown_cb cb, void *ao2_data, ast_transport_monitor_data_matcher matches)
Register a reliable transport shutdown monitor callback replacing any duplicate.
void ast_sip_transport_monitor_unregister(pjsip_transport *transport, ast_transport_monitor_shutdown_cb cb, void *data, ast_transport_monitor_data_matcher matches)
Unregister a reliable transport shutdown monitor.
static int verify_cert_name(const pj_str_t *local, const pj_str_t *remote)
static void transport_state_do_reg_callbacks(struct ao2_container *transports, pjsip_transport *transport)
AO2_STRING_FIELD_CMP_FN(transport_monitor, key)
Comparison function for struct transport_monitor.
void ast_sip_transport_monitor_unregister_all(ast_transport_monitor_shutdown_cb cb, void *data, ast_transport_monitor_data_matcher matches)
Unregister a transport shutdown monitor from all reliable transports.
static int verify_cert_names(const pj_str_t *host, const pj_ssl_cert_info *remote)
enum ast_transport_monitor_reg ast_sip_transport_monitor_register_replace_key(const char *transport_key, ast_transport_monitor_shutdown_cb cb, void *ao2_data, ast_transport_monitor_data_matcher matches)
Register a reliable transport shutdown monitor callback replacing any duplicate.
static char * cli_show_monitors(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
int ast_sip_initialize_transport_events(void)
enum ast_transport_monitor_reg ast_sip_transport_monitor_register(pjsip_transport *transport, ast_transport_monitor_shutdown_cb cb, void *ao2_data)
Register a reliable transport shutdown monitor callback.
void ast_sip_transport_state_unregister(struct ast_sip_tpmgr_state_callback *element)
Unregister a transport state notification callback element.
static void transport_monitor_dtor(void *vdoomed)
static int transport_tls_verify(const pjsip_transport *transport, const pjsip_tls_state_info *state_info)
static void transport_state_callback(pjsip_transport *transport, pjsip_transport_state state, const pjsip_transport_state_info *info)
Callback invoked when transport state changes occur.
static pjsip_tp_state_callback tpmgr_state_callback
Existing transport events callback that we need to invoke.
static int ptr_matcher(void *a, void *b)
static const char * transport_state2str(pjsip_transport_state state)
static int transport_monitor_unregister_cb(void *obj, void *arg, int flags)
static AO2_GLOBAL_OBJ_STATIC(active_transports)
Global container of active reliable transports.
void ast_sip_transport_monitor_unregister_key(const char *transport_key, ast_transport_monitor_shutdown_cb cb, void *data, ast_transport_monitor_data_matcher matches)
Unregister a reliable transport shutdown monitor.
void ast_sip_destroy_transport_events(void)
#define ACTIVE_TRANSPORTS_BUCKETS
Number of buckets for monitored active transports.
int(* ast_transport_monitor_data_matcher)(void *a, void *b)
Transport shutdown monitor data matcher.
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
#define AST_SIP_MAKE_REMOTE_IPADDR_PORT_STR(_transport, _dest)
Fill a buffer with a pjsip transport's remote ip address and port.
#define IP6ADDR_COLON_PORT_BUFLEN
ast_transport_monitor_reg
@ AST_TRANSPORT_MONITOR_REG_NOT_FOUND
Transport not found to monitor.
@ AST_TRANSPORT_MONITOR_REG_FAILED
Error while registering transport monitor.
@ AST_TRANSPORT_MONITOR_REG_SUCCESS
Successfully registered the transport monitor.
void(* ast_transport_monitor_shutdown_cb)(void *data)
Transport shutdown monitor callback.
struct ast_sip_transport_state * ast_sip_get_transport_state(const char *transport_id)
Retrieve transport state.
static int log_level
Log level for history output.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
descriptor for a cli entry.
pjsip_tp_state_callback cb
Structure for SIP transport information.
struct pjsip_transport * transport
Transport itself.
ast_transport_monitor_data_matcher matches
ast_transport_monitor_shutdown_cb cb
ast_transport_monitor_shutdown_cb cb
Structure for transport to be monitored.
pjsip_transport * transport
The underlying PJSIP transport.
char key[IP6ADDR_COLON_PORT_BUFLEN]
Key <ipaddr>:<port>
char * transport_obj_name
struct transport_monitor::@456 monitors
int error(const char *format,...)
Vector container support.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
#define AST_VECTOR_REMOVE_UNORDERED(vec, idx)
Remove an element from an unordered vector by index.
#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.
#define AST_VECTOR(name, type)
Define a vector structure.
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.