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:
gardners 2012-02-05 16:15:19 +10:30
parent 8a24fb95b1
commit 5cc6079c0f
7 changed files with 196 additions and 65 deletions

View File

@ -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
View File

@ -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
View File

@ -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,

View File

@ -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");
} }
} }
} }

View File

@ -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)
{ {
/* /*

View File

@ -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
View File

@ -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");