mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
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: https://origsvn.digium.com/svn/asterisk/trunk@58304 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
33
CHANGES
33
CHANGES
@@ -6,10 +6,8 @@ Miscellaneous
|
|||||||
-------------
|
-------------
|
||||||
|
|
||||||
* Added the bindaddr option to gtalk.conf.
|
* Added the bindaddr option to gtalk.conf.
|
||||||
* Added the ability to specify arguments to the Dial application when using
|
|
||||||
the DUNDi switch in the dialplan.
|
|
||||||
* Added the ability to customize which sound files are used for some of the
|
* Added the ability to customize which sound files are used for some of the
|
||||||
prompts within the Voicemail application by changing them in voicemail.conf
|
prompts within the Voicemail application by changing them in voicemail.conf
|
||||||
* Argument support for Gosub application
|
* Argument support for Gosub application
|
||||||
* Ability to set process limits without restarting Asterisk
|
* Ability to set process limits without restarting Asterisk
|
||||||
* SS7 support in chan_zap (via libss7 library)
|
* SS7 support in chan_zap (via libss7 library)
|
||||||
@@ -85,7 +83,7 @@ Dialplan functions
|
|||||||
------------------
|
------------------
|
||||||
* Added the DEVSTATE() dialplan function which allows retrieving any device
|
* Added the DEVSTATE() dialplan function which allows retrieving any device
|
||||||
state in the dialplan, as well as creating custom device states that are
|
state in the dialplan, as well as creating custom device states that are
|
||||||
controllable from the dialplan.
|
controllable from the dialplan.
|
||||||
* Extend CALLERID() function with "pres" and "ton" parameters to
|
* Extend CALLERID() function with "pres" and "ton" parameters to
|
||||||
fetch string representation of calling number presentation indicator
|
fetch string representation of calling number presentation indicator
|
||||||
and numeric representation of type of calling number value.
|
and numeric representation of type of calling number value.
|
||||||
@@ -100,18 +98,27 @@ SIP changes
|
|||||||
-----------
|
-----------
|
||||||
* The default SIP useragent= identifier now includes the Asterisk version
|
* The default SIP useragent= identifier now includes the Asterisk version
|
||||||
* A new option, match_auth_username in sip.conf changes the matching of incoming requests.
|
* A new option, match_auth_username in sip.conf changes the matching of incoming requests.
|
||||||
If set, and the incoming request carries authentication info,
|
If set, and the incoming request carries authentication info,
|
||||||
the username to match in the users list is taken from the Digest header
|
the username to match in the users list is taken from the Digest header
|
||||||
rather than from the From: field. This feature is considered experimental.
|
rather than from the From: field. This feature is considered experimental.
|
||||||
* The "musiconhold" and "musicclass" settings in sip.conf are now removed,
|
* The "musiconhold" and "musicclass" settings in sip.conf are now removed,
|
||||||
since they where replaced by "mohsuggest" and "mohinterpret" in version 1.4
|
since they where replaced by "mohsuggest" and "mohinterpret" in version 1.4
|
||||||
* The "localmask" setting was removed in version 1.2 and the reminder about it
|
* The "localmask" setting was removed in version 1.2 and the reminder about it
|
||||||
being removed is now also removed.
|
being removed is now also removed.
|
||||||
* A new option "busy-level" for setting a level of calls where asterisk reports
|
* A new option "busy-level" for setting a level of calls where asterisk reports
|
||||||
a device as busy, to separate it from call-limit
|
a device as busy, to separate it from call-limit
|
||||||
* A new realtime family called "sipregs" is now supported to store SIP registration
|
* A new realtime family called "sipregs" is now supported to store SIP registration
|
||||||
data. If this family is defined, "sippeers" will be used for configuration and
|
data. If this family is defined, "sippeers" will be used for configuration and
|
||||||
"sipregs" for registrations. If it's not defined, "sippeers" will be used for
|
"sipregs" for registrations. If it's not defined, "sippeers" will be used for
|
||||||
registration data, as before.
|
registration data, as before.
|
||||||
* The SIPPEER function have new options for port address, call and pickup groups
|
* The SIPPEER function have new options for port address, call and pickup groups
|
||||||
* Added support for T.140 realtime text in SIP/RTP
|
* Added support for T.140 realtime text in SIP/RTP
|
||||||
|
|
||||||
|
DUNDi changes
|
||||||
|
-------------
|
||||||
|
* Added the ability to specify arguments to the Dial application when using
|
||||||
|
the DUNDi switch in the dialplan.
|
||||||
|
* Added the ability to set weights for responses dynamically. This can be
|
||||||
|
done using a global variable or a dialplan function. Using the SHELL()
|
||||||
|
function would allow you to have an external script set the weight for
|
||||||
|
each response.
|
||||||
|
@@ -125,8 +125,27 @@ autokill=yes
|
|||||||
;digexten => default,0,IAX2,guest@lappy/${NUMBER}
|
;digexten => default,0,IAX2,guest@lappy/${NUMBER}
|
||||||
;asdf =>
|
;asdf =>
|
||||||
|
|
||||||
|
|
||||||
;
|
;
|
||||||
|
; Weights for mappings can be set a few different ways:
|
||||||
|
;
|
||||||
|
; 1) It can be set as a static number.
|
||||||
|
;testmap1 => context1,222,IAX2,guest@peer1/${NUMBER}
|
||||||
|
;
|
||||||
|
; 2) It can be an Asterisk global variable.
|
||||||
|
;testmap2 => context2,${DUNDITESTVAR},IAX2,guest@peer2${NUMBER}
|
||||||
|
;
|
||||||
|
; 3) It can be retrieved using a dialplan function. This can be extremely
|
||||||
|
; useful if you want to let an external script decide what the weight
|
||||||
|
; in a response shouuld be.
|
||||||
|
;testmap3 => context3,${SHELL(echo 123)},IAX2,guest@peer3/${NUMBER}
|
||||||
|
;
|
||||||
|
; Note than when using a global variable or dialplan function to set the
|
||||||
|
; weight for a mapping, that response caching should be disabled if you
|
||||||
|
; plan for these values to change frequently at all. If the results are
|
||||||
|
; cached, then any change in value will not take effect until the cache
|
||||||
|
; has expired.
|
||||||
|
;
|
||||||
|
|
||||||
;
|
;
|
||||||
; The remaining sections represent the peers
|
; The remaining sections represent the peers
|
||||||
; that we fundamentally trust. The section name
|
; that we fundamentally trust. The section name
|
||||||
|
@@ -79,6 +79,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
|
|
||||||
#define MAX_PACKET_SIZE 8192
|
#define MAX_PACKET_SIZE 8192
|
||||||
|
|
||||||
|
#define MAX_WEIGHT 59999
|
||||||
|
|
||||||
#define DUNDI_MODEL_INBOUND (1 << 0)
|
#define DUNDI_MODEL_INBOUND (1 << 0)
|
||||||
#define DUNDI_MODEL_OUTBOUND (1 << 1)
|
#define DUNDI_MODEL_OUTBOUND (1 << 1)
|
||||||
#define DUNDI_MODEL_SYMMETRIC (DUNDI_MODEL_INBOUND | DUNDI_MODEL_OUTBOUND)
|
#define DUNDI_MODEL_SYMMETRIC (DUNDI_MODEL_INBOUND | DUNDI_MODEL_OUTBOUND)
|
||||||
@@ -211,7 +213,8 @@ struct dundi_request {
|
|||||||
struct dundi_mapping {
|
struct dundi_mapping {
|
||||||
char dcontext[AST_MAX_EXTENSION];
|
char dcontext[AST_MAX_EXTENSION];
|
||||||
char lcontext[AST_MAX_EXTENSION];
|
char lcontext[AST_MAX_EXTENSION];
|
||||||
int weight;
|
int _weight;
|
||||||
|
char *weightstr;
|
||||||
int options;
|
int options;
|
||||||
int tech;
|
int tech;
|
||||||
int dead;
|
int dead;
|
||||||
@@ -511,6 +514,19 @@ struct dundi_query_state {
|
|||||||
char fluffy[0];
|
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)
|
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};
|
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_set_flag(&flags, map->options & 0xffff);
|
||||||
ast_copy_flags(dr + anscnt, &flags, AST_FLAGS_ALL);
|
ast_copy_flags(dr + anscnt, &flags, AST_FLAGS_ALL);
|
||||||
dr[anscnt].techint = map->tech;
|
dr[anscnt].techint = map->tech;
|
||||||
dr[anscnt].weight = map->weight;
|
dr[anscnt].weight = get_mapping_weight(map);
|
||||||
dr[anscnt].expiration = dundi_cache_time;
|
dr[anscnt].expiration = dundi_cache_time;
|
||||||
ast_copy_string(dr[anscnt].tech, tech2str(map->tech), sizeof(dr[anscnt].tech));
|
ast_copy_string(dr[anscnt].tech, tech2str(map->tech), sizeof(dr[anscnt].tech));
|
||||||
dr[anscnt].eid = *us_eid;
|
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[])
|
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 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;
|
struct dundi_mapping *map;
|
||||||
char fs[256];
|
char fs[256];
|
||||||
|
char weight[8];
|
||||||
if (argc != 3)
|
if (argc != 3)
|
||||||
return RESULT_SHOWUSAGE;
|
return RESULT_SHOWUSAGE;
|
||||||
AST_LIST_LOCK(&peers);
|
AST_LIST_LOCK(&peers);
|
||||||
ast_cli(fd, FORMAT2, "DUNDi Cntxt", "Weight", "Local Cntxt", "Options", "Tech", "Destination");
|
ast_cli(fd, FORMAT2, "DUNDi Cntxt", "Weight", "Local Cntxt", "Options", "Tech", "Destination");
|
||||||
AST_LIST_TRAVERSE(&mappings, map, list) {
|
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,
|
ast_strlen_zero(map->lcontext) ? "<none>" : map->lcontext,
|
||||||
dundi_flags2str(fs, sizeof(fs), map->options), tech2str(map->tech), map->dest);
|
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)
|
static void destroy_map(struct dundi_mapping *map)
|
||||||
{
|
{
|
||||||
|
if (map->weightstr)
|
||||||
|
free(map->weightstr);
|
||||||
free(map);
|
free(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3960,11 +3980,15 @@ static void build_mapping(char *name, char *value)
|
|||||||
} else if (x >= 4) {
|
} else if (x >= 4) {
|
||||||
ast_copy_string(map->dcontext, name, sizeof(map->dcontext));
|
ast_copy_string(map->dcontext, name, sizeof(map->dcontext));
|
||||||
ast_copy_string(map->lcontext, fields[0], sizeof(map->lcontext));
|
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));
|
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;
|
map->dead = 0;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ast_log(LOG_WARNING, "Invalid weight '%s' specified, deleting entry '%s/%s'\n", fields[1], map->dcontext, map->lcontext);
|
ast_log(LOG_WARNING, "Invalid weight '%s' specified, deleting entry '%s/%s'\n", fields[1], map->dcontext, map->lcontext);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user