mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-04-13 22:03:09 +00:00
Re-route packets on retransmision if the route has changed
This commit is contained in:
parent
b048e8874f
commit
13bb8a558d
@ -476,11 +476,11 @@ int send_please_explain(struct decode_context *context, struct subscriber *sourc
|
||||
frame->ttl=1;// how will this work with olsr??
|
||||
if (context->interface){
|
||||
frame->destination = destination;
|
||||
frame->destinations[frame->destination_count++].destination=add_destination_ref(context->interface->destination);
|
||||
frame_add_destination(frame, NULL, context->interface->destination);
|
||||
|
||||
struct network_destination *dest = create_unicast_destination(&context->addr, context->interface);
|
||||
if (dest)
|
||||
frame->destinations[frame->destination_count++].destination=dest;
|
||||
frame_add_destination(frame, NULL, dest);
|
||||
|
||||
}else{
|
||||
FATAL("This context doesn't have an interface?");
|
||||
|
@ -189,9 +189,8 @@ int overlay_send_probe(struct subscriber *peer, struct network_destination *dest
|
||||
frame->destination = peer;
|
||||
frame->ttl=1;
|
||||
frame->queue=queue;
|
||||
unsigned dest = frame->destination_count++;
|
||||
frame->destinations[dest].destination=add_destination_ref(destination);
|
||||
frame->destinations[dest].next_hop = peer;
|
||||
frame_add_destination(frame, peer, destination);
|
||||
|
||||
if ((frame->payload = ob_new()) == NULL) {
|
||||
op_free(frame);
|
||||
return -1;
|
||||
|
@ -119,5 +119,7 @@ int op_free(struct overlay_frame *p);
|
||||
struct overlay_frame *op_dup(struct overlay_frame *f);
|
||||
|
||||
int reload_mdp_packet_rules(void);
|
||||
void frame_remove_destination(struct overlay_frame *frame, int i);
|
||||
void frame_add_destination(struct overlay_frame *frame, struct subscriber *next_hop, struct network_destination *dest);
|
||||
|
||||
#endif //__SERVAL_DNA__OVERLAY_PACKET_H
|
||||
|
@ -178,7 +178,8 @@ int _overlay_payload_enqueue(struct __sourceloc __whence, struct overlay_frame *
|
||||
p->packet_version=1;
|
||||
|
||||
if (config.debug.verbose && config.debug.overlayframes)
|
||||
DEBUGF("Enqueue packet %p", p);
|
||||
DEBUGF("Enqueue packet to %s",
|
||||
p->destination?alloca_tohex_sid_t_trunc(p->destination->sid, 14): "broadcast");
|
||||
|
||||
if (p->destination_count==0){
|
||||
if (!p->destination){
|
||||
@ -278,13 +279,26 @@ int overlay_queue_schedule_next(time_ms_t next_allowed_packet){
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void remove_destination(struct overlay_frame *frame, int i){
|
||||
void frame_remove_destination(struct overlay_frame *frame, int i){
|
||||
release_destination_ref(frame->destinations[i].destination);
|
||||
frame->destination_count --;
|
||||
if (i<frame->destination_count)
|
||||
frame->destinations[i]=frame->destinations[frame->destination_count];
|
||||
}
|
||||
|
||||
void frame_add_destination(struct overlay_frame *frame, struct subscriber *next_hop, struct network_destination *dest){
|
||||
if (frame->destination_count >= MAX_PACKET_DESTINATIONS)
|
||||
return;
|
||||
unsigned i = frame->destination_count++;
|
||||
frame->destinations[i].destination=add_destination_ref(dest);
|
||||
frame->destinations[i].next_hop = next_hop;
|
||||
frame->destinations[i].sent_sequence=-1;
|
||||
if (config.debug.verbose && config.debug.overlayframes)
|
||||
DEBUGF("Sending %s on interface %s",
|
||||
frame->destinations[i].destination->unicast?"unicast":"broadcast",
|
||||
frame->destinations[i].destination->interface->name);
|
||||
}
|
||||
|
||||
// update the alarm time and return 1 if changed
|
||||
static int
|
||||
overlay_calc_queue_time(struct overlay_frame *frame)
|
||||
@ -359,21 +373,10 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim
|
||||
goto skip;
|
||||
|
||||
// quickly skip payloads that have no chance of fitting
|
||||
if (packet->buffer && ob_limit(frame->payload) > ob_remaining(packet->buffer))
|
||||
if (packet->buffer && ob_position(frame->payload) > ob_remaining(packet->buffer))
|
||||
goto skip;
|
||||
|
||||
if (frame->destination_count==0 && frame->destination){
|
||||
link_add_destinations(frame);
|
||||
|
||||
int i=0;
|
||||
for (i=0;i<frame->destination_count;i++){
|
||||
frame->destinations[i].sent_sequence=-1;
|
||||
if (config.debug.verbose && config.debug.overlayframes)
|
||||
DEBUGF("Sending %s on interface %s",
|
||||
frame->destinations[i].destination->unicast?"unicast":"broadcast",
|
||||
frame->destinations[i].destination->interface->name);
|
||||
}
|
||||
}
|
||||
link_add_destinations(frame);
|
||||
|
||||
if (frame->mdp_sequence == -1){
|
||||
frame->mdp_sequence = mdp_sequence = (mdp_sequence+1)&0xFFFF;
|
||||
@ -397,7 +400,13 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim
|
||||
FATALF("Destination interface %d is NULL", i);
|
||||
if (dest->interface->state!=INTERFACE_STATE_UP){
|
||||
// remove this destination
|
||||
remove_destination(frame, i);
|
||||
frame_remove_destination(frame, i);
|
||||
continue;
|
||||
}
|
||||
if (ob_position(frame->payload) > (unsigned)dest->ifconfig.mtu){
|
||||
WARNF("Skipping packet destination as size %zu > destination mtu %zd",
|
||||
ob_position(frame->payload), dest->ifconfig.mtu);
|
||||
frame_remove_destination(frame, i);
|
||||
continue;
|
||||
}
|
||||
// degrade packet version if required to reach the destination
|
||||
@ -494,15 +503,13 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim
|
||||
if (!will_retransmit){
|
||||
if (config.debug.overlayframes)
|
||||
DEBUGF("Not waiting for retransmission (%d, %d, %d)", frame->packet_version, frame->resend, packet->seq);
|
||||
remove_destination(frame, destination_index);
|
||||
frame_remove_destination(frame, destination_index);
|
||||
if (frame->destination_count==0){
|
||||
frame = overlay_queue_remove(queue, frame);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO recalc route on retransmittion??
|
||||
|
||||
skip:
|
||||
// if we can't send the payload now, check when we should try next
|
||||
overlay_calc_queue_time(frame);
|
||||
@ -610,7 +617,7 @@ int overlay_queue_ack(struct subscriber *neighbour, struct network_destination *
|
||||
frame = overlay_queue_remove(&overlay_tx[i], frame);
|
||||
continue;
|
||||
}
|
||||
remove_destination(frame, j);
|
||||
frame_remove_destination(frame, j);
|
||||
|
||||
}else if (seq_delta < 128 && frame->destination && frame->delay_until>now){
|
||||
// retransmit asap
|
||||
|
32
route_link.c
32
route_link.c
@ -912,8 +912,11 @@ static int link_send_neighbours()
|
||||
if (out->destination->ifconfig.tick_ms>0 && out->destination->unicast){
|
||||
if (out->destination->last_tx + out->destination->ifconfig.tick_ms < now)
|
||||
overlay_send_tick_packet(out->destination);
|
||||
if (out->destination->last_tx + out->destination->ifconfig.tick_ms < ALARM_STRUCT(link_send).alarm)
|
||||
ALARM_STRUCT(link_send).alarm = out->destination->last_tx + out->destination->ifconfig.tick_ms;
|
||||
if (out->destination->last_tx + out->destination->ifconfig.tick_ms < ALARM_STRUCT(link_send).alarm){
|
||||
time_ms_t next_tick = out->destination->last_tx + out->destination->ifconfig.tick_ms;
|
||||
time_ms_t next_allowed = limit_next_allowed(&out->destination->transfer_limit);
|
||||
ALARM_STRUCT(link_send).alarm = next_tick < next_allowed ? next_tick : next_allowed;
|
||||
}
|
||||
}
|
||||
out=out->_next;
|
||||
}
|
||||
@ -1038,7 +1041,7 @@ int link_add_destinations(struct overlay_frame *frame)
|
||||
&& directory_service->reachable&REACHABLE)
|
||||
next_hop = directory_service;
|
||||
|
||||
if (next_hop->reachable==REACHABLE_NONE){
|
||||
if (next_hop->reachable==REACHABLE_NONE && frame->destination_count==0){
|
||||
// if the destination is a network neighbour, but we haven't established any viable route yet
|
||||
// we need to add all likely links so that we can send ack's and bootstrap the routing table
|
||||
struct neighbour *n = get_neighbour(frame->destination, 0);
|
||||
@ -1046,11 +1049,8 @@ int link_add_destinations(struct overlay_frame *frame)
|
||||
struct link_out *out = n->out_links;
|
||||
time_ms_t now = gettime_ms();
|
||||
while(out){
|
||||
if (out->timeout>=now && frame->destination_count < MAX_PACKET_DESTINATIONS){
|
||||
unsigned dest = frame->destination_count++;
|
||||
frame->destinations[dest].destination = add_destination_ref(out->destination);
|
||||
frame->destinations[dest].next_hop = next_hop;
|
||||
}
|
||||
if (out->timeout>=now && frame->destination_count < MAX_PACKET_DESTINATIONS)
|
||||
frame_add_destination(frame, next_hop, out->destination);
|
||||
out = out->_next;
|
||||
}
|
||||
}
|
||||
@ -1060,13 +1060,17 @@ int link_add_destinations(struct overlay_frame *frame)
|
||||
next_hop = next_hop->next_hop;
|
||||
|
||||
if (next_hop->reachable&REACHABLE_DIRECT){
|
||||
if (frame->destination_count < MAX_PACKET_DESTINATIONS){
|
||||
unsigned dest = frame->destination_count++;
|
||||
frame->destinations[dest].destination=add_destination_ref(next_hop->destination);
|
||||
frame->destinations[dest].next_hop = next_hop;
|
||||
unsigned i;
|
||||
// do nothing if this packet is already going the right way
|
||||
// or remove any stale destinations
|
||||
for (i=frame->destination_count;i>0;i--){
|
||||
if (frame->destinations[i-1].destination == next_hop->destination)
|
||||
return 0;
|
||||
frame_remove_destination(frame, i-1);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
frame_add_destination(frame, next_hop, next_hop->destination);
|
||||
}
|
||||
}else if (frame->destination_count==0){
|
||||
char added_interface[OVERLAY_MAX_INTERFACES];
|
||||
bzero(added_interface, sizeof(added_interface));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user