mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-18 18:58:22 +00:00
Add cache bypass mode
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4075 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -141,6 +141,7 @@ struct dundi_cause {
|
||||
#define DUNDI_IE_EMAIL 26 /* E-mail addy, for EIDQUERY (string) */
|
||||
#define DUNDI_IE_PHONE 27 /* Contact Phone, for EIDQUERY (string) */
|
||||
#define DUNDI_IE_IPADDR 28 /* IP Address, for EIDQUERY (string) */
|
||||
#define DUNDI_IE_CACHEBYPASS 29 /* Bypass cache (empty) */
|
||||
|
||||
#define DUNDI_FLUFF_TIME 2000 /* Amount of time for answer */
|
||||
#define DUNDI_TTL_TIME 200 /* Incremental average time */
|
||||
@@ -180,7 +181,7 @@ struct dundi_entity_info {
|
||||
|
||||
/* Lookup the given number in the given dundi context (or e164 if unspecified) using the given callerid (if specified) and return up to maxret results in the array specified.
|
||||
returns the number of results found or -1 on a hangup of teh channel. */
|
||||
int dundi_lookup(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number);
|
||||
int dundi_lookup(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int nocache);
|
||||
|
||||
/* Retrieve information on a specific EID */
|
||||
int dundi_query_eid(struct dundi_entity_info *dei, const char *dcontext, dundi_eid eid);
|
||||
|
@@ -115,6 +115,12 @@ static void dump_string(char *output, int maxlen, void *value, int len)
|
||||
output[maxlen] = '\0';
|
||||
}
|
||||
|
||||
static void dump_cbypass(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
strncpy(output, "Bypass Caches", maxlen);
|
||||
output[maxlen] = '\0';
|
||||
}
|
||||
|
||||
static void dump_eid(char *output, int maxlen, void *value, int len)
|
||||
{
|
||||
if (len == 6)
|
||||
@@ -358,6 +364,7 @@ static struct dundi_ie {
|
||||
{ DUNDI_IE_EMAIL, "EMAIL", dump_string },
|
||||
{ DUNDI_IE_PHONE, "PHONE", dump_string },
|
||||
{ DUNDI_IE_IPADDR, "ADDRESS", dump_string },
|
||||
{ DUNDI_IE_CACHEBYPASS, "CBYPASS", dump_cbypass },
|
||||
};
|
||||
|
||||
const char *dundi_ie2str(int ie)
|
||||
@@ -380,7 +387,7 @@ static void dump_ies(unsigned char *iedata, int spaces, int len)
|
||||
char tmp[1024];
|
||||
if (len < 2)
|
||||
return;
|
||||
while(len > 2) {
|
||||
while(len >= 2) {
|
||||
ie = iedata[0];
|
||||
ielen = iedata[1];
|
||||
/* Encrypted data is the remainder */
|
||||
@@ -441,7 +448,8 @@ void dundi_showframe(struct dundi_hdr *fhi, int rx, struct sockaddr_in *sin, int
|
||||
"REGRESPONSE ",
|
||||
"CANCEL ",
|
||||
"ENCRYPT ",
|
||||
"ENCREJ " };
|
||||
"ENCREJ ",
|
||||
"PRECACHE " };
|
||||
char class2[20];
|
||||
char *class;
|
||||
char subclass2[20];
|
||||
@@ -784,6 +792,9 @@ int dundi_parse_ies(struct dundi_ies *ies, unsigned char *data, int datalen)
|
||||
errorf(tmp);
|
||||
}
|
||||
break;
|
||||
case DUNDI_IE_CACHEBYPASS:
|
||||
ies->cbypass = 1;
|
||||
break;
|
||||
default:
|
||||
snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", dundi_ie2str(ie), ie, len);
|
||||
outputf(tmp);
|
||||
|
@@ -48,6 +48,7 @@ struct dundi_ies {
|
||||
unsigned long keycrc32;
|
||||
struct dundi_encblock *encblock;
|
||||
int enclen;
|
||||
int cbypass;
|
||||
};
|
||||
|
||||
struct dundi_ie_data {
|
||||
|
@@ -186,6 +186,7 @@ struct dundi_request {
|
||||
int maxcount;
|
||||
int respcount;
|
||||
int expiration;
|
||||
int cbypass;
|
||||
int pfds[2];
|
||||
unsigned long crc32; /* CRC-32 of all but root EID's in avoid list */
|
||||
struct dundi_transaction *trans; /* Transactions */
|
||||
@@ -295,7 +296,7 @@ static int str2tech(char *str)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int ttl, int blockempty, struct dundi_hint_metadata *md, int *expiration, dundi_eid *avoid[], int direct[]);
|
||||
static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int ttl, int blockempty, struct dundi_hint_metadata *md, int *expiration, int cybpass, dundi_eid *avoid[], int direct[]);
|
||||
static struct dundi_transaction *create_transaction(struct dundi_peer *p);
|
||||
static struct dundi_transaction *find_transaction(struct dundi_hdr *hdr, struct sockaddr_in *sin)
|
||||
{
|
||||
@@ -479,6 +480,7 @@ struct dundi_query_state {
|
||||
char called_number[AST_MAX_EXTENSION];
|
||||
struct dundi_mapping *maps;
|
||||
int nummaps;
|
||||
int nocache;
|
||||
struct dundi_transaction *trans;
|
||||
void *chal;
|
||||
int challen;
|
||||
@@ -593,7 +595,7 @@ static void *dundi_lookup_thread(void *data)
|
||||
|
||||
if (max) {
|
||||
/* If we do not have a canonical result, keep looking */
|
||||
res = dundi_lookup_internal(dr + ouranswers, MAX_RESULTS - ouranswers, NULL, st->called_context, st->called_number, st->ttl, 1, &hmd, &expiration, st->eids, st->directs);
|
||||
res = dundi_lookup_internal(dr + ouranswers, MAX_RESULTS - ouranswers, NULL, st->called_context, st->called_number, st->ttl, 1, &hmd, &expiration, st->nocache, st->eids, st->directs);
|
||||
if (res > 0) {
|
||||
/* Append answer in result */
|
||||
ouranswers += res;
|
||||
@@ -793,6 +795,7 @@ static int dundi_answer_query(struct dundi_transaction *trans, struct dundi_ies
|
||||
strncpy(st->called_number, ies->called_number, sizeof(st->called_number) - 1);
|
||||
st->trans = trans;
|
||||
st->ttl = ies->ttl - 1;
|
||||
st->nocache = ies->cbypass;
|
||||
if (st->ttl < 0)
|
||||
st->ttl = 0;
|
||||
s = st->fluffy;
|
||||
@@ -2062,10 +2065,17 @@ static int dundi_do_lookup(int fd, int argc, char *argv[])
|
||||
char fs[80] = "";
|
||||
char *context;
|
||||
int x;
|
||||
int bypass = 0;
|
||||
struct dundi_result dr[MAX_RESULTS];
|
||||
struct timeval start;
|
||||
if ((argc < 3) || (argc > 3))
|
||||
if ((argc < 3) || (argc > 4))
|
||||
return RESULT_SHOWUSAGE;
|
||||
if (argc > 3) {
|
||||
if (!strcasecmp(argv[3], "bypass"))
|
||||
bypass=1;
|
||||
else
|
||||
return RESULT_SHOWUSAGE;
|
||||
}
|
||||
strncpy(tmp, argv[2], sizeof(tmp) - 1);
|
||||
context = strchr(tmp, '@');
|
||||
if (context) {
|
||||
@@ -2073,7 +2083,7 @@ static int dundi_do_lookup(int fd, int argc, char *argv[])
|
||||
context++;
|
||||
}
|
||||
gettimeofday(&start, NULL);
|
||||
res = dundi_lookup(dr, MAX_RESULTS, NULL, context, tmp);
|
||||
res = dundi_lookup(dr, MAX_RESULTS, NULL, context, tmp, bypass);
|
||||
|
||||
if (res < 0)
|
||||
ast_cli(fd, "DUNDi lookup returned error.\n");
|
||||
@@ -2388,10 +2398,10 @@ static char show_requests_usage[] =
|
||||
" Lists all known pending DUNDi requests.\n";
|
||||
|
||||
static char lookup_usage[] =
|
||||
"Usage: dundi lookup <number>[@context]\n"
|
||||
"Usage: dundi lookup <number>[@context] [bypass]\n"
|
||||
" Lookup the given number within the given DUNDi context\n"
|
||||
"(or e164 if none is specified).\n"
|
||||
"if specified.\n";
|
||||
"(or e164 if none is specified). Bypasses cache if 'bypass'\n"
|
||||
"keyword is specified.\n";
|
||||
|
||||
static char query_usage[] =
|
||||
"Usage: dundi query <entity>[@context]\n"
|
||||
@@ -2561,7 +2571,7 @@ static void destroy_trans(struct dundi_transaction *trans, int fromtimeout)
|
||||
peer->qualtrans = NULL;
|
||||
}
|
||||
if (trans->flags & FLAG_STOREHIST) {
|
||||
if (trans->parent) {
|
||||
if (trans->parent && !ast_strlen_zero(trans->parent->number)) {
|
||||
if (!dundi_eid_cmp(&trans->them_eid, &peer->eid)) {
|
||||
peer->avgms = 0;
|
||||
cnt = 0;
|
||||
@@ -2787,6 +2797,8 @@ static int dundi_discover(struct dundi_transaction *trans)
|
||||
dundi_ie_append_str(&ied, DUNDI_IE_CALLED_NUMBER, trans->parent->number);
|
||||
dundi_ie_append_str(&ied, DUNDI_IE_CALLED_CONTEXT, trans->parent->dcontext);
|
||||
dundi_ie_append_short(&ied, DUNDI_IE_TTL, trans->ttl);
|
||||
if (trans->parent->cbypass)
|
||||
dundi_ie_append(&ied, DUNDI_IE_CACHEBYPASS);
|
||||
if (trans->autokilltimeout)
|
||||
trans->autokillid = ast_sched_add(sched, trans->autokilltimeout, do_autokill, trans);
|
||||
return dundi_send(trans, DUNDI_COMMAND_DPDISCOVER, 0, 0, &ied);
|
||||
@@ -2953,7 +2965,7 @@ static void abort_request(struct dundi_request *dr)
|
||||
ast_mutex_unlock(&peerlock);
|
||||
}
|
||||
|
||||
static void build_transactions(struct dundi_request *dr, int ttl, int order, int *foundcache, int *skipped, int blockempty, dundi_eid *avoid[], int directs[])
|
||||
static void build_transactions(struct dundi_request *dr, int ttl, int order, int *foundcache, int *skipped, int blockempty, int nocache, dundi_eid *avoid[], int directs[])
|
||||
{
|
||||
struct dundi_peer *p;
|
||||
int x;
|
||||
@@ -2967,7 +2979,8 @@ static void build_transactions(struct dundi_request *dr, int ttl, int order, int
|
||||
/* Check order first, then check cache, regardless of
|
||||
omissions, this gets us more likely to not have an
|
||||
affected answer. */
|
||||
if (!(res = cache_lookup(dr, &p->eid, dr->crc32, &dr->expiration))) {
|
||||
if(nocache || !(res = cache_lookup(dr, &p->eid, dr->crc32, &dr->expiration))) {
|
||||
res = 0;
|
||||
/* Make sure we haven't already seen it and that it won't
|
||||
affect our answer */
|
||||
for (x=0;avoid[x];x++) {
|
||||
@@ -3080,7 +3093,7 @@ static unsigned long avoid_crc32(dundi_eid *avoid[])
|
||||
return acrc32;
|
||||
}
|
||||
|
||||
static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int ttl, int blockempty, struct dundi_hint_metadata *hmd, int *expiration, dundi_eid *avoid[], int direct[])
|
||||
static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int ttl, int blockempty, struct dundi_hint_metadata *hmd, int *expiration, int cbypass, dundi_eid *avoid[], int direct[])
|
||||
{
|
||||
int res;
|
||||
struct dundi_request dr, *pending;
|
||||
@@ -3112,6 +3125,7 @@ static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct
|
||||
dr.hmd = hmd;
|
||||
dr.maxcount = maxret;
|
||||
dr.expiration = *expiration;
|
||||
dr.cbypass = cbypass;
|
||||
dr.crc32 = avoid_crc32(avoid);
|
||||
strncpy(dr.dcontext, dcontext ? dcontext : "e164", sizeof(dr.dcontext) - 1);
|
||||
strncpy(dr.number, number, sizeof(dr.number) - 1);
|
||||
@@ -3145,7 +3159,7 @@ static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct
|
||||
order = skipped;
|
||||
skipped = 0;
|
||||
foundcache = 0;
|
||||
build_transactions(&dr, ttl, order, &foundcache, &skipped, blockempty, avoid, direct);
|
||||
build_transactions(&dr, ttl, order, &foundcache, &skipped, blockempty, cbypass, avoid, direct);
|
||||
} while (skipped && !foundcache && !dr.trans);
|
||||
/* If no TTL, abort and return 0 now after setting TTL expired hint. Couldn't
|
||||
do this earlier because we didn't know if we were going to have transactions
|
||||
@@ -3180,7 +3194,7 @@ static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct
|
||||
return res;
|
||||
}
|
||||
|
||||
int dundi_lookup(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number)
|
||||
int dundi_lookup(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int cbypass)
|
||||
{
|
||||
struct dundi_hint_metadata hmd;
|
||||
dundi_eid *avoid[1] = { NULL, };
|
||||
@@ -3188,7 +3202,7 @@ int dundi_lookup(struct dundi_result *result, int maxret, struct ast_channel *ch
|
||||
int expiration = DUNDI_DEFAULT_CACHE_TIME;
|
||||
memset(&hmd, 0, sizeof(hmd));
|
||||
hmd.flags = DUNDI_HINT_DONT_ASK | DUNDI_HINT_UNAFFECTED;
|
||||
return dundi_lookup_internal(result, maxret, chan, dcontext, number, dundi_ttl, 0, &hmd, &expiration, avoid, direct);
|
||||
return dundi_lookup_internal(result, maxret, chan, dcontext, number, dundi_ttl, 0, &hmd, &expiration, cbypass, avoid, direct);
|
||||
}
|
||||
|
||||
static int dundi_query_eid_internal(struct dundi_entity_info *dei, const char *dcontext, dundi_eid *eid, struct dundi_hint_metadata *hmd, int ttl, int blockempty, dundi_eid *avoid[])
|
||||
@@ -3215,7 +3229,7 @@ static int dundi_query_eid_internal(struct dundi_entity_info *dei, const char *d
|
||||
if (rooteid)
|
||||
dr.root_eid = *rooteid;
|
||||
/* Create transactions */
|
||||
build_transactions(&dr, ttl, 9999, &foundcache, &skipped, blockempty, avoid, NULL);
|
||||
build_transactions(&dr, ttl, 9999, &foundcache, &skipped, blockempty, 0, avoid, NULL);
|
||||
|
||||
/* If no TTL, abort and return 0 now after setting TTL expired hint. Couldn't
|
||||
do this earlier because we didn't know if we were going to have transactions
|
||||
@@ -3726,7 +3740,7 @@ static int dundi_helper(struct ast_channel *chan, const char *context, const cha
|
||||
if (!data || ast_strlen_zero(data))
|
||||
data = context;
|
||||
}
|
||||
res = dundi_lookup(results, MAX_RESULTS, chan, data, exten);
|
||||
res = dundi_lookup(results, MAX_RESULTS, chan, data, exten, 0);
|
||||
for (x=0;x<res;x++) {
|
||||
if (results[x].flags & flag)
|
||||
found++;
|
||||
@@ -3777,7 +3791,7 @@ static int dundi_exec(struct ast_channel *chan, const char *context, const char
|
||||
if (!data || ast_strlen_zero(data))
|
||||
data = context;
|
||||
}
|
||||
res = dundi_lookup(results, MAX_RESULTS, chan, data, exten);
|
||||
res = dundi_lookup(results, MAX_RESULTS, chan, data, exten, 0);
|
||||
if (res > 0) {
|
||||
sort_results(results, res);
|
||||
for (x=0;x<res;x++) {
|
||||
|
Reference in New Issue
Block a user