* Contributor(s):
*
* Anthony Minessale II <anthm@freeswitch.org>
+ * Jay Binks <jaybinks@gmail.com>
*
* mod_enum.c -- ENUM
*
#endif
#include <ldns/ldns.h>
+#define ENUM_MAXNAMESERVERS 10 /* max nameservers that will be used */
+
SWITCH_MODULE_LOAD_FUNCTION(mod_enum_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_enum_shutdown);
SWITCH_MODULE_DEFINITION(mod_enum, mod_enum_load, mod_enum_shutdown, NULL);
int timeout;
int retries;
int random;
+ char *nameserver[ENUM_MAXNAMESERVERS];
} globals;
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_root, globals.root);
static switch_status_t load_config(void)
{
char *cf = "enum.conf";
+ int inameserver = 0;
switch_xml_t cfg, xml = NULL, param, settings, route, routes;
switch_status_t status = SWITCH_STATUS_SUCCESS;
globals.random = switch_true(val);
} else if (!strcasecmp(var, "default-isn-root")) {
set_global_isn_root(val);
+ } else if (!strcasecmp(var, "nameserver")) {
+ if ( inameserver < ENUM_MAXNAMESERVERS ) {
+ globals.nameserver[inameserver] = (char *) val;
+ inameserver++;
+ }
} else if (!strcasecmp(var, "log-level-trace")) {
}
return;
}
-
-switch_status_t ldns_lookup(const char *number, const char *root, const char *server_name, enum_record_t **results)
+switch_status_t ldns_lookup(const char *number, const char *root, char *server_name[ENUM_MAXNAMESERVERS] , enum_record_t **results)
{
ldns_resolver *res = NULL;
ldns_rdf *domain = NULL;
switch_status_t status = SWITCH_STATUS_FALSE;
char *name = NULL;
struct timeval to = { 0, 0};
+ int inameserver = 0;
if (!(name = reverse_number(number, root))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Parse Error!\n");
goto end;
}
- if (!zstr(server_name)) {
+ if (server_name) {
res = ldns_resolver_new();
switch_assert(res);
- if ((serv_rdf = ldns_rdf_new_addr_frm_str(server_name))) {
- s = ldns_resolver_push_nameserver(res, serv_rdf);
- ldns_rdf_deep_free(serv_rdf);
+ for(inameserver=0; inameserver<ENUM_MAXNAMESERVERS; inameserver++) {
+ if ( server_name[inameserver] != NULL )
+ {
+ if ((serv_rdf = ldns_rdf_new_addr_frm_str( server_name[inameserver] ))) {
+ s = ldns_resolver_push_nameserver(res, serv_rdf);
+ ldns_rdf_deep_free(serv_rdf);
+ }
+ };
}
+
} else {
/* create a new resolver from /etc/resolv.conf */
s = ldns_resolver_new_frm_file(&res, NULL);
return status;
}
-static switch_status_t enum_lookup(char *root, char *in, enum_record_t **results)
+static switch_status_t enum_lookup(char *root, char *in, enum_record_t **results, switch_channel_t *channel, switch_core_session_t *session)
{
switch_status_t sstatus = SWITCH_STATUS_SUCCESS;
char *mnum = NULL, *mroot = NULL, *p;
- char *server = NULL;
+ char *server[ENUM_MAXNAMESERVERS];
+ int inameserver = 0;
+ char *argv[ ENUM_MAXNAMESERVERS ] = { 0 };
+ int argc;
+ int x = 0;
+ char *enum_nameserver_dup;
*results = NULL;
root = globals.root;
}
+ /* Empty the server array */
+ for(inameserver=0; inameserver<ENUM_MAXNAMESERVERS; inameserver++) {
+ server[inameserver] = NULL;
+ }
+
+ if (!(server[0] = switch_core_get_variable("enum-server"))) {
+ server[0] = globals.server;
+ }
+
+ /* use config param "nameserver" ( can be up to ENUM_MAXNAMESERVERS ) */
+ for(inameserver=0; inameserver<ENUM_MAXNAMESERVERS; inameserver++) {
+ server[inameserver] = NULL;
+ if ( globals.nameserver[inameserver] != NULL )
+ {
+ server[inameserver] = globals.nameserver[inameserver];
+ };
+ }
+
+ /* check for enum_nameserver channel var */
+ if ( channel != NULL ) {
+ const char *enum_nameserver = switch_channel_get_variable(channel, "enum_nameserver");
+ if (!zstr(enum_nameserver))
+ {
+ /* Blank the server array */
+ for(inameserver=0; inameserver<ENUM_MAXNAMESERVERS; inameserver++) {
+ server[inameserver] = NULL;
+ }
- if (!(server = switch_core_get_variable("enum-server"))) {
- server = globals.server;
+ enum_nameserver_dup = switch_core_session_strdup(session, enum_nameserver);
+ argc = switch_separate_string(enum_nameserver_dup, ',', argv, (sizeof(argv) / sizeof(argv[0])));
+
+ inameserver = 0;
+ for (x = 0; x < argc; x++) {
+ server[inameserver] = argv[x];
+ inameserver++;
+ }
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Enum nameserver override : %s\n", enum_nameserver);
+ }
}
ldns_lookup(mnum, root, server, results);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ENUM Lookup on %s\n", caller_profile->destination_number);
- if (enum_lookup(dp, caller_profile->destination_number, &results) == SWITCH_STATUS_SUCCESS) {
+ if (enum_lookup(dp, caller_profile->destination_number, &results, channel, session) == SWITCH_STATUS_SUCCESS) {
if ((extension = switch_caller_extension_new(session, caller_profile->destination_number, caller_profile->destination_number)) == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
free_results(&results);
if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) {
dest = argv[0];
root = argv[1];
- if (enum_lookup(root, dest, &results) == SWITCH_STATUS_SUCCESS) {
+ if (enum_lookup(root, dest, &results, channel, session) == SWITCH_STATUS_SUCCESS) {
switch_event_t *vars;
if (switch_channel_get_variables(channel, &vars) == SWITCH_STATUS_SUCCESS) {
dest = argv[0];
root = argv[1];
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Looking up %s@%s\n", dest, root);
- if (enum_lookup(root, dest, &results) == SWITCH_STATUS_SUCCESS) {
+ if (enum_lookup(root, dest, &results, NULL, session) == SWITCH_STATUS_SUCCESS) {
for (rp = results; rp; rp = rp->next) {
if (!rp->supported) {
continue;
}
- if (!enum_lookup(root, dest, &results) == SWITCH_STATUS_SUCCESS) {
+ if (!enum_lookup(root, dest, &results, NULL, session) == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "No Match!\n");
return SWITCH_STATUS_SUCCESS;
}