aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet-new_connection.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-01-19 15:52:22 +0100
committerChristian Grothoff <christian@grothoff.org>2017-01-19 15:52:22 +0100
commitbc43d8978d8695ff97cc67b65c29769e9c7f8f0e (patch)
tree94d1428dc2b4e70d87d6521b487a92c6fc139827 /src/cadet/gnunet-service-cadet-new_connection.c
parentbd3147503e27ddefcb6ba0dcb99c2b32947622a4 (diff)
downloadgnunet-bc43d8978d8695ff97cc67b65c29769e9c7f8f0e.tar.gz
gnunet-bc43d8978d8695ff97cc67b65c29769e9c7f8f0e.zip
much work on connection/route/peer-level queue management
Diffstat (limited to 'src/cadet/gnunet-service-cadet-new_connection.c')
-rw-r--r--src/cadet/gnunet-service-cadet-new_connection.c361
1 files changed, 221 insertions, 140 deletions
diff --git a/src/cadet/gnunet-service-cadet-new_connection.c b/src/cadet/gnunet-service-cadet-new_connection.c
index 5123f9d45..bf88d78e1 100644
--- a/src/cadet/gnunet-service-cadet-new_connection.c
+++ b/src/cadet/gnunet-service-cadet-new_connection.c
@@ -27,11 +27,8 @@
27 * @author Christian Grothoff 27 * @author Christian Grothoff
28 * 28 *
29 * TODO: 29 * TODO:
30 * - congestion control
31 * - GCC_debug()
32 * - keepalive messages 30 * - keepalive messages
33 * - performance metrics 31 * - keep performance metrics (?)
34 * - back-off reset
35 */ 32 */
36#include "platform.h" 33#include "platform.h"
37#include "gnunet-service-cadet-new_channel.h" 34#include "gnunet-service-cadet-new_channel.h"
@@ -64,19 +61,16 @@ enum CadetConnectionState
64 CADET_CONNECTION_SENT, 61 CADET_CONNECTION_SENT,
65 62
66 /** 63 /**
67 * Connection confirmed, ready to carry traffic. 64 * We are an inbound connection, and received a CREATE. Need to
65 * send an CREATE_ACK back.
68 */ 66 */
69 CADET_CONNECTION_READY, 67 CADET_CONNECTION_CREATE_RECEIVED,
70 68
71 /** 69 /**
72 * Connection to be destroyed, just waiting to empty queues. 70 * Connection confirmed, ready to carry traffic.
73 */ 71 */
74 CADET_CONNECTION_DESTROYED, 72 CADET_CONNECTION_READY
75 73
76 /**
77 * Connection to be destroyed because of a distant peer, same as DESTROYED.
78 */
79 CADET_CONNECTION_BROKEN
80}; 74};
81 75
82 76
@@ -112,11 +106,6 @@ struct CadetConnection
112 struct GNUNET_MQ_Envelope *env; 106 struct GNUNET_MQ_Envelope *env;
113 107
114 /** 108 /**
115 * Message queue to the first hop, or NULL if we have no connection yet.
116 */
117 struct GNUNET_MQ_Handle *mq;
118
119 /**
120 * Handle for calling #GCP_request_mq_cancel() once we are finished. 109 * Handle for calling #GCP_request_mq_cancel() once we are finished.
121 */ 110 */
122 struct GCP_MessageQueueManager *mq_man; 111 struct GCP_MessageQueueManager *mq_man;
@@ -129,7 +118,7 @@ struct CadetConnection
129 /** 118 /**
130 * Function to call once we are ready to transmit. 119 * Function to call once we are ready to transmit.
131 */ 120 */
132 GNUNET_SCHEDULER_TaskCallback ready_cb; 121 GCC_ReadyCallback ready_cb;
133 122
134 /** 123 /**
135 * Closure for @e ready_cb. 124 * Closure for @e ready_cb.
@@ -151,22 +140,12 @@ struct CadetConnection
151 */ 140 */
152 unsigned int off; 141 unsigned int off;
153 142
154}; 143 /**
155 144 * Are we ready to transmit via @e mq_man right now?
145 */
146 int mqm_ready;
156 147
157/** 148};
158 * Is the given connection currently ready for transmission?
159 *
160 * @param cc connection to transmit on
161 * @return #GNUNET_YES if we could transmit
162 */
163int
164GCC_is_ready (struct CadetConnection *cc)
165{
166 return ( (NULL != cc->mq) &&
167 (CADET_CONNECTION_READY == cc->state) &&
168 (NULL == cc->env) ) ? GNUNET_YES : GNUNET_NO;
169}
170 149
171 150
172/** 151/**
@@ -177,29 +156,19 @@ GCC_is_ready (struct CadetConnection *cc)
177void 156void
178GCC_destroy (struct CadetConnection *cc) 157GCC_destroy (struct CadetConnection *cc)
179{ 158{
180 if (NULL != cc->env) 159 struct GNUNET_MQ_Envelope *env = NULL;
181 { 160
182 if (NULL != cc->mq) 161 if (CADET_CONNECTION_SENDING_CREATE != cc->state)
183 GNUNET_MQ_send_cancel (cc->env);
184 else
185 GNUNET_MQ_discard (cc->env);
186 cc->env = NULL;
187 }
188 if ( (NULL != cc->mq) &&
189 (CADET_CONNECTION_SENDING_CREATE != cc->state) )
190 { 162 {
191 /* Need to notify next hop that we are down. */
192 struct GNUNET_MQ_Envelope *env;
193 struct GNUNET_CADET_ConnectionDestroyMessage *destroy_msg; 163 struct GNUNET_CADET_ConnectionDestroyMessage *destroy_msg;
194 164
165 /* Need to notify next hop that we are down. */
195 env = GNUNET_MQ_msg (destroy_msg, 166 env = GNUNET_MQ_msg (destroy_msg,
196 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY); 167 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY);
197 destroy_msg->cid = cc->cid; 168 destroy_msg->cid = cc->cid;
198 GNUNET_MQ_send (cc->mq,
199 env);
200 } 169 }
201 cc->mq = NULL; 170 GCP_request_mq_cancel (cc->mq_man,
202 GCP_request_mq_cancel (cc->mq_man); 171 env);
203 cc->mq_man = NULL; 172 cc->mq_man = NULL;
204 GCPP_del_connection (cc->path, 173 GCPP_del_connection (cc->path,
205 cc->off, 174 cc->off,
@@ -234,14 +203,20 @@ GCC_get_ct (struct CadetConnection *cc)
234void 203void
235GCC_handle_connection_ack (struct CadetConnection *cc) 204GCC_handle_connection_ack (struct CadetConnection *cc)
236{ 205{
237 GNUNET_SCHEDULER_cancel (cc->task); 206 if (NULL != cc->task)
238#if FIXME 207 {
208 GNUNET_SCHEDULER_cancel (cc->task);
209 cc->task = NULL;
210 }
211#if FIXME_KEEPALIVE
239 cc->task = GNUNET_SCHEDULER_add_delayed (cc->keepalive_period, 212 cc->task = GNUNET_SCHEDULER_add_delayed (cc->keepalive_period,
240 &send_keepalive, 213 &send_keepalive,
241 cc); 214 cc);
242#endif 215#endif
243 cc->state = CADET_CONNECTION_READY; 216 cc->state = CADET_CONNECTION_READY;
244 cc->ready_cb (cc->ready_cb_cls); 217 if (GNUNET_YES == cc->mqm_ready)
218 cc->ready_cb (cc->ready_cb_cls,
219 GNUNET_YES);
245} 220}
246 221
247 222
@@ -255,6 +230,12 @@ void
255GCC_handle_kx (struct CadetConnection *cc, 230GCC_handle_kx (struct CadetConnection *cc,
256 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg) 231 const struct GNUNET_CADET_TunnelKeyExchangeMessage *msg)
257{ 232{
233 if (CADET_CONNECTION_SENT == cc->state)
234 {
235 /* We didn't get the CREATE_ACK, but instead got payload. That's fine,
236 clearly something is working, so pretend we got an ACK. */
237 GCC_handle_connection_ack (cc);
238 }
258 GCT_handle_kx (cc->ct, 239 GCT_handle_kx (cc->ct,
259 msg); 240 msg);
260} 241}
@@ -270,6 +251,12 @@ void
270GCC_handle_encrypted (struct CadetConnection *cc, 251GCC_handle_encrypted (struct CadetConnection *cc,
271 const struct GNUNET_CADET_TunnelEncryptedMessage *msg) 252 const struct GNUNET_CADET_TunnelEncryptedMessage *msg)
272{ 253{
254 if (CADET_CONNECTION_SENT == cc->state)
255 {
256 /* We didn't get the CREATE_ACK, but instead got payload. That's fine,
257 clearly something is working, so pretend we got an ACK. */
258 GCC_handle_connection_ack (cc);
259 }
273 GCT_handle_encrypted (cc->ct, 260 GCT_handle_encrypted (cc->ct,
274 msg); 261 msg);
275} 262}
@@ -281,37 +268,40 @@ GCC_handle_encrypted (struct CadetConnection *cc,
281 * @param cls the `struct CadetConnection` to initiate 268 * @param cls the `struct CadetConnection` to initiate
282 */ 269 */
283static void 270static void
284send_create (void *cls); 271send_create (void *cls)
285
286
287/**
288 * We finished transmission of the create message, now wait for
289 * ACK or retransmit.
290 *
291 * @param cls the `struct CadetConnection` that sent the create message
292 */
293static void
294transmit_create_done_cb (void *cls)
295{ 272{
296 struct CadetConnection *cc = cls; 273 struct CadetConnection *cc = cls;
274 struct GNUNET_CADET_ConnectionCreateMessage *create_msg;
275 struct GNUNET_PeerIdentity *pids;
276 struct GNUNET_MQ_Envelope *env;
277 unsigned int path_length;
297 278
279 cc->task = NULL;
280 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
281 path_length = GCPP_get_length (cc->path);
282 env = GNUNET_MQ_msg_extra (create_msg,
283 path_length * sizeof (struct GNUNET_PeerIdentity),
284 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE);
285 create_msg->cid = cc->cid;
286 pids = (struct GNUNET_PeerIdentity *) &create_msg[1];
287 for (unsigned int i=0;i<path_length;i++)
288 pids[i] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path,
289 i));
290 cc->env = env;
291 cc->mqm_ready = GNUNET_NO;
298 cc->state = CADET_CONNECTION_SENT; 292 cc->state = CADET_CONNECTION_SENT;
299 cc->env = NULL; 293 GCP_send (cc->mq_man,
300 /* FIXME: at some point, we need to reset the delay back to 0! */ 294 env);
301 cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
302 cc->task = GNUNET_SCHEDULER_add_delayed (cc->retry_delay,
303 &send_create,
304 cc);
305} 295}
306 296
307 297
308/** 298/**
309 * Send a CREATE message to the first hop. 299 * Send a CREATE_ACK message towards the origin.
310 * 300 *
311 * @param cls the `struct CadetConnection` to initiate 301 * @param cls the `struct CadetConnection` to initiate
312 */ 302 */
313static void 303static void
314send_create (void *cls) 304send_create_ack (void *cls)
315{ 305{
316 struct CadetConnection *cc = cls; 306 struct CadetConnection *cc = cls;
317 struct GNUNET_CADET_ConnectionCreateMessage *create_msg; 307 struct GNUNET_CADET_ConnectionCreateMessage *create_msg;
@@ -320,7 +310,7 @@ send_create (void *cls)
320 unsigned int path_length; 310 unsigned int path_length;
321 311
322 cc->task = NULL; 312 cc->task = NULL;
323 GNUNET_assert (NULL != cc->mq); 313 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
324 path_length = GCPP_get_length (cc->path); 314 path_length = GCPP_get_length (cc->path);
325 env = GNUNET_MQ_msg_extra (create_msg, 315 env = GNUNET_MQ_msg_extra (create_msg,
326 path_length * sizeof (struct GNUNET_PeerIdentity), 316 path_length * sizeof (struct GNUNET_PeerIdentity),
@@ -331,11 +321,42 @@ send_create (void *cls)
331 pids[i] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path, 321 pids[i] = *GCP_get_id (GCPP_get_peer_at_offset (cc->path,
332 i)); 322 i));
333 cc->env = env; 323 cc->env = env;
334 GNUNET_MQ_notify_sent (env, 324 cc->mqm_ready = GNUNET_NO;
335 &transmit_create_done_cb, 325 cc->state = CADET_CONNECTION_READY;
336 cc); 326 GCP_send (cc->mq_man,
337 GNUNET_MQ_send (cc->mq, 327 env);
338 env); 328}
329
330
331/**
332 * We got a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE for a
333 * connection that we already have. Either our ACK got lost
334 * or something is fishy. Consider retransmitting the ACK.
335 *
336 * @param cc connection that got the duplicate CREATE
337 */
338void
339GCC_handle_duplicate_create (struct CadetConnection *cc)
340{
341 if (GNUNET_YES == cc->mqm_ready)
342 {
343 /* Tell tunnel that we are not ready for transmission anymore
344 (until CREATE_ACK is done) */
345 cc->ready_cb (cc->ready_cb_cls,
346 GNUNET_NO);
347
348 /* Revert back to the state of having only received the 'CREATE',
349 and immediately proceed to send the CREATE_ACK. */
350 cc->state = CADET_CONNECTION_CREATE_RECEIVED;
351 cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack,
352 cc);
353 }
354 else
355 {
356 /* We are currently sending something else back, which
357 can only be an ACK or payload, either of which would
358 do. So actually no need to do anything. */
359 }
339} 360}
340 361
341 362
@@ -344,34 +365,62 @@ send_create (void *cls)
344 * peer at the first hop. Adjust accordingly. 365 * peer at the first hop. Adjust accordingly.
345 * 366 *
346 * @param cls the `struct CadetConnection` 367 * @param cls the `struct CadetConnection`
347 * @param mq NULL if the CORE connection was lost, non-NULL if 368 * @param available #GNUNET_YES if sending is now possible,
348 * it became available 369 * #GNUNET_NO if sending is no longer possible
370 * #GNUNET_SYSERR if sending is no longer possible
371 * and the last envelope was discarded
349 */ 372 */
350static void 373static void
351manage_first_hop_mq (void *cls, 374manage_first_hop_mq (void *cls,
352 struct GNUNET_MQ_Handle *mq) 375 int available)
353{ 376{
354 struct CadetConnection *cc = cls; 377 struct CadetConnection *cc = cls;
355 378
356 if (NULL == mq) 379 if (GNUNET_YES != available)
357 { 380 {
358 /* Connection is down, for now... */ 381 /* Connection is down, for now... */
359 cc->mq = NULL; 382 cc->mqm_ready = GNUNET_NO;
383 cc->state = CADET_CONNECTION_NEW;
384 cc->retry_delay = GNUNET_TIME_UNIT_ZERO;
360 if (NULL != cc->task) 385 if (NULL != cc->task)
361 { 386 {
362 GNUNET_SCHEDULER_cancel (cc->task); 387 GNUNET_SCHEDULER_cancel (cc->task);
363 cc->task = NULL; 388 cc->task = NULL;
364 } 389 }
390 cc->ready_cb (cc->ready_cb_cls,
391 GNUNET_NO);
365 return; 392 return;
366 } 393 }
367 394
368 cc->mq = mq; 395 cc->mqm_ready = GNUNET_YES;
369 cc->state = CADET_CONNECTION_SENDING_CREATE; 396 switch (cc->state)
370 397 {
371 /* Now repeat sending connection creation messages 398 case CADET_CONNECTION_NEW:
372 down the path, until we get an ACK! */ 399 /* Transmit immediately */
373 cc->task = GNUNET_SCHEDULER_add_now (&send_create, 400 cc->task = GNUNET_SCHEDULER_add_now (&send_create,
374 cc); 401 cc);
402 break;
403 case CADET_CONNECTION_SENDING_CREATE:
404 /* Should not be possible to be called in this state. */
405 GNUNET_assert (0);
406 break;
407 case CADET_CONNECTION_SENT:
408 /* Retry a bit later... */
409 cc->retry_delay = GNUNET_TIME_STD_BACKOFF (cc->retry_delay);
410 cc->task = GNUNET_SCHEDULER_add_delayed (cc->retry_delay,
411 &send_create,
412 cc);
413 break;
414 case CADET_CONNECTION_CREATE_RECEIVED:
415 /* We got the 'CREATE' (incoming connection), should send the CREATE_ACK */
416 cc->task = GNUNET_SCHEDULER_add_now (&send_create_ack,
417 cc);
418 break;
419 case CADET_CONNECTION_READY:
420 cc->ready_cb (cc->ready_cb_cls,
421 GNUNET_YES);
422 break;
423 }
375} 424}
376 425
377 426
@@ -383,6 +432,7 @@ manage_first_hop_mq (void *cls,
383 * @param destination where to go 432 * @param destination where to go
384 * @param path which path to take (may not be the full path) 433 * @param path which path to take (may not be the full path)
385 * @param ct which tunnel uses this connection 434 * @param ct which tunnel uses this connection
435 * @param init_state initial state for the connection
386 * @param ready_cb function to call when ready to transmit 436 * @param ready_cb function to call when ready to transmit
387 * @param ready_cb_cls closure for @a cb 437 * @param ready_cb_cls closure for @a cb
388 * @return handle to the connection 438 * @return handle to the connection
@@ -392,7 +442,8 @@ connection_create (struct CadetPeer *destination,
392 struct CadetPeerPath *path, 442 struct CadetPeerPath *path,
393 struct CadetTConnection *ct, 443 struct CadetTConnection *ct,
394 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, 444 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
395 GNUNET_SCHEDULER_TaskCallback ready_cb, 445 enum CadetConnectionState init_state,
446 GCC_ReadyCallback ready_cb,
396 void *ready_cb_cls) 447 void *ready_cb_cls)
397{ 448{
398 struct CadetConnection *cc; 449 struct CadetConnection *cc;
@@ -403,6 +454,7 @@ connection_create (struct CadetPeer *destination,
403 destination); 454 destination);
404 GNUNET_assert (UINT_MAX > off); 455 GNUNET_assert (UINT_MAX > off);
405 cc = GNUNET_new (struct CadetConnection); 456 cc = GNUNET_new (struct CadetConnection);
457 cc->state = init_state;
406 cc->ct = ct; 458 cc->ct = ct;
407 cc->cid = *cid; 459 cc->cid = *cid;
408 GNUNET_assert (GNUNET_OK == 460 GNUNET_assert (GNUNET_OK ==
@@ -448,19 +500,16 @@ GCC_create_inbound (struct CadetPeer *destination,
448 struct CadetPeerPath *path, 500 struct CadetPeerPath *path,
449 struct CadetTConnection *ct, 501 struct CadetTConnection *ct,
450 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid, 502 const struct GNUNET_CADET_ConnectionTunnelIdentifier *cid,
451 GNUNET_SCHEDULER_TaskCallback ready_cb, 503 GCC_ReadyCallback ready_cb,
452 void *ready_cb_cls) 504 void *ready_cb_cls)
453{ 505{
454 struct CadetConnection *cc; 506 return connection_create (destination,
455 507 path,
456 cc = connection_create (destination, 508 ct,
457 path, 509 cid,
458 ct, 510 CADET_CONNECTION_CREATE_RECEIVED,
459 cid, 511 ready_cb,
460 ready_cb, 512 ready_cb_cls);
461 ready_cb_cls);
462 /* FIXME: send CREATE_ACK? */
463 return cc;
464} 513}
465 514
466 515
@@ -479,41 +528,21 @@ struct CadetConnection *
479GCC_create (struct CadetPeer *destination, 528GCC_create (struct CadetPeer *destination,
480 struct CadetPeerPath *path, 529 struct CadetPeerPath *path,
481 struct CadetTConnection *ct, 530 struct CadetTConnection *ct,
482 GNUNET_SCHEDULER_TaskCallback ready_cb, 531 GCC_ReadyCallback ready_cb,
483 void *ready_cb_cls) 532 void *ready_cb_cls)
484{ 533{
485 struct GNUNET_CADET_ConnectionTunnelIdentifier cid; 534 struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
486 struct CadetConnection *cc;
487 535
488 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, 536 GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
489 &cid, 537 &cid,
490 sizeof (cid)); 538 sizeof (cid));
491 cc = connection_create (destination, 539 return connection_create (destination,
492 path, 540 path,
493 ct, 541 ct,
494 &cid, 542 &cid,
495 ready_cb, 543 CADET_CONNECTION_NEW,
496 ready_cb_cls); 544 ready_cb,
497 /* FIXME: send CREATE? */ 545 ready_cb_cls);
498 return cc;
499}
500
501
502/**
503 * We finished transmission of a message, if we are still ready, tell
504 * the tunnel!
505 *
506 * @param cls our `struct CadetConnection`
507 */
508static void
509transmit_done_cb (void *cls)
510{
511 struct CadetConnection *cc = cls;
512
513 cc->env = NULL;
514 if ( (NULL != cc->mq) &&
515 (CADET_CONNECTION_READY == cc->state) )
516 cc->ready_cb (cc->ready_cb_cls);
517} 546}
518 547
519 548
@@ -524,21 +553,18 @@ transmit_done_cb (void *cls)
524 * connection is right now ready for transmission. 553 * connection is right now ready for transmission.
525 * 554 *
526 * @param cc connection identification 555 * @param cc connection identification
527 * @param env envelope with message to transmit 556 * @param env envelope with message to transmit; must NOT
557 * yet have a #GNUNET_MQ_notify_sent() callback attached to it
528 */ 558 */
529void 559void
530GCC_transmit (struct CadetConnection *cc, 560GCC_transmit (struct CadetConnection *cc,
531 struct GNUNET_MQ_Envelope *env) 561 struct GNUNET_MQ_Envelope *env)
532{ 562{
533 GNUNET_assert (NULL == cc->env); 563 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
534 cc->env = env; 564 GNUNET_assert (CADET_CONNECTION_READY == cc->state);
535 GNUNET_MQ_notify_sent (env, 565 cc->mqm_ready = GNUNET_NO;
536 &transmit_done_cb, 566 GCP_send (cc->mq_man,
537 cc); 567 env);
538 if ( (NULL != cc->mq) &&
539 (CADET_CONNECTION_READY == cc->state) )
540 GNUNET_MQ_send (cc->mq,
541 env);
542} 568}
543 569
544 570
@@ -569,6 +595,39 @@ GCC_get_id (struct CadetConnection *cc)
569 595
570 596
571/** 597/**
598 * Get a (static) string for a connection.
599 *
600 * @param cc Connection.
601 */
602const char *
603GCC_2s (const struct CadetConnection *cc)
604{
605 static char buf[128];
606
607 if (NULL == cc)
608 return "Connection(NULL)";
609
610 if (NULL != cc->ct)
611 {
612 GNUNET_snprintf (buf,
613 sizeof (buf),
614 "Connection(%s(Tunnel(%s)))",
615 GNUNET_sh2s (&cc->cid.connection_of_tunnel),
616 GCT_2s (cc->ct->t));
617 return buf;
618 }
619 GNUNET_snprintf (buf,
620 sizeof (buf),
621 "Connection(%s(Tunnel(NULL)))",
622 GNUNET_sh2s (&cc->cid.connection_of_tunnel));
623 return buf;
624}
625
626
627#define LOG2(level, ...) GNUNET_log_from_nocheck(level,"cadet-con",__VA_ARGS__)
628
629
630/**
572 * Log connection info. 631 * Log connection info.
573 * 632 *
574 * @param cc connection 633 * @param cc connection
@@ -578,7 +637,29 @@ void
578GCC_debug (struct CadetConnection *cc, 637GCC_debug (struct CadetConnection *cc,
579 enum GNUNET_ErrorType level) 638 enum GNUNET_ErrorType level)
580{ 639{
581 GNUNET_break (0); // FIXME: implement... 640 int do_log;
641 char *s;
642
643 do_log = GNUNET_get_log_call_status (level & (~GNUNET_ERROR_TYPE_BULK),
644 "cadet-con",
645 __FILE__, __FUNCTION__, __LINE__);
646 if (0 == do_log)
647 return;
648 if (NULL == cc)
649 {
650 LOG2 (level,
651 "Connection (NULL)\n");
652 return;
653 }
654 s = GCPP_2s (cc->path);
655 LOG2 (level,
656 "Connection %s to %s via path %s in state %d is %s\n",
657 GCC_2s (cc),
658 GCP_2s (cc->destination),
659 s,
660 cc->state,
661 (GNUNET_YES == cc->mqm_ready) ? "ready" : "busy");
662 GNUNET_free (s);
582} 663}
583 664
584/* end of gnunet-service-cadet-new_connection.c */ 665/* end of gnunet-service-cadet-new_connection.c */