aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet-new_connection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cadet/gnunet-service-cadet-new_connection.c')
-rw-r--r--src/cadet/gnunet-service-cadet-new_connection.c115
1 files changed, 107 insertions, 8 deletions
diff --git a/src/cadet/gnunet-service-cadet-new_connection.c b/src/cadet/gnunet-service-cadet-new_connection.c
index 60389008c..58922bc1e 100644
--- a/src/cadet/gnunet-service-cadet-new_connection.c
+++ b/src/cadet/gnunet-service-cadet-new_connection.c
@@ -27,16 +27,18 @@
27 * @author Christian Grothoff 27 * @author Christian Grothoff
28 * 28 *
29 * TODO: 29 * TODO:
30 * - Optimization: keepalive messages / timeout (timeout to be done @ peer level!) 30 * - Implement: keepalive messages / timeout (timeout to be done @ peer level!)
31 * - Optimization: keep performance metrics (?) 31 * - Optimization: keep performance metrics (?)
32 */ 32 */
33#include "platform.h" 33#include "platform.h"
34#include "gnunet-service-cadet-new.h"
34#include "gnunet-service-cadet-new_channel.h" 35#include "gnunet-service-cadet-new_channel.h"
35#include "gnunet-service-cadet-new_connection.h" 36#include "gnunet-service-cadet-new_connection.h"
36#include "gnunet-service-cadet-new_paths.h" 37#include "gnunet-service-cadet-new_paths.h"
37#include "gnunet-service-cadet-new_peer.h" 38#include "gnunet-service-cadet-new_peer.h"
38#include "gnunet-service-cadet-new_tunnels.h" 39#include "gnunet-service-cadet-new_tunnels.h"
39#include "gnunet_cadet_service.h" 40#include "gnunet_cadet_service.h"
41#include "gnunet_statistics_service.h"
40#include "cadet_protocol.h" 42#include "cadet_protocol.h"
41 43
42 44
@@ -119,6 +121,11 @@ struct CadetConnection
119 struct GNUNET_SCHEDULER_Task *task; 121 struct GNUNET_SCHEDULER_Task *task;
120 122
121 /** 123 /**
124 * Queue entry for keepalive messages.
125 */
126 struct CadetTunnelQueueEntry *keepalive_qe;
127
128 /**
122 * Function to call once we are ready to transmit. 129 * Function to call once we are ready to transmit.
123 */ 130 */
124 GCC_ReadyCallback ready_cb; 131 GCC_ReadyCallback ready_cb;
@@ -184,6 +191,11 @@ GCC_destroy (struct CadetConnection *cc)
184 GNUNET_SCHEDULER_cancel (cc->task); 191 GNUNET_SCHEDULER_cancel (cc->task);
185 cc->task = NULL; 192 cc->task = NULL;
186 } 193 }
194 if (NULL != cc->keepalive_qe)
195 {
196 GCT_send_cancel (cc->keepalive_qe);
197 cc->keepalive_qe = NULL;
198 }
187 GCPP_del_connection (cc->path, 199 GCPP_del_connection (cc->path,
188 cc->off, 200 cc->off,
189 cc); 201 cc);
@@ -209,7 +221,72 @@ GCC_get_ct (struct CadetConnection *cc)
209 221
210 222
211/** 223/**
212 * A CADET_CONNECTION_ACK was received for this connection, implying 224 * Send a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE through the
225 * tunnel to prevent it from timing out.
226 *
227 * @param cls the `struct CadetConnection` to keep alive.
228 */
229static void
230send_keepalive (void *cls);
231
232
233/**
234 * Keepalive was transmitted. Remember this, and possibly
235 * schedule the next one.
236 *
237 * @param cls the `struct CadetConnection` to keep alive.
238 */
239static void
240keepalive_done (void *cls)
241{
242 struct CadetConnection *cc = cls;
243
244 cc->keepalive_qe = NULL;
245 if ( (GNUNET_YES == cc->mqm_ready) &&
246 (NULL == cc->task) )
247 cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
248 &send_keepalive,
249 cc);
250}
251
252
253/**
254 * Send a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE through the
255 * tunnel to prevent it from timing out.
256 *
257 * @param cls the `struct CadetConnection` to keep alive.
258 */
259static void
260send_keepalive (void *cls)
261{
262 struct CadetConnection *cc = cls;
263 struct GNUNET_MessageHeader msg;
264
265 cc->task = NULL;
266 GNUNET_assert (NULL != cc->ct);
267 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
268 GNUNET_assert (NULL == cc->keepalive_qe);
269 LOG (GNUNET_ERROR_TYPE_INFO,
270 "Sending KEEPALIVE on behalf of %s via %s\n",
271 GCC_2s (cc),
272 GCT_2s (cc->ct->t));
273 GNUNET_STATISTICS_update (stats,
274 "# keepalives sent",
275 1,
276 GNUNET_NO);
277 msg.size = htons (sizeof (msg));
278 msg.type = htons (GNUNET_MESSAGE_TYPE_CADET_CHANNEL_KEEPALIVE);
279
280 cc->keepalive_qe
281 = GCT_send (cc->ct->t,
282 &msg,
283 &keepalive_done,
284 cc);
285}
286
287
288/**
289 * A #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE_ACK was received for this connection, implying
213 * that the end-to-end connection is up. Process it. 290 * that the end-to-end connection is up. Process it.
214 * 291 *
215 * @param cc the connection that got the ACK. 292 * @param cc the connection that got the ACK.
@@ -227,15 +304,18 @@ GCC_handle_connection_create_ack (struct CadetConnection *cc)
227 GNUNET_SCHEDULER_cancel (cc->task); 304 GNUNET_SCHEDULER_cancel (cc->task);
228 cc->task = NULL; 305 cc->task = NULL;
229 } 306 }
230#if FIXME_KEEPALIVE
231 cc->task = GNUNET_SCHEDULER_add_delayed (cc->keepalive_period,
232 &send_keepalive,
233 cc);
234#endif
235 cc->state = CADET_CONNECTION_READY; 307 cc->state = CADET_CONNECTION_READY;
236 if (GNUNET_YES == cc->mqm_ready) 308 if (GNUNET_YES == cc->mqm_ready)
309 {
237 cc->ready_cb (cc->ready_cb_cls, 310 cc->ready_cb (cc->ready_cb_cls,
238 GNUNET_YES); 311 GNUNET_YES);
312 if ( (NULL == cc->keepalive_qe) &&
313 (GNUNET_YES == cc->mqm_ready) &&
314 (NULL == cc->task) )
315 cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
316 &send_keepalive,
317 cc);
318 }
239} 319}
240 320
241 321
@@ -288,7 +368,8 @@ GCC_handle_encrypted (struct CadetConnection *cc,
288 368
289 369
290/** 370/**
291 * Send a CREATE message to the first hop. 371 * Send a #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE message to the
372 * first hop.
292 * 373 *
293 * @param cls the `struct CadetConnection` to initiate 374 * @param cls the `struct CadetConnection` to initiate
294 */ 375 */
@@ -459,6 +540,19 @@ manage_first_hop_mq (void *cls,
459 case CADET_CONNECTION_READY: 540 case CADET_CONNECTION_READY:
460 cc->ready_cb (cc->ready_cb_cls, 541 cc->ready_cb (cc->ready_cb_cls,
461 GNUNET_YES); 542 GNUNET_YES);
543 if ( (NULL == cc->keepalive_qe) &&
544 (GNUNET_YES == cc->mqm_ready) &&
545 (NULL == cc->task) )
546 {
547 LOG (GNUNET_ERROR_TYPE_DEBUG,
548 "Scheduling keepalive for %s in %s\n",
549 GCC_2s (cc),
550 GNUNET_STRINGS_relative_time_to_string (keepalive_period,
551 GNUNET_YES));
552 cc->task = GNUNET_SCHEDULER_add_delayed (keepalive_period,
553 &send_keepalive,
554 cc);
555 }
462 break; 556 break;
463 } 557 }
464} 558}
@@ -610,6 +704,11 @@ GCC_transmit (struct CadetConnection *cc,
610 GNUNET_assert (GNUNET_YES == cc->mqm_ready); 704 GNUNET_assert (GNUNET_YES == cc->mqm_ready);
611 GNUNET_assert (CADET_CONNECTION_READY == cc->state); 705 GNUNET_assert (CADET_CONNECTION_READY == cc->state);
612 cc->mqm_ready = GNUNET_NO; 706 cc->mqm_ready = GNUNET_NO;
707 if (NULL != cc->task)
708 {
709 GNUNET_SCHEDULER_cancel (cc->task);
710 cc->task = NULL;
711 }
613 GCP_send (cc->mq_man, 712 GCP_send (cc->mq_man,
614 env); 713 env);
615} 714}