Work on precaching
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@4045 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
parent
624733ced2
commit
4ff08f5831
|
@ -139,6 +139,9 @@ autokill=yes
|
|||
; model - inbound, outbound, or symmetric for whether we receive
|
||||
; requests only, transmit requests only, or do both.
|
||||
;
|
||||
; canprecache - Permits this peer to provide answers (which are cached)
|
||||
; for queries we did not make (a.k.a. pre-caching)
|
||||
;
|
||||
; The '*' peer is special and matches an unspecified entity
|
||||
;
|
||||
|
||||
|
|
|
@ -101,6 +101,7 @@ struct dundi_cause {
|
|||
#define DUNDI_COMMAND_DPRESPONSE (2 | 0x40) /* Respond to a discovery request */
|
||||
#define DUNDI_COMMAND_EIDQUERY 3 /* Request information for a peer */
|
||||
#define DUNDI_COMMAND_EIDRESPONSE (4 | 0x40) /* Response to a peer query */
|
||||
#define DUNDI_COMMAND_PRECACHE 5 /* Unsolicited answer pre-cache */
|
||||
#define DUNDI_COMMAND_INVALID (7 | 0x40) /* Invalid dialog state (does not require ack) */
|
||||
#define DUNDI_COMMAND_UNKNOWN (8 | 0x40) /* Unknown command */
|
||||
#define DUNDI_COMMAND_NULL 9 /* No-op */
|
||||
|
|
|
@ -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;
|
||||
|
|
Reference in New Issue