Asterisk - The Open Source Telephony Project GIT-master-70eff7f
Loading...
Searching...
No Matches
Data Structures | Macros | Functions | Variables
res_pjsip_endpoint_identifier_ip.c File Reference
#include "asterisk.h"
#include <pjsip.h>
#include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_cli.h"
#include "asterisk/module.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "res_pjsip/include/res_pjsip_private.h"
Include dependency graph for res_pjsip_endpoint_identifier_ip.c:

Go to the source code of this file.

Data Structures

struct  ip_identify_match
 Structure for an IP identification matching object. More...
 

Macros

#define HOSTS_BUCKETS   53
 The number of buckets for storing hosts for resolution.
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static struct ao2_containercli_get_container (const char *regex)
 
static int cli_iterator (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 struct ast_sip_endpointcommon_identify (ao2_callback_fn *identify_match_cb, void *arg)
 
static int format_ami_endpoint_identify (const struct ast_sip_endpoint *endpoint, struct ast_sip_ami *ami)
 
static struct ast_sip_endpointheader_identify (pjsip_rx_data *rdata)
 
static int header_identify_match_check (void *obj, void *arg, int flags)
 Comparator function for matching an object by header.
 
static struct ast_sip_endpointip_identify (pjsip_rx_data *rdata)
 
static void * ip_identify_alloc (const char *name)
 Allocator function for a matching object.
 
static int ip_identify_apply (const struct ast_sorcery *sorcery, void *obj)
 Apply handler for identify type.
 
static void ip_identify_destroy (void *obj)
 Destructor function for a matching object.
 
static int ip_identify_match_check (void *obj, void *arg, int flags)
 Comparator function for matching an object by IP address.
 
static int ip_identify_match_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Custom handler for match field.
 
static int ip_identify_match_host_lookup (struct ip_identify_match *identify, const char *host, int *resolved)
 Helper function which performs a host lookup and adds result to identify match.
 
static int ip_identify_match_srv_lookup (struct ip_identify_match *identify, const char *prefix, const char *host, int results, int *resolved)
 Helper function which performs an SRV lookup and then resolves the hostname.
 
static int load_module (void)
 
static int match_to_str (const void *obj, const intptr_t *args, char **buf)
 
static int match_to_var_list (const void *obj, struct ast_variable **fields)
 
static void match_to_var_list_append (struct ast_variable **head, struct ast_ha *ha)
 
static char * my_cli_traverse_objects (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int reload_module (void)
 
static struct ast_sip_endpointrequest_identify (pjsip_rx_data *rdata)
 
static int request_identify_match_check (void *obj, void *arg, int flags)
 Comparator function for matching an object by request URI.
 
static int send_identify_ami_event (void *obj, void *arg, void *data, int flags)
 
static int sip_identify_to_ami (const struct ip_identify_match *identify, struct ast_str **buf)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP IP endpoint identifier" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND - 4, .requires = "res_pjsip", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_sip_cli_formatter_entrycli_formatter
 
static struct ast_cli_entry cli_identify []
 
struct ast_sip_endpoint_formatter endpoint_identify_formatter
 
static struct ast_sip_endpoint_identifier header_identifier
 
static struct ast_sip_endpoint_identifier ip_identifier
 
static struct ast_sip_endpoint_identifier request_identifier
 

Macro Definition Documentation

◆ HOSTS_BUCKETS

#define HOSTS_BUCKETS   53

The number of buckets for storing hosts for resolution.

Definition at line 162 of file res_pjsip_endpoint_identifier_ip.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 1042 of file res_pjsip_endpoint_identifier_ip.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 1042 of file res_pjsip_endpoint_identifier_ip.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 1042 of file res_pjsip_endpoint_identifier_ip.c.

◆ cli_get_container()

static struct ao2_container * cli_get_container ( const char *  regex)
static

Definition at line 825 of file res_pjsip_endpoint_identifier_ip.c.

826{
828 struct ao2_container *s_container;
829
831 if (!container) {
832 return NULL;
833 }
834
837 if (!s_container) {
838 return NULL;
839 }
840
841 if (ao2_container_dup(s_container, container, 0)) {
842 ao2_ref(s_container, -1);
843 return NULL;
844 }
845
846 return s_container;
847}
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
Copy all object references in the src container into the dest container.
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition astobj2.h:367
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Definition astobj2.h:1327
static int regex(struct ast_channel *chan, const char *cmd, char *parse, char *buf, size_t len)
struct ao2_container * container
Definition res_fax.c:603
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
#define NULL
Definition resample.c:96
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.
Definition sorcery.c:2018
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Definition sorcery.c:2528
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
Definition sorcery.c:2504
Generic container type.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition utils.h:981

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_cleanup, ao2_container_alloc_list, ao2_container_dup(), ao2_ref, ast_sip_get_sorcery(), ast_sorcery_object_id_compare(), ast_sorcery_object_id_sort(), ast_sorcery_retrieve_by_regex(), container, NULL, RAII_VAR, and regex().

Referenced by load_module().

◆ cli_iterator()

static int cli_iterator ( void *  container,
ao2_callback_fn  callback,
void *  args 
)
static

Definition at line 802 of file res_pjsip_endpoint_identifier_ip.c.

803{
804 const struct ast_sip_endpoint *endpoint = container;
805 struct ao2_container *identifies;
806
807 struct ast_variable fields = {
808 .name = "endpoint",
809 .value = ast_sorcery_object_get_id(endpoint),
810 .next = NULL,
811 };
812
813 identifies = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify",
815 if (!identifies) {
816 return -1;
817 }
818
819 ao2_callback(identifies, OBJ_NODATA, callback, args);
820 ao2_cleanup(identifies);
821
822 return 0;
823}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition astobj2.h:1693
@ OBJ_NODATA
Definition astobj2.h:1044
static struct ast_channel * callback(struct ast_channelstorage_instance *driver, ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags, int rdlock)
static struct @522 args
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition sorcery.c:2381
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
Definition sorcery.h:120
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.
Definition sorcery.c:1961
An entity with which Asterisk communicates.
Definition res_pjsip.h:1067
Structure for variables, used for configurations and for channel variables.

References ao2_callback, ao2_cleanup, args, AST_RETRIEVE_FLAG_MULTIPLE, ast_sip_get_sorcery(), ast_sorcery_object_get_id(), ast_sorcery_retrieve_by_fields(), callback(), container, ast_variable::name, NULL, and OBJ_NODATA.

Referenced by load_module().

◆ cli_print_body()

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

Definition at line 881 of file res_pjsip_endpoint_identifier_ip.c.

882{
884 struct ip_identify_match *ident = obj;
885 struct ast_sip_cli_context *context = arg;
886 struct ast_ha *match;
887 int indent;
888
889 ast_assert(context->output_buffer != NULL);
890
891 ast_str_append(&context->output_buffer, 0, "%*s: %s/%s\n",
892 CLI_INDENT_TO_SPACES(context->indent_level), "Identify",
894
895 if (context->recurse) {
896 context->indent_level++;
897 indent = CLI_INDENT_TO_SPACES(context->indent_level);
898
899 for (match = ident->matches; match; match = match->next) {
900 const char *addr;
901
902 if (ast_sockaddr_port(&match->addr)) {
904 } else {
906 }
907
908 ast_str_append(&context->output_buffer, 0, "%*s: %s%s/%d\n",
909 indent,
910 "Match",
911 match->sense == AST_SENSE_ALLOW ? "!" : "",
913 }
914
915 if (!ast_strlen_zero(ident->match_header)) {
916 ast_str_append(&context->output_buffer, 0, "%*s: %s\n",
917 indent,
918 "Header",
919 ident->match_header);
920 }
921
922 if (!ast_strlen_zero(ident->match_request_uri)) {
923 ast_str_append(&context->output_buffer, 0, "%*s: %s\n",
924 indent,
925 "RequestURI",
926 ident->match_request_uri);
927 }
928
929 context->indent_level--;
930
931 if (context->indent_level == 0) {
932 ast_str_append(&context->output_buffer, 0, "\n");
933 }
934 }
935
936 if (context->show_details
937 || (context->show_details_only_level_0 && context->indent_level == 0)) {
938 ast_str_append(&context->output_buffer, 0, "\n");
939 ast_sip_cli_print_sorcery_objectset(ident, context, 0);
940 }
941
942 return 0;
943}
@ AST_SENSE_ALLOW
Definition acl.h:38
const char * str
Definition app_jack.c:150
#define ast_free(a)
Definition astmm.h:180
static int match(struct ast_sockaddr *addr, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
Definition chan_iax2.c:2401
int ast_sockaddr_cidr_bits(const struct ast_sockaddr *sa)
Count the 1 bits in a netmask.
Definition netsock2.c:130
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition netsock2.h:256
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition netsock2.h:517
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition netsock2.h:286
int ast_sip_cli_print_sorcery_objectset(void *obj, void *arg, int flags)
Prints a sorcery object's ast_variable list.
Definition pjsip_cli.c:36
#define CLI_INDENT_TO_SPACES(x)
#define MAX_OBJECT_FIELD
Maximum length of an object field name.
Definition sorcery.h:110
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition strings.h:1139
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition strings.h:659
internal representation of ACL entries In principle user applications would have no need for this,...
Definition acl.h:51
struct ast_sockaddr addr
Definition acl.h:53
struct ast_sockaddr netmask
Definition acl.h:54
CLI Formatter Context passed to all formatters.
Support for dynamic strings.
Definition strings.h:623
Structure for an IP identification matching object.
const ast_string_field match_header
struct ast_ha * matches
Networks or addresses that should match this.
const ast_string_field match_request_uri
const ast_string_field endpoint_name
#define ast_assert(a)
Definition utils.h:779

References ast_ha::addr, ast_assert, ast_free, AST_SENSE_ALLOW, ast_sip_cli_print_sorcery_objectset(), ast_sockaddr_cidr_bits(), ast_sockaddr_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_sorcery_object_get_id(), ast_str_append(), ast_str_create, ast_strlen_zero(), CLI_INDENT_TO_SPACES, ip_identify_match::endpoint_name, match(), ip_identify_match::match_header, ip_identify_match::match_request_uri, ip_identify_match::matches, MAX_OBJECT_FIELD, NULL, RAII_VAR, and str.

Referenced by load_module().

◆ cli_print_header()

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

Definition at line 854 of file res_pjsip_endpoint_identifier_ip.c.

855{
856 struct ast_sip_cli_context *context = arg;
857 int indent = CLI_INDENT_TO_SPACES(context->indent_level);
858 int filler = CLI_MAX_WIDTH - indent - 22;
859
860 ast_assert(context->output_buffer != NULL);
861
862 ast_str_append(&context->output_buffer, 0,
863 "%*s: <Identify/Endpoint%*.*s>\n",
864 indent, "Identify", filler, filler, CLI_HEADER_FILLER);
865
866 if (context->recurse) {
867 context->indent_level++;
868 indent = CLI_INDENT_TO_SPACES(context->indent_level);
869 filler = CLI_LAST_TABSTOP - indent - 24;
870
871 ast_str_append(&context->output_buffer, 0,
872 "%*s: <criteria%*.*s>\n",
873 indent, "Match", filler, filler, CLI_HEADER_FILLER);
874
875 context->indent_level--;
876 }
877
878 return 0;
879}
#define CLI_HEADER_FILLER
#define CLI_MAX_WIDTH
#define CLI_LAST_TABSTOP

References ast_assert, ast_str_append(), CLI_HEADER_FILLER, CLI_INDENT_TO_SPACES, CLI_LAST_TABSTOP, CLI_MAX_WIDTH, and NULL.

Referenced by load_module().

◆ cli_retrieve_by_id()

static void * cli_retrieve_by_id ( const char *  id)
static

Definition at line 849 of file res_pjsip_endpoint_identifier_ip.c.

850{
851 return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "identify", id);
852}
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition sorcery.c:1917

References ast_sip_get_sorcery(), and ast_sorcery_retrieve_by_id().

Referenced by load_module().

◆ common_identify()

static struct ast_sip_endpoint * common_identify ( ao2_callback_fn identify_match_cb,
void *  arg 
)
static

Definition at line 349 of file res_pjsip_endpoint_identifier_ip.c.

350{
351 RAII_VAR(struct ao2_container *, candidates, NULL, ao2_cleanup);
352 struct ip_identify_match *match;
353 struct ast_sip_endpoint *endpoint;
354
355 /* If no possibilities exist return early to save some time */
356 candidates = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify",
358 if (!candidates || !ao2_container_count(candidates)) {
359 ast_debug(3, "No identify sections to match against\n");
360 return NULL;
361 }
362
363 match = ao2_callback(candidates, 0, identify_match_cb, arg);
364 if (!match) {
365 return NULL;
366 }
367
368 endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
369 match->endpoint_name);
370 if (endpoint) {
371 ast_debug(3, "Identify '%s' SIP message matched to endpoint %s\n",
372 ast_sorcery_object_get_id(match), match->endpoint_name);
373 } else {
374 ast_log(LOG_WARNING, "Identify '%s' points to endpoint '%s' but endpoint could not be found\n",
375 ast_sorcery_object_get_id(match), match->endpoint_name);
376 }
377
378 ao2_ref(match, -1);
379 return endpoint;
380}
#define ast_log
Definition astobj2.c:42
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_WARNING
@ AST_RETRIEVE_FLAG_ALL
Perform no matching, return all objects.
Definition sorcery.h:123

References ao2_callback, ao2_cleanup, ao2_container_count(), ao2_ref, ast_debug, ast_log, AST_RETRIEVE_FLAG_ALL, AST_RETRIEVE_FLAG_MULTIPLE, ast_sip_get_sorcery(), ast_sorcery_object_get_id(), ast_sorcery_retrieve_by_fields(), ast_sorcery_retrieve_by_id(), LOG_WARNING, match(), NULL, and RAII_VAR.

Referenced by header_identify(), ip_identify(), and request_identify().

◆ format_ami_endpoint_identify()

static int format_ami_endpoint_identify ( const struct ast_sip_endpoint endpoint,
struct ast_sip_ami ami 
)
static

Definition at line 773 of file res_pjsip_endpoint_identifier_ip.c.

775{
776 struct ao2_container *identifies;
777 struct ast_variable fields = {
778 .name = "endpoint",
779 .value = ast_sorcery_object_get_id(endpoint),
780 };
781
782 identifies = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify",
784 if (!identifies) {
785 return -1;
786 }
787
788 /* Build and send any found identify object's AMI IdentifyDetail event. */
791 (void *) ast_sorcery_object_get_id(endpoint),
792 ami);
793
794 ao2_ref(identifies, -1);
795 return 0;
796}
#define ao2_callback_data(container, flags, cb_fn, arg, data)
Definition astobj2.h:1723
@ OBJ_MULTIPLE
Definition astobj2.h:1049
static int send_identify_ami_event(void *obj, void *arg, void *data, int flags)

References ao2_callback_data, ao2_ref, AST_RETRIEVE_FLAG_MULTIPLE, ast_sip_get_sorcery(), ast_sorcery_object_get_id(), ast_sorcery_retrieve_by_fields(), ast_variable::name, OBJ_MULTIPLE, OBJ_NODATA, and send_identify_ami_event().

◆ header_identify()

static struct ast_sip_endpoint * header_identify ( pjsip_rx_data *  rdata)
static

Definition at line 396 of file res_pjsip_endpoint_identifier_ip.c.

397{
399}
static struct ast_sip_endpoint * common_identify(ao2_callback_fn *identify_match_cb, void *arg)
static int header_identify_match_check(void *obj, void *arg, int flags)
Comparator function for matching an object by header.

References common_identify(), and header_identify_match_check().

◆ header_identify_match_check()

static int header_identify_match_check ( void *  obj,
void *  arg,
int  flags 
)
static

Comparator function for matching an object by header.

Definition at line 227 of file res_pjsip_endpoint_identifier_ip.c.

228{
229 struct ip_identify_match *identify = obj;
230 struct pjsip_rx_data *rdata = arg;
231 pjsip_hdr *header;
232 pj_str_t pj_header_name;
233 int header_present;
234
235 if (ast_strlen_zero(identify->match_header)) {
236 return 0;
237 }
238
239 pj_header_name = pj_str((void *) identify->match_header_name);
240
241 /* Check all headers of the given name for a match. */
242 header_present = 0;
243 for (header = NULL;
244 (header = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &pj_header_name, header));
245 header = header->next) {
246 char *pos;
247 int len;
248 char buf[PATH_MAX];
249
250 header_present = 1;
251
252 /* Print header line to buf */
253 len = pjsip_hdr_print_on(header, buf, sizeof(buf) - 1);
254 if (len < 0) {
255 /* Buffer not large enough or no header vptr! */
256 ast_assert(0);
257 continue;
258 }
259 buf[len] = '\0';
260
261 /* Remove header name from pj_buf and trim blanks. */
262 pos = strchr(buf, ':');
263 if (!pos) {
264 /* No header name? Bug in PJPROJECT if so. */
265 ast_assert(0);
266 continue;
267 }
268 pos = ast_strip(pos + 1);
269
270 /* Does header value match what we are looking for? */
271 if (identify->is_header_regex) {
272 if (!regexec(&identify->regex_header_buf, pos, 0, NULL, 0)) {
273 return CMP_MATCH;
274 }
275 } else if (!strcmp(identify->match_header_value, pos)) {
276 return CMP_MATCH;
277 }
278
279 ast_debug(3, "Identify '%s': SIP message has '%s' header but value '%s' does not match '%s'.\n",
281 identify->match_header_name,
282 pos,
283 identify->match_header_value);
284 }
285 if (!header_present) {
286 ast_debug(3, "Identify '%s': SIP message does not have '%s' header.\n",
288 identify->match_header_name);
289 }
290 return 0;
291}
#define PATH_MAX
Definition asterisk.h:40
@ CMP_MATCH
Definition astobj2.h:1027
char buf[BUFSIZE]
Definition eagi_proxy.c:66
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition strings.h:223
struct header * next
const ast_string_field match_header_value
const ast_string_field match_header_name

References ast_assert, ast_debug, ast_sorcery_object_get_id(), ast_strip(), ast_strlen_zero(), buf, CMP_MATCH, ip_identify_match::is_header_regex, len(), ip_identify_match::match_header, ip_identify_match::match_header_name, ip_identify_match::match_header_value, header::next, NULL, PATH_MAX, and ip_identify_match::regex_header_buf.

Referenced by header_identify().

◆ ip_identify()

static struct ast_sip_endpoint * ip_identify ( pjsip_rx_data *  rdata)
static

Definition at line 382 of file res_pjsip_endpoint_identifier_ip.c.

383{
384 struct ast_sockaddr addr = { { 0, } };
385
386 ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
387 ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port);
388
390}
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition netsock2.c:230
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition netsock2.h:532
static int ip_identify_match_check(void *obj, void *arg, int flags)
Comparator function for matching an object by IP address.
Socket address structure.
Definition netsock2.h:97

