diff --git a/client.c b/client.c index bd7255ca..5172174e 100644 --- a/client.c +++ b/client.c @@ -345,7 +345,7 @@ int getReplyPackets(int method,int peer,int batchP,struct response_set *response if (debug) fprintf(stderr,"Simulation mode: Dropped packet due to simulated link parameters.\n"); continue; } - if (!packetOk(buffer,len,transaction_id,recvaddr,recvaddrlen,0)) { + if (!packetOk(-1,buffer,len,transaction_id,recvaddr,recvaddrlen,0)) { /* Packet passes tests - extract responses and append them to the end of the response list */ if (extractResponses(client_addr,buffer,len,responses)) return setReason("Problem extracting response fields from reply packets"); diff --git a/mphlr.h b/mphlr.h index 32a69dcd..2deb60be 100644 --- a/mphlr.h +++ b/mphlr.h @@ -296,7 +296,7 @@ int server(char *backing_file,int size,int foregroundMode); int setReason(char *fmt, ...); int hexvalue(unsigned char c); int dump(char *name,unsigned char *addr,int len); -int packetOk(unsigned char *packet,int len,unsigned char *transaction_id, +int packetOk(int interface,unsigned char *packet,int len,unsigned char *transaction_id, struct sockaddr *recvaddr,int recvaddrlen,int parseP); int process_packet(unsigned char *packet,int len,struct sockaddr *sender,int sender_len); int packetMakeHeader(unsigned char *packet,int packet_maxlen,int *packet_len,unsigned char *transaction_id); @@ -365,7 +365,7 @@ int runCommand(char *cmd); int asteriskObtainGateway(char *requestor_sid,char *did,char *uri_out); int packetOkDNA(unsigned char *packet,int len,unsigned char *transaction_id, struct sockaddr *recvaddr,int recvaddrlen,int parseP); -int packetOkOverlay(unsigned char *packet,int len,unsigned char *transaction_id, +int packetOkOverlay(int interface,unsigned char *packet,int len,unsigned char *transaction_id, struct sockaddr *recvaddr,int recvaddrlen,int parseP); int prepareGateway(char *gatewayspec); int packetSendRequest(int method,unsigned char *packet,int packet_len,int batchP, @@ -434,6 +434,14 @@ typedef struct overlay_interface { #define OVERLAY_MAX_INTERFACES 16 extern overlay_interface overlay_interfaces[OVERLAY_MAX_INTERFACES]; +/* Has someone sent us an abbreviation of an unknown type recently? If so remind them + that we don't accept these. + XXX - This method assumes bidirectional links. We should consider sending direct + to the perpetuator. We will deal with that in time, the main thing is that we have + a message type that can be used for the purpose. +*/ +extern int overlay_interface_repeat_abbreviation_policy[OVERLAY_MAX_INTERFACES]; + /* For each peer we need to keep track of the routes that we know to reach it. @@ -603,7 +611,7 @@ extern int overlay_interface_count; Limited to 255 bytes of payload. 1 byte channel/port indicator for each end */ #define OF_TYPE_RHIZOME_ADVERT 0x50 /* Advertisment of file availability via Rhizome */ -#define OF_TYPE_RESERVED_06 0x60 +#define OF_TYPE_PLEASEEXPLAIN 0x60 /* Request for resolution of an abbreviated address */ #define OF_TYPE_RESERVED_07 0x70 #define OF_TYPE_RESERVED_08 0x80 #define OF_TYPE_RESERVED_09 0x90 @@ -645,11 +653,12 @@ int overlay_address_cache_address(unsigned char *sid); int overlay_abbreviate_cache_lookup(unsigned char *in,unsigned char *out,int *ofs, int prefix_bytes,int index_bytes); int overlay_abbreviate_remember_index(int index_byte_count,unsigned char *in,unsigned char *index_bytes); +extern int overlay_abbreviate_repeat_policy; /* Return codes for resolution of abbreviated addressses */ #define OA_UNINITIALISED 0 /* Nothing has been written into the field */ #define OA_RESOLVED 1 /* We expanded the abbreviation successfully */ -#define OA_PLEASEEXPLAIN 1 /* We need the sender to explain their abbreviation */ +#define OA_PLEASEEXPLAIN 2 /* We need the sender to explain their abbreviation */ #define OA_UNSUPPORTED 3 /* We cannot expand the abbreviation as we do not understand this code */ /* Codes used to describe abbreviated addresses. @@ -696,3 +705,5 @@ typedef struct overlay_frame { int rfs; /* remainder of frame size */ } overlay_frame; + +int overlay_frame_process(int interface,overlay_frame *f); diff --git a/overlay.c b/overlay.c index fe06d258..650747b8 100644 --- a/overlay.c +++ b/overlay.c @@ -107,7 +107,58 @@ int overlayServerMode() return 0; } -int overlay_frame_process(overlay_frame *f) +int overlay_frame_process(int interface,overlay_frame *f) { + if (!f) return WHY("f==NULL"); + + /* First order of business is whether the nexthop address has been resolved. + If not, we need to think about asking for it to be resolved. + The trouble is that we do not want to trigger a Hanson Event (a storm of + please explains/resolution requests). Yet, we do not want to delay + communications unnecessarily. + + The simple solution for now is to queue the address for resolution request + in our next tick. If we see another resolution request for the same + address in the mean time, then we can cancel our request */ + switch (f->nexthop_address_status) + { + case OA_UNINITIALISED: + /* Um? Right. */ + return WHY("frame passed with ununitialised nexthop address"); + break; + case OA_RESOLVED: + /* Great, we have the address, so we can get on with things */ + break; + case OA_PLEASEEXPLAIN: + break; + case OA_UNSUPPORTED: + default: + /* If we don't support the address format, we should probably tell + the sender. Again, we queue this up, and cancel it if someone else + tells them in the meantime to avoid an Opposition Event (like a Hanson + Event, but repeatedly berating any node that holds a different policy + to itself. */ + overlay_interface_repeat_abbreviation_policy[interface]=1; + return -1; + break; + } + + /* Okay, nexthop is valid, so let's see if it is us */ + int forMe=0,i; + for(i=0;i<SID_SIZE;i++) if (f->nexthop[i]!=0xff) break; + if (i==SID_SIZE) forMe=1; + for(i=0;i<SID_SIZE;i++) if (f->nexthop[i]!=hlr[4+i]) break; + if (i==SID_SIZE) forMe=1; + + fprintf(stderr,"This frame is%s for me.\n",forMe?"":" not"); + + switch(f->type) + { + case OF_TYPE_SELFANNOUNCE: + break; + default: + break; + } + return WHY("Not implemented"); } diff --git a/overlay_abbreviations.c b/overlay_abbreviations.c index fd5bd4bc..a446b9fa 100644 --- a/overlay_abbreviations.c +++ b/overlay_abbreviations.c @@ -294,7 +294,7 @@ int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char case OA_CODE_BROADCAST: /* broadcast */ memset(&out[*ofs],0xff,SID_SIZE); (*inofs)++; - return 0; + return OA_RESOLVED; case OA_CODE_FULL_INDEX1: case OA_CODE_FULL_INDEX2: default: /* Full address, optionally followed by index for us to remember */ if (in[0]==OA_CODE_FULL_INDEX1) bytes=1; @@ -302,7 +302,7 @@ int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char bcopy(in,&out[*ofs],SID_SIZE); if (bytes) overlay_abbreviate_remember_index(bytes,in,&in[SID_SIZE]); (*inofs)+=SID_SIZE+bytes; - return 0; + return OA_RESOLVED; } } diff --git a/overlay_interface.c b/overlay_interface.c index 71f209d6..f2f97bb8 100644 --- a/overlay_interface.c +++ b/overlay_interface.c @@ -19,6 +19,9 @@ struct interface_rules { struct interface_rules *interface_filter=NULL; +/* Do we need to repeat our abbreviation policy? */ +int overlay_interface_repeat_abbreviation_policy[OVERLAY_MAX_INTERFACES]={1}; + int overlay_interface_type(char *s) { if (!strcasecmp(s,"ethernet")) return OVERLAY_INTERFACE_ETHERNET; @@ -249,7 +252,7 @@ int overlay_rx_messages() bzero(&transaction_id[0],8); bzero(&src_addr,sizeof(src_addr)); if ((packet[0]==0x01)&&!(packet[1]|packet[2]|packet[3])) - { if (!packetOk(&packet[128],plen,transaction_id,&src_addr,addrlen,1)) WHY("Malformed packet from dummy interface"); } + { if (!packetOk(i,&packet[128],plen,transaction_id,&src_addr,addrlen,1)) WHY("Malformed packet from dummy interface"); } else WHY("Invalid packet version in dummy interface"); } else { c[i]=0; count--; } @@ -262,7 +265,7 @@ int overlay_rx_messages() if (debug&4)fprintf(stderr,"Received %d bytes on interface #%d\n",plen,i); bzero(&transaction_id[0],8); - if (!packetOk(packet,plen,transaction_id,&src_addr,addrlen,1)) WHY("Malformed packet"); + if (!packetOk(i,packet,plen,transaction_id,&src_addr,addrlen,1)) WHY("Malformed packet"); } } } diff --git a/overlay_packetformats.c b/overlay_packetformats.c index 6a3487af..fda6255e 100644 --- a/overlay_packetformats.c +++ b/overlay_packetformats.c @@ -1,7 +1,7 @@ #include "mphlr.h" -int packetOkOverlay(unsigned char *packet,int len,unsigned char *transaction_id, +int packetOkOverlay(int interface,unsigned char *packet,int len,unsigned char *transaction_id, struct sockaddr *recvaddr,int recvaddrlen,int parseP) { /* @@ -97,7 +97,6 @@ int packetOkOverlay(unsigned char *packet,int len,unsigned char *transaction_id, f.modifiers=0; ofs+=2; break; - case OF_TYPE_RESERVED_06: case OF_TYPE_RESERVED_07: case OF_TYPE_RESERVED_08: case OF_TYPE_RESERVED_09: @@ -110,6 +109,7 @@ int packetOkOverlay(unsigned char *packet,int len,unsigned char *transaction_id, case OF_TYPE_DATA: case OF_TYPE_DATA_VOICE: case OF_TYPE_RHIZOME_ADVERT: + case OF_TYPE_PLEASEEXPLAIN: /* No extra bytes to deal with here */ ofs++; break; @@ -136,11 +136,11 @@ int packetOkOverlay(unsigned char *packet,int len,unsigned char *transaction_id, f.bytecount=f.rfs-(offset-ofs); /* Finally process the frame */ - overlay_frame_process(&f); + overlay_frame_process(interface,&f); /* Skip the rest of the bytes in this frame so that we can examine the next one in this ensemble */ - fprintf(stderr,"ofs=%d, f.rfs=%d, len=%d\n",ofs,f.rfs,len); + if (debug&4) fprintf(stderr,"ofs=%d, f.rfs=%d, len=%d\n",ofs,f.rfs,len); ofs+=f.rfs; } diff --git a/packetformats.c b/packetformats.c index 84ed76b8..a3ba7700 100644 --- a/packetformats.c +++ b/packetformats.c @@ -57,7 +57,7 @@ int process_packet(unsigned char *packet,int len,struct sockaddr *sender,int sen return 0; } -int packetOk(unsigned char *packet,int len,unsigned char *transaction_id, +int packetOk(int interface,unsigned char *packet,int len,unsigned char *transaction_id, struct sockaddr *recvaddr,int recvaddrlen,int parseP) { if (len<HEADERFIELDS_LEN) return setReason("Packet is too short"); @@ -66,7 +66,13 @@ int packetOk(unsigned char *packet,int len,unsigned char *transaction_id, return packetOkDNA(packet,len,transaction_id,recvaddr,recvaddrlen,parseP); if (packet[0]==0x4F&&packet[1]==0x10) - return packetOkOverlay(packet,len,transaction_id,recvaddr,recvaddrlen,parseP); + { + if (interface>-1) + return packetOkOverlay(interface,packet,len,transaction_id,recvaddr,recvaddrlen,parseP); + else + /* We ignore overlay mesh packets in simple server mode, which is indicated by interface==-1 */ + return -1; + } return setReason("Packet type not recognised."); } diff --git a/server.c b/server.c index 631ee3b8..ff605c28 100644 --- a/server.c +++ b/server.c @@ -530,7 +530,8 @@ int simpleServerMode() if (debug) fprintf(stderr,"Simulation mode: Dropped packet due to simulated link parameters.\n"); continue; } - if (packetOk(buffer,len,NULL,&recvaddr,recvaddrlen,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 (debug) setReason("Ignoring invalid packet"); } if (debug>1) fprintf(stderr,"Finished processing packet, waiting for next one.\n");