config_transport.c File Reference

#include "asterisk.h"
#include <pjsip.h>
#include <pjlib.h>
#include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_cli.h"
#include "asterisk/logger.h"
#include "asterisk/astobj2.h"
#include "asterisk/sorcery.h"
#include "asterisk/acl.h"
#include "include/res_pjsip_private.h"
#include "asterisk/http_websocket.h"

Include dependency graph for config_transport.c:

Go to the source code of this file.

Functions

int ast_sip_destroy_sorcery_transport (void)
int ast_sip_initialize_sorcery_transport (void)
 Initialize sorcery with transport support.
static pj_ssl_cipher cipher_name_to_id (const char *name)
 Helper function which turns a cipher name into an identifier.
static void cipher_to_str (char **buf, const pj_ssl_cipher *ciphers, unsigned int cipher_num)
static struct ao2_containercli_get_container (void)
static int cli_iterate (void *container, ao2_callback_fn callback, void *args)
static int cli_print_body (void *obj, void *arg, int flags)
static int cli_print_header (void *obj, void *arg, int flags)
static void * cli_retrieve_by_id (const char *id)
static int destroy_transport_state (void *data)
static int format_ami_endpoint_transport (const struct ast_sip_endpoint *endpoint, struct ast_sip_ami *ami)
static char * handle_pjsip_list_ciphers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int localnet_to_str (const void *obj, const intptr_t *args, char **buf)
static int localnet_to_vl (const void *obj, struct ast_variable **fields)
static int require_client_cert_to_str (const void *obj, const intptr_t *args, char **buf)
static void set_qos (struct ast_sip_transport *transport, pj_qos_params *qos)
static int sip_transport_to_ami (const struct ast_sip_transport *transport, struct ast_str **buf)
static int tls_method_to_str (const void *obj, const intptr_t *args, char **buf)
static int tos_to_str (const void *obj, const intptr_t *args, char **buf)
static void * transport_alloc (const char *name)
 Allocator for transport.
static int transport_apply (const struct ast_sorcery *sorcery, void *obj)
 Apply handler for transports.
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 transport_bind_to_str (const void *obj, const intptr_t *args, char **buf)
static int transport_cipher_add (struct ast_sip_transport *transport, const char *name)
static void transport_destroy (void *obj)
 Destructor for transport.
static int transport_localnet_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Custom handler for localnet setting.
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.
static int transport_protocol_to_str (const void *obj, const intptr_t *args, char **buf)
static void transport_state_destroy (void *obj)
 Destructor for transport state information.
static int transport_tls_bool_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Custom handler for TLS boolean settings.
static int transport_tls_cipher_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Custom handler for TLS cipher setting.
static int transport_tls_cipher_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.
static int transport_tos_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Custom handler for TOS setting.
static int verify_client_to_str (const void *obj, const intptr_t *args, char **buf)
static int verify_server_to_str (const void *obj, const intptr_t *args, char **buf)

Variables

static struct ast_cli_entry cli_commands []
static struct
ast_sip_cli_formatter_entry
cli_formatter
struct ast_sip_endpoint_formatter endpoint_transport_formatter
static const char * tls_method_map []
static const char * transport_types []


Function Documentation

int ast_sip_destroy_sorcery_transport ( void   ) 

int ast_sip_initialize_sorcery_transport ( void   ) 

Initialize sorcery with transport support.

Definition at line 738 of file config_transport.c.

References ao2_alloc, ARRAY_LEN, ast_cli_register_multiple(), AST_DEFAULT_WEBSOCKET_WRITE_TIMEOUT_STR, ast_log, ast_sip_get_sorcery(), ast_sip_register_cli_formatter(), ast_sorcery_apply_default, ast_sorcery_object_field_register, ast_sorcery_object_field_register_custom, ast_sorcery_object_get_id(), ast_sorcery_object_register_no_reload, cli_get_container(), cli_iterate(), cli_print_body(), cli_print_header(), cli_retrieve_by_id(), cos, FLDSET, ast_sip_cli_formatter_entry::get_container, ast_sip_cli_formatter_entry::get_id, internal_sip_register_endpoint_formatter(), ast_sip_cli_formatter_entry::iterate, localnet_to_str(), localnet_to_vl(), LOG_ERROR, ast_sip_cli_formatter_entry::name, NULL, OPT_INT_T, OPT_NOOP_T, OPT_STRINGFIELD_T, OPT_UINT_T, PARSE_IN_RANGE, password, ast_sip_cli_formatter_entry::print_body, ast_sip_cli_formatter_entry::print_header, require_client_cert_to_str(), ast_sip_cli_formatter_entry::retrieve_by_id, sorcery, STRFLDSET, tls_method_to_str(), tos_to_str(), transport_alloc(), transport_apply(), transport_bind_handler(), transport_bind_to_str(), transport_localnet_handler(), transport_protocol_handler(), transport_protocol_to_str(), transport_tls_bool_handler(), transport_tls_cipher_handler(), transport_tls_cipher_to_str(), transport_tls_method_handler(), transport_tos_handler(), verify_client_to_str(), and verify_server_to_str().

Referenced by ast_res_pjsip_initialize_configuration().