References ast_sockaddr_parse(), ast_sockaddr_set_port, common_identify(), ip_identify_match_check(), and PARSE_PORT_FORBID.

◆ ip_identify_alloc()

static void * ip_identify_alloc ( const char *  name)
static

Allocator function for a matching object.

Definition at line 214 of file res_pjsip_endpoint_identifier_ip.c.

215{
216 struct ip_identify_match *identify = ast_sorcery_generic_alloc(sizeof(*identify), ip_identify_destroy);
217
218 if (!identify || ast_string_field_init(identify, 256)) {
219 ao2_cleanup(identify);
220 return NULL;
221 }
222
223 return identify;
224}
static void ip_identify_destroy(void *obj)
Destructor function for a matching object.
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
Definition sorcery.c:1792
#define ast_string_field_init(x, size)
Initialize a field pool and fields.

References ao2_cleanup, ast_sorcery_generic_alloc(), ast_string_field_init, ip_identify_destroy(), and NULL.

Referenced by load_module().

◆ ip_identify_apply()

static int ip_identify_apply ( const struct ast_sorcery sorcery,
void *  obj 
)
static

Apply handler for identify type.

Definition at line 538 of file res_pjsip_endpoint_identifier_ip.c.

539{
540 struct ip_identify_match *identify = obj;
541 char *current_string;
542 struct ao2_iterator i;
543
544 /* Validate the identify object configuration */
545 if (ast_strlen_zero(identify->endpoint_name)) {
546 ast_log(LOG_ERROR, "Identify '%s' missing required endpoint name.\n",
547 ast_sorcery_object_get_id(identify));
548 return -1;
549 }
550 if (ast_strlen_zero(identify->match_header) /* No header to match */
551 && ast_strlen_zero(identify->match_request_uri) /* and no request to match */
552 /* and no static IP addresses with a mask */
553 && !identify->matches
554 /* and no addresses to resolve */
555 && (!identify->hosts || !ao2_container_count(identify->hosts))) {
556 ast_log(LOG_ERROR, "Identify '%s' is not configured to match anything.\n",
557 ast_sorcery_object_get_id(identify));
558 return -1;
559 }
560
561 if (!ast_strlen_zero(identify->match_header)) {
562 char *c_header;
563 char *c_value;
564 int len;
565
566 /* Split the header name and value */
567 c_header = ast_strdupa(identify->match_header);
568 c_value = strchr(c_header, ':');
569 if (!c_value) {
570 ast_log(LOG_ERROR, "Identify '%s' missing ':' separator in match_header '%s'.\n",
571 ast_sorcery_object_get_id(identify), identify->match_header);
572 return -1;
573 }
574 *c_value = '\0';
575 c_value = ast_strip(c_value + 1);
576 c_header = ast_strip(c_header);
577
578 if (ast_strlen_zero(c_header)) {
579 ast_log(LOG_ERROR, "Identify '%s' has no SIP header to match in match_header '%s'.\n",
580 ast_sorcery_object_get_id(identify), identify->match_header);
581 return -1;
582 }
583
584 if (!strcmp(c_value, "//")) {
585 /* An empty regex is the same as an empty literal string. */
586 c_value = "";
587 }
588
589 if (ast_string_field_set(identify, match_header_name, c_header)
590 || ast_string_field_set(identify, match_header_value, c_value)) {
591 return -1;
592 }
593
594 len = strlen(c_value);
595 if (2 < len && c_value[0] == '/' && c_value[len - 1] == '/') {
596 /* Make "/regex/" into "regex" */
597 c_value[len - 1] = '\0';
598 ++c_value;
599
600 if (regcomp(&identify->regex_header_buf, c_value, REG_EXTENDED | REG_NOSUB)) {
601 ast_log(LOG_ERROR, "Identify '%s' failed to compile match_request_uri regex '%s'.\n",
602 ast_sorcery_object_get_id(identify), c_value);
603 return -1;
604 }
605 identify->is_header_regex = 1;
606 }
607 }
608
609 if (!ast_strlen_zero(identify->match_request_uri)) {
610 char *c_string;
611 int len;
612
613 len = strlen(identify->match_request_uri);
614 c_string = ast_strdupa(identify->match_request_uri);
615
616 if (!strcmp(c_string, "//")) {
617 /* An empty regex is the same as an empty literal string. */
618 c_string = "";
619 }
620
621 if (2 < len && c_string[0] == '/' && c_string[len - 1] == '/') {
622 /* Make "/regex/" into "regex" */
623 c_string[len - 1] = '\0';
624 ++c_string;
625
626 if (regcomp(&identify->regex_request_uri_buf, c_string, REG_EXTENDED | REG_NOSUB)) {
627 ast_log(LOG_ERROR, "Identify '%s' failed to compile match_header regex '%s'.\n",
628 ast_sorcery_object_get_id(identify), c_string);
629 return -1;
630 }
631 identify->is_request_uri_regex = 1;
632 }
633 }
634
635 if (!identify->hosts) {
636 /* No match addresses to resolve */
637 return 0;
638 }
639
640 /* Hosts can produce dynamic content, so mark the identify as such */
642
643 /* Resolve the match addresses now */
644 i = ao2_iterator_init(identify->hosts, 0);
645 while ((current_string = ao2_iterator_next(&i))) {
646 int results = 0;
647 int resolved = 0;
648 char *colon = strrchr(current_string, ':');
649
650 /* We skip SRV lookup if a colon is present, assuming a port was specified */
651 if (!colon) {
652 /* No port, and we know this is not an IP address, so perform SRV resolution on it */
653 if (identify->srv_lookups) {
654 results = ip_identify_match_srv_lookup(identify, "_sip._udp", current_string,
655 results, &resolved);
656 if (results != -1) {
657 results = ip_identify_match_srv_lookup(identify, "_sip._tcp",
658 current_string, results, &resolved);
659 }
660 if (results != -1) {
661 results = ip_identify_match_srv_lookup(identify, "_sips._tcp",
662 current_string, results, &resolved);
663 }
664 }
665 }
666
667 /* If SRV fails fall back to a normal lookup on the host itself */
668 if (!results) {
669 results = ip_identify_match_host_lookup(identify, current_string, &resolved);
670 }
671
672 if (results == -1) {
673 ast_log(LOG_ERROR, "Identify '%s' failed when adding resolution results of '%s'\n",
674 ast_sorcery_object_get_id(identify), current_string);
675 ao2_ref(current_string, -1);
677 return -1;
678 } else if (!results && resolved) {
679 ast_log(LOG_WARNING, "Identify '%s' provided address '%s' resolved, "
680 "but resolved addresses are already present for matching\n",
681 ast_sorcery_object_get_id(identify), current_string);
682 } else if (!results) {
683 ast_log(LOG_WARNING, "Identify '%s' provided address '%s' did not resolve to any address\n",
684 ast_sorcery_object_get_id(identify), current_string);
685 }
686
687 ao2_ref(current_string, -1);
688 }
690
691 ao2_ref(identify->hosts, -1);
692 identify->hosts = NULL;
693
694 return 0;
695}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition astmm.h:298
#define ao2_iterator_next(iter)
Definition astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
#define LOG_ERROR
static int ip_identify_match_srv_lookup(struct ip_identify_match *identify, const char *prefix, const char *host, int results, int *resolved)
Helper function which performs an SRV lookup and then resolves the hostname.
static int ip_identify_match_host_lookup(struct ip_identify_match *identify, const char *host, int *resolved)
Helper function which performs a host lookup and adds result to identify match.
void ast_sorcery_object_set_has_dynamic_contents(const void *object)
Set the dynamic contents flag on a sorcery object.
Definition sorcery.c:2448
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition astobj2.h:1821
struct ao2_container * hosts
Hosts to be resolved when applying configuration.
unsigned int srv_lookups
Perform SRV resolution of hostnames.

