2012-11-21 12:52:39 +10:30
/*
2013-12-04 16:56:55 +10:30
Copyright ( C ) 2012 - 2013 Serval Project Inc .
2012-11-21 12:52:39 +10:30
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*/
2013-11-25 16:43:32 +10:30
# include <assert.h>
2012-11-20 16:41:06 +10:30
# include "serval.h"
2012-12-11 15:59:46 +10:30
# include "conf.h"
2012-11-20 16:41:06 +10:30
# include "overlay_buffer.h"
2013-12-09 17:45:47 +10:30
# include "overlay_interface.h"
2012-11-20 16:41:06 +10:30
# include "overlay_packet.h"
2013-11-25 15:05:33 +10:30
# include "radio_link.h"
2012-11-20 16:41:06 +10:30
# include "str.h"
2012-11-22 10:55:54 +10:30
# include "strbuf.h"
2015-08-31 15:18:08 +09:30
# include "route_link.h"
2017-09-12 15:24:10 +09:30
# include "server.h"
2017-11-24 10:33:39 +10:30
# include "debug.h"
2012-11-20 16:41:06 +10:30
typedef struct overlay_txqueue {
struct overlay_frame * first ;
struct overlay_frame * last ;
int length ; /* # frames in queue */
int maxLength ; /* max # frames in queue before we consider ourselves congested */
2013-05-27 13:10:58 +09:30
int small_packet_grace_interval ;
2012-11-20 16:41:06 +10:30
/* Latency target in ms for this traffic class.
Frames older than the latency target will get dropped . */
int latencyTarget ;
} overlay_txqueue ;
overlay_txqueue overlay_tx [ OQ_MAX ] ;
2013-08-08 15:20:31 +09:30
// short lived data while we are constructing an outgoing packet
2012-11-20 16:41:06 +10:30
struct outgoing_packet {
2013-08-08 15:20:31 +09:30
struct network_destination * destination ;
int seq ;
2013-05-24 13:52:31 +09:30
int packet_version ;
2012-12-04 14:47:57 +10:30
int header_length ;
2012-11-20 16:41:06 +10:30
struct overlay_buffer * buffer ;
2012-11-23 09:04:42 +10:30
struct decode_context context ;
2012-11-20 16:41:06 +10:30
} ;
2013-05-27 13:10:58 +09:30
# define SMALL_PACKET_SIZE (400)
2013-05-24 13:52:31 +09:30
int32_t mdp_sequence = 0 ;
2012-11-20 16:41:06 +10:30
struct sched_ent next_packet ;
struct profile_total send_packet ;
static void overlay_send_packet ( struct sched_ent * alarm ) ;
2013-12-09 18:22:18 +10:30
static int overlay_calc_queue_time ( struct overlay_frame * frame ) ;
2012-11-20 16:41:06 +10:30
int overlay_queue_init ( ) {
/* Set default congestion levels for queues */
2017-09-11 14:09:05 +09:30
unsigned i ;
2012-11-20 16:41:06 +10:30
for ( i = 0 ; i < OQ_MAX ; i + + ) {
overlay_tx [ i ] . maxLength = 100 ;
2015-11-30 14:22:45 +10:30
overlay_tx [ i ] . latencyTarget = 0 ; // no QOS time limit by default, depend on per destination timeouts
2013-05-27 13:10:58 +09:30
overlay_tx [ i ] . small_packet_grace_interval = 5 ;
2012-11-20 16:41:06 +10:30
}
/* expire voice/video call packets much sooner, as they just aren't any use if late */
2012-12-19 10:38:17 +10:30
overlay_tx [ OQ_ISOCHRONOUS_VOICE ] . maxLength = 20 ;
2012-11-20 16:41:06 +10:30
overlay_tx [ OQ_ISOCHRONOUS_VOICE ] . latencyTarget = 200 ;
2013-05-27 13:10:58 +09:30
2012-11-20 16:41:06 +10:30
overlay_tx [ OQ_ISOCHRONOUS_VIDEO ] . latencyTarget = 200 ;
2013-05-27 13:10:58 +09:30
2015-03-30 14:15:08 +10:30
overlay_tx [ OQ_OPPORTUNISTIC ] . small_packet_grace_interval = 100 ;
2013-05-27 13:10:58 +09:30
return 0 ;
2012-11-20 16:41:06 +10:30
}
/* remove and free a payload from the queue */
static struct overlay_frame *
overlay_queue_remove ( overlay_txqueue * queue , struct overlay_frame * frame ) {
struct overlay_frame * prev = frame - > prev ;
struct overlay_frame * next = frame - > next ;
if ( prev )
prev - > next = next ;
else if ( frame = = queue - > first )
queue - > first = next ;
if ( next )
next - > prev = prev ;
else if ( frame = = queue - > last )
queue - > last = prev ;
queue - > length - - ;
2013-08-08 15:20:31 +09:30
while ( frame - > destination_count > 0 )
release_destination_ref ( frame - > destinations [ - - frame - > destination_count ] . destination ) ;
2012-11-20 16:41:06 +10:30
op_free ( frame ) ;
return next ;
}
2017-09-12 15:24:10 +09:30
static void overlay_queue_release ( ) {
2017-09-11 14:09:05 +09:30
unsigned i ;
for ( i = 0 ; i < OQ_MAX ; i + + ) {
while ( overlay_tx [ i ] . first )
overlay_queue_remove ( & overlay_tx [ i ] , overlay_tx [ i ] . first ) ;
}
}
2017-09-12 15:24:10 +09:30
DEFINE_TRIGGER ( shutdown , overlay_queue_release ) ;
2017-09-11 14:09:05 +09:30
2012-12-07 14:09:55 +10:30
#if 0 // unused
2012-11-20 16:41:06 +10:30
static int
overlay_queue_dump ( overlay_txqueue * q )
{
strbuf b = strbuf_alloca ( 8192 ) ;
struct overlay_frame * f ;
strbuf_sprintf ( b , " overlay_txqueue @ 0x%p \n " , q ) ;
strbuf_sprintf ( b , " length=%d \n " , q - > length ) ;
strbuf_sprintf ( b , " maxLenght=%d \n " , q - > maxLength ) ;
strbuf_sprintf ( b , " latencyTarget=%d milli-seconds \n " , q - > latencyTarget ) ;
strbuf_sprintf ( b , " first=%p \n " , q - > first ) ;
f = q - > first ;
while ( f ) {
strbuf_sprintf ( b , " %p: ->next=%p, ->prev=%p \n " ,
f , f - > next , f - > prev ) ;
if ( f = = f - > next ) {
strbuf_sprintf ( b , " LOOP! \n " ) ; break ;
}
f = f - > next ;
}
strbuf_sprintf ( b , " last=%p \n " , q - > last ) ;
f = q - > last ;
while ( f ) {
strbuf_sprintf ( b , " %p: ->next=%p, ->prev=%p \n " ,
f , f - > next , f - > prev ) ;
if ( f = = f - > prev ) {
strbuf_sprintf ( b , " LOOP! \n " ) ; break ;
}
f = f - > prev ;
}
2015-07-06 17:49:49 +09:30
_DEBUG ( strbuf_str ( b ) ) ;
2012-11-20 16:41:06 +10:30
return 0 ;
}
2012-12-07 14:09:55 +10:30
# endif
2012-11-20 16:41:06 +10:30
2013-01-28 13:35:24 +11:00
int overlay_queue_remaining ( int queue ) {
if ( queue < 0 | | queue > = OQ_MAX )
return - 1 ;
return overlay_tx [ queue ] . maxLength - overlay_tx [ queue ] . length ;
}
2014-06-28 20:17:26 +09:30
int _overlay_payload_enqueue ( struct __sourceloc __whence , struct overlay_frame * p )
2012-11-20 16:41:06 +10:30
{
/* Add payload p to queue q.
Queues get scanned from first to last , so we should append new entries
on the end of the queue .
Complain if there are too many frames in the queue .
*/
2013-11-25 16:43:32 +10:30
assert ( p ! = NULL ) ;
assert ( p - > queue < OQ_MAX ) ;
assert ( p - > payload ! = NULL ) ;
2014-06-28 20:17:26 +09:30
p - > whence = __whence ;
2012-11-20 16:41:06 +10:30
overlay_txqueue * queue = & overlay_tx [ p - > queue ] ;
2013-05-15 11:33:43 +09:30
2012-11-20 16:41:06 +10:30
2013-11-25 16:43:32 +10:30
if ( ob_overrun ( p - > payload ) )
return WHY ( " Packet content overrun -- not queueing " ) ;
2012-11-20 16:41:06 +10:30
2016-05-23 14:57:03 +09:30
if ( ob_position ( p - > payload ) > = MDP_OVERLAY_MTU )
2016-03-16 10:31:09 +10:30
FATALF ( " Queued packet len %u is too big " , ob_position ( p - > payload ) ) ;
2013-11-25 16:43:32 +10:30
2012-11-20 16:41:06 +10:30
if ( queue - > length > = queue - > maxLength )
return WHYF ( " Queue #%d congested (size = %d) " ,p->queue,queue->maxLength) ;
2013-08-08 15:20:31 +09:30
2013-07-08 16:01:58 +09:30
// it should be safe to try sending all packets with an mdp sequence
if ( p - > packet_version < = 0 )
p - > packet_version = 1 ;
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " Enqueue packet to %s " ,
p - > destination ? alloca_tohex_sid_t_trunc ( p - > destination - > sid , 14 ) : " broadcast " ) ;
2013-08-08 15:20:31 +09:30
if ( p - > destination_count = = 0 ) {
if ( ! p - > destination ) {
2012-12-04 14:47:57 +10:30
// hook to allow for flooding via olsr
olsr_send ( p ) ;
2013-08-09 16:19:45 +09:30
link_add_destinations ( p ) ;
2013-08-08 15:20:31 +09:30
2012-12-04 14:47:57 +10:30
// just drop it now
2013-08-08 15:20:31 +09:30
if ( p - > destination_count = = 0 ) {
2015-07-06 17:49:49 +09:30
DEBUGF ( mdprequests , " Not transmitting, as we have nowhere to send it " ) ;
2014-03-27 13:31:43 +10:30
// free the packet and return success.
op_free ( p ) ;
return 0 ;
2013-05-29 11:14:26 +09:30
}
2012-11-20 16:41:06 +10:30
}
2013-08-08 15:20:31 +09:30
// allow the packet to be resent
if ( p - > resend = = 0 )
p - > resend = 1 ;
2015-06-22 12:30:18 +09:30
} else {
p - > manual_destinations = 1 ;
2013-08-08 15:20:31 +09:30
}
2013-08-29 15:05:32 +09:30
int i = 0 ;
for ( i = 0 ; i < p - > destination_count ; i + + ) {
p - > destinations [ i ] . sent_sequence = - 1 ;
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " Sending %s on interface %s " ,
p - > destinations [ i ] . destination - > unicast ? " unicast " : " broadcast " ,
p - > destinations [ i ] . destination - > interface - > name ) ;
2012-11-20 16:41:06 +10:30
}
struct overlay_frame * l = queue - > last ;
if ( l ) l - > next = p ;
p - > prev = l ;
p - > next = NULL ;
p - > enqueued_at = gettime_ms ( ) ;
2013-05-24 13:52:31 +09:30
p - > mdp_sequence = - 1 ;
2012-11-20 16:41:06 +10:30
queue - > last = p ;
if ( ! queue - > first ) queue - > first = p ;
queue - > length + + ;
2012-12-16 10:05:32 +10:30
if ( p - > queue = = OQ_ISOCHRONOUS_VOICE )
rhizome_saw_voice_traffic ( ) ;
2012-11-20 16:41:06 +10:30
2013-12-09 18:22:18 +10:30
overlay_calc_queue_time ( p ) ;
2012-11-20 16:41:06 +10:30
return 0 ;
}
2013-11-25 16:43:32 +10:30
static int
2013-08-08 15:20:31 +09:30
overlay_init_packet ( struct outgoing_packet * packet , int packet_version ,
2013-11-25 16:43:32 +10:30
struct network_destination * destination )
{
2013-08-08 15:20:31 +09:30
packet - > context . interface = destination - > interface ;
2013-11-25 16:43:32 +10:30
if ( ( packet - > buffer = ob_new ( ) ) = = NULL )
return - 1 ;
2013-05-24 13:52:31 +09:30
packet - > packet_version = packet_version ;
2013-07-16 15:16:07 +09:30
packet - > context . packet_version = packet_version ;
2013-08-13 15:16:17 +09:30
packet - > destination = add_destination_ref ( destination ) ;
2013-08-09 12:18:14 +09:30
if ( destination - > sequence_number < 0 )
packet - > seq = - 1 ;
else
packet - > seq = destination - > sequence_number = ( destination - > sequence_number + 1 ) & 0xFFFF ;
2015-03-16 12:22:38 +10:30
ob_limitsize ( packet - > buffer , destination - > ifconfig . mtu ) ;
2013-11-25 16:43:32 +10:30
int i = destination - > interface - overlay_interfaces ;
2015-03-16 12:22:38 +10:30
if ( overlay_packet_init_header ( packet_version , destination - > ifconfig . encapsulation ,
2013-11-25 16:43:32 +10:30
& packet - > context , packet - > buffer ,
destination - > unicast ,
i , packet - > seq ) = = - 1
) {
ob_free ( packet - > buffer ) ;
packet - > buffer = NULL ;
return - 1 ;
}
2012-12-04 14:47:57 +10:30
packet - > header_length = ob_position ( packet - > buffer ) ;
2015-07-06 17:49:49 +09:30
DEBUGF ( overlayframes , " Creating %d packet for interface %s, seq %d, %s " ,
packet_version ,
destination - > interface - > name , destination - > sequence_number ,
alloca_socket_address ( & destination - > address )
) ;
2013-11-25 16:43:32 +10:30
return 0 ;
2012-11-20 16:41:06 +10:30
}
2013-02-06 17:10:43 +10:30
int overlay_queue_schedule_next ( time_ms_t next_allowed_packet ) {
if ( next_packet . alarm = = 0 | | next_allowed_packet < next_packet . alarm ) {
if ( ! next_packet . function ) {
next_packet . function = overlay_send_packet ;
send_packet . name = " overlay_send_packet " ;
next_packet . stats = & send_packet ;
}
unschedule ( & next_packet ) ;
next_packet . alarm = next_allowed_packet ;
// small grace period, we want to read incoming IO first
next_packet . deadline = next_allowed_packet + 15 ;
schedule ( & next_packet ) ;
}
return 0 ;
}
2015-03-30 11:27:37 +10:30
void frame_remove_destination ( struct overlay_frame * frame , int i ) {
2015-07-06 17:49:49 +09:30
DEBUGF ( overlayframes , " Remove %s destination on interface %s " ,
frame - > destinations [ i ] . destination - > unicast ? " unicast " : " broadcast " ,
frame - > destinations [ i ] . destination - > interface - > name
) ;
2013-08-08 15:20:31 +09:30
release_destination_ref ( frame - > destinations [ i ] . destination ) ;
frame - > destination_count - - ;
if ( i < frame - > destination_count )
frame - > destinations [ i ] = frame - > destinations [ frame - > destination_count ] ;
}
2015-03-30 11:27:37 +10:30
void frame_add_destination ( struct overlay_frame * frame , struct subscriber * next_hop , struct network_destination * dest ) {
2015-08-03 11:12:39 +09:30
if ( ( ! dest - > ifconfig . send ) | | frame - > destination_count > = MAX_PACKET_DESTINATIONS )
2015-03-30 11:27:37 +10:30
return ;
2015-08-03 11:12:39 +09:30
2015-03-30 11:27:37 +10:30
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 ;
2015-07-06 17:49:49 +09:30
DEBUGF ( overlayframes , " Add %s destination on interface %s " ,
frame - > destinations [ i ] . destination - > unicast ? " unicast " : " broadcast " ,
frame - > destinations [ i ] . destination - > interface - > name
) ;
2015-03-30 11:27:37 +10:30
}
2012-11-20 16:41:06 +10:30
// update the alarm time and return 1 if changed
static int
2013-12-09 18:22:18 +10:30
overlay_calc_queue_time ( struct overlay_frame * frame )
{
2013-08-08 15:20:31 +09:30
2012-12-13 17:50:09 +10:30
time_ms_t next_allowed_packet = 0 ;
2013-08-08 15:20:31 +09:30
// check all interfaces
if ( frame - > destination_count > 0 ) {
2012-12-13 17:50:09 +10:30
int i ;
2013-08-08 15:20:31 +09:30
for ( i = 0 ; i < frame - > destination_count ; i + + )
2012-12-13 17:50:09 +10:30
{
2013-11-25 15:05:33 +10:30
if ( radio_link_is_busy ( frame - > destinations [ i ] . destination - > interface ) )
2013-08-27 20:43:56 +09:30
continue ;
2013-08-08 15:20:31 +09:30
time_ms_t next_packet = limit_next_allowed ( & frame - > destinations [ i ] . destination - > transfer_limit ) ;
2013-08-29 15:05:32 +09:30
if ( frame - > destinations [ i ] . transmit_time ) {
time_ms_t delay_until = frame - > destinations [ i ] . transmit_time + frame - > destinations [ i ] . destination - > resend_delay ;
if ( next_packet < delay_until )
next_packet = delay_until ;
}
2012-12-13 17:50:09 +10:30
if ( next_allowed_packet = = 0 | | next_packet < next_allowed_packet )
next_allowed_packet = next_packet ;
}
2013-08-08 15:20:31 +09:30
if ( next_allowed_packet = = 0 ) {
return 0 ;
}
} else {
if ( ! frame - > destination ) {
2012-12-19 10:38:17 +10:30
return 0 ;
2013-08-08 15:20:31 +09:30
}
2012-12-13 17:50:09 +10:30
}
2012-12-04 14:47:57 +10:30
2013-08-08 15:20:31 +09:30
if ( next_allowed_packet < frame - > delay_until )
next_allowed_packet = frame - > delay_until ;
if ( next_allowed_packet < frame - > enqueued_at )
next_allowed_packet = frame - > enqueued_at ;
2013-05-15 11:33:43 +09:30
2013-05-27 13:10:58 +09:30
if ( ob_position ( frame - > payload ) < SMALL_PACKET_SIZE & &
next_allowed_packet < frame - > enqueued_at + overlay_tx [ frame - > queue ] . small_packet_grace_interval )
next_allowed_packet = frame - > enqueued_at + overlay_tx [ frame - > queue ] . small_packet_grace_interval ;
2013-02-06 17:10:43 +10:30
overlay_queue_schedule_next ( next_allowed_packet ) ;
2012-11-20 16:41:06 +10:30
2012-12-19 10:38:17 +10:30
return 0 ;
2012-11-20 16:41:06 +10:30
}
static void
2014-06-26 16:47:23 +09:30
overlay_stuff_packet ( struct outgoing_packet * packet , overlay_txqueue * queue , time_ms_t now , strbuf debug ) {
2012-11-20 16:41:06 +10:30
struct overlay_frame * frame = queue - > first ;
// TODO stop when the packet is nearly full?
while ( frame ) {
2015-03-30 14:15:08 +10:30
if ( queue - > latencyTarget ! = 0 & & frame - > enqueued_at + queue - > latencyTarget < now ) {
2015-11-30 14:22:45 +10:30
DEBUGF ( ack , " Dropping frame (%p) type %x (length %zu) for %s due to expiry timeout " ,
frame , frame - > type , frame - > payload - > checkpointLength ,
2015-07-06 17:49:49 +09:30
frame - > destination ? alloca_tohex_sid_t ( frame - > destination - > sid ) : " All "
) ;
2012-11-20 16:41:06 +10:30
frame = overlay_queue_remove ( queue , frame ) ;
continue ;
}
2012-12-13 17:50:09 +10:30
2013-08-08 15:20:31 +09:30
/* Note, once we queue a broadcast packet we are currently
* committed to sending it to every destination ,
* even if we hear it from somewhere else in the mean time
2012-11-20 16:41:06 +10:30
*/
2013-05-15 11:33:43 +09:30
// ignore payloads that are waiting for ack / nack resends
2013-08-08 15:20:31 +09:30
if ( frame - > delay_until > now )
2013-05-15 11:33:43 +09:30
goto skip ;
2015-03-16 12:22:38 +10:30
if ( packet - > buffer & & packet - > destination - > ifconfig . encapsulation = = ENCAP_SINGLE )
2013-08-08 15:20:31 +09:30
goto skip ;
2012-12-13 17:50:09 +10:30
// quickly skip payloads that have no chance of fitting
2015-03-30 11:27:37 +10:30
if ( packet - > buffer & & ob_position ( frame - > payload ) > ob_remaining ( packet - > buffer ) )
2012-12-13 17:50:09 +10:30
goto skip ;
2015-06-22 12:30:18 +09:30
if ( ! frame - > manual_destinations )
link_add_destinations ( frame ) ;
2013-08-08 15:20:31 +09:30
2015-06-22 10:43:54 +09:30
if ( frame - > mdp_sequence ! = - 1 & & ( ( mdp_sequence - frame - > mdp_sequence ) & 0xFFFF ) > = 64 ) {
2014-06-28 20:17:26 +09:30
// too late, we've sent too many packets for the next hop to correctly de-duplicate
2015-07-06 17:49:49 +09:30
DEBUGF ( overlayframes , " Retransmition of frame %p mdp seq %d, is too late to be de-duplicated " ,
frame , frame - > mdp_sequence ) ;
2014-06-28 20:17:26 +09:30
frame = overlay_queue_remove ( queue , frame ) ;
continue ;
}
2013-08-08 15:20:31 +09:30
int destination_index = - 1 ;
{
int i ;
for ( i = frame - > destination_count - 1 ; i > = 0 ; i - - ) {
struct network_destination * dest = frame - > destinations [ i ] . destination ;
if ( ! dest )
FATALF ( " Destination %d is NULL " , i ) ;
if ( ! dest - > interface )
FATALF ( " Destination interface %d is NULL " , i ) ;
if ( dest - > interface - > state ! = INTERFACE_STATE_UP ) {
// remove this destination
2015-03-30 11:27:37 +10:30
frame_remove_destination ( frame , i ) ;
continue ;
}
2015-03-30 14:15:08 +10:30
if ( frame - > enqueued_at + dest - > ifconfig . transmit_timeout_ms < now ) {
2015-11-30 14:22:45 +10:30
DEBUGF ( ack , " Dropping %p, %s packet destination for %s sent w. seq %d, %dms ago " ,
frame , dest - > unicast ? " unicast " : " broadcast " ,
frame - > whence . function , frame - > destinations [ i ] . sent_sequence ,
( int ) ( gettime_ms ( ) - frame - > destinations [ i ] . transmit_time ) ) ;
2015-03-30 14:15:08 +10:30
frame_remove_destination ( frame , i ) ;
continue ;
}
2015-03-30 11:27:37 +10:30
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 ) ;
2013-08-08 15:20:31 +09:30
continue ;
}
2014-09-23 13:47:48 +09:30
// degrade packet version if required to reach the destination
if ( frame - > destinations [ i ] . next_hop
& & frame - > packet_version > frame - > destinations [ i ] . next_hop - > max_packet_version )
frame - > packet_version = frame - > destinations [ i ] . next_hop - > max_packet_version ;
2013-08-08 15:20:31 +09:30
2013-08-29 15:05:32 +09:30
if ( frame - > destinations [ i ] . transmit_time & &
frame - > destinations [ i ] . transmit_time + frame - > destinations [ i ] . destination - > resend_delay > now )
2013-08-08 15:20:31 +09:30
continue ;
2012-11-20 16:41:06 +10:30
2012-12-03 13:44:31 +10:30
if ( packet - > buffer ) {
2013-08-08 15:20:31 +09:30
if ( frame - > packet_version ! = packet - > packet_version )
continue ;
2012-12-03 13:44:31 +10:30
2013-08-08 15:20:31 +09:30
// is this packet going our way?
if ( dest = = packet - > destination ) {
destination_index = i ;
2012-12-13 17:50:09 +10:30
break ;
2012-12-03 13:44:31 +10:30
}
2013-08-08 15:20:31 +09:30
} else {
// skip this interface if the stream tx buffer has data
2013-11-25 15:05:33 +10:30
if ( radio_link_is_busy ( dest - > interface ) )
2012-12-03 13:44:31 +10:30
continue ;
2013-08-08 15:20:31 +09:30
2015-03-16 12:22:38 +10:30
// can we send a packet to this destination now?
2013-08-08 15:20:31 +09:30
if ( limit_is_allowed ( & dest - > transfer_limit ) )
continue ;
// send a packet to this destination
if ( frame - > source_full )
2016-10-19 05:26:11 -04:00
get_my_subscriber ( 1 ) - > send_full = 1 ;
2013-11-25 16:43:32 +10:30
if ( overlay_init_packet ( packet , frame - > packet_version , dest ) ! = - 1 ) {
2014-06-26 16:47:23 +09:30
if ( debug ) {
strbuf_sprintf ( debug , " building packet %s %s %d [ " ,
packet - > destination - > interface - > name ,
alloca_socket_address ( & packet - > destination - > address ) ,
packet - > seq ) ;
}
2013-11-25 16:43:32 +10:30
destination_index = i ;
frame - > destinations [ i ] . sent_sequence = dest - > sequence_number ;
break ;
}
2012-11-20 16:41:06 +10:30
}
}
}
2013-08-08 15:20:31 +09:30
if ( frame - > destination_count = = 0 ) {
frame = overlay_queue_remove ( queue , frame ) ;
continue ;
2013-05-15 14:27:38 +09:30
}
2012-12-03 13:44:31 +10:30
2013-08-08 15:20:31 +09:30
if ( destination_index = = - 1 )
goto skip ;
2013-05-15 14:27:38 +09:30
if ( frame - > send_hook ) {
// last minute check if we really want to send this frame, or track when we sent it
2015-06-22 12:30:18 +09:30
if ( frame - > send_hook ( frame , packet - > destination , packet - > seq , frame - > send_context ) ) {
2013-05-15 14:27:38 +09:30
// drop packet
frame = overlay_queue_remove ( queue , frame ) ;
continue ;
}
}
2013-08-30 17:24:52 +09:30
2015-06-22 10:43:54 +09:30
if ( frame - > mdp_sequence = = - 1 ) {
frame - > mdp_sequence = mdp_sequence = ( mdp_sequence + 1 ) & 0xFFFF ;
}
2013-08-30 17:24:52 +09:30
char will_retransmit = 1 ;
if ( frame - > packet_version < 1 | | frame - > resend < = 0 | | packet - > seq = = - 1 )
will_retransmit = 0 ;
2015-03-16 12:22:38 +10:30
if ( overlay_frame_append_payload ( & packet - > context , packet - > destination - > ifconfig . encapsulation , frame ,
2014-09-23 13:47:48 +09:30
frame - > destinations [ destination_index ] . next_hop , packet - > buffer , will_retransmit ) ) {
2013-07-15 15:29:14 +09:30
// payload was not queued, delay the next attempt slightly
2013-08-08 15:20:31 +09:30
frame - > delay_until = now + 5 ;
2013-07-15 15:29:14 +09:30
goto skip ;
2013-05-24 13:52:31 +09:30
}
2013-08-29 15:05:32 +09:30
2014-09-23 13:47:48 +09:30
frame - > transmit_count + + ;
2013-08-29 15:05:32 +09:30
{
struct packet_destination * dest = & frame - > destinations [ destination_index ] ;
dest - > sent_sequence = dest - > destination - > sequence_number ;
dest - > transmit_time = now ;
2014-09-23 13:47:48 +09:30
if ( debug )
strbuf_sprintf ( debug , " %d(%s), " , frame - > mdp_sequence , frame - > whence . function ) ;
2015-07-06 17:49:49 +09:30
DEBUGF ( overlayframes , " Appended payload %p, %d type %x len %zd for %s via %s " ,
frame , frame - > mdp_sequence ,
frame - > type , ob_position ( frame - > payload ) ,
frame - > destination ? alloca_tohex_sid_t ( frame - > destination - > sid ) : " All " ,
dest - > next_hop ? alloca_tohex_sid_t ( dest - > next_hop - > sid ) : alloca_tohex ( frame - > broadcast_id . id , BROADCAST_LEN )
) ;
2013-08-29 15:05:32 +09:30
}
2013-02-07 15:16:07 +10:30
2013-08-08 15:20:31 +09:30
// dont retransmit if we aren't sending sequence numbers, or we've been asked not to
2013-08-30 17:24:52 +09:30
if ( ! will_retransmit ) {
2015-07-06 17:49:49 +09:30
DEBUGF ( overlayframes , " Not waiting for retransmission (%d, %d, %d) " , frame - > packet_version , frame - > resend , packet - > seq ) ;
2015-03-30 11:27:37 +10:30
frame_remove_destination ( frame , destination_index ) ;
2013-08-08 15:20:31 +09:30
if ( frame - > destination_count = = 0 ) {
frame = overlay_queue_remove ( queue , frame ) ;
continue ;
2012-11-20 16:41:06 +10:30
}
}
2013-05-22 13:27:41 +09:30
2012-11-20 16:41:06 +10:30
skip :
2012-12-04 14:47:57 +10:30
// if we can't send the payload now, check when we should try next
2013-12-09 18:22:18 +10:30
overlay_calc_queue_time ( frame ) ;
2012-11-20 16:41:06 +10:30
frame = frame - > next ;
}
}
// fill a packet from our outgoing queues and send it
2017-11-20 10:39:32 +10:30
static void
2014-06-26 16:47:23 +09:30
overlay_fill_send_packet ( struct outgoing_packet * packet , time_ms_t now , strbuf debug ) {
2012-11-20 16:41:06 +10:30
IN ( ) ;
2013-08-13 15:16:17 +09:30
int i ;
2014-06-26 16:47:23 +09:30
2012-11-20 16:41:06 +10:30
// while we're looking at queues, work out when to schedule another packet
unschedule ( & next_packet ) ;
next_packet . alarm = 0 ;
next_packet . deadline = 0 ;
for ( i = 0 ; i < OQ_MAX ; i + + ) {
overlay_txqueue * queue = & overlay_tx [ i ] ;
2014-06-26 16:47:23 +09:30
overlay_stuff_packet ( packet , queue , now , debug ) ;
2012-11-20 16:41:06 +10:30
}
if ( packet - > buffer ) {
2014-06-26 16:47:23 +09:30
if ( debug ) {
strbuf_sprintf ( debug , " ] " ) ;
2015-07-06 17:49:49 +09:30
_DEBUGF ( " %s " , strbuf_str ( debug ) ) ;
2014-06-26 16:47:23 +09:30
}
2017-11-20 10:39:32 +10:30
2013-09-11 11:13:33 +09:30
overlay_broadcast_ensemble ( packet - > destination , packet - > buffer ) ;
2012-11-20 16:41:06 +10:30
}
2013-08-13 15:16:17 +09:30
if ( packet - > destination )
release_destination_ref ( packet - > destination ) ;
2013-02-17 04:17:24 +10:30
OUT ( ) ;
2012-11-20 16:41:06 +10:30
}
// when the queue timer elapses, send a packet
2013-12-09 18:22:18 +10:30
static void overlay_send_packet ( struct sched_ent * UNUSED ( alarm ) )
{
2012-11-20 16:41:06 +10:30
struct outgoing_packet packet ;
bzero ( & packet , sizeof ( struct outgoing_packet ) ) ;
2013-05-22 13:27:41 +09:30
packet . seq = - 1 ;
2015-07-06 17:49:49 +09:30
strbuf debug = IF_DEBUG ( packets_sent ) ? strbuf_alloca ( 256 ) : NULL ;
2014-06-26 16:47:23 +09:30
overlay_fill_send_packet ( & packet , gettime_ms ( ) , debug ) ;
2012-11-20 16:41:06 +10:30
}
2013-04-30 16:35:45 +09:30
2013-11-25 16:43:32 +10:30
int overlay_send_tick_packet ( struct network_destination * destination )
{
2013-04-30 16:35:45 +09:30
struct outgoing_packet packet ;
bzero ( & packet , sizeof ( struct outgoing_packet ) ) ;
2014-06-26 16:47:23 +09:30
if ( overlay_init_packet ( & packet , 0 , destination ) ! = - 1 ) {
strbuf debug = NULL ;
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( packets_sent ) ) {
2014-06-26 16:47:23 +09:30
debug = strbuf_alloca ( 256 ) ;
strbuf_sprintf ( debug , " building packet %s %s %d [ " ,
packet . destination - > interface - > name ,
alloca_socket_address ( & packet . destination - > address ) ,
packet . seq ) ;
}
overlay_fill_send_packet ( & packet , gettime_ms ( ) , debug ) ;
2016-09-06 15:00:21 +09:30
// This debug statement is used for testing; do not remove or alter.
DEBUGF ( overlaytick , " TICK name=%s destination=%s seq=%d " ,
packet . destination - > interface - > name ,
alloca_socket_address ( & packet . destination - > address ) ,
packet . seq ) ;
2014-06-26 16:47:23 +09:30
}
2013-04-30 16:35:45 +09:30
return 0 ;
}
2013-05-13 12:23:44 +09:30
2013-05-15 11:33:43 +09:30
// de-queue all packets that have been sent to this subscriber & have arrived.
2013-08-08 15:20:31 +09:30
int overlay_queue_ack ( struct subscriber * neighbour , struct network_destination * destination , uint32_t ack_mask , int ack_seq )
2013-05-13 12:23:44 +09:30
{
2013-08-08 15:20:31 +09:30
int i , j ;
2013-05-20 13:23:35 +09:30
time_ms_t now = gettime_ms ( ) ;
2014-05-12 13:39:46 +09:30
int rtt = 0 ;
2013-05-15 11:33:43 +09:30
for ( i = 0 ; i < OQ_MAX ; i + + ) {
struct overlay_frame * frame = overlay_tx [ i ] . first ;
2013-05-13 12:23:44 +09:30
2013-05-15 11:33:43 +09:30
while ( frame ) {
2013-08-12 14:21:31 +09:30
for ( j = frame - > destination_count - 1 ; j > = 0 ; j - - )
if ( frame - > destinations [ j ] . destination = = destination )
break ;
if ( j > = 0 ) {
int frame_seq = frame - > destinations [ j ] . sent_sequence ;
2014-09-23 13:47:48 +09:30
if ( frame_seq > = 0 & & ( frame - > destinations [ j ] . next_hop = = neighbour | | ! frame - > destination ) ) {
2013-08-12 14:21:31 +09:30
int seq_delta = ( ack_seq - frame_seq ) & 0xFF ;
2016-01-25 17:02:21 +10:30
char acked = ( seq_delta = = 0 | | ( seq_delta < = 32 & & ack_mask & ( ( uint32_t ) 1 < < ( seq_delta - 1 ) ) ) ) ? 1 : 0 ;
2013-08-12 14:21:31 +09:30
if ( acked ) {
2014-05-12 13:39:46 +09:30
int this_rtt = now - frame - > destinations [ j ] . transmit_time ;
2013-12-16 14:54:30 +10:30
// if we're on a fake network, the actual rtt can be unrealistic
2014-05-12 13:39:46 +09:30
if ( this_rtt < 10 )
this_rtt = 10 ;
if ( ! rtt | | this_rtt < rtt )
rtt = this_rtt ;
2013-08-29 15:05:32 +09:30
2015-07-06 17:49:49 +09:30
DEBUGF ( ack , " DROPPED DUE TO ACK: Packet %p to %s sent by seq %d, acked with seq %d " ,
frame , alloca_tohex_sid_t ( neighbour - > sid ) , frame_seq , ack_seq ) ;
2013-08-12 14:21:31 +09:30
// drop packets that don't need to be retransmitted
if ( frame - > destination | | frame - > destination_count < = 1 ) {
frame = overlay_queue_remove ( & overlay_tx [ i ] , frame ) ;
continue ;
2013-05-20 13:23:35 +09:30
}
2015-03-30 11:27:37 +10:30
frame_remove_destination ( frame , j ) ;
2013-08-12 14:21:31 +09:30
} else if ( seq_delta < 128 & & frame - > destination & & frame - > delay_until > now ) {
// retransmit asap
2015-07-06 17:49:49 +09:30
DEBUGF ( ack , " RE-TX DUE TO NACK: Requeue packet %p to %s sent by seq %d due to ack of seq %d " , frame , alloca_tohex_sid_t ( neighbour - > sid ) , frame_seq , ack_seq ) ;
2013-08-12 14:21:31 +09:30
frame - > delay_until = now ;
2013-12-09 18:22:18 +10:30
overlay_calc_queue_time ( frame ) ;
2013-05-20 13:23:35 +09:30
}
2013-05-15 11:33:43 +09:30
}
}
2013-08-08 15:20:31 +09:30
2013-08-12 14:21:31 +09:30
frame = frame - > next ;
2013-05-15 11:33:43 +09:30
}
}
2014-05-12 13:39:46 +09:30
if ( rtt ) {
if ( ! destination - > min_rtt | | rtt < destination - > min_rtt ) {
destination - > min_rtt = rtt ;
int delay = rtt * 2 + 40 ;
if ( delay < destination - > resend_delay ) {
destination - > resend_delay = delay ;
2015-07-06 17:49:49 +09:30
DEBUGF ( linkstate , " Adjusting resend delay to %d " , destination - > resend_delay ) ;
2014-05-12 13:39:46 +09:30
}
}
if ( ! destination - > max_rtt | | rtt > destination - > max_rtt )
destination - > max_rtt = rtt ;
}
2013-05-13 12:23:44 +09:30
return 0 ;
}