Allow clients to request variables for all records by passing empty did.

Always add DONE flag to the last packet sent.
This commit is contained in:
Jeremy Lakeman 2011-04-27 12:17:26 +09:30
parent a2bcb56e1f
commit bfccb3816d
8 changed files with 207 additions and 183 deletions

View File

@ -50,8 +50,9 @@ int stowDid(unsigned char *packet,int *ofs,char *did)
int nybl;
int d=0;
int len=0;
if (debug>2) printf("Packing DID \"%s\"\n",did);
while(did[d]&&(len<DID_MAXSIZE))
while(did[d]&&(d<DID_MAXSIZE))
{
switch(did[d])
{
@ -68,10 +69,11 @@ int stowDid(unsigned char *packet,int *ofs,char *did)
if (highP) { packet[*ofs]=nybl<<4; highP=0; }
else {
packet[(*ofs)++]|=nybl; highP=1;
len++;
}
d++; len++;
d++;
}
if (len>=DID_MAXSIZE)
if (d>=DID_MAXSIZE)
{
setReason("DID number too long");
return -1;
@ -79,9 +81,10 @@ int stowDid(unsigned char *packet,int *ofs,char *did)
/* Append end of number code, filling the whole byte for fast and easy comparison */
if (highP) packet[(*ofs)++]=0xff;
else packet[(*ofs)++]|=0x0f;
len++;
/* Fill remainder of field with randomness to protect any encryption */
for(;len<DID_MAXSIZE;len++) packet[(*ofs)++]=random()&0xff;
for(;len<SID_SIZE;len++) packet[(*ofs)++]=random()&0xff;
return 0;
}
@ -103,6 +106,7 @@ int extractSid(unsigned char *packet,int *ofs,char *sid)
int stowSid(unsigned char *packet,int ofs,char *sid)
{
int i;
if (debug>2) printf("Stowing SID \"%s\"\n",sid);
if (strlen(sid)!=64) return setReason("Asked to stow invalid SID (should be 64 hex digits)");
for(i=0;i<SID_SIZE;i++)
{

View File

@ -39,7 +39,7 @@ int nextHlr(unsigned char *hlr,int *ofs)
record_length|=hlr[(*ofs)+1]<<16;
record_length|=hlr[(*ofs)+0]<<24;
if (!record_length) return 0;
if (!record_length) return -1;
(*ofs)+=record_length;
return 0;

View File

@ -423,6 +423,7 @@ int extractResponses(struct in_addr sender,unsigned char *buffer,int len,struct
r->response=malloc(r->response_len+1);
if (!r->response) exit(setReason("malloc() failed."));
bcopy(&rr[0],r->response,r->response_len);
r->response[r->response_len]=0;
ofs+=r->response_len;
}

View File

@ -218,6 +218,12 @@ int processRequest(unsigned char *packet,int len,
case ACTION_SET:
ofs=0;
if (debug>1) fprintf(stderr,"Looking for hlr entries with sid='%s' / did='%s'\n",sid,did);
if ((!sid)||(!sid[0])) {
setReason("You can only set variables by SID");
return respondSimple(NULL,ACTION_ERROR,(unsigned char *)"SET requires authentication by SID",0,transaction_id);
}
while(findHlr(hlr,&ofs,sid,did))
{
int itemId,instance,start_offset,bytes,flags;
@ -233,11 +239,6 @@ int processRequest(unsigned char *packet,int len,
/* XXX Doesn't verify PIN authentication */
/* Get write request */
if ((!sid)||(!sid[0])) {
setReason("You can only set variables by SID");
return
respondSimple(NULL,ACTION_ERROR,(unsigned char *)"SET requires authentication by SID",0,transaction_id);
}
pofs++; rofs=pofs;
if (extractRequest(packet,&pofs,len,
@ -296,17 +297,32 @@ int processRequest(unsigned char *packet,int len,
}
break;
case ACTION_GET:
ofs=0;
if (debug>1) fprintf(stderr,"Looking for hlr entries with sid='%s' / did='%s'\n",sid,did);
while(findHlr(hlr,&ofs,sid,did))
{
/* 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;
int var_id=packet[pofs+1];
int instance=packet[pofs+2];
int offset=(packet[pofs+3]<<8)+packet[pofs+4];
int sendDone=0;
char *hlr_sid=NULL;
pofs+=7;
if (debug>2) dump("Request bytes",&packet[pofs],8);
if (debug>1) fprintf(stderr,"Processing ACTION_GET (var_id=%02x, instance=%02x, pofs=0x%x, len=%d)\n",var_id,instance,pofs,len);
ofs=0;
if (debug>1) fprintf(stderr,"Looking for hlr entries with sid='%s' / did='%s'\n",sid?sid:"null",did?did:"null");
while(1)
{
struct hlrentry_handle *h;
if (debug>1) fprintf(stderr,"findHlr found a match at 0x%x\n",ofs);
// if an empty did was passed in, get results from all hlr records
if (*sid || *did){
if (!findHlr(hlr,&ofs,sid,did)) break;
if (debug>1) fprintf(stderr,"findHlr found a match @ 0x%x\n",ofs);
}
if (debug>2) hlrDump(hlr,ofs);
/* XXX consider taking action on this HLR
@ -316,8 +332,6 @@ int processRequest(unsigned char *packet,int len,
if (instance==0xff) instance=-1;
if (debug>1) fprintf(stderr,"Responding to ACTION_GET (var_id=%02x, instance=%02x, pofs=0x%x, len=%d)\n",var_id,instance,pofs,len);
if (debug>2) dump("Request bytes",&packet[pofs],8);
/* Step through HLR to find any matching instances of the requested variable */
h=openhlrentry(hlr,ofs);
if (debug>1) fprintf(stderr,"openhlrentry(hlr,%d) returned %p\n",ofs,h);
@ -330,18 +344,20 @@ int processRequest(unsigned char *packet,int len,
{
if (h->var_instance==instance||instance==-1)
{
/* Limit transfer size to MAX_DATA_BYTES, plus an allowance for variable packing. */
unsigned char data[MAX_DATA_BYTES+16];
int dlen=0;
if (debug>1) fprintf(stderr,"Sending matching variable value instance (instance #%d), value offset %d.\n",
h->var_instance,offset);
// only send each value when the *next* record is found, that way we can easily stamp the last response with DONE
if (sendDone>0)
respondSimple(hlr_sid,ACTION_DATA,data,dlen,transaction_id);
dlen=0;
if (packageVariableSegment(data,&dlen,h,offset,MAX_DATA_BYTES+16))
return setReason("packageVariableSegment() failed.");
hlr_sid=hlrSid(hlr,ofs);
respondSimple(hlrSid(hlr,ofs),ACTION_DATA,data,dlen,transaction_id);
if (instance==-1) sendDone++;
sendDone++;
}
else
if (debug>2) fprintf(stderr,"Ignoring variable instance %d (not %d)\n",
@ -352,18 +368,17 @@ int processRequest(unsigned char *packet,int len,
h->var_id,var_id);
h=hlrentrygetent(h);
}
if (sendDone)
{
unsigned char data[1];
data[0]=sendDone&0xff;
respondSimple(hlrSid(hlr,ofs),ACTION_DONE,data,1,transaction_id);
}
/* Advance to next record and keep searching */
if (nextHlr(hlr,&ofs)) break;
}
pofs+=7;
if (sendDone)
{
data[dlen++]=ACTION_DONE;
data[dlen++]=sendDone&0xff;
respondSimple(hlr_sid,ACTION_DATA,data,dlen,transaction_id);
}
}
break;
default:
setReason("Asked to perform unsupported action");

View File

@ -65,9 +65,9 @@ srandomdev(void)
{
struct timeval tv;
unsigned int seed;
#ifndef WIN32
FILE *fd;
#ifndef WIN32
if ((fd = fopen("/dev/urandom", O_RDONLY)) >= 0) {
fread(&seed, sizeof seed, 1, fd);
fclose(fd);

View File

@ -62,7 +62,9 @@
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib Shlwapi.lib"
LinkIncremental="2"
LinkIncremental="1"
GenerateManifest="false"
IgnoreAllDefaultLibraries="true"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
@ -117,7 +119,7 @@
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
RuntimeLibrary="2"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
@ -134,9 +136,11 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="ws2_32.lib Shlwapi.lib"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
GenerateManifest="false"
GenerateDebugInformation="false"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"