aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/cadet_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cadet/cadet_api.c')
-rw-r--r--src/cadet/cadet_api.c1757
1 files changed, 408 insertions, 1349 deletions
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 */