00739 {
00740    struct ast_sorcery *sorcery = ast_sip_get_sorcery();
00741 
00742    ast_sorcery_apply_default(sorcery, "transport", "config", "pjsip.conf,criteria=type=transport");
00743 
00744    if (ast_sorcery_object_register_no_reload(sorcery, "transport", transport_alloc, NULL, transport_apply)) {
00745       return -1;
00746    }
00747 
00748    ast_sorcery_object_field_register(sorcery, "transport", "type", "", OPT_NOOP_T, 0, 0);
00749    ast_sorcery_object_field_register_custom(sorcery, "transport", "protocol", "udp", transport_protocol_handler, transport_protocol_to_str, NULL, 0, 0);
00750    ast_sorcery_object_field_register_custom(sorcery, "transport", "bind", "", transport_bind_handler, transport_bind_to_str, NULL, 0, 0);
00751    ast_sorcery_object_field_register(sorcery, "transport", "async_operations", "1", OPT_UINT_T, 0, FLDSET(struct ast_sip_transport, async_operations));
00752    ast_sorcery_object_field_register(sorcery, "transport", "ca_list_file", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, ca_list_file));
00753    ast_sorcery_object_field_register(sorcery, "transport", "ca_list_path", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, ca_list_path));
00754    ast_sorcery_object_field_register(sorcery, "transport", "cert_file", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, cert_file));
00755    ast_sorcery_object_field_register(sorcery, "transport", "priv_key_file", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, privkey_file));
00756    ast_sorcery_object_field_register(sorcery, "transport", "password", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, password));
00757    ast_sorcery_object_field_register(sorcery, "transport", "external_signaling_address", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, external_signaling_address));
00758    ast_sorcery_object_field_register(sorcery, "transport", "external_signaling_port", "0", OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_sip_transport, external_signaling_port), 0, 65535);
00759    ast_sorcery_object_field_register(sorcery, "transport", "external_media_address", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, external_media_address));
00760    ast_sorcery_object_field_register(sorcery, "transport", "domain", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, domain));
00761    ast_sorcery_object_field_register_custom(sorcery, "transport", "verify_server", "", transport_tls_bool_handler, verify_server_to_str, NULL, 0, 0);
00762    ast_sorcery_object_field_register_custom(sorcery, "transport", "verify_client", "", transport_tls_bool_handler, verify_client_to_str, NULL, 0, 0);
00763    ast_sorcery_object_field_register_custom(sorcery, "transport", "require_client_cert", "", transport_tls_bool_handler, require_client_cert_to_str, NULL, 0, 0);
00764    ast_sorcery_object_field_register_custom(sorcery, "transport", "method", "", transport_tls_method_handler, tls_method_to_str, NULL, 0, 0);
00765    ast_sorcery_object_field_register_custom(sorcery, "transport", "cipher", "", transport_tls_cipher_handler, transport_tls_cipher_to_str, NULL, 0, 0);
00766    ast_sorcery_object_field_register_custom(sorcery, "transport", "local_net", "", transport_localnet_handler, localnet_to_str, localnet_to_vl, 0, 0);
00767    ast_sorcery_object_field_register_custom(sorcery, "transport", "tos", "0", transport_tos_handler, tos_to_str, NULL, 0, 0);
00768    ast_sorcery_object_field_register(sorcery, "transport", "cos", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_transport, cos));
00769    ast_sorcery_object_field_register(sorcery, "transport", "websocket_write_timeout", AST_DEFAULT_WEBSOCKET_WRITE_TIMEOUT_STR, OPT_INT_T, PARSE_IN_RANGE, FLDSET(struct ast_sip_transport, write_timeout), 1, INT_MAX);
00770 
00771    internal_sip_register_endpoint_formatter(&endpoint_transport_formatter);
00772 
00773    cli_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
00774    if (!cli_formatter) {
00775       ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
00776       return -1;
00777    }
00778    cli_formatter->name = "transport";
00779    cli_formatter->print_header = cli_print_header;
00780    cli_formatter->print_body = cli_print_body;
00781    cli_formatter->get_container = cli_get_container;
00782    cli_formatter->iterate = cli_iterate;
00783    cli_formatter->get_id = ast_sorcery_object_get_id;
00784    cli_formatter->retrieve_by_id = cli_retrieve_by_id;
00785 
00786    ast_sip_register_cli_formatter(cli_formatter);
00787    ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands));
00788 
00789    return 0;
00790 }

static pj_ssl_cipher cipher_name_to_id ( const char *  name  )  [static]

Helper function which turns a cipher name into an identifier.

Definition at line 397 of file config_transport.c.

References ast_sip_transport::ciphers.

Referenced by transport_cipher_add().

00398 {
00399    pj_ssl_cipher ciphers[100];
00400    pj_ssl_cipher id = 0;
00401    unsigned int cipher_num = PJ_ARRAY_SIZE(ciphers);
00402    int pos;
00403    const char *pos_name;
00404 
00405    if (pj_ssl_cipher_get_availables(ciphers, &cipher_num)) {
00406       return 0;
00407    }
00408 
00409    for (pos = 0; pos < cipher_num; ++pos) {
00410       pos_name = pj_ssl_cipher_name(ciphers[pos]);
00411       if (!pos_name || strcmp(pos_name, name)) {
00412          continue;
00413       }
00414 
00415       id = ciphers[pos];
00416       break;
00417    }
00418 
00419    return id;
00420 }

static void cipher_to_str ( char **  buf,
const pj_ssl_cipher *  ciphers,
unsigned int  cipher_num 
) [static]

Definition at line 487 of file config_transport.c.

References ast_free, ast_str_append(), ast_str_buffer(), ast_str_create(), ast_strdup, NULL, and str.

Referenced by handle_pjsip_list_ciphers(), and transport_tls_cipher_to_str().

00488 {
00489    struct ast_str *str;
00490    int idx;
00491 
00492    str = ast_str_create(128);
00493    if (!str) {
00494       *buf = NULL;
00495       return;
00496    }
00497 
00498    for (idx = 0; idx < cipher_num; ++idx) {
00499       ast_str_append(&str, 0, "%s", pj_ssl_cipher_name(ciphers[idx]));
00500       if (idx < cipher_num - 1) {
00501          ast_str_append(&str, 0, ", ");
00502       }
00503    }
00504 
00505    *buf = ast_strdup(ast_str_buffer(str));
00506    ast_free(str);
00507 }

