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

@ -94,7 +94,7 @@ int sendToPeers(unsigned char *packet,int packet_len,int method,int peerId,struc
int ret;
struct sockaddr_in peer_addr;
bzero(&peer_addr, sizeof(peer_addr));
bzero(&peer_addr, sizeof(peer_addr));
peer_addr.sin_family=AF_INET;
peer_addr.sin_port = htons(4110);

149
server.c
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,74 +297,88 @@ 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))
{
int var_id=packet[pofs+1];
int instance=packet[pofs+2];
int offset=(packet[pofs+3]<<8)+packet[pofs+4];
int sendDone=0;
struct hlrentry_handle *h;
{
/* 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];
char *hlr_sid=NULL;
if (debug>1) fprintf(stderr,"findHlr found a match at 0x%x\n",ofs);
if (debug>2) hlrDump(hlr,ofs);
/* XXX consider taking action on this HLR
(check PIN first depending on the action requested) */
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);
/* Form a reply packet containing the requested data */
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);
while(h)
{
/* Is this the variable? */
if (debug>2) fprintf(stderr," considering var_id=%02x, instance=%02x\n",
h->var_id,h->var_instance);
if (h->var_id==var_id)
{
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);
if (packageVariableSegment(data,&dlen,h,offset,MAX_DATA_BYTES+16))
return setReason("packageVariableSegment() failed.");
respondSimple(hlrSid(hlr,ofs),ACTION_DATA,data,dlen,transaction_id);
if (instance==-1) sendDone++;
}
else
if (debug>2) fprintf(stderr,"Ignoring variable instance %d (not %d)\n",
h->var_instance,instance);
}
else
if (debug>2) fprintf(stderr,"Ignoring variable ID %d (not %d)\n",
h->var_id,var_id);
h=hlrentrygetent(h);
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 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
(check PIN first depending on the action requested) */
/* Form a reply packet containing the requested data */
if (instance==0xff) instance=-1;
/* 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);
while(h)
{
/* Is this the variable? */
if (debug>2) fprintf(stderr," considering var_id=%02x, instance=%02x\n",
h->var_id,h->var_instance);
if (h->var_id==var_id)
{
if (h->var_instance==instance||instance==-1)
{
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);
sendDone++;
}
else
if (debug>2) fprintf(stderr,"Ignoring variable instance %d (not %d)\n",
h->var_instance,instance);
}
else
if (debug>2) fprintf(stderr,"Ignoring variable ID %d (not %d)\n",
h->var_id,var_id);
h=hlrentrygetent(h);
}
/* Advance to next record and keep searching */
if (nextHlr(hlr,&ofs)) break;
}
if (sendDone)
{
unsigned char data[1];
data[0]=sendDone&0xff;
respondSimple(hlrSid(hlr,ofs),ACTION_DONE,data,1,transaction_id);
data[dlen++]=ACTION_DONE;
data[dlen++]=sendDone&0xff;
respondSimple(hlr_sid,ACTION_DATA,data,dlen,transaction_id);
}
/* Advance to next record and keep searching */
if (nextHlr(hlr,&ofs)) break;
}
pofs+=7;
}
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"

View File

@ -1,108 +1,108 @@
#include "../mphlr.h"
char *optarg; // global argument pointer
int optind = 0; // global argv index
#include "../mphlr.h"
char *optarg; // global argument pointer
int optind = 0; // global argv index
int strncasecmp(char *a,char *b,int len){
return CompareStringA(LOCALE_INVARIANT, NORM_IGNORECASE, a, -1, b, len) -2;
}
int getopt(int argc, char *argv[], char *optstring)
{
char c;
char *cp;
static char *next = NULL;
if (optind == 0)
next = NULL;
optarg = NULL;
if (next == NULL || *next == '\0')
{
if (optind == 0)
optind++;
if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
{
optarg = NULL;
if (optind < argc)
optarg = argv[optind];
return EOF;
}
if (strcmp(argv[optind], "--") == 0)
{
optind++;
optarg = NULL;
if (optind < argc)
optarg = argv[optind];
return EOF;
}
next = argv[optind];
next++; // skip past -
optind++;
}
c = *next++;
cp = strchr(optstring, c);
if (cp == NULL || c == ':')
return '?';
cp++;
if (*cp == ':')
{
if (*next != '\0')
{
optarg = next;
next = NULL;
}
else if (optind < argc)
{
optarg = argv[optind];
optind++;
}
else
{
return '?';
}
}
return c;
}
int gettimeofday(struct timeval *tv, void *tz)
{
FILETIME ft;
unsigned __int64 tmpres = 0;
static int tzflag;
if (NULL != tv)
{
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tmpres /= 10; /*convert into microseconds*/
tv->tv_sec = (long)(tmpres / 1000000UL);
tv->tv_usec = (long)(tmpres % 1000000UL);
}
return 0;
}
void * mmap(void *i1, size_t len, int i2, int i3, int fd, int offset){
HANDLE fm;
HANDLE h = (HANDLE) _get_osfhandle (fd);
fm = CreateFileMapping(h, NULL, PAGE_READWRITE, 0, len+offset, NULL);
return MapViewOfFile(fm, FILE_MAP_WRITE, 0, offset, len);
}
int getopt(int argc, char *argv[], char *optstring)
{
char c;
char *cp;
static char *next = NULL;
if (optind == 0)
next = NULL;
optarg = NULL;
if (next == NULL || *next == '\0')
{
if (optind == 0)
optind++;
if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
{
optarg = NULL;
if (optind < argc)
optarg = argv[optind];
return EOF;
}
if (strcmp(argv[optind], "--") == 0)
{
optind++;
optarg = NULL;
if (optind < argc)
optarg = argv[optind];
return EOF;
}
next = argv[optind];
next++; // skip past -
optind++;
}
c = *next++;
cp = strchr(optstring, c);
if (cp == NULL || c == ':')
return '?';
cp++;
if (*cp == ':')
{
if (*next != '\0')
{
optarg = next;
next = NULL;
}
else if (optind < argc)
{
optarg = argv[optind];
optind++;
}
else
{
return '?';
}
}
return c;
}
int gettimeofday(struct timeval *tv, void *tz)
{
FILETIME ft;
unsigned __int64 tmpres = 0;
static int tzflag;
if (NULL != tv)
{
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
/*converting file time to unix epoch*/
tmpres -= DELTA_EPOCH_IN_MICROSECS;
tmpres /= 10; /*convert into microseconds*/
tv->tv_sec = (long)(tmpres / 1000000UL);
tv->tv_usec = (long)(tmpres % 1000000UL);
}
return 0;
}
void * mmap(void *i1, size_t len, int i2, int i3, int fd, int offset){
HANDLE fm;
HANDLE h = (HANDLE) _get_osfhandle (fd);
fm = CreateFileMapping(h, NULL, PAGE_READWRITE, 0, len+offset, NULL);
return MapViewOfFile(fm, FILE_MAP_WRITE, 0, offset, len);
}