diff --git a/overlay_payload.c b/overlay_payload.c index 58286c61..f5476ee2 100644 --- a/overlay_payload.c +++ b/overlay_payload.c @@ -105,8 +105,10 @@ int overlay_frame_append_payload(struct decode_context *context, overlay_interfa broadcast = &p->broadcast_id; } int i = interface - overlay_interfaces; + int previous_seq = p->destination ? p->interface_sent_sequence[i]:-1; + if (overlay_frame_build_header(context, b, - p->queue, p->type, p->modifiers, p->ttl, p->interface_sent_sequence[i], + p->queue, p->type, p->modifiers, p->ttl, previous_seq, broadcast, p->next_hop, p->destination, p->source)) goto cleanup; diff --git a/overlay_queue.c b/overlay_queue.c index 5d0e4c0b..0039b2a2 100644 --- a/overlay_queue.c +++ b/overlay_queue.c @@ -39,7 +39,7 @@ overlay_txqueue overlay_tx[OQ_MAX]; struct outgoing_packet{ overlay_interface *interface; - int seq; + int32_t seq; int i; struct subscriber *unicast_subscriber; struct sockaddr_in dest; @@ -253,7 +253,7 @@ overlay_init_packet(struct outgoing_packet *packet, struct subscriber *destinati if (unicast) packet->unicast_subscriber = destination; else - packet->seq = interface->sequence_number = (interface->sequence_number + 1)&0xFF; + packet->seq = interface->sequence_number = (interface->sequence_number + 1)&0xFFFF; ob_limitsize(packet->buffer, packet->interface->mtu); overlay_packet_init_header(ENCAP_OVERLAY, &packet->context, packet->buffer, @@ -302,15 +302,16 @@ overlay_calc_queue_time(overlay_txqueue *queue, struct overlay_frame *frame){ if (frame->interface->tx_bytes_pending>0) return 0; next_allowed_packet = limit_next_allowed(&frame->interface->transfer_limit); - }else if(!frame->destination){ + }else{ // check all interfaces int i; for(i=0;iinterface_sent_sequence[i]==FRAME_DONT_SEND || + if (overlay_interfaces[i].state!=INTERFACE_STATE_UP || !link_state_interface_has_neighbour(&overlay_interfaces[i])) continue; + if (frame->interface_sent_sequence[i]==FRAME_DONT_SEND && !frame->destination) + continue; time_ms_t next_packet = limit_next_allowed(&overlay_interfaces[i].transfer_limit); if (next_packet < frame->interface_dont_send_until[i]) next_packet = frame->interface_dont_send_until[i]; @@ -416,7 +417,7 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim int i, keep=0; for(i=0;iinterface_sent_sequence[i]==FRAME_DONT_SEND || !link_state_interface_has_neighbour(&overlay_interfaces[i])) continue; @@ -495,11 +496,11 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim goto skip; } - sent: if (frame->interface_sent_sequence[packet->i]>=0 && config.debug.overlayframes) DEBUGF("Retransmitted frame %p from seq %d in seq %d", frame, frame->interface_sent_sequence[packet->i], packet->seq); - frame->interface_sent_sequence[packet->i] = packet->seq; + + sent: frame->interface_dont_send_until[packet->i] = now+200; if (config.debug.overlayframes){ @@ -517,16 +518,15 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim frame->next_hop->last_tx=now; // mark the payload as sent - int keep_payload = 0; - + frame->resend --; if (frame->destination_resolved){ if (frame->resend>0 && frame->next_hop && packet->seq!=-1 && (!frame->unicast)){ frame->dont_send_until = now+200; frame->destination_resolved = 0; - keep_payload = 1; if (config.debug.overlayframes) DEBUGF("Holding onto payload for ack/nack resend in %lldms", frame->dont_send_until - now); + goto skip; } }else{ if (frame->resend<=0 || packet->seq==-1 || frame->unicast){ @@ -538,16 +538,13 @@ overlay_stuff_packet(struct outgoing_packet *packet, overlay_txqueue *queue, tim if (overlay_interfaces[i].state==INTERFACE_STATE_UP && link_state_interface_has_neighbour(&overlay_interfaces[i]) && frame->interface_sent_sequence[i]!=FRAME_DONT_SEND){ - keep_payload = 1; - break; + goto skip; } } } - - if (!keep_payload){ - frame = overlay_queue_remove(queue, frame); - continue; - } + + frame = overlay_queue_remove(queue, frame); + continue; skip: // if we can't send the payload now, check when we should try next @@ -593,12 +590,14 @@ overlay_fill_send_packet(struct outgoing_packet *packet, time_ms_t now) { static void overlay_send_packet(struct sched_ent *alarm){ struct outgoing_packet packet; bzero(&packet, sizeof(struct outgoing_packet)); + packet.seq=-1; overlay_fill_send_packet(&packet, gettime_ms()); } int overlay_send_tick_packet(struct overlay_interface *interface){ struct outgoing_packet packet; bzero(&packet, sizeof(struct outgoing_packet)); + packet.seq=-1; overlay_init_packet(&packet, NULL, 0, interface, interface->broadcast_address); overlay_fill_send_packet(&packet, gettime_ms()); @@ -627,7 +626,8 @@ int overlay_queue_ack(struct subscriber *neighbour, struct overlay_interface *in int j; for(j=0;jinterface_sent_sequence[j]!=FRAME_DONT_SEND){ + frame->interface_sent_sequence[j]!=FRAME_DONT_SEND && + link_state_interface_has_neighbour(&overlay_interfaces[j])){ discard = 0; break; } diff --git a/route_link.c b/route_link.c index b12c500e..f9486fd7 100644 --- a/route_link.c +++ b/route_link.c @@ -621,7 +621,8 @@ static int send_neighbour_link(struct neighbour *n) if (config.debug.linkstate && config.debug.verbose) DEBUGF("LINK STATE; Sending ack to %s for seq %d", alloca_tohex_sid(n->subscriber->sid), n->best_link->ack_sequence); - append_link_state(frame->payload, flags, n->subscriber, my_subscriber, n->best_link->neighbour_interface, 1, n->best_link->ack_sequence, n->best_link->ack_mask, -1); + append_link_state(frame->payload, flags, n->subscriber, my_subscriber, n->best_link->neighbour_interface, 1, + n->best_link->ack_sequence, n->best_link->ack_mask, -1); if (overlay_payload_enqueue(frame)) op_free(frame); else @@ -766,8 +767,16 @@ int link_received_duplicate(struct subscriber *subscriber, struct overlay_interf struct neighbour_link *link=get_neighbour_link(neighbour, interface, sender_interface, unicast); int offset = (link->ack_sequence - 1 - previous_seq)&0xFF; - if (offset < 32) - return link->ack_mask & (1<= 64 || (link->ack_mask & (1<sid), previous_seq); + return 1; + } + + if (config.debug.linkstate && config.debug.verbose) + DEBUGF("LINK STATE; allowing duplicate %s, didn't see seq %d", + alloca_tohex_sid(subscriber->sid), previous_seq); return 0; } @@ -788,7 +797,7 @@ int link_received_packet(struct subscriber *subscriber, struct overlay_interface if (sender_seq >=0){ if (link->ack_sequence != -1){ int offset = (link->ack_sequence - 1 - sender_seq)&0xFF; - if (offset < 32){ + if (offset < 64){ if (config.debug.verbose && config.debug.linkstate) DEBUGF("LINK STATE; late seq %d from %s on %s", sender_seq, alloca_tohex_sid(subscriber->sid), interface->name);