static struct ao2_container* cli_get_container ( void   )  [static, read]

Definition at line 636 of file config_transport.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_list, ao2_container_dup(), ao2_ref, AST_RETRIEVE_FLAG_ALL, AST_RETRIEVE_FLAG_MULTIPLE, ast_sip_get_sorcery(), ast_sorcery_object_id_compare(), ast_sorcery_object_id_sort(), ast_sorcery_retrieve_by_fields(), container, NULL, and RAII_VAR.

00637 {
00638    RAII_VAR(struct ao2_container *, container, NULL, ao2_cleanup);
00639    struct ao2_container *s_container;
00640 
00641    container = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "transport",
00642       AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
00643    if (!container) {
00644       return NULL;
00645    }
00646 
00647    s_container = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0,
00648       ast_sorcery_object_id_sort, ast_sorcery_object_id_compare);
00649    if (!s_container) {
00650       return NULL;
00651    }
00652 
00653    if (ao2_container_dup(s_container, container, 0)) {
00654       ao2_ref(s_container, -1);
00655       return NULL;
00656    }
00657 
00658    return s_container;
00659 }

static int cli_iterate ( void *  container,
ao2_callback_fn  callback,
void *  args 
) [static]

Definition at line 661 of file config_transport.c.

References ast_sip_get_sorcery(), ast_sorcery_retrieve_by_id(), and ast_sip_endpoint::transport.

Referenced by ast_sip_initialize_sorcery_transport().

00662 {
00663    const struct ast_sip_endpoint *endpoint = container;
00664    struct ast_sip_transport *transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(),
00665       "transport", endpoint->transport);
00666 
00667    if (!transport) {
00668       return -1;
00669    }
00670 
00671    return callback(transport, args, 0);
00672 }

static int cli_print_body ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 694 of file config_transport.c.

References ARRAY_IN_BOUNDS, ast_assert, ast_sip_cli_print_sorcery_objectset(), ast_sorcery_object_get_id(), ast_str_append(), CLI_INDENT_TO_SPACES, context, ast_sip_transport::cos, ast_sip_transport::host, ast_sip_cli_context::indent_level, NULL, ast_sip_cli_context::output_buffer, ast_sip_cli_context::show_details, ast_sip_cli_context::show_details_only_level_0, ast_sip_transport::tos, transport_types, and ast_sip_transport::type.

00695 {
00696    struct ast_sip_transport *transport = obj;
00697    struct ast_sip_cli_context *context = arg;
00698    char hoststr[PJ_INET6_ADDRSTRLEN];
00699 
00700    ast_assert(context->output_buffer != NULL);
00701 
00702    pj_sockaddr_print(&transport->host, hoststr, sizeof(hoststr), 3);
00703 
00704    ast_str_append(&context->output_buffer, 0, "%*s:  %-21s  %6s  %5u  %5u  %s\n",
00705       CLI_INDENT_TO_SPACES(context->indent_level), "Transport",
00706       ast_sorcery_object_get_id(transport),
00707       ARRAY_IN_BOUNDS(transport->type, transport_types) ? transport_types[transport->type] : "Unknown",
00708       transport->cos, transport->tos, hoststr);
00709 
00710    if (context->show_details
00711       || (context->show_details_only_level_0 && context->indent_level == 0)) {
00712       ast_str_append(&context->output_buffer, 0, "\n");
00713       ast_sip_cli_print_sorcery_objectset(transport, context, 0);
00714    }
00715 
00716    return 0;
00717 }

static int cli_print_header ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 679 of file config_transport.c.

References ast_assert, ast_str_append(), CLI_HEADER_FILLER, CLI_INDENT_TO_SPACES, CLI_MAX_WIDTH, context, ast_sip_cli_context::indent_level, NULL, and ast_sip_cli_context::output_buffer.

00680 {
00681    struct ast_sip_cli_context *context = arg;
00682    int indent = CLI_INDENT_TO_SPACES(context->indent_level);
00683    int filler = CLI_MAX_WIDTH - indent - 61;
00684 
00685    ast_assert(context->output_buffer != NULL);
00686 
00687    ast_str_append(&context->output_buffer, 0,
00688       "%*s:  <TransportId........>  <Type>  <cos>  <tos>  <BindAddress%*.*s>\n",
00689       indent, "Transport", filler, filler, CLI_HEADER_FILLER);
00690 
00691    return 0;
00692 }

static void* cli_retrieve_by_id ( const char *  id  )  [static]

Definition at line 674 of file config_transport.c.

References ast_sip_get_sorcery(), and ast_sorcery_retrieve_by_id().

00675 {
00676    return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", id);
00677 }

static int destroy_transport_state ( void *  data  )  [static]

Definition at line 77 of file config_transport.c.

Referenced by transport_state_destroy().

00078 {
00079    pjsip_transport *transport = data;
00080    pjsip_transport_shutdown(transport);
00081    return 0;
00082 }

static int format_ami_endpoint_transport ( const struct ast_sip_endpoint endpoint,
struct ast_sip_ami ami 
) [static]

Definition at line 39 of file config_transport.c.

References ao2_cleanup, ast_free, ast_sip_create_ami_event(), ast_sip_get_sorcery(), ast_sorcery_object_get_id(), ast_sorcery_retrieve_by_id(), ast_str_append(), ast_str_buffer(), ast_strlen_zero, astman_append(), astman_send_error_va(), buf, ast_sip_ami::count, ast_sip_ami::m, NULL, RAII_VAR, ast_sip_ami::s, sip_transport_to_ami(), and ast_sip_endpoint::transport.

