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 2b4a0d8e1..0f82a2e4b 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
355 355
356\subsection{Starting Two Peers by Hand} 356\subsection{Starting Two Peers by Hand}
357 357
358This section describes how to start two peers on the same machine by hand.
359The process is rather painful, but the description is somewhat instructive.
360In practice, you might prefer the automated method described in
361Section~\ref{sec:testbed}.
362
358\subsubsection{Setup a second peer} 363\subsubsection{Setup a second peer}
359We will now start a second peer on your machine. 364We will now start a second peer on your machine.
360For the second peer, you will need to manually create a modified 365For the second peer, you will need to manually create a modified
@@ -376,7 +381,7 @@ $ cat $PREFIX/share/gnunet/config.d/*.conf > peer2.conf
376Now you have to edit {\tt peer2.conf} and change: 381Now you have to edit {\tt peer2.conf} and change:
377\begin{itemize} 382\begin{itemize}
378 \itemsep0em 383 \itemsep0em
379 \item{\texttt{SERVICEHOME} under \texttt{PATHS}} 384 \item{\texttt{GNUNET\_TEST\_HOME} under \texttt{PATHS}}
380 \item{Every (uncommented) value for ``\texttt{PORT}'' (add 10000) in any 385 \item{Every (uncommented) value for ``\texttt{PORT}'' (add 10000) in any
381 section (the option may be commented out if \texttt{PORT} is 386 section (the option may be commented out if \texttt{PORT} is
382 prefixed by "\#", in this case, UNIX domain sockets are used 387 prefixed by "\#", in this case, UNIX domain sockets are used
@@ -460,7 +465,7 @@ $ gnunet-core -c peer1.conf
460Peer `9TVUCS8P5A7ILLBGO6 [...shortened...] 1KNBJ4NGCHP3JPVULDG' 465Peer `9TVUCS8P5A7ILLBGO6 [...shortened...] 1KNBJ4NGCHP3JPVULDG'
461\end{lstlisting} 466\end{lstlisting}
462 467
463\subsection{Starting Peers Using the Testbed Service} 468\subsection{Starting Peers Using the Testbed Service} \label{sec:testbed}
464 469
465GNUnet's testbed service is used for testing scenarios where a number of peers 470GNUnet's testbed service is used for testing scenarios where a number of peers
466are to be started. The testbed can manage peers on a single host or on multiple 471are 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:
497$ export CPPFLAGS="-I/path/to/gnunet/headers" 502$ export CPPFLAGS="-I/path/to/gnunet/headers"
498$ export LDFLAGS="-L/path/to/gnunet/libraries" 503$ export LDFLAGS="-L/path/to/gnunet/libraries"
499$ gcc $CPPFLAGS $LDFLAGS -o testbed-test testbed_test.c -lgnunettestbed -lgnunetdht -lgnunetutil 504$ gcc $CPPFLAGS $LDFLAGS -o testbed-test testbed_test.c -lgnunettestbed -lgnunetdht -lgnunetutil
505$ touch template.conf # Generate (empty) configuration
506$ ./testbed-test # run it (press CTRL-C to stop)
500\end{lstlisting} 507\end{lstlisting}
501The \texttt{CPPFLAGS} and \texttt{LDFLAGS} are necessary if GNUnet is installed 508The \texttt{CPPFLAGS} and \texttt{LDFLAGS} are necessary if GNUnet is installed
502into a different directory other than \texttt{/usr/local}. 509into a different directory other than \texttt{/usr/local}.
diff --git a/src/cadet/Makefile.am b/src/cadet/Makefile.am
index 1fe912305..af1a6720c 100644
--- a/src/cadet/Makefile.am
+++ b/src/cadet/Makefile.am
@@ -29,35 +29,23 @@ bin_PROGRAMS = \
29 gnunet-cadet 29 gnunet-cadet
30 30
31lib_LTLIBRARIES = \ 31lib_LTLIBRARIES = \
32 libgnunetcadetnew.la \
33 libgnunetcadet.la \ 32 libgnunetcadet.la \
34 $(EXP_LIB) 33 $(EXP_LIB)
35 34
36libgnunetcadet_la_SOURCES = \ 35libgnunetcadet_la_SOURCES = \
37 cadet_api.c cadet_common.c 36 cadet_api.c
38libgnunetcadet_la_LIBADD = \ 37libgnunetcadet_la_LIBADD = \
39 $(top_builddir)/src/util/libgnunetutil.la \ 38 $(top_builddir)/src/util/libgnunetutil.la \
40 $(XLIB) \ 39 $(XLIB) \
41 $(LTLIBINTL) 40 $(LTLIBINTL)
42libgnunetcadet_la_LDFLAGS = \ 41libgnunetcadet_la_LDFLAGS = \
43 $(GN_LIB_LDFLAGS) $(WINFLAGS) \ 42 $(GN_LIB_LDFLAGS) $(WINFLAGS) \
44 -version-info 5:0:0 43 -version-info 7:0:0
45
46
47libgnunetcadetnew_la_SOURCES = \
48 cadet_api_new.c
49libgnunetcadetnew_la_LIBADD = \
50 $(top_builddir)/src/util/libgnunetutil.la \
51 $(XLIB) \
52 $(LTLIBINTL)
53libgnunetcadetnew_la_LDFLAGS = \
54 $(GN_LIB_LDFLAGS) $(WINFLAGS) \
55 -version-info 6:0:0
56 44
57gnunet_cadet_SOURCES = \ 45gnunet_cadet_SOURCES = \
58 gnunet-cadet.c 46 gnunet-cadet.c
59gnunet_cadet_LDADD = \ 47gnunet_cadet_LDADD = \
60 libgnunetcadetnew.la \ 48 libgnunetcadet.la \
61 $(top_builddir)/src/util/libgnunetutil.la 49 $(top_builddir)/src/util/libgnunetutil.la
62 50
63gnunet_service_cadet_SOURCES = \ 51gnunet_service_cadet_SOURCES = \
@@ -121,7 +109,7 @@ endif
121test_cadet_local_mq_SOURCES = \ 109test_cadet_local_mq_SOURCES = \
122 test_cadet_local_mq.c 110 test_cadet_local_mq.c
123test_cadet_local_mq_LDADD = \ 111test_cadet_local_mq_LDADD = \
124 libgnunetcadetnew.la \ 112 libgnunetcadet.la \
125 $(top_builddir)/src/testing/libgnunettesting.la \ 113 $(top_builddir)/src/testing/libgnunettesting.la \
126 $(top_builddir)/src/util/libgnunetutil.la 114 $(top_builddir)/src/util/libgnunetutil.la
127 115
@@ -131,17 +119,17 @@ libgnunetcadettest_la_SOURCES = \
131libgnunetcadettest_la_LIBADD = \ 119libgnunetcadettest_la_LIBADD = \
132 $(top_builddir)/src/util/libgnunetutil.la \ 120 $(top_builddir)/src/util/libgnunetutil.la \
133 $(top_builddir)/src/testbed/libgnunettestbed.la \ 121 $(top_builddir)/src/testbed/libgnunettestbed.la \
134 libgnunetcadetnew.la 122 libgnunetcadet.la
135 123
136ld_cadet_test_lib = \ 124ld_cadet_test_lib = \
137 $(top_builddir)/src/util/libgnunetutil.la \ 125 $(top_builddir)/src/util/libgnunetutil.la \
138 $(top_builddir)/src/testing/libgnunettesting.la \ 126 $(top_builddir)/src/testing/libgnunettesting.la \
139 libgnunetcadetnew.la \ 127 libgnunetcadet.la \
140 libgnunetcadettest.la \ 128 libgnunetcadettest.la \
141 $(top_builddir)/src/testbed/libgnunettestbed.la \ 129 $(top_builddir)/src/testbed/libgnunettestbed.la \
142 $(top_builddir)/src/statistics/libgnunetstatistics.la 130 $(top_builddir)/src/statistics/libgnunetstatistics.la
143dep_cadet_test_lib = \ 131dep_cadet_test_lib = \
144 libgnunetcadetnew.la \ 132 libgnunetcadet.la \
145 libgnunetcadettest.la \ 133 libgnunetcadettest.la \
146 $(top_builddir)/src/statistics/libgnunetstatistics.la 134 $(top_builddir)/src/statistics/libgnunetstatistics.la
147 135
diff --git a/src/cadet/TODO b/src/cadet/TODO
index 820efab7a..06567b0ad 100644
--- a/src/cadet/TODO
+++ b/src/cadet/TODO
@@ -1,6 +1,10 @@
1- URGENT: Congestion/flow control (CHANNEL): 1- URGENT:
2 + estimate max bandwidth using bursts and use to for CONGESTION CONTROL! 2 + if 'client-not-ready', we do not ACK at all, and sender keeps
3 (and figure out how/where to use this!) 3 retransmitting again and again; would be good to do flow-control notification instead
4 of not ACKing that we got the data but are simply not ready for more!
5 + Congestion/flow control (CHANNEL):
6 estimate max bandwidth using bursts and use to for CONGESTION CONTROL!
7 (and figure out how/where to use this!)
4 8
5- HIGH: revisit handling of 'unbuffered' traffic! (CHANNEL/TUNNEL) 9- HIGH: revisit handling of 'unbuffered' traffic! (CHANNEL/TUNNEL)
6 (need to push down through tunnel into connection selection); 10 (need to push down through tunnel into connection selection);
diff --git a/src/cadet/cadet_api.c b/src/cadet/cadet_api.c
index 7b9ac62b3..decf473a9 100644
--- a/src/cadet/cadet_api.c
+++ b/src/cadet/cadet_api.c
@@ -21,8 +21,8 @@
21 * @file cadet/cadet_api.c 21 * @file cadet/cadet_api.c
22 * @brief cadet api: client implementation of cadet service 22 * @brief cadet api: client implementation of cadet service
23 * @author Bartlomiej Polot 23 * @author Bartlomiej Polot
24 * @author Christian Grothoff
24 */ 25 */
25
26#include "platform.h" 26#include "platform.h"
27#include "gnunet_util_lib.h" 27#include "gnunet_util_lib.h"
28#include "gnunet_constants.h" 28#include "gnunet_constants.h"
@@ -32,57 +32,9 @@
32 32
33#define LOG(kind,...) GNUNET_log_from (kind, "cadet-api",__VA_ARGS__) 33#define LOG(kind,...) GNUNET_log_from (kind, "cadet-api",__VA_ARGS__)
34 34
35/******************************************************************************/
36/************************ DATA STRUCTURES ****************************/
37/******************************************************************************/
38
39/** 35/**
40 * Transmission queue to the service 36 * Ugly legacy hack.
41 *
42 * @deprecated
43 */ 37 */
44struct GNUNET_CADET_TransmitHandle
45{
46 /**
47 * Double Linked list
48 */
49 struct GNUNET_CADET_TransmitHandle *next;
50
51 /**
52 * Double Linked list
53 */
54 struct GNUNET_CADET_TransmitHandle *prev;
55
56 /**
57 * Channel this message is sent on / for (may be NULL for control messages).
58 */
59 struct GNUNET_CADET_Channel *channel;
60
61 /**
62 * Request data task.
63 */
64 struct GNUNET_SCHEDULER_Task *request_data_task;
65
66 /**
67 * Callback to obtain the message to transmit, or NULL if we
68 * got the message in 'data'. Notice that messages built
69 * by 'notify' need to be encapsulated with information about
70 * the 'target'.
71 */
72 GNUNET_CONNECTION_TransmitReadyNotify notify;
73
74 /**
75 * Closure for 'notify'
76 */
77 void *notify_cls;
78
79 /**
80 * Size of the payload.
81 */
82 size_t size;
83};
84
85
86union CadetInfoCB 38union CadetInfoCB
87{ 39{
88 40
@@ -119,69 +71,19 @@ union CadetInfoCB
119struct GNUNET_CADET_Handle 71struct GNUNET_CADET_Handle
120{ 72{
121 /** 73 /**
122 * Flag to indicate old or MQ API. 74 * Message queue.
123 */
124 int mq_api;
125
126 /**
127 * Message queue (if available).
128 */ 75 */
129 struct GNUNET_MQ_Handle *mq; 76 struct GNUNET_MQ_Handle *mq;
130 77
131 /** 78 /**
132 * Set of handlers used for processing incoming messages in the channels
133 *
134 * @deprecated
135 */
136 const struct GNUNET_CADET_MessageHandler *message_handlers;
137
138 /**
139 * Number of handlers in the handlers array.
140 *
141 * @deprecated
142 */
143 unsigned int n_handlers;
144
145 /**
146 * Ports open. 79 * Ports open.
147 */ 80 */
148 struct GNUNET_CONTAINER_MultiHashMap *ports; 81 struct GNUNET_CONTAINER_MultiHashMap *ports;
149 82
150 /** 83 /**
151 * Double linked list of the channels this client is connected to, head. 84 * Channels open.
152 */ 85 */
153 struct GNUNET_CADET_Channel *channels_head; 86 struct GNUNET_CONTAINER_MultiHashMap32 *channels;
154
155 /**
156 * Double linked list of the channels this client is connected to, tail.
157 */
158 struct GNUNET_CADET_Channel *channels_tail;
159
160 /**
161 * Callback for inbound channel disconnection
162 */
163 GNUNET_CADET_ChannelEndHandler *cleaner;
164
165 /**
166 * Closure for all the handlers given by the client
167 *
168 * @deprecated
169 */
170 void *cls;
171
172 /**
173 * Messages to send to the service, head.
174 *
175 * @deprecated
176 */
177 struct GNUNET_CADET_TransmitHandle *th_head;
178
179 /**
180 * Messages to send to the service, tail.
181 *
182 * @deprecated
183 */
184 struct GNUNET_CADET_TransmitHandle *th_tail;
185 87
186 /** 88 /**
187 * child of the next channel to create (to avoid reusing IDs often) 89 * child of the next channel to create (to avoid reusing IDs often)
@@ -194,14 +96,9 @@ struct GNUNET_CADET_Handle
194 const struct GNUNET_CONFIGURATION_Handle *cfg; 96 const struct GNUNET_CONFIGURATION_Handle *cfg;
195 97
196 /** 98 /**
197 * Time to the next reconnect in case one reconnect fails
198 */
199 struct GNUNET_TIME_Relative reconnect_time;
200
201 /**
202 * Task for trying to reconnect. 99 * Task for trying to reconnect.
203 */ 100 */
204 struct GNUNET_SCHEDULER_Task * reconnect_task; 101 struct GNUNET_SCHEDULER_Task *reconnect_task;
205 102
206 /** 103 /**
207 * Callback for an info task (only one active at a time). 104 * Callback for an info task (only one active at a time).
@@ -212,23 +109,12 @@ struct GNUNET_CADET_Handle
212 * Info callback closure for @c info_cb. 109 * Info callback closure for @c info_cb.
213 */ 110 */
214 void *info_cls; 111 void *info_cls;
215};
216
217 112
218/**
219 * Description of a peer
220 */
221struct GNUNET_CADET_Peer
222{
223 /** 113 /**
224 * ID of the peer in short form 114 * Time to the next reconnect in case one reconnect fails
225 */ 115 */
226 GNUNET_PEER_Id id; 116 struct GNUNET_TIME_Relative reconnect_time;
227 117
228 /**
229 * Channel this peer belongs to
230 */
231 struct GNUNET_CADET_Channel *t;
232}; 118};
233 119
234 120
@@ -237,15 +123,11 @@ struct GNUNET_CADET_Peer
237 */ 123 */
238struct GNUNET_CADET_Channel 124struct GNUNET_CADET_Channel
239{ 125{
240 /**
241 * DLL next
242 */
243 struct GNUNET_CADET_Channel *next;
244 126
245 /** 127 /**
246 * DLL prev 128 * Other end of the channel.
247 */ 129 */
248 struct GNUNET_CADET_Channel *prev; 130 struct GNUNET_PeerIdentity peer;
249 131
250 /** 132 /**
251 * Handle to the cadet this channel belongs to 133 * Handle to the cadet this channel belongs to
@@ -253,40 +135,18 @@ struct GNUNET_CADET_Channel
253 struct GNUNET_CADET_Handle *cadet; 135 struct GNUNET_CADET_Handle *cadet;
254 136
255 /** 137 /**
256 * Local ID of the channel
257 */
258 struct GNUNET_CADET_ClientChannelNumber ccn;
259
260 /**
261 * Channel's port, if incoming. 138 * Channel's port, if incoming.
262 */ 139 */
263 struct GNUNET_CADET_Port *incoming_port; 140 struct GNUNET_CADET_Port *incoming_port;
264 141
265 /** 142 /**
266 * Other end of the channel. 143 * Any data the caller wants to put in here, used for the
267 */ 144 * various callbacks (@e disconnects, @e window_changes, handlers).
268 GNUNET_PEER_Id peer;
269
270 /**
271 * Any data the caller wants to put in here
272 */ 145 */
273 void *ctx; 146 void *ctx;
274 147
275 /** 148 /**
276 * Channel options: reliability, etc. 149 * Message Queue for the channel (which we are implementing).
277 */
278 enum GNUNET_CADET_ChannelOption options;
279
280 /**
281 * Are we allowed to send to the service?
282 *
283 * @deprecated?
284 */
285 unsigned int allow_send;
286
287 /***************************** MQ ************************************/
288 /**
289 * Message Queue for the channel.
290 */ 150 */
291 struct GNUNET_MQ_Handle *mq; 151 struct GNUNET_MQ_Handle *mq;
292 152
@@ -296,7 +156,9 @@ struct GNUNET_CADET_Channel
296 struct GNUNET_SCHEDULER_Task *mq_cont; 156 struct GNUNET_SCHEDULER_Task *mq_cont;
297 157
298 /** 158 /**
299 * Pending envelope in case we don't have an ACK from the service. 159 * Pending envelope with a message to be transmitted to the
160 * service as soon as we are allowed to. Should only be
161 * non-NULL if @e allow_send is 0.
300 */ 162 */
301 struct GNUNET_MQ_Envelope *pending_env; 163 struct GNUNET_MQ_Envelope *pending_env;
302 164
@@ -310,6 +172,21 @@ struct GNUNET_CADET_Channel
310 */ 172 */
311 GNUNET_CADET_DisconnectEventHandler disconnects; 173 GNUNET_CADET_DisconnectEventHandler disconnects;
312 174
175 /**
176 * Local ID of the channel, #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI bit is set if outbound.
177 */
178 struct GNUNET_CADET_ClientChannelNumber ccn;
179
180 /**
181 * Channel options: reliability, etc.
182 */
183 enum GNUNET_CADET_ChannelOption options;
184
185 /**
186 * How many messages are we allowed to send to the service right now?
187 */
188 unsigned int allow_send;
189
313}; 190};
314 191
315 192
@@ -318,35 +195,22 @@ struct GNUNET_CADET_Channel
318 */ 195 */
319struct GNUNET_CADET_Port 196struct GNUNET_CADET_Port
320{ 197{
321 /**
322 * Handle to the CADET session this port belongs to.
323 */
324 struct GNUNET_CADET_Handle *cadet;
325 198
326 /** 199 /**
327 * Port ID. 200 * Port "number"
328 *
329 * @deprecated
330 */ 201 */
331 struct GNUNET_HashCode *hash; 202 struct GNUNET_HashCode id;
332 203
333 /** 204 /**
334 * Callback handler for incoming channels on this port. 205 * Handle to the CADET session this port belongs to.
335 */ 206 */
336 GNUNET_CADET_InboundChannelNotificationHandler *handler; 207 struct GNUNET_CADET_Handle *cadet;
337 208
338 /** 209 /**
339 * Closure for @a handler. 210 * Closure for @a handler.
340 */ 211 */
341 void *cls; 212 void *cls;
342 213
343 /***************************** MQ ************************************/
344
345 /**
346 * Port "number"
347 */
348 struct GNUNET_HashCode id;
349
350 /** 214 /**
351 * Handler for incoming channels on this port 215 * Handler for incoming channels on this port
352 */ 216 */
@@ -355,7 +219,7 @@ struct GNUNET_CADET_Port
355 /** 219 /**
356 * Closure for @ref connects 220 * Closure for @ref connects
357 */ 221 */
358 void * connects_cls; 222 void *connects_cls;
359 223
360 /** 224 /**
361 * Window size change handler. 225 * Window size change handler.
@@ -363,106 +227,30 @@ struct GNUNET_CADET_Port
363 GNUNET_CADET_WindowSizeEventHandler window_changes; 227 GNUNET_CADET_WindowSizeEventHandler window_changes;
364 228
365 /** 229 /**
366 * Handler called when an incoming channel is destroyed.. 230 * Handler called when an incoming channel is destroyed.
367 */ 231 */
368 GNUNET_CADET_DisconnectEventHandler disconnects; 232 GNUNET_CADET_DisconnectEventHandler disconnects;
369 233
370 /** 234 /**
371 * Payload handlers for incoming channels. 235 * Payload handlers for incoming channels.
372 */ 236 */
373 const struct GNUNET_MQ_MessageHandler *handlers; 237 struct GNUNET_MQ_MessageHandler *handlers;
374}; 238};
375 239
376 240
377/** 241/**
378 * Implementation state for cadet's message queue.
379 */
380struct CadetMQState
381{
382 /**
383 * The current transmit handle, or NULL
384 * if no transmit is active.
385 */
386 struct GNUNET_CADET_TransmitHandle *th;
387
388 /**
389 * Channel to send the data over.
390 */
391 struct GNUNET_CADET_Channel *channel;
392};
393
394
395
396/******************************************************************************/
397/********************* FUNCTION DECLARATIONS *************************/
398/******************************************************************************/
399
400/**
401 * Reconnect to the service, retransmit all infomation to try to restore the
402 * original state.
403 *
404 * @param h Handle to the CADET service.
405 */
406static void
407schedule_reconnect (struct GNUNET_CADET_Handle *h);
408
409
410/**
411 * Reconnect callback: tries to reconnect again after a failer previous
412 * reconnection.
413 *
414 * @param cls Closure (cadet handle).
415 */
416static void
417reconnect_cbk (void *cls);
418
419
420/**
421 * Reconnect to the service, retransmit all infomation to try to restore the
422 * original state.
423 *
424 * @param h handle to the cadet
425 */
426static void
427reconnect (struct GNUNET_CADET_Handle *h);
428
429
430/******************************************************************************/
431/*********************** AUXILIARY FUNCTIONS *************************/
432/******************************************************************************/
433
434/**
435 * Check if transmission is a payload packet.
436 *
437 * @param th Transmission handle.
438 *
439 * @return #GNUNET_YES if it is a payload packet,
440 * #GNUNET_NO if it is a cadet management packet.
441 */
442static int
443th_is_payload (struct GNUNET_CADET_TransmitHandle *th)
444{
445 return (th->notify != NULL) ? GNUNET_YES : GNUNET_NO;
446}
447
448
449/**
450 * Find the Port struct for a hash. 242 * Find the Port struct for a hash.
451 * 243 *
452 * @param h CADET handle. 244 * @param h CADET handle.
453 * @param hash HashCode for the port number. 245 * @param hash HashCode for the port number.
454 *
455 * @return The port handle if known, NULL otherwise. 246 * @return The port handle if known, NULL otherwise.
456 */ 247 */
457static struct GNUNET_CADET_Port * 248static struct GNUNET_CADET_Port *
458find_port (const struct GNUNET_CADET_Handle *h, 249find_port (const struct GNUNET_CADET_Handle *h,
459 const struct GNUNET_HashCode *hash) 250 const struct GNUNET_HashCode *hash)
460{ 251{
461 struct GNUNET_CADET_Port *p; 252 return GNUNET_CONTAINER_multihashmap_get (h->ports,
462 253 hash);
463 p = GNUNET_CONTAINER_multihashmap_get (h->ports, hash);
464
465 return p;
466} 254}
467 255
468 256
@@ -474,15 +262,11 @@ find_port (const struct GNUNET_CADET_Handle *h,
474 * @return handle to the required channel or NULL if not found 262 * @return handle to the required channel or NULL if not found
475 */ 263 */
476static struct GNUNET_CADET_Channel * 264static struct GNUNET_CADET_Channel *
477retrieve_channel (struct GNUNET_CADET_Handle *h, 265find_channel (struct GNUNET_CADET_Handle *h,
478 struct GNUNET_CADET_ClientChannelNumber ccn) 266 struct GNUNET_CADET_ClientChannelNumber ccn)
479{ 267{
480 struct GNUNET_CADET_Channel *ch; 268 return GNUNET_CONTAINER_multihashmap32_get (h->channels,
481 269 ntohl (ccn.channel_of_client));
482 for (ch = h->channels_head; NULL != ch; ch = ch->next)
483 if (ch->ccn.channel_of_client == ccn.channel_of_client)
484 return ch;
485 return NULL;
486} 270}
487 271
488 272
@@ -490,38 +274,37 @@ retrieve_channel (struct GNUNET_CADET_Handle *h,
490 * Create a new channel and insert it in the channel list of the cadet handle 274 * Create a new channel and insert it in the channel list of the cadet handle
491 * 275 *
492 * @param h Cadet handle 276 * @param h Cadet handle
493 * @param ccn Desired ccn of the channel, 0 to assign one automatically. 277 * @param ccnp pointer to desired ccn of the channel, NULL to assign one automatically.
494 *
495 * @return Handle to the created channel. 278 * @return Handle to the created channel.
496 */ 279 */
497static struct GNUNET_CADET_Channel * 280static struct GNUNET_CADET_Channel *
498create_channel (struct GNUNET_CADET_Handle *h, 281create_channel (struct GNUNET_CADET_Handle *h,
499 struct GNUNET_CADET_ClientChannelNumber ccn) 282 const struct GNUNET_CADET_ClientChannelNumber *ccnp)
500{ 283{
501 struct GNUNET_CADET_Channel *ch; 284 struct GNUNET_CADET_Channel *ch;
285 struct GNUNET_CADET_ClientChannelNumber ccn;
502 286
503 ch = GNUNET_new (struct GNUNET_CADET_Channel); 287 ch = GNUNET_new (struct GNUNET_CADET_Channel);
504 GNUNET_CONTAINER_DLL_insert (h->channels_head,
505 h->channels_tail,
506 ch);
507 ch->cadet = h; 288 ch->cadet = h;
508 if (0 == ccn.channel_of_client) 289 if (NULL == ccnp)
509 { 290 {
510 ch->ccn = h->next_ccn; 291 while (NULL !=
511 while (NULL != retrieve_channel (h, 292 find_channel (h,
512 h->next_ccn)) 293 h->next_ccn))
513 {
514 h->next_ccn.channel_of_client 294 h->next_ccn.channel_of_client
515 = htonl (1 + ntohl (h->next_ccn.channel_of_client)); 295 = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI | (1 + ntohl (h->next_ccn.channel_of_client)));
516 if (0 == ntohl (h->next_ccn.channel_of_client)) 296 ccn = h->next_ccn;
517 h->next_ccn.channel_of_client
518 = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
519 }
520 } 297 }
521 else 298 else
522 { 299 {
523 ch->ccn = ccn; 300 ccn = *ccnp;
524 } 301 }
302 ch->ccn = ccn;
303 GNUNET_assert (GNUNET_OK ==
304 GNUNET_CONTAINER_multihashmap32_put (h->channels,
305 ntohl (ch->ccn.channel_of_client),
306 ch,
307 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
525 return ch; 308 return ch;
526} 309}
527 310
@@ -535,114 +318,106 @@ create_channel (struct GNUNET_CADET_Handle *h,
535 * 318 *
536 * @param ch Pointer to the channel. 319 * @param ch Pointer to the channel.
537 * @param call_cleaner Whether to call the cleaner handler. 320 * @param call_cleaner Whether to call the cleaner handler.
538 *
539 * @return Handle to the required channel or NULL if not found.
540 */ 321 */
541static void 322static void
542destroy_channel (struct GNUNET_CADET_Channel *ch) 323destroy_channel (struct GNUNET_CADET_Channel *ch)
543{ 324{
544 struct GNUNET_CADET_Handle *h; 325 struct GNUNET_CADET_Handle *h = ch->cadet;
545 struct GNUNET_CADET_TransmitHandle *th;
546 struct GNUNET_CADET_TransmitHandle *next;
547 326
548 if (NULL == ch)
549 {
550 GNUNET_break (0);
551 return;
552 }
553 h = ch->cadet;
554 LOG (GNUNET_ERROR_TYPE_DEBUG, 327 LOG (GNUNET_ERROR_TYPE_DEBUG,
555 " destroy_channel %X of %p\n", 328 "Destroying channel %X of %p\n",
556 ch->ccn, 329 ch->ccn,
557 h); 330 h);
558 331 GNUNET_assert (GNUNET_YES ==
559 GNUNET_CONTAINER_DLL_remove (h->channels_head, 332 GNUNET_CONTAINER_multihashmap32_remove (h->channels,
560 h->channels_tail, 333 ntohl (ch->ccn.channel_of_client),
561 ch); 334 ch));
562 if (NULL != ch->mq_cont) 335 if (NULL != ch->mq_cont)
563 { 336 {
564 GNUNET_SCHEDULER_cancel (ch->mq_cont); 337 GNUNET_SCHEDULER_cancel (ch->mq_cont);
565 ch->mq_cont = NULL; 338 ch->mq_cont = NULL;
566 } 339 }
567 /* signal channel destruction */ 340 /* signal channel destruction */
568 if (0 != ch->peer) 341 if (NULL != ch->disconnects)
569 { 342 ch->disconnects (ch->ctx,
570 if (NULL != h->cleaner) 343 ch);
571 { 344 if (NULL != ch->pending_env)
572 /** @a deprecated */ 345 GNUNET_MQ_discard (ch->pending_env);
573 LOG (GNUNET_ERROR_TYPE_DEBUG, 346 GNUNET_MQ_destroy (ch->mq);
574 " calling cleaner\n");
575 h->cleaner (h->cls, ch, ch->ctx);
576 }
577 else if (NULL != ch->disconnects)
578 {
579 LOG (GNUNET_ERROR_TYPE_DEBUG,
580 " calling disconnect handler\n");
581 ch->disconnects (ch->ctx, ch);
582 }
583 else
584 {
585 /* Application won't be aware of the channel destruction and use
586 * a pointer to free'd memory.
587 */
588 GNUNET_assert (0);
589 }
590 }
591
592 /* check that clients did not leave messages behind in the queue */
593 for (th = h->th_head; NULL != th; th = next)
594 {
595 next = th->next;
596 if (th->channel != ch)
597 continue;
598 /* Clients should have aborted their requests already.
599 * Management traffic should be ok, as clients can't cancel that.
600 * If the service crashed and we are reconnecting, it's ok.
601 */
602 GNUNET_break (GNUNET_NO == th_is_payload (th));
603 GNUNET_CADET_notify_transmit_ready_cancel (th);
604 }
605
606 if (0 != ch->peer)
607 GNUNET_PEER_change_rc (ch->peer, -1);
608 GNUNET_free (ch); 347 GNUNET_free (ch);
609} 348}
610 349
611 350
612/** 351/**
613 * Add a transmit handle to the transmission queue and set the 352 * Reconnect to the service, retransmit all infomation to try to restore the
614 * timeout if needed. 353 * original state.
354 *
355 * @param h handle to the cadet
356 */
357static void
358reconnect (struct GNUNET_CADET_Handle *h);
359
360
361/**
362 * Reconnect callback: tries to reconnect again after a failer previous
363 * reconnecttion
615 * 364 *
616 * @param h cadet handle with the queue head and tail 365 * @param cls closure (cadet handle)
617 * @param th handle to the packet to be transmitted
618 */ 366 */
619static void 367static void
620add_to_queue (struct GNUNET_CADET_Handle *h, 368reconnect_cbk (void *cls)
621 struct GNUNET_CADET_TransmitHandle *th) 369{
370 struct GNUNET_CADET_Handle *h = cls;
371
372 h->reconnect_task = NULL;
373 reconnect (h);
374}
375
376
377/**
378 * Function called during #reconnect() to destroy
379 * all channels that are still open.
380 *
381 * @param cls the `struct GNUNET_CADET_Handle`
382 * @param cid chanenl ID
383 * @param value a `struct GNUNET_CADET_Channel` to destroy
384 * @return #GNUNET_OK (continue to iterate)
385 */
386static int
387destroy_channel_on_reconnect_cb (void *cls,
388 uint32_t cid,
389 void *value)
622{ 390{
623 GNUNET_CONTAINER_DLL_insert_tail (h->th_head, 391 /* struct GNUNET_CADET_Handle *handle = cls; */
624 h->th_tail, 392 struct GNUNET_CADET_Channel *ch = value;
625 th); 393
394 destroy_channel (ch);
395 return GNUNET_OK;
626} 396}
627 397
628 398
629/** 399/**
630 * Remove a transmit handle from the transmission queue, if present. 400 * Reconnect to the service, retransmit all infomation to try to restore the
401 * original state.
631 * 402 *
632 * Safe to call even if not queued. 403 * @param h handle to the cadet
633 * 404 *
634 * @param th handle to the packet to be unqueued. 405 * @return #GNUNET_YES in case of sucess, #GNUNET_NO otherwise (service down...)
635 */ 406 */
636static void 407static void
637remove_from_queue (struct GNUNET_CADET_TransmitHandle *th) 408schedule_reconnect (struct GNUNET_CADET_Handle *h)
638{ 409{
639 struct GNUNET_CADET_Handle *h = th->channel->cadet; 410 if (NULL != h->reconnect_task)
640 411 return;
641 /* It might or might not have been queued (rarely not), but check anyway. */ 412 GNUNET_CONTAINER_multihashmap32_iterate (h->channels,
642 if (NULL != th->next || h->th_tail == th) 413 &destroy_channel_on_reconnect_cb,
643 { 414 h);
644 GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th); 415 h->reconnect_task
645 } 416 = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
417 &reconnect_cbk,
418 h);
419 h->reconnect_time
420 = GNUNET_TIME_STD_BACKOFF (h->reconnect_time);
646} 421}
647 422
648 423
@@ -655,29 +430,44 @@ static void
655notify_window_size (struct GNUNET_CADET_Channel *ch) 430notify_window_size (struct GNUNET_CADET_Channel *ch)
656{ 431{
657 if (NULL != ch->window_changes) 432 if (NULL != ch->window_changes)
658 { 433 ch->window_changes (ch->ctx,
659 ch->window_changes (ch->ctx, ch, ch->allow_send); 434 ch, /* FIXME: remove 'ch'? */
660 } 435 ch->allow_send);
661} 436}
662 437
663/******************************************************************************/
664/*********************** MQ API CALLBACKS ****************************/
665/******************************************************************************/
666 438
667/** 439/**
668 * Allow the MQ implementation to send the next message. 440 * Transmit the next message from our queue.
669 * 441 *
670 * @param cls Closure (channel whose mq to activate). 442 * @param cls Closure (channel whose mq to activate).
671 */ 443 */
672static void 444static void
673cadet_mq_send_continue (void *cls) 445cadet_mq_send_now (void *cls)
674{ 446{
675 struct GNUNET_CADET_Channel *ch = cls; 447 struct GNUNET_CADET_Channel *ch = cls;
448 struct GNUNET_MQ_Envelope *env = ch->pending_env;
676 449
677 ch->mq_cont = NULL; 450 ch->mq_cont = NULL;
451 if (0 == ch->allow_send)
452 {
453 /* how did we get here? */
454 GNUNET_break (0);
455 return;
456 }
457 if (NULL == env)
458 {
459 /* how did we get here? */
460 GNUNET_break (0);
461 return;
462 }
463 ch->allow_send--;
464 ch->pending_env = NULL;
465 GNUNET_MQ_send (ch->cadet->mq,
466 env);
678 GNUNET_MQ_impl_send_continue (ch->mq); 467 GNUNET_MQ_impl_send_continue (ch->mq);
679} 468}
680 469
470
681/** 471/**
682 * Implement sending functionality of a message queue for 472 * Implement sending functionality of a message queue for
683 * us sending messages to a peer. 473 * us sending messages to a peer.
@@ -701,7 +491,6 @@ cadet_mq_send_impl (struct GNUNET_MQ_Handle *mq,
701 struct GNUNET_MQ_Envelope *env; 491 struct GNUNET_MQ_Envelope *env;
702 struct GNUNET_CADET_LocalData *cadet_msg; 492 struct GNUNET_CADET_LocalData *cadet_msg;
703 493
704
705 if (NULL == h->mq) 494 if (NULL == h->mq)
706 { 495 {
707 /* We're currently reconnecting, pretend this worked */ 496 /* We're currently reconnecting, pretend this worked */
@@ -717,26 +506,16 @@ cadet_mq_send_impl (struct GNUNET_MQ_Handle *mq,
717 GNUNET_MQ_impl_send_continue (mq); 506 GNUNET_MQ_impl_send_continue (mq);
718 return; 507 return;
719 } 508 }
720
721 env = GNUNET_MQ_msg_nested_mh (cadet_msg, 509 env = GNUNET_MQ_msg_nested_mh (cadet_msg,
722 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA, 510 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
723 msg); 511 msg);
724 cadet_msg->ccn = ch->ccn; 512 cadet_msg->ccn = ch->ccn;
725 513 GNUNET_assert (NULL == ch->pending_env);
514 ch->pending_env = env;
726 if (0 < ch->allow_send) 515 if (0 < ch->allow_send)
727 { 516 ch->mq_cont
728 /* Service has allowed this message, just send it and continue accepting */ 517 = GNUNET_SCHEDULER_add_now (&cadet_mq_send_now,
729 GNUNET_MQ_send (h->mq, env); 518 ch);
730 ch->allow_send--;
731 ch->mq_cont = GNUNET_SCHEDULER_add_now (&cadet_mq_send_continue, ch);
732 // notify_window_size (ch); /* FIXME add "verbose" setting? */
733 }
734 else
735 {
736 /* Service has NOT allowed this message, queue it and wait for an ACK */
737 GNUNET_assert (NULL == ch->pending_env);
738 ch->pending_env = env;
739 }
740} 519}
741 520
742 521
@@ -763,14 +542,25 @@ cadet_mq_destroy_impl (struct GNUNET_MQ_Handle *mq,
763 * the CADET service. We should just complain about it but otherwise 542 * the CADET service. We should just complain about it but otherwise
764 * continue processing. 543 * continue processing.
765 * 544 *
766 * @param cls closure 545 * @param cls closure with our `struct GNUNET_CADET_Channel`
767 * @param error error code 546 * @param error error code
768 */ 547 */
769static void 548static void
770cadet_mq_error_handler (void *cls, 549cadet_mq_error_handler (void *cls,
771 enum GNUNET_MQ_Error error) 550 enum GNUNET_MQ_Error error)
772{ 551{
773 GNUNET_break_op (0); 552 struct GNUNET_CADET_Channel *ch = cls;
553
554 GNUNET_break (0);
555 if (GNUNET_MQ_ERROR_NO_MATCH == error)
556 {
557 /* Got a message we did not understand, still try to continue! */
558 GNUNET_CADET_receive_done (ch);
559 }
560 else
561 {
562 schedule_reconnect (ch->cadet);
563 }
774} 564}
775 565
776 566
@@ -781,65 +571,20 @@ cadet_mq_error_handler (void *cls,
781 * @param mq message queue 571 * @param mq message queue
782 * @param impl_state state specific to the implementation 572 * @param impl_state state specific to the implementation
783 */ 573 */
784
785static void 574static void
786cadet_mq_cancel_impl (struct GNUNET_MQ_Handle *mq, 575cadet_mq_cancel_impl (struct GNUNET_MQ_Handle *mq,
787 void *impl_state) 576 void *impl_state)
788{ 577{
789 struct GNUNET_CADET_Channel *ch = impl_state; 578 struct GNUNET_CADET_Channel *ch = impl_state;
790 579
791 LOG (GNUNET_ERROR_TYPE_WARNING, 580 GNUNET_assert (NULL != ch->pending_env);
792 "Cannot cancel mq message on channel %X of %p\n", 581 GNUNET_MQ_discard (ch->pending_env);
793 ch->ccn.channel_of_client, ch->cadet); 582 ch->pending_env = NULL;
794 583 if (NULL != ch->mq_cont)
795 GNUNET_break (0); 584 {
796} 585 GNUNET_SCHEDULER_cancel (ch->mq_cont);
797 586 ch->mq_cont = NULL;
798 587 }
799/******************************************************************************/
800/*********************** RECEIVE HANDLERS ****************************/
801/******************************************************************************/
802
803
804/**
805 * Call the @a notify callback given to #GNUNET_CADET_notify_transmit_ready to
806 * request the data to send over MQ. Since MQ manages the queue, this function
807 * is scheduled immediatly after a transmit ready notification.
808 *
809 * @param cls Closure (transmit handle).
810 */
811static void
812request_data (void *cls)
813{
814 struct GNUNET_CADET_TransmitHandle *th = cls;
815 struct GNUNET_CADET_LocalData *msg;
816 struct GNUNET_MQ_Envelope *env;
817 size_t osize;
818
819 LOG (GNUNET_ERROR_TYPE_DEBUG,
820 "Requesting Data: %u bytes (allow send is %u)\n",
821 th->size,
822 th->channel->allow_send);
823
824 GNUNET_assert (0 < th->channel->allow_send);
825 th->channel->allow_send--;
826 /* NOTE: we may be allowed to send another packet immediately,
827 albeit the current logic waits for the ACK. */
828 th->request_data_task = NULL;
829 remove_from_queue (th);
830
831 env = GNUNET_MQ_msg_extra (msg,
832 th->size,
833 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
834 msg->ccn = th->channel->ccn;
835 osize = th->notify (th->notify_cls,
836 th->size,
837 &msg[1]);
838 GNUNET_assert (osize == th->size);
839
840 GNUNET_MQ_send (th->channel->cadet->mq,
841 env);
842 GNUNET_free (th);
843} 588}
844 589
845 590
@@ -866,7 +611,8 @@ handle_channel_created (void *cls,
866 GNUNET_break (0); 611 GNUNET_break (0);
867 return; 612 return;
868 } 613 }
869 port = find_port (h, port_number); 614 port = find_port (h,
615 port_number);
870 if (NULL == port) 616 if (NULL == port)
871 { 617 {
872 /* We could have closed the port but the service didn't know about it yet 618 /* We could have closed the port but the service didn't know about it yet
@@ -875,7 +621,6 @@ handle_channel_created (void *cls,
875 struct GNUNET_CADET_LocalChannelDestroyMessage *d_msg; 621 struct GNUNET_CADET_LocalChannelDestroyMessage *d_msg;
876 struct GNUNET_MQ_Envelope *env; 622 struct GNUNET_MQ_Envelope *env;
877 623
878 GNUNET_break (0);
879 LOG (GNUNET_ERROR_TYPE_DEBUG, 624 LOG (GNUNET_ERROR_TYPE_DEBUG,
880 "No handler for incoming channel %X (on port %s, recently closed?)\n", 625 "No handler for incoming channel %X (on port %s, recently closed?)\n",
881 ntohl (ccn.channel_of_client), 626 ntohl (ccn.channel_of_client),
@@ -889,10 +634,9 @@ handle_channel_created (void *cls,
889 } 634 }
890 635
891 ch = create_channel (h, 636 ch = create_channel (h,
892 ccn); 637 &ccn);
893 ch->peer = GNUNET_PEER_intern (&msg->peer); 638 ch->peer = msg->peer;
894 ch->cadet = h; 639 ch->cadet = h;
895 ch->ccn = ccn;
896 ch->incoming_port = port; 640 ch->incoming_port = port;
897 ch->options = ntohl (msg->opt); 641 ch->options = ntohl (msg->opt);
898 LOG (GNUNET_ERROR_TYPE_DEBUG, 642 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -901,34 +645,21 @@ handle_channel_created (void *cls,
901 GNUNET_h2s (port_number), 645 GNUNET_h2s (port_number),
902 ch); 646 ch);
903 647
904 if (NULL != port->handler) 648 GNUNET_assert (NULL != port->connects);
905 { 649 ch->window_changes = port->window_changes;
906 /** @deprecated */ 650 ch->disconnects = port->disconnects;
907 /* Old style API */ 651 ch->mq = GNUNET_MQ_queue_for_callbacks (&cadet_mq_send_impl,
908 ch->ctx = port->handler (port->cls, 652 &cadet_mq_destroy_impl,
909 ch, 653 &cadet_mq_cancel_impl,
910 &msg->peer, 654 ch,
911 port->hash, 655 port->handlers,
912 ch->options); 656 &cadet_mq_error_handler,
913 } 657 ch);
914 else 658 ch->ctx = port->connects (port->cls,
915 { 659 ch,
916 /* MQ API */ 660 &msg->peer);
917 GNUNET_assert (NULL != port->connects); 661 GNUNET_MQ_set_handlers_closure (ch->mq,
918 ch->window_changes = port->window_changes; 662 ch->ctx);
919 ch->disconnects = port->disconnects;
920 ch->mq = GNUNET_MQ_queue_for_callbacks (&cadet_mq_send_impl,
921 &cadet_mq_destroy_impl,
922 &cadet_mq_cancel_impl,
923 ch,
924 port->handlers,
925 &cadet_mq_error_handler,
926 ch);
927 ch->ctx = port->connects (port->cls,
928 ch,
929 &msg->peer);
930 GNUNET_MQ_set_handlers_closure (ch->mq, ch->ctx);
931 }
932} 663}
933 664
934 665
@@ -944,22 +675,19 @@ handle_channel_destroy (void *cls,
944{ 675{
945 struct GNUNET_CADET_Handle *h = cls; 676 struct GNUNET_CADET_Handle *h = cls;
946 struct GNUNET_CADET_Channel *ch; 677 struct GNUNET_CADET_Channel *ch;
947 struct GNUNET_CADET_ClientChannelNumber ccn;
948
949 ccn = msg->ccn;
950 LOG (GNUNET_ERROR_TYPE_DEBUG,
951 "Channel %X Destroy from service\n",
952 ntohl (ccn.channel_of_client));
953 ch = retrieve_channel (h,
954 ccn);
955 678
679 ch = find_channel (h,
680 msg->ccn);
956 if (NULL == ch) 681 if (NULL == ch)
957 { 682 {
958 LOG (GNUNET_ERROR_TYPE_DEBUG, 683 LOG (GNUNET_ERROR_TYPE_DEBUG,
959 "channel %X unknown\n", 684 "Received channel destroy for unknown channel %X from CADET service (recently close?)\n",
960 ntohl (ccn.channel_of_client)); 685 ntohl (msg->ccn.channel_of_client));
961 return; 686 return;
962 } 687 }
688 LOG (GNUNET_ERROR_TYPE_DEBUG,
689 "Received channel destroy for channel %X from CADET service\n",
690 ntohl (msg->ccn.channel_of_client));
963 destroy_channel (ch); 691 destroy_channel (ch);
964} 692}
965 693
@@ -976,25 +704,14 @@ static int
976check_local_data (void *cls, 704check_local_data (void *cls,
977 const struct GNUNET_CADET_LocalData *message) 705 const struct GNUNET_CADET_LocalData *message)
978{ 706{
979 struct GNUNET_CADET_Handle *h = cls;
980 struct GNUNET_CADET_Channel *ch;
981 uint16_t size; 707 uint16_t size;
982 708
983 size = ntohs (message->header.size); 709 size = ntohs (message->header.size);
984 if (sizeof (*message) + sizeof (struct GNUNET_MessageHeader) > size) 710 if (sizeof (*message) + sizeof (struct GNUNET_MessageHeader) > size)
985 { 711 {
986 GNUNET_break_op (0); 712 GNUNET_break (0);
987 return GNUNET_SYSERR;
988 }
989
990 ch = retrieve_channel (h,
991 message->ccn);
992 if (NULL == ch)
993 {
994 GNUNET_break_op (0);
995 return GNUNET_SYSERR; 713 return GNUNET_SYSERR;
996 } 714 }
997
998 return GNUNET_OK; 715 return GNUNET_OK;
999} 716}
1000 717
@@ -1011,62 +728,31 @@ handle_local_data (void *cls,
1011{ 728{
1012 struct GNUNET_CADET_Handle *h = cls; 729 struct GNUNET_CADET_Handle *h = cls;
1013 const struct GNUNET_MessageHeader *payload; 730 const struct GNUNET_MessageHeader *payload;
1014 const struct GNUNET_CADET_MessageHandler *handler;
1015 struct GNUNET_CADET_Channel *ch; 731 struct GNUNET_CADET_Channel *ch;
1016 uint16_t type; 732 uint16_t type;
1017 int fwd; 733 int fwd;
1018 734
1019 ch = retrieve_channel (h, 735 ch = find_channel (h,
1020 message->ccn); 736 message->ccn);
1021 if (NULL == ch) 737 if (NULL == ch)
1022 { 738 {
1023 GNUNET_break_op (0); 739 LOG (GNUNET_ERROR_TYPE_DEBUG,
1024 reconnect (h); 740 "Unknown channel %X for incoming data (recently closed?)\n",
741 ntohl (message->ccn.channel_of_client));
1025 return; 742 return;
1026 } 743 }
1027 744
1028 payload = (struct GNUNET_MessageHeader *) &message[1]; 745 payload = (const struct GNUNET_MessageHeader *) &message[1];
1029 type = ntohs (payload->type); 746 type = ntohs (payload->type);
1030 fwd = ntohl (ch->ccn.channel_of_client) <= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI; 747 fwd = ntohl (ch->ccn.channel_of_client) <= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
1031 LOG (GNUNET_ERROR_TYPE_DEBUG, 748 LOG (GNUNET_ERROR_TYPE_DEBUG,
1032 "Got a %s data on channel %s [%X] of type %s (%u)\n", 749 "Got a %s data on channel %s [%X] of type %u\n",
1033 GC_f2s (fwd), 750 fwd ? "FWD" : "BWD",
1034 GNUNET_i2s (GNUNET_PEER_resolve2 (ch->peer)), 751 GNUNET_i2s (&ch->peer),
1035 ntohl (message->ccn.channel_of_client), 752 ntohl (message->ccn.channel_of_client),
1036 GC_m2s (type),
1037 type); 753 type);
1038 if (NULL != ch->mq) 754 GNUNET_MQ_inject_message (ch->mq,
1039 { 755 payload);
1040 LOG (GNUNET_ERROR_TYPE_DEBUG,
1041 "injecting msg %s into mq %p\n",
1042 GC_m2s (ntohs (payload->type)),
1043 ch->mq);
1044 GNUNET_MQ_inject_message (ch->mq, payload);
1045 return;
1046 }
1047 /** @a deprecated */
1048 for (unsigned i=0;i<h->n_handlers;i++)
1049 {
1050 handler = &h->message_handlers[i];
1051 if (handler->type == type)
1052 {
1053 if (GNUNET_OK !=
1054 handler->callback (h->cls,
1055 ch,
1056 &ch->ctx,
1057 payload))
1058 {
1059 LOG (GNUNET_ERROR_TYPE_DEBUG,
1060 "callback caused disconnection\n");
1061 GNUNET_CADET_channel_destroy (ch);
1062 return;
1063 }
1064 return;
1065 }
1066 }
1067 /* Other peer sent message we do not comprehend. */
1068 GNUNET_break_op (0);
1069 GNUNET_CADET_receive_done (ch);
1070} 756}
1071 757
1072 758
@@ -1083,55 +769,34 @@ handle_local_ack (void *cls,
1083{ 769{
1084 struct GNUNET_CADET_Handle *h = cls; 770 struct GNUNET_CADET_Handle *h = cls;
1085 struct GNUNET_CADET_Channel *ch; 771 struct GNUNET_CADET_Channel *ch;
1086 struct GNUNET_CADET_ClientChannelNumber ccn;
1087 struct GNUNET_CADET_TransmitHandle *th;
1088 772
1089 ccn = message->ccn; 773 ch = find_channel (h,
1090 ch = retrieve_channel (h, ccn); 774 message->ccn);
1091 if (NULL == ch) 775 if (NULL == ch)
1092 { 776 {
1093 LOG (GNUNET_ERROR_TYPE_DEBUG, 777 LOG (GNUNET_ERROR_TYPE_DEBUG,
1094 "ACK on unknown channel %X\n", 778 "ACK on unknown channel %X\n",
1095 ntohl (ccn.channel_of_client)); 779 ntohl (message->ccn.channel_of_client));
1096 return; 780 return;
1097 } 781 }
1098 ch->allow_send++; 782 ch->allow_send++;
1099 if (NULL != ch->mq) 783 if (NULL == ch->pending_env)
1100 { 784 {
1101 if (NULL == ch->pending_env) 785 LOG (GNUNET_ERROR_TYPE_DEBUG,
1102 { 786 "Got an ACK on mq channel %X, allow send now %u!\n",
1103 LOG (GNUNET_ERROR_TYPE_DEBUG, 787 ntohl (ch->ccn.channel_of_client),
1104 "Got an ACK on mq channel %X, allow send now %u!\n", 788 ch->allow_send);
1105 ntohl (ch->ccn.channel_of_client), 789 notify_window_size (ch);
1106 ch->allow_send);
1107 notify_window_size (ch);
1108 }
1109 else
1110 {
1111 LOG (GNUNET_ERROR_TYPE_DEBUG,
1112 "Got an ACK on mq channel %X, sending pending message!\n",
1113 ntohl (ch->ccn.channel_of_client));
1114 GNUNET_MQ_send (h->mq, ch->pending_env);
1115 ch->allow_send--;
1116 ch->pending_env = NULL;
1117 ch->mq_cont = GNUNET_SCHEDULER_add_now (&cadet_mq_send_continue, ch);
1118 }
1119 return; 790 return;
1120 } 791 }
1121 792 if (NULL != ch->mq_cont)
1122 /** @deprecated */ 793 return; /* already working on it! */
1123 /* Old style API */ 794 LOG (GNUNET_ERROR_TYPE_DEBUG,
1124 for (th = h->th_head; NULL != th; th = th->next) 795 "Got an ACK on mq channel %X, sending pending message!\n",
1125 { 796 ntohl (ch->ccn.channel_of_client));
1126 if ( (th->channel == ch) && 797 ch->mq_cont
1127 (NULL == th->request_data_task) ) 798 = GNUNET_SCHEDULER_add_now (&cadet_mq_send_now,
1128 { 799 ch);
1129 th->request_data_task
1130 = GNUNET_SCHEDULER_add_now (&request_data,
1131 th);
1132 break;
1133 }
1134 }
1135} 800}
1136 801
1137 802
@@ -1149,134 +814,15 @@ handle_mq_error (void *cls,
1149{ 814{
1150 struct GNUNET_CADET_Handle *h = cls; 815 struct GNUNET_CADET_Handle *h = cls;
1151 816
1152 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MQ ERROR: %u\n", error); 817 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
818 "MQ ERROR: %u\n",
819 error);
1153 GNUNET_MQ_destroy (h->mq); 820 GNUNET_MQ_destroy (h->mq);
1154 h->mq = NULL; 821 h->mq = NULL;
1155 reconnect (h); 822 reconnect (h);
1156} 823}
1157 824
1158 825
1159/*
1160 * Process a local reply about info on all channels, pass info to the user.
1161 *
1162 * @param h Cadet handle.
1163 * @param message Message itself.
1164 */
1165// static void
1166// process_get_channels (struct GNUNET_CADET_Handle *h,
1167// const struct GNUNET_MessageHeader *message)
1168// {
1169// struct GNUNET_CADET_LocalInfo *msg;
1170//
1171// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Get Channels messasge received\n");
1172//
1173// if (NULL == h->channels_cb)
1174// {
1175// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " ignored\n");
1176// return;
1177// }
1178//
1179// msg = (struct GNUNET_CADET_LocalInfo *) message;
1180// if (ntohs (message->size) !=
1181// (sizeof (struct GNUNET_CADET_LocalInfo) +
1182// sizeof (struct GNUNET_PeerIdentity)))
1183// {
1184// GNUNET_break_op (0);
1185// GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1186// "Get channels message: size %hu - expected %u\n",
1187// ntohs (message->size),
1188// sizeof (struct GNUNET_CADET_LocalInfo));
1189// return;
1190// }
1191// h->channels_cb (h->channels_cls,
1192// ntohl (msg->channel_id),
1193// &msg->owner,
1194// &msg->destination);
1195// }
1196
1197
1198
1199/*
1200 * Process a local monitor_channel reply, pass info to the user.
1201 *
1202 * @param h Cadet handle.
1203 * @param message Message itself.
1204 */
1205// static void
1206// process_show_channel (struct GNUNET_CADET_Handle *h,
1207// const struct GNUNET_MessageHeader *message)
1208// {
1209// struct GNUNET_CADET_LocalInfo *msg;
1210// size_t esize;
1211//
1212// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Show Channel messasge received\n");
1213//
1214// if (NULL == h->channel_cb)
1215// {
1216// GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " ignored\n");
1217// return;
1218// }
1219//
1220// /* Verify message sanity */
1221// msg = (struct GNUNET_CADET_LocalInfo *) message;
1222// esize = sizeof (struct GNUNET_CADET_LocalInfo);
1223// if (ntohs (message->size) != esize)
1224// {
1225// GNUNET_break_op (0);
1226// GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1227// "Show channel message: size %hu - expected %u\n",
1228// ntohs (message->size),
1229// esize);
1230//
1231// h->channel_cb (h->channel_cls, NULL, NULL);
1232// h->channel_cb = NULL;
1233// h->channel_cls = NULL;
1234//
1235// return;
1236// }
1237//
1238// h->channel_cb (h->channel_cls,
1239// &msg->destination,
1240// &msg->owner);
1241// }
1242
1243
1244
1245/**
1246 * Check that message received from CADET service is well-formed.
1247 *
1248 * @param cls the `struct GNUNET_CADET_Handle`
1249 * @param message the message we got
1250 * @return #GNUNET_OK if the message is well-formed,
1251 * #GNUNET_SYSERR otherwise
1252 */
1253static int
1254check_get_peers (void *cls,
1255 const struct GNUNET_CADET_LocalInfoPeer *message)
1256{
1257 struct GNUNET_CADET_Handle *h = cls;
1258 uint16_t size;
1259
1260 if (NULL == h->info_cb.peers_cb)
1261 {
1262 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1263 " no handler for peesr monitor message!\n");
1264 return GNUNET_SYSERR;
1265 }
1266
1267 size = ntohs (message->header.size);
1268 if (sizeof (struct GNUNET_CADET_LocalInfoPeer) > size)
1269 {
1270 h->info_cb.peers_cb (h->info_cls, NULL, -1, 0, 0);
1271 h->info_cb.peers_cb = NULL;
1272 h->info_cls = NULL;
1273 return GNUNET_SYSERR;
1274 }
1275
1276 return GNUNET_OK;
1277}
1278
1279
1280/** 826/**
1281 * Process a local reply about info on all tunnels, pass info to the user. 827 * Process a local reply about info on all tunnels, pass info to the user.
1282 * 828 *
@@ -1288,9 +834,13 @@ handle_get_peers (void *cls,
1288 const struct GNUNET_CADET_LocalInfoPeer *msg) 834 const struct GNUNET_CADET_LocalInfoPeer *msg)
1289{ 835{
1290 struct GNUNET_CADET_Handle *h = cls; 836 struct GNUNET_CADET_Handle *h = cls;
1291 h->info_cb.peers_cb (h->info_cls, &msg->destination, 837
838 if (NULL == h->info_cb.peers_cb)
839 return;
840 h->info_cb.peers_cb (h->info_cls,
841 &msg->destination,
1292 (int) ntohs (msg->tunnel), 842 (int) ntohs (msg->tunnel),
1293 (unsigned int ) ntohs (msg->paths), 843 (unsigned int) ntohs (msg->paths),
1294 0); 844 0);
1295} 845}
1296 846
@@ -1307,62 +857,39 @@ static int
1307check_get_peer (void *cls, 857check_get_peer (void *cls,
1308 const struct GNUNET_CADET_LocalInfoPeer *message) 858 const struct GNUNET_CADET_LocalInfoPeer *message)
1309{ 859{
1310 struct GNUNET_CADET_Handle *h = cls; 860 size_t msize = sizeof (struct GNUNET_CADET_LocalInfoPeer);
1311 const size_t msize = sizeof (struct GNUNET_CADET_LocalInfoPeer); 861 const struct GNUNET_PeerIdentity *paths_array;
1312 struct GNUNET_PeerIdentity *paths_array;
1313 size_t esize; 862 size_t esize;
1314 unsigned int epaths; 863 unsigned int epaths;
1315 unsigned int paths; 864 unsigned int paths;
1316 unsigned int peers; 865 unsigned int peers;
1317 866
1318 if (NULL == h->info_cb.peer_cb)
1319 {
1320 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1321 " no handler for peer monitor message!\n");
1322 goto clean_cls;
1323 }
1324
1325 /* Verify message sanity */
1326 esize = ntohs (message->header.size); 867 esize = ntohs (message->header.size);
1327 if (esize < msize) 868 if (esize < msize)
1328 { 869 {
1329 GNUNET_break_op (0); 870 GNUNET_break (0);
1330 h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL); 871 return GNUNET_SYSERR;
1331 goto clean_cls;
1332 } 872 }
1333 if (0 != ((esize - msize) % sizeof (struct GNUNET_PeerIdentity))) 873 if (0 != ((esize - msize) % sizeof (struct GNUNET_PeerIdentity)))
1334 { 874 {
1335 GNUNET_break_op (0); 875 GNUNET_break (0);
1336 h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL); 876 return GNUNET_SYSERR;
1337 goto clean_cls;
1338
1339 } 877 }
1340 peers = (esize - msize) / sizeof (struct GNUNET_PeerIdentity); 878 peers = (esize - msize) / sizeof (struct GNUNET_PeerIdentity);
1341 epaths = (unsigned int) ntohs (message->paths); 879 epaths = ntohs (message->paths);
1342 paths_array = (struct GNUNET_PeerIdentity *) &message[1]; 880 paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
1343 paths = 0; 881 paths = 0;
1344 for (int i = 0; i < peers; i++) 882 for (unsigned int i = 0; i < peers; i++)
1345 { 883 if (0 == memcmp (&paths_array[i],
1346 if (0 == memcmp (&paths_array[i], &message->destination, 884 &message->destination,
1347 sizeof (struct GNUNET_PeerIdentity))) 885 sizeof (struct GNUNET_PeerIdentity)))
1348 {
1349 paths++; 886 paths++;
1350 }
1351 }
1352 if (paths != epaths) 887 if (paths != epaths)
1353 { 888 {
1354 GNUNET_break_op (0); 889 GNUNET_break (0);
1355 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "p:%u, e: %u\n", paths, epaths); 890 return GNUNET_SYSERR;
1356 h->info_cb.peer_cb (h->info_cls, NULL, 0, 0, 0, NULL);
1357 goto clean_cls;
1358 } 891 }
1359
1360 return GNUNET_OK; 892 return GNUNET_OK;
1361
1362clean_cls:
1363 h->info_cb.peer_cb = NULL;
1364 h->info_cls = NULL;
1365 return GNUNET_SYSERR;
1366} 893}
1367 894
1368 895
@@ -1377,22 +904,26 @@ handle_get_peer (void *cls,
1377 const struct GNUNET_CADET_LocalInfoPeer *message) 904 const struct GNUNET_CADET_LocalInfoPeer *message)
1378{ 905{
1379 struct GNUNET_CADET_Handle *h = cls; 906 struct GNUNET_CADET_Handle *h = cls;
1380 struct GNUNET_PeerIdentity *paths_array; 907 const struct GNUNET_PeerIdentity *paths_array;
1381 unsigned int paths; 908 unsigned int paths;
1382 unsigned int path_length; 909 unsigned int path_length;
1383 int neighbor; 910 int neighbor;
1384 unsigned int peers; 911 unsigned int peers;
1385 912
1386 paths = (unsigned int) ntohs (message->paths); 913 if (NULL == h->info_cb.peer_cb)
1387 paths_array = (struct GNUNET_PeerIdentity *) &message[1]; 914 return;
915 paths = ntohs (message->paths);
916 paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
1388 peers = (ntohs (message->header.size) - sizeof (*message)) 917 peers = (ntohs (message->header.size) - sizeof (*message))
1389 / sizeof (struct GNUNET_PeerIdentity); 918 / sizeof (struct GNUNET_PeerIdentity);
1390 path_length = 0; 919 path_length = 0;
1391 neighbor = GNUNET_NO; 920 neighbor = GNUNET_NO;
1392 921
1393 for (int i = 0; i < peers; i++) 922 for (unsigned int i = 0; i < peers; i++)
1394 { 923 {
1395 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", GNUNET_i2s (&paths_array[i])); 924 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
925 " %s\n",
926 GNUNET_i2s (&paths_array[i]));
1396 path_length++; 927 path_length++;
1397 if (0 == memcmp (&paths_array[i], &message->destination, 928 if (0 == memcmp (&paths_array[i], &message->destination,
1398 sizeof (struct GNUNET_PeerIdentity))) 929 sizeof (struct GNUNET_PeerIdentity)))
@@ -1404,7 +935,7 @@ handle_get_peer (void *cls,
1404 } 935 }
1405 936
1406 /* Call Callback with tunnel info. */ 937 /* Call Callback with tunnel info. */
1407 paths_array = (struct GNUNET_PeerIdentity *) &message[1]; 938 paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
1408 h->info_cb.peer_cb (h->info_cls, 939 h->info_cb.peer_cb (h->info_cls,
1409 &message->destination, 940 &message->destination,
1410 (int) ntohs (message->tunnel), 941 (int) ntohs (message->tunnel),
@@ -1415,40 +946,6 @@ handle_get_peer (void *cls,
1415 946
1416 947
1417/** 948/**
1418 * Check that message received from CADET service is well-formed.
1419 *
1420 * @param cls the `struct GNUNET_CADET_Handle`
1421 * @param msg the message we got
1422 * @return #GNUNET_OK if the message is well-formed,
1423 * #GNUNET_SYSERR otherwise
1424 */
1425static int
1426check_get_tunnels (void *cls,
1427 const struct GNUNET_CADET_LocalInfoTunnel *msg)
1428{
1429 struct GNUNET_CADET_Handle *h = cls;
1430 uint16_t size;
1431
1432 if (NULL == h->info_cb.tunnels_cb)
1433 {
1434 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1435 " no handler for tunnels monitor message!\n");
1436 return GNUNET_SYSERR;
1437 }
1438
1439 size = ntohs (msg->header.size);
1440 if (sizeof (struct GNUNET_CADET_LocalInfoTunnel) > size)
1441 {
1442 h->info_cb.tunnels_cb (h->info_cls, NULL, 0, 0, 0, 0);
1443 h->info_cb.tunnels_cb = NULL;
1444 h->info_cls = NULL;
1445 return GNUNET_SYSERR;
1446 }
1447 return GNUNET_OK;
1448}
1449
1450
1451/**
1452 * Process a local reply about info on all tunnels, pass info to the user. 949 * Process a local reply about info on all tunnels, pass info to the user.
1453 * 950 *
1454 * @param cls Closure (Cadet handle). 951 * @param cls Closure (Cadet handle).
@@ -1460,6 +957,8 @@ handle_get_tunnels (void *cls,
1460{ 957{
1461 struct GNUNET_CADET_Handle *h = cls; 958 struct GNUNET_CADET_Handle *h = cls;
1462 959
960 if (NULL == h->info_cb.tunnels_cb)
961 return;
1463 h->info_cb.tunnels_cb (h->info_cls, 962 h->info_cb.tunnels_cb (h->info_cls,
1464 &msg->destination, 963 &msg->destination,
1465 ntohl (msg->channels), 964 ntohl (msg->channels),
@@ -1482,28 +981,18 @@ static int
1482check_get_tunnel (void *cls, 981check_get_tunnel (void *cls,
1483 const struct GNUNET_CADET_LocalInfoTunnel *msg) 982 const struct GNUNET_CADET_LocalInfoTunnel *msg)
1484{ 983{
1485 struct GNUNET_CADET_Handle *h = cls;
1486 unsigned int ch_n; 984 unsigned int ch_n;
1487 unsigned int c_n; 985 unsigned int c_n;
1488 size_t esize; 986 size_t esize;
1489 size_t msize; 987 size_t msize;
1490 988
1491 if (NULL == h->info_cb.tunnel_cb)
1492 {
1493 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1494 " no handler for tunnel monitor message!\n");
1495 goto clean_cls;
1496 }
1497
1498 /* Verify message sanity */ 989 /* Verify message sanity */
1499 msize = ntohs (msg->header.size); 990 msize = ntohs (msg->header.size);
1500 esize = sizeof (struct GNUNET_CADET_LocalInfoTunnel); 991 esize = sizeof (struct GNUNET_CADET_LocalInfoTunnel);
1501 if (esize > msize) 992 if (esize > msize)
1502 { 993 {
1503 GNUNET_break_op (0); 994 GNUNET_break (0);
1504 h->info_cb.tunnel_cb (h->info_cls, 995 return GNUNET_SYSERR;
1505 NULL, 0, 0, NULL, NULL, 0, 0);
1506 goto clean_cls;
1507 } 996 }
1508 ch_n = ntohl (msg->channels); 997 ch_n = ntohl (msg->channels);
1509 c_n = ntohl (msg->connections); 998 c_n = ntohl (msg->connections);
@@ -1518,17 +1007,9 @@ check_get_tunnel (void *cls,
1518 (unsigned int) esize, 1007 (unsigned int) esize,
1519 ch_n, 1008 ch_n,
1520 c_n); 1009 c_n);
1521 h->info_cb.tunnel_cb (h->info_cls, 1010 return GNUNET_SYSERR;
1522 NULL, 0, 0, NULL, NULL, 0, 0);
1523 goto clean_cls;
1524 } 1011 }
1525
1526 return GNUNET_OK; 1012 return GNUNET_OK;
1527
1528clean_cls:
1529 h->info_cb.tunnel_cb = NULL;
1530 h->info_cls = NULL;
1531 return GNUNET_SYSERR;
1532} 1013}
1533 1014
1534 1015
@@ -1548,6 +1029,9 @@ handle_get_tunnel (void *cls,
1548 const struct GNUNET_CADET_ConnectionTunnelIdentifier *conns; 1029 const struct GNUNET_CADET_ConnectionTunnelIdentifier *conns;
1549 const struct GNUNET_CADET_ChannelTunnelNumber *chns; 1030 const struct GNUNET_CADET_ChannelTunnelNumber *chns;
1550 1031
1032 if (NULL == h->info_cb.tunnel_cb)
1033 return;
1034
1551 ch_n = ntohl (msg->channels); 1035 ch_n = ntohl (msg->channels);
1552 c_n = ntohl (msg->connections); 1036 c_n = ntohl (msg->connections);
1553 1037
@@ -1591,44 +1075,25 @@ reconnect (struct GNUNET_CADET_Handle *h)
1591 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK, 1075 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
1592 struct GNUNET_CADET_LocalAck, 1076 struct GNUNET_CADET_LocalAck,
1593 h), 1077 h),
1594 GNUNET_MQ_hd_var_size (get_peers, 1078 GNUNET_MQ_hd_fixed_size (get_peers,
1595 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS, 1079 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS,
1596 struct GNUNET_CADET_LocalInfoPeer, 1080 struct GNUNET_CADET_LocalInfoPeer,
1597 h), 1081 h),
1598 GNUNET_MQ_hd_var_size (get_peer, 1082 GNUNET_MQ_hd_var_size (get_peer,
1599 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER, 1083 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER,
1600 struct GNUNET_CADET_LocalInfoPeer, 1084 struct GNUNET_CADET_LocalInfoPeer,
1601 h), 1085 h),
1602 GNUNET_MQ_hd_var_size (get_tunnels, 1086 GNUNET_MQ_hd_fixed_size (get_tunnels,
1603 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS, 1087 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS,
1604 struct GNUNET_CADET_LocalInfoTunnel, 1088 struct GNUNET_CADET_LocalInfoTunnel,
1605 h), 1089 h),
1606 GNUNET_MQ_hd_var_size (get_tunnel, 1090 GNUNET_MQ_hd_var_size (get_tunnel,
1607 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL, 1091 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL,
1608 struct GNUNET_CADET_LocalInfoTunnel, 1092 struct GNUNET_CADET_LocalInfoTunnel,
1609 h), 1093 h),
1610// FIXME
1611// GNUNET_MQ_hd_fixed_Y size (channel_destroyed,
1612// GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED,
1613// struct GNUNET_CADET_ChannelDestroyMessage);
1614 GNUNET_MQ_handler_end () 1094 GNUNET_MQ_handler_end ()
1615 }; 1095 };
1616 struct GNUNET_CADET_Channel *ch;
1617
1618 while (NULL != (ch = h->channels_head))
1619 {
1620 LOG (GNUNET_ERROR_TYPE_DEBUG,
1621 "Destroying channel due to a reconnect\n");
1622 destroy_channel (ch);
1623 }
1624
1625 LOG (GNUNET_ERROR_TYPE_DEBUG, "Connecting to CADET\n");
1626 1096
1627 if (NULL != h->mq)
1628 {
1629 GNUNET_MQ_destroy (h->mq);
1630 h->mq = NULL;
1631 }
1632 h->mq = GNUNET_CLIENT_connect (h->cfg, 1097 h->mq = GNUNET_CLIENT_connect (h->cfg,
1633 "cadet", 1098 "cadet",
1634 handlers, 1099 handlers,
@@ -1639,85 +1104,60 @@ reconnect (struct GNUNET_CADET_Handle *h)
1639 schedule_reconnect (h); 1104 schedule_reconnect (h);
1640 return; 1105 return;
1641 } 1106 }
1642 else 1107 h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1643 {
1644 h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1645 }
1646} 1108}
1647 1109
1110
1648/** 1111/**
1649 * Reconnect callback: tries to reconnect again after a failer previous 1112 * Function called during #GNUNET_CADET_disconnect() to destroy
1650 * reconnecttion 1113 * all channels that are still open.
1651 * 1114 *
1652 * @param cls closure (cadet handle) 1115 * @param cls the `struct GNUNET_CADET_Handle`
1116 * @param cid chanenl ID
1117 * @param value a `struct GNUNET_CADET_Channel` to destroy
1118 * @return #GNUNET_OK (continue to iterate)
1653 */ 1119 */
1654static void 1120static int
1655reconnect_cbk (void *cls) 1121destroy_channel_cb (void *cls,
1122 uint32_t cid,
1123 void *value)
1656{ 1124{
1657 struct GNUNET_CADET_Handle *h = cls; 1125 /* struct GNUNET_CADET_Handle *handle = cls; */
1126 struct GNUNET_CADET_Channel *ch = value;
1658 1127
1659 h->reconnect_task = NULL; 1128 if (ntohl (ch->ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1660 reconnect (h); 1129 {
1130 GNUNET_break (0);
1131 LOG (GNUNET_ERROR_TYPE_DEBUG,
1132 "channel %X not destroyed\n",
1133 ntohl (ch->ccn.channel_of_client));
1134 }
1135 destroy_channel (ch);
1136 return GNUNET_OK;
1661} 1137}
1662 1138
1663 1139
1664/** 1140/**
1665 * Reconnect to the service, retransmit all infomation to try to restore the 1141 * Function called during #GNUNET_CADET_disconnect() to destroy
1666 * original state. 1142 * all ports that are still open.
1667 * 1143 *
1668 * @param h handle to the cadet 1144 * @param cls the `struct GNUNET_CADET_Handle`
1669 * 1145 * @param id port ID
1670 * @return #GNUNET_YES in case of sucess, #GNUNET_NO otherwise (service down...) 1146 * @param value a `struct GNUNET_CADET_Channel` to destroy
1147 * @return #GNUNET_OK (continue to iterate)
1671 */ 1148 */
1672static void 1149static int
1673schedule_reconnect (struct GNUNET_CADET_Handle *h) 1150destroy_port_cb (void *cls,
1674{ 1151 const struct GNUNET_HashCode *id,
1675 if (NULL == h->reconnect_task) 1152 void *value)
1676 {
1677 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
1678 &reconnect_cbk, h);
1679 h->reconnect_time = GNUNET_TIME_STD_BACKOFF (h->reconnect_time);
1680 }
1681}
1682
1683
1684/******************************************************************************/
1685/********************** API CALL DEFINITIONS *************************/
1686/******************************************************************************/
1687
1688struct GNUNET_CADET_Handle *
1689GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
1690 void *cls,
1691 GNUNET_CADET_ChannelEndHandler cleaner,
1692 const struct GNUNET_CADET_MessageHandler *handlers)
1693{ 1153{
1694 struct GNUNET_CADET_Handle *h; 1154 /* struct GNUNET_CADET_Handle *handle = cls; */
1695 1155 struct GNUNET_CADET_Port *port = value;
1696 h = GNUNET_new (struct GNUNET_CADET_Handle);
1697 LOG (GNUNET_ERROR_TYPE_DEBUG,
1698 "GNUNET_CADET_connect() %p\n",
1699 h);
1700 h->cfg = cfg;
1701 h->cleaner = cleaner;
1702 h->ports = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_YES);
1703 reconnect (h);
1704 if (h->mq == NULL)
1705 {
1706 GNUNET_break (0);
1707 GNUNET_CADET_disconnect (h);
1708 return NULL;
1709 }
1710 h->cls = cls;
1711 h->message_handlers = handlers;
1712 h->next_ccn.channel_of_client = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
1713 h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1714 h->reconnect_task = NULL;
1715 1156
1716 /* count handlers */ 1157 /* This is a warning, the app should have cleanly closed all open ports */
1717 for (h->n_handlers = 0; 1158 GNUNET_break (0);
1718 handlers && handlers[h->n_handlers].type; 1159 GNUNET_CADET_close_port (port);
1719 h->n_handlers++) ; 1160 return GNUNET_OK;
1720 return h;
1721} 1161}
1722 1162
1723 1163
@@ -1732,57 +1172,16 @@ GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
1732void 1172void
1733GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle) 1173GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle)
1734{ 1174{
1735 struct GNUNET_CADET_Channel *ch; 1175 GNUNET_CONTAINER_multihashmap_iterate (handle->ports,
1736 struct GNUNET_CADET_Channel *aux; 1176 &destroy_port_cb,
1737 struct GNUNET_CADET_TransmitHandle *th; 1177 handle);
1738 1178 GNUNET_CONTAINER_multihashmap_destroy (handle->ports);
1739 LOG (GNUNET_ERROR_TYPE_DEBUG, 1179 handle->ports = NULL;
1740 "CADET DISCONNECT\n"); 1180 GNUNET_CONTAINER_multihashmap32_iterate (handle->channels,
1741 ch = handle->channels_head; 1181 &destroy_channel_cb,
1742 while (NULL != ch) 1182 handle);
1743 { 1183 GNUNET_CONTAINER_multihashmap32_destroy (handle->channels);
1744 aux = ch->next; 1184 handle->channels = NULL;
1745 if (ntohl (ch->ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1746 {
1747 GNUNET_break (0);
1748 LOG (GNUNET_ERROR_TYPE_DEBUG,
1749 "channel %X not destroyed\n",
1750 ntohl (ch->ccn.channel_of_client));
1751 }
1752 destroy_channel (ch);
1753 ch = aux;
1754 }
1755 while (NULL != (th = handle->th_head))
1756 {
1757 struct GNUNET_MessageHeader *msg;
1758
1759 /* Make sure it is an allowed packet (everything else should have been
1760 * already canceled).
1761 */
1762 GNUNET_break (GNUNET_NO == th_is_payload (th));
1763 msg = (struct GNUNET_MessageHeader *) &th[1];
1764 switch (ntohs(msg->type))
1765 {
1766 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN:
1767 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY:
1768 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN:
1769 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE:
1770 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNELS:
1771 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL:
1772 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER:
1773 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS:
1774 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL:
1775 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS:
1776 break;
1777 default:
1778 GNUNET_break (0);
1779 LOG (GNUNET_ERROR_TYPE_ERROR, "unexpected unsent msg %s\n",
1780 GC_m2s (ntohs(msg->type)));
1781 }
1782
1783 GNUNET_CADET_notify_transmit_ready_cancel (th);
1784 }
1785
1786 if (NULL != handle->mq) 1185 if (NULL != handle->mq)
1787 { 1186 {
1788 GNUNET_MQ_destroy (handle->mq); 1187 GNUNET_MQ_destroy (handle->mq);
@@ -1790,58 +1189,15 @@ GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle)
1790 } 1189 }
1791 if (NULL != handle->reconnect_task) 1190 if (NULL != handle->reconnect_task)
1792 { 1191 {
1793 GNUNET_SCHEDULER_cancel(handle->reconnect_task); 1192 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
1794 handle->reconnect_task = NULL; 1193 handle->reconnect_task = NULL;
1795 } 1194 }
1796
1797 GNUNET_CONTAINER_multihashmap_destroy (handle->ports);
1798 handle->ports = NULL;
1799 GNUNET_free (handle); 1195 GNUNET_free (handle);
1800} 1196}
1801 1197
1802 1198
1803/** 1199/**
1804 * Open a port to receive incomming channels. 1200 * Close a port opened with @a GNUNET_CADET_open_port().
1805 *
1806 * @param h CADET handle.
1807 * @param port Hash representing the port number.
1808 * @param new_channel Function called when an channel is received.
1809 * @param new_channel_cls Closure for @a new_channel.
1810 * @return Port handle.
1811 */
1812struct GNUNET_CADET_Port *
1813GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h,
1814 const struct GNUNET_HashCode *port,
1815 GNUNET_CADET_InboundChannelNotificationHandler
1816 new_channel,
1817 void *new_channel_cls)
1818{
1819 struct GNUNET_CADET_PortMessage *msg;
1820 struct GNUNET_MQ_Envelope *env;
1821 struct GNUNET_CADET_Port *p;
1822
1823 GNUNET_assert (NULL != new_channel);
1824 p = GNUNET_new (struct GNUNET_CADET_Port);
1825 p->cadet = h;
1826 p->hash = GNUNET_new (struct GNUNET_HashCode);
1827 *p->hash = *port;
1828 p->handler = new_channel;
1829 p->cls = new_channel_cls;
1830 GNUNET_assert (GNUNET_OK ==
1831 GNUNET_CONTAINER_multihashmap_put (h->ports,
1832 p->hash,
1833 p,
1834 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1835
1836 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN);
1837 msg->port = *p->hash;
1838 GNUNET_MQ_send (h->mq, env);
1839
1840 return p;
1841}
1842
1843/**
1844 * Close a port opened with @a GNUNET_CADET_open_port.
1845 * The @a new_channel callback will no longer be called. 1201 * The @a new_channel callback will no longer be called.
1846 * 1202 *
1847 * @param p Port handle. 1203 * @param p Port handle.
@@ -1851,111 +1207,45 @@ GNUNET_CADET_close_port (struct GNUNET_CADET_Port *p)
1851{ 1207{
1852 struct GNUNET_CADET_PortMessage *msg; 1208 struct GNUNET_CADET_PortMessage *msg;
1853 struct GNUNET_MQ_Envelope *env; 1209 struct GNUNET_MQ_Envelope *env;
1854 struct GNUNET_HashCode *id;
1855
1856 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE);
1857 1210
1858 id = NULL != p->hash ? p->hash : &p->id; 1211 env = GNUNET_MQ_msg (msg,
1859 msg->port = *id; 1212 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE);
1860 GNUNET_MQ_send (p->cadet->mq, env); 1213 msg->port = p->id;
1861 GNUNET_CONTAINER_multihashmap_remove (p->cadet->ports, id, p); 1214 GNUNET_MQ_send (p->cadet->mq,
1862 GNUNET_free_non_null (p->hash); 1215 env);
1216 GNUNET_assert (GNUNET_YES ==
1217 GNUNET_CONTAINER_multihashmap_remove (p->cadet->ports,
1218 &p->id,
1219 p));
1220 GNUNET_free_non_null (p->handlers);
1863 GNUNET_free (p); 1221 GNUNET_free (p);
1864} 1222}
1865 1223
1866 1224
1867/** 1225/**
1868 * Create a new channel towards a remote peer. 1226 * Destroy an existing channel.
1869 * 1227 *
1870 * If the destination port is not open by any peer or the destination peer 1228 * The existing end callback for the channel will be called immediately.
1871 * does not accept the channel, #GNUNET_CADET_ChannelEndHandler will be called 1229 * Any pending outgoing messages will be sent but no incoming messages will be
1872 * for this channel. 1230 * accepted and no data callbacks will be called.
1873 * 1231 *
1874 * @param h cadet handle 1232 * @param channel Channel handle, becomes invalid after this call.
1875 * @param channel_ctx client's channel context to associate with the channel
1876 * @param peer peer identity the channel should go to
1877 * @param port Port hash (port number).
1878 * @param options CadetOption flag field, with all desired option bits set to 1.
1879 * @return handle to the channel
1880 */ 1233 */
1881struct GNUNET_CADET_Channel *
1882GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h,
1883 void *channel_ctx,
1884 const struct GNUNET_PeerIdentity *peer,
1885 const struct GNUNET_HashCode *port,
1886 enum GNUNET_CADET_ChannelOption options)
1887{
1888 struct GNUNET_CADET_LocalChannelCreateMessage *msg;
1889 struct GNUNET_MQ_Envelope *env;
1890 struct GNUNET_CADET_Channel *ch;
1891 struct GNUNET_CADET_ClientChannelNumber ccn;
1892
1893 ccn.channel_of_client = htonl (0);
1894 ch = create_channel (h, ccn);
1895 ch->ctx = channel_ctx;
1896 ch->peer = GNUNET_PEER_intern (peer);
1897
1898 LOG (GNUNET_ERROR_TYPE_DEBUG,
1899 "Creating new channel to %s:%u at %p number %X\n",
1900 GNUNET_i2s (peer),
1901 port,
1902 ch,
1903 ntohl (ch->ccn.channel_of_client));
1904 env = GNUNET_MQ_msg (msg,
1905 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
1906 msg->ccn = ch->ccn;
1907 msg->port = *port;
1908 msg->peer = *peer;
1909 msg->opt = htonl (options);
1910 GNUNET_MQ_send (h->mq,
1911 env);
1912 return ch;
1913}
1914
1915
1916void 1234void
1917GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel) 1235GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel)
1918{ 1236{
1919 struct GNUNET_CADET_Handle *h; 1237 struct GNUNET_CADET_Handle *h = channel->cadet;
1920 struct GNUNET_CADET_LocalChannelDestroyMessage *msg; 1238 struct GNUNET_CADET_LocalChannelDestroyMessage *msg;
1921 struct GNUNET_MQ_Envelope *env; 1239 struct GNUNET_MQ_Envelope *env;
1922 struct GNUNET_CADET_TransmitHandle *th;
1923 struct GNUNET_CADET_TransmitHandle *next;
1924 1240
1925 LOG (GNUNET_ERROR_TYPE_DEBUG, 1241 if (NULL != h->mq)
1926 "Destroying channel\n");
1927 h = channel->cadet;
1928 for (th = h->th_head; th != NULL; th = next)
1929 { 1242 {
1930 next = th->next; 1243 env = GNUNET_MQ_msg (msg,
1931 if (th->channel == channel) 1244 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
1932 { 1245 msg->ccn = channel->ccn;
1933 GNUNET_break (0); 1246 GNUNET_MQ_send (h->mq,
1934 if (GNUNET_YES == th_is_payload (th)) 1247 env);
1935 {
1936 /* applications should cancel before destroying channel */
1937 LOG (GNUNET_ERROR_TYPE_WARNING,
1938 "Channel destroyed without cancelling transmission requests\n");
1939 th->notify (th->notify_cls, 0, NULL);
1940 }
1941 else
1942 {
1943 LOG (GNUNET_ERROR_TYPE_WARNING,
1944 "no meta-traffic should be queued\n");
1945 }
1946 GNUNET_CONTAINER_DLL_remove (h->th_head,
1947 h->th_tail,
1948 th);
1949 GNUNET_CADET_notify_transmit_ready_cancel (th);
1950 }
1951 } 1248 }
1952
1953 env = GNUNET_MQ_msg (msg,
1954 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
1955 msg->ccn = channel->ccn;
1956 GNUNET_MQ_send (h->mq,
1957 env);
1958
1959 destroy_channel (channel); 1249 destroy_channel (channel);
1960} 1250}
1961 1251
@@ -1971,10 +1261,10 @@ GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel)
1971 */ 1261 */
1972const union GNUNET_CADET_ChannelInfo * 1262const union GNUNET_CADET_ChannelInfo *
1973GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel, 1263GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel,
1974 enum GNUNET_CADET_ChannelOption option, ...) 1264 enum GNUNET_CADET_ChannelOption option,
1265 ...)
1975{ 1266{
1976 static int bool_flag; 1267 static int bool_flag;
1977 const union GNUNET_CADET_ChannelInfo *ret;
1978 1268
1979 switch (option) 1269 switch (option)
1980 { 1270 {
@@ -1985,74 +1275,15 @@ GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel,
1985 bool_flag = GNUNET_YES; 1275 bool_flag = GNUNET_YES;
1986 else 1276 else
1987 bool_flag = GNUNET_NO; 1277 bool_flag = GNUNET_NO;
1988 ret = (const union GNUNET_CADET_ChannelInfo *) &bool_flag; 1278 return (const union GNUNET_CADET_ChannelInfo *) &bool_flag;
1989 break; 1279 break;
1990 case GNUNET_CADET_OPTION_PEER: 1280 case GNUNET_CADET_OPTION_PEER:
1991 ret = (const union GNUNET_CADET_ChannelInfo *) GNUNET_PEER_resolve2 (channel->peer); 1281 return (const union GNUNET_CADET_ChannelInfo *) &channel->peer;
1992 break; 1282 break;
1993 default: 1283 default:
1994 GNUNET_break (0); 1284 GNUNET_break (0);
1995 return NULL; 1285 return NULL;
1996 } 1286 }
1997
1998 return ret;
1999}
2000
2001
2002struct GNUNET_CADET_TransmitHandle *
2003GNUNET_CADET_notify_transmit_ready (struct GNUNET_CADET_Channel *channel,
2004 int cork,
2005 struct GNUNET_TIME_Relative maxdelay,
2006 size_t notify_size,
2007 GNUNET_CONNECTION_TransmitReadyNotify notify,
2008 void *notify_cls)
2009{
2010 struct GNUNET_CADET_TransmitHandle *th;
2011
2012 GNUNET_assert (NULL != channel);
2013 GNUNET_assert (NULL != notify);
2014 GNUNET_assert (GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE >= notify_size);
2015 LOG (GNUNET_ERROR_TYPE_DEBUG,
2016 "CADET NOTIFY TRANSMIT READY on channel %X allow_send is %u to %s with %u bytes\n",
2017 ntohl (channel->ccn.channel_of_client),
2018 channel->allow_send,
2019 (ntohl (channel->ccn.channel_of_client) >=
2020 GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
2021 ? "origin"
2022 : "destination",
2023 (unsigned int) notify_size);
2024 if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us != maxdelay.rel_value_us)
2025 {
2026 LOG (GNUNET_ERROR_TYPE_WARNING,
2027 "CADET transmit ready timeout is deprected (has no effect)\n");
2028 }
2029
2030 th = GNUNET_new (struct GNUNET_CADET_TransmitHandle);
2031 th->channel = channel;
2032 th->size = notify_size;
2033 th->notify = notify;
2034 th->notify_cls = notify_cls;
2035 if (0 != channel->allow_send)
2036 th->request_data_task
2037 = GNUNET_SCHEDULER_add_now (&request_data,
2038 th);
2039 else
2040 add_to_queue (channel->cadet,
2041 th);
2042 return th;
2043}
2044
2045
2046void
2047GNUNET_CADET_notify_transmit_ready_cancel (struct GNUNET_CADET_TransmitHandle *th)
2048{
2049 if (NULL != th->request_data_task)
2050 {
2051 GNUNET_SCHEDULER_cancel (th->request_data_task);
2052 th->request_data_task = NULL;
2053 }
2054 remove_from_queue (th);
2055 GNUNET_free (th);
2056} 1287}
2057 1288
2058 1289
@@ -2078,18 +1309,23 @@ GNUNET_CADET_receive_done (struct GNUNET_CADET_Channel *channel)
2078} 1309}
2079 1310
2080 1311
1312/**
1313 * Send message of @a type to CADET service of @a h
1314 *
1315 * @param h handle to CADET service
1316 * @param type message type of trivial information request to send
1317 */
2081static void 1318static void
2082send_info_request (struct GNUNET_CADET_Handle *h, uint16_t type) 1319send_info_request (struct GNUNET_CADET_Handle *h,
1320 uint16_t type)
2083{ 1321{
2084 struct GNUNET_MessageHeader *msg; 1322 struct GNUNET_MessageHeader *msg;
2085 struct GNUNET_MQ_Envelope *env; 1323 struct GNUNET_MQ_Envelope *env;
2086 1324
2087 LOG (GNUNET_ERROR_TYPE_DEBUG, 1325 env = GNUNET_MQ_msg (msg,
2088 " Sending %s monitor message to service\n", 1326 type);
2089 GC_m2s(type)); 1327 GNUNET_MQ_send (h->mq,
2090 1328 env);
2091 env = GNUNET_MQ_msg (msg, type);
2092 GNUNET_MQ_send (h->mq, env);
2093} 1329}
2094 1330
2095 1331
@@ -2103,8 +1339,8 @@ send_info_request (struct GNUNET_CADET_Handle *h, uint16_t type)
2103void 1339void
2104GNUNET_CADET_request_dump (struct GNUNET_CADET_Handle *h) 1340GNUNET_CADET_request_dump (struct GNUNET_CADET_Handle *h)
2105{ 1341{
2106 LOG (GNUNET_ERROR_TYPE_DEBUG, "requesting dump\n"); 1342 send_info_request (h,
2107 send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP); 1343 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP);
2108} 1344}
2109 1345
2110 1346
@@ -2113,13 +1349,11 @@ GNUNET_CADET_request_dump (struct GNUNET_CADET_Handle *h)
2113 * The callback will be called for every peer known to the service. 1349 * The callback will be called for every peer known to the service.
2114 * Only one info request (of any kind) can be active at once. 1350 * Only one info request (of any kind) can be active at once.
2115 * 1351 *
2116 *
2117 * WARNING: unstable API, likely to change in the future! 1352 * WARNING: unstable API, likely to change in the future!
2118 * 1353 *
2119 * @param h Handle to the cadet peer. 1354 * @param h Handle to the cadet peer.
2120 * @param callback Function to call with the requested data. 1355 * @param callback Function to call with the requested data.
2121 * @param callback_cls Closure for @c callback. 1356 * @param callback_cls Closure for @c callback.
2122 *
2123 * @return #GNUNET_OK / #GNUNET_SYSERR 1357 * @return #GNUNET_OK / #GNUNET_SYSERR
2124 */ 1358 */
2125int 1359int
@@ -2132,7 +1366,8 @@ GNUNET_CADET_get_peers (struct GNUNET_CADET_Handle *h,
2132 GNUNET_break (0); 1366 GNUNET_break (0);
2133 return GNUNET_SYSERR; 1367 return GNUNET_SYSERR;
2134 } 1368 }
2135 send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS); 1369 send_info_request (h,
1370 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
2136 h->info_cb.peers_cb = callback; 1371 h->info_cb.peers_cb = callback;
2137 h->info_cls = callback_cls; 1372 h->info_cls = callback_cls;
2138 return GNUNET_OK; 1373 return GNUNET_OK;
@@ -2145,15 +1380,13 @@ GNUNET_CADET_get_peers (struct GNUNET_CADET_Handle *h,
2145 * WARNING: unstable API, likely to change in the future! 1380 * WARNING: unstable API, likely to change in the future!
2146 * 1381 *
2147 * @param h Cadet handle. 1382 * @param h Cadet handle.
2148 * 1383 * @return Closure given to GNUNET_CADET_get_peers().
2149 * @return Closure given to GNUNET_CADET_get_peers.
2150 */ 1384 */
2151void * 1385void *
2152GNUNET_CADET_get_peers_cancel (struct GNUNET_CADET_Handle *h) 1386GNUNET_CADET_get_peers_cancel (struct GNUNET_CADET_Handle *h)
2153{ 1387{
2154 void *cls; 1388 void *cls = h->info_cls;
2155 1389
2156 cls = h->info_cls;
2157 h->info_cb.peers_cb = NULL; 1390 h->info_cb.peers_cb = NULL;
2158 h->info_cls = NULL; 1391 h->info_cls = NULL;
2159 return cls; 1392 return cls;
@@ -2171,7 +1404,6 @@ GNUNET_CADET_get_peers_cancel (struct GNUNET_CADET_Handle *h)
2171 * @param id Peer whose tunnel to examine. 1404 * @param id Peer whose tunnel to examine.
2172 * @param callback Function to call with the requested data. 1405 * @param callback Function to call with the requested data.
2173 * @param callback_cls Closure for @c callback. 1406 * @param callback_cls Closure for @c callback.
2174 *
2175 * @return #GNUNET_OK / #GNUNET_SYSERR 1407 * @return #GNUNET_OK / #GNUNET_SYSERR
2176 */ 1408 */
2177int 1409int
@@ -2188,11 +1420,11 @@ GNUNET_CADET_get_peer (struct GNUNET_CADET_Handle *h,
2188 GNUNET_break (0); 1420 GNUNET_break (0);
2189 return GNUNET_SYSERR; 1421 return GNUNET_SYSERR;
2190 } 1422 }
2191 1423 env = GNUNET_MQ_msg (msg,
2192 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER); 1424 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
2193 msg->peer = *id; 1425 msg->peer = *id;
2194 GNUNET_MQ_send (h->mq, env); 1426 GNUNET_MQ_send (h->mq,
2195 1427 env);
2196 h->info_cb.peer_cb = callback; 1428 h->info_cb.peer_cb = callback;
2197 h->info_cls = callback_cls; 1429 h->info_cls = callback_cls;
2198 return GNUNET_OK; 1430 return GNUNET_OK;
@@ -2209,7 +1441,6 @@ GNUNET_CADET_get_peer (struct GNUNET_CADET_Handle *h,
2209 * @param h Handle to the cadet peer. 1441 * @param h Handle to the cadet peer.
2210 * @param callback Function to call with the requested data. 1442 * @param callback Function to call with the requested data.
2211 * @param callback_cls Closure for @c callback. 1443 * @param callback_cls Closure for @c callback.
2212 *
2213 * @return #GNUNET_OK / #GNUNET_SYSERR 1444 * @return #GNUNET_OK / #GNUNET_SYSERR
2214 */ 1445 */
2215int 1446int
@@ -2222,7 +1453,8 @@ GNUNET_CADET_get_tunnels (struct GNUNET_CADET_Handle *h,
2222 GNUNET_break (0); 1453 GNUNET_break (0);
2223 return GNUNET_SYSERR; 1454 return GNUNET_SYSERR;
2224 } 1455 }
2225 send_info_request (h, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS); 1456 send_info_request (h,
1457 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
2226 h->info_cb.tunnels_cb = callback; 1458 h->info_cb.tunnels_cb = callback;
2227 h->info_cls = callback_cls; 1459 h->info_cls = callback_cls;
2228 return GNUNET_OK; 1460 return GNUNET_OK;
@@ -2233,23 +1465,19 @@ GNUNET_CADET_get_tunnels (struct GNUNET_CADET_Handle *h,
2233 * Cancel a monitor request. The monitor callback will not be called. 1465 * Cancel a monitor request. The monitor callback will not be called.
2234 * 1466 *
2235 * @param h Cadet handle. 1467 * @param h Cadet handle.
2236 * 1468 * @return Closure given to GNUNET_CADET_get_tunnels().
2237 * @return Closure given to GNUNET_CADET_get_tunnels.
2238 */ 1469 */
2239void * 1470void *
2240GNUNET_CADET_get_tunnels_cancel (struct GNUNET_CADET_Handle *h) 1471GNUNET_CADET_get_tunnels_cancel (struct GNUNET_CADET_Handle *h)
2241{ 1472{
2242 void *cls; 1473 void *cls = h->info_cls;
2243 1474
2244 h->info_cb.tunnels_cb = NULL; 1475 h->info_cb.tunnels_cb = NULL;
2245 cls = h->info_cls;
2246 h->info_cls = NULL; 1476 h->info_cls = NULL;
2247
2248 return cls; 1477 return cls;
2249} 1478}
2250 1479
2251 1480
2252
2253/** 1481/**
2254 * Request information about a tunnel of the running cadet peer. 1482 * Request information about a tunnel of the running cadet peer.
2255 * The callback will be called for the tunnel once. 1483 * The callback will be called for the tunnel once.
@@ -2261,7 +1489,6 @@ GNUNET_CADET_get_tunnels_cancel (struct GNUNET_CADET_Handle *h)
2261 * @param id Peer whose tunnel to examine. 1489 * @param id Peer whose tunnel to examine.
2262 * @param callback Function to call with the requested data. 1490 * @param callback Function to call with the requested data.
2263 * @param callback_cls Closure for @c callback. 1491 * @param callback_cls Closure for @c callback.
2264 *
2265 * @return #GNUNET_OK / #GNUNET_SYSERR 1492 * @return #GNUNET_OK / #GNUNET_SYSERR
2266 */ 1493 */
2267int 1494int
@@ -2278,11 +1505,11 @@ GNUNET_CADET_get_tunnel (struct GNUNET_CADET_Handle *h,
2278 GNUNET_break (0); 1505 GNUNET_break (0);
2279 return GNUNET_SYSERR; 1506 return GNUNET_SYSERR;
2280 } 1507 }
2281 1508 env = GNUNET_MQ_msg (msg,
2282 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL); 1509 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
2283 msg->peer = *id; 1510 msg->peer = *id;
2284 GNUNET_MQ_send (h->mq, env); 1511 GNUNET_MQ_send (h->mq,
2285 1512 env);
2286 h->info_cb.tunnel_cb = callback; 1513 h->info_cb.tunnel_cb = callback;
2287 h->info_cls = callback_cls; 1514 h->info_cls = callback_cls;
2288 return GNUNET_OK; 1515 return GNUNET_OK;
@@ -2290,158 +1517,6 @@ GNUNET_CADET_get_tunnel (struct GNUNET_CADET_Handle *h,
2290 1517
2291 1518
2292/** 1519/**
2293 * Request information about a specific channel of the running cadet peer.
2294 *
2295 * WARNING: unstable API, likely to change in the future!
2296 * FIXME Add destination option.
2297 *
2298 * @param h Handle to the cadet peer.
2299 * @param initiator ID of the owner of the channel.
2300 * @param channel_number Channel number.
2301 * @param callback Function to call with the requested data.
2302 * @param callback_cls Closure for @c callback.
2303 *
2304 * @return #GNUNET_OK / #GNUNET_SYSERR
2305 */
2306int
2307GNUNET_CADET_show_channel (struct GNUNET_CADET_Handle *h,
2308 struct GNUNET_PeerIdentity *initiator,
2309 unsigned int channel_number,
2310 GNUNET_CADET_ChannelCB callback,
2311 void *callback_cls)
2312{
2313 struct GNUNET_CADET_LocalInfo *msg;
2314 struct GNUNET_MQ_Envelope *env;
2315
2316 if (NULL != h->info_cb.channel_cb)
2317 {
2318 GNUNET_break (0);
2319 return GNUNET_SYSERR;
2320 }
2321
2322 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL);
2323 msg->peer = *initiator;
2324 msg->ccn.channel_of_client = htonl (channel_number);
2325 GNUNET_MQ_send (h->mq, env);
2326
2327 h->info_cb.channel_cb = callback;
2328 h->info_cls = callback_cls;
2329 return GNUNET_OK;
2330}
2331
2332
2333/**
2334 * Function called to notify a client about the connection
2335 * begin ready to queue more data. "buf" will be
2336 * NULL and "size" zero if the connection was closed for
2337 * writing in the meantime.
2338 *
2339 * @param cls closure
2340 * @param size number of bytes available in buf
2341 * @param buf where the callee should write the message
2342 * @return number of bytes written to buf
2343 */
2344static size_t
2345cadet_mq_ntr (void *cls, size_t size,
2346 void *buf)
2347{
2348 struct GNUNET_MQ_Handle *mq = cls;
2349 struct CadetMQState *state = GNUNET_MQ_impl_state (mq);
2350 const struct GNUNET_MessageHeader *msg = GNUNET_MQ_impl_current (mq);
2351 uint16_t msize;
2352
2353 state->th = NULL;
2354 if (NULL == buf)
2355 {
2356 GNUNET_MQ_inject_error (mq, GNUNET_MQ_ERROR_WRITE);
2357 return 0;
2358 }
2359 msize = ntohs (msg->size);
2360 GNUNET_assert (msize <= size);
2361 GNUNET_memcpy (buf, msg, msize);
2362 GNUNET_MQ_impl_send_continue (mq);
2363 return msize;
2364}
2365
2366
2367/**
2368 * Signature of functions implementing the
2369 * sending functionality of a message queue.
2370 *
2371 * @param mq the message queue
2372 * @param msg the message to send
2373 * @param impl_state state of the implementation
2374 */
2375static void
2376cadet_mq_send_impl_old (struct GNUNET_MQ_Handle *mq,
2377 const struct GNUNET_MessageHeader *msg,
2378 void *impl_state)
2379{
2380 struct CadetMQState *state = impl_state;
2381
2382 GNUNET_assert (NULL == state->th);
2383 state->th =
2384 GNUNET_CADET_notify_transmit_ready (state->channel,
2385 /* FIXME: add option for corking */
2386 GNUNET_NO,
2387 GNUNET_TIME_UNIT_FOREVER_REL,
2388 ntohs (msg->size),
2389 &cadet_mq_ntr, mq);
2390
2391}
2392
2393
2394/**
2395 * Signature of functions implementing the
2396 * destruction of a message queue.
2397 * Implementations must not free 'mq', but should
2398 * take care of 'impl_state'.
2399 *
2400 * @param mq the message queue to destroy
2401 * @param impl_state state of the implementation
2402 */
2403static void
2404cadet_mq_destroy_impl_old (struct GNUNET_MQ_Handle *mq,
2405 void *impl_state)
2406{
2407 struct CadetMQState *state = impl_state;
2408
2409 if (NULL != state->th)
2410 GNUNET_CADET_notify_transmit_ready_cancel (state->th);
2411
2412 GNUNET_free (state);
2413}
2414
2415
2416/**
2417 * Create a message queue for a cadet channel.
2418 * The message queue can only be used to transmit messages,
2419 * not to receive them.
2420 *
2421 * @param channel the channel to create the message qeue for
2422 * @return a message queue to messages over the channel
2423 */
2424struct GNUNET_MQ_Handle *
2425GNUNET_CADET_mq_create (struct GNUNET_CADET_Channel *channel)
2426{
2427 struct GNUNET_MQ_Handle *mq;
2428 struct CadetMQState *state;
2429
2430 state = GNUNET_new (struct CadetMQState);
2431 state->channel = channel;
2432
2433 mq = GNUNET_MQ_queue_for_callbacks (&cadet_mq_send_impl_old,
2434 &cadet_mq_destroy_impl_old,
2435 NULL, /* FIXME: cancel impl. */
2436 state,
2437 NULL, /* no msg handlers */
2438 NULL, /* no err handlers */
2439 NULL); /* no handler cls */
2440 return mq;
2441}
2442
2443
2444/**
2445 * Transitional function to convert an unsigned int port to a hash value. 1520 * Transitional function to convert an unsigned int port to a hash value.
2446 * WARNING: local static value returned, NOT reentrant! 1521 * WARNING: local static value returned, NOT reentrant!
2447 * WARNING: do not use this function for new code! 1522 * WARNING: do not use this function for new code!
@@ -2456,19 +1531,14 @@ GC_u2h (uint32_t port)
2456 static struct GNUNET_HashCode hash; 1531 static struct GNUNET_HashCode hash;
2457 1532
2458 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1533 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2459 "This is a transitional function, " 1534 "This is a transitional function, use proper crypto hashes as CADET ports\n");
2460 "use proper crypto hashes as CADET ports\n"); 1535 GNUNET_CRYPTO_hash (&port,
2461 GNUNET_CRYPTO_hash (&port, sizeof (port), &hash); 1536 sizeof (port),
2462 1537 &hash);
2463 return &hash; 1538 return &hash;
2464} 1539}
2465 1540
2466 1541
2467
2468/******************************************************************************/
2469/******************************* MQ-BASED API *********************************/
2470/******************************************************************************/
2471
2472/** 1542/**
2473 * Connect to the MQ-based cadet service. 1543 * Connect to the MQ-based cadet service.
2474 * 1544 *
@@ -2477,16 +1547,17 @@ GC_u2h (uint32_t port)
2477 * @return Handle to the cadet service NULL on error. 1547 * @return Handle to the cadet service NULL on error.
2478 */ 1548 */
2479struct GNUNET_CADET_Handle * 1549struct GNUNET_CADET_Handle *
2480GNUNET_CADET_connecT (const struct GNUNET_CONFIGURATION_Handle *cfg) 1550GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
2481{ 1551{
2482 struct GNUNET_CADET_Handle *h; 1552 struct GNUNET_CADET_Handle *h;
2483 1553
2484 LOG (GNUNET_ERROR_TYPE_DEBUG, 1554 LOG (GNUNET_ERROR_TYPE_DEBUG,
2485 "GNUNET_CADET_connecT()\n"); 1555 "GNUNET_CADET_connect()\n");
2486 h = GNUNET_new (struct GNUNET_CADET_Handle); 1556 h = GNUNET_new (struct GNUNET_CADET_Handle);
2487 h->cfg = cfg; 1557 h->cfg = cfg;
2488 h->mq_api = GNUNET_YES; 1558 h->ports = GNUNET_CONTAINER_multihashmap_create (4,
2489 h->ports = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_YES); 1559 GNUNET_YES);
1560 h->channels = GNUNET_CONTAINER_multihashmap32_create (4);
2490 reconnect (h); 1561 reconnect (h);
2491 if (NULL == h->mq) 1562 if (NULL == h->mq)
2492 { 1563 {
@@ -2512,11 +1583,10 @@ GNUNET_CADET_connecT (const struct GNUNET_CONFIGURATION_Handle *cfg)
2512 * @param window_changes Function called when the transmit window size changes. 1583 * @param window_changes Function called when the transmit window size changes.
2513 * @param disconnects Function called when a channel is disconnected. 1584 * @param disconnects Function called when a channel is disconnected.
2514 * @param handlers Callbacks for messages we care about, NULL-terminated. 1585 * @param handlers Callbacks for messages we care about, NULL-terminated.
2515 *
2516 * @return Port handle. 1586 * @return Port handle.
2517 */ 1587 */
2518struct GNUNET_CADET_Port * 1588struct GNUNET_CADET_Port *
2519GNUNET_CADET_open_porT (struct GNUNET_CADET_Handle *h, 1589GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h,
2520 const struct GNUNET_HashCode *port, 1590 const struct GNUNET_HashCode *port,
2521 GNUNET_CADET_ConnectEventHandler connects, 1591 GNUNET_CADET_ConnectEventHandler connects,
2522 void * connects_cls, 1592 void * connects_cls,
@@ -2538,16 +1608,7 @@ GNUNET_CADET_open_porT (struct GNUNET_CADET_Handle *h,
2538 p->cls = connects_cls; 1608 p->cls = connects_cls;
2539 p->window_changes = window_changes; 1609 p->window_changes = window_changes;
2540 p->disconnects = disconnects; 1610 p->disconnects = disconnects;
2541 if (NULL != handlers) 1611 p->handlers = GNUNET_MQ_copy_handlers (handlers);
2542 {
2543 unsigned int i;
2544 for (i=0;NULL != handlers[i].cb; i++) ;
2545 p->handlers = GNUNET_new_array (i + 1,
2546 struct GNUNET_MQ_MessageHandler);
2547 GNUNET_memcpy ((struct GNUNET_MQ_MessageHandler *) p->handlers,
2548 handlers,
2549 i * sizeof (struct GNUNET_MQ_MessageHandler));
2550 }
2551 1612
2552 GNUNET_assert (GNUNET_OK == 1613 GNUNET_assert (GNUNET_OK ==
2553 GNUNET_CONTAINER_multihashmap_put (h->ports, 1614 GNUNET_CONTAINER_multihashmap_put (h->ports,
@@ -2555,10 +1616,11 @@ GNUNET_CADET_open_porT (struct GNUNET_CADET_Handle *h,
2555 p, 1616 p,
2556 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 1617 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
2557 1618
2558 env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN); 1619 env = GNUNET_MQ_msg (msg,
1620 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN);
2559 msg->port = p->id; 1621 msg->port = p->id;
2560 GNUNET_MQ_send (h->mq, env); 1622 GNUNET_MQ_send (h->mq,
2561 1623 env);
2562 return p; 1624 return p;
2563} 1625}
2564 1626
@@ -2580,11 +1642,10 @@ GNUNET_CADET_open_porT (struct GNUNET_CADET_Handle *h,
2580 * @param window_changes Function called when the transmit window size changes. 1642 * @param window_changes Function called when the transmit window size changes.
2581 * @param disconnects Function called when the channel is disconnected. 1643 * @param disconnects Function called when the channel is disconnected.
2582 * @param handlers Callbacks for messages we care about, NULL-terminated. 1644 * @param handlers Callbacks for messages we care about, NULL-terminated.
2583 *
2584 * @return Handle to the channel. 1645 * @return Handle to the channel.
2585 */ 1646 */
2586struct GNUNET_CADET_Channel * 1647struct GNUNET_CADET_Channel *
2587GNUNET_CADET_channel_creatE (struct GNUNET_CADET_Handle *h, 1648GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h,
2588 void *channel_cls, 1649 void *channel_cls,
2589 const struct GNUNET_PeerIdentity *destination, 1650 const struct GNUNET_PeerIdentity *destination,
2590 const struct GNUNET_HashCode *port, 1651 const struct GNUNET_HashCode *port,
@@ -2594,17 +1655,14 @@ GNUNET_CADET_channel_creatE (struct GNUNET_CADET_Handle *h,
2594 const struct GNUNET_MQ_MessageHandler *handlers) 1655 const struct GNUNET_MQ_MessageHandler *handlers)
2595{ 1656{
2596 struct GNUNET_CADET_Channel *ch; 1657 struct GNUNET_CADET_Channel *ch;
2597 struct GNUNET_CADET_ClientChannelNumber ccn;
2598 struct GNUNET_CADET_LocalChannelCreateMessage *msg; 1658 struct GNUNET_CADET_LocalChannelCreateMessage *msg;
2599 struct GNUNET_MQ_Envelope *env; 1659 struct GNUNET_MQ_Envelope *env;
2600 1660
2601 GNUNET_assert (NULL != disconnects); 1661 GNUNET_assert (NULL != disconnects);
2602 1662 ch = create_channel (h,
2603 /* Save parameters */ 1663 NULL);
2604 ccn.channel_of_client = htonl (0);
2605 ch = create_channel (h, ccn);
2606 ch->ctx = channel_cls; 1664 ch->ctx = channel_cls;
2607 ch->peer = GNUNET_PEER_intern (destination); 1665 ch->peer = *destination;
2608 ch->options = options; 1666 ch->options = options;
2609 ch->window_changes = window_changes; 1667 ch->window_changes = window_changes;
2610 ch->disconnects = disconnects; 1668 ch->disconnects = disconnects;
@@ -2628,7 +1686,6 @@ GNUNET_CADET_channel_creatE (struct GNUNET_CADET_Handle *h,
2628 msg->opt = htonl (options); 1686 msg->opt = htonl (options);
2629 GNUNET_MQ_send (h->mq, 1687 GNUNET_MQ_send (h->mq,
2630 env); 1688 env);
2631
2632 return ch; 1689 return ch;
2633} 1690}
2634 1691
@@ -2645,3 +1702,5 @@ GNUNET_CADET_get_mq (const struct GNUNET_CADET_Channel *channel)
2645{ 1702{
2646 return channel->mq; 1703 return channel->mq;
2647} 1704}
1705
1706/* 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 2d5d853b3..000000000
--- a/src/cadet/cadet_api_new.c
+++ /dev/null
@@ -1,1711 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2011, 2017 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20/**
21 * @file cadet/cadet_api.c
22 * @brief cadet api: client implementation of cadet service
23 * @author Bartlomiej Polot
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_constants.h"
29#include "gnunet_cadet_service.h"
30#include "cadet.h"
31#include "cadet_protocol.h"
32
33#define LOG(kind,...) GNUNET_log_from (kind, "cadet-api",__VA_ARGS__)
34
35/**
36 * Ugly legacy hack.
37 */
38union CadetInfoCB
39{
40
41 /**
42 * Channel callback.
43 */
44 GNUNET_CADET_ChannelCB channel_cb;
45
46 /**
47 * Monitor callback
48 */
49 GNUNET_CADET_PeersCB peers_cb;
50
51 /**
52 * Monitor callback
53 */
54 GNUNET_CADET_PeerCB peer_cb;
55
56 /**
57 * Monitor callback
58 */
59 GNUNET_CADET_TunnelsCB tunnels_cb;
60
61 /**
62 * Tunnel callback.
63 */
64 GNUNET_CADET_TunnelCB tunnel_cb;
65};
66
67
68/**
69 * Opaque handle to the service.
70 */
71struct GNUNET_CADET_Handle
72{
73 /**
74 * Message queue.
75 */
76 struct GNUNET_MQ_Handle *mq;
77
78 /**
79 * Ports open.
80 */
81 struct GNUNET_CONTAINER_MultiHashMap *ports;
82
83 /**
84 * Channels open.
85 */
86 struct GNUNET_CONTAINER_MultiHashMap32 *channels;
87
88 /**
89 * child of the next channel to create (to avoid reusing IDs often)
90 */
91 struct GNUNET_CADET_ClientChannelNumber next_ccn;
92
93 /**
94 * Configuration given by the client, in case of reconnection
95 */
96 const struct GNUNET_CONFIGURATION_Handle *cfg;
97
98 /**
99 * Task for trying to reconnect.
100 */
101 struct GNUNET_SCHEDULER_Task *reconnect_task;
102
103 /**
104 * Callback for an info task (only one active at a time).
105 */
106 union CadetInfoCB info_cb;
107
108 /**
109 * Info callback closure for @c info_cb.
110 */
111 void *info_cls;
112
113 /**
114 * Time to the next reconnect in case one reconnect fails
115 */
116 struct GNUNET_TIME_Relative reconnect_time;
117
118};
119
120
121/**
122 * Opaque handle to a channel.
123 */
124struct GNUNET_CADET_Channel
125{
126
127 /**
128 * Other end of the channel.
129 */
130 struct GNUNET_PeerIdentity peer;
131
132 /**
133 * Handle to the cadet this channel belongs to
134 */
135 struct GNUNET_CADET_Handle *cadet;
136
137 /**
138 * Channel's port, if incoming.
139 */
140 struct GNUNET_CADET_Port *incoming_port;
141
142 /**
143 * Any data the caller wants to put in here, used for the
144 * various callbacks (@e disconnects, @e window_changes, handlers).
145 */
146 void *ctx;
147
148 /**
149 * Message Queue for the channel (which we are implementing).
150 */
151 struct GNUNET_MQ_Handle *mq;
152
153 /**
154 * Task to allow mq to send more traffic.
155 */
156 struct GNUNET_SCHEDULER_Task *mq_cont;
157
158 /**
159 * Pending envelope with a message to be transmitted to the
160 * service as soon as we are allowed to. Should only be
161 * non-NULL if @e allow_send is 0.
162 */
163 struct GNUNET_MQ_Envelope *pending_env;
164
165 /**
166 * Window change handler.
167 */
168 GNUNET_CADET_WindowSizeEventHandler window_changes;
169
170 /**
171 * Disconnect handler.
172 */
173 GNUNET_CADET_DisconnectEventHandler disconnects;
174
175 /**
176 * Local ID of the channel, #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI bit is set if outbound.
177 */
178 struct GNUNET_CADET_ClientChannelNumber ccn;
179
180 /**
181 * Channel options: reliability, etc.
182 */
183 enum GNUNET_CADET_ChannelOption options;
184
185 /**
186 * How many messages are we allowed to send to the service right now?
187 */
188 unsigned int allow_send;
189
190};
191
192
193/**
194 * Opaque handle to a port.
195 */
196struct GNUNET_CADET_Port
197{
198
199 /**
200 * Port "number"
201 */
202 struct GNUNET_HashCode id;
203
204 /**
205 * Handle to the CADET session this port belongs to.
206 */
207 struct GNUNET_CADET_Handle *cadet;
208
209 /**
210 * Callback handler for incoming channels on this port.
211 */
212 GNUNET_CADET_InboundChannelNotificationHandler *handler;
213
214 /**
215 * Closure for @a handler.
216 */
217 void *cls;
218
219 /**
220 * Handler for incoming channels on this port
221 */
222 GNUNET_CADET_ConnectEventHandler connects;
223
224 /**
225 * Closure for @ref connects
226 */
227 void *connects_cls;
228
229 /**
230 * Window size change handler.
231 */
232 GNUNET_CADET_WindowSizeEventHandler window_changes;
233
234 /**
235 * Handler called when an incoming channel is destroyed.
236 */
237 GNUNET_CADET_DisconnectEventHandler disconnects;
238
239 /**
240 * Payload handlers for incoming channels.
241 */
242 struct GNUNET_MQ_MessageHandler *handlers;
243};
244
245
246/**
247 * Find the Port struct for a hash.
248 *
249 * @param h CADET handle.
250 * @param hash HashCode for the port number.
251 * @return The port handle if known, NULL otherwise.
252 */
253static struct GNUNET_CADET_Port *
254find_port (const struct GNUNET_CADET_Handle *h,
255 const struct GNUNET_HashCode *hash)
256{
257 return GNUNET_CONTAINER_multihashmap_get (h->ports,
258 hash);
259}
260
261
262/**
263 * Get the channel handler for the channel specified by id from the given handle
264 *
265 * @param h Cadet handle
266 * @param ccn ID of the wanted channel
267 * @return handle to the required channel or NULL if not found
268 */
269static struct GNUNET_CADET_Channel *
270find_channel (struct GNUNET_CADET_Handle *h,
271 struct GNUNET_CADET_ClientChannelNumber ccn)
272{
273 return GNUNET_CONTAINER_multihashmap32_get (h->channels,
274 ntohl (ccn.channel_of_client));
275}
276
277
278/**
279 * Create a new channel and insert it in the channel list of the cadet handle
280 *
281 * @param h Cadet handle
282 * @param ccnp pointer to desired ccn of the channel, NULL to assign one automatically.
283 * @return Handle to the created channel.
284 */
285static struct GNUNET_CADET_Channel *
286create_channel (struct GNUNET_CADET_Handle *h,
287 const struct GNUNET_CADET_ClientChannelNumber *ccnp)
288{
289 struct GNUNET_CADET_Channel *ch;
290 struct GNUNET_CADET_ClientChannelNumber ccn;
291
292 ch = GNUNET_new (struct GNUNET_CADET_Channel);
293 ch->cadet = h;
294 if (NULL == ccnp)
295 {
296 while (NULL !=
297 find_channel (h,
298 h->next_ccn))
299 h->next_ccn.channel_of_client
300 = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI | (1 + ntohl (h->next_ccn.channel_of_client)));
301 ccn = h->next_ccn;
302 }
303 else
304 {
305 ccn = *ccnp;
306 }
307 ch->ccn = ccn;
308 GNUNET_assert (GNUNET_OK ==
309 GNUNET_CONTAINER_multihashmap32_put (h->channels,
310 ntohl (ch->ccn.channel_of_client),
311 ch,
312 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
313 return ch;
314}
315
316
317/**
318 * Destroy the specified channel.
319 * - Destroys all peers, calling the disconnect callback on each if needed
320 * - Cancels all outgoing traffic for that channel, calling respective notifys
321 * - Calls cleaner if channel was inbound
322 * - Frees all memory used
323 *
324 * @param ch Pointer to the channel.
325 * @param call_cleaner Whether to call the cleaner handler.
326 */
327static void
328destroy_channel (struct GNUNET_CADET_Channel *ch)
329{
330 struct GNUNET_CADET_Handle *h = ch->cadet;
331
332 LOG (GNUNET_ERROR_TYPE_DEBUG,
333 "Destroying channel %X of %p\n",
334 ch->ccn,
335 h);
336 GNUNET_assert (GNUNET_YES ==
337 GNUNET_CONTAINER_multihashmap32_remove (h->channels,
338 ntohl (ch->ccn.channel_of_client),
339 ch));
340 if (NULL != ch->mq_cont)
341 {
342 GNUNET_SCHEDULER_cancel (ch->mq_cont);
343 ch->mq_cont = NULL;
344 }
345 /* signal channel destruction */
346 if (NULL != ch->disconnects)
347 ch->disconnects (ch->ctx,
348 ch);
349 if (NULL != ch->pending_env)
350 GNUNET_MQ_discard (ch->pending_env);
351 GNUNET_MQ_destroy (ch->mq);
352 GNUNET_free (ch);
353}
354
355
356/**
357 * Reconnect to the service, retransmit all infomation to try to restore the
358 * original state.
359 *
360 * @param h handle to the cadet
361 */
362static void
363reconnect (struct GNUNET_CADET_Handle *h);
364
365
366/**
367 * Reconnect callback: tries to reconnect again after a failer previous
368 * reconnecttion
369 *
370 * @param cls closure (cadet handle)
371 */
372static void
373reconnect_cbk (void *cls)
374{
375 struct GNUNET_CADET_Handle *h = cls;
376
377 h->reconnect_task = NULL;
378 reconnect (h);
379}
380
381
382/**
383 * Function called during #reconnect() to destroy
384 * all channels that are still open.
385 *
386 * @param cls the `struct GNUNET_CADET_Handle`
387 * @param cid chanenl ID
388 * @param value a `struct GNUNET_CADET_Channel` to destroy
389 * @return #GNUNET_OK (continue to iterate)
390 */
391static int
392destroy_channel_on_reconnect_cb (void *cls,
393 uint32_t cid,
394 void *value)
395{
396 /* struct GNUNET_CADET_Handle *handle = cls; */
397 struct GNUNET_CADET_Channel *ch = value;
398
399 destroy_channel (ch);
400 return GNUNET_OK;
401}
402
403
404/**
405 * Reconnect to the service, retransmit all infomation to try to restore the
406 * original state.
407 *
408 * @param h handle to the cadet
409 *
410 * @return #GNUNET_YES in case of sucess, #GNUNET_NO otherwise (service down...)
411 */
412static void
413schedule_reconnect (struct GNUNET_CADET_Handle *h)
414{
415 if (NULL != h->reconnect_task)
416 return;
417 GNUNET_CONTAINER_multihashmap32_iterate (h->channels,
418 &destroy_channel_on_reconnect_cb,
419 h);
420 h->reconnect_task
421 = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
422 &reconnect_cbk,
423 h);
424 h->reconnect_time
425 = GNUNET_TIME_STD_BACKOFF (h->reconnect_time);
426}
427
428
429/**
430 * Notify the application about a change in the window size (if needed).
431 *
432 * @param ch Channel to notify about.
433 */
434static void
435notify_window_size (struct GNUNET_CADET_Channel *ch)
436{
437 if (NULL != ch->window_changes)
438 ch->window_changes (ch->ctx,
439 ch, /* FIXME: remove 'ch'? */
440 ch->allow_send);
441}
442
443
444/**
445 * Transmit the next message from our queue.
446 *
447 * @param cls Closure (channel whose mq to activate).
448 */
449static void
450cadet_mq_send_now (void *cls)
451{
452 struct GNUNET_CADET_Channel *ch = cls;
453 struct GNUNET_MQ_Envelope *env = ch->pending_env;
454
455 ch->mq_cont = NULL;
456 if (0 == ch->allow_send)
457 {
458 /* how did we get here? */
459 GNUNET_break (0);
460 return;
461 }
462 if (NULL == env)
463 {
464 /* how did we get here? */
465 GNUNET_break (0);
466 return;
467 }
468 ch->allow_send--;
469 ch->pending_env = NULL;
470 GNUNET_MQ_send (ch->cadet->mq,
471 env);
472 GNUNET_MQ_impl_send_continue (ch->mq);
473}
474
475
476/**
477 * Implement sending functionality of a message queue for
478 * us sending messages to a peer.
479 *
480 * Encapsulates the payload message in a #GNUNET_CADET_LocalData message
481 * in order to label the message with the channel ID and send the
482 * encapsulated message to the service.
483 *
484 * @param mq the message queue
485 * @param msg the message to send
486 * @param impl_state state of the implementation
487 */
488static void
489cadet_mq_send_impl (struct GNUNET_MQ_Handle *mq,
490 const struct GNUNET_MessageHeader *msg,
491 void *impl_state)
492{
493 struct GNUNET_CADET_Channel *ch = impl_state;
494 struct GNUNET_CADET_Handle *h = ch->cadet;
495 uint16_t msize;
496 struct GNUNET_MQ_Envelope *env;
497 struct GNUNET_CADET_LocalData *cadet_msg;
498
499 if (NULL == h->mq)
500 {
501 /* We're currently reconnecting, pretend this worked */
502 GNUNET_MQ_impl_send_continue (mq);
503 return;
504 }
505
506 /* check message size for sanity */
507 msize = ntohs (msg->size);
508 if (msize > GNUNET_CONSTANTS_MAX_CADET_MESSAGE_SIZE)
509 {
510 GNUNET_break (0);
511 GNUNET_MQ_impl_send_continue (mq);
512 return;
513 }
514 env = GNUNET_MQ_msg_nested_mh (cadet_msg,
515 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
516 msg);
517 cadet_msg->ccn = ch->ccn;
518 GNUNET_assert (NULL == ch->pending_env);
519 ch->pending_env = env;
520 if (0 < ch->allow_send)
521 ch->mq_cont
522 = GNUNET_SCHEDULER_add_now (&cadet_mq_send_now,
523 ch);
524}
525
526
527/**
528 * Handle destruction of a message queue. Implementations must not
529 * free @a mq, but should take care of @a impl_state.
530 *
531 * @param mq the message queue to destroy
532 * @param impl_state state of the implementation
533 */
534static void
535cadet_mq_destroy_impl (struct GNUNET_MQ_Handle *mq,
536 void *impl_state)
537{
538 struct GNUNET_CADET_Channel *ch = impl_state;
539
540 GNUNET_assert (mq == ch->mq);
541 ch->mq = NULL;
542}
543
544
545/**
546 * We had an error processing a message we forwarded from a peer to
547 * the CADET service. We should just complain about it but otherwise
548 * continue processing.
549 *
550 * @param cls closure with our `struct GNUNET_CADET_Channel`
551 * @param error error code
552 */
553static void
554cadet_mq_error_handler (void *cls,
555 enum GNUNET_MQ_Error error)
556{
557 struct GNUNET_CADET_Channel *ch = cls;
558
559 GNUNET_break (0);
560 if (GNUNET_MQ_ERROR_NO_MATCH == error)
561 {
562 /* Got a message we did not understand, still try to continue! */
563 GNUNET_CADET_receive_done (ch);
564 }
565 else
566 {
567 schedule_reconnect (ch->cadet);
568 }
569}
570
571
572/**
573 * Implementation function that cancels the currently sent message.
574 * Should basically undo whatever #mq_send_impl() did.
575 *
576 * @param mq message queue
577 * @param impl_state state specific to the implementation
578 */
579static void
580cadet_mq_cancel_impl (struct GNUNET_MQ_Handle *mq,
581 void *impl_state)
582{
583 struct GNUNET_CADET_Channel *ch = impl_state;
584
585 GNUNET_assert (NULL != ch->pending_env);
586 GNUNET_MQ_discard (ch->pending_env);
587 ch->pending_env = NULL;
588 if (NULL != ch->mq_cont)
589 {
590 GNUNET_SCHEDULER_cancel (ch->mq_cont);
591 ch->mq_cont = NULL;
592 }
593}
594
595
596/**
597 * Process the new channel notification and add it to the channels in the handle
598 *
599 * @param h The cadet handle
600 * @param msg A message with the details of the new incoming channel
601 */
602static void
603handle_channel_created (void *cls,
604 const struct GNUNET_CADET_LocalChannelCreateMessage *msg)
605{
606 struct GNUNET_CADET_Handle *h = cls;
607 struct GNUNET_CADET_Channel *ch;
608 struct GNUNET_CADET_Port *port;
609 const struct GNUNET_HashCode *port_number;
610 struct GNUNET_CADET_ClientChannelNumber ccn;
611
612 ccn = msg->ccn;
613 port_number = &msg->port;
614 if (ntohl (ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
615 {
616 GNUNET_break (0);
617 return;
618 }
619 port = find_port (h,
620 port_number);
621 if (NULL == port)
622 {
623 /* We could have closed the port but the service didn't know about it yet
624 * This is not an error.
625 */
626 struct GNUNET_CADET_LocalChannelDestroyMessage *d_msg;
627 struct GNUNET_MQ_Envelope *env;
628
629 LOG (GNUNET_ERROR_TYPE_DEBUG,
630 "No handler for incoming channel %X (on port %s, recently closed?)\n",
631 ntohl (ccn.channel_of_client),
632 GNUNET_h2s (port_number));
633 env = GNUNET_MQ_msg (d_msg,
634 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
635 d_msg->ccn = msg->ccn;
636 GNUNET_MQ_send (h->mq,
637 env);
638 return;
639 }
640
641 ch = create_channel (h,
642 &ccn);
643 ch->peer = msg->peer;
644 ch->cadet = h;
645 ch->incoming_port = port;
646 ch->options = ntohl (msg->opt);
647 LOG (GNUNET_ERROR_TYPE_DEBUG,
648 "Creating incoming channel %X [%s] %p\n",
649 ntohl (ccn.channel_of_client),
650 GNUNET_h2s (port_number),
651 ch);
652
653 GNUNET_assert (NULL != port->connects);
654 ch->window_changes = port->window_changes;
655 ch->disconnects = port->disconnects;
656 ch->mq = GNUNET_MQ_queue_for_callbacks (&cadet_mq_send_impl,
657 &cadet_mq_destroy_impl,
658 &cadet_mq_cancel_impl,
659 ch,
660 port->handlers,
661 &cadet_mq_error_handler,
662 ch);
663 ch->ctx = port->connects (port->cls,
664 ch,
665 &msg->peer);
666 GNUNET_MQ_set_handlers_closure (ch->mq,
667 ch->ctx);
668}
669
670
671/**
672 * Process the channel destroy notification and free associated resources
673 *
674 * @param h The cadet handle
675 * @param msg A message with the details of the channel being destroyed
676 */
677static void
678handle_channel_destroy (void *cls,
679 const struct GNUNET_CADET_LocalChannelDestroyMessage *msg)
680{
681 struct GNUNET_CADET_Handle *h = cls;
682 struct GNUNET_CADET_Channel *ch;
683
684 ch = find_channel (h,
685 msg->ccn);
686 if (NULL == ch)
687 {
688 LOG (GNUNET_ERROR_TYPE_DEBUG,
689 "Received channel destroy for unknown channel %X from CADET service (recently close?)\n",
690 ntohl (msg->ccn.channel_of_client));
691 return;
692 }
693 LOG (GNUNET_ERROR_TYPE_DEBUG,
694 "Received channel destroy for channel %X from CADET service\n",
695 ntohl (msg->ccn.channel_of_client));
696 destroy_channel (ch);
697}
698
699
700/**
701 * Check that message received from CADET service is well-formed.
702 *
703 * @param cls the `struct GNUNET_CADET_Handle`
704 * @param message the message we got
705 * @return #GNUNET_OK if the message is well-formed,
706 * #GNUNET_SYSERR otherwise
707 */
708static int
709check_local_data (void *cls,
710 const struct GNUNET_CADET_LocalData *message)
711{
712 uint16_t size;
713
714 size = ntohs (message->header.size);
715 if (sizeof (*message) + sizeof (struct GNUNET_MessageHeader) > size)
716 {
717 GNUNET_break (0);
718 return GNUNET_SYSERR;
719 }
720 return GNUNET_OK;
721}
722
723
724/**
725 * Process the incoming data packets, call appropriate handlers.
726 *
727 * @param h The cadet handle
728 * @param message A message encapsulating the data
729 */
730static void
731handle_local_data (void *cls,
732 const struct GNUNET_CADET_LocalData *message)
733{
734 struct GNUNET_CADET_Handle *h = cls;
735 const struct GNUNET_MessageHeader *payload;
736 struct GNUNET_CADET_Channel *ch;
737 uint16_t type;
738 int fwd;
739
740 ch = find_channel (h,
741 message->ccn);
742 if (NULL == ch)
743 {
744 LOG (GNUNET_ERROR_TYPE_DEBUG,
745 "Unknown channel %X for incoming data (recently closed?)\n",
746 ntohl (message->ccn.channel_of_client));
747 return;
748 }
749
750 payload = (const struct GNUNET_MessageHeader *) &message[1];
751 type = ntohs (payload->type);
752 fwd = ntohl (ch->ccn.channel_of_client) <= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI;
753 LOG (GNUNET_ERROR_TYPE_DEBUG,
754 "Got a %s data on channel %s [%X] of type %u\n",
755 fwd ? "FWD" : "BWD",
756 GNUNET_i2s (&ch->peer),
757 ntohl (message->ccn.channel_of_client),
758 type);
759 GNUNET_MQ_inject_message (ch->mq,
760 payload);
761}
762
763
764/**
765 * Process a local ACK message, enabling the client to send
766 * more data to the service.
767 *
768 * @param h Cadet handle.
769 * @param message Message itself.
770 */
771static void
772handle_local_ack (void *cls,
773 const struct GNUNET_CADET_LocalAck *message)
774{
775 struct GNUNET_CADET_Handle *h = cls;
776 struct GNUNET_CADET_Channel *ch;
777
778 ch = find_channel (h,
779 message->ccn);
780 if (NULL == ch)
781 {
782 LOG (GNUNET_ERROR_TYPE_DEBUG,
783 "ACK on unknown channel %X\n",
784 ntohl (message->ccn.channel_of_client));
785 return;
786 }
787 ch->allow_send++;
788 if (NULL == ch->pending_env)
789 {
790 LOG (GNUNET_ERROR_TYPE_DEBUG,
791 "Got an ACK on mq channel %X, allow send now %u!\n",
792 ntohl (ch->ccn.channel_of_client),
793 ch->allow_send);
794 notify_window_size (ch);
795 return;
796 }
797 if (NULL != ch->mq_cont)
798 return; /* already working on it! */
799 LOG (GNUNET_ERROR_TYPE_DEBUG,
800 "Got an ACK on mq channel %X, sending pending message!\n",
801 ntohl (ch->ccn.channel_of_client));
802 ch->mq_cont
803 = GNUNET_SCHEDULER_add_now (&cadet_mq_send_now,
804 ch);
805}
806
807
808/**
809 * Generic error handler, called with the appropriate error code and
810 * the same closure specified at the creation of the message queue.
811 * Not every message queue implementation supports an error handler.
812 *
813 * @param cls closure, a `struct GNUNET_CORE_Handle *`
814 * @param error error code
815 */
816static void
817handle_mq_error (void *cls,
818 enum GNUNET_MQ_Error error)
819{
820 struct GNUNET_CADET_Handle *h = cls;
821
822 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
823 "MQ ERROR: %u\n",
824 error);
825 GNUNET_MQ_destroy (h->mq);
826 h->mq = NULL;
827 reconnect (h);
828}
829
830
831/**
832 * Process a local reply about info on all tunnels, pass info to the user.
833 *
834 * @param cls Closure (Cadet handle).
835 * @param msg Message itself.
836 */
837static void
838handle_get_peers (void *cls,
839 const struct GNUNET_CADET_LocalInfoPeer *msg)
840{
841 struct GNUNET_CADET_Handle *h = cls;
842
843 if (NULL == h->info_cb.peers_cb)
844 return;
845 h->info_cb.peers_cb (h->info_cls,
846 &msg->destination,
847 (int) ntohs (msg->tunnel),
848 (unsigned int) ntohs (msg->paths),
849 0);
850}
851
852
853/**
854 * Check that message received from CADET service is well-formed.
855 *
856 * @param cls the `struct GNUNET_CADET_Handle`
857 * @param message the message we got
858 * @return #GNUNET_OK if the message is well-formed,
859 * #GNUNET_SYSERR otherwise
860 */
861static int
862check_get_peer (void *cls,
863 const struct GNUNET_CADET_LocalInfoPeer *message)
864{
865 size_t msize = sizeof (struct GNUNET_CADET_LocalInfoPeer);
866 const struct GNUNET_PeerIdentity *paths_array;
867 size_t esize;
868 unsigned int epaths;
869 unsigned int paths;
870 unsigned int peers;
871
872 esize = ntohs (message->header.size);
873 if (esize < msize)
874 {
875 GNUNET_break (0);
876 return GNUNET_SYSERR;
877 }
878 if (0 != ((esize - msize) % sizeof (struct GNUNET_PeerIdentity)))
879 {
880 GNUNET_break (0);
881 return GNUNET_SYSERR;
882 }
883 peers = (esize - msize) / sizeof (struct GNUNET_PeerIdentity);
884 epaths = ntohs (message->paths);
885 paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
886 paths = 0;
887 for (unsigned int i = 0; i < peers; i++)
888 if (0 == memcmp (&paths_array[i],
889 &message->destination,
890 sizeof (struct GNUNET_PeerIdentity)))
891 paths++;
892 if (paths != epaths)
893 {
894 GNUNET_break (0);
895 return GNUNET_SYSERR;
896 }
897 return GNUNET_OK;
898}
899
900
901/**
902 * Process a local peer info reply, pass info to the user.
903 *
904 * @param cls Closure (Cadet handle).
905 * @param message Message itself.
906 */
907static void
908handle_get_peer (void *cls,
909 const struct GNUNET_CADET_LocalInfoPeer *message)
910{
911 struct GNUNET_CADET_Handle *h = cls;
912 const struct GNUNET_PeerIdentity *paths_array;
913 unsigned int paths;
914 unsigned int path_length;
915 int neighbor;
916 unsigned int peers;
917
918 if (NULL == h->info_cb.peer_cb)
919 return;
920 paths = ntohs (message->paths);
921 paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
922 peers = (ntohs (message->header.size) - sizeof (*message))
923 / sizeof (struct GNUNET_PeerIdentity);
924 path_length = 0;
925 neighbor = GNUNET_NO;
926
927 for (unsigned int i = 0; i < peers; i++)
928 {
929 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
930 " %s\n",
931 GNUNET_i2s (&paths_array[i]));
932 path_length++;
933 if (0 == memcmp (&paths_array[i], &message->destination,
934 sizeof (struct GNUNET_PeerIdentity)))
935 {
936 if (1 == path_length)
937 neighbor = GNUNET_YES;
938 path_length = 0;
939 }
940 }
941
942 /* Call Callback with tunnel info. */
943 paths_array = (const struct GNUNET_PeerIdentity *) &message[1];
944 h->info_cb.peer_cb (h->info_cls,
945 &message->destination,
946 (int) ntohs (message->tunnel),
947 neighbor,
948 paths,
949 paths_array);
950}
951
952
953/**
954 * Process a local reply about info on all tunnels, pass info to the user.
955 *
956 * @param cls Closure (Cadet handle).
957 * @param message Message itself.
958 */
959static void
960handle_get_tunnels (void *cls,
961 const struct GNUNET_CADET_LocalInfoTunnel *msg)
962{
963 struct GNUNET_CADET_Handle *h = cls;
964
965 if (NULL == h->info_cb.tunnels_cb)
966 return;
967 h->info_cb.tunnels_cb (h->info_cls,
968 &msg->destination,
969 ntohl (msg->channels),
970 ntohl (msg->connections),
971 ntohs (msg->estate),
972 ntohs (msg->cstate));
973
974}
975
976
977/**
978 * Check that message received from CADET service is well-formed.
979 *
980 * @param cls the `struct GNUNET_CADET_Handle`
981 * @param msg the message we got
982 * @return #GNUNET_OK if the message is well-formed,
983 * #GNUNET_SYSERR otherwise
984 */
985static int
986check_get_tunnel (void *cls,
987 const struct GNUNET_CADET_LocalInfoTunnel *msg)
988{
989 unsigned int ch_n;
990 unsigned int c_n;
991 size_t esize;
992 size_t msize;
993
994 /* Verify message sanity */
995 msize = ntohs (msg->header.size);
996 esize = sizeof (struct GNUNET_CADET_LocalInfoTunnel);
997 if (esize > msize)
998 {
999 GNUNET_break (0);
1000 return GNUNET_SYSERR;
1001 }
1002 ch_n = ntohl (msg->channels);
1003 c_n = ntohl (msg->connections);
1004 esize += ch_n * sizeof (struct GNUNET_CADET_ChannelTunnelNumber);
1005 esize += c_n * sizeof (struct GNUNET_CADET_ConnectionTunnelIdentifier);
1006 if (msize != esize)
1007 {
1008 GNUNET_break_op (0);
1009 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1010 "m:%u, e: %u (%u ch, %u conn)\n",
1011 (unsigned int) msize,
1012 (unsigned int) esize,
1013 ch_n,
1014 c_n);
1015 return GNUNET_SYSERR;
1016 }
1017 return GNUNET_OK;
1018}
1019
1020
1021/**
1022 * Process a local tunnel info reply, pass info to the user.
1023 *
1024 * @param cls Closure (Cadet handle).
1025 * @param msg Message itself.
1026 */
1027static void
1028handle_get_tunnel (void *cls,
1029 const struct GNUNET_CADET_LocalInfoTunnel *msg)
1030{
1031 struct GNUNET_CADET_Handle *h = cls;
1032 unsigned int ch_n;
1033 unsigned int c_n;
1034 const struct GNUNET_CADET_ConnectionTunnelIdentifier *conns;
1035 const struct GNUNET_CADET_ChannelTunnelNumber *chns;
1036
1037 if (NULL == h->info_cb.tunnel_cb)
1038 return;
1039
1040 ch_n = ntohl (msg->channels);
1041 c_n = ntohl (msg->connections);
1042
1043 /* Call Callback with tunnel info. */
1044 conns = (const struct GNUNET_CADET_ConnectionTunnelIdentifier *) &msg[1];
1045 chns = (const struct GNUNET_CADET_ChannelTunnelNumber *) &conns[c_n];
1046 h->info_cb.tunnel_cb (h->info_cls,
1047 &msg->destination,
1048 ch_n,
1049 c_n,
1050 chns,
1051 conns,
1052 ntohs (msg->estate),
1053 ntohs (msg->cstate));
1054}
1055
1056
1057/**
1058 * Reconnect to the service, retransmit all infomation to try to restore the
1059 * original state.
1060 *
1061 * @param h handle to the cadet
1062 */
1063static void
1064reconnect (struct GNUNET_CADET_Handle *h)
1065{
1066 struct GNUNET_MQ_MessageHandler handlers[] = {
1067 GNUNET_MQ_hd_fixed_size (channel_created,
1068 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE,
1069 struct GNUNET_CADET_LocalChannelCreateMessage,
1070 h),
1071 GNUNET_MQ_hd_fixed_size (channel_destroy,
1072 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY,
1073 struct GNUNET_CADET_LocalChannelDestroyMessage,
1074 h),
1075 GNUNET_MQ_hd_var_size (local_data,
1076 GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA,
1077 struct GNUNET_CADET_LocalData,
1078 h),
1079 GNUNET_MQ_hd_fixed_size (local_ack,
1080 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK,
1081 struct GNUNET_CADET_LocalAck,
1082 h),
1083 GNUNET_MQ_hd_fixed_size (get_peers,
1084 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS,
1085 struct GNUNET_CADET_LocalInfoPeer,
1086 h),
1087 GNUNET_MQ_hd_var_size (get_peer,
1088 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER,
1089 struct GNUNET_CADET_LocalInfoPeer,
1090 h),
1091 GNUNET_MQ_hd_fixed_size (get_tunnels,
1092 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS,
1093 struct GNUNET_CADET_LocalInfoTunnel,
1094 h),
1095 GNUNET_MQ_hd_var_size (get_tunnel,
1096 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL,
1097 struct GNUNET_CADET_LocalInfoTunnel,
1098 h),
1099 GNUNET_MQ_handler_end ()
1100 };
1101
1102 h->mq = GNUNET_CLIENT_connect (h->cfg,
1103 "cadet",
1104 handlers,
1105 &handle_mq_error,
1106 h);
1107 if (NULL == h->mq)
1108 {
1109 schedule_reconnect (h);
1110 return;
1111 }
1112 h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1113}
1114
1115
1116/**
1117 * Function called during #GNUNET_CADET_disconnect() to destroy
1118 * all channels that are still open.
1119 *
1120 * @param cls the `struct GNUNET_CADET_Handle`
1121 * @param cid chanenl ID
1122 * @param value a `struct GNUNET_CADET_Channel` to destroy
1123 * @return #GNUNET_OK (continue to iterate)
1124 */
1125static int
1126destroy_channel_cb (void *cls,
1127 uint32_t cid,
1128 void *value)
1129{
1130 /* struct GNUNET_CADET_Handle *handle = cls; */
1131 struct GNUNET_CADET_Channel *ch = value;
1132
1133 if (ntohl (ch->ccn.channel_of_client) >= GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
1134 {
1135 GNUNET_break (0);
1136 LOG (GNUNET_ERROR_TYPE_DEBUG,
1137 "channel %X not destroyed\n",
1138 ntohl (ch->ccn.channel_of_client));
1139 }
1140 destroy_channel (ch);
1141 return GNUNET_OK;
1142}
1143
1144
1145/**
1146 * Function called during #GNUNET_CADET_disconnect() to destroy
1147 * all ports that are still open.
1148 *
1149 * @param cls the `struct GNUNET_CADET_Handle`
1150 * @param id port ID
1151 * @param value a `struct GNUNET_CADET_Channel` to destroy
1152 * @return #GNUNET_OK (continue to iterate)
1153 */
1154static int
1155destroy_port_cb (void *cls,
1156 const struct GNUNET_HashCode *id,
1157 void *value)
1158{
1159 /* struct GNUNET_CADET_Handle *handle = cls; */
1160 struct GNUNET_CADET_Port *port = value;
1161
1162 /* This is a warning, the app should have cleanly closed all open ports */
1163 GNUNET_break (0);
1164 GNUNET_CADET_close_port (port);
1165 return GNUNET_OK;
1166}
1167
1168
1169/**
1170 * Disconnect from the cadet service. All channels will be destroyed. All channel
1171 * disconnect callbacks will be called on any still connected peers, notifying
1172 * about their disconnection. The registered inbound channel cleaner will be
1173 * called should any inbound channels still exist.
1174 *
1175 * @param handle connection to cadet to disconnect
1176 */
1177void
1178GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle)
1179{
1180 GNUNET_CONTAINER_multihashmap_iterate (handle->ports,
1181 &destroy_port_cb,
1182 handle);
1183 GNUNET_CONTAINER_multihashmap_destroy (handle->ports);
1184 handle->ports = NULL;
1185 GNUNET_CONTAINER_multihashmap32_iterate (handle->channels,
1186 &destroy_channel_cb,
1187 handle);
1188 GNUNET_CONTAINER_multihashmap32_destroy (handle->channels);
1189 handle->channels = NULL;
1190 if (NULL != handle->mq)
1191 {
1192 GNUNET_MQ_destroy (handle->mq);
1193 handle->mq = NULL;
1194 }
1195 if (NULL != handle->reconnect_task)
1196 {
1197 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
1198 handle->reconnect_task = NULL;
1199 }
1200 GNUNET_free (handle);
1201}
1202
1203
1204/**
1205 * Close a port opened with @a GNUNET_CADET_open_port().
1206 * The @a new_channel callback will no longer be called.
1207 *
1208 * @param p Port handle.
1209 */
1210void
1211GNUNET_CADET_close_port (struct GNUNET_CADET_Port *p)
1212{
1213 struct GNUNET_CADET_PortMessage *msg;
1214 struct GNUNET_MQ_Envelope *env;
1215
1216 env = GNUNET_MQ_msg (msg,
1217 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE);
1218 msg->port = p->id;
1219 GNUNET_MQ_send (p->cadet->mq,
1220 env);
1221 GNUNET_assert (GNUNET_YES ==
1222 GNUNET_CONTAINER_multihashmap_remove (p->cadet->ports,
1223 &p->id,
1224 p));
1225 GNUNET_free_non_null (p->handlers);
1226 GNUNET_free (p);
1227}
1228
1229
1230/**
1231 * Destroy an existing channel.
1232 *
1233 * The existing end callback for the channel will be called immediately.
1234 * Any pending outgoing messages will be sent but no incoming messages will be
1235 * accepted and no data callbacks will be called.
1236 *
1237 * @param channel Channel handle, becomes invalid after this call.
1238 */
1239void
1240GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel)
1241{
1242 struct GNUNET_CADET_Handle *h = channel->cadet;
1243 struct GNUNET_CADET_LocalChannelDestroyMessage *msg;
1244 struct GNUNET_MQ_Envelope *env;
1245
1246 if (NULL != h->mq)
1247 {
1248 env = GNUNET_MQ_msg (msg,
1249 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_DESTROY);
1250 msg->ccn = channel->ccn;
1251 GNUNET_MQ_send (h->mq,
1252 env);
1253 }
1254 destroy_channel (channel);
1255}
1256
1257
1258/**
1259 * Get information about a channel.
1260 *
1261 * @param channel Channel handle.
1262 * @param option Query (GNUNET_CADET_OPTION_*).
1263 * @param ... dependant on option, currently not used
1264 *
1265 * @return Union with an answer to the query.
1266 */
1267const union GNUNET_CADET_ChannelInfo *
1268GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel,
1269 enum GNUNET_CADET_ChannelOption option,
1270 ...)
1271{
1272 static int bool_flag;
1273
1274 switch (option)
1275 {
1276 case GNUNET_CADET_OPTION_NOBUFFER:
1277 case GNUNET_CADET_OPTION_RELIABLE:
1278 case GNUNET_CADET_OPTION_OUT_OF_ORDER:
1279 if (0 != (option & channel->options))
1280 bool_flag = GNUNET_YES;
1281 else
1282 bool_flag = GNUNET_NO;
1283 return (const union GNUNET_CADET_ChannelInfo *) &bool_flag;
1284 break;
1285 case GNUNET_CADET_OPTION_PEER:
1286 return (const union GNUNET_CADET_ChannelInfo *) &channel->peer;
1287 break;
1288 default:
1289 GNUNET_break (0);
1290 return NULL;
1291 }
1292}
1293
1294
1295/**
1296 * Send an ack on the channel to confirm the processing of a message.
1297 *
1298 * @param ch Channel on which to send the ACK.
1299 */
1300void
1301GNUNET_CADET_receive_done (struct GNUNET_CADET_Channel *channel)
1302{
1303 struct GNUNET_CADET_LocalAck *msg;
1304 struct GNUNET_MQ_Envelope *env;
1305
1306 env = GNUNET_MQ_msg (msg,
1307 GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
1308 LOG (GNUNET_ERROR_TYPE_DEBUG,
1309 "Sending ACK on channel %X\n",
1310 ntohl (channel->ccn.channel_of_client));
1311 msg->ccn = channel->ccn;
1312 GNUNET_MQ_send (channel->cadet->mq,
1313 env);
1314}
1315
1316
1317/**
1318 * Send message of @a type to CADET service of @a h
1319 *
1320 * @param h handle to CADET service
1321 * @param type message type of trivial information request to send
1322 */
1323static void
1324send_info_request (struct GNUNET_CADET_Handle *h,
1325 uint16_t type)
1326{
1327 struct GNUNET_MessageHeader *msg;
1328 struct GNUNET_MQ_Envelope *env;
1329
1330 env = GNUNET_MQ_msg (msg,
1331 type);
1332 GNUNET_MQ_send (h->mq,
1333 env);
1334}
1335
1336
1337/**
1338 * Request a debug dump on the service's STDERR.
1339 *
1340 * WARNING: unstable API, likely to change in the future!
1341 *
1342 * @param h cadet handle
1343 */
1344void
1345GNUNET_CADET_request_dump (struct GNUNET_CADET_Handle *h)
1346{
1347 send_info_request (h,
1348 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP);
1349}
1350
1351
1352/**
1353 * Request information about peers known to the running cadet service.
1354 * The callback will be called for every peer known to the service.
1355 * Only one info request (of any kind) can be active at once.
1356 *
1357 * WARNING: unstable API, likely to change in the future!
1358 *
1359 * @param h Handle to the cadet peer.
1360 * @param callback Function to call with the requested data.
1361 * @param callback_cls Closure for @c callback.
1362 * @return #GNUNET_OK / #GNUNET_SYSERR
1363 */
1364int
1365GNUNET_CADET_get_peers (struct GNUNET_CADET_Handle *h,
1366 GNUNET_CADET_PeersCB callback,
1367 void *callback_cls)
1368{
1369 if (NULL != h->info_cb.peers_cb)
1370 {
1371 GNUNET_break (0);
1372 return GNUNET_SYSERR;
1373 }
1374 send_info_request (h,
1375 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS);
1376 h->info_cb.peers_cb = callback;
1377 h->info_cls = callback_cls;
1378 return GNUNET_OK;
1379}
1380
1381
1382/**
1383 * Cancel a peer info request. The callback will not be called (anymore).
1384 *
1385 * WARNING: unstable API, likely to change in the future!
1386 *
1387 * @param h Cadet handle.
1388 * @return Closure given to GNUNET_CADET_get_peers().
1389 */
1390void *
1391GNUNET_CADET_get_peers_cancel (struct GNUNET_CADET_Handle *h)
1392{
1393 void *cls = h->info_cls;
1394
1395 h->info_cb.peers_cb = NULL;
1396 h->info_cls = NULL;
1397 return cls;
1398}
1399
1400
1401/**
1402 * Request information about a peer known to the running cadet peer.
1403 * The callback will be called for the tunnel once.
1404 * Only one info request (of any kind) can be active at once.
1405 *
1406 * WARNING: unstable API, likely to change in the future!
1407 *
1408 * @param h Handle to the cadet peer.
1409 * @param id Peer whose tunnel to examine.
1410 * @param callback Function to call with the requested data.
1411 * @param callback_cls Closure for @c callback.
1412 * @return #GNUNET_OK / #GNUNET_SYSERR
1413 */
1414int
1415GNUNET_CADET_get_peer (struct GNUNET_CADET_Handle *h,
1416 const struct GNUNET_PeerIdentity *id,
1417 GNUNET_CADET_PeerCB callback,
1418 void *callback_cls)
1419{
1420 struct GNUNET_CADET_LocalInfo *msg;
1421 struct GNUNET_MQ_Envelope *env;
1422
1423 if (NULL != h->info_cb.peer_cb)
1424 {
1425 GNUNET_break (0);
1426 return GNUNET_SYSERR;
1427 }
1428 env = GNUNET_MQ_msg (msg,
1429 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER);
1430 msg->peer = *id;
1431 GNUNET_MQ_send (h->mq,
1432 env);
1433 h->info_cb.peer_cb = callback;
1434 h->info_cls = callback_cls;
1435 return GNUNET_OK;
1436}
1437
1438
1439/**
1440 * Request information about tunnels of the running cadet peer.
1441 * The callback will be called for every tunnel of the service.
1442 * Only one info request (of any kind) can be active at once.
1443 *
1444 * WARNING: unstable API, likely to change in the future!
1445 *
1446 * @param h Handle to the cadet peer.
1447 * @param callback Function to call with the requested data.
1448 * @param callback_cls Closure for @c callback.
1449 * @return #GNUNET_OK / #GNUNET_SYSERR
1450 */
1451int
1452GNUNET_CADET_get_tunnels (struct GNUNET_CADET_Handle *h,
1453 GNUNET_CADET_TunnelsCB callback,
1454 void *callback_cls)
1455{
1456 if (NULL != h->info_cb.tunnels_cb)
1457 {
1458 GNUNET_break (0);
1459 return GNUNET_SYSERR;
1460 }
1461 send_info_request (h,
1462 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS);
1463 h->info_cb.tunnels_cb = callback;
1464 h->info_cls = callback_cls;
1465 return GNUNET_OK;
1466}
1467
1468
1469/**
1470 * Cancel a monitor request. The monitor callback will not be called.
1471 *
1472 * @param h Cadet handle.
1473 * @return Closure given to GNUNET_CADET_get_tunnels().
1474 */
1475void *
1476GNUNET_CADET_get_tunnels_cancel (struct GNUNET_CADET_Handle *h)
1477{
1478 void *cls = h->info_cls;
1479
1480 h->info_cb.tunnels_cb = NULL;
1481 h->info_cls = NULL;
1482 return cls;
1483}
1484
1485
1486/**
1487 * Request information about a tunnel of the running cadet peer.
1488 * The callback will be called for the tunnel once.
1489 * Only one info request (of any kind) can be active at once.
1490 *
1491 * WARNING: unstable API, likely to change in the future!
1492 *
1493 * @param h Handle to the cadet peer.
1494 * @param id Peer whose tunnel to examine.
1495 * @param callback Function to call with the requested data.
1496 * @param callback_cls Closure for @c callback.
1497 * @return #GNUNET_OK / #GNUNET_SYSERR
1498 */
1499int
1500GNUNET_CADET_get_tunnel (struct GNUNET_CADET_Handle *h,
1501 const struct GNUNET_PeerIdentity *id,
1502 GNUNET_CADET_TunnelCB callback,
1503 void *callback_cls)
1504{
1505 struct GNUNET_CADET_LocalInfo *msg;
1506 struct GNUNET_MQ_Envelope *env;
1507
1508 if (NULL != h->info_cb.tunnel_cb)
1509 {
1510 GNUNET_break (0);
1511 return GNUNET_SYSERR;
1512 }
1513 env = GNUNET_MQ_msg (msg,
1514 GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL);
1515 msg->peer = *id;
1516 GNUNET_MQ_send (h->mq,
1517 env);
1518 h->info_cb.tunnel_cb = callback;
1519 h->info_cls = callback_cls;
1520 return GNUNET_OK;
1521}
1522
1523
1524/**
1525 * Transitional function to convert an unsigned int port to a hash value.
1526 * WARNING: local static value returned, NOT reentrant!
1527 * WARNING: do not use this function for new code!
1528 *
1529 * @param port Numerical port (unsigned int format).
1530 *
1531 * @return A GNUNET_HashCode usable for the new CADET API.
1532 */
1533const struct GNUNET_HashCode *
1534GC_u2h (uint32_t port)
1535{
1536 static struct GNUNET_HashCode hash;
1537
1538 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1539 "This is a transitional function, use proper crypto hashes as CADET ports\n");
1540 GNUNET_CRYPTO_hash (&port,
1541 sizeof (port),
1542 &hash);
1543 return &hash;
1544}
1545
1546
1547/**
1548 * Connect to the MQ-based cadet service.
1549 *
1550 * @param cfg Configuration to use.
1551 *
1552 * @return Handle to the cadet service NULL on error.
1553 */
1554struct GNUNET_CADET_Handle *
1555GNUNET_CADET_connecT (const struct GNUNET_CONFIGURATION_Handle *cfg)
1556{
1557 struct GNUNET_CADET_Handle *h;
1558
1559 LOG (GNUNET_ERROR_TYPE_DEBUG,
1560 "GNUNET_CADET_connecT()\n");
1561 h = GNUNET_new (struct GNUNET_CADET_Handle);
1562 h->cfg = cfg;
1563 h->ports = GNUNET_CONTAINER_multihashmap_create (4,
1564 GNUNET_YES);
1565 h->channels = GNUNET_CONTAINER_multihashmap32_create (4);
1566 reconnect (h);
1567 if (NULL == h->mq)
1568 {
1569 GNUNET_break (0);
1570 GNUNET_CADET_disconnect (h);
1571 return NULL;
1572 }
1573 h->next_ccn.channel_of_client = htonl (GNUNET_CADET_LOCAL_CHANNEL_ID_CLI);
1574 h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
1575 h->reconnect_task = NULL;
1576
1577 return h;
1578}
1579
1580
1581/**
1582 * Open a port to receive incomming MQ-based channels.
1583 *
1584 * @param h CADET handle.
1585 * @param port Hash identifying the port.
1586 * @param connects Function called when an incoming channel is connected.
1587 * @param connects_cls Closure for the @a connects handler.
1588 * @param window_changes Function called when the transmit window size changes.
1589 * @param disconnects Function called when a channel is disconnected.
1590 * @param handlers Callbacks for messages we care about, NULL-terminated.
1591 * @return Port handle.
1592 */
1593struct GNUNET_CADET_Port *
1594GNUNET_CADET_open_porT (struct GNUNET_CADET_Handle *h,
1595 const struct GNUNET_HashCode *port,
1596 GNUNET_CADET_ConnectEventHandler connects,
1597 void * connects_cls,
1598 GNUNET_CADET_WindowSizeEventHandler window_changes,
1599 GNUNET_CADET_DisconnectEventHandler disconnects,
1600 const struct GNUNET_MQ_MessageHandler *handlers)
1601{
1602 struct GNUNET_CADET_PortMessage *msg;
1603 struct GNUNET_MQ_Envelope *env;
1604 struct GNUNET_CADET_Port *p;
1605
1606 GNUNET_assert (NULL != connects);
1607 GNUNET_assert (NULL != disconnects);
1608
1609 p = GNUNET_new (struct GNUNET_CADET_Port);
1610 p->cadet = h;
1611 p->id = *port;
1612 p->connects = connects;
1613 p->cls = connects_cls;
1614 p->window_changes = window_changes;
1615 p->disconnects = disconnects;
1616 p->handlers = GNUNET_MQ_copy_handlers (handlers);
1617
1618 GNUNET_assert (GNUNET_OK ==
1619 GNUNET_CONTAINER_multihashmap_put (h->ports,
1620 &p->id,
1621 p,
1622 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1623
1624 env = GNUNET_MQ_msg (msg,
1625 GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN);
1626 msg->port = p->id;
1627 GNUNET_MQ_send (h->mq,
1628 env);
1629 return p;
1630}
1631
1632
1633/**
1634 * Create a new channel towards a remote peer.
1635 *
1636 * If the destination port is not open by any peer or the destination peer
1637 * does not accept the channel, #GNUNET_CADET_ChannelEndHandler will be called
1638 * for this channel.
1639 *
1640 * @param h CADET handle.
1641 * @param channel_cls Closure for the channel. It's given to:
1642 * - The disconnect handler @a disconnects
1643 * - Each message type callback in @a handlers
1644 * @param destination Peer identity the channel should go to.
1645 * @param port Identification of the destination port.
1646 * @param options CadetOption flag field, with all desired option bits set to 1.
1647 * @param window_changes Function called when the transmit window size changes.
1648 * @param disconnects Function called when the channel is disconnected.
1649 * @param handlers Callbacks for messages we care about, NULL-terminated.
1650 * @return Handle to the channel.
1651 */
1652struct GNUNET_CADET_Channel *
1653GNUNET_CADET_channel_creatE (struct GNUNET_CADET_Handle *h,
1654 void *channel_cls,
1655 const struct GNUNET_PeerIdentity *destination,
1656 const struct GNUNET_HashCode *port,
1657 enum GNUNET_CADET_ChannelOption options,
1658 GNUNET_CADET_WindowSizeEventHandler window_changes,
1659 GNUNET_CADET_DisconnectEventHandler disconnects,
1660 const struct GNUNET_MQ_MessageHandler *handlers)
1661{
1662 struct GNUNET_CADET_Channel *ch;
1663 struct GNUNET_CADET_LocalChannelCreateMessage *msg;
1664 struct GNUNET_MQ_Envelope *env;
1665
1666 GNUNET_assert (NULL != disconnects);
1667 ch = create_channel (h,
1668 NULL);
1669 ch->ctx = channel_cls;
1670 ch->peer = *destination;
1671 ch->options = options;
1672 ch->window_changes = window_changes;
1673 ch->disconnects = disconnects;
1674
1675 /* Create MQ for channel */
1676 ch->mq = GNUNET_MQ_queue_for_callbacks (&cadet_mq_send_impl,
1677 &cadet_mq_destroy_impl,
1678 &cadet_mq_cancel_impl,
1679 ch,
1680 handlers,
1681 &cadet_mq_error_handler,
1682 ch);
1683 GNUNET_MQ_set_handlers_closure (ch->mq, channel_cls);
1684
1685 /* Request channel creation to service */
1686 env = GNUNET_MQ_msg (msg,
1687 GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
1688 msg->ccn = ch->ccn;
1689 msg->port = *port;
1690 msg->peer = *destination;
1691 msg->opt = htonl (options);
1692 GNUNET_MQ_send (h->mq,
1693 env);
1694 return ch;
1695}
1696
1697
1698/**
1699 * Obtain the message queue for a connected peer.
1700 *
1701 * @param channel The channel handle from which to get the MQ.
1702 *
1703 * @return NULL if @a channel is not yet connected.
1704 */
1705struct GNUNET_MQ_Handle *
1706GNUNET_CADET_get_mq (const struct GNUNET_CADET_Channel *channel)
1707{
1708 return channel->mq;
1709}
1710
1711/* end of cadet_api.c */
diff --git a/src/cadet/cadet_common.c b/src/cadet/cadet_common.c
deleted file mode 100644
index 95a3144e4..000000000
--- a/src/cadet/cadet_common.c
+++ /dev/null
@@ -1,370 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012 GNUnet e.V.
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21/**
22 * @file cadet/cadet_common.c
23 * @brief CADET helper functions
24 * @author Bartlomiej Polot
25 */
26
27#include "cadet.h"
28
29/**
30 * @brief Translate a fwd variable into a string representation, for logging.
31 *
32 * @param fwd Is FWD? (#GNUNET_YES or #GNUNET_NO)
33 *
34 * @return String representing FWD or BCK.
35 */
36char *
37GC_f2s (int fwd)
38{
39 if (GNUNET_YES == fwd)
40 {
41 return "FWD";
42 }
43 else if (GNUNET_NO == fwd)
44 {
45 return "BCK";
46 }
47 else
48 {
49 /* Not an error, can happen with CONNECTION_BROKEN messages. */
50 return "\???";
51 }
52}
53
54
55/**
56 * Test if @a bigger is larger than @a smaller.
57 * Considers the case that @a bigger just overflowed
58 * and is thus tiny while @a smaller is still below
59 * `UINT32_MAX`.
60 */
61int
62GC_is_pid_bigger (uint32_t bigger,
63 uint32_t smaller)
64{
65 return (PID_OVERFLOW (smaller, bigger) ||
66 ( (bigger > smaller) &&
67 (! PID_OVERFLOW (bigger, smaller))) );
68}
69
70
71uint32_t
72GC_max_pid (uint32_t a, uint32_t b)
73{
74 if (GC_is_pid_bigger(a, b))
75 return a;
76 return b;
77}
78
79
80uint32_t
81GC_min_pid (uint32_t a, uint32_t b)
82{
83 if (GC_is_pid_bigger(a, b))
84 return b;
85 return a;
86}
87
88
89/**
90 * Allocate a string with a hexdump of any binary data.
91 *
92 * @param bin Arbitrary binary data.
93 * @param len Length of @a bin in bytes.
94 * @param output Where to write the output (if *output be NULL it's allocated).
95 *
96 * @return The size of the output.
97 */
98size_t
99GC_bin2s (void *bin, unsigned int len, char **output)
100{
101 char *data = bin;
102 char *buf;
103 unsigned int s_len;
104 unsigned int i;
105
106 s_len = 2 * len + 1;
107 if (NULL == *output)
108 *output = GNUNET_malloc (s_len);
109 buf = *output;
110
111 for (i = 0; i < len; i++)
112 {
113 SPRINTF (&buf[2 * i], "%2X", data[i]);
114 }
115 buf[s_len - 1] = '\0';
116
117 return s_len;
118}
119
120
121#if !defined(GNUNET_CULL_LOGGING)
122const char *
123GC_m2s (uint16_t m)
124{
125 static char buf[2][16];
126 static int idx;
127 const char *s;
128
129 idx = (idx + 1) % 2;
130 switch (m)
131 {
132 /**
133 * Used to mark the "payload" of a non-payload message.
134 */
135 case 0:
136 s = "retransmit";
137 break;
138
139 /**
140 * Request the creation of a path
141 */
142 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE:
143 s = "CONN_CREAT";
144 break;
145
146 /**
147 * Request the modification of an existing path
148 */
149 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK:
150 s = "CONN_ACK";
151 break;
152
153 /**
154 * Notify that a connection of a path is no longer valid
155 */
156 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN:
157 s = "CONN_BRKN";
158 break;
159
160 /**
161 * At some point, the route will spontaneously change
162 */
163 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_PATH_CHANGED_UNIMPLEMENTED:
164 s = "PATH_CHNGD";
165 break;
166
167 /**
168 * Transport payload data.
169 */
170 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA:
171 s = "DATA";
172 break;
173
174 /**
175 * Confirm receipt of payload data.
176 */
177 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK:
178 s = "DATA_ACK";
179 break;
180
181 /**
182 * Key exchange message.
183 */
184 case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_KX:
185 s = "KX";
186 break;
187
188 /**
189 * Encrypted.
190 */
191 case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED:
192 s = "ENCRYPTED";
193 break;
194
195 /**
196 * Request the destuction of a path
197 */
198 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY:
199 s = "CONN_DSTRY";
200 break;
201
202 /**
203 * ACK for a data packet.
204 */
205 case GNUNET_MESSAGE_TYPE_CADET_CONNECTION_HOP_BY_HOP_ENCRYPTED_ACK:
206 s = "ACK";
207 break;
208
209 /**
210 * POLL for ACK.
211 */
212 case GNUNET_MESSAGE_TYPE_CADET_TUNNEL_ENCRYPTED_POLL:
213 s = "POLL";
214 break;
215
216 /**
217 * Announce origin is still alive.
218 */
219 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE:
220 s = "KEEPALIVE";
221 break;
222
223 /**
224 * Open port
225 */
226 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_OPEN:
227 s = "OPEN_PORT";
228 break;
229
230 /**
231 * Close port
232 */
233 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_PORT_CLOSE:
234 s = "CLOSE_PORT";
235 break;
236
237 /**
238 * Ask the cadet service to create a new tunnel
239 */
240 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN:
241 s = "CHAN_CREAT";
242 break;
243
244 /**
245 * Ask the cadet service to destroy a tunnel
246 */
247 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_DESTROY:
248 s = "CHAN_DSTRY";
249 break;
250
251 /**
252 * Confirm the creation of a channel.
253 */
254 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK:
255 s = "CHAN_ACK";
256 break;
257
258 /**
259 * Confirm the creation of a channel.
260 */
261 case GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_NACK_DEPRECATED:
262 s = "CHAN_NACK";
263 break;
264
265 /**
266 * Local payload traffic
267 */
268 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA:
269 s = "LOC_DATA";
270 break;
271
272 /**
273 * Local ACK for data.
274 */
275 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK:
276 s = "LOC_ACK";
277 break;
278
279 /**
280 * Local monitoring of channels.
281 */
282 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNELS:
283 s = "INFO_CHANS";
284 break;
285
286 /**
287 * Local monitoring of a channel.
288 */
289 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CHANNEL:
290 s = "INFO_CHAN";
291 break;
292
293 /**
294 * Local monitoring of service.
295 */
296 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNELS:
297 s = "INFO_TUNS";
298 break;
299
300 /**
301 * Local monitoring of service.
302 */
303 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_TUNNEL:
304 s = "INFO_TUN";
305 break;
306
307 /**
308 * Local information about all connections of service.
309 */
310 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CONNECTIONS:
311 s = "INFO_CONNS";
312 break;
313
314 /**
315 * Local information of service about a specific connection.
316 */
317 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_CONNECTION:
318 s = "INFO_CONN";
319 break;
320
321 /**
322 * Local information about all peers known to the service.
323 */
324 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEERS:
325 s = "INFO_PEERS";
326 break;
327
328 /**
329 * Local information of service about a specific peer.
330 */
331 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_PEER:
332 s = "INFO_PEER";
333 break;
334
335 /**
336 * Traffic (net-cat style) used by the Command Line Interface.
337 */
338 case GNUNET_MESSAGE_TYPE_CADET_CLI:
339 s = "CLI";
340 break;
341
342 /**
343 * Debug request.
344 */
345 case GNUNET_MESSAGE_TYPE_CADET_LOCAL_INFO_DUMP:
346 s = "INFO_DUMP";
347 break;
348
349 /**
350 * Used to mark the "payload" of a non-payload message.
351 */
352 case UINT16_MAX:
353 s = " N/A";
354 break;
355
356
357 default:
358 SPRINTF (buf[idx], "{UNK: %5u}", m);
359 return buf[idx];
360 }
361 SPRINTF (buf[idx], "{%10s}", s);
362 return buf[idx];
363}
364#else
365const char *
366GC_m2s (uint16_t m)
367{
368 return "";
369}
370#endif
diff --git a/src/cadet/cadet_test_lib.c b/src/cadet/cadet_test_lib.c
index b2131d49f..1df6bff0d 100644
--- a/src/cadet/cadet_test_lib.c
+++ b/src/cadet/cadet_test_lib.c
@@ -137,14 +137,14 @@ cadet_connect_adapter (void *cls,
137 struct GNUNET_CADET_Handle *h; 137 struct GNUNET_CADET_Handle *h;
138 unsigned int i; 138 unsigned int i;
139 139
140 h = GNUNET_CADET_connecT (cfg); 140 h = GNUNET_CADET_connect (cfg);
141 if (NULL == ctx->ports) 141 if (NULL == ctx->ports)
142 return h; 142 return h;
143 143
144 actx->ports = GNUNET_new_array (ctx->port_count, struct GNUNET_CADET_Port *); 144 actx->ports = GNUNET_new_array (ctx->port_count, struct GNUNET_CADET_Port *);
145 for (i = 0; i < ctx->port_count; i++) 145 for (i = 0; i < ctx->port_count; i++)
146 { 146 {
147 actx->ports[i] = GNUNET_CADET_open_porT (h, 147 actx->ports[i] = GNUNET_CADET_open_port (h,
148 ctx->ports[i], 148 ctx->ports[i],
149 ctx->connects, 149 ctx->connects,
150 (void *) (long) actx->peer, 150 (void *) (long) actx->peer,
diff --git a/src/cadet/gnunet-cadet.c b/src/cadet/gnunet-cadet.c
index abbf9a0a7..1556f7d86 100644
--- a/src/cadet/gnunet-cadet.c
+++ b/src/cadet/gnunet-cadet.c
@@ -829,7 +829,7 @@ run (void *cls,
829 829
830 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 830 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
831 "Connecting to CADET service\n"); 831 "Connecting to CADET service\n");
832 mh = GNUNET_CADET_connecT (cfg); 832 mh = GNUNET_CADET_connect (cfg);
833 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 833 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
834 NULL); 834 NULL);
835 if (NULL == mh) 835 if (NULL == mh)
@@ -844,7 +844,7 @@ run (void *cls,
844 GNUNET_CRYPTO_hash (listen_port, 844 GNUNET_CRYPTO_hash (listen_port,
845 strlen (listen_port), 845 strlen (listen_port),
846 &porthash); 846 &porthash);
847 lp = GNUNET_CADET_open_porT (mh, 847 lp = GNUNET_CADET_open_port (mh,
848 &porthash, 848 &porthash,
849 &channel_incoming, 849 &channel_incoming,
850 NULL, 850 NULL,
@@ -876,7 +876,7 @@ run (void *cls,
876 GNUNET_CRYPTO_hash (target_port, 876 GNUNET_CRYPTO_hash (target_port,
877 strlen(target_port), 877 strlen(target_port),
878 &porthash); 878 &porthash);
879 ch = GNUNET_CADET_channel_creatE (mh, 879 ch = GNUNET_CADET_channel_create (mh,
880 NULL, 880 NULL,
881 &pid, 881 &pid,
882 &porthash, 882 &porthash,
diff --git a/src/cadet/test_cadet.c b/src/cadet/test_cadet.c
index 4fe43b3bf..3586b26ac 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)
705/** 705/**
706 * Method called whenever a peer connects to a port in MQ-based CADET. 706 * Method called whenever a peer connects to a port in MQ-based CADET.
707 * 707 *
708 * @param cls Closure from #GNUNET_CADET_open_porT (peer # as long). 708 * @param cls Closure from #GNUNET_CADET_open_port (peer # as long).
709 * @param channel New handle to the channel. 709 * @param channel New handle to the channel.
710 * @param source Peer that started this channel. 710 * @param source Peer that started this channel.
711 * @return Closure for the incoming @a channel. It's given to: 711 * @return Closure for the incoming @a channel. It's given to:
712 * - The #GNUNET_CADET_DisconnectEventHandler (given to 712 * - The #GNUNET_CADET_DisconnectEventHandler (given to
713 * #GNUNET_CADET_open_porT) when the channel dies. 713 * #GNUNET_CADET_open_port) when the channel dies.
714 * - Each the #GNUNET_MQ_MessageCallback handlers for each message 714 * - Each the #GNUNET_MQ_MessageCallback handlers for each message
715 * received on the @a channel. 715 * received on the @a channel.
716 */ 716 */
@@ -840,7 +840,7 @@ start_test (void *cls)
840 } 840 }
841 841
842 ch = GNUNET_new (struct CadetTestChannelWrapper); 842 ch = GNUNET_new (struct CadetTestChannelWrapper);
843 outgoing_ch = GNUNET_CADET_channel_creatE (h1, 843 outgoing_ch = GNUNET_CADET_channel_create (h1,
844 ch, 844 ch,
845 p_id[1], 845 p_id[1],
846 &port, 846 &port,
diff --git a/src/cadet/test_cadet_local_mq.c b/src/cadet/test_cadet_local_mq.c
index 19bafbed1..3089c7fbb 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)
132/** 132/**
133 * Method called whenever a peer connects to a port in MQ-based CADET. 133 * Method called whenever a peer connects to a port in MQ-based CADET.
134 * 134 *
135 * @param cls Closure from #GNUNET_CADET_open_porT. 135 * @param cls Closure from #GNUNET_CADET_open_port.
136 * @param channel New handle to the channel. 136 * @param channel New handle to the channel.
137 * @param source Peer that started this channel. 137 * @param source Peer that started this channel.
138 * @return Closure for the incoming @a channel. It's given to: 138 * @return Closure for the incoming @a channel. It's given to:
139 * - The #GNUNET_CADET_DisconnectEventHandler (given to 139 * - The #GNUNET_CADET_DisconnectEventHandler (given to
140 * #GNUNET_CADET_open_porT) when the channel dies. 140 * #GNUNET_CADET_open_port) when the channel dies.
141 * - Each the #GNUNET_MQ_MessageCallback handlers for each message 141 * - Each the #GNUNET_MQ_MessageCallback handlers for each message
142 * received on the @a channel. 142 * received on the @a channel.
143 */ 143 */
@@ -235,7 +235,7 @@ do_connect (void *cls)
235 GNUNET_TESTING_peer_get_identity (me, &id); 235 GNUNET_TESTING_peer_get_identity (me, &id);
236 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 236 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
237 "creating channel\n"); 237 "creating channel\n");
238 ch = GNUNET_CADET_channel_creatE (cadet_peer_1, /* cadet handle */ 238 ch = GNUNET_CADET_channel_create (cadet_peer_1, /* cadet handle */
239 NULL, /* channel cls */ 239 NULL, /* channel cls */
240 &id, /* destination */ 240 &id, /* destination */
241 GC_u2h (TEST_MESSAGE_TYPE), /* port */ 241 GC_u2h (TEST_MESSAGE_TYPE), /* port */
@@ -282,8 +282,8 @@ run (void *cls,
282 abort_task = GNUNET_SCHEDULER_add_delayed (delay, 282 abort_task = GNUNET_SCHEDULER_add_delayed (delay,
283 &do_abort, 283 &do_abort,
284 (void *) (long) __LINE__); 284 (void *) (long) __LINE__);
285 cadet_peer_1 = GNUNET_CADET_connecT (cfg); 285 cadet_peer_1 = GNUNET_CADET_connect (cfg);
286 cadet_peer_2 = GNUNET_CADET_connecT (cfg); 286 cadet_peer_2 = GNUNET_CADET_connect (cfg);
287 287
288 if ( (NULL == cadet_peer_1) || 288 if ( (NULL == cadet_peer_1) ||
289 (NULL == cadet_peer_2) ) 289 (NULL == cadet_peer_2) )
@@ -297,7 +297,7 @@ run (void *cls,
297 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CADET 1: %p\n", cadet_peer_1); 297 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CADET 1: %p\n", cadet_peer_1);
298 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CADET 2: %p\n", cadet_peer_2); 298 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CADET 2: %p\n", cadet_peer_2);
299 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "handlers 2: %p\n", handlers); 299 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "handlers 2: %p\n", handlers);
300 GNUNET_CADET_open_porT (cadet_peer_2, /* cadet handle */ 300 GNUNET_CADET_open_port (cadet_peer_2, /* cadet handle */
301 GC_u2h (TEST_PORT_ID), /* port id */ 301 GC_u2h (TEST_PORT_ID), /* port id */
302 &connected, /* connect handler */ 302 &connected, /* connect handler */
303 (void *) 2L, /* handle for #connected */ 303 (void *) 2L, /* handle for #connected */
diff --git a/src/conversation/Makefile.am b/src/conversation/Makefile.am
index 83313e7f8..cc2938144 100644
--- a/src/conversation/Makefile.am
+++ b/src/conversation/Makefile.am
@@ -180,7 +180,7 @@ gnunet_service_conversation_LDADD = \
180 libgnunetconversation.la \ 180 libgnunetconversation.la \
181 libgnunetspeaker.la \ 181 libgnunetspeaker.la \
182 libgnunetmicrophone.la \ 182 libgnunetmicrophone.la \
183 $(top_builddir)/src/cadet/libgnunetcadetnew.la \ 183 $(top_builddir)/src/cadet/libgnunetcadet.la \
184 $(top_builddir)/src/util/libgnunetutil.la \ 184 $(top_builddir)/src/util/libgnunetutil.la \
185 $(INTLLIBS) 185 $(INTLLIBS)
186gnunet_service_conversation_LDFLAGS = \ 186gnunet_service_conversation_LDFLAGS = \
diff --git a/src/conversation/gnunet-service-conversation.c b/src/conversation/gnunet-service-conversation.c
index e61ed44a1..5f43bfe80 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,
1109 line->channel_tail, 1109 line->channel_tail,
1110 ch); 1110 ch);
1111 ch->status = CS_CALLER_CALLING; 1111 ch->status = CS_CALLER_CALLING;
1112 ch->channel = GNUNET_CADET_channel_creatE (cadet, 1112 ch->channel = GNUNET_CADET_channel_create (cadet,
1113 ch, 1113 ch,
1114 &msg->target, 1114 &msg->target,
1115 &msg->line_port, 1115 &msg->line_port,
@@ -1263,7 +1263,7 @@ handle_client_register_message (void *cls,
1263 }; 1263 };
1264 1264
1265 line->line_port = msg->line_port; 1265 line->line_port = msg->line_port;
1266 line->port = GNUNET_CADET_open_porT (cadet, 1266 line->port = GNUNET_CADET_open_port (cadet,
1267 &msg->line_port, 1267 &msg->line_port,
1268 &inbound_channel, 1268 &inbound_channel,
1269 line, 1269 line,
@@ -1306,7 +1306,7 @@ run (void *cls,
1306 GNUNET_assert (GNUNET_OK == 1306 GNUNET_assert (GNUNET_OK ==
1307 GNUNET_CRYPTO_get_peer_identity (cfg, 1307 GNUNET_CRYPTO_get_peer_identity (cfg,
1308 &my_identity)); 1308 &my_identity));
1309 cadet = GNUNET_CADET_connecT (cfg); 1309 cadet = GNUNET_CADET_connect (cfg);
1310 if (NULL == cadet) 1310 if (NULL == cadet)
1311 { 1311 {
1312 GNUNET_break (0); 1312 GNUNET_break (0);
diff --git a/src/exit/Makefile.am b/src/exit/Makefile.am
index 271b4ebd7..aa1210269 100644
--- a/src/exit/Makefile.am
+++ b/src/exit/Makefile.am
@@ -54,6 +54,6 @@ gnunet_daemon_exit_LDADD = \
54 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 54 $(top_builddir)/src/statistics/libgnunetstatistics.la \
55 $(top_builddir)/src/tun/libgnunettun.la \ 55 $(top_builddir)/src/tun/libgnunettun.la \
56 $(top_builddir)/src/util/libgnunetutil.la \ 56 $(top_builddir)/src/util/libgnunetutil.la \
57 $(top_builddir)/src/cadet/libgnunetcadetnew.la \ 57 $(top_builddir)/src/cadet/libgnunetcadet.la \
58 $(top_builddir)/src/regex/libgnunetregex.la \ 58 $(top_builddir)/src/regex/libgnunetregex.la \
59 $(GN_LIBINTL) 59 $(GN_LIBINTL)
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c
index 09576e393..a32cb3086 100644
--- a/src/exit/gnunet-daemon-exit.c
+++ b/src/exit/gnunet-daemon-exit.c
@@ -2502,7 +2502,7 @@ store_service (int proto,
2502 GNUNET_h2s (&cadet_port), 2502 GNUNET_h2s (&cadet_port),
2503 name, 2503 name,
2504 (unsigned int) destination_port); 2504 (unsigned int) destination_port);
2505 service->port = GNUNET_CADET_open_porT (cadet_handle, 2505 service->port = GNUNET_CADET_open_port (cadet_handle,
2506 &cadet_port, 2506 &cadet_port,
2507 &new_service_channel, 2507 &new_service_channel,
2508 service, 2508 service,
@@ -3579,7 +3579,7 @@ advertise_dns_exit ()
3579 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3579 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3580 "Opening CADET port %s for DNS exit service\n", 3580 "Opening CADET port %s for DNS exit service\n",
3581 GNUNET_h2s (&port)); 3581 GNUNET_h2s (&port));
3582 dns_port = GNUNET_CADET_open_porT (cadet_handle, 3582 dns_port = GNUNET_CADET_open_port (cadet_handle,
3583 &port, 3583 &port,
3584 &new_channel, 3584 &new_channel,
3585 NULL, 3585 NULL,
@@ -3829,7 +3829,7 @@ run (void *cls,
3829 NULL); 3829 NULL);
3830 stats = GNUNET_STATISTICS_create ("exit", 3830 stats = GNUNET_STATISTICS_create ("exit",
3831 cfg); 3831 cfg);
3832 cadet_handle = GNUNET_CADET_connecT (cfg); 3832 cadet_handle = GNUNET_CADET_connect (cfg);
3833 if (NULL == cadet_handle) 3833 if (NULL == cadet_handle)
3834 { 3834 {
3835 GNUNET_SCHEDULER_shutdown (); 3835 GNUNET_SCHEDULER_shutdown ();
@@ -3862,7 +3862,7 @@ run (void *cls,
3862 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3862 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3863 "Opening CADET port %s for IPv4 gateway service\n", 3863 "Opening CADET port %s for IPv4 gateway service\n",
3864 GNUNET_h2s (&port)); 3864 GNUNET_h2s (&port));
3865 cadet_port4 = GNUNET_CADET_open_porT (cadet_handle, 3865 cadet_port4 = GNUNET_CADET_open_port (cadet_handle,
3866 &port, 3866 &port,
3867 &new_channel, 3867 &new_channel,
3868 NULL, 3868 NULL,
@@ -3902,7 +3902,7 @@ run (void *cls,
3902 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3902 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3903 "Opening CADET port %s for IPv6 gateway service\n", 3903 "Opening CADET port %s for IPv6 gateway service\n",
3904 GNUNET_h2s (&port)); 3904 GNUNET_h2s (&port));
3905 cadet_port6 = GNUNET_CADET_open_porT (cadet_handle, 3905 cadet_port6 = GNUNET_CADET_open_port (cadet_handle,
3906 &port, 3906 &port,
3907 &new_channel, 3907 &new_channel,
3908 NULL, 3908 NULL,
diff --git a/src/fs/Makefile.am b/src/fs/Makefile.am
index 4374d45ea..33260a794 100644
--- a/src/fs/Makefile.am
+++ b/src/fs/Makefile.am
@@ -202,7 +202,7 @@ gnunet_service_fs_LDADD = \
202 $(top_builddir)/src/block/libgnunetblock.la \ 202 $(top_builddir)/src/block/libgnunetblock.la \
203 $(top_builddir)/src/datastore/libgnunetdatastore.la \ 203 $(top_builddir)/src/datastore/libgnunetdatastore.la \
204 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 204 $(top_builddir)/src/statistics/libgnunetstatistics.la \
205 $(top_builddir)/src/cadet/libgnunetcadetnew.la \ 205 $(top_builddir)/src/cadet/libgnunetcadet.la \
206 $(top_builddir)/src/ats/libgnunetats.la \ 206 $(top_builddir)/src/ats/libgnunetats.la \
207 $(top_builddir)/src/core/libgnunetcore.la \ 207 $(top_builddir)/src/core/libgnunetcore.la \
208 $(top_builddir)/src/util/libgnunetutil.la \ 208 $(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 55e0cbc24..c729ebe41 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)
487 GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER, 487 GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER,
488 strlen (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER), 488 strlen (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER),
489 &port); 489 &port);
490 mh->channel = GNUNET_CADET_channel_creatE (cadet_handle, 490 mh->channel = GNUNET_CADET_channel_create (cadet_handle,
491 mh, 491 mh,
492 &mh->target, 492 &mh->target,
493 &port, 493 &port,
@@ -627,7 +627,7 @@ get_cadet (const struct GNUNET_PeerIdentity *target)
627 GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER, 627 GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER,
628 strlen (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER), 628 strlen (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER),
629 &port); 629 &port);
630 mh->channel = GNUNET_CADET_channel_creatE (cadet_handle, 630 mh->channel = GNUNET_CADET_channel_create (cadet_handle,
631 mh, 631 mh,
632 &mh->target, 632 &mh->target,
633 &port, 633 &port,
diff --git a/src/fs/gnunet-service-fs_cadet_server.c b/src/fs/gnunet-service-fs_cadet_server.c
index adbce1154..8567e63a2 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 ()
499 "Initializing cadet FS server with a limit of %llu connections\n", 499 "Initializing cadet FS server with a limit of %llu connections\n",
500 sc_count_max); 500 sc_count_max);
501 cadet_map = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_YES); 501 cadet_map = GNUNET_CONTAINER_multipeermap_create (16, GNUNET_YES);
502 cadet_handle = GNUNET_CADET_connecT (GSF_cfg); 502 cadet_handle = GNUNET_CADET_connect (GSF_cfg);
503 GNUNET_assert (NULL != cadet_handle); 503 GNUNET_assert (NULL != cadet_handle);
504 GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER, 504 GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER,
505 strlen (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER), 505 strlen (GNUNET_APPLICATION_PORT_FS_BLOCK_TRANSFER),
506 &port); 506 &port);
507 cadet_port = GNUNET_CADET_open_porT (cadet_handle, 507 cadet_port = GNUNET_CADET_open_port (cadet_handle,
508 &port, 508 &port,
509 &connect_cb, 509 &connect_cb,
510 NULL, 510 NULL,
diff --git a/src/include/gnunet_cadet_service.h b/src/include/gnunet_cadet_service.h
index fd838df8d..f76f17a51 100644
--- a/src/include/gnunet_cadet_service.h
+++ b/src/include/gnunet_cadet_service.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2009-2014 GNUnet e.V. 3 Copyright (C) 2009-2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -49,7 +49,7 @@ extern "C"
49/** 49/**
50 * Version number of GNUnet-cadet API. 50 * Version number of GNUnet-cadet API.
51 */ 51 */
52#define GNUNET_CADET_VERSION 0x00000004 52#define GNUNET_CADET_VERSION 0x00000005
53 53
54 54
55/** 55/**
@@ -69,6 +69,33 @@ struct GNUNET_CADET_Port;
69 69
70 70
71/** 71/**
72 * Hash uniquely identifying a connection below a tunnel.
73 */
74struct GNUNET_CADET_ConnectionTunnelIdentifier
75{
76 struct GNUNET_ShortHashCode connection_of_tunnel;
77};
78
79
80/**
81 * Number identifying a CADET channel within a tunnel.
82 */
83struct GNUNET_CADET_ChannelTunnelNumber
84{
85 /**
86 * Which number does this channel have that uniquely identfies
87 * it within its tunnel, in network byte order.
88 *
89 * Given two peers, both may initiate channels over the same tunnel.
90 * The @e cn must be greater or equal to 0x80000000 (high-bit set)
91 * for tunnels initiated with the peer that has the larger peer
92 * identity as compared using #GNUNET_CRYPTO_cmp_peer_identity().
93 */
94 uint32_t cn GNUNET_PACKED;
95};
96
97
98/**
72 * Channel options. Second line indicates filed in the 99 * Channel options. Second line indicates filed in the
73 * CadetChannelInfo union carrying the answer. 100 * CadetChannelInfo union carrying the answer.
74 */ 101 */
@@ -108,118 +135,67 @@ enum GNUNET_CADET_ChannelOption
108 135
109 136
110/** 137/**
111 * Functions with this signature are called whenever a message is 138 * Method called whenever a peer connects to a port in MQ-based CADET.
112 * received.
113 *
114 * Each time the function must call #GNUNET_CADET_receive_done on the channel
115 * in order to receive the next message. This doesn't need to be immediate:
116 * can be delayed if some processing is done on the message.
117 * 139 *
118 * @param cls Closure (set from #GNUNET_CADET_connect). 140 * @param cls Closure from #GNUNET_CADET_open_port.
119 * @param channel Connection to the other end. 141 * @param channel New handle to the channel.
120 * @param channel_ctx Place to store local state associated with the channel. 142 * @param source Peer that started this channel.
121 * @param message The actual message. 143 * @return Closure for the incoming @a channel. It's given to:
122 * @return #GNUNET_OK to keep the channel open, 144 * - The #GNUNET_CADET_DisconnectEventHandler (given to
123 * #GNUNET_SYSERR to close it (signal serious error). 145 * #GNUNET_CADET_open_port) when the channel dies.
124 */ 146 * - Each the #GNUNET_MQ_MessageCallback handlers for each message
125typedef int 147 * received on the @a channel.
126(*GNUNET_CADET_MessageCallback) (void *cls,
127 struct GNUNET_CADET_Channel *channel,
128 void **channel_ctx,
129 const struct GNUNET_MessageHeader *message);
130
131
132/**
133 * Message handler. Each struct specifies how to handle on particular
134 * type of message received.
135 */ 148 */
136struct GNUNET_CADET_MessageHandler 149typedef void *
137{ 150(*GNUNET_CADET_ConnectEventHandler) (void *cls,
138 /** 151 struct GNUNET_CADET_Channel *channel,
139 * Function to call for messages of type @e type. 152 const struct GNUNET_PeerIdentity *source);
140 */
141 GNUNET_CADET_MessageCallback callback;
142
143 /**
144 * Type of the message this handler covers.
145 */
146 uint16_t type;
147
148 /**
149 * Expected size of messages of this type. Use 0 for variable-size.
150 * If non-zero, messages of the given type will be discarded if they
151 * do not have the right size.
152 */
153 uint16_t expected_size;
154};
155 153
156 154
157/** 155/**
158 * Method called whenever another peer has added us to a channel 156 * Function called whenever an MQ-channel is destroyed, even if the destruction
159 * the other peer initiated. 157 * was requested by #GNUNET_CADET_channel_destroy.
160 * Only called (once) upon reception of data with a message type which was 158 * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
161 * subscribed to in #GNUNET_CADET_connect.
162 *
163 * A call to #GNUNET_CADET_channel_destroy causes te channel to be ignored. In
164 * this case the handler MUST return NULL.
165 * 159 *
166 * @param cls closure 160 * It should clean up any associated state, including cancelling any pending
167 * @param channel new handle to the channel 161 * transmission on this channel.
168 * @param initiator peer that started the channel
169 * @param port Port this channel is for.
170 * @param options CadetOption flag field, with all active option bits set to 1.
171 * 162 *
172 * @return initial channel context for the channel 163 * @param cls Channel closure.
173 * (can be NULL -- that's not an error) 164 * @param channel Connection to the other end (henceforth invalid).
174 */ 165 */
175typedef void * 166typedef void
176(GNUNET_CADET_InboundChannelNotificationHandler) (void *cls, 167(*GNUNET_CADET_DisconnectEventHandler) (void *cls,
177 struct GNUNET_CADET_Channel *channel, 168 const struct GNUNET_CADET_Channel *channel);
178 const struct GNUNET_PeerIdentity *initiator,
179 const struct GNUNET_HashCode *port,
180 enum GNUNET_CADET_ChannelOption options);
181 169
182 170
183/** 171/**
184 * Function called whenever a channel is destroyed. Should clean up 172 * Function called whenever an MQ-channel's transmission window size changes.
185 * any associated state, including cancelling any pending transmission on this
186 * channel.
187 * 173 *
188 * It must NOT call #GNUNET_CADET_channel_destroy on the channel. 174 * The first callback in an outgoing channel will be with a non-zero value
175 * and will mean the channel is connected to the destination.
176 *
177 * For an incoming channel it will be called immediately after the
178 * #GNUNET_CADET_ConnectEventHandler, also with a non-zero value.
189 * 179 *
190 * @param cls closure (set from #GNUNET_CADET_connect) 180 * @param cls Channel closure.
191 * @param channel connection to the other end (henceforth invalid) 181 * @param channel Connection to the other end --- FIXME: drop?
192 * @param channel_ctx place where local state associated 182 * @param window_size New window size. If the is more messages than buffer size
193 * with the channel is stored 183 * this value will be negative. -- FIXME: make unsigned, we never call negative?
194 */ 184 */
195typedef void 185typedef void
196(GNUNET_CADET_ChannelEndHandler) (void *cls, 186(*GNUNET_CADET_WindowSizeEventHandler) (void *cls,
197 const struct GNUNET_CADET_Channel *channel, 187 const struct GNUNET_CADET_Channel *channel,
198 void *channel_ctx); 188 int window_size);
199 189
200 190
201/** 191/**
202 * Connect to the cadet service. 192 * Connect to the MQ-based cadet service.
203 * 193 *
204 * @param cfg Configuration to use. 194 * @param cfg Configuration to use.
205 * @param cls Closure for the various callbacks that follow (including 195 * @return Handle to the cadet service NULL on error.
206 * handlers in the handlers array).
207 * @param cleaner Function called when a channel is destroyed.
208 * It is called immediately if #GNUNET_CADET_channel_destroy
209 * is called on the channel.
210 * @param handlers Callbacks for messages we care about, NULL-terminated. Each
211 * one must call #GNUNET_CADET_receive_done on the channel to
212 * receive the next message. Messages of a type that is not
213 * in the handlers array are ignored if received.
214 *
215 * @return handle to the cadet service NULL on error
216 * (in this case, init is never called)
217 */ 196 */
218struct GNUNET_CADET_Handle * 197struct GNUNET_CADET_Handle *
219GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, 198GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg);
220 void *cls,
221 GNUNET_CADET_ChannelEndHandler cleaner,
222 const struct GNUNET_CADET_MessageHandler *handlers);
223 199
224 200
225/** 201/**
@@ -233,21 +209,29 @@ GNUNET_CADET_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
233void 209void
234GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle); 210GNUNET_CADET_disconnect (struct GNUNET_CADET_Handle *handle);
235 211
212
236/** 213/**
237 * Open a port to receive incomming channels. 214 * Open a port to receive incomming MQ-based channels.
238 * 215 *
239 * @param h CADET handle. 216 * @param h CADET handle.
240 * @param port Hash representing the port number. 217 * @param port Hash identifying the port.
241 * @param new_channel Function called when an channel is received. 218 * @param connects Function called when an incoming channel is connected.
242 * @param new_channel_cls Closure for @a new_channel. 219 * @param connects_cls Closure for the @a connects handler.
243 * 220 * @param window_changes Function called when the transmit window size changes.
221 * Can be NULL.
222 * @param disconnects Function called when a channel is disconnected.
223 * @param handlers Callbacks for messages we care about, NULL-terminated.
244 * @return Port handle. 224 * @return Port handle.
245 */ 225 */
246struct GNUNET_CADET_Port * 226struct GNUNET_CADET_Port *
247GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h, 227GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h,
248 const struct GNUNET_HashCode *port, 228 const struct GNUNET_HashCode *port,
249 GNUNET_CADET_InboundChannelNotificationHandler new_channel, 229 GNUNET_CADET_ConnectEventHandler connects,
250 void *new_channel_cls); 230 void *connects_cls,
231 GNUNET_CADET_WindowSizeEventHandler window_changes,
232 GNUNET_CADET_DisconnectEventHandler disconnects,
233 const struct GNUNET_MQ_MessageHandler *handlers);
234
251 235
252/** 236/**
253 * Close a port opened with @a GNUNET_CADET_open_port. 237 * Close a port opened with @a GNUNET_CADET_open_port.
@@ -258,27 +242,38 @@ GNUNET_CADET_open_port (struct GNUNET_CADET_Handle *h,
258void 242void
259GNUNET_CADET_close_port (struct GNUNET_CADET_Port *p); 243GNUNET_CADET_close_port (struct GNUNET_CADET_Port *p);
260 244
245
261/** 246/**
262 * Create a new channel towards a remote peer. 247 * Create a new channel towards a remote peer.
263 * 248 *
264 * If the destination port is not open by any peer or the destination peer 249 * If the destination port is not open by any peer or the destination peer
265 * does not accept the channel, #GNUNET_CADET_ChannelEndHandler will be called 250 * does not accept the channel, @a disconnects will be called
266 * for this channel. 251 * for this channel.
267 * 252 *
268 * @param h cadet handle 253 * @param h CADET handle.
269 * @param channel_ctx client's channel context to associate with the channel 254 * @param channel_cls Closure for the channel. It's given to:
270 * @param peer peer identity the channel should go to 255 * - The management handler @a window_changes.
271 * @param port Port hash (port number). 256 * - The disconnect handler @a disconnects
257 * - Each message type callback in @a handlers
258 * @param destination Peer identity the channel should go to.
259 * @param port Identification of the destination port.
272 * @param options CadetOption flag field, with all desired option bits set to 1. 260 * @param options CadetOption flag field, with all desired option bits set to 1.
273 * 261 * @param window_changes Function called when the transmit window size changes.
274 * @return handle to the channel 262 * Can be NULL if this data is of no interest.
263 * TODO Not yet implemented.
264 * @param disconnects Function called when the channel is disconnected.
265 * @param handlers Callbacks for messages we care about, NULL-terminated.
266 * @return Handle to the channel.
275 */ 267 */
276struct GNUNET_CADET_Channel * 268struct GNUNET_CADET_Channel *
277GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h, 269GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle *h,
278 void *channel_ctx, 270 void *channel_cls,
279 const struct GNUNET_PeerIdentity *peer, 271 const struct GNUNET_PeerIdentity *destination,
280 const struct GNUNET_HashCode *port, 272 const struct GNUNET_HashCode *port,
281 enum GNUNET_CADET_ChannelOption options); 273 enum GNUNET_CADET_ChannelOption options,
274 GNUNET_CADET_WindowSizeEventHandler window_changes,
275 GNUNET_CADET_DisconnectEventHandler disconnects,
276 const struct GNUNET_MQ_MessageHandler *handlers);
282 277
283 278
284/** 279/**
@@ -295,6 +290,52 @@ GNUNET_CADET_channel_destroy (struct GNUNET_CADET_Channel *channel);
295 290
296 291
297/** 292/**
293 * Obtain the message queue for a connected channel.
294 *
295 * @param channel The channel handle from which to get the MQ.
296 * @return The message queue of the channel.
297 */
298struct GNUNET_MQ_Handle *
299GNUNET_CADET_get_mq (const struct GNUNET_CADET_Channel *channel);
300
301
302/**
303 * Indicate readiness to receive the next message on a channel.
304 *
305 * Should only be called once per handler called.
306 *
307 * @param channel Channel that will be allowed to call another handler.
308 */
309void
310GNUNET_CADET_receive_done (struct GNUNET_CADET_Channel *channel);
311
312
313/******************************************************************************/
314/******************** MONITORING /DEBUG API *************************/
315/******************************************************************************/
316/* The following calls are not useful for normal CADET operation, but for */
317/* debug and monitoring of the cadet state. They can be safely ignored. */
318/* The API can change at any point without notice. */
319/* Please contact the developer if you consider any of this calls useful for */
320/* normal cadet applications. */
321/******************************************************************************/
322
323
324/**
325 * Transitional function to convert an unsigned int port to a hash value.
326 * WARNING: local static value returned, NOT reentrant!
327 * WARNING: do not use this function for new code!
328 *
329 * @param port Numerical port (unsigned int format).
330 *
331 * @return A GNUNET_HashCode usable for the new CADET API.
332 */
333const struct GNUNET_HashCode *
334GC_u2h (uint32_t port);
335
336
337
338/**
298 * Struct to retrieve info about a channel. 339 * Struct to retrieve info about a channel.
299 */ 340 */
300union GNUNET_CADET_ChannelInfo 341union GNUNET_CADET_ChannelInfo
@@ -327,76 +368,6 @@ GNUNET_CADET_channel_get_info (struct GNUNET_CADET_Channel *channel,
327 368
328 369
329/** 370/**
330 * Handle for a transmission request.
331 */
332struct GNUNET_CADET_TransmitHandle;
333
334
335/**
336 * Ask the cadet to call @a notify once it is ready to transmit the
337 * given number of bytes to the specified channel.
338 * Only one call can be active at any time, to issue another request,
339 * wait for the callback or cancel the current request.
340 *
341 * @param channel channel to use for transmission
342 * @param cork is corking allowed for this transmission?
343 * @param maxdelay how long can the message wait?
344 * @param notify_size how many bytes of buffer space does notify want?
345 * @param notify function to call when buffer space is available;
346 * will be called with NULL on timeout or if the overall queue
347 * for this peer is larger than queue_size and this is currently
348 * the message with the lowest priority
349 * @param notify_cls closure for @a notify
350 * @return non-NULL if the notify callback was queued,
351 * NULL if we can not even queue the request (insufficient
352 * memory); if NULL is returned, @a notify will NOT be called.
353 */
354struct GNUNET_CADET_TransmitHandle *
355GNUNET_CADET_notify_transmit_ready (struct GNUNET_CADET_Channel *channel,
356 int cork,
357 struct GNUNET_TIME_Relative maxdelay,
358 size_t notify_size,
359 GNUNET_CONNECTION_TransmitReadyNotify notify,
360 void *notify_cls);
361
362
363/**
364 * Cancel the specified transmission-ready notification.
365 *
366 * #DEPRECATED
367 * Since soon we will send immediately with mq (via request_data),
368 * there will be time or need to cancel a "pending" transmission.
369 *
370 * @param th handle that was returned by "notify_transmit_ready".
371 */
372void
373GNUNET_CADET_notify_transmit_ready_cancel (struct GNUNET_CADET_TransmitHandle *th);
374
375
376/**
377 * Indicate readiness to receive the next message on a channel.
378 *
379 * Should only be called once per handler called.
380 *
381 * @param channel Channel that will be allowed to call another handler.
382 */
383void
384GNUNET_CADET_receive_done (struct GNUNET_CADET_Channel *channel);
385
386
387
388/******************************************************************************/
389/******************** MONITORING /DEBUG API *************************/
390/******************************************************************************/
391/* The following calls are not useful for normal CADET operation, but for */
392/* debug and monitoring of the cadet state. They can be safely ignored. */
393/* The API can change at any point without notice. */
394/* Please contact the developer if you consider any of this calls useful for */
395/* normal cadet applications. */
396/******************************************************************************/
397
398
399/**
400 * Method called to retrieve information about a specific channel the cadet peer 371 * Method called to retrieve information about a specific channel the cadet peer
401 * is aware of, including all transit nodes. 372 * is aware of, including all transit nodes.
402 * 373 *
@@ -482,33 +453,6 @@ typedef void
482 453
483 454
484/** 455/**
485 * Hash uniquely identifying a connection below a tunnel.
486 */
487struct GNUNET_CADET_ConnectionTunnelIdentifier
488{
489 struct GNUNET_ShortHashCode connection_of_tunnel;
490};
491
492
493/**
494 * Number identifying a CADET channel within a tunnel.
495 */
496struct GNUNET_CADET_ChannelTunnelNumber
497{
498 /**
499 * Which number does this channel have that uniquely identfies
500 * it within its tunnel, in network byte order.
501 *
502 * Given two peers, both may initiate channels over the same tunnel.
503 * The @e cn must be greater or equal to 0x80000000 (high-bit set)
504 * for tunnels initiated with the peer that has the larger peer
505 * identity as compared using #GNUNET_CRYPTO_cmp_peer_identity().
506 */
507 uint32_t cn GNUNET_PACKED;
508};
509
510
511/**
512 * Method called to retrieve information about a specific tunnel the cadet peer 456 * Method called to retrieve information about a specific tunnel the cadet peer
513 * has established, o`r is trying to establish. 457 * has established, o`r is trying to establish.
514 * 458 *
@@ -667,169 +611,6 @@ GNUNET_CADET_get_tunnel (struct GNUNET_CADET_Handle *h,
667 void *callback_cls); 611 void *callback_cls);
668 612
669 613
670/**
671 * Create a message queue for a cadet channel.
672 * The message queue can only be used to transmit messages,
673 * not to receive them.
674 *
675 * @param channel the channel to create the message qeue for
676 * @return a message queue to messages over the channel
677 */
678struct GNUNET_MQ_Handle *
679GNUNET_CADET_mq_create (struct GNUNET_CADET_Channel *channel);
680
681
682/**
683 * Transitional function to convert an unsigned int port to a hash value.
684 * WARNING: local static value returned, NOT reentrant!
685 * WARNING: do not use this function for new code!
686 *
687 * @param port Numerical port (unsigned int format).
688 *
689 * @return A GNUNET_HashCode usable for the new CADET API.
690 */
691const struct GNUNET_HashCode *
692GC_u2h (uint32_t port);
693
694
695/******************************************************************************/
696/******************************* MQ-BASED API *********************************/
697/******************************************************************************/
698
699/**
700 * Method called whenever a peer connects to a port in MQ-based CADET.
701 *
702 * @param cls Closure from #GNUNET_CADET_open_porT.
703 * @param channel New handle to the channel.
704 * @param source Peer that started this channel.
705 * @return Closure for the incoming @a channel. It's given to:
706 * - The #GNUNET_CADET_DisconnectEventHandler (given to
707 * #GNUNET_CADET_open_porT) when the channel dies.
708 * - Each the #GNUNET_MQ_MessageCallback handlers for each message
709 * received on the @a channel.
710 */
711typedef void *
712(*GNUNET_CADET_ConnectEventHandler) (void *cls,
713 struct GNUNET_CADET_Channel *channel,
714 const struct GNUNET_PeerIdentity *source);
715
716
717/**
718 * Function called whenever an MQ-channel is destroyed, even if the destruction
719 * was requested by #GNUNET_CADET_channel_destroy.
720 * It must NOT call #GNUNET_CADET_channel_destroy on the channel.
721 *
722 * It should clean up any associated state, including cancelling any pending
723 * transmission on this channel.
724 *
725 * @param cls Channel closure.
726 * @param channel Connection to the other end (henceforth invalid).
727 */
728typedef void
729(*GNUNET_CADET_DisconnectEventHandler) (void *cls,
730 const struct GNUNET_CADET_Channel *channel);
731
732
733/**
734 * Function called whenever an MQ-channel's transmission window size changes.
735 *
736 * The first callback in an outgoing channel will be with a non-zero value
737 * and will mean the channel is connected to the destination.
738 *
739 * For an incoming channel it will be called immediately after the
740 * #GNUNET_CADET_ConnectEventHandler, also with a non-zero value.
741 *
742 * @param cls Channel closure.
743 * @param channel Connection to the other end --- FIXME: drop?
744 * @param window_size New window size. If the is more messages than buffer size
745 * this value will be negative. -- FIXME: make unsigned, we never call negative?
746 */
747typedef void
748(*GNUNET_CADET_WindowSizeEventHandler) (void *cls,
749 const struct GNUNET_CADET_Channel *channel,
750 int window_size);
751
752
753/**
754 * Connect to the MQ-based cadet service.
755 *
756 * @param cfg Configuration to use.
757 * @return Handle to the cadet service NULL on error.
758 */
759struct GNUNET_CADET_Handle *
760GNUNET_CADET_connecT (const struct GNUNET_CONFIGURATION_Handle *cfg);
761
762
763/**
764 * Open a port to receive incomming MQ-based channels.
765 *
766 * @param h CADET handle.
767 * @param port Hash identifying the port.
768 * @param connects Function called when an incoming channel is connected.
769 * @param connects_cls Closure for the @a connects handler.
770 * @param window_changes Function called when the transmit window size changes.
771 * Can be NULL.
772 * @param disconnects Function called when a channel is disconnected.
773 * @param handlers Callbacks for messages we care about, NULL-terminated.
774 * @return Port handle.
775 */
776struct GNUNET_CADET_Port *
777GNUNET_CADET_open_porT (struct GNUNET_CADET_Handle *h,
778 const struct GNUNET_HashCode *port,
779 GNUNET_CADET_ConnectEventHandler connects,
780 void *connects_cls,
781 GNUNET_CADET_WindowSizeEventHandler window_changes,
782 GNUNET_CADET_DisconnectEventHandler disconnects,
783 const struct GNUNET_MQ_MessageHandler *handlers);
784
785/**
786 * Create a new channel towards a remote peer.
787 *
788 * If the destination port is not open by any peer or the destination peer
789 * does not accept the channel, #GNUNET_CADET_ChannelEndHandler will be called
790 * for this channel.
791 *
792 * @param h CADET handle.
793 * @param channel_cls Closure for the channel. It's given to:
794 * - The management handler @a window_changes.
795 * - The disconnect handler @a disconnects
796 * - Each message type callback in @a handlers
797 * @param destination Peer identity the channel should go to.
798 * @param port Identification of the destination port.
799 * @param options CadetOption flag field, with all desired option bits set to 1.
800 * @param window_changes Function called when the transmit window size changes.
801 * Can be NULL if this data is of no interest.
802 * TODO Not yet implemented.
803 * @param disconnects Function called when the channel is disconnected.
804 * @param handlers Callbacks for messages we care about, NULL-terminated.
805 * @return Handle to the channel.
806 */
807struct GNUNET_CADET_Channel *
808GNUNET_CADET_channel_creatE (struct GNUNET_CADET_Handle *h,
809 void *channel_cls,
810 const struct GNUNET_PeerIdentity *destination,
811 const struct GNUNET_HashCode *port,
812 enum GNUNET_CADET_ChannelOption options,
813 GNUNET_CADET_WindowSizeEventHandler window_changes,
814 GNUNET_CADET_DisconnectEventHandler disconnects,
815 const struct GNUNET_MQ_MessageHandler *handlers);
816
817
818/**
819 * Obtain the message queue for a connected channel.
820 *
821 * @param channel The channel handle from which to get the MQ.
822 * @return The message queue of the channel.
823 */
824struct GNUNET_MQ_Handle *
825GNUNET_CADET_get_mq (const struct GNUNET_CADET_Channel *channel);
826
827
828/******************************************************************************/
829/******************************* MQ-BASED API *********************************/
830/******************************************************************************/
831
832
833 614
834#if 0 /* keep Emacsens' auto-indent happy */ 615#if 0 /* keep Emacsens' auto-indent happy */
835{ 616{
diff --git a/src/include/gnunet_datastore_service.h b/src/include/gnunet_datastore_service.h
index f594d8fa6..233598667 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,
201 201
202 202
203/** 203/**
204 * Update a value in the datastore.
205 *
206 * @param h handle to the datastore
207 * @param uid identifier for the value
208 * @param priority how much to increase the priority of the value
209 * @param expiration new expiration value should be MAX of existing and this argument
210 * @param queue_priority ranking of this request in the priority queue
211 * @param max_queue_size at what queue size should this request be dropped
212 * (if other requests of higher priority are in the queue)
213 * @param cont continuation to call when done
214 * @param cont_cls closure for @a cont
215 * @return NULL if the entry was not queued, otherwise a handle that can be used to
216 * cancel; note that even if NULL is returned, the callback will be invoked
217 * (or rather, will already have been invoked)
218 */
219struct GNUNET_DATASTORE_QueueEntry *
220GNUNET_DATASTORE_update (struct GNUNET_DATASTORE_Handle *h,
221 uint64_t uid,
222 uint32_t priority,
223 struct GNUNET_TIME_Absolute expiration,
224 unsigned int queue_priority,
225 unsigned int max_queue_size,
226 GNUNET_DATASTORE_ContinuationWithStatus cont,
227 void *cont_cls);
228
229
230/**
231 * Explicitly remove some content from the database. @a cont will be 204 * Explicitly remove some content from the database. @a cont will be
232 * called with status #GNUNET_OK if content was removed, #GNUNET_NO if 205 * called with status #GNUNET_OK if content was removed, #GNUNET_NO if
233 * no matching entry was found and #GNUNET_SYSERR on all other types 206 * 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 8d3356cbc..1be582650 100644
--- a/src/integration-tests/confs/test_defaults.conf
+++ b/src/integration-tests/confs/test_defaults.conf
@@ -1,5 +1,5 @@
1@INLINE@ ../../contrib/no_forcestart.conf 1@INLINE@ ../../../contrib/no_forcestart.conf
2@INLINE@ ../../contrib/no_autostart_above_core.conf 2@INLINE@ ../../../contrib/no_autostart_above_core.conf
3 3
4[fs] 4[fs]
5FORCESTART = YES 5FORCESTART = YES
diff --git a/src/multicast/Makefile.am b/src/multicast/Makefile.am
index f599cf66b..2a00a7a02 100644
--- a/src/multicast/Makefile.am
+++ b/src/multicast/Makefile.am
@@ -46,7 +46,7 @@ gnunet_service_multicast_SOURCES = \
46 gnunet-service-multicast.c 46 gnunet-service-multicast.c
47gnunet_service_multicast_LDADD = \ 47gnunet_service_multicast_LDADD = \
48 $(top_builddir)/src/util/libgnunetutil.la \ 48 $(top_builddir)/src/util/libgnunetutil.la \
49 $(top_builddir)/src/cadet/libgnunetcadetnew.la \ 49 $(top_builddir)/src/cadet/libgnunetcadet.la \
50 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 50 $(top_builddir)/src/statistics/libgnunetstatistics.la \
51 $(GN_LIBINTL) 51 $(GN_LIBINTL)
52 52
diff --git a/src/multicast/gnunet-service-multicast.c b/src/multicast/gnunet-service-multicast.c
index b068f1308..cf39d3b22 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)
1299 GNUNET_MQ_handler_end () 1299 GNUNET_MQ_handler_end ()
1300 }; 1300 };
1301 1301
1302 chn->channel = GNUNET_CADET_channel_creatE (cadet, chn, &chn->peer, 1302 chn->channel = GNUNET_CADET_channel_create (cadet, chn, &chn->peer,
1303 &grp->cadet_port_hash, 1303 &grp->cadet_port_hash,
1304 GNUNET_CADET_OPTION_RELIABLE, 1304 GNUNET_CADET_OPTION_RELIABLE,
1305 cadet_notify_window_change, 1305 cadet_notify_window_change,
@@ -1389,7 +1389,7 @@ handle_client_origin_start (void *cls,
1389 }; 1389 };
1390 1390
1391 1391
1392 orig->cadet_port = GNUNET_CADET_open_porT (cadet, 1392 orig->cadet_port = GNUNET_CADET_open_port (cadet,
1393 &grp->cadet_port_hash, 1393 &grp->cadet_port_hash,
1394 cadet_notify_connect, 1394 cadet_notify_connect,
1395 NULL, 1395 NULL,
@@ -2082,7 +2082,7 @@ run (void *cls,
2082 replay_req_cadet = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); 2082 replay_req_cadet = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
2083 replay_req_client = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO); 2083 replay_req_client = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_NO);
2084 2084
2085 cadet = GNUNET_CADET_connecT (cfg); 2085 cadet = GNUNET_CADET_connect (cfg);
2086 2086
2087 GNUNET_assert (NULL != cadet); 2087 GNUNET_assert (NULL != cadet);
2088 2088
diff --git a/src/pt/Makefile.am b/src/pt/Makefile.am
index 7ea8257d5..e36630ae4 100644
--- a/src/pt/Makefile.am
+++ b/src/pt/Makefile.am
@@ -25,7 +25,7 @@ gnunet_daemon_pt_SOURCES = \
25 gnunet-daemon-pt.c 25 gnunet-daemon-pt.c
26gnunet_daemon_pt_LDADD = \ 26gnunet_daemon_pt_LDADD = \
27 $(top_builddir)/src/vpn/libgnunetvpn.la \ 27 $(top_builddir)/src/vpn/libgnunetvpn.la \
28 $(top_builddir)/src/cadet/libgnunetcadetnew.la \ 28 $(top_builddir)/src/cadet/libgnunetcadet.la \
29 $(top_builddir)/src/dht/libgnunetdht.la \ 29 $(top_builddir)/src/dht/libgnunetdht.la \
30 $(top_builddir)/src/dns/libgnunetdns.la \ 30 $(top_builddir)/src/dns/libgnunetdns.la \
31 $(top_builddir)/src/dns/libgnunetdnsparser.la \ 31 $(top_builddir)/src/dns/libgnunetdnsparser.la \
diff --git a/src/pt/gnunet-daemon-pt.c b/src/pt/gnunet-daemon-pt.c
index 9bd1fb16b..295082c0e 100644
--- a/src/pt/gnunet-daemon-pt.c
+++ b/src/pt/gnunet-daemon-pt.c
@@ -1084,7 +1084,7 @@ try_open_exit ()
1084 1084
1085 /* move to the head of the DLL */ 1085 /* move to the head of the DLL */
1086 pos->cadet_channel 1086 pos->cadet_channel
1087 = GNUNET_CADET_channel_creatE (cadet_handle, 1087 = GNUNET_CADET_channel_create (cadet_handle,
1088 pos, 1088 pos,
1089 &pos->peer, 1089 &pos->peer,
1090 &port, 1090 &port,
@@ -1246,7 +1246,7 @@ run (void *cls, char *const *args GNUNET_UNUSED,
1246 GNUNET_SCHEDULER_shutdown (); 1246 GNUNET_SCHEDULER_shutdown ();
1247 return; 1247 return;
1248 } 1248 }
1249 cadet_handle = GNUNET_CADET_connecT (cfg); 1249 cadet_handle = GNUNET_CADET_connect (cfg);
1250 if (NULL == cadet_handle) 1250 if (NULL == cadet_handle)
1251 { 1251 {
1252 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1252 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
diff --git a/src/rps/Makefile.am b/src/rps/Makefile.am
index de7f853c1..e6c8cd929 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
100TESTS = $(check_PROGRAMS) 100TESTS = $(check_PROGRAMS)
101endif 101endif
102 102
103test_service_rps_view_SOURCES = gnunet-service-rps_view.h gnunet-service-rps_view.c \ 103test_service_rps_view_SOURCES = \
104 test_service_rps_view.c 104 gnunet-service-rps_view.h gnunet-service-rps_view.c \
105 test_service_rps_view.c
105test_service_rps_view_LDADD = $(top_builddir)/src/util/libgnunetutil.la 106test_service_rps_view_LDADD = $(top_builddir)/src/util/libgnunetutil.la
106 107
107test_service_rps_peers_SOURCES = gnunet-service-rps_peers.h gnunet-service-rps_peers.c \ 108test_service_rps_peers_SOURCES = \
108 test_service_rps_peers.c 109 gnunet-service-rps_peers.h gnunet-service-rps_peers.c \
109test_service_rps_peers_LDADD = $(top_builddir)/src/util/libgnunetutil.la \ 110 test_service_rps_peers.c
110 $(top_builddir)/src/cadet/libgnunetcadet.la 111test_service_rps_peers_LDADD = \
111 112 $(top_builddir)/src/util/libgnunetutil.la \
112test_service_rps_custommap_SOURCES = gnunet-service-rps_custommap.h gnunet-service-rps_custommap.c \ 113 $(top_builddir)/src/cadet/libgnunetcadet.la
113 test_service_rps_custommap.c 114
114test_service_rps_custommap_LDADD = $(top_builddir)/src/util/libgnunetutil.la 115test_service_rps_custommap_SOURCES = \
115 116 gnunet-service-rps_custommap.h gnunet-service-rps_custommap.c \
116test_service_rps_sampler_elem_SOURCES = gnunet-service-rps_sampler_elem.h gnunet-service-rps_sampler_elem.c \ 117 test_service_rps_custommap.c
117 rps-test_util.h rps-test_util.c \ 118test_service_rps_custommap_LDADD = \
118 test_service_rps_sampler_elem.c 119 $(top_builddir)/src/util/libgnunetutil.la
120
121test_service_rps_sampler_elem_SOURCES = \
122 gnunet-service-rps_sampler_elem.h gnunet-service-rps_sampler_elem.c \
123 rps-test_util.h rps-test_util.c \
124 test_service_rps_sampler_elem.c
119test_service_rps_sampler_elem_LDADD = $(top_builddir)/src/util/libgnunetutil.la 125test_service_rps_sampler_elem_LDADD = $(top_builddir)/src/util/libgnunetutil.la
120 126
121test_rps_malicious_1_SOURCES = $(rps_test_src) 127test_rps_malicious_1_SOURCES = $(rps_test_src)
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c
index adcfe7d02..4a2f96123 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;
217static struct GNUNET_CADET_Handle *cadet_handle; 217static struct GNUNET_CADET_Handle *cadet_handle;
218 218
219/** 219/**
220 * @brief Port to communicate to other peers.
221 */
222static struct GNUNET_CADET_Port *cadet_port;
223
224/**
220 * Handler to PEERINFO. 225 * Handler to PEERINFO.
221 */ 226 */
222static struct GNUNET_PEERINFO_Handle *peerinfo_handle; 227static struct GNUNET_PEERINFO_Handle *peerinfo_handle;
@@ -838,14 +843,10 @@ clean_peer (const struct GNUNET_PeerIdentity *peer)
838 */ 843 */
839static void 844static void
840cleanup_destroyed_channel (void *cls, 845cleanup_destroyed_channel (void *cls,
841 const struct GNUNET_CADET_Channel *channel, 846 const struct GNUNET_CADET_Channel *channel)
842 void *channel_ctx)
843{ 847{
844 struct GNUNET_PeerIdentity *peer; 848 struct GNUNET_PeerIdentity *peer = cls;
845 849 uint32_t *channel_flag;
846 peer = (struct GNUNET_PeerIdentity *) GNUNET_CADET_channel_get_info (
847 (struct GNUNET_CADET_Channel *) channel, GNUNET_CADET_OPTION_PEER);
848 // FIXME wait for cadet to change this function
849 850
850 if (GNUNET_NO == Peers_check_peer_known (peer)) 851 if (GNUNET_NO == Peers_check_peer_known (peer))
851 { /* We don't know a context to that peer */ 852 { /* We don't know a context to that peer */
@@ -858,7 +859,7 @@ cleanup_destroyed_channel (void *cls,
858 if (GNUNET_YES == Peers_check_peer_flag (peer, Peers_TO_DESTROY)) 859 if (GNUNET_YES == Peers_check_peer_flag (peer, Peers_TO_DESTROY))
859 { /* We are in the middle of removing that peer from our knowledge. In this 860 { /* We are in the middle of removing that peer from our knowledge. In this
860 case simply make sure that the channels are cleaned. */ 861 case simply make sure that the channels are cleaned. */
861 Peers_cleanup_destroyed_channel (cls, channel, channel_ctx); 862 Peers_cleanup_destroyed_channel (cls, channel);
862 to_file (file_name_view_log, 863 to_file (file_name_view_log,
863 "-%s\t(cleanup channel, ourself)", 864 "-%s\t(cleanup channel, ourself)",
864 GNUNET_i2s_full (peer)); 865 GNUNET_i2s_full (peer));
@@ -872,16 +873,17 @@ cleanup_destroyed_channel (void *cls,
872 * - ourselves -> cleaning send channel -> clean context 873 * - ourselves -> cleaning send channel -> clean context
873 * - other peer -> peer probably went down -> remove 874 * - other peer -> peer probably went down -> remove
874 */ 875 */
875 if (GNUNET_YES == Peers_check_channel_flag (channel_ctx, Peers_CHANNEL_CLEAN)) 876 channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_SENDING);
877 if (GNUNET_YES == Peers_check_channel_flag (channel_flag, Peers_CHANNEL_CLEAN))
876 { /* We are about to clean the sending channel. Clean the respective 878 { /* We are about to clean the sending channel. Clean the respective
877 * context */ 879 * context */
878 Peers_cleanup_destroyed_channel (cls, channel, channel_ctx); 880 Peers_cleanup_destroyed_channel (cls, channel);
879 return; 881 return;
880 } 882 }
881 else 883 else
882 { /* Other peer destroyed our sending channel that he is supposed to keep 884 { /* Other peer destroyed our sending channel that he is supposed to keep
883 * open. It probably went down. Remove it from our knowledge. */ 885 * open. It probably went down. Remove it from our knowledge. */
884 Peers_cleanup_destroyed_channel (cls, channel, channel_ctx); 886 Peers_cleanup_destroyed_channel (cls, channel);
885 remove_peer (peer); 887 remove_peer (peer);
886 return; 888 return;
887 } 889 }
@@ -893,17 +895,18 @@ cleanup_destroyed_channel (void *cls,
893 * - ourselves -> peer tried to establish channel twice -> clean context 895 * - ourselves -> peer tried to establish channel twice -> clean context
894 * - other peer -> peer doesn't want to send us data -> clean 896 * - other peer -> peer doesn't want to send us data -> clean
895 */ 897 */
898 channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_RECEIVING);
896 if (GNUNET_YES == 899 if (GNUNET_YES ==
897 Peers_check_channel_flag (channel_ctx, Peers_CHANNEL_ESTABLISHED_TWICE)) 900 Peers_check_channel_flag (channel_flag, Peers_CHANNEL_ESTABLISHED_TWICE))
898 { /* Other peer tried to establish a channel to us twice. We do not accept 901 { /* Other peer tried to establish a channel to us twice. We do not accept
899 * that. Clean the context. */ 902 * that. Clean the context. */
900 Peers_cleanup_destroyed_channel (cls, channel, channel_ctx); 903 Peers_cleanup_destroyed_channel (cls, channel);
901 return; 904 return;
902 } 905 }
903 else 906 else
904 { /* Other peer doesn't want to send us data anymore. We are free to clean 907 { /* Other peer doesn't want to send us data anymore. We are free to clean
905 * it. */ 908 * it. */
906 Peers_cleanup_destroyed_channel (cls, channel, channel_ctx); 909 Peers_cleanup_destroyed_channel (cls, channel);
907 clean_peer (peer); 910 clean_peer (peer);
908 return; 911 return;
909 } 912 }
@@ -1048,7 +1051,6 @@ client_respond (void *cls,
1048 * Handle RPS request from the client. 1051 * Handle RPS request from the client.
1049 * 1052 *
1050 * @param cls closure 1053 * @param cls closure
1051 * @param client identification of the client
1052 * @param message the actual message 1054 * @param message the actual message
1053 */ 1055 */
1054static void 1056static void
@@ -1100,12 +1102,11 @@ handle_client_request (void *cls,
1100 * @brief Handle a message that requests the cancellation of a request 1102 * @brief Handle a message that requests the cancellation of a request
1101 * 1103 *
1102 * @param cls unused 1104 * @param cls unused
1103 * @param client the client that requests the cancellation
1104 * @param message the message containing the id of the request 1105 * @param message the message containing the id of the request
1105 */ 1106 */
1106static void 1107static void
1107handle_client_request_cancel (void *cls, 1108handle_client_request_cancel (void *cls,
1108 const struct GNUNET_RPS_CS_RequestCancelMessage *msg) 1109 const struct GNUNET_RPS_CS_RequestCancelMessage *msg)
1109{ 1110{
1110 struct ClientContext *cli_ctx = cls; 1111 struct ClientContext *cli_ctx = cls;
1111 struct ReplyCls *rep_cls; 1112 struct ReplyCls *rep_cls;
@@ -1157,7 +1158,6 @@ check_client_seed (void *cls, const struct GNUNET_RPS_CS_SeedMessage *msg)
1157 * Handle seed from the client. 1158 * Handle seed from the client.
1158 * 1159 *
1159 * @param cls closure 1160 * @param cls closure
1160 * @param client identification of the client
1161 * @param message the actual message 1161 * @param message the actual message
1162 */ 1162 */
1163static void 1163static void
@@ -1172,7 +1172,7 @@ handle_client_seed (void *cls,
1172 num_peers = ntohl (msg->num_peers); 1172 num_peers = ntohl (msg->num_peers);
1173 peers = (struct GNUNET_PeerIdentity *) &msg[1]; 1173 peers = (struct GNUNET_PeerIdentity *) &msg[1];
1174 //peers = GNUNET_new_array (num_peers, struct GNUNET_PeerIdentity); 1174 //peers = GNUNET_new_array (num_peers, struct GNUNET_PeerIdentity);
1175 //GNUNET_memcpy (peers, &in_msg[1], num_peers * sizeof (struct GNUNET_PeerIdentity)); 1175 //GNUNET_memcpy (peers, &msg[1], num_peers * sizeof (struct GNUNET_PeerIdentity));
1176 1176
1177 LOG (GNUNET_ERROR_TYPE_DEBUG, 1177 LOG (GNUNET_ERROR_TYPE_DEBUG,
1178 "Client seeded peers:\n"); 1178 "Client seeded peers:\n");
@@ -1200,18 +1200,15 @@ handle_client_seed (void *cls,
1200 * the channel is blocked for all other communication. 1200 * the channel is blocked for all other communication.
1201 * 1201 *
1202 * @param cls Closure 1202 * @param cls Closure
1203 * @param channel The channel the CHECK was received over
1204 * @param channel_ctx The context associated with this channel
1205 * @param msg The message header 1203 * @param msg The message header
1206 */ 1204 */
1207static int 1205static void
1208handle_peer_check (void *cls, 1206handle_peer_check (void *cls,
1209 struct GNUNET_CADET_Channel *channel, 1207 const struct GNUNET_MessageHeader *msg)
1210 void **channel_ctx,
1211 const struct GNUNET_MessageHeader *msg)
1212{ 1208{
1213 GNUNET_CADET_receive_done (channel); 1209 const struct GNUNET_PeerIdentity *peer = cls;
1214 return GNUNET_OK; 1210
1211 GNUNET_CADET_receive_done (Peers_get_recv_channel (peer));
1215} 1212}
1216 1213
1217/** 1214/**
@@ -1221,24 +1218,16 @@ handle_peer_check (void *cls,
1221 * in the temporary list for pushed PeerIDs. 1218 * in the temporary list for pushed PeerIDs.
1222 * 1219 *
1223 * @param cls Closure 1220 * @param cls Closure
1224 * @param channel The channel the PUSH was received over
1225 * @param channel_ctx The context associated with this channel
1226 * @param msg The message header 1221 * @param msg The message header
1227 */ 1222 */
1228static int 1223static void
1229handle_peer_push (void *cls, 1224handle_peer_push (void *cls,
1230 struct GNUNET_CADET_Channel *channel, 1225 const struct GNUNET_MessageHeader *msg)
1231 void **channel_ctx,
1232 const struct GNUNET_MessageHeader *msg)
1233{ 1226{
1234 const struct GNUNET_PeerIdentity *peer; 1227 const struct GNUNET_PeerIdentity *peer = cls;
1235 1228
1236 // (check the proof of work (?)) 1229 // (check the proof of work (?))
1237 1230
1238 peer = (const struct GNUNET_PeerIdentity *)
1239 GNUNET_CADET_channel_get_info (channel, GNUNET_CADET_OPTION_PEER);
1240 // FIXME wait for cadet to change this function
1241
1242 LOG (GNUNET_ERROR_TYPE_DEBUG, 1231 LOG (GNUNET_ERROR_TYPE_DEBUG,
1243 "Received PUSH (%s)\n", 1232 "Received PUSH (%s)\n",
1244 GNUNET_i2s (peer)); 1233 GNUNET_i2s (peer));
@@ -1261,23 +1250,20 @@ handle_peer_push (void *cls,
1261 tmp_att_peer); 1250 tmp_att_peer);
1262 add_peer_array_to_set (peer, 1, att_peer_set); 1251 add_peer_array_to_set (peer, 1, att_peer_set);
1263 } 1252 }
1264 GNUNET_CADET_receive_done (channel); 1253 GNUNET_CADET_receive_done (Peers_get_recv_channel (peer));
1265 return GNUNET_OK;
1266 } 1254 }
1267 1255
1268 1256
1269 else if (2 == mal_type) 1257 else if (2 == mal_type)
1270 { /* We attack one single well-known peer - simply ignore */ 1258 { /* We attack one single well-known peer - simply ignore */
1271 GNUNET_CADET_receive_done (channel); 1259 GNUNET_CADET_receive_done (Peers_get_recv_channel (peer));
1272 return GNUNET_OK;
1273 } 1260 }
1274 #endif /* ENABLE_MALICIOUS */ 1261 #endif /* ENABLE_MALICIOUS */
1275 1262
1276 /* Add the sending peer to the push_map */ 1263 /* Add the sending peer to the push_map */
1277 CustomPeerMap_put (push_map, peer); 1264 CustomPeerMap_put (push_map, peer);
1278 1265
1279 GNUNET_CADET_receive_done (channel); 1266 GNUNET_CADET_receive_done (Peers_get_recv_channel (peer));
1280 return GNUNET_OK;
1281} 1267}
1282 1268
1283 1269
@@ -1287,24 +1273,15 @@ handle_peer_push (void *cls,
1287 * Reply with the view of PeerIDs. 1273 * Reply with the view of PeerIDs.
1288 * 1274 *
1289 * @param cls Closure 1275 * @param cls Closure
1290 * @param channel The channel the PULL REQUEST was received over
1291 * @param channel_ctx The context associated with this channel
1292 * @param msg The message header 1276 * @param msg The message header
1293 */ 1277 */
1294static int 1278static void
1295handle_peer_pull_request (void *cls, 1279handle_peer_pull_request (void *cls,
1296 struct GNUNET_CADET_Channel *channel, 1280 const struct GNUNET_MessageHeader *msg)
1297 void **channel_ctx,
1298 const struct GNUNET_MessageHeader *msg)
1299{ 1281{
1300 struct GNUNET_PeerIdentity *peer; 1282 struct GNUNET_PeerIdentity *peer = cls;
1301 const struct GNUNET_PeerIdentity *view_array; 1283 const struct GNUNET_PeerIdentity *view_array;
1302 1284
1303 peer = (struct GNUNET_PeerIdentity *)
1304 GNUNET_CADET_channel_get_info (channel,
1305 GNUNET_CADET_OPTION_PEER);
1306 // FIXME wait for cadet to change this function
1307
1308 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REQUEST (%s)\n", GNUNET_i2s (peer)); 1285 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REQUEST (%s)\n", GNUNET_i2s (peer));
1309 1286
1310 #ifdef ENABLE_MALICIOUS 1287 #ifdef ENABLE_MALICIOUS
@@ -1312,8 +1289,7 @@ handle_peer_pull_request (void *cls,
1312 || 3 == mal_type) 1289 || 3 == mal_type)
1313 { /* Try to maximise representation */ 1290 { /* Try to maximise representation */
1314 send_pull_reply (peer, mal_peers, num_mal_peers); 1291 send_pull_reply (peer, mal_peers, num_mal_peers);
1315 GNUNET_CADET_receive_done (channel); 1292 GNUNET_CADET_receive_done (Peers_get_recv_channel (peer));
1316 return GNUNET_OK;
1317 } 1293 }
1318 1294
1319 else if (2 == mal_type) 1295 else if (2 == mal_type)
@@ -1322,101 +1298,93 @@ handle_peer_pull_request (void *cls,
1322 { 1298 {
1323 send_pull_reply (peer, mal_peers, num_mal_peers); 1299 send_pull_reply (peer, mal_peers, num_mal_peers);
1324 } 1300 }
1325 GNUNET_CADET_receive_done (channel); 1301 GNUNET_CADET_receive_done (Peers_get_recv_channel (peer));
1326 return GNUNET_OK;
1327 } 1302 }
1328 #endif /* ENABLE_MALICIOUS */ 1303 #endif /* ENABLE_MALICIOUS */
1329 1304
1330 view_array = View_get_as_array (); 1305 view_array = View_get_as_array ();
1331
1332 send_pull_reply (peer, view_array, View_size ()); 1306 send_pull_reply (peer, view_array, View_size ());
1333 1307
1334 GNUNET_CADET_receive_done (channel); 1308 GNUNET_CADET_receive_done (Peers_get_recv_channel (peer));
1335 return GNUNET_OK;
1336} 1309}
1337 1310
1338 1311
1339/** 1312/**
1340 * Handle PULL REPLY message from another peer.
1341 *
1342 * Check whether we sent a corresponding request and 1313 * Check whether we sent a corresponding request and
1343 * whether this reply is the first one. 1314 * whether this reply is the first one.
1344 * 1315 *
1345 * @param cls Closure 1316 * @param cls Closure
1346 * @param channel The channel the PUSH was received over
1347 * @param channel_ctx The context associated with this channel
1348 * @param msg The message header 1317 * @param msg The message header
1349 */ 1318 */
1350static int 1319static int
1351handle_peer_pull_reply (void *cls, 1320check_peer_pull_reply (void *cls,
1352 struct GNUNET_CADET_Channel *channel, 1321 const struct GNUNET_RPS_P2P_PullReplyMessage *msg)
1353 void **channel_ctx,
1354 const struct GNUNET_MessageHeader *msg)
1355{ 1322{
1356 struct GNUNET_RPS_P2P_PullReplyMessage *in_msg; 1323 struct GNUNET_PeerIdentity *sender = cls;
1357 struct GNUNET_PeerIdentity *peers;
1358 struct GNUNET_PeerIdentity *sender;
1359 uint32_t i;
1360#ifdef ENABLE_MALICIOUS
1361 struct AttackedPeer *tmp_att_peer;
1362#endif /* ENABLE_MALICIOUS */
1363 1324
1364 /* Check for protocol violation */ 1325 if (sizeof (struct GNUNET_RPS_P2P_PullReplyMessage) > ntohs (msg->header.size))
1365 if (sizeof (struct GNUNET_RPS_P2P_PullReplyMessage) > ntohs (msg->size))
1366 { 1326 {
1367 GNUNET_break_op (0); 1327 GNUNET_break_op (0);
1368 GNUNET_CADET_receive_done (channel);
1369 return GNUNET_SYSERR; 1328 return GNUNET_SYSERR;
1370 } 1329 }
1371 1330
1372 in_msg = (struct GNUNET_RPS_P2P_PullReplyMessage *) msg; 1331 if ((ntohs (msg->header.size) - sizeof (struct GNUNET_RPS_P2P_PullReplyMessage)) /
1373 if ((ntohs (msg->size) - sizeof (struct GNUNET_RPS_P2P_PullReplyMessage)) / 1332 sizeof (struct GNUNET_PeerIdentity) != ntohl (msg->num_peers))
1374 sizeof (struct GNUNET_PeerIdentity) != ntohl (in_msg->num_peers))
1375 { 1333 {
1376 LOG (GNUNET_ERROR_TYPE_ERROR, 1334 LOG (GNUNET_ERROR_TYPE_ERROR,
1377 "message says it sends %" PRIu32 " peers, have space for %lu peers\n", 1335 "message says it sends %" PRIu32 " peers, have space for %lu peers\n",
1378 ntohl (in_msg->num_peers), 1336 ntohl (msg->num_peers),
1379 (ntohs (msg->size) - sizeof (struct GNUNET_RPS_P2P_PullReplyMessage)) / 1337 (ntohs (msg->header.size) - sizeof (struct GNUNET_RPS_P2P_PullReplyMessage)) /
1380 sizeof (struct GNUNET_PeerIdentity)); 1338 sizeof (struct GNUNET_PeerIdentity));
1381 GNUNET_break_op (0); 1339 GNUNET_break_op (0);
1382 GNUNET_CADET_receive_done (channel);
1383 return GNUNET_SYSERR; 1340 return GNUNET_SYSERR;
1384 } 1341 }
1385 1342
1386 // Guess simply casting isn't the nicest way...
1387 // FIXME wait for cadet to change this function
1388 sender = (struct GNUNET_PeerIdentity *)
1389 GNUNET_CADET_channel_get_info (channel, GNUNET_CADET_OPTION_PEER);
1390
1391 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REPLY (%s)\n", GNUNET_i2s (sender));
1392
1393 if (GNUNET_YES != Peers_check_peer_flag (sender, Peers_PULL_REPLY_PENDING)) 1343 if (GNUNET_YES != Peers_check_peer_flag (sender, Peers_PULL_REPLY_PENDING))
1394 { 1344 {
1395 LOG (GNUNET_ERROR_TYPE_WARNING, 1345 LOG (GNUNET_ERROR_TYPE_WARNING,
1396 "Received a pull reply from a peer we didn't request one from!\n"); 1346 "Received a pull reply from a peer we didn't request one from!\n");
1397 GNUNET_CADET_receive_done (channel);
1398 GNUNET_break_op (0); 1347 GNUNET_break_op (0);
1399 return GNUNET_OK; 1348 return GNUNET_SYSERR;
1400 } 1349 }
1350 return GNUNET_OK;
1351}
1352
1353/**
1354 * Handle PULL REPLY message from another peer.
1355 *
1356 * @param cls Closure
1357 * @param msg The message header
1358 */
1359static void
1360handle_peer_pull_reply (void *cls,
1361 const struct GNUNET_RPS_P2P_PullReplyMessage *msg)
1362{
1363 struct GNUNET_PeerIdentity *peers;
1364 struct GNUNET_PeerIdentity *sender = cls;
1365 uint32_t i;
1366#ifdef ENABLE_MALICIOUS
1367 struct AttackedPeer *tmp_att_peer;
1368#endif /* ENABLE_MALICIOUS */
1401 1369
1370 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REPLY (%s)\n", GNUNET_i2s (sender));
1402 1371
1403 #ifdef ENABLE_MALICIOUS 1372 #ifdef ENABLE_MALICIOUS
1404 // We shouldn't even receive pull replies as we're not sending 1373 // We shouldn't even receive pull replies as we're not sending
1405 if (2 == mal_type) 1374 if (2 == mal_type)
1406 { 1375 {
1407 GNUNET_CADET_receive_done (channel); 1376 GNUNET_CADET_receive_done (Peers_get_recv_channel (sender));
1408 return GNUNET_OK;
1409 } 1377 }
1410 #endif /* ENABLE_MALICIOUS */ 1378 #endif /* ENABLE_MALICIOUS */
1411 1379
1412 /* Do actual logic */ 1380 /* Do actual logic */
1413 peers = (struct GNUNET_PeerIdentity *) &in_msg[1]; 1381 peers = (struct GNUNET_PeerIdentity *) &msg[1];
1414 1382
1415 LOG (GNUNET_ERROR_TYPE_DEBUG, 1383 LOG (GNUNET_ERROR_TYPE_DEBUG,
1416 "PULL REPLY received, got following %u peers:\n", 1384 "PULL REPLY received, got following %u peers:\n",
1417 ntohl (in_msg->num_peers)); 1385 ntohl (msg->num_peers));
1418 1386
1419 for (i = 0 ; i < ntohl (in_msg->num_peers) ; i++) 1387 for (i = 0; i < ntohl (msg->num_peers); i++)
1420 { 1388 {
1421 LOG (GNUNET_ERROR_TYPE_DEBUG, 1389 LOG (GNUNET_ERROR_TYPE_DEBUG,
1422 "%u. %s\n", 1390 "%u. %s\n",
@@ -1466,8 +1434,7 @@ handle_peer_pull_reply (void *cls,
1466 Peers_unset_peer_flag (sender, Peers_PULL_REPLY_PENDING); 1434 Peers_unset_peer_flag (sender, Peers_PULL_REPLY_PENDING);
1467 clean_peer (sender); 1435 clean_peer (sender);
1468 1436
1469 GNUNET_CADET_receive_done (channel); 1437 GNUNET_CADET_receive_done (Peers_get_recv_channel (sender));
1470 return GNUNET_OK;
1471} 1438}
1472 1439
1473 1440
@@ -2273,15 +2240,24 @@ run (void *cls,
2273 const struct GNUNET_CONFIGURATION_Handle *c, 2240 const struct GNUNET_CONFIGURATION_Handle *c,
2274 struct GNUNET_SERVICE_Handle *service) 2241 struct GNUNET_SERVICE_Handle *service)
2275{ 2242{
2276 static const struct GNUNET_CADET_MessageHandler cadet_handlers[] = { 2243 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
2277 {&handle_peer_check , GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE, 2244 GNUNET_MQ_hd_fixed_size (peer_check,
2278 sizeof (struct GNUNET_MessageHeader)}, 2245 GNUNET_MESSAGE_TYPE_RPS_PP_CHECK_LIVE,
2279 {&handle_peer_push , GNUNET_MESSAGE_TYPE_RPS_PP_PUSH, 2246 struct GNUNET_MessageHeader,
2280 sizeof (struct GNUNET_MessageHeader)}, 2247 NULL),
2281 {&handle_peer_pull_request, GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST, 2248 GNUNET_MQ_hd_fixed_size (peer_push,
2282 sizeof (struct GNUNET_MessageHeader)}, 2249 GNUNET_MESSAGE_TYPE_RPS_PP_PUSH,
2283 {&handle_peer_pull_reply , GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY, 0}, 2250 struct GNUNET_MessageHeader,
2284 {NULL, 0, 0} 2251 NULL),
2252 GNUNET_MQ_hd_fixed_size (peer_pull_request,
2253 GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REQUEST,
2254 struct GNUNET_MessageHeader,
2255 NULL),
2256 GNUNET_MQ_hd_var_size (peer_pull_reply,
2257 GNUNET_MESSAGE_TYPE_RPS_PP_PULL_REPLY,
2258 struct GNUNET_RPS_P2P_PullReplyMessage,
2259 NULL),
2260 GNUNET_MQ_handler_end ()
2285 }; 2261 };
2286 2262
2287 int size; 2263 int size;
@@ -2373,21 +2349,23 @@ run (void *cls,
2373 2349
2374 2350
2375 /* Initialise cadet */ 2351 /* Initialise cadet */
2376 cadet_handle = GNUNET_CADET_connect (cfg, 2352 cadet_handle = GNUNET_CADET_connect (cfg);
2377 cls,
2378 &cleanup_destroyed_channel,
2379 cadet_handlers);
2380 GNUNET_assert (NULL != cadet_handle); 2353 GNUNET_assert (NULL != cadet_handle);
2381 GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_RPS, 2354 GNUNET_CRYPTO_hash (GNUNET_APPLICATION_PORT_RPS,
2382 strlen (GNUNET_APPLICATION_PORT_RPS), 2355 strlen (GNUNET_APPLICATION_PORT_RPS),
2383 &port); 2356 &port);
2384 GNUNET_CADET_open_port (cadet_handle, 2357 cadet_port = GNUNET_CADET_open_port (cadet_handle,
2385 &port, 2358 &port,
2386 &Peers_handle_inbound_channel, cls); 2359 &Peers_handle_inbound_channel, /* Connect handler */
2360 NULL, /* cls */
2361 NULL, /* WindowSize handler */
2362 cleanup_destroyed_channel, /* Disconnect handler */
2363 cadet_handlers);
2387 2364
2388 2365
2389 peerinfo_handle = GNUNET_PEERINFO_connect (cfg); 2366 peerinfo_handle = GNUNET_PEERINFO_connect (cfg);
2390 Peers_initialise (fn_valid_peers, cadet_handle, &own_identity); 2367 Peers_initialise (fn_valid_peers, cadet_handle, cleanup_destroyed_channel,
2368 cadet_handlers, &own_identity);
2391 GNUNET_free (fn_valid_peers); 2369 GNUNET_free (fn_valid_peers);
2392 2370
2393 /* Initialise sampler */ 2371 /* Initialise sampler */
diff --git a/src/rps/gnunet-service-rps_peers.c b/src/rps/gnunet-service-rps_peers.c
index e0b278bd0..58aa84ccf 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;
251 */ 251 */
252static struct GNUNET_CADET_Handle *cadet_handle; 252static struct GNUNET_CADET_Handle *cadet_handle;
253 253
254/**
255 * @brief Disconnect handler
256 */
257static GNUNET_CADET_DisconnectEventHandler cleanup_destroyed_channel;
258
259/**
260 * @brief cadet handlers
261 */
262static const struct GNUNET_MQ_MessageHandler *cadet_handlers;
263
264
254 265
255/** 266/**
256 * @brief Get the #PeerContext associated with a peer 267 * @brief Get the #PeerContext associated with a peer
@@ -523,10 +534,13 @@ get_channel (const struct GNUNET_PeerIdentity *peer)
523 &port); 534 &port);
524 peer_ctx->send_channel = 535 peer_ctx->send_channel =
525 GNUNET_CADET_channel_create (cadet_handle, 536 GNUNET_CADET_channel_create (cadet_handle,
526 peer_ctx->send_channel_flags, /* context */ 537 (struct GNUNET_PeerIdentity *) peer, /* context */
527 peer, 538 peer,
528 &port, 539 &port,
529 GNUNET_CADET_OPTION_RELIABLE); 540 GNUNET_CADET_OPTION_RELIABLE,
541 NULL, /* WindowSize handler */
542 cleanup_destroyed_channel, /* Disconnect handler */
543 cadet_handlers);
530 } 544 }
531 GNUNET_assert (NULL != peer_ctx->send_channel); 545 GNUNET_assert (NULL != peer_ctx->send_channel);
532 return peer_ctx->send_channel; 546 return peer_ctx->send_channel;
@@ -552,7 +566,7 @@ get_mq (const struct GNUNET_PeerIdentity *peer)
552 if (NULL == peer_ctx->mq) 566 if (NULL == peer_ctx->mq)
553 { 567 {
554 (void) get_channel (peer); 568 (void) get_channel (peer);
555 peer_ctx->mq = GNUNET_CADET_mq_create (peer_ctx->send_channel); 569 peer_ctx->mq = GNUNET_CADET_get_mq (peer_ctx->send_channel);
556 } 570 }
557 return peer_ctx->mq; 571 return peer_ctx->mq;
558} 572}
@@ -649,9 +663,7 @@ remove_pending_message (struct PendingMessage *pending_msg)
649 GNUNET_CONTAINER_DLL_remove (peer_ctx->pending_messages_head, 663 GNUNET_CONTAINER_DLL_remove (peer_ctx->pending_messages_head,
650 peer_ctx->pending_messages_tail, 664 peer_ctx->pending_messages_tail,
651 pending_msg); 665 pending_msg);
652 /* FIXME We are not able to cancel messages as #GNUNET_CADET_mq_create () does 666 GNUNET_MQ_send_cancel (peer_ctx->pending_messages_head->ev);
653 * not set a #GNUNET_MQ_CancelImpl */
654 /* GNUNET_MQ_send_cancel (peer_ctx->pending_messages_head->ev); */
655 GNUNET_free (pending_msg); 667 GNUNET_free (pending_msg);
656} 668}
657 669
@@ -932,15 +944,21 @@ restore_valid_peers ()
932 * 944 *
933 * @param fn_valid_peers filename of the file used to store valid peer ids 945 * @param fn_valid_peers filename of the file used to store valid peer ids
934 * @param cadet_h cadet handle 946 * @param cadet_h cadet handle
947 * @param disconnect_handler Disconnect handler
948 * @param c_handlers cadet handlers
935 * @param own_id own peer identity 949 * @param own_id own peer identity
936 */ 950 */
937void 951void
938Peers_initialise (char* fn_valid_peers, 952Peers_initialise (char* fn_valid_peers,
939 struct GNUNET_CADET_Handle *cadet_h, 953 struct GNUNET_CADET_Handle *cadet_h,
954 GNUNET_CADET_DisconnectEventHandler disconnect_handler,
955 const struct GNUNET_MQ_MessageHandler *c_handlers,
940 const struct GNUNET_PeerIdentity *own_id) 956 const struct GNUNET_PeerIdentity *own_id)
941{ 957{
942 filename_valid_peers = GNUNET_strdup (fn_valid_peers); 958 filename_valid_peers = GNUNET_strdup (fn_valid_peers);
943 cadet_handle = cadet_h; 959 cadet_handle = cadet_h;
960 cleanup_destroyed_channel = disconnect_handler;
961 cadet_handlers = c_handlers;
944 own_identity = own_id; 962 own_identity = own_id;
945 peer_map = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO); 963 peer_map = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO);
946 valid_peers = GNUNET_CONTAINER_multipeermap_create (4, GNUNET_NO); 964 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
1279 return check_channel_flag_set (channel_flags, flags); 1297 return check_channel_flag_set (channel_flags, flags);
1280} 1298}
1281 1299
1300/**
1301 * @brief Get the flags for the channel in @a role for @a peer.
1302 *
1303 * @param peer Peer to get the channel flags for.
1304 * @param role Role of channel to get flags for
1305 *
1306 * @return The flags.
1307 */
1308uint32_t *
1309Peers_get_channel_flag (const struct GNUNET_PeerIdentity *peer,
1310 enum Peers_ChannelRole role)
1311{
1312 const struct PeerContext *peer_ctx;
1313
1314 peer_ctx = get_peer_ctx (peer);
1315 if (Peers_CHANNEL_ROLE_SENDING == role)
1316 {
1317 return peer_ctx->send_channel_flags;
1318 }
1319 else if (Peers_CHANNEL_ROLE_RECEIVING == role)
1320 {
1321 return peer_ctx->recv_channel_flags;
1322 }
1323 else
1324 {
1325 GNUNET_assert (0);
1326 }
1327}
1282 1328
1283/** 1329/**
1284 * @brief Check whether we have information about the given peer. 1330 * @brief Check whether we have information about the given peer.
@@ -1358,8 +1404,6 @@ Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer)
1358 * @param cls The closure 1404 * @param cls The closure
1359 * @param channel The channel the peer wants to establish 1405 * @param channel The channel the peer wants to establish
1360 * @param initiator The peer's peer ID 1406 * @param initiator The peer's peer ID
1361 * @param port The port the channel is being established over
1362 * @param options Further options
1363 * 1407 *
1364 * @return initial channel context for the channel 1408 * @return initial channel context for the channel
1365 * (can be NULL -- that's not an error) 1409 * (can be NULL -- that's not an error)
@@ -1367,9 +1411,7 @@ Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer)
1367void * 1411void *
1368Peers_handle_inbound_channel (void *cls, 1412Peers_handle_inbound_channel (void *cls,
1369 struct GNUNET_CADET_Channel *channel, 1413 struct GNUNET_CADET_Channel *channel,
1370 const struct GNUNET_PeerIdentity *initiator, 1414 const struct GNUNET_PeerIdentity *initiator)
1371 const struct GNUNET_HashCode *port,
1372 enum GNUNET_CADET_ChannelOption options)
1373{ 1415{
1374 struct PeerContext *peer_ctx; 1416 struct PeerContext *peer_ctx;
1375 1417
@@ -1387,10 +1429,10 @@ Peers_handle_inbound_channel (void *cls,
1387 Peers_CHANNEL_ESTABLISHED_TWICE); 1429 Peers_CHANNEL_ESTABLISHED_TWICE);
1388 GNUNET_CADET_channel_destroy (channel); 1430 GNUNET_CADET_channel_destroy (channel);
1389 /* return the channel context */ 1431 /* return the channel context */
1390 return peer_ctx->recv_channel_flags; 1432 return &peer_ctx->peer_id;
1391 } 1433 }
1392 peer_ctx->recv_channel = channel; 1434 peer_ctx->recv_channel = channel;
1393 return peer_ctx->recv_channel_flags; 1435 return &peer_ctx->peer_id;
1394} 1436}
1395 1437
1396 1438
@@ -1500,16 +1542,11 @@ Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer)
1500 */ 1542 */
1501void 1543void
1502Peers_cleanup_destroyed_channel (void *cls, 1544Peers_cleanup_destroyed_channel (void *cls,
1503 const struct GNUNET_CADET_Channel *channel, 1545 const struct GNUNET_CADET_Channel *channel)
1504 void *channel_ctx)
1505{ 1546{
1506 struct GNUNET_PeerIdentity *peer; 1547 struct GNUNET_PeerIdentity *peer = cls;
1507 struct PeerContext *peer_ctx; 1548 struct PeerContext *peer_ctx;
1508 1549
1509 peer = (struct GNUNET_PeerIdentity *) GNUNET_CADET_channel_get_info (
1510 (struct GNUNET_CADET_Channel *) channel, GNUNET_CADET_OPTION_PEER);
1511 // FIXME wait for cadet to change this function
1512
1513 if (GNUNET_NO == Peers_check_peer_known (peer)) 1550 if (GNUNET_NO == Peers_check_peer_known (peer))
1514 {/* We don't want to implicitly create a context that we're about to kill */ 1551 {/* We don't want to implicitly create a context that we're about to kill */
1515 LOG (GNUNET_ERROR_TYPE_DEBUG, 1552 LOG (GNUNET_ERROR_TYPE_DEBUG,
@@ -1635,4 +1672,23 @@ Peers_schedule_operation (const struct GNUNET_PeerIdentity *peer,
1635 return GNUNET_NO; 1672 return GNUNET_NO;
1636} 1673}
1637 1674
1675/**
1676 * @brief Get the recv_channel of @a peer.
1677 * Needed to correctly handle (call #GNUNET_CADET_receive_done()) incoming
1678 * messages.
1679 *
1680 * @param peer The peer to get the recv_channel from.
1681 *
1682 * @return The recv_channel.
1683 */
1684struct GNUNET_CADET_Channel *
1685Peers_get_recv_channel (const struct GNUNET_PeerIdentity *peer)
1686{
1687 struct PeerContext *peer_ctx;
1688
1689 GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer));
1690 peer_ctx = get_peer_ctx (peer);
1691 return peer_ctx->recv_channel;
1692}
1693
1638/* end of gnunet-service-rps_peers.c */ 1694/* 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 bbac86003..15970a7ce 100644
--- a/src/rps/gnunet-service-rps_peers.h
+++ b/src/rps/gnunet-service-rps_peers.h
@@ -117,11 +117,15 @@ typedef int
117 * 117 *
118 * @param fn_valid_peers filename of the file used to store valid peer ids 118 * @param fn_valid_peers filename of the file used to store valid peer ids
119 * @param cadet_h cadet handle 119 * @param cadet_h cadet handle
120 * @param disconnect_handler Disconnect handler
121 * @param c_handlers cadet handlers
120 * @param own_id own peer identity 122 * @param own_id own peer identity
121 */ 123 */
122void 124void
123Peers_initialise (char* fn_valid_peers, 125Peers_initialise (char* fn_valid_peers,
124 struct GNUNET_CADET_Handle *cadet_h, 126 struct GNUNET_CADET_Handle *cadet_h,
127 GNUNET_CADET_DisconnectEventHandler disconnect_handler,
128 const struct GNUNET_MQ_MessageHandler *c_handlers,
125 const struct GNUNET_PeerIdentity *own_id); 129 const struct GNUNET_PeerIdentity *own_id);
126 130
127/** 131/**
@@ -259,6 +263,18 @@ int
259Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags); 263Peers_check_channel_flag (uint32_t *channel_flags, enum Peers_ChannelFlags flags);
260 264
261/** 265/**
266 * @brief Get the flags for the channel in @a role for @a peer.
267 *
268 * @param peer Peer to get the channel flags for.
269 * @param role Role of channel to get flags for
270 *
271 * @return The flags.
272 */
273uint32_t *
274Peers_get_channel_flag (const struct GNUNET_PeerIdentity *peer,
275 enum Peers_ChannelRole role);
276
277/**
262 * @brief Check whether we have information about the given peer. 278 * @brief Check whether we have information about the given peer.
263 * 279 *
264 * FIXME probably deprecated. Make this the new _online. 280 * FIXME probably deprecated. Make this the new _online.
@@ -312,8 +328,6 @@ Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer);
312 * @param cls The closure 328 * @param cls The closure
313 * @param channel The channel the peer wants to establish 329 * @param channel The channel the peer wants to establish
314 * @param initiator The peer's peer ID 330 * @param initiator The peer's peer ID
315 * @param port The port the channel is being established over
316 * @param options Further options
317 * 331 *
318 * @return initial channel context for the channel 332 * @return initial channel context for the channel
319 * (can be NULL -- that's not an error) 333 * (can be NULL -- that's not an error)
@@ -321,9 +335,7 @@ Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer);
321void * 335void *
322Peers_handle_inbound_channel (void *cls, 336Peers_handle_inbound_channel (void *cls,
323 struct GNUNET_CADET_Channel *channel, 337 struct GNUNET_CADET_Channel *channel,
324 const struct GNUNET_PeerIdentity *initiator, 338 const struct GNUNET_PeerIdentity *initiator);
325 const struct GNUNET_HashCode *port,
326 enum GNUNET_CADET_ChannelOption options);
327 339
328/** 340/**
329 * @brief Check whether a sending channel towards the given peer exists 341 * @brief Check whether a sending channel towards the given peer exists
@@ -379,8 +391,7 @@ Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer);
379 */ 391 */
380void 392void
381Peers_cleanup_destroyed_channel (void *cls, 393Peers_cleanup_destroyed_channel (void *cls,
382 const struct GNUNET_CADET_Channel *channel, 394 const struct GNUNET_CADET_Channel *channel);
383 void *channel_ctx);
384 395
385/** 396/**
386 * @brief Send a message to another peer. 397 * @brief Send a message to another peer.
@@ -411,4 +422,16 @@ int
411Peers_schedule_operation (const struct GNUNET_PeerIdentity *peer, 422Peers_schedule_operation (const struct GNUNET_PeerIdentity *peer,
412 const PeerOp peer_op); 423 const PeerOp peer_op);
413 424
425/**
426 * @brief Get the recv_channel of @a peer.
427 * Needed to correctly handle (call #GNUNET_CADET_receive_done()) incoming
428 * messages.
429 *
430 * @param peer The peer to get the recv_channel from.
431 *
432 * @return The recv_channel.
433 */
434struct GNUNET_CADET_Channel *
435Peers_get_recv_channel (const struct GNUNET_PeerIdentity *peer);
436
414/* end of gnunet-service-rps_peers.h */ 437/* 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 37ed1974c..9cd677fef 100644
--- a/src/rps/test_service_rps_peers.c
+++ b/src/rps/test_service_rps_peers.c
@@ -59,25 +59,25 @@ check ()
59 memset (&own_id, 1, sizeof (own_id)); 59 memset (&own_id, 1, sizeof (own_id));
60 60
61 /* Do nothing */ 61 /* Do nothing */
62 Peers_initialise (FN_VALID_PEERS, NULL, &own_id); 62 Peers_initialise (FN_VALID_PEERS, NULL, NULL, NULL, &own_id);
63 Peers_terminate (); 63 Peers_terminate ();
64 64
65 65
66 /* Create peer */ 66 /* Create peer */
67 Peers_initialise (FN_VALID_PEERS, NULL, &own_id); 67 Peers_initialise (FN_VALID_PEERS, NULL, NULL, NULL, &own_id);
68 CHECK (GNUNET_YES == Peers_insert_peer (&k1)); 68 CHECK (GNUNET_YES == Peers_insert_peer (&k1));
69 Peers_terminate (); 69 Peers_terminate ();
70 70
71 71
72 /* Create peer */ 72 /* Create peer */
73 Peers_initialise (FN_VALID_PEERS, NULL, &own_id); 73 Peers_initialise (FN_VALID_PEERS, NULL, NULL, NULL, &own_id);
74 CHECK (GNUNET_YES == Peers_insert_peer (&k1)); 74 CHECK (GNUNET_YES == Peers_insert_peer (&k1));
75 CHECK (GNUNET_YES == Peers_remove_peer (&k1)); 75 CHECK (GNUNET_YES == Peers_remove_peer (&k1));
76 Peers_terminate (); 76 Peers_terminate ();
77 77
78 78
79 /* Insertion and Removal */ 79 /* Insertion and Removal */
80 Peers_initialise (FN_VALID_PEERS, NULL, &own_id); 80 Peers_initialise (FN_VALID_PEERS, NULL, NULL, NULL, &own_id);
81 CHECK (GNUNET_NO == Peers_check_peer_known (&k1)); 81 CHECK (GNUNET_NO == Peers_check_peer_known (&k1));
82 82
83 CHECK (GNUNET_YES == Peers_insert_peer (&k1)); 83 CHECK (GNUNET_YES == Peers_insert_peer (&k1));
diff --git a/src/scalarproduct/Makefile.am b/src/scalarproduct/Makefile.am
index 98829408a..10e04284f 100644
--- a/src/scalarproduct/Makefile.am
+++ b/src/scalarproduct/Makefile.am
@@ -42,7 +42,7 @@ gnunet_service_scalarproduct_alice_SOURCES = \
42 gnunet-service-scalarproduct_alice.c 42 gnunet-service-scalarproduct_alice.c
43gnunet_service_scalarproduct_alice_LDADD = \ 43gnunet_service_scalarproduct_alice_LDADD = \
44 $(top_builddir)/src/util/libgnunetutil.la \ 44 $(top_builddir)/src/util/libgnunetutil.la \
45 $(top_builddir)/src/cadet/libgnunetcadetnew.la \ 45 $(top_builddir)/src/cadet/libgnunetcadet.la \
46 $(top_builddir)/src/set/libgnunetset.la \ 46 $(top_builddir)/src/set/libgnunetset.la \
47 $(LIBGCRYPT_LIBS) \ 47 $(LIBGCRYPT_LIBS) \
48 -lgcrypt \ 48 -lgcrypt \
@@ -53,7 +53,7 @@ gnunet_service_scalarproduct_bob_SOURCES = \
53 gnunet-service-scalarproduct_bob.c 53 gnunet-service-scalarproduct_bob.c
54gnunet_service_scalarproduct_bob_LDADD = \ 54gnunet_service_scalarproduct_bob_LDADD = \
55 $(top_builddir)/src/util/libgnunetutil.la \ 55 $(top_builddir)/src/util/libgnunetutil.la \
56 $(top_builddir)/src/cadet/libgnunetcadetnew.la \ 56 $(top_builddir)/src/cadet/libgnunetcadet.la \
57 $(top_builddir)/src/set/libgnunetset.la \ 57 $(top_builddir)/src/set/libgnunetset.la \
58 $(LIBGCRYPT_LIBS) \ 58 $(LIBGCRYPT_LIBS) \
59 -lgcrypt \ 59 -lgcrypt \
@@ -64,7 +64,7 @@ gnunet_service_scalarproduct_ecc_alice_SOURCES = \
64 gnunet-service-scalarproduct-ecc_alice.c 64 gnunet-service-scalarproduct-ecc_alice.c
65gnunet_service_scalarproduct_ecc_alice_LDADD = \ 65gnunet_service_scalarproduct_ecc_alice_LDADD = \
66 $(top_builddir)/src/util/libgnunetutil.la \ 66 $(top_builddir)/src/util/libgnunetutil.la \
67 $(top_builddir)/src/cadet/libgnunetcadetnew.la \ 67 $(top_builddir)/src/cadet/libgnunetcadet.la \
68 $(top_builddir)/src/set/libgnunetset.la \ 68 $(top_builddir)/src/set/libgnunetset.la \
69 $(LIBGCRYPT_LIBS) \ 69 $(LIBGCRYPT_LIBS) \
70 -lgcrypt \ 70 -lgcrypt \
@@ -75,7 +75,7 @@ gnunet_service_scalarproduct_ecc_bob_SOURCES = \
75 gnunet-service-scalarproduct-ecc_bob.c 75 gnunet-service-scalarproduct-ecc_bob.c
76gnunet_service_scalarproduct_ecc_bob_LDADD = \ 76gnunet_service_scalarproduct_ecc_bob_LDADD = \
77 $(top_builddir)/src/util/libgnunetutil.la \ 77 $(top_builddir)/src/util/libgnunetutil.la \
78 $(top_builddir)/src/cadet/libgnunetcadetnew.la \ 78 $(top_builddir)/src/cadet/libgnunetcadet.la \
79 $(top_builddir)/src/set/libgnunetset.la \ 79 $(top_builddir)/src/set/libgnunetset.la \
80 $(LIBGCRYPT_LIBS) \ 80 $(LIBGCRYPT_LIBS) \
81 -lgcrypt \ 81 -lgcrypt \
diff --git a/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c b/src/scalarproduct/gnunet-service-scalarproduct-ecc_alice.c
index ca92fb9ea..c0b33f8ef 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)
842 "Creating new channel for session with key %s.\n", 842 "Creating new channel for session with key %s.\n",
843 GNUNET_h2s (&s->session_id)); 843 GNUNET_h2s (&s->session_id));
844 s->channel 844 s->channel
845 = GNUNET_CADET_channel_creatE (my_cadet, 845 = GNUNET_CADET_channel_create (my_cadet,
846 s, 846 s,
847 &s->peer, 847 &s->peer,
848 &s->session_id, 848 &s->session_id,
@@ -1173,7 +1173,7 @@ run (void *cls,
1173 GNUNET_CRYPTO_ecc_rnd_mpi (edc, 1173 GNUNET_CRYPTO_ecc_rnd_mpi (edc,
1174 &my_privkey, 1174 &my_privkey,
1175 &my_privkey_inv); 1175 &my_privkey_inv);
1176 my_cadet = GNUNET_CADET_connecT (cfg); 1176 my_cadet = GNUNET_CADET_connect (cfg);
1177 if (NULL == my_cadet) 1177 if (NULL == my_cadet)
1178 { 1178 {
1179 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1179 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 3851ca763..0b0333332 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,
950 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 950 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
951 "Received client request, opening port %s!\n", 951 "Received client request, opening port %s!\n",
952 GNUNET_h2s (&msg->session_key)); 952 GNUNET_h2s (&msg->session_key));
953 s->port = GNUNET_CADET_open_porT (my_cadet, 953 s->port = GNUNET_CADET_open_port (my_cadet,
954 &msg->session_key, 954 &msg->session_key,
955 &cb_channel_incoming, 955 &cb_channel_incoming,
956 s, 956 s,
@@ -1054,7 +1054,7 @@ run (void *cls,
1054 /* We don't really do DLOG, so we can setup with very minimal resources */ 1054 /* We don't really do DLOG, so we can setup with very minimal resources */
1055 edc = GNUNET_CRYPTO_ecc_dlog_prepare (4 /* max value */, 1055 edc = GNUNET_CRYPTO_ecc_dlog_prepare (4 /* max value */,
1056 2 /* RAM */); 1056 2 /* RAM */);
1057 my_cadet = GNUNET_CADET_connecT (cfg); 1057 my_cadet = GNUNET_CADET_connect (cfg);
1058 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 1058 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1059 NULL); 1059 NULL);
1060 if (NULL == my_cadet) 1060 if (NULL == my_cadet)
diff --git a/src/scalarproduct/gnunet-service-scalarproduct_alice.c b/src/scalarproduct/gnunet-service-scalarproduct_alice.c
index 6d7a0a3b8..a55d03900 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)
1076 "Creating new channel for session with key %s.\n", 1076 "Creating new channel for session with key %s.\n",
1077 GNUNET_h2s (&s->session_id)); 1077 GNUNET_h2s (&s->session_id));
1078 s->channel 1078 s->channel
1079 = GNUNET_CADET_channel_creatE (my_cadet, 1079 = GNUNET_CADET_channel_create (my_cadet,
1080 s, 1080 s,
1081 &s->peer, 1081 &s->peer,
1082 &s->session_id, 1082 &s->session_id,
@@ -1398,7 +1398,7 @@ run (void *cls,
1398 GNUNET_CRYPTO_PAILLIER_BITS / 3); 1398 GNUNET_CRYPTO_PAILLIER_BITS / 3);
1399 GNUNET_CRYPTO_paillier_create (&my_pubkey, 1399 GNUNET_CRYPTO_paillier_create (&my_pubkey,
1400 &my_privkey); 1400 &my_privkey);
1401 my_cadet = GNUNET_CADET_connecT (cfg); 1401 my_cadet = GNUNET_CADET_connect (cfg);
1402 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 1402 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1403 NULL); 1403 NULL);
1404 if (NULL == my_cadet) 1404 if (NULL == my_cadet)
diff --git a/src/scalarproduct/gnunet-service-scalarproduct_bob.c b/src/scalarproduct/gnunet-service-scalarproduct_bob.c
index f3b5327f1..0c38cb426 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,
1230 } 1230 }
1231 GNUNET_SERVICE_client_continue (s->client); 1231 GNUNET_SERVICE_client_continue (s->client);
1232 /* We're ready, open the port */ 1232 /* We're ready, open the port */
1233 s->port = GNUNET_CADET_open_porT (my_cadet, 1233 s->port = GNUNET_CADET_open_port (my_cadet,
1234 &msg->session_key, 1234 &msg->session_key,
1235 &cb_channel_incoming, 1235 &cb_channel_incoming,
1236 s, 1236 s,
@@ -1336,7 +1336,7 @@ run (void *cls,
1336 1336
1337 GNUNET_CRYPTO_paillier_create (&my_pubkey, 1337 GNUNET_CRYPTO_paillier_create (&my_pubkey,
1338 &my_privkey); 1338 &my_privkey);
1339 my_cadet = GNUNET_CADET_connecT (cfg); 1339 my_cadet = GNUNET_CADET_connect (cfg);
1340 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 1340 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1341 NULL); 1341 NULL);
1342 if (NULL == my_cadet) 1342 if (NULL == my_cadet)
diff --git a/src/set/Makefile.am b/src/set/Makefile.am
index 03c258352..14667d0ef 100644
--- a/src/set/Makefile.am
+++ b/src/set/Makefile.am
@@ -60,7 +60,7 @@ gnunet_service_set_LDADD = \
60 $(top_builddir)/src/util/libgnunetutil.la \ 60 $(top_builddir)/src/util/libgnunetutil.la \
61 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 61 $(top_builddir)/src/statistics/libgnunetstatistics.la \
62 $(top_builddir)/src/core/libgnunetcore.la \ 62 $(top_builddir)/src/core/libgnunetcore.la \
63 $(top_builddir)/src/cadet/libgnunetcadetnew.la \ 63 $(top_builddir)/src/cadet/libgnunetcadet.la \
64 $(top_builddir)/src/block/libgnunetblock.la \ 64 $(top_builddir)/src/block/libgnunetblock.la \
65 libgnunetset.la \ 65 libgnunetset.la \
66 $(GN_LIBINTL) 66 $(GN_LIBINTL)
diff --git a/src/set/gnunet-service-set.c b/src/set/gnunet-service-set.c
index 8f1506c6a..12af653c1 100644
--- a/src/set/gnunet-service-set.c
+++ b/src/set/gnunet-service-set.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2013, 2014, 2017 GNUnet e.V. 3 Copyright (C) 2013-2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -35,6 +35,35 @@
35 */ 35 */
36#define INCOMING_CHANNEL_TIMEOUT GNUNET_TIME_UNIT_MINUTES 36#define INCOMING_CHANNEL_TIMEOUT GNUNET_TIME_UNIT_MINUTES
37 37
38
39/**
40 * Lazy copy requests made by a client.
41 */
42struct LazyCopyRequest
43{
44 /**
45 * Kept in a DLL.
46 */
47 struct LazyCopyRequest *prev;
48
49 /**
50 * Kept in a DLL.
51 */
52 struct LazyCopyRequest *next;
53
54 /**
55 * Which set are we supposed to copy?
56 */
57 struct Set *source_set;
58
59 /**
60 * Cookie identifying the request.
61 */
62 uint32_t cookie;
63
64};
65
66
38/** 67/**
39 * A listener is inhabited by a client, and waits for evaluation 68 * A listener is inhabited by a client, and waits for evaluation
40 * requests from remote peers. 69 * requests from remote peers.
@@ -52,21 +81,24 @@ struct Listener
52 struct Listener *prev; 81 struct Listener *prev;
53 82
54 /** 83 /**
55 * Client that owns the listener. 84 * Head of DLL of operations this listener is responsible for.
56 * Only one client may own a listener. 85 * Once the client has accepted/declined the operation, the
86 * operation is moved to the respective set's operation DLLS.
57 */ 87 */
58 struct GNUNET_SERVICE_Client *client; 88 struct Operation *op_head;
59 89
60 /** 90 /**
61 * Message queue for the client 91 * Tail of DLL of operations this listener is responsible for.
92 * Once the client has accepted/declined the operation, the
93 * operation is moved to the respective set's operation DLLS.
62 */ 94 */
63 struct GNUNET_MQ_Handle *client_mq; 95 struct Operation *op_tail;
64 96
65 /** 97 /**
66 * Application ID for the operation, used to distinguish 98 * Client that owns the listener.
67 * multiple operations of the same type with the same peer. 99 * Only one client may own a listener.
68 */ 100 */
69 struct GNUNET_HashCode app_id; 101 struct ClientState *cs;
70 102
71 /** 103 /**
72 * The port we are listening on with CADET. 104 * The port we are listening on with CADET.
@@ -74,27 +106,18 @@ struct Listener
74 struct GNUNET_CADET_Port *open_port; 106 struct GNUNET_CADET_Port *open_port;
75 107
76 /** 108 /**
109 * Application ID for the operation, used to distinguish
110 * multiple operations of the same type with the same peer.
111 */
112 struct GNUNET_HashCode app_id;
113
114 /**
77 * The type of the operation. 115 * The type of the operation.
78 */ 116 */
79 enum GNUNET_SET_OperationType operation; 117 enum GNUNET_SET_OperationType operation;
80}; 118};
81 119
82 120
83struct LazyCopyRequest
84{
85 struct Set *source_set;
86 uint32_t cookie;
87
88 struct LazyCopyRequest *prev;
89 struct LazyCopyRequest *next;
90};
91
92
93/**
94 * Configuration of our local peer.
95 */
96static const struct GNUNET_CONFIGURATION_Handle *configuration;
97
98/** 121/**
99 * Handle to the cadet service, used to listen for and connect to 122 * Handle to the cadet service, used to listen for and connect to
100 * remote peers. 123 * remote peers.
@@ -102,96 +125,48 @@ static const struct GNUNET_CONFIGURATION_Handle *configuration;
102static struct GNUNET_CADET_Handle *cadet; 125static struct GNUNET_CADET_Handle *cadet;
103 126
104/** 127/**
105 * Sets are held in a doubly linked list. 128 * DLL of lazy copy requests by this client.
106 */ 129 */
107static struct Set *sets_head; 130static struct LazyCopyRequest *lazy_copy_head;
108 131
109/** 132/**
110 * Sets are held in a doubly linked list. 133 * DLL of lazy copy requests by this client.
111 */ 134 */
112static struct Set *sets_tail; 135static struct LazyCopyRequest *lazy_copy_tail;
113 136
114/** 137/**
115 * Listeners are held in a doubly linked list. 138 * Generator for unique cookie we set per lazy copy request.
116 */ 139 */
117static struct Listener *listeners_head; 140static uint32_t lazy_copy_cookie;
118 141
119/** 142/**
120 * Listeners are held in a doubly linked list. 143 * Statistics handle.
121 */ 144 */
122static struct Listener *listeners_tail; 145struct GNUNET_STATISTICS_Handle *_GSS_statistics;
123 146
124/** 147/**
125 * Incoming sockets from remote peers are held in a doubly linked 148 * Listeners are held in a doubly linked list.
126 * list.
127 */ 149 */
128static struct Operation *incoming_head; 150static struct Listener *listener_head;
129 151
130/** 152/**
131 * Incoming sockets from remote peers are held in a doubly linked 153 * Listeners are held in a doubly linked list.
132 * list.
133 */ 154 */
134static struct Operation *incoming_tail; 155static struct Listener *listener_tail;
135
136static struct LazyCopyRequest *lazy_copy_head;
137static struct LazyCopyRequest *lazy_copy_tail;
138
139static uint32_t lazy_copy_cookie = 1;
140 156
141/** 157/**
142 * Counter for allocating unique IDs for clients, used to identify 158 * Counter for allocating unique IDs for clients, used to identify
143 * incoming operation requests from remote peers, that the client can 159 * incoming operation requests from remote peers, that the client can
144 * choose to accept or refuse. 160 * choose to accept or refuse. 0 must not be used (reserved for
145 */ 161 * uninitialized).
146static uint32_t suggest_id = 1;
147
148/**
149 * Statistics handle.
150 */
151struct GNUNET_STATISTICS_Handle *_GSS_statistics;
152
153
154/**
155 * Get set that is owned by the given client, if any.
156 *
157 * @param client client to look for
158 * @return set that the client owns, NULL if the client
159 * does not own a set
160 */
161static struct Set *
162set_get (struct GNUNET_SERVICE_Client *client)
163{
164 struct Set *set;
165
166 for (set = sets_head; NULL != set; set = set->next)
167 if (set->client == client)
168 return set;
169 return NULL;
170}
171
172
173/**
174 * Get the listener associated with the given client, if any.
175 *
176 * @param client the client
177 * @return listener associated with the client, NULL
178 * if there isn't any
179 */ 162 */
180static struct Listener * 163static uint32_t suggest_id;
181listener_get (struct GNUNET_SERVICE_Client *client)
182{
183 struct Listener *listener;
184
185 for (listener = listeners_head; NULL != listener; listener = listener->next)
186 if (listener->client == client)
187 return listener;
188 return NULL;
189}
190 164
191 165
192/** 166/**
193 * Get the incoming socket associated with the given id. 167 * Get the incoming socket associated with the given id.
194 * 168 *
169 * @param listener the listener to look in
195 * @param id id to look for 170 * @param id id to look for
196 * @return the incoming socket associated with the id, 171 * @return the incoming socket associated with the id,
197 * or NULL if there is none 172 * or NULL if there is none
@@ -199,46 +174,49 @@ listener_get (struct GNUNET_SERVICE_Client *client)
199static struct Operation * 174static struct Operation *
200get_incoming (uint32_t id) 175get_incoming (uint32_t id)
201{ 176{
202 struct Operation *op; 177 for (struct Listener *listener = listener_head;
203 178 NULL != listener;
204 for (op = incoming_head; NULL != op; op = op->next) 179 listener = listener->next)
205 if (op->suggest_id == id) 180 {
206 { 181 for (struct Operation *op = listener->op_head; NULL != op; op = op->next)
207 GNUNET_assert (GNUNET_YES == op->is_incoming); 182 if (op->suggest_id == id)
208 return op; 183 return op;
209 } 184 }
210 return NULL; 185 return NULL;
211} 186}
212 187
213 188
214/** 189/**
215 * Destroy a listener, free all resources associated with it. 190 * Destroy an incoming request from a remote peer
216 * 191 *
217 * @param listener listener to destroy 192 * @param op remote request to destroy
218 */ 193 */
219static void 194static void
220listener_destroy (struct Listener *listener) 195incoming_destroy (struct Operation *op)
221{ 196{
222 /* If the client is not dead yet, destroy it. 197 struct Listener *listener;
223 * The client's destroy callback will destroy the listener again. */ 198 struct GNUNET_CADET_Channel *channel;
224 if (NULL != listener->client)
225 {
226 struct GNUNET_SERVICE_Client *client = listener->client;
227
228 GNUNET_MQ_destroy (listener->client_mq);
229 listener->client_mq = NULL;
230 199
231 listener->client = NULL; 200 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
232 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 201 "Destroying incoming operation %p\n",
233 "Disconnecting listener client\n"); 202 op);
234 GNUNET_SERVICE_client_drop (client); 203 if (NULL != (listener = op->listener))
235 return; 204 {
205 GNUNET_CONTAINER_DLL_remove (listener->op_head,
206 listener->op_tail,
207 op);
208 op->listener = NULL;
209 }
210 if (NULL != op->timeout_task)
211 {
212 GNUNET_SCHEDULER_cancel (op->timeout_task);
213 op->timeout_task = NULL;
214 }
215 if (NULL != (channel = op->channel))
216 {
217 op->channel = NULL;
218 GNUNET_CADET_channel_destroy (channel);
236 } 219 }
237 GNUNET_CADET_close_port (listener->open_port);
238 GNUNET_CONTAINER_DLL_remove (listeners_head,
239 listeners_tail,
240 listener);
241 GNUNET_free (listener);
242} 220}
243 221
244 222
@@ -308,12 +286,11 @@ garbage_collect_cb (void *cls,
308static void 286static void
309collect_generation_garbage (struct Set *set) 287collect_generation_garbage (struct Set *set)
310{ 288{
311 struct Operation *op;
312 struct GarbageContext gc; 289 struct GarbageContext gc;
313 290
314 gc.min_op_generation = UINT_MAX; 291 gc.min_op_generation = UINT_MAX;
315 gc.max_op_generation = 0; 292 gc.max_op_generation = 0;
316 for (op = set->ops_head; NULL != op; op = op->next) 293 for (struct Operation *op = set->ops_head; NULL != op; op = op->next)
317 { 294 {
318 gc.min_op_generation = GNUNET_MIN (gc.min_op_generation, 295 gc.min_op_generation = GNUNET_MIN (gc.min_op_generation,
319 op->generation_created); 296 op->generation_created);
@@ -327,23 +304,36 @@ collect_generation_garbage (struct Set *set)
327} 304}
328 305
329 306
307/**
308 * Is @a generation in the range of exclusions?
309 *
310 * @param generation generation to query
311 * @param excluded array of generations where the element is excluded
312 * @param excluded_size length of the @a excluded array
313 * @return #GNUNET_YES if @a generation is in any of the ranges
314 */
330static int 315static int
331is_excluded_generation (unsigned int generation, 316is_excluded_generation (unsigned int generation,
332 struct GenerationRange *excluded, 317 struct GenerationRange *excluded,
333 unsigned int excluded_size) 318 unsigned int excluded_size)
334{ 319{
335 unsigned int i; 320 for (unsigned int i = 0; i < excluded_size; i++)
336 321 if ( (generation >= excluded[i].start) &&
337 for (i = 0; i < excluded_size; i++) 322 (generation < excluded[i].end) )
338 {
339 if ( (generation >= excluded[i].start) && (generation < excluded[i].end) )
340 return GNUNET_YES; 323 return GNUNET_YES;
341 }
342
343 return GNUNET_NO; 324 return GNUNET_NO;
344} 325}
345 326
346 327
328/**
329 * Is element @a ee part of the set during @a query_generation?
330 *
331 * @param ee element to test
332 * @param query_generation generation to query
333 * @param excluded array of generations where the element is excluded
334 * @param excluded_size length of the @a excluded array
335 * @return #GNUNET_YES if the element is in the set, #GNUNET_NO if not
336 */
347static int 337static int
348is_element_of_generation (struct ElementEntry *ee, 338is_element_of_generation (struct ElementEntry *ee,
349 unsigned int query_generation, 339 unsigned int query_generation,
@@ -352,11 +342,12 @@ is_element_of_generation (struct ElementEntry *ee,
352{ 342{
353 struct MutationEvent *mut; 343 struct MutationEvent *mut;
354 int is_present; 344 int is_present;
355 unsigned int i;
356 345
357 GNUNET_assert (NULL != ee->mutations); 346 GNUNET_assert (NULL != ee->mutations);
358 347 if (GNUNET_YES ==
359 if (GNUNET_YES == is_excluded_generation (query_generation, excluded, excluded_size)) 348 is_excluded_generation (query_generation,
349 excluded,
350 excluded_size))
360 { 351 {
361 GNUNET_break (0); 352 GNUNET_break (0);
362 return GNUNET_NO; 353 return GNUNET_NO;
@@ -366,7 +357,7 @@ is_element_of_generation (struct ElementEntry *ee,
366 357
367 /* Could be made faster with binary search, but lists 358 /* Could be made faster with binary search, but lists
368 are small, so why bother. */ 359 are small, so why bother. */
369 for (i = 0; i < ee->mutations_size; i++) 360 for (unsigned int i = 0; i < ee->mutations_size; i++)
370 { 361 {
371 mut = &ee->mutations[i]; 362 mut = &ee->mutations[i];
372 363
@@ -378,7 +369,10 @@ is_element_of_generation (struct ElementEntry *ee,
378 continue; 369 continue;
379 } 370 }
380 371
381 if (GNUNET_YES == is_excluded_generation (mut->generation, excluded, excluded_size)) 372 if (GNUNET_YES ==
373 is_excluded_generation (mut->generation,
374 excluded,
375 excluded_size))
382 { 376 {
383 /* The generation is excluded (because it belongs to another 377 /* The generation is excluded (because it belongs to another
384 fork via a lazy copy) and thus mutations aren't considered 378 fork via a lazy copy) and thus mutations aren't considered
@@ -387,11 +381,12 @@ is_element_of_generation (struct ElementEntry *ee,
387 } 381 }
388 382
389 /* This would be an inconsistency in how we manage mutations. */ 383 /* This would be an inconsistency in how we manage mutations. */
390 if ( (GNUNET_YES == is_present) && (GNUNET_YES == mut->added) ) 384 if ( (GNUNET_YES == is_present) &&
385 (GNUNET_YES == mut->added) )
391 GNUNET_assert (0); 386 GNUNET_assert (0);
392
393 /* Likewise. */ 387 /* Likewise. */
394 if ( (GNUNET_NO == is_present) && (GNUNET_NO == mut->added) ) 388 if ( (GNUNET_NO == is_present) &&
389 (GNUNET_NO == mut->added) )
395 GNUNET_assert (0); 390 GNUNET_assert (0);
396 391
397 is_present = mut->added; 392 is_present = mut->added;
@@ -401,44 +396,33 @@ is_element_of_generation (struct ElementEntry *ee,
401} 396}
402 397
403 398
404int 399/**
405_GSS_is_element_of_set (struct ElementEntry *ee, 400 * Is element @a ee part of the set used by @a op?
406 struct Set *set) 401 *
407{ 402 * @param ee element to test
408 return is_element_of_generation (ee, 403 * @param op operation the defines the set and its generation
409 set->current_generation, 404 * @return #GNUNET_YES if the element is in the set, #GNUNET_NO if not
410 set->excluded_generations, 405 */
411 set->excluded_generations_size);
412}
413
414
415static int
416is_element_of_iteration (struct ElementEntry *ee,
417 struct Set *set)
418{
419 return is_element_of_generation (ee,
420 set->iter_generation,
421 set->excluded_generations,
422 set->excluded_generations_size);
423}
424
425
426int 406int
427_GSS_is_element_of_operation (struct ElementEntry *ee, 407_GSS_is_element_of_operation (struct ElementEntry *ee,
428 struct Operation *op) 408 struct Operation *op)
429{ 409{
430 return is_element_of_generation (ee, 410 return is_element_of_generation (ee,
431 op->generation_created, 411 op->generation_created,
432 op->spec->set->excluded_generations, 412 op->set->excluded_generations,
433 op->spec->set->excluded_generations_size); 413 op->set->excluded_generations_size);
434} 414}
435 415
436 416
437/** 417/**
438 * Destroy the given operation. Call the implementation-specific 418 * Destroy the given operation. Used for any operation where both
439 * cancel function of the operation. Disconnects from the remote 419 * peers were known and that thus actually had a vt and channel. Must
440 * peer. Does not disconnect the client, as there may be multiple 420 * not be used for operations where 'listener' is still set and we do
441 * operations per set. 421 * not know the other peer.
422 *
423 * Call the implementation-specific cancel function of the operation.
424 * Disconnects from the remote peer. Does not disconnect the client,
425 * as there may be multiple operations per set.
442 * 426 *
443 * @param op operation to destroy 427 * @param op operation to destroy
444 * @param gc #GNUNET_YES to perform garbage collection on the set 428 * @param gc #GNUNET_YES to perform garbage collection on the set
@@ -447,39 +431,39 @@ void
447_GSS_operation_destroy (struct Operation *op, 431_GSS_operation_destroy (struct Operation *op,
448 int gc) 432 int gc)
449{ 433{
450 struct Set *set; 434 struct Set *set = op->set;
451 struct GNUNET_CADET_Channel *channel; 435 struct GNUNET_CADET_Channel *channel;
452 436
453 if (NULL == op->vt) 437 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
438 "Destroying operation %p\n",
439 op);
440 GNUNET_assert (NULL == op->listener);
441 if (NULL != op->state)
454 { 442 {
455 /* already in #_GSS_operation_destroy() */ 443 set->vt->cancel (op);
456 return; 444 op->state = NULL;
457 } 445 }
458 GNUNET_assert (GNUNET_NO == op->is_incoming); 446 if (NULL != set)
459 GNUNET_assert (NULL != op->spec);
460 set = op->spec->set;
461 GNUNET_CONTAINER_DLL_remove (set->ops_head,
462 set->ops_tail,
463 op);
464 op->vt->cancel (op);
465 op->vt = NULL;
466 if (NULL != op->spec)
467 { 447 {
468 if (NULL != op->spec->context_msg) 448 GNUNET_CONTAINER_DLL_remove (set->ops_head,
469 { 449 set->ops_tail,
470 GNUNET_free (op->spec->context_msg); 450 op);
471 op->spec->context_msg = NULL; 451 op->set = NULL;
472 } 452 }
473 GNUNET_free (op->spec); 453 if (NULL != op->context_msg)
474 op->spec = NULL; 454 {
455 GNUNET_free (op->context_msg);
456 op->context_msg = NULL;
475 } 457 }
476 if (NULL != (channel = op->channel)) 458 if (NULL != (channel = op->channel))
477 { 459 {
460 /* This will free op; called conditionally as this helper function
461 is also called from within the channel disconnect handler. */
478 op->channel = NULL; 462 op->channel = NULL;
479 GNUNET_CADET_channel_destroy (channel); 463 GNUNET_CADET_channel_destroy (channel);
480 } 464 }
481 465 if ( (NULL != set) &&
482 if (GNUNET_YES == gc) 466 (GNUNET_YES == gc) )
483 collect_generation_garbage (set); 467 collect_generation_garbage (set);
484 /* We rely on the channel end handler to free 'op'. When 'op->channel' was NULL, 468 /* We rely on the channel end handler to free 'op'. When 'op->channel' was NULL,
485 * there was a channel end handler that will free 'op' on the call stack. */ 469 * there was a channel end handler that will free 'op' on the call stack. */
@@ -487,6 +471,28 @@ _GSS_operation_destroy (struct Operation *op,
487 471
488 472
489/** 473/**
474 * Callback called when a client connects to the service.
475 *
476 * @param cls closure for the service
477 * @param c the new client that connected to the service
478 * @param mq the message queue used to send messages to the client
479 * @return @a `struct ClientState`
480 */
481static void *
482client_connect_cb (void *cls,
483 struct GNUNET_SERVICE_Client *c,
484 struct GNUNET_MQ_Handle *mq)
485{
486 struct ClientState *cs;
487
488 cs = GNUNET_new (struct ClientState);
489 cs->client = c;
490 cs->mq = mq;
491 return cs;
492}
493
494
495/**
490 * Iterator over hash map entries to free element entries. 496 * Iterator over hash map entries to free element entries.
491 * 497 *
492 * @param cls closure 498 * @param cls closure
@@ -502,66 +508,76 @@ destroy_elements_iterator (void *cls,
502 struct ElementEntry *ee = value; 508 struct ElementEntry *ee = value;
503 509
504 GNUNET_free_non_null (ee->mutations); 510 GNUNET_free_non_null (ee->mutations);
505
506 GNUNET_free (ee); 511 GNUNET_free (ee);
507 return GNUNET_YES; 512 return GNUNET_YES;
508} 513}
509 514
510 515
511/** 516/**
512 * Destroy a set, and free all resources and operations associated with it. 517 * Clean up after a client has disconnected
513 * 518 *
514 * @param set the set to destroy 519 * @param cls closure, unused
520 * @param client the client to clean up after
521 * @param internal_cls the `struct ClientState`
515 */ 522 */
516static void 523static void
517set_destroy (struct Set *set) 524client_disconnect_cb (void *cls,
525 struct GNUNET_SERVICE_Client *client,
526 void *internal_cls)
518{ 527{
519 if (NULL != set->client) 528 struct ClientState *cs = internal_cls;
520 { 529 struct Operation *op;
521 /* If the client is not dead yet, destroy it. The client's destroy 530 struct Listener *listener;
522 * callback will call `set_destroy()` again in this case. We do 531 struct Set *set;
523 * this so that the channel end handler still has a valid set handle 532
524 * to destroy. */ 533 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
525 struct GNUNET_SERVICE_Client *client = set->client; 534 "Client disconnected, cleaning up\n");
526 535 if (NULL != (set = cs->set))
527 set->client = NULL;
528 GNUNET_SERVICE_client_drop (client);
529 return;
530 }
531 GNUNET_assert (NULL != set->state);
532 while (NULL != set->ops_head)
533 _GSS_operation_destroy (set->ops_head, GNUNET_NO);
534 set->vt->destroy_set (set->state);
535 set->state = NULL;
536 if (NULL != set->iter)
537 {
538 GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter);
539 set->iter = NULL;
540 set->iteration_id++;
541 }
542 { 536 {
543 struct SetContent *content; 537 struct SetContent *content = set->content;
544 struct PendingMutation *pm; 538 struct PendingMutation *pm;
545 struct PendingMutation *pm_current; 539 struct PendingMutation *pm_current;
540 struct LazyCopyRequest *lcr;
546 541
547 content = set->content; 542 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
543 "Destroying client's set\n");
544 /* Destroy pending set operations */
545 while (NULL != set->ops_head)
546 _GSS_operation_destroy (set->ops_head,
547 GNUNET_NO);
548
549 /* Destroy operation-specific state */
550 GNUNET_assert (NULL != set->state);
551 set->vt->destroy_set (set->state);
552 set->state = NULL;
553
554 /* Clean up ongoing iterations */
555 if (NULL != set->iter)
556 {
557 GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter);
558 set->iter = NULL;
559 set->iteration_id++;
560 }
548 561
549 // discard any pending mutations that reference this set 562 /* discard any pending mutations that reference this set */
550 pm = content->pending_mutations_head; 563 pm = content->pending_mutations_head;
551 while (NULL != pm) 564 while (NULL != pm)
552 { 565 {
553 pm_current = pm; 566 pm_current = pm;
554 pm = pm->next; 567 pm = pm->next;
555 if (pm_current-> set == set) 568 if (pm_current->set == set)
569 {
556 GNUNET_CONTAINER_DLL_remove (content->pending_mutations_head, 570 GNUNET_CONTAINER_DLL_remove (content->pending_mutations_head,
557 content->pending_mutations_tail, 571 content->pending_mutations_tail,
558 pm_current); 572 pm_current);
559 573 GNUNET_free (pm_current);
574 }
560 } 575 }
561 576
577 /* free set content (or at least decrement RC) */
562 set->content = NULL; 578 set->content = NULL;
563 GNUNET_assert (0 != content->refcount); 579 GNUNET_assert (0 != content->refcount);
564 content->refcount -= 1; 580 content->refcount--;
565 if (0 == content->refcount) 581 if (0 == content->refcount)
566 { 582 {
567 GNUNET_assert (NULL != content->elements); 583 GNUNET_assert (NULL != content->elements);
@@ -572,166 +588,41 @@ set_destroy (struct Set *set)
572 content->elements = NULL; 588 content->elements = NULL;
573 GNUNET_free (content); 589 GNUNET_free (content);
574 } 590 }
575 } 591 GNUNET_free_non_null (set->excluded_generations);
576 GNUNET_free_non_null (set->excluded_generations); 592 set->excluded_generations = NULL;
577 set->excluded_generations = NULL;
578 GNUNET_CONTAINER_DLL_remove (sets_head,
579 sets_tail,
580 set);
581 593
582 // remove set from pending copy requests 594 /* remove set from pending copy requests */
583 {
584 struct LazyCopyRequest *lcr;
585 lcr = lazy_copy_head; 595 lcr = lazy_copy_head;
586 while (NULL != lcr) 596 while (NULL != lcr)
587 { 597 {
588 struct LazyCopyRequest *lcr_current; 598 struct LazyCopyRequest *lcr_current = lcr;
589 lcr_current = lcr; 599
590 lcr = lcr->next; 600 lcr = lcr->next;
591 if (lcr_current->source_set == set) 601 if (lcr_current->source_set == set)
602 {
592 GNUNET_CONTAINER_DLL_remove (lazy_copy_head, 603 GNUNET_CONTAINER_DLL_remove (lazy_copy_head,
593 lazy_copy_tail, 604 lazy_copy_tail,
594 lcr_current); 605 lcr_current);
606 GNUNET_free (lcr_current);
607 }
595 } 608 }
609 GNUNET_free (set);
596 } 610 }
597 611
598 GNUNET_free (set); 612 if (NULL != (listener = cs->listener))
599}
600
601
602/**
603 * Callback called when a client connects to the service.
604 *
605 * @param cls closure for the service
606 * @param c the new client that connected to the service
607 * @param mq the message queue used to send messages to the client
608 * @return @a c
609 */
610static void *
611client_connect_cb (void *cls,
612 struct GNUNET_SERVICE_Client *c,
613 struct GNUNET_MQ_Handle *mq)
614{
615 return c;
616}
617
618
619/**
620 * Destroy an incoming request from a remote peer
621 *
622 * @param incoming remote request to destroy
623 */
624static void
625incoming_destroy (struct Operation *incoming)
626{
627 struct GNUNET_CADET_Channel *channel;
628
629 GNUNET_assert (GNUNET_YES == incoming->is_incoming);
630 GNUNET_CONTAINER_DLL_remove (incoming_head,
631 incoming_tail,
632 incoming);
633 if (NULL != incoming->timeout_task)
634 {
635 GNUNET_SCHEDULER_cancel (incoming->timeout_task);
636 incoming->timeout_task = NULL;
637 }
638 /* make sure that the tunnel end handler will not destroy us again */
639 incoming->vt = NULL;
640 if (NULL != incoming->spec)
641 {
642 GNUNET_free (incoming->spec);
643 incoming->spec = NULL;
644 }
645 if (NULL != (channel = incoming->channel))
646 {
647 incoming->channel = NULL;
648 GNUNET_CADET_channel_destroy (channel);
649 }
650}
651
652
653/**
654 * Clean up after a client has disconnected
655 *
656 * @param cls closure, unused
657 * @param client the client to clean up after
658 * @param internal_cls our client-specific internal data structure
659 */
660static void
661client_disconnect_cb (void *cls,
662 struct GNUNET_SERVICE_Client *client,
663 void *internal_cls)
664{
665 struct Set *set;
666
667 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
668 "client disconnected, cleaning up\n");
669 set = set_get (client);
670 if (NULL != set)
671 { 613 {
672 set->client = NULL;
673 set_destroy (set);
674 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 614 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
675 "Client's set destroyed\n"); 615 "Destroying client's listener\n");
676 } 616 GNUNET_CADET_close_port (listener->open_port);
677 struct Listener *listener = listener_get (client); 617 listener->open_port = NULL;
678 if (NULL != listener) 618 while (NULL != (op = listener->op_head))
679 { 619 incoming_destroy (op);
680 /* destroy all incoming operations whose client just 620 GNUNET_CONTAINER_DLL_remove (listener_head,
681 * got destroyed */ 621 listener_tail,
682 //struct Operation *op = incoming_head; 622 listener);
683 /* 623 GNUNET_free (listener);
684 while (NULL != op)
685 {
686 struct Operation *curr = op;
687 op = op->next;
688 if ( (GNUNET_YES == curr->is_incoming) &&
689 (curr->listener == listener) )
690 incoming_destroy (curr);
691 }
692 */
693 listener->client = NULL;
694 listener_destroy (listener);
695 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
696 "Client's listener destroyed\n");
697 } 624 }
698} 625 GNUNET_free (cs);
699
700
701/**
702 * Suggest the given request to the listener. The listening client can
703 * then accept or reject the remote request.
704 *
705 * @param incoming the incoming peer with the request to suggest
706 * @param listener the listener to suggest the request to
707 */
708static void
709incoming_suggest (struct Operation *incoming,
710 struct Listener *listener)
711{
712 struct GNUNET_MQ_Envelope *mqm;
713 struct GNUNET_SET_RequestMessage *cmsg;
714
715 GNUNET_assert (GNUNET_YES == incoming->is_incoming);
716 GNUNET_assert (NULL != incoming->spec);
717 GNUNET_assert (0 == incoming->suggest_id);
718 incoming->suggest_id = suggest_id++;
719 if (0 == suggest_id)
720 suggest_id++;
721 GNUNET_assert (NULL != incoming->timeout_task);
722 GNUNET_SCHEDULER_cancel (incoming->timeout_task);
723 incoming->timeout_task = NULL;
724 mqm = GNUNET_MQ_msg_nested_mh (cmsg,
725 GNUNET_MESSAGE_TYPE_SET_REQUEST,
726 incoming->spec->context_msg);
727 GNUNET_assert (NULL != mqm);
728 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
729 "Suggesting incoming request with accept id %u to listener\n",
730 incoming->suggest_id);
731 cmsg->accept_id = htonl (incoming->suggest_id);
732 cmsg->peer_id = incoming->spec->peer;
733 GNUNET_MQ_send (listener->client_mq,
734 mqm);
735} 626}
736 627
737 628
@@ -748,10 +639,22 @@ check_incoming_msg (void *cls,
748 const struct OperationRequestMessage *msg) 639 const struct OperationRequestMessage *msg)
749{ 640{
750 struct Operation *op = cls; 641 struct Operation *op = cls;
642 struct Listener *listener = op->listener;
751 const struct GNUNET_MessageHeader *nested_context; 643 const struct GNUNET_MessageHeader *nested_context;
752 644
753 /* double operation request */ 645 /* double operation request */
754 if (NULL != op->spec) 646 if (0 != op->suggest_id)
647 {
648 GNUNET_break_op (0);
649 return GNUNET_SYSERR;
650 }
651 /* This should be equivalent to the previous condition, but can't hurt to check twice */
652 if (NULL == op->listener)
653 {
654 GNUNET_break (0);
655 return GNUNET_SYSERR;
656 }
657 if (listener->operation != (enum GNUNET_SET_OperationType) ntohl (msg->operation))
755 { 658 {
756 GNUNET_break_op (0); 659 GNUNET_break_op (0);
757 return GNUNET_SYSERR; 660 return GNUNET_SYSERR;
@@ -790,61 +693,74 @@ handle_incoming_msg (void *cls,
790{ 693{
791 struct Operation *op = cls; 694 struct Operation *op = cls;
792 struct Listener *listener = op->listener; 695 struct Listener *listener = op->listener;
793 struct OperationSpecification *spec;
794 const struct GNUNET_MessageHeader *nested_context; 696 const struct GNUNET_MessageHeader *nested_context;
697 struct GNUNET_MQ_Envelope *env;
698 struct GNUNET_SET_RequestMessage *cmsg;
795 699
796 GNUNET_assert (GNUNET_YES == op->is_incoming);
797 spec = GNUNET_new (struct OperationSpecification);
798 nested_context = GNUNET_MQ_extract_nested_mh (msg); 700 nested_context = GNUNET_MQ_extract_nested_mh (msg);
799 /* Make a copy of the nested_context (application-specific context 701 /* Make a copy of the nested_context (application-specific context
800 information that is opaque to set) so we can pass it to the 702 information that is opaque to set) so we can pass it to the
801 listener later on */ 703 listener later on */
802 if (NULL != nested_context) 704 if (NULL != nested_context)
803 spec->context_msg = GNUNET_copy_message (nested_context); 705 op->context_msg = GNUNET_copy_message (nested_context);
804 spec->operation = ntohl (msg->operation); 706 op->remote_element_count = ntohl (msg->element_count);
805 spec->app_id = listener->app_id;
806 spec->salt = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
807 UINT32_MAX);
808 spec->peer = op->peer;
809 spec->remote_element_count = ntohl (msg->element_count);
810 op->spec = spec;
811 listener = op->listener;
812 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 707 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
813 "Received P2P operation request (op %u, port %s) for active listener\n", 708 "Received P2P operation request (op %u, port %s) for active listener\n",
814 (uint32_t) ntohl (msg->operation), 709 (uint32_t) ntohl (msg->operation),
815 GNUNET_h2s (&listener->app_id)); 710 GNUNET_h2s (&op->listener->app_id));
816 incoming_suggest (op, 711 GNUNET_assert (0 == op->suggest_id);
817 listener); 712 if (0 == suggest_id)
713 suggest_id++;
714 op->suggest_id = suggest_id++;
715 GNUNET_assert (NULL != op->timeout_task);
716 GNUNET_SCHEDULER_cancel (op->timeout_task);
717 op->timeout_task = NULL;
718 env = GNUNET_MQ_msg_nested_mh (cmsg,
719 GNUNET_MESSAGE_TYPE_SET_REQUEST,
720 op->context_msg);
721 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
722 "Suggesting incoming request with accept id %u to listener %p of client %p\n",
723 op->suggest_id,
724 listener,
725 listener->cs);
726 cmsg->accept_id = htonl (op->suggest_id);
727 cmsg->peer_id = op->peer;
728 GNUNET_MQ_send (listener->cs->mq,
729 env);
730 /* NOTE: GNUNET_CADET_receive_done() will be called in
731 #handle_client_accept() */
818} 732}
819 733
820 734
735/**
736 * Add an element to @a set as specified by @a msg
737 *
738 * @param set set to manipulate
739 * @param msg message specifying the change
740 */
821static void 741static void
822execute_add (struct Set *set, 742execute_add (struct Set *set,
823 const struct GNUNET_MessageHeader *m) 743 const struct GNUNET_SET_ElementMessage *msg)
824{ 744{
825 const struct GNUNET_SET_ElementMessage *msg;
826 struct GNUNET_SET_Element el; 745 struct GNUNET_SET_Element el;
827 struct ElementEntry *ee; 746 struct ElementEntry *ee;
828 struct GNUNET_HashCode hash; 747 struct GNUNET_HashCode hash;
829 748
830 GNUNET_assert (GNUNET_MESSAGE_TYPE_SET_ADD == ntohs (m->type)); 749 GNUNET_assert (GNUNET_MESSAGE_TYPE_SET_ADD == ntohs (msg->header.type));
831 750 el.size = ntohs (msg->header.size) - sizeof (*msg);
832 msg = (const struct GNUNET_SET_ElementMessage *) m;
833 el.size = ntohs (m->size) - sizeof *msg;
834 el.data = &msg[1]; 751 el.data = &msg[1];
835 el.element_type = ntohs (msg->element_type); 752 el.element_type = ntohs (msg->element_type);
836 GNUNET_SET_element_hash (&el, &hash); 753 GNUNET_SET_element_hash (&el,
837 754 &hash);
838 ee = GNUNET_CONTAINER_multihashmap_get (set->content->elements, 755 ee = GNUNET_CONTAINER_multihashmap_get (set->content->elements,
839 &hash); 756 &hash);
840
841 if (NULL == ee) 757 if (NULL == ee)
842 { 758 {
843 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 759 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
844 "Client inserts element %s of size %u\n", 760 "Client inserts element %s of size %u\n",
845 GNUNET_h2s (&hash), 761 GNUNET_h2s (&hash),
846 el.size); 762 el.size);
847 ee = GNUNET_malloc (el.size + sizeof *ee); 763 ee = GNUNET_malloc (el.size + sizeof (*ee));
848 ee->element.size = el.size; 764 ee->element.size = el.size;
849 GNUNET_memcpy (&ee[1], 765 GNUNET_memcpy (&ee[1],
850 el.data, 766 el.data,
@@ -861,7 +777,11 @@ execute_add (struct Set *set,
861 ee, 777 ee,
862 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 778 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
863 } 779 }
864 else if (GNUNET_YES == _GSS_is_element_of_set (ee, set)) 780 else if (GNUNET_YES ==
781 is_element_of_generation (ee,
782 set->current_generation,
783 set->excluded_generations,
784 set->excluded_generations_size))
865 { 785 {
866 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 786 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
867 "Client inserted element %s of size %u twice (ignored)\n", 787 "Client inserted element %s of size %u twice (ignored)\n",
@@ -881,24 +801,27 @@ execute_add (struct Set *set,
881 ee->mutations_size, 801 ee->mutations_size,
882 mut); 802 mut);
883 } 803 }
884 804 set->vt->add (set->state,
885 set->vt->add (set->state, ee); 805 ee);
886} 806}
887 807
888 808
809/**
810 * Remove an element from @a set as specified by @a msg
811 *
812 * @param set set to manipulate
813 * @param msg message specifying the change
814 */
889static void 815static void
890execute_remove (struct Set *set, 816execute_remove (struct Set *set,
891 const struct GNUNET_MessageHeader *m) 817 const struct GNUNET_SET_ElementMessage *msg)
892{ 818{
893 const struct GNUNET_SET_ElementMessage *msg;
894 struct GNUNET_SET_Element el; 819 struct GNUNET_SET_Element el;
895 struct ElementEntry *ee; 820 struct ElementEntry *ee;
896 struct GNUNET_HashCode hash; 821 struct GNUNET_HashCode hash;
897 822
898 GNUNET_assert (GNUNET_MESSAGE_TYPE_SET_REMOVE == ntohs (m->type)); 823 GNUNET_assert (GNUNET_MESSAGE_TYPE_SET_REMOVE == ntohs (msg->header.type));
899 824 el.size = ntohs (msg->header.size) - sizeof (*msg);
900 msg = (const struct GNUNET_SET_ElementMessage *) m;
901 el.size = ntohs (m->size) - sizeof *msg;
902 el.data = &msg[1]; 825 el.data = &msg[1];
903 el.element_type = ntohs (msg->element_type); 826 el.element_type = ntohs (msg->element_type);
904 GNUNET_SET_element_hash (&el, &hash); 827 GNUNET_SET_element_hash (&el, &hash);
@@ -912,7 +835,11 @@ execute_remove (struct Set *set,
912 el.size); 835 el.size);
913 return; 836 return;
914 } 837 }
915 if (GNUNET_NO == _GSS_is_element_of_set (ee, set)) 838 if (GNUNET_NO ==
839 is_element_of_generation (ee,
840 set->current_generation,
841 set->excluded_generations,
842 set->excluded_generations_size))
916 { 843 {
917 /* Client tried to remove element twice */ 844 /* Client tried to remove element twice */
918 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 845 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -935,22 +862,28 @@ execute_remove (struct Set *set,
935 ee->mutations_size, 862 ee->mutations_size,
936 mut); 863 mut);
937 } 864 }
938 set->vt->remove (set->state, ee); 865 set->vt->remove (set->state,
866 ee);
939} 867}
940 868
941 869
942 870/**
871 * Perform a mutation on a set as specified by the @a msg
872 *
873 * @param set the set to mutate
874 * @param msg specification of what to change
875 */
943static void 876static void
944execute_mutation (struct Set *set, 877execute_mutation (struct Set *set,
945 const struct GNUNET_MessageHeader *m) 878 const struct GNUNET_SET_ElementMessage *msg)
946{ 879{
947 switch (ntohs (m->type)) 880 switch (ntohs (msg->header.type))
948 { 881 {
949 case GNUNET_MESSAGE_TYPE_SET_ADD: 882 case GNUNET_MESSAGE_TYPE_SET_ADD:
950 execute_add (set, m); 883 execute_add (set, msg);
951 break; 884 break;
952 case GNUNET_MESSAGE_TYPE_SET_REMOVE: 885 case GNUNET_MESSAGE_TYPE_SET_REMOVE:
953 execute_remove (set, m); 886 execute_remove (set, msg);
954 break; 887 break;
955 default: 888 default:
956 GNUNET_break (0); 889 GNUNET_break (0);
@@ -958,6 +891,34 @@ execute_mutation (struct Set *set,
958} 891}
959 892
960 893
894/**
895 * Execute mutations that were delayed on a set because of
896 * pending operations.
897 *
898 * @param set the set to execute mutations on
899 */
900static void
901execute_delayed_mutations (struct Set *set)
902{
903 struct PendingMutation *pm;
904
905 if (0 != set->content->iterator_count)
906 return; /* still cannot do this */
907 while (NULL != (pm = set->content->pending_mutations_head))
908 {
909 GNUNET_CONTAINER_DLL_remove (set->content->pending_mutations_head,
910 set->content->pending_mutations_tail,
911 pm);
912 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
913 "Executing pending mutation on %p.\n",
914 pm->set);
915 execute_mutation (pm->set,
916 pm->msg);
917 GNUNET_free (pm->msg);
918 GNUNET_free (pm);
919 }
920}
921
961 922
962/** 923/**
963 * Send the next element of a set to the set's client. The next element is given by 924 * 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)
981 struct GNUNET_SET_IterResponseMessage *msg; 942 struct GNUNET_SET_IterResponseMessage *msg;
982 943
983 GNUNET_assert (NULL != set->iter); 944 GNUNET_assert (NULL != set->iter);
984 945 do {
985again: 946 ret = GNUNET_CONTAINER_multihashmap_iterator_next (set->iter,
986 947 NULL,
987 ret = GNUNET_CONTAINER_multihashmap_iterator_next (set->iter, 948 (const void **) &ee);
988 NULL, 949 if (GNUNET_NO == ret)
989 (const void **) &ee);
990 if (GNUNET_NO == ret)
991 {
992 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
993 "Iteration on %p done.\n",
994 (void *) set);
995 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_ITER_DONE);
996 GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter);
997 set->iter = NULL;
998 set->iteration_id++;
999
1000 GNUNET_assert (set->content->iterator_count > 0);
1001 set->content->iterator_count -= 1;
1002
1003 if (0 == set->content->iterator_count)
1004 { 950 {
1005 while (NULL != set->content->pending_mutations_head) 951 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1006 { 952 "Iteration on %p done.\n",
1007 struct PendingMutation *pm; 953 set);
1008 954 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_ITER_DONE);
1009 pm = set->content->pending_mutations_head; 955 GNUNET_CONTAINER_multihashmap_iterator_destroy (set->iter);
1010 GNUNET_CONTAINER_DLL_remove (set->content->pending_mutations_head, 956 set->iter = NULL;
1011 set->content->pending_mutations_tail, 957 set->iteration_id++;
1012 pm); 958 GNUNET_assert (set->content->iterator_count > 0);
1013 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 959 set->content->iterator_count--;
1014 "Executing pending mutation on %p.\n", 960 execute_delayed_mutations (set);
1015 (void *) pm->set); 961 GNUNET_MQ_send (set->cs->mq,
1016 execute_mutation (pm->set, pm->mutation_message); 962 ev);
1017 GNUNET_free (pm->mutation_message); 963 return;
1018 GNUNET_free (pm);
1019 }
1020 } 964 }
1021
1022 }
1023 else
1024 {
1025 GNUNET_assert (NULL != ee); 965 GNUNET_assert (NULL != ee);
1026 966 } while (GNUNET_NO ==
1027 if (GNUNET_NO == is_element_of_iteration (ee, set)) 967 is_element_of_generation (ee,
1028 goto again; 968 set->iter_generation,
1029 969 set->excluded_generations,
1030 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 970 set->excluded_generations_size));
1031 "Sending iteration element on %p.\n", 971 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1032 (void *) set); 972 "Sending iteration element on %p.\n",
1033 ev = GNUNET_MQ_msg_extra (msg, 973 set);
1034 ee->element.size, 974 ev = GNUNET_MQ_msg_extra (msg,
1035 GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT); 975 ee->element.size,
1036 GNUNET_memcpy (&msg[1], 976 GNUNET_MESSAGE_TYPE_SET_ITER_ELEMENT);
1037 ee->element.data, 977 GNUNET_memcpy (&msg[1],
1038 ee->element.size); 978 ee->element.data,
1039 msg->element_type = htons (ee->element.element_type); 979 ee->element.size);
1040 msg->iteration_id = htons (set->iteration_id); 980 msg->element_type = htons (ee->element.element_type);
1041 } 981 msg->iteration_id = htons (set->iteration_id);
1042 GNUNET_MQ_send (set->client_mq, ev); 982 GNUNET_MQ_send (set->cs->mq,
983 ev);
1043} 984}
1044 985
1045 986
@@ -1056,22 +997,21 @@ static void
1056handle_client_iterate (void *cls, 997handle_client_iterate (void *cls,
1057 const struct GNUNET_MessageHeader *m) 998 const struct GNUNET_MessageHeader *m)
1058{ 999{
1059 struct GNUNET_SERVICE_Client *client = cls; 1000 struct ClientState *cs = cls;
1060 struct Set *set; 1001 struct Set *set;
1061 1002
1062 set = set_get (client); 1003 if (NULL == (set = cs->set))
1063 if (NULL == set)
1064 { 1004 {
1065 /* attempt to iterate over a non existing set */ 1005 /* attempt to iterate over a non existing set */
1066 GNUNET_break (0); 1006 GNUNET_break (0);
1067 GNUNET_SERVICE_client_drop (client); 1007 GNUNET_SERVICE_client_drop (cs->client);
1068 return; 1008 return;
1069 } 1009 }
1070 if (NULL != set->iter) 1010 if (NULL != set->iter)
1071 { 1011 {
1072 /* Only one concurrent iterate-action allowed per set */ 1012 /* Only one concurrent iterate-action allowed per set */
1073 GNUNET_break (0); 1013 GNUNET_break (0);
1074 GNUNET_SERVICE_client_drop (client); 1014 GNUNET_SERVICE_client_drop (cs->client);
1075 return; 1015 return;
1076 } 1016 }
1077 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1017 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1079,8 +1019,8 @@ handle_client_iterate (void *cls,
1079 (void *) set, 1019 (void *) set,
1080 set->current_generation, 1020 set->current_generation,
1081 GNUNET_CONTAINER_multihashmap_size (set->content->elements)); 1021 GNUNET_CONTAINER_multihashmap_size (set->content->elements));
1082 GNUNET_SERVICE_client_continue (client); 1022 GNUNET_SERVICE_client_continue (cs->client);
1083 set->content->iterator_count += 1; 1023 set->content->iterator_count++;
1084 set->iter = GNUNET_CONTAINER_multihashmap_iterator_create (set->content->elements); 1024 set->iter = GNUNET_CONTAINER_multihashmap_iterator_create (set->content->elements);
1085 set->iter_generation = set->current_generation; 1025 set->iter_generation = set->current_generation;
1086 send_client_element (set); 1026 send_client_element (set);
@@ -1099,17 +1039,17 @@ static void
1099handle_client_create_set (void *cls, 1039handle_client_create_set (void *cls,
1100 const struct GNUNET_SET_CreateMessage *msg) 1040 const struct GNUNET_SET_CreateMessage *msg)
1101{ 1041{
1102 struct GNUNET_SERVICE_Client *client = cls; 1042 struct ClientState *cs = cls;
1103 struct Set *set; 1043 struct Set *set;
1104 1044
1105 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1045 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1106 "Client created new set (operation %u)\n", 1046 "Client created new set (operation %u)\n",
1107 (uint32_t) ntohl (msg->operation)); 1047 (uint32_t) ntohl (msg->operation));
1108 if (NULL != set_get (client)) 1048 if (NULL != cs->set)
1109 { 1049 {
1110 /* There can only be one set per client */ 1050 /* There can only be one set per client */
1111 GNUNET_break (0); 1051 GNUNET_break (0);
1112 GNUNET_SERVICE_client_drop (client); 1052 GNUNET_SERVICE_client_drop (cs->client);
1113 return; 1053 return;
1114 } 1054 }
1115 set = GNUNET_new (struct Set); 1055 set = GNUNET_new (struct Set);
@@ -1117,36 +1057,32 @@ handle_client_create_set (void *cls,
1117 { 1057 {
1118 case GNUNET_SET_OPERATION_INTERSECTION: 1058 case GNUNET_SET_OPERATION_INTERSECTION:
1119 set->vt = _GSS_intersection_vt (); 1059 set->vt = _GSS_intersection_vt ();
1120 set->type = OT_INTERSECTION;
1121 break; 1060 break;
1122 case GNUNET_SET_OPERATION_UNION: 1061 case GNUNET_SET_OPERATION_UNION:
1123 set->vt = _GSS_union_vt (); 1062 set->vt = _GSS_union_vt ();
1124 set->type = OT_UNION;
1125 break; 1063 break;
1126 default: 1064 default:
1127 GNUNET_free (set); 1065 GNUNET_free (set);
1128 GNUNET_break (0); 1066 GNUNET_break (0);
1129 GNUNET_SERVICE_client_drop (client); 1067 GNUNET_SERVICE_client_drop (cs->client);
1130 return; 1068 return;
1131 } 1069 }
1132 set->operation = ntohl (msg->operation); 1070 set->operation = (enum GNUNET_SET_OperationType) ntohl (msg->operation);
1133 set->state = set->vt->create (); 1071 set->state = set->vt->create ();
1134 if (NULL == set->state) 1072 if (NULL == set->state)
1135 { 1073 {
1136 /* initialization failed (i.e. out of memory) */ 1074 /* initialization failed (i.e. out of memory) */
1137 GNUNET_free (set); 1075 GNUNET_free (set);
1138 GNUNET_SERVICE_client_drop (client); 1076 GNUNET_SERVICE_client_drop (cs->client);
1139 return; 1077 return;
1140 } 1078 }
1141 set->content = GNUNET_new (struct SetContent); 1079 set->content = GNUNET_new (struct SetContent);
1142 set->content->refcount = 1; 1080 set->content->refcount = 1;
1143 set->content->elements = GNUNET_CONTAINER_multihashmap_create (1, GNUNET_YES); 1081 set->content->elements = GNUNET_CONTAINER_multihashmap_create (1,
1144 set->client = client; 1082 GNUNET_YES);
1145 set->client_mq = GNUNET_SERVICE_client_get_mq (client); 1083 set->cs = cs;
1146 GNUNET_CONTAINER_DLL_insert (sets_head, 1084 cs->set = set;
1147 sets_tail, 1085 GNUNET_SERVICE_client_continue (cs->client);
1148 set);
1149 GNUNET_SERVICE_client_continue (client);
1150} 1086}
1151 1087
1152 1088
@@ -1162,31 +1098,12 @@ handle_client_create_set (void *cls,
1162static void 1098static void
1163incoming_timeout_cb (void *cls) 1099incoming_timeout_cb (void *cls)
1164{ 1100{
1165 struct Operation *incoming = cls; 1101 struct Operation *op = cls;
1166 1102
1167 incoming->timeout_task = NULL; 1103 op->timeout_task = NULL;
1168 GNUNET_assert (GNUNET_YES == incoming->is_incoming);
1169 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1104 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1170 "Remote peer's incoming request timed out\n"); 1105 "Remote peer's incoming request timed out\n");
1171 incoming_destroy (incoming);
1172}
1173
1174
1175/**
1176 * Terminates an incoming operation in case we have not yet received an
1177 * operation request. Called by the channel destruction handler.
1178 *
1179 * @param op the channel context
1180 */
1181static void
1182handle_incoming_disconnect (struct Operation *op)
1183{
1184 GNUNET_assert (GNUNET_YES == op->is_incoming);
1185 /* channel is already dead, incoming_destroy must not
1186 * destroy it ... */
1187 op->channel = NULL;
1188 incoming_destroy (op); 1106 incoming_destroy (op);
1189 op->vt = NULL;
1190} 1107}
1191 1108
1192 1109
@@ -1211,31 +1128,26 @@ channel_new_cb (void *cls,
1211 struct GNUNET_CADET_Channel *channel, 1128 struct GNUNET_CADET_Channel *channel,
1212 const struct GNUNET_PeerIdentity *source) 1129 const struct GNUNET_PeerIdentity *source)
1213{ 1130{
1214 static const struct SetVT incoming_vt = {
1215 .peer_disconnect = &handle_incoming_disconnect
1216 };
1217 struct Listener *listener = cls; 1131 struct Listener *listener = cls;
1218 struct Operation *incoming; 1132 struct Operation *op;
1219 1133
1220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1134 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1221 "New incoming channel\n"); 1135 "New incoming channel\n");
1222 incoming = GNUNET_new (struct Operation); 1136 op = GNUNET_new (struct Operation);
1223 incoming->listener = listener; 1137 op->listener = listener;
1224 incoming->is_incoming = GNUNET_YES; 1138 op->peer = *source;
1225 incoming->peer = *source; 1139 op->channel = channel;
1226 incoming->channel = channel; 1140 op->mq = GNUNET_CADET_get_mq (op->channel);
1227 incoming->mq = GNUNET_CADET_get_mq (incoming->channel); 1141 op->salt = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
1228 incoming->vt = &incoming_vt; 1142 UINT32_MAX);
1229 incoming->timeout_task 1143 op->timeout_task
1230 = GNUNET_SCHEDULER_add_delayed (INCOMING_CHANNEL_TIMEOUT, 1144 = GNUNET_SCHEDULER_add_delayed (INCOMING_CHANNEL_TIMEOUT,
1231 &incoming_timeout_cb, 1145 &incoming_timeout_cb,
1232 incoming); 1146 op);
1233 GNUNET_CONTAINER_DLL_insert_tail (incoming_head, 1147 GNUNET_CONTAINER_DLL_insert (listener->op_head,
1234 incoming_tail, 1148 listener->op_tail,
1235 incoming); 1149 op);
1236 // incoming_suggest (incoming, 1150 return op;
1237 // listener);
1238 return incoming;
1239} 1151}
1240 1152
1241 1153
@@ -1264,22 +1176,14 @@ channel_end_cb (void *channel_ctx,
1264 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1176 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1265 "channel_end_cb called\n"); 1177 "channel_end_cb called\n");
1266 op->channel = NULL; 1178 op->channel = NULL;
1267 op->keep++; 1179 if (NULL != op->listener)
1268 /* the vt can be null if a client already requested canceling op. */ 1180 incoming_destroy (op);
1269 if (NULL != op->vt) 1181 else if (NULL != op->set)
1270 { 1182 op->set->vt->channel_death (op);
1271 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1183 else
1272 "calling peer disconnect due to channel end\n"); 1184 _GSS_operation_destroy (op,
1273 op->vt->peer_disconnect (op); 1185 GNUNET_YES);
1274 } 1186 GNUNET_free (op);
1275 op->keep--;
1276 if (0 == op->keep)
1277 {
1278 /* cadet will never call us with the context again! */
1279 GNUNET_free (op);
1280 }
1281 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1282 "channel_end_cb finished\n");
1283} 1187}
1284 1188
1285 1189
@@ -1316,7 +1220,7 @@ static void
1316handle_client_listen (void *cls, 1220handle_client_listen (void *cls,
1317 const struct GNUNET_SET_ListenMessage *msg) 1221 const struct GNUNET_SET_ListenMessage *msg)
1318{ 1222{
1319 struct GNUNET_SERVICE_Client *client = cls; 1223 struct ClientState *cs = cls;
1320 struct GNUNET_MQ_MessageHandler cadet_handlers[] = { 1224 struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1321 GNUNET_MQ_hd_var_size (incoming_msg, 1225 GNUNET_MQ_hd_var_size (incoming_msg,
1322 GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST, 1226 GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST,
@@ -1382,50 +1286,33 @@ handle_client_listen (void *cls,
1382 }; 1286 };
1383 struct Listener *listener; 1287 struct Listener *listener;
1384 1288
1385 if (NULL != listener_get (client)) 1289 if (NULL != cs->listener)
1386 { 1290 {
1387 /* max. one active listener per client! */ 1291 /* max. one active listener per client! */
1388 GNUNET_break (0); 1292 GNUNET_break (0);
1389 GNUNET_SERVICE_client_drop (client); 1293 GNUNET_SERVICE_client_drop (cs->client);
1390 return; 1294 return;
1391 } 1295 }
1392 listener = GNUNET_new (struct Listener); 1296 listener = GNUNET_new (struct Listener);
1393 listener->client = client; 1297 listener->cs = cs;
1394 listener->client_mq = GNUNET_SERVICE_client_get_mq (client);
1395 listener->app_id = msg->app_id; 1298 listener->app_id = msg->app_id;
1396 listener->operation = ntohl (msg->operation); 1299 listener->operation = (enum GNUNET_SET_OperationType) ntohl (msg->operation);
1397 GNUNET_CONTAINER_DLL_insert_tail (listeners_head, 1300 GNUNET_CONTAINER_DLL_insert (listener_head,
1398 listeners_tail, 1301 listener_tail,
1399 listener); 1302 listener);
1400 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1303 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1401 "New listener created (op %u, port %s)\n", 1304 "New listener created (op %u, port %s)\n",
1402 listener->operation, 1305 listener->operation,
1403 GNUNET_h2s (&listener->app_id)); 1306 GNUNET_h2s (&listener->app_id));
1404 listener->open_port = GNUNET_CADET_open_porT (cadet, 1307 listener->open_port
1405 &msg->app_id, 1308 = GNUNET_CADET_open_port (cadet,
1406 &channel_new_cb, 1309 &msg->app_id,
1407 listener, 1310 &channel_new_cb,
1408 &channel_window_cb, 1311 listener,
1409 &channel_end_cb, 1312 &channel_window_cb,
1410 cadet_handlers); 1313 &channel_end_cb,
1411 /* check for existing incoming requests the listener might be interested in */ 1314 cadet_handlers);
1412 for (struct Operation *op = incoming_head; NULL != op; op = op->next) 1315 GNUNET_SERVICE_client_continue (cs->client);
1413 {
1414 if (NULL == op->spec)
1415 continue; /* no details available yet */
1416 if (0 != op->suggest_id)
1417 continue; /* this one has been already suggested to a listener */
1418 if (listener->operation != op->spec->operation)
1419 continue; /* incompatible operation */
1420 if (0 != GNUNET_CRYPTO_hash_cmp (&listener->app_id,
1421 &op->spec->app_id))
1422 continue; /* incompatible appliation */
1423 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1424 "Found matching existing request\n");
1425 incoming_suggest (op,
1426 listener);
1427 }
1428 GNUNET_SERVICE_client_continue (client);
1429} 1316}
1430 1317
1431 1318
@@ -1440,23 +1327,26 @@ static void
1440handle_client_reject (void *cls, 1327handle_client_reject (void *cls,
1441 const struct GNUNET_SET_RejectMessage *msg) 1328 const struct GNUNET_SET_RejectMessage *msg)
1442{ 1329{
1443 struct GNUNET_SERVICE_Client *client = cls; 1330 struct ClientState *cs = cls;
1444 struct Operation *incoming; 1331 struct Operation *op;
1445 1332
1446 incoming = get_incoming (ntohl (msg->accept_reject_id)); 1333 op = get_incoming (ntohl (msg->accept_reject_id));
1447 if (NULL == incoming) 1334 if (NULL == op)
1448 { 1335 {
1449 /* no matching incoming operation for this reject */ 1336 /* no matching incoming operation for this reject;
1450 GNUNET_break (0); 1337 could be that the other peer already disconnected... */
1451 GNUNET_SERVICE_client_drop (client); 1338 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1339 "Client rejected unknown operation %u\n",
1340 (unsigned int) ntohl (msg->accept_reject_id));
1341 GNUNET_SERVICE_client_continue (cs->client);
1452 return; 1342 return;
1453 } 1343 }
1454 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1344 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1455 "Peer request (op %u, app %s) rejected by client\n", 1345 "Peer request (op %u, app %s) rejected by client\n",
1456 incoming->spec->operation, 1346 op->listener->operation,
1457 GNUNET_h2s (&incoming->spec->app_id)); 1347 GNUNET_h2s (&cs->listener->app_id));
1458 GNUNET_CADET_channel_destroy (incoming->channel); 1348 GNUNET_CADET_channel_destroy (op->channel);
1459 GNUNET_SERVICE_client_continue (client); 1349 GNUNET_SERVICE_client_continue (cs->client);
1460} 1350}
1461 1351
1462 1352
@@ -1464,13 +1354,14 @@ handle_client_reject (void *cls,
1464 * Called when a client wants to add or remove an element to a set it inhabits. 1354 * Called when a client wants to add or remove an element to a set it inhabits.
1465 * 1355 *
1466 * @param cls client that sent the message 1356 * @param cls client that sent the message
1467 * @param m message sent by the client 1357 * @param msg message sent by the client
1468 */ 1358 */
1469static int 1359static int
1470check_client_mutation (void *cls, 1360check_client_mutation (void *cls,
1471 const struct GNUNET_MessageHeader *m) 1361 const struct GNUNET_SET_ElementMessage *msg)
1472{ 1362{
1473 /* FIXME: any check we might want to do here? */ 1363 /* NOTE: Technically, we should probably check with the
1364 block library whether the element we are given is well-formed */
1474 return GNUNET_OK; 1365 return GNUNET_OK;
1475} 1366}
1476 1367
@@ -1479,25 +1370,23 @@ check_client_mutation (void *cls,
1479 * Called when a client wants to add or remove an element to a set it inhabits. 1370 * Called when a client wants to add or remove an element to a set it inhabits.
1480 * 1371 *
1481 * @param cls client that sent the message 1372 * @param cls client that sent the message
1482 * @param m message sent by the client 1373 * @param msg message sent by the client
1483 */ 1374 */
1484static void 1375static void
1485handle_client_mutation (void *cls, 1376handle_client_mutation (void *cls,
1486 const struct GNUNET_MessageHeader *m) 1377 const struct GNUNET_SET_ElementMessage *msg)
1487{ 1378{
1488 struct GNUNET_SERVICE_Client *client = cls; 1379 struct ClientState *cs = cls;
1489 struct Set *set; 1380 struct Set *set;
1490 1381
1491 set = set_get (client); 1382 if (NULL == (set = cs->set))
1492 if (NULL == set)
1493 { 1383 {
1494 /* client without a set requested an operation */ 1384 /* client without a set requested an operation */
1495 GNUNET_break (0); 1385 GNUNET_break (0);
1496 GNUNET_SERVICE_client_drop (client); 1386 GNUNET_SERVICE_client_drop (cs->client);
1497 return; 1387 return;
1498 } 1388 }
1499 1389 GNUNET_SERVICE_client_continue (cs->client);
1500 GNUNET_SERVICE_client_continue (client);
1501 1390
1502 if (0 != set->content->iterator_count) 1391 if (0 != set->content->iterator_count)
1503 { 1392 {
@@ -1505,16 +1394,18 @@ handle_client_mutation (void *cls,
1505 1394
1506 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1395 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1507 "Scheduling mutation on set\n"); 1396 "Scheduling mutation on set\n");
1508
1509 pm = GNUNET_new (struct PendingMutation); 1397 pm = GNUNET_new (struct PendingMutation);
1510 pm->mutation_message = GNUNET_copy_message (m); 1398 pm->msg = (struct GNUNET_SET_ElementMessage *) GNUNET_copy_message (&msg->header);
1511 pm->set = set; 1399 pm->set = set;
1512 GNUNET_CONTAINER_DLL_insert_tail (set->content->pending_mutations_head, 1400 GNUNET_CONTAINER_DLL_insert_tail (set->content->pending_mutations_head,
1513 set->content->pending_mutations_tail, 1401 set->content->pending_mutations_tail,
1514 pm); 1402 pm);
1515 return; 1403 return;
1516 } 1404 }
1517 execute_mutation (set, m); 1405 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1406 "Executing mutation on set\n");
1407 execute_mutation (set,
1408 msg);
1518} 1409}
1519 1410
1520 1411
@@ -1531,8 +1422,8 @@ advance_generation (struct Set *set)
1531 1422
1532 if (set->current_generation == set->content->latest_generation) 1423 if (set->current_generation == set->content->latest_generation)
1533 { 1424 {
1534 set->content->latest_generation += 1; 1425 set->content->latest_generation++;
1535 set->current_generation += 1; 1426 set->current_generation++;
1536 return; 1427 return;
1537 } 1428 }
1538 1429
@@ -1540,10 +1431,8 @@ advance_generation (struct Set *set)
1540 1431
1541 r.start = set->current_generation + 1; 1432 r.start = set->current_generation + 1;
1542 r.end = set->content->latest_generation + 1; 1433 r.end = set->content->latest_generation + 1;
1543
1544 set->content->latest_generation = r.end; 1434 set->content->latest_generation = r.end;
1545 set->current_generation = r.end; 1435 set->current_generation = r.end;
1546
1547 GNUNET_array_append (set->excluded_generations, 1436 GNUNET_array_append (set->excluded_generations,
1548 set->excluded_generations_size, 1437 set->excluded_generations_size,
1549 r); 1438 r);
@@ -1581,7 +1470,7 @@ static void
1581handle_client_evaluate (void *cls, 1470handle_client_evaluate (void *cls,
1582 const struct GNUNET_SET_EvaluateMessage *msg) 1471 const struct GNUNET_SET_EvaluateMessage *msg)
1583{ 1472{
1584 struct GNUNET_SERVICE_Client *client = cls; 1473 struct ClientState *cs = cls;
1585 struct Operation *op = GNUNET_new (struct Operation); 1474 struct Operation *op = GNUNET_new (struct Operation);
1586 const struct GNUNET_MQ_MessageHandler cadet_handlers[] = { 1475 const struct GNUNET_MQ_MessageHandler cadet_handlers[] = {
1587 GNUNET_MQ_hd_var_size (incoming_msg, 1476 GNUNET_MQ_hd_var_size (incoming_msg,
@@ -1647,46 +1536,39 @@ handle_client_evaluate (void *cls,
1647 GNUNET_MQ_handler_end () 1536 GNUNET_MQ_handler_end ()
1648 }; 1537 };
1649 struct Set *set; 1538 struct Set *set;
1650 struct OperationSpecification *spec;
1651 const struct GNUNET_MessageHeader *context; 1539 const struct GNUNET_MessageHeader *context;
1652 1540
1653 set = set_get (client); 1541 if (NULL == (set = cs->set))
1654 if (NULL == set)
1655 { 1542 {
1656 GNUNET_break (0); 1543 GNUNET_break (0);
1657 GNUNET_free (op); 1544 GNUNET_free (op);
1658 GNUNET_SERVICE_client_drop (client); 1545 GNUNET_SERVICE_client_drop (cs->client);
1659 return; 1546 return;
1660 } 1547 }
1661 spec = GNUNET_new (struct OperationSpecification); 1548 op->salt = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
1662 spec->operation = set->operation; 1549 UINT32_MAX);
1663 spec->app_id = msg->app_id; 1550 op->peer = msg->target_peer;
1664 spec->salt = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, 1551 op->result_mode = ntohl (msg->result_mode);
1665 UINT32_MAX); 1552 op->client_request_id = ntohl (msg->request_id);
1666 spec->peer = msg->target_peer; 1553 op->byzantine = msg->byzantine;
1667 spec->set = set; 1554 op->byzantine_lower_bound = msg->byzantine_lower_bound;
1668 spec->result_mode = ntohl (msg->result_mode); 1555 op->force_full = msg->force_full;
1669 spec->client_request_id = ntohl (msg->request_id); 1556 op->force_delta = msg->force_delta;
1670 spec->byzantine = msg->byzantine;
1671 spec->byzantine_lower_bound = msg->byzantine_lower_bound;
1672 spec->force_full = msg->force_full;
1673 spec->force_delta = msg->force_delta;
1674 context = GNUNET_MQ_extract_nested_mh (msg); 1557 context = GNUNET_MQ_extract_nested_mh (msg);
1675 op->spec = spec;
1676 1558
1677 // Advance generation values, so that 1559 /* Advance generation values, so that
1678 // mutations won't interfer with the running operation. 1560 mutations won't interfer with the running operation. */
1561 op->set = set;
1679 op->generation_created = set->current_generation; 1562 op->generation_created = set->current_generation;
1680 advance_generation (set); 1563 advance_generation (set);
1681 op->type = set->type;
1682 op->vt = set->vt;
1683 GNUNET_CONTAINER_DLL_insert (set->ops_head, 1564 GNUNET_CONTAINER_DLL_insert (set->ops_head,
1684 set->ops_tail, 1565 set->ops_tail,
1685 op); 1566 op);
1686 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1567 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1687 "Creating new CADET channel to port %s\n", 1568 "Creating new CADET channel to port %s for set operation type %u\n",
1688 GNUNET_h2s (&msg->app_id)); 1569 GNUNET_h2s (&msg->app_id),
1689 op->channel = GNUNET_CADET_channel_creatE (cadet, 1570 set->operation);
1571 op->channel = GNUNET_CADET_channel_create (cadet,
1690 op, 1572 op,
1691 &msg->target_peer, 1573 &msg->target_peer,
1692 &msg->app_id, 1574 &msg->app_id,
@@ -1695,9 +1577,15 @@ handle_client_evaluate (void *cls,
1695 &channel_end_cb, 1577 &channel_end_cb,
1696 cadet_handlers); 1578 cadet_handlers);
1697 op->mq = GNUNET_CADET_get_mq (op->channel); 1579 op->mq = GNUNET_CADET_get_mq (op->channel);
1698 set->vt->evaluate (op, 1580 op->state = set->vt->evaluate (op,
1699 context); 1581 context);
1700 GNUNET_SERVICE_client_continue (client); 1582 if (NULL == op->state)
1583 {
1584 GNUNET_break (0);
1585 GNUNET_SERVICE_client_drop (cs->client);
1586 return;
1587 }
1588 GNUNET_SERVICE_client_continue (cs->client);
1701} 1589}
1702 1590
1703 1591
@@ -1713,15 +1601,14 @@ static void
1713handle_client_iter_ack (void *cls, 1601handle_client_iter_ack (void *cls,
1714 const struct GNUNET_SET_IterAckMessage *ack) 1602 const struct GNUNET_SET_IterAckMessage *ack)
1715{ 1603{
1716 struct GNUNET_SERVICE_Client *client = cls; 1604 struct ClientState *cs = cls;
1717 struct Set *set; 1605 struct Set *set;
1718 1606
1719 set = set_get (client); 1607 if (NULL == (set = cs->set))
1720 if (NULL == set)
1721 { 1608 {
1722 /* client without a set acknowledged receiving a value */ 1609 /* client without a set acknowledged receiving a value */
1723 GNUNET_break (0); 1610 GNUNET_break (0);
1724 GNUNET_SERVICE_client_drop (client); 1611 GNUNET_SERVICE_client_drop (cs->client);
1725 return; 1612 return;
1726 } 1613 }
1727 if (NULL == set->iter) 1614 if (NULL == set->iter)
@@ -1729,10 +1616,10 @@ handle_client_iter_ack (void *cls,
1729 /* client sent an ack, but we were not expecting one (as 1616 /* client sent an ack, but we were not expecting one (as
1730 set iteration has finished) */ 1617 set iteration has finished) */
1731 GNUNET_break (0); 1618 GNUNET_break (0);
1732 GNUNET_SERVICE_client_drop (client); 1619 GNUNET_SERVICE_client_drop (cs->client);
1733 return; 1620 return;
1734 } 1621 }
1735 GNUNET_SERVICE_client_continue (client); 1622 GNUNET_SERVICE_client_continue (cs->client);
1736 if (ntohl (ack->send_more)) 1623 if (ntohl (ack->send_more))
1737 { 1624 {
1738 send_client_element (set); 1625 send_client_element (set);
@@ -1756,42 +1643,33 @@ static void
1756handle_client_copy_lazy_prepare (void *cls, 1643handle_client_copy_lazy_prepare (void *cls,
1757 const struct GNUNET_MessageHeader *mh) 1644 const struct GNUNET_MessageHeader *mh)
1758{ 1645{
1759 struct GNUNET_SERVICE_Client *client = cls; 1646 struct ClientState *cs = cls;
1760 struct Set *set; 1647 struct Set *set;
1761 struct LazyCopyRequest *cr; 1648 struct LazyCopyRequest *cr;
1762 struct GNUNET_MQ_Envelope *ev; 1649 struct GNUNET_MQ_Envelope *ev;
1763 struct GNUNET_SET_CopyLazyResponseMessage *resp_msg; 1650 struct GNUNET_SET_CopyLazyResponseMessage *resp_msg;
1764 1651
1765 set = set_get (client); 1652 if (NULL == (set = cs->set))
1766 if (NULL == set)
1767 { 1653 {
1768 /* client without a set requested an operation */ 1654 /* client without a set requested an operation */
1769 GNUNET_break (0); 1655 GNUNET_break (0);
1770 GNUNET_SERVICE_client_drop (client); 1656 GNUNET_SERVICE_client_drop (cs->client);
1771 return; 1657 return;
1772 } 1658 }
1773 1659 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1660 "Client requested creation of lazy copy\n");
1774 cr = GNUNET_new (struct LazyCopyRequest); 1661 cr = GNUNET_new (struct LazyCopyRequest);
1775 1662 cr->cookie = ++lazy_copy_cookie;
1776 cr->cookie = lazy_copy_cookie;
1777 lazy_copy_cookie += 1;
1778 cr->source_set = set; 1663 cr->source_set = set;
1779
1780 GNUNET_CONTAINER_DLL_insert (lazy_copy_head, 1664 GNUNET_CONTAINER_DLL_insert (lazy_copy_head,
1781 lazy_copy_tail, 1665 lazy_copy_tail,
1782 cr); 1666 cr);
1783
1784
1785 ev = GNUNET_MQ_msg (resp_msg, 1667 ev = GNUNET_MQ_msg (resp_msg,
1786 GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE); 1668 GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_RESPONSE);
1787 resp_msg->cookie = cr->cookie; 1669 resp_msg->cookie = cr->cookie;
1788 GNUNET_MQ_send (set->client_mq, ev); 1670 GNUNET_MQ_send (set->cs->mq,
1789 1671 ev);
1790 1672 GNUNET_SERVICE_client_continue (cs->client);
1791 GNUNET_SERVICE_client_continue (client);
1792
1793 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1794 "Client requested lazy copy\n");
1795} 1673}
1796 1674
1797 1675
@@ -1805,21 +1683,19 @@ static void
1805handle_client_copy_lazy_connect (void *cls, 1683handle_client_copy_lazy_connect (void *cls,
1806 const struct GNUNET_SET_CopyLazyConnectMessage *msg) 1684 const struct GNUNET_SET_CopyLazyConnectMessage *msg)
1807{ 1685{
1808 struct GNUNET_SERVICE_Client *client = cls; 1686 struct ClientState *cs = cls;
1809 struct LazyCopyRequest *cr; 1687 struct LazyCopyRequest *cr;
1810 struct Set *set; 1688 struct Set *set;
1811 int found; 1689 int found;
1812 1690
1813 if (NULL != set_get (client)) 1691 if (NULL != cs->set)
1814 { 1692 {
1815 /* There can only be one set per client */ 1693 /* There can only be one set per client */
1816 GNUNET_break (0); 1694 GNUNET_break (0);
1817 GNUNET_SERVICE_client_drop (client); 1695 GNUNET_SERVICE_client_drop (cs->client);
1818 return; 1696 return;
1819 } 1697 }
1820
1821 found = GNUNET_NO; 1698 found = GNUNET_NO;
1822
1823 for (cr = lazy_copy_head; NULL != cr; cr = cr->next) 1699 for (cr = lazy_copy_head; NULL != cr; cr = cr->next)
1824 { 1700 {
1825 if (cr->cookie == msg->cookie) 1701 if (cr->cookie == msg->cookie)
@@ -1828,30 +1704,27 @@ handle_client_copy_lazy_connect (void *cls,
1828 break; 1704 break;
1829 } 1705 }
1830 } 1706 }
1831
1832 if (GNUNET_NO == found) 1707 if (GNUNET_NO == found)
1833 { 1708 {
1834 /* client asked for copy with cookie we don't know */ 1709 /* client asked for copy with cookie we don't know */
1835 GNUNET_break (0); 1710 GNUNET_break (0);
1836 GNUNET_SERVICE_client_drop (client); 1711 GNUNET_SERVICE_client_drop (cs->client);
1837 return; 1712 return;
1838 } 1713 }
1839
1840 GNUNET_CONTAINER_DLL_remove (lazy_copy_head, 1714 GNUNET_CONTAINER_DLL_remove (lazy_copy_head,
1841 lazy_copy_tail, 1715 lazy_copy_tail,
1842 cr); 1716 cr);
1843 1717 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1718 "Client %p requested use of lazy copy\n",
1719 cs);
1844 set = GNUNET_new (struct Set); 1720 set = GNUNET_new (struct Set);
1845
1846 switch (cr->source_set->operation) 1721 switch (cr->source_set->operation)
1847 { 1722 {
1848 case GNUNET_SET_OPERATION_INTERSECTION: 1723 case GNUNET_SET_OPERATION_INTERSECTION:
1849 set->vt = _GSS_intersection_vt (); 1724 set->vt = _GSS_intersection_vt ();
1850 set->type = OT_INTERSECTION;
1851 break; 1725 break;
1852 case GNUNET_SET_OPERATION_UNION: 1726 case GNUNET_SET_OPERATION_UNION:
1853 set->vt = _GSS_union_vt (); 1727 set->vt = _GSS_union_vt ();
1854 set->type = OT_UNION;
1855 break; 1728 break;
1856 default: 1729 default:
1857 GNUNET_assert (0); 1730 GNUNET_assert (0);
@@ -1864,37 +1737,28 @@ handle_client_copy_lazy_connect (void *cls,
1864 GNUNET_break (0); 1737 GNUNET_break (0);
1865 GNUNET_free (set); 1738 GNUNET_free (set);
1866 GNUNET_free (cr); 1739 GNUNET_free (cr);
1867 GNUNET_SERVICE_client_drop (client); 1740 GNUNET_SERVICE_client_drop (cs->client);
1868 return; 1741 return;
1869 } 1742 }
1870 1743
1871 set->operation = cr->source_set->operation; 1744 set->operation = cr->source_set->operation;
1872 set->state = set->vt->copy_state (cr->source_set); 1745 set->state = set->vt->copy_state (cr->source_set->state);
1873 set->content = cr->source_set->content; 1746 set->content = cr->source_set->content;
1874 set->content->refcount += 1; 1747 set->content->refcount++;
1875 1748
1876 set->current_generation = cr->source_set->current_generation; 1749 set->current_generation = cr->source_set->current_generation;
1877 set->excluded_generations_size = cr->source_set->excluded_generations_size; 1750 set->excluded_generations_size = cr->source_set->excluded_generations_size;
1878 set->excluded_generations = GNUNET_memdup (cr->source_set->excluded_generations, 1751 set->excluded_generations
1879 set->excluded_generations_size * sizeof (struct GenerationRange)); 1752 = GNUNET_memdup (cr->source_set->excluded_generations,
1753 set->excluded_generations_size * sizeof (struct GenerationRange));
1880 1754
1881 /* Advance the generation of the new set, so that mutations to the 1755 /* Advance the generation of the new set, so that mutations to the
1882 of the cloned set and the source set are independent. */ 1756 of the cloned set and the source set are independent. */
1883 advance_generation (set); 1757 advance_generation (set);
1884 1758 set->cs = cs;
1885 1759 cs->set = set;
1886 set->client = client;
1887 set->client_mq = GNUNET_SERVICE_client_get_mq (client);
1888 GNUNET_CONTAINER_DLL_insert (sets_head,
1889 sets_tail,
1890 set);
1891
1892 GNUNET_free (cr); 1760 GNUNET_free (cr);
1893 1761 GNUNET_SERVICE_client_continue (cs->client);
1894 GNUNET_SERVICE_client_continue (client);
1895
1896 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1897 "Client connected to lazy set\n");
1898} 1762}
1899 1763
1900 1764
@@ -1908,26 +1772,22 @@ static void
1908handle_client_cancel (void *cls, 1772handle_client_cancel (void *cls,
1909 const struct GNUNET_SET_CancelMessage *msg) 1773 const struct GNUNET_SET_CancelMessage *msg)
1910{ 1774{
1911 struct GNUNET_SERVICE_Client *client = cls; 1775 struct ClientState *cs = cls;
1912 struct Set *set; 1776 struct Set *set;
1913 struct Operation *op; 1777 struct Operation *op;
1914 int found; 1778 int found;
1915 1779
1916 set = set_get (client); 1780 if (NULL == (set = cs->set))
1917 if (NULL == set)
1918 { 1781 {
1919 /* client without a set requested an operation */ 1782 /* client without a set requested an operation */
1920 GNUNET_break (0); 1783 GNUNET_break (0);
1921 GNUNET_SERVICE_client_drop (client); 1784 GNUNET_SERVICE_client_drop (cs->client);
1922 return; 1785 return;
1923 } 1786 }
1924 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1925 "Client requested cancel for op %u\n",
1926 (uint32_t) ntohl (msg->request_id));
1927 found = GNUNET_NO; 1787 found = GNUNET_NO;
1928 for (op = set->ops_head; NULL != op; op = op->next) 1788 for (op = set->ops_head; NULL != op; op = op->next)
1929 { 1789 {
1930 if (op->spec->client_request_id == ntohl (msg->request_id)) 1790 if (op->client_request_id == ntohl (msg->request_id))
1931 { 1791 {
1932 found = GNUNET_YES; 1792 found = GNUNET_YES;
1933 break; 1793 break;
@@ -1940,15 +1800,19 @@ handle_client_cancel (void *cls,
1940 * yet and try to cancel the (just barely non-existent) operation. 1800 * yet and try to cancel the (just barely non-existent) operation.
1941 * So this is not a hard error. 1801 * So this is not a hard error.
1942 */ 1802 */
1943 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1803 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1944 "Client canceled non-existent op\n"); 1804 "Client canceled non-existent op %u\n",
1805 (uint32_t) ntohl (msg->request_id));
1945 } 1806 }
1946 else 1807 else
1947 { 1808 {
1809 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1810 "Client requested cancel for op %u\n",
1811 (uint32_t) ntohl (msg->request_id));
1948 _GSS_operation_destroy (op, 1812 _GSS_operation_destroy (op,
1949 GNUNET_YES); 1813 GNUNET_YES);
1950 } 1814 }
1951 GNUNET_SERVICE_client_continue (client); 1815 GNUNET_SERVICE_client_continue (cs->client);
1952} 1816}
1953 1817
1954 1818
@@ -1964,18 +1828,18 @@ static void
1964handle_client_accept (void *cls, 1828handle_client_accept (void *cls,
1965 const struct GNUNET_SET_AcceptMessage *msg) 1829 const struct GNUNET_SET_AcceptMessage *msg)
1966{ 1830{
1967 struct GNUNET_SERVICE_Client *client = cls; 1831 struct ClientState *cs = cls;
1968 struct Set *set; 1832 struct Set *set;
1969 struct Operation *op; 1833 struct Operation *op;
1970 struct GNUNET_SET_ResultMessage *result_message; 1834 struct GNUNET_SET_ResultMessage *result_message;
1971 struct GNUNET_MQ_Envelope *ev; 1835 struct GNUNET_MQ_Envelope *ev;
1836 struct Listener *listener;
1972 1837
1973 set = set_get (client); 1838 if (NULL == (set = cs->set))
1974 if (NULL == set)
1975 { 1839 {
1976 /* client without a set requested to accept */ 1840 /* client without a set requested to accept */
1977 GNUNET_break (0); 1841 GNUNET_break (0);
1978 GNUNET_SERVICE_client_drop (client); 1842 GNUNET_SERVICE_client_drop (cs->client);
1979 return; 1843 return;
1980 } 1844 }
1981 op = get_incoming (ntohl (msg->accept_reject_id)); 1845 op = get_incoming (ntohl (msg->accept_reject_id));
@@ -1983,72 +1847,75 @@ handle_client_accept (void *cls,
1983 { 1847 {
1984 /* It is not an error if the set op does not exist -- it may 1848 /* It is not an error if the set op does not exist -- it may
1985 * have been destroyed when the partner peer disconnected. */ 1849 * have been destroyed when the partner peer disconnected. */
1986 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1850 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1987 "Client accepted request that is no longer active\n"); 1851 "Client %p accepted request %u of listener %p that is no longer active\n",
1852 cs,
1853 ntohl (msg->accept_reject_id),
1854 cs->listener);
1988 ev = GNUNET_MQ_msg (result_message, 1855 ev = GNUNET_MQ_msg (result_message,
1989 GNUNET_MESSAGE_TYPE_SET_RESULT); 1856 GNUNET_MESSAGE_TYPE_SET_RESULT);
1990 result_message->request_id = msg->request_id; 1857 result_message->request_id = msg->request_id;
1991 result_message->element_type = 0;
1992 result_message->result_status = htons (GNUNET_SET_STATUS_FAILURE); 1858 result_message->result_status = htons (GNUNET_SET_STATUS_FAILURE);
1993 GNUNET_MQ_send (set->client_mq, ev); 1859 GNUNET_MQ_send (set->cs->mq,
1994 GNUNET_SERVICE_client_continue (client); 1860 ev);
1861 GNUNET_SERVICE_client_continue (cs->client);
1995 return; 1862 return;
1996 } 1863 }
1997
1998 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1864 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1999 "Client accepting request %u\n", 1865 "Client accepting request %u\n",
2000 (uint32_t) ntohl (msg->accept_reject_id)); 1866 (uint32_t) ntohl (msg->accept_reject_id));
2001 GNUNET_assert (GNUNET_YES == op->is_incoming); 1867 listener = op->listener;
2002 op->is_incoming = GNUNET_NO; 1868 op->listener = NULL;
2003 GNUNET_CONTAINER_DLL_remove (incoming_head, 1869 GNUNET_CONTAINER_DLL_remove (listener->op_head,
2004 incoming_tail, 1870 listener->op_tail,
2005 op); 1871 op);
2006 op->spec->set = set; 1872 op->set = set;
2007 GNUNET_CONTAINER_DLL_insert (set->ops_head, 1873 GNUNET_CONTAINER_DLL_insert (set->ops_head,
2008 set->ops_tail, 1874 set->ops_tail,
2009 op); 1875 op);
2010 op->spec->client_request_id = ntohl (msg->request_id); 1876 op->client_request_id = ntohl (msg->request_id);
2011 op->spec->result_mode = ntohl (msg->result_mode); 1877 op->result_mode = ntohl (msg->result_mode);
2012 op->spec->byzantine = msg->byzantine; 1878 op->byzantine = msg->byzantine;
2013 op->spec->byzantine_lower_bound = msg->byzantine_lower_bound; 1879 op->byzantine_lower_bound = msg->byzantine_lower_bound;
2014 op->spec->force_full = msg->force_full; 1880 op->force_full = msg->force_full;
2015 op->spec->force_delta = msg->force_delta; 1881 op->force_delta = msg->force_delta;
2016 1882
2017 // Advance generation values, so that 1883 /* Advance generation values, so that future mutations do not
2018 // mutations won't interfer with the running operation. 1884 interfer with the running operation. */
2019 op->generation_created = set->current_generation; 1885 op->generation_created = set->current_generation;
2020 advance_generation (set); 1886 advance_generation (set);
2021 1887 GNUNET_assert (NULL == op->state);
2022 op->vt = set->vt; 1888 op->state = set->vt->accept (op);
2023 op->type = set->type; 1889 if (NULL == op->state)
2024 op->vt->accept (op); 1890 {
2025 GNUNET_SERVICE_client_continue (client); 1891 GNUNET_break (0);
1892 GNUNET_SERVICE_client_drop (cs->client);
1893 return;
1894 }
1895 /* Now allow CADET to continue, as we did not do this in
1896 #handle_incoming_msg (as we wanted to first see if the
1897 local client would accept the request). */
1898 GNUNET_CADET_receive_done (op->channel);
1899 GNUNET_SERVICE_client_continue (cs->client);
2026} 1900}
2027 1901
2028 1902
2029/** 1903/**
2030 * Called to clean up, after a shutdown has been requested. 1904 * Called to clean up, after a shutdown has been requested.
2031 * 1905 *
2032 * @param cls closure 1906 * @param cls closure, NULL
2033 */ 1907 */
2034static void 1908static void
2035shutdown_task (void *cls) 1909shutdown_task (void *cls)
2036{ 1910{
2037 while (NULL != incoming_head) 1911 /* Delay actual shutdown to allow service to disconnect clients */
2038 incoming_destroy (incoming_head);
2039 while (NULL != listeners_head)
2040 listener_destroy (listeners_head);
2041 while (NULL != sets_head)
2042 set_destroy (sets_head);
2043
2044 /* it's important to destroy cadet at the end, as all channels
2045 * must be destroyed before the cadet handle! */
2046 if (NULL != cadet) 1912 if (NULL != cadet)
2047 { 1913 {
2048 GNUNET_CADET_disconnect (cadet); 1914 GNUNET_CADET_disconnect (cadet);
2049 cadet = NULL; 1915 cadet = NULL;
2050 } 1916 }
2051 GNUNET_STATISTICS_destroy (_GSS_statistics, GNUNET_YES); 1917 GNUNET_STATISTICS_destroy (_GSS_statistics,
1918 GNUNET_YES);
2052 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1919 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2053 "handled shutdown request\n"); 1920 "handled shutdown request\n");
2054} 1921}
@@ -2067,15 +1934,19 @@ run (void *cls,
2067 const struct GNUNET_CONFIGURATION_Handle *cfg, 1934 const struct GNUNET_CONFIGURATION_Handle *cfg,
2068 struct GNUNET_SERVICE_Handle *service) 1935 struct GNUNET_SERVICE_Handle *service)
2069{ 1936{
2070 configuration = cfg; 1937 /* FIXME: need to modify SERVICE (!) API to allow
1938 us to run a shutdown task *after* clients were
1939 forcefully disconnected! */
2071 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 1940 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
2072 NULL); 1941 NULL);
2073 _GSS_statistics = GNUNET_STATISTICS_create ("set", cfg); 1942 _GSS_statistics = GNUNET_STATISTICS_create ("set",
2074 cadet = GNUNET_CADET_connecT (cfg); 1943 cfg);
1944 cadet = GNUNET_CADET_connect (cfg);
2075 if (NULL == cadet) 1945 if (NULL == cadet)
2076 { 1946 {
2077 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1947 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2078 _("Could not connect to CADET service\n")); 1948 _("Could not connect to CADET service\n"));
1949 GNUNET_SCHEDULER_shutdown ();
2079 return; 1950 return;
2080 } 1951 }
2081} 1952}
@@ -2101,7 +1972,7 @@ GNUNET_SERVICE_MAIN
2101 NULL), 1972 NULL),
2102 GNUNET_MQ_hd_var_size (client_mutation, 1973 GNUNET_MQ_hd_var_size (client_mutation,
2103 GNUNET_MESSAGE_TYPE_SET_ADD, 1974 GNUNET_MESSAGE_TYPE_SET_ADD,
2104 struct GNUNET_MessageHeader, 1975 struct GNUNET_SET_ElementMessage,
2105 NULL), 1976 NULL),
2106 GNUNET_MQ_hd_fixed_size (client_create_set, 1977 GNUNET_MQ_hd_fixed_size (client_create_set,
2107 GNUNET_MESSAGE_TYPE_SET_CREATE, 1978 GNUNET_MESSAGE_TYPE_SET_CREATE,
@@ -2125,7 +1996,7 @@ GNUNET_SERVICE_MAIN
2125 NULL), 1996 NULL),
2126 GNUNET_MQ_hd_var_size (client_mutation, 1997 GNUNET_MQ_hd_var_size (client_mutation,
2127 GNUNET_MESSAGE_TYPE_SET_REMOVE, 1998 GNUNET_MESSAGE_TYPE_SET_REMOVE,
2128 struct GNUNET_MessageHeader, 1999 struct GNUNET_SET_ElementMessage,
2129 NULL), 2000 NULL),
2130 GNUNET_MQ_hd_fixed_size (client_cancel, 2001 GNUNET_MQ_hd_fixed_size (client_cancel,
2131 GNUNET_MESSAGE_TYPE_SET_CANCEL, 2002 GNUNET_MESSAGE_TYPE_SET_CANCEL,
diff --git a/src/set/gnunet-service-set.h b/src/set/gnunet-service-set.h
index c981430ef..19413fd30 100644
--- a/src/set/gnunet-service-set.h
+++ b/src/set/gnunet-service-set.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 Copyright (C) 2013, 2014 GNUnet e.V. 3 Copyright (C) 2013-2017 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -68,92 +68,13 @@ struct Operation;
68 68
69 69
70/** 70/**
71 * Detail information about an operation.
72 */
73struct OperationSpecification
74{
75
76 /**
77 * The remove peer we evaluate the operation with.
78 */
79 struct GNUNET_PeerIdentity peer;
80
81 /**
82 * Application ID for the operation, used to distinguish
83 * multiple operations of the same type with the same peer.
84 */
85 struct GNUNET_HashCode app_id;
86
87 /**
88 * Context message, may be NULL.
89 */
90 struct GNUNET_MessageHeader *context_msg;
91
92 /**
93 * Set associated with the operation, NULL until the spec has been
94 * associated with a set.
95 */
96 struct Set *set;
97
98 /**
99 * Salt to use for the operation.
100 */
101 uint32_t salt;
102
103 /**
104 * Remote peers element count
105 */
106 uint32_t remote_element_count;
107
108 /**
109 * ID used to identify an operation between service and client
110 */
111 uint32_t client_request_id;
112
113 /**
114 * The type of the operation.
115 */
116 enum GNUNET_SET_OperationType operation;
117
118 /**
119 * When are elements sent to the client, and which elements are sent?
120 */
121 enum GNUNET_SET_ResultMode result_mode;
122
123 /**
124 * Always use delta operation instead of sending full sets,
125 * even it it's less efficient.
126 */
127 int force_delta;
128
129 /**
130 * Always send full sets, even if delta operations would
131 * be more efficient.
132 */
133 int force_full;
134
135 /**
136 * #GNUNET_YES to fail operations where Byzantine faults
137 * are suspected
138 */
139 int byzantine;
140
141 /**
142 * Lower bound for the set size, used only when
143 * byzantine mode is enabled.
144 */
145 int byzantine_lower_bound;
146};
147
148
149/**
150 * Signature of functions that create the implementation-specific 71 * Signature of functions that create the implementation-specific
151 * state for a set supporting a specific operation. 72 * state for a set supporting a specific operation.
152 * 73 *
153 * @return a set state specific to the supported operation, NULL on error 74 * @return a set state specific to the supported operation, NULL on error
154 */ 75 */
155typedef struct SetState * 76typedef struct SetState *
156(*CreateImpl) (void); 77(*SetCreateImpl) (void);
157 78
158 79
159/** 80/**
@@ -164,18 +85,18 @@ typedef struct SetState *
164 * @param ee element message from the client 85 * @param ee element message from the client
165 */ 86 */
166typedef void 87typedef void
167(*AddRemoveImpl) (struct SetState *state, 88(*SetAddRemoveImpl) (struct SetState *state,
168 struct ElementEntry *ee); 89 struct ElementEntry *ee);
169 90
170 91
171/** 92/**
172 * Signature of functions that handle disconnection of the remote 93 * Make a copy of a set's internal state.
173 * peer.
174 * 94 *
175 * @param op the set operation, contains implementation-specific data 95 * @param state set state to copy
96 * @return copy of the internal state
176 */ 97 */
177typedef void 98typedef struct SetState *
178(*PeerDisconnectImpl) (struct Operation *op); 99(*SetCopyStateImpl) (struct SetState *state);
179 100
180 101
181/** 102/**
@@ -185,7 +106,7 @@ typedef void
185 * @param state the set state, contains implementation-specific data 106 * @param state the set state, contains implementation-specific data
186 */ 107 */
187typedef void 108typedef void
188(*DestroySetImpl) (struct SetState *state); 109(*SetDestroyImpl) (struct SetState *state);
189 110
190 111
191/** 112/**
@@ -193,8 +114,9 @@ typedef void
193 * 114 *
194 * @param op operation that is created by accepting the operation, 115 * @param op operation that is created by accepting the operation,
195 * should be initialized by the implementation 116 * should be initialized by the implementation
117 * @return operation-specific state to keep in @a op
196 */ 118 */
197typedef void 119typedef struct OperationState *
198(*OpAcceptImpl) (struct Operation *op); 120(*OpAcceptImpl) (struct Operation *op);
199 121
200 122
@@ -206,23 +128,31 @@ typedef void
206 * begin the evaluation 128 * begin the evaluation
207 * @param opaque_context message to be transmitted to the listener 129 * @param opaque_context message to be transmitted to the listener
208 * to convince him to accept, may be NULL 130 * to convince him to accept, may be NULL
131 * @return operation-specific state to keep in @a op
209 */ 132 */
210typedef void 133typedef struct OperationState *
211(*OpEvaluateImpl) (struct Operation *op, 134(*OpEvaluateImpl) (struct Operation *op,
212 const struct GNUNET_MessageHeader *opaque_context); 135 const struct GNUNET_MessageHeader *opaque_context);
213 136
214
215/** 137/**
216 * Signature of functions that implement operation cancellation 138 * Signature of functions that implement operation cancelation.
139 * This includes notifying the client about the operation's final
140 * state.
217 * 141 *
218 * @param op operation state 142 * @param op operation state
219 */ 143 */
220typedef void 144typedef void
221(*CancelImpl) (struct Operation *op); 145(*OpCancelImpl) (struct Operation *op);
222 146
223 147
224typedef struct SetState * 148/**
225(*CopyStateImpl) (struct Set *op); 149 * Signature of functions called when the CADET channel died.
150 *
151 * @param op operation state
152 */
153typedef void
154(*OpChannelDeathImpl) (struct Operation *op);
155
226 156
227 157
228/** 158/**
@@ -234,17 +164,27 @@ struct SetVT
234 /** 164 /**
235 * Callback for the set creation. 165 * Callback for the set creation.
236 */ 166 */
237 CreateImpl create; 167 SetCreateImpl create;
238 168
239 /** 169 /**
240 * Callback for element insertion 170 * Callback for element insertion
241 */ 171 */
242 AddRemoveImpl add; 172 SetAddRemoveImpl add;
243 173
244 /** 174 /**
245 * Callback for element removal. 175 * Callback for element removal.
246 */ 176 */
247 AddRemoveImpl remove; 177 SetAddRemoveImpl remove;
178
179 /**
180 * Callback for making a copy of a set's internal state.
181 */
182 SetCopyStateImpl copy_state;
183
184 /**
185 * Callback for destruction of the set state.
186 */
187 SetDestroyImpl destroy_set;
248 188
249 /** 189 /**
250 * Callback for accepting a set operation request 190 * Callback for accepting a set operation request
@@ -257,21 +197,15 @@ struct SetVT
257 OpEvaluateImpl evaluate; 197 OpEvaluateImpl evaluate;
258 198
259 /** 199 /**
260 * Callback for destruction of the set state. 200 * Callback for canceling an operation.
261 */
262 DestroySetImpl destroy_set;
263
264 /**
265 * Callback for handling the remote peer's disconnect.
266 */ 201 */
267 PeerDisconnectImpl peer_disconnect; 202 OpCancelImpl cancel;
268 203
269 /** 204 /**
270 * Callback for canceling an operation by its ID. 205 * Callback called in case the CADET channel died.
271 */ 206 */
272 CancelImpl cancel; 207 OpChannelDeathImpl channel_death;
273 208
274 CopyStateImpl copy_state;
275}; 209};
276 210
277 211
@@ -341,27 +275,38 @@ struct ElementEntry
341}; 275};
342 276
343 277
278/**
279 * A listener is inhabited by a client, and waits for evaluation
280 * requests from remote peers.
281 */
344struct Listener; 282struct Listener;
345 283
346 284
347/** 285/**
348 * Possible set operations. 286 * State we keep per client.
349 */ 287 */
350enum OperationType { 288struct ClientState
289{
351 /** 290 /**
352 * Operation type unknown. 291 * Set, if associated with the client, otherwise NULL.
353 */ 292 */
354 OT_UNKNOWN = 0, 293 struct Set *set;
355 294
356 /** 295 /**
357 * We are performing a union. 296 * Listener, if associated with the client, otherwise NULL.
358 */ 297 */
359 OT_UNION, 298 struct Listener *listener;
360 299
361 /** 300 /**
362 * We are performing an intersection. 301 * Client handle.
363 */ 302 */
364 OT_INTERSECTION 303 struct GNUNET_SERVICE_Client *client;
304
305 /**
306 * Message queue.
307 */
308 struct GNUNET_MQ_Handle *mq;
309
365}; 310};
366 311
367 312
@@ -370,12 +315,16 @@ enum OperationType {
370 */ 315 */
371struct Operation 316struct Operation
372{ 317{
318
373 /** 319 /**
374 * V-Table for the operation belonging to the tunnel contest. 320 * Kept in a DLL of the listener, if @e listener is non-NULL.
375 *
376 * Used for all operation specific operations after receiving the ops request
377 */ 321 */
378 const struct SetVT *vt; 322 struct Operation *next;
323
324 /**
325 * Kept in a DLL of the listener, if @e listener is non-NULL.
326 */
327 struct Operation *prev;
379 328
380 /** 329 /**
381 * Channel to the peer. 330 * Channel to the peer.
@@ -393,11 +342,15 @@ struct Operation
393 struct GNUNET_MQ_Handle *mq; 342 struct GNUNET_MQ_Handle *mq;
394 343
395 /** 344 /**
396 * Detail information about the set operation, including the set to 345 * Context message, may be NULL.
397 * use. When 'spec' is NULL, the operation is not yet entirely 346 */
398 * initialized. 347 struct GNUNET_MessageHeader *context_msg;
348
349 /**
350 * Set associated with the operation, NULL until the spec has been
351 * associated with a set.
399 */ 352 */
400 struct OperationSpecification *spec; 353 struct Set *set;
401 354
402 /** 355 /**
403 * Operation-specific operation state. Note that the exact 356 * Operation-specific operation state. Note that the exact
@@ -407,16 +360,6 @@ struct Operation
407 struct OperationState *state; 360 struct OperationState *state;
408 361
409 /** 362 /**
410 * Evaluate operations are held in a linked list.
411 */
412 struct Operation *next;
413
414 /**
415 * Evaluate operations are held in a linked list.
416 */
417 struct Operation *prev;
418
419 /**
420 * The identity of the requesting peer. Needs to 363 * The identity of the requesting peer. Needs to
421 * be stored here as the op spec might not have been created yet. 364 * be stored here as the op spec might not have been created yet.
422 */ 365 */
@@ -429,9 +372,48 @@ struct Operation
429 struct GNUNET_SCHEDULER_Task *timeout_task; 372 struct GNUNET_SCHEDULER_Task *timeout_task;
430 373
431 /** 374 /**
432 * What type of operation is this? 375 * Salt to use for the operation.
376 */
377 uint32_t salt;
378
379 /**
380 * Remote peers element count
381 */
382 uint32_t remote_element_count;
383
384 /**
385 * ID used to identify an operation between service and client
386 */
387 uint32_t client_request_id;
388
389 /**
390 * When are elements sent to the client, and which elements are sent?
433 */ 391 */
434 enum OperationType type; 392 enum GNUNET_SET_ResultMode result_mode;
393
394 /**
395 * Always use delta operation instead of sending full sets,
396 * even it it's less efficient.
397 */
398 int force_delta;
399
400 /**
401 * Always send full sets, even if delta operations would
402 * be more efficient.
403 */
404 int force_full;
405
406 /**
407 * #GNUNET_YES to fail operations where Byzantine faults
408 * are suspected
409 */
410 int byzantine;
411
412 /**
413 * Lower bound for the set size, used only when
414 * byzantine mode is enabled.
415 */
416 int byzantine_lower_bound;
435 417
436 /** 418 /**
437 * Unique request id for the request from a remote peer, sent to the 419 * Unique request id for the request from a remote peer, sent to the
@@ -441,45 +423,26 @@ struct Operation
441 uint32_t suggest_id; 423 uint32_t suggest_id;
442 424
443 /** 425 /**
444 * #GNUNET_YES if this is not a "real" set operation yet, and we still
445 * need to wait for the other peer to give us more details.
446 */
447 int is_incoming;
448
449 /**
450 * Generation in which the operation handle 426 * Generation in which the operation handle
451 * was created. 427 * was created.
452 */ 428 */
453 unsigned int generation_created; 429 unsigned int generation_created;
454 430
455 /**
456 * Incremented whenever (during shutdown) some component still
457 * needs to do something with this before the operation is freed.
458 * (Used as a reference counter, but only during termination.)
459 */
460 unsigned int keep;
461}; 431};
462 432
463 433
464/** 434/**
465 * SetContent stores the actual set elements, 435 * SetContent stores the actual set elements, which may be shared by
466 * which may be shared by multiple generations derived 436 * multiple generations derived from one set.
467 * from one set.
468 */ 437 */
469struct SetContent 438struct SetContent
470{ 439{
471 /**
472 * Number of references to the content.
473 */
474 unsigned int refcount;
475 440
476 /** 441 /**
477 * Maps `struct GNUNET_HashCode *` to `struct ElementEntry *`. 442 * Maps `struct GNUNET_HashCode *` to `struct ElementEntry *`.
478 */ 443 */
479 struct GNUNET_CONTAINER_MultiHashMap *elements; 444 struct GNUNET_CONTAINER_MultiHashMap *elements;
480 445
481 unsigned int latest_generation;
482
483 /** 446 /**
484 * Mutations requested by the client that we're 447 * Mutations requested by the client that we're
485 * unable to execute right now because we're iterating 448 * unable to execute right now because we're iterating
@@ -495,6 +458,16 @@ struct SetContent
495 struct PendingMutation *pending_mutations_tail; 458 struct PendingMutation *pending_mutations_tail;
496 459
497 /** 460 /**
461 * Number of references to the content.
462 */
463 unsigned int refcount;
464
465 /**
466 * FIXME: document!
467 */
468 unsigned int latest_generation;
469
470 /**
498 * Number of concurrently active iterators. 471 * Number of concurrently active iterators.
499 */ 472 */
500 int iterator_count; 473 int iterator_count;
@@ -515,11 +488,24 @@ struct GenerationRange
515}; 488};
516 489
517 490
491/**
492 * Information about a mutation to apply to a set.
493 */
518struct PendingMutation 494struct PendingMutation
519{ 495{
496 /**
497 * Mutations are kept in a DLL.
498 */
520 struct PendingMutation *prev; 499 struct PendingMutation *prev;
500
501 /**
502 * Mutations are kept in a DLL.
503 */
521 struct PendingMutation *next; 504 struct PendingMutation *next;
522 505
506 /**
507 * Set this mutation is about.
508 */
523 struct Set *set; 509 struct Set *set;
524 510
525 /** 511 /**
@@ -527,7 +513,7 @@ struct PendingMutation
527 * May only be a #GNUNET_MESSAGE_TYPE_SET_ADD or 513 * May only be a #GNUNET_MESSAGE_TYPE_SET_ADD or
528 * #GNUNET_MESSAGE_TYPE_SET_REMOVE. 514 * #GNUNET_MESSAGE_TYPE_SET_REMOVE.
529 */ 515 */
530 struct GNUNET_MessageHeader *mutation_message; 516 struct GNUNET_SET_ElementMessage *msg;
531}; 517};
532 518
533 519
@@ -551,12 +537,13 @@ struct Set
551 * Client that owns the set. Only one client may own a set, 537 * Client that owns the set. Only one client may own a set,
552 * and there can only be one set per client. 538 * and there can only be one set per client.
553 */ 539 */
554 struct GNUNET_SERVICE_Client *client; 540 struct ClientState *cs;
555 541
556 /** 542 /**
557 * Message queue for the client. 543 * Content, possibly shared by multiple sets,
544 * and thus reference counted.
558 */ 545 */
559 struct GNUNET_MQ_Handle *client_mq; 546 struct SetContent *content;
560 547
561 /** 548 /**
562 * Virtual table for this set. Determined by the operation type of 549 * Virtual table for this set. Determined by the operation type of
@@ -589,9 +576,9 @@ struct Set
589 struct Operation *ops_tail; 576 struct Operation *ops_tail;
590 577
591 /** 578 /**
592 * What type of operation is this set for? 579 * List of generations we have to exclude, due to lazy copies.
593 */ 580 */
594 enum OperationType type; 581 struct GenerationRange *excluded_generations;
595 582
596 /** 583 /**
597 * Current generation, that is, number of previously executed 584 * Current generation, that is, number of previously executed
@@ -600,11 +587,6 @@ struct Set
600 unsigned int current_generation; 587 unsigned int current_generation;
601 588
602 /** 589 /**
603 * List of generations we have to exclude, due to lazy copies.
604 */
605 struct GenerationRange *excluded_generations;
606
607 /**
608 * Number of elements in array @a excluded_generations. 590 * Number of elements in array @a excluded_generations.
609 */ 591 */
610 unsigned int excluded_generations_size; 592 unsigned int excluded_generations_size;
@@ -615,21 +597,16 @@ struct Set
615 enum GNUNET_SET_OperationType operation; 597 enum GNUNET_SET_OperationType operation;
616 598
617 /** 599 /**
618 * Each @e iter is assigned a unique number, so that the client
619 * can distinguish iterations.
620 */
621 uint16_t iteration_id;
622
623 /**
624 * Generation we're currently iteration over. 600 * Generation we're currently iteration over.
625 */ 601 */
626 unsigned int iter_generation; 602 unsigned int iter_generation;
627 603
628 /** 604 /**
629 * Content, possibly shared by multiple sets, 605 * Each @e iter is assigned a unique number, so that the client
630 * and thus reference counted. 606 * can distinguish iterations.
631 */ 607 */
632 struct SetContent *content; 608 uint16_t iteration_id;
609
633}; 610};
634 611
635 612
@@ -637,10 +614,14 @@ extern struct GNUNET_STATISTICS_Handle *_GSS_statistics;
637 614
638 615
639/** 616/**
640 * Destroy the given operation. Call the implementation-specific 617 * Destroy the given operation. Used for any operation where both
641 * cancel function of the operation. Disconnects from the remote 618 * peers were known and that thus actually had a vt and channel. Must
642 * peer. Does not disconnect the client, as there may be multiple 619 * not be used for operations where 'listener' is still set and we do
643 * operations per set. 620 * not know the other peer.
621 *
622 * Call the implementation-specific cancel function of the operation.
623 * Disconnects from the remote peer. Does not disconnect the client,
624 * as there may be multiple operations per set.
644 * 625 *
645 * @param op operation to destroy 626 * @param op operation to destroy
646 * @param gc #GNUNET_YES to perform garbage collection on the set 627 * @param gc #GNUNET_YES to perform garbage collection on the set
@@ -668,10 +649,13 @@ const struct SetVT *
668_GSS_intersection_vt (void); 649_GSS_intersection_vt (void);
669 650
670 651
671int 652/**
672_GSS_is_element_of_set (struct ElementEntry *ee, 653 * Is element @a ee part of the set used by @a op?
673 struct Set *set); 654 *
674 655 * @param ee element to test
656 * @param op operation the defines the set and its generation
657 * @return #GNUNET_YES if the element is in the set, #GNUNET_NO if not
658 */
675int 659int
676_GSS_is_element_of_operation (struct ElementEntry *ee, 660_GSS_is_element_of_operation (struct ElementEntry *ee,
677 struct Operation *op); 661 struct Operation *op);
diff --git a/src/set/gnunet-service-set_intersection.c b/src/set/gnunet-service-set_intersection.c
index bb369a81f..9dc421792 100644
--- a/src/set/gnunet-service-set_intersection.c
+++ b/src/set/gnunet-service-set_intersection.c
@@ -56,6 +56,18 @@ enum IntersectionOperationPhase
56 PHASE_BF_EXCHANGE, 56 PHASE_BF_EXCHANGE,
57 57
58 /** 58 /**
59 * We must next send the P2P DONE message (after finishing mostly
60 * with the local client). Then we will wait for the channel to close.
61 */
62 PHASE_MUST_SEND_DONE,
63
64 /**
65 * We have received the P2P DONE message, and must finish with the
66 * local client before terminating the channel.
67 */
68 PHASE_DONE_RECEIVED,
69
70 /**
59 * The protocol is over. Results may still have to be sent to the 71 * The protocol is over. Results may still have to be sent to the
60 * client. 72 * client.
61 */ 73 */
@@ -162,6 +174,13 @@ struct OperationState
162 * Did we send the client that we are done? 174 * Did we send the client that we are done?
163 */ 175 */
164 int client_done_sent; 176 int client_done_sent;
177
178 /**
179 * Set whenever we reach the state where the death of the
180 * channel is perfectly find and should NOT result in the
181 * operation being cancelled.
182 */
183 int channel_death_expected;
165}; 184};
166 185
167 186
@@ -193,12 +212,12 @@ send_client_removed_element (struct Operation *op,
193 struct GNUNET_MQ_Envelope *ev; 212 struct GNUNET_MQ_Envelope *ev;
194 struct GNUNET_SET_ResultMessage *rm; 213 struct GNUNET_SET_ResultMessage *rm;
195 214
196 if (GNUNET_SET_RESULT_REMOVED != op->spec->result_mode) 215 if (GNUNET_SET_RESULT_REMOVED != op->result_mode)
197 return; /* Wrong mode for transmitting removed elements */ 216 return; /* Wrong mode for transmitting removed elements */
198 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 217 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
199 "Sending removed element (size %u) to client\n", 218 "Sending removed element (size %u) to client\n",
200 element->size); 219 element->size);
201 GNUNET_assert (0 != op->spec->client_request_id); 220 GNUNET_assert (0 != op->client_request_id);
202 ev = GNUNET_MQ_msg_extra (rm, 221 ev = GNUNET_MQ_msg_extra (rm,
203 element->size, 222 element->size,
204 GNUNET_MESSAGE_TYPE_SET_RESULT); 223 GNUNET_MESSAGE_TYPE_SET_RESULT);
@@ -208,12 +227,12 @@ send_client_removed_element (struct Operation *op,
208 return; 227 return;
209 } 228 }
210 rm->result_status = htons (GNUNET_SET_STATUS_OK); 229 rm->result_status = htons (GNUNET_SET_STATUS_OK);
211 rm->request_id = htonl (op->spec->client_request_id); 230 rm->request_id = htonl (op->client_request_id);
212 rm->element_type = element->element_type; 231 rm->element_type = element->element_type;
213 GNUNET_memcpy (&rm[1], 232 GNUNET_memcpy (&rm[1],
214 element->data, 233 element->data,
215 element->size); 234 element->size);
216 GNUNET_MQ_send (op->spec->set->client_mq, 235 GNUNET_MQ_send (op->set->cs->mq,
217 ev); 236 ev);
218} 237}
219 238
@@ -397,9 +416,9 @@ fail_intersection_operation (struct Operation *op)
397 ev = GNUNET_MQ_msg (msg, 416 ev = GNUNET_MQ_msg (msg,
398 GNUNET_MESSAGE_TYPE_SET_RESULT); 417 GNUNET_MESSAGE_TYPE_SET_RESULT);
399 msg->result_status = htons (GNUNET_SET_STATUS_FAILURE); 418 msg->result_status = htons (GNUNET_SET_STATUS_FAILURE);
400 msg->request_id = htonl (op->spec->client_request_id); 419 msg->request_id = htonl (op->client_request_id);
401 msg->element_type = htons (0); 420 msg->element_type = htons (0);
402 GNUNET_MQ_send (op->spec->set->client_mq, 421 GNUNET_MQ_send (op->set->cs->mq,
403 ev); 422 ev);
404 _GSS_operation_destroy (op, 423 _GSS_operation_destroy (op,
405 GNUNET_YES); 424 GNUNET_YES);
@@ -428,8 +447,8 @@ send_bloomfilter (struct Operation *op)
428 should use more bits to maximize its set reduction 447 should use more bits to maximize its set reduction
429 potential and minimize overall bandwidth consumption. */ 448 potential and minimize overall bandwidth consumption. */
430 bf_elementbits = 2 + ceil (log2((double) 449 bf_elementbits = 2 + ceil (log2((double)
431 (op->spec->remote_element_count / 450 (op->remote_element_count /
432 (double) op->state->my_element_count))); 451 (double) op->state->my_element_count)));
433 if (bf_elementbits < 1) 452 if (bf_elementbits < 1)
434 bf_elementbits = 1; /* make sure k is not 0 */ 453 bf_elementbits = 1; /* make sure k is not 0 */
435 /* optimize BF-size to ~50% of bits set */ 454 /* optimize BF-size to ~50% of bits set */
@@ -515,12 +534,14 @@ send_client_done_and_destroy (void *cls)
515 struct GNUNET_MQ_Envelope *ev; 534 struct GNUNET_MQ_Envelope *ev;
516 struct GNUNET_SET_ResultMessage *rm; 535 struct GNUNET_SET_ResultMessage *rm;
517 536
537 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
538 "Intersection succeeded, sending DONE to local client\n");
518 ev = GNUNET_MQ_msg (rm, 539 ev = GNUNET_MQ_msg (rm,
519 GNUNET_MESSAGE_TYPE_SET_RESULT); 540 GNUNET_MESSAGE_TYPE_SET_RESULT);
520 rm->request_id = htonl (op->spec->client_request_id); 541 rm->request_id = htonl (op->client_request_id);
521 rm->result_status = htons (GNUNET_SET_STATUS_DONE); 542 rm->result_status = htons (GNUNET_SET_STATUS_DONE);
522 rm->element_type = htons (0); 543 rm->element_type = htons (0);
523 GNUNET_MQ_send (op->spec->set->client_mq, 544 GNUNET_MQ_send (op->set->cs->mq,
524 ev); 545 ev);
525 _GSS_operation_destroy (op, 546 _GSS_operation_destroy (op,
526 GNUNET_YES); 547 GNUNET_YES);
@@ -528,6 +549,53 @@ send_client_done_and_destroy (void *cls)
528 549
529 550
530/** 551/**
552 * Remember that we are done dealing with the local client
553 * AND have sent the other peer our message that we are done,
554 * so we are not just waiting for the channel to die before
555 * telling the local client that we are done as our last act.
556 *
557 * @param cls the `struct Operation`.
558 */
559static void
560finished_local_operations (void *cls)
561{
562 struct Operation *op = cls;
563
564 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
565 "DONE sent to other peer, now waiting for other end to close the channel\n");
566 op->state->phase = PHASE_FINISHED;
567 op->state->channel_death_expected = GNUNET_YES;
568}
569
570
571/**
572 * Notify the other peer that we are done. Once this message
573 * is out, we still need to notify the local client that we
574 * are done.
575 *
576 * @param op operation to notify for.
577 */
578static void
579send_p2p_done (struct Operation *op)
580{
581 struct GNUNET_MQ_Envelope *ev;
582 struct IntersectionDoneMessage *idm;
583
584 GNUNET_assert (PHASE_MUST_SEND_DONE == op->state->phase);
585 GNUNET_assert (GNUNET_NO == op->state->channel_death_expected);
586 ev = GNUNET_MQ_msg (idm,
587 GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE);
588 idm->final_element_count = htonl (op->state->my_element_count);
589 idm->element_xor_hash = op->state->my_xor;
590 GNUNET_MQ_notify_sent (ev,
591 &finished_local_operations,
592 op);
593 GNUNET_MQ_send (op->mq,
594 ev);
595}
596
597
598/**
531 * Send all elements in the full result iterator. 599 * Send all elements in the full result iterator.
532 * 600 *
533 * @param cls the `struct Operation *` 601 * @param cls the `struct Operation *`
@@ -550,10 +618,21 @@ send_remaining_elements (void *cls)
550 { 618 {
551 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 619 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
552 "Sending done and destroy because iterator ran out\n"); 620 "Sending done and destroy because iterator ran out\n");
553 op->keep--;
554 GNUNET_CONTAINER_multihashmap_iterator_destroy (op->state->full_result_iter); 621 GNUNET_CONTAINER_multihashmap_iterator_destroy (op->state->full_result_iter);
555 op->state->full_result_iter = NULL; 622 op->state->full_result_iter = NULL;
556 send_client_done_and_destroy (op); 623 if (PHASE_DONE_RECEIVED == op->state->phase)
624 {
625 op->state->phase = PHASE_FINISHED;
626 send_client_done_and_destroy (op);
627 }
628 else if (PHASE_MUST_SEND_DONE == op->state->phase)
629 {
630 send_p2p_done (op);
631 }
632 else
633 {
634 GNUNET_assert (0);
635 }
557 return; 636 return;
558 } 637 }
559 ee = nxt; 638 ee = nxt;
@@ -562,48 +641,136 @@ send_remaining_elements (void *cls)
562 "Sending element %s:%u to client (full set)\n", 641 "Sending element %s:%u to client (full set)\n",
563 GNUNET_h2s (&ee->element_hash), 642 GNUNET_h2s (&ee->element_hash),
564 element->size); 643 element->size);
565 GNUNET_assert (0 != op->spec->client_request_id); 644 GNUNET_assert (0 != op->client_request_id);
566 ev = GNUNET_MQ_msg_extra (rm, 645 ev = GNUNET_MQ_msg_extra (rm,
567 element->size, 646 element->size,
568 GNUNET_MESSAGE_TYPE_SET_RESULT); 647 GNUNET_MESSAGE_TYPE_SET_RESULT);
569 GNUNET_assert (NULL != ev); 648 GNUNET_assert (NULL != ev);
570 rm->result_status = htons (GNUNET_SET_STATUS_OK); 649 rm->result_status = htons (GNUNET_SET_STATUS_OK);
571 rm->request_id = htonl (op->spec->client_request_id); 650 rm->request_id = htonl (op->client_request_id);
572 rm->element_type = element->element_type; 651 rm->element_type = element->element_type;
573 GNUNET_memcpy (&rm[1], 652 GNUNET_memcpy (&rm[1],
574 element->data, 653 element->data,
575 element->size); 654 element->size);
576 GNUNET_MQ_notify_sent (ev, 655 GNUNET_MQ_notify_sent (ev,
577 &send_remaining_elements, 656 &send_remaining_elements,
578 op); 657 op);
579 GNUNET_MQ_send (op->spec->set->client_mq, 658 GNUNET_MQ_send (op->set->cs->mq,
580 ev); 659 ev);
581} 660}
582 661
583 662
584/** 663/**
585 * Inform the peer that this operation is complete. 664 * Fills the "my_elements" hashmap with the initial set of
665 * (non-deleted) elements from the set of the specification.
586 * 666 *
587 * @param op the intersection operation to fail 667 * @param cls closure with the `struct Operation *`
668 * @param key current key code for the element
669 * @param value value in the hash map with the `struct ElementEntry *`
670 * @return #GNUNET_YES (we should continue to iterate)
671 */
672static int
673initialize_map_unfiltered (void *cls,
674 const struct GNUNET_HashCode *key,
675 void *value)
676{
677 struct ElementEntry *ee = value;
678 struct Operation *op = cls;
679
680 if (GNUNET_NO == _GSS_is_element_of_operation (ee, op))
681 return GNUNET_YES; /* element not live in operation's generation */
682 GNUNET_CRYPTO_hash_xor (&op->state->my_xor,
683 &ee->element_hash,
684 &op->state->my_xor);
685 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
686 "Initial full initialization of my_elements, adding %s:%u\n",
687 GNUNET_h2s (&ee->element_hash),
688 ee->element.size);
689 GNUNET_break (GNUNET_YES ==
690 GNUNET_CONTAINER_multihashmap_put (op->state->my_elements,
691 &ee->element_hash,
692 ee,
693 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
694 return GNUNET_YES;
695}
696
697
698/**
699 * Send our element count to the peer, in case our element count is
700 * lower than his.
701 *
702 * @param op intersection operation
588 */ 703 */
589static void 704static void
590send_peer_done (struct Operation *op) 705send_element_count (struct Operation *op)
591{ 706{
592 struct GNUNET_MQ_Envelope *ev; 707 struct GNUNET_MQ_Envelope *ev;
593 struct IntersectionDoneMessage *idm; 708 struct IntersectionElementInfoMessage *msg;
594 709
595 op->state->phase = PHASE_FINISHED;
596 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 710 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
597 "Intersection succeeded, sending DONE\n"); 711 "Sending our element count (%u)\n",
598 GNUNET_CONTAINER_bloomfilter_free (op->state->local_bf); 712 op->state->my_element_count);
599 op->state->local_bf = NULL; 713 ev = GNUNET_MQ_msg (msg,
714 GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO);
715 msg->sender_element_count = htonl (op->state->my_element_count);
716 GNUNET_MQ_send (op->mq, ev);
717}
600 718
601 ev = GNUNET_MQ_msg (idm, 719
602 GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_DONE); 720/**
603 idm->final_element_count = htonl (op->state->my_element_count); 721 * We go first, initialize our map with all elements and
604 idm->element_xor_hash = op->state->my_xor; 722 * send the first Bloom filter.
605 GNUNET_MQ_send (op->mq, 723 *
606 ev); 724 * @param op operation to start exchange for
725 */
726static void
727begin_bf_exchange (struct Operation *op)
728{
729 op->state->phase = PHASE_BF_EXCHANGE;
730 GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements,
731 &initialize_map_unfiltered,
732 op);
733 send_bloomfilter (op);
734}
735
736
737/**
738 * Handle the initial `struct IntersectionElementInfoMessage` from a
739 * remote peer.
740 *
741 * @param cls the intersection operation
742 * @param mh the header of the message
743 */
744void
745handle_intersection_p2p_element_info (void *cls,
746 const struct IntersectionElementInfoMessage *msg)
747{
748 struct Operation *op = cls;
749
750 if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation)
751 {
752 GNUNET_break_op (0);
753 fail_intersection_operation(op);
754 return;
755 }
756 op->remote_element_count = ntohl (msg->sender_element_count);
757 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
758 "Received remote element count (%u), I have %u\n",
759 op->remote_element_count,
760 op->state->my_element_count);
761 if ( ( (PHASE_INITIAL != op->state->phase) &&
762 (PHASE_COUNT_SENT != op->state->phase) ) ||
763 (op->state->my_element_count > op->remote_element_count) ||
764 (0 == op->state->my_element_count) ||
765 (0 == op->remote_element_count) )
766 {
767 GNUNET_break_op (0);
768 fail_intersection_operation(op);
769 return;
770 }
771 GNUNET_break (NULL == op->state->remote_bf);
772 begin_bf_exchange (op);
773 GNUNET_CADET_receive_done (op->channel);
607} 774}
608 775
609 776
@@ -618,9 +785,9 @@ process_bf (struct Operation *op)
618 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 785 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
619 "Received BF in phase %u, foreign count is %u, my element count is %u/%u\n", 786 "Received BF in phase %u, foreign count is %u, my element count is %u/%u\n",
620 op->state->phase, 787 op->state->phase,
621 op->spec->remote_element_count, 788 op->remote_element_count,
622 op->state->my_element_count, 789 op->state->my_element_count,
623 GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements)); 790 GNUNET_CONTAINER_multihashmap_size (op->set->content->elements));
624 switch (op->state->phase) 791 switch (op->state->phase)
625 { 792 {
626 case PHASE_INITIAL: 793 case PHASE_INITIAL:
@@ -631,7 +798,7 @@ process_bf (struct Operation *op)
631 /* This is the first BF being sent, build our initial map with 798 /* This is the first BF being sent, build our initial map with
632 filtering in place */ 799 filtering in place */
633 op->state->my_element_count = 0; 800 op->state->my_element_count = 0;
634 GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements, 801 GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements,
635 &filtered_map_initialization, 802 &filtered_map_initialization,
636 op); 803 op);
637 break; 804 break;
@@ -641,6 +808,14 @@ process_bf (struct Operation *op)
641 &iterator_bf_reduce, 808 &iterator_bf_reduce,
642 op); 809 op);
643 break; 810 break;
811 case PHASE_MUST_SEND_DONE:
812 GNUNET_break_op (0);
813 fail_intersection_operation(op);
814 return;
815 case PHASE_DONE_RECEIVED:
816 GNUNET_break_op (0);
817 fail_intersection_operation(op);
818 return;
644 case PHASE_FINISHED: 819 case PHASE_FINISHED:
645 GNUNET_break_op (0); 820 GNUNET_break_op (0);
646 fail_intersection_operation(op); 821 fail_intersection_operation(op);
@@ -650,13 +825,28 @@ process_bf (struct Operation *op)
650 op->state->remote_bf = NULL; 825 op->state->remote_bf = NULL;
651 826
652 if ( (0 == op->state->my_element_count) || /* fully disjoint */ 827 if ( (0 == op->state->my_element_count) || /* fully disjoint */
653 ( (op->state->my_element_count == op->spec->remote_element_count) && 828 ( (op->state->my_element_count == op->remote_element_count) &&
654 (0 == memcmp (&op->state->my_xor, 829 (0 == memcmp (&op->state->my_xor,
655 &op->state->other_xor, 830 &op->state->other_xor,
656 sizeof (struct GNUNET_HashCode))) ) ) 831 sizeof (struct GNUNET_HashCode))) ) )
657 { 832 {
658 /* we are done */ 833 /* we are done */
659 send_peer_done (op); 834 op->state->phase = PHASE_MUST_SEND_DONE;
835 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
836 "Intersection succeeded, sending DONE to other peer\n");
837 GNUNET_CONTAINER_bloomfilter_free (op->state->local_bf);
838 op->state->local_bf = NULL;
839 if (GNUNET_SET_RESULT_FULL == op->result_mode)
840 {
841 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
842 "Sending full result set (%u elements)\n",
843 GNUNET_CONTAINER_multihashmap_size (op->state->my_elements));
844 op->state->full_result_iter
845 = GNUNET_CONTAINER_multihashmap_iterator_create (op->state->my_elements);
846 send_remaining_elements (op);
847 return;
848 }
849 send_p2p_done (op);
660 return; 850 return;
661 } 851 }
662 op->state->phase = PHASE_BF_EXCHANGE; 852 op->state->phase = PHASE_BF_EXCHANGE;
@@ -677,7 +867,7 @@ check_intersection_p2p_bf (void *cls,
677{ 867{
678 struct Operation *op = cls; 868 struct Operation *op = cls;
679 869
680 if (OT_INTERSECTION != op->type) 870 if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation)
681 { 871 {
682 GNUNET_break_op (0); 872 GNUNET_break_op (0);
683 return GNUNET_SYSERR; 873 return GNUNET_SYSERR;
@@ -727,7 +917,7 @@ handle_intersection_p2p_bf (void *cls,
727 bf_size, 917 bf_size,
728 bf_bits_per_element); 918 bf_bits_per_element);
729 op->state->salt = ntohl (msg->sender_mutator); 919 op->state->salt = ntohl (msg->sender_mutator);
730 op->spec->remote_element_count = ntohl (msg->sender_element_count); 920 op->remote_element_count = ntohl (msg->sender_element_count);
731 process_bf (op); 921 process_bf (op);
732 break; 922 break;
733 } 923 }
@@ -740,7 +930,7 @@ handle_intersection_p2p_bf (void *cls,
740 op->state->bf_bits_per_element = bf_bits_per_element; 930 op->state->bf_bits_per_element = bf_bits_per_element;
741 op->state->bf_data_offset = 0; 931 op->state->bf_data_offset = 0;
742 op->state->salt = ntohl (msg->sender_mutator); 932 op->state->salt = ntohl (msg->sender_mutator);
743 op->spec->remote_element_count = ntohl (msg->sender_element_count); 933 op->remote_element_count = ntohl (msg->sender_element_count);
744 } 934 }
745 else 935 else
746 { 936 {
@@ -749,7 +939,7 @@ handle_intersection_p2p_bf (void *cls,
749 (op->state->bf_bits_per_element != bf_bits_per_element) || 939 (op->state->bf_bits_per_element != bf_bits_per_element) ||
750 (op->state->bf_data_offset + chunk_size > bf_size) || 940 (op->state->bf_data_offset + chunk_size > bf_size) ||
751 (op->state->salt != ntohl (msg->sender_mutator)) || 941 (op->state->salt != ntohl (msg->sender_mutator)) ||
752 (op->spec->remote_element_count != ntohl (msg->sender_element_count)) ) 942 (op->remote_element_count != ntohl (msg->sender_element_count)) )
753 { 943 {
754 GNUNET_break_op (0); 944 GNUNET_break_op (0);
755 fail_intersection_operation (op); 945 fail_intersection_operation (op);
@@ -783,147 +973,6 @@ handle_intersection_p2p_bf (void *cls,
783 973
784 974
785/** 975/**
786 * Fills the "my_elements" hashmap with the initial set of
787 * (non-deleted) elements from the set of the specification.
788 *
789 * @param cls closure with the `struct Operation *`
790 * @param key current key code for the element
791 * @param value value in the hash map with the `struct ElementEntry *`
792 * @return #GNUNET_YES (we should continue to iterate)
793 */
794static int
795initialize_map_unfiltered (void *cls,
796 const struct GNUNET_HashCode *key,
797 void *value)
798{
799 struct ElementEntry *ee = value;
800 struct Operation *op = cls;
801
802 if (GNUNET_NO == _GSS_is_element_of_operation (ee, op))
803 return GNUNET_YES; /* element not live in operation's generation */
804 GNUNET_CRYPTO_hash_xor (&op->state->my_xor,
805 &ee->element_hash,
806 &op->state->my_xor);
807 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
808 "Initial full initialization of my_elements, adding %s:%u\n",
809 GNUNET_h2s (&ee->element_hash),
810 ee->element.size);
811 GNUNET_break (GNUNET_YES ==
812 GNUNET_CONTAINER_multihashmap_put (op->state->my_elements,
813 &ee->element_hash,
814 ee,
815 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
816 return GNUNET_YES;
817}
818
819
820/**
821 * Send our element count to the peer, in case our element count is
822 * lower than his.
823 *
824 * @param op intersection operation
825 */
826static void
827send_element_count (struct Operation *op)
828{
829 struct GNUNET_MQ_Envelope *ev;
830 struct IntersectionElementInfoMessage *msg;
831
832 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
833 "Sending our element count (%u)\n",
834 op->state->my_element_count);
835 ev = GNUNET_MQ_msg (msg,
836 GNUNET_MESSAGE_TYPE_SET_INTERSECTION_P2P_ELEMENT_INFO);
837 msg->sender_element_count = htonl (op->state->my_element_count);
838 GNUNET_MQ_send (op->mq, ev);
839}
840
841
842/**
843 * We go first, initialize our map with all elements and
844 * send the first Bloom filter.
845 *
846 * @param op operation to start exchange for
847 */
848static void
849begin_bf_exchange (struct Operation *op)
850{
851 op->state->phase = PHASE_BF_EXCHANGE;
852 GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements,
853 &initialize_map_unfiltered,
854 op);
855 send_bloomfilter (op);
856}
857
858
859/**
860 * Handle the initial `struct IntersectionElementInfoMessage` from a
861 * remote peer.
862 *
863 * @param cls the intersection operation
864 * @param mh the header of the message
865 */
866void
867handle_intersection_p2p_element_info (void *cls,
868 const struct IntersectionElementInfoMessage *msg)
869{
870 struct Operation *op = cls;
871
872 if (OT_INTERSECTION != op->type)
873 {
874 GNUNET_break_op (0);
875 fail_intersection_operation(op);
876 return;
877 }
878 op->spec->remote_element_count = ntohl (msg->sender_element_count);
879 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
880 "Received remote element count (%u), I have %u\n",
881 op->spec->remote_element_count,
882 op->state->my_element_count);
883 if ( ( (PHASE_INITIAL != op->state->phase) &&
884 (PHASE_COUNT_SENT != op->state->phase) ) ||
885 (op->state->my_element_count > op->spec->remote_element_count) ||
886 (0 == op->state->my_element_count) ||
887 (0 == op->spec->remote_element_count) )
888 {
889 GNUNET_break_op (0);
890 fail_intersection_operation(op);
891 return;
892 }
893 GNUNET_break (NULL == op->state->remote_bf);
894 begin_bf_exchange (op);
895 GNUNET_CADET_receive_done (op->channel);
896}
897
898
899/**
900 * Send a result message to the client indicating that the operation
901 * is over. After the result done message has been sent to the
902 * client, destroy the evaluate operation.
903 *
904 * @param op intersection operation
905 */
906static void
907finish_and_destroy (struct Operation *op)
908{
909 GNUNET_assert (GNUNET_NO == op->state->client_done_sent);
910
911 if (GNUNET_SET_RESULT_FULL == op->spec->result_mode)
912 {
913 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
914 "Sending full result set (%u elements)\n",
915 GNUNET_CONTAINER_multihashmap_size (op->state->my_elements));
916 op->state->full_result_iter
917 = GNUNET_CONTAINER_multihashmap_iterator_create (op->state->my_elements);
918 op->keep++;
919 send_remaining_elements (op);
920 return;
921 }
922 send_client_done_and_destroy (op);
923}
924
925
926/**
927 * Remove all elements from our hashmap. 976 * Remove all elements from our hashmap.
928 * 977 *
929 * @param cls closure with the `struct Operation *` 978 * @param cls closure with the `struct Operation *`
@@ -970,10 +1019,10 @@ handle_intersection_p2p_done (void *cls,
970{ 1019{
971 struct Operation *op = cls; 1020 struct Operation *op = cls;
972 1021
973 if (OT_INTERSECTION != op->type) 1022 if (GNUNET_SET_OPERATION_INTERSECTION != op->set->operation)
974 { 1023 {
975 GNUNET_break_op (0); 1024 GNUNET_break_op (0);
976 fail_intersection_operation(op); 1025 fail_intersection_operation (op);
977 return; 1026 return;
978 } 1027 }
979 if (PHASE_BF_EXCHANGE != op->state->phase) 1028 if (PHASE_BF_EXCHANGE != op->state->phase)
@@ -1005,9 +1054,22 @@ handle_intersection_p2p_done (void *cls,
1005 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1054 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1006 "Got IntersectionDoneMessage, have %u elements in intersection\n", 1055 "Got IntersectionDoneMessage, have %u elements in intersection\n",
1007 op->state->my_element_count); 1056 op->state->my_element_count);
1008 op->state->phase = PHASE_FINISHED; 1057 op->state->phase = PHASE_DONE_RECEIVED;
1009 finish_and_destroy (op);
1010 GNUNET_CADET_receive_done (op->channel); 1058 GNUNET_CADET_receive_done (op->channel);
1059
1060 GNUNET_assert (GNUNET_NO == op->state->client_done_sent);
1061 if (GNUNET_SET_RESULT_FULL == op->result_mode)
1062 {
1063 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1064 "Sending full result set to client (%u elements)\n",
1065 GNUNET_CONTAINER_multihashmap_size (op->state->my_elements));
1066 op->state->full_result_iter
1067 = GNUNET_CONTAINER_multihashmap_iterator_create (op->state->my_elements);
1068 send_remaining_elements (op);
1069 return;
1070 }
1071 op->state->phase = PHASE_FINISHED;
1072 send_client_done_and_destroy (op);
1011} 1073}
1012 1074
1013 1075
@@ -1018,24 +1080,16 @@ handle_intersection_p2p_done (void *cls,
1018 * begin the evaluation 1080 * begin the evaluation
1019 * @param opaque_context message to be transmitted to the listener 1081 * @param opaque_context message to be transmitted to the listener
1020 * to convince him to accept, may be NULL 1082 * to convince him to accept, may be NULL
1083 * @return operation-specific state to keep in @a op
1021 */ 1084 */
1022static void 1085static struct OperationState *
1023intersection_evaluate (struct Operation *op, 1086intersection_evaluate (struct Operation *op,
1024 const struct GNUNET_MessageHeader *opaque_context) 1087 const struct GNUNET_MessageHeader *opaque_context)
1025{ 1088{
1089 struct OperationState *state;
1026 struct GNUNET_MQ_Envelope *ev; 1090 struct GNUNET_MQ_Envelope *ev;
1027 struct OperationRequestMessage *msg; 1091 struct OperationRequestMessage *msg;
1028 1092
1029 op->state = GNUNET_new (struct OperationState);
1030 /* we started the operation, thus we have to send the operation request */
1031 op->state->phase = PHASE_INITIAL;
1032 op->state->my_element_count = op->spec->set->state->current_set_element_count;
1033 op->state->my_elements
1034 = GNUNET_CONTAINER_multihashmap_create (op->state->my_element_count,
1035 GNUNET_YES);
1036
1037 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1038 "Initiating intersection operation evaluation\n");
1039 ev = GNUNET_MQ_msg_nested_mh (msg, 1093 ev = GNUNET_MQ_msg_nested_mh (msg,
1040 GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST, 1094 GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST,
1041 opaque_context); 1095 opaque_context);
@@ -1043,20 +1097,30 @@ intersection_evaluate (struct Operation *op,
1043 { 1097 {
1044 /* the context message is too large!? */ 1098 /* the context message is too large!? */
1045 GNUNET_break (0); 1099 GNUNET_break (0);
1046 GNUNET_SERVICE_client_drop (op->spec->set->client); 1100 return NULL;
1047 return;
1048 } 1101 }
1102 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1103 "Initiating intersection operation evaluation\n");
1104 state = GNUNET_new (struct OperationState);
1105 /* we started the operation, thus we have to send the operation request */
1106 state->phase = PHASE_INITIAL;
1107 state->my_element_count = op->set->state->current_set_element_count;
1108 state->my_elements
1109 = GNUNET_CONTAINER_multihashmap_create (state->my_element_count,
1110 GNUNET_YES);
1111
1049 msg->operation = htonl (GNUNET_SET_OPERATION_INTERSECTION); 1112 msg->operation = htonl (GNUNET_SET_OPERATION_INTERSECTION);
1050 msg->element_count = htonl (op->state->my_element_count); 1113 msg->element_count = htonl (state->my_element_count);
1051 GNUNET_MQ_send (op->mq, 1114 GNUNET_MQ_send (op->mq,
1052 ev); 1115 ev);
1053 op->state->phase = PHASE_COUNT_SENT; 1116 state->phase = PHASE_COUNT_SENT;
1054 if (NULL != opaque_context) 1117 if (NULL != opaque_context)
1055 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1118 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1056 "Sent op request with context message\n"); 1119 "Sent op request with context message\n");
1057 else 1120 else
1058 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1121 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1059 "Sent op request without context message\n"); 1122 "Sent op request without context message\n");
1123 return state;
1060} 1124}
1061 1125
1062 1126
@@ -1066,53 +1130,33 @@ intersection_evaluate (struct Operation *op,
1066 * 1130 *
1067 * @param op operation that will be accepted as an intersection operation 1131 * @param op operation that will be accepted as an intersection operation
1068 */ 1132 */
1069static void 1133static struct OperationState *
1070intersection_accept (struct Operation *op) 1134intersection_accept (struct Operation *op)
1071{ 1135{
1136 struct OperationState *state;
1137
1072 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1138 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1073 "Accepting set intersection operation\n"); 1139 "Accepting set intersection operation\n");
1074 op->state = GNUNET_new (struct OperationState); 1140 state = GNUNET_new (struct OperationState);
1075 op->state->phase = PHASE_INITIAL; 1141 state->phase = PHASE_INITIAL;
1076 op->state->my_element_count 1142 state->my_element_count
1077 = op->spec->set->state->current_set_element_count; 1143 = op->set->state->current_set_element_count;
1078 GNUNET_assert (NULL == op->state->my_elements); 1144 state->my_elements
1079 op->state->my_elements 1145 = GNUNET_CONTAINER_multihashmap_create (GNUNET_MIN (state->my_element_count,
1080 = GNUNET_CONTAINER_multihashmap_create (GNUNET_MIN (op->state->my_element_count, 1146 op->remote_element_count),
1081 op->spec->remote_element_count),
1082 GNUNET_YES); 1147 GNUNET_YES);
1083 if (op->spec->remote_element_count < op->state->my_element_count) 1148 op->state = state;
1149 if (op->remote_element_count < state->my_element_count)
1084 { 1150 {
1085 /* If the other peer (Alice) has fewer elements than us (Bob), 1151 /* If the other peer (Alice) has fewer elements than us (Bob),
1086 we just send the count as Alice should send the first BF */ 1152 we just send the count as Alice should send the first BF */
1087 send_element_count (op); 1153 send_element_count (op);
1088 op->state->phase = PHASE_COUNT_SENT; 1154 state->phase = PHASE_COUNT_SENT;
1089 return; 1155 return state;
1090 } 1156 }
1091 /* We have fewer elements, so we start with the BF */ 1157 /* We have fewer elements, so we start with the BF */
1092 begin_bf_exchange (op); 1158 begin_bf_exchange (op);
1093} 1159 return state;
1094
1095
1096/**
1097 * Handler for peer-disconnects, notifies the client about the aborted
1098 * operation. If we did not expect anything from the other peer, we
1099 * gracefully terminate the operation.
1100 *
1101 * @param op the destroyed operation
1102 */
1103static void
1104intersection_peer_disconnect (struct Operation *op)
1105{
1106 if (PHASE_FINISHED != op->state->phase)
1107 {
1108 fail_intersection_operation (op);
1109 return;
1110 }
1111 /* the session has already been concluded */
1112 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1113 "Other peer disconnected (finished)\n");
1114 if (GNUNET_NO == op->state->client_done_sent)
1115 finish_and_destroy (op);
1116} 1160}
1117 1161
1118 1162
@@ -1215,6 +1259,28 @@ intersection_remove (struct SetState *set_state,
1215 1259
1216 1260
1217/** 1261/**
1262 * Callback for channel death for the intersection operation.
1263 *
1264 * @param op operation that lost the channel
1265 */
1266static void
1267intersection_channel_death (struct Operation *op)
1268{
1269 if (GNUNET_YES == op->state->channel_death_expected)
1270 {
1271 /* oh goodie, we are done! */
1272 send_client_done_and_destroy (op);
1273 }
1274 else
1275 {
1276 /* sorry, channel went down early, too bad. */
1277 _GSS_operation_destroy (op,
1278 GNUNET_YES);
1279 }
1280}
1281
1282
1283/**
1218 * Get the table with implementing functions for set intersection. 1284 * Get the table with implementing functions for set intersection.
1219 * 1285 *
1220 * @return the operation specific VTable 1286 * @return the operation specific VTable
@@ -1229,8 +1295,8 @@ _GSS_intersection_vt ()
1229 .destroy_set = &intersection_set_destroy, 1295 .destroy_set = &intersection_set_destroy,
1230 .evaluate = &intersection_evaluate, 1296 .evaluate = &intersection_evaluate,
1231 .accept = &intersection_accept, 1297 .accept = &intersection_accept,
1232 .peer_disconnect = &intersection_peer_disconnect,
1233 .cancel = &intersection_op_cancel, 1298 .cancel = &intersection_op_cancel,
1299 .channel_death = &intersection_channel_death,
1234 }; 1300 };
1235 1301
1236 return &intersection_vt; 1302 return &intersection_vt;
diff --git a/src/set/gnunet-service-set_union.c b/src/set/gnunet-service-set_union.c
index 1ff3d7716..fc7e578e6 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)
368 "union operation failed\n"); 368 "union operation failed\n");
369 ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_RESULT); 369 ev = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_RESULT);
370 msg->result_status = htons (GNUNET_SET_STATUS_FAILURE); 370 msg->result_status = htons (GNUNET_SET_STATUS_FAILURE);
371 msg->request_id = htonl (op->spec->client_request_id); 371 msg->request_id = htonl (op->client_request_id);
372 msg->element_type = htons (0); 372 msg->element_type = htons (0);
373 GNUNET_MQ_send (op->spec->set->client_mq, ev); 373 GNUNET_MQ_send (op->set->cs->mq,
374 ev);
374 _GSS_operation_destroy (op, GNUNET_YES); 375 _GSS_operation_destroy (op, GNUNET_YES);
375} 376}
376 377
@@ -401,7 +402,14 @@ get_ibf_key (const struct GNUNET_HashCode *src)
401 */ 402 */
402struct GetElementContext 403struct GetElementContext
403{ 404{
405 /**
406 * FIXME.
407 */
404 struct GNUNET_HashCode hash; 408 struct GNUNET_HashCode hash;
409
410 /**
411 * FIXME.
412 */
405 struct KeyEntry *k; 413 struct KeyEntry *k;
406}; 414};
407 415
@@ -504,6 +512,9 @@ op_register_element (struct Operation *op,
504} 512}
505 513
506 514
515/**
516 * FIXME.
517 */
507static void 518static void
508salt_key (const struct IBF_Key *k_in, 519salt_key (const struct IBF_Key *k_in,
509 uint32_t salt, 520 uint32_t salt,
@@ -517,6 +528,9 @@ salt_key (const struct IBF_Key *k_in,
517} 528}
518 529
519 530
531/**
532 * FIXME.
533 */
520static void 534static void
521unsalt_key (const struct IBF_Key *k_in, 535unsalt_key (const struct IBF_Key *k_in,
522 uint32_t salt, 536 uint32_t salt,
@@ -550,7 +564,9 @@ prepare_ibf_iterator (void *cls,
550 (void *) op, 564 (void *) op,
551 (unsigned long) ke->ibf_key.key_val, 565 (unsigned long) ke->ibf_key.key_val,
552 GNUNET_h2s (&ke->element->element_hash)); 566 GNUNET_h2s (&ke->element->element_hash));
553 salt_key (&ke->ibf_key, op->state->salt_send, &salted_key); 567 salt_key (&ke->ibf_key,
568 op->state->salt_send,
569 &salted_key);
554 ibf_insert (op->state->local_ibf, salted_key); 570 ibf_insert (op->state->local_ibf, salted_key);
555 return GNUNET_YES; 571 return GNUNET_YES;
556} 572}
@@ -576,12 +592,14 @@ init_key_to_element_iterator (void *cls,
576 592
577 /* make sure that the element belongs to the set at the time 593 /* make sure that the element belongs to the set at the time
578 * of creating the operation */ 594 * of creating the operation */
579 if (GNUNET_NO == _GSS_is_element_of_operation (ee, op)) 595 if (GNUNET_NO ==
596 _GSS_is_element_of_operation (ee,
597 op))
580 return GNUNET_YES; 598 return GNUNET_YES;
581
582 GNUNET_assert (GNUNET_NO == ee->remote); 599 GNUNET_assert (GNUNET_NO == ee->remote);
583 600 op_register_element (op,
584 op_register_element (op, ee, GNUNET_NO); 601 ee,
602 GNUNET_NO);
585 return GNUNET_YES; 603 return GNUNET_YES;
586} 604}
587 605
@@ -598,9 +616,11 @@ initialize_key_to_element (struct Operation *op)
598 unsigned int len; 616 unsigned int len;
599 617
600 GNUNET_assert (NULL == op->state->key_to_element); 618 GNUNET_assert (NULL == op->state->key_to_element);
601 len = GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements); 619 len = GNUNET_CONTAINER_multihashmap_size (op->set->content->elements);
602 op->state->key_to_element = GNUNET_CONTAINER_multihashmap32_create (len + 1); 620 op->state->key_to_element = GNUNET_CONTAINER_multihashmap32_create (len + 1);
603 GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements, init_key_to_element_iterator, op); 621 GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements,
622 &init_key_to_element_iterator,
623 op);
604} 624}
605 625
606 626
@@ -707,44 +727,6 @@ send_ibf (struct Operation *op,
707 727
708 728
709/** 729/**
710 * Send a strata estimator to the remote peer.
711 *
712 * @param op the union operation with the remote peer
713 */
714static void
715send_strata_estimator (struct Operation *op)
716{
717 const struct StrataEstimator *se = op->state->se;
718 struct GNUNET_MQ_Envelope *ev;
719 struct StrataEstimatorMessage *strata_msg;
720 char *buf;
721 size_t len;
722 uint16_t type;
723
724 buf = GNUNET_malloc (se->strata_count * IBF_BUCKET_SIZE * se->ibf_size);
725 len = strata_estimator_write (op->state->se,
726 buf);
727 if (len < se->strata_count * IBF_BUCKET_SIZE * se->ibf_size)
728 type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC;
729 else
730 type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE;
731 ev = GNUNET_MQ_msg_extra (strata_msg,
732 len,
733 type);
734 GNUNET_memcpy (&strata_msg[1],
735 buf,
736 len);
737 GNUNET_free (buf);
738 strata_msg->set_size = GNUNET_htonll (GNUNET_CONTAINER_multihashmap_size (op->spec->set->content->elements));
739 GNUNET_MQ_send (op->mq,
740 ev);
741 op->state->phase = PHASE_EXPECT_IBF;
742 LOG (GNUNET_ERROR_TYPE_DEBUG,
743 "sent SE, expecting IBF\n");
744}
745
746
747/**
748 * Compute the necessary order of an ibf 730 * Compute the necessary order of an ibf
749 * from the size of the symmetric set difference. 731 * from the size of the symmetric set difference.
750 * 732 *
@@ -777,7 +759,7 @@ get_order_from_difference (unsigned int diff)
777 * @return #GNUNET_YES (to continue iterating) 759 * @return #GNUNET_YES (to continue iterating)
778 */ 760 */
779static int 761static int
780send_element_iterator (void *cls, 762send_full_element_iterator (void *cls,
781 const struct GNUNET_HashCode *key, 763 const struct GNUNET_HashCode *key,
782 void *value) 764 void *value)
783{ 765{
@@ -803,16 +785,23 @@ send_element_iterator (void *cls,
803} 785}
804 786
805 787
788/**
789 * Switch to full set transmission for @a op.
790 *
791 * @param op operation to switch to full set transmission.
792 */
806static void 793static void
807send_full_set (struct Operation *op) 794send_full_set (struct Operation *op)
808{ 795{
809 struct GNUNET_MQ_Envelope *ev; 796 struct GNUNET_MQ_Envelope *ev;
810 797
811 op->state->phase = PHASE_FULL_SENDING; 798 op->state->phase = PHASE_FULL_SENDING;
799 LOG (GNUNET_ERROR_TYPE_INFO,
800 "Dedicing to transmit the full set\n");
812 /* FIXME: use a more memory-friendly way of doing this with an 801 /* FIXME: use a more memory-friendly way of doing this with an
813 iterator, just as we do in the non-full case! */ 802 iterator, just as we do in the non-full case! */
814 (void) GNUNET_CONTAINER_multihashmap_iterate (op->spec->set->content->elements, 803 (void) GNUNET_CONTAINER_multihashmap_iterate (op->set->content->elements,
815 &send_element_iterator, 804 &send_full_element_iterator,
816 op); 805 op);
817 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE); 806 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE);
818 GNUNET_MQ_send (op->mq, 807 GNUNET_MQ_send (op->mq,
@@ -923,15 +912,15 @@ handle_union_p2p_strata_estimator (void *cls,
923 } 912 }
924 } 913 }
925 914
926 if ( (GNUNET_YES == op->spec->byzantine) && 915 if ( (GNUNET_YES == op->byzantine) &&
927 (other_size < op->spec->byzantine_lower_bound) ) 916 (other_size < op->byzantine_lower_bound) )
928 { 917 {
929 GNUNET_break (0); 918 GNUNET_break (0);
930 fail_union_operation (op); 919 fail_union_operation (op);
931 return; 920 return;
932 } 921 }
933 922
934 if ( (GNUNET_YES == op->spec->force_full) || 923 if ( (GNUNET_YES == op->force_full) ||
935 (diff > op->state->initial_size / 4) || 924 (diff > op->state->initial_size / 4) ||
936 (0 == other_size) ) 925 (0 == other_size) )
937 { 926 {
@@ -1058,14 +1047,16 @@ decode_and_send (struct Operation *op)
1058 GNUNET_assert (PHASE_INVENTORY_ACTIVE == op->state->phase); 1047 GNUNET_assert (PHASE_INVENTORY_ACTIVE == op->state->phase);
1059 1048
1060 if (GNUNET_OK != 1049 if (GNUNET_OK !=
1061 prepare_ibf (op, op->state->remote_ibf->size)) 1050 prepare_ibf (op,
1051 op->state->remote_ibf->size))
1062 { 1052 {
1063 GNUNET_break (0); 1053 GNUNET_break (0);
1064 /* allocation failed */ 1054 /* allocation failed */
1065 return GNUNET_SYSERR; 1055 return GNUNET_SYSERR;
1066 } 1056 }
1067 diff_ibf = ibf_dup (op->state->local_ibf); 1057 diff_ibf = ibf_dup (op->state->local_ibf);
1068 ibf_subtract (diff_ibf, op->state->remote_ibf); 1058 ibf_subtract (diff_ibf,
1059 op->state->remote_ibf);
1069 1060
1070 ibf_destroy (op->state->remote_ibf); 1061 ibf_destroy (op->state->remote_ibf);
1071 op->state->remote_ibf = NULL; 1062 op->state->remote_ibf = NULL;
@@ -1162,8 +1153,12 @@ decode_and_send (struct Operation *op)
1162 if (1 == side) 1153 if (1 == side)
1163 { 1154 {
1164 struct IBF_Key unsalted_key; 1155 struct IBF_Key unsalted_key;
1165 unsalt_key (&key, op->state->salt_receive, &unsalted_key); 1156
1166 send_offers_for_key (op, unsalted_key); 1157 unsalt_key (&key,
1158 op->state->salt_receive,
1159 &unsalted_key);
1160 send_offers_for_key (op,
1161 unsalted_key);
1167 } 1162 }
1168 else if (-1 == side) 1163 else if (-1 == side)
1169 { 1164 {
@@ -1211,7 +1206,7 @@ check_union_p2p_ibf (void *cls,
1211 struct Operation *op = cls; 1206 struct Operation *op = cls;
1212 unsigned int buckets_in_message; 1207 unsigned int buckets_in_message;
1213 1208
1214 if (OT_UNION != op->type) 1209 if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1215 { 1210 {
1216 GNUNET_break_op (0); 1211 GNUNET_break_op (0);
1217 return GNUNET_SYSERR; 1212 return GNUNET_SYSERR;
@@ -1304,6 +1299,8 @@ handle_union_p2p_ibf (void *cls,
1304 else 1299 else
1305 { 1300 {
1306 GNUNET_assert (op->state->phase == PHASE_EXPECT_IBF_CONT); 1301 GNUNET_assert (op->state->phase == PHASE_EXPECT_IBF_CONT);
1302 LOG (GNUNET_ERROR_TYPE_INFO,
1303 "Received more of IBF\n");
1307 } 1304 }
1308 GNUNET_assert (NULL != op->state->remote_ibf); 1305 GNUNET_assert (NULL != op->state->remote_ibf);
1309 1306
@@ -1351,7 +1348,7 @@ send_client_element (struct Operation *op,
1351 LOG (GNUNET_ERROR_TYPE_DEBUG, 1348 LOG (GNUNET_ERROR_TYPE_DEBUG,
1352 "sending element (size %u) to client\n", 1349 "sending element (size %u) to client\n",
1353 element->size); 1350 element->size);
1354 GNUNET_assert (0 != op->spec->client_request_id); 1351 GNUNET_assert (0 != op->client_request_id);
1355 ev = GNUNET_MQ_msg_extra (rm, element->size, GNUNET_MESSAGE_TYPE_SET_RESULT); 1352 ev = GNUNET_MQ_msg_extra (rm, element->size, GNUNET_MESSAGE_TYPE_SET_RESULT);
1356 if (NULL == ev) 1353 if (NULL == ev)
1357 { 1354 {
@@ -1360,11 +1357,14 @@ send_client_element (struct Operation *op,
1360 return; 1357 return;
1361 } 1358 }
1362 rm->result_status = htons (status); 1359 rm->result_status = htons (status);
1363 rm->request_id = htonl (op->spec->client_request_id); 1360 rm->request_id = htonl (op->client_request_id);
1364 rm->element_type = htons (element->element_type); 1361 rm->element_type = htons (element->element_type);
1365 rm->current_size = GNUNET_htonll (GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element)); 1362 rm->current_size = GNUNET_htonll (GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element));
1366 GNUNET_memcpy (&rm[1], element->data, element->size); 1363 GNUNET_memcpy (&rm[1],
1367 GNUNET_MQ_send (op->spec->set->client_mq, ev); 1364 element->data,
1365 element->size);
1366 GNUNET_MQ_send (op->set->cs->mq,
1367 ev);
1368} 1368}
1369 1369
1370 1370
@@ -1381,14 +1381,19 @@ send_done_and_destroy (void *cls)
1381 struct GNUNET_MQ_Envelope *ev; 1381 struct GNUNET_MQ_Envelope *ev;
1382 struct GNUNET_SET_ResultMessage *rm; 1382 struct GNUNET_SET_ResultMessage *rm;
1383 1383
1384 ev = GNUNET_MQ_msg (rm, GNUNET_MESSAGE_TYPE_SET_RESULT); 1384 LOG (GNUNET_ERROR_TYPE_INFO,
1385 rm->request_id = htonl (op->spec->client_request_id); 1385 "Signalling client that union operation is done\n");
1386 ev = GNUNET_MQ_msg (rm,
1387 GNUNET_MESSAGE_TYPE_SET_RESULT);
1388 rm->request_id = htonl (op->client_request_id);
1386 rm->result_status = htons (GNUNET_SET_STATUS_DONE); 1389 rm->result_status = htons (GNUNET_SET_STATUS_DONE);
1387 rm->element_type = htons (0); 1390 rm->element_type = htons (0);
1388 rm->current_size = GNUNET_htonll (GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element)); 1391 rm->current_size = GNUNET_htonll (GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element));
1389 GNUNET_MQ_send (op->spec->set->client_mq, ev); 1392 GNUNET_MQ_send (op->set->cs->mq,
1393 ev);
1390 /* Will also call the union-specific cancel function. */ 1394 /* Will also call the union-specific cancel function. */
1391 _GSS_operation_destroy (op, GNUNET_YES); 1395 _GSS_operation_destroy (op,
1396 GNUNET_YES);
1392} 1397}
1393 1398
1394 1399
@@ -1415,8 +1420,8 @@ maybe_finish (struct Operation *op)
1415 1420
1416 op->state->phase = PHASE_DONE; 1421 op->state->phase = PHASE_DONE;
1417 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE); 1422 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DONE);
1418 GNUNET_MQ_send (op->mq, ev); 1423 GNUNET_MQ_send (op->mq,
1419 1424 ev);
1420 /* We now wait until the other peer closes the channel 1425 /* We now wait until the other peer closes the channel
1421 * after it got all elements from us. */ 1426 * after it got all elements from us. */
1422 } 1427 }
@@ -1447,7 +1452,7 @@ check_union_p2p_elements (void *cls,
1447{ 1452{
1448 struct Operation *op = cls; 1453 struct Operation *op = cls;
1449 1454
1450 if (OT_UNION != op->type) 1455 if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1451 { 1456 {
1452 GNUNET_break_op (0); 1457 GNUNET_break_op (0);
1453 return GNUNET_SYSERR; 1458 return GNUNET_SYSERR;
@@ -1535,7 +1540,7 @@ handle_union_p2p_elements (void *cls,
1535 op->state->received_fresh++; 1540 op->state->received_fresh++;
1536 op_register_element (op, ee, GNUNET_YES); 1541 op_register_element (op, ee, GNUNET_YES);
1537 /* only send results immediately if the client wants it */ 1542 /* only send results immediately if the client wants it */
1538 switch (op->spec->result_mode) 1543 switch (op->result_mode)
1539 { 1544 {
1540 case GNUNET_SET_RESULT_ADDED: 1545 case GNUNET_SET_RESULT_ADDED:
1541 send_client_element (op, &ee->element, GNUNET_SET_STATUS_OK); 1546 send_client_element (op, &ee->element, GNUNET_SET_STATUS_OK);
@@ -1575,7 +1580,7 @@ check_union_p2p_full_element (void *cls,
1575{ 1580{
1576 struct Operation *op = cls; 1581 struct Operation *op = cls;
1577 1582
1578 if (OT_UNION != op->type) 1583 if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1579 { 1584 {
1580 GNUNET_break_op (0); 1585 GNUNET_break_op (0);
1581 return GNUNET_SYSERR; 1586 return GNUNET_SYSERR;
@@ -1644,7 +1649,7 @@ handle_union_p2p_full_element (void *cls,
1644 op->state->received_fresh++; 1649 op->state->received_fresh++;
1645 op_register_element (op, ee, GNUNET_YES); 1650 op_register_element (op, ee, GNUNET_YES);
1646 /* only send results immediately if the client wants it */ 1651 /* only send results immediately if the client wants it */
1647 switch (op->spec->result_mode) 1652 switch (op->result_mode)
1648 { 1653 {
1649 case GNUNET_SET_RESULT_ADDED: 1654 case GNUNET_SET_RESULT_ADDED:
1650 send_client_element (op, &ee->element, GNUNET_SET_STATUS_OK); 1655 send_client_element (op, &ee->element, GNUNET_SET_STATUS_OK);
@@ -1659,7 +1664,7 @@ handle_union_p2p_full_element (void *cls,
1659 } 1664 }
1660 } 1665 }
1661 1666
1662 if ( (GNUNET_YES == op->spec->byzantine) && 1667 if ( (GNUNET_YES == op->byzantine) &&
1663 (op->state->received_total > 384 + op->state->received_fresh * 4) && 1668 (op->state->received_total > 384 + op->state->received_fresh * 4) &&
1664 (op->state->received_fresh < op->state->received_total / 6) ) 1669 (op->state->received_fresh < op->state->received_total / 6) )
1665 { 1670 {
@@ -1690,7 +1695,7 @@ check_union_p2p_inquiry (void *cls,
1690 struct Operation *op = cls; 1695 struct Operation *op = cls;
1691 unsigned int num_keys; 1696 unsigned int num_keys;
1692 1697
1693 if (OT_UNION != op->type) 1698 if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1694 { 1699 {
1695 GNUNET_break_op (0); 1700 GNUNET_break_op (0);
1696 return GNUNET_SYSERR; 1701 return GNUNET_SYSERR;
@@ -1727,6 +1732,8 @@ handle_union_p2p_inquiry (void *cls,
1727 const struct IBF_Key *ibf_key; 1732 const struct IBF_Key *ibf_key;
1728 unsigned int num_keys; 1733 unsigned int num_keys;
1729 1734
1735 LOG (GNUNET_ERROR_TYPE_INFO,
1736 "Received union inquiry\n");
1730 num_keys = (ntohs (msg->header.size) - sizeof (struct InquiryMessage)) 1737 num_keys = (ntohs (msg->header.size) - sizeof (struct InquiryMessage))
1731 / sizeof (struct IBF_Key); 1738 / sizeof (struct IBF_Key);
1732 ibf_key = (const struct IBF_Key *) &msg[1]; 1739 ibf_key = (const struct IBF_Key *) &msg[1];
@@ -1734,8 +1741,11 @@ handle_union_p2p_inquiry (void *cls,
1734 { 1741 {
1735 struct IBF_Key unsalted_key; 1742 struct IBF_Key unsalted_key;
1736 1743
1737 unsalt_key (ibf_key, ntohl (msg->salt), &unsalted_key); 1744 unsalt_key (ibf_key,
1738 send_offers_for_key (op, unsalted_key); 1745 ntohl (msg->salt),
1746 &unsalted_key);
1747 send_offers_for_key (op,
1748 unsalted_key);
1739 ibf_key++; 1749 ibf_key++;
1740 } 1750 }
1741 GNUNET_CADET_receive_done (op->channel); 1751 GNUNET_CADET_receive_done (op->channel);
@@ -1753,9 +1763,9 @@ handle_union_p2p_inquiry (void *cls,
1753 * #GNUNET_NO if not. 1763 * #GNUNET_NO if not.
1754 */ 1764 */
1755static int 1765static int
1756send_missing_elements_iter (void *cls, 1766send_missing_full_elements_iter (void *cls,
1757 uint32_t key, 1767 uint32_t key,
1758 void *value) 1768 void *value)
1759{ 1769{
1760 struct Operation *op = cls; 1770 struct Operation *op = cls;
1761 struct KeyEntry *ke = value; 1771 struct KeyEntry *ke = value;
@@ -1765,13 +1775,15 @@ send_missing_elements_iter (void *cls,
1765 1775
1766 if (GNUNET_YES == ke->received) 1776 if (GNUNET_YES == ke->received)
1767 return GNUNET_YES; 1777 return GNUNET_YES;
1768 1778 ev = GNUNET_MQ_msg_extra (emsg,
1769 ev = GNUNET_MQ_msg_extra (emsg, ee->element.size, GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT); 1779 ee->element.size,
1770 GNUNET_memcpy (&emsg[1], ee->element.data, ee->element.size); 1780 GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_ELEMENT);
1771 emsg->reserved = htons (0); 1781 GNUNET_memcpy (&emsg[1],
1782 ee->element.data,
1783 ee->element.size);
1772 emsg->element_type = htons (ee->element.element_type); 1784 emsg->element_type = htons (ee->element.element_type);
1773 GNUNET_MQ_send (op->mq, ev); 1785 GNUNET_MQ_send (op->mq,
1774 1786 ev);
1775 return GNUNET_YES; 1787 return GNUNET_YES;
1776} 1788}
1777 1789
@@ -1790,7 +1802,7 @@ handle_union_p2p_request_full (void *cls,
1790 1802
1791 LOG (GNUNET_ERROR_TYPE_INFO, 1803 LOG (GNUNET_ERROR_TYPE_INFO,
1792 "Received request for full set transmission\n"); 1804 "Received request for full set transmission\n");
1793 if (OT_UNION != op->type) 1805 if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1794 { 1806 {
1795 GNUNET_break_op (0); 1807 GNUNET_break_op (0);
1796 fail_union_operation (op); 1808 fail_union_operation (op);
@@ -1833,11 +1845,15 @@ handle_union_p2p_full_done (void *cls,
1833 1845
1834 /* send all the elements that did not come from the remote peer */ 1846 /* send all the elements that did not come from the remote peer */
1835 GNUNET_CONTAINER_multihashmap32_iterate (op->state->key_to_element, 1847 GNUNET_CONTAINER_multihashmap32_iterate (op->state->key_to_element,
1836 &send_missing_elements_iter, 1848 &send_missing_full_elements_iter,
1837 op); 1849 op);
1838 1850
1839 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE); 1851 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_UNION_P2P_FULL_DONE);
1840 GNUNET_MQ_send (op->mq, ev); 1852 GNUNET_MQ_notify_sent (ev,
1853 &send_done_and_destroy,
1854 op);
1855 GNUNET_MQ_send (op->mq,
1856 ev);
1841 op->state->phase = PHASE_DONE; 1857 op->state->phase = PHASE_DONE;
1842 /* we now wait until the other peer shuts the tunnel down*/ 1858 /* we now wait until the other peer shuts the tunnel down*/
1843 } 1859 }
@@ -1880,7 +1896,7 @@ check_union_p2p_demand (void *cls,
1880 struct Operation *op = cls; 1896 struct Operation *op = cls;
1881 unsigned int num_hashes; 1897 unsigned int num_hashes;
1882 1898
1883 if (OT_UNION != op->type) 1899 if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1884 { 1900 {
1885 GNUNET_break_op (0); 1901 GNUNET_break_op (0);
1886 return GNUNET_SYSERR; 1902 return GNUNET_SYSERR;
@@ -1921,7 +1937,7 @@ handle_union_p2p_demand (void *cls,
1921 num_hashes > 0; 1937 num_hashes > 0;
1922 hash++, num_hashes--) 1938 hash++, num_hashes--)
1923 { 1939 {
1924 ee = GNUNET_CONTAINER_multihashmap_get (op->spec->set->content->elements, 1940 ee = GNUNET_CONTAINER_multihashmap_get (op->set->content->elements,
1925 hash); 1941 hash);
1926 if (NULL == ee) 1942 if (NULL == ee)
1927 { 1943 {
@@ -1952,7 +1968,7 @@ handle_union_p2p_demand (void *cls,
1952 1, 1968 1,
1953 GNUNET_NO); 1969 GNUNET_NO);
1954 1970
1955 switch (op->spec->result_mode) 1971 switch (op->result_mode)
1956 { 1972 {
1957 case GNUNET_SET_RESULT_ADDED: 1973 case GNUNET_SET_RESULT_ADDED:
1958 /* Nothing to do. */ 1974 /* Nothing to do. */
@@ -1984,7 +2000,7 @@ check_union_p2p_offer (void *cls,
1984 struct Operation *op = cls; 2000 struct Operation *op = cls;
1985 unsigned int num_hashes; 2001 unsigned int num_hashes;
1986 2002
1987 if (OT_UNION != op->type) 2003 if (GNUNET_SET_OPERATION_UNION != op->set->operation)
1988 { 2004 {
1989 GNUNET_break_op (0); 2005 GNUNET_break_op (0);
1990 return GNUNET_SYSERR; 2006 return GNUNET_SYSERR;
@@ -1998,8 +2014,8 @@ check_union_p2p_offer (void *cls,
1998 } 2014 }
1999 num_hashes = (ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader)) 2015 num_hashes = (ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader))
2000 / sizeof (struct GNUNET_HashCode); 2016 / sizeof (struct GNUNET_HashCode);
2001 if ((ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader)) 2017 if ((ntohs (mh->size) - sizeof (struct GNUNET_MessageHeader)) !=
2002 != num_hashes * sizeof (struct GNUNET_HashCode)) 2018 num_hashes * sizeof (struct GNUNET_HashCode))
2003 { 2019 {
2004 GNUNET_break_op (0); 2020 GNUNET_break_op (0);
2005 return GNUNET_SYSERR; 2021 return GNUNET_SYSERR;
@@ -2033,7 +2049,7 @@ handle_union_p2p_offer (void *cls,
2033 struct GNUNET_MessageHeader *demands; 2049 struct GNUNET_MessageHeader *demands;
2034 struct GNUNET_MQ_Envelope *ev; 2050 struct GNUNET_MQ_Envelope *ev;
2035 2051
2036 ee = GNUNET_CONTAINER_multihashmap_get (op->spec->set->content->elements, 2052 ee = GNUNET_CONTAINER_multihashmap_get (op->set->content->elements,
2037 hash); 2053 hash);
2038 if (NULL != ee) 2054 if (NULL != ee)
2039 if (GNUNET_YES == _GSS_is_element_of_operation (ee, op)) 2055 if (GNUNET_YES == _GSS_is_element_of_operation (ee, op))
@@ -2060,7 +2076,9 @@ handle_union_p2p_offer (void *cls,
2060 ev = GNUNET_MQ_msg_header_extra (demands, 2076 ev = GNUNET_MQ_msg_header_extra (demands,
2061 sizeof (struct GNUNET_HashCode), 2077 sizeof (struct GNUNET_HashCode),
2062 GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND); 2078 GNUNET_MESSAGE_TYPE_SET_UNION_P2P_DEMAND);
2063 *(struct GNUNET_HashCode *) &demands[1] = *hash; 2079 GNUNET_memcpy (&demands[1],
2080 hash,
2081 sizeof (struct GNUNET_HashCode));
2064 GNUNET_MQ_send (op->mq, ev); 2082 GNUNET_MQ_send (op->mq, ev);
2065 } 2083 }
2066 GNUNET_CADET_receive_done (op->channel); 2084 GNUNET_CADET_receive_done (op->channel);
@@ -2079,7 +2097,7 @@ handle_union_p2p_done (void *cls,
2079{ 2097{
2080 struct Operation *op = cls; 2098 struct Operation *op = cls;
2081 2099
2082 if (OT_UNION != op->type) 2100 if (GNUNET_SET_OPERATION_UNION != op->set->operation)
2083 { 2101 {
2084 GNUNET_break_op (0); 2102 GNUNET_break_op (0);
2085 fail_union_operation (op); 2103 fail_union_operation (op);
@@ -2134,21 +2152,31 @@ handle_union_p2p_done (void *cls,
2134 * @param opaque_context message to be transmitted to the listener 2152 * @param opaque_context message to be transmitted to the listener
2135 * to convince him to accept, may be NULL 2153 * to convince him to accept, may be NULL
2136 */ 2154 */
2137static void 2155static struct OperationState *
2138union_evaluate (struct Operation *op, 2156union_evaluate (struct Operation *op,
2139 const struct GNUNET_MessageHeader *opaque_context) 2157 const struct GNUNET_MessageHeader *opaque_context)
2140{ 2158{
2159 struct OperationState *state;
2141 struct GNUNET_MQ_Envelope *ev; 2160 struct GNUNET_MQ_Envelope *ev;
2142 struct OperationRequestMessage *msg; 2161 struct OperationRequestMessage *msg;
2143 2162
2144 GNUNET_assert (NULL == op->state); 2163 ev = GNUNET_MQ_msg_nested_mh (msg,
2145 op->state = GNUNET_new (struct OperationState); 2164 GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST,
2146 op->state->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); 2165 opaque_context);
2166 if (NULL == ev)
2167 {
2168 /* the context message is too large */
2169 GNUNET_break (0);
2170 return NULL;
2171 }
2172 state = GNUNET_new (struct OperationState);
2173 state->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32,
2174 GNUNET_NO);
2147 /* copy the current generation's strata estimator for this operation */ 2175 /* copy the current generation's strata estimator for this operation */
2148 op->state->se = strata_estimator_dup (op->spec->set->state->se); 2176 state->se = strata_estimator_dup (op->set->state->se);
2149 /* we started the operation, thus we have to send the operation request */ 2177 /* we started the operation, thus we have to send the operation request */
2150 op->state->phase = PHASE_EXPECT_SE; 2178 state->phase = PHASE_EXPECT_SE;
2151 op->state->salt_receive = op->state->salt_send = 42; 2179 state->salt_receive = state->salt_send = 42; // FIXME?????
2152 LOG (GNUNET_ERROR_TYPE_DEBUG, 2180 LOG (GNUNET_ERROR_TYPE_DEBUG,
2153 "Initiating union operation evaluation\n"); 2181 "Initiating union operation evaluation\n");
2154 GNUNET_STATISTICS_update (_GSS_statistics, 2182 GNUNET_STATISTICS_update (_GSS_statistics,
@@ -2159,16 +2187,6 @@ union_evaluate (struct Operation *op,
2159 "# of initiated union operations", 2187 "# of initiated union operations",
2160 1, 2188 1,
2161 GNUNET_NO); 2189 GNUNET_NO);
2162 ev = GNUNET_MQ_msg_nested_mh (msg,
2163 GNUNET_MESSAGE_TYPE_SET_P2P_OPERATION_REQUEST,
2164 opaque_context);
2165 if (NULL == ev)
2166 {
2167 /* the context message is too large */
2168 GNUNET_break (0);
2169 GNUNET_SERVICE_client_drop (op->spec->set->client);
2170 return;
2171 }
2172 msg->operation = htonl (GNUNET_SET_OPERATION_UNION); 2190 msg->operation = htonl (GNUNET_SET_OPERATION_UNION);
2173 GNUNET_MQ_send (op->mq, 2191 GNUNET_MQ_send (op->mq,
2174 ev); 2192 ev);
@@ -2180,8 +2198,10 @@ union_evaluate (struct Operation *op,
2180 LOG (GNUNET_ERROR_TYPE_DEBUG, 2198 LOG (GNUNET_ERROR_TYPE_DEBUG,
2181 "sent op request without context message\n"); 2199 "sent op request without context message\n");
2182 2200
2201 op->state = state;
2183 initialize_key_to_element (op); 2202 initialize_key_to_element (op);
2184 op->state->initial_size = GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element); 2203 state->initial_size = GNUNET_CONTAINER_multihashmap32_size (state->key_to_element);
2204 return state;
2185} 2205}
2186 2206
2187 2207
@@ -2191,13 +2211,19 @@ union_evaluate (struct Operation *op,
2191 * 2211 *
2192 * @param op operation that will be accepted as a union operation 2212 * @param op operation that will be accepted as a union operation
2193 */ 2213 */
2194static void 2214static struct OperationState *
2195union_accept (struct Operation *op) 2215union_accept (struct Operation *op)
2196{ 2216{
2217 struct OperationState *state;
2218 const struct StrataEstimator *se;
2219 struct GNUNET_MQ_Envelope *ev;
2220 struct StrataEstimatorMessage *strata_msg;
2221 char *buf;
2222 size_t len;
2223 uint16_t type;
2224
2197 LOG (GNUNET_ERROR_TYPE_DEBUG, 2225 LOG (GNUNET_ERROR_TYPE_DEBUG,
2198 "accepting set union operation\n"); 2226 "accepting set union operation\n");
2199 GNUNET_assert (NULL == op->state);
2200
2201 GNUNET_STATISTICS_update (_GSS_statistics, 2227 GNUNET_STATISTICS_update (_GSS_statistics,
2202 "# of accepted union operations", 2228 "# of accepted union operations",
2203 1, 2229 1,
@@ -2207,14 +2233,37 @@ union_accept (struct Operation *op)
2207 1, 2233 1,
2208 GNUNET_NO); 2234 GNUNET_NO);
2209 2235
2210 op->state = GNUNET_new (struct OperationState); 2236 state = GNUNET_new (struct OperationState);
2211 op->state->se = strata_estimator_dup (op->spec->set->state->se); 2237 state->se = strata_estimator_dup (op->set->state->se);
2212 op->state->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO); 2238 state->demanded_hashes = GNUNET_CONTAINER_multihashmap_create (32,
2213 op->state->salt_receive = op->state->salt_send = 42; 2239 GNUNET_NO);
2240 state->salt_receive = state->salt_send = 42; // FIXME?????
2241 op->state = state;
2214 initialize_key_to_element (op); 2242 initialize_key_to_element (op);
2215 op->state->initial_size = GNUNET_CONTAINER_multihashmap32_size (op->state->key_to_element); 2243 state->initial_size = GNUNET_CONTAINER_multihashmap32_size (state->key_to_element);
2244
2216 /* kick off the operation */ 2245 /* kick off the operation */
2217 send_strata_estimator (op); 2246 se = state->se;
2247 buf = GNUNET_malloc (se->strata_count * IBF_BUCKET_SIZE * se->ibf_size);
2248 len = strata_estimator_write (se,
2249 buf);
2250 if (len < se->strata_count * IBF_BUCKET_SIZE * se->ibf_size)
2251 type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SEC;
2252 else
2253 type = GNUNET_MESSAGE_TYPE_SET_UNION_P2P_SE;
2254 ev = GNUNET_MQ_msg_extra (strata_msg,
2255 len,
2256 type);
2257 GNUNET_memcpy (&strata_msg[1],
2258 buf,
2259 len);
2260 GNUNET_free (buf);
2261 strata_msg->set_size
2262 = GNUNET_htonll (GNUNET_CONTAINER_multihashmap_size (op->set->content->elements));
2263 GNUNET_MQ_send (op->mq,
2264 ev);
2265 state->phase = PHASE_EXPECT_IBF;
2266 return state;
2218} 2267}
2219 2268
2220 2269
@@ -2254,7 +2303,8 @@ union_set_create (void)
2254 * @param ee the element to add to the set 2303 * @param ee the element to add to the set
2255 */ 2304 */
2256static void 2305static void
2257union_add (struct SetState *set_state, struct ElementEntry *ee) 2306union_add (struct SetState *set_state,
2307 struct ElementEntry *ee)
2258{ 2308{
2259 strata_estimator_insert (set_state->se, 2309 strata_estimator_insert (set_state->se,
2260 get_ibf_key (&ee->element_hash)); 2310 get_ibf_key (&ee->element_hash));
@@ -2269,7 +2319,8 @@ union_add (struct SetState *set_state, struct ElementEntry *ee)
2269 * @param ee set element to remove 2319 * @param ee set element to remove
2270 */ 2320 */
2271static void 2321static void
2272union_remove (struct SetState *set_state, struct ElementEntry *ee) 2322union_remove (struct SetState *set_state,
2323 struct ElementEntry *ee)
2273{ 2324{
2274 strata_estimator_remove (set_state->se, 2325 strata_estimator_remove (set_state->se,
2275 get_ibf_key (&ee->element_hash)); 2326 get_ibf_key (&ee->element_hash));
@@ -2294,61 +2345,39 @@ union_set_destroy (struct SetState *set_state)
2294 2345
2295 2346
2296/** 2347/**
2297 * Handler for peer-disconnects, notifies the client
2298 * about the aborted operation in case the op was not concluded.
2299 *
2300 * @param op the destroyed operation
2301 */
2302static void
2303union_peer_disconnect (struct Operation *op)
2304{
2305 if (PHASE_DONE != op->state->phase)
2306 {
2307 struct GNUNET_MQ_Envelope *ev;
2308 struct GNUNET_SET_ResultMessage *msg;
2309
2310 ev = GNUNET_MQ_msg (msg,
2311 GNUNET_MESSAGE_TYPE_SET_RESULT);
2312 msg->request_id = htonl (op->spec->client_request_id);
2313 msg->result_status = htons (GNUNET_SET_STATUS_FAILURE);
2314 msg->element_type = htons (0);
2315 GNUNET_MQ_send (op->spec->set->client_mq,
2316 ev);
2317 LOG (GNUNET_ERROR_TYPE_WARNING,
2318 "other peer disconnected prematurely, phase %u\n",
2319 op->state->phase);
2320 _GSS_operation_destroy (op,
2321 GNUNET_YES);
2322 return;
2323 }
2324 // else: the session has already been concluded
2325 LOG (GNUNET_ERROR_TYPE_DEBUG,
2326 "other peer disconnected (finished)\n");
2327 if (GNUNET_NO == op->state->client_done_sent)
2328 send_done_and_destroy (op);
2329}
2330
2331
2332/**
2333 * Copy union-specific set state. 2348 * Copy union-specific set state.
2334 * 2349 *
2335 * @param set source set for copying the union state 2350 * @param state source state for copying the union state
2336 * @return a copy of the union-specific set state 2351 * @return a copy of the union-specific set state
2337 */ 2352 */
2338static struct SetState * 2353static struct SetState *
2339union_copy_state (struct Set *set) 2354union_copy_state (struct SetState *state)
2340{ 2355{
2341 struct SetState *new_state; 2356 struct SetState *new_state;
2342 2357
2358 GNUNET_assert ( (NULL != state) &&
2359 (NULL != state->se) );
2343 new_state = GNUNET_new (struct SetState); 2360 new_state = GNUNET_new (struct SetState);
2344 GNUNET_assert ( (NULL != set->state) && (NULL != set->state->se) ); 2361 new_state->se = strata_estimator_dup (state->se);
2345 new_state->se = strata_estimator_dup (set->state->se);
2346 2362
2347 return new_state; 2363 return new_state;
2348} 2364}
2349 2365
2350 2366
2351/** 2367/**
2368 * Handle case where channel went down for an operation.
2369 *
2370 * @param op operation that lost the channel
2371 */
2372static void
2373union_channel_death (struct Operation *op)
2374{
2375 _GSS_operation_destroy (op,
2376 GNUNET_YES);
2377}
2378
2379
2380/**
2352 * Get the table with implementing functions for 2381 * Get the table with implementing functions for
2353 * set union. 2382 * set union.
2354 * 2383 *
@@ -2364,9 +2393,9 @@ _GSS_union_vt ()
2364 .destroy_set = &union_set_destroy, 2393 .destroy_set = &union_set_destroy,
2365 .evaluate = &union_evaluate, 2394 .evaluate = &union_evaluate,
2366 .accept = &union_accept, 2395 .accept = &union_accept,
2367 .peer_disconnect = &union_peer_disconnect,
2368 .cancel = &union_op_cancel, 2396 .cancel = &union_op_cancel,
2369 .copy_state = &union_copy_state, 2397 .copy_state = &union_copy_state,
2398 .channel_death = &union_channel_death
2370 }; 2399 };
2371 2400
2372 return &union_vt; 2401 return &union_vt;
diff --git a/src/set/set_api.c b/src/set/set_api.c
index bc428f9f6..f5c43a9a7 100644
--- a/src/set/set_api.c
+++ b/src/set/set_api.c
@@ -310,6 +310,8 @@ handle_iter_element (void *cls,
310 struct GNUNET_MQ_Envelope *ev; 310 struct GNUNET_MQ_Envelope *ev;
311 uint16_t msize; 311 uint16_t msize;
312 312
313 LOG (GNUNET_ERROR_TYPE_DEBUG,
314 "Received element in set iteration\n");
313 msize = ntohs (msg->header.size); 315 msize = ntohs (msg->header.size);
314 if (set->iteration_id != ntohs (msg->iteration_id)) 316 if (set->iteration_id != ntohs (msg->iteration_id))
315 { 317 {
@@ -346,7 +348,15 @@ handle_iter_done (void *cls,
346 GNUNET_SET_ElementIterator iter = set->iterator; 348 GNUNET_SET_ElementIterator iter = set->iterator;
347 349
348 if (NULL == iter) 350 if (NULL == iter)
351 {
352 /* FIXME: if this is true, could cancel+start a fresh one
353 cause elements to go to the wrong iteration? */
354 LOG (GNUNET_ERROR_TYPE_INFO,
355 "Service completed set iteration that was already cancelled\n");
349 return; 356 return;
357 }
358 LOG (GNUNET_ERROR_TYPE_DEBUG,
359 "Set iteration completed\n");
350 set->destroy_requested = GNUNET_SYSERR; 360 set->destroy_requested = GNUNET_SYSERR;
351 set->iterator = NULL; 361 set->iterator = NULL;
352 set->iteration_id++; 362 set->iteration_id++;
@@ -392,7 +402,7 @@ handle_result (void *cls,
392 int destroy_set; 402 int destroy_set;
393 403
394 GNUNET_assert (NULL != set->mq); 404 GNUNET_assert (NULL != set->mq);
395 result_status = ntohs (msg->result_status); 405 result_status = (enum GNUNET_SET_Status) ntohs (msg->result_status);
396 LOG (GNUNET_ERROR_TYPE_DEBUG, 406 LOG (GNUNET_ERROR_TYPE_DEBUG,
397 "Got result message with status %d\n", 407 "Got result message with status %d\n",
398 result_status); 408 result_status);
@@ -507,6 +517,8 @@ GNUNET_SET_operation_cancel (struct GNUNET_SET_OperationHandle *oh)
507 struct GNUNET_SET_CancelMessage *m; 517 struct GNUNET_SET_CancelMessage *m;
508 struct GNUNET_MQ_Envelope *mqm; 518 struct GNUNET_MQ_Envelope *mqm;
509 519
520 LOG (GNUNET_ERROR_TYPE_DEBUG,
521 "Cancelling SET operation\n");
510 if (NULL != set) 522 if (NULL != set)
511 { 523 {
512 mqm = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_SET_CANCEL); 524 mqm = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_SET_CANCEL);
@@ -560,6 +572,9 @@ handle_client_set_error (void *cls,
560} 572}
561 573
562 574
575/**
576 * FIXME.
577 */
563static struct GNUNET_SET_Handle * 578static struct GNUNET_SET_Handle *
564create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg, 579create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg,
565 enum GNUNET_SET_OperationType op, 580 enum GNUNET_SET_OperationType op,
@@ -618,7 +633,8 @@ create_internal (const struct GNUNET_CONFIGURATION_Handle *cfg,
618 GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT); 633 GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_CONNECT);
619 copy_msg->cookie = *cookie; 634 copy_msg->cookie = *cookie;
620 } 635 }
621 GNUNET_MQ_send (set->mq, mqm); 636 GNUNET_MQ_send (set->mq,
637 mqm);
622 return set; 638 return set;
623} 639}
624 640
@@ -638,7 +654,16 @@ struct GNUNET_SET_Handle *
638GNUNET_SET_create (const struct GNUNET_CONFIGURATION_Handle *cfg, 654GNUNET_SET_create (const struct GNUNET_CONFIGURATION_Handle *cfg,
639 enum GNUNET_SET_OperationType op) 655 enum GNUNET_SET_OperationType op)
640{ 656{
641 return create_internal (cfg, op, NULL); 657 struct GNUNET_SET_Handle *set;
658
659 set = create_internal (cfg,
660 op,
661 NULL);
662 LOG (GNUNET_ERROR_TYPE_DEBUG,
663 "Creating set %p for operation %d\n",
664 set,
665 op);
666 return set;
642} 667}
643 668
644 669
@@ -664,8 +689,10 @@ GNUNET_SET_add_element (struct GNUNET_SET_Handle *set,
664 struct GNUNET_MQ_Envelope *mqm; 689 struct GNUNET_MQ_Envelope *mqm;
665 struct GNUNET_SET_ElementMessage *msg; 690 struct GNUNET_SET_ElementMessage *msg;
666 691
667 LOG (GNUNET_ERROR_TYPE_INFO, "adding element of type %u\n", (unsigned) element->element_type); 692 LOG (GNUNET_ERROR_TYPE_INFO,
668 693 "adding element of type %u to set %p\n",
694 (unsigned int) element->element_type,
695 set);
669 if (GNUNET_YES == set->invalid) 696 if (GNUNET_YES == set->invalid)
670 { 697 {
671 if (NULL != cont) 698 if (NULL != cont)
@@ -708,6 +735,9 @@ GNUNET_SET_remove_element (struct GNUNET_SET_Handle *set,
708 struct GNUNET_MQ_Envelope *mqm; 735 struct GNUNET_MQ_Envelope *mqm;
709 struct GNUNET_SET_ElementMessage *msg; 736 struct GNUNET_SET_ElementMessage *msg;
710 737
738 LOG (GNUNET_ERROR_TYPE_DEBUG,
739 "Removing element from set %p\n",
740 set);
711 if (GNUNET_YES == set->invalid) 741 if (GNUNET_YES == set->invalid)
712 { 742 {
713 if (NULL != cont) 743 if (NULL != cont)
@@ -878,7 +908,8 @@ handle_request (void *cls,
878 struct GNUNET_SET_RejectMessage *rmsg; 908 struct GNUNET_SET_RejectMessage *rmsg;
879 909
880 LOG (GNUNET_ERROR_TYPE_DEBUG, 910 LOG (GNUNET_ERROR_TYPE_DEBUG,
881 "Processing incoming operation request\n"); 911 "Processing incoming operation request with id %u\n",
912 ntohl (msg->accept_id));
882 /* we got another valid request => reset the backoff */ 913 /* we got another valid request => reset the backoff */
883 lh->reconnect_backoff = GNUNET_TIME_UNIT_MILLISECONDS; 914 lh->reconnect_backoff = GNUNET_TIME_UNIT_MILLISECONDS;
884 req.accept_id = ntohl (msg->accept_id); 915 req.accept_id = ntohl (msg->accept_id);
@@ -892,7 +923,8 @@ handle_request (void *cls,
892 if (GNUNET_YES == req.accepted) 923 if (GNUNET_YES == req.accepted)
893 return; /* the accept-case is handled in #GNUNET_SET_accept() */ 924 return; /* the accept-case is handled in #GNUNET_SET_accept() */
894 LOG (GNUNET_ERROR_TYPE_DEBUG, 925 LOG (GNUNET_ERROR_TYPE_DEBUG,
895 "Rejecting request\n"); 926 "Rejected request %u\n",
927 ntohl (msg->accept_id));
896 mqm = GNUNET_MQ_msg (rmsg, 928 mqm = GNUNET_MQ_msg (rmsg,
897 GNUNET_MESSAGE_TYPE_SET_REJECT); 929 GNUNET_MESSAGE_TYPE_SET_REJECT);
898 rmsg->accept_reject_id = msg->accept_id; 930 rmsg->accept_reject_id = msg->accept_id;
@@ -982,6 +1014,9 @@ GNUNET_SET_listen (const struct GNUNET_CONFIGURATION_Handle *cfg,
982{ 1014{
983 struct GNUNET_SET_ListenHandle *lh; 1015 struct GNUNET_SET_ListenHandle *lh;
984 1016
1017 LOG (GNUNET_ERROR_TYPE_DEBUG,
1018 "Starting listener for app %s\n",
1019 GNUNET_h2s (app_id));
985 lh = GNUNET_new (struct GNUNET_SET_ListenHandle); 1020 lh = GNUNET_new (struct GNUNET_SET_ListenHandle);
986 lh->listen_cb = listen_cb; 1021 lh->listen_cb = listen_cb;
987 lh->listen_cls = listen_cls; 1022 lh->listen_cls = listen_cls;
@@ -1008,7 +1043,8 @@ void
1008GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh) 1043GNUNET_SET_listen_cancel (struct GNUNET_SET_ListenHandle *lh)
1009{ 1044{
1010 LOG (GNUNET_ERROR_TYPE_DEBUG, 1045 LOG (GNUNET_ERROR_TYPE_DEBUG,
1011 "Canceling listener\n"); 1046 "Canceling listener %s\n",
1047 GNUNET_h2s (&lh->app_id));
1012 if (NULL != lh->mq) 1048 if (NULL != lh->mq)
1013 { 1049 {
1014 GNUNET_MQ_destroy (lh->mq); 1050 GNUNET_MQ_destroy (lh->mq);
@@ -1050,10 +1086,12 @@ GNUNET_SET_accept (struct GNUNET_SET_Request *request,
1050 1086
1051 GNUNET_assert (GNUNET_NO == request->accepted); 1087 GNUNET_assert (GNUNET_NO == request->accepted);
1052 LOG (GNUNET_ERROR_TYPE_DEBUG, 1088 LOG (GNUNET_ERROR_TYPE_DEBUG,
1053 "Client accepts set operation (%d)\n", 1089 "Client accepts set operation (%d) with id %u\n",
1054 result_mode); 1090 result_mode,
1091 request->accept_id);
1055 request->accepted = GNUNET_YES; 1092 request->accepted = GNUNET_YES;
1056 mqm = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_SET_ACCEPT); 1093 mqm = GNUNET_MQ_msg (msg,
1094 GNUNET_MESSAGE_TYPE_SET_ACCEPT);
1057 msg->accept_reject_id = htonl (request->accept_id); 1095 msg->accept_reject_id = htonl (request->accept_id);
1058 msg->result_mode = htonl (result_mode); 1096 msg->result_mode = htonl (result_mode);
1059 oh = GNUNET_new (struct GNUNET_SET_OperationHandle); 1097 oh = GNUNET_new (struct GNUNET_SET_OperationHandle);
@@ -1151,6 +1189,8 @@ GNUNET_SET_copy_lazy (struct GNUNET_SET_Handle *set,
1151 struct GNUNET_MQ_Envelope *ev; 1189 struct GNUNET_MQ_Envelope *ev;
1152 struct SetCopyRequest *req; 1190 struct SetCopyRequest *req;
1153 1191
1192 LOG (GNUNET_ERROR_TYPE_DEBUG,
1193 "Creating lazy copy of set\n");
1154 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_PREPARE); 1194 ev = GNUNET_MQ_msg_header (GNUNET_MESSAGE_TYPE_SET_COPY_LAZY_PREPARE);
1155 GNUNET_MQ_send (set->mq, ev); 1195 GNUNET_MQ_send (set->mq, ev);
1156 1196
diff --git a/src/set/test_set_api.c b/src/set/test_set_api.c
index dd3f004f2..ca7d8a4e2 100644
--- a/src/set/test_set_api.c
+++ b/src/set/test_set_api.c
@@ -116,6 +116,7 @@ result_cb_set2 (void *cls,
116 oh2 = NULL; 116 oh2 = NULL;
117 fprintf (stderr, 117 fprintf (stderr,
118 "set 2: received failure status\n"); 118 "set 2: received failure status\n");
119 GNUNET_SCHEDULER_shutdown ();
119 ret = 1; 120 ret = 1;
120 break; 121 break;
121 case GNUNET_SET_STATUS_DONE: 122 case GNUNET_SET_STATUS_DONE:
@@ -147,8 +148,6 @@ listen_cb (void *cls,
147 GNUNET_assert (ntohs (context_msg->type) == GNUNET_MESSAGE_TYPE_DUMMY); 148 GNUNET_assert (ntohs (context_msg->type) == GNUNET_MESSAGE_TYPE_DUMMY);
148 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 149 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
149 "listen cb called\n"); 150 "listen cb called\n");
150 GNUNET_SET_listen_cancel (listen_handle);
151 listen_handle = NULL;
152 oh2 = GNUNET_SET_accept (request, 151 oh2 = GNUNET_SET_accept (request,
153 GNUNET_SET_RESULT_ADDED, 152 GNUNET_SET_RESULT_ADDED,
154 (struct GNUNET_SET_Option[]) { 0 }, 153 (struct GNUNET_SET_Option[]) { 0 },
@@ -200,19 +199,25 @@ init_set2 (void *cls)
200{ 199{
201 struct GNUNET_SET_Element element; 200 struct GNUNET_SET_Element element;
202 201
203 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initializing set 2\n"); 202 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
203 "initializing set 2\n");
204 204
205 element.element_type = 0; 205 element.element_type = 0;
206
207 element.data = "hello"; 206 element.data = "hello";
208 element.size = strlen(element.data); 207 element.size = strlen(element.data);
209 GNUNET_SET_add_element (set2, &element, NULL, NULL); 208 GNUNET_SET_add_element (set2,
209 &element,
210 NULL, NULL);
210 element.data = "quux"; 211 element.data = "quux";
211 element.size = strlen(element.data); 212 element.size = strlen(element.data);
212 GNUNET_SET_add_element (set2, &element, NULL, NULL); 213 GNUNET_SET_add_element (set2,
214 &element,
215 NULL, NULL);
213 element.data = "baz"; 216 element.data = "baz";
214 element.size = strlen(element.data); 217 element.size = strlen(element.data);
215 GNUNET_SET_add_element (set2, &element, &start, NULL); 218 GNUNET_SET_add_element (set2,
219 &element,
220 &start, NULL);
216} 221}
217 222
218 223
@@ -225,14 +230,17 @@ init_set1 (void)
225 struct GNUNET_SET_Element element; 230 struct GNUNET_SET_Element element;
226 231
227 element.element_type = 0; 232 element.element_type = 0;
228
229 element.data = "hello"; 233 element.data = "hello";
230 element.size = strlen(element.data); 234 element.size = strlen(element.data);
231 GNUNET_SET_add_element (set1, &element, NULL, NULL); 235 GNUNET_SET_add_element (set1,
236 &element,
237 NULL, NULL);
232 element.data = "bar"; 238 element.data = "bar";
233 element.size = strlen(element.data); 239 element.size = strlen(element.data);
234 GNUNET_SET_add_element (set1, &element, init_set2, NULL); 240 GNUNET_SET_add_element (set1,
235 241 &element,
242 &init_set2,
243 NULL);
236 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 244 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
237 "initialized set 1\n"); 245 "initialized set 1\n");
238} 246}
@@ -242,10 +250,15 @@ static int
242iter_cb (void *cls, 250iter_cb (void *cls,
243 const struct GNUNET_SET_Element *element) 251 const struct GNUNET_SET_Element *element)
244{ 252{
253 struct GNUNET_SET_Handle *set = cls;
254
245 if (NULL == element) 255 if (NULL == element)
246 { 256 {
247 GNUNET_assert (3 == iter_count); 257 GNUNET_assert (3 == iter_count);
248 GNUNET_SET_destroy (cls); 258 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
259 "Iteration finished, destroying set %p\n",
260 set);
261 GNUNET_SET_destroy (set);
249 return GNUNET_YES; 262 return GNUNET_YES;
250 } 263 }
251 iter_count++; 264 iter_count++;
@@ -262,21 +275,31 @@ test_iter ()
262 struct GNUNET_SET_Element element; 275 struct GNUNET_SET_Element element;
263 struct GNUNET_SET_Handle *iter_set; 276 struct GNUNET_SET_Handle *iter_set;
264 277
265 iter_set = GNUNET_SET_create (config, GNUNET_SET_OPERATION_UNION); 278 iter_set = GNUNET_SET_create (config,
266 279 GNUNET_SET_OPERATION_UNION);
280 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
281 "Testing iteration over 3 elements on set %p\n",
282 iter_set);
267 element.element_type = 0; 283 element.element_type = 0;
268 284
269 element.data = "hello"; 285 element.data = "hello";
270 element.size = strlen(element.data); 286 element.size = strlen(element.data);
271 GNUNET_SET_add_element (iter_set, &element, NULL, NULL); 287 GNUNET_SET_add_element (iter_set,
288 &element,
289 NULL, NULL);
272 element.data = "bar"; 290 element.data = "bar";
273 element.size = strlen(element.data); 291 element.size = strlen(element.data);
274 GNUNET_SET_add_element (iter_set, &element, NULL, NULL); 292 GNUNET_SET_add_element (iter_set,
293 &element,
294 NULL, NULL);
275 element.data = "quux"; 295 element.data = "quux";
276 element.size = strlen(element.data); 296 element.size = strlen(element.data);
277 GNUNET_SET_add_element (iter_set, &element, NULL, NULL); 297 GNUNET_SET_add_element (iter_set,
278 298 &element,
279 GNUNET_SET_iterate (iter_set, iter_cb, iter_set); 299 NULL, NULL);
300 GNUNET_SET_iterate (iter_set,
301 &iter_cb,
302 iter_set);
280} 303}
281 304
282 305
@@ -372,12 +395,20 @@ run (void *cls,
372 GNUNET_i2s (&local_id)); 395 GNUNET_i2s (&local_id));
373 test_iter (); 396 test_iter ();
374 397
375 set1 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION); 398 set1 = GNUNET_SET_create (cfg,
376 set2 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION); 399 GNUNET_SET_OPERATION_UNION);
400 set2 = GNUNET_SET_create (cfg,
401 GNUNET_SET_OPERATION_UNION);
402 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
403 "Created sets %p and %p for union operation\n",
404 set1,
405 set2);
377 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, 406 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
378 &app_id); 407 &app_id);
379 408
380 ///* test if canceling an uncommited request works! */ 409 /* test if canceling an uncommited request works! */
410 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
411 "Launching and instantly stopping set operation\n");
381 my_oh = GNUNET_SET_prepare (&local_id, 412 my_oh = GNUNET_SET_prepare (&local_id,
382 &app_id, 413 &app_id,
383 NULL, 414 NULL,
@@ -385,7 +416,6 @@ run (void *cls,
385 (struct GNUNET_SET_Option[]) { 0 }, 416 (struct GNUNET_SET_Option[]) { 0 },
386 NULL, 417 NULL,
387 NULL); 418 NULL);
388
389 GNUNET_SET_operation_cancel (my_oh); 419 GNUNET_SET_operation_cancel (my_oh);
390 420
391 /* test the real set reconciliation */ 421 /* test the real set reconciliation */
diff --git a/src/set/test_set_union_copy.c b/src/set/test_set_union_copy.c
index a1eba6311..242b9f2f2 100644
--- a/src/set/test_set_union_copy.c
+++ b/src/set/test_set_union_copy.c
@@ -265,7 +265,8 @@ run (void *cls,
265 GNUNET_TESTING_peer_get_identity (peer, 265 GNUNET_TESTING_peer_get_identity (peer,
266 &local_id); 266 &local_id);
267 267
268 set1 = GNUNET_SET_create (cfg, GNUNET_SET_OPERATION_UNION); 268 set1 = GNUNET_SET_create (cfg,
269 GNUNET_SET_OPERATION_UNION);
269 add_element_str (set1, 270 add_element_str (set1,
270 "333"); 271 "333");
271 add_element_str (set1, 272 add_element_str (set1,
diff --git a/src/statistics/gnunet-service-statistics.c b/src/statistics/gnunet-service-statistics.c
index 161327421..85c84b89d 100644
--- a/src/statistics/gnunet-service-statistics.c
+++ b/src/statistics/gnunet-service-statistics.c
@@ -776,7 +776,7 @@ check_watch (void *cls,
776 size_t size; 776 size_t size;
777 const char *service; 777 const char *service;
778 const char *name; 778 const char *name;
779 779
780 size = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader); 780 size = ntohs (message->size) - sizeof (struct GNUNET_MessageHeader);
781 if (size != 781 if (size !=
782 GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1], 782 GNUNET_STRINGS_buffer_tokenize ((const char *) &message[1],
@@ -870,7 +870,7 @@ handle_watch (void *cls,
870 870
871/** 871/**
872 * Handle DISCONNECT-message. Sync to disk and send 872 * Handle DISCONNECT-message. Sync to disk and send
873 * back a #GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT_CONFIRM 873 * back a #GNUNET_MESSAGE_TYPE_STATISTICS_DISCONNECT_CONFIRM
874 * message. 874 * message.
875 * 875 *
876 * @param cls the `struct ClientEntry *` 876 * @param cls the `struct ClientEntry *`
@@ -984,6 +984,7 @@ client_disconnect_cb (void *cls,
984 } 984 }
985 } 985 }
986 } 986 }
987 GNUNET_free (ce);
987 if ( (0 == client_count) && 988 if ( (0 == client_count) &&
988 (GNUNET_YES == in_shutdown) ) 989 (GNUNET_YES == in_shutdown) )
989 do_shutdown (); 990 do_shutdown ();
@@ -992,7 +993,7 @@ client_disconnect_cb (void *cls,
992 993
993/** 994/**
994 * We've read a `struct GNUNET_STATISTICS_SetMessage *` from 995 * We've read a `struct GNUNET_STATISTICS_SetMessage *` from
995 * disk. Check that it is well-formed, and if so pass it to 996 * disk. Check that it is well-formed, and if so pass it to
996 * the handler for set messages. 997 * the handler for set messages.
997 * 998 *
998 * @param cls NULL 999 * @param cls NULL
diff --git a/src/util/client.c b/src/util/client.c
index 0f7d0d359..163ae6eb9 100644
--- a/src/util/client.c
+++ b/src/util/client.c
@@ -298,11 +298,11 @@ recv_message (void *cls,
298 298
299 if (GNUNET_YES == cstate->in_destroy) 299 if (GNUNET_YES == cstate->in_destroy)
300 return GNUNET_SYSERR; 300 return GNUNET_SYSERR;
301 301 LOG (GNUNET_ERROR_TYPE_DEBUG,
302 LOG (GNUNET_ERROR_TYPE_INFO,
303 "Received message of type %u and size %u from %s\n", 302 "Received message of type %u and size %u from %s\n",
304 ntohs (msg->type), ntohs (msg->size), cstate->service_name); 303 ntohs (msg->type),
305 304 ntohs (msg->size),
305 cstate->service_name);
306 GNUNET_MQ_inject_message (cstate->mq, 306 GNUNET_MQ_inject_message (cstate->mq,
307 msg); 307 msg);
308 if (GNUNET_YES == cstate->in_destroy) 308 if (GNUNET_YES == cstate->in_destroy)
diff --git a/src/util/service_new.c b/src/util/service_new.c
index 5b3a332ac..9c0ee539b 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,
2000 if (NULL != client->drop_task) 2000 if (NULL != client->drop_task)
2001 return; /* we're going down right now, do not try to send */ 2001 return; /* we're going down right now, do not try to send */
2002 GNUNET_assert (NULL == client->send_task); 2002 GNUNET_assert (NULL == client->send_task);
2003 2003 LOG (GNUNET_ERROR_TYPE_DEBUG,
2004 LOG (GNUNET_ERROR_TYPE_INFO,
2005 "Sending message of type %u and size %u to client\n", 2004 "Sending message of type %u and size %u to client\n",
2006 ntohs (msg->type), ntohs (msg->size)); 2005 ntohs (msg->type),
2007 2006 ntohs (msg->size));
2008 client->msg = msg; 2007 client->msg = msg;
2009 client->msg_pos = 0; 2008 client->msg_pos = 0;
2010 client->send_task 2009 client->send_task
@@ -2103,10 +2102,10 @@ service_client_mst_cb (void *cls,
2103{ 2102{
2104 struct GNUNET_SERVICE_Client *client = cls; 2103 struct GNUNET_SERVICE_Client *client = cls;
2105 2104
2106 LOG (GNUNET_ERROR_TYPE_INFO, 2105 LOG (GNUNET_ERROR_TYPE_DEBUG,
2107 "Received message of type %u and size %u from client\n", 2106 "Received message of type %u and size %u from client\n",
2108 ntohs (message->type), ntohs (message->size)); 2107 ntohs (message->type),
2109 2108 ntohs (message->size));
2110 GNUNET_assert (GNUNET_NO == client->needs_continue); 2109 GNUNET_assert (GNUNET_NO == client->needs_continue);
2111 client->needs_continue = GNUNET_YES; 2110 client->needs_continue = GNUNET_YES;
2112 client->warn_type = ntohs (message->type); 2111 client->warn_type = ntohs (message->type);
diff --git a/src/util/util.conf b/src/util/util.conf
index ecc94ead0..ceb5fdcbb 100644
--- a/src/util/util.conf
+++ b/src/util/util.conf
@@ -37,9 +37,8 @@ GNUNET_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/gnunet-system-runtime/
37GNUNET_USER_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/gnunet-${USERHOME:-${USER:-user}}-runtime/ 37GNUNET_USER_RUNTIME_DIR = ${TMPDIR:-${TMP:-/tmp}}/gnunet-${USERHOME:-${USER:-user}}-runtime/
38 38
39 39
40# Legacy option... 40# Override for GNUNET_HOME used by test cases.
41# GNUNET_TEST_HOME = ~/.gnunet/ 41# GNUNET_TEST_HOME = /tmp/foo/bar
42# GNUNET_TEST_HOME = /var/lib/gnunet/
43 42
44# DEFAULTCONFIG = /etc/gnunet.conf 43# DEFAULTCONFIG = /etc/gnunet.conf
45# If 'DEFAULTCONFIG' is not defined, the current 44# If 'DEFAULTCONFIG' is not defined, the current
diff --git a/src/vpn/Makefile.am b/src/vpn/Makefile.am
index 417d2eb89..5c16fa349 100644
--- a/src/vpn/Makefile.am
+++ b/src/vpn/Makefile.am
@@ -59,7 +59,7 @@ gnunet_service_vpn_LDADD = \
59 $(top_builddir)/src/statistics/libgnunetstatistics.la \ 59 $(top_builddir)/src/statistics/libgnunetstatistics.la \
60 $(top_builddir)/src/tun/libgnunettun.la \ 60 $(top_builddir)/src/tun/libgnunettun.la \
61 $(top_builddir)/src/util/libgnunetutil.la \ 61 $(top_builddir)/src/util/libgnunetutil.la \
62 $(top_builddir)/src/cadet/libgnunetcadetnew.la \ 62 $(top_builddir)/src/cadet/libgnunetcadet.la \
63 $(top_builddir)/src/regex/libgnunetregex.la \ 63 $(top_builddir)/src/regex/libgnunetregex.la \
64 $(GN_LIBINTL) 64 $(GN_LIBINTL)
65gnunet_service_vpn_CFLAGS = \ 65gnunet_service_vpn_CFLAGS = \
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c
index aab0a143f..ab0b00d76 100644
--- a/src/vpn/gnunet-service-vpn.c
+++ b/src/vpn/gnunet-service-vpn.c
@@ -1384,7 +1384,7 @@ create_channel (struct ChannelState *ts,
1384 GNUNET_MQ_handler_end() 1384 GNUNET_MQ_handler_end()
1385 }; 1385 };
1386 1386
1387 return GNUNET_CADET_channel_creatE (cadet_handle, 1387 return GNUNET_CADET_channel_create (cadet_handle,
1388 ts, 1388 ts,
1389 target, 1389 target,
1390 port, 1390 port,
@@ -3068,7 +3068,7 @@ run (void *cls,
3068 } 3068 }
3069 vpn_argv[6] = NULL; 3069 vpn_argv[6] = NULL;
3070 3070
3071 cadet_handle = GNUNET_CADET_connecT (cfg_); 3071 cadet_handle = GNUNET_CADET_connect (cfg_);
3072 // FIXME never opens ports??? 3072 // FIXME never opens ports???
3073 helper_handle = GNUNET_HELPER_start (GNUNET_NO, 3073 helper_handle = GNUNET_HELPER_start (GNUNET_NO,
3074 "gnunet-helper-vpn", vpn_argv, 3074 "gnunet-helper-vpn", vpn_argv,