aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/transport/plugin_transport_udp_new.c231
-rw-r--r--src/transport/plugin_transport_udp_new.h7
-rw-r--r--src/transport/plugin_transport_udp_new_broadcasting.c25
3 files changed, 246 insertions, 17 deletions
diff --git a/src/transport/plugin_transport_udp_new.c b/src/transport/plugin_transport_udp_new.c
index fb8c6cf36..057364829 100644
--- a/src/transport/plugin_transport_udp_new.c
+++ b/src/transport/plugin_transport_udp_new.c
@@ -64,6 +64,29 @@ struct PrettyPrinterContext
64 uint16_t port; 64 uint16_t port;
65}; 65};
66 66
67struct Session
68{
69 /**
70 * Which peer is this session for?
71 */
72 struct GNUNET_PeerIdentity target;
73
74 /**
75 * Address of the other peer
76 */
77 const struct sockaddr *sock_addr;
78
79 size_t addrlen;
80};
81
82
83struct SessionCompareContext
84{
85 struct Session *res;
86 const struct GNUNET_HELLO_Address *addr;
87};
88
89
67 90
68/** 91/**
69 * Function called for a quick conversion of the binary address to 92 * Function called for a quick conversion of the binary address to
@@ -293,6 +316,40 @@ udp_plugin_check_address (void *cls, const void *addr, size_t addrlen)
293 316
294 317
295/** 318/**
319 * Destroy a session, plugin is being unloaded.
320 *
321 * @param cls unused
322 * @param key hash of public key of target peer
323 * @param value a 'struct PeerSession*' to clean up
324 * @return GNUNET_OK (continue to iterate)
325 */
326static int
327disconnect_and_free_it (void *cls, const GNUNET_HashCode * key, void *value)
328{
329 struct Plugin *plugin = cls;
330 struct Session *s = value;
331
332#if DEBUG_UDP
333 LOG (GNUNET_ERROR_TYPE_DEBUG,
334 "Session %p to peer `%s' address ended \n",
335 s,
336 GNUNET_i2s (&s->target),
337 GNUNET_a2s (s->sock_addr, s->addrlen));
338#endif
339
340 plugin->env->session_end (plugin->env->cls, &s->target, s);
341
342 GNUNET_assert (GNUNET_YES ==
343 GNUNET_CONTAINER_multihashmap_remove (plugin->sessions,
344 &s->target.hashPubKey,
345 s));
346
347 GNUNET_free (s);
348 return GNUNET_OK;
349}
350
351
352/**
296 * Disconnect from a remote node. Clean up session if we have one for this peer 353 * Disconnect from a remote node. Clean up session if we have one for this peer
297 * 354 *
298 * @param cls closure for this call (should be handle to Plugin) 355 * @param cls closure for this call (should be handle to Plugin)
@@ -302,9 +359,129 @@ udp_plugin_check_address (void *cls, const void *addr, size_t addrlen)
302static void 359static void
303udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) 360udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
304{ 361{
362 struct Plugin *plugin = cls;
363 GNUNET_assert (plugin != NULL);
364
365 GNUNET_assert (target != NULL);
366#if DEBUG_UDP
367 LOG (GNUNET_ERROR_TYPE_DEBUG,
368 "Disconnecting from peer `%s'\n", GNUNET_i2s (target));
369#endif
370 /* Clean up sessions */
371 GNUNET_CONTAINER_multihashmap_get_multiple (plugin->sessions, &target->hashPubKey, &disconnect_and_free_it, plugin);
305 372
306} 373}
307 374
375static struct Session *
376create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
377 const void *addr, size_t addrlen,
378 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
379{
380 struct Session *s;
381 const struct IPv4UdpAddress *t4;
382 const struct IPv6UdpAddress *t6;
383 struct sockaddr_in *v4;
384 struct sockaddr_in6 *v6;
385 size_t len;
386 struct GNUNET_ATS_Information ats;
387
388 switch (addrlen)
389 {
390 case sizeof (struct IPv4UdpAddress):
391 if (NULL == plugin->sockv4)
392 {
393 return NULL;
394 }
395 t4 = addr;
396 s = GNUNET_malloc (sizeof (struct Session) + sizeof (struct sockaddr_in));
397 len = sizeof (struct sockaddr_in);
398 v4 = (struct sockaddr_in *) &s[1];
399 v4->sin_family = AF_INET;
400#if HAVE_SOCKADDR_IN_SIN_LEN
401 v4->sin_len = sizeof (struct sockaddr_in);
402#endif
403 v4->sin_port = t4->u4_port;
404 v4->sin_addr.s_addr = t4->ipv4_addr;
405 ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) v4, sizeof (struct sockaddr_in));
406 break;
407 case sizeof (struct IPv6UdpAddress):
408 if (NULL == plugin->sockv6)
409 {
410 return NULL;
411 }
412 t6 = addr;
413 s =
414 GNUNET_malloc (sizeof (struct Session) + sizeof (struct sockaddr_in6));
415 len = sizeof (struct sockaddr_in6);
416 v6 = (struct sockaddr_in6 *) &s[1];
417 v6->sin6_family = AF_INET6;
418#if HAVE_SOCKADDR_IN_SIN_LEN
419 v6->sin6_len = sizeof (struct sockaddr_in6);
420#endif
421 v6->sin6_port = t6->u6_port;
422 v6->sin6_addr = t6->ipv6_addr;
423 ats = plugin->env->get_address_type (plugin->env->cls, (const struct sockaddr *) v6, sizeof (struct sockaddr_in6));
424 break;
425 default:
426 /* Must have a valid address to send to */
427 GNUNET_break_op (0);
428 return NULL;
429 }
430
431 s->addrlen = len;
432 s->target = *target;
433 s->sock_addr = (const struct sockaddr *) &s[1];
434
435 return s;
436}
437
438static int session_cmp_it (void *cls,
439 const GNUNET_HashCode * key,
440 void *value)
441{
442 struct SessionCompareContext * cctx = cls;
443 const struct GNUNET_HELLO_Address *address = cctx->addr;
444 struct Session *s = value;
445 struct Session *r = cctx->res;
446 struct IPv4UdpAddress * u4 = NULL;
447 struct IPv6UdpAddress * u6 = NULL;
448 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "AAAAAAAAAAAAAAAAAAa\n");
449 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Looking for existing session for address %s\n", udp_address_to_string (NULL, (void *) address->address, address->address_length));
450
451 if (s->addrlen == address->address_length)
452 {
453 if (address->address_length == sizeof (struct IPv4UdpAddress))
454 {
455 u4 = (struct IPv4UdpAddress * ) address->address;
456 struct sockaddr_in *sai = (struct sockaddr_in *) s->sock_addr;
457 if ((u4->ipv4_addr == sai->sin_addr.s_addr) &&
458 (u4->u4_port == sai->sin_port))
459 {
460 r = s;
461 return GNUNET_NO;
462 }
463 }
464 else if (address->address_length == sizeof (struct IPv6UdpAddress))
465 {
466 u6 = (struct IPv6UdpAddress * ) address->address;
467 struct sockaddr_in6 *sai = (struct sockaddr_in6 *) s->sock_addr;
468
469 if ((0 == memcmp (&u6->ipv6_addr, &sai->sin6_addr, sizeof (struct in6_addr))) &&
470 (u6->u6_port == sai->sin6_port))
471 {
472 r = s;
473 return GNUNET_NO;
474 }
475 }
476 else
477 {
478 GNUNET_break (0);
479 return GNUNET_YES;
480 }
481 }
482 return GNUNET_YES;
483}
484
308 485
309/** 486/**
310 * Creates a new outbound session the transport service will use to send data to the 487 * Creates a new outbound session the transport service will use to send data to the
@@ -314,13 +491,50 @@ udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
314 * @param address the address 491 * @param address the address
315 * @return the session or NULL of max connections exceeded 492 * @return the session or NULL of max connections exceeded
316 */ 493 */
317
318static struct Session * 494static struct Session *
319udp_plugin_get_session (void *cls, 495udp_plugin_get_session (void *cls,
320 const struct GNUNET_HELLO_Address *address) 496 const struct GNUNET_HELLO_Address *address)
321{ 497{
322 struct Session * s = NULL; 498 struct Session * s = NULL;
323 //struct Plugin * plugin = cls; 499 struct Plugin * plugin = cls;
500
501 GNUNET_assert (plugin != NULL);
502 GNUNET_assert (address != NULL);
503
504 if ((address->address == NULL) ||
505 ((address->address_length != sizeof (struct IPv4UdpAddress)) &&
506 (address->address_length != sizeof (struct IPv6UdpAddress))))
507 {
508 GNUNET_break (0);
509 return NULL;
510 }
511
512 /* check if session already exists */
513 if (NULL != NULL)
514 {
515 struct SessionCompareContext cctx;
516 cctx.addr = address;
517 cctx.res = NULL;
518 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Looking for existing session for peer `%s' `%s' \n", GNUNET_i2s (&address->peer), udp_address_to_string(NULL, address->address, address->address_length));
519 GNUNET_CONTAINER_multihashmap_get_multiple(plugin->sessions, &address->peer.hashPubKey, session_cmp_it, &cctx);
520 if (cctx.res != NULL)
521 {
522 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found existing session\n");
523 return cctx.res;
524 }
525 }
526 /* otherwise create new */
527 s = create_session (plugin,
528 &address->peer,
529 address->address,
530 address->address_length,
531 NULL, NULL);
532 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Creating new session %p\n", s);
533 GNUNET_assert (GNUNET_OK ==
534 GNUNET_CONTAINER_multihashmap_put (plugin->sessions,
535 &s->target.hashPubKey,
536 s,
537 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
324 538
325 return s; 539 return s;
326} 540}
@@ -784,6 +998,8 @@ libgnunet_plugin_transport_udp_init (void *cls)
784 GNUNET_BANDWIDTH_tracker_init (&plugin->tracker, 998 GNUNET_BANDWIDTH_tracker_init (&plugin->tracker,
785 GNUNET_BANDWIDTH_value_init ((uint32_t)udp_max_bps), 30); 999 GNUNET_BANDWIDTH_value_init ((uint32_t)udp_max_bps), 30);
786 1000
1001
1002 plugin->sessions = GNUNET_CONTAINER_multihashmap_create (10);
787 plugin->port = port; 1003 plugin->port = port;
788 plugin->aport = aport; 1004 plugin->aport = aport;
789 plugin->last_expected_delay = GNUNET_TIME_UNIT_SECONDS; 1005 plugin->last_expected_delay = GNUNET_TIME_UNIT_SECONDS;
@@ -819,7 +1035,6 @@ libgnunet_plugin_transport_udp_init (void *cls)
819 return api; 1035 return api;
820} 1036}
821 1037
822
823/** 1038/**
824 * The exported method. Makes the core api available via a global and 1039 * The exported method. Makes the core api available via a global and
825 * returns the udp transport API. 1040 * returns the udp transport API.
@@ -848,8 +1063,16 @@ libgnunet_plugin_transport_udp_done (void *cls)
848 } 1063 }
849 GNUNET_NETWORK_fdset_destroy (plugin->rs); 1064 GNUNET_NETWORK_fdset_destroy (plugin->rs);
850 GNUNET_NETWORK_fdset_destroy (plugin->ws); 1065 GNUNET_NETWORK_fdset_destroy (plugin->ws);
851
852 GNUNET_NAT_unregister (plugin->nat); 1066 GNUNET_NAT_unregister (plugin->nat);
1067
1068 /* Clean up sessions */
1069#if DEBUG_UDP
1070 LOG (GNUNET_ERROR_TYPE_DEBUG,
1071 "Cleaning up sessions\n");
1072#endif
1073 GNUNET_CONTAINER_multihashmap_iterate (plugin->sessions, &disconnect_and_free_it, plugin);
1074 GNUNET_CONTAINER_multihashmap_destroy (plugin->sessions);
1075
853 plugin->nat = NULL; 1076 plugin->nat = NULL;
854 GNUNET_free (plugin); 1077 GNUNET_free (plugin);
855 GNUNET_free (api); 1078 GNUNET_free (api);
diff --git a/src/transport/plugin_transport_udp_new.h b/src/transport/plugin_transport_udp_new.h
index c98553062..062849e9d 100644
--- a/src/transport/plugin_transport_udp_new.h
+++ b/src/transport/plugin_transport_udp_new.h
@@ -42,6 +42,7 @@
42#define LOG(kind,...) GNUNET_log_from (kind, "transport-udp", __VA_ARGS__) 42#define LOG(kind,...) GNUNET_log_from (kind, "transport-udp", __VA_ARGS__)
43 43
44#define DEBUG_UDP GNUNET_YES 44#define DEBUG_UDP GNUNET_YES
45#define DEBUG_UDP_BROADCASTING GNUNET_NO
45 46
46/** 47/**
47 * MTU for fragmentation subsystem. Should be conservative since 48 * MTU for fragmentation subsystem. Should be conservative since
@@ -128,12 +129,6 @@ struct Plugin
128 struct GNUNET_CONTAINER_MultiHashMap *sessions; 129 struct GNUNET_CONTAINER_MultiHashMap *sessions;
129 130
130 /** 131 /**
131 * Session of peers with whom we are currently connected,
132 * map of peer identity to 'struct PeerSession'.
133 */
134 struct GNUNET_CONTAINER_MultiHashMap *inbound_sessions;
135
136 /**
137 * Heap with all of our defragmentation activities. 132 * Heap with all of our defragmentation activities.
138 */ 133 */
139 struct GNUNET_CONTAINER_Heap *defrags; 134 struct GNUNET_CONTAINER_Heap *defrags;
diff --git a/src/transport/plugin_transport_udp_new_broadcasting.c b/src/transport/plugin_transport_udp_new_broadcasting.c
index 849cdd15f..3c2d82675 100644
--- a/src/transport/plugin_transport_udp_new_broadcasting.c
+++ b/src/transport/plugin_transport_udp_new_broadcasting.c
@@ -105,12 +105,12 @@ broadcast_ipv6_mst_cb (void *cls, void *client,
105 if (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON != 105 if (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON !=
106 ntohs (msg->header.type)) 106 ntohs (msg->header.type))
107 return; 107 return;
108 108#if DEBUG_UDP_BROADCASTING
109 LOG (GNUNET_ERROR_TYPE_DEBUG, 109 LOG (GNUNET_ERROR_TYPE_DEBUG,
110 "Received beacon with %u bytes from peer `%s' via address `%s'\n", 110 "Received beacon with %u bytes from peer `%s' via address `%s'\n",
111 ntohs (msg->header.size), GNUNET_i2s (&msg->sender), 111 ntohs (msg->header.size), GNUNET_i2s (&msg->sender),
112 udp_address_to_string (NULL, &mc->addr, sizeof (mc->addr))); 112 udp_address_to_string (NULL, &mc->addr, sizeof (mc->addr)));
113 113#endif
114 struct GNUNET_ATS_Information atsi[2]; 114 struct GNUNET_ATS_Information atsi[2];
115 115
116 /* setup ATS */ 116 /* setup ATS */
@@ -146,11 +146,12 @@ broadcast_ipv4_mst_cb (void *cls, void *client,
146 if (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON != 146 if (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON !=
147 ntohs (msg->header.type)) 147 ntohs (msg->header.type))
148 return; 148 return;
149 149#if DEBUG_UDP_BROADCASTING
150 LOG (GNUNET_ERROR_TYPE_DEBUG, 150 LOG (GNUNET_ERROR_TYPE_DEBUG,
151 "Received beacon with %u bytes from peer `%s' via address `%s'\n", 151 "Received beacon with %u bytes from peer `%s' via address `%s'\n",
152 ntohs (msg->header.size), GNUNET_i2s (&msg->sender), 152 ntohs (msg->header.size), GNUNET_i2s (&msg->sender),
153 udp_address_to_string (NULL, &mc->addr, sizeof (mc->addr))); 153 udp_address_to_string (NULL, &mc->addr, sizeof (mc->addr)));
154#endif
154 155
155 struct GNUNET_ATS_Information atsi[2]; 156 struct GNUNET_ATS_Information atsi[2];
156 157
@@ -180,10 +181,11 @@ udp_broadcast_receive (struct Plugin *plugin, const char * buf, ssize_t size, st
180 181
181 if (addrlen == sizeof (struct sockaddr_in)) 182 if (addrlen == sizeof (struct sockaddr_in))
182 { 183 {
184#if DEBUG_UDP_BROADCASTING
183 LOG (GNUNET_ERROR_TYPE_DEBUG, 185 LOG (GNUNET_ERROR_TYPE_DEBUG,
184 "Received IPv4 HELLO beacon broadcast with %i bytes from address %s\n", 186 "Received IPv4 HELLO beacon broadcast with %i bytes from address %s\n",
185 size, GNUNET_a2s ((const struct sockaddr *) addr, addrlen)); 187 size, GNUNET_a2s ((const struct sockaddr *) addr, addrlen));
186 188#endif
187 struct Mstv4Context *mc; 189 struct Mstv4Context *mc;
188 190
189 mc = GNUNET_malloc (sizeof (struct Mstv4Context)); 191 mc = GNUNET_malloc (sizeof (struct Mstv4Context));
@@ -200,10 +202,11 @@ udp_broadcast_receive (struct Plugin *plugin, const char * buf, ssize_t size, st
200 } 202 }
201 else if (addrlen == sizeof (struct sockaddr_in6)) 203 else if (addrlen == sizeof (struct sockaddr_in6))
202 { 204 {
205#if DEBUG_UDP_BROADCASTING
203 LOG (GNUNET_ERROR_TYPE_DEBUG, 206 LOG (GNUNET_ERROR_TYPE_DEBUG,
204 "Received IPv6 HELLO beacon broadcast with %i bytes from address %s\n", 207 "Received IPv6 HELLO beacon broadcast with %i bytes from address %s\n",
205 size, GNUNET_a2s ((const struct sockaddr *) &addr, addrlen)); 208 size, GNUNET_a2s ((const struct sockaddr *) &addr, addrlen));
206 209#endif
207 struct Mstv6Context *mc; 210 struct Mstv6Context *mc;
208 211
209 mc = GNUNET_malloc (sizeof (struct Mstv6Context)); 212 mc = GNUNET_malloc (sizeof (struct Mstv6Context));
@@ -267,9 +270,13 @@ udp_ipv4_broadcast_send (void *cls,
267 if (sent == GNUNET_SYSERR) 270 if (sent == GNUNET_SYSERR)
268 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto"); 271 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto");
269 else 272 else
273 {
274#if DEBUG_UDP_BROADCASTING
270 LOG (GNUNET_ERROR_TYPE_DEBUG, 275 LOG (GNUNET_ERROR_TYPE_DEBUG,
271 "Sent HELLO beacon broadcast with %i bytes to address %s\n", sent, 276 "Sent HELLO beacon broadcast with %i bytes to address %s\n", sent,
272 GNUNET_a2s (baddr->addr, baddr->addrlen)); 277 GNUNET_a2s (baddr->addr, baddr->addrlen));
278#endif
279 }
273 baddr = baddr->next; 280 baddr = baddr->next;
274 } 281 }
275 282
@@ -316,12 +323,15 @@ udp_ipv6_broadcast_send (void *cls,
316 if (sent == GNUNET_SYSERR) 323 if (sent == GNUNET_SYSERR)
317 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto"); 324 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto");
318 else 325 else
326 {
327#if DEBUG_UDP_BROADCASTING
319 LOG (GNUNET_ERROR_TYPE_DEBUG, 328 LOG (GNUNET_ERROR_TYPE_DEBUG,
320 "Sending IPv6 HELLO beacon broadcast with %i bytes to address %s\n", 329 "Sending IPv6 HELLO beacon broadcast with %i bytes to address %s\n",
321 sent, 330 sent,
322 GNUNET_a2s ((const struct sockaddr *) &plugin->ipv6_multicast_address, 331 GNUNET_a2s ((const struct sockaddr *) &plugin->ipv6_multicast_address,
323 sizeof (struct sockaddr_in6))); 332 sizeof (struct sockaddr_in6)));
324 333#endif
334 }
325 335
326 336
327 plugin->send_ipv6_broadcast_task = 337 plugin->send_ipv6_broadcast_task =
@@ -339,6 +349,7 @@ iface_proc (void *cls, const char *name, int isDefault,
339 349
340 if (addr != NULL) 350 if (addr != NULL)
341 { 351 {
352#if DEBUG_UDP_BROADCASTING
342 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "address %s for interface %s %p\n ", 353 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "address %s for interface %s %p\n ",
343 GNUNET_a2s (addr, addrlen), name, addr); 354 GNUNET_a2s (addr, addrlen), name, addr);
344 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 355 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -346,7 +357,7 @@ iface_proc (void *cls, const char *name, int isDefault,
346 GNUNET_a2s (broadcast_addr, addrlen), name, broadcast_addr); 357 GNUNET_a2s (broadcast_addr, addrlen), name, broadcast_addr);
347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "netmask %s for interface %s %p\n ", 358 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "netmask %s for interface %s %p\n ",
348 GNUNET_a2s (netmask, addrlen), name, netmask); 359 GNUNET_a2s (netmask, addrlen), name, netmask);
349 360#endif
350 361
351 /* Collecting broadcast addresses */ 362 /* Collecting broadcast addresses */
352 if (broadcast_addr != NULL) 363 if (broadcast_addr != NULL)