aboutsummaryrefslogtreecommitdiff
path: root/src/cadet/gnunet-service-cadet-new_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cadet/gnunet-service-cadet-new_core.c')
-rw-r--r--src/cadet/gnunet-service-cadet-new_core.c460
1 files changed, 460 insertions, 0 deletions
diff --git a/src/cadet/gnunet-service-cadet-new_core.c b/src/cadet/gnunet-service-cadet-new_core.c
index a24f7a3ce..8cc6c843e 100644
--- a/src/cadet/gnunet-service-cadet-new_core.c
+++ b/src/cadet/gnunet-service-cadet-new_core.c
@@ -28,15 +28,435 @@
28 */ 28 */
29#include "platform.h" 29#include "platform.h"
30#include "gnunet-service-cadet-new_core.h" 30#include "gnunet-service-cadet-new_core.h"
31#include "gnunet-service-cadet-new_paths.h"
31#include "gnunet-service-cadet-new_peer.h" 32#include "gnunet-service-cadet-new_peer.h"
32#include "gnunet-service-cadet-new_connection.h" 33#include "gnunet-service-cadet-new_connection.h"
33#include "gnunet_core_service.h" 34#include "gnunet_core_service.h"
35#include "cadet_protocol.h"
36
37
38/**
39 * Description of a segment of a `struct CadetConnection` at the
40 * intermediate peers. Routes are basically entries in a peer's
41 * routing table for forwarding traffic. At both endpoints, the
42 * routes are terminated by a `struct CadetConnection`, which knows
43 * the complete `struct CadetPath` that is formed by the individual
44 * routes.
45 */
46struct CadetRoute
47{
48
49 /**
50 * Previous hop on this route.
51 */
52 struct CadetPeer *prev_hop;
53
54 /**
55 * Next hop on this route.
56 */
57 struct CadetPeer *next_hop;
58
59 /**
60 * Unique identifier for the connection that uses this route.
61 */
62 struct GNUNET_CADET_ConnectionTunnelIdentifier cid;
63
64 /**
65 * When was this route last in use?
66 */
67 struct GNUNET_TIME_Absolute last_use;
68
69};
70
34 71
35/** 72/**
36 * Handle to the CORE service. 73 * Handle to the CORE service.
37 */ 74 */
38static struct GNUNET_CORE_Handle *core; 75static struct GNUNET_CORE_Handle *core;
39 76
77/**
78 * Routes on which this peer is an intermediate.
79 */
80static struct GNUNET_CONTAINER_MultiHashMap *routes;
81
82
83/**
84 * Get the route corresponding to a hash.
85 *
86 * @param cid hash generated from the connection identifier
87 */
88static struct CadetRoute *
89get_route (const struct GNUNET_HashCode *cid)
90{
91 return GNUNET_CONTAINER_multihashmap_get (routes,
92 cid);
93}
94
95
96/**
97 * We message @a msg from @a prev. Find its route by @a cid and
98 * forward to the next hop. Drop and signal broken route if we do not
99 * have a route.
100 *
101 * @param prev previous hop (sender)
102 * @param cid connection identifier, tells us which route to use
103 * @param msg the message to forward
104 */
105static void
106route_message (struct CadetPeer *prev,
107 const struct GNUNET_HashCode *cid, /* FIXME: bad type... */
108 const struct GNUNET_MessageHeader *msg)
109{
110 struct CadetRoute *route;
111
112 route = get_route (cid);
113 if (NULL == route)
114 {
115 struct GNUNET_MQ_Envelope *env;
116 struct GNUNET_CADET_ConnectionBroken *bm;
117
118 env = GNUNET_MQ_msg (bm,
119 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN);
120 /* FIXME: ugly */
121 memcpy (&bm->cid,
122 cid,
123 sizeof (bm->cid));
124 bm->peer1 = my_full_id;
125 GCP_send (prev,
126 env);
127 return;
128 }
129 GNUNET_assert (0); /* FIXME: determine next hop from route and prev! */
130
131}
132
133
134/**
135 * Check if the create_connection message has the appropriate size.
136 *
137 * @param cls Closure (unused).
138 * @param msg Message to check.
139 *
140 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
141 */
142static int
143check_create (void *cls,
144 const struct GNUNET_CADET_ConnectionCreate *msg)
145{
146 uint16_t size = ntohs (msg->header.size) - sizeof (*msg);
147
148 if (0 != (size % sizeof (struct GNUNET_PeerIdentity)))
149 {
150 GNUNET_break_op (0);
151 return GNUNET_NO;
152 }
153 return GNUNET_YES;
154}
155
156
157/**
158 * Destroy our state for @a route.
159 *
160 * @param route route to destroy
161 */
162static void
163destroy_route (struct CadetRoute *route)
164{
165 GNUNET_break (0); // fIXME: implement!
166}
167
168
169/**
170 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE
171 *
172 * @param cls Closure (CadetPeer for neighbor that sent the message).
173 * @param msg Message itself.
174 */
175static void
176handle_create (void *cls,
177 const struct GNUNET_CADET_ConnectionCreate *msg)
178{
179 struct CadetPeer *peer = cls;
180 uint16_t size = ntohs (msg->header.size) - sizeof (*msg);
181 unsigned int path_length;
182
183 path_length = size / sizeof (struct GNUNET_PeerIdentity);
184#if FIXME
185 GCC_handle_create (peer,
186 &msg->cid,
187 path_length,
188 (const struct GNUNET_PeerIdentity *) &msg[1]);
189#endif
190}
191
192
193/**
194 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK
195 *
196 * @param cls Closure (CadetPeer for neighbor that sent the message).
197 * @param msg Message itself.
198 */
199static void
200handle_connection_ack (void *cls,
201 const struct GNUNET_CADET_ConnectionACK *msg)
202{
203 struct CadetPeer *peer = cls;
204 const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel);
205 struct CadetConnection *cc;
206
207 /* First, check if ACK belongs to a connection that ends here. */
208 cc = GNUNET_CONTAINER_multihashmap_get (connections,
209 cid);
210 if (NULL != cc)
211 {
212 /* verify ACK came from the right direction */
213 struct CadetPeerPath *path = GCC_get_path (cc);
214
215 if (peer !=
216 GCPP_get_peer_at_offset (path,
217 0))
218 {
219 /* received ACK from unexpected direction, ignore! */
220 GNUNET_break_op (0);
221 return;
222 }
223 GCC_handle_connection_ack (cc);
224 return;
225 }
226
227 /* We're just an intermediary peer, route the message along its path */
228 route_message (peer,
229 cid,
230 &msg->header);
231}
232
233
234/**
235 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN
236 *
237 * @param cls Closure (CadetPeer for neighbor that sent the message).
238 * @param msg Message itself.
239 * @deprecated duplicate logic with #handle_destroy(); dedup!
240 */
241static void
242handle_broken (void *cls,
243 const struct GNUNET_CADET_ConnectionBroken *msg)
244{
245 struct CadetPeer *peer = cls;
246 const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel);
247 struct CadetConnection *cc;
248 struct CadetRoute *route;
249
250 /* First, check if message belongs to a connection that ends here. */
251 cc = GNUNET_CONTAINER_multihashmap_get (connections,
252 cid);
253 if (NULL != cc)
254 {
255 /* verify message came from the right direction */
256 struct CadetPeerPath *path = GCC_get_path (cc);
257
258 if (peer !=
259 GCPP_get_peer_at_offset (path,
260 0))
261 {
262 /* received message from unexpected direction, ignore! */
263 GNUNET_break_op (0);
264 return;
265 }
266 GCC_destroy (cc);
267 return;
268 }
269
270 /* We're just an intermediary peer, route the message along its path */
271 route = get_route (cid);
272 route_message (peer,
273 cid,
274 &msg->header);
275 destroy_route (route);
276}
277
278
279/**
280 * Handle for #GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY
281 *
282 * @param cls Closure (CadetPeer for neighbor that sent the message).
283 * @param msg Message itself.
284 */
285static void
286handle_destroy (void *cls,
287 const struct GNUNET_CADET_ConnectionDestroy *msg)
288{
289 struct CadetPeer *peer = cls;
290 const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel);
291 struct CadetConnection *cc;
292 struct CadetRoute *route;
293
294 /* First, check if message belongs to a connection that ends here. */
295 cc = GNUNET_CONTAINER_multihashmap_get (connections,
296 cid);
297 if (NULL != cc)
298 {
299 /* verify message came from the right direction */
300 struct CadetPeerPath *path = GCC_get_path (cc);
301
302 if (peer !=
303 GCPP_get_peer_at_offset (path,
304 0))
305 {
306 /* received message from unexpected direction, ignore! */
307 GNUNET_break_op (0);
308 return;
309 }
310 GCC_destroy (cc);
311 return;
312 }
313
314 /* We're just an intermediary peer, route the message along its path */
315 route = get_route (cid);
316 route_message (peer,
317 cid,
318 &msg->header);
319 destroy_route (route);
320}
321
322
323/**
324 * Handle for #GNUNET_MESSAGE_TYPE_CADET_ACK
325 *
326 * @param cls Closure (CadetPeer for neighbor that sent the message).
327 * @param msg Message itself.
328 */
329static void
330handle_ack (void *cls,
331 const struct GNUNET_CADET_ACK *msg)
332{
333 struct CadetPeer *peer = cls;
334
335#if FIXME
336 GCC_handle_ack (peer,
337 msg);
338#endif
339}
340
341
342/**
343 * Handle for #GNUNET_MESSAGE_TYPE_CADET_POLL
344 *
345 * @param cls Closure (CadetPeer for neighbor that sent the message).
346 * @param msg Message itself.
347 */
348static void
349handle_poll (void *cls,
350 const struct GNUNET_CADET_Poll *msg)
351{
352 struct CadetPeer *peer = cls;
353
354#if FIXME
355 GCC_handle_poll (peer,
356 msg);
357#endif
358}
359
360
361/**
362 * Handle for #GNUNET_MESSAGE_TYPE_CADET_KX
363 *
364 * @param cls Closure (CadetPeer for neighbor that sent the message).
365 * @param msg Message itself.
366 */
367static void
368handle_kx (void *cls,
369 const struct GNUNET_CADET_KX *msg)
370{
371 struct CadetPeer *peer = cls;
372 const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel);
373 struct CadetConnection *cc;
374
375 /* First, check if message belongs to a connection that ends here. */
376 cc = GNUNET_CONTAINER_multihashmap_get (connections,
377 cid);
378 if (NULL != cc)
379 {
380 /* verify message came from the right direction */
381 struct CadetPeerPath *path = GCC_get_path (cc);
382
383 if (peer !=
384 GCPP_get_peer_at_offset (path,
385 0))
386 {
387 /* received message from unexpected direction, ignore! */
388 GNUNET_break_op (0);
389 return;
390 }
391 GCC_handle_kx (cc,
392 msg);
393 return;
394 }
395
396 /* We're just an intermediary peer, route the message along its path */
397 route_message (peer,
398 cid,
399 &msg->header);
400}
401
402
403/**
404 * Check if the encrypted message has the appropriate size.
405 *
406 * @param cls Closure (unused).
407 * @param msg Message to check.
408 *
409 * @return #GNUNET_YES if size is correct, #GNUNET_NO otherwise.
410 */
411static int
412check_encrypted (void *cls,
413 const struct GNUNET_CADET_Encrypted *msg)
414{
415 return GNUNET_YES;
416}
417
418
419/**
420 * Handle for #GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED.
421 *
422 * @param cls Closure (CadetPeer for neighbor that sent the message).
423 * @param msg Message itself.
424 */
425static void
426handle_encrypted (void *cls,
427 const struct GNUNET_CADET_Encrypted *msg)
428{
429 struct CadetPeer *peer = cls;
430 const struct GNUNET_HashCode *cid = GCC_h2hc (&msg->cid.connection_of_tunnel);
431 struct CadetConnection *cc;
432
433 /* First, check if message belongs to a connection that ends here. */
434 cc = GNUNET_CONTAINER_multihashmap_get (connections,
435 cid);
436 if (NULL != cc)
437 {
438 /* verify message came from the right direction */
439 struct CadetPeerPath *path = GCC_get_path (cc);
440
441 if (peer !=
442 GCPP_get_peer_at_offset (path,
443 0))
444 {
445 /* received message from unexpected direction, ignore! */
446 GNUNET_break_op (0);
447 return;
448 }
449 GCC_handle_encrypted (cc,
450 msg);
451 return;
452 }
453
454 /* We're just an intermediary peer, route the message along its path */
455 route_message (peer,
456 cid,
457 &msg->header);
458}
459
40 460
41/** 461/**
42 * Function called after #GNUNET_CORE_connect has succeeded (or failed 462 * Function called after #GNUNET_CORE_connect has succeeded (or failed
@@ -100,6 +520,9 @@ core_disconnect_cb (void *cls,
100{ 520{
101 struct CadetPeer *cp = peer_cls; 521 struct CadetPeer *cp = peer_cls;
102 522
523 /* FIXME: also check all routes going via peer and
524 send broken messages to the other direction! */
525 GNUNET_break (0);
103 GCP_set_mq (cp, 526 GCP_set_mq (cp,
104 NULL); 527 NULL);
105} 528}
@@ -114,8 +537,43 @@ void
114GCO_init (const struct GNUNET_CONFIGURATION_Handle *c) 537GCO_init (const struct GNUNET_CONFIGURATION_Handle *c)
115{ 538{
116 struct GNUNET_MQ_MessageHandler handlers[] = { 539 struct GNUNET_MQ_MessageHandler handlers[] = {
540 GNUNET_MQ_hd_var_size (create,
541 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_CREATE,
542 struct GNUNET_CADET_ConnectionCreate,
543 NULL),
544 GNUNET_MQ_hd_fixed_size (connection_ack,
545 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_ACK,
546 struct GNUNET_CADET_ConnectionACK,
547 NULL),
548 GNUNET_MQ_hd_fixed_size (broken,
549 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_BROKEN,
550 struct GNUNET_CADET_ConnectionBroken,
551 NULL),
552 GNUNET_MQ_hd_fixed_size (destroy,
553 GNUNET_MESSAGE_TYPE_CADET_CONNECTION_DESTROY,
554 struct GNUNET_CADET_ConnectionDestroy,
555 NULL),
556 GNUNET_MQ_hd_fixed_size (ack,
557 GNUNET_MESSAGE_TYPE_CADET_ACK,
558 struct GNUNET_CADET_ACK,
559 NULL),
560 GNUNET_MQ_hd_fixed_size (poll,
561 GNUNET_MESSAGE_TYPE_CADET_POLL,
562 struct GNUNET_CADET_Poll,
563 NULL),
564 GNUNET_MQ_hd_fixed_size (kx,
565 GNUNET_MESSAGE_TYPE_CADET_KX,
566 struct GNUNET_CADET_KX,
567 NULL),
568 GNUNET_MQ_hd_var_size (encrypted,
569 GNUNET_MESSAGE_TYPE_CADET_ENCRYPTED,
570 struct GNUNET_CADET_Encrypted,
571 NULL),
117 GNUNET_MQ_handler_end () 572 GNUNET_MQ_handler_end ()
118 }; 573 };
574
575 routes = GNUNET_CONTAINER_multihashmap_create (1024,
576 GNUNET_NO);
119 core = GNUNET_CORE_connect (c, 577 core = GNUNET_CORE_connect (c,
120 NULL, 578 NULL,
121 &core_init_cb, 579 &core_init_cb,
@@ -136,6 +594,8 @@ GCO_shutdown ()
136 GNUNET_CORE_disconnect (core); 594 GNUNET_CORE_disconnect (core);
137 core = NULL; 595 core = NULL;
138 } 596 }
597 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (routes));
598 GNUNET_CONTAINER_multihashmap_destroy (routes);
139} 599}
140 600
141/* end of gnunet-cadet-service_core.c */ 601/* end of gnunet-cadet-service_core.c */