References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_log, ast_sorcery_object_get_id(), ast_sorcery_object_set_has_dynamic_contents(), ast_strdupa, ast_string_field_set, ast_strip(), ast_strlen_zero(), ip_identify_match::endpoint_name, ip_identify_match::hosts, ip_identify_match_host_lookup(), ip_identify_match_srv_lookup(), ip_identify_match::is_header_regex, ip_identify_match::is_request_uri_regex, len(), LOG_ERROR, LOG_WARNING, ip_identify_match::match_header, ip_identify_match::match_request_uri, ip_identify_match::matches, NULL, ip_identify_match::regex_header_buf, ip_identify_match::regex_request_uri_buf, and ip_identify_match::srv_lookups.

Referenced by load_module().

◆ ip_identify_destroy()

static void ip_identify_destroy ( void *  obj)
static

Destructor function for a matching object.

Definition at line 198 of file res_pjsip_endpoint_identifier_ip.c.

199{
200 struct ip_identify_match *identify = obj;
201
203 ast_free_ha(identify->matches);
204 ao2_cleanup(identify->hosts);
205 if (identify->is_header_regex) {
206 regfree(&identify->regex_header_buf);
207 }
208 if (identify->is_request_uri_regex) {
209 regfree(&identify->regex_request_uri_buf);
210 }
211}
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition acl.c:222
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object

