36#define MAX_POINTER_STRING 33
39#define DEFAULT_STATE_BUCKETS 53
88 const char *right_key = arg;
93 right_key = object_right->
id;
96 cmp = strcmp(object_left->
id, right_key);
138 const char *right_key = arg;
143 right_key = object_right->
id;
146 cmp = strcmp(object_left->
id, right_key);
216 if (!transport_state) {
220 if (!transport_state->
flow) {
228 pjsip_transport_dec_ref(transport_state->
transport);
232 pjsip_transport_add_ref(transport_state->
transport);
251 if (!transport_state) {
255 if (!transport_state->
flow) {
280 if (!transport_state) {
285 if (!transport_state->
flow) {
312 if (tdata->msg->type != PJSIP_REQUEST_MSG ||
313 (pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_invite_method) &&
314 pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_cancel_method) &&
315 pjsip_method_cmp(&tdata->msg->line.req.method, &pjsip_options_method))) {
320 if (!transport_state) {
324 if (!transport_state->
flow) {
356 service_routes =
ast_calloc(1,
sizeof(*service_routes));
357 if (!service_routes) {
363 return service_routes;
368 if (!service_routes) {
378 int tos_as_dscp = transport->
tos >> 2;
380 if (transport->
tos) {
381 qos->flags |= PJ_QOS_PARAM_HAS_DSCP;
382 qos->dscp_val = tos_as_dscp;
384 if (transport->
cos) {
385 qos->flags |= PJ_QOS_PARAM_HAS_SO_PRIO;
386 qos->so_prio = transport->
cos;
429 pjsip_transport_shutdown(transport_state->
transport);
555 pjsip_tls_setting_default(&new_state->
tls);
556#ifdef HAVE_PJSIP_TLS_TRANSPORT_PROTO
558 new_state->
tls.proto = 0;
576 transport->external_address_refresher =
transport->state->external_signaling_address_refresher;
577 memcpy(&
transport->external_address, &
transport->state->external_signaling_address,
sizeof(
transport->external_signaling_address));
580#ifdef HAVE_PJSIP_TLS_TRANSPORT_RESTART
581static int file_stat_cmp(
const struct stat *old_stat,
const struct stat *new_stat)
583 return old_stat->st_size != new_stat->st_size
584 || old_stat->st_mtime != new_stat->st_mtime
585#if defined(HAVE_STRUCT_STAT_ST_MTIM)
586 || old_stat->st_mtim.tv_nsec != new_stat->st_mtim.tv_nsec
587#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
588 || old_stat->st_mtimensec != new_stat->st_mtimensec
589#elif defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
590 || old_stat->st_mtimespec.tv_nsec != new_stat->st_mtimespec.tv_nsec
598 if (
a->type !=
b->type) {
602 if (pj_sockaddr_cmp(&
a->host, &
b->host)) {
606 if ((
a->localnet ||
b->localnet)
607 && ((!
a->localnet != !
b->localnet)
614 if (
ast_sockaddr_cmp(&
a->external_signaling_address, &
b->external_signaling_address)) {
622 if (
a->tls.method !=
b->tls.method
623 ||
a->tls.ciphers_num !=
b->tls.ciphers_num
624#ifdef HAVE_PJSIP_TLS_TRANSPORT_PROTO
625 ||
a->tls.proto !=
b->tls.proto
627 ||
a->tls.verify_client !=
b->tls.verify_client
628 ||
a->tls.verify_server !=
b->tls.verify_server
629 ||
a->tls.require_client_cert !=
b->tls.require_client_cert) {
633 if (memcmp(
a->ciphers,
b->ciphers,
sizeof(pj_ssl_cipher) * fmax(
a->tls.ciphers_num,
b->tls.ciphers_num))) {
637#ifdef HAVE_PJSIP_TLS_TRANSPORT_RESTART
638 if (file_stat_cmp(&
a->cert_file_stat, &
b->cert_file_stat) || file_stat_cmp(&
a->privkey_file_stat, &
b->privkey_file_stat)) {
662 pj_status_t res = -1;
665#define BIND_DELAY_US 100000
680 ast_log(
LOG_ERROR,
"Transport '%s' failed to allocate memory\n", transport_id);
685 ast_log(
LOG_WARNING,
"The async_operations setting on transport '%s' has been set to '%d'. The setting can no longer be set and is always 1.\n",
695 transport->
state = perm_state->state;
703 memcpy(&temp_state->state->host, &perm_state->state->host,
sizeof(temp_state->state->host));
704 memcpy(&temp_state->state->tls, &perm_state->state->tls,
sizeof(temp_state->state->tls));
705 memcpy(&temp_state->state->ciphers, &perm_state->state->ciphers,
sizeof(temp_state->state->ciphers));
710 if (temp_state->state->host.addr.sa_family != PJ_AF_INET && temp_state->state->host.addr.sa_family != PJ_AF_INET6) {
711 ast_log(
LOG_ERROR,
"Transport '%s' could not be started as binding not specified\n", transport_id);
716 if (!pj_sockaddr_get_port(&temp_state->state->host)) {
717 pj_sockaddr_set_port(&temp_state->state->host, (transport->
type ==
AST_TRANSPORT_TLS) ? 5061 : 5060);
723 if (temp_state->state->host.addr.sa_family == pj_AF_INET()) {
724 temp_state->state->external_signaling_address.ss.ss_family = AF_INET;
725 }
else if (temp_state->state->host.addr.sa_family == pj_AF_INET6()) {
726 temp_state->state->external_signaling_address.ss.ss_family = AF_INET6;
728 ast_log(
LOG_ERROR,
"Unknown address family for transport '%s', could not get external signaling address\n",
734 ast_log(
LOG_ERROR,
"Could not create dnsmgr for external signaling address on '%s'\n", transport_id);
740 if (temp_state->state->host.addr.sa_family == pj_AF_INET()) {
741 temp_state->state->external_media_address.ss.ss_family = AF_INET;
742 }
else if (temp_state->state->host.addr.sa_family == pj_AF_INET6()) {
743 temp_state->state->external_media_address.ss.ss_family = AF_INET6;
745 ast_log(
LOG_ERROR,
"Unknown address family for transport '%s', could not get external media address\n",
751 ast_log(
LOG_ERROR,
"Could not create dnsmgr for external media address on '%s'\n", transport_id);
756 if (transport->
flow) {
759 ast_debug(1,
"Ignoring any bind configuration on transport '%s' as it is a child of another\n",
761 pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&
address,
"0.0.0.0"), &temp_state->state->host);
763 temp_state->state->flow = 1;
767#ifdef HAVE_PJSIP_TLS_TRANSPORT_RESTART
768 ast_log(
LOG_NOTICE,
"Transport '%s' is not fully reloadable, not reloading: protocol, bind, TLS (everything but certificate and private key if filename is unchanged), TCP, ToS, or CoS options.\n", transport_id);
771 if (strcmp(perm_state->transport->cert_file, temp_state->transport->cert_file) ||
772 strcmp(perm_state->transport->privkey_file, temp_state->transport->privkey_file)) {
773 ast_log(
LOG_ERROR,
"Unable to restart TLS transport '%s' as certificate or private key filename has changed\n",
775 }
else if (file_stat_cmp(&perm_state->state->cert_file_stat, &temp_state->state->cert_file_stat) ||
776 file_stat_cmp(&perm_state->state->privkey_file_stat, &temp_state->state->privkey_file_stat)) {
777 if (pjsip_tls_transport_restart(perm_state->state->factory, &perm_state->state->host,
NULL) != PJ_SUCCESS) {
780 sprintf(perm_state->state->factory->info,
"%s", transport_id);
785 ast_log(
LOG_NOTICE,
"Transport '%s' is not fully reloadable, not reloading: protocol, bind, TLS, TCP, ToS, or CoS options.\n", transport_id);
787 temp_state->state->transport = perm_state->state->transport;
788 perm_state->state->transport =
NULL;
789 temp_state->state->factory = perm_state->state->factory;
790 perm_state->state->factory =
NULL;
795 for (i = 0; i <
BIND_TRIES && res != PJ_SUCCESS; i++) {
796 if (perm_state && perm_state->state && perm_state->state->transport) {
797 pjsip_udp_transport_pause(perm_state->state->transport,
798 PJSIP_UDP_TRANSPORT_DESTROY_SOCKET);
802 if (temp_state->state->host.addr.sa_family == pj_AF_INET()) {
805 &temp_state->state->transport);
806 }
else if (temp_state->state->host.addr.sa_family == pj_AF_INET6()) {
809 &temp_state->state->transport);
813 if (res == PJ_SUCCESS) {
814 temp_state->state->transport->info = pj_pool_alloc(temp_state->state->transport->pool,
817 sprintf(temp_state->state->transport->info,
"%s:%s",
AST_SIP_X_AST_TXP, transport_id);
819 if (transport->
tos || transport->
cos) {
821 pj_qos_params qos_params;
822 sock = pjsip_udp_transport_get_socket(temp_state->state->transport);
823 pj_sock_get_qos_params(sock, &qos_params);
824 set_qos(transport, &qos_params);
825 pj_sock_set_qos_params(sock, &qos_params);
829 pjsip_tcp_transport_cfg cfg;
830 static int option = 1;
831 int sockopt_count = 0;
833 pjsip_tcp_transport_cfg_default(&cfg, temp_state->state->host.addr.sa_family);
834 cfg.bind_addr = temp_state->state->host;
836 set_qos(transport, &cfg.qos_params);
839 cfg.sockopt_params.options[sockopt_count].level = pj_SOL_TCP();
840 cfg.sockopt_params.options[sockopt_count].optname = pj_TCP_NODELAY();
841 cfg.sockopt_params.options[sockopt_count].optval = &option;
842 cfg.sockopt_params.options[sockopt_count].optlen =
sizeof(option);
846#if defined(PJ_MAX_SOCKOPT_PARAMS) && PJ_MAX_SOCKOPT_PARAMS >= 5
847 ast_log(
LOG_DEBUG,
"TCP Keepalive enabled for transport '%s'. Idle Time: %d, Interval: %d, Count: %d\n",
850 cfg.sockopt_params.options[sockopt_count].level = pj_SOL_SOCKET();
851 cfg.sockopt_params.options[sockopt_count].optname = SO_KEEPALIVE;
852 cfg.sockopt_params.options[sockopt_count].optval = &option;
853 cfg.sockopt_params.options[sockopt_count].optlen =
sizeof(option);
856 cfg.sockopt_params.options[sockopt_count].level = pj_SOL_TCP();
857 cfg.sockopt_params.options[sockopt_count].optname = TCP_KEEPIDLE;
862 cfg.sockopt_params.options[sockopt_count].level = pj_SOL_TCP();
863 cfg.sockopt_params.options[sockopt_count].optname = TCP_KEEPINTVL;
868 cfg.sockopt_params.options[sockopt_count].level = pj_SOL_TCP();
869 cfg.sockopt_params.options[sockopt_count].optname = TCP_KEEPCNT;
874 ast_log(
LOG_WARNING,
"TCP keepalive settings for '%s' not set due to PJSIP built without support for setting all options. Consider using bundled PJSIP.\n",
879 cfg.sockopt_params.cnt = sockopt_count;
881 for (i = 0; i <
BIND_TRIES && res != PJ_SUCCESS; i++) {
882 if (perm_state && perm_state->state && perm_state->state->factory
883 && perm_state->state->factory->destroy) {
884 perm_state->state->factory->destroy(perm_state->state->factory);
889 &temp_state->state->factory);
892#if defined(PJ_HAS_SSL_SOCK) && PJ_HAS_SSL_SOCK != 0
893 static int option = 1;
894 int sockopt_count = 0;
897 ast_log(
LOG_ERROR,
"Transport: %s: When protocol=tls and pjproject version < 2.5.0, async_operations can't be > 1\n",
902 temp_state->state->tls.password = pj_str((
char*)transport->
password);
906 temp_state->state->tls.sockopt_params.options[sockopt_count].level = pj_SOL_TCP();
907 temp_state->state->tls.sockopt_params.options[sockopt_count].optname = pj_TCP_NODELAY();
908 temp_state->state->tls.sockopt_params.options[sockopt_count].optval = &option;
909 temp_state->state->tls.sockopt_params.options[sockopt_count].optlen =
sizeof(option);
913#if defined(PJ_MAX_SOCKOPT_PARAMS) && PJ_MAX_SOCKOPT_PARAMS >= 5
914 ast_log(
LOG_DEBUG,
"TCP Keepalive enabled for transport '%s'. Idle Time: %d, Interval: %d, Count: %d\n",
917 temp_state->state->tls.sockopt_params.options[sockopt_count].level = pj_SOL_SOCKET();
918 temp_state->state->tls.sockopt_params.options[sockopt_count].optname = SO_KEEPALIVE;
919 temp_state->state->tls.sockopt_params.options[sockopt_count].optval = &option;
920 temp_state->state->tls.sockopt_params.options[sockopt_count].optlen =
sizeof(option);
923 temp_state->state->tls.sockopt_params.options[sockopt_count].level = pj_SOL_TCP();
924 temp_state->state->tls.sockopt_params.options[sockopt_count].optname = TCP_KEEPIDLE;
926 temp_state->state->tls.sockopt_params.options[sockopt_count].optlen =
sizeof(transport->
tcp_keepalive_idle_time);
929 temp_state->state->tls.sockopt_params.options[sockopt_count].level = pj_SOL_TCP();
930 temp_state->state->tls.sockopt_params.options[sockopt_count].optname = TCP_KEEPINTVL;
935 temp_state->state->tls.sockopt_params.options[sockopt_count].level = pj_SOL_TCP();
936 temp_state->state->tls.sockopt_params.options[sockopt_count].optname = TCP_KEEPCNT;
941 ast_log(
LOG_WARNING,
"TCP keepalive settings for '%s' not set due to PJSIP built without support for setting all options. Consider using bundled PJSIP.\n",
946 temp_state->state->tls.sockopt_params.cnt = sockopt_count;
948 for (i = 0; i <
BIND_TRIES && res != PJ_SUCCESS; i++) {
949 if (perm_state && perm_state->state && perm_state->state->factory
950 && perm_state->state->factory->destroy) {
951 perm_state->state->factory->destroy(perm_state->state->factory);
957 &temp_state->state->factory);
960 if (res == PJ_SUCCESS) {
965 temp_state->state->factory->info = pj_pool_alloc(
971 sprintf(temp_state->state->factory->info,
"%s", transport_id);
974 ast_log(
LOG_ERROR,
"Transport: %s: PJSIP has not been compiled with TLS transport support, ensure OpenSSL development packages are installed\n",
979 if (transport->
cos || transport->
tos) {
983 ast_log(
LOG_WARNING,
"TLS certificate values ignored for websocket transport as they are configured in http.conf\n");
988 if (res != PJ_SUCCESS) {
989 char msg[PJ_ERR_MSG_SIZE];
991 pj_strerror(res, msg,
sizeof(msg));
1032 ast_log(
LOG_ERROR,
"Transport: %s: %s %s is either missing or not readable\n",
1037 if (!strcasecmp(
var->name,
"ca_list_file")) {
1038 state->tls.ca_list_file = pj_str((
char*)
var->value);
1040 }
else if (!strcasecmp(
var->name,
"ca_list_path")) {
1041#ifdef HAVE_PJ_SSL_CERT_LOAD_FROM_FILES2
1042 state->tls.ca_list_path = pj_str((
char *)
var->value);
1045 ast_log(
LOG_WARNING,
"Asterisk has been built against a version of pjproject that does not "
1046 "support the 'ca_list_path' option. Please upgrade to version 2.4 or later.\n");
1048 }
else if (!strcasecmp(
var->name,
"cert_file")) {
1049 state->tls.cert_file = pj_str((
char *)
var->value);
1051#ifdef HAVE_PJSIP_TLS_TRANSPORT_RESTART
1052 if (stat(
var->value, &
state->cert_file_stat)) {
1053 ast_log(
LOG_ERROR,
"Failed to stat certificate file '%s' for transport '%s' due to '%s'\n",
1059 }
else if (!strcasecmp(
var->name,
"priv_key_file")) {
1060 state->tls.privkey_file = pj_str((
char *)
var->value);
1062#ifdef HAVE_PJSIP_TLS_TRANSPORT_RESTART
1063 if (stat(
var->value, &
state->privkey_file_stat)) {
1064 ast_log(
LOG_ERROR,
"Failed to stat private key file '%s' for transport '%s' due to '%s'\n",
1121 if (!strcasecmp(
var->value,
"flow")) {
1122 transport->
flow = 1;
1124 if (!strcasecmp(
var->value,
"udp")) {
1126 }
else if (!strcasecmp(
var->value,
"tcp")) {
1128 }
else if (!strcasecmp(
var->value,
"tls")) {
1130 }
else if (!strcasecmp(
var->value,
"ws")) {
1132 }
else if (!strcasecmp(
var->value,
"wss")) {
1137 transport->
flow = 0;
1157 if (transport->
flow) {
1178 rc = pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&
buf,
var->value), &
state->host);
1180 return rc != PJ_SUCCESS ? -1 : 0;
1212 if (!strcasecmp(
var->name,
"verify_server")) {
1214 }
else if (!strcasecmp(
var->name,
"verify_client")) {
1216 }
else if (!strcasecmp(
var->name,
"require_client_cert")) {
1217 state->tls.require_client_cert =
ast_true(
var->value) ? PJ_TRUE : PJ_FALSE;
1218 }
else if (!strcasecmp(
var->name,
"allow_wildcard_certs")) {
1294 state->tls.method = PJSIP_SSL_DEFAULT_METHOD;
1295 }
else if (!strcasecmp(
var->value,
"unspecified")) {
1296 state->tls.method = PJSIP_SSL_UNSPECIFIED_METHOD;
1297 }
else if (!strcasecmp(
var->value,
"tlsv1")) {
1298 state->tls.method = PJSIP_TLSV1_METHOD;
1299#ifdef HAVE_PJSIP_TLS_1_1
1300 }
else if (!strcasecmp(
var->value,
"tlsv1_1")) {
1301 state->tls.method = PJSIP_TLSV1_1_METHOD;
1303#ifdef HAVE_PJSIP_TLS_1_2
1304 }
else if (!strcasecmp(
var->value,
"tlsv1_2")) {
1305 state->tls.method = PJSIP_TLSV1_2_METHOD;
1307#ifdef HAVE_PJSIP_TLS_1_3
1308 }
else if (!strcasecmp(
var->value,
"tlsv1_3")) {
1309 state->tls.method = PJSIP_TLSV1_3_METHOD;
1311 }
else if (!strcasecmp(
var->value,
"sslv2")) {
1312 state->tls.method = PJSIP_SSLV2_METHOD;
1313 }
else if (!strcasecmp(
var->value,
"sslv3")) {
1314 state->tls.method = PJSIP_SSLV3_METHOD;
1315 }
else if (!strcasecmp(
var->value,
"sslv23")) {
1316 state->tls.method = PJSIP_SSLV23_METHOD;
1325 [PJSIP_SSL_UNSPECIFIED_METHOD] =
"unspecified",
1326 [PJSIP_TLSV1_METHOD] =
"tlsv1",
1327#ifdef HAVE_PJSIP_TLS_1_1
1328 [PJSIP_TLSV1_1_METHOD] =
"tlsv1_1",
1330#ifdef HAVE_PJSIP_TLS_1_2
1331 [PJSIP_TLSV1_2_METHOD] =
"tlsv1_2",
1333#ifdef HAVE_PJSIP_TLS_1_3
1334 [PJSIP_TLSV1_3_METHOD] =
"tlsv1_3",
1336 [PJSIP_SSLV2_METHOD] =
"sslv2",
1337 [PJSIP_SSLV3_METHOD] =
"sslv3",
1338 [PJSIP_SSLV23_METHOD] =
"sslv23",
1357#if defined(PJ_HAS_SSL_SOCK) && PJ_HAS_SSL_SOCK != 0
1359static pj_ssl_cipher cipher_name_to_id(
const char *
name)
1361 pj_ssl_cipher
ciphers[PJ_SSL_SOCK_MAX_CIPHERS];
1362 unsigned int cipher_num = PJ_ARRAY_SIZE(
ciphers);
1365 if (pj_ssl_cipher_get_availables(
ciphers, &cipher_num)) {
1369 for (pos = 0; pos < cipher_num; ++pos) {
1370 const char *pos_name = pj_ssl_cipher_name(
ciphers[pos]);
1371 if (pos_name && !strcmp(pos_name,
name)) {
1380#if defined(PJ_HAS_SSL_SOCK) && PJ_HAS_SSL_SOCK != 0
1393 pj_ssl_cipher cipher;
1396 cipher = cipher_name_to_id(
name);
1399 if (!strnicmp(
name,
"0x", 2)) {
1400 pj_str_t cipher_st = pj_str((
char *)
name + 2);
1401 cipher = pj_strtoul2(&cipher_st,
NULL, 16);
1403 cipher = atoi(
name);
1407 if (pj_ssl_cipher_is_supported(cipher)) {
1408 for (idx =
state->tls.ciphers_num; idx--;) {
1409 if (
state->ciphers[idx] == cipher) {
1414 state->ciphers[
state->tls.ciphers_num++] = cipher;
1423#if defined(PJ_HAS_SSL_SOCK) && PJ_HAS_SSL_SOCK != 0
1447 res |= transport_cipher_add(
state,
name);
1449 return res ? -1 : 0;
1453#if defined(PJ_HAS_SSL_SOCK) && PJ_HAS_SSL_SOCK != 0
1454static void cipher_to_str(
char **
buf,
const pj_ssl_cipher *
ciphers,
unsigned int cipher_num)
1465 for (idx = 0; idx < cipher_num; ++idx) {
1467 if (idx < cipher_num - 1) {
1477#if defined(PJ_HAS_SSL_SOCK) && PJ_HAS_SSL_SOCK != 0
1478static int transport_tls_cipher_to_str(
const void *obj,
const intptr_t *
args,
char **
buf)
1488 return *
buf ? 0 : -1;
1492#if defined(PJ_HAS_SSL_SOCK) && PJ_HAS_SSL_SOCK != 0
1495 pj_ssl_cipher
ciphers[PJ_SSL_SOCK_MAX_CIPHERS];
1496 unsigned int cipher_num = PJ_ARRAY_SIZE(
ciphers);
1501 e->
command =
"pjsip list ciphers";
1502 e->
usage =
"Usage: pjsip list ciphers\n"
1503 " List available OpenSSL cipher names.\n";
1509 if (pj_ssl_cipher_get_availables(
ciphers, &cipher_num) || !cipher_num) {
1518 ast_cli(
a->fd,
"No available ciphers\n");
1572 for (ha =
state->localnet; ha; ha = ha->
next) {
1606 "interpret 'tos' value '%s'\n",
1615 "transport '%s' - 'tos' value '%s' uses bits that are "
1616 "discarded when converted to DSCP. Using equivalent %u instead.\n",
1669 return callback(transport,
args, 0);
1686 "%*s: <TransportId........> <Type> <cos> <tos> <BindAddress%*.*s>\n",
1696 char hoststr[PJ_INET6_ADDRSTRLEN];
1705 pj_sockaddr_print(&
state->host, hoststr,
sizeof(hoststr), 3);
1711 transport->
cos, transport->
tos, hoststr);
1714 || (
context->show_details_only_level_0 &&
context->indent_level == 0)) {
1723#if defined(PJ_HAS_SSL_SOCK) && PJ_HAS_SSL_SOCK != 0
1724 AST_CLI_DEFINE(handle_pjsip_list_ciphers,
"List available OpenSSL cipher names"),
1727 .
command =
"pjsip list transports",
1728 .
usage =
"Usage: pjsip list transports [ like <pattern> ]\n"
1729 " List the configured PJSIP Transports\n"
1730 " Optional regular expression pattern is used to filter the list.\n"),
1732 .
command =
"pjsip show transports",
1733 .
usage =
"Usage: pjsip show transports [ like <pattern> ]\n"
1734 " Show the configured PJSIP Transport\n"
1735 " Optional regular expression pattern is used to filter the list.\n"),
1737 .
command =
"pjsip show transport",
1738 .
usage =
"Usage: pjsip show transport <id>\n"
1739 " Show the configured PJSIP Transport\n"),
1762 if (trans_state->
flow) {
1765 pjsip_transport_dec_ref(trans_state->
transport);
1842#if defined(PJ_HAS_SSL_SOCK) && PJ_HAS_SSL_SOCK != 0
Access Control of various sorts.
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
int ast_str2tos(const char *value, unsigned int *tos)
Convert a string to the appropriate TOS value.
void ast_ha_join(const struct ast_ha *ha, struct ast_str **buf)
Convert HAs to a comma separated string value.
struct ast_ha * ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule to a list of HAs.
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
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ast_calloc(num, len)
A wrapper for calloc()
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_link(container, obj)
Add an object to a container.
@ AO2_ALLOC_OPT_LOCK_NOLOCK
@ AO2_ALLOC_OPT_LOCK_MUTEX
#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_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_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_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,...)
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
@ OPT_UINT_T
Type for default option handler for unsigned integers.
@ OPT_BOOL_T
Type for default option handler for bools (ast_true/ast_false)
@ OPT_INT_T
Type for default option handler for signed integers.
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.
static struct ast_sip_transport_state * find_temporary_state(struct ast_sip_transport *transport)
static int require_client_cert_to_str(const void *obj, const intptr_t *args, char **buf)
static int transport_state_init(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom handler for type just makes sure the state is created.
int ast_sip_initialize_sorcery_transport(void)
Initialize sorcery with transport support.
static struct ast_cli_entry cli_commands[]
static int verify_server_to_str(const void *obj, const intptr_t *args, char **buf)
static int transport_tls_method_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom handler for TLS method setting.
int ast_sip_transport_state_set_transport(const char *transport_name, pjsip_transport *transport)
Sets the PJSIP transport on a child transport.
static int format_ami_endpoint_transport(const struct ast_sip_endpoint *endpoint, struct ast_sip_ami *ami)
static int transport_state_hash(const void *obj, const int flags)
hashing function for state objects
static int cli_print_header(void *obj, void *arg, int flags)
struct ao2_container * ast_sip_get_transport_states(void)
Retrieves all transport states.
static int destroy_sip_transport_state(void *data)
static int transport_state_cmp(void *obj, void *arg, int flags)
comparator function for state objects
static int transport_bind_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom handler for turning a string bind into a pj_sockaddr.
static int tls_method_to_str(const void *obj, const intptr_t *args, char **buf)
static void sip_transport_state_destroy(void *obj)
Destructor for ast_sip_transport state information.
static int transport_protocol_to_str(const void *obj, const intptr_t *args, char **buf)
static void sip_transport_destroy(void *obj)
Destructor for transport.
#define DEFAULT_STATE_BUCKETS
Default number of state container buckets.
static int internal_state_hash(const void *obj, const int flags)
hashing function for state objects
static int verify_client_to_str(const void *obj, const intptr_t *args, char **buf)
static void localnet_to_vl_append(struct ast_variable **head, struct ast_ha *ha)
static int allow_wildcard_certs_to_str(const void *obj, const intptr_t *args, char **buf)
static int cert_file_to_str(const void *obj, const intptr_t *args, char **buf)
static int transport_tls_bool_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom handler for TLS boolean settings.
void ast_sip_message_apply_transport(const char *transport_name, pjsip_tx_data *tdata)
Apply the configuration for a transport to an outgoing message.
static int transport_bind_to_str(const void *obj, const intptr_t *args, char **buf)
static struct ast_sip_transport_state * find_state_by_transport(const struct ast_sip_transport *transport)
static struct ast_sip_transport_state * find_or_create_temporary_state(struct ast_sip_transport *transport)
static int internal_state_cmp(void *obj, void *arg, int flags)
comparator function for state objects
void ast_sip_service_route_vector_destroy(struct ast_sip_service_route_vector *service_routes)
Destroy a vector of service routes.
static int localnet_to_str(const void *obj, const intptr_t *args, char **buf)
static int privkey_file_to_str(const void *obj, const intptr_t *args, char **buf)
static int sip_transport_to_ami(const struct ast_sip_transport *transport, struct ast_str **buf)
static int cli_iterate(void *container, ao2_callback_fn callback, void *args)
static void copy_state_to_transport(struct ast_sip_transport *transport)
static struct internal_state * internal_state_alloc(struct ast_sip_transport *transport)
static int transport_localnet_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom handler for localnet setting.
static void * cli_retrieve_by_id(const char *id)
static struct internal_state * find_internal_state_by_transport(const struct ast_sip_transport *transport)
static int populate_transport_states(void *obj, void *arg, int flags)
static void temp_state_store_cleanup(void *data)
static void set_qos(struct ast_sip_transport *transport, pj_qos_params *qos)
struct ast_sip_service_route_vector * ast_sip_service_route_vector_alloc(void)
Allocate a vector of service routes.
static int tos_to_str(const void *obj, const intptr_t *args, char **buf)
static struct ao2_container * cli_get_container(const char *regex)
static int transport_apply(const struct ast_sorcery *sorcery, void *obj)
Apply handler for transports.
static int cli_print_body(void *obj, void *arg, int flags)
struct ast_sip_transport_state * ast_sip_get_transport_state(const char *transport_id)
Retrieve transport state.
static int localnet_to_vl(const void *obj, struct ast_variable **fields)
static int transport_tls_file_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom handler for TLS method setting.
int ast_sip_destroy_sorcery_transport(void)
static const char * transport_types[]
struct ast_sip_endpoint_formatter endpoint_transport_formatter
static int transport_tos_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom handler for TOS setting.
static int ca_list_file_to_str(const void *obj, const intptr_t *args, char **buf)
static struct ast_threadstorage temp_state_store
static struct ast_sip_cli_formatter_entry * cli_formatter
static void * sip_transport_alloc(const char *name)
Allocator for transport.
static int remove_temporary_state(void)
static void internal_state_destroy(void *obj)
Destructor for ast_sip_transport state information.
static int ca_list_path_to_str(const void *obj, const intptr_t *args, char **buf)
int ast_sip_transport_state_set_preferred_identity(const char *transport_name, const char *identity)
Sets the P-Preferred-Identity on a child transport.
static const char * tls_method_map[]
static int has_state_changed(struct ast_sip_transport_state *a, struct ast_sip_transport_state *b)
static int transport_protocol_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom handler for turning a string protocol into an enum.
int ast_sip_transport_state_set_service_routes(const char *transport_name, struct ast_sip_service_route_vector *service_routes)
Sets the service routes on a child transport.
static struct ao2_container * transport_states
static void states_cleanup(void *states)
void ast_dnsmgr_release(struct ast_dnsmgr_entry *entry)
Free a DNS manager entry.
int ast_dnsmgr_lookup(const char *name, struct ast_sockaddr *result, struct ast_dnsmgr_entry **dnsmgr, const char *service)
Allocate and initialize a DNS manager entry.
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
void astman_send_error_va(struct mansession *s, const struct message *m, const char *fmt,...)
Send error in manager transaction (with va_args support)
void astman_append(struct mansession *s, const char *fmt,...)
int ast_sip_push_task_wait_servant(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Push a task to SIP servants and wait for it to complete.
Support for WebSocket connections within the Asterisk HTTP server and client WebSocket connections to...
#define AST_DEFAULT_WEBSOCKET_WRITE_TIMEOUT_STR
Default websocket write timeout, in ms (as a string)
char * strsep(char **str, const char *delims)
#define ast_variable_new(name, value, filename)
#define ast_variable_list_append(head, new_var)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Support for logging to various files, console and syslog Configuration in file logger....
#define ast_debug(level,...)
Log a DEBUG message.
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
struct ao2_container * container
#define AST_SIP_X_AST_TXP
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
#define SIP_TLS_MAX_CIPHERS
Maximum number of ciphers supported for a TLS transport.
void ast_sip_register_endpoint_formatter(struct ast_sip_endpoint_formatter *obj)
Register an endpoint formatter.
void ast_sip_unregister_endpoint_formatter(struct ast_sip_endpoint_formatter *obj)
Unregister an endpoint formatter.
int ast_sip_sorcery_object_to_ami(const void *obj, struct ast_str **buf)
Converts a sorcery object to a string of object properties.
struct ast_str * ast_sip_create_ami_event(const char *event, struct ast_sip_ami *ami)
Creates a string to store AMI event data in.
int ast_sip_add_header(pjsip_tx_data *tdata, const char *name, const char *value)
Add a header to an outbound SIP message.
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
#define AST_SIP_X_AST_TXP_LEN
int ast_sip_unregister_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Unregisters a CLI formatter.
#define CLI_HEADER_FILLER
int ast_sip_cli_print_sorcery_objectset(void *obj, void *arg, int flags)
Prints a sorcery object's ast_variable list.
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.
static struct ast_sorcery * sorcery
Sorcery Data Access Layer API.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
@ AST_RETRIEVE_FLAG_ALL
Perform no matching, return all objects.
void ast_sorcery_object_set_has_dynamic_contents(const void *object)
Set the dynamic contents flag on a sorcery object.
int ast_sorcery_diff(const struct ast_sorcery *sorcery, const void *original, const void *modified, struct ast_variable **changes)
Create a changeset of two objects.
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
struct ao2_container * ast_sorcery_retrieve_by_regex(const struct ast_sorcery *sorcery, const char *type, const char *regex)
Retrieve multiple objects using a regular expression on their id.
#define ast_sorcery_object_field_register_custom(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags,...)
Register a field within an object with custom handlers.
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
#define MAX_OBJECT_FIELD
Maximum length of an object field name.
#define ast_sorcery_apply_default(sorcery, type, name, data)
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
#define AST_YESNO(x)
return Yes or No depending on the argument.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
descriptor for a cli entry.
internal representation of ACL entries In principle user applications would have no need for this,...
struct ast_sockaddr netmask
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.
const ast_string_field transport
Structure for SIP transport information.
struct ast_dnsmgr_entry * external_media_address_refresher
struct ast_sip_service_route_vector * service_routes
char * preferred_identity
struct pjsip_transport * transport
Transport itself.
struct ast_dnsmgr_entry * external_signaling_address_refresher
pj_ssl_cipher ciphers[SIP_TLS_MAX_CIPHERS]
const ast_string_field privkey_file
const ast_string_field ca_list_path
const ast_string_field cert_file
const ast_string_field password
int tcp_keepalive_probe_count
const ast_string_field external_signaling_address
const ast_string_field ca_list_file
struct ast_sip_transport_state * state
unsigned int async_operations
pj_ssl_cipher ciphers[SIP_TLS_MAX_CIPHERS]
const ast_string_field external_media_address
int tcp_keepalive_interval_time
int tcp_keepalive_idle_time
Full structure for sorcery.
Support for dynamic strings.
Structure for variables, used for configurations and for channel variables.
struct ast_sip_transport_state * state
Transport state information.
struct ast_sip_transport * transport
Transport configuration object.
#define AST_THREADSTORAGE_CUSTOM(a, b, c)
Define a thread storage variable, with custom initialization and cleanup.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
int error(const char *format,...)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
int ast_file_is_readable(const char *filename)
Test that a file exists and is readable by the effective user.
int ast_compare_versions(const char *version1, const char *version2)
Compare 2 major.minor.patch.extra version strings.
#define ARRAY_IN_BOUNDS(v, a)
Checks to see if value is within the bounds of the given array.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
#define AST_VECTOR_CALLBACK_VOID(vec, callback,...)
Execute a callback on every element in a vector disregarding callback return.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.