00041 {
00042    RAII_VAR(struct ast_str *, buf, NULL, ast_free);
00043    RAII_VAR(struct ast_sip_transport *, transport, NULL, ao2_cleanup);
00044 
00045    if (ast_strlen_zero(endpoint->transport)) {
00046       return 0;
00047    }
00048 
00049    buf = ast_sip_create_ami_event("TransportDetail", ami);
00050    if (!buf) {
00051       return -1;
00052    }
00053 
00054    transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport",
00055       endpoint->transport);
00056    if (!transport) {
00057       astman_send_error_va(ami->s, ami->m, "Unable to retrieve "
00058                  "transport %s\n", endpoint->transport);
00059       return -1;
00060    }
00061 
00062    sip_transport_to_ami(transport, &buf);
00063 
00064    ast_str_append(&buf, 0, "EndpointName: %s\r\n",
00065              ast_sorcery_object_get_id(endpoint));
00066 
00067    astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
00068    ami->count++;
00069 
00070    return 0;
00071 }

static char* handle_pjsip_list_ciphers ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 517 of file config_transport.c.

References ast_cli(), ast_free, ast_strlen_zero, buf, cipher_to_str(), ast_sip_transport::ciphers, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, NULL, and ast_cli_entry::usage.

00518 {
00519    pj_ssl_cipher ciphers[100];
00520    unsigned int cipher_num = PJ_ARRAY_SIZE(ciphers);
00521    char *buf;
00522 
00523    switch (cmd) {
00524    case CLI_INIT:
00525       e->command = "pjsip list ciphers";
00526       e->usage = "Usage: pjsip list ciphers\n"
00527          "       List available OpenSSL cipher names.\n";
00528       return NULL;
00529    case CLI_GENERATE:
00530       return NULL;
00531    }
00532 
00533    if (pj_ssl_cipher_get_availables(ciphers, &cipher_num) || !cipher_num) {
00534       buf = NULL;
00535    } else {
00536       cipher_to_str(&buf, ciphers, cipher_num);
00537    }
00538 
00539    if (!ast_strlen_zero(buf)) {
00540       ast_cli(a->fd, "Available ciphers: '%s'\n", buf);
00541    } else {
00542       ast_cli(a->fd, "No available ciphers\n");
00543    }
00544    ast_free(buf);
00545    return CLI_SUCCESS;
00546 }

static int localnet_to_str ( const void *  obj,
const intptr_t *  args,
char **  buf 
) [static]

Definition at line 590 of file config_transport.c.

References ast_free, ast_ha_join(), ast_str_buffer(), ast_str_create(), ast_strdup, ast_sip_transport::localnet, MAX_OBJECT_FIELD, RAII_VAR, and str.

Referenced by ast_sip_initialize_sorcery_transport().

00591 {
00592    RAII_VAR(struct ast_str *, str, ast_str_create(MAX_OBJECT_FIELD), ast_free);
00593    const struct ast_sip_transport *transport = obj;
00594 
00595    ast_ha_join(transport->localnet, &str);
00596    *buf = ast_strdup(ast_str_buffer(str));
00597    return 0;
00598 }

static int localnet_to_vl ( const void *  obj,
struct ast_variable **  fields 
) [static]

Definition at line 567 of file config_transport.c.

References ast_ha::addr, AST_SENSE_ALLOW, ast_sockaddr_stringify_addr(), ast_strdupa, ast_variable_list_append, ast_variable_new(), ast_sip_transport::localnet, MAX_OBJECT_FIELD, ast_ha::netmask, ast_ha::next, NULL, ast_ha::sense, and str.

Referenced by ast_sip_initialize_sorcery_transport().

00568 {
00569    const struct ast_sip_transport *transport = obj;
00570 
00571    char str[MAX_OBJECT_FIELD];
00572    struct ast_variable *head = NULL;
00573    struct ast_ha *ha = transport->localnet;
00574 
00575    for (; ha; ha = ha->next) {
00576       const char *addr = ast_strdupa(ast_sockaddr_stringify_addr(&ha->addr));
00577       snprintf(str, MAX_OBJECT_FIELD, "%s%s/%s", ha->sense == AST_SENSE_ALLOW ? "!" : "",
00578          addr, ast_sockaddr_stringify_addr(&ha->netmask));
00579 
00580       ast_variable_list_append(&head, ast_variable_new("local_net", str, ""));
00581    }
00582 
00583    if (head) {
00584       *fields = head;
00585    }
00586 
00587    return 0;
00588 }

static int require_client_cert_to_str ( const void *  obj,
const intptr_t *  args,
char **  buf 
) [static]

Definition at line 348 of file config_transport.c.

References ast_strdup, AST_YESNO, and ast_sip_transport::tls.

Referenced by ast_sip_initialize_sorcery_transport().

00349 {
00350    const struct ast_sip_transport *transport = obj;
00351    *buf = ast_strdup(AST_YESNO(transport->tls.require_client_cert));
00352    return 0;
00353 }

static void set_qos ( struct ast_sip_transport transport,
pj_qos_params *  qos 
) [static]

Definition at line 129 of file config_transport.c.

References ast_sip_transport::cos, and ast_sip_transport::tos.

Referenced by transport_apply().

00130 {
00131    int tos_as_dscp = transport->tos >> 2;
00132 
00133    if (transport->tos) {
00134       qos->flags |= PJ_QOS_PARAM_HAS_DSCP;
00135       qos->dscp_val = tos_as_dscp;
00136    }
00137    if (transport->cos) {
00138       qos->flags |= PJ_QOS_PARAM_HAS_SO_PRIO;
00139       qos->so_prio = transport->cos;
00140    }
00141 }

static int sip_transport_to_ami ( const struct ast_sip_transport transport,
struct ast_str **  buf 
) [static]

Definition at line 33 of file config_transport.c.

