mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-16 06:48:25 +00:00
Work on precaching
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4045 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -139,6 +139,9 @@ autokill=yes
|
|||||||
; model - inbound, outbound, or symmetric for whether we receive
|
; model - inbound, outbound, or symmetric for whether we receive
|
||||||
; requests only, transmit requests only, or do both.
|
; 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
|
; 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_DPRESPONSE (2 | 0x40) /* Respond to a discovery request */
|
||||||
#define DUNDI_COMMAND_EIDQUERY 3 /* Request information for a peer */
|
#define DUNDI_COMMAND_EIDQUERY 3 /* Request information for a peer */
|
||||||
#define DUNDI_COMMAND_EIDRESPONSE (4 | 0x40) /* Response to a peer query */
|
#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_INVALID (7 | 0x40) /* Invalid dialog state (does not require ack) */
|
||||||
#define DUNDI_COMMAND_UNKNOWN (8 | 0x40) /* Unknown command */
|
#define DUNDI_COMMAND_UNKNOWN (8 | 0x40) /* Unknown command */
|
||||||
#define DUNDI_COMMAND_NULL 9 /* No-op */
|
#define DUNDI_COMMAND_NULL 9 /* No-op */
|
||||||
|
|||||||
@@ -203,6 +203,7 @@ static struct dundi_peer {
|
|||||||
int registerid;
|
int registerid;
|
||||||
int qualifyid;
|
int qualifyid;
|
||||||
int sentfullkey;
|
int sentfullkey;
|
||||||
|
int canprecache;
|
||||||
int order;
|
int order;
|
||||||
unsigned char txenckey[256]; /* Transmitted encrypted key + sig */
|
unsigned char txenckey[256]; /* Transmitted encrypted key + sig */
|
||||||
unsigned char rxenckey[256]; /* Cache received 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 x,y,z;
|
||||||
int resp;
|
int resp;
|
||||||
int res;
|
int res;
|
||||||
|
int authpass=0;
|
||||||
unsigned char *bufcpy;
|
unsigned char *bufcpy;
|
||||||
struct dundi_ie_data ied;
|
struct dundi_ie_data ied;
|
||||||
struct dundi_ies ies;
|
struct dundi_ies ies;
|
||||||
@@ -1349,10 +1351,82 @@ static int handle_command_response(struct dundi_transaction *trans, struct dundi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case DUNDI_COMMAND_DPRESPONSE:
|
||||||
/* A dialplan response, lets see what we got... */
|
/* A dialplan response, lets see what we got... */
|
||||||
if (ies.cause < 1) {
|
if (ies.cause < 1) {
|
||||||
int authpass=0;
|
|
||||||
/* Success of some sort */
|
/* Success of some sort */
|
||||||
ast_log(LOG_DEBUG, "Looks like success of some sort (%d), %d answers\n", ies.cause, ies.anscount);
|
ast_log(LOG_DEBUG, "Looks like success of some sort (%d), %d answers\n", ies.cause, ies.anscount);
|
||||||
if (trans->flags & FLAG_ENCRYPT) {
|
if (trans->flags & FLAG_ENCRYPT) {
|
||||||
@@ -1437,7 +1511,6 @@ static int handle_command_response(struct dundi_transaction *trans, struct dundi
|
|||||||
case DUNDI_COMMAND_EIDRESPONSE:
|
case DUNDI_COMMAND_EIDRESPONSE:
|
||||||
/* A dialplan response, lets see what we got... */
|
/* A dialplan response, lets see what we got... */
|
||||||
if (ies.cause < 1) {
|
if (ies.cause < 1) {
|
||||||
int authpass=0;
|
|
||||||
/* Success of some sort */
|
/* Success of some sort */
|
||||||
ast_log(LOG_DEBUG, "Looks like success of some sort (%d)\n", ies.cause);
|
ast_log(LOG_DEBUG, "Looks like success of some sort (%d)\n", ies.cause);
|
||||||
if (trans->flags & FLAG_ENCRYPT) {
|
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);
|
strncpy(peer->inkey, v->value, sizeof(peer->inkey) - 1);
|
||||||
} else if (!strcasecmp(v->name, "outkey")) {
|
} else if (!strcasecmp(v->name, "outkey")) {
|
||||||
strncpy(peer->outkey, v->value, sizeof(peer->outkey) - 1);
|
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")) {
|
} else if (!strcasecmp(v->name, "host")) {
|
||||||
if (!strcasecmp(v->value, "dynamic")) {
|
if (!strcasecmp(v->value, "dynamic")) {
|
||||||
peer->dynamic = 1;
|
peer->dynamic = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user