Initial work towards rhizome direct syncrhonisation functions #9

This commit is contained in:
gardners 2012-08-28 13:32:02 +09:30
parent 420add0f4b
commit 2b29893a02
4 changed files with 136 additions and 0 deletions

View File

@ -43,6 +43,7 @@ SRCS= \
rhizome_bundle.c \
rhizome_crypto.c \
rhizome_database.c \
rhizome_direct.c \
rhizome_fetch.c \
rhizome_http.c \
rhizome_packetformats.c \

View File

@ -1783,6 +1783,11 @@ command_line_option command_line_options[]={
"Extract a manifest from Rhizome and write it to the given path"},
{app_rhizome_extract_file,{"rhizome","extract","file","<fileid>","[<filepath>]","[<key>]",NULL},CLIFLAG_STANDALONE,
"Extract a file from Rhizome and write it to the given path"},
{app_rhizome_direct_server,{"rhizome","direct","server",NULL},CLIFLAG_STANDALONE,
"Listen for Rhizome Direct requests"},
{app_rhizome_direct_sync,{"rhizome","direct","sync","<ip:port>",NULL},
CLIFLAG_STANDALONE,
"Synchronise with the specified Rhizome Direct server. Return when done."},
{app_keyring_create,{"keyring","create",NULL},0,
"Create a new keyring file."},
{app_keyring_list,{"keyring","list","[<pin,pin...>]",NULL},CLIFLAG_STANDALONE,

125
rhizome_direct.c Normal file
View File

@ -0,0 +1,125 @@
/*
Serval Mesh Software
Copyright (C) 2010-2012 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.
*/
/*
Rhizome Direct (github issue #9)
The base rhizome protocol allows the automatic and progressive transfer of data
bundles (typically files and their associated meta-data) between devices sharing
a common network interface.
There are several use-cases where that is insufficient, e.g.:
1. User wishes to cause two near-by devices to completely synchronise, e.g., as
part of a regular data courier activity, or a field operation centre wishing to
extract all field-collected data from a device, and possibly provide the field
device with updated operational information and software.
2. Two remote devices wish to synchronise, e.g., redundant Serval Rhizome servers
forming part of a humanitarian or governmental emergency/disaster response
capability.
3. As (2), but with regular synchronisation.
In all cases what is required is a mechanism for one Serval daemon instance to
communicate via another Serval daemon instance, and determine the bundles that
need to be transfered in each direction, and effect those transfers.
Several challenges complicate this objective:
1. Network Address Translation (NAT) or some other barrier may make it impossible
for one of the devices to initiate a TCP connection to the other device. Thus
the protocol must be able to operate "one-sided", yet be able to synchronise
bundles in both directions.
2. The protocol must not impair the real-time requirements of the Serval daemon
at either end. Therefore the protocol must be implemented in a separate thread
or process. As the Serval design is for single-threaded processes to improve
portability and reliability, a separate process will be used. That separate
process will be another instance of the Serval daemon that will be run from the
command line, and terminate when the synchronisation has completed, or when it
receives an appropriate signal. This approach also ensures that the Rhizome
databases at each end will always be consistent (or more properly, not become
inconsistent due to the operation of this protocol).
The test suites to exercise this protocol are located in "tests/rhizomeprotocol".
The above functionality resolves down to several specific functions:
1. Ability to enquire running servald and generate a list of BARs that it has
stored, and present that list of "IHAVE"'s to the far end for examination.
2. Ability to respond to such a list of BAR's, compare the list to the local
servald instance's Rhizome database, and send back a list of "IHAVE"'s for any
bundles that are newer than those presented in the list, or that were not present
in the list.
3. Ability to parse such a list of "IHAVE"'s, and from that determine the set of
bundles to synchronise in each direction.
4. As each server may have very many bundles, the above transactions must be able
to operate on a limited range of bundle-IDs. Each request shall therefore include
the lowest and highest bundle-ID covered by the list.
Note that the above actions are between the two Rhizome Direct processes, and not
the Serval daemon processes (although each Rhizome Direct process will necessarily
need to communicate with their local Serval daemon instances).
5. Ability to present a BAR to the remote end Serval daemon instance and fetch the
associated data bundle, and then present it to the local Serval daemon instance
for adding to the local Rhizome database.
It is recognised that the Serval daemon's real-time behaviour is compromised by
the current mechanism for importing bundles into the Rhizome database. This will
be addressed as part of the on-going development of the main Rhizome protocol, and
its rectification is beyond the scope of Rhizome Direct.
6. Ability to present manifest and associated data for a bundle to the remote
Rhizome Direct process for that process to schedule its insertion into the Rhizome
database.
As with the existing Rhizome protocol, it seems reasonable to use HTTP as the
basis. The interactions will be M2M, so we do not need a fully-fledged HTTP
server at this stage, but can make use of our own spartan HTTP server already
integrated into servald.
In light of the above, the Rhizome Direct process will need to have it's own TCP
port number. It is also necessary to have a Rhizome Direct process running to
accept Rhizome Direct requests from clients.
*/
#include "serval.h"
int app_rhizome_direct_server(int argc, const char *const *argv,
struct command_line_option *o)
{
/* Start Rhizome Direct server on configured port. */
return -1;
}
int app_rhizome_direct_sync(int argc, const char *const *argv,
struct command_line_option *o)
{
/* Attempt to connect with a remote Rhizome Direct instance,
and negotiate which BARs to synchronise. */
return -1;
}

View File

@ -1055,6 +1055,11 @@ int overlay_broadcast_ensemble(int interface_number,
struct sockaddr_in *recipientaddr /* NULL == broadcast */,
unsigned char *bytes,int len);
int app_rhizome_direct_sync(int argc, const char *const *argv,
struct command_line_option *o);
int app_rhizome_direct_server(int argc, const char *const *argv,
struct command_line_option *o);
#ifdef HAVE_VOIPTEST
int app_pa_phone(int argc, const char *const *argv, struct command_line_option *o);
#endif