References ao2_cleanup, ast_free_ha(), ast_string_field_free_memory, ip_identify_match::hosts, ip_identify_match::is_header_regex, ip_identify_match::is_request_uri_regex, ip_identify_match::matches, ip_identify_match::regex_header_buf, and ip_identify_match::regex_request_uri_buf.

Referenced by ip_identify_alloc().

◆ ip_identify_match_check()

static int ip_identify_match_check ( void *  obj,
void *  arg,
int  flags 
)
static

Comparator function for matching an object by IP address.

Definition at line 329 of file res_pjsip_endpoint_identifier_ip.c.

330{
331 struct ip_identify_match *identify = obj;
332 struct ast_sockaddr *addr = arg;
333 int sense;
334
335 sense = ast_apply_ha(identify->matches, addr);
336 if (sense != AST_SENSE_ALLOW) {
337 ast_debug(3, "Source address %s matches identify '%s'\n",
339 ast_sorcery_object_get_id(identify));
340 return CMP_MATCH;
341 } else {
342 ast_debug(3, "Source address %s does not match identify '%s'\n",
344 ast_sorcery_object_get_id(identify));
345 return 0;
346 }
347}
enum ast_acl_sense ast_apply_ha(const struct ast_ha *ha, const struct ast_sockaddr *addr)
Apply a set of rules to a given IP address.
Definition acl.c:807