References ast_sip_sorcery_object_to_ami().

Referenced by format_ami_endpoint_transport().

00035 {
00036    return ast_sip_sorcery_object_to_ami(transport, buf);
00037 }

static int tls_method_to_str ( const void *  obj,
const intptr_t *  args,
char **  buf 
) [static]

Definition at line 387 of file config_transport.c.

References ARRAY_IN_BOUNDS, ast_strdup, ast_sip_transport::tls, and tls_method_map.

Referenced by ast_sip_initialize_sorcery_transport().

00388 {
00389    const struct ast_sip_transport *transport = obj;
00390    if (ARRAY_IN_BOUNDS(transport->tls.method, tls_method_map)) {
00391       *buf = ast_strdup(tls_method_map[transport->tls.method]);
00392    }
00393    return 0;
00394 }

static int tos_to_str ( const void *  obj,
const intptr_t *  args,
char **  buf 
) [static]

Definition at line 626 of file config_transport.c.

References ast_asprintf, and ast_sip_transport::tos.

Referenced by ast_sip_initialize_sorcery_transport().

00627 {
00628    const struct ast_sip_transport *transport = obj;
00629 
00630    if (ast_asprintf(buf, "%u", transport->tos) == -1) {
00631       return -1;
00632    }
00633    return 0;
00634 }

static void* transport_alloc ( const char *  name  )  [static]

Allocator for transport.

Definition at line 110 of file config_transport.c.

References ao2_cleanup, ast_sorcery_generic_alloc(), ast_string_field_init, ast_sip_transport::ciphers, NULL, ast_sip_transport::tls, and transport_destroy().

Referenced by ast_sip_initialize_sorcery_transport().

00111 {
00112    struct ast_sip_transport *transport = ast_sorcery_generic_alloc(sizeof(*transport), transport_destroy);
00113 
00114    if (!transport) {
00115       return NULL;
00116    }
00117 
00118    if (ast_string_field_init(transport, 256)) {
00119       ao2_cleanup(transport);
00120       return NULL;
00121    }
00122 
00123    pjsip_tls_setting_default(&transport->tls);
00124    transport->tls.ciphers = transport->ciphers;
00125 
00126    return transport;
00127 }

static int transport_apply ( const struct ast_sorcery sorcery,
void *  obj 
) [static]

Apply handler for transports.

Definition at line 144 of file config_transport.c.

References ao2_alloc, ao2_cleanup, ao2_ref, ast_dnsmgr_lookup(), ast_log, ast_sip_get_pjsip_endpoint(), ast_sorcery_object_get_id(), ast_sorcery_retrieve_by_id(), ast_strlen_zero, AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, AST_TRANSPORT_UDP, AST_TRANSPORT_WS, AST_TRANSPORT_WSS, ast_sip_transport::async_operations, ast_sip_transport::ca_list_file, ast_sip_transport::ca_list_path, ast_sip_transport::cert_file, ast_sip_transport::cos, ast_sip_transport::external_address, ast_sip_transport::external_address_refresher, ast_sip_transport::external_signaling_address, ast_sip_transport_state::factory, ast_sip_transport::host, LOG_ERROR, LOG_WARNING, NULL, ast_sip_transport::password, ast_sip_transport::privkey_file, RAII_VAR, set_qos(), ast_sockaddr::ss, ast_sip_transport::state, ast_sip_transport::tls, ast_sip_transport::tos, ast_sip_transport_state::transport, transport_state_destroy(), and ast_sip_transport::type.

Referenced by ast_sip_initialize_sorcery_transport().

