2011-12-21 09:55:05 +00:00
/*
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 02:15:42 +00:00
# include "serval.h"
2012-12-11 05:29:46 +00:00
# include "conf.h"
2013-11-29 02:26:59 +00:00
# include "socket.h"
2012-11-07 06:12:45 +00:00
# include "str.h"
2012-07-17 06:00:50 +00:00
# include "strbuf.h"
2013-12-09 07:15:47 +00:00
# include "strbuf_helpers.h"
2012-08-22 00:51:38 +00:00
# include "overlay_buffer.h"
2013-12-09 07:15:47 +00:00
# include "overlay_interface.h"
2012-08-27 00:34:59 +00:00
# include "overlay_packet.h"
2011-08-15 07:27:29 +00:00
2013-12-09 07:15:47 +00:00
2012-09-27 05:44:43 +00:00
struct sockaddr_in loopback ;
2012-01-12 06:17:24 +00:00
2012-11-21 05:00:20 +00:00
2012-12-14 06:30:54 +00:00
# define PACKET_UNICAST (1<<0)
# define PACKET_INTERFACE (1<<1)
# define PACKET_SEQ (1<<2)
2013-05-24 04:22:31 +00:00
# define SUPPORTED_PACKET_VERSION 1
int overlay_packet_init_header ( int packet_version , int encapsulation ,
2013-02-14 03:48:56 +00:00
struct decode_context * context , struct overlay_buffer * buff ,
2013-05-15 02:03:43 +00:00
char unicast , char interface , int seq ) {
2012-12-14 06:30:54 +00:00
2013-05-24 04:22:31 +00:00
if ( packet_version < 0 | | packet_version > SUPPORTED_PACKET_VERSION )
return WHY ( " Invalid packet version " ) ;
2013-02-14 03:48:56 +00:00
if ( encapsulation ! = ENCAP_OVERLAY & & encapsulation ! = ENCAP_SINGLE )
return WHY ( " Invalid packet encapsulation " ) ;
2013-11-25 06:13:32 +00:00
ob_append_byte ( buff , packet_version ) ;
ob_append_byte ( buff , encapsulation ) ;
2013-08-08 05:50:31 +00:00
2015-03-16 01:52:38 +00:00
if ( context - > interface - > ifconfig . point_to_point
2013-11-25 06:13:32 +00:00
& & context - > interface - > other_device
& & packet_version > = 1
)
2013-08-08 05:50:31 +00:00
context - > point_to_point_device = context - > interface - > other_device ;
2013-07-16 05:46:07 +00:00
context - > encoding_header = 1 ;
2013-11-25 06:13:32 +00:00
overlay_address_append ( context , buff , my_subscriber ) ;
2013-08-08 05:50:31 +00:00
2013-07-16 05:46:07 +00:00
context - > encoding_header = 0 ;
2012-11-26 04:51:01 +00:00
context - > sender = my_subscriber ;
2012-12-14 06:30:54 +00:00
int flags = 0 ;
if ( unicast )
flags | = PACKET_UNICAST ;
if ( interface )
flags | = PACKET_INTERFACE ;
2013-05-03 06:53:23 +00:00
if ( seq > = 0 )
2012-12-14 06:30:54 +00:00
flags | = PACKET_SEQ ;
2012-12-04 04:17:57 +00:00
ob_append_byte ( buff , flags ) ;
2012-12-14 06:30:54 +00:00
if ( flags & PACKET_INTERFACE )
ob_append_byte ( buff , interface ) ;
if ( flags & PACKET_SEQ )
ob_append_byte ( buff , seq ) ;
2012-11-26 04:51:01 +00:00
return 0 ;
2012-11-21 05:00:20 +00:00
}
2012-08-27 00:34:59 +00:00
// a frame destined for one of our local addresses, or broadcast, has arrived. Process it.
2013-12-10 06:52:50 +00:00
int process_incoming_frame ( time_ms_t now , struct overlay_interface * UNUSED ( interface ) , struct overlay_frame * f , struct decode_context * context )
{
2012-11-23 05:55:32 +00:00
IN ( ) ;
2012-08-27 00:34:59 +00:00
switch ( f - > type )
{
2013-05-09 05:29:33 +00:00
case OF_TYPE_SELFANNOUNCE_ACK :
link_state_legacy_ack ( f , now ) ;
break ;
2012-08-27 00:34:59 +00:00
// data frames
case OF_TYPE_RHIZOME_ADVERT :
2013-12-09 07:52:18 +00:00
overlay_rhizome_saw_advertisements ( context , f ) ;
2012-08-27 00:34:59 +00:00
break ;
case OF_TYPE_DATA :
2013-12-09 07:52:18 +00:00
overlay_saw_mdp_containing_frame ( f ) ;
2012-08-27 00:34:59 +00:00
break ;
2012-09-19 04:46:40 +00:00
case OF_TYPE_PLEASEEXPLAIN :
process_explain ( f ) ;
break ;
2012-08-27 00:34:59 +00:00
default :
2015-07-06 08:19:49 +00:00
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " Overlay type f->type=0x%x not supported " , f - > type ) ;
2012-08-27 00:34:59 +00:00
}
2012-11-23 05:55:32 +00:00
RETURN ( 0 ) ;
2013-02-16 17:47:24 +00:00
OUT ( ) ;
2012-08-27 00:34:59 +00:00
}
// duplicate the frame and queue it
int overlay_forward_payload ( struct overlay_frame * f ) {
2012-11-23 05:55:32 +00:00
IN ( ) ;
2013-04-30 07:05:45 +00:00
if ( f - > ttl = = 0 ) {
2015-07-06 08:19:49 +00:00
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " NOT FORWARDING, due to ttl=0 " ) ;
2012-11-23 05:55:32 +00:00
RETURN ( 0 ) ;
2013-04-30 07:05:45 +00:00
}
2012-08-27 00:34:59 +00:00
2015-07-06 08:19:49 +00:00
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " Forwarding payload for %s, ttl=%u " ,
2013-10-09 08:24:21 +00:00
( f - > destination ? alloca_tohex_sid_t ( f - > destination - > sid ) : " broadcast " ) ,
2013-04-12 07:46:50 +00:00
( unsigned ) f - > ttl ) ;
2012-08-27 00:34:59 +00:00
/* 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 05:55:32 +00:00
RETURN ( WHY ( " Could not clone frame for queuing " ) ) ;
2012-08-27 00:34:59 +00:00
2012-10-09 05:14:37 +00:00
if ( overlay_payload_enqueue ( qf ) ) {
2012-08-27 00:34:59 +00:00
op_free ( qf ) ;
2012-11-23 05:55:32 +00:00
RETURN ( WHY ( " failed to enqueue forwarded payload " ) ) ;
2012-08-27 00:34:59 +00:00
}
2012-11-23 05:55:32 +00:00
RETURN ( 0 ) ;
2013-02-16 17:47:24 +00:00
OUT ( ) ;
2012-08-27 00:34:59 +00:00
}
2013-02-07 04:46:07 +00:00
// 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 06:32:39 +00:00
struct overlay_buffer * buffer , struct subscriber * * nexthop )
{
2013-02-14 03:48:56 +00:00
IN ( ) ;
2013-02-07 04:46:07 +00:00
int process = 1 ;
int forward = 2 ;
int flags = ob_get ( buffer ) ;
if ( flags < 0 )
2013-02-14 03:48:56 +00:00
RETURN ( WHY ( " Unable to read flags " ) ) ;
2013-02-07 04:46:07 +00:00
if ( flags & PAYLOAD_FLAG_SENDER_SAME ) {
if ( ! context - > sender )
context - > invalid_addresses = 1 ;
frame - > source = context - > sender ;
} else {
int ret = overlay_address_parse ( context , buffer , & frame - > source ) ;
if ( ret < 0 )
2013-02-14 03:48:56 +00:00
RETURN ( WHY ( " Unable to parse payload source " ) ) ;
if ( ! frame - > source | | frame - > source - > reachable = = REACHABLE_SELF ) {
2013-02-07 04:46:07 +00:00
process = forward = 0 ;
2015-07-06 08:19:49 +00:00
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " Ignoring my packet (or unparsable source) " ) ;
2013-02-14 03:48:56 +00:00
}
2013-02-07 04:46:07 +00:00
}
if ( flags & PAYLOAD_FLAG_TO_BROADCAST ) {
if ( ! ( flags & PAYLOAD_FLAG_ONE_HOP ) ) {
if ( overlay_broadcast_parse ( buffer , & frame - > broadcast_id ) )
2013-02-14 03:48:56 +00:00
RETURN ( WHY ( " Unable to read broadcast address " ) ) ;
2013-02-07 04:46:07 +00:00
if ( overlay_broadcast_drop_check ( & frame - > broadcast_id ) ) {
process = forward = 0 ;
2015-07-06 08:19:49 +00:00
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " Ignoring duplicate broadcast (%s) " , alloca_tohex ( frame - > broadcast_id . id , BROADCAST_LEN ) ) ;
2013-02-07 04:46:07 +00:00
}
2013-05-29 01:44:26 +00:00
if ( link_state_should_forward_broadcast ( context - > sender ) = = 0 ) {
forward = 0 ;
2015-07-06 08:19:49 +00:00
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 01:44:26 +00:00
}
2013-02-07 04:46:07 +00:00
}
frame - > destination = NULL ;
} else {
int ret = overlay_address_parse ( context , buffer , & frame - > destination ) ;
if ( ret < 0 )
2013-02-14 03:48:56 +00:00
RETURN ( WHY ( " Unable to parse payload destination " ) ) ;
2013-02-07 04:46:07 +00:00
2013-02-14 03:48:56 +00:00
if ( ! frame - > destination | | frame - > destination - > reachable ! = REACHABLE_SELF ) {
2013-02-07 04:46:07 +00:00
process = 0 ;
2015-07-06 08:19:49 +00:00
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " Don't process packet not addressed to me " ) ;
2013-02-14 03:48:56 +00:00
}
2013-02-07 04:46:07 +00:00
if ( ! ( flags & PAYLOAD_FLAG_ONE_HOP ) ) {
ret = overlay_address_parse ( context , buffer , nexthop ) ;
if ( ret < 0 )
2013-02-14 03:48:56 +00:00
RETURN ( WHY ( " Unable to parse payload nexthop " ) ) ;
2013-02-07 04:46:07 +00:00
2013-02-14 03:48:56 +00:00
if ( ! ( * nexthop ) | | ( * nexthop ) - > reachable ! = REACHABLE_SELF ) {
2013-02-07 04:46:07 +00:00
forward = 0 ;
2015-07-06 08:19:49 +00:00
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " Don't forward packet not addressed to me " ) ;
2013-02-14 03:48:56 +00:00
}
2013-02-07 04:46:07 +00:00
}
}
2013-04-23 06:32:39 +00:00
if ( flags & PAYLOAD_FLAG_ONE_HOP ) {
2013-02-07 04:46:07 +00:00
frame - > ttl = 1 ;
2013-04-23 06:32:39 +00:00
} else {
2013-02-07 04:46:07 +00:00
int ttl_qos = ob_get ( buffer ) ;
if ( ttl_qos < 0 )
2013-02-14 03:48:56 +00:00
RETURN ( WHY ( " Unable to read ttl " ) ) ;
2013-02-07 04:46:07 +00:00
frame - > ttl = ttl_qos & 0x1F ;
frame - > queue = ( ttl_qos > > 5 ) & 3 ;
}
2013-04-23 06:32:39 +00:00
if ( frame - > ttl )
- - frame - > ttl ;
if ( frame - > ttl = = 0 ) {
2013-04-12 07:46:50 +00:00
forward = 0 ;
2015-07-06 08:19:49 +00:00
if ( IF_DEBUG ( verbose ) )
DEBUGF ( overlayframes , " NOT FORWARDING, due to ttl=0 " ) ;
2013-04-23 06:32:39 +00:00
}
2013-02-07 04:46:07 +00:00
if ( flags & PAYLOAD_FLAG_LEGACY_TYPE ) {
2013-04-12 07:46:50 +00:00
int ftype = ob_get ( buffer ) ;
if ( ftype = = - 1 )
2013-02-14 03:48:56 +00:00
RETURN ( WHY ( " Unable to read type " ) ) ;
2013-04-12 07:46:50 +00:00
frame - > type = ftype ;
2013-02-07 04:46:07 +00:00
} else
frame - > type = OF_TYPE_DATA ;
2013-05-15 06:26:43 +00:00
2013-06-03 06:34:08 +00:00
if ( context - > packet_version > = 1 ) {
2013-05-24 04:22:31 +00:00
int seq = ob_get ( buffer ) ;
if ( seq = = - 1 )
RETURN ( WHY ( " Unable to read packet seq " ) ) ;
2015-08-03 01:42:39 +00:00
if ( link_received_duplicate ( context , seq ) ) {
2015-07-06 08:19:49 +00:00
if ( IF_DEBUG ( verbose ) )
DEBUG ( overlayframes , " Don't process or forward duplicate payloads " ) ;
2014-06-26 07:50:06 +00:00
forward = process = 0 ;
2013-05-15 06:26:43 +00:00
}
}
2013-02-07 04:46:07 +00:00
frame - > modifiers = flags ;
2013-05-24 04:22:31 +00:00
frame - > packet_version = context - > packet_version ;
2013-02-07 04:46:07 +00:00
// if we can't understand one of the addresses, skip processing the payload
2013-02-14 03:48:56 +00:00
if ( ( forward | | process ) & & context - > invalid_addresses ) {
2015-07-06 08:19:49 +00:00
if ( IF_DEBUG ( verbose ) )
DEBUG ( overlayframes , " Don't process or forward with invalid addresses " ) ;
2013-02-14 03:48:56 +00:00
forward = process = 0 ;
2013-02-07 04:46:07 +00:00
}
2013-02-14 03:48:56 +00:00
RETURN ( forward | process ) ;
2013-02-16 17:47:24 +00:00
OUT ( ) ;
2013-02-07 04:46:07 +00:00
}
int parseEnvelopeHeader ( struct decode_context * context , struct overlay_interface * interface ,
2013-12-09 07:15:47 +00:00
struct socket_address * addr , struct overlay_buffer * buffer ) {
2013-02-14 03:48:56 +00:00
IN ( ) ;
2013-02-07 04:46:07 +00:00
2013-07-16 05:46:07 +00:00
context - > interface = interface ;
2015-03-16 01:52:38 +00:00
if ( interface - > ifconfig . point_to_point & & interface - > other_device )
2013-08-08 05:50:31 +00:00
context - > point_to_point_device = interface - > other_device ;
2013-07-16 05:46:07 +00:00
context - > sender_interface = 0 ;
2013-05-24 04:22:31 +00:00
context - > packet_version = ob_get ( buffer ) ;
2013-07-16 05:46:07 +00:00
2013-05-24 04:22:31 +00:00
if ( context - > packet_version < 0 | | context - > packet_version > SUPPORTED_PACKET_VERSION )
2013-07-10 03:46:22 +00:00
RETURN ( WHYF ( " Packet version %d not recognised. " , context - > packet_version ) ) ;
2013-05-24 04:22:31 +00:00
context - > encapsulation = ob_get ( buffer ) ;
if ( context - > encapsulation ! = ENCAP_OVERLAY & & context - > encapsulation ! = ENCAP_SINGLE )
2013-07-10 03:46:22 +00:00
RETURN ( WHYF ( " Invalid packet encapsulation, %d " , context - > encapsulation ) ) ;
2013-05-24 04:22:31 +00:00
2013-02-07 04:46:07 +00:00
if ( overlay_address_parse ( context , buffer , & context - > sender ) )
2013-02-14 03:48:56 +00:00
RETURN ( WHY ( " Unable to parse sender " ) ) ;
2013-02-07 04:46:07 +00:00
int packet_flags = ob_get ( buffer ) ;
2013-04-26 07:23:04 +00:00
int sender_seq = - 1 ;
2013-02-07 04:46:07 +00:00
if ( packet_flags & PACKET_INTERFACE )
2013-05-15 06:26:43 +00:00
context - > sender_interface = ob_get ( buffer ) ;
2013-02-07 04:46:07 +00:00
if ( packet_flags & PACKET_SEQ )
2013-05-15 04:57:38 +00:00
sender_seq = ob_get ( buffer ) & 0xFF ;
2013-02-07 04:46:07 +00:00
2013-08-08 05:50:31 +00:00
if ( addr )
context - > addr = * addr ;
2013-02-07 04:46:07 +00:00
if ( context - > sender ) {
2013-02-14 03:48:56 +00:00
if ( context - > sender - > reachable = = REACHABLE_SELF ) {
2015-07-06 08:19:49 +00:00
if ( IF_DEBUG ( verbose ) )
DEBUG ( overlayframes , " Completely ignore packets I sent " ) ;
2013-02-14 03:48:56 +00:00
RETURN ( 1 ) ;
}
2013-08-08 05:50:31 +00:00
2013-08-09 06:49:45 +00:00
if ( context - > packet_version > context - > sender - > max_packet_version )
context - > sender - > max_packet_version = context - > packet_version ;
2015-03-16 01:52:38 +00:00
if ( interface - > ifconfig . point_to_point & & interface - > other_device ! = context - > sender ) {
2013-10-09 08:24:21 +00:00
INFOF ( " Established point to point link with %s on %s " , alloca_tohex_sid_t ( context - > sender - > sid ) , interface - > name ) ;
2013-08-08 05:50:31 +00:00
context - > point_to_point_device = context - > interface - > other_device = context - > sender ;
2013-07-16 05:46:07 +00:00
}
2013-02-07 04:46:07 +00:00
2015-07-06 08:19:49 +00:00
DEBUGF ( overlayframes , " Received %s packet seq %d from %s on %s %s " ,
2013-08-09 02:48:14 +00:00
packet_flags & PACKET_UNICAST ? " unicast " : " broadcast " ,
2015-06-22 03:00:18 +00:00
sender_seq , alloca_tohex_sid_t ( context - > sender - > sid ) ,
interface - > name , alloca_socket_address ( addr ) ) ;
2013-02-07 04:46:07 +00:00
}
2015-08-03 01:42:39 +00:00
RETURN ( link_received_packet ( context , sender_seq , packet_flags & PACKET_UNICAST ) ) ;
2013-02-16 17:47:24 +00:00
OUT ( ) ;
2013-02-07 04:46:07 +00:00
}
2012-07-03 06:06:51 +00:00
int packetOkOverlay ( struct overlay_interface * interface , unsigned char * packet , size_t len ,
2013-12-09 07:52:18 +00:00
struct socket_address * recvaddr )
2011-08-15 07:27:29 +00:00
{
2012-11-23 05:55:32 +00:00
IN ( ) ;
2011-08-15 07:27:29 +00:00
/*
2012-07-18 05:24:23 +00:00
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 01:22:17 +00:00
Frame type ( 8 - 24 bits )
2011-08-15 11:50:30 +00:00
TTL ( 8 bits )
2011-08-17 01:22:17 +00:00
Remaining frame size ( RFS ) ( see overlay_payload . c or overlay_buffer . c for explanation of format )
2011-08-15 07:27:29 +00:00
Next hop ( variable length due to address abbreviation )
2012-07-18 05:24:23 +00:00
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 07:27:29 +00: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 05:24:23 +00:00
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 07:27:29 +00: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 05:24:23 +00:00
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 07:27:29 +00: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 08:19:49 +00:00
if ( IF_DEBUG ( packetrx ) | | interface - > ifconfig . debug ) {
_DEBUGF ( " Received on %s, len %d " , interface - > name , ( int ) len ) ;
2013-09-18 04:14:18 +00:00
DEBUG_packet_visualise ( " Received packet " , packet , len ) ;
}
2012-08-27 00:34:59 +00:00
struct overlay_frame f ;
2012-11-23 05:55:32 +00:00
struct decode_context context ;
bzero ( & context , sizeof context ) ;
2012-12-04 04:17:57 +00:00
bzero ( & f , sizeof f ) ;
2012-09-19 04:46:40 +00:00
2012-08-27 00:34:59 +00:00
time_ms_t now = gettime_ms ( ) ;
struct overlay_buffer * b = ob_static ( packet , len ) ;
ob_limitsize ( b , len ) ;
2012-11-21 05:00:20 +00:00
2013-08-08 05:50:31 +00:00
f . interface = interface ;
2013-02-07 04:46:07 +00:00
2013-12-09 07:15:47 +00:00
int ret = parseEnvelopeHeader ( & context , interface , recvaddr , b ) ;
2013-02-14 03:48:56 +00:00
if ( ret ) {
2013-02-07 04:46:07 +00:00
ob_free ( b ) ;
2013-02-14 03:48:56 +00:00
RETURN ( ret ) ;
2012-12-04 04:17:57 +00:00
}
2013-08-08 05:50:31 +00:00
f . sender_interface = context . sender_interface ;
2013-09-23 01:41:58 +00:00
interface - > recv_count + + ;
2012-12-04 04:17:57 +00:00
2013-02-14 03:48:56 +00:00
while ( ob_remaining ( b ) > 0 ) {
2012-09-19 04:46:40 +00:00
context . invalid_addresses = 0 ;
2012-11-26 04:22:49 +00:00
struct subscriber * nexthop = NULL ;
bzero ( f . broadcast_id . id , BROADCAST_LEN ) ;
2013-05-30 03:54:37 +00:00
unsigned char * header_start = ob_ptr ( b ) + ob_position ( b ) ;
2013-02-14 03:48:56 +00:00
int header_valid = parseMdpPacketHeader ( & context , & f , b , & nexthop ) ;
if ( header_valid < 0 ) {
ret = WHY ( " Header is too short " ) ;
2013-02-07 04:46:07 +00:00
break ;
2012-11-26 04:22:49 +00:00
}
2013-08-08 05:50:31 +00:00
// TODO allow for single byte length?
2013-12-10 06:33:30 +00:00
size_t payload_len ;
2012-11-23 05:55:32 +00:00
2013-05-24 04:22:31 +00:00
switch ( context . encapsulation ) {
2013-02-14 03:48:56 +00:00
case ENCAP_SINGLE :
payload_len = ob_remaining ( b ) ;
break ;
2013-05-24 04:22:31 +00:00
default :
2013-02-14 03:48:56 +00:00
case ENCAP_OVERLAY :
payload_len = ob_get_ui16 ( b ) ;
if ( payload_len > ob_remaining ( b ) ) {
2013-05-30 03:54:37 +00:00
unsigned char * current = ob_ptr ( b ) + ob_position ( b ) ;
2015-07-06 08:19:49 +00:00
if ( IF_DEBUG ( overlayframes ) )
2013-08-09 02:48:14 +00:00
dump ( " Payload Header " , header_start , current - header_start ) ;
2013-12-16 04:49:15 +00:00
ret = WHYF ( " Invalid payload length (%zd) " , payload_len ) ;
2013-02-14 03:48:56 +00:00
goto end ;
}
break ;
}
2012-12-15 23:35:32 +00:00
int next_payload = ob_position ( b ) + payload_len ;
2012-08-27 00:34:59 +00:00
2015-07-06 08:19:49 +00:00
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 03:48:56 +00:00
if ( ! is_all_matching ( f . broadcast_id . id , BROADCAST_LEN , 0 ) )
2015-07-06 08:19:49 +00:00
DEBUGF ( overlayframes , " Broadcast id %s " , alloca_tohex ( f . broadcast_id . id , BROADCAST_LEN ) ) ;
2013-02-14 03:48:56 +00:00
if ( nexthop )
2015-07-06 08:19:49 +00:00
DEBUGF ( overlayframes , " Next hop %s " , alloca_tohex_sid_t ( nexthop - > sid ) ) ;
2013-02-14 03:48:56 +00:00
}
if ( header_valid ! = 0 ) {
2012-08-27 00:34:59 +00:00
2013-12-10 06:33:30 +00:00
f . payload = ob_slice ( b , ob_position ( b ) , payload_len ) ;
2013-02-07 04:46:07 +00:00
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 00:34:59 +00:00
2013-02-07 04:46:07 +00:00
// forward payloads that are for someone else or everyone
2013-02-14 03:48:56 +00:00
if ( header_valid & HEADER_FORWARD )
2013-02-07 04:46:07 +00:00
overlay_forward_payload ( & f ) ;
// process payloads that are for me or everyone
2013-02-14 03:48:56 +00:00
if ( header_valid & HEADER_PROCESS )
2013-02-07 04:46:07 +00:00
process_incoming_frame ( now , interface , & f , & context ) ;
2013-05-15 02:03:43 +00:00
2013-08-30 05:41:48 +00:00
// We may need to schedule an ACK / NACK soon when we receive a payload addressed to us, or broadcast
2013-08-30 07:54:52 +00:00
if ( f . modifiers & PAYLOAD_FLAG_ACK_SOON & &
( f . next_hop = = my_subscriber | | f . destination = = my_subscriber | | ! f . destination ) )
2013-05-15 02:03:43 +00:00
link_state_ack_soon ( context . sender ) ;
2012-08-27 00:34:59 +00:00
}
if ( f . payload ) {
ob_free ( f . payload ) ;
f . payload = NULL ;
}
b - > position = next_payload ;
}
2012-07-17 06:00:50 +00:00
2013-02-14 03:48:56 +00:00
end :
2012-11-23 05:55:32 +00:00
send_please_explain ( & context , my_subscriber , context . sender ) ;
2012-08-27 00:34:59 +00:00
ob_free ( b ) ;
2012-09-19 04:46:40 +00:00
2013-02-14 03:48:56 +00:00
RETURN ( ret ) ;
2013-02-16 17:47:24 +00:00
OUT ( ) ;
2011-08-15 11:50:30 +00:00
}