References ast_apply_ha(), ast_debug, AST_SENSE_ALLOW, ast_sockaddr_stringify(), ast_sorcery_object_get_id(), CMP_MATCH, and ip_identify_match::matches.

Referenced by ip_identify().

◆ ip_identify_match_handler()

static int ip_identify_match_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Custom handler for match field.

Definition at line 482 of file res_pjsip_endpoint_identifier_ip.c.

483{
484 struct ip_identify_match *identify = obj;
485 char *input_string = ast_strdupa(var->value);
486 char *current_string;
487
488 if (ast_strlen_zero(var->value)) {
489 return 0;
490 }
491
492 while ((current_string = ast_strip(strsep(&input_string, ",")))) {
493 char *mask;
494 struct ast_sockaddr address;
495 int error = 0;
496
497 if (ast_strlen_zero(current_string)) {
498 continue;
499 }
500
501 mask = strrchr(current_string, '/');
502
503 /* If it looks like a netmask is present, or we can immediately parse as an IP,
504 * hand things off to the ACL */
505 if (mask || ast_sockaddr_parse(&address, current_string, 0)) {
506 identify->matches = ast_append_ha_with_port("d", current_string, identify->matches, &error);
507
508 if (!identify->matches || error) {
509 ast_log(LOG_ERROR, "Failed to add address '%s' to ip endpoint identifier '%s'\n",
510 current_string, ast_sorcery_object_get_id(obj));
511 return -1;
512 }
513
514 continue;
515 }
516
517 if (!identify->hosts) {
519 if (!identify->hosts) {
520 ast_log(LOG_ERROR, "Failed to create container to store hosts on ip endpoint identifier '%s'\n",
522 return -1;
523 }
524 }
525
526 error = ast_str_container_add(identify->hosts, current_string);
527 if (error) {
528 ast_log(LOG_ERROR, "Failed to store host '%s' for resolution on ip endpoint identifier '%s'\n",
529 current_string, ast_sorcery_object_get_id(obj));
530 return -1;
531 }
532 }
533
534 return 0;
535}
struct ast_ha * ast_append_ha_with_port(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule with optional port to a list of HAs.
Definition acl.c:717
#define var
Definition ast_expr2f.c:605
char * strsep(char **str, const char *delims)
char * address
Definition f2c.h:59
#define HOSTS_BUCKETS
The number of buckets for storing hosts for resolution.
struct ao2_container * ast_str_container_alloc_options(enum ao2_alloc_opts opts, int buckets)
Allocates a hash container for bare strings.
Definition strings.c:200
int ast_str_container_add(struct ao2_container *str_container, const char *add)
Adds a string to a string container allocated by ast_str_container_alloc.
Definition strings.c:205
int error(const char *format,...)

References AO2_ALLOC_OPT_LOCK_NOLOCK, ast_append_ha_with_port(), ast_log, ast_sockaddr_parse(), ast_sorcery_object_get_id(), ast_str_container_add(), ast_str_container_alloc_options(), ast_strdupa, ast_strip(), ast_strlen_zero(), error(), ip_identify_match::hosts, HOSTS_BUCKETS, LOG_ERROR, ip_identify_match::matches, strsep(), and var.

Referenced by load_module().

◆ ip_identify_match_host_lookup()

static int ip_identify_match_host_lookup ( struct ip_identify_match identify,
const char *  host,
int *  resolved 
)
static

Helper function which performs a host lookup and adds result to identify match.

Definition at line 415 of file res_pjsip_endpoint_identifier_ip.c.

416{
417 struct ast_sockaddr *addrs;
418 int num_addrs = 0, error = 0, i;
419 int results = 0;
420
421 num_addrs = ast_sockaddr_resolve(&addrs, host, 0, AST_AF_UNSPEC);
422 if (!num_addrs) {
423 return -1;
424 }
425 *resolved = 1;
426
427 for (i = 0; i < num_addrs; ++i) {
428 /* Check if the address is already in the list, if so don't add it again */
429 if (identify->matches && (ast_apply_ha(identify->matches, &addrs[i]) != AST_SENSE_ALLOW)) {
430 continue;
431 }
432
433 /* We deny what we actually want to match because there is an implicit permit all rule for ACLs */
434 identify->matches = ast_append_ha_with_port("d", ast_sockaddr_stringify(&addrs[i]), identify->matches, &error);
435
436 if (!identify->matches || error) {
437 results = -1;
438 break;
439 }
440
441 results += 1;
442 }
443
444 ast_free(addrs);
445
446 return results;
447}
int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, int flags, int family)
Parses a string with an IPv4 or IPv6 address and place results into an array.
Definition netsock2.c:280
@ AST_AF_UNSPEC
Definition netsock2.h:54

References AST_AF_UNSPEC, ast_append_ha_with_port(), ast_apply_ha(), ast_free, AST_SENSE_ALLOW, ast_sockaddr_resolve(), ast_sockaddr_stringify(), error(), and ip_identify_match::matches.

Referenced by ip_identify_apply(), and ip_identify_match_srv_lookup().

◆ ip_identify_match_srv_lookup()

static int ip_identify_match_srv_lookup ( struct ip_identify_match identify,
const char *  prefix,
const char *  host,
int  results,
int *  resolved 
)
static

Helper function which performs an SRV lookup and then resolves the hostname.

Definition at line 450 of file res_pjsip_endpoint_identifier_ip.c.

452{
453 char service[NI_MAXHOST];
454 struct srv_context *context = NULL;
455 int srv_ret;
456 const char *srvhost;
457 unsigned short srvport;
458
459 snprintf(service, sizeof(service), "%s.%s", prefix, host);
460
461 while (!(srv_ret = ast_srv_lookup(&context, service, &srvhost, &srvport))) {
462 int hosts;
463
464 /* In the case of the SRV lookup we don't care if it fails, we will output a log message
465 * when we fallback to a normal lookup.
466 */
467 hosts = ip_identify_match_host_lookup(identify, srvhost, resolved);
468 if (hosts == -1) {
469 results = -1;
470 break;
471 } else {
472 results += hosts;
473 }
474 }
475
476 ast_srv_cleanup(&context);
477
478 return results;
479}
enum ast_cc_service_type service
Definition ccss.c:399
static char prefix[MAX_PREFIX]
Definition http.c:145
void ast_srv_cleanup(struct srv_context **context)
Cleanup resources associated with ast_srv_lookup.
Definition srv.c:248
int ast_srv_lookup(struct srv_context **context, const char *service, const char **host, unsigned short *port)
Retrieve set of SRV lookups, in order.
Definition srv.c:202

References ast_srv_cleanup(), ast_srv_lookup(), ip_identify_match_host_lookup(), NULL, prefix, and service.

Referenced by ip_identify_apply().

◆ load_module()

static int load_module ( void  )
static

Definition at line 975 of file res_pjsip_endpoint_identifier_ip.c.

976{
977 ast_sorcery_apply_config(ast_sip_get_sorcery(), "res_pjsip_endpoint_identifier_ip");
978 ast_sorcery_apply_default(ast_sip_get_sorcery(), "identify", "config", "pjsip.conf,criteria=type=identify");
979
982 }
983
984 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "type", "", OPT_NOOP_T, 0, 0);
985 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "endpoint", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, endpoint_name));
987 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "match_header", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, match_header));
988 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "match_request_uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ip_identify_match, match_request_uri));
989 ast_sorcery_object_field_register(ast_sip_get_sorcery(), "identify", "srv_lookups", "yes", OPT_BOOL_T, 1, FLDSET(struct ip_identify_match, srv_lookups));
991
996
998 if (!cli_formatter) {
999 ast_log(LOG_ERROR, "Unable to allocate memory for cli formatter\n");
1001 }
1002 cli_formatter->name = "identify";
1009
1012
1014}
#define ao2_alloc(data_size, destructor_fn)
Definition astobj2.h:409
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition cli.h:265
#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_NOOP_T
Type for a default handler that should do nothing.
@ OPT_BOOL_T
Type for default option handler for bools (ast_true/ast_false)
@ OPT_STRINGFIELD_T
Type for default option handler for stringfields.
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition module.h:78
void ast_sip_register_endpoint_formatter(struct ast_sip_endpoint_formatter *obj)
Register an endpoint formatter.
Definition res_pjsip.c:479
int ast_sip_register_endpoint_identifier_with_name(struct ast_sip_endpoint_identifier *identifier, const char *name)
Register a SIP endpoint identifier with a name.
Definition res_pjsip.c:227
int ast_sip_register_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Registers a CLI formatter.
Definition pjsip_cli.c:310
static int cli_print_header(void *obj, void *arg, int flags)
static int cli_iterator(void *container, ao2_callback_fn callback, void *args)
static void * ip_identify_alloc(const char *name)
Allocator function for a matching object.
static struct ast_sip_endpoint_identifier request_identifier
static int ip_identify_apply(const struct ast_sorcery *sorcery, void *obj)
Apply handler for identify type.
static int ip_identify_match_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
Custom handler for match field.
static struct ast_sip_endpoint_identifier header_identifier
static void * cli_retrieve_by_id(const char *id)
static struct ast_cli_entry cli_identify[]
static struct ao2_container * cli_get_container(const char *regex)
struct ast_sip_endpoint_formatter endpoint_identify_formatter
static int cli_print_body(void *obj, void *arg, int flags)
static struct ast_sip_cli_formatter_entry * cli_formatter
static struct ast_sip_endpoint_identifier ip_identifier
static int match_to_str(const void *obj, const intptr_t *args, char **buf)
static int match_to_var_list(const void *obj, struct ast_variable **fields)
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
Definition sorcery.h:837
void ast_sorcery_load_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to load persistent objects.
Definition sorcery.c:1457
#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.
Definition sorcery.h:1005
#define ast_sorcery_apply_config(sorcery, name)
Definition sorcery.h:455
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
Definition sorcery.h:955
#define ast_sorcery_apply_default(sorcery, type, name, data)
Definition sorcery.h:476
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)
const char * name
ao2_callback_fn * print_body
struct ao2_container *(* get_container)(const char *regex)
#define ARRAY_LEN(a)
Definition utils.h:706

