mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-18 20:57:56 +00:00
Resend last ACK if it is explicitly NACKed
This commit is contained in:
parent
e5856225cf
commit
e519633f7a
@ -33,6 +33,8 @@ struct overlay_frame {
|
||||
unsigned char ttl;
|
||||
unsigned char queue;
|
||||
char resend;
|
||||
void *send_context;
|
||||
int (*send_hook)(struct overlay_frame *, int seq, void *context);
|
||||
|
||||
/* Mark which interfaces the frame has been sent on,
|
||||
so that we can ensure that broadcast frames get sent
|
||||
|
@ -253,7 +253,7 @@ int parseEnvelopeHeader(struct decode_context *context, struct overlay_interface
|
||||
sender_interface = ob_get(buffer);
|
||||
|
||||
if (packet_flags & PACKET_SEQ)
|
||||
sender_seq = ob_get(buffer);
|
||||
sender_seq = ob_get(buffer)&0xFF;
|
||||
|
||||
if (context->sender){
|
||||
// ignore packets that have been reflected back to me
|
||||
|
@ -469,10 +469,21 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim
|
||||
}
|
||||
}
|
||||
|
||||
if (frame->send_hook){
|
||||
// last minute check if we really want to send this frame, or track when we sent it
|
||||
if (frame->send_hook(frame, packet->seq, frame->send_context)){
|
||||
// drop packet
|
||||
frame = overlay_queue_remove(queue, frame);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (overlay_frame_append_payload(&packet->context, packet->interface, frame, packet->buffer)){
|
||||
// payload was not queued
|
||||
goto skip;
|
||||
}
|
||||
if (frame->sent_seq!=-1 && config.debug.overlayframes)
|
||||
DEBUGF("Retransmitted frame from seq %d in seq %d", frame->sent_seq, packet->seq);
|
||||
frame->sent_seq = packet->seq;
|
||||
|
||||
sent:
|
||||
|
34
route_link.c
34
route_link.c
@ -87,6 +87,7 @@ struct neighbour{
|
||||
// next link update
|
||||
time_ms_t next_neighbour_update;
|
||||
time_ms_t last_update;
|
||||
int last_update_seq;
|
||||
time_ms_t rtt;
|
||||
int ack_counter;
|
||||
|
||||
@ -157,6 +158,7 @@ static struct neighbour *get_neighbour(struct subscriber *subscriber, char creat
|
||||
n = emalloc_zero(sizeof(struct neighbour));
|
||||
n->subscriber = subscriber;
|
||||
n->_next = neighbours;
|
||||
n->last_update_seq = -1;
|
||||
// TODO measure min/max rtt
|
||||
n->rtt = 120;
|
||||
neighbours = n;
|
||||
@ -565,7 +567,18 @@ static int neighbour_find_best_link(struct neighbour *n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int send_neighbour_link(struct neighbour *n){
|
||||
static int neighbour_link_sent(struct overlay_frame *frame, int sequence, void *context)
|
||||
{
|
||||
struct subscriber *subscriber = context;
|
||||
struct neighbour *neighbour = get_neighbour(subscriber, 1);
|
||||
neighbour->last_update_seq = sequence;
|
||||
if (config.debug.linkstate && config.debug.verbose)
|
||||
DEBUGF("LINK STATE; ack sent to neighbour %s in seq %d", alloca_tohex_sid(subscriber->sid), sequence);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int send_neighbour_link(struct neighbour *n)
|
||||
{
|
||||
IN();
|
||||
if (!n->best_link)
|
||||
RETURN(-1);
|
||||
@ -582,6 +595,9 @@ static int send_neighbour_link(struct neighbour *n){
|
||||
frame->ttl=1;
|
||||
frame->queue=OQ_MESH_MANAGEMENT;
|
||||
frame->payload = ob_new();
|
||||
frame->send_hook = neighbour_link_sent;
|
||||
frame->send_context = n->subscriber;
|
||||
|
||||
if (n->subscriber->reachable & REACHABLE_DIRECT && (!(n->subscriber->reachable&REACHABLE_ASSUMED))){
|
||||
frame->destination_resolved = 1;
|
||||
frame->interface = n->subscriber->interface;
|
||||
@ -907,8 +923,24 @@ int link_receive(overlay_mdp_frame *mdp)
|
||||
version++;
|
||||
|
||||
// process acks / nacks
|
||||
if (ack_seq!=-1){
|
||||
overlay_queue_ack(sender, interface, ack_mask, ack_seq);
|
||||
|
||||
// did they miss our last ack?
|
||||
if (neighbour->last_update_seq!=-1){
|
||||
int seq_delta = (ack_seq - neighbour->last_update_seq)&0xFF;
|
||||
if (seq_delta <= 32 && (seq_delta==0 || ack_mask&(1<<(seq_delta-1)))){
|
||||
neighbour->last_update_seq = -1;
|
||||
}else if(seq_delta < 128){
|
||||
// send another ack asap
|
||||
if (config.debug.linkstate && config.debug.verbose)
|
||||
DEBUGF("LINK STATE; neighbour %s missed ack %d, queue another", alloca_tohex_sid(sender->sid), neighbour->last_update_seq);
|
||||
neighbour->next_neighbour_update=now;
|
||||
update_alarm(neighbour->next_neighbour_update);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
link->last_ack_seq = ack_seq;
|
||||
}
|
||||
|
||||
|
@ -363,7 +363,7 @@ test_multi_interface() {
|
||||
wait_until multi_has_link $SIDA
|
||||
}
|
||||
|
||||
doc_ping_unreliable="Ping over an unreliable link"
|
||||
doc_ping_unreliable="Ping over a 1-hop unreliable link"
|
||||
setup_ping_unreliable() {
|
||||
setup_servald
|
||||
assert_no_servald_processes
|
||||
@ -380,7 +380,7 @@ test_ping_unreliable() {
|
||||
wait_until path_exists +A +B
|
||||
wait_until path_exists +B +A
|
||||
set_instance +A
|
||||
executeOk_servald mdp ping $SIDB 40
|
||||
executeOk_servald mdp ping --interval=0.020 --timeout=1 $SIDB 500
|
||||
tfw_cat --stdout --stderr
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user