summaryrefslogtreecommitdiff
path: root/res/res_pjsip_endpoint_identifier_ip.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2017-12-22 19:50:34 -0600
committerRichard Mudgett <rmudgett@digium.com>2018-01-16 12:50:34 -0600
commit8494e78010d8917a4165d877045be34ddc2dda22 (patch)
treeb1ecd89e12d5925258d337e67e966164b044f99c /res/res_pjsip_endpoint_identifier_ip.c
parent2f392bedb3987ee3c587bd8b046299320b84d5c5 (diff)
res_pjsip: Split type=identify to IP address and SIP header matching priorities
The type=identify endpoint identification method can match by IP address and by SIP header. However, the SIP header matching has limited usefulness because you cannot specify the SIP header matching priority relative to the IP address matching. All the matching happens at the same priority and the order of evaluating the identify sections is indeterminate. e.g., If you had two type=identify sections where one matches by IP address for endpoint alice and the other matches by SIP header for endpoint bob then you couldn't predict which endpoint is matched when a request comes in that matches both. * Extract the SIP header matching criteria into its own "header" endpoint identification method so the user can specify the relative priority of the SIP header and the IP address matching criteria in the global endpoint_identifier_order option. The "ip" endpoint identification method now only matches by IP address. ASTERISK-27491 Change-Id: I9df142a575b7e1e3471b7cda5d3ea156cef08095
Diffstat (limited to 'res/res_pjsip_endpoint_identifier_ip.c')
-rw-r--r--res/res_pjsip_endpoint_identifier_ip.c57
1 files changed, 36 insertions, 21 deletions
diff --git a/res/res_pjsip_endpoint_identifier_ip.c b/res/res_pjsip_endpoint_identifier_ip.c
index 58e462460..ee47e4d4e 100644
--- a/res/res_pjsip_endpoint_identifier_ip.c
+++ b/res/res_pjsip_endpoint_identifier_ip.c
@@ -186,7 +186,7 @@ static int header_identify_match_check(void *obj, void *arg, int flags)
return 0;
}
- return CMP_MATCH | CMP_STOP;
+ return CMP_MATCH;
}
/*! \brief Comparator function for matching an object by IP address */
@@ -201,7 +201,7 @@ static int ip_identify_match_check(void *obj, void *arg, int flags)
ast_debug(3, "Source address %s matches identify '%s'\n",
ast_sockaddr_stringify(addr),
ast_sorcery_object_get_id(identify));
- return CMP_MATCH | CMP_STOP;
+ return CMP_MATCH;
} else {
ast_debug(3, "Source address %s does not match identify '%s'\n",
ast_sockaddr_stringify(addr),
@@ -210,48 +210,62 @@ static int ip_identify_match_check(void *obj, void *arg, int flags)
}
}
-static struct ast_sip_endpoint *ip_identify(pjsip_rx_data *rdata)
+static struct ast_sip_endpoint *common_identify(ao2_callback_fn *identify_match_cb, void *arg)
{
- struct ast_sockaddr addr = { { 0, } };
RAII_VAR(struct ao2_container *, candidates, NULL, ao2_cleanup);
- RAII_VAR(struct ip_identify_match *, match, NULL, ao2_cleanup);
+ struct ip_identify_match *match;
struct ast_sip_endpoint *endpoint;
/* If no possibilities exist return early to save some time */
- if (!(candidates = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL)) ||
- !ao2_container_count(candidates)) {
+ candidates = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "identify",
+ AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
+ if (!candidates || !ao2_container_count(candidates)) {
ast_debug(3, "No identify sections to match against\n");
return NULL;
}
- ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
- ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port);
-
- match = ao2_callback(candidates, 0, ip_identify_match_check, &addr);
+ match = ao2_callback(candidates, 0, identify_match_cb, arg);
if (!match) {
- ast_debug(3, "Identify checks by IP address failed to find match: '%s' did not match any identify section rules\n",
- ast_sockaddr_stringify(&addr));
- match = ao2_callback(candidates, 0, header_identify_match_check, rdata);
- if (!match) {
- return NULL;
- }
+ return NULL;
}
- endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", match->endpoint_name);
+ endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint",
+ match->endpoint_name);
if (endpoint) {
- ast_debug(3, "Retrieved endpoint %s\n", ast_sorcery_object_get_id(endpoint));
+ ast_debug(3, "Identify '%s' SIP message matched to endpoint %s\n",
+ ast_sorcery_object_get_id(match), match->endpoint_name);
} else {
- ast_log(LOG_WARNING, "Identify section '%s' points to endpoint '%s' but endpoint could not be looked up\n",
- ast_sorcery_object_get_id(match), match->endpoint_name);
+ ast_log(LOG_WARNING, "Identify '%s' points to endpoint '%s' but endpoint could not be found\n",
+ ast_sorcery_object_get_id(match), match->endpoint_name);
}
+ ao2_ref(match, -1);
return endpoint;
}
+static struct ast_sip_endpoint *ip_identify(pjsip_rx_data *rdata)
+{
+ struct ast_sockaddr addr = { { 0, } };
+
+ ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
+ ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port);
+
+ return common_identify(ip_identify_match_check, &addr);
+}
+
static struct ast_sip_endpoint_identifier ip_identifier = {
.identify_endpoint = ip_identify,
};
+static struct ast_sip_endpoint *header_identify(pjsip_rx_data *rdata)
+{
+ return common_identify(header_identify_match_check, rdata);
+}
+
+static struct ast_sip_endpoint_identifier header_identifier = {
+ .identify_endpoint = header_identify,
+};
+
/*! \brief Helper function which performs a host lookup and adds result to identify match */
static int ip_identify_match_host_lookup(struct ip_identify_match *identify, const char *host)
{
@@ -720,6 +734,7 @@ static int load_module(void)
ast_sorcery_load_object(ast_sip_get_sorcery(), "identify");
ast_sip_register_endpoint_identifier_with_name(&ip_identifier, "ip");
+ ast_sip_register_endpoint_identifier_with_name(&header_identifier, "header");
ast_sip_register_endpoint_formatter(&endpoint_identify_formatter);
cli_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);