summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2017-01-23 16:08:37 +0000
committerJoshua Colp <jcolp@digium.com>2017-01-23 16:08:37 +0000
commit6d23b2e360789f44923b527fa97564a2ff648268 (patch)
treee493cb6c15ccc4df1de5fe0a6aa86e2ceb23ab1b
parentfb21931a5295140e28878d8a83b0baa18424771b (diff)
res_pjsip_endpoint_identifier_ip: Read settings before resolving.
An option has been added, srv_lookups, which controls whether SRV lookups are performed on the provided match hosts or not. It was possible for this option to be applied after resolution had already happened. This change makes it so hosts are stored away, settings are read and applied, and then resolution is done. This ensures that no matter the ordering the srv_lookups option is in effect. ASTERISK-26735 Change-Id: I750378cb277be0140f8c5539450270afbfc43388
-rw-r--r--res/res_pjsip_endpoint_identifier_ip.c51
1 files changed, 47 insertions, 4 deletions
diff --git a/res/res_pjsip_endpoint_identifier_ip.c b/res/res_pjsip_endpoint_identifier_ip.c
index cf950ea18..68922315e 100644
--- a/res/res_pjsip_endpoint_identifier_ip.c
+++ b/res/res_pjsip_endpoint_identifier_ip.c
@@ -66,6 +66,9 @@
</configInfo>
***/
+/*! \brief The number of buckets for storing hosts for resolution */
+#define HOSTS_BUCKETS 53
+
/*! \brief Structure for an IP identification matching object */
struct ip_identify_match {
/*! \brief Sorcery object details */
@@ -79,6 +82,8 @@ struct ip_identify_match {
struct ast_ha *matches;
/*! \brief Perform SRV resolution of hostnames */
unsigned int srv_lookups;
+ /*! \brief Hosts to be resolved after applying configuration */
+ struct ao2_container *hosts;
};
/*! \brief Destructor function for a matching object */
@@ -88,6 +93,7 @@ static void ip_identify_destroy(void *obj)
ast_string_field_free_memory(identify);
ast_free_ha(identify->matches);
+ ao2_cleanup(identify->hosts);
}
/*! \brief Allocator function for a matching object */
@@ -241,8 +247,7 @@ static int ip_identify_match_handler(const struct aco_option *opt, struct ast_va
while ((current_string = ast_strip(strsep(&input_string, ",")))) {
char *mask = strrchr(current_string, '/');
- struct ast_sockaddr address;
- int error, results = 0;
+ int error;
if (ast_strlen_zero(current_string)) {
continue;
@@ -260,6 +265,42 @@ static int ip_identify_match_handler(const struct aco_option *opt, struct ast_va
continue;
}
+ if (!identify->hosts) {
+ identify->hosts = ast_str_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, HOSTS_BUCKETS);
+ if (!identify->hosts) {
+ ast_log(LOG_ERROR, "Failed to create container to store hosts on ip endpoint identifier '%s'\n",
+ ast_sorcery_object_get_id(obj));
+ return -1;
+ }
+ }
+
+ error = ast_str_container_add(identify->hosts, current_string);
+ if (error) {
+ ast_log(LOG_ERROR, "Failed to store host '%s' for resolution on ip endpoint identifier '%s'\n",
+ current_string, ast_sorcery_object_get_id(obj));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/*! \brief Apply handler for identify type */
+static int ip_identify_apply(const struct ast_sorcery *sorcery, void *obj)
+{
+ struct ip_identify_match *identify = obj;
+ char *current_string;
+ struct ao2_iterator i;
+
+ if (!identify->hosts) {
+ return 0;
+ }
+
+ i = ao2_iterator_init(identify->hosts, 0);
+ while ((current_string = ao2_iterator_next(&i))) {
+ struct ast_sockaddr address;
+ int results = 0;
+
/* If the provided string is not an IP address perform SRV resolution on it */
if (identify->srv_lookups && !ast_sockaddr_parse(&address, current_string, 0)) {
results = ip_identify_match_srv_lookup(identify, "_sip._udp", current_string);
@@ -286,10 +327,12 @@ static int ip_identify_match_handler(const struct aco_option *opt, struct ast_va
}
}
+ ao2_ref(identify->hosts, -1);
+ identify->hosts = NULL;
+
return 0;
}
-
static int match_to_str(const void *obj, const intptr_t *args, char **buf)
{
RAII_VAR(struct ast_str *, str, ast_str_create(MAX_OBJECT_FIELD), ast_free);
@@ -537,7 +580,7 @@ static int load_module(void)
ast_sorcery_apply_config(ast_sip_get_sorcery(), "res_pjsip_endpoint_identifier_ip");
ast_sorcery_apply_default(ast_sip_get_sorcery(), "identify", "config", "pjsip.conf,criteria=type=identify");
- if (ast_sorcery_object_register(ast_sip_get_sorcery(), "identify", ip_identify_alloc, NULL, NULL)) {
+ if (ast_sorcery_object_register(ast_sip_get_sorcery(), "identify", ip_identify_alloc, NULL, ip_identify_apply)) {
return AST_MODULE_LOAD_DECLINE;
}