Replace DEBUG_HLR with DEBUG_KEYRING

Convert several fprintf(stderr,...) into DEBUGF() statements
This commit is contained in:
Andrew Bettison 2012-07-27 11:26:19 +09:30
parent 82648b7e63
commit a69f637b3a
4 changed files with 273 additions and 281 deletions

View File

@ -247,8 +247,10 @@ void keyring_free_identity(keyring_identity *id)
if (id->PKRPin) {
/* Wipe pin before freeing (slightly tricky since this is a variable length string */
for(i=0;id->PKRPin[i];i++) {
fprintf(stderr,"clearing PIN char '%c'\n",id->PKRPin[i]);
id->PKRPin[i]=' '; }
if (debug & DEBUG_KEYRING)
DEBUGF("clearing PIN char '%c'", id->PKRPin[i]);
id->PKRPin[i]=' ';
}
i=0;
free(id->PKRPin); id->PKRPin=NULL;
@ -973,23 +975,22 @@ int keyring_commit(keyring_file *k)
k->contexts[cn]->KeyRingPin,
k->contexts[cn]->identities[in]->PKRPin))
errorCount++;
else
{
/* Store */
off_t file_offset
=KEYRING_PAGE_SIZE
*k->contexts[cn]->identities[in]->slot;
if (!file_offset) {
fprintf(stderr,"ID %d:%d has slot=0\n",
cn,in);
}
else if (fseeko(k->file,file_offset,SEEK_SET))
errorCount++;
else
if (fwrite(pkr,KEYRING_PAGE_SIZE,1,k->file)!=1)
errorCount++;
else {
/* Store */
off_t file_offset
=KEYRING_PAGE_SIZE
*k->contexts[cn]->identities[in]->slot;
if (!file_offset) {
if (debug * DEBUG_KEYRING)
DEBUGF("ID %d:%d has slot=0", cn,in);
}
}
else if (fseeko(k->file,file_offset,SEEK_SET))
errorCount++;
else
if (fwrite(pkr,KEYRING_PAGE_SIZE,1,k->file)!=1)
errorCount++;
}
}
}
if (errorCount) WHY("One or more errors occurred while commiting keyring to disk");
@ -1006,7 +1007,8 @@ int keyring_set_did(keyring_identity *id,char *did,char *name)
int i;
for(i=0;i<id->keypair_count;i++)
if (id->keypairs[i]->type==KEYTYPE_DID) {
DEBUG("Identity contains DID");
if (debug & DEBUG_KEYRING)
DEBUG("Identity contains DID");
break;
}
@ -1026,7 +1028,8 @@ int keyring_set_did(keyring_identity *id,char *did,char *name)
id->keypairs[i]->public_key=packedName;
id->keypairs[i]->public_key_len=64;
id->keypair_count++;
DEBUG("Created DID record for identity");
if (debug & DEBUG_KEYRING)
DEBUG("Created DID record for identity");
}
/* Store DID unpacked for ease of searching */
@ -1131,7 +1134,8 @@ unsigned char *keyring_find_sas_private(keyring_file *k,unsigned char *sid,
if (sas_public)
*sas_public=
k->contexts[cn]->identities[in]->keypairs[kp]->public_key;
if (0) DEBUGF("Found SAS entry for %s*", alloca_tohex(sid, 7));
if (debug & DEBUG_KEYRING)
DEBUGF("Found SAS entry for %s*", alloca_tohex(sid, 7));
RETURN(k->contexts[cn]->identities[in]->keypairs[kp]->private_key);
}
@ -1196,11 +1200,13 @@ int keyring_mapping_request(keyring_file *k,overlay_mdp_frame *req)
+slen;
overlay_mdp_swap_src_dst(req);
req->packetTypeAndFlags=MDP_TX; /* crypt and sign */
DEBUG("Sent SID:SAS mapping mutual-signature");
printf("%d byte reply is from %s:%u\n to %s:%u\n",
req->out.payload_length,
alloca_tohex_sid(req->out.src.sid),req->out.src.port,
alloca_tohex_sid(req->out.dst.sid),req->out.dst.port);
if (debug & DEBUG_KEYRING) {
DEBUG("Sent SID:SAS mapping mutual-signature");
DEBUGF("%d byte reply from %s:%u to %s:%u",
req->out.payload_length,
alloca_tohex_sid(req->out.src.sid),req->out.src.port,
alloca_tohex_sid(req->out.dst.sid),req->out.dst.port);
}
return overlay_mdp_dispatch(req,1,NULL,0);
} else {
/* It's probably a response. */
@ -1228,16 +1234,16 @@ int keyring_mapping_request(keyring_file *k,overlay_mdp_frame *req)
int r=crypto_sign_edwards25519sha512batch_open(plain,&plain_len,
signature,siglen,
sas_public);
if (r)
return
WHY("Verification of signed SID in key mapping assertion failed");
if (r)
return WHY("Verification of signed SID in key mapping assertion failed");
/* These next two tests should never be able to fail, but let's just
check anyway. */
if (plain_len!=SID_SIZE)
if (plain_len!=SID_SIZE)
return WHY("key mapping signed block is wrong length");
if (memcmp(plain,req->out.src.sid,SID_SIZE))
return WHY("key mapping signed block is for wrong SID");
DEBUG("Key mapping looks valid");
if (debug & DEBUG_KEYRING)
DEBUG("Key mapping looks valid");
/* work out where to put it */
int i;
@ -1251,15 +1257,17 @@ int keyring_mapping_request(keyring_file *k,overlay_mdp_frame *req)
bcopy(&req->out.src.sid,&sid_sas_mappings[i].sid[0],SID_SIZE);
bcopy(sas_public,&sid_sas_mappings[i].sas_public[0],
crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES);
fprintf(stderr,"Mapping #%d (count=%d) SID=%s to SAS=%s*\n",i,
sid_sas_mapping_count,
alloca_tohex_sid(sid_sas_mappings[i].sid),
alloca_tohex_sid(sid_sas_mappings[i].sas_public));
if (debug & DEBUG_KEYRING)
DEBUGF("Mapping #%d (count=%d) SID=%s to SAS=%s*\n",i,
sid_sas_mapping_count,
alloca_tohex_sid(sid_sas_mappings[i].sid),
alloca_tohex_sid(sid_sas_mappings[i].sas_public));
sid_sas_mappings[i].validP=1;
sid_sas_mappings[i].last_request_time_in_ms=0;
DEBUG("Stored mapping");
if (debug & DEBUG_KEYRING)
DEBUG("Stored mapping");
return 0;
}
}
break;
default:
WARN("Key mapping response for unknown key type. Oh well.");
@ -1289,7 +1297,8 @@ unsigned char *keyring_find_sas_public(keyring_file *k,unsigned char *sid)
{
if (memcmp(sid,sid_sas_mappings[i].sid,SID_SIZE)) continue;
if (sid_sas_mappings[i].validP) {
if (0) DEBUGF("Found SAS public entry for %s*", alloca_tohex(sid, 7));
if (debug & DEBUG_KEYRING)
DEBUGF("Found SAS public entry for %s*", alloca_tohex(sid, 7));
RETURN(sid_sas_mappings[i].sas_public);
}
/* Don't flood the network with mapping requests */

2
log.c
View File

@ -264,7 +264,7 @@ unsigned int debugFlagMask(const char *flagname) {
else if (!strcasecmp(flagname,"packetformats")) return DEBUG_PACKETFORMATS;
else if (!strcasecmp(flagname,"packetconstruction")) return DEBUG_PACKETCONSTRUCTION;
else if (!strcasecmp(flagname,"gateway")) return DEBUG_GATEWAY;
else if (!strcasecmp(flagname,"hlr")) return DEBUG_HLR;
else if (!strcasecmp(flagname,"keyring")) return DEBUG_KEYRING;
else if (!strcasecmp(flagname,"sockio")) return DEBUG_IO;
else if (!strcasecmp(flagname,"frames")) return DEBUG_OVERLAYFRAMES;
else if (!strcasecmp(flagname,"abbreviations")) return DEBUG_OVERLAYABBREVIATIONS;

View File

@ -1132,7 +1132,7 @@ int overlay_saw_mdp_containing_frame(overlay_frame *f,long long now);
#define DEBUG_RHIZOME_RX (1 << 8)
#define DEBUG_PACKETFORMATS (1 << 9)
#define DEBUG_GATEWAY (1 << 10)
#define DEBUG_HLR (1 << 11) // Deprecated, TODO: delete
#define DEBUG_KEYRING (1 << 11)
#define DEBUG_IO (1 << 12)
#define DEBUG_OVERLAYFRAMES (1 << 13)
#define DEBUG_OVERLAYABBREVIATIONS (1 << 14)

465
server.c
View File

@ -509,261 +509,244 @@ int processRequest(unsigned char *packet,int len,
unsigned char *transaction_id,int recvttl, char *did,char *sid)
{
/* Find HLR entry by DID or SID, unless creating */
int records_searched=0;
int prev_pofs=0;
int pofs=OFS_PAYLOAD;
while(pofs<len)
{
if (debug&DEBUG_DNARESPONSES) DEBUGF(" processRequest: len=%d, pofs=%d, pofs_prev=%d",len,pofs,prev_pofs);
/* Avoid infinite loops */
if (pofs<=prev_pofs) break;
prev_pofs=pofs;
while (pofs < len) {
if (debug & DEBUG_DNARESPONSES)
DEBUGF("len=%d, pofs=%d, pofs_prev=%d",len,pofs,prev_pofs);
/* Avoid infinite loops */
if (pofs<=prev_pofs) break;
prev_pofs=pofs;
if (packet[pofs]==ACTION_CREATEHLR)
{
/* Creating an HLR requires an initial DID number and definitely no SID -
you can't choose a SID. */
if (debug&DEBUG_HLR) DEBUGF("Creating a new HLR record. did='%s', sid='%s'",did,sid);
if (!did[0]) return respondSimple(NULL,ACTION_DECLINED,NULL,0,transaction_id,recvttl,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
if (sid[0])
return respondSimple(NULL,ACTION_DECLINED,NULL,0,transaction_id,
recvttl,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
if (debug&DEBUG_HLR) DEBUG("Verified that create request supplies DID but not SID");
if (debug & DEBUG_DNARESPONSES)
DEBUGF("action code 0x%02x @ packet offset 0x%x", packet[pofs], pofs);
switch (packet[pofs]) {
case ACTION_CREATEHLR: {
/* Creating an HLR requires an initial DID number and definitely no SID -
you can't choose a SID. */
if (debug & DEBUG_DNARESPONSES)
DEBUGF("Creating a new HLR record. did='%s', sid='%s'",did,sid);
if (!did[0] || sid[0])
return respondSimple(NULL, ACTION_DECLINED, NULL, 0, transaction_id, recvttl, sender, CRYPT_CIPHERED|CRYPT_SIGNED);
if (debug & DEBUG_DNARESPONSES)
DEBUG("Verified that create request supplies DID but not SID");
/* Creating an identity is nice and easy now with the new keyring */
keyring_identity *id=keyring_create_identity(keyring,keyring->contexts[0], "");
if (id)
keyring_set_did(id, did, "Mr. Smith");
if (id==NULL||keyring_commit(keyring))
return respondSimple(NULL, ACTION_DECLINED, NULL, 0, transaction_id, recvttl, sender, CRYPT_CIPHERED|CRYPT_SIGNED);
else
return respondSimple(id, ACTION_OKAY, NULL, 0, transaction_id, recvttl, sender, CRYPT_CIPHERED|CRYPT_SIGNED);
pofs += 1;
pofs += 1 + SID_SIZE;
}
break;
case ACTION_PAD: /* Skip padding */
pofs++;
pofs+=1+packet[pofs];
break;
case ACTION_EOT: /* EOT */
pofs=len;
break;
case ACTION_STATS: {
/* short16 variable id,
int32 value */
pofs++;
short field=packet[pofs+1]+(packet[pofs]<<8);
int value=packet[pofs+5]+(packet[pofs+4]<<8)+(packet[pofs+3]<<16)+(packet[pofs+2]<<24);
pofs+=6;
if (instrumentation_file)
{
if (!i_f) { if (strcmp(instrumentation_file,"-")) i_f=fopen(instrumentation_file,"a"); else i_f=stdout; }
if (i_f) fprintf(i_f,"%ld:%02x%02x%02x%02x:%d:%d\n",time(0),sender->sa_data[0],sender->sa_data[1],sender->sa_data[2],sender->sa_data[3],field,value);
if (i_f) fflush(i_f);
}
}
break;
case ACTION_SET:
WHY("You can only set keyring variables locally");
return respondSimple(NULL,ACTION_ERROR,
(unsigned char *)"Would be insecure",
0,transaction_id,recvttl,
sender,CRYPT_CIPHERED|CRYPT_SIGNED);
break;
case ACTION_GET: {
/* Limit transfer size to MAX_DATA_BYTES, plus an allowance for variable packing. */
unsigned char data[MAX_DATA_BYTES+16];
int dlen=0;
int sendDone=0;
if (debug&DEBUG_DNARESPONSES)
dump("Request bytes", &packet[pofs], 8);
pofs++;
int var_id=packet[pofs];
int instance=-1;
if (var_id&0x80) instance=packet[++pofs];
if (instance==0xff) instance=-1;
pofs++;
int offset=(packet[pofs]<<8)+packet[pofs+1]; pofs+=2;
keyring_identity *responding_id=NULL;
pofs+=2;
if (debug&DEBUG_DNARESPONSES) {
DEBUGF("Processing ACTION_GET (var_id=%02x, instance=%02x, pofs=0x%x, len=%d)",var_id,instance,pofs,len);
DEBUGF("Looking for identities with sid=%s did='%s'", (sid&&sid[0])?sid:"null",did?did:"null");
}
/* Creating an identity is nice and easy now with the new keyring */
keyring_identity *id=keyring_create_identity(keyring,keyring->contexts[0], "");
if (id) keyring_set_did(id,did,"Mr. Smith");
if (id==NULL||keyring_commit(keyring))
return respondSimple(NULL,ACTION_DECLINED,NULL,0,transaction_id,recvttl,
sender,CRYPT_CIPHERED|CRYPT_SIGNED);
else
return respondSimple(id,ACTION_OKAY,NULL,0,transaction_id,recvttl,
sender,CRYPT_CIPHERED|CRYPT_SIGNED);
pofs+=1;
pofs+=1+SID_SIZE;
/* Keyring only has DIDs in it for now. Location is implied, so we allow that */
switch (var_id) {
case VAR_DIDS:
case VAR_LOCATIONS:
break;
default:
return respondSimple(NULL,ACTION_ERROR,
(unsigned char *)"Unsupported variable",
0,transaction_id,recvttl,
sender,CRYPT_CIPHERED|CRYPT_SIGNED);
}
else
{
if (debug&DEBUG_DNARESPONSES) DEBUGF("Looking at action code 0x%02x @ packet offset 0x%x",
packet[pofs],pofs);
switch(packet[pofs])
{
case ACTION_PAD: /* Skip padding */
pofs++;
pofs+=1+packet[pofs];
break;
case ACTION_EOT: /* EOT */
pofs=len;
break;
case ACTION_STATS:
/* short16 variable id,
int32 value */
{
pofs++;
short field=packet[pofs+1]+(packet[pofs]<<8);
int value=packet[pofs+5]+(packet[pofs+4]<<8)+(packet[pofs+3]<<16)+(packet[pofs+2]<<24);
pofs+=6;
if (instrumentation_file)
{
if (!i_f) { if (strcmp(instrumentation_file,"-")) i_f=fopen(instrumentation_file,"a"); else i_f=stdout; }
if (i_f) fprintf(i_f,"%ld:%02x%02x%02x%02x:%d:%d\n",time(0),sender->sa_data[0],sender->sa_data[1],sender->sa_data[2],sender->sa_data[3],field,value);
if (i_f) fflush(i_f);
}
int cn=0,in=0,kp=0;
int found=0;
int count=0;
while(cn<keyring->context_count) {
found=0;
if (sid&&sid[0]) {
unsigned char packedSid[SID_SIZE];
stowSid(packedSid,0,sid);
found=keyring_find_sid(keyring,&cn,&in,&kp,packedSid);
} else {
found=keyring_find_did(keyring,&cn,&in,&kp,did);
}
struct response r;
unsigned char packedDid[64];
if (found&&(instance==-1||instance==count)) {
/* We have a matching identity/DID, now see what variable
they want.
VAR_DIDS and VAR_LOCATIONS are the only ones we support
with the new keyring file format for now. */
r.var_id=var_id;
r.var_instance=instance;
switch(var_id) {
case VAR_DIDS:
/* We need to pack the DID before sending off */
r.value_len=0;
stowDid(packedDid,&r.value_len,
(char *)keyring->contexts[cn]->identities[in]
->keypairs[kp]->private_key);
r.response=packedDid;
break;
case VAR_LOCATIONS:
r.response=(unsigned char *)"4000@";
r.value_len=strlen((char *)r.response);
break;
}
break;
case ACTION_SET:
WHY("You can only set keyring variables locally");
return respondSimple(NULL,ACTION_ERROR,
(unsigned char *)"Would be insecure",
0,transaction_id,recvttl,
sender,CRYPT_CIPHERED|CRYPT_SIGNED);
break;
case ACTION_GET:
{
/* Limit transfer size to MAX_DATA_BYTES, plus an allowance for variable packing. */
unsigned char data[MAX_DATA_BYTES+16];
int dlen=0;
int sendDone=0;
if (debug&DEBUG_HLR) dump("Request bytes",&packet[pofs],8);
/* For multiple packet responses, we want to tag only the
last one with DONE, so we queue up the most recently generated
packet, and only dispatch it when we are about to produce
another. Then at the end of the loop, if we have a packet
waiting we simply mark that with with DONE, and everything
falls into place. */
if (sendDone>0)
/* Send previous packet */
respondSimple(responding_id,ACTION_DATA,data,dlen,
transaction_id,recvttl,sender,
CRYPT_CIPHERED|CRYPT_SIGNED);
/* Prepare new packet */
dlen=0;
if (packageVariableSegment(data,&dlen,&r,offset, MAX_DATA_BYTES+16))
return WHY("packageVariableSegment() failed.");
responding_id = keyring->contexts[cn]->identities[in];
pofs++;
int var_id=packet[pofs];
int instance=-1;
if (var_id&0x80) instance=packet[++pofs];
if (instance==0xff) instance=-1;
pofs++;
int offset=(packet[pofs]<<8)+packet[pofs+1]; pofs+=2;
keyring_identity *responding_id=NULL;
/* Remember that we need to send this new packet */
sendDone++;
pofs+=2;
if (debug&DEBUG_DNARESPONSES) DEBUGF("Processing ACTION_GET (var_id=%02x, instance=%02x, pofs=0x%x, len=%d)",var_id,instance,pofs,len);
if (debug&DEBUG_HLR) DEBUGF("Looking for identities with sid='%s' / did='%s'",(sid&&sid[0])?sid:"null",did?did:"null");
/* Keyring only has DIDs in it for now.
Location is implied, so we allow that */
switch(var_id) {
case VAR_DIDS:
case VAR_LOCATIONS:
break;
default:
return respondSimple(NULL,ACTION_ERROR,
(unsigned char *)"Unsupported variable",
0,transaction_id,recvttl,
sender,CRYPT_CIPHERED|CRYPT_SIGNED);
}
{
int cn=0,in=0,kp=0;
int found=0;
int count=0;
while(cn<keyring->context_count) {
found=0;
if (sid&&sid[0]) {
unsigned char packedSid[SID_SIZE];
stowSid(packedSid,0,sid);
found=keyring_find_sid(keyring,&cn,&in,&kp,packedSid);
} else {
found=keyring_find_did(keyring,&cn,&in,&kp,did);
}
struct response r;
unsigned char packedDid[64];
if (found&&(instance==-1||instance==count)) {
/* We have a matching identity/DID, now see what variable
they want.
VAR_DIDS and VAR_LOCATIONS are the only ones we support
with the new keyring file format for now. */
r.var_id=var_id;
r.var_instance=instance;
switch(var_id) {
case VAR_DIDS:
/* We need to pack the DID before sending off */
r.value_len=0;
stowDid(packedDid,&r.value_len,
(char *)keyring->contexts[cn]->identities[in]
->keypairs[kp]->private_key);
r.response=packedDid;
break;
case VAR_LOCATIONS:
r.response=(unsigned char *)"4000@";
r.value_len=strlen((char *)r.response);
break;
}
/* For multiple packet responses, we want to tag only the
last one with DONE, so we queue up the most recently generated
packet, and only dispatch it when we are about to produce
another. Then at the end of the loop, if we have a packet
waiting we simply mark that with with DONE, and everything
falls into place. */
if (sendDone>0)
/* Send previous packet */
respondSimple(responding_id,ACTION_DATA,data,dlen,
transaction_id,recvttl,sender,
CRYPT_CIPHERED|CRYPT_SIGNED);
/* Prepare new packet */
dlen=0;
if (packageVariableSegment(data,&dlen,&r,offset,
MAX_DATA_BYTES+16))
return WHY("packageVariableSegment() failed.");
responding_id = keyring->contexts[cn]->identities[in];
/* Remember that we need to send this new packet */
sendDone++;
count++;
}
/* look for next record.
Here the placing of DONE at the end of the response stream
becomes challenging, as we may be responding as multiple
identities. This means we have to DONE after each identity. */
int lastin=in,lastcn=cn;
kp++;
keyring_sanitise_position(keyring,&cn,&in,&kp);
if (lastin!=in||lastcn!=cn) {
/* moved off last identity, so send waiting packet if there is
one. */
if (sendDone)
{
data[dlen++]=ACTION_DONE;
data[dlen++]=sendDone&0xff;
respondSimple(responding_id,ACTION_DATA,data,dlen,
transaction_id,
recvttl,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
}
sendDone=0;
}
}
}
/* Now, see if we have a final queued packet which needs marking with
DONE and then sending. */
if (sendDone)
{
data[dlen++]=ACTION_DONE;
data[dlen++]=sendDone&0xff;
respondSimple(responding_id,ACTION_DATA,data,dlen,transaction_id,
recvttl,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
}
if (gatewayspec&&(var_id==VAR_LOCATIONS)&&did&&strlen(did))
{
/* We are a gateway, so offer connection via the gateway as well */
unsigned char data[MAX_DATA_BYTES+16];
int dlen=0;
struct response fake;
unsigned char uri[1024];
/* We use asterisk to provide the gateway service,
so we need to create a temporary extension in extensions.conf,
ask asterisk to re-read extensions.conf, and then make sure it has
a functional SIP gateway.
*/
if (!asteriskObtainGateway(sid,did,(char *)uri))
{
fake.value_len=strlen((char *)uri);
fake.var_id=var_id;
fake.response=uri;
if (packageVariableSegment(data,&dlen,&fake,offset,MAX_DATA_BYTES+16))
return WHY("packageVariableSegment() of gateway URI failed.");
WHY("Gateway claims to be 1st identity, when it should probably have its own identity");
respondSimple(keyring->contexts[0]->identities[0],
ACTION_DATA,data,dlen,
transaction_id,recvttl,sender,
CRYPT_CIPHERED|CRYPT_SIGNED);
}
else
{
/* Should we indicate the gateway is not available? */
}
}
count++;
}
/* look for next record.
Here the placing of DONE at the end of the response stream
becomes challenging, as we may be responding as multiple
identities. This means we have to DONE after each identity. */
int lastin=in,lastcn=cn;
kp++;
keyring_sanitise_position(keyring,&cn,&in,&kp);
if (lastin!=in||lastcn!=cn) {
/* moved off last identity, so send waiting packet if there is
one. */
if (sendDone) {
data[dlen++]=ACTION_DONE;
data[dlen++]=sendDone&0xff;
respondSimple(responding_id,ACTION_DATA,data,dlen,
transaction_id,
recvttl,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
}
break;
default:
if (debug&DEBUG_PACKETFORMATS) DEBUGF("Asked to perform unsipported action at Packet offset = 0x%x",pofs);
if (debug&DEBUG_PACKETFORMATS) dump("Packet",packet,len);
return WHY("Asked to perform unsupported action.");
}
sendDone=0;
}
}
}
/* Now, see if we have a final queued packet which needs marking with
DONE and then sending. */
if (sendDone) {
data[dlen++]=ACTION_DONE;
data[dlen++]=sendDone&0xff;
respondSimple(responding_id,ACTION_DATA,data,dlen,transaction_id,
recvttl,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
}
if (gatewayspec&&(var_id==VAR_LOCATIONS)&&did&&strlen(did))
{
/* We are a gateway, so offer connection via the gateway as well */
unsigned char data[MAX_DATA_BYTES+16];
int dlen=0;
struct response fake;
unsigned char uri[1024];
/* We use asterisk to provide the gateway service,
so we need to create a temporary extension in extensions.conf,
ask asterisk to re-read extensions.conf, and then make sure it has
a functional SIP gateway.
*/
if (!asteriskObtainGateway(sid,did,(char *)uri))
{
fake.value_len=strlen((char *)uri);
fake.var_id=var_id;
fake.response=uri;
if (packageVariableSegment(data,&dlen,&fake,offset,MAX_DATA_BYTES+16))
return WHY("packageVariableSegment() of gateway URI failed.");
WHY("Gateway claims to be 1st identity, when it should probably have its own identity");
respondSimple(keyring->contexts[0]->identities[0],
ACTION_DATA,data,dlen,
transaction_id,recvttl,sender,
CRYPT_CIPHERED|CRYPT_SIGNED);
}
else
{
/* Should we indicate the gateway is not available? */
}
}
}
break;
default:
if (debug & DEBUG_PACKETFORMATS) {
DEBUGF("Asked to perform unsipported action at Packet offset = 0x%x", pofs);
dump("Packet", packet, len);
}
return WHY("unsupported action");
}
if (debug&DEBUG_HLR) DEBUGF("Searched %d HLR entries",records_searched);
}
return 0;
}