00145 {
00146    struct ast_sip_transport *transport = obj;
00147    RAII_VAR(struct ast_sip_transport *, existing, ast_sorcery_retrieve_by_id(sorcery, "transport", ast_sorcery_object_get_id(obj)), ao2_cleanup);
00148    pj_status_t res = -1;
00149 
00150    if (!existing || !existing->state) {
00151       if (!(transport->state = ao2_alloc(sizeof(*transport->state), transport_state_destroy))) {
00152          ast_log(LOG_ERROR, "Transport state for '%s' could not be allocated\n", ast_sorcery_object_get_id(obj));
00153          return -1;
00154       }
00155    } else {
00156       transport->state = existing->state;
00157       ao2_ref(transport->state, +1);
00158    }
00159 
00160    /* Once active a transport can not be reconfigured */
00161    if (transport->state->transport || transport->state->factory) {
00162       return -1;
00163    }
00164 
00165    if (transport->host.addr.sa_family != PJ_AF_INET && transport->host.addr.sa_family != PJ_AF_INET6) {
00166       ast_log(LOG_ERROR, "Transport '%s' could not be started as binding not specified\n", ast_sorcery_object_get_id(obj));
00167       return -1;
00168    }
00169 
00170    /* Set default port if not present */
00171    if (!pj_sockaddr_get_port(&transport->host)) {
00172       pj_sockaddr_set_port(&transport->host, (transport->type == AST_TRANSPORT_TLS) ? 5061 : 5060);
00173    }
00174 
00175    /* Now that we know what address family we can set up a dnsmgr refresh for the external media address if present */
00176    if (!ast_strlen_zero(transport->external_signaling_address)) {
00177       if (transport->host.addr.sa_family == pj_AF_INET()) {
00178          transport->external_address.ss.ss_family = AF_INET;
00179       } else if (transport->host.addr.sa_family == pj_AF_INET6()) {
00180          transport->external_address.ss.ss_family = AF_INET6;
00181       } else {
00182          ast_log(LOG_ERROR, "Unknown address family for transport '%s', could not get external signaling address\n",
00183                ast_sorcery_object_get_id(obj));
00184          return -1;
00185       }
00186 
00187       if (ast_dnsmgr_lookup(transport->external_signaling_address, &transport->external_address, &transport->external_address_refresher, NULL) < 0) {
00188          ast_log(LOG_ERROR, "Could not create dnsmgr for external signaling address on '%s'\n", ast_sorcery_object_get_id(obj));
00189          return -1;
00190       }
00191    }
00192 
00193    if (transport->type == AST_TRANSPORT_UDP) {
00194       if (transport->host.addr.sa_family == pj_AF_INET()) {
00195          res = pjsip_udp_transport_start(ast_sip_get_pjsip_endpoint(), &transport->host.ipv4, NULL, transport->async_operations, &transport->state->transport);
00196       } else if (transport->host.addr.sa_family == pj_AF_INET6()) {
00197          res = pjsip_udp_transport_start6(ast_sip_get_pjsip_endpoint(), &transport->host.ipv6, NULL, transport->async_operations, &transport->state->transport);
00198       }
00199 
00200       if (res == PJ_SUCCESS && (transport->tos || transport->cos)) {
00201          pj_sock_t sock;
00202          pj_qos_params qos_params;
00203 
00204          sock = pjsip_udp_transport_get_socket(transport->state->transport);
00205          pj_sock_get_qos_params(sock, &qos_params);
00206          set_qos(transport, &qos_params);
00207          pj_sock_set_qos_params(sock, &qos_params);
00208       }
00209    } else if (transport->type == AST_TRANSPORT_TCP) {
00210       pjsip_tcp_transport_cfg cfg;
00211 
00212       pjsip_tcp_transport_cfg_default(&cfg, transport->host.addr.sa_family);
00213       cfg.bind_addr = transport->host;
00214       cfg.async_cnt = transport->async_operations;
00215       set_qos(transport, &cfg.qos_params);
00216 
00217       res = pjsip_tcp_transport_start3(ast_sip_get_pjsip_endpoint(), &cfg, &transport->state->factory);
00218    } else if (transport->type == AST_TRANSPORT_TLS) {
00219       transport->tls.ca_list_file = pj_str((char*)transport->ca_list_file);
00220 #ifdef HAVE_PJ_SSL_CERT_LOAD_FROM_FILES2
00221       transport->tls.ca_list_path = pj_str((char*)transport->ca_list_path);
00222 #else
00223       if (!ast_strlen_zero(transport->ca_list_path)) {
00224          ast_log(LOG_WARNING, "Asterisk has been built against a version of pjproject that does not "
00225                "support the 'ca_list_path' option. Please upgrade to version 2.4 or later.\n");
00226       }
00227 #endif
00228       transport->tls.cert_file = pj_str((char*)transport->cert_file);
00229       transport->tls.privkey_file = pj_str((char*)transport->privkey_file);
00230       transport->tls.password = pj_str((char*)transport->password);
00231       set_qos(transport, &transport->tls.qos_params);
00232 
00233       res = pjsip_tls_transport_start2(ast_sip_get_pjsip_endpoint(), &transport->tls, &transport->host, NULL, transport->async_operations, &transport->state->factory);
00234    } else if ((transport->type == AST_TRANSPORT_WS) || (transport->type == AST_TRANSPORT_WSS)) {
00235       if (transport->cos || transport->tos) {
00236          ast_log(LOG_WARNING, "TOS and COS values ignored for websocket transport\n");
00237       }
00238       res = PJ_SUCCESS;
00239    }
00240 
00241    if (res != PJ_SUCCESS) {
00242       char msg[PJ_ERR_MSG_SIZE];
00243 
00244       pj_strerror(res, msg, sizeof(msg));
00245       ast_log(LOG_ERROR, "Transport '%s' could not be started: %s\n", ast_sorcery_object_get_id(obj), msg);
00246       return -1;
00247    }
00248    return 0;
00249 }

static int transport_bind_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
) [static]

Custom handler for turning a string bind into a pj_sockaddr.

Definition at line 293 of file config_transport.c.

References buf, ast_sip_transport::host, and ast_variable::value.

Referenced by ast_sip_initialize_sorcery_transport().

00294 {
00295    struct ast_sip_transport *transport = obj;
00296    pj_str_t buf;
00297    int rc = pj_sockaddr_parse(pj_AF_UNSPEC(), 0, pj_cstr(&buf, var->value), &transport->host);
00298 
00299    return rc != PJ_SUCCESS ? -1 : 0;
00300 }

static int transport_bind_to_str ( const void *  obj,
const intptr_t *  args,
char **  buf 
) [static]

Definition at line 302 of file config_transport.c.

References ast_calloc, ast_sip_transport::host, and MAX_OBJECT_FIELD.

Referenced by ast_sip_initialize_sorcery_transport().

00303 {
00304    const struct ast_sip_transport *transport = obj;
00305 
00306    if (!(*buf = ast_calloc(MAX_OBJECT_FIELD, sizeof(char)))) {
00307       return -1;
00308    }
00309 
00310    /* include port as well as brackets if IPv6 */
00311    pj_sockaddr_print(&transport->host, *buf, MAX_OBJECT_FIELD, 1 | 2);
00312 
00313    return 0;
00314 }

static int transport_cipher_add ( struct ast_sip_transport transport,
const char *  name 
) [static]

Definition at line 432 of file config_transport.c.

References ast_log, cipher_name_to_id(), ast_sip_transport::ciphers, LOG_ERROR, NULL, and ast_sip_transport::tls.

Referenced by transport_tls_cipher_handler().

