diff --git a/overlay_address.c b/overlay_address.c
index 916c68e5..0311d62e 100644
--- a/overlay_address.c
+++ b/overlay_address.c
@@ -458,15 +458,14 @@ int send_please_explain(struct decode_context *context, struct subscriber *sourc
   if (!context->sender)
     frame->source_full=1;
   
+  frame->destination = destination;
   if (destination){
     frame->ttl = PAYLOAD_TTL_DEFAULT; // MAX?
-    frame->destination = destination;
     frame->source_full=1;
   }else{
     // send both a broadcast & unicast response out the same interface this packet arrived on.
     frame->ttl=1;// how will this work with olsr??
     if (context->interface){
-      frame->destination = destination;
       frame_add_destination(frame, NULL, context->interface->destination);
       
       struct network_destination *dest = create_unicast_destination(&context->addr, context->interface);
diff --git a/overlay_packetformats.c b/overlay_packetformats.c
index 10051918..4218b35c 100644
--- a/overlay_packetformats.c
+++ b/overlay_packetformats.c
@@ -238,7 +238,7 @@ int parseMdpPacketHeader(struct decode_context *context, struct overlay_frame *f
     int seq = ob_get(buffer);
     if (seq == -1)
       RETURN(WHY("Unable to read packet seq"));
-    if (link_received_duplicate(context->sender, seq)){
+    if (link_received_duplicate(context, seq)){
       if (IF_DEBUG(verbose))
 	DEBUG(overlayframes, "Don't process or forward duplicate payloads");
       forward=process=0;
@@ -313,9 +313,7 @@ int parseEnvelopeHeader(struct decode_context *context, struct overlay_interface
 	interface->name, alloca_socket_address(addr));
   }
   
-  link_received_packet(context, sender_seq, packet_flags & PACKET_UNICAST);
-  
-  RETURN(0);
+  RETURN(link_received_packet(context, sender_seq, packet_flags & PACKET_UNICAST));
   OUT();
 }
 
diff --git a/overlay_queue.c b/overlay_queue.c
index e289cb0f..fcb76c6b 100644
--- a/overlay_queue.c
+++ b/overlay_queue.c
@@ -288,8 +288,9 @@ 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){
-  if (frame->destination_count >= MAX_PACKET_DESTINATIONS)
+  if ((!dest->ifconfig.send)||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;
diff --git a/route_link.c b/route_link.c
index 92c4b943..4a9a28f3 100644
--- a/route_link.c
+++ b/route_link.c
@@ -1146,9 +1146,9 @@ int link_state_ack_soon(struct subscriber *subscriber)
 }
 
 // our neighbour is sending a duplicate frame, did we see the original?
-int link_received_duplicate(struct subscriber *subscriber, int payload_seq)
+int link_received_duplicate(struct decode_context *context, int payload_seq)
 {
-  struct neighbour *neighbour = get_neighbour(subscriber, 0);
+  struct neighbour *neighbour = get_neighbour(context->sender, 0);
   if (!neighbour)
     return 0;
 
@@ -1244,13 +1244,20 @@ int link_received_packet(struct decode_context *context, int sender_seq, char un
 
   create_out_links(neighbour, context->interface, &context->addr);
 
-  link->ack_counter --;
-
   // for now we'll use a simple time based link up/down flag + dropped packet count
   if (sender_seq >=0){
     if (link->ack_sequence != -1){
       int offset = (link->ack_sequence - 1 - sender_seq)&0xFF;
       if (offset < 64){
+	if (link->ack_mask & (1ull<<offset)){
+	  // received duplicate frame?
+	  if (IF_DEBUG(verbose))
+	    DEBUGF(linkstate, "LINK STATE; duplicate seq %d from %s on %s",
+		   sender_seq, alloca_tohex_sid_t(context->sender->sid), context->interface->name);
+	  return 1;
+	}
+	  
+	// packets were re-ordered?
 	if (IF_DEBUG(verbose))
           DEBUGF(linkstate, "LINK STATE; late seq %d from %s on %s",
 		 sender_seq, alloca_tohex_sid_t(context->sender->sid), context->interface->name);
@@ -1285,6 +1292,7 @@ int link_received_packet(struct decode_context *context, int sender_seq, char un
   }
   link->link_timeout = now + context->interface->destination->ifconfig.reachable_timeout_ms;
 
+  link->ack_counter --;
   // force an update soon when we need to promptly ack packets
   if (neighbour->using_us && link->ack_counter <=0){
     neighbour_find_best_link(neighbour);
diff --git a/serval.h b/serval.h
index 8604ea7a..ce8b1236 100644
--- a/serval.h
+++ b/serval.h
@@ -302,7 +302,7 @@ int unpack_uint(unsigned char *buffer, int buff_size, uint64_t *v);
 void rhizome_fetch_log_short_status();
 extern char crash_handler_clue[1024];
 
-int link_received_duplicate(struct subscriber *subscriber, int previous_seq);
+int link_received_duplicate(struct decode_context *context, int payload_seq);
 int link_received_packet(struct decode_context *context, int sender_seq, char unicast);
 int link_receive(struct internal_mdp_header *header, struct overlay_buffer *payload);
 void link_explained(struct subscriber *subscriber);