References ao2_alloc, ARRAY_LEN, ast_cli_register_multiple, ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_sip_get_sorcery(), ast_sip_register_cli_formatter(), ast_sip_register_endpoint_formatter(), ast_sip_register_endpoint_identifier_with_name(), ast_sorcery_apply_config, ast_sorcery_apply_default, ast_sorcery_load_object(), ast_sorcery_object_field_register, ast_sorcery_object_field_register_custom, ast_sorcery_object_get_id(), ast_sorcery_object_register, cli_formatter, cli_get_container(), cli_identify, cli_iterator(), cli_print_body(), cli_print_header(), cli_retrieve_by_id(), endpoint_identify_formatter, FLDSET, ast_sip_cli_formatter_entry::get_container, ast_sip_cli_formatter_entry::get_id, header_identifier, ip_identifier, ip_identify_alloc(), ip_identify_apply(), ip_identify_match_handler(), ast_sip_cli_formatter_entry::iterate, LOG_ERROR, match_to_str(), match_to_var_list(), ast_sip_cli_formatter_entry::name, NULL, OPT_BOOL_T, OPT_NOOP_T, OPT_STRINGFIELD_T, ast_sip_cli_formatter_entry::print_body, ast_sip_cli_formatter_entry::print_header, request_identifier, ast_sip_cli_formatter_entry::retrieve_by_id, and STRFLDSET.

