2011-12-21 20:25:05 +10:30
/*
Serval Distributed Numbering Architecture ( DNA )
Copyright ( C ) 2010 Paul Gardner - Stephen
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 .
*/
2012-02-23 12:45:42 +10:30
# include "serval.h"
2012-12-11 15:59:46 +10:30
# include "conf.h"
2013-11-29 12:56:59 +10:30
# include "socket.h"
2012-11-07 16:42:45 +10:30
# include "str.h"
2012-07-17 15:30:50 +09:30
# include "strbuf.h"
2013-12-09 17:45:47 +10:30
# include "strbuf_helpers.h"
2012-08-22 10:21:38 +09:30
# include "overlay_buffer.h"
2013-12-09 17:45:47 +10:30
# include "overlay_interface.h"
2012-08-27 10:04:59 +09:30
# include "overlay_packet.h"
2015-08-31 15:18:08 +09:30
# include "route_link.h"
2013-12-09 17:45:47 +10:30
2012-09-27 15:14:43 +09:30
struct sockaddr_in loopback ;
2012-01-12 16:47:24 +10:30
2012-11-21 15:30:20 +10:30
2012-12-14 17:00:54 +10:30
# define PACKET_UNICAST (1<<0)
# define PACKET_INTERFACE (1<<1)
# define PACKET_SEQ (1<<2)
2013-05-24 13:52:31 +09:30
# define SUPPORTED_PACKET_VERSION 1
int overlay_packet_init_header ( int packet_version , int encapsulation ,
2013-02-14 14:18:56 +10:30
struct decode_context * context , struct overlay_buffer * buff ,
2013-05-15 11:33:43 +09:30
char unicast , char interface , int seq ) {
2012-12-14 17:00:54 +10:30
2013-05-24 13:52:31 +09:30
if ( packet_version < 0 | | packet_version > SUPPORTED_PACKET_VERSION )
return WHY ( " Invalid packet version " ) ;
2013-02-14 14:18:56 +10:30
if ( encapsulation ! = ENCAP_OVERLAY & & encapsulation ! = ENCAP_SINGLE )
return WHY ( " Invalid packet encapsulation " ) ;
2013-11-25 16:43:32 +10:30
ob_append_byte ( buff , packet_version ) ;
ob_append_byte ( buff , encapsulation ) ;
2013-08-08 15:20:31 +09:30
2015-03-16 12:22:38 +10:30
if ( context - > interface - > ifconfig . point_to_point
2013-11-25 16:43:32 +10:30
& & context - > interface - > other_device
& & packet_version > = 1
)
2013-08-08 15:20:31 +09:30
context - > point_to_point_device = context - > interface - > other_device ;
2015-11-16 13:47:28 +10:30
context - > flags = DECODE_FLAG_ENCODING_HEADER ;
2016-06-15 17:08:25 +09:30
overlay_address_append ( context , buff , get_my_subscriber ( ) ) ;
2013-08-08 15:20:31 +09:30
2015-11-16 13:47:28 +10:30
context - > flags = 0 ;
2016-06-15 17:08:25 +09:30
context - > sender = get_my_subscriber ( ) ;
2012-12-14 17:00:54 +10:30
int flags = 0 ;
if ( unicast )
flags | = PACKET_UNICAST ;
if ( interface )
flags | = PACKET_INTERFACE ;
2013-05-03 16:23:23 +09:30
if ( seq > = 0 )
2012-12-14 17:00:54 +10:30
flags | = PACKET_SEQ ;
2012-12-04 14:47:57 +10:30
ob_append_byte ( buff , flags ) ;
2012-12-14 17:00:54 +10:30
if ( flags & PACKET_INTERFACE )
ob_append_byte ( buff , interface ) ;
if ( flags & PACKET_SEQ )
ob_append_byte ( buff , seq ) ;
2012-11-26 15:21:01 +10:30
return 0 ;
2012-11-21 15:30:20 +10:30
}
2012-08-27 10:04:59 +09:30
// a frame destined for one of our local addresses, or broadcast, has arrived. Process it.
2013-12-10 17:22:50 +10:30
int process_incoming_frame ( time_ms_t now , struct overlay_interface * UNUSED ( interface ) , struct overlay_frame * f , struct decode_context * context )
{
2012-11-23 16:25:32 +10:30
IN ( ) ;
2012-08-27 10:04:59 +09:30
switch ( f - > type )
{
2013-05-09 14:59:33 +09:30
case OF_TYPE_SELFANNOUNCE_ACK :
link_state_legacy_ack ( f , now ) ;
break ;
2012-08-27 10:04:59 +09:30
// data frames
case OF_TYPE_RHIZOME_ADVERT :
2013-12-09 18:22:18 +10:30
overlay_rhizome_saw_advertisements ( context , f ) ;
2012-08-27 10:04:59 +09:30
break ;
case OF_TYPE_DATA :
2013-12-09 18:22:18 +10:30
overlay_saw_mdp_containing_frame ( f ) ;
2012-08-27 10:04:59 +09:30
break ;
2012-09-19 14:16:40 +09:30
case OF_TYPE_PLEASEEXPLAIN :
process_explain ( f ) ;
break ;
2012-08-27 10:04:59 +09:30
default :
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " Overlay type f->type=0x%x not supported " , f - > type ) ;
2012-08-27 10:04:59 +09:30
}
2012-11-23 16:25:32 +10:30
RETURN ( 0 ) ;
2013-02-17 04:17:24 +10:30
OUT ( ) ;
2012-08-27 10:04:59 +09:30
}
// duplicate the frame and queue it
int overlay_forward_payload ( struct overlay_frame * f ) {
2012-11-23 16:25:32 +10:30
IN ( ) ;
2013-04-30 16:35:45 +09:30
if ( f - > ttl = = 0 ) {
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " NOT FORWARDING, due to ttl=0 " ) ;
2012-11-23 16:25:32 +10:30
RETURN ( 0 ) ;
2013-04-30 16:35:45 +09:30
}
2012-08-27 10:04:59 +09:30
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " Forwarding payload for %s, ttl=%u " ,
2013-10-09 18:54:21 +10:30
( f - > destination ? alloca_tohex_sid_t ( f - > destination - > sid ) : " broadcast " ) ,
2013-04-12 17:16:50 +09:30
( unsigned ) f - > ttl ) ;
2012-08-27 10:04:59 +09:30
/* Queue frame for dispatch.
Don ' t forget to put packet in the correct queue based on type .
( e . g . , mesh management , voice , video , ordinary or opportunistic ) .
But the really important bit is to clone the frame , since the
structure we are looking at here must be left as is and returned
to the caller to do as they please */
struct overlay_frame * qf = op_dup ( f ) ;
if ( ! qf )
2012-11-23 16:25:32 +10:30
RETURN ( WHY ( " Could not clone frame for queuing " ) ) ;
2012-08-27 10:04:59 +09:30
2012-10-09 15:44:37 +10:30
if ( overlay_payload_enqueue ( qf ) ) {
2012-08-27 10:04:59 +09:30
op_free ( qf ) ;
2012-11-23 16:25:32 +10:30
RETURN ( WHY ( " failed to enqueue forwarded payload " ) ) ;
2012-08-27 10:04:59 +09:30
}
2012-11-23 16:25:32 +10:30
RETURN ( 0 ) ;
2013-02-17 04:17:24 +10:30
OUT ( ) ;
2012-08-27 10:04:59 +09:30
}
2013-02-07 15:16:07 +10:30
// Parse the mdp envelope header
// may return (HEADER_PROCESS|HEADER_FORWARD) || -1
int parseMdpPacketHeader ( struct decode_context * context , struct overlay_frame * frame ,
2013-04-23 16:02:39 +09:30
struct overlay_buffer * buffer , struct subscriber * * nexthop )
{
2013-02-14 14:18:56 +10:30
IN ( ) ;
2013-02-07 15:16:07 +10:30
int process = 1 ;
int forward = 2 ;
int flags = ob_get ( buffer ) ;
if ( flags < 0 )
2013-02-14 14:18:56 +10:30
RETURN ( WHY ( " Unable to read flags " ) ) ;
2013-02-07 15:16:07 +10:30
if ( flags & PAYLOAD_FLAG_SENDER_SAME ) {
if ( ! context - > sender )
2015-11-16 13:47:28 +10:30
context - > flags | = DECODE_FLAG_INVALID_ADDRESS ;
2013-02-07 15:16:07 +10:30
frame - > source = context - > sender ;
} else {
int ret = overlay_address_parse ( context , buffer , & frame - > source ) ;
if ( ret < 0 )
2013-02-14 14:18:56 +10:30
RETURN ( WHY ( " Unable to parse payload source " ) ) ;
if ( ! frame - > source | | frame - > source - > reachable = = REACHABLE_SELF ) {
2013-02-07 15:16:07 +10:30
process = forward = 0 ;
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " Ignoring my packet (or unparsable source) " ) ;
2013-02-14 14:18:56 +10:30
}
2013-02-07 15:16:07 +10:30
}
if ( flags & PAYLOAD_FLAG_TO_BROADCAST ) {
if ( ! ( flags & PAYLOAD_FLAG_ONE_HOP ) ) {
if ( overlay_broadcast_parse ( buffer , & frame - > broadcast_id ) )
2013-02-14 14:18:56 +10:30
RETURN ( WHY ( " Unable to read broadcast address " ) ) ;
2013-02-07 15:16:07 +10:30
if ( overlay_broadcast_drop_check ( & frame - > broadcast_id ) ) {
process = forward = 0 ;
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " Ignoring duplicate broadcast (%s) " , alloca_tohex ( frame - > broadcast_id . id , BROADCAST_LEN ) ) ;
2013-02-07 15:16:07 +10:30
}
2013-05-29 11:14:26 +09:30
if ( link_state_should_forward_broadcast ( context - > sender ) = = 0 ) {
forward = 0 ;
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " Not forwarding broadcast (%s), as we aren't a relay in the senders routing table " , alloca_tohex ( frame - > broadcast_id . id , BROADCAST_LEN ) ) ;
2013-05-29 11:14:26 +09:30
}
2013-02-07 15:16:07 +10:30
}
frame - > destination = NULL ;
} else {
int ret = overlay_address_parse ( context , buffer , & frame - > destination ) ;
if ( ret < 0 )
2013-02-14 14:18:56 +10:30
RETURN ( WHY ( " Unable to parse payload destination " ) ) ;
2013-02-07 15:16:07 +10:30
2013-02-14 14:18:56 +10:30
if ( ! frame - > destination | | frame - > destination - > reachable ! = REACHABLE_SELF ) {
2013-02-07 15:16:07 +10:30
process = 0 ;
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " Don't process packet not addressed to me " ) ;
2013-02-14 14:18:56 +10:30
}
2013-02-07 15:16:07 +10:30
if ( ! ( flags & PAYLOAD_FLAG_ONE_HOP ) ) {
ret = overlay_address_parse ( context , buffer , nexthop ) ;
if ( ret < 0 )
2013-02-14 14:18:56 +10:30
RETURN ( WHY ( " Unable to parse payload nexthop " ) ) ;
2013-02-07 15:16:07 +10:30
2013-02-14 14:18:56 +10:30
if ( ! ( * nexthop ) | | ( * nexthop ) - > reachable ! = REACHABLE_SELF ) {
2013-02-07 15:16:07 +10:30
forward = 0 ;
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " Don't forward packet not addressed to me " ) ;
2013-02-14 14:18:56 +10:30
}
2013-02-07 15:16:07 +10:30
}
}
2013-04-23 16:02:39 +09:30
if ( flags & PAYLOAD_FLAG_ONE_HOP ) {
2013-02-07 15:16:07 +10:30
frame - > ttl = 1 ;
2013-04-23 16:02:39 +09:30
} else {
2013-02-07 15:16:07 +10:30
int ttl_qos = ob_get ( buffer ) ;
if ( ttl_qos < 0 )
2013-02-14 14:18:56 +10:30
RETURN ( WHY ( " Unable to read ttl " ) ) ;
2013-02-07 15:16:07 +10:30
frame - > ttl = ttl_qos & 0x1F ;
frame - > queue = ( ttl_qos > > 5 ) & 3 ;
}
2013-04-23 16:02:39 +09:30
if ( frame - > ttl )
- - frame - > ttl ;
if ( frame - > ttl = = 0 ) {
2013-04-12 17:16:50 +09:30
forward = 0 ;
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " NOT FORWARDING, due to ttl=0 " ) ;
2013-04-23 16:02:39 +09:30
}
2013-02-07 15:16:07 +10:30
if ( flags & PAYLOAD_FLAG_LEGACY_TYPE ) {
2013-04-12 17:16:50 +09:30
int ftype = ob_get ( buffer ) ;
if ( ftype = = - 1 )
2013-02-14 14:18:56 +10:30
RETURN ( WHY ( " Unable to read type " ) ) ;
2013-04-12 17:16:50 +09:30
frame - > type = ftype ;
2013-02-07 15:16:07 +10:30
} else
frame - > type = OF_TYPE_DATA ;
2013-05-15 15:56:43 +09:30
2013-06-03 16:04:08 +09:30
if ( context - > packet_version > = 1 ) {
2013-05-24 13:52:31 +09:30
int seq = ob_get ( buffer ) ;
if ( seq = = - 1 )
RETURN ( WHY ( " Unable to read packet seq " ) ) ;
2015-08-03 11:12:39 +09:30
if ( link_received_duplicate ( context , seq ) ) {
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( verbose ) )
DEBUG ( overlayframes , " Don't process or forward duplicate payloads " ) ;
2014-06-26 17:20:06 +09:30
forward = process = 0 ;
2013-05-15 15:56:43 +09:30
}
}
2013-02-07 15:16:07 +10:30
frame - > modifiers = flags ;
2013-05-24 13:52:31 +09:30
frame - > packet_version = context - > packet_version ;
2013-02-07 15:16:07 +10:30
// if we can't understand one of the addresses, skip processing the payload
2015-11-16 13:47:28 +10:30
if ( ( forward | | process ) & & ( context - > flags & DECODE_FLAG_INVALID_ADDRESS ) ) {
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( verbose ) )
DEBUG ( overlayframes , " Don't process or forward with invalid addresses " ) ;
2013-02-14 14:18:56 +10:30
forward = process = 0 ;
2013-02-07 15:16:07 +10:30
}
2013-02-14 14:18:56 +10:30
RETURN ( forward | process ) ;
2013-02-17 04:17:24 +10:30
OUT ( ) ;
2013-02-07 15:16:07 +10:30
}
int parseEnvelopeHeader ( struct decode_context * context , struct overlay_interface * interface ,
2013-12-09 17:45:47 +10:30
struct socket_address * addr , struct overlay_buffer * buffer ) {
2013-02-14 14:18:56 +10:30
IN ( ) ;
2015-08-31 15:18:08 +09:30
2013-07-16 15:16:07 +09:30
context - > interface = interface ;
2015-03-16 12:22:38 +10:30
if ( interface - > ifconfig . point_to_point & & interface - > other_device )
2013-08-08 15:20:31 +09:30
context - > point_to_point_device = interface - > other_device ;
2013-07-16 15:16:07 +09:30
context - > sender_interface = 0 ;
2013-05-24 13:52:31 +09:30
context - > packet_version = ob_get ( buffer ) ;
2013-07-16 15:16:07 +09:30
2013-05-24 13:52:31 +09:30
if ( context - > packet_version < 0 | | context - > packet_version > SUPPORTED_PACKET_VERSION )
2013-07-10 13:16:22 +09:30
RETURN ( WHYF ( " Packet version %d not recognised. " , context - > packet_version ) ) ;
2013-05-24 13:52:31 +09:30
context - > encapsulation = ob_get ( buffer ) ;
if ( context - > encapsulation ! = ENCAP_OVERLAY & & context - > encapsulation ! = ENCAP_SINGLE )
2013-07-10 13:16:22 +09:30
RETURN ( WHYF ( " Invalid packet encapsulation, %d " , context - > encapsulation ) ) ;
2013-05-24 13:52:31 +09:30
2013-02-07 15:16:07 +10:30
if ( overlay_address_parse ( context , buffer , & context - > sender ) )
2013-02-14 14:18:56 +10:30
RETURN ( WHY ( " Unable to parse sender " ) ) ;
2013-02-07 15:16:07 +10:30
int packet_flags = ob_get ( buffer ) ;
2013-04-26 16:53:04 +09:30
int sender_seq = - 1 ;
2013-02-07 15:16:07 +10:30
if ( packet_flags & PACKET_INTERFACE )
2013-05-15 15:56:43 +09:30
context - > sender_interface = ob_get ( buffer ) ;
2013-02-07 15:16:07 +10:30
if ( packet_flags & PACKET_SEQ )
2013-05-15 14:27:38 +09:30
sender_seq = ob_get ( buffer ) & 0xFF ;
2013-02-07 15:16:07 +10:30
2013-08-08 15:20:31 +09:30
if ( addr )
context - > addr = * addr ;
2013-02-07 15:16:07 +10:30
if ( context - > sender ) {
2013-02-14 14:18:56 +10:30
if ( context - > sender - > reachable = = REACHABLE_SELF ) {
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( verbose ) )
DEBUG ( overlayframes , " Completely ignore packets I sent " ) ;
2013-02-14 14:18:56 +10:30
RETURN ( 1 ) ;
}
2013-08-08 15:20:31 +09:30
2013-08-09 16:19:45 +09:30
if ( context - > packet_version > context - > sender - > max_packet_version )
context - > sender - > max_packet_version = context - > packet_version ;
2015-03-16 12:22:38 +10:30
if ( interface - > ifconfig . point_to_point & & interface - > other_device ! = context - > sender ) {
2013-10-09 18:54:21 +10:30
INFOF ( " Established point to point link with %s on %s " , alloca_tohex_sid_t ( context - > sender - > sid ) , interface - > name ) ;
2013-08-08 15:20:31 +09:30
context - > point_to_point_device = context - > interface - > other_device = context - > sender ;
2013-07-16 15:16:07 +09:30
}
2013-02-07 15:16:07 +10:30
2015-07-06 17:49:49 +09:30
DEBUGF ( overlayframes , " Received %s packet seq %d from %s on %s %s " ,
2013-08-09 12:18:14 +09:30
packet_flags & PACKET_UNICAST ? " unicast " : " broadcast " ,
2015-06-22 12:30:18 +09:30
sender_seq , alloca_tohex_sid_t ( context - > sender - > sid ) ,
interface - > name , alloca_socket_address ( addr ) ) ;
2013-02-07 15:16:07 +10:30
}
2015-08-03 11:12:39 +09:30
RETURN ( link_received_packet ( context , sender_seq , packet_flags & PACKET_UNICAST ) ) ;
2013-02-17 04:17:24 +10:30
OUT ( ) ;
2013-02-07 15:16:07 +10:30
}
2012-07-03 15:36:51 +09:30
int packetOkOverlay ( struct overlay_interface * interface , unsigned char * packet , size_t len ,
2013-12-09 18:22:18 +10:30
struct socket_address * recvaddr )
2011-08-15 09:27:29 +02:00
{
2012-11-23 16:25:32 +10:30
IN ( ) ;
2011-08-15 09:27:29 +02:00
/*
2012-07-18 14:54:23 +09:30
This function decodes overlay packets which have been assembled for delivery overy IP networks .
IP based wireless networks have a high , but limited rate of packets that can be sent . In order
to increase throughput of small payloads , we ammend many payloads together and have used a scheme
to compress common network identifiers .
A different network type may have very different constraints on the number and size of packets ,
and may need a different encoding scheme to use the bandwidth efficiently .
The current structure of an overlay packet is as follows ;
Fixed header [ 0x4F , 0x10 ]
Version [ 0x00 , 0x01 ]
Each frame within the packet has the following fields :
2011-08-17 10:52:17 +09:30
Frame type ( 8 - 24 bits )
2011-08-15 13:50:30 +02:00
TTL ( 8 bits )
2011-08-17 10:52:17 +09:30
Remaining frame size ( RFS ) ( see overlay_payload . c or overlay_buffer . c for explanation of format )
2011-08-15 09:27:29 +02:00
Next hop ( variable length due to address abbreviation )
2012-07-18 14:54:23 +09:30
Destination ( variable length due to address abbreviation )
Source ( variable length due to address abbreviation )
Payload ( length = RFS - len ( frame type ) - len ( next hop )
2011-08-15 09:27:29 +02:00
This structure is intended to allow relaying nodes to quickly ignore frames that are
not addressed to them as either the next hop or final destination .
The RFS field uses additional bytes to encode the length of longer frames .
This provides us with a slight space saving for the common case of short frames .
2012-07-18 14:54:23 +09:30
The frame payload itself can be enciphered with the final destination ' s public key , so
that it is not possible for the relaying 3 rd parties to observe the content .
2011-08-15 09:27:29 +02:00
Naturally some information will leak simply based on the size , periodicity and other
characteristics of the traffic , and some 3 rd parties may be malevolent , so noone should
assume that this provides complete security .
2012-07-18 14:54:23 +09:30
It would be possible to design a super - paranoid mode where onion routing is used with
concentric shells of encryption so that each hop can only work out the next node to send it
to . However , that would result in rather large frames , which may well betray more information
than the super - paranoid mode would hide .
2011-08-15 09:27:29 +02:00
Note also that it is possible to dispatch frames on a local link which are addressed to
broadcast , but are enciphered . In that situation only the intended recipient can
decode the frame , but at the cost of having all nodes on the local link having to decrypt
frame . Of course the nodes may elect to not decrypt such anonymous frames .
Such frames could even be flooded throughout part of the mesh by having the TTL > 1 , and
optionally with an anonymous source address to provide some plausible deniability for both
sending and reception if combined with a randomly selected TTL to give the impression of
the source having received the frame from elsewhere .
*/
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( packetrx ) | | interface - > ifconfig . debug ) {
_DEBUGF ( " Received on %s, len %d " , interface - > name , ( int ) len ) ;
2013-09-18 13:44:18 +09:30
DEBUG_packet_visualise ( " Received packet " , packet , len ) ;
}
2012-08-27 10:04:59 +09:30
struct overlay_frame f ;
2012-11-23 16:25:32 +10:30
struct decode_context context ;
bzero ( & context , sizeof context ) ;
2012-12-04 14:47:57 +10:30
bzero ( & f , sizeof f ) ;
2012-09-19 14:16:40 +09:30
2012-08-27 10:04:59 +09:30
time_ms_t now = gettime_ms ( ) ;
struct overlay_buffer * b = ob_static ( packet , len ) ;
ob_limitsize ( b , len ) ;
2012-11-21 15:30:20 +10:30
2013-08-08 15:20:31 +09:30
f . interface = interface ;
2013-02-07 15:16:07 +10:30
2013-12-09 17:45:47 +10:30
int ret = parseEnvelopeHeader ( & context , interface , recvaddr , b ) ;
2013-02-14 14:18:56 +10:30
if ( ret ) {
2013-02-07 15:16:07 +10:30
ob_free ( b ) ;
2013-02-14 14:18:56 +10:30
RETURN ( ret ) ;
2012-12-04 14:47:57 +10:30
}
2013-08-08 15:20:31 +09:30
f . sender_interface = context . sender_interface ;
2013-09-23 11:11:58 +09:30
interface - > recv_count + + ;
2012-12-04 14:47:57 +10:30
2013-02-14 14:18:56 +10:30
while ( ob_remaining ( b ) > 0 ) {
2015-11-16 13:47:28 +10:30
context . flags = 0 ;
2012-11-26 14:52:49 +10:30
struct subscriber * nexthop = NULL ;
bzero ( f . broadcast_id . id , BROADCAST_LEN ) ;
2013-05-30 13:24:37 +09:30
unsigned char * header_start = ob_ptr ( b ) + ob_position ( b ) ;
2013-02-14 14:18:56 +10:30
int header_valid = parseMdpPacketHeader ( & context , & f , b , & nexthop ) ;
if ( header_valid < 0 ) {
ret = WHY ( " Header is too short " ) ;
2013-02-07 15:16:07 +10:30
break ;
2012-11-26 14:52:49 +10:30
}
2013-08-08 15:20:31 +09:30
// TODO allow for single byte length?
2013-12-10 17:03:30 +10:30
size_t payload_len ;
2012-11-23 16:25:32 +10:30
2013-05-24 13:52:31 +09:30
switch ( context . encapsulation ) {
2013-02-14 14:18:56 +10:30
case ENCAP_SINGLE :
payload_len = ob_remaining ( b ) ;
break ;
2013-05-24 13:52:31 +09:30
default :
2013-02-14 14:18:56 +10:30
case ENCAP_OVERLAY :
payload_len = ob_get_ui16 ( b ) ;
if ( payload_len > ob_remaining ( b ) ) {
2013-05-30 13:24:37 +09:30
unsigned char * current = ob_ptr ( b ) + ob_position ( b ) ;
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( overlayframes ) )
2013-08-09 12:18:14 +09:30
dump ( " Payload Header " , header_start , current - header_start ) ;
2015-08-31 15:18:08 +09:30
ret = WHYF ( " Payload length %zd suggests frame should be %zd bytes, but was only %zd " ,
payload_len , ob_position ( b ) + payload_len , len ) ;
// TODO signal reduced MTU?
2013-02-14 14:18:56 +10:30
goto end ;
}
break ;
}
2012-12-16 10:05:32 +10:30
int next_payload = ob_position ( b ) + payload_len ;
2012-08-27 10:04:59 +09:30
2015-07-06 17:49:49 +09:30
if ( IF_DEBUG ( overlayframes ) ) {
DEBUGF ( overlayframes , " Received payload type %x, len %zd " , f . type , payload_len ) ;
DEBUGF ( overlayframes , " Payload from %s " , f . source ? alloca_tohex_sid_t ( f . source - > sid ) : " NULL " ) ;
DEBUGF ( overlayframes , " Payload to %s " , ( f . destination ? alloca_tohex_sid_t ( f . destination - > sid ) : " broadcast " ) ) ;
2013-02-14 14:18:56 +10:30
if ( ! is_all_matching ( f . broadcast_id . id , BROADCAST_LEN , 0 ) )
2015-07-06 17:49:49 +09:30
DEBUGF ( overlayframes , " Broadcast id %s " , alloca_tohex ( f . broadcast_id . id , BROADCAST_LEN ) ) ;
2013-02-14 14:18:56 +10:30
if ( nexthop )
2015-07-06 17:49:49 +09:30
DEBUGF ( overlayframes , " Next hop %s " , alloca_tohex_sid_t ( nexthop - > sid ) ) ;
2013-02-14 14:18:56 +10:30
}
if ( header_valid ! = 0 ) {
2012-08-27 10:04:59 +09:30
2013-12-10 17:03:30 +10:30
f . payload = ob_slice ( b , ob_position ( b ) , payload_len ) ;
2013-02-07 15:16:07 +10:30
if ( ! f . payload ) {
// out of memory?
WHY ( " Unable to slice payload " ) ;
break ;
}
// mark the entire payload as having valid data
ob_limitsize ( f . payload , payload_len ) ;
2012-08-27 10:04:59 +09:30
2013-02-07 15:16:07 +10:30
// forward payloads that are for someone else or everyone
2013-02-14 14:18:56 +10:30
if ( header_valid & HEADER_FORWARD )
2013-02-07 15:16:07 +10:30
overlay_forward_payload ( & f ) ;
// process payloads that are for me or everyone
2013-02-14 14:18:56 +10:30
if ( header_valid & HEADER_PROCESS )
2013-02-07 15:16:07 +10:30
process_incoming_frame ( now , interface , & f , & context ) ;
2013-05-15 11:33:43 +09:30
2013-08-30 15:11:48 +09:30
// We may need to schedule an ACK / NACK soon when we receive a payload addressed to us, or broadcast
2013-08-30 17:24:52 +09:30
if ( f . modifiers & PAYLOAD_FLAG_ACK_SOON & &
2016-06-15 17:08:25 +09:30
( f . next_hop = = get_my_subscriber ( ) | | f . destination = = get_my_subscriber ( ) | | ! f . destination ) )
2013-05-15 11:33:43 +09:30
link_state_ack_soon ( context . sender ) ;
2012-08-27 10:04:59 +09:30
}
if ( f . payload ) {
ob_free ( f . payload ) ;
f . payload = NULL ;
}
b - > position = next_payload ;
}
2012-07-17 15:30:50 +09:30
2013-02-14 14:18:56 +10:30
end :
2016-06-15 17:08:25 +09:30
send_please_explain ( & context , get_my_subscriber ( ) , context . sender ) ;
2012-11-23 16:25:32 +10:30
2012-08-27 10:04:59 +09:30
ob_free ( b ) ;
2012-09-19 14:16:40 +09:30
2013-02-14 14:18:56 +10:30
RETURN ( ret ) ;
2013-02-17 04:17:24 +10:30
OUT ( ) ;
2011-08-15 13:50:30 +02:00
}