mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-30 08:03:49 +00:00
Move from recvfrom() to recvmsg() so that we can get packet TTLs on
reception. Other changes associated with overlay mesh.
This commit is contained in:
parent
8a24fb95b1
commit
5cc6079c0f
43
client.c
43
client.c
@ -79,7 +79,7 @@ int packetSendRequest(int method,unsigned char *packet,int packet_len,int batchP
|
|||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
if (overlayMode)
|
if (overlayMode)
|
||||||
r=overlay_sendto(recvaddr,packet,packet_len);
|
r=overlay_sendto((struct sockaddr_in *)recvaddr,packet,packet_len);
|
||||||
else
|
else
|
||||||
r=sendto(sock,packet,packet_len,0,recvaddr,sizeof(struct sockaddr_in));
|
r=sendto(sock,packet,packet_len,0,recvaddr,sizeof(struct sockaddr_in));
|
||||||
if (r<packet_len) {
|
if (r<packet_len) {
|
||||||
@ -210,7 +210,8 @@ int packetSendRequest(int method,unsigned char *packet,int packet_len,int batchP
|
|||||||
sendToPeers() does it that way. We just have to remember to
|
sendToPeers() does it that way. We just have to remember to
|
||||||
ask for serialised attempts, rather than all at once.
|
ask for serialised attempts, rather than all at once.
|
||||||
*/
|
*/
|
||||||
int requestNewHLR(char *did,char *pin,char *sid,struct sockaddr *recvaddr)
|
int requestNewHLR(char *did,char *pin,char *sid,
|
||||||
|
int recvttl,struct sockaddr *recvaddr)
|
||||||
{
|
{
|
||||||
unsigned char packet[8000];
|
unsigned char packet[8000];
|
||||||
int packet_len=0;
|
int packet_len=0;
|
||||||
@ -224,11 +225,12 @@ int requestNewHLR(char *did,char *pin,char *sid,struct sockaddr *recvaddr)
|
|||||||
bcopy(&packet[OFS_TRANSIDFIELD],transaction_id,TRANSID_SIZE);
|
bcopy(&packet[OFS_TRANSIDFIELD],transaction_id,TRANSID_SIZE);
|
||||||
if (packetSetDid(packet,8000,&packet_len,did)) return -1;
|
if (packetSetDid(packet,8000,&packet_len,did)) return -1;
|
||||||
if (packetAddHLRCreateRequest(packet,8000,&packet_len)) return -1;
|
if (packetAddHLRCreateRequest(packet,8000,&packet_len)) return -1;
|
||||||
if (packetFinalise(packet,8000,&packet_len,CRYPT_PUBLIC)) return -1;
|
if (packetFinalise(packet,8000,recvttl,&packet_len,CRYPT_PUBLIC)) return -1;
|
||||||
|
|
||||||
/* Send it to peers, starting with ourselves, one at a time until one succeeds.
|
/* Send it to peers, starting with ourselves, one at a time until one succeeds.
|
||||||
XXX - This could take a while if we have long timeouts for each. */
|
XXX - This could take a while if we have long timeouts for each. */
|
||||||
if (packetSendRequest(REQ_SERIAL,packet,packet_len,NONBATCH,transaction_id,recvaddr,&responses)) return -1;
|
if (packetSendRequest(REQ_SERIAL,packet,packet_len,NONBATCH,
|
||||||
|
transaction_id,recvaddr,&responses)) return -1;
|
||||||
|
|
||||||
/* Extract response */
|
/* Extract response */
|
||||||
if (debug&DEBUG_DNARESPONSES) dumpResponses(&responses);
|
if (debug&DEBUG_DNARESPONSES) dumpResponses(&responses);
|
||||||
@ -344,9 +346,10 @@ int getReplyPackets(int method,int peer,int batchP,struct response_set *response
|
|||||||
|
|
||||||
/* Use this temporary socket address structure if one was not supplied */
|
/* Use this temporary socket address structure if one was not supplied */
|
||||||
struct sockaddr reply_recvaddr;
|
struct sockaddr reply_recvaddr;
|
||||||
|
int ttl=-1;
|
||||||
if (!recvaddr) recvaddr=&reply_recvaddr;
|
if (!recvaddr) recvaddr=&reply_recvaddr;
|
||||||
|
|
||||||
len=recvfrom(sock,buffer,sizeof(buffer),0,recvaddr,&recvaddrlen);
|
len=recvwithttl(sock,buffer,sizeof(buffer),&ttl,recvaddr,&recvaddrlen);
|
||||||
if (len<=0) return setReason("Unable to receive packet.");
|
if (len<=0) return setReason("Unable to receive packet.");
|
||||||
|
|
||||||
if (recvaddr) {
|
if (recvaddr) {
|
||||||
@ -362,7 +365,7 @@ int getReplyPackets(int method,int peer,int batchP,struct response_set *response
|
|||||||
if (debug&DEBUG_SIMULATION) fprintf(stderr,"Simulation mode: Dropped packet due to simulated link parameters.\n");
|
if (debug&DEBUG_SIMULATION) fprintf(stderr,"Simulation mode: Dropped packet due to simulated link parameters.\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!packetOk(-1,buffer,len,transaction_id,recvaddr,recvaddrlen,0)) {
|
if (!packetOk(-1,buffer,len,transaction_id,ttl,recvaddr,recvaddrlen,0)) {
|
||||||
/* Packet passes tests - extract responses and append them to the end of the response list */
|
/* Packet passes tests - extract responses and append them to the end of the response list */
|
||||||
if (extractResponses(client_addr,buffer,len,responses))
|
if (extractResponses(client_addr,buffer,len,responses))
|
||||||
return setReason("Problem extracting response fields from reply packets");
|
return setReason("Problem extracting response fields from reply packets");
|
||||||
@ -393,7 +396,8 @@ int getReplyPackets(int method,int peer,int batchP,struct response_set *response
|
|||||||
}
|
}
|
||||||
|
|
||||||
int writeItem(char *sid,int var_id,int instance,unsigned char *value,
|
int writeItem(char *sid,int var_id,int instance,unsigned char *value,
|
||||||
int value_start,int value_length,int flags, struct sockaddr *recvaddr)
|
int value_start,int value_length,int flags,
|
||||||
|
int recvttl,struct sockaddr *recvaddr)
|
||||||
{
|
{
|
||||||
unsigned char packet[8000];
|
unsigned char packet[8000];
|
||||||
int packet_len=0;
|
int packet_len=0;
|
||||||
@ -423,7 +427,7 @@ int writeItem(char *sid,int var_id,int instance,unsigned char *value,
|
|||||||
if (o+bytes>value_length) bytes=value_length-o;
|
if (o+bytes>value_length) bytes=value_length-o;
|
||||||
if (debug&DEBUG_DNAVARS) fprintf(stderr," writing [%d,%d)\n",o,o+bytes-1);
|
if (debug&DEBUG_DNAVARS) fprintf(stderr," writing [%d,%d)\n",o,o+bytes-1);
|
||||||
if (writeItem(sid,var_id,instance,&value[o-value_start],o,bytes,
|
if (writeItem(sid,var_id,instance,&value[o-value_start],o,bytes,
|
||||||
flags|((o>value_start)?SET_FRAGMENT:0),NULL))
|
flags|((o>value_start)?SET_FRAGMENT:0),recvttl,NULL))
|
||||||
{
|
{
|
||||||
if (debug&DEBUG_DNAVARS) fprintf(stderr," - writing installment failed\n");
|
if (debug&DEBUG_DNAVARS) fprintf(stderr," - writing installment failed\n");
|
||||||
return setReason("Failure during multi-packet write of long-value");
|
return setReason("Failure during multi-packet write of long-value");
|
||||||
@ -439,7 +443,7 @@ int writeItem(char *sid,int var_id,int instance,unsigned char *value,
|
|||||||
if (packetSetSid(packet,8000,&packet_len,sid)) return -1;
|
if (packetSetSid(packet,8000,&packet_len,sid)) return -1;
|
||||||
if (packetAddVariableWrite(packet,8000,&packet_len,var_id,instance,
|
if (packetAddVariableWrite(packet,8000,&packet_len,var_id,instance,
|
||||||
value,value_start,value_length,flags)) return -1;
|
value,value_start,value_length,flags)) return -1;
|
||||||
if (packetFinalise(packet,8000,&packet_len,CRYPT_SIGNED|CRYPT_CIPHERED)) return -1;
|
if (packetFinalise(packet,8000,recvttl,&packet_len,CRYPT_SIGNED|CRYPT_CIPHERED)) return -1;
|
||||||
|
|
||||||
/* XXX should be able to target to the peer holding the SID, if we have it.
|
/* XXX should be able to target to the peer holding the SID, if we have it.
|
||||||
In any case, we */
|
In any case, we */
|
||||||
@ -525,7 +529,7 @@ int peerAddress(char *did,char *sid,int flags)
|
|||||||
if (debug&DEBUG_DNAVARS) fprintf(stderr,"%s() failed at line %d\n",__FUNCTION__,__LINE__);
|
if (debug&DEBUG_DNAVARS) fprintf(stderr,"%s() failed at line %d\n",__FUNCTION__,__LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (packetFinalise(packet,8000,&packet_len,CRYPT_PUBLIC)) {
|
if (packetFinalise(packet,8000,-1,&packet_len,CRYPT_PUBLIC)) {
|
||||||
if (debug&DEBUG_PACKETFORMATS) fprintf(stderr,"%s() failed at line %d\n",__FUNCTION__,__LINE__);
|
if (debug&DEBUG_PACKETFORMATS) fprintf(stderr,"%s() failed at line %d\n",__FUNCTION__,__LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -564,7 +568,8 @@ int peerAddress(char *did,char *sid,int flags)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int requestItem(char *did,char *sid,char *item,int instance,unsigned char *buffer,int buffer_length,int *len,
|
int requestItem(char *did,char *sid,char *item,int instance,
|
||||||
|
unsigned char *buffer,int buffer_length,int *len,
|
||||||
unsigned char *transaction_id)
|
unsigned char *transaction_id)
|
||||||
{
|
{
|
||||||
unsigned char packet[8000];
|
unsigned char packet[8000];
|
||||||
@ -606,7 +611,7 @@ int requestItem(char *did,char *sid,char *item,int instance,unsigned char *buffe
|
|||||||
if (debug&DEBUG_PACKETFORMATS) fprintf(stderr,"requestItem() failed at line %d\n",__LINE__);
|
if (debug&DEBUG_PACKETFORMATS) fprintf(stderr,"requestItem() failed at line %d\n",__LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (packetFinalise(packet,8000,&packet_len,CRYPT_SIGNED|CRYPT_CIPHERED)) {
|
if (packetFinalise(packet,8000,-1,&packet_len,CRYPT_SIGNED|CRYPT_CIPHERED)) {
|
||||||
if (debug&DEBUG_PACKETFORMATS) fprintf(stderr,"requestItem() failed at line %d\n",__LINE__);
|
if (debug&DEBUG_PACKETFORMATS) fprintf(stderr,"requestItem() failed at line %d\n",__LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -626,8 +631,8 @@ int requestItem(char *did,char *sid,char *item,int instance,unsigned char *buffe
|
|||||||
extractSid(r->sid,&slen,sid);
|
extractSid(r->sid,&slen,sid);
|
||||||
switch(r->code)
|
switch(r->code)
|
||||||
{
|
{
|
||||||
case ACTION_OKAY: printf("OK:%s\n",sid); if (buffer) {strcpy((char *)buffer,sid); *len=strlen(sid); } successes++; break;
|
case ACTION_OKAY: printf("OK:%s:%d\n",sid,r->recvttl); if (buffer) {strcpy((char *)buffer,sid); *len=strlen(sid); } successes++; break;
|
||||||
case ACTION_DECLINED: printf("DECLINED:%s\n",sid); errors++; break;
|
case ACTION_DECLINED: printf("DECLINED:%s:%d\n",sid,r->recvttl); errors++; break;
|
||||||
case ACTION_DATA:
|
case ACTION_DATA:
|
||||||
/* Display data.
|
/* Display data.
|
||||||
The trick is knowing the format of the data.
|
The trick is knowing the format of the data.
|
||||||
@ -643,7 +648,7 @@ int requestItem(char *did,char *sid,char *item,int instance,unsigned char *buffe
|
|||||||
int dlen=0;
|
int dlen=0;
|
||||||
did[0]=0;
|
did[0]=0;
|
||||||
extractDid(r->response,&dlen,did);
|
extractDid(r->response,&dlen,did);
|
||||||
printf("DIDS:%s:%d:%s\n",sid,r->var_instance,did);
|
printf("DIDS:%s:%d:%d:%s\n",sid,r->recvttl,r->var_instance,did);
|
||||||
if (buffer) {strcpy((char *)buffer,did); *len=strlen(did); }
|
if (buffer) {strcpy((char *)buffer,did); *len=strlen(did); }
|
||||||
successes++;
|
successes++;
|
||||||
}
|
}
|
||||||
@ -658,7 +663,7 @@ int requestItem(char *did,char *sid,char *item,int instance,unsigned char *buffe
|
|||||||
while(vars[v].name&&vars[v].id!=r->var_id) v++;
|
while(vars[v].name&&vars[v].id!=r->var_id) v++;
|
||||||
if (!vars[v].id) printf("0x%02x",r->var_id);
|
if (!vars[v].id) printf("0x%02x",r->var_id);
|
||||||
while(vars[v].name[i]) fputc(toupper(vars[v].name[i++]),stdout);
|
while(vars[v].name[i]) fputc(toupper(vars[v].name[i++]),stdout);
|
||||||
printf(":%s:%d:",sid,r->var_instance);
|
printf(":%s:%d:%d:",sid,r->recvttl,r->var_instance);
|
||||||
*len=r->value_len;
|
*len=r->value_len;
|
||||||
|
|
||||||
if (outputtemplate)
|
if (outputtemplate)
|
||||||
@ -713,7 +718,7 @@ int requestItem(char *did,char *sid,char *item,int instance,unsigned char *buffe
|
|||||||
/* Send accumulated request direct to the responder */
|
/* Send accumulated request direct to the responder */
|
||||||
if (packet_len>=MAX_DATA_BYTES)
|
if (packet_len>=MAX_DATA_BYTES)
|
||||||
{
|
{
|
||||||
if (packetFinalise(packet,8000,&packet_len,CRYPT_CIPHERED|CRYPT_SIGNED)) {
|
if (packetFinalise(packet,8000,-1,&packet_len,CRYPT_CIPHERED|CRYPT_SIGNED)) {
|
||||||
if (debug&DEBUG_DNAREQUESTS) fprintf(stderr,"requestItem() failed at line %d\n",__LINE__);
|
if (debug&DEBUG_DNAREQUESTS) fprintf(stderr,"requestItem() failed at line %d\n",__LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -745,7 +750,7 @@ int requestItem(char *did,char *sid,char *item,int instance,unsigned char *buffe
|
|||||||
/* Send accumulated request direct to the responder */
|
/* Send accumulated request direct to the responder */
|
||||||
if (packet_len)
|
if (packet_len)
|
||||||
{
|
{
|
||||||
if (packetFinalise(packet,8000,&packet_len,CRYPT_SIGNED|CRYPT_CIPHERED)) {
|
if (packetFinalise(packet,8000,-1,&packet_len,CRYPT_SIGNED|CRYPT_CIPHERED)) {
|
||||||
if (debug&DEBUG_PACKETFORMATS) fprintf(stderr,"requestItem() failed at line %d\n",__LINE__);
|
if (debug&DEBUG_PACKETFORMATS) fprintf(stderr,"requestItem() failed at line %d\n",__LINE__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -797,7 +802,7 @@ int requestItem(char *did,char *sid,char *item,int instance,unsigned char *buffe
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ACTION_DONE:
|
case ACTION_DONE:
|
||||||
printf("DONE:%s:%d\n",sid,r->response[0]);
|
printf("DONE:%s:%d:%d\n",sid,r->recvttl,r->response[0]);
|
||||||
break;
|
break;
|
||||||
case ACTION_GET: printf("ERROR:You cant respond with GET\n"); break;
|
case ACTION_GET: printf("ERROR:You cant respond with GET\n"); break;
|
||||||
case ACTION_SET: printf("ERROR:You cant respond with SET\n"); break;
|
case ACTION_SET: printf("ERROR:You cant respond with SET\n"); break;
|
||||||
|
6
dna.c
6
dna.c
@ -462,7 +462,7 @@ int main(int argc,char **argv)
|
|||||||
int value_len=65535;
|
int value_len=65535;
|
||||||
if (parseAssignment((unsigned char *)optarg,&var_id,value,&value_len)) return -1;
|
if (parseAssignment((unsigned char *)optarg,&var_id,value,&value_len)) return -1;
|
||||||
value[value_len]=0;
|
value[value_len]=0;
|
||||||
return writeItem(did?did:sid,var_id,instance,value,0,value_len,SET_NOREPLACE,NULL);
|
return writeItem(did?did:sid,var_id,instance,value,0,value_len,SET_NOREPLACE,-1,NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'U': /* write or update a variable */
|
case 'U': /* write or update a variable */
|
||||||
@ -472,14 +472,14 @@ int main(int argc,char **argv)
|
|||||||
int value_len=65535;
|
int value_len=65535;
|
||||||
if (parseAssignment((unsigned char *)optarg,&var_id,value,&value_len)) return -1;
|
if (parseAssignment((unsigned char *)optarg,&var_id,value,&value_len)) return -1;
|
||||||
value[value_len]=0;
|
value[value_len]=0;
|
||||||
return writeItem(did?did:sid,var_id,instance,value,0,value_len,SET_REPLACE,NULL);
|
return writeItem(did?did:sid,var_id,instance,value,0,value_len,SET_REPLACE,-1,NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'C': /* create a new HLR entry */
|
case 'C': /* create a new HLR entry */
|
||||||
{
|
{
|
||||||
if (optind<argc) usage("Extraneous options after HLR creation request");
|
if (optind<argc) usage("Extraneous options after HLR creation request");
|
||||||
if ((!did)||(sid)) usage("Specify exactly one DID and no SID to create a new HLR entry");
|
if ((!did)||(sid)) usage("Specify exactly one DID and no SID to create a new HLR entry");
|
||||||
return requestNewHLR(did,pin,sid,NULL);
|
return requestNewHLR(did,pin,sid,-1,NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'O': /* output to templated files */
|
case 'O': /* output to templated files */
|
||||||
|
28
mphlr.h
28
mphlr.h
@ -206,6 +206,7 @@ struct response {
|
|||||||
int code;
|
int code;
|
||||||
unsigned char sid[32];
|
unsigned char sid[32];
|
||||||
struct in_addr sender;
|
struct in_addr sender;
|
||||||
|
int recvttl;
|
||||||
unsigned char *response;
|
unsigned char *response;
|
||||||
int response_len;
|
int response_len;
|
||||||
int var_id;
|
int var_id;
|
||||||
@ -283,6 +284,7 @@ extern struct mphlr_variable vars[];
|
|||||||
#define ACTION_WROTE 0x83
|
#define ACTION_WROTE 0x83
|
||||||
|
|
||||||
#define ACTION_XFER 0xf0
|
#define ACTION_XFER 0xf0
|
||||||
|
#define ACTION_RECVTTL 0xfd
|
||||||
#define ACTION_PAD 0xfe
|
#define ACTION_PAD 0xfe
|
||||||
#define ACTION_EOT 0xff
|
#define ACTION_EOT 0xff
|
||||||
|
|
||||||
@ -293,27 +295,33 @@ extern int hexdigit[16];
|
|||||||
|
|
||||||
extern int sock;
|
extern int sock;
|
||||||
|
|
||||||
|
int recvwithttl(int sock,unsigned char *buffer,int bufferlen,int *ttl,
|
||||||
|
struct sockaddr *recvaddr,unsigned int *recvaddrlen);
|
||||||
int stowSid(unsigned char *packet,int ofs,char *sid);
|
int stowSid(unsigned char *packet,int ofs,char *sid);
|
||||||
int stowDid(unsigned char *packet,int *ofs,char *did);
|
int stowDid(unsigned char *packet,int *ofs,char *did);
|
||||||
int isFieldZeroP(unsigned char *packet,int start,int count);
|
int isFieldZeroP(unsigned char *packet,int start,int count);
|
||||||
void srandomdev();
|
void srandomdev();
|
||||||
int respondSimple(char *sid,int action,unsigned char *action_text,int action_len,
|
int respondSimple(char *sid,int action,unsigned char *action_text,int action_len,
|
||||||
unsigned char *transaction_id,struct sockaddr *recvaddr,int cryptoFlags);
|
unsigned char *transaction_id,int recvttl,
|
||||||
|
struct sockaddr *recvaddr,int cryptoFlags);
|
||||||
int requestItem(char *did,char *sid,char *item,int instance,unsigned char *buffer,int buffer_length,int *len,
|
int requestItem(char *did,char *sid,char *item,int instance,unsigned char *buffer,int buffer_length,int *len,
|
||||||
unsigned char *transaction_id);
|
unsigned char *transaction_id);
|
||||||
int requestNewHLR(char *did,char *pin,char *sid,struct sockaddr *recvaddr);
|
int requestNewHLR(char *did,char *pin,char *sid,int recvttl,struct sockaddr *recvaddr);
|
||||||
int server(char *backing_file,int size,int foregroundMode);
|
int server(char *backing_file,int size,int foregroundMode);
|
||||||
|
|
||||||
int setReason(char *fmt, ...);
|
int setReason(char *fmt, ...);
|
||||||
int hexvalue(unsigned char c);
|
int hexvalue(unsigned char c);
|
||||||
int dump(char *name,unsigned char *addr,int len);
|
int dump(char *name,unsigned char *addr,int len);
|
||||||
int packetOk(int interface,unsigned char *packet,int len,unsigned char *transaction_id,
|
int packetOk(int interface,unsigned char *packet,int len,
|
||||||
|
unsigned char *transaction_id, int recvttl,
|
||||||
struct sockaddr *recvaddr,int recvaddrlen,int parseP);
|
struct sockaddr *recvaddr,int recvaddrlen,int parseP);
|
||||||
int process_packet(unsigned char *packet,int len,struct sockaddr *sender,int sender_len);
|
int process_packet(unsigned char *packet,int len,
|
||||||
|
int recvttl,struct sockaddr *sender,int sender_len);
|
||||||
int packetMakeHeader(unsigned char *packet,int packet_maxlen,int *packet_len,unsigned char *transaction_id,int cryptoflags);
|
int packetMakeHeader(unsigned char *packet,int packet_maxlen,int *packet_len,unsigned char *transaction_id,int cryptoflags);
|
||||||
int packetSetDid(unsigned char *packet,int packet_maxlen,int *packet_len,char *did);
|
int packetSetDid(unsigned char *packet,int packet_maxlen,int *packet_len,char *did);
|
||||||
int packetSetSid(unsigned char *packet,int packet_maxlen,int *packet_len,char *sid);
|
int packetSetSid(unsigned char *packet,int packet_maxlen,int *packet_len,char *sid);
|
||||||
int packetFinalise(unsigned char *packet,int packet_maxlen,int *packet_len,int cryptoflags);
|
int packetFinalise(unsigned char *packet,int packet_maxlen,int recvttl,
|
||||||
|
int *packet_len,int cryptoflags);
|
||||||
int packetAddHLRCreateRequest(unsigned char *packet,int packet_maxlen,int *packet_len);
|
int packetAddHLRCreateRequest(unsigned char *packet,int packet_maxlen,int *packet_len);
|
||||||
int extractResponses(struct in_addr sender,unsigned char *buffer,int len,struct response_set *responses);
|
int extractResponses(struct in_addr sender,unsigned char *buffer,int len,struct response_set *responses);
|
||||||
int packetAddVariableRequest(unsigned char *packet,int packet_maxlen,int *packet_len,
|
int packetAddVariableRequest(unsigned char *packet,int packet_maxlen,int *packet_len,
|
||||||
@ -345,11 +353,12 @@ int extractDid(unsigned char *packet,int *ofs,char *did);
|
|||||||
char *hlrSid(unsigned char *hlr,int ofs);
|
char *hlrSid(unsigned char *hlr,int ofs);
|
||||||
int parseAssignment(unsigned char *text,int *var_id,unsigned char *value,int *value_len);
|
int parseAssignment(unsigned char *text,int *var_id,unsigned char *value,int *value_len);
|
||||||
int writeItem(char *sid,int var_id,int instance,unsigned char *value,
|
int writeItem(char *sid,int var_id,int instance,unsigned char *value,
|
||||||
int value_start,int value_length,int flags, struct sockaddr *recvaddr);
|
int value_start,int value_length,int flags,
|
||||||
|
int recvttl,struct sockaddr *recvaddr);
|
||||||
int packetAddVariableWrite(unsigned char *packet,int packet_maxlen,int *packet_len,
|
int packetAddVariableWrite(unsigned char *packet,int packet_maxlen,int *packet_len,
|
||||||
int itemId,int instance,unsigned char *value,int start_offset,int value_len,int flags);
|
int itemId,int instance,unsigned char *value,int start_offset,int value_len,int flags);
|
||||||
int processRequest(unsigned char *packet,int len,struct sockaddr *sender,int sender_len,
|
int processRequest(unsigned char *packet,int len,struct sockaddr *sender,int sender_len,
|
||||||
unsigned char *transaction_id,char *did,char *sid);
|
unsigned char *transaction_id,int recvttl,char *did,char *sid);
|
||||||
|
|
||||||
int extractRequest(unsigned char *packet,int *packet_ofs,int packet_len,
|
int extractRequest(unsigned char *packet,int *packet_ofs,int packet_len,
|
||||||
int *itemId,int *instance,unsigned char *value,
|
int *itemId,int *instance,unsigned char *value,
|
||||||
@ -375,8 +384,9 @@ int openHlrFile(char *backing_file,int size);
|
|||||||
int runCommand(char *cmd);
|
int runCommand(char *cmd);
|
||||||
int asteriskObtainGateway(char *requestor_sid,char *did,char *uri_out);
|
int asteriskObtainGateway(char *requestor_sid,char *did,char *uri_out);
|
||||||
int packetOkDNA(unsigned char *packet,int len,unsigned char *transaction_id,
|
int packetOkDNA(unsigned char *packet,int len,unsigned char *transaction_id,
|
||||||
struct sockaddr *recvaddr,int recvaddrlen,int parseP);
|
int recvttl,struct sockaddr *recvaddr,int recvaddrlen,int parseP);
|
||||||
int packetOkOverlay(int interface,unsigned char *packet,int len,unsigned char *transaction_id,
|
int packetOkOverlay(int interface,unsigned char *packet,int len,
|
||||||
|
unsigned char *transaction_id,int recvttl,
|
||||||
struct sockaddr *recvaddr,int recvaddrlen,int parseP);
|
struct sockaddr *recvaddr,int recvaddrlen,int parseP);
|
||||||
int prepareGateway(char *gatewayspec);
|
int prepareGateway(char *gatewayspec);
|
||||||
int packetSendRequest(int method,unsigned char *packet,int packet_len,int batchP,
|
int packetSendRequest(int method,unsigned char *packet,int packet_len,int batchP,
|
||||||
|
@ -319,7 +319,10 @@ int overlay_rx_messages()
|
|||||||
bzero(&transaction_id[0],8);
|
bzero(&transaction_id[0],8);
|
||||||
bzero(&src_addr,sizeof(src_addr));
|
bzero(&src_addr,sizeof(src_addr));
|
||||||
if ((plen>=0)&&(packet[0]==0x01)&&!(packet[1]|packet[2]|packet[3])) {
|
if ((plen>=0)&&(packet[0]==0x01)&&!(packet[1]|packet[2]|packet[3])) {
|
||||||
{ if (packetOk(i,&packet[128],plen,transaction_id,&src_addr,addrlen,1)) WHY("Malformed or unsupported packet from dummy interface (packetOK() failed)"); } }
|
{ if (packetOk(i,&packet[128],plen,transaction_id,
|
||||||
|
-1 /* fake TTL */,
|
||||||
|
&src_addr,addrlen,1))
|
||||||
|
WHY("Malformed or unsupported packet from dummy interface (packetOK() failed)"); } }
|
||||||
else WHY("Invalid packet version in dummy interface");
|
else WHY("Invalid packet version in dummy interface");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -329,9 +332,9 @@ int overlay_rx_messages()
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Read from UDP socket */
|
/* Read from UDP socket */
|
||||||
plen=recvfrom(overlay_interfaces[i].fd,packet,sizeof(packet),
|
int recvttl=1;
|
||||||
MSG_DONTWAIT,
|
plen=recvwithttl(overlay_interfaces[i].fd,packet,sizeof(packet),
|
||||||
&src_addr,&addrlen);
|
&recvttl,&src_addr,&addrlen);
|
||||||
if (plen<0) {
|
if (plen<0) {
|
||||||
c[i]=0; count--;
|
c[i]=0; count--;
|
||||||
} else {
|
} else {
|
||||||
@ -341,7 +344,8 @@ int overlay_rx_messages()
|
|||||||
packet,plen);
|
packet,plen);
|
||||||
if (debug&DEBUG_OVERLAYINTERFACES)fprintf(stderr,"Received %d bytes on interface #%d (%s)\n",plen,i,overlay_interfaces[i].name);
|
if (debug&DEBUG_OVERLAYINTERFACES)fprintf(stderr,"Received %d bytes on interface #%d (%s)\n",plen,i,overlay_interfaces[i].name);
|
||||||
|
|
||||||
if (packetOk(i,packet,plen,NULL,&src_addr,addrlen,1)) WHY("Malformed packet");
|
if (packetOk(i,packet,plen,NULL,recvttl,&src_addr,addrlen,1))
|
||||||
|
WHY("Malformed packet");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,8 @@ struct sockaddr_in loopback = {
|
|||||||
.sin_addr.s_addr=0x0100007f
|
.sin_addr.s_addr=0x0100007f
|
||||||
};
|
};
|
||||||
|
|
||||||
int packetOkOverlay(int interface,unsigned char *packet,int len,unsigned char *transaction_id,
|
int packetOkOverlay(int interface,unsigned char *packet,int len,
|
||||||
|
unsigned char *transaction_id,int recvttl,
|
||||||
struct sockaddr *recvaddr,int recvaddrlen,int parseP)
|
struct sockaddr *recvaddr,int recvaddrlen,int parseP)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -19,7 +19,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
|
|
||||||
#include "mphlr.h"
|
#include "mphlr.h"
|
||||||
|
|
||||||
int process_packet(unsigned char *packet,int len,struct sockaddr *sender,int sender_len)
|
int process_packet(unsigned char *packet,int len,
|
||||||
|
int recvttl,struct sockaddr *sender,int sender_len)
|
||||||
{
|
{
|
||||||
int authenticatedP=0;
|
int authenticatedP=0;
|
||||||
char did[128];
|
char did[128];
|
||||||
@ -52,26 +53,29 @@ int process_packet(unsigned char *packet,int len,struct sockaddr *sender,int sen
|
|||||||
if (debug&DEBUG_SECURITY) fprintf(stderr,"No PIN was supplied.\n");
|
if (debug&DEBUG_SECURITY) fprintf(stderr,"No PIN was supplied.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serverMode) return processRequest(packet,len,sender,sender_len,transaction_id,did,sid);
|
if (serverMode) return processRequest(packet,len,sender,sender_len,transaction_id,
|
||||||
|
recvttl,did,sid);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int packetOk(int interface,unsigned char *packet,int len,unsigned char *transaction_id,
|
int packetOk(int interface,unsigned char *packet,int len,
|
||||||
|
unsigned char *transaction_id,int ttl,
|
||||||
struct sockaddr *recvaddr,int recvaddrlen,int parseP)
|
struct sockaddr *recvaddr,int recvaddrlen,int parseP)
|
||||||
{
|
{
|
||||||
if (len<HEADERFIELDS_LEN) return setReason("Packet is too short");
|
if (len<HEADERFIELDS_LEN) return setReason("Packet is too short");
|
||||||
|
|
||||||
if (packet[0]==0x41&&packet[1]==0x10)
|
if (packet[0]==0x41&&packet[1]==0x10)
|
||||||
{
|
{
|
||||||
return packetOkDNA(packet,len,transaction_id,recvaddr,recvaddrlen,parseP);
|
return packetOkDNA(packet,len,transaction_id,ttl,recvaddr,recvaddrlen,parseP);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet[0]==0x4F&&packet[1]==0x10)
|
if (packet[0]==0x4F&&packet[1]==0x10)
|
||||||
{
|
{
|
||||||
if (interface>-1)
|
if (interface>-1)
|
||||||
{
|
{
|
||||||
return packetOkOverlay(interface,packet,len,transaction_id,recvaddr,recvaddrlen,parseP);
|
return packetOkOverlay(interface,packet,len,transaction_id,ttl,
|
||||||
|
recvaddr,recvaddrlen,parseP);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* We ignore overlay mesh packets in simple server mode, which is indicated by interface==-1 */
|
/* We ignore overlay mesh packets in simple server mode, which is indicated by interface==-1 */
|
||||||
@ -82,6 +86,7 @@ int packetOk(int interface,unsigned char *packet,int len,unsigned char *transact
|
|||||||
}
|
}
|
||||||
|
|
||||||
int packetOkDNA(unsigned char *packet,int len,unsigned char *transaction_id,
|
int packetOkDNA(unsigned char *packet,int len,unsigned char *transaction_id,
|
||||||
|
int recvttl,
|
||||||
struct sockaddr *recvaddr,int recvaddrlen,int parseP)
|
struct sockaddr *recvaddr,int recvaddrlen,int parseP)
|
||||||
{
|
{
|
||||||
/* Make sure that the packet is meant for us, and is not mal-formed */
|
/* Make sure that the packet is meant for us, and is not mal-formed */
|
||||||
@ -123,7 +128,7 @@ int packetOkDNA(unsigned char *packet,int len,unsigned char *transaction_id,
|
|||||||
if (debug&DEBUG_PACKETFORMATS) fprintf(stderr,"Packet passes sanity checks and is ready for decoding.\n");
|
if (debug&DEBUG_PACKETFORMATS) fprintf(stderr,"Packet passes sanity checks and is ready for decoding.\n");
|
||||||
if (debug&DEBUG_PACKETFORMATS) dump("unrotated packet",packet,len);
|
if (debug&DEBUG_PACKETFORMATS) dump("unrotated packet",packet,len);
|
||||||
|
|
||||||
if (parseP) return process_packet(packet,len,recvaddr,recvaddrlen); else return 0;
|
if (parseP) return process_packet(packet,len,recvttl,recvaddr,recvaddrlen); else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int packetMakeHeader(unsigned char *packet,int packet_maxlen,int *packet_len,
|
int packetMakeHeader(unsigned char *packet,int packet_maxlen,int *packet_len,
|
||||||
@ -201,7 +206,8 @@ int packetSetSid(unsigned char *packet,int packet_maxlen,int *packet_len,char *s
|
|||||||
return stowSid(packet,ofs,sid);
|
return stowSid(packet,ofs,sid);
|
||||||
}
|
}
|
||||||
|
|
||||||
int packetFinalise(unsigned char *packet,int packet_maxlen,int *packet_len,int cryptoflags)
|
int packetFinalise(unsigned char *packet,int packet_maxlen,int recvttl,
|
||||||
|
int *packet_len,int cryptoflags)
|
||||||
{
|
{
|
||||||
/* Add any padding bytes and EOT to packet */
|
/* Add any padding bytes and EOT to packet */
|
||||||
int paddingBytes=rand()&0xf;
|
int paddingBytes=rand()&0xf;
|
||||||
@ -215,6 +221,15 @@ int packetFinalise(unsigned char *packet,int packet_maxlen,int *packet_len,int c
|
|||||||
while(paddingBytes--) packet[(*packet_len)++]=random()&0xff;
|
while(paddingBytes--) packet[(*packet_len)++]=random()&0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* tell requester what the ttl was when we received the packet */
|
||||||
|
if (recvttl>-1) {
|
||||||
|
CHECK_PACKET_LEN(2);
|
||||||
|
packet[(*packet_len)++]=ACTION_RECVTTL;
|
||||||
|
packet[(*packet_len)++]=recvttl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mark end of packet */
|
||||||
|
CHECK_PACKET_LEN(1);
|
||||||
packet[(*packet_len)++]=ACTION_EOT;
|
packet[(*packet_len)++]=ACTION_EOT;
|
||||||
|
|
||||||
/* Set payload length */
|
/* Set payload length */
|
||||||
@ -390,6 +405,8 @@ int extractResponses(struct in_addr sender,unsigned char *buffer,int len,struct
|
|||||||
{
|
{
|
||||||
int ofs=OFS_PAYLOAD;
|
int ofs=OFS_PAYLOAD;
|
||||||
|
|
||||||
|
struct response *first_response=NULL;
|
||||||
|
|
||||||
while(ofs<len)
|
while(ofs<len)
|
||||||
{
|
{
|
||||||
/* XXX should allocate responses from a temporary and bounded slab of memory */
|
/* XXX should allocate responses from a temporary and bounded slab of memory */
|
||||||
@ -433,6 +450,18 @@ int extractResponses(struct in_addr sender,unsigned char *buffer,int len,struct
|
|||||||
unpackageVariableSegment(&buffer[ofs+1],len-ofs,WITHOUTDATA,r);
|
unpackageVariableSegment(&buffer[ofs+1],len-ofs,WITHOUTDATA,r);
|
||||||
r->response=NULL;
|
r->response=NULL;
|
||||||
break;
|
break;
|
||||||
|
case ACTION_RECVTTL:
|
||||||
|
r->recvttl=buffer[ofs+1];
|
||||||
|
r->response_len=1;
|
||||||
|
/* Attach TTL to other responses from this packet */
|
||||||
|
{
|
||||||
|
struct response *rr=first_response;
|
||||||
|
while(rr) {
|
||||||
|
rr->recvttl=r->recvttl;
|
||||||
|
rr=rr->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ACTION_SET:
|
case ACTION_SET:
|
||||||
case ACTION_DEL:
|
case ACTION_DEL:
|
||||||
case ACTION_XFER:
|
case ACTION_XFER:
|
||||||
@ -472,6 +501,8 @@ int extractResponses(struct in_addr sender,unsigned char *buffer,int len,struct
|
|||||||
responses->last_response=r;
|
responses->last_response=r;
|
||||||
responses->response_count++;
|
responses->response_count++;
|
||||||
|
|
||||||
|
if (!first_response) first_response=r;
|
||||||
|
|
||||||
responseFromPeer(responses,r->peer_id);
|
responseFromPeer(responses,r->peer_id);
|
||||||
|
|
||||||
if (debug&DEBUG_DNARESPONSES) dumpResponses(responses);
|
if (debug&DEBUG_DNARESPONSES) dumpResponses(responses);
|
||||||
|
122
server.c
122
server.c
@ -17,6 +17,9 @@ along with this program; if not, write to the Free Software
|
|||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#include "mphlr.h"
|
#include "mphlr.h"
|
||||||
|
|
||||||
unsigned char *hlr=NULL;
|
unsigned char *hlr=NULL;
|
||||||
@ -31,6 +34,57 @@ int getBackingStore(char *s,int size);
|
|||||||
int createServerSocket();
|
int createServerSocket();
|
||||||
int simpleServerMode();
|
int simpleServerMode();
|
||||||
|
|
||||||
|
int recvwithttl(int sock,unsigned char *buffer,int bufferlen,int *ttl,
|
||||||
|
struct sockaddr *recvaddr,unsigned int *recvaddrlen)
|
||||||
|
{
|
||||||
|
struct msghdr msg;
|
||||||
|
struct iovec iov[1];
|
||||||
|
|
||||||
|
iov[0].iov_base=buffer;
|
||||||
|
iov[0].iov_len=bufferlen;
|
||||||
|
bzero(&msg,sizeof(msg));
|
||||||
|
msg.msg_name = recvaddr;
|
||||||
|
msg.msg_namelen = *recvaddrlen;
|
||||||
|
msg.msg_iov = &iov[0];
|
||||||
|
msg.msg_iovlen = 1;
|
||||||
|
// setting the following makes the data end up in the wrong place
|
||||||
|
// msg.msg_iov->iov_base=iov_buffer;
|
||||||
|
// msg.msg_iov->iov_len=sizeof(iov_buffer);
|
||||||
|
|
||||||
|
struct cmsghdr cmsgcmsg[16];
|
||||||
|
msg.msg_control = &cmsgcmsg[0];
|
||||||
|
msg.msg_controllen = sizeof(struct cmsghdr)*16;
|
||||||
|
msg.msg_flags = 0;
|
||||||
|
|
||||||
|
fcntl(sock,F_SETFL, O_NONBLOCK);
|
||||||
|
|
||||||
|
int len = recvmsg(sock,&msg,0);
|
||||||
|
|
||||||
|
fprintf(stderr,"recvmsg returned %d bytes (flags=%d,msg_controllen=%d)\n",
|
||||||
|
len,msg.msg_flags,msg.msg_controllen);
|
||||||
|
|
||||||
|
if (len>0) {
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
for (cmsg = CMSG_FIRSTHDR(&msg);
|
||||||
|
cmsg != NULL;
|
||||||
|
cmsg = CMSG_NXTHDR(&msg,cmsg)) {
|
||||||
|
|
||||||
|
if ((cmsg->cmsg_level == IPPROTO_IP) && (cmsg->cmsg_type == IP_RECVTTL) &&
|
||||||
|
(cmsg->cmsg_len) ){
|
||||||
|
fprintf(stderr," TTL (%p) data location resolves to %p\n",
|
||||||
|
ttl,CMSG_DATA(cmsg));
|
||||||
|
if (CMSG_DATA(cmsg)) {
|
||||||
|
*ttl = *(unsigned char *) CMSG_DATA(cmsg);
|
||||||
|
fprintf(stderr," TTL of packet is %d\n",*ttl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*recvaddrlen=msg.msg_namelen;
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int server(char *backing_file,int size,int foregroundMode)
|
int server(char *backing_file,int size,int foregroundMode)
|
||||||
{
|
{
|
||||||
@ -119,7 +173,7 @@ int getBackingStore(char *backing_file,int size)
|
|||||||
|
|
||||||
int processRequest(unsigned char *packet,int len,
|
int processRequest(unsigned char *packet,int len,
|
||||||
struct sockaddr *sender,int sender_len,
|
struct sockaddr *sender,int sender_len,
|
||||||
unsigned char *transaction_id,char *did,char *sid)
|
unsigned char *transaction_id,int recvttl, char *did,char *sid)
|
||||||
{
|
{
|
||||||
/* Find HLR entry by DID or SID, unless creating */
|
/* Find HLR entry by DID or SID, unless creating */
|
||||||
int ofs,rofs=0;
|
int ofs,rofs=0;
|
||||||
@ -140,17 +194,19 @@ int processRequest(unsigned char *packet,int len,
|
|||||||
/* Creating an HLR requires an initial DID number and definately no SID -
|
/* Creating an HLR requires an initial DID number and definately no SID -
|
||||||
you can't choose a SID. */
|
you can't choose a SID. */
|
||||||
if (debug&DEBUG_HLR) fprintf(stderr,"Creating a new HLR record. did='%s', sid='%s'\n",did,sid);
|
if (debug&DEBUG_HLR) fprintf(stderr,"Creating a new HLR record. did='%s', sid='%s'\n",did,sid);
|
||||||
if (!did[0]) return respondSimple(NULL,ACTION_DECLINED,NULL,0,transaction_id,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
if (!did[0]) return respondSimple(NULL,ACTION_DECLINED,NULL,0,transaction_id,recvttl,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||||
if (sid[0]) return respondSimple(sid,ACTION_DECLINED,NULL,0,transaction_id,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
if (sid[0]) return respondSimple(sid,ACTION_DECLINED,NULL,0,transaction_id,recvttl,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||||
if (debug&DEBUG_HLR) fprintf(stderr,"Verified that create request supplies DID but not SID\n");
|
if (debug&DEBUG_HLR) fprintf(stderr,"Verified that create request supplies DID but not SID\n");
|
||||||
|
|
||||||
{
|
{
|
||||||
char sid[128];
|
char sid[128];
|
||||||
/* make HLR with new random SID and initial DID */
|
/* make HLR with new random SID and initial DID */
|
||||||
if (!createHlr(did,sid))
|
if (!createHlr(did,sid))
|
||||||
return respondSimple(sid,ACTION_OKAY,NULL,0,transaction_id,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
return respondSimple(sid,ACTION_OKAY,NULL,0,transaction_id,
|
||||||
|
recvttl,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||||
else
|
else
|
||||||
return respondSimple(NULL,ACTION_DECLINED,NULL,0,transaction_id,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
return respondSimple(NULL,ACTION_DECLINED,NULL,0,transaction_id,
|
||||||
|
recvttl,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||||
}
|
}
|
||||||
pofs+=1;
|
pofs+=1;
|
||||||
pofs+=1+SID_SIZE;
|
pofs+=1+SID_SIZE;
|
||||||
@ -214,7 +270,8 @@ int processRequest(unsigned char *packet,int len,
|
|||||||
sprintf(amCommand, "am broadcast -a org.servalproject.DT -e number \"%s\" -e content \"%s\"", emitterPhoneNumber, message);
|
sprintf(amCommand, "am broadcast -a org.servalproject.DT -e number \"%s\" -e content \"%s\"", emitterPhoneNumber, message);
|
||||||
if (debug&DEBUG_DNAREQUESTS) fprintf(stderr,"Delivering DT message via intent: %s\n",amCommand);
|
if (debug&DEBUG_DNAREQUESTS) fprintf(stderr,"Delivering DT message via intent: %s\n",amCommand);
|
||||||
runCommand(amCommand);
|
runCommand(amCommand);
|
||||||
respondSimple(hlrSid(hlr, ofs),ACTION_OKAY,NULL,0,transaction_id,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
respondSimple(hlrSid(hlr, ofs),ACTION_OKAY,NULL,0,transaction_id,
|
||||||
|
recvttl,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -224,7 +281,9 @@ int processRequest(unsigned char *packet,int len,
|
|||||||
|
|
||||||
if ((!sid)||(!sid[0])) {
|
if ((!sid)||(!sid[0])) {
|
||||||
setReason("You can only set variables by SID");
|
setReason("You can only set variables by SID");
|
||||||
return respondSimple(NULL,ACTION_ERROR,(unsigned char *)"SET requires authentication by SID",0,transaction_id,
|
return respondSimple(NULL,ACTION_ERROR,
|
||||||
|
(unsigned char *)"SET requires authentication by SID",
|
||||||
|
0,transaction_id,recvttl,
|
||||||
sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,7 +310,9 @@ int processRequest(unsigned char *packet,int len,
|
|||||||
{
|
{
|
||||||
setReason("Could not extract ACTION_SET request");
|
setReason("Could not extract ACTION_SET request");
|
||||||
return
|
return
|
||||||
respondSimple(NULL,ACTION_ERROR,(unsigned char *)"Mal-formed SET request",0,transaction_id,
|
respondSimple(NULL,ACTION_ERROR,
|
||||||
|
(unsigned char *)"Mal-formed SET request",
|
||||||
|
0,transaction_id,recvttl,
|
||||||
sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,7 +327,7 @@ int processRequest(unsigned char *packet,int len,
|
|||||||
return
|
return
|
||||||
respondSimple(NULL,ACTION_ERROR,
|
respondSimple(NULL,ACTION_ERROR,
|
||||||
(unsigned char *)"Cannot SET NOCREATE/REPLACE a value that does not exist",
|
(unsigned char *)"Cannot SET NOCREATE/REPLACE a value that does not exist",
|
||||||
0,transaction_id,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
0,transaction_id,recvttl,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (flags==SET_NOREPLACE) {
|
if (flags==SET_NOREPLACE) {
|
||||||
@ -275,7 +336,7 @@ int processRequest(unsigned char *packet,int len,
|
|||||||
return
|
return
|
||||||
respondSimple(NULL,ACTION_ERROR,
|
respondSimple(NULL,ACTION_ERROR,
|
||||||
(unsigned char *)"Cannot SET NOREPLACE; a value exists",
|
(unsigned char *)"Cannot SET NOREPLACE; a value exists",
|
||||||
0,transaction_id,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
0,transaction_id,recvttl,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Replace the changed portion of the stored value */
|
/* Replace the changed portion of the stored value */
|
||||||
@ -290,14 +351,17 @@ int processRequest(unsigned char *packet,int len,
|
|||||||
{
|
{
|
||||||
setReason("Failed to write variable");
|
setReason("Failed to write variable");
|
||||||
return
|
return
|
||||||
respondSimple(NULL,ACTION_ERROR,(unsigned char *)"Failed to SET variable",0,transaction_id,
|
respondSimple(NULL,ACTION_ERROR,
|
||||||
|
(unsigned char *)"Failed to SET variable",
|
||||||
|
0,transaction_id,recvttl,
|
||||||
sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||||
}
|
}
|
||||||
if (debug&DEBUG_HLR) { fprintf(stderr,"HLR after writing:\n"); hlrDump(hlr,ofs); }
|
if (debug&DEBUG_HLR) { fprintf(stderr,"HLR after writing:\n"); hlrDump(hlr,ofs); }
|
||||||
|
|
||||||
/* Reply that we wrote the fragment */
|
/* Reply that we wrote the fragment */
|
||||||
respondSimple(sid,ACTION_WROTE,&packet[rofs],6,
|
respondSimple(sid,ACTION_WROTE,&packet[rofs],6,
|
||||||
transaction_id,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
transaction_id,recvttl,
|
||||||
|
sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||||
/* Advance to next record and keep searching */
|
/* Advance to next record and keep searching */
|
||||||
if (nextHlr(hlr,&ofs)) break;
|
if (nextHlr(hlr,&ofs)) break;
|
||||||
}
|
}
|
||||||
@ -361,7 +425,8 @@ int processRequest(unsigned char *packet,int len,
|
|||||||
|
|
||||||
// only send each value when the *next* record is found, that way we can easily stamp the last response with DONE
|
// only send each value when the *next* record is found, that way we can easily stamp the last response with DONE
|
||||||
if (sendDone>0)
|
if (sendDone>0)
|
||||||
respondSimple(hlr_sid,ACTION_DATA,data,dlen,transaction_id,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
respondSimple(hlr_sid,ACTION_DATA,data,dlen,
|
||||||
|
transaction_id,recvttl,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||||
|
|
||||||
dlen=0;
|
dlen=0;
|
||||||
|
|
||||||
@ -388,7 +453,8 @@ int processRequest(unsigned char *packet,int len,
|
|||||||
{
|
{
|
||||||
data[dlen++]=ACTION_DONE;
|
data[dlen++]=ACTION_DONE;
|
||||||
data[dlen++]=sendDone&0xff;
|
data[dlen++]=sendDone&0xff;
|
||||||
respondSimple(hlr_sid,ACTION_DATA,data,dlen,transaction_id,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
respondSimple(hlr_sid,ACTION_DATA,data,dlen,transaction_id,
|
||||||
|
recvttl,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||||
}
|
}
|
||||||
if (gatewayspec&&(var_id==VAR_LOCATIONS)&&did&&strlen(did))
|
if (gatewayspec&&(var_id==VAR_LOCATIONS)&&did&&strlen(did))
|
||||||
{
|
{
|
||||||
@ -413,7 +479,9 @@ int processRequest(unsigned char *packet,int len,
|
|||||||
if (packageVariableSegment(data,&dlen,&fake,offset,MAX_DATA_BYTES+16))
|
if (packageVariableSegment(data,&dlen,&fake,offset,MAX_DATA_BYTES+16))
|
||||||
return setReason("packageVariableSegment() of gateway URI failed.");
|
return setReason("packageVariableSegment() of gateway URI failed.");
|
||||||
|
|
||||||
respondSimple(hlrSid(hlr,0),ACTION_DATA,data,dlen,transaction_id,sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
respondSimple(hlrSid(hlr,0),ACTION_DATA,data,dlen,
|
||||||
|
transaction_id,recvttl,sender,
|
||||||
|
CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -438,7 +506,8 @@ int processRequest(unsigned char *packet,int len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int respondSimple(char *sid,int action,unsigned char *action_text,int action_len,
|
int respondSimple(char *sid,int action,unsigned char *action_text,int action_len,
|
||||||
unsigned char *transaction_id,struct sockaddr *recvaddr,int cryptoFlags)
|
unsigned char *transaction_id,int recvttl,
|
||||||
|
struct sockaddr *recvaddr,int cryptoFlags)
|
||||||
{
|
{
|
||||||
unsigned char packet[8000];
|
unsigned char packet[8000];
|
||||||
int pl=0;
|
int pl=0;
|
||||||
@ -478,7 +547,7 @@ int respondSimple(char *sid,int action,unsigned char *action_text,int action_len
|
|||||||
|
|
||||||
if (debug&DEBUG_DNARESPONSES) dump("Simple response octets",action_text,action_len);
|
if (debug&DEBUG_DNARESPONSES) dump("Simple response octets",action_text,action_len);
|
||||||
|
|
||||||
if (packetFinalise(packet,8000,packet_len,cryptoFlags))
|
if (packetFinalise(packet,8000,recvttl,packet_len,cryptoFlags))
|
||||||
return WHY("packetFinalise() failed.");
|
return WHY("packetFinalise() failed.");
|
||||||
|
|
||||||
if (debug&DEBUG_DNARESPONSES) fprintf(stderr,"Sending response of %d bytes.\n",*packet_len);
|
if (debug&DEBUG_DNARESPONSES) fprintf(stderr,"Sending response of %d bytes.\n",*packet_len);
|
||||||
@ -502,7 +571,14 @@ int createServerSocket()
|
|||||||
|
|
||||||
int TRUE=1;
|
int TRUE=1;
|
||||||
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &TRUE, sizeof(TRUE));
|
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &TRUE, sizeof(TRUE));
|
||||||
|
|
||||||
|
errno=0;
|
||||||
|
if(setsockopt(sock, IPPROTO_IP, IP_RECVDSTADDR, &TRUE,sizeof(TRUE))<0)
|
||||||
|
perror("setsockopt(IP_RECVDSTADDR)");
|
||||||
|
errno=0;
|
||||||
|
if(setsockopt(sock, IPPROTO_IP, IP_RECVTTL, &TRUE,sizeof(TRUE))<0)
|
||||||
|
perror("setsockopt(IP_RECVTTL)");
|
||||||
|
|
||||||
bind_addr.sin_family = AF_INET;
|
bind_addr.sin_family = AF_INET;
|
||||||
bind_addr.sin_port = htons( PORT_DNA );
|
bind_addr.sin_port = htons( PORT_DNA );
|
||||||
bind_addr.sin_addr.s_addr = htonl( INADDR_ANY );
|
bind_addr.sin_addr.s_addr = htonl( INADDR_ANY );
|
||||||
@ -519,7 +595,6 @@ extern int rhizome_server_socket;
|
|||||||
int simpleServerMode()
|
int simpleServerMode()
|
||||||
{
|
{
|
||||||
while(1) {
|
while(1) {
|
||||||
unsigned char buffer[16384];
|
|
||||||
struct sockaddr recvaddr;
|
struct sockaddr recvaddr;
|
||||||
socklen_t recvaddrlen=sizeof(recvaddr);
|
socklen_t recvaddrlen=sizeof(recvaddr);
|
||||||
struct pollfd fds[128];
|
struct pollfd fds[128];
|
||||||
@ -552,9 +627,14 @@ int simpleServerMode()
|
|||||||
}
|
}
|
||||||
if (rhizome_datastore_path) rhizome_server_poll();
|
if (rhizome_datastore_path) rhizome_server_poll();
|
||||||
|
|
||||||
|
unsigned char buffer[16384];
|
||||||
|
int ttl=-1; // unknown
|
||||||
|
|
||||||
if (fds[0].revents&POLLIN) {
|
if (fds[0].revents&POLLIN) {
|
||||||
len=recvfrom(sock,buffer,sizeof(buffer),0,&recvaddr,&recvaddrlen);
|
|
||||||
|
|
||||||
|
len=recvwithttl(sock,buffer,sizeof(buffer),&ttl,&recvaddr,&recvaddrlen);
|
||||||
|
|
||||||
|
|
||||||
client_port=((struct sockaddr_in*)&recvaddr)->sin_port;
|
client_port=((struct sockaddr_in*)&recvaddr)->sin_port;
|
||||||
client_addr=((struct sockaddr_in*)&recvaddr)->sin_addr;
|
client_addr=((struct sockaddr_in*)&recvaddr)->sin_addr;
|
||||||
|
|
||||||
@ -566,7 +646,7 @@ int simpleServerMode()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Simple server mode doesn't really use interface numbers, so lie and say interface -1 */
|
/* Simple server mode doesn't really use interface numbers, so lie and say interface -1 */
|
||||||
if (packetOk(-1,buffer,len,NULL,&recvaddr,recvaddrlen,1)) {
|
if (packetOk(-1,buffer,len,NULL,ttl,&recvaddr,recvaddrlen,1)) {
|
||||||
if (debug&DEBUG_PACKETFORMATS) setReason("Ignoring invalid packet");
|
if (debug&DEBUG_PACKETFORMATS) setReason("Ignoring invalid packet");
|
||||||
}
|
}
|
||||||
if (debug&DEBUG_PACKETXFER) fprintf(stderr,"Finished processing packet, waiting for next one.\n");
|
if (debug&DEBUG_PACKETXFER) fprintf(stderr,"Finished processing packet, waiting for next one.\n");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user