00433 {
00434    pj_ssl_cipher cipher;
00435    int idx;
00436 
00437    cipher = cipher_name_to_id(name);
00438    if (!cipher) {
00439       /* TODO: Check this over/tweak - it's taken from pjsua for now */
00440       if (!strnicmp(name, "0x", 2)) {
00441          pj_str_t cipher_st = pj_str((char *) name + 2);
00442          cipher = pj_strtoul2(&cipher_st, NULL, 16);
00443       } else {
00444          cipher = atoi(name);
00445       }
00446    }
00447 
00448    if (pj_ssl_cipher_is_supported(cipher)) {
00449       for (idx = transport->tls.ciphers_num; idx--;) {
00450          if (transport->ciphers[idx] == cipher) {
00451             /* The cipher is already in the list. */
00452             return 0;
00453          }
00454       }
00455       transport->ciphers[transport->tls.ciphers_num++] = cipher;
00456       return 0;
00457    } else {
00458       ast_log(LOG_ERROR, "Cipher '%s' is unsupported\n", name);
00459       return -1;
00460    }
00461 }

static void transport_destroy ( void *  obj  )  [static]

Destructor for transport.

Definition at line 95 of file config_transport.c.

References ao2_cleanup, ast_dnsmgr_release(), ast_free_ha(), ast_string_field_free_memory, ast_sip_transport::external_address_refresher, ast_sip_transport::localnet, and ast_sip_transport::state.

Referenced by transport_alloc().

00096 {
00097    struct ast_sip_transport *transport = obj;
00098 
00099    ast_string_field_free_memory(transport);
00100    ast_free_ha(transport->localnet);
00101 
00102    if (transport->external_address_refresher) {
00103       ast_dnsmgr_release(transport->external_address_refresher);
00104    }
00105 
00106    ao2_cleanup(transport->state);
00107 }

static int transport_localnet_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
) [static]

Custom handler for localnet setting.

Definition at line 549 of file config_transport.c.

References ast_append_ha(), ast_free_ha(), ast_strlen_zero, error(), ast_sip_transport::localnet, NULL, and ast_variable::value.

Referenced by ast_sip_initialize_sorcery_transport().

00550 {
00551    struct ast_sip_transport *transport = obj;
00552    int error = 0;
00553 
00554    if (ast_strlen_zero(var->value)) {
00555       ast_free_ha(transport->localnet);
00556       transport->localnet = NULL;
00557       return 0;
00558    }
00559 
00560    if (!(transport->localnet = ast_append_ha("d", var->value, transport->localnet, &error))) {
00561       return -1;
00562    }
00563 
00564    return error;
00565 }

static int transport_protocol_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
) [static]

Custom handler for turning a string protocol into an enum.

Definition at line 252 of file config_transport.c.

References AST_TRANSPORT_TCP, AST_TRANSPORT_TLS, AST_TRANSPORT_UDP, AST_TRANSPORT_WS, AST_TRANSPORT_WSS, ast_sip_transport::type, and ast_variable::value.

Referenced by ast_sip_initialize_sorcery_transport().

00253 {
00254    struct ast_sip_transport *transport = obj;
00255 
00256    if (!strcasecmp(var->value, "udp")) {
00257       transport->type = AST_TRANSPORT_UDP;
00258    } else if (!strcasecmp(var->value, "tcp")) {
00259       transport->type = AST_TRANSPORT_TCP;
00260    } else if (!strcasecmp(var->value, "tls")) {
00261       transport->type = AST_TRANSPORT_TLS;
00262    } else if (!strcasecmp(var->value, "ws")) {
00263       transport->type = AST_TRANSPORT_WS;
00264    } else if (!strcasecmp(var->value, "wss")) {
00265       transport->type = AST_TRANSPORT_WSS;
00266    } else {
00267       return -1;
00268    }
00269 
00270    return 0;
00271 }

static int transport_protocol_to_str ( const void *  obj,
const intptr_t *  args,
char **  buf 
) [static]

Definition at line 281 of file config_transport.c.

References ARRAY_IN_BOUNDS, ast_strdup, transport_types, and ast_sip_transport::type.

Referenced by ast_sip_initialize_sorcery_transport().

00282 {
00283    const struct ast_sip_transport *transport = obj;
00284 
00285    if (ARRAY_IN_BOUNDS(transport->type, transport_types)) {
00286       *buf = ast_strdup(transport_types[transport->type]);
00287    }
00288 
00289    return 0;
00290 }

static void transport_state_destroy ( void *  obj  )  [static]

Destructor for transport state information.

Definition at line 85 of file config_transport.c.

References ast_sip_push_task_synchronous(), destroy_transport_state(), NULL, and ast_sip_transport_state::transport.

Referenced by transport_apply().

00086 {
00087    struct ast_sip_transport_state *state = obj;
00088 
00089    if (state->transport) {
00090       ast_sip_push_task_synchronous(NULL, destroy_transport_state, state->transport);
00091    }
00092 }

static int transport_tls_bool_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
) [static]

Custom handler for TLS boolean settings.

Definition at line 317 of file config_transport.c.

References ast_true(), ast_variable::name, ast_sip_transport::tls, and ast_variable::value.

Referenced by ast_sip_initialize_sorcery_transport().

00318 {
00319    struct ast_sip_transport *transport = obj;
00320 
00321    if (!strcasecmp(var->name, "verify_server")) {
00322       transport->tls.verify_server = ast_true(var->value) ? PJ_TRUE : PJ_FALSE;
00323    } else if (!strcasecmp(var->name, "verify_client")) {
00324       transport->tls.verify_client = ast_true(var->value) ? PJ_TRUE : PJ_FALSE;
00325    } else if (!strcasecmp(var->name, "require_client_cert")) {
00326       transport->tls.require_client_cert = ast_true(var->value) ? PJ_TRUE : PJ_FALSE;
00327    } else {
00328       return -1;
00329    }
00330 
00331    return 0;
00332 }

static int transport_tls_cipher_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
) [static]

Custom handler for TLS cipher setting.

