mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-21 01:42:18 +00:00
Rework broadcast address handling, working towards a unified address struct
This commit is contained in:
parent
aa5706f9d7
commit
22c6b530ed
@ -43,6 +43,7 @@ SERVALD_SRC_FILES = \
|
||||
serval-dna/simulate.c \
|
||||
serval-dna/srandomdev.c \
|
||||
serval-dna/str.c \
|
||||
serval-dna/subscribers.c \
|
||||
serval-dna/keyring.c \
|
||||
serval-dna/vomp.c \
|
||||
serval-dna/lsif.c \
|
||||
|
@ -218,8 +218,9 @@ int overlay_frame_process(struct overlay_interface *interface,overlay_frame *f)
|
||||
|
||||
// only examine payloads that are broadcasts, or where I'm the next hop
|
||||
if (overlay_address_is_broadcast(f->nexthop)) {
|
||||
// Note we can only check for dropping once per payload, as a second test would return true.
|
||||
if (overlay_broadcast_drop_check(f->nexthop)){
|
||||
if (debug&DEBUG_OVERLAYFRAMES)
|
||||
if (debug&(DEBUG_OVERLAYFRAMES|DEBUG_BROADCASTS))
|
||||
DEBUGF("Dropping frame, duplicate broadcast %s", alloca_tohex_sid(f->nexthop));
|
||||
RETURN(0);
|
||||
}
|
||||
|
@ -27,11 +27,21 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#include "serval.h"
|
||||
|
||||
#define BROADCAST_LEN 8
|
||||
|
||||
struct broadcast{
|
||||
unsigned char id[BROADCAST_LEN];
|
||||
};
|
||||
|
||||
#define MAX_BPIS 1024
|
||||
#define BPI_MASK 0x3ff
|
||||
struct broadcast bpilist[MAX_BPIS];
|
||||
|
||||
/* Determine if an address is broadcast */
|
||||
int overlay_address_is_broadcast(unsigned char *a)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<(SID_SIZE-8);i++)
|
||||
for(i=0;i<(SID_SIZE - BROADCAST_LEN);i++)
|
||||
if (a[i]!=0xff) return 0;
|
||||
return 1;
|
||||
}
|
||||
@ -39,15 +49,11 @@ int overlay_address_is_broadcast(unsigned char *a)
|
||||
int overlay_broadcast_generate_address(unsigned char *a)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<(SID_SIZE-8);i++) a[i]=0xff;
|
||||
for(i=0;i<(SID_SIZE - BROADCAST_LEN);i++) a[i]=0xff;
|
||||
for(;i<SID_SIZE;i++) a[i]=random()&0xff;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_BPIS 1024
|
||||
#define BPI_MASK 0x3ff
|
||||
unsigned char bpilist[MAX_BPIS][8];
|
||||
|
||||
int overlay_broadcast_drop_check(unsigned char *a)
|
||||
{
|
||||
/* Don't drop frames to non-broadcast addresses */
|
||||
@ -60,31 +66,21 @@ int overlay_broadcast_drop_check(unsigned char *a)
|
||||
robustness it is however required. */
|
||||
int bpi_index=0;
|
||||
int i;
|
||||
for(i=0;i<8;i++)
|
||||
for(i=0;i<BROADCAST_LEN;i++)
|
||||
{
|
||||
bpi_index=((bpi_index<<3)&0xfff8)+((bpi_index>>13)&0x7);
|
||||
bpi_index^=a[24+i];
|
||||
bpi_index^=a[SID_SIZE - BROADCAST_LEN + i];
|
||||
}
|
||||
bpi_index&=BPI_MASK;
|
||||
if (debug&DEBUG_BROADCASTS)
|
||||
DEBUGF("BPI %02X%02X%02X%02X%02X%02X%02X%02X resolves to hash bin %d",
|
||||
a[24],a[25],a[26],a[27],a[28],a[29],a[30],a[31],bpi_index);
|
||||
|
||||
int bpiNew=0;
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
if (a[24+i]!=bpilist[bpi_index][i]) bpiNew=1;
|
||||
bpilist[bpi_index][i]=a[24+i];
|
||||
}
|
||||
|
||||
if (bpiNew)
|
||||
{
|
||||
if (debug&DEBUG_BROADCASTS) DEBUGF(" BPI is new, so don't drop frame");
|
||||
return 0; /* don't drop */
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug&DEBUG_BROADCASTS) DEBUGF(" BPI is already in our list, so drop the frame to prevent broadcast storms");
|
||||
return 1; /* drop frame because we have seen this BPI recently */
|
||||
}
|
||||
if (memcmp(bpilist[bpi_index].id, a + SID_SIZE - BROADCAST_LEN, BROADCAST_LEN)){
|
||||
if (debug&DEBUG_BROADCASTS)
|
||||
DEBUGF("BPI %s is new", alloca_tohex(a + SID_SIZE - BROADCAST_LEN, BROADCAST_LEN));
|
||||
bcopy(a + SID_SIZE - BROADCAST_LEN, bpilist[bpi_index].id, BROADCAST_LEN);
|
||||
return 0; /* don't drop */
|
||||
}else{
|
||||
if (debug&DEBUG_BROADCASTS)
|
||||
DEBUGF("BPI %s is a duplicate", alloca_tohex(a + SID_SIZE - BROADCAST_LEN, BROADCAST_LEN));
|
||||
return 1; /* drop frame because we have seen this BPI recently */
|
||||
}
|
||||
}
|
||||
|
@ -972,19 +972,16 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim
|
||||
// TODO stop when the packet is nearly full?
|
||||
|
||||
while(frame){
|
||||
int drop =0;
|
||||
frame->isBroadcast = overlay_address_is_broadcast(frame->destination);
|
||||
|
||||
if (frame->enqueued_at + queue->latencyTarget < now)
|
||||
drop=1;
|
||||
else if(frame->isBroadcast)
|
||||
drop=overlay_broadcast_drop_check(frame->destination);
|
||||
|
||||
if (drop){
|
||||
if (frame->enqueued_at + queue->latencyTarget < now){
|
||||
DEBUG("Dropping frame due to expiry timeout");
|
||||
frame = overlay_queue_remove(queue, frame);
|
||||
continue;
|
||||
}
|
||||
/* Note, once we queue a broadcast packet we are committed to sending it out every interface,
|
||||
even if we hear it from somewhere else in the mean time
|
||||
*/
|
||||
|
||||
if (overlay_resolve_next_hop(frame))
|
||||
goto skip;
|
||||
|
@ -147,7 +147,6 @@ int packetOkOverlay(struct overlay_interface *interface,unsigned char *packet, s
|
||||
break;
|
||||
}
|
||||
|
||||
int payloadStart = ofs;
|
||||
int nextPayload = ofs+f.rfs;
|
||||
|
||||
if (nextPayload > len){
|
||||
|
@ -66,7 +66,6 @@ int overlay_frame_package_fmt1(overlay_frame *p,overlay_buffer *b)
|
||||
Will pick a next hop if one has not been chosen.
|
||||
*/
|
||||
|
||||
int i;
|
||||
overlay_buffer *headers;
|
||||
|
||||
headers=ob_new(256);
|
||||
@ -80,33 +79,6 @@ int overlay_frame_package_fmt1(overlay_frame *p,overlay_buffer *b)
|
||||
|
||||
/* Build header */
|
||||
|
||||
if (p->nexthop_address_status!=OA_RESOLVED) {
|
||||
if (0) WHYF("next hop is NOT resolved for packet to %s",
|
||||
alloca_tohex_sid(p->destination));
|
||||
if (overlay_address_is_broadcast(p->destination)) {
|
||||
/* Broadcast frames are broadcast rather than unicast to next hop.
|
||||
Just check if the broadcast frame should be dropped first. */
|
||||
if (overlay_broadcast_drop_check(p->destination)){
|
||||
WHY("This broadcast packet ID has been seen recently");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Copy the broadcast address exactly so that we preserve the BPI */
|
||||
for(i=0;i<SID_SIZE;i++) p->nexthop[i]=p->destination[i];
|
||||
p->nexthop_address_status=OA_RESOLVED;
|
||||
} else {
|
||||
if (overlay_get_nexthop((unsigned char *)p->destination,p->nexthop,&p->nexthop_interface)) {
|
||||
WHY("could not determine next hop address for payload");
|
||||
goto cleanup;
|
||||
}
|
||||
else p->nexthop_address_status=OA_RESOLVED;
|
||||
}
|
||||
} else {
|
||||
if (0) WHYF("next hop IS resolved for packet to %s",
|
||||
alloca_tohex_sid(p->destination));
|
||||
}
|
||||
|
||||
|
||||
if (p->source[0]<0x10) {
|
||||
// Make sure that addresses do not overload the special address spaces of 0x00*-0x0f*
|
||||
WHY("packet source address begins with reserved value 0x00-0x0f");
|
||||
@ -318,6 +290,9 @@ overlay_frame *op_dup(overlay_frame *in)
|
||||
int overlay_frame_set_broadcast_as_destination(overlay_frame *f)
|
||||
{
|
||||
overlay_broadcast_generate_address(f->destination);
|
||||
// remember the broadcast address we are about to send so we don't sent the packet twice
|
||||
overlay_broadcast_drop_check(f->destination);
|
||||
f->isBroadcast=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -203,13 +203,8 @@ int overlay_get_nexthop(unsigned char *d,unsigned char *nexthop,int *interface)
|
||||
DEBUGF("No open path to %s, invalid sid",alloca_tohex_sid(d));
|
||||
return -1;
|
||||
}
|
||||
// Note, broadcast address handling is already done by this point
|
||||
|
||||
if (overlay_broadcast_drop_check(d)) return WHY("I have sent that broadcast frame before");
|
||||
if (overlay_address_is_broadcast(d)) {
|
||||
bcopy(&d[0],&nexthop[0],SID_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
overlay_node *n=overlay_route_find_node(d,SID_SIZE,0 /* don't create if missing */ );
|
||||
if (!n){
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
@ -353,12 +348,8 @@ int overlay_route_ack_selfannounce(overlay_frame *f,
|
||||
out->nexthop_address_status=OA_UNINITIALISED;
|
||||
if (overlay_resolve_next_hop(out)) {
|
||||
/* no open path, so convert to broadcast */
|
||||
int i;
|
||||
for(i=0;i<(SID_SIZE-8);i++) out->nexthop[i]=0xff;
|
||||
for(i=(SID_SIZE-8);i<SID_SIZE;i++) out->nexthop[i]=random()&0xff;
|
||||
out->nexthop_address_status=OA_RESOLVED;
|
||||
overlay_frame_set_broadcast_as_destination(out);
|
||||
out->ttl=2;
|
||||
out->isBroadcast=1;
|
||||
if (debug&DEBUG_OVERLAYROUTING)
|
||||
DEBUG("Broadcasting ack to selfannounce for hithero unroutable node");
|
||||
} else
|
||||
|
1
serval.h
1
serval.h
@ -723,7 +723,6 @@ unsigned int overlay_route_hash_sid(const unsigned char *sid);
|
||||
unsigned char *overlay_get_my_sid();
|
||||
int overlay_frame_set_me_as_source(overlay_frame *f);
|
||||
int overlay_frame_set_broadcast_as_destination(overlay_frame *f);
|
||||
int overlay_broadcast_generate_address(unsigned char *a);
|
||||
int packetEncipher(unsigned char *packet,int maxlen,int *len,int cryptoflags);
|
||||
int overlayServerMode();
|
||||
int overlay_payload_enqueue(int q,overlay_frame *p,int forceBroadcastP);
|
||||
|
Loading…
x
Reference in New Issue
Block a user