aboutsummaryrefslogtreecommitdiffstats
path: root/pbx
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2007-03-07 22:30:52 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2007-03-07 22:30:52 +0000
commit37371ea446a869461a4b9511a1cfcdd316c92627 (patch)
tree8d4088c771d6cffda4f94c22688bf0e952b739a3 /pbx
parentad62ae0f76479d764136eb88fbc9ebb42c5407f4 (diff)
Add the ability to dynamically specify weights for responses to DUNDi queries.
This can be done using a global variable or a dialplan function. Using the SHELL() function will allow you to use an external script to determine what the weight in the response should be. This can be very useful in load balancing applications. (inspired by discussions with blitzrage and jsmith in #asterisk-bugs) git-svn-id: http://svn.digium.com/svn/asterisk/trunk@58304 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'pbx')
-rw-r--r--pbx/pbx_dundi.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/pbx/pbx_dundi.c b/pbx/pbx_dundi.c
index 62c2c558b..21a06a079 100644
--- a/pbx/pbx_dundi.c
+++ b/pbx/pbx_dundi.c
@@ -79,6 +79,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#define MAX_PACKET_SIZE 8192
+#define MAX_WEIGHT 59999
+
#define DUNDI_MODEL_INBOUND (1 << 0)
#define DUNDI_MODEL_OUTBOUND (1 << 1)
#define DUNDI_MODEL_SYMMETRIC (DUNDI_MODEL_INBOUND | DUNDI_MODEL_OUTBOUND)
@@ -211,7 +213,8 @@ struct dundi_request {
struct dundi_mapping {
char dcontext[AST_MAX_EXTENSION];
char lcontext[AST_MAX_EXTENSION];
- int weight;
+ int _weight;
+ char *weightstr;
int options;
int tech;
int dead;
@@ -511,6 +514,19 @@ struct dundi_query_state {
char fluffy[0];
};
+static int get_mapping_weight(struct dundi_mapping *map)
+{
+ char buf[32] = "";
+
+ if (map->weightstr) {
+ pbx_substitute_variables_helper(NULL, map->weightstr, buf, sizeof(buf) - 1);
+ if (sscanf(buf, "%d", &map->_weight) != 1)
+ map->_weight = MAX_WEIGHT;
+ }
+
+ return map->_weight;
+}
+
static int dundi_lookup_local(struct dundi_result *dr, struct dundi_mapping *map, char *called_number, dundi_eid *us_eid, int anscnt, struct dundi_hint_metadata *hmd)
{
struct ast_flags flags = {0};
@@ -539,7 +555,7 @@ static int dundi_lookup_local(struct dundi_result *dr, struct dundi_mapping *map
ast_set_flag(&flags, map->options & 0xffff);
ast_copy_flags(dr + anscnt, &flags, AST_FLAGS_ALL);
dr[anscnt].techint = map->tech;
- dr[anscnt].weight = map->weight;
+ dr[anscnt].weight = get_mapping_weight(map);
dr[anscnt].expiration = dundi_cache_time;
ast_copy_string(dr[anscnt].tech, tech2str(map->tech), sizeof(dr[anscnt].tech));
dr[anscnt].eid = *us_eid;
@@ -2591,15 +2607,17 @@ static int dundi_show_requests(int fd, int argc, char *argv[])
static int dundi_show_mappings(int fd, int argc, char *argv[])
{
#define FORMAT2 "%-12.12s %-7.7s %-12.12s %-10.10s %-5.5s %-25.25s\n"
-#define FORMAT "%-12.12s %-7d %-12.12s %-10.10s %-5.5s %-25.25s\n"
+#define FORMAT "%-12.12s %-7s %-12.12s %-10.10s %-5.5s %-25.25s\n"
struct dundi_mapping *map;
char fs[256];
+ char weight[8];
if (argc != 3)
return RESULT_SHOWUSAGE;
AST_LIST_LOCK(&peers);
ast_cli(fd, FORMAT2, "DUNDi Cntxt", "Weight", "Local Cntxt", "Options", "Tech", "Destination");
AST_LIST_TRAVERSE(&mappings, map, list) {
- ast_cli(fd, FORMAT, map->dcontext, map->weight,
+ snprintf(weight, sizeof(weight), "%d", get_mapping_weight(map));
+ ast_cli(fd, FORMAT, map->dcontext, weight,
ast_strlen_zero(map->lcontext) ? "<none>" : map->lcontext,
dundi_flags2str(fs, sizeof(fs), map->options), tech2str(map->tech), map->dest);
}
@@ -3871,6 +3889,8 @@ static void destroy_peer(struct dundi_peer *peer)
static void destroy_map(struct dundi_mapping *map)
{
+ if (map->weightstr)
+ free(map->weightstr);
free(map);
}
@@ -3960,11 +3980,15 @@ static void build_mapping(char *name, char *value)
} else if (x >= 4) {
ast_copy_string(map->dcontext, name, sizeof(map->dcontext));
ast_copy_string(map->lcontext, fields[0], sizeof(map->lcontext));
- if ((sscanf(fields[1], "%d", &map->weight) == 1) && (map->weight >= 0) && (map->weight < 60000)) {
+ if ((sscanf(fields[1], "%d", &map->_weight) == 1) && (map->_weight >= 0) && (map->_weight <= MAX_WEIGHT)) {
ast_copy_string(map->dest, fields[3], sizeof(map->dest));
- if ((map->tech = str2tech(fields[2]))) {
+ if ((map->tech = str2tech(fields[2])))
+ map->dead = 0;
+ } else if (!strncmp(fields[1], "${", 2) && fields[1][strlen(fields[1]) - 1] == '}') {
+ map->weightstr = ast_strdup(fields[1]);
+ ast_copy_string(map->dest, fields[3], sizeof(map->dest));
+ if ((map->tech = str2tech(fields[2])))
map->dead = 0;
- }
} else {
ast_log(LOG_WARNING, "Invalid weight '%s' specified, deleting entry '%s/%s'\n", fields[1], map->dcontext, map->lcontext);
}