Definition at line 464 of file config_transport.c.

References ARRAY_LEN, ast_log, ast_strdupa, ast_strip(), ast_strlen_zero, ast_sip_transport::ciphers, LOG_ERROR, name, parse(), S_OR, strsep(), ast_sip_transport::tls, transport_cipher_add(), and ast_variable::value.

Referenced by ast_sip_initialize_sorcery_transport().

00465 {
00466    struct ast_sip_transport *transport = obj;
00467    char *parse;
00468    char *name;
00469    int res = 0;
00470 
00471    parse = ast_strdupa(S_OR(var->value, ""));
00472    while ((name = strsep(&parse, ","))) {
00473       name = ast_strip(name);
00474       if (ast_strlen_zero(name)) {
00475          continue;
00476       }
00477       if (ARRAY_LEN(transport->ciphers) <= transport->tls.ciphers_num) {
00478          ast_log(LOG_ERROR, "Too many ciphers specified\n");
00479          res = -1;
00480          break;
00481       }
00482       res |= transport_cipher_add(transport, name);
00483    }
00484    return res ? -1 : 0;
00485 }

static int transport_tls_cipher_to_str ( const void *  obj,
const intptr_t *  args,
char **  buf 
) [static]

Definition at line 509 of file config_transport.c.

References cipher_to_str(), ast_sip_transport::ciphers, and ast_sip_transport::tls.

Referenced by ast_sip_initialize_sorcery_transport().

00510 {
00511    const struct ast_sip_transport *transport = obj;
00512 
00513    cipher_to_str(buf, transport->ciphers, transport->tls.ciphers_num);
00514    return *buf ? 0 : -1;
00515 }

static int transport_tls_method_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
) [static]

Custom handler for TLS method setting.

Definition at line 356 of file config_transport.c.

References ast_strlen_zero, ast_sip_transport::tls, and ast_variable::value.

Referenced by ast_sip_initialize_sorcery_transport().

00357 {
00358    struct ast_sip_transport *transport = obj;
00359 
00360    if (ast_strlen_zero(var->value) || !strcasecmp(var->value, "default")) {
00361       transport->tls.method = PJSIP_SSL_DEFAULT_METHOD;
00362    } else if (!strcasecmp(var->value, "unspecified")) {
00363       transport->tls.method = PJSIP_SSL_UNSPECIFIED_METHOD;
00364    } else if (!strcasecmp(var->value, "tlsv1")) {
00365       transport->tls.method = PJSIP_TLSV1_METHOD;
00366    } else if (!strcasecmp(var->value, "sslv2")) {
00367       transport->tls.method = PJSIP_SSLV2_METHOD;
00368    } else if (!strcasecmp(var->value, "sslv3")) {
00369       transport->tls.method = PJSIP_SSLV3_METHOD;
00370    } else if (!strcasecmp(var->value, "sslv23")) {
00371       transport->tls.method = PJSIP_SSLV23_METHOD;
00372    } else {
00373       return -1;
00374    }
00375 
00376    return 0;
00377 }

static int transport_tos_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
) [static]

Custom handler for TOS setting.

Definition at line 601 of file config_transport.c.

References ast_log, ast_sorcery_object_get_id(), ast_str2tos(), LOG_ERROR, LOG_WARNING, ast_sip_transport::tos, ast_variable::value, and value.

Referenced by ast_sip_initialize_sorcery_transport().

00602 {
00603    struct ast_sip_transport *transport = obj;
00604    unsigned int value;
00605 
00606    if (ast_str2tos(var->value, &value)) {
00607       ast_log(LOG_ERROR, "Error configuring transport '%s' - Could not "
00608          "interpret 'tos' value '%s'\n",
00609          ast_sorcery_object_get_id(transport), var->value);
00610       return -1;
00611    }
00612 
00613    if (value % 4) {
00614       value = value >> 2;
00615       value = value << 2;
00616       ast_log(LOG_WARNING,
00617          "transport '%s' - 'tos' value '%s' uses bits that are "
00618          "discarded when converted to DSCP. Using equivalent %u instead.\n",
00619          ast_sorcery_object_get_id(transport), var->value, value);
00620    }
00621 
00622    transport->tos = value;
00623    return 0;
00624 }

static int verify_client_to_str ( const void *  obj,
const intptr_t *  args,
char **  buf 
) [static]

Definition at line 341 of file config_transport.c.

References ast_strdup, AST_YESNO, and ast_sip_transport::tls.

Referenced by ast_sip_initialize_sorcery_transport().

00342 {
00343    const struct ast_sip_transport *transport = obj;
00344    *buf = ast_strdup(AST_YESNO(transport->tls.verify_client));
00345    return 0;
00346 }

static int verify_server_to_str ( const void *  obj,
const intptr_t *  args,
char **  buf 
) [static]

Definition at line 334 of file config_transport.c.

References ast_strdup, AST_YESNO, and ast_sip_transport::tls.

Referenced by ast_sip_initialize_sorcery_transport().

00335 {
00336    const struct ast_sip_transport *transport = obj;
00337    *buf = ast_strdup(AST_YESNO(transport->tls.verify_server));
00338    return 0;
00339 }


Variable Documentation

struct ast_cli_entry cli_commands[] [static]

Definition at line 719 of file config_transport.c.

Definition at line 735 of file config_transport.c.

Initial value:

 {
   .format_ami = format_ami_endpoint_transport
}

Definition at line 73 of file config_transport.c.

const char* tls_method_map[] [static]

Definition at line 379 of file config_transport.c.

Referenced by tls_method_to_str().

const char* transport_types[] [static]

Definition at line 273 of file config_transport.c.

Referenced by cli_print_body(), and transport_protocol_to_str().


Generated on Thu Apr 16 06:30:28 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6