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 nybl;
int d=0; int d=0;
int len=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]) switch(did[d])
{ {
@ -68,10 +69,11 @@ int stowDid(unsigned char *packet,int *ofs,char *did)
if (highP) { packet[*ofs]=nybl<<4; highP=0; } if (highP) { packet[*ofs]=nybl<<4; highP=0; }
else { else {
packet[(*ofs)++]|=nybl; highP=1; packet[(*ofs)++]|=nybl; highP=1;
len++;
} }
d++; len++; d++;
} }
if (len>=DID_MAXSIZE) if (d>=DID_MAXSIZE)
{ {
setReason("DID number too long"); setReason("DID number too long");
return -1; 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 */ /* Append end of number code, filling the whole byte for fast and easy comparison */
if (highP) packet[(*ofs)++]=0xff; if (highP) packet[(*ofs)++]=0xff;
else packet[(*ofs)++]|=0x0f; else packet[(*ofs)++]|=0x0f;
len++;
/* Fill remainder of field with randomness to protect any encryption */ /* 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; 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 stowSid(unsigned char *packet,int ofs,char *sid)
{ {
int i; 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)"); if (strlen(sid)!=64) return setReason("Asked to stow invalid SID (should be 64 hex digits)");
for(i=0;i<SID_SIZE;i++) 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)+1]<<16;
record_length|=hlr[(*ofs)+0]<<24; record_length|=hlr[(*ofs)+0]<<24;
if (!record_length) return 0; if (!record_length) return -1;
(*ofs)+=record_length; (*ofs)+=record_length;
return 0; 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); r->response=malloc(r->response_len+1);
if (!r->response) exit(setReason("malloc() failed.")); if (!r->response) exit(setReason("malloc() failed."));
bcopy(&rr[0],r->response,r->response_len); bcopy(&rr[0],r->response,r->response_len);
r->response[r->response_len]=0;
ofs+=r->response_len; ofs+=r->response_len;
} }

View File

@ -218,6 +218,12 @@ int processRequest(unsigned char *packet,int len,
case ACTION_SET: case ACTION_SET:
ofs=0; ofs=0;
if (debug>1) fprintf(stderr,"Looking for hlr entries with sid='%s' / did='%s'\n",sid,did); 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)) while(findHlr(hlr,&ofs,sid,did))
{ {
int itemId,instance,start_offset,bytes,flags; int itemId,instance,start_offset,bytes,flags;
@ -233,11 +239,6 @@ int processRequest(unsigned char *packet,int len,
/* XXX Doesn't verify PIN authentication */ /* XXX Doesn't verify PIN authentication */
/* Get write request */ /* 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; pofs++; rofs=pofs;
if (extractRequest(packet,&pofs,len, if (extractRequest(packet,&pofs,len,
@ -296,17 +297,32 @@ int processRequest(unsigned char *packet,int len,
} }
break; break;
case ACTION_GET: 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 var_id=packet[pofs+1];
int instance=packet[pofs+2]; int instance=packet[pofs+2];
int offset=(packet[pofs+3]<<8)+packet[pofs+4]; 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; 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); if (debug>2) hlrDump(hlr,ofs);
/* XXX consider taking action on this HLR /* XXX consider taking action on this HLR
@ -316,8 +332,6 @@ int processRequest(unsigned char *packet,int len,
if (instance==0xff) instance=-1; 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 */ /* Step through HLR to find any matching instances of the requested variable */
h=openhlrentry(hlr,ofs); h=openhlrentry(hlr,ofs);
if (debug>1) fprintf(stderr,"openhlrentry(hlr,%d) returned %p\n",ofs,h); 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) 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", if (debug>1) fprintf(stderr,"Sending matching variable value instance (instance #%d), value offset %d.\n",
h->var_instance,offset); 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)) if (packageVariableSegment(data,&dlen,h,offset,MAX_DATA_BYTES+16))
return setReason("packageVariableSegment() failed."); return setReason("packageVariableSegment() failed.");
hlr_sid=hlrSid(hlr,ofs);
respondSimple(hlrSid(hlr,ofs),ACTION_DATA,data,dlen,transaction_id); sendDone++;
if (instance==-1) sendDone++;
} }
else else
if (debug>2) fprintf(stderr,"Ignoring variable instance %d (not %d)\n", 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->var_id,var_id);
h=hlrentrygetent(h); 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 */ /* Advance to next record and keep searching */
if (nextHlr(hlr,&ofs)) break; if (nextHlr(hlr,&ofs)) break;
} }
if (sendDone)
pofs+=7; {
data[dlen++]=ACTION_DONE;
data[dlen++]=sendDone&0xff;
respondSimple(hlr_sid,ACTION_DATA,data,dlen,transaction_id);
}
}
break; break;
default: default:
setReason("Asked to perform unsupported action"); setReason("Asked to perform unsupported action");

View File

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

View File

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