aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/gnunet-c-tutorial.tex11
-rw-r--r--src/cadet/Makefile.am26
-rw-r--r--src/cadet/TODO10
-rw-r--r--src/cadet/cadet_api.c1757
-rw-r--r--src/cadet/cadet_api_new.c1711
-rw-r--r--src/cadet/cadet_common.c370
-rw-r--r--src/cadet/cadet_test_lib.c4
-rw-r--r--src/cadet/gnunet-cadet.c6
-rw-r--r--src/cadet/test_cadet.c6
-rw-r--r--src/cadet/test_cadet_local_mq.c12
-rw-r--r--src/conversation/Makefile.am2
-rw-r--r--src/conversation/gnunet-service-conversation.c6
-rw-r--r--src/exit/Makefile.am2
-rw-r--r--src/exit/gnunet-daemon-exit.c10
-rw-r--r--src/fs/Makefile.am2
-rw-r--r--src/fs/gnunet-service-fs_cadet_client.c4
-rw-r--r--src/fs/gnunet-service-fs_cadet_server.c4
-rw-r--r--src/include/gnunet_cadet_service.h523
-rw-r--r--src/include/gnunet_datastore_service.h27
-rw-r--r--src/integration-tests/confs/test_defaults.conf4
-rw-r--r--src/multicast/Makefile.am2
-rw-r--r--src/multicast/gnunet-service-multicast.c6
-rw-r--r--src/pt/Makefile.am2
-rw-r--r--src/pt/gnunet-daemon-pt.c4
-rw-r--r--src/rps/Makefile.am34
-rw-r--r--src/rps/gnunet-service-rps.c218
-rw-r--r--src/rps/gnunet-service-rps_peers.c96
-rw-r--r--src/rps/gnunet-service-rps_peers.h37
-rw-r--r--src/rps/test_service_rps_peers.c8
-rw-r--r--src/scalarproduct/Makefile.am8
-rw-r--r--src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c4
-rw-r--r--src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c4
-rw-r--r--src/scalarproduct/gnunet-service-scalarproduct_alice.c4
-rw-r--r--src/scalarproduct/gnunet-service-scalarproduct_bob.c4
-rw-r--r--src/set/Makefile.am2
-rw-r--r--src/set/gnunet-service-set.c1351
-rw-r--r--src/set/gnunet-service-set.h354
-rw-r--r--src/set/gnunet-service-set_intersection.c542
-rw-r--r--src/set/gnunet-service-set_union.c363
-rw-r--r--src/set/set_api.c62
-rw-r--r--src/set/test_set_api.c76
-rw-r--r--src/set/test_set_union_copy.c3
-rw-r--r--src/statistics/gnunet-service-statistics.c7
-rw-r--r--src/util/client.c8
-rw-r--r--src/util/service_new.c13
-rw-r--r--src/util/util.conf5
-rw-r--r--src/vpn/Makefile.am2
-rw-r--r--src/vpn/gnunet-service-vpn.c4
48 files changed, 2267 insertions, 5453 deletions
diff --git a/doc/gnunet-c-tutorial.tex b/doc/gnunet-c-tutorial.tex
index 2b4a0d8e13..0f82a2e4b7 100644
--- a/doc/gnunet-c-tutorial.tex
+++ b/doc/gnunet-c-tutorial.tex
@@ -355,6 +355,11 @@ $ gnunet-statistics -c ~/peer1.conf -s dht # print statistics about DHT service
\subsection{Starting Two Peers by Hand}
+This section describes how to start two peers on the same machine by hand.
+The process is rather painful, but the description is somewhat instructive.
+In practice, you might prefer the automated method described in
+Section~\ref{sec:testbed}.
+
\subsubsection{Setup a second peer}
We will now start a second peer on your machine.
For the second peer, you will need to manually create a modified
@@ -376,7 +381,7 @@ $ cat $PREFIX/share/gnunet/config.d/*.conf > peer2.conf
Now you have to edit {\tt peer2.conf} and change:
\begin{itemize}
\itemsep0em
- \item{\texttt{SERVICEHOME} under \texttt{PATHS}}
+ \item{\texttt{GNUNET\_TEST\_HOME} under \texttt{PATHS}}
\item{Every (uncommented) value for ``\texttt{PORT}'' (add 10000) in any
section (the option may be commented out if \texttt{PORT} is
prefixed by "\#", in this case, UNIX domain sockets are used
@@ -460,7 +465,7 @@ $ gnunet-core -c peer1.conf
Peer `9TVUCS8P5A7ILLBGO6 [...shortened...] 1KNBJ4NGCHP3JPVULDG'
\end{lstlisting}
-\subsection{Starting Peers Using the Testbed Service}
+\subsection{Starting Peers Using the Testbed Service} \label{sec:testbed}
GNUnet's testbed service is used for testing scenarios where a number of peers
are to be started. The testbed can manage peers on a single host or on multiple
@@ -497,6 +502,8 @@ After installing GNUnet, the above source code can be compiled as:
$ export CPPFLAGS="-I/path/to/gnunet/headers"
$ export LDFLAGS="-L/path/to/gnunet/libraries"
$ gcc $CPPFLAGS $LDFLAGS -o testbed-test testbed_test.c -lgnunettestbed -lgnunetdht -lgnunetutil
+$ touch template.conf # Generate (empty) configuration
+$ ./testbed-test # run it (press CTRL-C to stop)
\end{lstlisting}
The \texttt{CPPFLAGS} and \texttt{LDFLAGS} are necessary if GNUnet is installed
into a different directory other than \texttt{/usr/local}.
diff --git a/src/cadet/Makefile.am b/src/cadet/Makefile.am
index 1fe9123057..af1a6720ce 100644
--- a/src/cadet/Makefile.am
+++ b/src/cadet/Makefile.am
@@ -29,35 +29,23 @@ bin_PROGRAMS = \
gnunet-cadet
lib_LTLIBRARIES = \
- libgnunetcadetnew.la \
libgnunetcadet.la \
$(EXP_LIB)
libgnunetcadet_la_SOURCES = \
- cadet_api.c cadet_common.c
+ cadet_api.c
libgnunetcadet_la_LIBADD = \
$(top_builddir)/src/util/libgnunetutil.la \
$(XLIB) \
$(LTLIBINTL)
libgnunetcadet_la_LDFLAGS = \
$(GN_LIB_LDFLAGS) $(WINFLAGS) \
- -version-info 5:0:0
-
-
-libgnunetcadetnew_la_SOURCES = \
- cadet_api_new.c
-libgnunetcadetnew_la_LIBADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(XLIB) \
- $(LTLIBINTL)
-libgnunetcadetnew_la_LDFLAGS = \
- $(GN_LIB_LDFLAGS) $(WINFLAGS) \
- -version-info 6:0:0
+ -version-info 7:0:0
gnunet_cadet_SOURCES = \
gnunet-cadet.c
gnunet_cadet_LDADD = \
- libgnunetcadetnew.la \
+ libgnunetcadet.la \
$(top_builddir)/src/util/libgnunetutil.la
gnunet_service_cadet_SOURCES = \
@@ -121,7 +109,7 @@ endif
test_cadet_local_mq_SOURCES = \
test_cadet_local_mq.c
test_cadet_local_mq_LDADD = \
- libgnunetcadetnew.la \
+ libgnunetcadet.la \
$(top_builddir)/src/testing/libgnunettesting.la \
$(top_builddir)/src/util/libgnunetutil.la
@@ -131,17 +119,17 @@ libgnunetcadettest_la_SOURCES = \
libgnunetcadettest_la_LIBADD = \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/testbed/libgnunettestbed.la \
- libgnunetcadetnew.la
+ libgnunetcadet.la
ld_cadet_test_lib = \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/testing/libgnunettesting.la \
- libgnunetcadetnew.la \
+ libgnunetcadet.la \
libgnunetcadettest.la \
$(top_builddir)/src/testbed/libgnunettestbed.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la
dep_cadet_test_lib = \
- libgnunetcadetnew.la \
+ libgnunetcadet.la \
libgnunetcadettest.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la
diff --git a/src/cadet/TODO b/src/cadet/TODO
index 820efab7a6..06567b0ad7 100644
--- a/src/cadet/TODO
+++ b/src/cadet/TODO
@@ -1,6 +1,10 @@
-- URGENT: Congestion/flow control (CHANNEL):
- + estimate max bandwidth using bursts and use to for CONGESTION CONTROL!
- (and figure out how/where to use this!)
+- URGENT:
+ + if 'client-not-ready', we do not ACK at all, and sender keeps
+ retransmitting again and again; would be good to do flow-control notification instead
+ of not ACKing that we got the data but are simply not ready for more!
+ + Congestion/flow control (CHANNEL):
+ estimate max bandwidth using bursts and use to for CONGESTION CONTROL!
+ (and figure out how/where to use this!)
- HIGH: revisit handling of 'unbuffered' traffic! (CHANNEL/TUNNEL)
(need to push down through tunnel into connection selection);
diff --git a/src/cadet/cadet_api.c b/src/cadet/cadet_api.c
index 7b9ac62b38..decf473a9c 100644
--- a/src/cadet/cadet_api.c
+++ b/src/cadet/cadet_api.c
@@ -21,8 +21,8 @@
* @file cadet/cadet_api.c
* @brief cadet api: client implementation of cadet service
* @author Bartlomiej Polot
+ * @author Christian Grothoff
*/
-
#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_constants.h"
@@ -32,57 +32,9 @@
#define LOG(kind,...) GNUNET_log_from (kind, "cadet-api",__VA_ARGS__)
-/******************************************************************************/
-/************************ DATA STRUCTURES ****************************/
-/******************************************************************************/
-
/**
- * Transmission queue to the service
- *
- * @deprecated
+ * Ugly legacy hack.
*/
-struct GNUNET_CADET_TransmitHandle
-{
- /**
- * Double Linked list
- */
- struct GNUNET_CADET_TransmitHandle *next;
-
- /**
- * Double Linked list
- */
- struct GNUNET_CADET_TransmitHandle *prev;
-
- /**
- * Channel this message is sent on / for (may be NULL for control messages).
- */
- struct GNUNET_CADET_Channel *channel;
-
- /**
- * Request data task.
- */
- struct GNUNET_SCHEDULER_Task *request_data_task;
-
- /**
- * Callback to obtain the message to transmit, or NULL if we
- * got the message in 'data'. Notice that messages built
- * by 'notify' need to be encapsulated with information about
- * the 'target'.
- */
- GNUNET_CONNECTION_TransmitReadyNotify notify;
-
- /**
- * Closure for 'notify'
- */
- void *notify_cls;
-
- /**
- * Size of the payload.
- */
- size_t size;
-};
-
-
union CadetInfoCB
{
@@ -119,69 +71,19 @@ union CadetInfoCB
struct GNUNET_CADET_Handle
{
/**
- * Flag to indicate old or MQ API.
- */
- int mq_api;
-
- /**
- * Message queue (if available).
+ * Message queue.
*/
struct GNUNET_MQ_Handle *mq;
/**
- * Set of handlers used for processing incoming messages in the channels
- *
- * @deprecated
- */
- const struct GNUNET_CADET_MessageHandler *message_handlers;
-
- /**
- * Number of handlers in the handlers array.
- *
- * @deprecated
- */
- unsigned int n_handlers;
-
- /**
* Ports open.
*/
struct GNUNET_CONTAINER_MultiHashMap *ports;
/**
- * Double linked list of the channels this client is connected to, head.
+ * Channels open.
*/
- struct GNUNET_CADET_Channel *channels_head;
-
- /**
- * Double linked list of the channels this client is connected to, tail.
- */
- struct GNUNET_CADET_Channel *channels_tail;
-
- /**
- * Callback for inbound channel disconnection
- */
- GNUNET_CADET_ChannelEndHandler *cleaner;
-
- /**
- * Closure for all the handlers given by the client
- *
- * @deprecated
- */
- void *cls;
-
- /**
- * Messages to send to the service, head.
- *
- * @deprecated
- */
- struct GNUNET_CADET_TransmitHandle *th_head;
-
- /**
- * Messages to send to the service, tail.
- *
- * @deprecated
- */
- struct GNUNET_CADET_TransmitHandle *th_tail;
+ struct GNUNET_CONTAINER_MultiHashMap32 *channels;
/**
* child of the next channel to create (to avoid reusing IDs often)
@@ -194,14 +96,9 @@ struct GNUNET_CADET_Handle
const struct GNUNET_CONFIGURATION_Handle *cfg;
/**
- * Time to the next reconnect in case one reconnect fails
- */
- struct GNUNET_TIME_Relative reconnect_time;
-
- /**
* Task for trying to reconnect.
*/
- struct GNUNET_SCHEDULER_Task * reconnect_task;
+ struct GNUNET_SCHEDULER_Task *reconnect_task;
/**
* Callback for an info task (only one active at a time).
@@ -212,23 +109,12 @@ struct GNUNET_CADET_Handle
* Info callback closure for @c info_cb.
*/
void *info_cls;
-};
-
-/**
- * Description of a peer
- */
-struct GNUNET_CADET_Peer
-{
/**
- * ID of the peer in short form
+ * Time to the next reconnect in case one reconnect fails
*/
- GNUNET_PEER_Id id;
+ struct GNUNET_TIME_Relative reconnect_time;
- /**
- * Channel this peer belongs to
- */
- struct GNUNET_CADET_Channel *t;
};
@@ -237,15 +123,11 @@ struct GNUNET_CADET_Peer
*/
struct GNUNET_CADET_Channel
{
- /**
- * DLL next
- */
- struct GNUNET_CADET_Channel *next;
/**
- * DLL prev
+ * Other end of the channel.
*/
- struct GNUNET_CADET_Channel *prev;
+ struct GNUNET_PeerIdentity peer;
/**
* Handle to the cadet this channel belongs to
@@ -253,40 +135,18 @@ struct GNUNET_CADET_Channel
struct GNUNET_CADET_Handle *cadet;
/**
- * Local ID of the channel
- */
- struct GNUNET_CADET_ClientChannelNumber ccn;
-
- /**
* Channel's port, if incoming.
*/
struct GNUNET_CADET_Port *incoming_port;
/**
- * Other end of the channel.
- */
- GNUNET_PEER_Id peer;
-
- /**
- * Any data the caller wants to put in here
+ * Any data the caller wants to put in here, used for the
+ * various callbacks (@e disconnects, @e window_changes, handlers).
*/
void *ctx;
/**
- * Channel options: reliability, etc.
- */
- enum GNUNET_CADET_ChannelOption options;
-
- /**
- * Are we allowed to send to the service?
- *
- * @deprecated?
- */
- unsigned int allow_send;
-
- /***************************** MQ ************************************/
- /**
- * Message Queue for the channel.
+ * Message Queue for the channel (which we are implementing).
*/
struct GNUNET_MQ_Handle *mq;
@@ -296,7 +156,9 @@ struct GNUNET_CADET_Channel
struct GNUNET_SCHEDULER_Task *mq_cont;
/**
- * Pending envelope in case we don't have an ACK from the service.
+ * Pending envelope with a message to be transmitted to the
+ * service as soon as we are allowed to. Should only be
+ * non-NULL if @e allow_send is 0.
*/
struct GNUNET_MQ_Envelope *pending_env;
@@ -310,6 +172,21 @@ struct GNUNET_CADET_Channel
*/
GNUNET_CADET_DisconnectEventHandler disconnects;
+ /**
+ * Local ID of the channel, #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI bit is set if outbound.
+ */
+ struct GNUNET_CADET_ClientChannelNumber ccn;
+
+ /**
+ * Channel options: reliability, etc.
+ */
+ enum GNUNET_CADET_ChannelOption options;
+
+ /**
+ * How many messages are we allowed to send to the service right now?
+ */
+ unsigned int allow_send;
+
};
@@ -318,35 +195,22 @@ struct GNUNET_CADET_Channel
*/
struct GNUNET_CADET_Port
{
- /**
- * Handle to the CADET session this port belongs to.
- */
- struct GNUNET_CADET_Handle *cadet;
/**
- * Port ID.
- *
- * @deprecated
+ * Port "number"
*/
- struct GNUNET_HashCode *hash;
+ struct GNUNET_HashCode id;
/**
- * Callback handler for incoming channels on this port.
+ * Handle to the CADET session this port belongs to.
*/
- GNUNET_CADET_InboundChannelNotificationHandler *handler;
+ struct GNUNET_CADET_Handle *cadet;
/**
* Closure for @a handler.
*/
void *cls;
- /***************************** MQ ************************************/
-
- /**
- * Port "number"
- */
- struct GNUNET_HashCode id;
-
/**
* Handler for incoming channels on this port
*/
@@ -355,7 +219,7 @@ struct GNUNET_CADET_Port
/**
* Closure for @ref connects
*/
- void * connects_cls;
+ void *connects_cls;
/**
* Window size change handler.
@@ -363,106 +227,30 @@ struct GNUNET_CADET_Port
GNUNET_CADET_WindowSizeEventHandler window_changes;
/**
- * Handler called when an incoming channel is destroyed..
+ * Handler called when an incoming channel is destroyed.
*/
GNUNET_CADET_DisconnectEventHandler disconnects;
/**
* Payload handlers for incoming channels.
*/
- const struct GNUNET_MQ_MessageHandler *handlers;
+ struct GNUNET_MQ_MessageHandler *handlers;
};
/**
- * Implementation state for cadet's message queue.
- */
-struct CadetMQState
-{
- /**
- * The current transmit handle, or NULL
- * if no transmit is active.
- */
- struct GNUNET_CADET_TransmitHandle *th;
-
- /**
- * Channel to send the data over.
- */
- struct GNUNET_CADET_Channel *channel;
-};
-
-
-
-/******************************************************************************/
-/********************* FUNCTION DECLARATIONS *************************/
-/******************************************************************************/
-
-/**
- * Reconnect to the service, retransmit all infomation to try to restore the
- * original state.
- *
- * @param h Handle to the CADET service.
- */
-static void
-schedule_reconnect (struct GNUNET_CADET_Handle *h);
-
-
-/**
- * Reconnect callback: tries to reconnect again after a failer previous
- * reconnection.
- *
- * @param cls Closure (cadet handle).
- */
-static void
-reconnect_cbk (void *cls);
-
-
-/**
- * Reconnect to the service, retransmit all infomation to try to restore the
- * original state.
- *
- * @param h handle to the cadet
- */
-static void
-reconnect (struct GNUNET_CADET_Handle *h);
-
-
-/******************************************************************************/
-/*********************** AUXILIARY FUNCTIONS *************************/
-/******************************************************************************/
-
-/**
- * Check if transmission is a payload packet.
- *
- * @param th Transmission handle.
- *
- * @return #GNUNET_YES if it is a payload packet,
- * #GNUNET_NO if it is a cadet management packet.
- */
-static int
-th_is_payload (struct GNUNET_CADET_TransmitHandle *th)
-{
- return (th->notify != NULL) ? GNUNET_YES : GNUNET_NO;
-}
-
-
-/**
* Find the Port struct for a hash.
*
* @param h CADET handle.
* @param hash HashCode for the port number.
- *
* @return The port handle if known, NULL otherwise.
*/
static struct GNUNET_CADET_Port *
find_port (const struct GNUNET_CADET_Handle *h,
const struct GNUNET_HashCode *hash)
{
- struct GNUNET_CADET_Port *p;
-
- p = GNUNET_CONTAINER_multihashmap_get (h->ports, hash);
-
- return p;
+ return GNUNET_CONTAINER_multihashmap_get (h->ports,
+ hash);
}
@@ -474,15 +262,11 @@ find_port (const struct GNUNET_CADET_Handle *h,
* @return handle to the required channel or NULL if not found
*/
static struct GNUNET_CADET_Channel *
-retrieve_channel (struct GNUNET_CADET_Handle *h,
- struct GNUNET_CADET_ClientChannelNumber ccn)
+find_channel (struct GNUNET_CADET_Handle *h,
+ struct GNUNET_CADET_ClientChannelNumber ccn)
{
- struct GNUNET_CADET_Channel *ch;
-
- for (ch = h->channels_head; NULL != ch; ch = ch->next)
- if (ch->ccn.channel_of_client == ccn.channel_of_client)
- return ch;
- return NULL;
+ return GNUNET_CONTAINER_multihashmap32_get (h->channels,
+ ntohl (ccn.channel_of_client));
}
@@ -490,38 +274,37 @@ retrieve_channel (struct GNUNET_CADET_Handle *h,
* Create a new channel and insert it in the channel list of the cadet handle
*
* @param h Cadet handle
- * @param ccn Desired ccn of the channel, 0 to assign one automatically.
- *
+ * @param ccnp pointer to desired ccn of the channel, NULL to assign one automatically.
* @return Handle to the created channel.
*/
static struct GNUNET_CADET_Channel *
create_channel (struct GNUNET_CADET_Handle *h,
- struct GNUNET_CADET_ClientChannelNumber ccn)
+ const struct GNUNET_CADET_ClientChannelNumber *ccnp)
{
struct GNUNET_CADET_Channel *ch;
+ struct GNUNET_CADET_ClientChannelNumber ccn;
ch = GNUNET_new (struct GNUNET_CADET_Channel);
- GNUNET_CONTAINER_DLL_insert (h->channels_head,
- h->channels_tail,
- ch);
ch->cadet = h;
- if (0 == ccn.channel_of_client)
+ if (NULL == ccnp)
{
- ch->ccn = h->next_ccn;
- while (NULL != retrieve_channel (h,
- h->next_ccn))
- {
+ while (NULL !=
+ find_channel (h,
+ h->next_ccn))
h->next_ccn.channel_of_client
- = htonl (1 + ntohl (h->next_ccn.channel_of_client));
- if (0 == ntohl (h->next_ccn.channel_of_client))
- h->next_ccn.channel_of_client
- = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
- }
+ = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI | (1 + ntohl (h->next_ccn.channel_of_client)));
+ ccn = h->next_ccn;
}
else
{
- ch->ccn = ccn;
+ ccn = *ccnp;
}
+ ch->ccn = ccn;
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CONTAINER_multihashmap32_put (h->channels,
+ ntohl (ch->ccn.channel_of_client),
+ ch,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
return ch;
}
@@ -535,114 +318,106 @@ create_channel (struct GNUNET_CADET_Handle *h,
*
* @param ch Pointer to the channel.
* @param call_cleaner Whether to call the cleaner handler.
- *
- * @return Handle to the required channel or NULL if not found.
*/
static void
destroy_channel (struct GNUNET_CADET_Channel *ch)
{
- struct GNUNET_CADET_Handle *h;
- struct GNUNET_CADET_TransmitHandle *th;
- struct GNUNET_CADET_TransmitHandle *next;
+ struct GNUNET_CADET_Handle *h = ch->cadet;
- if (NULL == ch)
- {
- GNUNET_break (0);
- return;
- }
- h = ch->cadet;
LOG (GNUNET_ERROR_TYPE_DEBUG,
- " destroy_channel %X of %p\n",
+ "Destroying channel %X of %p\n",
ch->ccn,
h);
-
- GNUNET_CONTAINER_DLL_remove (h->channels_head,
- h->channels_tail,
- ch);
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CONTAINER_multihashmap32_remove (h->channels,
+ ntohl (ch->ccn.channel_of_client),
+ ch));
if (NULL != ch->mq_cont)
{
GNUNET_SCHEDULER_cancel (ch->mq_cont);
ch->mq_cont = NULL;
}
/* signal channel destruction */
- if (0 != ch->peer)
- {
- if (NULL != h->cleaner)
- {
- /** @a deprecated */
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- " calling cleaner\n");
- h->cleaner (h->cls, ch, ch->ctx);
- }
- else if (NULL != ch->disconnects)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- " calling disconnect handler\n");
- ch->disconnects (ch->ctx, ch);
- }
- else
- {
- /* Application won't be aware of the channel destruction and use
- * a pointer to free'd memory.
- */
- GNUNET_assert (0);
- }
- }
-
- /* check that clients did not leave messages behind in the queue */
- for (th = h->th_head; NULL != th; th = next)
- {
- next = th->next;
- if (th->channel != ch)
- continue;
- /* Clients should have aborted their requests already.
- * Management traffic should be ok, as clients can't cancel that.
- * If the service crashed and we are reconnecting, it's ok.
- */
- GNUNET_break (GNUNET_NO == th_is_payload (th));
- GNUNET_CADET_notify_transmit_ready_cancel (th);
- }
-
- if (0 != ch->peer)
- GNUNET_PEER_change_rc (ch->peer, -1);
+ if (NULL != ch->disconnects)
+ ch->disconnects (ch->ctx,
+ ch);
+ if (NULL != ch->pending_env)
+ GNUNET_MQ_discard (ch->pending_env);
+ GNUNET_MQ_destroy (ch->mq);
GNUNET_free (ch);
}
/**
- * Add a transmit handle to the transmission queue and set the
- * timeout if needed.
+ * Reconnect to the service, retransmit all infomation to try to restore the
+ * original state.
+ *
+ * @param h handle to the cadet
+ */
+static void
+reconnect (struct GNUNET_CADET_Handle *h);
+
+
+/**
+ * Reconnect callback: tries to reconnect again after a failer previous
+ * reconnecttion
*
- * @param h cadet handle with the queue head and tail
- * @param th handle to the packet to be transmitted
+ * @param cls closure (cadet handle)
*/
static void
-add_to_queue (struct GNUNET_CADET_Handle *h,
- struct GNUNET_CADET_TransmitHandle *th)
+reconnect_cbk (void *cls)
+{
+ struct GNUNET_CADET_Handle *h = cls;
+
+ h->reconnect_task = NULL;
+ reconnect (h);
+}
+
+
+/**
+ * Function called during #reconnect() to destroy
+ * all channels that are still open.
+ *
+ * @param cls the `struct GNUNET_CADET_Handle`
+ * @param cid chanenl ID
+ * @param value a `struct GNUNET_CADET_Channel` to destroy
+ * @return #GNUNET_OK (continue to iterate)
+ */
+static int
+destroy_channel_on_reconnect_cb (void *cls,
+ uint32_t cid,
+ void *value)
{
- GNUNET_CONTAINER_DLL_insert_tail (h->th_head,
- h->th_tail,
- th);
+ /* struct GNUNET_CADET_Handle *handle = cls; */
+ struct GNUNET_CADET_Channel *ch = value;
+
+ destroy_channel (ch);
+ return GNUNET_OK;
}
/**
- * Remove a transmit handle from the transmission queue, if present.
+ * Reconnect to the service, retransmit all infomation to try to restore the
+ * original state.
*
- * Safe to call even if not queued.
+ * @param h handle to the cadet
*
- * @param th handle to the packet to be unqueued.
+ * @return #GNUNET_YES in case of sucess, #GNUNET_NO otherwise (service down...)
*/
static void
-remove_from_queue (struct GNUNET_CADET_TransmitHandle *th)
+schedule_reconnect (struct GNUNET_CADET_Handle *h)
{
- struct GNUNET_CADET_Handle *h = th->channel->cadet;
-
- /* It might or might not have been queued (rarely not), but check anyway. */
- if (NULL != th->next || h->th_tail == th)
- {
- GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th);
- }
+ if (NULL != h->reconnect_task)
+ return;
+ GNUNET_CONTAINER_multihashmap32_iterate (h->channels,
+ &destroy_channel_on_reconnect_cb,
+ h);
+ h->reconnect_task
+ = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
+ &reconnect_cbk,
+ h);
+ h->reconnect_time
+ = GNUNET_TIME_STD_BACKOFF (h->reconnect_time);
}
@@ -655,29 +430,44 @@ static void
notify_window_size (struct GNUNET_CADET_Channel *ch)
{
if (NULL != ch->window_changes)
- {
- ch->window_changes (ch->ctx, ch, ch->allow_send);
- }
+ ch->window_changes (ch->ctx,
+ ch, /* FIXME: remove 'ch'? */
+ ch->allow_send);
}
-/******************************************************************************/
-/*********************** MQ API CALLBACKS ****************************/
-/******************************************************************************/
/**
- * Allow the MQ implementation to send the next message.
+ * Transmit the next message from our queue.
*
* @param cls Closure (channel whose mq to activate).
*/
static void
-cadet_mq_send_continue (void *cls)
+cadet_mq_send_now (void *cls)
{
struct GNUNET_CADET_Channel *ch = cls;
+ struct GNUNET_MQ_Envelope *env = ch->pending_env;
ch->mq_cont = NULL;
+ if (0 == ch->allow_send)
+ {
+ /* how did we get here? */
+ GNUNET_break (0);
+ return;
+ }
+ if (NULL == env)
+ {
+ /* how did we get here? */
+ GNUNET_break (0);
+ return;
+ }
+ ch->allow_send--;
+ ch->pending_env = NULL;
+ GNUNET_MQ_send (ch->cadet->mq,
+ env);
GNUNET_MQ_impl_send_continue (ch->mq);
}
+
/**
* Implement sending functionality of a message queue for
* us sending messages to a peer.
@@ -701,7 +491,6 @@ cadet_mq_send_impl (struct GNUNET_MQ_Handle *mq,
struct GNUNET_MQ_Envelope *env;
struct GNUNET_CADET_LocalData *cadet_msg;
-
if (NULL == h->mq)
{
/* We're currently reconnecting, pretend this worked */
@@ -717,26 +506,16 @@ cadet_mq_send_impl (struct GNUNET_MQ_Handle *mq,
GNUNET_MQ_impl_send_continue (mq);
return;
}
-
env = GNUNET_MQ_msg_nested_mh (cadet_msg,
GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
msg);
cadet_msg->ccn = ch->ccn;
-
+ GNUNET_assert (NULL == ch->pending_env);
+ ch->pending_env = env;
if (0 < ch->allow_send)
- {
- /* Service has allowed this message, just send it and continue accepting */
- GNUNET_MQ_send (h->mq, env);
- ch->allow_send--;
- ch->mq_cont = GNUNET_SCHEDULER_add_now (&cadet_mq_send_continue, ch);
- // notify_window_size (ch); /* FIXME add "verbose" setting? */
- }
- else
- {
- /* Service has NOT allowed this message, queue it and wait for an ACK */
- GNUNET_assert (NULL == ch->pending_env);
- ch->pending_env = env;
- }
+ ch->mq_cont
+ = GNUNET_SCHEDULER_add_now (&cadet_mq_send_now,
+ ch);
}
@@ -763,14 +542,25 @@ cadet_mq_destroy_impl (struct GNUNET_MQ_Handle *mq,
* the CADET service. We should just complain about it but otherwise
* continue processing.
*
- * @param cls closure
+ * @param cls closure with our `struct GNUNET_CADET_Channel`
* @param error error code
*/
static void
cadet_mq_error_handler (void *cls,
enum GNUNET_MQ_Error error)
{
- GNUNET_break_op (0);
+ struct GNUNET_CADET_Channel *ch = cls;
+
+ GNUNET_break (0);
+ if (GNUNET_MQ_ERROR_NO_MATCH == error)
+ {
+ /* Got a message we did not understand, still try to continue! */
+ GNUNET_CADET_receive_done (ch);
+ }
+ else
+ {
+ schedule_reconnect (ch->cadet);
+ }
}
@@ -781,65 +571,20 @@ cadet_mq_error_handler (void *cls,
* @param mq message queue
* @param impl_state state specific to the implementation
*/
-
static void
cadet_mq_cancel_impl (struct GNUNET_MQ_Handle *mq,
void *impl_state)
{
struct GNUNET_CADET_Channel *ch = impl_state;
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "Cannot cancel mq message on channel %X of %p\n",
- ch->ccn.channel_of_client, ch->cadet);
-
- GNUNET_break (0);
-}
-
-
-/******************************************************************************/
-/*********************** RECEIVE HANDLERS ****************************/
-/******************************************************************************/
-
-
-/**
- * Call the @a notify callback given to #GNUNET_CADET_notify_transmit_ready to
- * request the data to send over MQ. Since MQ manages the queue, this function
- * is scheduled immediatly after a transmit ready notification.
- *
- * @param cls Closure (transmit handle).
- */
-static void
-request_data (void *cls)
-{
- struct GNUNET_CADET_TransmitHandle *th = cls;
- struct GNUNET_CADET_LocalData *msg;
- struct GNUNET_MQ_Envelope *env;
- size_t osize;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Requesting Data: %u bytes (allow send is %u)\n",
- th->size,
- th->channel->allow_send);
-
- GNUNET_assert (0 < th->channel->allow_send);
- th->channel->allow_send--;
- /* NOTE: we may be allowed to send another packet immediately,
- albeit the current logic waits for the ACK. */
- th->request_data_task = NULL;
- remove_from_queue (th);
-
- env = GNUNET_MQ_msg_extra (msg,
- th->size,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
- msg->ccn = th->channel->ccn;
- osize = th->notify (th->notify_cls,
- th->size,
- &msg[1]);
- GNUNET_assert (osize == th->size);
-
- GNUNET_MQ_send (th->channel->cadet->mq,
- env);
- GNUNET_free (th);
+ GNUNET_assert (NULL != ch->pending_env);
+ GNUNET_MQ_discard (ch->pending_env);
+ ch->pending_env = NULL;
+ if (NULL != ch->mq_cont)
+ {
+ GNUNET_SCHEDULER_cancel (ch->mq_cont);
+ ch->mq_cont = NULL;
+ }
}
@@ -866,7 +611,8 @@ handle_channel_created (void *cls,
GNUNET_break (0);
return;
}
- port = find_port (h, port_number);
+ port = find_port (h,
+ port_number);
if (NULL == port)
{
/* We could have closed the port but the service didn't know about it yet
@@ -875,7 +621,6 @@ handle_channel_created (void *cls,
struct GNUNET_CADET_LocalChannelDestroyMessage *d_msg;
struct GNUNET_MQ_Envelope *env;
- GNUNET_break (0);
LOG (GNUNET_ERROR_TYPE_DEBUG,
"No handler for incoming channel %X (on port %s, recently closed?)\n",
ntohl (ccn.channel_of_client),
@@ -889,10 +634,9 @@ handle_channel_created (void *cls,
}
ch = create_channel (h,
- ccn);
- ch->peer = GNUNET_PEER_intern (&msg->peer);
+ &ccn);
+ ch->peer = msg->peer;
ch->cadet = h;
- ch->ccn = ccn;
ch->incoming_port = port;
ch->options = ntohl (msg->opt);
LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -901,34 +645,21 @@ handle_channel_created (void *cls,
GNUNET_h2s (port_number),
ch);
- if (NULL != port->handler)
- {
- /** @deprecated */
- /* Old style API */
- ch->ctx = port->handler (port->cls,
- ch,
- &msg->peer,
- port->hash,
- ch->options);
- }
- else
- {
- /* MQ API */
- GNUNET_assert (NULL != port->connects);
- ch->window_changes = port->window_changes;
- ch->disconnects = port->disconnects;
- ch->mq = GNUNET_MQ_queue_for_callbacks (&cadet_mq_send_impl,
- &cadet_mq_destroy_impl,
- &cadet_mq_cancel_impl,
- ch,
- port->handlers,
- &cadet_mq_error_handler,
- ch);
- ch->ctx = port->connects (port->cls,
- ch,
- &msg->peer);
- GNUNET_MQ_set_handlers_closure (ch->mq, ch->ctx);
- }
+ GNUNET_assert (NULL != port->connects);
+ ch->window_changes = port->window_changes;
+ ch->disconnects = port->disconnects;
+ ch->mq = GNUNET_MQ_queue_for_callbacks (&cadet_mq_send_impl,
+ &cadet_mq_destroy_impl,
+ &cadet_mq_cancel_impl,
+ ch,
+ port->handlers,
+ &cadet_mq_error_handler,
+ ch);
+ ch->ctx = port->connects (port->cls,
+ ch,
+ &msg->peer);
+ GNUNET_MQ_set_handlers_closure (ch->mq,
+ ch->ctx);
}
@@ -944,22 +675,19 @@ handle_channel_destroy (void *cls,
{
struct GNUNET_CADET_Handle *h = cls;
struct GNUNET_CADET_Channel *ch;
- struct GNUNET_CADET_ClientChannelNumber ccn;
-
- ccn = msg->ccn;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Channel %X Destroy from service\n",
- ntohl (ccn.channel_of_client));
- ch = retrieve_channel (h,
- ccn);
+ ch = find_channel (h,
+ msg->ccn);
if (NULL == ch)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "channel %X unknown\n",
- ntohl (ccn.channel_of_client));
+ "Received channel destroy for unknown channel %X from CADET service (recently close?)\n",
+ ntohl (msg->ccn.channel_of_client));
return;
}
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Received channel destroy for channel %X from CADET service\n",
+ ntohl (msg->ccn.channel_of_client));
destroy_channel (ch);
}
@@ -976,25 +704,14 @@ static int
check_local_data (void *cls,
const struct GNUNET_CADET_LocalData *message)
{
- struct GNUNET_CADET_Handle *h = cls;
- struct GNUNET_CADET_Channel *ch;
uint16_t size;
size = ntohs (message->header.size);
if (sizeof (*message) + sizeof (struct GNUNET_MessageHeader) > size)
{
- GNUNET_break_op (0);
- return GNUNET_SYSERR;
- }
-
- ch = retrieve_channel (h,
- message->ccn);
- if (NULL == ch)
- {
- GNUNET_break_op (0);
+ GNUNET_break (0);
return GNUNET_SYSERR;
}
-
return GNUNET_OK;
}
@@ -1011,62 +728,31 @@ handle_local_data (void *cls,
{
struct GNUNET_CADET_Handle *h = cls;
const struct GNUNET_MessageHeader *payload;
- const struct GNUNET_CADET_MessageHandler *handler;
struct GNUNET_CADET_Channel *ch;
uint16_t type;
int fwd;
- ch = retrieve_channel (h,
- message->ccn);
+ ch = find_channel (h,
+ message->ccn);
if (NULL == ch)
{
- GNUNET_break_op (0);
- reconnect (h);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Unknown channel %X for incoming data (recently closed?)\n",
+ ntohl (message->ccn.channel_of_client));
return;
}
- payload = (struct GNUNET_MessageHeader *) &message[1];
+ payload = (const struct GNUNET_MessageHeader *) &message[1];
type = ntohs (payload->type);
fwd = ntohl (ch->ccn.channel_of_client) <= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Got a %s data on channel %s [%X] of type %s (%u)\n",
- GC_f2s (fwd),
- GNUNET_i2s (GNUNET_PEER_resolve2 (ch->peer)),
+ "Got a %s data on channel %s [%X] of type %u\n",
+ fwd ? "FWD" : "BWD",
+ GNUNET_i2s (&ch->peer),
ntohl (message->ccn.channel_of_client),
- GC_m2s (type),
type);
- if (NULL != ch->mq)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "injecting msg %s into mq %p\n",
- GC_m2s (ntohs (payload->type)),
- ch->mq);
- GNUNET_MQ_inject_message (ch->mq, payload);
- return;
- }
- /** @a deprecated */
- for (unsigned i=0;i<h->n_handlers;i++)
- {
- handler = &h->message_handlers[i];
- if (handler->type == type)
- {
- if (GNUNET_OK !=
- handler->callback (h->cls,
- ch,
- &ch->ctx,
- payload))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "callback caused disconnection\n");
- GNUNET_CADET_channel_destroy (ch);
- return;
- }
- return;
- }
- }
- /* Other peer sent message we do not comprehend. */
- GNUNET_break_op (0);
- GNUNET_CADET_receive_done (ch);
+ GNUNET_MQ_inject_message (ch->mq,
+ payload);
}
@@ -1083,55 +769,34 @@ handle_local_ack (void *cls,
{
struct GNUNET_CADET_Handle *h = cls;
struct GNUNET_CADET_Channel *ch;
- struct GNUNET_CADET_ClientChannelNumber ccn;
- struct GNUNET_CADET_TransmitHandle *th;
- ccn = message->ccn;
- ch = retrieve_channel (h, ccn);
+ ch = find_channel (h,
+ message->ccn);
if (NULL == ch)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
"ACK on unknown channel %X\n",
- ntohl (ccn.channel_of_client));
+ ntohl (message->ccn.channel_of_client));
return;
}
ch->allow_send++;
- if (NULL != ch->mq)
+ if (NULL == ch->pending_env)
{
- if (NULL == ch->pending_env)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Got an ACK on mq channel %X, allow send now %u!\n",
- ntohl (ch->ccn.channel_of_client),
- ch->allow_send);
- notify_window_size (ch);
- }
- else
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Got an ACK on mq channel %X, sending pending message!\n",
- ntohl (ch->ccn.channel_of_client));
- GNUNET_MQ_send (h->mq, ch->pending_env);
- ch->allow_send--;
- ch->pending_env = NULL;
- ch->mq_cont = GNUNET_SCHEDULER_add_now (&cadet_mq_send_continue, ch);
- }
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Got an ACK on mq channel %X, allow send now %u!\n",
+ ntohl (ch->ccn.channel_of_client),
+ ch->allow_send);
+ notify_window_size (ch);
return;
}
-
- /** @deprecated */
- /* Old style API */
- for (th = h->th_head; NULL != th; th = th->next)
- {
- if ( (th->channel == ch) &&
- (NULL == th->request_data_task) )
- {
- th->request_data_task
- = GNUNET_SCHEDULER_add_now (&request_data,
- th);
- break;
- }
- }
+ if (NULL != ch->mq_cont)
+ return; /* already working on it! */
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Got an ACK on mq channel %X, sending pending message!\n",
+ ntohl (ch->ccn.channel_of_client));
+ ch->mq_cont
+ = GNUNET_SCHEDULER_add_now (&cadet_mq_send_now,
+ ch);
}
@@ -1149,134 +814,15 @@ handle_mq_error (void *cls,
{
struct GNUNET_CADET_Handle *h = cls;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MQ ERROR: %u\n", error);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "MQ ERROR: %u\n",
+ error);
GNUNET_MQ_destroy (h->mq);
h->mq = NULL;
reconnect (h);
}
-/*
- * Process a local reply about info on all channels, pass info to the user.
- *
- * @param h Cadet handle.
- * @param message Message itself.
- */
-// static void
-// process_get_channels (struct GNUNET_CADET_Handle *h,
-// const struct GNUNET_MessageHeader *message)
-// {
-// struct GNUNET_CADET_LocalInfo *msg;
-//
-// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Get Channels messasge received\n");
-//
-// if (NULL == h->channels_cb)
-// {
-// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " ignored\n");
-// return;
-// }
-//
-// msg = (struct GNUNET_CADET_LocalInfo *) message;
-// if (ntohs (message->size) !=
-// (sizeof (struct GNUNET_CADET_LocalInfo) +
-// sizeof (struct GNUNET_PeerIdentity)))
-// {
-// GNUNET_break_op (0);
-// GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-// "Get channels message: size %hu - expected %u\n",
-// ntohs (message->size),
-// sizeof (struct GNUNET_CADET_LocalInfo));
-// return;
-// }
-// h->channels_cb (h->channels_cls,
-// ntohl (msg->channel_id),
-// &msg->owner,
-// &msg->destination);
-// }
-
-
-
-/*
- * Process a local monitor_channel reply, pass info to the user.
- *
- * @param h Cadet handle.
- * @param message Message itself.
- */
-// static void
-// process_show_channel (struct GNUNET_CADET_Handle *h,
-// const struct GNUNET_MessageHeader *message)
-// {
-// struct GNUNET_CADET_LocalInfo *msg;
-// size_t esize;
-//
-// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Show Channel messasge received\n");
-//
-// if (NULL == h->channel_cb)
-// {
-// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " ignored\n");
-// return;
-// }
-//
-// /* Verify message sanity */
-// msg = (struct GNUNET_CADET_LocalInfo *) message;
-// esize = sizeof (struct GNUNET_CADET_LocalInfo);
-// if (ntohs (message->size) != esize)
-// {
-// GNUNET_break_op (0);
-// GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-// "Show channel message: size %hu - expected %u\n",
-// ntohs (message->size),
-// esize);
-//
-// h->channel_cb (h->channel_cls, NULL, NULL);
-// h->channel_cb = NULL;
-// h->channel_cls = NULL;
-//
-// return;
-// }
-//
-// h->channel_cb (h->channel_cls,
-// &msg->destination,
-// &msg->owner);
-// }
-
-
-
-/**
- * Check that message received from CADET service is well-formed.
- *
- * @param cls the `struct GNUNET_CADET_Handle`
- * @param message the message we got
- * @return #GNUNET_OK if the message is well-formed,
- * #GNUNET_SYSERR otherwise
- */
-static int
-check_get_peers (void *cls,
- const struct GNUNET_CADET_LocalInfoPeer *message)
-{
- struct GNUNET_CADET_Handle *h = cls;
- uint16_t size;
-
- if (NULL == h->info_cb.peers_cb)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- " no handler for peesr monitor message!\n");
- return GNUNET_SYSERR;
- }
-
- size = ntohs (message->header.size);
- if (sizeof (struct GNUNET_CADET_LocalInfoPeer) > size)
- {
- h->info_cb.peers_cb (h->info_cls, NULL, -1, 0, 0);
- h->info_cb.peers_cb = NULL;
- h->info_cls = NULL;
- return GNUNET_SYSERR;
- }
-
- return GNUNET_OK;
-}
-
-
/**
* Process a local reply about info on all tunnels, pass info to the user.
*
@@ -1288,9 +834,13 @@ handle_get_peers (void *cls,
const struct GNUNET_CADET_LocalInfoPeer *msg)
{
struct GNUNET_CADET_Handle *h = cls;
- h->info_cb.peers_cb (h->info_cls, &msg->destination,
+
+ if (NULL == h->info_cb.peers_cb)
+ return;
+ h->info_cb.peers_cb (h->info_cls,
+ &msg->destination,
(int) ntohs (msg->tunnel),
- (unsigned int ) ntohs (msg->paths),
+ (unsigned int) ntohs (msg->paths),
0);
}
@@ -1307,62 +857,39 @@ static int
check_get_peer (void *cls,
const struct GNUNET_CADET_LocalInfoPeer *message)
{
- struct GNUNET_CADET_Handle *h = cls;
- const size_t msize = sizeof (struct GNUNET_CADET_LocalInfoPeer);
- struct GNUNET_PeerIdentity *paths_array;
+ size_t msize = sizeof (struct GNUNET_CADET_LocalInfoPeer);
+ const struct GNUNET_PeerIdentity *paths_array;
size_t esize;
unsigned int epaths;
unsigned int paths;
unsigned int peers;
- if (NULL == h->info_cb.peer_cb)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- " no handler for peer monitor message!\n");
- goto clean_cls;
- }
-
- /* Verify message sanity */
esize = ntohs (message->header.size);
if (esize < msize)
{
- GNUNET_break_op (0);
- h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
- goto clean_cls;
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
}
if (0 != ((esize - msize) % sizeof (struct GNUNET_PeerIdentity)))
{
- GNUNET_break_op (0);
- h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
- goto clean_cls;
-
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
}
peers = (esize - msize) / sizeof (struct GNUNET_PeerIdentity);
- epaths = (unsigned int) ntohs (message->paths);
- paths_array = (struct GNUNET_PeerIdentity *) &message[1];
+ epaths = ntohs (message->paths);
+ paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
paths = 0;
- for (int i = 0; i < peers; i++)
- {
- if (0 == memcmp (&paths_array[i], &message->destination,
+ for (unsigned int i = 0; i < peers; i++)
+ if (0 == memcmp (&paths_array[i],
+ &message->destination,
sizeof (struct GNUNET_PeerIdentity)))
- {
paths++;
- }
- }
if (paths != epaths)
{
- GNUNET_break_op (0);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "p:%u, e: %u\n", paths, epaths);
- h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
- goto clean_cls;
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
}
-
return GNUNET_OK;
-
-clean_cls:
- h->info_cb.peer_cb = NULL;
- h->info_cls = NULL;
- return GNUNET_SYSERR;
}
@@ -1377,22 +904,26 @@ handle_get_peer (void *cls,
const struct GNUNET_CADET_LocalInfoPeer *message)
{
struct GNUNET_CADET_Handle *h = cls;
- struct GNUNET_PeerIdentity *paths_array;
+ const struct GNUNET_PeerIdentity *paths_array;
unsigned int paths;
unsigned int path_length;
int neighbor;
unsigned int peers;
- paths = (unsigned int) ntohs (message->paths);
- paths_array = (struct GNUNET_PeerIdentity *) &message[1];
+ if (NULL == h->info_cb.peer_cb)
+ return;
+ paths = ntohs (message->paths);
+ paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
peers = (ntohs (message->header.size) - sizeof (*message))
/ sizeof (struct GNUNET_PeerIdentity);
path_length = 0;
neighbor = GNUNET_NO;
- for (int i = 0; i < peers; i++)
+ for (unsigned int i = 0; i < peers; i++)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", GNUNET_i2s (&paths_array[i]));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ " %s\n",
+ GNUNET_i2s (&paths_array[i]));
path_length++;
if (0 == memcmp (&paths_array[i], &message->destination,
sizeof (struct GNUNET_PeerIdentity)))
@@ -1404,7 +935,7 @@ handle_get_peer (void *cls,
}
/* Call Callback with tunnel info. */
- paths_array = (struct GNUNET_PeerIdentity *) &message[1];
+ paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
h->info_cb.peer_cb (h->info_cls,
&message->destination,
(int) ntohs (message->tunnel),
@@ -1415,40 +946,6 @@ handle_get_peer (void *cls,
/**
- * Check that message received from CADET service is well-formed.
- *
- * @param cls the `struct GNUNET_CADET_Handle`
- * @param msg the message we got
- * @return #GNUNET_OK if the message is well-formed,
- * #GNUNET_SYSERR otherwise
- */
-static int
-check_get_tunnels (void *cls,
- const struct GNUNET_CADET_LocalInfoTunnel *msg)
-{
- struct GNUNET_CADET_Handle *h = cls;
- uint16_t size;
-
- if (NULL == h->info_cb.tunnels_cb)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- " no handler for tunnels monitor message!\n");
- return GNUNET_SYSERR;
- }
-
- size = ntohs (msg->header.size);
- if (sizeof (struct GNUNET_CADET_LocalInfoTunnel) > size)
- {
- h->info_cb.tunnels_cb (h->info_cls, NULL, 0, 0, 0, 0);
- h->info_cb.tunnels_cb = NULL;
- h->info_cls = NULL;
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
-}
-
-
-/**
* Process a local reply about info on all tunnels, pass info to the user.
*
* @param cls Closure (Cadet handle).
@@ -1460,6 +957,8 @@ handle_get_tunnels (void *cls,
{
struct GNUNET_CADET_Handle *h = cls;
+ if (NULL == h->info_cb.tunnels_cb)
+ return;
h->info_cb.tunnels_cb (h->info_cls,
&msg->destination,
ntohl (msg->channels),
@@ -1482,28 +981,18 @@ static int
check_get_tunnel (void *cls,
const struct GNUNET_CADET_LocalInfoTunnel *msg)
{
- struct GNUNET_CADET_Handle *h = cls;
unsigned int ch_n;
unsigned int c_n;
size_t esize;
size_t msize;
- if (NULL == h->info_cb.tunnel_cb)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- " no handler for tunnel monitor message!\n");
- goto clean_cls;
- }
-
/* Verify message sanity */
msize = ntohs (msg->header.size);
esize = sizeof (struct GNUNET_CADET_LocalInfoTunnel);
if (esize > msize)
{
- GNUNET_break_op (0);
- h->info_cb.tunnel_cb (h->info_cls,
- NULL, 0, 0, NULL, NULL, 0, 0);
- goto clean_cls;
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
}
ch_n = ntohl (msg->channels);
c_n = ntohl (msg->connections);
@@ -1518,17 +1007,9 @@ check_get_tunnel (void *cls,
(unsigned int) esize,
ch_n,
c_n);
- h->info_cb.tunnel_cb (h->info_cls,
- NULL, 0, 0, NULL, NULL, 0, 0);
- goto clean_cls;
+ return GNUNET_SYSERR;
}
-
return GNUNET_OK;
-
-clean_cls:
- h->info_cb.tunnel_cb = NULL;
- h->info_cls = NULL;
- return GNUNET_SYSERR;
}
@@ -1548,6 +1029,9 @@ handle_get_tunnel (void *cls,
const struct GNUNET_CADET_ConnectionTunnelIdentifier *conns;
const struct GNUNET_CADET_ChannelTunnelNumber *chns;
+ if (NULL == h->info_cb.tunnel_cb)
+ return;
+
ch_n = ntohl (msg->channels);
c_n = ntohl (msg->connections);
@@ -1591,44 +1075,25 @@ reconnect (struct GNUNET_CADET_Handle *h)
GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
struct GNUNET_CADET_LocalAck,
h),
- GNUNET_MQ_hd_var_size (get_peers,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS,
- struct GNUNET_CADET_LocalInfoPeer,
- h),
+ GNUNET_MQ_hd_fixed_size (get_peers,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS,
+ struct GNUNET_CADET_LocalInfoPeer,
+ h),
GNUNET_MQ_hd_var_size (get_peer,
GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER,
struct GNUNET_CADET_LocalInfoPeer,
h),
- GNUNET_MQ_hd_var_size (get_tunnels,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS,
- struct GNUNET_CADET_LocalInfoTunnel,
- h),
+ GNUNET_MQ_hd_fixed_size (get_tunnels,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS,
+ struct GNUNET_CADET_LocalInfoTunnel,
+ h),
GNUNET_MQ_hd_var_size (get_tunnel,
GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL,
struct GNUNET_CADET_LocalInfoTunnel,
h),
-// FIXME
-// GNUNET_MQ_hd_fixed_Y size (channel_destroyed,
-// GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED,
-// struct GNUNET_CADET_ChannelDestroyMessage);
GNUNET_MQ_handler_end ()
};
- struct GNUNET_CADET_Channel *ch;
-
- while (NULL != (ch = h->channels_head))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Destroying channel due to a reconnect\n");
- destroy_channel (ch);
- }
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to CADET\n");
- if (NULL != h->mq)
- {
- GNUNET_MQ_destroy (h->mq);
- h->mq = NULL;
- }
h->mq = GNUNET_CLIENT_connect (h->cfg,
"cadet",
handlers,
@@ -1639,85 +1104,60 @@ reconnect (struct GNUNET_CADET_Handle *h)
schedule_reconnect (h);
return;
}
- else
- {
- h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
- }
+ h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
}
+
/**
- * Reconnect callback: tries to reconnect again after a failer previous
- * reconnecttion
+ * Function called during #GNUNET_CADET_disconnect() to destroy
+ * all channels that are still open.
*
- * @param cls closure (cadet handle)
+ * @param cls the `struct GNUNET_CADET_Handle`
+ * @param cid chanenl ID
+ * @param value a `struct GNUNET_CADET_Channel` to destroy
+ * @return #GNUNET_OK (continue to iterate)
*/
-static void
-reconnect_cbk (void *cls)
+static int
+destroy_channel_cb (void *cls,
+ uint32_t cid,
+ void *value)
{
- struct GNUNET_CADET_Handle *h = cls;
+ /* struct GNUNET_CADET_Handle *handle = cls; */
+ struct GNUNET_CADET_Channel *ch = value;
- h->reconnect_task = NULL;
- reconnect (h);
+ if (ntohl (ch->ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
+ {
+ GNUNET_break (0);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "channel %X not destroyed\n",
+ ntohl (ch->ccn.channel_of_client));
+ }
+ destroy_channel (ch);
+ return GNUNET_OK;
}
/**
- * Reconnect to the service, retransmit all infomation to try to restore the
- * original state.
+ * Function called during #GNUNET_CADET_disconnect() to destroy
+ * all ports that are still open.
*
- * @param h handle to the cadet
- *
- * @return #GNUNET_YES in case of sucess, #GNUNET_NO otherwise (service down...)
+ * @param cls the `struct GNUNET_CADET_Handle`
+ * @param id port ID
+ * @param value a `struct GNUNET_CADET_Channel` to destroy
+ * @return #GNUNET_OK (continue to iterate)
*/
-static void
-schedule_reconnect (struct GNUNET_CADET_Handle *h)
-{
- if (NULL == h->reconnect_task)
- {
- h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
- &reconnect_cbk, h);
- h->reconnect_time = GNUNET_TIME_STD_BACKOFF (h->reconnect_time);
- }
-}
-
-
-/******************************************************************************/
-/********************** API CALL DEFINITIONS *************************/
-/******************************************************************************/
-
-struct GNUNET_CADET_Handle *
-GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
- void *cls,
- GNUNET_CADET_ChannelEndHandler cleaner,
- const struct GNUNET_CADET_MessageHandler *handlers)
+static int
+destroy_port_cb (void *cls,
+ const struct GNUNET_HashCode *id,
+ void *value)
{
- struct GNUNET_CADET_Handle *h;
-
- h = GNUNET_new (struct GNUNET_CADET_Handle);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "GNUNET_CADET_connect() %p\n",
- h);
- h->cfg = cfg;
- h->cleaner = cleaner;
- h->ports = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_YES);
- reconnect (h);
- if (h->mq == NULL)
- {
- GNUNET_break (0);
- GNUNET_CADET_disconnect (h);
- return NULL;
- }
- h->cls = cls;
- h->message_handlers = handlers;
- h->next_ccn.channel_of_client = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
- h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
- h->reconnect_task = NULL;
+ /* struct GNUNET_CADET_Handle *handle = cls; */
+ struct GNUNET_CADET_Port *port = value;
- /* count handlers */
- for (h->n_handlers = 0;
- handlers && handlers[h->n_handlers].type;
- h->n_handlers++) ;
- return h;
+ /* This is a warning, the app should have cleanly closed all open ports */
+ GNUNET_break (0);
+ GNUNET_CADET_close_port (port);
+ return GNUNET_OK;
}
@@ -1732,57 +1172,16 @@ GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
void
GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle)
{
- struct GNUNET_CADET_Channel *ch;
- struct GNUNET_CADET_Channel *aux;
- struct GNUNET_CADET_TransmitHandle *th;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "CADET DISCONNECT\n");
- ch = handle->channels_head;
- while (NULL != ch)
- {
- aux = ch->next;
- if (ntohl (ch->ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
- {
- GNUNET_break (0);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "channel %X not destroyed\n",
- ntohl (ch->ccn.channel_of_client));
- }
- destroy_channel (ch);
- ch = aux;
- }
- while (NULL != (th = handle->th_head))
- {
- struct GNUNET_MessageHeader *msg;
-
- /* Make sure it is an allowed packet (everything else should have been
- * already canceled).
- */
- GNUNET_break (GNUNET_NO == th_is_payload (th));
- msg = (struct GNUNET_MessageHeader *) &th[1];
- switch (ntohs(msg->type))
- {
- case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN:
- case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY:
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN:
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE:
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNELS:
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL:
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER:
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS:
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL:
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS:
- break;
- default:
- GNUNET_break (0);
- LOG (GNUNET_ERROR_TYPE_ERROR, "unexpected unsent msg %s\n",
- GC_m2s (ntohs(msg->type)));
- }
-
- GNUNET_CADET_notify_transmit_ready_cancel (th);
- }
-
+ GNUNET_CONTAINER_multihashmap_iterate (handle->ports,
+ &destroy_port_cb,
+ handle);
+ GNUNET_CONTAINER_multihashmap_destroy (handle->ports);
+ handle->ports = NULL;
+ GNUNET_CONTAINER_multihashmap32_iterate (handle->channels,
+ &destroy_channel_cb,
+ handle);
+ GNUNET_CONTAINER_multihashmap32_destroy (handle->channels);
+ handle->channels = NULL;
if (NULL != handle->mq)
{
GNUNET_MQ_destroy (handle->mq);
@@ -1790,58 +1189,15 @@ GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle)
}
if (NULL != handle->reconnect_task)
{
- GNUNET_SCHEDULER_cancel(handle->reconnect_task);
+ GNUNET_SCHEDULER_cancel (handle->reconnect_task);
handle->reconnect_task = NULL;
}
-
- GNUNET_CONTAINER_multihashmap_destroy (handle->ports);
- handle->ports = NULL;
GNUNET_free (handle);
}
/**
- * Open a port to receive incomming channels.
- *
- * @param h CADET handle.
- * @param port Hash representing the port number.
- * @param new_channel Function called when an channel is received.
- * @param new_channel_cls Closure for @a new_channel.
- * @return Port handle.
- */
-struct GNUNET_CADET_Port *
-GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h,
- const struct GNUNET_HashCode *port,
- GNUNET_CADET_InboundChannelNotificationHandler
- new_channel,
- void *new_channel_cls)
-{
- struct GNUNET_CADET_PortMessage *msg;
- struct GNUNET_MQ_Envelope *env;
- struct GNUNET_CADET_Port *p;
-
- GNUNET_assert (NULL != new_channel);
- p = GNUNET_new (struct GNUNET_CADET_Port);
- p->cadet = h;
- p->hash = GNUNET_new (struct GNUNET_HashCode);
- *p->hash = *port;
- p->handler = new_channel;
- p->cls = new_channel_cls;
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_multihashmap_put (h->ports,
- p->hash,
- p,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
-
- env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN);
- msg->port = *p->hash;
- GNUNET_MQ_send (h->mq, env);
-
- return p;
-}
-
-/**
- * Close a port opened with @a GNUNET_CADET_open_port.
+ * Close a port opened with @a GNUNET_CADET_open_port().
* The @a new_channel callback will no longer be called.
*
* @param p Port handle.
@@ -1851,111 +1207,45 @@ GNUNET_CADET_close_port (struct GNUNET_CADET_Port *p)
{
struct GNUNET_CADET_PortMessage *msg;
struct GNUNET_MQ_Envelope *env;
- struct GNUNET_HashCode *id;
-
- env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE);
- id = NULL != p->hash ? p->hash : &p->id;
- msg->port = *id;
- GNUNET_MQ_send (p->cadet->mq, env);
- GNUNET_CONTAINER_multihashmap_remove (p->cadet->ports, id, p);
- GNUNET_free_non_null (p->hash);
+ env = GNUNET_MQ_msg (msg,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE);
+ msg->port = p->id;
+ GNUNET_MQ_send (p->cadet->mq,
+ env);
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CONTAINER_multihashmap_remove (p->cadet->ports,
+ &p->id,
+ p));
+ GNUNET_free_non_null (p->handlers);
GNUNET_free (p);
}
/**
- * Create a new channel towards a remote peer.
+ * Destroy an existing channel.
*
- * If the destination port is not open by any peer or the destination peer
- * does not accept the channel, #GNUNET_CADET_ChannelEndHandler will be called
- * for this channel.
+ * The existing end callback for the channel will be called immediately.
+ * Any pending outgoing messages will be sent but no incoming messages will be
+ * accepted and no data callbacks will be called.
*
- * @param h cadet handle
- * @param channel_ctx client's channel context to associate with the channel
- * @param peer peer identity the channel should go to
- * @param port Port hash (port number).
- * @param options CadetOption flag field, with all desired option bits set to 1.
- * @return handle to the channel
+ * @param channel Channel handle, becomes invalid after this call.
*/
-struct GNUNET_CADET_Channel *
-GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h,
- void *channel_ctx,
- const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_HashCode *port,
- enum GNUNET_CADET_ChannelOption options)
-{
- struct GNUNET_CADET_LocalChannelCreateMessage *msg;
- struct GNUNET_MQ_Envelope *env;
- struct GNUNET_CADET_Channel *ch;
- struct GNUNET_CADET_ClientChannelNumber ccn;
-
- ccn.channel_of_client = htonl (0);
- ch = create_channel (h, ccn);
- ch->ctx = channel_ctx;
- ch->peer = GNUNET_PEER_intern (peer);
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Creating new channel to %s:%u at %p number %X\n",
- GNUNET_i2s (peer),
- port,
- ch,
- ntohl (ch->ccn.channel_of_client));
- env = GNUNET_MQ_msg (msg,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
- msg->ccn = ch->ccn;
- msg->port = *port;
- msg->peer = *peer;
- msg->opt = htonl (options);
- GNUNET_MQ_send (h->mq,
- env);
- return ch;
-}
-
-
void
GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel)
{
- struct GNUNET_CADET_Handle *h;
+ struct GNUNET_CADET_Handle *h = channel->cadet;
struct GNUNET_CADET_LocalChannelDestroyMessage *msg;
struct GNUNET_MQ_Envelope *env;
- struct GNUNET_CADET_TransmitHandle *th;
- struct GNUNET_CADET_TransmitHandle *next;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Destroying channel\n");
- h = channel->cadet;
- for (th = h->th_head; th != NULL; th = next)
+ if (NULL != h->mq)
{
- next = th->next;
- if (th->channel == channel)
- {
- GNUNET_break (0);
- if (GNUNET_YES == th_is_payload (th))
- {
- /* applications should cancel before destroying channel */
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "Channel destroyed without cancelling transmission requests\n");
- th->notify (th->notify_cls, 0, NULL);
- }
- else
- {
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "no meta-traffic should be queued\n");
- }
- GNUNET_CONTAINER_DLL_remove (h->th_head,
- h->th_tail,
- th);
- GNUNET_CADET_notify_transmit_ready_cancel (th);
- }
+ env = GNUNET_MQ_msg (msg,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
+ msg->ccn = channel->ccn;
+ GNUNET_MQ_send (h->mq,
+ env);
}
-
- env = GNUNET_MQ_msg (msg,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
- msg->ccn = channel->ccn;
- GNUNET_MQ_send (h->mq,
- env);
-
destroy_channel (channel);
}
@@ -1971,10 +1261,10 @@ GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel)
*/
const union GNUNET_CADET_ChannelInfo *
GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel,
- enum GNUNET_CADET_ChannelOption option, ...)
+ enum GNUNET_CADET_ChannelOption option,
+ ...)
{
static int bool_flag;
- const union GNUNET_CADET_ChannelInfo *ret;
switch (option)
{
@@ -1985,74 +1275,15 @@ GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel,
bool_flag = GNUNET_YES;
else
bool_flag = GNUNET_NO;
- ret = (const union GNUNET_CADET_ChannelInfo *) &bool_flag;
+ return (const union GNUNET_CADET_ChannelInfo *) &bool_flag;
break;
case GNUNET_CADET_OPTION_PEER:
- ret = (const union GNUNET_CADET_ChannelInfo *) GNUNET_PEER_resolve2 (channel->peer);
+ return (const union GNUNET_CADET_ChannelInfo *) &channel->peer;
break;
default:
GNUNET_break (0);
return NULL;
}
-
- return ret;
-}
-
-
-struct GNUNET_CADET_TransmitHandle *
-GNUNET_CADET_notify_transmit_ready (struct GNUNET_CADET_Channel *channel,
- int cork,
- struct GNUNET_TIME_Relative maxdelay,
- size_t notify_size,
- GNUNET_CONNECTION_TransmitReadyNotify notify,
- void *notify_cls)
-{
- struct GNUNET_CADET_TransmitHandle *th;
-
- GNUNET_assert (NULL != channel);
- GNUNET_assert (NULL != notify);
- GNUNET_assert (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE >= notify_size);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "CADET NOTIFY TRANSMIT READY on channel %X allow_send is %u to %s with %u bytes\n",
- ntohl (channel->ccn.channel_of_client),
- channel->allow_send,
- (ntohl (channel->ccn.channel_of_client) >=
- GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
- ? "origin"
- : "destination",
- (unsigned int) notify_size);
- if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us != maxdelay.rel_value_us)
- {
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "CADET transmit ready timeout is deprected (has no effect)\n");
- }
-
- th = GNUNET_new (struct GNUNET_CADET_TransmitHandle);
- th->channel = channel;
- th->size = notify_size;
- th->notify = notify;
- th->notify_cls = notify_cls;
- if (0 != channel->allow_send)
- th->request_data_task
- = GNUNET_SCHEDULER_add_now (&request_data,
- th);
- else
- add_to_queue (channel->cadet,
- th);
- return th;
-}
-
-
-void
-GNUNET_CADET_notify_transmit_ready_cancel (struct GNUNET_CADET_TransmitHandle *th)
-{
- if (NULL != th->request_data_task)
- {
- GNUNET_SCHEDULER_cancel (th->request_data_task);
- th->request_data_task = NULL;
- }
- remove_from_queue (th);
- GNUNET_free (th);
}
@@ -2078,18 +1309,23 @@ GNUNET_CADET_receive_done (struct GNUNET_CADET_Channel *channel)
}
+/**
+ * Send message of @a type to CADET service of @a h
+ *
+ * @param h handle to CADET service
+ * @param type message type of trivial information request to send
+ */
static void
-send_info_request (struct GNUNET_CADET_Handle *h, uint16_t type)
+send_info_request (struct GNUNET_CADET_Handle *h,
+ uint16_t type)
{
struct GNUNET_MessageHeader *msg;
struct GNUNET_MQ_Envelope *env;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- " Sending %s monitor message to service\n",
- GC_m2s(type));
-
- env = GNUNET_MQ_msg (msg, type);
- GNUNET_MQ_send (h->mq, env);
+ env = GNUNET_MQ_msg (msg,
+ type);
+ GNUNET_MQ_send (h->mq,
+ env);
}
@@ -2103,8 +1339,8 @@ send_info_request (struct GNUNET_CADET_Handle *h, uint16_t type)
void
GNUNET_CADET_request_dump (struct GNUNET_CADET_Handle *h)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, "requesting dump\n");
- send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP);
+ send_info_request (h,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP);
}
@@ -2113,13 +1349,11 @@ GNUNET_CADET_request_dump (struct GNUNET_CADET_Handle *h)
* The callback will be called for every peer known to the service.
* Only one info request (of any kind) can be active at once.
*
- *
* WARNING: unstable API, likely to change in the future!
*
* @param h Handle to the cadet peer.
* @param callback Function to call with the requested data.
* @param callback_cls Closure for @c callback.
- *
* @return #GNUNET_OK / #GNUNET_SYSERR
*/
int
@@ -2132,7 +1366,8 @@ GNUNET_CADET_get_peers (struct GNUNET_CADET_Handle *h,
GNUNET_break (0);
return GNUNET_SYSERR;
}
- send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
+ send_info_request (h,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
h->info_cb.peers_cb = callback;
h->info_cls = callback_cls;
return GNUNET_OK;
@@ -2145,15 +1380,13 @@ GNUNET_CADET_get_peers (struct GNUNET_CADET_Handle *h,
* WARNING: unstable API, likely to change in the future!
*
* @param h Cadet handle.
- *
- * @return Closure given to GNUNET_CADET_get_peers.
+ * @return Closure given to GNUNET_CADET_get_peers().
*/
void *
GNUNET_CADET_get_peers_cancel (struct GNUNET_CADET_Handle *h)
{
- void *cls;
+ void *cls = h->info_cls;
- cls = h->info_cls;
h->info_cb.peers_cb = NULL;
h->info_cls = NULL;
return cls;
@@ -2171,7 +1404,6 @@ GNUNET_CADET_get_peers_cancel (struct GNUNET_CADET_Handle *h)
* @param id Peer whose tunnel to examine.
* @param callback Function to call with the requested data.
* @param callback_cls Closure for @c callback.
- *
* @return #GNUNET_OK / #GNUNET_SYSERR
*/
int
@@ -2188,11 +1420,11 @@ GNUNET_CADET_get_peer (struct GNUNET_CADET_Handle *h,
GNUNET_break (0);
return GNUNET_SYSERR;
}
-
- env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
+ env = GNUNET_MQ_msg (msg,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
msg->peer = *id;
- GNUNET_MQ_send (h->mq, env);
-
+ GNUNET_MQ_send (h->mq,
+ env);
h->info_cb.peer_cb = callback;
h->info_cls = callback_cls;
return GNUNET_OK;
@@ -2209,7 +1441,6 @@ GNUNET_CADET_get_peer (struct GNUNET_CADET_Handle *h,
* @param h Handle to the cadet peer.
* @param callback Function to call with the requested data.
* @param callback_cls Closure for @c callback.
- *
* @return #GNUNET_OK / #GNUNET_SYSERR
*/
int
@@ -2222,7 +1453,8 @@ GNUNET_CADET_get_tunnels (struct GNUNET_CADET_Handle *h,
GNUNET_break (0);
return GNUNET_SYSERR;
}
- send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
+ send_info_request (h,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
h->info_cb.tunnels_cb = callback;
h->info_cls = callback_cls;
return GNUNET_OK;
@@ -2233,23 +1465,19 @@ GNUNET_CADET_get_tunnels (struct GNUNET_CADET_Handle *h,
* Cancel a monitor request. The monitor callback will not be called.
*
* @param h Cadet handle.
- *
- * @return Closure given to GNUNET_CADET_get_tunnels.
+ * @return Closure given to GNUNET_CADET_get_tunnels().
*/
void *
GNUNET_CADET_get_tunnels_cancel (struct GNUNET_CADET_Handle *h)
{
- void *cls;
+ void *cls = h->info_cls;
h->info_cb.tunnels_cb = NULL;
- cls = h->info_cls;
h->info_cls = NULL;
-
return cls;
}
-
/**
* Request information about a tunnel of the running cadet peer.
* The callback will be called for the tunnel once.
@@ -2261,7 +1489,6 @@ GNUNET_CADET_get_tunnels_cancel (struct GNUNET_CADET_Handle *h)
* @param id Peer whose tunnel to examine.
* @param callback Function to call with the requested data.
* @param callback_cls Closure for @c callback.
- *
* @return #GNUNET_OK / #GNUNET_SYSERR
*/
int
@@ -2278,11 +1505,11 @@ GNUNET_CADET_get_tunnel (struct GNUNET_CADET_Handle *h,
GNUNET_break (0);
return GNUNET_SYSERR;
}
-
- env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
+ env = GNUNET_MQ_msg (msg,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
msg->peer = *id;
- GNUNET_MQ_send (h->mq, env);
-
+ GNUNET_MQ_send (h->mq,
+ env);
h->info_cb.tunnel_cb = callback;
h->info_cls = callback_cls;
return GNUNET_OK;
@@ -2290,158 +1517,6 @@ GNUNET_CADET_get_tunnel (struct GNUNET_CADET_Handle *h,
/**
- * Request information about a specific channel of the running cadet peer.
- *
- * WARNING: unstable API, likely to change in the future!
- * FIXME Add destination option.
- *
- * @param h Handle to the cadet peer.
- * @param initiator ID of the owner of the channel.
- * @param channel_number Channel number.
- * @param callback Function to call with the requested data.
- * @param callback_cls Closure for @c callback.
- *
- * @return #GNUNET_OK / #GNUNET_SYSERR
- */
-int
-GNUNET_CADET_show_channel (struct GNUNET_CADET_Handle *h,
- struct GNUNET_PeerIdentity *initiator,
- unsigned int channel_number,
- GNUNET_CADET_ChannelCB callback,
- void *callback_cls)
-{
- struct GNUNET_CADET_LocalInfo *msg;
- struct GNUNET_MQ_Envelope *env;
-
- if (NULL != h->info_cb.channel_cb)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
-
- env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL);
- msg->peer = *initiator;
- msg->ccn.channel_of_client = htonl (channel_number);
- GNUNET_MQ_send (h->mq, env);
-
- h->info_cb.channel_cb = callback;
- h->info_cls = callback_cls;
- return GNUNET_OK;
-}
-
-
-/**
- * Function called to notify a client about the connection
- * begin ready to queue more data. "buf" will be
- * NULL and "size" zero if the connection was closed for
- * writing in the meantime.
- *
- * @param cls closure
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
- */
-static size_t
-cadet_mq_ntr (void *cls, size_t size,
- void *buf)
-{
- struct GNUNET_MQ_Handle *mq = cls;
- struct CadetMQState *state = GNUNET_MQ_impl_state (mq);
- const struct GNUNET_MessageHeader *msg = GNUNET_MQ_impl_current (mq);
- uint16_t msize;
-
- state->th = NULL;
- if (NULL == buf)
- {
- GNUNET_MQ_inject_error (mq, GNUNET_MQ_ERROR_WRITE);
- return 0;
- }
- msize = ntohs (msg->size);
- GNUNET_assert (msize <= size);
- GNUNET_memcpy (buf, msg, msize);
- GNUNET_MQ_impl_send_continue (mq);
- return msize;
-}
-
-
-/**
- * Signature of functions implementing the
- * sending functionality of a message queue.
- *
- * @param mq the message queue
- * @param msg the message to send
- * @param impl_state state of the implementation
- */
-static void
-cadet_mq_send_impl_old (struct GNUNET_MQ_Handle *mq,
- const struct GNUNET_MessageHeader *msg,
- void *impl_state)
-{
- struct CadetMQState *state = impl_state;
-
- GNUNET_assert (NULL == state->th);
- state->th =
- GNUNET_CADET_notify_transmit_ready (state->channel,
- /* FIXME: add option for corking */
- GNUNET_NO,
- GNUNET_TIME_UNIT_FOREVER_REL,
- ntohs (msg->size),
- &cadet_mq_ntr, mq);
-
-}
-
-
-/**
- * Signature of functions implementing the
- * destruction of a message queue.
- * Implementations must not free 'mq', but should
- * take care of 'impl_state'.
- *
- * @param mq the message queue to destroy
- * @param impl_state state of the implementation
- */
-static void
-cadet_mq_destroy_impl_old (struct GNUNET_MQ_Handle *mq,
- void *impl_state)
-{
- struct CadetMQState *state = impl_state;
-
- if (NULL != state->th)
- GNUNET_CADET_notify_transmit_ready_cancel (state->th);
-
- GNUNET_free (state);
-}
-
-
-/**
- * Create a message queue for a cadet channel.
- * The message queue can only be used to transmit messages,
- * not to receive them.
- *
- * @param channel the channel to create the message qeue for
- * @return a message queue to messages over the channel
- */
-struct GNUNET_MQ_Handle *
-GNUNET_CADET_mq_create (struct GNUNET_CADET_Channel *channel)
-{
- struct GNUNET_MQ_Handle *mq;
- struct CadetMQState *state;
-
- state = GNUNET_new (struct CadetMQState);
- state->channel = channel;
-
- mq = GNUNET_MQ_queue_for_callbacks (&cadet_mq_send_impl_old,
- &cadet_mq_destroy_impl_old,
- NULL, /* FIXME: cancel impl. */
- state,
- NULL, /* no msg handlers */
- NULL, /* no err handlers */
- NULL); /* no handler cls */
- return mq;
-}
-
-
-/**
* Transitional function to convert an unsigned int port to a hash value.
* WARNING: local static value returned, NOT reentrant!
* WARNING: do not use this function for new code!
@@ -2456,19 +1531,14 @@ GC_u2h (uint32_t port)
static struct GNUNET_HashCode hash;
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "This is a transitional function, "
- "use proper crypto hashes as CADET ports\n");
- GNUNET_CRYPTO_hash (&port, sizeof (port), &hash);
-
+ "This is a transitional function, use proper crypto hashes as CADET ports\n");
+ GNUNET_CRYPTO_hash (&port,
+ sizeof (port),
+ &hash);
return &hash;
}
-
-/******************************************************************************/
-/******************************* MQ-BASED API *********************************/
-/******************************************************************************/
-
/**
* Connect to the MQ-based cadet service.
*
@@ -2477,16 +1547,17 @@ GC_u2h (uint32_t port)
* @return Handle to the cadet service NULL on error.
*/
struct GNUNET_CADET_Handle *
-GNUNET_CADET_connecT (const struct GNUNET_CONFIGURATION_Handle *cfg)
+GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
{
struct GNUNET_CADET_Handle *h;
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "GNUNET_CADET_connecT()\n");
+ "GNUNET_CADET_connect()\n");
h = GNUNET_new (struct GNUNET_CADET_Handle);
h->cfg = cfg;
- h->mq_api = GNUNET_YES;
- h->ports = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_YES);
+ h->ports = GNUNET_CONTAINER_multihashmap_create (4,
+ GNUNET_YES);
+ h->channels = GNUNET_CONTAINER_multihashmap32_create (4);
reconnect (h);
if (NULL == h->mq)
{
@@ -2512,11 +1583,10 @@ GNUNET_CADET_connecT (const struct GNUNET_CONFIGURATION_Handle *cfg)
* @param window_changes Function called when the transmit window size changes.
* @param disconnects Function called when a channel is disconnected.
* @param handlers Callbacks for messages we care about, NULL-terminated.
- *
* @return Port handle.
*/
struct GNUNET_CADET_Port *
-GNUNET_CADET_open_porT (struct GNUNET_CADET_Handle *h,
+GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h,
const struct GNUNET_HashCode *port,
GNUNET_CADET_ConnectEventHandler connects,
void * connects_cls,
@@ -2538,16 +1608,7 @@ GNUNET_CADET_open_porT (struct GNUNET_CADET_Handle *h,
p->cls = connects_cls;
p->window_changes = window_changes;
p->disconnects = disconnects;
- if (NULL != handlers)
- {
- unsigned int i;
- for (i=0;NULL != handlers[i].cb; i++) ;
- p->handlers = GNUNET_new_array (i + 1,
- struct GNUNET_MQ_MessageHandler);
- GNUNET_memcpy ((struct GNUNET_MQ_MessageHandler *) p->handlers,
- handlers,
- i * sizeof (struct GNUNET_MQ_MessageHandler));
- }
+ p->handlers = GNUNET_MQ_copy_handlers (handlers);
GNUNET_assert (GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_put (h->ports,
@@ -2555,10 +1616,11 @@ GNUNET_CADET_open_porT (struct GNUNET_CADET_Handle *h,
p,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
- env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN);
+ env = GNUNET_MQ_msg (msg,
+ GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN);
msg->port = p->id;
- GNUNET_MQ_send (h->mq, env);
-
+ GNUNET_MQ_send (h->mq,
+ env);
return p;
}
@@ -2580,11 +1642,10 @@ GNUNET_CADET_open_porT (struct GNUNET_CADET_Handle *h,
* @param window_changes Function called when the transmit window size changes.
* @param disconnects Function called when the channel is disconnected.
* @param handlers Callbacks for messages we care about, NULL-terminated.
- *
* @return Handle to the channel.
*/
struct GNUNET_CADET_Channel *
-GNUNET_CADET_channel_creatE (struct GNUNET_CADET_Handle *h,
+GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h,
void *channel_cls,
const struct GNUNET_PeerIdentity *destination,
const struct GNUNET_HashCode *port,
@@ -2594,17 +1655,14 @@ GNUNET_CADET_channel_creatE (struct GNUNET_CADET_Handle *h,
const struct GNUNET_MQ_MessageHandler *handlers)
{
struct GNUNET_CADET_Channel *ch;
- struct GNUNET_CADET_ClientChannelNumber ccn;
struct GNUNET_CADET_LocalChannelCreateMessage *msg;
struct GNUNET_MQ_Envelope *env;
GNUNET_assert (NULL != disconnects);
-
- /* Save parameters */
- ccn.channel_of_client = htonl (0);
- ch = create_channel (h, ccn);
+ ch = create_channel (h,
+ NULL);
ch->ctx = channel_cls;
- ch->peer = GNUNET_PEER_intern (destination);
+ ch->peer = *destination;
ch->options = options;
ch->window_changes = window_changes;
ch->disconnects = disconnects;
@@ -2628,7 +1686,6 @@ GNUNET_CADET_channel_creatE (struct GNUNET_CADET_Handle *h,
msg->opt = htonl (options);
GNUNET_MQ_send (h->mq,
env);
-
return ch;
}
@@ -2645,3 +1702,5 @@ GNUNET_CADET_get_mq (const struct GNUNET_CADET_Channel *channel)
{
return channel->mq;
}
+
+/* end of cadet_api.c */
diff --git a/src/cadet/cadet_api_new.c b/src/cadet/cadet_api_new.c
deleted file mode 100644
index 2d5d853b37..0000000000
--- a/src/cadet/cadet_api_new.c
+++ /dev/null
@@ -1,1711 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2011, 2017 GNUnet e.V.
-
- GNUnet 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 3, or (at your
- option) any later version.
-
- GNUnet 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 GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-/**
- * @file cadet/cadet_api.c
- * @brief cadet api: client implementation of cadet service
- * @author Bartlomiej Polot
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_constants.h"
-#include "gnunet_cadet_service.h"
-#include "cadet.h"
-#include "cadet_protocol.h"
-
-#define LOG(kind,...) GNUNET_log_from (kind, "cadet-api",__VA_ARGS__)
-
-/**
- * Ugly legacy hack.
- */
-union CadetInfoCB
-{
-
- /**
- * Channel callback.
- */
- GNUNET_CADET_ChannelCB channel_cb;
-
- /**
- * Monitor callback
- */
- GNUNET_CADET_PeersCB peers_cb;
-
- /**
- * Monitor callback
- */
- GNUNET_CADET_PeerCB peer_cb;
-
- /**
- * Monitor callback
- */
- GNUNET_CADET_TunnelsCB tunnels_cb;
-
- /**
- * Tunnel callback.
- */
- GNUNET_CADET_TunnelCB tunnel_cb;
-};
-
-
-/**
- * Opaque handle to the service.
- */
-struct GNUNET_CADET_Handle
-{
- /**
- * Message queue.
- */
- struct GNUNET_MQ_Handle *mq;
-
- /**
- * Ports open.
- */
- struct GNUNET_CONTAINER_MultiHashMap *ports;
-
- /**
- * Channels open.
- */
- struct GNUNET_CONTAINER_MultiHashMap32 *channels;
-
- /**
- * child of the next channel to create (to avoid reusing IDs often)
- */
- struct GNUNET_CADET_ClientChannelNumber next_ccn;
-
- /**
- * Configuration given by the client, in case of reconnection
- */
- const struct GNUNET_CONFIGURATION_Handle *cfg;
-
- /**
- * Task for trying to reconnect.
- */
- struct GNUNET_SCHEDULER_Task *reconnect_task;
-
- /**
- * Callback for an info task (only one active at a time).
- */
- union CadetInfoCB info_cb;
-
- /**
- * Info callback closure for @c info_cb.
- */
- void *info_cls;
-
- /**
- * Time to the next reconnect in case one reconnect fails
- */
- struct GNUNET_TIME_Relative reconnect_time;
-
-};
-
-
-/**
- * Opaque handle to a channel.
- */
-struct GNUNET_CADET_Channel
-{
-
- /**
- * Other end of the channel.
- */
- struct GNUNET_PeerIdentity peer;
-
- /**
- * Handle to the cadet this channel belongs to
- */
- struct GNUNET_CADET_Handle *cadet;
-
- /**
- * Channel's port, if incoming.
- */
- struct GNUNET_CADET_Port *incoming_port;
-
- /**
- * Any data the caller wants to put in here, used for the
- * various callbacks (@e disconnects, @e window_changes, handlers).
- */
- void *ctx;
-
- /**
- * Message Queue for the channel (which we are implementing).
- */
- struct GNUNET_MQ_Handle *mq;
-
- /**
- * Task to allow mq to send more traffic.
- */
- struct GNUNET_SCHEDULER_Task *mq_cont;
-
- /**
- * Pending envelope with a message to be transmitted to the
- * service as soon as we are allowed to. Should only be
- * non-NULL if @e allow_send is 0.
- */
- struct GNUNET_MQ_Envelope *pending_env;
-
- /**
- * Window change handler.
- */
- GNUNET_CADET_WindowSizeEventHandler window_changes;
-
- /**
- * Disconnect handler.
- */
- GNUNET_CADET_DisconnectEventHandler disconnects;
-
- /**
- * Local ID of the channel, #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI bit is set if outbound.
- */
- struct GNUNET_CADET_ClientChannelNumber ccn;
-
- /**
- * Channel options: reliability, etc.
- */
- enum GNUNET_CADET_ChannelOption options;
-
- /**
- * How many messages are we allowed to send to the service right now?
- */
- unsigned int allow_send;
-
-};
-
-
-/**
- * Opaque handle to a port.
- */
-struct GNUNET_CADET_Port
-{
-
- /**
- * Port "number"
- */
- struct GNUNET_HashCode id;
-
- /**
- * Handle to the CADET session this port belongs to.
- */
- struct GNUNET_CADET_Handle *cadet;
-
- /**
- * Callback handler for incoming channels on this port.
- */
- GNUNET_CADET_InboundChannelNotificationHandler *handler;
-
- /**
- * Closure for @a handler.
- */
- void *cls;
-
- /**
- * Handler for incoming channels on this port
- */
- GNUNET_CADET_ConnectEventHandler connects;
-
- /**
- * Closure for @ref connects
- */
- void *connects_cls;
-
- /**
- * Window size change handler.
- */
- GNUNET_CADET_WindowSizeEventHandler window_changes;
-
- /**
- * Handler called when an incoming channel is destroyed.
- */
- GNUNET_CADET_DisconnectEventHandler disconnects;
-
- /**
- * Payload handlers for incoming channels.
- */
- struct GNUNET_MQ_MessageHandler *handlers;
-};
-
-
-/**
- * Find the Port struct for a hash.
- *
- * @param h CADET handle.
- * @param hash HashCode for the port number.
- * @return The port handle if known, NULL otherwise.
- */
-static struct GNUNET_CADET_Port *
-find_port (const struct GNUNET_CADET_Handle *h,
- const struct GNUNET_HashCode *hash)
-{
- return GNUNET_CONTAINER_multihashmap_get (h->ports,
- hash);
-}
-
-
-/**
- * Get the channel handler for the channel specified by id from the given handle
- *
- * @param h Cadet handle
- * @param ccn ID of the wanted channel
- * @return handle to the required channel or NULL if not found
- */
-static struct GNUNET_CADET_Channel *
-find_channel (struct GNUNET_CADET_Handle *h,
- struct GNUNET_CADET_ClientChannelNumber ccn)
-{
- return GNUNET_CONTAINER_multihashmap32_get (h->channels,
- ntohl (ccn.channel_of_client));
-}
-
-
-/**
- * Create a new channel and insert it in the channel list of the cadet handle
- *
- * @param h Cadet handle
- * @param ccnp pointer to desired ccn of the channel, NULL to assign one automatically.
- * @return Handle to the created channel.
- */
-static struct GNUNET_CADET_Channel *
-create_channel (struct GNUNET_CADET_Handle *h,
- const struct GNUNET_CADET_ClientChannelNumber *ccnp)
-{
- struct GNUNET_CADET_Channel *ch;
- struct GNUNET_CADET_ClientChannelNumber ccn;
-
- ch = GNUNET_new (struct GNUNET_CADET_Channel);
- ch->cadet = h;
- if (NULL == ccnp)
- {
- while (NULL !=
- find_channel (h,
- h->next_ccn))
- h->next_ccn.channel_of_client
- = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI | (1 + ntohl (h->next_ccn.channel_of_client)));
- ccn = h->next_ccn;
- }
- else
- {
- ccn = *ccnp;
- }
- ch->ccn = ccn;
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_multihashmap32_put (h->channels,
- ntohl (ch->ccn.channel_of_client),
- ch,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
- return ch;
-}
-
-
-/**
- * Destroy the specified channel.
- * - Destroys all peers, calling the disconnect callback on each if needed
- * - Cancels all outgoing traffic for that channel, calling respective notifys
- * - Calls cleaner if channel was inbound
- * - Frees all memory used
- *
- * @param ch Pointer to the channel.
- * @param call_cleaner Whether to call the cleaner handler.
- */
-static void
-destroy_channel (struct GNUNET_CADET_Channel *ch)
-{
- struct GNUNET_CADET_Handle *h = ch->cadet;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Destroying channel %X of %p\n",
- ch->ccn,
- h);
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap32_remove (h->channels,
- ntohl (ch->ccn.channel_of_client),
- ch));
- if (NULL != ch->mq_cont)
- {
- GNUNET_SCHEDULER_cancel (ch->mq_cont);
- ch->mq_cont = NULL;
- }
- /* signal channel destruction */
- if (NULL != ch->disconnects)
- ch->disconnects (ch->ctx,
- ch);
- if (NULL != ch->pending_env)
- GNUNET_MQ_discard (ch->pending_env);
- GNUNET_MQ_destroy (ch->mq);
- GNUNET_free (ch);
-}
-
-
-/**
- * Reconnect to the service, retransmit all infomation to try to restore the
- * original state.
- *
- * @param h handle to the cadet
- */
-static void
-reconnect (struct GNUNET_CADET_Handle *h);
-
-
-/**
- * Reconnect callback: tries to reconnect again after a failer previous
- * reconnecttion
- *
- * @param cls closure (cadet handle)
- */
-static void
-reconnect_cbk (void *cls)
-{
- struct GNUNET_CADET_Handle *h = cls;
-
- h->reconnect_task = NULL;
- reconnect (h);
-}
-
-
-/**
- * Function called during #reconnect() to destroy
- * all channels that are still open.
- *
- * @param cls the `struct GNUNET_CADET_Handle`
- * @param cid chanenl ID
- * @param value a `struct GNUNET_CADET_Channel` to destroy
- * @return #GNUNET_OK (continue to iterate)
- */
-static int
-destroy_channel_on_reconnect_cb (void *cls,
- uint32_t cid,
- void *value)
-{
- /* struct GNUNET_CADET_Handle *handle = cls; */
- struct GNUNET_CADET_Channel *ch = value;
-
- destroy_channel (ch);
- return GNUNET_OK;
-}
-
-
-/**
- * Reconnect to the service, retransmit all infomation to try to restore the
- * original state.
- *
- * @param h handle to the cadet
- *
- * @return #GNUNET_YES in case of sucess, #GNUNET_NO otherwise (service down...)
- */
-static void
-schedule_reconnect (struct GNUNET_CADET_Handle *h)
-{
- if (NULL != h->reconnect_task)
- return;
- GNUNET_CONTAINER_multihashmap32_iterate (h->channels,
- &destroy_channel_on_reconnect_cb,
- h);
- h->reconnect_task
- = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
- &reconnect_cbk,
- h);
- h->reconnect_time
- = GNUNET_TIME_STD_BACKOFF (h->reconnect_time);
-}
-
-
-/**
- * Notify the application about a change in the window size (if needed).
- *
- * @param ch Channel to notify about.
- */
-static void
-notify_window_size (struct GNUNET_CADET_Channel *ch)
-{
- if (NULL != ch->window_changes)
- ch->window_changes (ch->ctx,
- ch, /* FIXME: remove 'ch'? */
- ch->allow_send);
-}
-
-
-/**
- * Transmit the next message from our queue.
- *
- * @param cls Closure (channel whose mq to activate).
- */
-static void
-cadet_mq_send_now (void *cls)
-{
- struct GNUNET_CADET_Channel *ch = cls;
- struct GNUNET_MQ_Envelope *env = ch->pending_env;
-
- ch->mq_cont = NULL;
- if (0 == ch->allow_send)
- {
- /* how did we get here? */
- GNUNET_break (0);
- return;
- }
- if (NULL == env)
- {
- /* how did we get here? */
- GNUNET_break (0);
- return;
- }
- ch->allow_send--;
- ch->pending_env = NULL;
- GNUNET_MQ_send (ch->cadet->mq,
- env);
- GNUNET_MQ_impl_send_continue (ch->mq);
-}
-
-
-/**
- * Implement sending functionality of a message queue for
- * us sending messages to a peer.
- *
- * Encapsulates the payload message in a #GNUNET_CADET_LocalData message
- * in order to label the message with the channel ID and send the
- * encapsulated message to the service.
- *
- * @param mq the message queue
- * @param msg the message to send
- * @param impl_state state of the implementation
- */
-static void
-cadet_mq_send_impl (struct GNUNET_MQ_Handle *mq,
- const struct GNUNET_MessageHeader *msg,
- void *impl_state)
-{
- struct GNUNET_CADET_Channel *ch = impl_state;
- struct GNUNET_CADET_Handle *h = ch->cadet;
- uint16_t msize;
- struct GNUNET_MQ_Envelope *env;
- struct GNUNET_CADET_LocalData *cadet_msg;
-
- if (NULL == h->mq)
- {
- /* We're currently reconnecting, pretend this worked */
- GNUNET_MQ_impl_send_continue (mq);
- return;
- }
-
- /* check message size for sanity */
- msize = ntohs (msg->size);
- if (msize > GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE)
- {
- GNUNET_break (0);
- GNUNET_MQ_impl_send_continue (mq);
- return;
- }
- env = GNUNET_MQ_msg_nested_mh (cadet_msg,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
- msg);
- cadet_msg->ccn = ch->ccn;
- GNUNET_assert (NULL == ch->pending_env);
- ch->pending_env = env;
- if (0 < ch->allow_send)
- ch->mq_cont
- = GNUNET_SCHEDULER_add_now (&cadet_mq_send_now,
- ch);
-}
-
-
-/**
- * Handle destruction of a message queue. Implementations must not
- * free @a mq, but should take care of @a impl_state.
- *
- * @param mq the message queue to destroy
- * @param impl_state state of the implementation
- */
-static void
-cadet_mq_destroy_impl (struct GNUNET_MQ_Handle *mq,
- void *impl_state)
-{
- struct GNUNET_CADET_Channel *ch = impl_state;
-
- GNUNET_assert (mq == ch->mq);
- ch->mq = NULL;
-}
-
-
-/**
- * We had an error processing a message we forwarded from a peer to
- * the CADET service. We should just complain about it but otherwise
- * continue processing.
- *
- * @param cls closure with our `struct GNUNET_CADET_Channel`
- * @param error error code
- */
-static void
-cadet_mq_error_handler (void *cls,
- enum GNUNET_MQ_Error error)
-{
- struct GNUNET_CADET_Channel *ch = cls;
-
- GNUNET_break (0);
- if (GNUNET_MQ_ERROR_NO_MATCH == error)
- {
- /* Got a message we did not understand, still try to continue! */
- GNUNET_CADET_receive_done (ch);
- }
- else
- {
- schedule_reconnect (ch->cadet);
- }
-}
-
-
-/**
- * Implementation function that cancels the currently sent message.
- * Should basically undo whatever #mq_send_impl() did.
- *
- * @param mq message queue
- * @param impl_state state specific to the implementation
- */
-static void
-cadet_mq_cancel_impl (struct GNUNET_MQ_Handle *mq,
- void *impl_state)
-{
- struct GNUNET_CADET_Channel *ch = impl_state;
-
- GNUNET_assert (NULL != ch->pending_env);
- GNUNET_MQ_discard (ch->pending_env);
- ch->pending_env = NULL;
- if (NULL != ch->mq_cont)
- {
- GNUNET_SCHEDULER_cancel (ch->mq_cont);
- ch->mq_cont = NULL;
- }
-}
-
-
-/**
- * Process the new channel notification and add it to the channels in the handle
- *
- * @param h The cadet handle
- * @param msg A message with the details of the new incoming channel
- */
-static void
-handle_channel_created (void *cls,
- const struct GNUNET_CADET_LocalChannelCreateMessage *msg)
-{
- struct GNUNET_CADET_Handle *h = cls;
- struct GNUNET_CADET_Channel *ch;
- struct GNUNET_CADET_Port *port;
- const struct GNUNET_HashCode *port_number;
- struct GNUNET_CADET_ClientChannelNumber ccn;
-
- ccn = msg->ccn;
- port_number = &msg->port;
- if (ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
- {
- GNUNET_break (0);
- return;
- }
- port = find_port (h,
- port_number);
- if (NULL == port)
- {
- /* We could have closed the port but the service didn't know about it yet
- * This is not an error.
- */
- struct GNUNET_CADET_LocalChannelDestroyMessage *d_msg;
- struct GNUNET_MQ_Envelope *env;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "No handler for incoming channel %X (on port %s, recently closed?)\n",
- ntohl (ccn.channel_of_client),
- GNUNET_h2s (port_number));
- env = GNUNET_MQ_msg (d_msg,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
- d_msg->ccn = msg->ccn;
- GNUNET_MQ_send (h->mq,
- env);
- return;
- }
-
- ch = create_channel (h,
- &ccn);
- ch->peer = msg->peer;
- ch->cadet = h;
- ch->incoming_port = port;
- ch->options = ntohl (msg->opt);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Creating incoming channel %X [%s] %p\n",
- ntohl (ccn.channel_of_client),
- GNUNET_h2s (port_number),
- ch);
-
- GNUNET_assert (NULL != port->connects);
- ch->window_changes = port->window_changes;
- ch->disconnects = port->disconnects;
- ch->mq = GNUNET_MQ_queue_for_callbacks (&cadet_mq_send_impl,
- &cadet_mq_destroy_impl,
- &cadet_mq_cancel_impl,
- ch,
- port->handlers,
- &cadet_mq_error_handler,
- ch);
- ch->ctx = port->connects (port->cls,
- ch,
- &msg->peer);
- GNUNET_MQ_set_handlers_closure (ch->mq,
- ch->ctx);
-}
-
-
-/**
- * Process the channel destroy notification and free associated resources
- *
- * @param h The cadet handle
- * @param msg A message with the details of the channel being destroyed
- */
-static void
-handle_channel_destroy (void *cls,
- const struct GNUNET_CADET_LocalChannelDestroyMessage *msg)
-{
- struct GNUNET_CADET_Handle *h = cls;
- struct GNUNET_CADET_Channel *ch;
-
- ch = find_channel (h,
- msg->ccn);
- if (NULL == ch)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Received channel destroy for unknown channel %X from CADET service (recently close?)\n",
- ntohl (msg->ccn.channel_of_client));
- return;
- }
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Received channel destroy for channel %X from CADET service\n",
- ntohl (msg->ccn.channel_of_client));
- destroy_channel (ch);
-}
-
-
-/**
- * Check that message received from CADET service is well-formed.
- *
- * @param cls the `struct GNUNET_CADET_Handle`
- * @param message the message we got
- * @return #GNUNET_OK if the message is well-formed,
- * #GNUNET_SYSERR otherwise
- */
-static int
-check_local_data (void *cls,
- const struct GNUNET_CADET_LocalData *message)
-{
- uint16_t size;
-
- size = ntohs (message->header.size);
- if (sizeof (*message) + sizeof (struct GNUNET_MessageHeader) > size)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Process the incoming data packets, call appropriate handlers.
- *
- * @param h The cadet handle
- * @param message A message encapsulating the data
- */
-static void
-handle_local_data (void *cls,
- const struct GNUNET_CADET_LocalData *message)
-{
- struct GNUNET_CADET_Handle *h = cls;
- const struct GNUNET_MessageHeader *payload;
- struct GNUNET_CADET_Channel *ch;
- uint16_t type;
- int fwd;
-
- ch = find_channel (h,
- message->ccn);
- if (NULL == ch)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Unknown channel %X for incoming data (recently closed?)\n",
- ntohl (message->ccn.channel_of_client));
- return;
- }
-
- payload = (const struct GNUNET_MessageHeader *) &message[1];
- type = ntohs (payload->type);
- fwd = ntohl (ch->ccn.channel_of_client) <= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Got a %s data on channel %s [%X] of type %u\n",
- fwd ? "FWD" : "BWD",
- GNUNET_i2s (&ch->peer),
- ntohl (message->ccn.channel_of_client),
- type);
- GNUNET_MQ_inject_message (ch->mq,
- payload);
-}
-
-
-/**
- * Process a local ACK message, enabling the client to send
- * more data to the service.
- *
- * @param h Cadet handle.
- * @param message Message itself.
- */
-static void
-handle_local_ack (void *cls,
- const struct GNUNET_CADET_LocalAck *message)
-{
- struct GNUNET_CADET_Handle *h = cls;
- struct GNUNET_CADET_Channel *ch;
-
- ch = find_channel (h,
- message->ccn);
- if (NULL == ch)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "ACK on unknown channel %X\n",
- ntohl (message->ccn.channel_of_client));
- return;
- }
- ch->allow_send++;
- if (NULL == ch->pending_env)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Got an ACK on mq channel %X, allow send now %u!\n",
- ntohl (ch->ccn.channel_of_client),
- ch->allow_send);
- notify_window_size (ch);
- return;
- }
- if (NULL != ch->mq_cont)
- return; /* already working on it! */
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Got an ACK on mq channel %X, sending pending message!\n",
- ntohl (ch->ccn.channel_of_client));
- ch->mq_cont
- = GNUNET_SCHEDULER_add_now (&cadet_mq_send_now,
- ch);
-}
-
-
-/**
- * Generic error handler, called with the appropriate error code and
- * the same closure specified at the creation of the message queue.
- * Not every message queue implementation supports an error handler.
- *
- * @param cls closure, a `struct GNUNET_CORE_Handle *`
- * @param error error code
- */
-static void
-handle_mq_error (void *cls,
- enum GNUNET_MQ_Error error)
-{
- struct GNUNET_CADET_Handle *h = cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "MQ ERROR: %u\n",
- error);
- GNUNET_MQ_destroy (h->mq);
- h->mq = NULL;
- reconnect (h);
-}
-
-
-/**
- * Process a local reply about info on all tunnels, pass info to the user.
- *
- * @param cls Closure (Cadet handle).
- * @param msg Message itself.
- */
-static void
-handle_get_peers (void *cls,
- const struct GNUNET_CADET_LocalInfoPeer *msg)
-{
- struct GNUNET_CADET_Handle *h = cls;
-
- if (NULL == h->info_cb.peers_cb)
- return;
- h->info_cb.peers_cb (h->info_cls,
- &msg->destination,
- (int) ntohs (msg->tunnel),
- (unsigned int) ntohs (msg->paths),
- 0);
-}
-
-
-/**
- * Check that message received from CADET service is well-formed.
- *
- * @param cls the `struct GNUNET_CADET_Handle`
- * @param message the message we got
- * @return #GNUNET_OK if the message is well-formed,
- * #GNUNET_SYSERR otherwise
- */
-static int
-check_get_peer (void *cls,
- const struct GNUNET_CADET_LocalInfoPeer *message)
-{
- size_t msize = sizeof (struct GNUNET_CADET_LocalInfoPeer);
- const struct GNUNET_PeerIdentity *paths_array;
- size_t esize;
- unsigned int epaths;
- unsigned int paths;
- unsigned int peers;
-
- esize = ntohs (message->header.size);
- if (esize < msize)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- if (0 != ((esize - msize) % sizeof (struct GNUNET_PeerIdentity)))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- peers = (esize - msize) / sizeof (struct GNUNET_PeerIdentity);
- epaths = ntohs (message->paths);
- paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
- paths = 0;
- for (unsigned int i = 0; i < peers; i++)
- if (0 == memcmp (&paths_array[i],
- &message->destination,
- sizeof (struct GNUNET_PeerIdentity)))
- paths++;
- if (paths != epaths)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Process a local peer info reply, pass info to the user.
- *
- * @param cls Closure (Cadet handle).
- * @param message Message itself.
- */
-static void
-handle_get_peer (void *cls,
- const struct GNUNET_CADET_LocalInfoPeer *message)
-{
- struct GNUNET_CADET_Handle *h = cls;
- const struct GNUNET_PeerIdentity *paths_array;
- unsigned int paths;
- unsigned int path_length;
- int neighbor;
- unsigned int peers;
-
- if (NULL == h->info_cb.peer_cb)
- return;
- paths = ntohs (message->paths);
- paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
- peers = (ntohs (message->header.size) - sizeof (*message))
- / sizeof (struct GNUNET_PeerIdentity);
- path_length = 0;
- neighbor = GNUNET_NO;
-
- for (unsigned int i = 0; i < peers; i++)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " %s\n",
- GNUNET_i2s (&paths_array[i]));
- path_length++;
- if (0 == memcmp (&paths_array[i], &message->destination,
- sizeof (struct GNUNET_PeerIdentity)))
- {
- if (1 == path_length)
- neighbor = GNUNET_YES;
- path_length = 0;
- }
- }
-
- /* Call Callback with tunnel info. */
- paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
- h->info_cb.peer_cb (h->info_cls,
- &message->destination,
- (int) ntohs (message->tunnel),
- neighbor,
- paths,
- paths_array);
-}
-
-
-/**
- * Process a local reply about info on all tunnels, pass info to the user.
- *
- * @param cls Closure (Cadet handle).
- * @param message Message itself.
- */
-static void
-handle_get_tunnels (void *cls,
- const struct GNUNET_CADET_LocalInfoTunnel *msg)
-{
- struct GNUNET_CADET_Handle *h = cls;
-
- if (NULL == h->info_cb.tunnels_cb)
- return;
- h->info_cb.tunnels_cb (h->info_cls,
- &msg->destination,
- ntohl (msg->channels),
- ntohl (msg->connections),
- ntohs (msg->estate),
- ntohs (msg->cstate));
-
-}
-
-
-/**
- * Check that message received from CADET service is well-formed.
- *
- * @param cls the `struct GNUNET_CADET_Handle`
- * @param msg the message we got
- * @return #GNUNET_OK if the message is well-formed,
- * #GNUNET_SYSERR otherwise
- */
-static int
-check_get_tunnel (void *cls,
- const struct GNUNET_CADET_LocalInfoTunnel *msg)
-{
- unsigned int ch_n;
- unsigned int c_n;
- size_t esize;
- size_t msize;
-
- /* Verify message sanity */
- msize = ntohs (msg->header.size);
- esize = sizeof (struct GNUNET_CADET_LocalInfoTunnel);
- if (esize > msize)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- ch_n = ntohl (msg->channels);
- c_n = ntohl (msg->connections);
- esize += ch_n * sizeof (struct GNUNET_CADET_ChannelTunnelNumber);
- esize += c_n * sizeof (struct GNUNET_CADET_ConnectionTunnelIdentifier);
- if (msize != esize)
- {
- GNUNET_break_op (0);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "m:%u, e: %u (%u ch, %u conn)\n",
- (unsigned int) msize,
- (unsigned int) esize,
- ch_n,
- c_n);
- return GNUNET_SYSERR;
- }
- return GNUNET_OK;
-}
-
-
-/**
- * Process a local tunnel info reply, pass info to the user.
- *
- * @param cls Closure (Cadet handle).
- * @param msg Message itself.
- */
-static void
-handle_get_tunnel (void *cls,
- const struct GNUNET_CADET_LocalInfoTunnel *msg)
-{
- struct GNUNET_CADET_Handle *h = cls;
- unsigned int ch_n;
- unsigned int c_n;
- const struct GNUNET_CADET_ConnectionTunnelIdentifier *conns;
- const struct GNUNET_CADET_ChannelTunnelNumber *chns;
-
- if (NULL == h->info_cb.tunnel_cb)
- return;
-
- ch_n = ntohl (msg->channels);
- c_n = ntohl (msg->connections);
-
- /* Call Callback with tunnel info. */
- conns = (const struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1];
- chns = (const struct GNUNET_CADET_ChannelTunnelNumber *) &conns[c_n];
- h->info_cb.tunnel_cb (h->info_cls,
- &msg->destination,
- ch_n,
- c_n,
- chns,
- conns,
- ntohs (msg->estate),
- ntohs (msg->cstate));
-}
-
-
-/**
- * Reconnect to the service, retransmit all infomation to try to restore the
- * original state.
- *
- * @param h handle to the cadet
- */
-static void
-reconnect (struct GNUNET_CADET_Handle *h)
-{
- struct GNUNET_MQ_MessageHandler handlers[] = {
- GNUNET_MQ_hd_fixed_size (channel_created,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE,
- struct GNUNET_CADET_LocalChannelCreateMessage,
- h),
- GNUNET_MQ_hd_fixed_size (channel_destroy,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY,
- struct GNUNET_CADET_LocalChannelDestroyMessage,
- h),
- GNUNET_MQ_hd_var_size (local_data,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
- struct GNUNET_CADET_LocalData,
- h),
- GNUNET_MQ_hd_fixed_size (local_ack,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
- struct GNUNET_CADET_LocalAck,
- h),
- GNUNET_MQ_hd_fixed_size (get_peers,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS,
- struct GNUNET_CADET_LocalInfoPeer,
- h),
- GNUNET_MQ_hd_var_size (get_peer,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER,
- struct GNUNET_CADET_LocalInfoPeer,
- h),
- GNUNET_MQ_hd_fixed_size (get_tunnels,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS,
- struct GNUNET_CADET_LocalInfoTunnel,
- h),
- GNUNET_MQ_hd_var_size (get_tunnel,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL,
- struct GNUNET_CADET_LocalInfoTunnel,
- h),
- GNUNET_MQ_handler_end ()
- };
-
- h->mq = GNUNET_CLIENT_connect (h->cfg,
- "cadet",
- handlers,
- &handle_mq_error,
- h);
- if (NULL == h->mq)
- {
- schedule_reconnect (h);
- return;
- }
- h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
-}
-
-
-/**
- * Function called during #GNUNET_CADET_disconnect() to destroy
- * all channels that are still open.
- *
- * @param cls the `struct GNUNET_CADET_Handle`
- * @param cid chanenl ID
- * @param value a `struct GNUNET_CADET_Channel` to destroy
- * @return #GNUNET_OK (continue to iterate)
- */
-static int
-destroy_channel_cb (void *cls,
- uint32_t cid,
- void *value)
-{
- /* struct GNUNET_CADET_Handle *handle = cls; */
- struct GNUNET_CADET_Channel *ch = value;
-
- if (ntohl (ch->ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
- {
- GNUNET_break (0);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "channel %X not destroyed\n",
- ntohl (ch->ccn.channel_of_client));
- }
- destroy_channel (ch);
- return GNUNET_OK;
-}
-
-
-/**
- * Function called during #GNUNET_CADET_disconnect() to destroy
- * all ports that are still open.
- *
- * @param cls the `struct GNUNET_CADET_Handle`
- * @param id port ID
- * @param value a `struct GNUNET_CADET_Channel` to destroy
- * @return #GNUNET_OK (continue to iterate)
- */
-static int
-destroy_port_cb (void *cls,
- const struct GNUNET_HashCode *id,
- void *value)
-{
- /* struct GNUNET_CADET_Handle *handle = cls; */
- struct GNUNET_CADET_Port *port = value;
-
- /* This is a warning, the app should have cleanly closed all open ports */
- GNUNET_break (0);
- GNUNET_CADET_close_port (port);
- return GNUNET_OK;
-}
-
-
-/**
- * Disconnect from the cadet service. All channels will be destroyed. All channel
- * disconnect callbacks will be called on any still connected peers, notifying
- * about their disconnection. The registered inbound channel cleaner will be
- * called should any inbound channels still exist.
- *
- * @param handle connection to cadet to disconnect
- */
-void
-GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle)
-{
- GNUNET_CONTAINER_multihashmap_iterate (handle->ports,
- &destroy_port_cb,
- handle);
- GNUNET_CONTAINER_multihashmap_destroy (handle->ports);
- handle->ports = NULL;
- GNUNET_CONTAINER_multihashmap32_iterate (handle->channels,
- &destroy_channel_cb,
- handle);
- GNUNET_CONTAINER_multihashmap32_destroy (handle->channels);
- handle->channels = NULL;
- if (NULL != handle->mq)
- {
- GNUNET_MQ_destroy (handle->mq);
- handle->mq = NULL;
- }
- if (NULL != handle->reconnect_task)
- {
- GNUNET_SCHEDULER_cancel (handle->reconnect_task);
- handle->reconnect_task = NULL;
- }
- GNUNET_free (handle);
-}
-
-
-/**
- * Close a port opened with @a GNUNET_CADET_open_port().
- * The @a new_channel callback will no longer be called.
- *
- * @param p Port handle.
- */
-void
-GNUNET_CADET_close_port (struct GNUNET_CADET_Port *p)
-{
- struct GNUNET_CADET_PortMessage *msg;
- struct GNUNET_MQ_Envelope *env;
-
- env = GNUNET_MQ_msg (msg,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE);
- msg->port = p->id;
- GNUNET_MQ_send (p->cadet->mq,
- env);
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_remove (p->cadet->ports,
- &p->id,
- p));
- GNUNET_free_non_null (p->handlers);
- GNUNET_free (p);
-}
-
-
-/**
- * Destroy an existing channel.
- *
- * The existing end callback for the channel will be called immediately.
- * Any pending outgoing messages will be sent but no incoming messages will be
- * accepted and no data callbacks will be called.
- *
- * @param channel Channel handle, becomes invalid after this call.
- */
-void
-GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel)
-{
- struct GNUNET_CADET_Handle *h = channel->cadet;
- struct GNUNET_CADET_LocalChannelDestroyMessage *msg;
- struct GNUNET_MQ_Envelope *env;
-
- if (NULL != h->mq)
- {
- env = GNUNET_MQ_msg (msg,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
- msg->ccn = channel->ccn;
- GNUNET_MQ_send (h->mq,
- env);
- }
- destroy_channel (channel);
-}
-
-
-/**
- * Get information about a channel.
- *
- * @param channel Channel handle.
- * @param option Query (GNUNET_CADET_OPTION_*).
- * @param ... dependant on option, currently not used
- *
- * @return Union with an answer to the query.
- */
-const union GNUNET_CADET_ChannelInfo *
-GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel,
- enum GNUNET_CADET_ChannelOption option,
- ...)
-{
- static int bool_flag;
-
- switch (option)
- {
- case GNUNET_CADET_OPTION_NOBUFFER:
- case GNUNET_CADET_OPTION_RELIABLE:
- case GNUNET_CADET_OPTION_OUT_OF_ORDER:
- if (0 != (option & channel->options))
- bool_flag = GNUNET_YES;
- else
- bool_flag = GNUNET_NO;
- return (const union GNUNET_CADET_ChannelInfo *) &bool_flag;
- break;
- case GNUNET_CADET_OPTION_PEER:
- return (const union GNUNET_CADET_ChannelInfo *) &channel->peer;
- break;
- default:
- GNUNET_break (0);
- return NULL;
- }
-}
-
-
-/**
- * Send an ack on the channel to confirm the processing of a message.
- *
- * @param ch Channel on which to send the ACK.
- */
-void
-GNUNET_CADET_receive_done (struct GNUNET_CADET_Channel *channel)
-{
- struct GNUNET_CADET_LocalAck *msg;
- struct GNUNET_MQ_Envelope *env;
-
- env = GNUNET_MQ_msg (msg,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Sending ACK on channel %X\n",
- ntohl (channel->ccn.channel_of_client));
- msg->ccn = channel->ccn;
- GNUNET_MQ_send (channel->cadet->mq,
- env);
-}
-
-
-/**
- * Send message of @a type to CADET service of @a h
- *
- * @param h handle to CADET service
- * @param type message type of trivial information request to send
- */
-static void
-send_info_request (struct GNUNET_CADET_Handle *h,
- uint16_t type)
-{
- struct GNUNET_MessageHeader *msg;
- struct GNUNET_MQ_Envelope *env;
-
- env = GNUNET_MQ_msg (msg,
- type);
- GNUNET_MQ_send (h->mq,
- env);
-}
-
-
-/**
- * Request a debug dump on the service's STDERR.
- *
- * WARNING: unstable API, likely to change in the future!
- *
- * @param h cadet handle
- */
-void
-GNUNET_CADET_request_dump (struct GNUNET_CADET_Handle *h)
-{
- send_info_request (h,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP);
-}
-
-
-/**
- * Request information about peers known to the running cadet service.
- * The callback will be called for every peer known to the service.
- * Only one info request (of any kind) can be active at once.
- *
- * WARNING: unstable API, likely to change in the future!
- *
- * @param h Handle to the cadet peer.
- * @param callback Function to call with the requested data.
- * @param callback_cls Closure for @c callback.
- * @return #GNUNET_OK / #GNUNET_SYSERR
- */
-int
-GNUNET_CADET_get_peers (struct GNUNET_CADET_Handle *h,
- GNUNET_CADET_PeersCB callback,
- void *callback_cls)
-{
- if (NULL != h->info_cb.peers_cb)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- send_info_request (h,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
- h->info_cb.peers_cb = callback;
- h->info_cls = callback_cls;
- return GNUNET_OK;
-}
-
-
-/**
- * Cancel a peer info request. The callback will not be called (anymore).
- *
- * WARNING: unstable API, likely to change in the future!
- *
- * @param h Cadet handle.
- * @return Closure given to GNUNET_CADET_get_peers().
- */
-void *
-GNUNET_CADET_get_peers_cancel (struct GNUNET_CADET_Handle *h)
-{
- void *cls = h->info_cls;
-
- h->info_cb.peers_cb = NULL;
- h->info_cls = NULL;
- return cls;
-}
-
-
-/**
- * Request information about a peer known to the running cadet peer.
- * The callback will be called for the tunnel once.
- * Only one info request (of any kind) can be active at once.
- *
- * WARNING: unstable API, likely to change in the future!
- *
- * @param h Handle to the cadet peer.
- * @param id Peer whose tunnel to examine.
- * @param callback Function to call with the requested data.
- * @param callback_cls Closure for @c callback.
- * @return #GNUNET_OK / #GNUNET_SYSERR
- */
-int
-GNUNET_CADET_get_peer (struct GNUNET_CADET_Handle *h,
- const struct GNUNET_PeerIdentity *id,
- GNUNET_CADET_PeerCB callback,
- void *callback_cls)
-{
- struct GNUNET_CADET_LocalInfo *msg;
- struct GNUNET_MQ_Envelope *env;
-
- if (NULL != h->info_cb.peer_cb)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- env = GNUNET_MQ_msg (msg,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
- msg->peer = *id;
- GNUNET_MQ_send (h->mq,
- env);
- h->info_cb.peer_cb = callback;
- h->info_cls = callback_cls;
- return GNUNET_OK;
-}
-
-
-/**
- * Request information about tunnels of the running cadet peer.
- * The callback will be called for every tunnel of the service.
- * Only one info request (of any kind) can be active at once.
- *
- * WARNING: unstable API, likely to change in the future!
- *
- * @param h Handle to the cadet peer.
- * @param callback Function to call with the requested data.
- * @param callback_cls Closure for @c callback.
- * @return #GNUNET_OK / #GNUNET_SYSERR
- */
-int
-GNUNET_CADET_get_tunnels (struct GNUNET_CADET_Handle *h,
- GNUNET_CADET_TunnelsCB callback,
- void *callback_cls)
-{
- if (NULL != h->info_cb.tunnels_cb)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- send_info_request (h,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
- h->info_cb.tunnels_cb = callback;
- h->info_cls = callback_cls;
- return GNUNET_OK;
-}
-
-
-/**
- * Cancel a monitor request. The monitor callback will not be called.
- *
- * @param h Cadet handle.
- * @return Closure given to GNUNET_CADET_get_tunnels().
- */
-void *
-GNUNET_CADET_get_tunnels_cancel (struct GNUNET_CADET_Handle *h)
-{
- void *cls = h->info_cls;
-
- h->info_cb.tunnels_cb = NULL;
- h->info_cls = NULL;
- return cls;
-}
-
-
-/**
- * Request information about a tunnel of the running cadet peer.
- * The callback will be called for the tunnel once.
- * Only one info request (of any kind) can be active at once.
- *
- * WARNING: unstable API, likely to change in the future!
- *
- * @param h Handle to the cadet peer.
- * @param id Peer whose tunnel to examine.
- * @param callback Function to call with the requested data.
- * @param callback_cls Closure for @c callback.
- * @return #GNUNET_OK / #GNUNET_SYSERR
- */
-int
-GNUNET_CADET_get_tunnel (struct GNUNET_CADET_Handle *h,
- const struct GNUNET_PeerIdentity *id,
- GNUNET_CADET_TunnelCB callback,
- void *callback_cls)
-{
- struct GNUNET_CADET_LocalInfo *msg;
- struct GNUNET_MQ_Envelope *env;
-
- if (NULL != h->info_cb.tunnel_cb)
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- env = GNUNET_MQ_msg (msg,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
- msg->peer = *id;
- GNUNET_MQ_send (h->mq,
- env);
- h->info_cb.tunnel_cb = callback;
- h->info_cls = callback_cls;
- return GNUNET_OK;
-}
-
-
-/**
- * Transitional function to convert an unsigned int port to a hash value.
- * WARNING: local static value returned, NOT reentrant!
- * WARNING: do not use this function for new code!
- *
- * @param port Numerical port (unsigned int format).
- *
- * @return A GNUNET_HashCode usable for the new CADET API.
- */
-const struct GNUNET_HashCode *
-GC_u2h (uint32_t port)
-{
- static struct GNUNET_HashCode hash;
-
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "This is a transitional function, use proper crypto hashes as CADET ports\n");
- GNUNET_CRYPTO_hash (&port,
- sizeof (port),
- &hash);
- return &hash;
-}
-
-
-/**
- * Connect to the MQ-based cadet service.
- *
- * @param cfg Configuration to use.
- *
- * @return Handle to the cadet service NULL on error.
- */
-struct GNUNET_CADET_Handle *
-GNUNET_CADET_connecT (const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- struct GNUNET_CADET_Handle *h;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "GNUNET_CADET_connecT()\n");
- h = GNUNET_new (struct GNUNET_CADET_Handle);
- h->cfg = cfg;
- h->ports = GNUNET_CONTAINER_multihashmap_create (4,
- GNUNET_YES);
- h->channels = GNUNET_CONTAINER_multihashmap32_create (4);
- reconnect (h);
- if (NULL == h->mq)
- {
- GNUNET_break (0);
- GNUNET_CADET_disconnect (h);
- return NULL;
- }
- h->next_ccn.channel_of_client = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
- h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
- h->reconnect_task = NULL;
-
- return h;
-}
-
-
-/**
- * Open a port to receive incomming MQ-based channels.
- *
- * @param h CADET handle.
- * @param port Hash identifying the port.
- * @param connects Function called when an incoming channel is connected.
- * @param connects_cls Closure for the @a connects handler.
- * @param window_changes Function called when the transmit window size changes.
- * @param disconnects Function called when a channel is disconnected.
- * @param handlers Callbacks for messages we care about, NULL-terminated.
- * @return Port handle.
- */
-struct GNUNET_CADET_Port *
-GNUNET_CADET_open_porT (struct GNUNET_CADET_Handle *h,
- const struct GNUNET_HashCode *port,
- GNUNET_CADET_ConnectEventHandler connects,
- void * connects_cls,
- GNUNET_CADET_WindowSizeEventHandler window_changes,
- GNUNET_CADET_DisconnectEventHandler disconnects,
- const struct GNUNET_MQ_MessageHandler *handlers)
-{
- struct GNUNET_CADET_PortMessage *msg;
- struct GNUNET_MQ_Envelope *env;
- struct GNUNET_CADET_Port *p;
-
- GNUNET_assert (NULL != connects);
- GNUNET_assert (NULL != disconnects);
-
- p = GNUNET_new (struct GNUNET_CADET_Port);
- p->cadet = h;
- p->id = *port;
- p->connects = connects;
- p->cls = connects_cls;
- p->window_changes = window_changes;
- p->disconnects = disconnects;
- p->handlers = GNUNET_MQ_copy_handlers (handlers);
-
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_multihashmap_put (h->ports,
- &p->id,
- p,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
-
- env = GNUNET_MQ_msg (msg,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN);
- msg->port = p->id;
- GNUNET_MQ_send (h->mq,
- env);
- return p;
-}
-
-
-/**
- * Create a new channel towards a remote peer.
- *
- * If the destination port is not open by any peer or the destination peer
- * does not accept the channel, #GNUNET_CADET_ChannelEndHandler will be called
- * for this channel.
- *
- * @param h CADET handle.
- * @param channel_cls Closure for the channel. It's given to:
- * - The disconnect handler @a disconnects
- * - Each message type callback in @a handlers
- * @param destination Peer identity the channel should go to.
- * @param port Identification of the destination port.
- * @param options CadetOption flag field, with all desired option bits set to 1.
- * @param window_changes Function called when the transmit window size changes.
- * @param disconnects Function called when the channel is disconnected.
- * @param handlers Callbacks for messages we care about, NULL-terminated.
- * @return Handle to the channel.
- */
-struct GNUNET_CADET_Channel *
-GNUNET_CADET_channel_creatE (struct GNUNET_CADET_Handle *h,
- void *channel_cls,
- const struct GNUNET_PeerIdentity *destination,
- const struct GNUNET_HashCode *port,
- enum GNUNET_CADET_ChannelOption options,
- GNUNET_CADET_WindowSizeEventHandler window_changes,
- GNUNET_CADET_DisconnectEventHandler disconnects,
- const struct GNUNET_MQ_MessageHandler *handlers)
-{
- struct GNUNET_CADET_Channel *ch;
- struct GNUNET_CADET_LocalChannelCreateMessage *msg;
- struct GNUNET_MQ_Envelope *env;
-
- GNUNET_assert (NULL != disconnects);
- ch = create_channel (h,
- NULL);
- ch->ctx = channel_cls;
- ch->peer = *destination;
- ch->options = options;
- ch->window_changes = window_changes;
- ch->disconnects = disconnects;
-
- /* Create MQ for channel */
- ch->mq = GNUNET_MQ_queue_for_callbacks (&cadet_mq_send_impl,
- &cadet_mq_destroy_impl,
- &cadet_mq_cancel_impl,
- ch,
- handlers,
- &cadet_mq_error_handler,
- ch);
- GNUNET_MQ_set_handlers_closure (ch->mq, channel_cls);
-
- /* Request channel creation to service */
- env = GNUNET_MQ_msg (msg,
- GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
- msg->ccn = ch->ccn;
- msg->port = *port;
- msg->peer = *destination;
- msg->opt = htonl (options);
- GNUNET_MQ_send (h->mq,
- env);
- return ch;
-}
-
-
-/**
- * Obtain the message queue for a connected peer.
- *
- * @param channel The channel handle from which to get the MQ.
- *
- * @return NULL if @a channel is not yet connected.
- */
-struct GNUNET_MQ_Handle *
-GNUNET_CADET_get_mq (const struct GNUNET_CADET_Channel *channel)
-{
- return channel->mq;
-}
-
-/* end of cadet_api.c */
diff --git a/src/cadet/cadet_common.c b/src/cadet/cadet_common.c
deleted file mode 100644
index 95a3144e4d..0000000000
--- a/src/cadet/cadet_common.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- This file is part of GNUnet.
- Copyright (C) 2012 GNUnet e.V.
-
- GNUnet 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 3, or (at your
- option) any later version.
-
- GNUnet 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 GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-
-/**
- * @file cadet/cadet_common.c
- * @brief CADET helper functions
- * @author Bartlomiej Polot
- */
-
-#include "cadet.h"
-
-/**
- * @brief Translate a fwd variable into a string representation, for logging.
- *
- * @param fwd Is FWD? (#GNUNET_YES or #GNUNET_NO)
- *
- * @return String representing FWD or BCK.
- */
-char *
-GC_f2s (int fwd)
-{
- if (GNUNET_YES == fwd)
- {
- return "FWD";
- }
- else if (GNUNET_NO == fwd)
- {
- return "BCK";
- }
- else
- {
- /* Not an error, can happen with CONNECTION_BROKEN messages. */
- return "\???";
- }
-}
-
-
-/**
- * Test if @a bigger is larger than @a smaller.
- * Considers the case that @a bigger just overflowed
- * and is thus tiny while @a smaller is still below
- * `UINT32_MAX`.
- */
-int
-GC_is_pid_bigger (uint32_t bigger,
- uint32_t smaller)
-{
- return (PID_OVERFLOW (smaller, bigger) ||
- ( (bigger > smaller) &&
- (! PID_OVERFLOW (bigger, smaller))) );
-}
-
-
-uint32_t
-GC_max_pid (uint32_t a, uint32_t b)
-{
- if (GC_is_pid_bigger(a, b))
- return a;
- return b;
-}
-
-
-uint32_t
-GC_min_pid (uint32_t a, uint32_t b)
-{
- if (GC_is_pid_bigger(a, b))
- return b;
- return a;
-}
-
-
-/**
- * Allocate a string with a hexdump of any binary data.
- *
- * @param bin Arbitrary binary data.
- * @param len Length of @a bin in bytes.
- * @param output Where to write the output (if *output be NULL it's allocated).
- *
- * @return The size of the output.
- */
-size_t
-GC_bin2s (void *bin, unsigned int len, char **output)
-{
- char *data = bin;
- char *buf;
- unsigned int s_len;
- unsigned int i;
-
- s_len = 2 * len + 1;
- if (NULL == *output)
- *output = GNUNET_malloc (s_len);
- buf = *output;
-
- for (i = 0; i < len; i++)
- {
- SPRINTF (&buf[2 * i], "%2X", data[i]);
- }
- buf[s_len - 1] = '\0';
-
- return s_len;
-}
-
-
-#if !defined(GNUNET_CULL_LOGGING)
-const char *
-GC_m2s (uint16_t m)
-{
- static char buf[2][16];
- static int idx;
- const char *s;
-
- idx = (idx + 1) % 2;
- switch (m)
- {
- /**
- * Used to mark the "payload" of a non-payload message.
- */
- case 0:
- s = "retransmit";
- break;
-
- /**
- * Request the creation of a path
- */
- case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE:
- s = "CONN_CREAT";
- break;
-
- /**
- * Request the modification of an existing path
- */
- case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK:
- s = "CONN_ACK";
- break;
-
- /**
- * Notify that a connection of a path is no longer valid
- */
- case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN:
- s = "CONN_BRKN";
- break;
-
- /**
- * At some point, the route will spontaneously change
- */
- case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_PATH_CHANGED_UNIMPLEMENTED:
- s = "PATH_CHNGD";
- break;
-
- /**
- * Transport payload data.
- */
- case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA:
- s = "DATA";
- break;
-
- /**
- * Confirm receipt of payload data.
- */
- case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK:
- s = "DATA_ACK";
- break;
-
- /**
- * Key exchange message.
- */
- case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX:
- s = "KX";
- break;
-
- /**
- * Encrypted.
- */
- case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED:
- s = "ENCRYPTED";
- break;
-
- /**
- * Request the destuction of a path
- */
- case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY:
- s = "CONN_DSTRY";
- break;
-
- /**
- * ACK for a data packet.
- */
- case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK:
- s = "ACK";
- break;
-
- /**
- * POLL for ACK.
- */
- case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL:
- s = "POLL";
- break;
-
- /**
- * Announce origin is still alive.
- */
- case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE:
- s = "KEEPALIVE";
- break;
-
- /**
- * Open port
- */
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN:
- s = "OPEN_PORT";
- break;
-
- /**
- * Close port
- */
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE:
- s = "CLOSE_PORT";
- break;
-
- /**
- * Ask the cadet service to create a new tunnel
- */
- case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN:
- s = "CHAN_CREAT";
- break;
-
- /**
- * Ask the cadet service to destroy a tunnel
- */
- case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY:
- s = "CHAN_DSTRY";
- break;
-
- /**
- * Confirm the creation of a channel.
- */
- case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK:
- s = "CHAN_ACK";
- break;
-
- /**
- * Confirm the creation of a channel.
- */
- case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED:
- s = "CHAN_NACK";
- break;
-
- /**
- * Local payload traffic
- */
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA:
- s = "LOC_DATA";
- break;
-
- /**
- * Local ACK for data.
- */
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK:
- s = "LOC_ACK";
- break;
-
- /**
- * Local monitoring of channels.
- */
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNELS:
- s = "INFO_CHANS";
- break;
-
- /**
- * Local monitoring of a channel.
- */
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL:
- s = "INFO_CHAN";
- break;
-
- /**
- * Local monitoring of service.
- */
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS:
- s = "INFO_TUNS";
- break;
-
- /**
- * Local monitoring of service.
- */
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL:
- s = "INFO_TUN";
- break;
-
- /**
- * Local information about all connections of service.
- */
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CONNECTIONS:
- s = "INFO_CONNS";
- break;
-
- /**
- * Local information of service about a specific connection.
- */
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CONNECTION:
- s = "INFO_CONN";
- break;
-
- /**
- * Local information about all peers known to the service.
- */
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS:
- s = "INFO_PEERS";
- break;
-
- /**
- * Local information of service about a specific peer.
- */
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER:
- s = "INFO_PEER";
- break;
-
- /**
- * Traffic (net-cat style) used by the Command Line Interface.
- */
- case GNUNET_MESSAGE_TYPE_CADET_CLI:
- s = "CLI";
- break;
-
- /**
- * Debug request.
- */
- case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP:
- s = "INFO_DUMP";
- break;
-
- /**
- * Used to mark the "payload" of a non-payload message.
- */
- case UINT16_MAX:
- s = " N/A";
- break;
-
-
- default:
- SPRINTF (buf[idx], "{UNK: %5u}", m);
- return buf[idx];
- }
- SPRINTF (buf[idx], "{%10s}", s);
- return buf[idx];
-}
-#else
-const char *
-GC_m2s (uint16_t m)
-{
- return "";
-}
-#endif
diff --git a/src/cadet/cadet_test_lib.c b/src/cadet/cadet_test_lib.c
index b2131d49f7..1df6bff0df 100644
--- a/src/cadet/cadet_test_lib.c
+++ b/src/cadet/cadet_test_lib.c
@@ -137,14 +137,14 @@ cadet_connect_adapter (void *cls,
struct GNUNET_CADET_Handle *h;
unsigned int i;
- h = GNUNET_CADET_connecT (cfg);
+ h = GNUNET_CADET_connect (cfg);
if (NULL == ctx->ports)
return h;
actx->ports = GNUNET_new_array (ctx->port_count, struct GNUNET_CADET_Port *);
for (i = 0; i < ctx->port_count; i++)
{
- actx->ports[i] = GNUNET_CADET_open_porT (h,
+ actx->ports[i] = GNUNET_CADET_open_port (h,
ctx->ports[i],
ctx->connects,
(void *) (long) actx->peer,
diff --git a/src/cadet/gnunet-cadet.c b/src/cadet/gnunet-cadet.c
index abbf9a0a79..1556f7d86a 100644
--- a/src/cadet/gnunet-cadet.c
+++ b/src/cadet/gnunet-cadet.c
@@ -829,7 +829,7 @@ run (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Connecting to CADET service\n");
- mh = GNUNET_CADET_connecT (cfg);
+ mh = GNUNET_CADET_connect (cfg);
GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
NULL);
if (NULL == mh)
@@ -844,7 +844,7 @@ run (void *cls,
GNUNET_CRYPTO_hash (listen_port,
strlen (listen_port),
&porthash);
- lp = GNUNET_CADET_open_porT (mh,
+ lp = GNUNET_CADET_open_port (mh,
&porthash,
&channel_incoming,
NULL,
@@ -876,7 +876,7 @@ run (void *cls,
GNUNET_CRYPTO_hash (target_port,
strlen(target_port),
&porthash);
- ch = GNUNET_CADET_channel_creatE (mh,
+ ch = GNUNET_CADET_channel_create (mh,
NULL,
&pid,
&porthash,
diff --git a/src/cadet/test_cadet.c b/src/cadet/test_cadet.c
index 4fe43b3bf0..3586b26ac5 100644
--- a/src/cadet/test_cadet.c
+++ b/src/cadet/test_cadet.c
@@ -705,12 +705,12 @@ handle_data (void *cls, const struct GNUNET_MessageHeader *message)
/**
* Method called whenever a peer connects to a port in MQ-based CADET.
*
- * @param cls Closure from #GNUNET_CADET_open_porT (peer # as long).
+ * @param cls Closure from #GNUNET_CADET_open_port (peer # as long).
* @param channel New handle to the channel.
* @param source Peer that started this channel.
* @return Closure for the incoming @a channel. It's given to:
* - The #GNUNET_CADET_DisconnectEventHandler (given to
- * #GNUNET_CADET_open_porT) when the channel dies.
+ * #GNUNET_CADET_open_port) when the channel dies.
* - Each the #GNUNET_MQ_MessageCallback handlers for each message
* received on the @a channel.
*/
@@ -840,7 +840,7 @@ start_test (void *cls)
}
ch = GNUNET_new (struct CadetTestChannelWrapper);
- outgoing_ch = GNUNET_CADET_channel_creatE (h1,
+ outgoing_ch = GNUNET_CADET_channel_create (h1,
ch,
p_id[1],
&port,
diff --git a/src/cadet/test_cadet_local_mq.c b/src/cadet/test_cadet_local_mq.c
index 19bafbed1f..3089c7fbb2 100644
--- a/src/cadet/test_cadet_local_mq.c
+++ b/src/cadet/test_cadet_local_mq.c
@@ -132,12 +132,12 @@ do_abort (void *cls)
/**
* Method called whenever a peer connects to a port in MQ-based CADET.
*
- * @param cls Closure from #GNUNET_CADET_open_porT.
+ * @param cls Closure from #GNUNET_CADET_open_port.
* @param channel New handle to the channel.
* @param source Peer that started this channel.
* @return Closure for the incoming @a channel. It's given to:
* - The #GNUNET_CADET_DisconnectEventHandler (given to
- * #GNUNET_CADET_open_porT) when the channel dies.
+ * #GNUNET_CADET_open_port) when the channel dies.
* - Each the #GNUNET_MQ_MessageCallback handlers for each message
* received on the @a channel.
*/
@@ -235,7 +235,7 @@ do_connect (void *cls)
GNUNET_TESTING_peer_get_identity (me, &id);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"creating channel\n");
- ch = GNUNET_CADET_channel_creatE (cadet_peer_1, /* cadet handle */
+ ch = GNUNET_CADET_channel_create (cadet_peer_1, /* cadet handle */
NULL, /* channel cls */
&id, /* destination */
GC_u2h (TEST_MESSAGE_TYPE), /* port */
@@ -282,8 +282,8 @@ run (void *cls,
abort_task = GNUNET_SCHEDULER_add_delayed (delay,
&do_abort,
(void *) (long) __LINE__);
- cadet_peer_1 = GNUNET_CADET_connecT (cfg);
- cadet_peer_2 = GNUNET_CADET_connecT (cfg);
+ cadet_peer_1 = GNUNET_CADET_connect (cfg);
+ cadet_peer_2 = GNUNET_CADET_connect (cfg);
if ( (NULL == cadet_peer_1) ||
(NULL == cadet_peer_2) )
@@ -297,7 +297,7 @@ run (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CADET 1: %p\n", cadet_peer_1);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CADET 2: %p\n", cadet_peer_2);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "handlers 2: %p\n", handlers);
- GNUNET_CADET_open_porT (cadet_peer_2, /* cadet handle */
+ GNUNET_CADET_open_port (cadet_peer_2, /* cadet handle */
GC_u2h (TEST_PORT_ID), /* port id */
&connected, /* connect handler */
(void *) 2L, /* handle for #connected */
diff --git a/src/conversation/Makefile.am b/src/conversation/Makefile.am
index 83313e7f8d..cc29381445 100644
--- a/src/conversation/Makefile.am
+++ b/src/conversation/Makefile.am
@@ -180,7 +180,7 @@ gnunet_service_conversation_LDADD = \
libgnunetconversation.la \
libgnunetspeaker.la \
libgnunetmicrophone.la \
- $(top_builddir)/src/cadet/libgnunetcadetnew.la \
+ $(top_builddir)/src/cadet/libgnunetcadet.la \
$(top_builddir)/src/util/libgnunetutil.la \
$(INTLLIBS)
gnunet_service_conversation_LDFLAGS = \
diff --git a/src/conversation/gnunet-service-conversation.c b/src/conversation/gnunet-service-conversation.c
index e61ed44a1b..5f43bfe80d 100644
--- a/src/conversation/gnunet-service-conversation.c
+++ b/src/conversation/gnunet-service-conversation.c
@@ -1109,7 +1109,7 @@ handle_client_call_message (void *cls,
line->channel_tail,
ch);
ch->status = CS_CALLER_CALLING;
- ch->channel = GNUNET_CADET_channel_creatE (cadet,
+ ch->channel = GNUNET_CADET_channel_create (cadet,
ch,
&msg->target,
&msg->line_port,
@@ -1263,7 +1263,7 @@ handle_client_register_message (void *cls,
};
line->line_port = msg->line_port;
- line->port = GNUNET_CADET_open_porT (cadet,
+ line->port = GNUNET_CADET_open_port (cadet,
&msg->line_port,
&inbound_channel,
line,
@@ -1306,7 +1306,7 @@ run (void *cls,
GNUNET_assert (GNUNET_OK ==
GNUNET_CRYPTO_get_peer_identity (cfg,
&my_identity));
- cadet = GNUNET_CADET_connecT (cfg);
+ cadet = GNUNET_CADET_connect (cfg);
if (NULL == cadet)
{
GNUNET_break (0);
diff --git a/src/exit/Makefile.am b/src/exit/Makefile.am
index 271b4ebd7e..aa1210269e 100644
--- a/src/exit/Makefile.am
+++ b/src/exit/Makefile.am
@@ -54,6 +54,6 @@ gnunet_daemon_exit_LDADD = \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/tun/libgnunettun.la \
$(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/cadet/libgnunetcadetnew.la \
+ $(top_builddir)/src/cadet/libgnunetcadet.la \
$(top_builddir)/src/regex/libgnunetregex.la \
$(GN_LIBINTL)
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c
index 09576e3935..a32cb3086b 100644
--- a/src/exit/gnunet-daemon-exit.c
+++ b/src/exit/gnunet-daemon-exit.c
@@ -2502,7 +2502,7 @@ store_service (int proto,
GNUNET_h2s (&cadet_port),
name,
(unsigned int) destination_port);
- service->port = GNUNET_CADET_open_porT (cadet_handle,
+ service->port = GNUNET_CADET_open_port (cadet_handle,
&cadet_port,
&new_service_channel,
service,
@@ -3579,7 +3579,7 @@ advertise_dns_exit ()
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Opening CADET port %s for DNS exit service\n",
GNUNET_h2s (&port));
- dns_port = GNUNET_CADET_open_porT (cadet_handle,
+ dns_port = GNUNET_CADET_open_port (cadet_handle,
&port,
&new_channel,
NULL,
@@ -3829,7 +3829,7 @@ run (void *cls,
NULL);
stats = GNUNET_STATISTICS_create ("exit",
cfg);
- cadet_handle = GNUNET_CADET_connecT (cfg);
+ cadet_handle = GNUNET_CADET_connect (cfg);
if (NULL == cadet_handle)
{
GNUNET_SCHEDULER_shutdown ();
@@ -3862,7 +3862,7 @@ run (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Opening CADET port %s for IPv4 gateway service\n",
GNUNET_h2s (&port));
- cadet_port4 = GNUNET_CADET_open_porT (cadet_handle,
+ cadet_port4 = GNUNET_CADET_open_port (cadet_handle,
&port,
&new_channel,
NULL,
@@ -3902,7 +3902,7 @@ run (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Opening CADET port %s for IPv6 gateway service\n",
GNUNET_h2s (&port));
- cadet_port6 = GNUNET_CADET_open_porT (cadet_handle,
+ cadet_port6 = GNUNET_CADET_open_port (cadet_handle,
&port,
&new_channel,
NULL,
diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am
index 4374d45eab..33260a7940 100644
--- a/src/fs/Makefile.am
+++ b/src/fs/Makefile.am
@@ -202,7 +202,7 @@ gnunet_service_fs_LDADD = \
$(top_builddir)/src/block/libgnunetblock.la \
$(top_builddir)/src/datastore/libgnunetdatastore.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
- $(top_builddir)/src/cadet/libgnunetcadetnew.la \
+ $(top_builddir)/src/cadet/libgnunetcadet.la \
$(top_builddir)/src/ats/libgnunetats.la \
$(top_builddir)/src/core/libgnunetcore.la \
$(top_builddir)/src/util/libgnunetutil.la \
diff --git a/src/fs/gnunet-service-fs_cadet_client.c b/src/fs/gnunet-service-fs_cadet_client.c
index 55e0cbc246..c729ebe414 100644
--- a/src/fs/gnunet-service-fs_cadet_client.c
+++ b/src/fs/gnunet-service-fs_cadet_client.c
@@ -487,7 +487,7 @@ reset_cadet (struct CadetHandle *mh)
GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER,
strlen (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER),
&port);
- mh->channel = GNUNET_CADET_channel_creatE (cadet_handle,
+ mh->channel = GNUNET_CADET_channel_create (cadet_handle,
mh,
&mh->target,
&port,
@@ -627,7 +627,7 @@ get_cadet (const struct GNUNET_PeerIdentity *target)
GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER,
strlen (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER),
&port);
- mh->channel = GNUNET_CADET_channel_creatE (cadet_handle,
+ mh->channel = GNUNET_CADET_channel_create (cadet_handle,
mh,
&mh->target,
&port,
diff --git a/src/fs/gnunet-service-fs_cadet_server.c b/src/fs/gnunet-service-fs_cadet_server.c
index adbce11545..8567e63a2c 100644
--- a/src/fs/gnunet-service-fs_cadet_server.c
+++ b/src/fs/gnunet-service-fs_cadet_server.c
@@ -499,12 +499,12 @@ GSF_cadet_start_server ()
"Initializing cadet FS server with a limit of %llu connections\n",
sc_count_max);
cadet_map = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_YES);
- cadet_handle = GNUNET_CADET_connecT (GSF_cfg);
+ cadet_handle = GNUNET_CADET_connect (GSF_cfg);
GNUNET_assert (NULL != cadet_handle);
GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER,
strlen (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER),
&port);
- cadet_port = GNUNET_CADET_open_porT (cadet_handle,
+ cadet_port = GNUNET_CADET_open_port (cadet_handle,
&port,
&connect_cb,
NULL,
diff --git a/src/include/gnunet_cadet_service.h b/src/include/gnunet_cadet_service.h
index fd838df8d6..f76f17a518 100644
--- a/src/include/gnunet_cadet_service.h
+++ b/src/include/gnunet_cadet_service.h
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- Copyright (C) 2009-2014 GNUnet e.V.
+ Copyright (C) 2009-2017 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -49,7 +49,7 @@ extern "C"
/**
* Version number of GNUnet-cadet API.
*/
-#define GNUNET_CADET_VERSION 0x00000004
+#define GNUNET_CADET_VERSION 0x00000005
/**
@@ -69,6 +69,33 @@ struct GNUNET_CADET_Port;
/**
+ * Hash uniquely identifying a connection below a tunnel.
+ */
+struct GNUNET_CADET_ConnectionTunnelIdentifier
+{
+ struct GNUNET_ShortHashCode connection_of_tunnel;
+};
+
+
+/**
+ * Number identifying a CADET channel within a tunnel.
+ */
+struct GNUNET_CADET_ChannelTunnelNumber
+{
+ /**
+ * Which number does this channel have that uniquely identfies
+ * it within its tunnel, in network byte order.
+ *
+ * Given two peers, both may initiate channels over the same tunnel.
+ * The @e cn must be greater or equal to 0x80000000 (high-bit set)
+ * for tunnels initiated with the peer that has the larger peer
+ * identity as compared using #GNUNET_CRYPTO_cmp_peer_identity().
+ */
+ uint32_t cn GNUNET_PACKED;
+};
+
+
+/**
* Channel options. Second line indicates filed in the
* CadetChannelInfo union carrying the answer.
*/
@@ -108,118 +135,67 @@ enum GNUNET_CADET_ChannelOption
/**
- * Functions with this signature are called whenever a message is
- * received.
- *
- * Each time the function must call #GNUNET_CADET_receive_done on the channel
- * in order to receive the next message. This doesn't need to be immediate:
- * can be delayed if some processing is done on the message.
+ * Method called whenever a peer connects to a port in MQ-based CADET.
*
- * @param cls Closure (set from #GNUNET_CADET_connect).
- * @param channel Connection to the other end.
- * @param channel_ctx Place to store local state associated with the channel.
- * @param message The actual message.
- * @return #GNUNET_OK to keep the channel open,
- * #GNUNET_SYSERR to close it (signal serious error).
- */
-typedef int
-(*GNUNET_CADET_MessageCallback) (void *cls,
- struct GNUNET_CADET_Channel *channel,
- void **channel_ctx,
- const struct GNUNET_MessageHeader *message);
-
-
-/**
- * Message handler. Each struct specifies how to handle on particular
- * type of message received.
+ * @param cls Closure from #GNUNET_CADET_open_port.
+ * @param channel New handle to the channel.
+ * @param source Peer that started this channel.
+ * @return Closure for the incoming @a channel. It's given to:
+ * - The #GNUNET_CADET_DisconnectEventHandler (given to
+ * #GNUNET_CADET_open_port) when the channel dies.
+ * - Each the #GNUNET_MQ_MessageCallback handlers for each message
+ * received on the @a channel.
*/
-struct GNUNET_CADET_MessageHandler
-{
- /**
- * Function to call for messages of type @e type.
- */
- GNUNET_CADET_MessageCallback callback;
-
- /**
- * Type of the message this handler covers.
- */
- uint16_t type;
-
- /**
- * Expected size of messages of this type. Use 0 for variable-size.
- * If non-zero, messages of the given type will be discarded if they
- * do not have the right size.
- */
- uint16_t expected_size;
-};
+typedef void *
+(*GNUNET_CADET_ConnectEventHandler) (void *cls,
+ struct GNUNET_CADET_Channel *channel,
+ const struct GNUNET_PeerIdentity *source);
/**
- * Method called whenever another peer has added us to a channel
- * the other peer initiated.
- * Only called (once) upon reception of data with a message type which was
- * subscribed to in #GNUNET_CADET_connect.
- *
- * A call to #GNUNET_CADET_channel_destroy causes te channel to be ignored. In
- * this case the handler MUST return NULL.
+ * Function called whenever an MQ-channel is destroyed, even if the destruction
+ * was requested by #GNUNET_CADET_channel_destroy.
+ * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
*
- * @param cls closure
- * @param channel new handle to the channel
- * @param initiator peer that started the channel
- * @param port Port this channel is for.
- * @param options CadetOption flag field, with all active option bits set to 1.
+ * It should clean up any associated state, including cancelling any pending
+ * transmission on this channel.
*
- * @return initial channel context for the channel
- * (can be NULL -- that's not an error)
+ * @param cls Channel closure.
+ * @param channel Connection to the other end (henceforth invalid).
*/
-typedef void *
-(GNUNET_CADET_InboundChannelNotificationHandler) (void *cls,
- struct GNUNET_CADET_Channel *channel,
- const struct GNUNET_PeerIdentity *initiator,
- const struct GNUNET_HashCode *port,
- enum GNUNET_CADET_ChannelOption options);
+typedef void
+(*GNUNET_CADET_DisconnectEventHandler) (void *cls,
+ const struct GNUNET_CADET_Channel *channel);
/**
- * Function called whenever a channel is destroyed. Should clean up
- * any associated state, including cancelling any pending transmission on this
- * channel.
+ * Function called whenever an MQ-channel's transmission window size changes.
*
- * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
+ * The first callback in an outgoing channel will be with a non-zero value
+ * and will mean the channel is connected to the destination.
+ *
+ * For an incoming channel it will be called immediately after the
+ * #GNUNET_CADET_ConnectEventHandler, also with a non-zero value.
*
- * @param cls closure (set from #GNUNET_CADET_connect)
- * @param channel connection to the other end (henceforth invalid)
- * @param channel_ctx place where local state associated
- * with the channel is stored
+ * @param cls Channel closure.
+ * @param channel Connection to the other end --- FIXME: drop?
+ * @param window_size New window size. If the is more messages than buffer size
+ * this value will be negative. -- FIXME: make unsigned, we never call negative?
*/
typedef void
-(GNUNET_CADET_ChannelEndHandler) (void *cls,
- const struct GNUNET_CADET_Channel *channel,
- void *channel_ctx);
+(*GNUNET_CADET_WindowSizeEventHandler) (void *cls,
+ const struct GNUNET_CADET_Channel *channel,
+ int window_size);
/**
- * Connect to the cadet service.
+ * Connect to the MQ-based cadet service.
*
* @param cfg Configuration to use.
- * @param cls Closure for the various callbacks that follow (including
- * handlers in the handlers array).
- * @param cleaner Function called when a channel is destroyed.
- * It is called immediately if #GNUNET_CADET_channel_destroy
- * is called on the channel.
- * @param handlers Callbacks for messages we care about, NULL-terminated. Each
- * one must call #GNUNET_CADET_receive_done on the channel to
- * receive the next message. Messages of a type that is not
- * in the handlers array are ignored if received.
- *
- * @return handle to the cadet service NULL on error
- * (in this case, init is never called)
+ * @return Handle to the cadet service NULL on error.
*/
struct GNUNET_CADET_Handle *
-GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
- void *cls,
- GNUNET_CADET_ChannelEndHandler cleaner,
- const struct GNUNET_CADET_MessageHandler *handlers);
+GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg);
/**
@@ -233,21 +209,29 @@ GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
void
GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle);
+
/**
- * Open a port to receive incomming channels.
+ * Open a port to receive incomming MQ-based channels.
*
* @param h CADET handle.
- * @param port Hash representing the port number.
- * @param new_channel Function called when an channel is received.
- * @param new_channel_cls Closure for @a new_channel.
- *
+ * @param port Hash identifying the port.
+ * @param connects Function called when an incoming channel is connected.
+ * @param connects_cls Closure for the @a connects handler.
+ * @param window_changes Function called when the transmit window size changes.
+ * Can be NULL.
+ * @param disconnects Function called when a channel is disconnected.
+ * @param handlers Callbacks for messages we care about, NULL-terminated.
* @return Port handle.
*/
struct GNUNET_CADET_Port *
GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h,
- const struct GNUNET_HashCode *port,
- GNUNET_CADET_InboundChannelNotificationHandler new_channel,
- void *new_channel_cls);
+ const struct GNUNET_HashCode *port,
+ GNUNET_CADET_ConnectEventHandler connects,
+ void *connects_cls,
+ GNUNET_CADET_WindowSizeEventHandler window_changes,
+ GNUNET_CADET_DisconnectEventHandler disconnects,
+ const struct GNUNET_MQ_MessageHandler *handlers);
+
/**
* Close a port opened with @a GNUNET_CADET_open_port.
@@ -258,27 +242,38 @@ GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h,
void
GNUNET_CADET_close_port (struct GNUNET_CADET_Port *p);
+
/**
* Create a new channel towards a remote peer.
*
* If the destination port is not open by any peer or the destination peer
- * does not accept the channel, #GNUNET_CADET_ChannelEndHandler will be called
+ * does not accept the channel, @a disconnects will be called
* for this channel.
*
- * @param h cadet handle
- * @param channel_ctx client's channel context to associate with the channel
- * @param peer peer identity the channel should go to
- * @param port Port hash (port number).
+ * @param h CADET handle.
+ * @param channel_cls Closure for the channel. It's given to:
+ * - The management handler @a window_changes.
+ * - The disconnect handler @a disconnects
+ * - Each message type callback in @a handlers
+ * @param destination Peer identity the channel should go to.
+ * @param port Identification of the destination port.
* @param options CadetOption flag field, with all desired option bits set to 1.
- *
- * @return handle to the channel
+ * @param window_changes Function called when the transmit window size changes.
+ * Can be NULL if this data is of no interest.
+ * TODO Not yet implemented.
+ * @param disconnects Function called when the channel is disconnected.
+ * @param handlers Callbacks for messages we care about, NULL-terminated.
+ * @return Handle to the channel.
*/
struct GNUNET_CADET_Channel *
GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h,
- void *channel_ctx,
- const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_HashCode *port,
- enum GNUNET_CADET_ChannelOption options);
+ void *channel_cls,
+ const struct GNUNET_PeerIdentity *destination,
+ const struct GNUNET_HashCode *port,
+ enum GNUNET_CADET_ChannelOption options,
+ GNUNET_CADET_WindowSizeEventHandler window_changes,
+ GNUNET_CADET_DisconnectEventHandler disconnects,
+ const struct GNUNET_MQ_MessageHandler *handlers);
/**
@@ -295,6 +290,52 @@ GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel);
/**
+ * Obtain the message queue for a connected channel.
+ *
+ * @param channel The channel handle from which to get the MQ.
+ * @return The message queue of the channel.
+ */
+struct GNUNET_MQ_Handle *
+GNUNET_CADET_get_mq (const struct GNUNET_CADET_Channel *channel);
+
+
+/**
+ * Indicate readiness to receive the next message on a channel.
+ *
+ * Should only be called once per handler called.
+ *
+ * @param channel Channel that will be allowed to call another handler.
+ */
+void
+GNUNET_CADET_receive_done (struct GNUNET_CADET_Channel *channel);
+
+
+/******************************************************************************/
+/******************** MONITORING /DEBUG API *************************/
+/******************************************************************************/
+/* The following calls are not useful for normal CADET operation, but for */
+/* debug and monitoring of the cadet state. They can be safely ignored. */
+/* The API can change at any point without notice. */
+/* Please contact the developer if you consider any of this calls useful for */
+/* normal cadet applications. */
+/******************************************************************************/
+
+
+/**
+ * Transitional function to convert an unsigned int port to a hash value.
+ * WARNING: local static value returned, NOT reentrant!
+ * WARNING: do not use this function for new code!
+ *
+ * @param port Numerical port (unsigned int format).
+ *
+ * @return A GNUNET_HashCode usable for the new CADET API.
+ */
+const struct GNUNET_HashCode *
+GC_u2h (uint32_t port);
+
+
+
+/**
* Struct to retrieve info about a channel.
*/
union GNUNET_CADET_ChannelInfo
@@ -327,76 +368,6 @@ GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel,
/**
- * Handle for a transmission request.
- */
-struct GNUNET_CADET_TransmitHandle;
-
-
-/**
- * Ask the cadet to call @a notify once it is ready to transmit the
- * given number of bytes to the specified channel.
- * Only one call can be active at any time, to issue another request,
- * wait for the callback or cancel the current request.
- *
- * @param channel channel to use for transmission
- * @param cork is corking allowed for this transmission?
- * @param maxdelay how long can the message wait?
- * @param notify_size how many bytes of buffer space does notify want?
- * @param notify function to call when buffer space is available;
- * will be called with NULL on timeout or if the overall queue
- * for this peer is larger than queue_size and this is currently
- * the message with the lowest priority
- * @param notify_cls closure for @a notify
- * @return non-NULL if the notify callback was queued,
- * NULL if we can not even queue the request (insufficient
- * memory); if NULL is returned, @a notify will NOT be called.
- */
-struct GNUNET_CADET_TransmitHandle *
-GNUNET_CADET_notify_transmit_ready (struct GNUNET_CADET_Channel *channel,
- int cork,
- struct GNUNET_TIME_Relative maxdelay,
- size_t notify_size,
- GNUNET_CONNECTION_TransmitReadyNotify notify,
- void *notify_cls);
-
-
-/**
- * Cancel the specified transmission-ready notification.
- *
- * #DEPRECATED
- * Since soon we will send immediately with mq (via request_data),
- * there will be time or need to cancel a "pending" transmission.
- *
- * @param th handle that was returned by "notify_transmit_ready".
- */
-void
-GNUNET_CADET_notify_transmit_ready_cancel (struct GNUNET_CADET_TransmitHandle *th);
-
-
-/**
- * Indicate readiness to receive the next message on a channel.
- *
- * Should only be called once per handler called.
- *
- * @param channel Channel that will be allowed to call another handler.
- */
-void
-GNUNET_CADET_receive_done (struct GNUNET_CADET_Channel *channel);
-
-
-
-/******************************************************************************/
-/******************** MONITORING /DEBUG API *************************/
-/******************************************************************************/
-/* The following calls are not useful for normal CADET operation, but for */
-/* debug and monitoring of the cadet state. They can be safely ignored. */
-/* The API can change at any point without notice. */
-/* Please contact the developer if you consider any of this calls useful for */
-/* normal cadet applications. */
-/******************************************************************************/
-
-
-/**
* Method called to retrieve information about a specific channel the cadet peer
* is aware of, including all transit nodes.
*
@@ -482,33 +453,6 @@ typedef void
/**
- * Hash uniquely identifying a connection below a tunnel.
- */
-struct GNUNET_CADET_ConnectionTunnelIdentifier
-{
- struct GNUNET_ShortHashCode connection_of_tunnel;
-};
-
-
-/**
- * Number identifying a CADET channel within a tunnel.
- */
-struct GNUNET_CADET_ChannelTunnelNumber
-{
- /**
- * Which number does this channel have that uniquely identfies
- * it within its tunnel, in network byte order.
- *
- * Given two peers, both may initiate channels over the same tunnel.
- * The @e cn must be greater or equal to 0x80000000 (high-bit set)
- * for tunnels initiated with the peer that has the larger peer
- * identity as compared using #GNUNET_CRYPTO_cmp_peer_identity().
- */
- uint32_t cn GNUNET_PACKED;
-};
-
-
-/**
* Method called to retrieve information about a specific tunnel the cadet peer
* has established, o`r is trying to establish.
*
@@ -667,169 +611,6 @@ GNUNET_CADET_get_tunnel (struct GNUNET_CADET_Handle *h,
void *callback_cls);
-/**
- * Create a message queue for a cadet channel.
- * The message queue can only be used to transmit messages,
- * not to receive them.
- *
- * @param channel the channel to create the message qeue for
- * @return a message queue to messages over the channel
- */
-struct GNUNET_MQ_Handle *
-GNUNET_CADET_mq_create (struct GNUNET_CADET_Channel *channel);
-
-
-/**
- * Transitional function to convert an unsigned int port to a hash value.
- * WARNING: local static value returned, NOT reentrant!
- * WARNING: do not use this function for new code!
- *
- * @param port Numerical port (unsigned int format).
- *
- * @return A GNUNET_HashCode usable for the new CADET API.
- */
-const struct GNUNET_HashCode *
-GC_u2h (uint32_t port);
-
-
-/******************************************************************************/
-/******************************* MQ-BASED API *********************************/
-/******************************************************************************/
-
-/**
- * Method called whenever a peer connects to a port in MQ-based CADET.
- *
- * @param cls Closure from #GNUNET_CADET_open_porT.
- * @param channel New handle to the channel.
- * @param source Peer that started this channel.
- * @return Closure for the incoming @a channel. It's given to:
- * - The #GNUNET_CADET_DisconnectEventHandler (given to
- * #GNUNET_CADET_open_porT) when the channel dies.
- * - Each the #GNUNET_MQ_MessageCallback handlers for each message
- * received on the @a channel.
- */
-typedef void *
-(*GNUNET_CADET_ConnectEventHandler) (void *cls,
- struct GNUNET_CADET_Channel *channel,
- const struct GNUNET_PeerIdentity *source);
-
-
-/**
- * Function called whenever an MQ-channel is destroyed, even if the destruction
- * was requested by #GNUNET_CADET_channel_destroy.
- * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
- *
- * It should clean up any associated state, including cancelling any pending
- * transmission on this channel.
- *
- * @param cls Channel closure.
- * @param channel Connection to the other end (henceforth invalid).
- */
-typedef void
-(*GNUNET_CADET_DisconnectEventHandler) (void *cls,
- const struct GNUNET_CADET_Channel *channel);
-
-
-/**
- * Function called whenever an MQ-channel's transmission window size changes.
- *
- * The first callback in an outgoing channel will be with a non-zero value
- * and will mean the channel is connected to the destination.
- *
- * For an incoming channel it will be called immediately after the
- * #GNUNET_CADET_ConnectEventHandler, also with a non-zero value.
- *
- * @param cls Channel closure.
- * @param channel Connection to the other end --- FIXME: drop?
- * @param window_size New window size. If the is more messages than buffer size
- * this value will be negative. -- FIXME: make unsigned, we never call negative?
- */
-typedef void
-(*GNUNET_CADET_WindowSizeEventHandler) (void *cls,
- const struct GNUNET_CADET_Channel *channel,
- int window_size);
-
-
-/**
- * Connect to the MQ-based cadet service.
- *
- * @param cfg Configuration to use.
- * @return Handle to the cadet service NULL on error.
- */
-struct GNUNET_CADET_Handle *
-GNUNET_CADET_connecT (const struct GNUNET_CONFIGURATION_Handle *cfg);
-
-
-/**
- * Open a port to receive incomming MQ-based channels.
- *
- * @param h CADET handle.
- * @param port Hash identifying the port.
- * @param connects Function called when an incoming channel is connected.
- * @param connects_cls Closure for the @a connects handler.
- * @param window_changes Function called when the transmit window size changes.
- * Can be NULL.
- * @param disconnects Function called when a channel is disconnected.
- * @param handlers Callbacks for messages we care about, NULL-terminated.
- * @return Port handle.
- */
-struct GNUNET_CADET_Port *
-GNUNET_CADET_open_porT (struct GNUNET_CADET_Handle *h,
- const struct GNUNET_HashCode *port,
- GNUNET_CADET_ConnectEventHandler connects,
- void *connects_cls,
- GNUNET_CADET_WindowSizeEventHandler window_changes,
- GNUNET_CADET_DisconnectEventHandler disconnects,
- const struct GNUNET_MQ_MessageHandler *handlers);
-
-/**
- * Create a new channel towards a remote peer.
- *
- * If the destination port is not open by any peer or the destination peer
- * does not accept the channel, #GNUNET_CADET_ChannelEndHandler will be called
- * for this channel.
- *
- * @param h CADET handle.
- * @param channel_cls Closure for the channel. It's given to:
- * - The management handler @a window_changes.
- * - The disconnect handler @a disconnects
- * - Each message type callback in @a handlers
- * @param destination Peer identity the channel should go to.
- * @param port Identification of the destination port.
- * @param options CadetOption flag field, with all desired option bits set to 1.
- * @param window_changes Function called when the transmit window size changes.
- * Can be NULL if this data is of no interest.
- * TODO Not yet implemented.
- * @param disconnects Function called when the channel is disconnected.
- * @param handlers Callbacks for messages we care about, NULL-terminated.
- * @return Handle to the channel.
- */
-struct GNUNET_CADET_Channel *
-GNUNET_CADET_channel_creatE (struct GNUNET_CADET_Handle *h,
- void *channel_cls,
- const struct GNUNET_PeerIdentity *destination,
- const struct GNUNET_HashCode *port,
- enum GNUNET_CADET_ChannelOption options,
- GNUNET_CADET_WindowSizeEventHandler window_changes,
- GNUNET_CADET_DisconnectEventHandler disconnects,
- const struct GNUNET_MQ_MessageHandler *handlers);
-
-
-/**
- * Obtain the message queue for a connected channel.
- *
- * @param channel The channel handle from which to get the MQ.
- * @return The message queue of the channel.
- */
-struct GNUNET_MQ_Handle *
-GNUNET_CADET_get_mq (const struct GNUNET_CADET_Channel *channel);
-
-
-/******************************************************************************/
-/******************************* MQ-BASED API *********************************/
-/******************************************************************************/
-
-
#if 0 /* keep Emacsens' auto-indent happy */
{
diff --git a/src/include/gnunet_datastore_service.h b/src/include/gnunet_datastore_service.h
index f594d8fa61..2335986671 100644
--- a/src/include/gnunet_datastore_service.h
+++ b/src/include/gnunet_datastore_service.h
@@ -201,33 +201,6 @@ GNUNET_DATASTORE_release_reserve (struct GNUNET_DATASTORE_Handle *h,
/**
- * Update a value in the datastore.
- *
- * @param h handle to the datastore
- * @param uid identifier for the value
- * @param priority how much to increase the priority of the value
- * @param expiration new expiration value should be MAX of existing and this argument
- * @param queue_priority ranking of this request in the priority queue
- * @param max_queue_size at what queue size should this request be dropped
- * (if other requests of higher priority are in the queue)
- * @param cont continuation to call when done
- * @param cont_cls closure for @a cont
- * @return NULL if the entry was not queued, otherwise a handle that can be used to
- * cancel; note that even if NULL is returned, the callback will be invoked
- * (or rather, will already have been invoked)
- */
-struct GNUNET_DATASTORE_QueueEntry *
-GNUNET_DATASTORE_update (struct GNUNET_DATASTORE_Handle *h,
- uint64_t uid,
- uint32_t priority,
- struct GNUNET_TIME_Absolute expiration,
- unsigned int queue_priority,
- unsigned int max_queue_size,
- GNUNET_DATASTORE_ContinuationWithStatus cont,
- void *cont_cls);
-
-
-/**
* Explicitly remove some content from the database. @a cont will be
* called with status #GNUNET_OK if content was removed, #GNUNET_NO if
* no matching entry was found and #GNUNET_SYSERR on all other types
diff --git a/src/integration-tests/confs/test_defaults.conf b/src/integration-tests/confs/test_defaults.conf
index 8d3356cbc7..1be5826507 100644
--- a/src/integration-tests/confs/test_defaults.conf
+++ b/src/integration-tests/confs/test_defaults.conf
@@ -1,5 +1,5 @@
-@INLINE@ ../../contrib/no_forcestart.conf
-@INLINE@ ../../contrib/no_autostart_above_core.conf
+@INLINE@ ../../../contrib/no_forcestart.conf
+@INLINE@ ../../../contrib/no_autostart_above_core.conf
[fs]
FORCESTART = YES
diff --git a/src/multicast/Makefile.am b/src/multicast/Makefile.am
index f599cf66b7..2a00a7a027 100644
--- a/src/multicast/Makefile.am
+++ b/src/multicast/Makefile.am
@@ -46,7 +46,7 @@ gnunet_service_multicast_SOURCES = \
gnunet-service-multicast.c
gnunet_service_multicast_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/cadet/libgnunetcadetnew.la \
+ $(top_builddir)/src/cadet/libgnunetcadet.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(GN_LIBINTL)
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c
index b068f13083..cf39d3b22b 100644
--- a/src/multicast/gnunet-service-multicast.c
+++ b/src/multicast/gnunet-service-multicast.c
@@ -1299,7 +1299,7 @@ cadet_channel_create (struct Group *grp, struct GNUNET_PeerIdentity *peer)
GNUNET_MQ_handler_end ()
};
- chn->channel = GNUNET_CADET_channel_creatE (cadet, chn, &chn->peer,
+ chn->channel = GNUNET_CADET_channel_create (cadet, chn, &chn->peer,
&grp->cadet_port_hash,
GNUNET_CADET_OPTION_RELIABLE,
cadet_notify_window_change,
@@ -1389,7 +1389,7 @@ handle_client_origin_start (void *cls,
};
- orig->cadet_port = GNUNET_CADET_open_porT (cadet,
+ orig->cadet_port = GNUNET_CADET_open_port (cadet,
&grp->cadet_port_hash,
cadet_notify_connect,
NULL,
@@ -2082,7 +2082,7 @@ run (void *cls,
replay_req_cadet = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
replay_req_client = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
- cadet = GNUNET_CADET_connecT (cfg);
+ cadet = GNUNET_CADET_connect (cfg);
GNUNET_assert (NULL != cadet);
diff --git a/src/pt/Makefile.am b/src/pt/Makefile.am
index 7ea8257d5e..e36630ae44 100644
--- a/src/pt/Makefile.am
+++ b/src/pt/Makefile.am
@@ -25,7 +25,7 @@ gnunet_daemon_pt_SOURCES = \
gnunet-daemon-pt.c
gnunet_daemon_pt_LDADD = \
$(top_builddir)/src/vpn/libgnunetvpn.la \
- $(top_builddir)/src/cadet/libgnunetcadetnew.la \
+ $(top_builddir)/src/cadet/libgnunetcadet.la \
$(top_builddir)/src/dht/libgnunetdht.la \
$(top_builddir)/src/dns/libgnunetdns.la \
$(top_builddir)/src/dns/libgnunetdnsparser.la \
diff --git a/src/pt/gnunet-daemon-pt.c b/src/pt/gnunet-daemon-pt.c
index 9bd1fb16bb..295082c0ec 100644
--- a/src/pt/gnunet-daemon-pt.c
+++ b/src/pt/gnunet-daemon-pt.c
@@ -1084,7 +1084,7 @@ try_open_exit ()
/* move to the head of the DLL */
pos->cadet_channel
- = GNUNET_CADET_channel_creatE (cadet_handle,
+ = GNUNET_CADET_channel_create (cadet_handle,
pos,
&pos->peer,
&port,
@@ -1246,7 +1246,7 @@ run (void *cls, char *const *args GNUNET_UNUSED,
GNUNET_SCHEDULER_shutdown ();
return;
}
- cadet_handle = GNUNET_CADET_connecT (cfg);
+ cadet_handle = GNUNET_CADET_connect (cfg);
if (NULL == cadet_handle)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
diff --git a/src/rps/Makefile.am b/src/rps/Makefile.am
index de7f853c1d..e6c8cd9299 100644
--- a/src/rps/Makefile.am
+++ b/src/rps/Makefile.am
@@ -100,22 +100,28 @@ AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PAT
TESTS = $(check_PROGRAMS)
endif
-test_service_rps_view_SOURCES = gnunet-service-rps_view.h gnunet-service-rps_view.c \
- test_service_rps_view.c
+test_service_rps_view_SOURCES = \
+ gnunet-service-rps_view.h gnunet-service-rps_view.c \
+ test_service_rps_view.c
test_service_rps_view_LDADD = $(top_builddir)/src/util/libgnunetutil.la
-test_service_rps_peers_SOURCES = gnunet-service-rps_peers.h gnunet-service-rps_peers.c \
- test_service_rps_peers.c
-test_service_rps_peers_LDADD = $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/cadet/libgnunetcadet.la
-
-test_service_rps_custommap_SOURCES = gnunet-service-rps_custommap.h gnunet-service-rps_custommap.c \
- test_service_rps_custommap.c
-test_service_rps_custommap_LDADD = $(top_builddir)/src/util/libgnunetutil.la
-
-test_service_rps_sampler_elem_SOURCES = gnunet-service-rps_sampler_elem.h gnunet-service-rps_sampler_elem.c \
- rps-test_util.h rps-test_util.c \
- test_service_rps_sampler_elem.c
+test_service_rps_peers_SOURCES = \
+ gnunet-service-rps_peers.h gnunet-service-rps_peers.c \
+ test_service_rps_peers.c
+test_service_rps_peers_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/cadet/libgnunetcadet.la
+
+test_service_rps_custommap_SOURCES = \
+ gnunet-service-rps_custommap.h gnunet-service-rps_custommap.c \
+ test_service_rps_custommap.c
+test_service_rps_custommap_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la
+
+test_service_rps_sampler_elem_SOURCES = \
+ gnunet-service-rps_sampler_elem.h gnunet-service-rps_sampler_elem.c \
+ rps-test_util.h rps-test_util.c \
+ test_service_rps_sampler_elem.c
test_service_rps_sampler_elem_LDADD = $(top_builddir)/src/util/libgnunetutil.la
test_rps_malicious_1_SOURCES = $(rps_test_src)
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c
index adcfe7d02f..4a2f96123b 100644
--- a/src/rps/gnunet-service-rps.c
+++ b/src/rps/gnunet-service-rps.c
@@ -217,6 +217,11 @@ static struct GNUNET_NSE_Handle *nse;
static struct GNUNET_CADET_Handle *cadet_handle;
/**
+ * @brief Port to communicate to other peers.
+ */
+static struct GNUNET_CADET_Port *cadet_port;
+
+/**
* Handler to PEERINFO.
*/
static struct GNUNET_PEERINFO_Handle *peerinfo_handle;
@@ -838,14 +843,10 @@ clean_peer (const struct GNUNET_PeerIdentity *peer)
*/
static void
cleanup_destroyed_channel (void *cls,
- const struct GNUNET_CADET_Channel *channel,
- void *channel_ctx)
+ const struct GNUNET_CADET_Channel *channel)
{
- struct GNUNET_PeerIdentity *peer;
-
- peer = (struct GNUNET_PeerIdentity *) GNUNET_CADET_channel_get_info (
- (struct GNUNET_CADET_Channel *) channel, GNUNET_CADET_OPTION_PEER);
- // FIXME wait for cadet to change this function
+ struct GNUNET_PeerIdentity *peer = cls;
+ uint32_t *channel_flag;
if (GNUNET_NO == Peers_check_peer_known (peer))
{ /* We don't know a context to that peer */
@@ -858,7 +859,7 @@ cleanup_destroyed_channel (void *cls,
if (GNUNET_YES == Peers_check_peer_flag (peer, Peers_TO_DESTROY))
{ /* We are in the middle of removing that peer from our knowledge. In this
case simply make sure that the channels are cleaned. */
- Peers_cleanup_destroyed_channel (cls, channel, channel_ctx);
+ Peers_cleanup_destroyed_channel (cls, channel);
to_file (file_name_view_log,
"-%s\t(cleanup channel, ourself)",
GNUNET_i2s_full (peer));
@@ -872,16 +873,17 @@ cleanup_destroyed_channel (void *cls,
* - ourselves -> cleaning send channel -> clean context
* - other peer -> peer probably went down -> remove
*/
- if (GNUNET_YES == Peers_check_channel_flag (channel_ctx, Peers_CHANNEL_CLEAN))
+ channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_SENDING);
+ if (GNUNET_YES == Peers_check_channel_flag (channel_flag, Peers_CHANNEL_CLEAN))
{ /* We are about to clean the sending channel. Clean the respective
* context */
- Peers_cleanup_destroyed_channel (cls, channel, channel_ctx);
+ Peers_cleanup_destroyed_channel (cls, channel);
return;
}
else
{ /* Other peer destroyed our sending channel that he is supposed to keep
* open. It probably went down. Remove it from our knowledge. */
- Peers_cleanup_destroyed_channel (cls, channel, channel_ctx);
+ Peers_cleanup_destroyed_channel (cls, channel);
remove_peer (peer);
return;
}
@@ -893,17 +895,18 @@ cleanup_destroyed_channel (void *cls,
* - ourselves -> peer tried to establish channel twice -> clean context
* - other peer -> peer doesn't want to send us data -> clean
*/
+ channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_RECEIVING);
if (GNUNET_YES ==
- Peers_check_channel_flag (channel_ctx, Peers_CHANNEL_ESTABLISHED_TWICE))
+ Peers_check_channel_flag (channel_flag, Peers_CHANNEL_ESTABLISHED_TWICE))
{ /* Other peer tried to establish a channel to us twice. We do not accept
* that. Clean the context. */
- Peers_cleanup_destroyed_channel (cls, channel, channel_ctx);
+ Peers_cleanup_destroyed_channel (cls, channel);
return;
}
else
{ /* Other peer doesn't want to send us data anymore. We are free to clean
* it. */
- Peers_cleanup_destroyed_channel (cls, channel, channel_ctx);
+ Peers_cleanup_destroyed_channel (cls, channel);
clean_peer (peer);
return;
}
@@ -1048,7 +1051,6 @@ client_respond (void *cls,
* Handle RPS request from the client.
*
* @param cls closure
- * @param client identification of the client
* @param message the actual message
*/
static void
@@ -1100,12 +1102,11 @@ handle_client_request (void *cls,
* @brief Handle a message that requests the cancellation of a request
*
* @param cls unused
- * @param client the client that requests the cancellation
* @param message the message containing the id of the request
*/
static void
handle_client_request_cancel (void *cls,
- const struct GNUNET_RPS_CS_RequestCancelMessage *msg)
+ const struct GNUNET_RPS_CS_RequestCancelMessage *msg)
{
struct ClientContext *cli_ctx = cls;
struct ReplyCls *rep_cls;
@@ -1157,7 +1158,6 @@ check_client_seed (void *cls, const struct GNUNET_RPS_CS_SeedMessage *msg)
* Handle seed from the client.
*
* @param cls closure
- * @param client identification of the client
* @param message the actual message
*/
static void
@@ -1172,7 +1172,7 @@ handle_client_seed (void *cls,
num_peers = ntohl (msg->num_peers);
peers = (struct GNUNET_PeerIdentity *) &msg[1];
//peers = GNUNET_new_array (num_peers, struct GNUNET_PeerIdentity);
- //GNUNET_memcpy (peers, &in_msg[1], num_peers * sizeof (struct GNUNET_PeerIdentity));
+ //GNUNET_memcpy (peers, &msg[1], num_peers * sizeof (struct GNUNET_PeerIdentity));
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Client seeded peers:\n");
@@ -1200,18 +1200,15 @@ handle_client_seed (void *cls,
* the channel is blocked for all other communication.
*
* @param cls Closure
- * @param channel The channel the CHECK was received over
- * @param channel_ctx The context associated with this channel
* @param msg The message header
*/
-static int
+static void
handle_peer_check (void *cls,
- struct GNUNET_CADET_Channel *channel,
- void **channel_ctx,
- const struct GNUNET_MessageHeader *msg)
+ const struct GNUNET_MessageHeader *msg)
{
- GNUNET_CADET_receive_done (channel);
- return GNUNET_OK;
+ const struct GNUNET_PeerIdentity *peer = cls;
+
+ GNUNET_CADET_receive_done (Peers_get_recv_channel (peer));
}
/**
@@ -1221,24 +1218,16 @@ handle_peer_check (void *cls,
* in the temporary list for pushed PeerIDs.
*
* @param cls Closure
- * @param channel The channel the PUSH was received over
- * @param channel_ctx The context associated with this channel
* @param msg The message header
*/
-static int
+static void
handle_peer_push (void *cls,
- struct GNUNET_CADET_Channel *channel,
- void **channel_ctx,
- const struct GNUNET_MessageHeader *msg)
+ const struct GNUNET_MessageHeader *msg)
{
- const struct GNUNET_PeerIdentity *peer;
+ const struct GNUNET_PeerIdentity *peer = cls;
// (check the proof of work (?))
- peer = (const struct GNUNET_PeerIdentity *)
- GNUNET_CADET_channel_get_info (channel, GNUNET_CADET_OPTION_PEER);
- // FIXME wait for cadet to change this function
-
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Received PUSH (%s)\n",
GNUNET_i2s (peer));
@@ -1261,23 +1250,20 @@ handle_peer_push (void *cls,
tmp_att_peer);
add_peer_array_to_set (peer, 1, att_peer_set);
}
- GNUNET_CADET_receive_done (channel);
- return GNUNET_OK;
+ GNUNET_CADET_receive_done (Peers_get_recv_channel (peer));
}
else if (2 == mal_type)
{ /* We attack one single well-known peer - simply ignore */
- GNUNET_CADET_receive_done (channel);
- return GNUNET_OK;
+ GNUNET_CADET_receive_done (Peers_get_recv_channel (peer));
}
#endif /* ENABLE_MALICIOUS */
/* Add the sending peer to the push_map */
CustomPeerMap_put (push_map, peer);
- GNUNET_CADET_receive_done (channel);
- return GNUNET_OK;
+ GNUNET_CADET_receive_done (Peers_get_recv_channel (peer));
}
@@ -1287,24 +1273,15 @@ handle_peer_push (void *cls,
* Reply with the view of PeerIDs.
*
* @param cls Closure
- * @param channel The channel the PULL REQUEST was received over
- * @param channel_ctx The context associated with this channel
* @param msg The message header
*/
-static int
+static void
handle_peer_pull_request (void *cls,
- struct GNUNET_CADET_Channel *channel,
- void **channel_ctx,
- const struct GNUNET_MessageHeader *msg)
+ const struct GNUNET_MessageHeader *msg)
{
- struct GNUNET_PeerIdentity *peer;
+ struct GNUNET_PeerIdentity *peer = cls;
const struct GNUNET_PeerIdentity *view_array;
- peer = (struct GNUNET_PeerIdentity *)
- GNUNET_CADET_channel_get_info (channel,
- GNUNET_CADET_OPTION_PEER);
- // FIXME wait for cadet to change this function
-
LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REQUEST (%s)\n", GNUNET_i2s (peer));
#ifdef ENABLE_MALICIOUS
@@ -1312,8 +1289,7 @@ handle_peer_pull_request (void *cls,
|| 3 == mal_type)
{ /* Try to maximise representation */
send_pull_reply (peer, mal_peers, num_mal_peers);
- GNUNET_CADET_receive_done (channel);
- return GNUNET_OK;
+ GNUNET_CADET_receive_done (Peers_get_recv_channel (peer));
}
else if (2 == mal_type)
@@ -1322,101 +1298,93 @@ handle_peer_pull_request (void *cls,
{
send_pull_reply (peer, mal_peers, num_mal_peers);
}
- GNUNET_CADET_receive_done (channel);
- return GNUNET_OK;
+ GNUNET_CADET_receive_done (Peers_get_recv_channel (peer));
}
#endif /* ENABLE_MALICIOUS */
view_array = View_get_as_array ();
-
send_pull_reply (peer, view_array, View_size ());
- GNUNET_CADET_receive_done (channel);
- return GNUNET_OK;
+ GNUNET_CADET_receive_done (Peers_get_recv_channel (peer));
}
/**
- * Handle PULL REPLY message from another peer.
- *
* Check whether we sent a corresponding request and
* whether this reply is the first one.
*
* @param cls Closure
- * @param channel The channel the PUSH was received over
- * @param channel_ctx The context associated with this channel
* @param msg The message header
*/
static int
-handle_peer_pull_reply (void *cls,
- struct GNUNET_CADET_Channel *channel,
- void **channel_ctx,
- const struct GNUNET_MessageHeader *msg)
+check_peer_pull_reply (void *cls,
+ const struct GNUNET_RPS_P2P_PullReplyMessage *msg)
{
- struct GNUNET_RPS_P2P_PullReplyMessage *in_msg;
- struct GNUNET_PeerIdentity *peers;
- struct GNUNET_PeerIdentity *sender;
- uint32_t i;
-#ifdef ENABLE_MALICIOUS
- struct AttackedPeer *tmp_att_peer;
-#endif /* ENABLE_MALICIOUS */
+ struct GNUNET_PeerIdentity *sender = cls;
- /* Check for protocol violation */
- if (sizeof (struct GNUNET_RPS_P2P_PullReplyMessage) > ntohs (msg->size))
+ if (sizeof (struct GNUNET_RPS_P2P_PullReplyMessage) > ntohs (msg->header.size))
{
GNUNET_break_op (0);
- GNUNET_CADET_receive_done (channel);
return GNUNET_SYSERR;
}
- in_msg = (struct GNUNET_RPS_P2P_PullReplyMessage *) msg;
- if ((ntohs (msg->size) - sizeof (struct GNUNET_RPS_P2P_PullReplyMessage)) /
- sizeof (struct GNUNET_PeerIdentity) != ntohl (in_msg->num_peers))
+ if ((ntohs (msg->header.size) - sizeof (struct GNUNET_RPS_P2P_PullReplyMessage)) /
+ sizeof (struct GNUNET_PeerIdentity) != ntohl (msg->num_peers))
{
LOG (GNUNET_ERROR_TYPE_ERROR,
"message says it sends %" PRIu32 " peers, have space for %lu peers\n",
- ntohl (in_msg->num_peers),
- (ntohs (msg->size) - sizeof (struct GNUNET_RPS_P2P_PullReplyMessage)) /
+ ntohl (msg->num_peers),
+ (ntohs (msg->header.size) - sizeof (struct GNUNET_RPS_P2P_PullReplyMessage)) /
sizeof (struct GNUNET_PeerIdentity));
GNUNET_break_op (0);
- GNUNET_CADET_receive_done (channel);
return GNUNET_SYSERR;
}
- // Guess simply casting isn't the nicest way...
- // FIXME wait for cadet to change this function
- sender = (struct GNUNET_PeerIdentity *)
- GNUNET_CADET_channel_get_info (channel, GNUNET_CADET_OPTION_PEER);
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REPLY (%s)\n", GNUNET_i2s (sender));
-
if (GNUNET_YES != Peers_check_peer_flag (sender, Peers_PULL_REPLY_PENDING))
{
LOG (GNUNET_ERROR_TYPE_WARNING,
"Received a pull reply from a peer we didn't request one from!\n");
- GNUNET_CADET_receive_done (channel);
GNUNET_break_op (0);
- return GNUNET_OK;
+ return GNUNET_SYSERR;
}
+ return GNUNET_OK;
+}
+
+/**
+ * Handle PULL REPLY message from another peer.
+ *
+ * @param cls Closure
+ * @param msg The message header
+ */
+static void
+handle_peer_pull_reply (void *cls,
+ const struct GNUNET_RPS_P2P_PullReplyMessage *msg)
+{
+ struct GNUNET_PeerIdentity *peers;
+ struct GNUNET_PeerIdentity *sender = cls;
+ uint32_t i;
+#ifdef ENABLE_MALICIOUS
+ struct AttackedPeer *tmp_att_peer;
+#endif /* ENABLE_MALICIOUS */
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REPLY (%s)\n", GNUNET_i2s (sender));
#ifdef ENABLE_MALICIOUS
// We shouldn't even receive pull replies as we're not sending
if (2 == mal_type)
{
- GNUNET_CADET_receive_done (channel);
- return GNUNET_OK;
+ GNUNET_CADET_receive_done (Peers_get_recv_channel (sender));
}
#endif /* ENABLE_MALICIOUS */
/* Do actual logic */
- peers = (struct GNUNET_PeerIdentity *) &in_msg[1];
+ peers = (struct GNUNET_PeerIdentity *) &msg[1];
LOG (GNUNET_ERROR_TYPE_DEBUG,
"PULL REPLY received, got following %u peers:\n",
- ntohl (in_msg->num_peers));
+ ntohl (msg->num_peers));
- for (i = 0 ; i < ntohl (in_msg->num_peers) ; i++)
+ for (i = 0; i < ntohl (msg->num_peers); i++)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
"%u. %s\n",
@@ -1466,8 +1434,7 @@ handle_peer_pull_reply (void *cls,
Peers_unset_peer_flag (sender, Peers_PULL_REPLY_PENDING);
clean_peer (sender);
- GNUNET_CADET_receive_done (channel);
- return GNUNET_OK;
+ GNUNET_CADET_receive_done (Peers_get_recv_channel (sender));
}
@@ -2273,15 +2240,24 @@ run (void *cls,
const struct GNUNET_CONFIGURATION_Handle *c,
struct GNUNET_SERVICE_Handle *service)
{
- static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = {
- {&handle_peer_check , GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE,
- sizeof (struct GNUNET_MessageHeader)},
- {&handle_peer_push , GNUNET_MESSAGE_TYPE_RPS_PP_PUSH,
- sizeof (struct GNUNET_MessageHeader)},
- {&handle_peer_pull_request, GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST,
- sizeof (struct GNUNET_MessageHeader)},
- {&handle_peer_pull_reply , GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY, 0},
- {NULL, 0, 0}
+ struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
+ GNUNET_MQ_hd_fixed_size (peer_check,
+ GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE,
+ struct GNUNET_MessageHeader,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (peer_push,
+ GNUNET_MESSAGE_TYPE_RPS_PP_PUSH,
+ struct GNUNET_MessageHeader,
+ NULL),
+ GNUNET_MQ_hd_fixed_size (peer_pull_request,
+ GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST,
+ struct GNUNET_MessageHeader,
+ NULL),
+ GNUNET_MQ_hd_var_size (peer_pull_reply,
+ GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY,
+ struct GNUNET_RPS_P2P_PullReplyMessage,
+ NULL),
+ GNUNET_MQ_handler_end ()
};
int size;
@@ -2373,21 +2349,23 @@ run (void *cls,
/* Initialise cadet */
- cadet_handle = GNUNET_CADET_connect (cfg,
- cls,
- &cleanup_destroyed_channel,
- cadet_handlers);
+ cadet_handle = GNUNET_CADET_connect (cfg);
GNUNET_assert (NULL != cadet_handle);
GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_RPS,
strlen (GNUNET_APPLICATION_PORT_RPS),
&port);
- GNUNET_CADET_open_port (cadet_handle,
- &port,
- &Peers_handle_inbound_channel, cls);
+ cadet_port = GNUNET_CADET_open_port (cadet_handle,
+ &port,
+ &Peers_handle_inbound_channel, /* Connect handler */
+ NULL, /* cls */
+ NULL, /* WindowSize handler */
+ cleanup_destroyed_channel, /* Disconnect handler */
+ cadet_handlers);
peerinfo_handle = GNUNET_PEERINFO_connect (cfg);
- Peers_initialise (fn_valid_peers, cadet_handle, &own_identity);
+ Peers_initialise (fn_valid_peers, cadet_handle, cleanup_destroyed_channel,
+ cadet_handlers, &own_identity);
GNUNET_free (fn_valid_peers);
/* Initialise sampler */
diff --git a/src/rps/gnunet-service-rps_peers.c b/src/rps/gnunet-service-rps_peers.c
index e0b278bd00..58aa84ccf5 100644
--- a/src/rps/gnunet-service-rps_peers.c
+++ b/src/rps/gnunet-service-rps_peers.c
@@ -251,6 +251,17 @@ static const struct GNUNET_PeerIdentity *own_identity;
*/
static struct GNUNET_CADET_Handle *cadet_handle;
+/**
+ * @brief Disconnect handler
+ */
+static GNUNET_CADET_DisconnectEventHandler cleanup_destroyed_channel;
+
+/**
+ * @brief cadet handlers
+ */
+static const struct GNUNET_MQ_MessageHandler *cadet_handlers;
+
+
/**
* @brief Get the #PeerContext associated with a peer
@@ -523,10 +534,13 @@ get_channel (const struct GNUNET_PeerIdentity *peer)
&port);
peer_ctx->send_channel =
GNUNET_CADET_channel_create (cadet_handle,
- peer_ctx->send_channel_flags, /* context */
+ (struct GNUNET_PeerIdentity *) peer, /* context */
peer,
&port,
- GNUNET_CADET_OPTION_RELIABLE);
+ GNUNET_CADET_OPTION_RELIABLE,
+ NULL, /* WindowSize handler */
+ cleanup_destroyed_channel, /* Disconnect handler */
+ cadet_handlers);
}
GNUNET_assert (NULL != peer_ctx->send_channel);
return peer_ctx->send_channel;
@@ -552,7 +566,7 @@ get_mq (const struct GNUNET_PeerIdentity *peer)
if (NULL == peer_ctx->mq)
{
(void) get_channel (peer);
- peer_ctx->mq = GNUNET_CADET_mq_create (peer_ctx->send_channel);
+ peer_ctx->mq = GNUNET_CADET_get_mq (peer_ctx->send_channel);
}
return peer_ctx->mq;
}
@@ -649,9 +663,7 @@ remove_pending_message (struct PendingMessage *pending_msg)
GNUNET_CONTAINER_DLL_remove (peer_ctx->pending_messages_head,
peer_ctx->pending_messages_tail,
pending_msg);
- /* FIXME We are not able to cancel messages as #GNUNET_CADET_mq_create () does
- * not set a #GNUNET_MQ_CancelImpl */
- /* GNUNET_MQ_send_cancel (peer_ctx->pending_messages_head->ev); */
+ GNUNET_MQ_send_cancel (peer_ctx->pending_messages_head->ev);
GNUNET_free (pending_msg);
}
@@ -932,15 +944,21 @@ restore_valid_peers ()
*
* @param fn_valid_peers filename of the file used to store valid peer ids
* @param cadet_h cadet handle
+ * @param disconnect_handler Disconnect handler
+ * @param c_handlers cadet handlers
* @param own_id own peer identity
*/
void
Peers_initialise (char* fn_valid_peers,
struct GNUNET_CADET_Handle *cadet_h,
+ GNUNET_CADET_DisconnectEventHandler disconnect_handler,
+ const struct GNUNET_MQ_MessageHandler *c_handlers,
const struct GNUNET_PeerIdentity *own_id)
{
filename_valid_peers = GNUNET_strdup (fn_valid_peers);
cadet_handle = cadet_h;
+ cleanup_destroyed_channel = disconnect_handler;
+ cadet_handlers = c_handlers;
own_identity = own_id;
peer_map = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO);
valid_peers = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO);
@@ -1279,6 +1297,34 @@ Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags
return check_channel_flag_set (channel_flags, flags);
}
+/**
+ * @brief Get the flags for the channel in @a role for @a peer.
+ *
+ * @param peer Peer to get the channel flags for.
+ * @param role Role of channel to get flags for
+ *
+ * @return The flags.
+ */
+uint32_t *
+Peers_get_channel_flag (const struct GNUNET_PeerIdentity *peer,
+ enum Peers_ChannelRole role)
+{
+ const struct PeerContext *peer_ctx;
+
+ peer_ctx = get_peer_ctx (peer);
+ if (Peers_CHANNEL_ROLE_SENDING == role)
+ {
+ return peer_ctx->send_channel_flags;
+ }
+ else if (Peers_CHANNEL_ROLE_RECEIVING == role)
+ {
+ return peer_ctx->recv_channel_flags;
+ }
+ else
+ {
+ GNUNET_assert (0);
+ }
+}
/**
* @brief Check whether we have information about the given peer.
@@ -1358,8 +1404,6 @@ Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer)
* @param cls The closure
* @param channel The channel the peer wants to establish
* @param initiator The peer's peer ID
- * @param port The port the channel is being established over
- * @param options Further options
*
* @return initial channel context for the channel
* (can be NULL -- that's not an error)
@@ -1367,9 +1411,7 @@ Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer)
void *
Peers_handle_inbound_channel (void *cls,
struct GNUNET_CADET_Channel *channel,
- const struct GNUNET_PeerIdentity *initiator,
- const struct GNUNET_HashCode *port,
- enum GNUNET_CADET_ChannelOption options)
+ const struct GNUNET_PeerIdentity *initiator)
{
struct PeerContext *peer_ctx;
@@ -1387,10 +1429,10 @@ Peers_handle_inbound_channel (void *cls,
Peers_CHANNEL_ESTABLISHED_TWICE);
GNUNET_CADET_channel_destroy (channel);
/* return the channel context */
- return peer_ctx->recv_channel_flags;
+ return &peer_ctx->peer_id;
}
peer_ctx->recv_channel = channel;
- return peer_ctx->recv_channel_flags;
+ return &peer_ctx->peer_id;
}
@@ -1500,16 +1542,11 @@ Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer)
*/
void
Peers_cleanup_destroyed_channel (void *cls,
- const struct GNUNET_CADET_Channel *channel,
- void *channel_ctx)
+ const struct GNUNET_CADET_Channel *channel)
{
- struct GNUNET_PeerIdentity *peer;
+ struct GNUNET_PeerIdentity *peer = cls;
struct PeerContext *peer_ctx;
- peer = (struct GNUNET_PeerIdentity *) GNUNET_CADET_channel_get_info (
- (struct GNUNET_CADET_Channel *) channel, GNUNET_CADET_OPTION_PEER);
- // FIXME wait for cadet to change this function
-
if (GNUNET_NO == Peers_check_peer_known (peer))
{/* We don't want to implicitly create a context that we're about to kill */
LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -1635,4 +1672,23 @@ Peers_schedule_operation (const struct GNUNET_PeerIdentity *peer,
return GNUNET_NO;
}
+/**
+ * @brief Get the recv_channel of @a peer.
+ * Needed to correctly handle (call #GNUNET_CADET_receive_done()) incoming
+ * messages.
+ *
+ * @param peer The peer to get the recv_channel from.
+ *
+ * @return The recv_channel.
+ */
+struct GNUNET_CADET_Channel *
+Peers_get_recv_channel (const struct GNUNET_PeerIdentity *peer)
+{
+ struct PeerContext *peer_ctx;
+
+ GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer));
+ peer_ctx = get_peer_ctx (peer);
+ return peer_ctx->recv_channel;
+}
+
/* end of gnunet-service-rps_peers.c */
diff --git a/src/rps/gnunet-service-rps_peers.h b/src/rps/gnunet-service-rps_peers.h
index bbac860033..15970a7cee 100644
--- a/src/rps/gnunet-service-rps_peers.h
+++ b/src/rps/gnunet-service-rps_peers.h
@@ -117,11 +117,15 @@ typedef int
*
* @param fn_valid_peers filename of the file used to store valid peer ids
* @param cadet_h cadet handle
+ * @param disconnect_handler Disconnect handler
+ * @param c_handlers cadet handlers
* @param own_id own peer identity
*/
void
Peers_initialise (char* fn_valid_peers,
struct GNUNET_CADET_Handle *cadet_h,
+ GNUNET_CADET_DisconnectEventHandler disconnect_handler,
+ const struct GNUNET_MQ_MessageHandler *c_handlers,
const struct GNUNET_PeerIdentity *own_id);
/**
@@ -259,6 +263,18 @@ int
Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags);
/**
+ * @brief Get the flags for the channel in @a role for @a peer.
+ *
+ * @param peer Peer to get the channel flags for.
+ * @param role Role of channel to get flags for
+ *
+ * @return The flags.
+ */
+uint32_t *
+Peers_get_channel_flag (const struct GNUNET_PeerIdentity *peer,
+ enum Peers_ChannelRole role);
+
+/**
* @brief Check whether we have information about the given peer.
*
* FIXME probably deprecated. Make this the new _online.
@@ -312,8 +328,6 @@ Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer);
* @param cls The closure
* @param channel The channel the peer wants to establish
* @param initiator The peer's peer ID
- * @param port The port the channel is being established over
- * @param options Further options
*
* @return initial channel context for the channel
* (can be NULL -- that's not an error)
@@ -321,9 +335,7 @@ Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer);
void *
Peers_handle_inbound_channel (void *cls,
struct GNUNET_CADET_Channel *channel,
- const struct GNUNET_PeerIdentity *initiator,
- const struct GNUNET_HashCode *port,
- enum GNUNET_CADET_ChannelOption options);
+ const struct GNUNET_PeerIdentity *initiator);
/**
* @brief Check whether a sending channel towards the given peer exists
@@ -379,8 +391,7 @@ Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer);
*/
void
Peers_cleanup_destroyed_channel (void *cls,
- const struct GNUNET_CADET_Channel *channel,
- void *channel_ctx);
+ const struct GNUNET_CADET_Channel *channel);
/**
* @brief Send a message to another peer.
@@ -411,4 +422,16 @@ int
Peers_schedule_operation (const struct GNUNET_PeerIdentity *peer,
const PeerOp peer_op);
+/**
+ * @brief Get the recv_channel of @a peer.
+ * Needed to correctly handle (call #GNUNET_CADET_receive_done()) incoming
+ * messages.
+ *
+ * @param peer The peer to get the recv_channel from.
+ *
+ * @return The recv_channel.
+ */
+struct GNUNET_CADET_Channel *
+Peers_get_recv_channel (const struct GNUNET_PeerIdentity *peer);
+
/* end of gnunet-service-rps_peers.h */
diff --git a/src/rps/test_service_rps_peers.c b/src/rps/test_service_rps_peers.c
index 37ed1974c0..9cd677fef5 100644
--- a/src/rps/test_service_rps_peers.c
+++ b/src/rps/test_service_rps_peers.c
@@ -59,25 +59,25 @@ check ()
memset (&own_id, 1, sizeof (own_id));
/* Do nothing */
- Peers_initialise (FN_VALID_PEERS, NULL, &own_id);
+ Peers_initialise (FN_VALID_PEERS, NULL, NULL, NULL, &own_id);
Peers_terminate ();
/* Create peer */
- Peers_initialise (FN_VALID_PEERS, NULL, &own_id);
+ Peers_initialise (FN_VALID_PEERS, NULL, NULL, NULL, &own_id);
CHECK (GNUNET_YES == Peers_insert_peer (&k1));
Peers_terminate ();
/* Create peer */
- Peers_initialise (FN_VALID_PEERS, NULL, &own_id);
+ Peers_initialise (FN_VALID_PEERS, NULL, NULL, NULL, &own_id);
CHECK (GNUNET_YES == Peers_insert_peer (&k1));
CHECK (GNUNET_YES == Peers_remove_peer (&k1));
Peers_terminate ();
/* Insertion and Removal */
- Peers_initialise (FN_VALID_PEERS, NULL, &own_id);
+ Peers_initialise (FN_VALID_PEERS, NULL, NULL, NULL, &own_id);
CHECK (GNUNET_NO == Peers_check_peer_known (&k1));
CHECK (GNUNET_YES == Peers_insert_peer (&k1));
diff --git a/src/scalarproduct/Makefile.am b/src/scalarproduct/Makefile.am
index 98829408af..10e04284f1 100644
--- a/src/scalarproduct/Makefile.am
+++ b/src/scalarproduct/Makefile.am
@@ -42,7 +42,7 @@ gnunet_service_scalarproduct_alice_SOURCES = \
gnunet-service-scalarproduct_alice.c
gnunet_service_scalarproduct_alice_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/cadet/libgnunetcadetnew.la \
+ $(top_builddir)/src/cadet/libgnunetcadet.la \
$(top_builddir)/src/set/libgnunetset.la \
$(LIBGCRYPT_LIBS) \
-lgcrypt \
@@ -53,7 +53,7 @@ gnunet_service_scalarproduct_bob_SOURCES = \
gnunet-service-scalarproduct_bob.c
gnunet_service_scalarproduct_bob_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/cadet/libgnunetcadetnew.la \
+ $(top_builddir)/src/cadet/libgnunetcadet.la \
$(top_builddir)/src/set/libgnunetset.la \
$(LIBGCRYPT_LIBS) \
-lgcrypt \
@@ -64,7 +64,7 @@ gnunet_service_scalarproduct_ecc_alice_SOURCES = \
gnunet-service-scalarproduct-ecc_alice.c
gnunet_service_scalarproduct_ecc_alice_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/cadet/libgnunetcadetnew.la \
+ $(top_builddir)/src/cadet/libgnunetcadet.la \
$(top_builddir)/src/set/libgnunetset.la \
$(LIBGCRYPT_LIBS) \
-lgcrypt \
@@ -75,7 +75,7 @@ gnunet_service_scalarproduct_ecc_bob_SOURCES = \
gnunet-service-scalarproduct-ecc_bob.c
gnunet_service_scalarproduct_ecc_bob_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/cadet/libgnunetcadetnew.la \
+ $(top_builddir)/src/cadet/libgnunetcadet.la \
$(top_builddir)/src/set/libgnunetset.la \
$(LIBGCRYPT_LIBS) \
-lgcrypt \
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
index ca92fb9ead..c0b33f8efe 100644
--- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
+++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
@@ -842,7 +842,7 @@ client_request_complete_alice (struct AliceServiceSession *s)
"Creating new channel for session with key %s.\n",
GNUNET_h2s (&s->session_id));
s->channel
- = GNUNET_CADET_channel_creatE (my_cadet,
+ = GNUNET_CADET_channel_create (my_cadet,
s,
&s->peer,
&s->session_id,
@@ -1173,7 +1173,7 @@ run (void *cls,
GNUNET_CRYPTO_ecc_rnd_mpi (edc,
&my_privkey,
&my_privkey_inv);
- my_cadet = GNUNET_CADET_connecT (cfg);
+ my_cadet = GNUNET_CADET_connect (cfg);
if (NULL == my_cadet)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
index 3851ca7634..0b0333332a 100644
--- a/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
+++ b/src/scalarproduct/gnunet-service-scalarproduct-ecc_bob.c
@@ -950,7 +950,7 @@ handle_bob_client_message (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received client request, opening port %s!\n",
GNUNET_h2s (&msg->session_key));
- s->port = GNUNET_CADET_open_porT (my_cadet,
+ s->port = GNUNET_CADET_open_port (my_cadet,
&msg->session_key,
&cb_channel_incoming,
s,
@@ -1054,7 +1054,7 @@ run (void *cls,
/* We don't really do DLOG, so we can setup with very minimal resources */
edc = GNUNET_CRYPTO_ecc_dlog_prepare (4 /* max value */,
2 /* RAM */);
- my_cadet = GNUNET_CADET_connecT (cfg);
+ my_cadet = GNUNET_CADET_connect (cfg);
GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
NULL);
if (NULL == my_cadet)
diff --git a/src/scalarproduct/gnunet-service-scalarproduct_alice.c b/src/scalarproduct/gnunet-service-scalarproduct_alice.c
index 6d7a0a3b84..a55d039009 100644
--- a/src/scalarproduct/gnunet-service-scalarproduct_alice.c
+++ b/src/scalarproduct/gnunet-service-scalarproduct_alice.c
@@ -1076,7 +1076,7 @@ client_request_complete_alice (struct AliceServiceSession *s)
"Creating new channel for session with key %s.\n",
GNUNET_h2s (&s->session_id));
s->channel
- = GNUNET_CADET_channel_creatE (my_cadet,
+ = GNUNET_CADET_channel_create (my_cadet,
s,
&s->peer,
&s->session_id,
@@ -1398,7 +1398,7 @@ run (void *cls,
GNUNET_CRYPTO_PAILLIER_BITS / 3);
GNUNET_CRYPTO_paillier_create (&my_pubkey,
&my_privkey);
- my_cadet = GNUNET_CADET_connecT (cfg);
+ my_cadet = GNUNET_CADET_connect (cfg);
GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
NULL);
if (NULL == my_cadet)
diff --git a/src/scalarproduct/gnunet-service-scalarproduct_bob.c b/src/scalarproduct/gnunet-service-scalarproduct_bob.c
index f3b5327f1d..0c38cb4269 100644
--- a/src/scalarproduct/gnunet-service-scalarproduct_bob.c
+++ b/src/scalarproduct/gnunet-service-scalarproduct_bob.c
@@ -1230,7 +1230,7 @@ handle_bob_client_message (void *cls,
}
GNUNET_SERVICE_client_continue (s->client);
/* We're ready, open the port */
- s->port = GNUNET_CADET_open_porT (my_cadet,
+ s->port = GNUNET_CADET_open_port (my_cadet,
&msg->session_key,
&cb_channel_incoming,
s,
@@ -1336,7 +1336,7 @@ run (void *cls,
GNUNET_CRYPTO_paillier_create (&my_pubkey,
&my_privkey);
- my_cadet = GNUNET_CADET_connecT (cfg);
+ my_cadet = GNUNET_CADET_connect (cfg);
GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
NULL);
if (NULL == my_cadet)
diff --git a/src/set/Makefile.am b/src/set/Makefile.am
index 03c258352c..14667d0ef9 100644
--- a/src/set/Makefile.am
+++ b/src/set/Makefile.am
@@ -60,7 +60,7 @@ gnunet_service_set_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/core/libgnunetcore.la \
- $(top_builddir)/src/cadet/libgnunetcadetnew.la \
+ $(top_builddir)/src/cadet/libgnunetcadet.la \
$(top_builddir)/src/block/libgnunetblock.la \
libgnunetset.la \
$(GN_LIBINTL)
diff --git a/src/set/gnunet-service-set.c b/src/set/gnunet-service-set.c
index 8f1506c6ab..12af653c1b 100644
--- a/src/set/gnunet-service-set.c
+++ b/src/set/gnunet-service-set.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet
- Copyright (C) 2013, 2014, 2017 GNUnet e.V.
+ Copyright (C) 2013-2017 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -35,6 +35,35 @@
*/
#define INCOMING_CHANNEL_TIMEOUT GNUNET_TIME_UNIT_MINUTES
+
+/**
+ * Lazy copy requests made by a client.
+ */
+struct LazyCopyRequest
+{
+ /**
+ * Kept in a DLL.
+ */
+ struct LazyCopyRequest *prev;
+
+ /**
+ * Kept in a DLL.
+ */
+ struct LazyCopyRequest *next;
+
+ /**
+ * Which set are we supposed to copy?
+ */
+ struct Set *source_set;
+
+ /**
+ * Cookie identifying the request.
+ */
+ uint32_t cookie;
+
+};
+
+
/**
* A listener is inhabited by a client, and waits for evaluation
* requests from remote peers.
@@ -52,21 +81,24 @@ struct Listener
struct Listener *prev;
/**
- * Client that owns the listener.
- * Only one client may own a listener.
+ * Head of DLL of operations this listener is responsible for.
+ * Once the client has accepted/declined the operation, the
+ * operation is moved to the respective set's operation DLLS.
*/
- struct GNUNET_SERVICE_Client *client;
+ struct Operation *op_head;
/**
- * Message queue for the client
+ * Tail of DLL of operations this listener is responsible for.
+ * Once the client has accepted/declined the operation, the
+ * operation is moved to the respective set's operation DLLS.
*/
- struct GNUNET_MQ_Handle *client_mq;
+ struct Operation *op_tail;
/**
- * Application ID for the operation, used to distinguish
- * multiple operations of the same type with the same peer.
+ * Client that owns the listener.
+ * Only one client may own a listener.
*/
- struct GNUNET_HashCode app_id;
+ struct ClientState *cs;
/**
* The port we are listening on with CADET.
@@ -74,27 +106,18 @@ struct Listener
struct GNUNET_CADET_Port *open_port;
/**
+ * Application ID for the operation, used to distinguish
+ * multiple operations of the same type with the same peer.
+ */
+ struct GNUNET_HashCode app_id;
+
+ /**
* The type of the operation.
*/
enum GNUNET_SET_OperationType operation;
};
-struct LazyCopyRequest
-{
- struct Set *source_set;
- uint32_t cookie;
-
- struct LazyCopyRequest *prev;
- struct LazyCopyRequest *next;
-};
-
-
-/**
- * Configuration of our local peer.
- */
-static const struct GNUNET_CONFIGURATION_Handle *configuration;
-
/**
* Handle to the cadet service, used to listen for and connect to
* remote peers.
@@ -102,96 +125,48 @@ static const struct GNUNET_CONFIGURATION_Handle *configuration;
static struct GNUNET_CADET_Handle *cadet;
/**
- * Sets are held in a doubly linked list.
+ * DLL of lazy copy requests by this client.
*/
-static struct Set *sets_head;
+static struct LazyCopyRequest *lazy_copy_head;
/**
- * Sets are held in a doubly linked list.
+ * DLL of lazy copy requests by this client.
*/
-static struct Set *sets_tail;
+static struct LazyCopyRequest *lazy_copy_tail;
/**
- * Listeners are held in a doubly linked list.
+ * Generator for unique cookie we set per lazy copy request.
*/
-static struct Listener *listeners_head;
+static uint32_t lazy_copy_cookie;
/**
- * Listeners are held in a doubly linked list.
+ * Statistics handle.
*/
-static struct Listener *listeners_tail;
+struct GNUNET_STATISTICS_Handle *_GSS_statistics;
/**
- * Incoming sockets from remote peers are held in a doubly linked
- * list.
+ * Listeners are held in a doubly linked list.
*/
-static struct Operation *incoming_head;
+static struct Listener *listener_head;
/**
- * Incoming sockets from remote peers are held in a doubly linked
- * list.
+ * Listeners are held in a doubly linked list.
*/
-static struct Operation *incoming_tail;
-
-static struct LazyCopyRequest *lazy_copy_head;
-static struct LazyCopyRequest *lazy_copy_tail;
-
-static uint32_t lazy_copy_cookie = 1;
+static struct Listener *listener_tail;
/**
* Counter for allocating unique IDs for clients, used to identify
* incoming operation requests from remote peers, that the client can
- * choose to accept or refuse.
- */
-static uint32_t suggest_id = 1;
-
-/**
- * Statistics handle.
- */
-struct GNUNET_STATISTICS_Handle *_GSS_statistics;
-
-
-/**
- * Get set that is owned by the given client, if any.
- *
- * @param client client to look for
- * @return set that the client owns, NULL if the client
- * does not own a set
- */
-static struct Set *
-set_get (struct GNUNET_SERVICE_Client *client)
-{
- struct Set *set;
-
- for (set = sets_head; NULL != set; set = set->next)
- if (set->client == client)
- return set;
- return NULL;
-}
-
-
-/**
- * Get the listener associated with the given client, if any.
- *
- * @param client the client
- * @return listener associated with the client, NULL
- * if there isn't any
+ * choose to accept or refuse. 0 must not be used (reserved for
+ * uninitialized).
*/
-static struct Listener *
-listener_get (struct GNUNET_SERVICE_Client *client)
-{
- struct Listener *listener;
-
- for (listener = listeners_head; NULL != listener; listener = listener->next)
- if (listener->client == client)
- return listener;
- return NULL;
-}
+static uint32_t suggest_id;
/**
* Get the incoming socket associated with the given id.
*
+ * @param listener the listener to look in
* @param id id to look for
* @return the incoming socket associated with the id,
* or NULL if there is none
@@ -199,46 +174,49 @@ listener_get (struct GNUNET_SERVICE_Client *client)
static struct Operation *
get_incoming (uint32_t id)
{
- struct Operation *op;
-
- for (op = incoming_head; NULL != op; op = op->next)
- if (op->suggest_id == id)
- {
- GNUNET_assert (GNUNET_YES == op->is_incoming);
- return op;
- }
+ for (struct Listener *listener = listener_head;
+ NULL != listener;
+ listener = listener->next)
+ {
+ for (struct Operation *op = listener->op_head; NULL != op; op = op->next)
+ if (op->suggest_id == id)
+ return op;
+ }
return NULL;
}
/**
- * Destroy a listener, free all resources associated with it.
+ * Destroy an incoming request from a remote peer
*
- * @param listener listener to destroy
+ * @param op remote request to destroy
*/
static void
-listener_destroy (struct Listener *listener)
+incoming_destroy (struct Operation *op)
{
- /* If the client is not dead yet, destroy it.
- * The client's destroy callback will destroy the listener again. */
- if (NULL != listener->client)
- {
- struct GNUNET_SERVICE_Client *client = listener->client;
-
- GNUNET_MQ_destroy (listener->client_mq);
- listener->client_mq = NULL;
+ struct Listener *listener;
+ struct GNUNET_CADET_Channel *channel;
- listener->client = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Disconnecting listener client\n");
- GNUNET_SERVICE_client_drop (client);
- return;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Destroying incoming operation %p\n",
+ op);
+ if (NULL != (listener = op->listener))
+ {
+ GNUNET_CONTAINER_DLL_remove (listener->op_head,
+ listener->op_tail,
+ op);
+ op->listener = NULL;
+ }
+ if (NULL != op->timeout_task)
+ {
+ GNUNET_SCHEDULER_cancel (op->timeout_task);
+ op->timeout_task = NULL;
+ }
+ if (NULL != (channel = op->channel))
+ {
+ op->channel = NULL;
+ GNUNET_CADET_channel_destroy (channel);
}
- GNUNET_CADET_close_port (listener->open_port);
- GNUNET_CONTAINER_DLL_remove (listeners_head,
- listeners_tail,
- listener);
- GNUNET_free (listener);
}
@@ -308,12 +286,11 @@ garbage_collect_cb (void *cls,
static void
collect_generation_garbage (struct Set *set)
{
- struct Operation *op;
struct GarbageContext gc;
gc.min_op_generation = UINT_MAX;
gc.max_op_generation = 0;
- for (op = set->ops_head; NULL != op; op = op->next)
+ for (struct Operation *op = set->ops_head; NULL != op; op = op->next)
{
gc.min_op_generation = GNUNET_MIN (gc.min_op_generation,
op->generation_created);
@@ -327,23 +304,36 @@ collect_generation_garbage (struct Set *set)
}
+/**
+ * Is @a generation in the range of exclusions?
+ *
+ * @param generation generation to query
+ * @param excluded array of generations where the element is excluded
+ * @param excluded_size length of the @a excluded array
+ * @return #GNUNET_YES if @a generation is in any of the ranges
+ */
static int
is_excluded_generation (unsigned int generation,
struct GenerationRange *excluded,
unsigned int excluded_size)
{
- unsigned int i;
-
- for (i = 0; i < excluded_size; i++)
- {
- if ( (generation >= excluded[i].start) && (generation < excluded[i].end) )
+ for (unsigned int i = 0; i < excluded_size; i++)
+ if ( (generation >= excluded[i].start) &&
+ (generation < excluded[i].end) )
return GNUNET_YES;
- }
-
return GNUNET_NO;
}
+/**
+ * Is element @a ee part of the set during @a query_generation?
+ *
+ * @param ee element to test
+ * @param query_generation generation to query
+ * @param excluded array of generations where the element is excluded
+ * @param excluded_size length of the @a excluded array
+ * @return #GNUNET_YES if the element is in the set, #GNUNET_NO if not
+ */
static int
is_element_of_generation (struct ElementEntry *ee,
unsigned int query_generation,
@@ -352,11 +342,12 @@ is_element_of_generation (struct ElementEntry *ee,
{
struct MutationEvent *mut;
int is_present;
- unsigned int i;
GNUNET_assert (NULL != ee->mutations);
-
- if (GNUNET_YES == is_excluded_generation (query_generation, excluded, excluded_size))
+ if (GNUNET_YES ==
+ is_excluded_generation (query_generation,
+ excluded,
+ excluded_size))
{
GNUNET_break (0);
return GNUNET_NO;
@@ -366,7 +357,7 @@ is_element_of_generation (struct ElementEntry *ee,
/* Could be made faster with binary search, but lists
are small, so why bother. */
- for (i = 0; i < ee->mutations_size; i++)
+ for (unsigned int i = 0; i < ee->mutations_size; i++)
{
mut = &ee->mutations[i];
@@ -378,7 +369,10 @@ is_element_of_generation (struct ElementEntry *ee,
continue;
}
- if (GNUNET_YES == is_excluded_generation (mut->generation, excluded, excluded_size))
+ if (GNUNET_YES ==
+ is_excluded_generation (mut->generation,
+ excluded,
+ excluded_size))
{
/* The generation is excluded (because it belongs to another
fork via a lazy copy) and thus mutations aren't considered
@@ -387,11 +381,12 @@ is_element_of_generation (struct ElementEntry *ee,
}
/* This would be an inconsistency in how we manage mutations. */
- if ( (GNUNET_YES == is_present) && (GNUNET_YES == mut->added) )
+ if ( (GNUNET_YES == is_present) &&
+ (GNUNET_YES == mut->added) )
GNUNET_assert (0);
-
/* Likewise. */
- if ( (GNUNET_NO == is_present) && (GNUNET_NO == mut->added) )
+ if ( (GNUNET_NO == is_present) &&
+ (GNUNET_NO == mut->added) )
GNUNET_assert (0);
is_present = mut->added;
@@ -401,44 +396,33 @@ is_element_of_generation (struct ElementEntry *ee,
}
-int
-_GSS_is_element_of_set (struct ElementEntry *ee,
- struct Set *set)
-{
- return is_element_of_generation (ee,
- set->current_generation,
- set->excluded_generations,
- set->excluded_generations_size);
-}
-
-
-static int
-is_element_of_iteration (struct ElementEntry *ee,
- struct Set *set)
-{
- return is_element_of_generation (ee,
- set->iter_generation,
- set->excluded_generations,
- set->excluded_generations_size);
-}
-
-
+/**
+ * Is element @a ee part of the set used by @a op?
+ *
+ * @param ee element to test
+ * @param op operation the defines the set and its generation
+ * @return #GNUNET_YES if the element is in the set, #GNUNET_NO if not
+ */
int
_GSS_is_element_of_operation (struct ElementEntry *ee,
struct Operation *op)
{
return is_element_of_generation (ee,
op->generation_created,
- op->spec->set->excluded_generations,
- op->spec->set->excluded_generations_size);
+ op->set->excluded_generations,
+ op->set->excluded_generations_size);
}
/**
- * Destroy the given operation. Call the implementation-specific
- * cancel function of the operation. Disconnects from the remote
- * peer. Does not disconnect the client, as there may be multiple
- * operations per set.
+ * Destroy the given operation. Used for any operation where both
+ * peers were known and that thus actually had a vt and channel. Must
+ * not be used for operations where 'listener' is still set and we do
+ * not know the other peer.
+ *
+ * Call the implementation-specific cancel function of the operation.
+ * Disconnects from the remote peer. Does not disconnect the client,
+ * as there may be multiple operations per set.
*
* @param op operation to destroy
* @param gc #GNUNET_YES to perform garbage collection on the set
@@ -447,39 +431,39 @@ void
_GSS_operation_destroy (struct Operation *op,
int gc)
{
- struct Set *set;
+ struct Set *set = op->set;
struct GNUNET_CADET_Channel *channel;
- if (NULL == op->vt)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Destroying operation %p\n",
+ op);
+ GNUNET_assert (NULL == op->listener);
+ if (NULL != op->state)
{
- /* already in #_GSS_operation_destroy() */
- return;
+ set->vt->cancel (op);
+ op->state = NULL;
}
- GNUNET_assert (GNUNET_NO == op->is_incoming);
- GNUNET_assert (NULL != op->spec);
- set = op->spec->set;
- GNUNET_CONTAINER_DLL_remove (set->ops_head,
- set->ops_tail,
- op);
- op->vt->cancel (op);
- op->vt = NULL;
- if (NULL != op->spec)
+ if (NULL != set)
{
- if (NULL != op->spec->context_msg)
- {
- GNUNET_free (op->spec->context_msg);
- op->spec->context_msg = NULL;
- }
- GNUNET_free (op->spec);
- op->spec = NULL;
+ GNUNET_CONTAINER_DLL_remove (set->ops_head,
+ set->ops_tail,
+ op);
+ op->set = NULL;
+ }
+ if (NULL != op->context_msg)
+ {
+ GNUNET_free (op->context_msg);
+ op->context_msg = NULL;
}
if (NULL != (channel = op->channel))
{
+ /* This will free op; called conditionally as this helper function
+ is also called from within the channel disconnect handler. */
op->channel = NULL;
GNUNET_CADET_channel_destroy (channel);
}
-
- if (GNUNET_YES == gc)
+ if ( (NULL != set) &&
+ (GNUNET_YES == gc) )
collect_generation_garbage (set);
/* We rely on the channel end handler to free 'op'. When 'op->channel' was NULL,
* there was a channel end handler that will free 'op' on the call stack. */
@@ -487,6 +471,28 @@ _GSS_operation_destroy (struct Operation *op,
/**
+ * Callback called when a client connects to the service.
+ *
+ * @param cls closure for the service
+ * @param c the new client that connected to the service
+ * @param mq the message queue used to send messages to the client
+ * @return @a `struct ClientState`
+ */
+static void *
+client_connect_cb (void *cls,
+ struct GNUNET_SERVICE_Client *c,
+ struct GNUNET_MQ_Handle *mq)
+{
+ struct ClientState *cs;
+
+ cs = GNUNET_new (struct ClientState);
+ cs->client = c;
+ cs->mq = mq;
+ return cs;
+}
+
+
+/**
* Iterator over hash map entries to free element entries.
*
* @param cls closure
@@ -502,66 +508,76 @@ destroy_elements_iterator (void *cls,
struct ElementEntry *ee = value;
GNUNET_free_non_null (ee->mutations);
-
GNUNET_free (ee);
return GNUNET_YES;
}
/**
- * Destroy a set, and free all resources and operations associated with it.
+ * Clean up after a client has disconnected
*
- * @param set the set to destroy
+ * @param cls closure, unused
+ * @param client the client to clean up after
+ * @param internal_cls the `struct ClientState`
*/
static void
-set_destroy (struct Set *set)
+client_disconnect_cb (void *cls,
+ struct GNUNET_SERVICE_Client *client,
+ void *internal_cls)
{
- if (NULL != set->client)
- {
- /* If the client is not dead yet, destroy it. The client's destroy
- * callback will call `set_destroy()` again in this case. We do
- * this so that the channel end handler still has a valid set handle
- * to destroy. */
- struct GNUNET_SERVICE_Client *client = set->client;
-
- set->client = NULL;
- GNUNET_SERVICE_client_drop (client);
- return;
- }
- GNUNET_assert (NULL != set->state);
- while (NULL != set->ops_head)
- _GSS_operation_destroy (set->ops_head, GNUNET_NO);
- set->vt->destroy_set (set->state);
- set->state = NULL;
- if (NULL != set->iter)
- {
- GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter);
- set->iter = NULL;
- set->iteration_id++;
- }
+ struct ClientState *cs = internal_cls;
+ struct Operation *op;
+ struct Listener *listener;
+ struct Set *set;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client disconnected, cleaning up\n");
+ if (NULL != (set = cs->set))
{
- struct SetContent *content;
+ struct SetContent *content = set->content;
struct PendingMutation *pm;
struct PendingMutation *pm_current;
+ struct LazyCopyRequest *lcr;
- content = set->content;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Destroying client's set\n");
+ /* Destroy pending set operations */
+ while (NULL != set->ops_head)
+ _GSS_operation_destroy (set->ops_head,
+ GNUNET_NO);
+
+ /* Destroy operation-specific state */
+ GNUNET_assert (NULL != set->state);
+ set->vt->destroy_set (set->state);
+ set->state = NULL;
+
+ /* Clean up ongoing iterations */
+ if (NULL != set->iter)
+ {
+ GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter);
+ set->iter = NULL;
+ set->iteration_id++;
+ }
- // discard any pending mutations that reference this set
+ /* discard any pending mutations that reference this set */
pm = content->pending_mutations_head;
while (NULL != pm)
{
pm_current = pm;
pm = pm->next;
- if (pm_current-> set == set)
+ if (pm_current->set == set)
+ {
GNUNET_CONTAINER_DLL_remove (content->pending_mutations_head,
content->pending_mutations_tail,
pm_current);
-
+ GNUNET_free (pm_current);
+ }
}
+ /* free set content (or at least decrement RC) */
set->content = NULL;
GNUNET_assert (0 != content->refcount);
- content->refcount -= 1;
+ content->refcount--;
if (0 == content->refcount)
{
GNUNET_assert (NULL != content->elements);
@@ -572,166 +588,41 @@ set_destroy (struct Set *set)
content->elements = NULL;
GNUNET_free (content);
}
- }
- GNUNET_free_non_null (set->excluded_generations);
- set->excluded_generations = NULL;
- GNUNET_CONTAINER_DLL_remove (sets_head,
- sets_tail,
- set);
+ GNUNET_free_non_null (set->excluded_generations);
+ set->excluded_generations = NULL;
- // remove set from pending copy requests
- {
- struct LazyCopyRequest *lcr;
+ /* remove set from pending copy requests */
lcr = lazy_copy_head;
while (NULL != lcr)
{
- struct LazyCopyRequest *lcr_current;
- lcr_current = lcr;
+ struct LazyCopyRequest *lcr_current = lcr;
+
lcr = lcr->next;
if (lcr_current->source_set == set)
+ {
GNUNET_CONTAINER_DLL_remove (lazy_copy_head,
lazy_copy_tail,
lcr_current);
+ GNUNET_free (lcr_current);
+ }
}
+ GNUNET_free (set);
}
- GNUNET_free (set);
-}
-
-
-/**
- * Callback called when a client connects to the service.
- *
- * @param cls closure for the service
- * @param c the new client that connected to the service
- * @param mq the message queue used to send messages to the client
- * @return @a c
- */
-static void *
-client_connect_cb (void *cls,
- struct GNUNET_SERVICE_Client *c,
- struct GNUNET_MQ_Handle *mq)
-{
- return c;
-}
-
-
-/**
- * Destroy an incoming request from a remote peer
- *
- * @param incoming remote request to destroy
- */
-static void
-incoming_destroy (struct Operation *incoming)
-{
- struct GNUNET_CADET_Channel *channel;
-
- GNUNET_assert (GNUNET_YES == incoming->is_incoming);
- GNUNET_CONTAINER_DLL_remove (incoming_head,
- incoming_tail,
- incoming);
- if (NULL != incoming->timeout_task)
- {
- GNUNET_SCHEDULER_cancel (incoming->timeout_task);
- incoming->timeout_task = NULL;
- }
- /* make sure that the tunnel end handler will not destroy us again */
- incoming->vt = NULL;
- if (NULL != incoming->spec)
- {
- GNUNET_free (incoming->spec);
- incoming->spec = NULL;
- }
- if (NULL != (channel = incoming->channel))
- {
- incoming->channel = NULL;
- GNUNET_CADET_channel_destroy (channel);
- }
-}
-
-
-/**
- * Clean up after a client has disconnected
- *
- * @param cls closure, unused
- * @param client the client to clean up after
- * @param internal_cls our client-specific internal data structure
- */
-static void
-client_disconnect_cb (void *cls,
- struct GNUNET_SERVICE_Client *client,
- void *internal_cls)
-{
- struct Set *set;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "client disconnected, cleaning up\n");
- set = set_get (client);
- if (NULL != set)
+ if (NULL != (listener = cs->listener))
{
- set->client = NULL;
- set_destroy (set);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Client's set destroyed\n");
- }
- struct Listener *listener = listener_get (client);
- if (NULL != listener)
- {
- /* destroy all incoming operations whose client just
- * got destroyed */
- //struct Operation *op = incoming_head;
- /*
- while (NULL != op)
- {
- struct Operation *curr = op;
- op = op->next;
- if ( (GNUNET_YES == curr->is_incoming) &&
- (curr->listener == listener) )
- incoming_destroy (curr);
- }
- */
- listener->client = NULL;
- listener_destroy (listener);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Client's listener destroyed\n");
+ "Destroying client's listener\n");
+ GNUNET_CADET_close_port (listener->open_port);
+ listener->open_port = NULL;
+ while (NULL != (op = listener->op_head))
+ incoming_destroy (op);
+ GNUNET_CONTAINER_DLL_remove (listener_head,
+ listener_tail,
+ listener);
+ GNUNET_free (listener);
}
-}
-
-
-/**
- * Suggest the given request to the listener. The listening client can
- * then accept or reject the remote request.
- *
- * @param incoming the incoming peer with the request to suggest
- * @param listener the listener to suggest the request to
- */
-static void
-incoming_suggest (struct Operation *incoming,
- struct Listener *listener)
-{
- struct GNUNET_MQ_Envelope *mqm;
- struct GNUNET_SET_RequestMessage *cmsg;
-
- GNUNET_assert (GNUNET_YES == incoming->is_incoming);
- GNUNET_assert (NULL != incoming->spec);
- GNUNET_assert (0 == incoming->suggest_id);
- incoming->suggest_id = suggest_id++;
- if (0 == suggest_id)
- suggest_id++;
- GNUNET_assert (NULL != incoming->timeout_task);
- GNUNET_SCHEDULER_cancel (incoming->timeout_task);
- incoming->timeout_task = NULL;
- mqm = GNUNET_MQ_msg_nested_mh (cmsg,
- GNUNET_MESSAGE_TYPE_SET_REQUEST,
- incoming->spec->context_msg);
- GNUNET_assert (NULL != mqm);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Suggesting incoming request with accept id %u to listener\n",
- incoming->suggest_id);
- cmsg->accept_id = htonl (incoming->suggest_id);
- cmsg->peer_id = incoming->spec->peer;
- GNUNET_MQ_send (listener->client_mq,
- mqm);
+ GNUNET_free (cs);
}
@@ -748,10 +639,22 @@ check_incoming_msg (void *cls,
const struct OperationRequestMessage *msg)
{
struct Operation *op = cls;
+ struct Listener *listener = op->listener;
const struct GNUNET_MessageHeader *nested_context;
/* double operation request */
- if (NULL != op->spec)
+ if (0 != op->suggest_id)
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ /* This should be equivalent to the previous condition, but can't hurt to check twice */
+ if (NULL == op->listener)
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ if (listener->operation != (enum GNUNET_SET_OperationType) ntohl (msg->operation))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@@ -790,61 +693,74 @@ handle_incoming_msg (void *cls,
{
struct Operation *op = cls;
struct Listener *listener = op->listener;
- struct OperationSpecification *spec;
const struct GNUNET_MessageHeader *nested_context;
+ struct GNUNET_MQ_Envelope *env;
+ struct GNUNET_SET_RequestMessage *cmsg;
- GNUNET_assert (GNUNET_YES == op->is_incoming);
- spec = GNUNET_new (struct OperationSpecification);
nested_context = GNUNET_MQ_extract_nested_mh (msg);
/* Make a copy of the nested_context (application-specific context
information that is opaque to set) so we can pass it to the
listener later on */
if (NULL != nested_context)
- spec->context_msg = GNUNET_copy_message (nested_context);
- spec->operation = ntohl (msg->operation);
- spec->app_id = listener->app_id;
- spec->salt = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
- UINT32_MAX);
- spec->peer = op->peer;
- spec->remote_element_count = ntohl (msg->element_count);
- op->spec = spec;
- listener = op->listener;
+ op->context_msg = GNUNET_copy_message (nested_context);
+ op->remote_element_count = ntohl (msg->element_count);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received P2P operation request (op %u, port %s) for active listener\n",
(uint32_t) ntohl (msg->operation),
- GNUNET_h2s (&listener->app_id));
- incoming_suggest (op,
- listener);
+ GNUNET_h2s (&op->listener->app_id));
+ GNUNET_assert (0 == op->suggest_id);
+ if (0 == suggest_id)
+ suggest_id++;
+ op->suggest_id = suggest_id++;
+ GNUNET_assert (NULL != op->timeout_task);
+ GNUNET_SCHEDULER_cancel (op->timeout_task);
+ op->timeout_task = NULL;
+ env = GNUNET_MQ_msg_nested_mh (cmsg,
+ GNUNET_MESSAGE_TYPE_SET_REQUEST,
+ op->context_msg);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Suggesting incoming request with accept id %u to listener %p of client %p\n",
+ op->suggest_id,
+ listener,
+ listener->cs);
+ cmsg->accept_id = htonl (op->suggest_id);
+ cmsg->peer_id = op->peer;
+ GNUNET_MQ_send (listener->cs->mq,
+ env);
+ /* NOTE: GNUNET_CADET_receive_done() will be called in
+ #handle_client_accept() */
}
+/**
+ * Add an element to @a set as specified by @a msg
+ *
+ * @param set set to manipulate
+ * @param msg message specifying the change
+ */
static void
execute_add (struct Set *set,
- const struct GNUNET_MessageHeader *m)
+ const struct GNUNET_SET_ElementMessage *msg)
{
- const struct GNUNET_SET_ElementMessage *msg;
struct GNUNET_SET_Element el;
struct ElementEntry *ee;
struct GNUNET_HashCode hash;
- GNUNET_assert (GNUNET_MESSAGE_TYPE_SET_ADD == ntohs (m->type));
-
- msg = (const struct GNUNET_SET_ElementMessage *) m;
- el.size = ntohs (m->size) - sizeof *msg;
+ GNUNET_assert (GNUNET_MESSAGE_TYPE_SET_ADD == ntohs (msg->header.type));
+ el.size = ntohs (msg->header.size) - sizeof (*msg);
el.data = &msg[1];
el.element_type = ntohs (msg->element_type);
- GNUNET_SET_element_hash (&el, &hash);
-
+ GNUNET_SET_element_hash (&el,
+ &hash);
ee = GNUNET_CONTAINER_multihashmap_get (set->content->elements,
&hash);
-
if (NULL == ee)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Client inserts element %s of size %u\n",
GNUNET_h2s (&hash),
el.size);
- ee = GNUNET_malloc (el.size + sizeof *ee);
+ ee = GNUNET_malloc (el.size + sizeof (*ee));
ee->element.size = el.size;
GNUNET_memcpy (&ee[1],
el.data,
@@ -861,7 +777,11 @@ execute_add (struct Set *set,
ee,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
}
- else if (GNUNET_YES == _GSS_is_element_of_set (ee, set))
+ else if (GNUNET_YES ==
+ is_element_of_generation (ee,
+ set->current_generation,
+ set->excluded_generations,
+ set->excluded_generations_size))
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Client inserted element %s of size %u twice (ignored)\n",
@@ -881,24 +801,27 @@ execute_add (struct Set *set,
ee->mutations_size,
mut);
}
-
- set->vt->add (set->state, ee);
+ set->vt->add (set->state,
+ ee);
}
+/**
+ * Remove an element from @a set as specified by @a msg
+ *
+ * @param set set to manipulate
+ * @param msg message specifying the change
+ */
static void
execute_remove (struct Set *set,
- const struct GNUNET_MessageHeader *m)
+ const struct GNUNET_SET_ElementMessage *msg)
{
- const struct GNUNET_SET_ElementMessage *msg;
struct GNUNET_SET_Element el;
struct ElementEntry *ee;
struct GNUNET_HashCode hash;
- GNUNET_assert (GNUNET_MESSAGE_TYPE_SET_REMOVE == ntohs (m->type));
-
- msg = (const struct GNUNET_SET_ElementMessage *) m;
- el.size = ntohs (m->size) - sizeof *msg;
+ GNUNET_assert (GNUNET_MESSAGE_TYPE_SET_REMOVE == ntohs (msg->header.type));
+ el.size = ntohs (msg->header.size) - sizeof (*msg);
el.data = &msg[1];
el.element_type = ntohs (msg->element_type);
GNUNET_SET_element_hash (&el, &hash);
@@ -912,7 +835,11 @@ execute_remove (struct Set *set,
el.size);
return;
}
- if (GNUNET_NO == _GSS_is_element_of_set (ee, set))
+ if (GNUNET_NO ==
+ is_element_of_generation (ee,
+ set->current_generation,
+ set->excluded_generations,
+ set->excluded_generations_size))
{
/* Client tried to remove element twice */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -935,22 +862,28 @@ execute_remove (struct Set *set,
ee->mutations_size,
mut);
}
- set->vt->remove (set->state, ee);
+ set->vt->remove (set->state,
+ ee);
}
-
+/**
+ * Perform a mutation on a set as specified by the @a msg
+ *
+ * @param set the set to mutate
+ * @param msg specification of what to change
+ */
static void
execute_mutation (struct Set *set,
- const struct GNUNET_MessageHeader *m)
+ const struct GNUNET_SET_ElementMessage *msg)
{
- switch (ntohs (m->type))
+ switch (ntohs (msg->header.type))
{
case GNUNET_MESSAGE_TYPE_SET_ADD:
- execute_add (set, m);
+ execute_add (set, msg);
break;
case GNUNET_MESSAGE_TYPE_SET_REMOVE:
- execute_remove (set, m);
+ execute_remove (set, msg);
break;
default:
GNUNET_break (0);
@@ -958,6 +891,34 @@ execute_mutation (struct Set *set,
}
+/**
+ * Execute mutations that were delayed on a set because of
+ * pending operations.
+ *
+ * @param set the set to execute mutations on
+ */
+static void
+execute_delayed_mutations (struct Set *set)
+{
+ struct PendingMutation *pm;
+
+ if (0 != set->content->iterator_count)
+ return; /* still cannot do this */
+ while (NULL != (pm = set->content->pending_mutations_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (set->content->pending_mutations_head,
+ set->content->pending_mutations_tail,
+ pm);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Executing pending mutation on %p.\n",
+ pm->set);
+ execute_mutation (pm->set,
+ pm->msg);
+ GNUNET_free (pm->msg);
+ GNUNET_free (pm);
+ }
+}
+
/**
* Send the next element of a set to the set's client. The next element is given by
@@ -981,65 +942,45 @@ send_client_element (struct Set *set)
struct GNUNET_SET_IterResponseMessage *msg;
GNUNET_assert (NULL != set->iter);
-
-again:
-
- ret = GNUNET_CONTAINER_multihashmap_iterator_next (set->iter,
- NULL,
- (const void **) &ee);
- if (GNUNET_NO == ret)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Iteration on %p done.\n",
- (void *) set);
- ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_ITER_DONE);
- GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter);
- set->iter = NULL;
- set->iteration_id++;
-
- GNUNET_assert (set->content->iterator_count > 0);
- set->content->iterator_count -= 1;
-
- if (0 == set->content->iterator_count)
+ do {
+ ret = GNUNET_CONTAINER_multihashmap_iterator_next (set->iter,
+ NULL,
+ (const void **) &ee);
+ if (GNUNET_NO == ret)
{
- while (NULL != set->content->pending_mutations_head)
- {
- struct PendingMutation *pm;
-
- pm = set->content->pending_mutations_head;
- GNUNET_CONTAINER_DLL_remove (set->content->pending_mutations_head,
- set->content->pending_mutations_tail,
- pm);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Executing pending mutation on %p.\n",
- (void *) pm->set);
- execute_mutation (pm->set, pm->mutation_message);
- GNUNET_free (pm->mutation_message);
- GNUNET_free (pm);
- }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Iteration on %p done.\n",
+ set);
+ ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_ITER_DONE);
+ GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter);
+ set->iter = NULL;
+ set->iteration_id++;
+ GNUNET_assert (set->content->iterator_count > 0);
+ set->content->iterator_count--;
+ execute_delayed_mutations (set);
+ GNUNET_MQ_send (set->cs->mq,
+ ev);
+ return;
}
-
- }
- else
- {
GNUNET_assert (NULL != ee);
-
- if (GNUNET_NO == is_element_of_iteration (ee, set))
- goto again;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending iteration element on %p.\n",
- (void *) set);
- ev = GNUNET_MQ_msg_extra (msg,
- ee->element.size,
- GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT);
- GNUNET_memcpy (&msg[1],
- ee->element.data,
- ee->element.size);
- msg->element_type = htons (ee->element.element_type);
- msg->iteration_id = htons (set->iteration_id);
- }
- GNUNET_MQ_send (set->client_mq, ev);
+ } while (GNUNET_NO ==
+ is_element_of_generation (ee,
+ set->iter_generation,
+ set->excluded_generations,
+ set->excluded_generations_size));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending iteration element on %p.\n",
+ set);
+ ev = GNUNET_MQ_msg_extra (msg,
+ ee->element.size,
+ GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT);
+ GNUNET_memcpy (&msg[1],
+ ee->element.data,
+ ee->element.size);
+ msg->element_type = htons (ee->element.element_type);
+ msg->iteration_id = htons (set->iteration_id);
+ GNUNET_MQ_send (set->cs->mq,
+ ev);
}
@@ -1056,22 +997,21 @@ static void
handle_client_iterate (void *cls,
const struct GNUNET_MessageHeader *m)
{
- struct GNUNET_SERVICE_Client *client = cls;
+ struct ClientState *cs = cls;
struct Set *set;
- set = set_get (client);
- if (NULL == set)
+ if (NULL == (set = cs->set))
{
/* attempt to iterate over a non existing set */
GNUNET_break (0);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (cs->client);
return;
}
if (NULL != set->iter)
{
/* Only one concurrent iterate-action allowed per set */
GNUNET_break (0);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (cs->client);
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1079,8 +1019,8 @@ handle_client_iterate (void *cls,
(void *) set,
set->current_generation,
GNUNET_CONTAINER_multihashmap_size (set->content->elements));
- GNUNET_SERVICE_client_continue (client);
- set->content->iterator_count += 1;
+ GNUNET_SERVICE_client_continue (cs->client);
+ set->content->iterator_count++;
set->iter = GNUNET_CONTAINER_multihashmap_iterator_create (set->content->elements);
set->iter_generation = set->current_generation;
send_client_element (set);
@@ -1099,17 +1039,17 @@ static void
handle_client_create_set (void *cls,
const struct GNUNET_SET_CreateMessage *msg)
{
- struct GNUNET_SERVICE_Client *client = cls;
+ struct ClientState *cs = cls;
struct Set *set;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Client created new set (operation %u)\n",
(uint32_t) ntohl (msg->operation));
- if (NULL != set_get (client))
+ if (NULL != cs->set)
{
/* There can only be one set per client */
GNUNET_break (0);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (cs->client);
return;
}
set = GNUNET_new (struct Set);
@@ -1117,36 +1057,32 @@ handle_client_create_set (void *cls,
{
case GNUNET_SET_OPERATION_INTERSECTION:
set->vt = _GSS_intersection_vt ();
- set->type = OT_INTERSECTION;
break;
case GNUNET_SET_OPERATION_UNION:
set->vt = _GSS_union_vt ();
- set->type = OT_UNION;
break;
default:
GNUNET_free (set);
GNUNET_break (0);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (cs->client);
return;
}
- set->operation = ntohl (msg->operation);
+ set->operation = (enum GNUNET_SET_OperationType) ntohl (msg->operation);
set->state = set->vt->create ();
if (NULL == set->state)
{
/* initialization failed (i.e. out of memory) */
GNUNET_free (set);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (cs->client);
return;
}
set->content = GNUNET_new (struct SetContent);
set->content->refcount = 1;
- set->content->elements = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES);
- set->client = client;
- set->client_mq = GNUNET_SERVICE_client_get_mq (client);
- GNUNET_CONTAINER_DLL_insert (sets_head,
- sets_tail,
- set);
- GNUNET_SERVICE_client_continue (client);
+ set->content->elements = GNUNET_CONTAINER_multihashmap_create (1,
+ GNUNET_YES);
+ set->cs = cs;
+ cs->set = set;
+ GNUNET_SERVICE_client_continue (cs->client);
}
@@ -1162,31 +1098,12 @@ handle_client_create_set (void *cls,
static void
incoming_timeout_cb (void *cls)
{
- struct Operation *incoming = cls;
+ struct Operation *op = cls;
- incoming->timeout_task = NULL;
- GNUNET_assert (GNUNET_YES == incoming->is_incoming);
+ op->timeout_task = NULL;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Remote peer's incoming request timed out\n");
- incoming_destroy (incoming);
-}
-
-
-/**
- * Terminates an incoming operation in case we have not yet received an
- * operation request. Called by the channel destruction handler.
- *
- * @param op the channel context
- */
-static void
-handle_incoming_disconnect (struct Operation *op)
-{
- GNUNET_assert (GNUNET_YES == op->is_incoming);
- /* channel is already dead, incoming_destroy must not
- * destroy it ... */
- op->channel = NULL;
incoming_destroy (op);
- op->vt = NULL;
}
@@ -1211,31 +1128,26 @@ channel_new_cb (void *cls,
struct GNUNET_CADET_Channel *channel,
const struct GNUNET_PeerIdentity *source)
{
- static const struct SetVT incoming_vt = {
- .peer_disconnect = &handle_incoming_disconnect
- };
struct Listener *listener = cls;
- struct Operation *incoming;
+ struct Operation *op;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"New incoming channel\n");
- incoming = GNUNET_new (struct Operation);
- incoming->listener = listener;
- incoming->is_incoming = GNUNET_YES;
- incoming->peer = *source;
- incoming->channel = channel;
- incoming->mq = GNUNET_CADET_get_mq (incoming->channel);
- incoming->vt = &incoming_vt;
- incoming->timeout_task
+ op = GNUNET_new (struct Operation);
+ op->listener = listener;
+ op->peer = *source;
+ op->channel = channel;
+ op->mq = GNUNET_CADET_get_mq (op->channel);
+ op->salt = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
+ UINT32_MAX);
+ op->timeout_task
= GNUNET_SCHEDULER_add_delayed (INCOMING_CHANNEL_TIMEOUT,
&incoming_timeout_cb,
- incoming);
- GNUNET_CONTAINER_DLL_insert_tail (incoming_head,
- incoming_tail,
- incoming);
- // incoming_suggest (incoming,
- // listener);
- return incoming;
+ op);
+ GNUNET_CONTAINER_DLL_insert (listener->op_head,
+ listener->op_tail,
+ op);
+ return op;
}
@@ -1264,22 +1176,14 @@ channel_end_cb (void *channel_ctx,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"channel_end_cb called\n");
op->channel = NULL;
- op->keep++;
- /* the vt can be null if a client already requested canceling op. */
- if (NULL != op->vt)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "calling peer disconnect due to channel end\n");
- op->vt->peer_disconnect (op);
- }
- op->keep--;
- if (0 == op->keep)
- {
- /* cadet will never call us with the context again! */
- GNUNET_free (op);
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "channel_end_cb finished\n");
+ if (NULL != op->listener)
+ incoming_destroy (op);
+ else if (NULL != op->set)
+ op->set->vt->channel_death (op);
+ else
+ _GSS_operation_destroy (op,
+ GNUNET_YES);
+ GNUNET_free (op);
}
@@ -1316,7 +1220,7 @@ static void
handle_client_listen (void *cls,
const struct GNUNET_SET_ListenMessage *msg)
{
- struct GNUNET_SERVICE_Client *client = cls;
+ struct ClientState *cs = cls;
struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
GNUNET_MQ_hd_var_size (incoming_msg,
GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST,
@@ -1382,50 +1286,33 @@ handle_client_listen (void *cls,
};
struct Listener *listener;
- if (NULL != listener_get (client))
+ if (NULL != cs->listener)
{
/* max. one active listener per client! */
GNUNET_break (0);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (cs->client);
return;
}
listener = GNUNET_new (struct Listener);
- listener->client = client;
- listener->client_mq = GNUNET_SERVICE_client_get_mq (client);
+ listener->cs = cs;
listener->app_id = msg->app_id;
- listener->operation = ntohl (msg->operation);
- GNUNET_CONTAINER_DLL_insert_tail (listeners_head,
- listeners_tail,
- listener);
+ listener->operation = (enum GNUNET_SET_OperationType) ntohl (msg->operation);
+ GNUNET_CONTAINER_DLL_insert (listener_head,
+ listener_tail,
+ listener);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"New listener created (op %u, port %s)\n",
listener->operation,
GNUNET_h2s (&listener->app_id));
- listener->open_port = GNUNET_CADET_open_porT (cadet,
- &msg->app_id,
- &channel_new_cb,
- listener,
- &channel_window_cb,
- &channel_end_cb,
- cadet_handlers);
- /* check for existing incoming requests the listener might be interested in */
- for (struct Operation *op = incoming_head; NULL != op; op = op->next)
- {
- if (NULL == op->spec)
- continue; /* no details available yet */
- if (0 != op->suggest_id)
- continue; /* this one has been already suggested to a listener */
- if (listener->operation != op->spec->operation)
- continue; /* incompatible operation */
- if (0 != GNUNET_CRYPTO_hash_cmp (&listener->app_id,
- &op->spec->app_id))
- continue; /* incompatible appliation */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Found matching existing request\n");
- incoming_suggest (op,
- listener);
- }
- GNUNET_SERVICE_client_continue (client);
+ listener->open_port
+ = GNUNET_CADET_open_port (cadet,
+ &msg->app_id,
+ &channel_new_cb,
+ listener,
+ &channel_window_cb,
+ &channel_end_cb,
+ cadet_handlers);
+ GNUNET_SERVICE_client_continue (cs->client);
}
@@ -1440,23 +1327,26 @@ static void
handle_client_reject (void *cls,
const struct GNUNET_SET_RejectMessage *msg)
{
- struct GNUNET_SERVICE_Client *client = cls;
- struct Operation *incoming;
+ struct ClientState *cs = cls;
+ struct Operation *op;
- incoming = get_incoming (ntohl (msg->accept_reject_id));
- if (NULL == incoming)
+ op = get_incoming (ntohl (msg->accept_reject_id));
+ if (NULL == op)
{
- /* no matching incoming operation for this reject */
- GNUNET_break (0);
- GNUNET_SERVICE_client_drop (client);
+ /* no matching incoming operation for this reject;
+ could be that the other peer already disconnected... */
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Client rejected unknown operation %u\n",
+ (unsigned int) ntohl (msg->accept_reject_id));
+ GNUNET_SERVICE_client_continue (cs->client);
return;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Peer request (op %u, app %s) rejected by client\n",
- incoming->spec->operation,
- GNUNET_h2s (&incoming->spec->app_id));
- GNUNET_CADET_channel_destroy (incoming->channel);
- GNUNET_SERVICE_client_continue (client);
+ op->listener->operation,
+ GNUNET_h2s (&cs->listener->app_id));
+ GNUNET_CADET_channel_destroy (op->channel);
+ GNUNET_SERVICE_client_continue (cs->client);
}
@@ -1464,13 +1354,14 @@ handle_client_reject (void *cls,
* Called when a client wants to add or remove an element to a set it inhabits.
*
* @param cls client that sent the message
- * @param m message sent by the client
+ * @param msg message sent by the client
*/
static int
check_client_mutation (void *cls,
- const struct GNUNET_MessageHeader *m)
+ const struct GNUNET_SET_ElementMessage *msg)
{
- /* FIXME: any check we might want to do here? */
+ /* NOTE: Technically, we should probably check with the
+ block library whether the element we are given is well-formed */
return GNUNET_OK;
}
@@ -1479,25 +1370,23 @@ check_client_mutation (void *cls,
* Called when a client wants to add or remove an element to a set it inhabits.
*
* @param cls client that sent the message
- * @param m message sent by the client
+ * @param msg message sent by the client
*/
static void
handle_client_mutation (void *cls,
- const struct GNUNET_MessageHeader *m)
+ const struct GNUNET_SET_ElementMessage *msg)
{
- struct GNUNET_SERVICE_Client *client = cls;
+ struct ClientState *cs = cls;
struct Set *set;
- set = set_get (client);
- if (NULL == set)
+ if (NULL == (set = cs->set))
{
/* client without a set requested an operation */
GNUNET_break (0);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (cs->client);
return;
}
-
- GNUNET_SERVICE_client_continue (client);
+ GNUNET_SERVICE_client_continue (cs->client);
if (0 != set->content->iterator_count)
{
@@ -1505,16 +1394,18 @@ handle_client_mutation (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Scheduling mutation on set\n");
-
pm = GNUNET_new (struct PendingMutation);
- pm->mutation_message = GNUNET_copy_message (m);
+ pm->msg = (struct GNUNET_SET_ElementMessage *) GNUNET_copy_message (&msg->header);
pm->set = set;
GNUNET_CONTAINER_DLL_insert_tail (set->content->pending_mutations_head,
set->content->pending_mutations_tail,
pm);
return;
}
- execute_mutation (set, m);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Executing mutation on set\n");
+ execute_mutation (set,
+ msg);
}
@@ -1531,8 +1422,8 @@ advance_generation (struct Set *set)
if (set->current_generation == set->content->latest_generation)
{
- set->content->latest_generation += 1;
- set->current_generation += 1;
+ set->content->latest_generation++;
+ set->current_generation++;
return;
}
@@ -1540,10 +1431,8 @@ advance_generation (struct Set *set)
r.start = set->current_generation + 1;
r.end = set->content->latest_generation + 1;
-
set->content->latest_generation = r.end;
set->current_generation = r.end;
-
GNUNET_array_append (set->excluded_generations,
set->excluded_generations_size,
r);
@@ -1581,7 +1470,7 @@ static void
handle_client_evaluate (void *cls,
const struct GNUNET_SET_EvaluateMessage *msg)
{
- struct GNUNET_SERVICE_Client *client = cls;
+ struct ClientState *cs = cls;
struct Operation *op = GNUNET_new (struct Operation);
const struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
GNUNET_MQ_hd_var_size (incoming_msg,
@@ -1647,46 +1536,39 @@ handle_client_evaluate (void *cls,
GNUNET_MQ_handler_end ()
};
struct Set *set;
- struct OperationSpecification *spec;
const struct GNUNET_MessageHeader *context;
- set = set_get (client);
- if (NULL == set)
+ if (NULL == (set = cs->set))
{
GNUNET_break (0);
GNUNET_free (op);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (cs->client);
return;
}
- spec = GNUNET_new (struct OperationSpecification);
- spec->operation = set->operation;
- spec->app_id = msg->app_id;
- spec->salt = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
- UINT32_MAX);
- spec->peer = msg->target_peer;
- spec->set = set;
- spec->result_mode = ntohl (msg->result_mode);
- spec->client_request_id = ntohl (msg->request_id);
- spec->byzantine = msg->byzantine;
- spec->byzantine_lower_bound = msg->byzantine_lower_bound;
- spec->force_full = msg->force_full;
- spec->force_delta = msg->force_delta;
+ op->salt = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
+ UINT32_MAX);
+ op->peer = msg->target_peer;
+ op->result_mode = ntohl (msg->result_mode);
+ op->client_request_id = ntohl (msg->request_id);
+ op->byzantine = msg->byzantine;
+ op->byzantine_lower_bound = msg->byzantine_lower_bound;
+ op->force_full = msg->force_full;
+ op->force_delta = msg->force_delta;
context = GNUNET_MQ_extract_nested_mh (msg);
- op->spec = spec;
- // Advance generation values, so that
- // mutations won't interfer with the running operation.
+ /* Advance generation values, so that
+ mutations won't interfer with the running operation. */
+ op->set = set;
op->generation_created = set->current_generation;
advance_generation (set);
- op->type = set->type;
- op->vt = set->vt;
GNUNET_CONTAINER_DLL_insert (set->ops_head,
set->ops_tail,
op);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Creating new CADET channel to port %s\n",
- GNUNET_h2s (&msg->app_id));
- op->channel = GNUNET_CADET_channel_creatE (cadet,
+ "Creating new CADET channel to port %s for set operation type %u\n",
+ GNUNET_h2s (&msg->app_id),
+ set->operation);
+ op->channel = GNUNET_CADET_channel_create (cadet,
op,
&msg->target_peer,
&msg->app_id,
@@ -1695,9 +1577,15 @@ handle_client_evaluate (void *cls,
&channel_end_cb,
cadet_handlers);
op->mq = GNUNET_CADET_get_mq (op->channel);
- set->vt->evaluate (op,
- context);
- GNUNET_SERVICE_client_continue (client);
+ op->state = set->vt->evaluate (op,
+ context);
+ if (NULL == op->state)
+ {
+ GNUNET_break (0);
+ GNUNET_SERVICE_client_drop (cs->client);
+ return;
+ }
+ GNUNET_SERVICE_client_continue (cs->client);
}
@@ -1713,15 +1601,14 @@ static void
handle_client_iter_ack (void *cls,
const struct GNUNET_SET_IterAckMessage *ack)
{
- struct GNUNET_SERVICE_Client *client = cls;
+ struct ClientState *cs = cls;
struct Set *set;
- set = set_get (client);
- if (NULL == set)
+ if (NULL == (set = cs->set))
{
/* client without a set acknowledged receiving a value */
GNUNET_break (0);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (cs->client);
return;
}
if (NULL == set->iter)
@@ -1729,10 +1616,10 @@ handle_client_iter_ack (void *cls,
/* client sent an ack, but we were not expecting one (as
set iteration has finished) */
GNUNET_break (0);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (cs->client);
return;
}
- GNUNET_SERVICE_client_continue (client);
+ GNUNET_SERVICE_client_continue (cs->client);
if (ntohl (ack->send_more))
{
send_client_element (set);
@@ -1756,42 +1643,33 @@ static void
handle_client_copy_lazy_prepare (void *cls,
const struct GNUNET_MessageHeader *mh)
{
- struct GNUNET_SERVICE_Client *client = cls;
+ struct ClientState *cs = cls;
struct Set *set;
struct LazyCopyRequest *cr;
struct GNUNET_MQ_Envelope *ev;
struct GNUNET_SET_CopyLazyResponseMessage *resp_msg;
- set = set_get (client);
- if (NULL == set)
+ if (NULL == (set = cs->set))
{
/* client without a set requested an operation */
GNUNET_break (0);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (cs->client);
return;
}
-
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client requested creation of lazy copy\n");
cr = GNUNET_new (struct LazyCopyRequest);
-
- cr->cookie = lazy_copy_cookie;
- lazy_copy_cookie += 1;
+ cr->cookie = ++lazy_copy_cookie;
cr->source_set = set;
-
GNUNET_CONTAINER_DLL_insert (lazy_copy_head,
lazy_copy_tail,
cr);
-
-
ev = GNUNET_MQ_msg (resp_msg,
GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE);
resp_msg->cookie = cr->cookie;
- GNUNET_MQ_send (set->client_mq, ev);
-
-
- GNUNET_SERVICE_client_continue (client);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Client requested lazy copy\n");
+ GNUNET_MQ_send (set->cs->mq,
+ ev);
+ GNUNET_SERVICE_client_continue (cs->client);
}
@@ -1805,21 +1683,19 @@ static void
handle_client_copy_lazy_connect (void *cls,
const struct GNUNET_SET_CopyLazyConnectMessage *msg)
{
- struct GNUNET_SERVICE_Client *client = cls;
+ struct ClientState *cs = cls;
struct LazyCopyRequest *cr;
struct Set *set;
int found;
- if (NULL != set_get (client))
+ if (NULL != cs->set)
{
/* There can only be one set per client */
GNUNET_break (0);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (cs->client);
return;
}
-
found = GNUNET_NO;
-
for (cr = lazy_copy_head; NULL != cr; cr = cr->next)
{
if (cr->cookie == msg->cookie)
@@ -1828,30 +1704,27 @@ handle_client_copy_lazy_connect (void *cls,
break;
}
}
-
if (GNUNET_NO == found)
{
/* client asked for copy with cookie we don't know */
GNUNET_break (0);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (cs->client);
return;
}
-
GNUNET_CONTAINER_DLL_remove (lazy_copy_head,
lazy_copy_tail,
cr);
-
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client %p requested use of lazy copy\n",
+ cs);
set = GNUNET_new (struct Set);
-
switch (cr->source_set->operation)
{
case GNUNET_SET_OPERATION_INTERSECTION:
set->vt = _GSS_intersection_vt ();
- set->type = OT_INTERSECTION;
break;
case GNUNET_SET_OPERATION_UNION:
set->vt = _GSS_union_vt ();
- set->type = OT_UNION;
break;
default:
GNUNET_assert (0);
@@ -1864,37 +1737,28 @@ handle_client_copy_lazy_connect (void *cls,
GNUNET_break (0);
GNUNET_free (set);
GNUNET_free (cr);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (cs->client);
return;
}
set->operation = cr->source_set->operation;
- set->state = set->vt->copy_state (cr->source_set);
+ set->state = set->vt->copy_state (cr->source_set->state);
set->content = cr->source_set->content;
- set->content->refcount += 1;
+ set->content->refcount++;
set->current_generation = cr->source_set->current_generation;
set->excluded_generations_size = cr->source_set->excluded_generations_size;
- set->excluded_generations = GNUNET_memdup (cr->source_set->excluded_generations,
- set->excluded_generations_size * sizeof (struct GenerationRange));
+ set->excluded_generations
+ = GNUNET_memdup (cr->source_set->excluded_generations,
+ set->excluded_generations_size * sizeof (struct GenerationRange));
/* Advance the generation of the new set, so that mutations to the
of the cloned set and the source set are independent. */
advance_generation (set);
-
-
- set->client = client;
- set->client_mq = GNUNET_SERVICE_client_get_mq (client);
- GNUNET_CONTAINER_DLL_insert (sets_head,
- sets_tail,
- set);
-
+ set->cs = cs;
+ cs->set = set;
GNUNET_free (cr);
-
- GNUNET_SERVICE_client_continue (client);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Client connected to lazy set\n");
+ GNUNET_SERVICE_client_continue (cs->client);
}
@@ -1908,26 +1772,22 @@ static void
handle_client_cancel (void *cls,
const struct GNUNET_SET_CancelMessage *msg)
{
- struct GNUNET_SERVICE_Client *client = cls;
+ struct ClientState *cs = cls;
struct Set *set;
struct Operation *op;
int found;
- set = set_get (client);
- if (NULL == set)
+ if (NULL == (set = cs->set))
{
/* client without a set requested an operation */
GNUNET_break (0);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (cs->client);
return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Client requested cancel for op %u\n",
- (uint32_t) ntohl (msg->request_id));
found = GNUNET_NO;
for (op = set->ops_head; NULL != op; op = op->next)
{
- if (op->spec->client_request_id == ntohl (msg->request_id))
+ if (op->client_request_id == ntohl (msg->request_id))
{
found = GNUNET_YES;
break;
@@ -1940,15 +1800,19 @@ handle_client_cancel (void *cls,
* yet and try to cancel the (just barely non-existent) operation.
* So this is not a hard error.
*/
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Client canceled non-existent op\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Client canceled non-existent op %u\n",
+ (uint32_t) ntohl (msg->request_id));
}
else
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Client requested cancel for op %u\n",
+ (uint32_t) ntohl (msg->request_id));
_GSS_operation_destroy (op,
GNUNET_YES);
}
- GNUNET_SERVICE_client_continue (client);
+ GNUNET_SERVICE_client_continue (cs->client);
}
@@ -1964,18 +1828,18 @@ static void
handle_client_accept (void *cls,
const struct GNUNET_SET_AcceptMessage *msg)
{
- struct GNUNET_SERVICE_Client *client = cls;
+ struct ClientState *cs = cls;
struct Set *set;
struct Operation *op;
struct GNUNET_SET_ResultMessage *result_message;
struct GNUNET_MQ_Envelope *ev;
+ struct Listener *listener;
- set = set_get (client);
- if (NULL == set)
+ if (NULL == (set = cs->set))
{
/* client without a set requested to accept */
GNUNET_break (0);
- GNUNET_SERVICE_client_drop (client);
+ GNUNET_SERVICE_client_drop (cs->client);
return;
}
op = get_incoming (ntohl (msg->accept_reject_id));
@@ -1983,72 +1847,75 @@ handle_client_accept (void *cls,
{
/* It is not an error if the set op does not exist -- it may
* have been destroyed when the partner peer disconnected. */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Client accepted request that is no longer active\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Client %p accepted request %u of listener %p that is no longer active\n",
+ cs,
+ ntohl (msg->accept_reject_id),
+ cs->listener);
ev = GNUNET_MQ_msg (result_message,
GNUNET_MESSAGE_TYPE_SET_RESULT);
result_message->request_id = msg->request_id;
- result_message->element_type = 0;
result_message->result_status = htons (GNUNET_SET_STATUS_FAILURE);
- GNUNET_MQ_send (set->client_mq, ev);
- GNUNET_SERVICE_client_continue (client);
+ GNUNET_MQ_send (set->cs->mq,
+ ev);
+ GNUNET_SERVICE_client_continue (cs->client);
return;
}
-
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Client accepting request %u\n",
(uint32_t) ntohl (msg->accept_reject_id));
- GNUNET_assert (GNUNET_YES == op->is_incoming);
- op->is_incoming = GNUNET_NO;
- GNUNET_CONTAINER_DLL_remove (incoming_head,
- incoming_tail,
+ listener = op->listener;
+ op->listener = NULL;
+ GNUNET_CONTAINER_DLL_remove (listener->op_head,
+ listener->op_tail,
op);
- op->spec->set = set;
+ op->set = set;
GNUNET_CONTAINER_DLL_insert (set->ops_head,
set->ops_tail,
op);
- op->spec->client_request_id = ntohl (msg->request_id);
- op->spec->result_mode = ntohl (msg->result_mode);
- op->spec->byzantine = msg->byzantine;
- op->spec->byzantine_lower_bound = msg->byzantine_lower_bound;
- op->spec->force_full = msg->force_full;
- op->spec->force_delta = msg->force_delta;
-
- // Advance generation values, so that
- // mutations won't interfer with the running operation.
+ op->client_request_id = ntohl (msg->request_id);
+ op->result_mode = ntohl (msg->result_mode);
+ op->byzantine = msg->byzantine;
+ op->byzantine_lower_bound = msg->byzantine_lower_bound;
+ op->force_full = msg->force_full;
+ op->force_delta = msg->force_delta;
+
+ /* Advance generation values, so that future mutations do not
+ interfer with the running operation. */
op->generation_created = set->current_generation;
advance_generation (set);
-
- op->vt = set->vt;
- op->type = set->type;
- op->vt->accept (op);
- GNUNET_SERVICE_client_continue (client);
+ GNUNET_assert (NULL == op->state);
+ op->state = set->vt->accept (op);
+ if (NULL == op->state)
+ {
+ GNUNET_break (0);
+ GNUNET_SERVICE_client_drop (cs->client);
+ return;
+ }
+ /* Now allow CADET to continue, as we did not do this in
+ #handle_incoming_msg (as we wanted to first see if the
+ local client would accept the request). */
+ GNUNET_CADET_receive_done (op->channel);
+ GNUNET_SERVICE_client_continue (cs->client);
}
/**
* Called to clean up, after a shutdown has been requested.
*
- * @param cls closure
+ * @param cls closure, NULL
*/
static void
shutdown_task (void *cls)
{
- while (NULL != incoming_head)
- incoming_destroy (incoming_head);
- while (NULL != listeners_head)
- listener_destroy (listeners_head);
- while (NULL != sets_head)
- set_destroy (sets_head);
-
- /* it's important to destroy cadet at the end, as all channels
- * must be destroyed before the cadet handle! */
+ /* Delay actual shutdown to allow service to disconnect clients */
if (NULL != cadet)
{
GNUNET_CADET_disconnect (cadet);
cadet = NULL;
}
- GNUNET_STATISTICS_destroy (_GSS_statistics, GNUNET_YES);
+ GNUNET_STATISTICS_destroy (_GSS_statistics,
+ GNUNET_YES);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"handled shutdown request\n");
}
@@ -2067,15 +1934,19 @@ run (void *cls,
const struct GNUNET_CONFIGURATION_Handle *cfg,
struct GNUNET_SERVICE_Handle *service)
{
- configuration = cfg;
+ /* FIXME: need to modify SERVICE (!) API to allow
+ us to run a shutdown task *after* clients were
+ forcefully disconnected! */
GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
NULL);
- _GSS_statistics = GNUNET_STATISTICS_create ("set", cfg);
- cadet = GNUNET_CADET_connecT (cfg);
+ _GSS_statistics = GNUNET_STATISTICS_create ("set",
+ cfg);
+ cadet = GNUNET_CADET_connect (cfg);
if (NULL == cadet)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("Could not connect to CADET service\n"));
+ GNUNET_SCHEDULER_shutdown ();
return;
}
}
@@ -2101,7 +1972,7 @@ GNUNET_SERVICE_MAIN
NULL),
GNUNET_MQ_hd_var_size (client_mutation,
GNUNET_MESSAGE_TYPE_SET_ADD,
- struct GNUNET_MessageHeader,
+ struct GNUNET_SET_ElementMessage,
NULL),
GNUNET_MQ_hd_fixed_size (client_create_set,
GNUNET_MESSAGE_TYPE_SET_CREATE,
@@ -2125,7 +1996,7 @@ GNUNET_SERVICE_MAIN
NULL),
GNUNET_MQ_hd_var_size (client_mutation,
GNUNET_MESSAGE_TYPE_SET_REMOVE,
- struct GNUNET_MessageHeader,
+ struct GNUNET_SET_ElementMessage,
NULL),
GNUNET_MQ_hd_fixed_size (client_cancel,
GNUNET_MESSAGE_TYPE_SET_CANCEL,
diff --git a/src/set/gnunet-service-set.h b/src/set/gnunet-service-set.h
index c981430ef0..19413fd304 100644
--- a/src/set/gnunet-service-set.h
+++ b/src/set/gnunet-service-set.h
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet
- Copyright (C) 2013, 2014 GNUnet e.V.
+ Copyright (C) 2013-2017 GNUnet e.V.
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -68,92 +68,13 @@ struct Operation;
/**
- * Detail information about an operation.
- */
-struct OperationSpecification
-{
-
- /**
- * The remove peer we evaluate the operation with.
- */
- struct GNUNET_PeerIdentity peer;
-
- /**
- * Application ID for the operation, used to distinguish
- * multiple operations of the same type with the same peer.
- */
- struct GNUNET_HashCode app_id;
-
- /**
- * Context message, may be NULL.
- */
- struct GNUNET_MessageHeader *context_msg;
-
- /**
- * Set associated with the operation, NULL until the spec has been
- * associated with a set.
- */
- struct Set *set;
-
- /**
- * Salt to use for the operation.
- */
- uint32_t salt;
-
- /**
- * Remote peers element count
- */
- uint32_t remote_element_count;
-
- /**
- * ID used to identify an operation between service and client
- */
- uint32_t client_request_id;
-
- /**
- * The type of the operation.
- */
- enum GNUNET_SET_OperationType operation;
-
- /**
- * When are elements sent to the client, and which elements are sent?
- */
- enum GNUNET_SET_ResultMode result_mode;
-
- /**
- * Always use delta operation instead of sending full sets,
- * even it it's less efficient.
- */
- int force_delta;
-
- /**
- * Always send full sets, even if delta operations would
- * be more efficient.
- */
- int force_full;
-
- /**
- * #GNUNET_YES to fail operations where Byzantine faults
- * are suspected
- */
- int byzantine;
-
- /**
- * Lower bound for the set size, used only when
- * byzantine mode is enabled.
- */
- int byzantine_lower_bound;
-};
-
-
-/**
* Signature of functions that create the implementation-specific
* state for a set supporting a specific operation.
*
* @return a set state specific to the supported operation, NULL on error
*/
typedef struct SetState *
-(*CreateImpl) (void);
+(*SetCreateImpl) (void);
/**
@@ -164,18 +85,18 @@ typedef struct SetState *
* @param ee element message from the client
*/
typedef void
-(*AddRemoveImpl) (struct SetState *state,
+(*SetAddRemoveImpl) (struct SetState *state,
struct ElementEntry *ee);
/**
- * Signature of functions that handle disconnection of the remote
- * peer.
+ * Make a copy of a set's internal state.
*
- * @param op the set operation, contains implementation-specific data
+ * @param state set state to copy
+ * @return copy of the internal state
*/
-typedef void
-(*PeerDisconnectImpl) (struct Operation *op);
+typedef struct SetState *
+(*SetCopyStateImpl) (struct SetState *state);
/**
@@ -185,7 +106,7 @@ typedef void
* @param state the set state, contains implementation-specific data
*/
typedef void
-(*DestroySetImpl) (struct SetState *state);
+(*SetDestroyImpl) (struct SetState *state);
/**
@@ -193,8 +114,9 @@ typedef void
*
* @param op operation that is created by accepting the operation,
* should be initialized by the implementation
+ * @return operation-specific state to keep in @a op
*/
-typedef void
+typedef struct OperationState *
(*OpAcceptImpl) (struct Operation *op);
@@ -206,23 +128,31 @@ typedef void
* begin the evaluation
* @param opaque_context message to be transmitted to the listener
* to convince him to accept, may be NULL
+ * @return operation-specific state to keep in @a op
*/
-typedef void
+typedef struct OperationState *
(*OpEvaluateImpl) (struct Operation *op,
const struct GNUNET_MessageHeader *opaque_context);
-
/**
- * Signature of functions that implement operation cancellation
+ * Signature of functions that implement operation cancelation.
+ * This includes notifying the client about the operation's final
+ * state.
*
* @param op operation state
*/
typedef void
-(*CancelImpl) (struct Operation *op);
+(*OpCancelImpl) (struct Operation *op);
-typedef struct SetState *
-(*CopyStateImpl) (struct Set *op);
+/**
+ * Signature of functions called when the CADET channel died.
+ *
+ * @param op operation state
+ */
+typedef void
+(*OpChannelDeathImpl) (struct Operation *op);
+
/**
@@ -234,17 +164,27 @@ struct SetVT
/**
* Callback for the set creation.
*/
- CreateImpl create;
+ SetCreateImpl create;
/**
* Callback for element insertion
*/
- AddRemoveImpl add;
+ SetAddRemoveImpl add;
/**
* Callback for element removal.
*/
- AddRemoveImpl remove;
+ SetAddRemoveImpl remove;
+
+ /**
+ * Callback for making a copy of a set's internal state.
+ */
+ SetCopyStateImpl copy_state;
+
+ /**
+ * Callback for destruction of the set state.
+ */
+ SetDestroyImpl destroy_set;
/**
* Callback for accepting a set operation request
@@ -257,21 +197,15 @@ struct SetVT
OpEvaluateImpl evaluate;
/**
- * Callback for destruction of the set state.
- */
- DestroySetImpl destroy_set;
-
- /**
- * Callback for handling the remote peer's disconnect.
+ * Callback for canceling an operation.
*/
- PeerDisconnectImpl peer_disconnect;
+ OpCancelImpl cancel;
/**
- * Callback for canceling an operation by its ID.
+ * Callback called in case the CADET channel died.
*/
- CancelImpl cancel;
+ OpChannelDeathImpl channel_death;
- CopyStateImpl copy_state;
};
@@ -341,27 +275,38 @@ struct ElementEntry
};
+/**
+ * A listener is inhabited by a client, and waits for evaluation
+ * requests from remote peers.
+ */
struct Listener;
/**
- * Possible set operations.
+ * State we keep per client.
*/
-enum OperationType {
+struct ClientState
+{
/**
- * Operation type unknown.
+ * Set, if associated with the client, otherwise NULL.
*/
- OT_UNKNOWN = 0,
+ struct Set *set;
/**
- * We are performing a union.
+ * Listener, if associated with the client, otherwise NULL.
*/
- OT_UNION,
+ struct Listener *listener;
/**
- * We are performing an intersection.
+ * Client handle.
*/
- OT_INTERSECTION
+ struct GNUNET_SERVICE_Client *client;
+
+ /**
+ * Message queue.
+ */
+ struct GNUNET_MQ_Handle *mq;
+
};
@@ -370,12 +315,16 @@ enum OperationType {
*/
struct Operation
{
+
/**
- * V-Table for the operation belonging to the tunnel contest.
- *
- * Used for all operation specific operations after receiving the ops request
+ * Kept in a DLL of the listener, if @e listener is non-NULL.
*/
- const struct SetVT *vt;
+ struct Operation *next;
+
+ /**
+ * Kept in a DLL of the listener, if @e listener is non-NULL.
+ */
+ struct Operation *prev;
/**
* Channel to the peer.
@@ -393,11 +342,15 @@ struct Operation
struct GNUNET_MQ_Handle *mq;
/**
- * Detail information about the set operation, including the set to
- * use. When 'spec' is NULL, the operation is not yet entirely
- * initialized.
+ * Context message, may be NULL.
+ */
+ struct GNUNET_MessageHeader *context_msg;
+
+ /**
+ * Set associated with the operation, NULL until the spec has been
+ * associated with a set.
*/
- struct OperationSpecification *spec;
+ struct Set *set;
/**
* Operation-specific operation state. Note that the exact
@@ -407,16 +360,6 @@ struct Operation
struct OperationState *state;
/**
- * Evaluate operations are held in a linked list.
- */
- struct Operation *next;
-
- /**
- * Evaluate operations are held in a linked list.
- */
- struct Operation *prev;
-
- /**
* The identity of the requesting peer. Needs to
* be stored here as the op spec might not have been created yet.
*/
@@ -429,9 +372,48 @@ struct Operation
struct GNUNET_SCHEDULER_Task *timeout_task;
/**
- * What type of operation is this?
+ * Salt to use for the operation.
+ */
+ uint32_t salt;
+
+ /**
+ * Remote peers element count
+ */
+ uint32_t remote_element_count;
+
+ /**
+ * ID used to identify an operation between service and client
+ */
+ uint32_t client_request_id;
+
+ /**
+ * When are elements sent to the client, and which elements are sent?
*/
- enum OperationType type;
+ enum GNUNET_SET_ResultMode result_mode;
+
+ /**
+ * Always use delta operation instead of sending full sets,
+ * even it it's less efficient.
+ */
+ int force_delta;
+
+ /**
+ * Always send full sets, even if delta operations would
+ * be more efficient.
+ */
+ int force_full;
+
+ /**
+ * #GNUNET_YES to fail operations where Byzantine faults
+ * are suspected
+ */
+ int byzantine;
+
+ /**
+ * Lower bound for the set size, used only when
+ * byzantine mode is enabled.
+ */
+ int byzantine_lower_bound;
/**
* Unique request id for the request from a remote peer, sent to the
@@ -441,45 +423,26 @@ struct Operation
uint32_t suggest_id;
/**
- * #GNUNET_YES if this is not a "real" set operation yet, and we still
- * need to wait for the other peer to give us more details.
- */
- int is_incoming;
-
- /**
* Generation in which the operation handle
* was created.
*/
unsigned int generation_created;
- /**
- * Incremented whenever (during shutdown) some component still
- * needs to do something with this before the operation is freed.
- * (Used as a reference counter, but only during termination.)
- */
- unsigned int keep;
};
/**
- * SetContent stores the actual set elements,
- * which may be shared by multiple generations derived
- * from one set.
+ * SetContent stores the actual set elements, which may be shared by
+ * multiple generations derived from one set.
*/
struct SetContent
{
- /**
- * Number of references to the content.
- */
- unsigned int refcount;
/**
* Maps `struct GNUNET_HashCode *` to `struct ElementEntry *`.
*/
struct GNUNET_CONTAINER_MultiHashMap *elements;
- unsigned int latest_generation;
-
/**
* Mutations requested by the client that we're
* unable to execute right now because we're iterating
@@ -495,6 +458,16 @@ struct SetContent
struct PendingMutation *pending_mutations_tail;
/**
+ * Number of references to the content.
+ */
+ unsigned int refcount;
+
+ /**
+ * FIXME: document!
+ */
+ unsigned int latest_generation;
+
+ /**
* Number of concurrently active iterators.
*/
int iterator_count;
@@ -515,11 +488,24 @@ struct GenerationRange
};
+/**
+ * Information about a mutation to apply to a set.
+ */
struct PendingMutation
{
+ /**
+ * Mutations are kept in a DLL.
+ */
struct PendingMutation *prev;
+
+ /**
+ * Mutations are kept in a DLL.
+ */
struct PendingMutation *next;
+ /**
+ * Set this mutation is about.
+ */
struct Set *set;
/**
@@ -527,7 +513,7 @@ struct PendingMutation
* May only be a #GNUNET_MESSAGE_TYPE_SET_ADD or
* #GNUNET_MESSAGE_TYPE_SET_REMOVE.
*/
- struct GNUNET_MessageHeader *mutation_message;
+ struct GNUNET_SET_ElementMessage *msg;
};
@@ -551,12 +537,13 @@ struct Set
* Client that owns the set. Only one client may own a set,
* and there can only be one set per client.
*/
- struct GNUNET_SERVICE_Client *client;
+ struct ClientState *cs;
/**
- * Message queue for the client.
+ * Content, possibly shared by multiple sets,
+ * and thus reference counted.
*/
- struct GNUNET_MQ_Handle *client_mq;
+ struct SetContent *content;
/**
* Virtual table for this set. Determined by the operation type of
@@ -589,9 +576,9 @@ struct Set
struct Operation *ops_tail;
/**
- * What type of operation is this set for?
+ * List of generations we have to exclude, due to lazy copies.
*/
- enum OperationType type;
+ struct GenerationRange *excluded_generations;
/**
* Current generation, that is, number of previously executed
@@ -600,11 +587,6 @@ struct Set
unsigned int current_generation;
/**
- * List of generations we have to exclude, due to lazy copies.
- */
- struct GenerationRange *excluded_generations;
-
- /**
* Number of elements in array @a excluded_generations.
*/
unsigned int excluded_generations_size;
@@ -615,21 +597,16 @@ struct Set
enum GNUNET_SET_OperationType operation;
/**
- * Each @e iter is assigned a unique number, so that the client
- * can distinguish iterations.
- */
- uint16_t iteration_id;
-
- /**
* Generation we're currently iteration over.
*/
unsigned int iter_generation;
/**
- * Content, possibly shared by multiple sets,
- * and thus reference counted.
+ * Each @e iter is assigned a unique number, so that the client
+ * can distinguish iterations.
*/
- struct SetContent *content;
+ uint16_t iteration_id;
+
};
@@ -637,10 +614,14 @@ extern struct GNUNET_STATISTICS_Handle *_GSS_statistics;
/**
- * Destroy the given operation. Call the implementation-specific
- * cancel function of the operation. Disconnects from the remote
- * peer. Does not disconnect the client, as there may be multiple
- * operations per set.
+ * Destroy the given operation. Used for any operation where both
+ * peers were known and that thus actually had a vt and channel. Must
+ * not be used for operations where 'listener' is still set and we do
+ * not know the other peer.
+ *
+ * Call the implementation-specific cancel function of the operation.
+ * Disconnects from the remote peer. Does not disconnect the client,
+ * as there may be multiple operations per set.
*
* @param op operation to destroy
* @param gc #GNUNET_YES to perform garbage collection on the set
@@ -668,10 +649,13 @@ const struct SetVT *
_GSS_intersection_vt (void);
-int
-_GSS_is_element_of_set (struct ElementEntry *ee,
- struct Set *set);
-
+/**
+ * Is element @a ee part of the set used by @a op?
+ *
+ * @param ee element to test
+ * @param op operation the defines the set and its generation
+ * @return #GNUNET_YES if the element is in the set, #GNUNET_NO if not
+ */
int
_GSS_is_element_of_operation (struct ElementEntry *ee,
struct Operation *op);
diff --git a/src/set/gnunet-service-set_intersection.c b/src/set/gnunet-service-set_intersection.c
index bb369a81f9..9dc4217921 100644
--- a/src/set/gnunet-service-set_intersection.c
+++ b/src/set/gnunet-service-set_intersection.c
@@ -56,6 +56,18 @@ enum IntersectionOperationPhase
PHASE_BF_EXCHANGE,
/**
+ * We must next send the P2P DONE message (after finishing mostly
+ * with the local client). Then we will wait for the channel to close.
+ */
+ PHASE_MUST_SEND_DONE,
+
+ /**
+ * We have received the P2P DONE message, and must finish with the
+ * local client before terminating the channel.
+ */
+ PHASE_DONE_RECEIVED,
+
+ /**
* The protocol is over. Results may still have to be sent to the
* client.
*/
@@ -162,6 +174,13 @@ struct OperationState
* Did we send the client that we are done?
*/
int client_done_sent;
+
+ /**
+ * Set whenever we reach the state where the death of the
+ * channel is perfectly find and should NOT result in the
+ * operation being cancelled.
+ */
+ int channel_death_expected;
};
@@ -193,12 +212,12 @@ send_client_removed_element (struct Operation *op,
struct GNUNET_MQ_Envelope *ev;
struct GNUNET_SET_ResultMessage *rm;
- if (GNUNET_SET_RESULT_REMOVED != op->spec->result_mode)
+ if (GNUNET_SET_RESULT_REMOVED != op->result_mode)
return; /* Wrong mode for transmitting removed elements */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sending removed element (size %u) to client\n",
element->size);
- GNUNET_assert (0 != op->spec->client_request_id);
+ GNUNET_assert (0 != op->client_request_id);
ev = GNUNET_MQ_msg_extra (rm,
element->size,
GNUNET_MESSAGE_TYPE_SET_RESULT);
@@ -208,12 +227,12 @@ send_client_removed_element (struct Operation *op,
return;
}
rm->result_status = htons (GNUNET_SET_STATUS_OK);
- rm->request_id = htonl (op->spec->client_request_id);
+ rm->request_id = htonl (op->client_request_id);
rm->element_type = element->element_type;
GNUNET_memcpy (&rm[1],
- element->data,
- element->size);
- GNUNET_MQ_send (op->spec->set->client_mq,
+ element->data,
+ element->size);
+ GNUNET_MQ_send (op->set->cs->mq,
ev);
}
@@ -397,9 +416,9 @@ fail_intersection_operation (struct Operation *op)
ev = GNUNET_MQ_msg (msg,
GNUNET_MESSAGE_TYPE_SET_RESULT);
msg->result_status = htons (GNUNET_SET_STATUS_FAILURE);
- msg->request_id = htonl (op->spec->client_request_id);
+ msg->request_id = htonl (op->client_request_id);
msg->element_type = htons (0);
- GNUNET_MQ_send (op->spec->set->client_mq,
+ GNUNET_MQ_send (op->set->cs->mq,
ev);
_GSS_operation_destroy (op,
GNUNET_YES);
@@ -428,8 +447,8 @@ send_bloomfilter (struct Operation *op)
should use more bits to maximize its set reduction
potential and minimize overall bandwidth consumption. */
bf_elementbits = 2 + ceil (log2((double)
- (op->spec->remote_element_count /
- (double) op->state->my_element_count)));
+ (op->remote_element_count /
+ (double) op->state->my_element_count)));
if (bf_elementbits < 1)
bf_elementbits = 1; /* make sure k is not 0 */
/* optimize BF-size to ~50% of bits set */
@@ -515,12 +534,14 @@ send_client_done_and_destroy (void *cls)
struct GNUNET_MQ_Envelope *ev;
struct GNUNET_SET_ResultMessage *rm;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Intersection succeeded, sending DONE to local client\n");
ev = GNUNET_MQ_msg (rm,
GNUNET_MESSAGE_TYPE_SET_RESULT);
- rm->request_id = htonl (op->spec->client_request_id);
+ rm->request_id = htonl (op->client_request_id);
rm->result_status = htons (GNUNET_SET_STATUS_DONE);
rm->element_type = htons (0);
- GNUNET_MQ_send (op->spec->set->client_mq,
+ GNUNET_MQ_send (op->set->cs->mq,
ev);
_GSS_operation_destroy (op,
GNUNET_YES);
@@ -528,6 +549,53 @@ send_client_done_and_destroy (void *cls)
/**
+ * Remember that we are done dealing with the local client
+ * AND have sent the other peer our message that we are done,
+ * so we are not just waiting for the channel to die before
+ * telling the local client that we are done as our last act.
+ *
+ * @param cls the `struct Operation`.
+ */
+static void
+finished_local_operations (void *cls)
+{
+ struct Operation *op = cls;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "DONE sent to other peer, now waiting for other end to close the channel\n");
+ op->state->phase = PHASE_FINISHED;
+ op->state->channel_death_expected = GNUNET_YES;
+}
+
+
+/**
+ * Notify the other peer that we are done. Once this message
+ * is out, we still need to notify the local client that we
+ * are done.
+ *
+ * @param op operation to notify for.
+ */
+static void
+send_p2p_done (struct Operation *op)
+{
+ struct GNUNET_MQ_Envelope *ev;
+ struct IntersectionDoneMessage *idm;
+
+ GNUNET_assert (PHASE_MUST_SEND_DONE == op->state->phase);
+ GNUNET_assert (GNUNET_NO == op->state->channel_death_expected);
+ ev = GNUNET_MQ_msg (idm,
+ GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE);
+ idm->final_element_count = htonl (op->state->my_element_count);
+ idm->element_xor_hash = op->state->my_xor;
+ GNUNET_MQ_notify_sent (ev,
+ &finished_local_operations,
+ op);
+ GNUNET_MQ_send (op->mq,
+ ev);
+}
+
+
+/**
* Send all elements in the full result iterator.
*
* @param cls the `struct Operation *`
@@ -550,10 +618,21 @@ send_remaining_elements (void *cls)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sending done and destroy because iterator ran out\n");
- op->keep--;
GNUNET_CONTAINER_multihashmap_iterator_destroy (op->state->full_result_iter);
op->state->full_result_iter = NULL;
- send_client_done_and_destroy (op);
+ if (PHASE_DONE_RECEIVED == op->state->phase)
+ {
+ op->state->phase = PHASE_FINISHED;
+ send_client_done_and_destroy (op);
+ }
+ else if (PHASE_MUST_SEND_DONE == op->state->phase)
+ {
+ send_p2p_done (op);
+ }
+ else
+ {
+ GNUNET_assert (0);
+ }
return;
}
ee = nxt;
@@ -562,48 +641,136 @@ send_remaining_elements (void *cls)
"Sending element %s:%u to client (full set)\n",
GNUNET_h2s (&ee->element_hash),
element->size);
- GNUNET_assert (0 != op->spec->client_request_id);
+ GNUNET_assert (0 != op->client_request_id);
ev = GNUNET_MQ_msg_extra (rm,
element->size,
GNUNET_MESSAGE_TYPE_SET_RESULT);
GNUNET_assert (NULL != ev);
rm->result_status = htons (GNUNET_SET_STATUS_OK);
- rm->request_id = htonl (op->spec->client_request_id);
+ rm->request_id = htonl (op->client_request_id);
rm->element_type = element->element_type;
GNUNET_memcpy (&rm[1],
- element->data,
- element->size);
+ element->data,
+ element->size);
GNUNET_MQ_notify_sent (ev,
&send_remaining_elements,
op);
- GNUNET_MQ_send (op->spec->set->client_mq,
+ GNUNET_MQ_send (op->set->cs->mq,
ev);
}
/**
- * Inform the peer that this operation is complete.
+ * Fills the "my_elements" hashmap with the initial set of
+ * (non-deleted) elements from the set of the specification.
*
- * @param op the intersection operation to fail
+ * @param cls closure with the `struct Operation *`
+ * @param key current key code for the element
+ * @param value value in the hash map with the `struct ElementEntry *`
+ * @return #GNUNET_YES (we should continue to iterate)
+ */
+static int
+initialize_map_unfiltered (void *cls,
+ const struct GNUNET_HashCode *key,
+ void *value)
+{
+ struct ElementEntry *ee = value;
+ struct Operation *op = cls;
+
+ if (GNUNET_NO == _GSS_is_element_of_operation (ee, op))
+ return GNUNET_YES; /* element not live in operation's generation */
+ GNUNET_CRYPTO_hash_xor (&op->state->my_xor,
+ &ee->element_hash,
+ &op->state->my_xor);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Initial full initialization of my_elements, adding %s:%u\n",
+ GNUNET_h2s (&ee->element_hash),
+ ee->element.size);
+ GNUNET_break (GNUNET_YES ==
+ GNUNET_CONTAINER_multihashmap_put (op->state->my_elements,
+ &ee->element_hash,
+ ee,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
+ return GNUNET_YES;
+}
+
+
+/**
+ * Send our element count to the peer, in case our element count is
+ * lower than his.
+ *
+ * @param op intersection operation
*/
static void
-send_peer_done (struct Operation *op)
+send_element_count (struct Operation *op)
{
struct GNUNET_MQ_Envelope *ev;
- struct IntersectionDoneMessage *idm;
+ struct IntersectionElementInfoMessage *msg;
- op->state->phase = PHASE_FINISHED;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Intersection succeeded, sending DONE\n");
- GNUNET_CONTAINER_bloomfilter_free (op->state->local_bf);
- op->state->local_bf = NULL;
+ "Sending our element count (%u)\n",
+ op->state->my_element_count);
+ ev = GNUNET_MQ_msg (msg,
+ GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO);
+ msg->sender_element_count = htonl (op->state->my_element_count);
+ GNUNET_MQ_send (op->mq, ev);
+}
- ev = GNUNET_MQ_msg (idm,
- GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE);
- idm->final_element_count = htonl (op->state->my_element_count);
- idm->element_xor_hash = op->state->my_xor;
- GNUNET_MQ_send (op->mq,
- ev);
+
+/**
+ * We go first, initialize our map with all elements and
+ * send the first Bloom filter.
+ *
+ * @param op operation to start exchange for
+ */
+static void
+begin_bf_exchange (struct Operation *op)
+{
+ op->state->phase = PHASE_BF_EXCHANGE;
+ GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements,
+ &initialize_map_unfiltered,
+ op);
+ send_bloomfilter (op);
+}
+
+
+/**
+ * Handle the initial `struct IntersectionElementInfoMessage` from a
+ * remote peer.
+ *
+ * @param cls the intersection operation
+ * @param mh the header of the message
+ */
+void
+handle_intersection_p2p_element_info (void *cls,
+ const struct IntersectionElementInfoMessage *msg)
+{
+ struct Operation *op = cls;
+
+ if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation)
+ {
+ GNUNET_break_op (0);
+ fail_intersection_operation(op);
+ return;
+ }
+ op->remote_element_count = ntohl (msg->sender_element_count);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received remote element count (%u), I have %u\n",
+ op->remote_element_count,
+ op->state->my_element_count);
+ if ( ( (PHASE_INITIAL != op->state->phase) &&
+ (PHASE_COUNT_SENT != op->state->phase) ) ||
+ (op->state->my_element_count > op->remote_element_count) ||
+ (0 == op->state->my_element_count) ||
+ (0 == op->remote_element_count) )
+ {
+ GNUNET_break_op (0);
+ fail_intersection_operation(op);
+ return;
+ }
+ GNUNET_break (NULL == op->state->remote_bf);
+ begin_bf_exchange (op);
+ GNUNET_CADET_receive_done (op->channel);
}
@@ -618,9 +785,9 @@ process_bf (struct Operation *op)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received BF in phase %u, foreign count is %u, my element count is %u/%u\n",
op->state->phase,
- op->spec->remote_element_count,
+ op->remote_element_count,
op->state->my_element_count,
- GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements));
+ GNUNET_CONTAINER_multihashmap_size (op->set->content->elements));
switch (op->state->phase)
{
case PHASE_INITIAL:
@@ -631,7 +798,7 @@ process_bf (struct Operation *op)
/* This is the first BF being sent, build our initial map with
filtering in place */
op->state->my_element_count = 0;
- GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements,
+ GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements,
&filtered_map_initialization,
op);
break;
@@ -641,6 +808,14 @@ process_bf (struct Operation *op)
&iterator_bf_reduce,
op);
break;
+ case PHASE_MUST_SEND_DONE:
+ GNUNET_break_op (0);
+ fail_intersection_operation(op);
+ return;
+ case PHASE_DONE_RECEIVED:
+ GNUNET_break_op (0);
+ fail_intersection_operation(op);
+ return;
case PHASE_FINISHED:
GNUNET_break_op (0);
fail_intersection_operation(op);
@@ -650,13 +825,28 @@ process_bf (struct Operation *op)
op->state->remote_bf = NULL;
if ( (0 == op->state->my_element_count) || /* fully disjoint */
- ( (op->state->my_element_count == op->spec->remote_element_count) &&
+ ( (op->state->my_element_count == op->remote_element_count) &&
(0 == memcmp (&op->state->my_xor,
&op->state->other_xor,
sizeof (struct GNUNET_HashCode))) ) )
{
/* we are done */
- send_peer_done (op);
+ op->state->phase = PHASE_MUST_SEND_DONE;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Intersection succeeded, sending DONE to other peer\n");
+ GNUNET_CONTAINER_bloomfilter_free (op->state->local_bf);
+ op->state->local_bf = NULL;
+ if (GNUNET_SET_RESULT_FULL == op->result_mode)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending full result set (%u elements)\n",
+ GNUNET_CONTAINER_multihashmap_size (op->state->my_elements));
+ op->state->full_result_iter
+ = GNUNET_CONTAINER_multihashmap_iterator_create (op->state->my_elements);
+ send_remaining_elements (op);
+ return;
+ }
+ send_p2p_done (op);
return;
}
op->state->phase = PHASE_BF_EXCHANGE;
@@ -677,7 +867,7 @@ check_intersection_p2p_bf (void *cls,
{
struct Operation *op = cls;
- if (OT_INTERSECTION != op->type)
+ if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation)
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@@ -727,7 +917,7 @@ handle_intersection_p2p_bf (void *cls,
bf_size,
bf_bits_per_element);
op->state->salt = ntohl (msg->sender_mutator);
- op->spec->remote_element_count = ntohl (msg->sender_element_count);
+ op->remote_element_count = ntohl (msg->sender_element_count);
process_bf (op);
break;
}
@@ -740,7 +930,7 @@ handle_intersection_p2p_bf (void *cls,
op->state->bf_bits_per_element = bf_bits_per_element;
op->state->bf_data_offset = 0;
op->state->salt = ntohl (msg->sender_mutator);
- op->spec->remote_element_count = ntohl (msg->sender_element_count);
+ op->remote_element_count = ntohl (msg->sender_element_count);
}
else
{
@@ -749,7 +939,7 @@ handle_intersection_p2p_bf (void *cls,
(op->state->bf_bits_per_element != bf_bits_per_element) ||
(op->state->bf_data_offset + chunk_size > bf_size) ||
(op->state->salt != ntohl (msg->sender_mutator)) ||
- (op->spec->remote_element_count != ntohl (msg->sender_element_count)) )
+ (op->remote_element_count != ntohl (msg->sender_element_count)) )
{
GNUNET_break_op (0);
fail_intersection_operation (op);
@@ -783,147 +973,6 @@ handle_intersection_p2p_bf (void *cls,
/**
- * Fills the "my_elements" hashmap with the initial set of
- * (non-deleted) elements from the set of the specification.
- *
- * @param cls closure with the `struct Operation *`
- * @param key current key code for the element
- * @param value value in the hash map with the `struct ElementEntry *`
- * @return #GNUNET_YES (we should continue to iterate)
- */
-static int
-initialize_map_unfiltered (void *cls,
- const struct GNUNET_HashCode *key,
- void *value)
-{
- struct ElementEntry *ee = value;
- struct Operation *op = cls;
-
- if (GNUNET_NO == _GSS_is_element_of_operation (ee, op))
- return GNUNET_YES; /* element not live in operation's generation */
- GNUNET_CRYPTO_hash_xor (&op->state->my_xor,
- &ee->element_hash,
- &op->state->my_xor);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Initial full initialization of my_elements, adding %s:%u\n",
- GNUNET_h2s (&ee->element_hash),
- ee->element.size);
- GNUNET_break (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_put (op->state->my_elements,
- &ee->element_hash,
- ee,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
- return GNUNET_YES;
-}
-
-
-/**
- * Send our element count to the peer, in case our element count is
- * lower than his.
- *
- * @param op intersection operation
- */
-static void
-send_element_count (struct Operation *op)
-{
- struct GNUNET_MQ_Envelope *ev;
- struct IntersectionElementInfoMessage *msg;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending our element count (%u)\n",
- op->state->my_element_count);
- ev = GNUNET_MQ_msg (msg,
- GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO);
- msg->sender_element_count = htonl (op->state->my_element_count);
- GNUNET_MQ_send (op->mq, ev);
-}
-
-
-/**
- * We go first, initialize our map with all elements and
- * send the first Bloom filter.
- *
- * @param op operation to start exchange for
- */
-static void
-begin_bf_exchange (struct Operation *op)
-{
- op->state->phase = PHASE_BF_EXCHANGE;
- GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements,
- &initialize_map_unfiltered,
- op);
- send_bloomfilter (op);
-}
-
-
-/**
- * Handle the initial `struct IntersectionElementInfoMessage` from a
- * remote peer.
- *
- * @param cls the intersection operation
- * @param mh the header of the message
- */
-void
-handle_intersection_p2p_element_info (void *cls,
- const struct IntersectionElementInfoMessage *msg)
-{
- struct Operation *op = cls;
-
- if (OT_INTERSECTION != op->type)
- {
- GNUNET_break_op (0);
- fail_intersection_operation(op);
- return;
- }
- op->spec->remote_element_count = ntohl (msg->sender_element_count);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received remote element count (%u), I have %u\n",
- op->spec->remote_element_count,
- op->state->my_element_count);
- if ( ( (PHASE_INITIAL != op->state->phase) &&
- (PHASE_COUNT_SENT != op->state->phase) ) ||
- (op->state->my_element_count > op->spec->remote_element_count) ||
- (0 == op->state->my_element_count) ||
- (0 == op->spec->remote_element_count) )
- {
- GNUNET_break_op (0);
- fail_intersection_operation(op);
- return;
- }
- GNUNET_break (NULL == op->state->remote_bf);
- begin_bf_exchange (op);
- GNUNET_CADET_receive_done (op->channel);
-}
-
-
-/**
- * Send a result message to the client indicating that the operation
- * is over. After the result done message has been sent to the
- * client, destroy the evaluate operation.
- *
- * @param op intersection operation
- */
-static void
-finish_and_destroy (struct Operation *op)
-{
- GNUNET_assert (GNUNET_NO == op->state->client_done_sent);
-
- if (GNUNET_SET_RESULT_FULL == op->spec->result_mode)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending full result set (%u elements)\n",
- GNUNET_CONTAINER_multihashmap_size (op->state->my_elements));
- op->state->full_result_iter
- = GNUNET_CONTAINER_multihashmap_iterator_create (op->state->my_elements);
- op->keep++;
- send_remaining_elements (op);
- return;
- }
- send_client_done_and_destroy (op);
-}
-
-
-/**
* Remove all elements from our hashmap.
*
* @param cls closure with the `struct Operation *`
@@ -970,10 +1019,10 @@ handle_intersection_p2p_done (void *cls,
{
struct Operation *op = cls;
- if (OT_INTERSECTION != op->type)
+ if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation)
{
GNUNET_break_op (0);
- fail_intersection_operation(op);
+ fail_intersection_operation (op);
return;
}
if (PHASE_BF_EXCHANGE != op->state->phase)
@@ -1005,9 +1054,22 @@ handle_intersection_p2p_done (void *cls,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Got IntersectionDoneMessage, have %u elements in intersection\n",
op->state->my_element_count);
- op->state->phase = PHASE_FINISHED;
- finish_and_destroy (op);
+ op->state->phase = PHASE_DONE_RECEIVED;
GNUNET_CADET_receive_done (op->channel);
+
+ GNUNET_assert (GNUNET_NO == op->state->client_done_sent);
+ if (GNUNET_SET_RESULT_FULL == op->result_mode)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending full result set to client (%u elements)\n",
+ GNUNET_CONTAINER_multihashmap_size (op->state->my_elements));
+ op->state->full_result_iter
+ = GNUNET_CONTAINER_multihashmap_iterator_create (op->state->my_elements);
+ send_remaining_elements (op);
+ return;
+ }
+ op->state->phase = PHASE_FINISHED;
+ send_client_done_and_destroy (op);
}
@@ -1018,24 +1080,16 @@ handle_intersection_p2p_done (void *cls,
* begin the evaluation
* @param opaque_context message to be transmitted to the listener
* to convince him to accept, may be NULL
+ * @return operation-specific state to keep in @a op
*/
-static void
+static struct OperationState *
intersection_evaluate (struct Operation *op,
const struct GNUNET_MessageHeader *opaque_context)
{
+ struct OperationState *state;
struct GNUNET_MQ_Envelope *ev;
struct OperationRequestMessage *msg;
- op->state = GNUNET_new (struct OperationState);
- /* we started the operation, thus we have to send the operation request */
- op->state->phase = PHASE_INITIAL;
- op->state->my_element_count = op->spec->set->state->current_set_element_count;
- op->state->my_elements
- = GNUNET_CONTAINER_multihashmap_create (op->state->my_element_count,
- GNUNET_YES);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Initiating intersection operation evaluation\n");
ev = GNUNET_MQ_msg_nested_mh (msg,
GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST,
opaque_context);
@@ -1043,20 +1097,30 @@ intersection_evaluate (struct Operation *op,
{
/* the context message is too large!? */
GNUNET_break (0);
- GNUNET_SERVICE_client_drop (op->spec->set->client);
- return;
+ return NULL;
}
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Initiating intersection operation evaluation\n");
+ state = GNUNET_new (struct OperationState);
+ /* we started the operation, thus we have to send the operation request */
+ state->phase = PHASE_INITIAL;
+ state->my_element_count = op->set->state->current_set_element_count;
+ state->my_elements
+ = GNUNET_CONTAINER_multihashmap_create (state->my_element_count,
+ GNUNET_YES);
+
msg->operation = htonl (GNUNET_SET_OPERATION_INTERSECTION);
- msg->element_count = htonl (op->state->my_element_count);
+ msg->element_count = htonl (state->my_element_count);
GNUNET_MQ_send (op->mq,
ev);
- op->state->phase = PHASE_COUNT_SENT;
+ state->phase = PHASE_COUNT_SENT;
if (NULL != opaque_context)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sent op request with context message\n");
else
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sent op request without context message\n");
+ return state;
}
@@ -1066,53 +1130,33 @@ intersection_evaluate (struct Operation *op,
*
* @param op operation that will be accepted as an intersection operation
*/
-static void
+static struct OperationState *
intersection_accept (struct Operation *op)
{
+ struct OperationState *state;
+
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Accepting set intersection operation\n");
- op->state = GNUNET_new (struct OperationState);
- op->state->phase = PHASE_INITIAL;
- op->state->my_element_count
- = op->spec->set->state->current_set_element_count;
- GNUNET_assert (NULL == op->state->my_elements);
- op->state->my_elements
- = GNUNET_CONTAINER_multihashmap_create (GNUNET_MIN (op->state->my_element_count,
- op->spec->remote_element_count),
+ state = GNUNET_new (struct OperationState);
+ state->phase = PHASE_INITIAL;
+ state->my_element_count
+ = op->set->state->current_set_element_count;
+ state->my_elements
+ = GNUNET_CONTAINER_multihashmap_create (GNUNET_MIN (state->my_element_count,
+ op->remote_element_count),
GNUNET_YES);
- if (op->spec->remote_element_count < op->state->my_element_count)
+ op->state = state;
+ if (op->remote_element_count < state->my_element_count)
{
/* If the other peer (Alice) has fewer elements than us (Bob),
we just send the count as Alice should send the first BF */
send_element_count (op);
- op->state->phase = PHASE_COUNT_SENT;
- return;
+ state->phase = PHASE_COUNT_SENT;
+ return state;
}
/* We have fewer elements, so we start with the BF */
begin_bf_exchange (op);
-}
-
-
-/**
- * Handler for peer-disconnects, notifies the client about the aborted
- * operation. If we did not expect anything from the other peer, we
- * gracefully terminate the operation.
- *
- * @param op the destroyed operation
- */
-static void
-intersection_peer_disconnect (struct Operation *op)
-{
- if (PHASE_FINISHED != op->state->phase)
- {
- fail_intersection_operation (op);
- return;
- }
- /* the session has already been concluded */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Other peer disconnected (finished)\n");
- if (GNUNET_NO == op->state->client_done_sent)
- finish_and_destroy (op);
+ return state;
}
@@ -1215,6 +1259,28 @@ intersection_remove (struct SetState *set_state,
/**
+ * Callback for channel death for the intersection operation.
+ *
+ * @param op operation that lost the channel
+ */
+static void
+intersection_channel_death (struct Operation *op)
+{
+ if (GNUNET_YES == op->state->channel_death_expected)
+ {
+ /* oh goodie, we are done! */
+ send_client_done_and_destroy (op);
+ }
+ else
+ {
+ /* sorry, channel went down early, too bad. */
+ _GSS_operation_destroy (op,
+ GNUNET_YES);
+ }
+}
+
+
+/**
* Get the table with implementing functions for set intersection.
*
* @return the operation specific VTable
@@ -1229,8 +1295,8 @@ _GSS_intersection_vt ()
.destroy_set = &intersection_set_destroy,
.evaluate = &intersection_evaluate,
.accept = &intersection_accept,
- .peer_disconnect = &intersection_peer_disconnect,
.cancel = &intersection_op_cancel,
+ .channel_death = &intersection_channel_death,
};
return &intersection_vt;
diff --git a/src/set/gnunet-service-set_union.c b/src/set/gnunet-service-set_union.c
index 1ff3d77164..fc7e578e68 100644
--- a/src/set/gnunet-service-set_union.c
+++ b/src/set/gnunet-service-set_union.c
@@ -368,9 +368,10 @@ fail_union_operation (struct Operation *op)
"union operation failed\n");
ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_RESULT);
msg->result_status = htons (GNUNET_SET_STATUS_FAILURE);
- msg->request_id = htonl (op->spec->client_request_id);
+ msg->request_id = htonl (op->client_request_id);
msg->element_type = htons (0);
- GNUNET_MQ_send (op->spec->set->client_mq, ev);
+ GNUNET_MQ_send (op->set->cs->mq,
+ ev);
_GSS_operation_destroy (op, GNUNET_YES);
}
@@ -401,7 +402,14 @@ get_ibf_key (const struct GNUNET_HashCode *src)
*/
struct GetElementContext
{
+ /**
+ * FIXME.
+ */
struct GNUNET_HashCode hash;
+
+ /**
+ * FIXME.
+ */
struct KeyEntry *k;
};
@@ -504,6 +512,9 @@ op_register_element (struct Operation *op,
}
+/**
+ * FIXME.
+ */
static void
salt_key (const struct IBF_Key *k_in,
uint32_t salt,
@@ -517,6 +528,9 @@ salt_key (const struct IBF_Key *k_in,
}
+/**
+ * FIXME.
+ */
static void
unsalt_key (const struct IBF_Key *k_in,
uint32_t salt,
@@ -550,7 +564,9 @@ prepare_ibf_iterator (void *cls,
(void *) op,
(unsigned long) ke->ibf_key.key_val,
GNUNET_h2s (&ke->element->element_hash));
- salt_key (&ke->ibf_key, op->state->salt_send, &salted_key);
+ salt_key (&ke->ibf_key,
+ op->state->salt_send,
+ &salted_key);
ibf_insert (op->state->local_ibf, salted_key);
return GNUNET_YES;
}
@@ -576,12 +592,14 @@ init_key_to_element_iterator (void *cls,
/* make sure that the element belongs to the set at the time
* of creating the operation */
- if (GNUNET_NO == _GSS_is_element_of_operation (ee, op))
+ if (GNUNET_NO ==
+ _GSS_is_element_of_operation (ee,
+ op))
return GNUNET_YES;
-
GNUNET_assert (GNUNET_NO == ee->remote);
-
- op_register_element (op, ee, GNUNET_NO);
+ op_register_element (op,
+ ee,
+ GNUNET_NO);
return GNUNET_YES;
}
@@ -598,9 +616,11 @@ initialize_key_to_element (struct Operation *op)
unsigned int len;
GNUNET_assert (NULL == op->state->key_to_element);
- len = GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements);
+ len = GNUNET_CONTAINER_multihashmap_size (op->set->content->elements);
op->state->key_to_element = GNUNET_CONTAINER_multihashmap32_create (len + 1);
- GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements, init_key_to_element_iterator, op);
+ GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements,
+ &init_key_to_element_iterator,
+ op);
}
@@ -707,44 +727,6 @@ send_ibf (struct Operation *op,
/**
- * Send a strata estimator to the remote peer.
- *
- * @param op the union operation with the remote peer
- */
-static void
-send_strata_estimator (struct Operation *op)
-{
- const struct StrataEstimator *se = op->state->se;
- struct GNUNET_MQ_Envelope *ev;
- struct StrataEstimatorMessage *strata_msg;
- char *buf;
- size_t len;
- uint16_t type;
-
- buf = GNUNET_malloc (se->strata_count * IBF_BUCKET_SIZE * se->ibf_size);
- len = strata_estimator_write (op->state->se,
- buf);
- if (len < se->strata_count * IBF_BUCKET_SIZE * se->ibf_size)
- type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC;
- else
- type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE;
- ev = GNUNET_MQ_msg_extra (strata_msg,
- len,
- type);
- GNUNET_memcpy (&strata_msg[1],
- buf,
- len);
- GNUNET_free (buf);
- strata_msg->set_size = GNUNET_htonll (GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements));
- GNUNET_MQ_send (op->mq,
- ev);
- op->state->phase = PHASE_EXPECT_IBF;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "sent SE, expecting IBF\n");
-}
-
-
-/**
* Compute the necessary order of an ibf
* from the size of the symmetric set difference.
*
@@ -777,7 +759,7 @@ get_order_from_difference (unsigned int diff)
* @return #GNUNET_YES (to continue iterating)
*/
static int
-send_element_iterator (void *cls,
+send_full_element_iterator (void *cls,
const struct GNUNET_HashCode *key,
void *value)
{
@@ -803,16 +785,23 @@ send_element_iterator (void *cls,
}
+/**
+ * Switch to full set transmission for @a op.
+ *
+ * @param op operation to switch to full set transmission.
+ */
static void
send_full_set (struct Operation *op)
{
struct GNUNET_MQ_Envelope *ev;
op->state->phase = PHASE_FULL_SENDING;
+ LOG (GNUNET_ERROR_TYPE_INFO,
+ "Dedicing to transmit the full set\n");
/* FIXME: use a more memory-friendly way of doing this with an
iterator, just as we do in the non-full case! */
- (void) GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements,
- &send_element_iterator,
+ (void) GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements,
+ &send_full_element_iterator,
op);
ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE);
GNUNET_MQ_send (op->mq,
@@ -923,15 +912,15 @@ handle_union_p2p_strata_estimator (void *cls,
}
}
- if ( (GNUNET_YES == op->spec->byzantine) &&
- (other_size < op->spec->byzantine_lower_bound) )
+ if ( (GNUNET_YES == op->byzantine) &&
+ (other_size < op->byzantine_lower_bound) )
{
GNUNET_break (0);
fail_union_operation (op);
return;
}
- if ( (GNUNET_YES == op->spec->force_full) ||
+ if ( (GNUNET_YES == op->force_full) ||
(diff > op->state->initial_size / 4) ||
(0 == other_size) )
{
@@ -1058,14 +1047,16 @@ decode_and_send (struct Operation *op)
GNUNET_assert (PHASE_INVENTORY_ACTIVE == op->state->phase);
if (GNUNET_OK !=
- prepare_ibf (op, op->state->remote_ibf->size))
+ prepare_ibf (op,
+ op->state->remote_ibf->size))
{
GNUNET_break (0);
/* allocation failed */
return GNUNET_SYSERR;
}
diff_ibf = ibf_dup (op->state->local_ibf);
- ibf_subtract (diff_ibf, op->state->remote_ibf);
+ ibf_subtract (diff_ibf,
+ op->state->remote_ibf);
ibf_destroy (op->state->remote_ibf);
op->state->remote_ibf = NULL;
@@ -1162,8 +1153,12 @@ decode_and_send (struct Operation *op)
if (1 == side)
{
struct IBF_Key unsalted_key;
- unsalt_key (&key, op->state->salt_receive, &unsalted_key);
- send_offers_for_key (op, unsalted_key);
+
+ unsalt_key (&key,
+ op->state->salt_receive,
+ &unsalted_key);
+ send_offers_for_key (op,
+ unsalted_key);
}
else if (-1 == side)
{
@@ -1211,7 +1206,7 @@ check_union_p2p_ibf (void *cls,
struct Operation *op = cls;
unsigned int buckets_in_message;
- if (OT_UNION != op->type)
+ if (GNUNET_SET_OPERATION_UNION != op->set->operation)
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@@ -1304,6 +1299,8 @@ handle_union_p2p_ibf (void *cls,
else
{
GNUNET_assert (op->state->phase == PHASE_EXPECT_IBF_CONT);
+ LOG (GNUNET_ERROR_TYPE_INFO,
+ "Received more of IBF\n");
}
GNUNET_assert (NULL != op->state->remote_ibf);
@@ -1351,7 +1348,7 @@ send_client_element (struct Operation *op,
LOG (GNUNET_ERROR_TYPE_DEBUG,
"sending element (size %u) to client\n",
element->size);
- GNUNET_assert (0 != op->spec->client_request_id);
+ GNUNET_assert (0 != op->client_request_id);
ev = GNUNET_MQ_msg_extra (rm, element->size, GNUNET_MESSAGE_TYPE_SET_RESULT);
if (NULL == ev)
{
@@ -1360,11 +1357,14 @@ send_client_element (struct Operation *op,
return;
}
rm->result_status = htons (status);
- rm->request_id = htonl (op->spec->client_request_id);
+ rm->request_id = htonl (op->client_request_id);
rm->element_type = htons (element->element_type);
rm->current_size = GNUNET_htonll (GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element));
- GNUNET_memcpy (&rm[1], element->data, element->size);
- GNUNET_MQ_send (op->spec->set->client_mq, ev);
+ GNUNET_memcpy (&rm[1],
+ element->data,
+ element->size);
+ GNUNET_MQ_send (op->set->cs->mq,
+ ev);
}
@@ -1381,14 +1381,19 @@ send_done_and_destroy (void *cls)
struct GNUNET_MQ_Envelope *ev;
struct GNUNET_SET_ResultMessage *rm;
- ev = GNUNET_MQ_msg (rm, GNUNET_MESSAGE_TYPE_SET_RESULT);
- rm->request_id = htonl (op->spec->client_request_id);
+ LOG (GNUNET_ERROR_TYPE_INFO,
+ "Signalling client that union operation is done\n");
+ ev = GNUNET_MQ_msg (rm,
+ GNUNET_MESSAGE_TYPE_SET_RESULT);
+ rm->request_id = htonl (op->client_request_id);
rm->result_status = htons (GNUNET_SET_STATUS_DONE);
rm->element_type = htons (0);
rm->current_size = GNUNET_htonll (GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element));
- GNUNET_MQ_send (op->spec->set->client_mq, ev);
+ GNUNET_MQ_send (op->set->cs->mq,
+ ev);
/* Will also call the union-specific cancel function. */
- _GSS_operation_destroy (op, GNUNET_YES);
+ _GSS_operation_destroy (op,
+ GNUNET_YES);
}
@@ -1415,8 +1420,8 @@ maybe_finish (struct Operation *op)
op->state->phase = PHASE_DONE;
ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE);
- GNUNET_MQ_send (op->mq, ev);
-
+ GNUNET_MQ_send (op->mq,
+ ev);
/* We now wait until the other peer closes the channel
* after it got all elements from us. */
}
@@ -1447,7 +1452,7 @@ check_union_p2p_elements (void *cls,
{
struct Operation *op = cls;
- if (OT_UNION != op->type)
+ if (GNUNET_SET_OPERATION_UNION != op->set->operation)
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@@ -1535,7 +1540,7 @@ handle_union_p2p_elements (void *cls,
op->state->received_fresh++;
op_register_element (op, ee, GNUNET_YES);
/* only send results immediately if the client wants it */
- switch (op->spec->result_mode)
+ switch (op->result_mode)
{
case GNUNET_SET_RESULT_ADDED:
send_client_element (op, &ee->element, GNUNET_SET_STATUS_OK);
@@ -1575,7 +1580,7 @@ check_union_p2p_full_element (void *cls,
{
struct Operation *op = cls;
- if (OT_UNION != op->type)
+ if (GNUNET_SET_OPERATION_UNION != op->set->operation)
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@@ -1644,7 +1649,7 @@ handle_union_p2p_full_element (void *cls,
op->state->received_fresh++;
op_register_element (op, ee, GNUNET_YES);
/* only send results immediately if the client wants it */
- switch (op->spec->result_mode)
+ switch (op->result_mode)
{
case GNUNET_SET_RESULT_ADDED:
send_client_element (op, &ee->element, GNUNET_SET_STATUS_OK);
@@ -1659,7 +1664,7 @@ handle_union_p2p_full_element (void *cls,
}
}
- if ( (GNUNET_YES == op->spec->byzantine) &&
+ if ( (GNUNET_YES == op->byzantine) &&
(op->state->received_total > 384 + op->state->received_fresh * 4) &&
(op->state->received_fresh < op->state->received_total / 6) )
{
@@ -1690,7 +1695,7 @@ check_union_p2p_inquiry (void *cls,
struct Operation *op = cls;
unsigned int num_keys;
- if (OT_UNION != op->type)
+ if (GNUNET_SET_OPERATION_UNION != op->set->operation)
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@@ -1727,6 +1732,8 @@ handle_union_p2p_inquiry (void *cls,
const struct IBF_Key *ibf_key;
unsigned int num_keys;
+ LOG (GNUNET_ERROR_TYPE_INFO,
+ "Received union inquiry\n");
num_keys = (ntohs (msg->header.size) - sizeof (struct InquiryMessage))
/ sizeof (struct IBF_Key);
ibf_key = (const struct IBF_Key *) &msg[1];
@@ -1734,8 +1741,11 @@ handle_union_p2p_inquiry (void *cls,
{
struct IBF_Key unsalted_key;
- unsalt_key (ibf_key, ntohl (msg->salt), &unsalted_key);
- send_offers_for_key (op, unsalted_key);
+ unsalt_key (ibf_key,
+ ntohl (msg->salt),
+ &unsalted_key);
+ send_offers_for_key (op,
+ unsalted_key);
ibf_key++;
}
GNUNET_CADET_receive_done (op->channel);
@@ -1753,9 +1763,9 @@ handle_union_p2p_inquiry (void *cls,
* #GNUNET_NO if not.
*/
static int
-send_missing_elements_iter (void *cls,
- uint32_t key,
- void *value)
+send_missing_full_elements_iter (void *cls,
+ uint32_t key,
+ void *value)
{
struct Operation *op = cls;
struct KeyEntry *ke = value;
@@ -1765,13 +1775,15 @@ send_missing_elements_iter (void *cls,
if (GNUNET_YES == ke->received)
return GNUNET_YES;
-
- ev = GNUNET_MQ_msg_extra (emsg, ee->element.size, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT);
- GNUNET_memcpy (&emsg[1], ee->element.data, ee->element.size);
- emsg->reserved = htons (0);
+ ev = GNUNET_MQ_msg_extra (emsg,
+ ee->element.size,
+ GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT);
+ GNUNET_memcpy (&emsg[1],
+ ee->element.data,
+ ee->element.size);
emsg->element_type = htons (ee->element.element_type);
- GNUNET_MQ_send (op->mq, ev);
-
+ GNUNET_MQ_send (op->mq,
+ ev);
return GNUNET_YES;
}
@@ -1790,7 +1802,7 @@ handle_union_p2p_request_full (void *cls,
LOG (GNUNET_ERROR_TYPE_INFO,
"Received request for full set transmission\n");
- if (OT_UNION != op->type)
+ if (GNUNET_SET_OPERATION_UNION != op->set->operation)
{
GNUNET_break_op (0);
fail_union_operation (op);
@@ -1833,11 +1845,15 @@ handle_union_p2p_full_done (void *cls,
/* send all the elements that did not come from the remote peer */
GNUNET_CONTAINER_multihashmap32_iterate (op->state->key_to_element,
- &send_missing_elements_iter,
+ &send_missing_full_elements_iter,
op);
ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE);
- GNUNET_MQ_send (op->mq, ev);
+ GNUNET_MQ_notify_sent (ev,
+ &send_done_and_destroy,
+ op);
+ GNUNET_MQ_send (op->mq,
+ ev);
op->state->phase = PHASE_DONE;
/* we now wait until the other peer shuts the tunnel down*/
}
@@ -1880,7 +1896,7 @@ check_union_p2p_demand (void *cls,
struct Operation *op = cls;
unsigned int num_hashes;
- if (OT_UNION != op->type)
+ if (GNUNET_SET_OPERATION_UNION != op->set->operation)
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@@ -1921,7 +1937,7 @@ handle_union_p2p_demand (void *cls,
num_hashes > 0;
hash++, num_hashes--)
{
- ee = GNUNET_CONTAINER_multihashmap_get (op->spec->set->content->elements,
+ ee = GNUNET_CONTAINER_multihashmap_get (op->set->content->elements,
hash);
if (NULL == ee)
{
@@ -1952,7 +1968,7 @@ handle_union_p2p_demand (void *cls,
1,
GNUNET_NO);
- switch (op->spec->result_mode)
+ switch (op->result_mode)
{
case GNUNET_SET_RESULT_ADDED:
/* Nothing to do. */
@@ -1984,7 +2000,7 @@ check_union_p2p_offer (void *cls,
struct Operation *op = cls;
unsigned int num_hashes;
- if (OT_UNION != op->type)
+ if (GNUNET_SET_OPERATION_UNION != op->set->operation)
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@@ -1998,8 +2014,8 @@ check_union_p2p_offer (void *cls,
}
num_hashes = (ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader))
/ sizeof (struct GNUNET_HashCode);
- if ((ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader))
- != num_hashes * sizeof (struct GNUNET_HashCode))
+ if ((ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader)) !=
+ num_hashes * sizeof (struct GNUNET_HashCode))
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
@@ -2033,7 +2049,7 @@ handle_union_p2p_offer (void *cls,
struct GNUNET_MessageHeader *demands;
struct GNUNET_MQ_Envelope *ev;
- ee = GNUNET_CONTAINER_multihashmap_get (op->spec->set->content->elements,
+ ee = GNUNET_CONTAINER_multihashmap_get (op->set->content->elements,
hash);
if (NULL != ee)
if (GNUNET_YES == _GSS_is_element_of_operation (ee, op))
@@ -2060,7 +2076,9 @@ handle_union_p2p_offer (void *cls,
ev = GNUNET_MQ_msg_header_extra (demands,
sizeof (struct GNUNET_HashCode),
GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND);
- *(struct GNUNET_HashCode *) &demands[1] = *hash;
+ GNUNET_memcpy (&demands[1],
+ hash,
+ sizeof (struct GNUNET_HashCode));
GNUNET_MQ_send (op->mq, ev);
}
GNUNET_CADET_receive_done (op->channel);
@@ -2079,7 +2097,7 @@ handle_union_p2p_done (void *cls,
{
struct Operation *op = cls;
- if (OT_UNION != op->type)
+ if (GNUNET_SET_OPERATION_UNION != op->set->operation)
{
GNUNET_break_op (0);
fail_union_operation (op);
@@ -2134,21 +2152,31 @@ handle_union_p2p_done (void *cls,
* @param opaque_context message to be transmitted to the listener
* to convince him to accept, may be NULL
*/
-static void
+static struct OperationState *
union_evaluate (struct Operation *op,
const struct GNUNET_MessageHeader *opaque_context)
{
+ struct OperationState *state;
struct GNUNET_MQ_Envelope *ev;
struct OperationRequestMessage *msg;
- GNUNET_assert (NULL == op->state);
- op->state = GNUNET_new (struct OperationState);
- op->state->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
+ ev = GNUNET_MQ_msg_nested_mh (msg,
+ GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST,
+ opaque_context);
+ if (NULL == ev)
+ {
+ /* the context message is too large */
+ GNUNET_break (0);
+ return NULL;
+ }
+ state = GNUNET_new (struct OperationState);
+ state->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32,
+ GNUNET_NO);
/* copy the current generation's strata estimator for this operation */
- op->state->se = strata_estimator_dup (op->spec->set->state->se);
+ state->se = strata_estimator_dup (op->set->state->se);
/* we started the operation, thus we have to send the operation request */
- op->state->phase = PHASE_EXPECT_SE;
- op->state->salt_receive = op->state->salt_send = 42;
+ state->phase = PHASE_EXPECT_SE;
+ state->salt_receive = state->salt_send = 42; // FIXME?????
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Initiating union operation evaluation\n");
GNUNET_STATISTICS_update (_GSS_statistics,
@@ -2159,16 +2187,6 @@ union_evaluate (struct Operation *op,
"# of initiated union operations",
1,
GNUNET_NO);
- ev = GNUNET_MQ_msg_nested_mh (msg,
- GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST,
- opaque_context);
- if (NULL == ev)
- {
- /* the context message is too large */
- GNUNET_break (0);
- GNUNET_SERVICE_client_drop (op->spec->set->client);
- return;
- }
msg->operation = htonl (GNUNET_SET_OPERATION_UNION);
GNUNET_MQ_send (op->mq,
ev);
@@ -2180,8 +2198,10 @@ union_evaluate (struct Operation *op,
LOG (GNUNET_ERROR_TYPE_DEBUG,
"sent op request without context message\n");
+ op->state = state;
initialize_key_to_element (op);
- op->state->initial_size = GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element);
+ state->initial_size = GNUNET_CONTAINER_multihashmap32_size (state->key_to_element);
+ return state;
}
@@ -2191,13 +2211,19 @@ union_evaluate (struct Operation *op,
*
* @param op operation that will be accepted as a union operation
*/
-static void
+static struct OperationState *
union_accept (struct Operation *op)
{
+ struct OperationState *state;
+ const struct StrataEstimator *se;
+ struct GNUNET_MQ_Envelope *ev;
+ struct StrataEstimatorMessage *strata_msg;
+ char *buf;
+ size_t len;
+ uint16_t type;
+
LOG (GNUNET_ERROR_TYPE_DEBUG,
"accepting set union operation\n");
- GNUNET_assert (NULL == op->state);
-
GNUNET_STATISTICS_update (_GSS_statistics,
"# of accepted union operations",
1,
@@ -2207,14 +2233,37 @@ union_accept (struct Operation *op)
1,
GNUNET_NO);
- op->state = GNUNET_new (struct OperationState);
- op->state->se = strata_estimator_dup (op->spec->set->state->se);
- op->state->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
- op->state->salt_receive = op->state->salt_send = 42;
+ state = GNUNET_new (struct OperationState);
+ state->se = strata_estimator_dup (op->set->state->se);
+ state->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32,
+ GNUNET_NO);
+ state->salt_receive = state->salt_send = 42; // FIXME?????
+ op->state = state;
initialize_key_to_element (op);
- op->state->initial_size = GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element);
+ state->initial_size = GNUNET_CONTAINER_multihashmap32_size (state->key_to_element);
+
/* kick off the operation */
- send_strata_estimator (op);
+ se = state->se;
+ buf = GNUNET_malloc (se->strata_count * IBF_BUCKET_SIZE * se->ibf_size);
+ len = strata_estimator_write (se,
+ buf);
+ if (len < se->strata_count * IBF_BUCKET_SIZE * se->ibf_size)
+ type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC;
+ else
+ type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE;
+ ev = GNUNET_MQ_msg_extra (strata_msg,
+ len,
+ type);
+ GNUNET_memcpy (&strata_msg[1],
+ buf,
+ len);
+ GNUNET_free (buf);
+ strata_msg->set_size
+ = GNUNET_htonll (GNUNET_CONTAINER_multihashmap_size (op->set->content->elements));
+ GNUNET_MQ_send (op->mq,
+ ev);
+ state->phase = PHASE_EXPECT_IBF;
+ return state;
}
@@ -2254,7 +2303,8 @@ union_set_create (void)
* @param ee the element to add to the set
*/
static void
-union_add (struct SetState *set_state, struct ElementEntry *ee)
+union_add (struct SetState *set_state,
+ struct ElementEntry *ee)
{
strata_estimator_insert (set_state->se,
get_ibf_key (&ee->element_hash));
@@ -2269,7 +2319,8 @@ union_add (struct SetState *set_state, struct ElementEntry *ee)
* @param ee set element to remove
*/
static void
-union_remove (struct SetState *set_state, struct ElementEntry *ee)
+union_remove (struct SetState *set_state,
+ struct ElementEntry *ee)
{
strata_estimator_remove (set_state->se,
get_ibf_key (&ee->element_hash));
@@ -2294,61 +2345,39 @@ union_set_destroy (struct SetState *set_state)
/**
- * Handler for peer-disconnects, notifies the client
- * about the aborted operation in case the op was not concluded.
- *
- * @param op the destroyed operation
- */
-static void
-union_peer_disconnect (struct Operation *op)
-{
- if (PHASE_DONE != op->state->phase)
- {
- struct GNUNET_MQ_Envelope *ev;
- struct GNUNET_SET_ResultMessage *msg;
-
- ev = GNUNET_MQ_msg (msg,
- GNUNET_MESSAGE_TYPE_SET_RESULT);
- msg->request_id = htonl (op->spec->client_request_id);
- msg->result_status = htons (GNUNET_SET_STATUS_FAILURE);
- msg->element_type = htons (0);
- GNUNET_MQ_send (op->spec->set->client_mq,
- ev);
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "other peer disconnected prematurely, phase %u\n",
- op->state->phase);
- _GSS_operation_destroy (op,
- GNUNET_YES);
- return;
- }
- // else: the session has already been concluded
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "other peer disconnected (finished)\n");
- if (GNUNET_NO == op->state->client_done_sent)
- send_done_and_destroy (op);
-}
-
-
-/**
* Copy union-specific set state.
*
- * @param set source set for copying the union state
+ * @param state source state for copying the union state
* @return a copy of the union-specific set state
*/
static struct SetState *
-union_copy_state (struct Set *set)
+union_copy_state (struct SetState *state)
{
struct SetState *new_state;
+ GNUNET_assert ( (NULL != state) &&
+ (NULL != state->se) );
new_state = GNUNET_new (struct SetState);
- GNUNET_assert ( (NULL != set->state) && (NULL != set->state->se) );
- new_state->se = strata_estimator_dup (set->state->se);
+ new_state->se = strata_estimator_dup (state->se);
return new_state;
}
/**
+ * Handle case where channel went down for an operation.
+ *
+ * @param op operation that lost the channel
+ */
+static void
+union_channel_death (struct Operation *op)
+{
+ _GSS_operation_destroy (op,
+ GNUNET_YES);
+}
+
+
+/**
* Get the table with implementing functions for
* set union.
*
@@ -2364,9 +2393,9 @@ _GSS_union_vt ()
.destroy_set = &union_set_destroy,
.evaluate = &union_evaluate,
.accept = &union_accept,
- .peer_disconnect = &union_peer_disconnect,
.cancel = &union_op_cancel,
.copy_state = &union_copy_state,
+ .channel_death = &union_channel_death
};
return &union_vt;
diff --git a/src/set/set_api.c b/src/set/set_api.c
index bc428f9f6d..f5c43a9a7c 100644
--- a/src/set/set_api.c
+++ b/src/set/set_api.c
@@ -310,6 +310,8 @@ handle_iter_element (void *cls,
struct GNUNET_MQ_Envelope *ev;
uint16_t msize;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Received element in set iteration\n");
msize = ntohs (msg->header.size);
if (set->iteration_id != ntohs (msg->iteration_id))
{
@@ -346,7 +348,15 @@ handle_iter_done (void *cls,
GNUNET_SET_ElementIterator iter = set->iterator;
if (NULL == iter)
+ {
+ /* FIXME: if this is true, could cancel+start a fresh one
+ cause elements to go to the wrong iteration? */
+ LOG (GNUNET_ERROR_TYPE_INFO,
+ "Service completed set iteration that was already cancelled\n");
return;
+ }
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Set iteration completed\n");
set->destroy_requested = GNUNET_SYSERR;
set->iterator = NULL;
set->iteration_id++;
@@ -392,7 +402,7 @@ handle_result (void *cls,
int destroy_set;
GNUNET_assert (NULL != set->mq);
- result_status = ntohs (msg->result_status);
+ result_status = (enum GNUNET_SET_Status) ntohs (msg->result_status);
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Got result message with status %d\n",
result_status);
@@ -507,6 +517,8 @@ GNUNET_SET_operation_cancel (struct GNUNET_SET_OperationHandle *oh)
struct GNUNET_SET_CancelMessage *m;
struct GNUNET_MQ_Envelope *mqm;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Cancelling SET operation\n");
if (NULL != set)
{
mqm = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_SET_CANCEL);
@@ -560,6 +572,9 @@ handle_client_set_error (void *cls,
}
+/**
+ * FIXME.
+ */
static struct GNUNET_SET_Handle *
create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg,
enum GNUNET_SET_OperationType op,
@@ -618,7 +633,8 @@ create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg,
GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT);
copy_msg->cookie = *cookie;
}
- GNUNET_MQ_send (set->mq, mqm);
+ GNUNET_MQ_send (set->mq,
+ mqm);
return set;
}
@@ -638,7 +654,16 @@ struct GNUNET_SET_Handle *
GNUNET_SET_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
enum GNUNET_SET_OperationType op)
{
- return create_internal (cfg, op, NULL);
+ struct GNUNET_SET_Handle *set;
+
+ set = create_internal (cfg,
+ op,
+ NULL);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Creating set %p for operation %d\n",
+ set,
+ op);
+ return set;
}
@@ -664,8 +689,10 @@ GNUNET_SET_add_element (struct GNUNET_SET_Handle *set,
struct GNUNET_MQ_Envelope *mqm;
struct GNUNET_SET_ElementMessage *msg;
- LOG (GNUNET_ERROR_TYPE_INFO, "adding element of type %u\n", (unsigned) element->element_type);
-
+ LOG (GNUNET_ERROR_TYPE_INFO,
+ "adding element of type %u to set %p\n",
+ (unsigned int) element->element_type,
+ set);
if (GNUNET_YES == set->invalid)
{
if (NULL != cont)
@@ -708,6 +735,9 @@ GNUNET_SET_remove_element (struct GNUNET_SET_Handle *set,
struct GNUNET_MQ_Envelope *mqm;
struct GNUNET_SET_ElementMessage *msg;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Removing element from set %p\n",
+ set);
if (GNUNET_YES == set->invalid)
{
if (NULL != cont)
@@ -878,7 +908,8 @@ handle_request (void *cls,
struct GNUNET_SET_RejectMessage *rmsg;
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Processing incoming operation request\n");
+ "Processing incoming operation request with id %u\n",
+ ntohl (msg->accept_id));
/* we got another valid request => reset the backoff */
lh->reconnect_backoff = GNUNET_TIME_UNIT_MILLISECONDS;
req.accept_id = ntohl (msg->accept_id);
@@ -892,7 +923,8 @@ handle_request (void *cls,
if (GNUNET_YES == req.accepted)
return; /* the accept-case is handled in #GNUNET_SET_accept() */
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Rejecting request\n");
+ "Rejected request %u\n",
+ ntohl (msg->accept_id));
mqm = GNUNET_MQ_msg (rmsg,
GNUNET_MESSAGE_TYPE_SET_REJECT);
rmsg->accept_reject_id = msg->accept_id;
@@ -982,6 +1014,9 @@ GNUNET_SET_listen (const struct GNUNET_CONFIGURATION_Handle *cfg,
{
struct GNUNET_SET_ListenHandle *lh;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Starting listener for app %s\n",
+ GNUNET_h2s (app_id));
lh = GNUNET_new (struct GNUNET_SET_ListenHandle);
lh->listen_cb = listen_cb;
lh->listen_cls = listen_cls;
@@ -1008,7 +1043,8 @@ void
GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Canceling listener\n");
+ "Canceling listener %s\n",
+ GNUNET_h2s (&lh->app_id));
if (NULL != lh->mq)
{
GNUNET_MQ_destroy (lh->mq);
@@ -1050,10 +1086,12 @@ GNUNET_SET_accept (struct GNUNET_SET_Request *request,
GNUNET_assert (GNUNET_NO == request->accepted);
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Client accepts set operation (%d)\n",
- result_mode);
+ "Client accepts set operation (%d) with id %u\n",
+ result_mode,
+ request->accept_id);
request->accepted = GNUNET_YES;
- mqm = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_ACCEPT);
+ mqm = GNUNET_MQ_msg (msg,
+ GNUNET_MESSAGE_TYPE_SET_ACCEPT);
msg->accept_reject_id = htonl (request->accept_id);
msg->result_mode = htonl (result_mode);
oh = GNUNET_new (struct GNUNET_SET_OperationHandle);
@@ -1151,6 +1189,8 @@ GNUNET_SET_copy_lazy (struct GNUNET_SET_Handle *set,
struct GNUNET_MQ_Envelope *ev;
struct SetCopyRequest *req;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Creating lazy copy of set\n");
ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_PREPARE);
GNUNET_MQ_send (set->mq, ev);
diff --git a/src/set/test_set_api.c b/src/set/test_set_api.c
index dd3f004f24..ca7d8a4e26 100644
--- a/src/set/test_set_api.c
+++ b/src/set/test_set_api.c
@@ -116,6 +116,7 @@ result_cb_set2 (void *cls,
oh2 = NULL;
fprintf (stderr,
"set 2: received failure status\n");
+ GNUNET_SCHEDULER_shutdown ();
ret = 1;
break;
case GNUNET_SET_STATUS_DONE:
@@ -147,8 +148,6 @@ listen_cb (void *cls,
GNUNET_assert (ntohs (context_msg->type) == GNUNET_MESSAGE_TYPE_DUMMY);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"listen cb called\n");
- GNUNET_SET_listen_cancel (listen_handle);
- listen_handle = NULL;
oh2 = GNUNET_SET_accept (request,
GNUNET_SET_RESULT_ADDED,
(struct GNUNET_SET_Option[]) { 0 },
@@ -200,19 +199,25 @@ init_set2 (void *cls)
{
struct GNUNET_SET_Element element;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initializing set 2\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "initializing set 2\n");
element.element_type = 0;
-
element.data = "hello";
element.size = strlen(element.data);
- GNUNET_SET_add_element (set2, &element, NULL, NULL);
+ GNUNET_SET_add_element (set2,
+ &element,
+ NULL, NULL);
element.data = "quux";
element.size = strlen(element.data);
- GNUNET_SET_add_element (set2, &element, NULL, NULL);
+ GNUNET_SET_add_element (set2,
+ &element,
+ NULL, NULL);
element.data = "baz";
element.size = strlen(element.data);
- GNUNET_SET_add_element (set2, &element, &start, NULL);
+ GNUNET_SET_add_element (set2,
+ &element,
+ &start, NULL);
}
@@ -225,14 +230,17 @@ init_set1 (void)
struct GNUNET_SET_Element element;
element.element_type = 0;
-
element.data = "hello";
element.size = strlen(element.data);
- GNUNET_SET_add_element (set1, &element, NULL, NULL);
+ GNUNET_SET_add_element (set1,
+ &element,
+ NULL, NULL);
element.data = "bar";
element.size = strlen(element.data);
- GNUNET_SET_add_element (set1, &element, init_set2, NULL);
-
+ GNUNET_SET_add_element (set1,
+ &element,
+ &init_set2,
+ NULL);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"initialized set 1\n");
}
@@ -242,10 +250,15 @@ static int
iter_cb (void *cls,
const struct GNUNET_SET_Element *element)
{
+ struct GNUNET_SET_Handle *set = cls;
+
if (NULL == element)
{
GNUNET_assert (3 == iter_count);
- GNUNET_SET_destroy (cls);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Iteration finished, destroying set %p\n",
+ set);
+ GNUNET_SET_destroy (set);
return GNUNET_YES;
}
iter_count++;
@@ -262,21 +275,31 @@ test_iter ()
struct GNUNET_SET_Element element;
struct GNUNET_SET_Handle *iter_set;
- iter_set = GNUNET_SET_create (config, GNUNET_SET_OPERATION_UNION);
-
+ iter_set = GNUNET_SET_create (config,
+ GNUNET_SET_OPERATION_UNION);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Testing iteration over 3 elements on set %p\n",
+ iter_set);
element.element_type = 0;
element.data = "hello";
element.size = strlen(element.data);
- GNUNET_SET_add_element (iter_set, &element, NULL, NULL);
+ GNUNET_SET_add_element (iter_set,
+ &element,
+ NULL, NULL);
element.data = "bar";
element.size = strlen(element.data);
- GNUNET_SET_add_element (iter_set, &element, NULL, NULL);
+ GNUNET_SET_add_element (iter_set,
+ &element,
+ NULL, NULL);
element.data = "quux";
element.size = strlen(element.data);
- GNUNET_SET_add_element (iter_set, &element, NULL, NULL);
-
- GNUNET_SET_iterate (iter_set, iter_cb, iter_set);
+ GNUNET_SET_add_element (iter_set,
+ &element,
+ NULL, NULL);
+ GNUNET_SET_iterate (iter_set,
+ &iter_cb,
+ iter_set);
}
@@ -372,12 +395,20 @@ run (void *cls,
GNUNET_i2s (&local_id));
test_iter ();
- set1 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION);
- set2 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION);
+ set1 = GNUNET_SET_create (cfg,
+ GNUNET_SET_OPERATION_UNION);
+ set2 = GNUNET_SET_create (cfg,
+ GNUNET_SET_OPERATION_UNION);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Created sets %p and %p for union operation\n",
+ set1,
+ set2);
GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
&app_id);
- ///* test if canceling an uncommited request works! */
+ /* test if canceling an uncommited request works! */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Launching and instantly stopping set operation\n");
my_oh = GNUNET_SET_prepare (&local_id,
&app_id,
NULL,
@@ -385,7 +416,6 @@ run (void *cls,
(struct GNUNET_SET_Option[]) { 0 },
NULL,
NULL);
-
GNUNET_SET_operation_cancel (my_oh);
/* test the real set reconciliation */
diff --git a/src/set/test_set_union_copy.c b/src/set/test_set_union_copy.c
index a1eba63115..242b9f2f2d 100644
--- a/src/set/test_set_union_copy.c
+++ b/src/set/test_set_union_copy.c
@@ -265,7 +265,8 @@ run (void *cls,
GNUNET_TESTING_peer_get_identity (peer,
&local_id);
- set1 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION);
+ set1 = GNUNET_SET_create (cfg,
+ GNUNET_SET_OPERATION_UNION);
add_element_str (set1,
"333");
add_element_str (set1,
diff --git a/src/statistics/gnunet-service-statistics.c b/src/statistics/gnunet-service-statistics.c
index 161327421e..85c84b89dc 100644
--- a/src/statistics/gnunet-service-statistics.c
+++ b/src/statistics/gnunet-service-statistics.c
@@ -776,7 +776,7 @@ check_watch (void *cls,
size_t size;
const char *service;
const char *name;
-
+
size = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader);
if (size !=
GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
@@ -870,7 +870,7 @@ handle_watch (void *cls,
/**
* Handle DISCONNECT-message. Sync to disk and send
- * back a #GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT_CONFIRM
+ * back a #GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT_CONFIRM
* message.
*
* @param cls the `struct ClientEntry *`
@@ -984,6 +984,7 @@ client_disconnect_cb (void *cls,
}
}
}
+ GNUNET_free (ce);
if ( (0 == client_count) &&
(GNUNET_YES == in_shutdown) )
do_shutdown ();
@@ -992,7 +993,7 @@ client_disconnect_cb (void *cls,
/**
* We've read a `struct GNUNET_STATISTICS_SetMessage *` from
- * disk. Check that it is well-formed, and if so pass it to
+ * disk. Check that it is well-formed, and if so pass it to
* the handler for set messages.
*
* @param cls NULL
diff --git a/src/util/client.c b/src/util/client.c
index 0f7d0d3593..163ae6eb9f 100644
--- a/src/util/client.c
+++ b/src/util/client.c
@@ -298,11 +298,11 @@ recv_message (void *cls,
if (GNUNET_YES == cstate->in_destroy)
return GNUNET_SYSERR;
-
- LOG (GNUNET_ERROR_TYPE_INFO,
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
"Received message of type %u and size %u from %s\n",
- ntohs (msg->type), ntohs (msg->size), cstate->service_name);
-
+ ntohs (msg->type),
+ ntohs (msg->size),
+ cstate->service_name);
GNUNET_MQ_inject_message (cstate->mq,
msg);
if (GNUNET_YES == cstate->in_destroy)
diff --git a/src/util/service_new.c b/src/util/service_new.c
index 5b3a332ac9..9c0ee539b5 100644
--- a/src/util/service_new.c
+++ b/src/util/service_new.c
@@ -2000,11 +2000,10 @@ service_mq_send (struct GNUNET_MQ_Handle *mq,
if (NULL != client->drop_task)
return; /* we're going down right now, do not try to send */
GNUNET_assert (NULL == client->send_task);
-
- LOG (GNUNET_ERROR_TYPE_INFO,
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
"Sending message of type %u and size %u to client\n",
- ntohs (msg->type), ntohs (msg->size));
-
+ ntohs (msg->type),
+ ntohs (msg->size));
client->msg = msg;
client->msg_pos = 0;
client->send_task
@@ -2103,10 +2102,10 @@ service_client_mst_cb (void *cls,
{
struct GNUNET_SERVICE_Client *client = cls;
- LOG (GNUNET_ERROR_TYPE_INFO,
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
"Received message of type %u and size %u from client\n",
- ntohs (message->type), ntohs (message->size));
-
+ ntohs (message->type),
+ ntohs (message->size));
GNUNET_assert (GNUNET_NO == client->needs_continue);
client->needs_continue = GNUNET_YES;
client->warn_type = ntohs (message->type);
diff --git a/src/util/util.conf b/src/util/util.conf
index ecc94ead00..ceb5fdcbba 100644
--- a/src/util/util.conf
+++ b/src/util/util.conf
@@ -37,9 +37,8 @@ GNUNET_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/gnunet-system-runtime/
GNUNET_USER_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/gnunet-${USERHOME:-${USER:-user}}-runtime/
-# Legacy option...
-# GNUNET_TEST_HOME = ~/.gnunet/
-# GNUNET_TEST_HOME = /var/lib/gnunet/
+# Override for GNUNET_HOME used by test cases.
+# GNUNET_TEST_HOME = /tmp/foo/bar
# DEFAULTCONFIG = /etc/gnunet.conf
# If 'DEFAULTCONFIG' is not defined, the current
diff --git a/src/vpn/Makefile.am b/src/vpn/Makefile.am
index 417d2eb899..5c16fa349d 100644
--- a/src/vpn/Makefile.am
+++ b/src/vpn/Makefile.am
@@ -59,7 +59,7 @@ gnunet_service_vpn_LDADD = \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/tun/libgnunettun.la \
$(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/cadet/libgnunetcadetnew.la \
+ $(top_builddir)/src/cadet/libgnunetcadet.la \
$(top_builddir)/src/regex/libgnunetregex.la \
$(GN_LIBINTL)
gnunet_service_vpn_CFLAGS = \
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c
index aab0a143fa..ab0b00d763 100644
--- a/src/vpn/gnunet-service-vpn.c
+++ b/src/vpn/gnunet-service-vpn.c
@@ -1384,7 +1384,7 @@ create_channel (struct ChannelState *ts,
GNUNET_MQ_handler_end()
};
- return GNUNET_CADET_channel_creatE (cadet_handle,
+ return GNUNET_CADET_channel_create (cadet_handle,
ts,
target,
port,
@@ -3068,7 +3068,7 @@ run (void *cls,
}
vpn_argv[6] = NULL;
- cadet_handle = GNUNET_CADET_connecT (cfg_);
+ cadet_handle = GNUNET_CADET_connect (cfg_);
// FIXME never opens ports???
helper_handle = GNUNET_HELPER_start (GNUNET_NO,
"gnunet-helper-vpn", vpn_argv,