◆ match_to_str()

static int match_to_str ( const void *  obj,
const intptr_t *  args,
char **  buf 
)
static

Definition at line 697 of file res_pjsip_endpoint_identifier_ip.c.

698{
700 const struct ip_identify_match *identify = obj;
701
702 ast_ha_join(identify->matches, &str);
704 return 0;
705}
void ast_ha_join(const struct ast_ha *ha, struct ast_str **buf)
Convert HAs to a comma separated string value.
Definition acl.c:722
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761

References ast_free, ast_ha_join(), ast_str_buffer(), ast_str_create, ast_strdup, buf, ip_identify_match::matches, MAX_OBJECT_FIELD, RAII_VAR, and str.

Referenced by load_module().

◆ match_to_var_list()

static int match_to_var_list ( const void *  obj,
struct ast_variable **  fields 
)
static

Definition at line 724 of file res_pjsip_endpoint_identifier_ip.c.

725{
726 const struct ip_identify_match *identify = obj;
727 struct ast_variable *head = NULL;
728 struct ast_ha *ha = identify->matches;
729
730 for (; ha; ha = ha->next) {
731 match_to_var_list_append(&head, ha);
732 }
733
734 if (head) {
735 *fields = head;
736 }
737
738 return 0;
739}
static void match_to_var_list_append(struct ast_variable **head, struct ast_ha *ha)
struct ast_ha * next
Definition acl.h:56

References match_to_var_list_append(), ip_identify_match::matches, ast_ha::next, and NULL.

Referenced by load_module().

◆ match_to_var_list_append()

static void match_to_var_list_append ( struct ast_variable **  head,
struct ast_ha ha 
)
static

Definition at line 707 of file res_pjsip_endpoint_identifier_ip.c.

708{
709 char str[MAX_OBJECT_FIELD];
710 const char *addr;
711
712 if (ast_sockaddr_port(&ha->addr)) {
714 } else {
716 }
717
718 snprintf(str, MAX_OBJECT_FIELD, "%s%s/%s", ha->sense == AST_SENSE_ALLOW ? "!" : "",
719 addr, ast_sockaddr_stringify_addr(&ha->netmask));
720
721 ast_variable_list_append(head, ast_variable_new("match", str, ""));
722}
#define ast_variable_new(name, value, filename)
#define ast_variable_list_append(head, new_var)
enum ast_acl_sense sense
Definition acl.h:55

References ast_ha::addr, AST_SENSE_ALLOW, ast_sockaddr_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_variable_list_append, ast_variable_new, MAX_OBJECT_FIELD, ast_ha::netmask, ast_ha::sense, and str.

Referenced by match_to_var_list().

◆ my_cli_traverse_objects()

static char * my_cli_traverse_objects ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 950 of file res_pjsip_endpoint_identifier_ip.c.

952{
953 return ast_sip_cli_traverse_objects(e, cmd, a);
954}
char * ast_sip_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition pjsip_cli.c:109
static struct test_val a

References a, and ast_sip_cli_traverse_objects().

◆ reload_module()

static int reload_module ( void  )
static

Definition at line 1016 of file res_pjsip_endpoint_identifier_ip.c.

1017{
1019
1020 return 0;
1021}
void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to reload persistent objects.
Definition sorcery.c:1506

References ast_sip_get_sorcery(), and ast_sorcery_reload_object().

◆ request_identify()

static struct ast_sip_endpoint * request_identify ( pjsip_rx_data *  rdata)
static

Definition at line 401 of file res_pjsip_endpoint_identifier_ip.c.

402{
404}
static int request_identify_match_check(void *obj, void *arg, int flags)
Comparator function for matching an object by request URI.

References common_identify(), and request_identify_match_check().

◆ request_identify_match_check()

static int request_identify_match_check ( void *  obj,
void *  arg,
int  flags 
)
static

Comparator function for matching an object by request URI.

Definition at line 294 of file res_pjsip_endpoint_identifier_ip.c.

295{
296 struct ip_identify_match *identify = obj;
297 struct pjsip_rx_data *rdata = arg;
298 int len;
299 char buf[PJSIP_MAX_URL_SIZE];
300
301 if (ast_strlen_zero(identify->match_request_uri)) {
302 return 0;
303 }
304
305 /* Print request URI to req_buf */
306 len = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, rdata->msg_info.msg->line.req.uri, buf, sizeof(buf) - 1);
307 if (len < 0) {
308 /* Buffer not large enough or no pj uri vptr! */
309 ast_assert(0);
310 } else {
311 /* Terminate the pj_str */
312 buf[len] = '\0';
313 /* Does request URI match what we are looking for? */
314 if (identify->is_request_uri_regex) {
315 if (!regexec(&identify->regex_request_uri_buf, buf, 0, NULL, 0)) {
316 return CMP_MATCH;
317 }
318 } else if (!strcmp(identify->match_request_uri, buf)) {
319 return CMP_MATCH;
320 }
321 ast_debug(3, "Identify '%s': request URI not match '%s' (value='%s').\n",
322 ast_sorcery_object_get_id(identify), identify->match_request_uri, buf);
323 }
324
325 return 0;
326}

References ast_assert, ast_debug, ast_sorcery_object_get_id(), ast_strlen_zero(), buf, CMP_MATCH, ip_identify_match::is_request_uri_regex, len(), ip_identify_match::match_request_uri, NULL, and ip_identify_match::regex_request_uri_buf.

