aboutsummaryrefslogtreecommitdiffstats
path: root/pbx
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-10-22 14:19:11 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-10-22 14:19:11 +0000
commit4ff08f5831bca1664a0dff071947498632161da0 (patch)
tree7bb4c4023f58141eff76d4832ace91a1df39c911 /pbx
parent624733ced21a3f476d5282284868c45533829aaa (diff)
Work on precaching
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@4045 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'pbx')
-rwxr-xr-xpbx/pbx_dundi.c79
1 files changed, 77 insertions, 2 deletions
diff --git a/pbx/pbx_dundi.c b/pbx/pbx_dundi.c
index f4847c598..b09c3dee0 100755
--- a/pbx/pbx_dundi.c
+++ b/pbx/pbx_dundi.c
@@ -203,6 +203,7 @@ static struct dundi_peer {
int registerid;
int qualifyid;
int sentfullkey;
+ int canprecache;
int order;
unsigned char txenckey[256]; /* Transmitted encrypted key + sig */
unsigned char rxenckey[256]; /* Cache received encrypted key + sig */
@@ -1240,6 +1241,7 @@ static int handle_command_response(struct dundi_transaction *trans, struct dundi
int x,y,z;
int resp;
int res;
+ int authpass=0;
unsigned char *bufcpy;
struct dundi_ie_data ied;
struct dundi_ies ies;
@@ -1349,10 +1351,82 @@ static int handle_command_response(struct dundi_transaction *trans, struct dundi
}
}
break;
+ case DUNDI_COMMAND_PRECACHE:
+ /* Success of some sort */
+ ast_log(LOG_DEBUG, "Looks like a precache with %d answers\n", ies.anscount);
+ /* A dialplan or entity discover -- qualify by highest level entity */
+ peer = find_peer(ies.eids[0]);
+ if (peer && ies.called_number) {
+ struct dundi_request dr;
+ struct dundi_result dr2[1];
+ memset(&dr, 0, sizeof(dr));
+ memset(&dr2, 0, sizeof(dr2));
+ /* Build placeholder Dundi Request */
+ trans->us_eid = peer->us_eid;
+ if (!ies.called_context)
+ ies.called_context = "e164";
+ strncpy(dr.dcontext, ies.called_context, sizeof(dr.dcontext) - 1);
+ strncpy(dr.number, ies.called_number, sizeof(dr.number) - 1);
+ dr.dr = dr2;
+ trans->parent = &dr;
+
+ /* Make sure we have all the proper auths */
+ if (strlen(peer->inkey)) {
+ authpass = encrypted;
+ } else
+ authpass = 1;
+ authpass &= has_permission(peer->include, ies.called_context);
+ authpass &= peer->canprecache;
+ if (authpass) {
+ /* Okay we're authentiated and all, now we check if they're authorized */
+ for (x=0;x<ies.anscount;x++) {
+ /* Copy into parent responses */
+ trans->parent->dr[0].flags = ntohs(ies.answers[x]->flags);
+ trans->parent->dr[0].techint = ies.answers[x]->protocol;
+ trans->parent->dr[0].weight = ntohs(ies.answers[x]->weight);
+ trans->parent->dr[0].eid = ies.answers[x]->eid;
+ if (ies.expiration > 0)
+ trans->parent->dr[0].expiration = ies.expiration;
+ else
+ trans->parent->dr[0].expiration = DUNDI_DEFAULT_CACHE_TIME;
+ dundi_eid_to_str(trans->parent->dr[0].eid_str,
+ sizeof(trans->parent->dr[0].eid_str),
+ &ies.answers[x]->eid);
+ strncpy(trans->parent->dr[0].dest, ies.answers[x]->data,
+ sizeof(trans->parent->dr[0].dest));
+ strncpy(trans->parent->dr[0].tech, tech2str(ies.answers[x]->protocol),
+ sizeof(trans->parent->dr[0].tech));
+ trans->parent->respcount=1;
+ /* Save all the results (if any) we had. Even if no results, still cache lookup. Let
+ the cache know if this request was unaffected by our entity list. */
+ cache_save(&trans->them_eid, trans->parent, 0,
+ ies.hint ? ntohs(ies.hint->flags) & DUNDI_HINT_UNAFFECTED : 0, ies.expiration);
+ }
+ if (ies.hint) {
+ cache_save_hint(&trans->them_eid, trans->parent, ies.hint, ies.expiration);
+ if (ntohs(ies.hint->flags) & DUNDI_HINT_TTL_EXPIRED)
+ trans->parent->hmd->flags |= DUNDI_HINT_TTL_EXPIRED;
+ if (ntohs(ies.hint->flags) & DUNDI_HINT_DONT_ASK) {
+ if (strlen(ies.hint->data) > strlen(trans->parent->hmd->exten)) {
+ strncpy(trans->parent->hmd->exten, ies.hint->data,
+ sizeof(trans->parent->hmd->exten) - 1);
+ }
+ } else {
+ trans->parent->hmd->flags &= ~DUNDI_HINT_DONT_ASK;
+ }
+ }
+ }
+ }
+ if (!authpass && ies.eids[0])
+ ast_log(LOG_NOTICE, "Peer '%s' does not have permission to pre-cache!\n",
+ dundi_eid_to_str(eid_str, sizeof(eid_str), ies.eids[0]));
+ /* Close connection if not final */
+ if (!final)
+ dundi_send(trans, DUNDI_COMMAND_CANCEL, 0, 1, NULL);
+ break;
case DUNDI_COMMAND_DPRESPONSE:
/* A dialplan response, lets see what we got... */
if (ies.cause < 1) {
- int authpass=0;
/* Success of some sort */
ast_log(LOG_DEBUG, "Looks like success of some sort (%d), %d answers\n", ies.cause, ies.anscount);
if (trans->flags & FLAG_ENCRYPT) {
@@ -1437,7 +1511,6 @@ static int handle_command_response(struct dundi_transaction *trans, struct dundi
case DUNDI_COMMAND_EIDRESPONSE:
/* A dialplan response, lets see what we got... */
if (ies.cause < 1) {
- int authpass=0;
/* Success of some sort */
ast_log(LOG_DEBUG, "Looks like success of some sort (%d)\n", ies.cause);
if (trans->flags & FLAG_ENCRYPT) {
@@ -3381,6 +3454,8 @@ static void build_peer(dundi_eid *eid, struct ast_variable *v)
strncpy(peer->inkey, v->value, sizeof(peer->inkey) - 1);
} else if (!strcasecmp(v->name, "outkey")) {
strncpy(peer->outkey, v->value, sizeof(peer->outkey) - 1);
+ } else if (!strcasecmp(v->name, "canprecache")) {
+ peer->canprecache = ast_true(v->value);
} else if (!strcasecmp(v->name, "host")) {
if (!strcasecmp(v->value, "dynamic")) {
peer->dynamic = 1;