mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-18 02:39:44 +00:00
Overlay mode with address summarisation closer to working.
Self-announcements now abbreviate addresses, and in theory they get expanded on reception -- but more testing and coding required.
This commit is contained in:
parent
f8064a1795
commit
229850c8d7
102
mphlr.h
102
mphlr.h
@ -405,6 +405,8 @@ typedef struct overlay_interface {
|
||||
int tick_ms;
|
||||
/* The time of the last tick on this interface in milli seconds */
|
||||
long long last_tick_ms;
|
||||
/* How many times have we abbreviated our address since we last announced it in full? */
|
||||
int ticks_since_sent_full_address;
|
||||
|
||||
/* Sequence number of last tick. Sent with announcments to help keep track of the reliability of
|
||||
getting traffic to/from us. */
|
||||
@ -589,8 +591,52 @@ int overlay_get_nexthop(overlay_payload *p,unsigned char *nexthop,int *nexthople
|
||||
|
||||
extern int overlay_interface_count;
|
||||
|
||||
/* Userland overlay mesh packet codes */
|
||||
#define OF_SELFANNOUNCE 0x01
|
||||
/* Overlay mesh packet codes */
|
||||
#define OF_TYPE_BITS 0xf0
|
||||
#define OF_TYPE_SELFANNOUNCE 0x10 /* BATMAN style announcement frames */
|
||||
#define OF_TYPE_SELFANNOUNCE_ACK 0x20 /* BATMAN style "I saw your announcment" frames */
|
||||
#define OF_TYPE_DATA 0x30 /* Ordinary data frame.
|
||||
Upto MTU bytes of payload.
|
||||
16 bit channel/port indicator for each end.
|
||||
*/
|
||||
#define OF_TYPE_DATA_VOICE 0x40 /* Voice data frame.
|
||||
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_RESERVED_07 0x70
|
||||
#define OF_TYPE_RESERVED_08 0x80
|
||||
#define OF_TYPE_RESERVED_09 0x90
|
||||
#define OF_TYPE_RESERVED_0a 0xa0
|
||||
#define OF_TYPE_RESERVED_0b 0xb0
|
||||
#define OF_TYPE_RESERVED_0c 0xc0
|
||||
#define OF_TYPE_RESERVED_0d 0xd0
|
||||
#define OF_TYPE_EXTENDED12 0xe0 /* modifier bits and next byte provide 12 bits extended format
|
||||
(for future expansion, just allows us to skip the frame) */
|
||||
#define OF_TYPE_EXTENDED20 0xf0 /* modifier bits and next 2 bytes provide 20 bits extended format
|
||||
(for future expansion, just allows us to skip the frame) */
|
||||
/* Flags used to control the interpretation of the resolved type field */
|
||||
#define OF_TYPE_FLAG_BITS 0xf0000000
|
||||
#define OF_TYPE_FLAG_NORMAL 0x0
|
||||
#define OF_TYPE_FLAG_E12 0x10000000
|
||||
#define OF_TYPE_FLAG_E20 0x00000000
|
||||
|
||||
/* Modifiers that indicate the disposition of the frame */
|
||||
#define OF_MODIFIER_BITS 0x0f
|
||||
|
||||
/* Crypto/security options */
|
||||
#define OF_CRYPTO_BITS 0x0c
|
||||
#define OF_CRYPTO_NONE 0x00
|
||||
#define OF_CRYPTO_CIPHERED 0x04 /* Encrypted frame */
|
||||
#define OF_CRYPTO_SIGNED 0x08 /* Encrypted and Digitally signed frame */
|
||||
#define OF_CRYPTO_PARANOID 0x0c /* Encrypted and digitally signed frame, with final destination address also encrypted. */
|
||||
|
||||
/* Data compression */
|
||||
#define OF_COMPRESS_BITS 0x03
|
||||
#define OF_COMPRESS_NONE 0x00
|
||||
#define OF_COMPRESS_GZIP 0x01 /* Frame compressed with gzip */
|
||||
#define OF_COMPRESS_BZIP2 0x02 /* bzip2 */
|
||||
#define OF_COMPRESS_RESERVED 0x03 /* Reserved for another compression system */
|
||||
|
||||
#define OVERLAY_ADDRESS_CACHE_SIZE 1024
|
||||
int overlay_abbreviate_address(unsigned char *in,char *out,int *ofs);
|
||||
@ -600,7 +646,53 @@ int overlay_abbreviate_cache_lookup(unsigned char *in,unsigned char *out,int *of
|
||||
int prefix_bytes,int index_bytes);
|
||||
int overlay_abbreviate_remember_index(int index_byte_count,unsigned char *in,unsigned char *index_bytes);
|
||||
|
||||
|
||||
#define OA_RESOLVED 0 /* We expanded the abbreviation */
|
||||
/* 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_UNSUPPORTED 2 /* We cannot expand the abbreviation as we do not understand this code */
|
||||
#define OA_UNSUPPORTED 3 /* We cannot expand the abbreviation as we do not understand this code */
|
||||
|
||||
/* Codes used to describe abbreviated addresses.
|
||||
Values 0x10 - 0xff are the first byte of, and implicit indicators of addresses written in full */
|
||||
#define OA_CODE_00 0x00
|
||||
#define OA_CODE_INDEX 0x01
|
||||
#define OA_CODE_02 0x02
|
||||
#define OA_CODE_PREVIOUS 0x03
|
||||
#define OA_CODE_04 0x04
|
||||
#define OA_CODE_PREFIX3 0x05
|
||||
#define OA_CODE_PREFIX7 0x06
|
||||
#define OA_CODE_PREFIX11 0x07
|
||||
#define OA_CODE_FULL_INDEX1 0x08
|
||||
#define OA_CODE_PREFIX3_INDEX1 0x09
|
||||
#define OA_CODE_PREFIX7_INDEX1 0x0a
|
||||
#define OA_CODE_PREFIX11_INDEX1 0x0b
|
||||
#define OA_CODE_0C 0x0c
|
||||
#define OA_CODE_PREFIX11_INDEX2 0x0d
|
||||
#define OA_CODE_FULL_INDEX2 0x0e
|
||||
/* The TTL field in a frame is used to differentiate between link-local and wide-area broadcasts */
|
||||
#define OA_CODE_BROADCAST 0x0f
|
||||
|
||||
typedef struct overlay_frame {
|
||||
unsigned int type;
|
||||
unsigned int modifiers;
|
||||
|
||||
unsigned char nexthop[32];
|
||||
int nexthop_address_status;
|
||||
|
||||
unsigned char destination[32];
|
||||
int destination_address_status;
|
||||
|
||||
unsigned char source[32];
|
||||
int source_address_status;
|
||||
|
||||
/* Frame content from destination address onwards */
|
||||
unsigned int bytecount;
|
||||
unsigned char *bytes;
|
||||
|
||||
/* Actual payload */
|
||||
unsigned int payloadlength;
|
||||
unsigned char *payload;
|
||||
|
||||
int rfs; /* remainder of frame size */
|
||||
|
||||
} overlay_frame;
|
||||
|
@ -103,4 +103,11 @@ int overlayServerMode()
|
||||
/* Check if we need to trigger any ticks on any interfaces */
|
||||
overlay_check_ticks();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_frame_process(overlay_frame *f)
|
||||
{
|
||||
return WHY("Not implemented");
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
0x0c = reserved.
|
||||
0x0d = same as 0x07, but assign two byte index.
|
||||
0x0e = full address followed by two-byte index allocation.
|
||||
0x0f = broadcast.
|
||||
0x0f = broadcast link-local.
|
||||
|
||||
However, in this implementation we not include support for the two-byte
|
||||
index code, as it requires 64Kx32=2MB storage, which is too much to ask
|
||||
@ -69,6 +69,10 @@
|
||||
no more than 33 bytes. In any case, indicating the crypto system is not the problem of
|
||||
this section, as we are just concerned with abbreviating and expanding the addresses.
|
||||
|
||||
(A simple solution to the multiple crypto-system problem is to have the receiver try each
|
||||
known crypto system when decoding a frame, and remember which addresses use which system.
|
||||
Probably a reasonable solution for now.)
|
||||
|
||||
To decode abbreviations supplied by other nodes we need to try to replicate a copy of
|
||||
their abbreviation table. This is where things get memory intensive (about 8KB per node).
|
||||
However, we only need the table of one-hop neighbours, and it is reasonable to have a
|
||||
@ -260,40 +264,41 @@ int overlay_abbreviate_expand_address(unsigned char *in,int *inofs,unsigned char
|
||||
int bytes=0;
|
||||
switch(in[0])
|
||||
{
|
||||
case 0x00: case 0x02: case 0x04: case 0x0c:
|
||||
case OA_CODE_00: case OA_CODE_02: case OA_CODE_04: case OA_CODE_0C:
|
||||
/* Unsupported codes, so tell the sender
|
||||
if the frame was addressed to us as next-hop */
|
||||
(*inofs)++;
|
||||
return OA_UNSUPPORTED;
|
||||
case 0x01: /* single byte index look up */
|
||||
case OA_CODE_INDEX: /* single byte index look up */
|
||||
exit(WHY("Unimplemented address abbreviation code"));
|
||||
break;
|
||||
case 0x03: /* Same as last address */
|
||||
case OA_CODE_PREVIOUS: /* Same as last address */
|
||||
(*inofs)++;
|
||||
bcopy(&overlay_abbreviate_previous_address.b[0],&out[*ofs],SID_SIZE);
|
||||
(*ofs)+=SID_SIZE;
|
||||
return OA_RESOLVED;
|
||||
break;
|
||||
case 0x05: case 0x09: /* 3-byte prefix */
|
||||
case OA_CODE_PREFIX3: case OA_CODE_PREFIX3_INDEX1: /* 3-byte prefix */
|
||||
if (in[0]==0x09) bytes=1;
|
||||
(*inofs)+=3+bytes;
|
||||
return overlay_abbreviate_cache_lookup(in,out,ofs,3,bytes);
|
||||
case 0x06: case 0x0a: /* 7-byte prefix */
|
||||
if (in[0]==0x0a) bytes=1;
|
||||
case OA_CODE_PREFIX7: case OA_CODE_PREFIX7_INDEX1: /* 7-byte prefix */
|
||||
if (in[0]==OA_CODE_PREFIX7_INDEX1) bytes=1;
|
||||
(*inofs)+=7+bytes;
|
||||
return overlay_abbreviate_cache_lookup(in,out,ofs,7,bytes);
|
||||
case 0x07: case 0x0b: case 0x0d: /* 11-byte prefix */
|
||||
if (in[0]==0x0b) bytes=1;
|
||||
if (in[0]==0x0d) bytes=2;
|
||||
case OA_CODE_PREFIX11: case OA_CODE_PREFIX11_INDEX1: case OA_CODE_PREFIX11_INDEX2: /* 11-byte prefix */
|
||||
if (in[0]==OA_CODE_PREFIX11_INDEX1) bytes=1;
|
||||
if (in[0]==OA_CODE_PREFIX11_INDEX2) bytes=2;
|
||||
(*inofs)+=11+bytes;
|
||||
return overlay_abbreviate_cache_lookup(in,out,ofs,11,bytes);
|
||||
case 0x0f: /* broadcast */
|
||||
case OA_CODE_BROADCAST: /* broadcast */
|
||||
memset(&out[*ofs],0xff,SID_SIZE);
|
||||
(*inofs)++;
|
||||
return 0;
|
||||
case 0x08: case 0x0e: default: /* Full address, optionally followed by index for us to remember */
|
||||
if (in[0]==0x08) bytes=1;
|
||||
if (in[0]==0x0e) bytes=2;
|
||||
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;
|
||||
if (in[0]==OA_CODE_FULL_INDEX2) bytes=2;
|
||||
bcopy(in,&out[*ofs],SID_SIZE);
|
||||
if (bytes) overlay_abbreviate_remember_index(bytes,in,&in[SID_SIZE]);
|
||||
(*inofs)+=SID_SIZE+bytes;
|
||||
|
237
overlay_packetformats.c
Normal file
237
overlay_packetformats.c
Normal file
@ -0,0 +1,237 @@
|
||||
#include "mphlr.h"
|
||||
|
||||
|
||||
int packetOkOverlay(unsigned char *packet,int len,unsigned char *transaction_id,
|
||||
struct sockaddr *recvaddr,int recvaddrlen,int parseP)
|
||||
{
|
||||
/*
|
||||
Overlay packets are ensembles contain one or more frames each of which
|
||||
should be handled separately.
|
||||
|
||||
There are two main types of enclosed frame.
|
||||
|
||||
1. Announcement frames which contain information that helps to maintain the
|
||||
operation of the mesh.
|
||||
|
||||
and
|
||||
|
||||
2. Data frames that contain messages directed to nodes on the mesh.
|
||||
|
||||
In both instances we allow the contained addresses to be shortened to save bandwidth,
|
||||
especially for low-bandwidth links.
|
||||
|
||||
All frames have the following fields:
|
||||
|
||||
Frame type (8bits)
|
||||
Remaining frame size (RFS) (8bits for <256 bytes, 16bits for <510 bytes etc)
|
||||
Next hop (variable length due to address abbreviation)
|
||||
Destination (variable length due to address abbreviation)*
|
||||
Source (variable length due to address abbreviation)*
|
||||
Payload (length = RFS- len(frame type) - len(next hop)*
|
||||
|
||||
This structure is intended to allow relaying nodes to quickly ignore frames that are
|
||||
not addressed to them as either the next hop or final destination.
|
||||
|
||||
The RFS field uses additional bytes to encode the length of longer frames.
|
||||
This provides us with a slight space saving for the common case of short frames.
|
||||
|
||||
* Indicates fields that may be encrypted. The source and destination addresses can
|
||||
be encrypted for paranoid traffic so that only the hops along the route know who is
|
||||
talking to whom. This is not totally secure, but does prevent collateral eaves dropping
|
||||
of frames by 4th parties. Paranoid communities could elect to only use nodes they trust
|
||||
to carry the frame. And finally, the frame payload itself can be enciphered with the
|
||||
final destination's public key, so that it is not possible even for the relaying 3rd
|
||||
parties to observe the content.
|
||||
|
||||
Naturally some information will leak simply based on the size, periodicity and other
|
||||
characteristics of the traffic, and some 3rd parties may be malevolent, so noone should
|
||||
assume that this provides complete security.
|
||||
|
||||
Paranoid mode introduces a bandwidth cost of one signature, and a potentially substantial
|
||||
energy cost of requiring every node along the delivery path to decrypt and reencrypt the
|
||||
frame.
|
||||
|
||||
It would also be possible to design a super-paranoid mode where source routing is used with
|
||||
concentric shells of encryption so that each hop can only work out the next hop to send it
|
||||
to. However, that would result in rather large frames, and require an on-demand routing
|
||||
approach which may well betray more information than the super-paranoid mode would hide.
|
||||
|
||||
Note also that it is possible to dispatch frames on a local link which are addressed to
|
||||
broadcast, but are enciphered. In that situation only the intended recipient can
|
||||
decode the frame, but at the cost of having all nodes on the local link having to decrypt
|
||||
frame. Of course the nodes may elect to not decrypt such anonymous frames.
|
||||
|
||||
Such frames could even be flooded throughout part of the mesh by having the TTL>1, and
|
||||
optionally with an anonymous source address to provide some plausible deniability for both
|
||||
sending and reception if combined with a randomly selected TTL to give the impression of
|
||||
the source having received the frame from elsewhere.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
int ofs;
|
||||
overlay_frame f;
|
||||
|
||||
for(ofs=0;ofs<len;)
|
||||
{
|
||||
/* Clear out the data structure ready for next frame */
|
||||
f.nexthop_address_status=OA_UNINITIALISED;
|
||||
f.destination_address_status=OA_UNINITIALISED;
|
||||
f.source_address_status=OA_UNINITIALISED;
|
||||
|
||||
/* Get normal form of packet type and modifiers */
|
||||
f.type=packet[ofs]&OF_TYPE_BITS;
|
||||
f.modifiers=packet[ofs]&OF_MODIFIER_BITS;
|
||||
|
||||
switch(packet[ofs]&OF_TYPE_BITS)
|
||||
{
|
||||
case OF_TYPE_EXTENDED20:
|
||||
/* Eat the next two bytes and then skip over this reserved frame type */
|
||||
f.type=OF_TYPE_FLAG_E20|(packet[ofs]&OF_MODIFIER_BITS)|(packet[ofs+2]<<12)|(packet[ofs+1]<<4);
|
||||
f.modifiers=0;
|
||||
ofs+=3;
|
||||
break;
|
||||
case OF_TYPE_EXTENDED12:
|
||||
/* Eat the next byte and then skip over this reserved frame type */
|
||||
f.type=OF_TYPE_FLAG_E12|(packet[ofs]&OF_MODIFIER_BITS)|(packet[ofs+1]<<4);
|
||||
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:
|
||||
case OF_TYPE_RESERVED_0a:
|
||||
case OF_TYPE_RESERVED_0b:
|
||||
case OF_TYPE_RESERVED_0c:
|
||||
case OF_TYPE_RESERVED_0d:
|
||||
case OF_TYPE_SELFANNOUNCE:
|
||||
case OF_TYPE_SELFANNOUNCE_ACK:
|
||||
case OF_TYPE_DATA:
|
||||
case OF_TYPE_DATA_VOICE:
|
||||
case OF_TYPE_RHIZOME_ADVERT:
|
||||
/* No extra bytes to deal with here */
|
||||
ofs++;
|
||||
break;
|
||||
}
|
||||
/* Get length of remainder of frame */
|
||||
f.rfs=packet[ofs];
|
||||
while (packet[ofs]==0xff&&(ofs<len)&&(f.rfs<16384)) f.rfs+=packet[++ofs];
|
||||
|
||||
if (!f.rfs) {
|
||||
/* Zero length -- assume we fell off the end of the packet */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Now extract the next hop address */
|
||||
int alen=0;
|
||||
int offset=ofs;
|
||||
f.nexthop_address_status=overlay_abbreviate_expand_address(packet,&offset,f.nexthop,&alen);
|
||||
|
||||
/* Now just make the rest of the frame available via the received frame structure, as the
|
||||
frame may not be for us, so there is no point wasting time and energy if we don't have
|
||||
to.
|
||||
*/
|
||||
f.bytes=&packet[ofs];
|
||||
f.bytecount=f.rfs-(offset-ofs);
|
||||
|
||||
/* Finally process the frame */
|
||||
overlay_frame_process(&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);
|
||||
ofs+=f.rfs;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_add_selfannouncement(int interface,overlay_buffer *b)
|
||||
{
|
||||
/* Pull the first record from the HLR database and turn it into a
|
||||
self-announcment. These are shorter than regular Subscriber Observation
|
||||
Notices (SON) because they are just single-hop announcments of presence.
|
||||
|
||||
Do we really need to push the whole SID (32 bytes), or will just, say,
|
||||
8 do so that we use a prefix of the SID which is still very hard to forge?
|
||||
|
||||
A hearer of a self-announcement who has not previously seen the sender might
|
||||
like to get some authentication to prevent naughty people from spoofing routes.
|
||||
|
||||
We can do this by having ourselves, the sender, keep track of the last few frames
|
||||
we have sent, so that we can be asked to sign them. Actually, we won't sign them,
|
||||
as that is too slow/energy intensive, but we could use a D-H exchange with the neighbour,
|
||||
performed once to get a shared secret that can be used to feed a stream cipher to
|
||||
produce some sort of verification.
|
||||
|
||||
XXX - But this functionality really needs to move up a level to whole frame composition.
|
||||
*/
|
||||
|
||||
unsigned char c;
|
||||
int zero=0;
|
||||
|
||||
/* Make sure we can find our SID */
|
||||
if (!findHlr(hlr,&zero,NULL,NULL)) return WHY("Could not find first entry in HLR");
|
||||
|
||||
/* Header byte */
|
||||
c=OF_TYPE_SELFANNOUNCE;
|
||||
if (ob_append_bytes(b,&c,1))
|
||||
return WHY("ob_append_bytes() could not add self-announcement header");
|
||||
|
||||
int send_prefix=(overlay_interfaces[interface].ticks_since_sent_full_address<4);
|
||||
|
||||
/* Add space for Remaining Frame Size field. This will always be a single byte
|
||||
for self-announcments as they are always <256 bytes. */
|
||||
c=1+1+(send_prefix?(1+7):SID_SIZE)+4+1;
|
||||
if (ob_append_bytes(b,&c,1))
|
||||
return WHY("ob_append_bytes() could not add RFS for self-announcement frame");
|
||||
|
||||
/* Add next-hop address. Always link-local broadcast for self-announcements */
|
||||
c=OA_CODE_BROADCAST;
|
||||
if (ob_append_bytes(b,&c,1))
|
||||
return WHY("ob_append_bytes() could not add self-announcement header");
|
||||
|
||||
/* Add final destination. Always broadcast for self-announcments.
|
||||
As we have just referenced the broadcast address, we can encode it in a single byte */
|
||||
c=OA_CODE_PREVIOUS;
|
||||
if (ob_append_bytes(b,&c,1))
|
||||
return WHY("ob_append_bytes() could not add self-announcement header");
|
||||
|
||||
/* Add our SID to the announcement as sender
|
||||
We can likely get away with abbreviating our own address much of the time, since these
|
||||
frames will be sent on a regular basis. However, we can only abbreviate using a prefix,
|
||||
not any of the fancier methods. Indeed, if we tried to use the standard abbreviation
|
||||
functions they would notice that we are attaching an address which is ourself, and send
|
||||
a uselessly short address. So instead we will use a simple scheme where we will send our
|
||||
address in full an arbitrary 1 in 4 times.
|
||||
*/
|
||||
if (overlay_interfaces[interface].ticks_since_sent_full_address>3)
|
||||
{ if (ob_append_bytes(b,&hlr[zero+4],SID_SIZE)) return WHY("Could not append SID to self-announcement");
|
||||
overlay_interfaces[interface].ticks_since_sent_full_address=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
c=OA_CODE_PREFIX7;
|
||||
if (ob_append_bytes(b,&c,1)) return WHY("ob_append_bytes() could not add address format code.");
|
||||
if (ob_append_bytes(b,&hlr[zero+4],7)) return WHY("Could not append SID prefix to self-announcement");
|
||||
overlay_interfaces[interface].ticks_since_sent_full_address++;
|
||||
}
|
||||
|
||||
/* A sequence number, so that others can keep track of their reception of our frames.
|
||||
These are per-interface */
|
||||
if (ob_append_int(b,overlay_interfaces[interface].sequence_number))
|
||||
return WHY("ob_append_int() could not add sequence number to self-announcement");
|
||||
|
||||
/* A TTL for this frame?
|
||||
XXX - BATMAN uses various TTLs, but I think that it may just be better to have all TTL=1,
|
||||
and have the onward nodes selectively choose which nodes to on-announce. If we prioritise
|
||||
newly arrived nodes somewhat (or at least reserve some slots for them), then we can still
|
||||
get the good news travels fast property of BATMAN, but without having to flood in the formal
|
||||
sense. */
|
||||
c=1;
|
||||
if (ob_append_bytes(b,&c,1))
|
||||
return WHY("ob_append_bytes() could not add TTL to self-announcement");
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,57 +1,5 @@
|
||||
#include "mphlr.h"
|
||||
|
||||
int overlay_add_selfannouncement(int interface,overlay_buffer *b)
|
||||
{
|
||||
/* Pull the first record from the HLR database and turn it into a
|
||||
self-announcment. These are shorter than regular Subscriber Observation
|
||||
Notices (SON) because they are just single-hop announcments of presence.
|
||||
|
||||
Do we really need to push the whole SID (32 bytes), or will just, say,
|
||||
8 do so that we use a prefix of the SID which is still very hard to forge?
|
||||
|
||||
A hearer of a self-announcement who has not previously seen the sender might
|
||||
like to get some authentication to prevent naughty people from spoofing routes.
|
||||
|
||||
We can do this by having ourselves, the sender, keep track of the last few frames
|
||||
we have sent, so that we can be asked to sign them. Actually, we won't sign them,
|
||||
as that is too slow/energy intensive, but we could use a D-H exchange with the neighbour,
|
||||
performed once to get a shared secret that can be used to feed a stream cipher to
|
||||
produce some sort of verification.
|
||||
|
||||
XXX - But this functionality really needs to move up a level to whole frame composition.
|
||||
*/
|
||||
|
||||
unsigned char c;
|
||||
int zero=0;
|
||||
|
||||
/* Make sure we can find our SID */
|
||||
if (!findHlr(hlr,&zero,NULL,NULL)) return WHY("Could not find first entry in HLR");
|
||||
|
||||
/* Header byte */
|
||||
c=OF_SELFANNOUNCE;
|
||||
if (ob_append_bytes(b,&c,1))
|
||||
return WHY("ob_append_bytes() could not add self-announcement header");
|
||||
|
||||
/* Add our SID to the announcement */
|
||||
if (ob_append_bytes(b,&hlr[zero+4],SID_SIZE)) return WHY("Could not append SID to self-announcement");
|
||||
|
||||
/* A sequence number, so that others can keep track of their reception of our frames.
|
||||
These are per-interface */
|
||||
if (ob_append_int(b,overlay_interfaces[interface].sequence_number))
|
||||
return WHY("ob_append_int() could not add sequence number to self-announcement");
|
||||
|
||||
/* A TTL for this frame?
|
||||
XXX - BATMAN uses various TTLs, but I think that it may just be better to have all TTL=1,
|
||||
and have the onward nodes selectively choose which nodes to on-announce. If we prioritise
|
||||
newly arrived nodes somewhat (or at least reserve some slots for them), then we can still
|
||||
get the good news travels fast property of BATMAN, but without having to flood in the formal
|
||||
sense. */
|
||||
c=1;
|
||||
if (ob_append_bytes(b,&c,1))
|
||||
return WHY("ob_append_bytes() could not add TTL to self-announcement");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int overlay_get_nexthop(overlay_payload *p,unsigned char *nexthop,int *nexthoplen)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user