Referenced by request_identify().

◆ send_identify_ami_event()

static int send_identify_ami_event ( void *  obj,
void *  arg,
void *  data,
int  flags 
)
static

Definition at line 747 of file res_pjsip_endpoint_identifier_ip.c.

748{
749 struct ip_identify_match *identify = obj;
750 const char *endpoint_name = arg;
751 struct ast_sip_ami *ami = data;
752 struct ast_str *buf;
753
754 /* Build AMI event */
755 buf = ast_sip_create_ami_event("IdentifyDetail", ami);
756 if (!buf) {
757 return CMP_STOP;
758 }
759 if (sip_identify_to_ami(identify, &buf)) {
760 ast_free(buf);
761 return CMP_STOP;
762 }
763 ast_str_append(&buf, 0, "EndpointName: %s\r\n", endpoint_name);
764
765 /* Send AMI event */
766 astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
767 ++ami->count;
768
769 ast_free(buf);
770 return 0;
771}
@ CMP_STOP
Definition astobj2.h:1028
void astman_append(struct mansession *s, const char *fmt,...)
Definition manager.c:1842
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.
static int sip_identify_to_ami(const struct ip_identify_match *identify, struct ast_str **buf)
AMI variable container.
Definition res_pjsip.h:3257
struct mansession * s
Definition res_pjsip.h:3259

References ast_free, ast_sip_create_ami_event(), ast_str_append(), ast_str_buffer(), astman_append(), buf, CMP_STOP, ast_sip_ami::count, ip_identify_match::endpoint_name, ast_sip_ami::s, and sip_identify_to_ami().

Referenced by format_ami_endpoint_identify().

◆ sip_identify_to_ami()

static int sip_identify_to_ami ( const struct ip_identify_match identify,
struct ast_str **  buf 
)
static

Definition at line 741 of file res_pjsip_endpoint_identifier_ip.c.

743{
744 return ast_sip_sorcery_object_to_ami(identify, buf);
745}
int ast_sip_sorcery_object_to_ami(const void *obj, struct ast_str **buf)
Converts a sorcery object to a string of object properties.

References ast_sip_sorcery_object_to_ami(), and buf.

Referenced by send_identify_ami_event().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 1023 of file res_pjsip_endpoint_identifier_ip.c.

1024{
1031
1032 return 0;
1033}
void ast_cli_unregister_multiple(void)
Definition ael_main.c:408
void ast_sip_unregister_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
Unregister a SIP endpoint identifier.
Definition res_pjsip.c:309
void ast_sip_unregister_endpoint_formatter(struct ast_sip_endpoint_formatter *obj)
Unregister an endpoint formatter.
Definition res_pjsip.c:485
int ast_sip_unregister_cli_formatter(struct ast_sip_cli_formatter_entry *formatter)
Unregisters a CLI formatter.
Definition pjsip_cli.c:326

References ARRAY_LEN, ast_cli_unregister_multiple(), ast_sip_unregister_cli_formatter(), ast_sip_unregister_endpoint_formatter(), ast_sip_unregister_endpoint_identifier(), cli_formatter, cli_identify, endpoint_identify_formatter, header_identifier, ip_identifier, and request_identifier.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP IP endpoint identifier" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .reload = reload_module, .unload = unload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND - 4, .requires = "res_pjsip", }
static

Definition at line 1042 of file res_pjsip_endpoint_identifier_ip.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 1042 of file res_pjsip_endpoint_identifier_ip.c.

◆ cli_formatter

struct ast_sip_cli_formatter_entry* cli_formatter
static

Definition at line 973 of file res_pjsip_endpoint_identifier_ip.c.

Referenced by load_module(), and unload_module().

◆ cli_identify

struct ast_cli_entry cli_identify[]
static

Definition at line 956 of file res_pjsip_endpoint_identifier_ip.c.

956 {
957AST_CLI_DEFINE(my_cli_traverse_objects, "List PJSIP Identifies",
958 .command = "pjsip list identifies",
959 .usage = "Usage: pjsip list identifies [ like <pattern> ]\n"
960 " List the configured PJSIP Identifies\n"
961 " Optional regular expression pattern is used to filter the list.\n"),
962AST_CLI_DEFINE(my_cli_traverse_objects, "Show PJSIP Identifies",
963 .command = "pjsip show identifies",
964 .usage = "Usage: pjsip show identifies [ like <pattern> ]\n"
965 " Show the configured PJSIP Identifies\n"
966 " Optional regular expression pattern is used to filter the list.\n"),
967AST_CLI_DEFINE(my_cli_traverse_objects, "Show PJSIP Identify",
968 .command = "pjsip show identify",
969 .usage = "Usage: pjsip show identify <id>\n"
970 " Show the configured PJSIP Identify\n"),
971};
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197
static char * my_cli_traverse_objects(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
char * usage
Definition utils/frame.c:37

Referenced by load_module(), and unload_module().

◆ endpoint_identify_formatter

struct ast_sip_endpoint_formatter endpoint_identify_formatter
Initial value:
= {
}
static int format_ami_endpoint_identify(const struct ast_sip_endpoint *endpoint, struct ast_sip_ami *ami)

Definition at line 798 of file res_pjsip_endpoint_identifier_ip.c.

798 {
799 .format_ami = format_ami_endpoint_identify
800};

Referenced by load_module(), and unload_module().

◆ header_identifier

struct ast_sip_endpoint_identifier header_identifier
static
Initial value:
= {
.identify_endpoint = header_identify,
}
static struct ast_sip_endpoint * header_identify(pjsip_rx_data *rdata)

Definition at line 406 of file res_pjsip_endpoint_identifier_ip.c.

406 {
407 .identify_endpoint = header_identify,
408};

Referenced by load_module(), and unload_module().

◆ ip_identifier

struct ast_sip_endpoint_identifier ip_identifier
static
Initial value:
= {
.identify_endpoint = ip_identify,
}
static struct ast_sip_endpoint * ip_identify(pjsip_rx_data *rdata)

Definition at line 392 of file res_pjsip_endpoint_identifier_ip.c.

392 {
393 .identify_endpoint = ip_identify,
394};

Referenced by load_module(), and unload_module().

◆ request_identifier

struct ast_sip_endpoint_identifier request_identifier
static
Initial value:
= {
.identify_endpoint = request_identify,
}
static struct ast_sip_endpoint * request_identify(pjsip_rx_data *rdata)

Definition at line 410 of file res_pjsip_endpoint_identifier_ip.c.

410 {
411 .identify_endpoint = request_identify,
412};

Referenced by load_module(), and unload_module().