2012-11-30 01:18:00 +00:00
/*
Copyright ( C ) 2010 - 2012 Paul Gardner - Stephen , Serval Project .
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 .
*/
# include <sys/stat.h>
# include "serval.h"
# include "str.h"
# include "strbuf.h"
# include "overlay_buffer.h"
# include "overlay_address.h"
# include "overlay_packet.h"
# include "mdp_client.h"
2012-11-30 04:17:27 +00:00
# include "rhizome.h"
2012-11-30 01:18:00 +00:00
# include "crypto.h"
2012-11-30 10:38:06 +00:00
# include "log.h"
2012-11-30 01:18:00 +00:00
2012-11-30 03:47:05 +00:00
int overlay_mdp_service_rhizomerequest ( overlay_mdp_frame * mdp )
{
IN ( ) ;
2012-12-01 00:22:08 +00:00
2012-11-30 11:20:17 +00:00
uint64_t fileOffset =
read_uint64 ( & mdp - > out . payload [ RHIZOME_MANIFEST_ID_BYTES + 8 ] ) ;
uint32_t bitmap =
read_uint32 ( & mdp - > out . payload [ RHIZOME_MANIFEST_ID_BYTES + 8 + 8 ] ) ;
uint16_t blockLength =
read_uint16 ( & mdp - > out . payload [ RHIZOME_MANIFEST_ID_BYTES + 8 + 8 + 4 ] ) ;
2012-12-01 00:22:08 +00:00
if ( blockLength > 1024 ) RETURN ( - 1 ) ;
2012-12-04 06:08:18 +00:00
struct subscriber * source = find_subscriber ( mdp - > out . src . sid , SID_SIZE , 0 ) ;
2012-12-01 00:22:08 +00:00
if ( 0 ) {
DEBUGF ( " Someone sent me a rhizome request via MDP " ) ;
DEBUGF ( " requestor sid = %s " , alloca_tohex_sid ( mdp - > out . src . sid ) ) ;
DEBUGF ( " bundle ID = %s " , alloca_tohex_bid ( & mdp - > out . payload [ 0 ] ) ) ;
DEBUGF ( " manifest version = 0x%llx " ,
read_uint64 ( & mdp - > out . payload [ RHIZOME_MANIFEST_ID_BYTES ] ) ) ;
DEBUGF ( " file offset = 0x%llx " , fileOffset ) ;
DEBUGF ( " bitmap = 0x%08x " , bitmap ) ;
DEBUGF ( " block length = %d " , blockLength ) ;
}
2012-11-30 11:20:17 +00:00
/* Find manifest that corresponds to BID and version.
If we don ' t have this combination , then do nothing .
If we do have the combination , then find the associated file ,
and open the blob so that we can send some of it .
TODO : If we have a newer version of the manifest , and the manifest is a
journal , then the newer version is okay to use to service this request .
*/
long long row_id = - 1 ;
2012-12-04 06:17:45 +00:00
if ( sqlite_exec_int64 ( & row_id , " SELECT rowid FROM FILEBLOBS WHERE id IN (SELECT filehash FROM MANIFESTS WHERE manifests.version=%lld AND manifests.id='%s'); " ,
2012-11-30 11:20:17 +00:00
read_uint64 ( & mdp - > out . payload [ RHIZOME_MANIFEST_ID_BYTES ] ) ,
alloca_tohex_bid ( & mdp - > out . payload [ 0 ] ) ) < 1 )
{
DEBUGF ( " Couldn't find stored file. " ) ;
RETURN ( - 1 ) ;
}
2012-12-01 00:22:08 +00:00
2012-11-30 11:20:17 +00:00
sqlite3_blob * blob = NULL ;
2012-12-04 06:17:45 +00:00
int ret = sqlite3_blob_open ( rhizome_db , " main " , " fileblobs " , " data " ,
2012-11-30 11:20:17 +00:00
row_id , 0 /* read only */ , & blob ) ;
if ( ret ! = SQLITE_OK )
{
DEBUGF ( " Failed to open blob: %s " , sqlite3_errmsg ( rhizome_db ) ) ;
RETURN ( - 1 ) ;
}
2012-12-01 00:22:08 +00:00
int blob_bytes = sqlite3_blob_bytes ( blob ) ;
2012-11-30 11:20:17 +00:00
if ( blob_bytes < fileOffset ) {
sqlite3_blob_close ( blob ) ; blob = NULL ;
RETURN ( - 1 ) ;
}
overlay_mdp_frame reply ;
bzero ( & reply , sizeof ( reply ) ) ;
// Reply is broadcast, so we cannot authcrypt, and signing is too time consuming
// for low devices. The result is that an attacker can prevent rhizome transfers
// if they want to by injecting fake blocks. The alternative is to not broadcast
// back replies, and then we can authcrypt.
2012-12-03 01:20:35 +00:00
// multiple receivers starting at different times, we really need merkle-tree hashing.
// so multiple receivers is not realistic for now. So use non-broadcast unicode
// for now would seem the safest. But that would stop us from allowing multiple
// receivers in the special case where additional nodes begin listening in from the
// beginning.
reply . packetTypeAndFlags = MDP_TX | MDP_NOCRYPT | MDP_NOSIGN ;
2012-11-30 11:20:17 +00:00
reply . out . ttl = 1 ;
bcopy ( my_subscriber - > sid , reply . out . src . sid , SID_SIZE ) ;
reply . out . src . port = MDP_PORT_RHIZOME_RESPONSE ;
2012-12-04 06:08:18 +00:00
if ( source & & source - > reachable & REACHABLE_UNICAST ) {
// if we get a request from a peer that we can only talk to via unicast, send data via unicast too.
bcopy ( mdp - > out . src . sid , reply . out . dst . sid , SID_SIZE ) ;
} else {
// send replies to broadcast so that others can hear blocks and record them
// (not that preemptive listening is implemented yet).
memset ( reply . out . dst . sid , 0xff , SID_SIZE ) ;
}
2012-11-30 11:20:17 +00:00
reply . out . dst . port = MDP_PORT_RHIZOME_RESPONSE ;
reply . out . queue = OQ_ORDINARY ;
reply . out . payload [ 0 ] = ' B ' ; // reply contains blocks
// include 16 bytes of BID prefix for identification
2012-11-30 11:22:44 +00:00
bcopy ( & mdp - > out . payload [ 0 ] , & reply . out . payload [ 1 ] , 16 ) ;
2012-11-30 11:20:17 +00:00
// and version of manifest
bcopy ( & mdp - > out . payload [ RHIZOME_MANIFEST_ID_BYTES ] ,
2012-11-30 11:22:44 +00:00
& reply . out . payload [ 1 + 16 ] , 8 ) ;
2012-11-30 11:20:17 +00:00
int i ;
for ( i = 0 ; i < 32 ; i + + )
if ( ! ( bitmap & ( 1 < < ( 31 - i ) ) ) )
{
// calculate and set offset of block
uint64_t blockOffset = fileOffset + i * blockLength ;
2012-11-30 11:22:44 +00:00
write_uint64 ( & reply . out . payload [ 1 + 16 + 8 ] , blockOffset ) ;
2012-11-30 11:20:17 +00:00
// work out how many bytes to read
int blockBytes = blob_bytes - blockOffset ;
if ( blockBytes > blockLength ) blockBytes = blockLength ;
// read data for block
if ( blob_bytes > = blockOffset ) {
2012-11-30 11:22:44 +00:00
sqlite3_blob_read ( blob , & reply . out . payload [ 1 + 16 + 8 + 8 ] ,
2012-11-30 12:15:27 +00:00
blockBytes , blockOffset ) ;
2012-11-30 11:22:44 +00:00
reply . out . payload_length = 1 + 16 + 8 + 8 + blockBytes ;
2012-11-30 12:12:28 +00:00
// Mark terminal block if required
if ( blockOffset + blockBytes = = blob_bytes ) reply . out . payload [ 0 ] = ' T ' ;
2012-11-30 11:32:10 +00:00
// send packet
overlay_mdp_dispatch ( & reply , 0 /* system generated */ , NULL , 0 ) ;
} else break ;
2012-11-30 11:20:17 +00:00
}
sqlite3_blob_close ( blob ) ; blob = NULL ;
2012-11-30 03:47:05 +00:00
RETURN ( - 1 ) ;
}
int overlay_mdp_service_rhizomeresponse ( overlay_mdp_frame * mdp )
{
IN ( ) ;
2012-11-30 11:32:10 +00:00
if ( ! mdp - > out . payload_length ) RETURN ( - 1 ) ;
int type = mdp - > out . payload [ 0 ] ;
switch ( type ) {
case ' B ' : /* data block */
2012-11-30 12:12:28 +00:00
case ' T ' : /* terminal data block */
2012-11-30 11:32:10 +00:00
{
if ( mdp - > out . payload_length < ( 1 + 16 + 8 + 8 + 1 ) ) RETURN ( - 1 ) ;
2012-11-30 11:56:31 +00:00
unsigned char * bidprefix = & mdp - > out . payload [ 1 ] ;
2012-11-30 11:32:10 +00:00
uint64_t version = read_uint64 ( & mdp - > out . payload [ 1 + 16 ] ) ;
uint64_t offset = read_uint64 ( & mdp - > out . payload [ 1 + 16 + 8 ] ) ;
2012-11-30 11:56:31 +00:00
int count = mdp - > out . payload_length - ( 1 + 16 + 8 + 8 ) ;
unsigned char * bytes = & mdp - > out . payload [ 1 + 16 + 8 + 8 ] ;
2012-11-30 21:07:22 +00:00
if ( 0 )
DEBUGF ( " Received %d bytes @ 0x%llx for %s* version 0x%llx " ,
count , offset , alloca_tohex ( bidprefix , 16 ) , version ) ;
2012-11-30 11:56:31 +00:00
/* Now see if there is a slot that matches. If so, then
see if the bytes are in the window , and write them .
If there is not matching slot , then consider setting
a slot to capture this files as it is being requested
by someone else .
*/
2012-11-30 12:12:28 +00:00
rhizome_received_content ( bidprefix , version , offset , count , bytes , type ) ;
2012-11-30 11:56:31 +00:00
2012-11-30 11:32:10 +00:00
RETURN ( - 1 ) ;
}
break ;
}
2012-11-30 03:47:05 +00:00
RETURN ( - 1 ) ;
}
2012-11-30 01:18:00 +00:00
int overlay_mdp_service_dnalookup ( overlay_mdp_frame * mdp )
{
IN ( ) ;
int cn = 0 , in = 0 , kp = 0 ;
char did [ 64 + 1 ] ;
int pll = mdp - > out . payload_length ;
if ( pll > 64 ) pll = 64 ;
/* get did from the packet */
if ( mdp - > out . payload_length < 1 ) {
RETURN ( WHY ( " Empty DID in DNA resolution request " ) ) ; }
bcopy ( & mdp - > out . payload [ 0 ] , & did [ 0 ] , pll ) ;
did [ pll ] = 0 ;
if ( debug & DEBUG_MDPREQUESTS )
DEBUG ( " MDP_PORT_DNALOOKUP " ) ;
int results = 0 ;
while ( keyring_find_did ( keyring , & cn , & in , & kp , did ) )
{
/* package DID and Name into reply (we include the DID because
it could be a wild - card DID search , but the SID is implied
in the source address of our reply ) . */
if ( keyring - > contexts [ cn ] - > identities [ in ] - > keypairs [ kp ] - > private_key_len > DID_MAXSIZE )
/* skip excessively long DID records */
continue ;
const unsigned char * packedSid = keyring - > contexts [ cn ] - > identities [ in ] - > keypairs [ 0 ] - > public_key ;
const char * unpackedDid = ( const char * ) keyring - > contexts [ cn ] - > identities [ in ] - > keypairs [ kp ] - > private_key ;
const char * name = ( const char * ) keyring - > contexts [ cn ] - > identities [ in ] - > keypairs [ kp ] - > public_key ;
// URI is sid://SIDHEX/DID
strbuf b = strbuf_alloca ( SID_STRLEN + DID_MAXSIZE + 10 ) ;
strbuf_puts ( b , " sid:// " ) ;
strbuf_tohex ( b , packedSid , SID_SIZE ) ;
strbuf_puts ( b , " /local/ " ) ;
strbuf_puts ( b , unpackedDid ) ;
overlay_mdp_dnalookup_reply ( & mdp - > out . src , packedSid , strbuf_str ( b ) , unpackedDid , name ) ;
kp + + ;
results + + ;
}
if ( ! results ) {
/* No local results, so see if servald has been configured to use
a DNA - helper that can provide additional mappings . This provides
a generalised interface for resolving telephone numbers into URIs .
The first use will be for resolving DIDs to SIP addresses for
OpenBTS boxes run by the OTI / Commotion project .
The helper is run asynchronously , and the replies will be delivered
when results become available , so this function will return
immediately , so as not to cause blockages and delays in servald .
*/
dna_helper_enqueue ( mdp , did , mdp - > out . src . sid ) ;
monitor_tell_formatted ( MONITOR_DNAHELPER , " LOOKUP:%s:%d:%s \n " ,
alloca_tohex_sid ( mdp - > out . src . sid ) , mdp - > out . src . port ,
did ) ;
}
RETURN ( 0 ) ;
}
int overlay_mdp_service_echo ( overlay_mdp_frame * mdp )
{
/* Echo is easy: we swap the sender and receiver addresses (and thus port
numbers ) and send the frame back . */
IN ( ) ;
/* Swap addresses */
overlay_mdp_swap_src_dst ( mdp ) ;
mdp - > out . ttl = 0 ;
/* Prevent echo:echo connections and the resulting denial of service from triggering endless pongs. */
if ( mdp - > out . dst . port = = MDP_PORT_ECHO ) {
RETURN ( WHY ( " echo loop averted " ) ) ;
}
/* If the packet was sent to broadcast, then replace broadcast address
with our local address . For now just responds with first local address */
if ( is_sid_broadcast ( mdp - > out . src . sid ) )
{
if ( my_subscriber )
bcopy ( my_subscriber - > sid ,
mdp - > out . src . sid , SID_SIZE ) ;
else
/* No local addresses, so put all zeroes */
bzero ( mdp - > out . src . sid , SID_SIZE ) ;
}
/* Always send PONGs auth-crypted so that the receipient knows
that they are genuine , and so that we avoid the extra cost
of signing ( which is slower than auth - crypting ) */
int preserved = mdp - > packetTypeAndFlags ;
mdp - > packetTypeAndFlags & = ~ ( MDP_NOCRYPT | MDP_NOSIGN ) ;
/* queue frame for delivery */
overlay_mdp_dispatch ( mdp , 0 /* system generated */ ,
NULL , 0 ) ;
mdp - > packetTypeAndFlags = preserved ;
/* and switch addresses back around in case the caller was planning on
using MDP structure again ( this happens if there is a loop - back reply
and the frame needs sending on , as happens with broadcasts . MDP ping
is a simple application where this occurs ) . */
overlay_mdp_swap_src_dst ( mdp ) ;
RETURN ( 0 ) ;
}
2012-12-04 04:17:57 +00:00
struct probe_contents {
struct sockaddr_in addr ;
unsigned char interface ;
} ;
/* Collection of unicast echo responses to detect working links */
static int
overlay_mdp_service_probe ( overlay_mdp_frame * mdp )
{
IN ( ) ;
if ( mdp - > out . src . port ! = MDP_PORT_ECHO | | mdp - > out . payload_length ! = sizeof ( struct probe_contents ) ) {
WARN ( " Probe packets should be returned from remote echo port " ) ;
RETURN ( - 1 ) ;
}
struct subscriber * peer = find_subscriber ( mdp - > out . src . sid , SID_SIZE , 0 ) ;
2012-12-06 00:29:19 +00:00
struct probe_contents probe ;
bcopy ( & mdp - > out . payload , & probe , sizeof ( struct probe_contents ) ) ;
if ( probe . addr . sin_family ! = AF_INET )
2012-12-04 04:17:57 +00:00
RETURN ( WHY ( " Unsupported address family " ) ) ;
2012-12-05 05:06:46 +00:00
if ( peer - > reachable = = REACHABLE_NONE | | peer - > reachable = = REACHABLE_INDIRECT | | ( peer - > reachable & REACHABLE_ASSUMED ) ) {
2012-12-08 04:39:41 +00:00
peer - > interface = & overlay_interfaces [ probe . interface ] ;
peer - > address . sin_family = AF_INET ;
peer - > address . sin_addr = probe . addr . sin_addr ;
peer - > address . sin_port = probe . addr . sin_port ;
set_reachable ( peer , REACHABLE_UNICAST ) ;
2012-12-04 04:17:57 +00:00
}
RETURN ( 0 ) ;
}
int overlay_send_probe ( struct subscriber * peer , struct sockaddr_in addr , overlay_interface * interface ) {
if ( interface = = NULL )
2012-12-07 05:34:40 +00:00
interface = overlay_interface_find ( addr . sin_addr , 1 ) ;
2012-12-04 04:17:57 +00:00
if ( ! interface )
return WHY ( " I don't know which interface to use " ) ;
2012-12-05 05:06:46 +00:00
time_ms_t now = gettime_ms ( ) ;
if ( peer & & peer - > last_probe + 1000 > now )
return - 1 ;
2012-12-04 04:17:57 +00:00
struct overlay_frame * frame = malloc ( sizeof ( struct overlay_frame ) ) ;
bzero ( frame , sizeof ( struct overlay_frame ) ) ;
frame - > type = OF_TYPE_DATA ;
frame - > source = my_subscriber ;
frame - > next_hop = frame - > destination = peer ;
frame - > ttl = 1 ;
frame - > queue = OQ_MESH_MANAGEMENT ;
frame - > destination_resolved = 1 ;
frame - > recvaddr = addr ;
frame - > flags = PACKET_UNICAST ;
frame - > interface = interface ;
frame - > payload = ob_new ( ) ;
2012-12-07 05:34:40 +00:00
// TODO call mdp payload encryption / signing without calling overlay_mdp_dispatch...
2012-12-08 04:39:41 +00:00
my_subscriber - > send_full = 1 ;
2012-12-04 04:17:57 +00:00
2012-12-05 05:06:46 +00:00
if ( peer )
peer - > last_probe = gettime_ms ( ) ;
2012-12-04 04:17:57 +00:00
if ( overlay_mdp_encode_ports ( frame - > payload , MDP_PORT_ECHO , MDP_PORT_PROBE ) ) {
op_free ( frame ) ;
return - 1 ;
}
// not worried about byte order here as we are the only node that should be parsing the contents.
2012-12-06 00:29:19 +00:00
unsigned char * dst = ob_append_space ( frame - > payload , sizeof ( struct probe_contents ) ) ;
if ( ! dst ) {
2012-12-04 04:17:57 +00:00
op_free ( frame ) ;
return - 1 ;
}
2012-12-06 00:29:19 +00:00
struct probe_contents probe ;
probe . addr = addr ;
2012-12-04 04:17:57 +00:00
// get interface number
2012-12-06 00:29:19 +00:00
probe . interface = interface - overlay_interfaces ;
bcopy ( & probe , dst , sizeof ( struct probe_contents ) ) ;
2012-12-04 04:17:57 +00:00
if ( overlay_payload_enqueue ( frame ) ) {
op_free ( frame ) ;
return - 1 ;
}
2012-12-08 04:39:41 +00:00
DEBUGF ( " Queued probe packet on interface %s to %s for %s " ,
interface - > name , inet_ntoa ( addr . sin_addr ) , peer ? alloca_tohex_sid ( peer - > sid ) : " ANY " ) ;
2012-12-04 04:17:57 +00:00
return 0 ;
}
2012-12-07 05:34:40 +00:00
// append the address of a unicast link into a packet buffer
static int overlay_append_unicast_address ( struct subscriber * subscriber , struct overlay_buffer * buff )
{
2012-12-08 04:39:41 +00:00
if ( subscriber - > reachable & REACHABLE_ASSUMED | | ! ( subscriber - > reachable & REACHABLE_UNICAST ) ) {
DEBUGF ( " Unable to give address of %s, %d " , alloca_tohex_sid ( subscriber - > sid ) , subscriber - > reachable ) ;
2012-12-07 05:34:40 +00:00
return 0 ;
2012-12-08 04:39:41 +00:00
}
2012-12-07 05:34:40 +00:00
if ( overlay_address_append ( NULL , buff , subscriber ) )
return - 1 ;
if ( ob_append_ui32 ( buff , subscriber - > address . sin_addr . s_addr ) )
return - 1 ;
if ( ob_append_ui16 ( buff , subscriber - > address . sin_port ) )
return - 1 ;
ob_checkpoint ( buff ) ;
DEBUGF ( " Added STUN info for %s " , alloca_tohex_sid ( subscriber - > sid ) ) ;
return 0 ;
}
2012-12-08 04:39:41 +00:00
// append the address of all neighbour unicast links into a packet buffer
/*
static int overlay_append_local_unicasts ( struct subscriber * subscriber , void * context )
{
struct overlay_buffer * buff = context ;
if ( ( ! subscriber - > interface ) | |
( ! ( subscriber - > reachable & REACHABLE_UNICAST ) ) | |
( subscriber - > reachable & REACHABLE_ASSUMED ) )
return 0 ;
if ( ( subscriber - > address . sin_addr . s_addr & subscriber - > interface - > netmask . s_addr ) ! =
( subscriber - > interface - > address . sin_addr . s_addr & subscriber - > interface - > netmask . s_addr ) )
return 0 ;
return overlay_append_unicast_address ( subscriber , buff ) ;
}
*/
2012-12-07 05:34:40 +00:00
static int overlay_mdp_service_stun_req ( overlay_mdp_frame * mdp )
{
DEBUGF ( " Processing STUN request from %s " , alloca_tohex_sid ( mdp - > out . src . sid ) ) ;
struct overlay_buffer * payload = ob_static ( mdp - > out . payload , mdp - > out . payload_length ) ;
ob_limitsize ( payload , mdp - > out . payload_length ) ;
overlay_mdp_frame reply ;
bzero ( & reply , sizeof ( reply ) ) ;
reply . packetTypeAndFlags = MDP_TX ;
bcopy ( mdp - > out . src . sid , reply . out . dst . sid , SID_SIZE ) ;
bcopy ( mdp - > out . dst . sid , reply . out . src . sid , SID_SIZE ) ;
reply . out . src . port = MDP_PORT_STUNREQ ;
reply . out . dst . port = MDP_PORT_STUN ;
struct overlay_buffer * replypayload = ob_static ( reply . out . payload , sizeof ( reply . out . payload ) ) ;
ob_checkpoint ( replypayload ) ;
while ( ob_remaining ( payload ) > 0 ) {
struct subscriber * subscriber = NULL ;
if ( overlay_address_parse ( NULL , payload , & subscriber ) )
break ;
2012-12-08 04:39:41 +00:00
if ( ! subscriber ) {
DEBUGF ( " Unknown subscriber " ) ;
2012-12-07 05:34:40 +00:00
continue ;
2012-12-08 04:39:41 +00:00
}
2012-12-07 05:34:40 +00:00
if ( overlay_append_unicast_address ( subscriber , replypayload ) )
break ;
}
ob_rewind ( replypayload ) ;
reply . out . payload_length = ob_position ( replypayload ) ;
2012-12-08 04:39:41 +00:00
if ( reply . out . payload_length ) {
DEBUGF ( " Sending reply " ) ;
2012-12-07 05:34:40 +00:00
overlay_mdp_dispatch ( & reply , 0 /* system generated */ ,
NULL , 0 ) ;
2012-12-08 04:39:41 +00:00
}
2012-12-07 05:34:40 +00:00
ob_free ( replypayload ) ;
ob_free ( payload ) ;
return 0 ;
}
static int overlay_mdp_service_stun ( overlay_mdp_frame * mdp )
{
struct overlay_buffer * buff = ob_static ( mdp - > out . payload , mdp - > out . payload_length ) ;
ob_limitsize ( buff , mdp - > out . payload_length ) ;
DEBUGF ( " Processing STUN info from %s " , alloca_tohex_sid ( mdp - > out . src . sid ) ) ;
while ( ob_remaining ( buff ) > 0 ) {
struct subscriber * subscriber = NULL ;
struct sockaddr_in addr ;
// TODO explain addresses, link expiry time, resolve differences between addresses...
if ( overlay_address_parse ( NULL , buff , & subscriber ) ) {
break ;
}
addr . sin_family = AF_INET ;
addr . sin_addr . s_addr = ob_get_ui32 ( buff ) ;
addr . sin_port = ob_get_ui16 ( buff ) ;
if ( ! subscriber | | ( subscriber - > reachable ! = REACHABLE_NONE ) )
continue ;
overlay_send_probe ( subscriber , addr , NULL ) ;
}
ob_free ( buff ) ;
return 0 ;
}
int overlay_send_stun_request ( struct subscriber * server , struct subscriber * request ) {
if ( ( ! server ) | | ( ! request ) )
return - 1 ;
if ( ! ( subscriber_is_reachable ( server ) & REACHABLE ) )
return - 1 ;
// don't bother with a stun request if the peer is already reachable directly
// TODO link timeouts
if ( subscriber_is_reachable ( request ) & REACHABLE_DIRECT )
return - 1 ;
overlay_mdp_frame mdp ;
bzero ( & mdp , sizeof ( mdp ) ) ;
mdp . packetTypeAndFlags = MDP_TX ;
bcopy ( my_subscriber - > sid , mdp . out . src . sid , SID_SIZE ) ;
bcopy ( server - > sid , mdp . out . dst . sid , SID_SIZE ) ;
mdp . out . src . port = MDP_PORT_STUN ;
mdp . out . dst . port = MDP_PORT_STUNREQ ;
struct overlay_buffer * payload = ob_static ( mdp . out . payload , sizeof ( mdp . out . payload ) ) ;
overlay_address_append ( NULL , payload , request ) ;
mdp . out . payload_length = ob_position ( payload ) ;
DEBUGF ( " Sending STUN request to %s " , alloca_tohex_sid ( server - > sid ) ) ;
overlay_mdp_dispatch ( & mdp , 0 /* system generated */ ,
NULL , 0 ) ;
ob_free ( payload ) ;
return 0 ;
}
2012-11-30 01:18:00 +00:00
int overlay_mdp_try_interal_services ( overlay_mdp_frame * mdp )
{
IN ( ) ;
switch ( mdp - > out . dst . port ) {
2012-11-30 03:47:05 +00:00
case MDP_PORT_VOMP : RETURN ( vomp_mdp_received ( mdp ) ) ;
case MDP_PORT_KEYMAPREQUEST : RETURN ( keyring_mapping_request ( keyring , mdp ) ) ;
case MDP_PORT_DNALOOKUP : RETURN ( overlay_mdp_service_dnalookup ( mdp ) ) ;
case MDP_PORT_ECHO : RETURN ( overlay_mdp_service_echo ( mdp ) ) ;
2012-12-04 04:17:57 +00:00
case MDP_PORT_PROBE : RETURN ( overlay_mdp_service_probe ( mdp ) ) ;
2012-12-07 05:34:40 +00:00
case MDP_PORT_STUNREQ : RETURN ( overlay_mdp_service_stun_req ( mdp ) ) ;
case MDP_PORT_STUN : RETURN ( overlay_mdp_service_stun ( mdp ) ) ;
2012-11-30 04:17:27 +00:00
case MDP_PORT_RHIZOME_REQUEST :
if ( is_rhizome_mdp_server_running ( ) ) {
RETURN ( overlay_mdp_service_rhizomerequest ( mdp ) ) ;
} else break ;
2012-12-04 05:40:17 +00:00
case MDP_PORT_RHIZOME_RESPONSE : RETURN ( overlay_mdp_service_rhizomeresponse ( mdp ) ) ;
2012-11-30 01:18:00 +00:00
}
2012-11-30 04:17:27 +00:00
/* Unbound socket. We won't be sending ICMP style connection refused
messages , partly because they are a waste of bandwidth . */
RETURN ( WHYF ( " Received packet for which no listening process exists (MDP ports: src=%d, dst=%d " ,
mdp - > out . src . port , mdp - > out . dst . port ) ) ;
2012-11-30 01:18:00 +00:00
}