aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2013-06-28 14:34:55 +0000
committerBart Polot <bart@net.in.tum.de>2013-06-28 14:34:55 +0000
commitcf19b5082fe8de33e38957f54d28647635b46b60 (patch)
treee6e41da7d5cb14d9a342ef6533633ecb2f34b18d /src
parent166d8f9122bf7ebbaa2a662d09a3fa4d34f6d092 (diff)
Replace mesh with new version
Diffstat (limited to 'src')
-rw-r--r--src/exit/gnunet-daemon-exit.c115
-rw-r--r--src/fs/gnunet-service-fs_mesh.c2
-rw-r--r--src/include/block_mesh.h4
-rw-r--r--src/include/gnunet_mesh2_service.h398
-rw-r--r--src/include/gnunet_mesh_service.h327
-rw-r--r--src/include/gnunet_stream_lib.h4
-rw-r--r--src/mesh/Makefile.am279
-rw-r--r--src/mesh/gnunet-mesh.c28
-rw-r--r--src/mesh/gnunet-service-mesh-new.c5205
-rw-r--r--src/mesh/gnunet-service-mesh.c5695
-rw-r--r--src/mesh/mesh.h185
-rw-r--r--src/mesh/mesh2.h349
-rw-r--r--src/mesh/mesh2_api.c1787
-rw-r--r--src/mesh/mesh2_protocol.h316
-rw-r--r--src/mesh/mesh2_test_lib.c283
-rw-r--r--src/mesh/mesh2_test_lib.h106
-rw-r--r--src/mesh/mesh_api.c1188
-rw-r--r--src/mesh/mesh_path.c2
-rw-r--r--src/mesh/mesh_path.h2
-rw-r--r--src/mesh/mesh_protocol.h116
-rw-r--r--src/mesh/mesh_test_lib.c30
-rw-r--r--src/mesh/mesh_test_lib.h4
-rw-r--r--src/mesh/plugin_block_mesh.c5
-rw-r--r--src/mesh/test_mesh.conf33
-rw-r--r--src/mesh/test_mesh2.conf89
-rw-r--r--src/mesh/test_mesh2_small.c833
-rw-r--r--src/mesh/test_mesh_2dtorus.c128
-rw-r--r--src/mesh/test_mesh_2dtorus.conf71
-rw-r--r--src/mesh/test_mesh_api.c138
-rw-r--r--src/mesh/test_mesh_local.c (renamed from src/mesh/test_mesh2_local.c)8
-rw-r--r--src/mesh/test_mesh_local_1.c294
-rw-r--r--src/mesh/test_mesh_local_2.c290
-rw-r--r--src/mesh/test_mesh_local_traffic.c526
-rw-r--r--src/mesh/test_mesh_small.c336
-rw-r--r--src/mesh/test_mesh_small.conf78
-rw-r--r--src/mesh/test_mesh_tree_api.c409
-rw-r--r--src/pt/gnunet-daemon-pt.c41
-rw-r--r--src/set/Makefile.am2
-rw-r--r--src/set/gnunet-service-set.h2
-rw-r--r--src/stream/stream_api.c276
-rw-r--r--src/vpn/gnunet-service-vpn.c81
41 files changed, 2005 insertions, 18060 deletions
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c
index 4e94ea5968..f26ddf7347 100644
--- a/src/exit/gnunet-daemon-exit.c
+++ b/src/exit/gnunet-daemon-exit.c
@@ -209,6 +209,12 @@ struct TunnelState
struct GNUNET_MESH_Tunnel *tunnel;
/**
+ * Who is the other end of this tunnel.
+ * FIXME is this needed? Only used for debugging messages
+ */
+ struct GNUNET_PeerIdentity peer;
+
+ /**
* Active tunnel transmission request (or NULL).
*/
struct GNUNET_MESH_TransmitHandle *th;
@@ -493,7 +499,6 @@ process_dns_result (void *cls,
ts->th = GNUNET_MESH_notify_transmit_ready (ts->tunnel,
GNUNET_NO,
GNUNET_TIME_UNIT_FOREVER_REL,
- NULL,
sizeof (struct GNUNET_MessageHeader) + r,
&transmit_reply_to_mesh,
ts);
@@ -506,18 +511,15 @@ process_dns_result (void *cls,
* @param cls closure, NULL
* @param tunnel connection to the other end
* @param tunnel_ctx pointer to our 'struct TunnelState *'
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
+ *
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
receive_dns_request (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
+ const struct GNUNET_MessageHeader *message)
{
struct TunnelState *ts = *tunnel_ctx;
const struct GNUNET_TUN_DnsHeader *dns;
@@ -782,7 +784,6 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf)
s->th = GNUNET_MESH_notify_transmit_ready (tunnel,
GNUNET_NO /* corking */,
GNUNET_TIME_UNIT_FOREVER_REL,
- NULL,
tnq->len,
&send_to_peer_notify_callback,
s);
@@ -799,7 +800,6 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf)
s->th = GNUNET_MESH_notify_transmit_ready (tunnel,
GNUNET_NO /* corking */,
GNUNET_TIME_UNIT_FOREVER_REL,
- NULL,
tnq->len,
&send_to_peer_notify_callback,
s);
@@ -817,19 +817,19 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf)
* @param tnq message to queue
*/
static void
-send_packet_to_mesh_tunnel (struct GNUNET_MESH_Tunnel *mesh_tunnel,
+send_packet_to_mesh_tunnel (struct TunnelState *s,
struct TunnelMessageQueue *tnq)
{
- struct TunnelState *s;
+ struct GNUNET_MESH_Tunnel *mesh_tunnel;
- s = GNUNET_MESH_tunnel_get_data (mesh_tunnel);
+ mesh_tunnel = s->tunnel;
GNUNET_assert (NULL != s);
GNUNET_CONTAINER_DLL_insert_tail (s->specifics.tcp_udp.head, s->specifics.tcp_udp.tail, tnq);
if (NULL == s->th)
s->th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel,
GNUNET_NO /* cork */,
GNUNET_TIME_UNIT_FOREVER_REL,
- NULL, tnq->len,
+ tnq->len,
&send_to_peer_notify_callback,
s);
}
@@ -1019,8 +1019,7 @@ icmp_from_helper (const struct GNUNET_TUN_IcmpHeader *icmp,
memcpy (&i2v->icmp_header,
icmp,
pktlen);
- send_packet_to_mesh_tunnel (state->tunnel,
- tnq);
+ send_packet_to_mesh_tunnel (state, tnq);
}
@@ -1097,8 +1096,7 @@ udp_from_helper (const struct GNUNET_TUN_UdpHeader *udp,
memcpy (&urm[1],
&udp[1],
pktlen - sizeof (struct GNUNET_TUN_UdpHeader));
- send_packet_to_mesh_tunnel (state->tunnel,
- tnq);
+ send_packet_to_mesh_tunnel (state, tnq);
}
@@ -1186,8 +1184,7 @@ tcp_from_helper (const struct GNUNET_TUN_TcpHeader *tcp,
memcpy (&tdm->tcp_header,
buf,
pktlen);
- send_packet_to_mesh_tunnel (state->tunnel,
- tnq);
+ send_packet_to_mesh_tunnel (state, tnq);
}
@@ -1796,18 +1793,15 @@ send_tcp_packet_via_tun (const struct SocketAddress *destination_address,
* @param cls closure, NULL
* @param tunnel connection to the other end
* @param tunnel_ctx pointer to our 'struct TunnelState *'
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
+ *
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
receive_tcp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx GNUNET_UNUSED,
- const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
+ const struct GNUNET_MessageHeader *message)
{
struct TunnelState *state = *tunnel_ctx;
const struct GNUNET_EXIT_TcpServiceStartMessage *start;
@@ -1853,7 +1847,7 @@ receive_tcp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
/* setup fresh connection */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received data from %s for forwarding to TCP service %s on port %u\n",
- GNUNET_i2s (sender),
+ GNUNET_i2s (&state->peer),
GNUNET_h2s (&start->service_descriptor),
(unsigned int) ntohs (start->tcp_header.destination_port));
if (NULL == (state->specifics.tcp_udp.serv = find_service (tcp_services, &start->service_descriptor,
@@ -1884,18 +1878,15 @@ receive_tcp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
* @param cls closure, NULL
* @param tunnel connection to the other end
* @param tunnel_ctx pointer to our 'struct TunnelState *'
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
+ *
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx GNUNET_UNUSED,
- const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
+ const struct GNUNET_MessageHeader *message)
{
struct TunnelState *state = *tunnel_ctx;
const struct GNUNET_EXIT_TcpInternetStartMessage *start;
@@ -1984,7 +1975,7 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
char buf[INET6_ADDRSTRLEN];
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received data from %s for starting TCP stream to %s:%u\n",
- GNUNET_i2s (sender),
+ GNUNET_i2s (&state->peer),
inet_ntop (af,
&state->specifics.tcp_udp.ri.remote_address.address,
buf, sizeof (buf)),
@@ -2008,18 +1999,15 @@ receive_tcp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
* @param cls closure, NULL
* @param tunnel connection to the other end
* @param tunnel_ctx pointer to our 'struct TunnelState *'
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
+ *
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
receive_tcp_data (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx GNUNET_UNUSED,
- const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
+ const struct GNUNET_MessageHeader *message)
{
struct TunnelState *state = *tunnel_ctx;
const struct GNUNET_EXIT_TcpDataMessage *data;
@@ -2069,7 +2057,7 @@ receive_tcp_data (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received additional %u bytes of data from %s for TCP stream to %s:%u\n",
pkt_len,
- GNUNET_i2s (sender),
+ GNUNET_i2s (&state->peer),
inet_ntop (state->specifics.tcp_udp.ri.remote_address.af,
&state->specifics.tcp_udp.ri.remote_address.address,
buf, sizeof (buf)),
@@ -2244,18 +2232,15 @@ make_up_icmpv6_payload (struct TunnelState *state,
* @param cls closure, NULL
* @param tunnel connection to the other end
* @param tunnel_ctx pointer to our 'struct TunnelState *'
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
+ *
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx GNUNET_UNUSED,
- const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
+ const struct GNUNET_MessageHeader *message)
{
struct TunnelState *state = *tunnel_ctx;
const struct GNUNET_EXIT_IcmpInternetMessage *msg;
@@ -2428,7 +2413,7 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
char buf[INET6_ADDRSTRLEN];
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received ICMP data from %s for forwarding to %s\n",
- GNUNET_i2s (sender),
+ GNUNET_i2s (&state->peer),
inet_ntop (af,
&state->specifics.tcp_udp.ri.remote_address.address,
buf, sizeof (buf)));
@@ -2498,18 +2483,15 @@ make_up_icmp_service_payload (struct TunnelState *state,
* @param cls closure, NULL
* @param tunnel connection to the other end
* @param tunnel_ctx pointer to our 'struct TunnelState *'
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
+ *
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
+ const struct GNUNET_MessageHeader *message)
{
struct TunnelState *state = *tunnel_ctx;
const struct GNUNET_EXIT_IcmpServiceMessage *msg;
@@ -2544,7 +2526,7 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel
pkt_len -= sizeof (struct GNUNET_EXIT_IcmpServiceMessage);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received data from %s for forwarding to ICMP service %s\n",
- GNUNET_i2s (sender),
+ GNUNET_i2s (&state->peer),
GNUNET_h2s (&msg->service_descriptor));
if (NULL == state->specifics.tcp_udp.serv)
{
@@ -2789,18 +2771,15 @@ send_udp_packet_via_tun (const struct SocketAddress *destination_address,
* @param cls closure, NULL
* @param tunnel connection to the other end
* @param tunnel_ctx pointer to our 'struct TunnelState *'
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
+ *
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx GNUNET_UNUSED,
- const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
+ const struct GNUNET_MessageHeader *message)
{
struct TunnelState *state = *tunnel_ctx;
const struct GNUNET_EXIT_UdpInternetMessage *msg;
@@ -2877,7 +2856,7 @@ receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
char buf[INET6_ADDRSTRLEN];
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received data from %s for forwarding to UDP %s:%u\n",
- GNUNET_i2s (sender),
+ GNUNET_i2s (&state->peer),
inet_ntop (af,
&state->specifics.tcp_udp.ri.remote_address.address,
buf, sizeof (buf)),
@@ -2903,18 +2882,15 @@ receive_udp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
* @param cls closure, NULL
* @param tunnel connection to the other end
* @param tunnel_ctx pointer to our 'struct TunnelState *'
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
+ *
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
+ const struct GNUNET_MessageHeader *message)
{
struct TunnelState *state = *tunnel_ctx;
const struct GNUNET_EXIT_UdpServiceMessage *msg;
@@ -2946,7 +2922,7 @@ receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
pkt_len -= sizeof (struct GNUNET_EXIT_UdpServiceMessage);
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Received data from %s for forwarding to UDP service %s on port %u\n",
- GNUNET_i2s (sender),
+ GNUNET_i2s (&state->peer),
GNUNET_h2s (&msg->service_descriptor),
(unsigned int) ntohs (msg->destination_port));
if (NULL == (state->specifics.tcp_udp.serv = find_service (udp_services, &msg->service_descriptor,
@@ -2978,17 +2954,17 @@ receive_udp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
* @param cls closure
* @param tunnel new handle to the tunnel
* @param initiator peer that started the tunnel
- * @param atsi performance information for the tunnel
+ * @param port destination port
* @return initial tunnel context for the tunnel
*/
static void *
new_tunnel (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *initiator GNUNET_UNUSED,
- const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
+ const struct GNUNET_PeerIdentity *initiator, uint32_t port)
{
struct TunnelState *s = GNUNET_malloc (sizeof (struct TunnelState));
s->is_dns = GNUNET_SYSERR;
+ s->peer = *initiator;
GNUNET_STATISTICS_update (stats,
gettext_noop ("# Inbound MESH tunnels created"),
1, GNUNET_NO);
@@ -3338,7 +3314,7 @@ run (void *cls, char *const *args GNUNET_UNUSED,
{NULL, 0, 0}
};
- static GNUNET_MESH_ApplicationType apptypes[] = {
+ static uint32_t apptypes[] = {
GNUNET_APPLICATION_TYPE_END,
GNUNET_APPLICATION_TYPE_END,
GNUNET_APPLICATION_TYPE_END,
@@ -3413,7 +3389,7 @@ run (void *cls, char *const *args GNUNET_UNUSED,
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
_("No useful service enabled. Exiting.\n"));
GNUNET_SCHEDULER_shutdown ();
- return;
+ return;
}
dns_exit = NULL;
@@ -3436,18 +3412,21 @@ run (void *cls, char *const *args GNUNET_UNUSED,
app_idx = 0;
- if (GNUNET_YES == ipv4_exit)
+ if (GNUNET_YES == ipv4_exit)
{
+ // FIXME use regex to put info
apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV4_GATEWAY;
app_idx++;
}
- if (GNUNET_YES == ipv6_exit)
+ if (GNUNET_YES == ipv6_exit)
{
+ // FIXME use regex to put info
apptypes[app_idx] = GNUNET_APPLICATION_TYPE_IPV6_GATEWAY;
app_idx++;
}
if (NULL != dns_exit)
{
+ // FIXME use regex to put info
apptypes[app_idx] = GNUNET_APPLICATION_TYPE_INTERNET_RESOLVER;
app_idx++;
}
@@ -3568,7 +3547,7 @@ run (void *cls, char *const *args GNUNET_UNUSED,
= GNUNET_MESH_connect (cfg, NULL,
&new_tunnel,
&clean_tunnel, handlers,
- apptypes);
+ apptypes); // FIXME use ports
if (NULL == mesh_handle)
{
GNUNET_SCHEDULER_shutdown ();
diff --git a/src/fs/gnunet-service-fs_mesh.c b/src/fs/gnunet-service-fs_mesh.c
index 10b29fa844..9eda536a9f 100644
--- a/src/fs/gnunet-service-fs_mesh.c
+++ b/src/fs/gnunet-service-fs_mesh.c
@@ -41,7 +41,7 @@
#include "platform.h"
#include "gnunet_constants.h"
#include "gnunet_util_lib.h"
-#include "gnunet_mesh2_service.h"
+#include "gnunet_mesh_service.h"
#include "gnunet_protocols.h"
#include "gnunet_applications.h"
#include "gnunet-service-fs.h"
diff --git a/src/include/block_mesh.h b/src/include/block_mesh.h
index 9dfb859454..508f52699b 100644
--- a/src/include/block_mesh.h
+++ b/src/include/block_mesh.h
@@ -48,10 +48,6 @@ struct PBlock
*/
struct GNUNET_PeerIdentity id;
- /**
- * Type of service offered
- */
- GNUNET_MESH_ApplicationType type;
};
#if 0 /* keep Emacsens' auto-indent happy */
diff --git a/src/include/gnunet_mesh2_service.h b/src/include/gnunet_mesh2_service.h
deleted file mode 100644
index 019dc8431f..0000000000
--- a/src/include/gnunet_mesh2_service.h
+++ /dev/null
@@ -1,398 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 2009, 2010, 2011, 2012, 2013 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file include/gnunet_mesh2_service.h
- * @brief mesh service; establish tunnels to distant peers
- * @author Christian Grothoff
- *
- * TODO:
- * - need to do sanity check that this is consistent
- * with current ideas for the multicast layer's needs
- */
-
-#ifndef GNUNET_MESH_SERVICE_H
-#define GNUNET_MESH_SERVICE_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0 /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-#include "gnunet_util_lib.h"
-#include "gnunet_transport_service.h"
-
-/**
- * Version number of GNUnet-mesh API.
- */
-#define GNUNET_MESH_VERSION 0x00000001
-
-
-/**
- * Opaque handle to the service.
- */
-struct GNUNET_MESH_Handle;
-
-/**
- * Opaque handle to a tunnel.
- */
-struct GNUNET_MESH_Tunnel;
-
-
-/**
- * Functions with this signature are called whenever a message is
- * received.
- *
- * Each time the function must call GNUNET_MESH_receive_done on the tunnel
- * in order to receive the next message. This doesn't need to be immediate:
- * can be delayed if some processing is done on the message.
- *
- * @param cls Closure (set from GNUNET_MESH_connect).
- * @param tunnel Connection to the other end.
- * @param tunnel_ctx Place to store local state associated with the tunnel.
- * @param message The actual message.
- *
- * @return GNUNET_OK to keep the tunnel open,
- * GNUNET_SYSERR to close it (signal serious error).
- */
-typedef int (*GNUNET_MESH_MessageCallback) (void *cls,
- struct GNUNET_MESH_Tunnel *tunnel,
- void **tunnel_ctx,
- const struct GNUNET_MessageHeader *message);
-
-
-/**
- * Message handler. Each struct specifies how to handle on particular
- * type of message received.
- */
-struct GNUNET_MESH_MessageHandler
-{
- /**
- * Function to call for messages of "type".
- */
- GNUNET_MESH_MessageCallback callback;
-
- /**
- * Type of the message this handler covers.
- */
- uint16_t type;
-
- /**
- * Expected size of messages of this type. Use 0 for variable-size.
- * If non-zero, messages of the given type will be discarded if they
- * do not have the right size.
- */
- uint16_t expected_size;
-};
-
-
-/**
- * Method called whenever another peer has added us to a tunnel
- * the other peer initiated.
- * Only called (once) upon reception of data with a message type which was
- * subscribed to in GNUNET_MESH_connect. A call to GNUNET_MESH_tunnel_destroy
- * causes te tunnel to be ignored and no further notifications are sent about
- * the same tunnel.
- *
- * @param cls closure
- * @param tunnel new handle to the tunnel
- * @param initiator peer that started the tunnel
- * @param port Port this tunnel is for.
- * @return initial tunnel context for the tunnel
- * (can be NULL -- that's not an error)
- */
-typedef void *(GNUNET_MESH_InboundTunnelNotificationHandler) (void *cls,
- struct
- GNUNET_MESH_Tunnel
- * tunnel,
- const struct
- GNUNET_PeerIdentity
- * initiator,
- uint32_t port);
-
-
-/**
- * Function called whenever a tunnel is destroyed. Should clean up
- * any associated state.
- *
- * It must NOT call GNUNET_MESH_tunnel_destroy on the tunnel.
- *
- * @param cls closure (set from GNUNET_MESH_connect)
- * @param tunnel connection to the other end (henceforth invalid)
- * @param tunnel_ctx place where local state associated
- * with the tunnel is stored
- */
-typedef void (GNUNET_MESH_TunnelEndHandler) (void *cls,
- const struct GNUNET_MESH_Tunnel *
- tunnel, void *tunnel_ctx);
-
-
-/**
- * Connect to the mesh service.
- *
- * @param cfg Configuration to use.
- * @param cls Closure for the various callbacks that follow (including
- * handlers in the handlers array).
- * @param new_tunnel Function called when an *inbound* tunnel is created.
- * Can be NULL if no inbound tunnels are desired.
- * @param cleaner Function called when a tunnel is destroyed by the remote peer.
- * It is NOT called if GNUNET_MESH_tunnel_destroy is called on
- * the tunnel.
- * @param handlers Callbacks for messages we care about, NULL-terminated. Each
- * one must call GNUNET_MESH_receive_done on the tunnel to
- * receive the next message. Messages of a type that is not
- * in the handlers array are ignored if received.
- * @param ports NULL or 0-terminated array of port numbers for incoming tunnels.
- *
- * @return handle to the mesh service NULL on error
- * (in this case, init is never called)
- */
-struct GNUNET_MESH_Handle *
-GNUNET_MESH_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls,
- GNUNET_MESH_InboundTunnelNotificationHandler new_tunnel,
- GNUNET_MESH_TunnelEndHandler cleaner,
- const struct GNUNET_MESH_MessageHandler *handlers,
- const uint32_t *ports);
-
-
-/**
- * Disconnect from the mesh service. All tunnels will be destroyed. All tunnel
- * disconnect callbacks will be called on any still connected peers, notifying
- * about their disconnection. The registered inbound tunnel cleaner will be
- * called should any inbound tunnels still exist.
- *
- * @param handle connection to mesh to disconnect
- */
-void
-GNUNET_MESH_disconnect (struct GNUNET_MESH_Handle *handle);
-
-
-/**
- * Create a new tunnel (we're initiator and will be allowed to add/remove peers
- * and to broadcast).
- *
- * @param h mesh handle
- * @param tunnel_ctx client's tunnel context to associate with the tunnel
- * @param peer peer identity the tunnel should go to
- * @param port Port number.
- * @return handle to the tunnel
- */
-struct GNUNET_MESH_Tunnel *
-GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h,
- void *tunnel_ctx,
- const struct GNUNET_PeerIdentity *peer,
- uint32_t port);
-
-
-/**
- * Destroy an existing tunnel.
- *
- * The existing end callback for the tunnel will be called immediately.
- * Any pending outgoing messages will be sent but no incoming messages will be
- * accepted and no data callbacks will be called.
- *
- * @param tunnel Tunnel handle, becomes invalid after this call.
- */
-void
-GNUNET_MESH_tunnel_destroy (struct GNUNET_MESH_Tunnel *tunnel);
-
-
-/**
- * Turn on/off the buffering status of the tunnel.
- *
- * @param tunnel Tunnel affected.
- * @param buffer GNUNET_YES to turn buffering on (default),
- * GNUNET_NO otherwise.
- */
-void
-GNUNET_MESH_tunnel_buffer (struct GNUNET_MESH_Tunnel *tunnel, int buffer);
-
-
-/**
- * Handle for a transmission request.
- */
-struct GNUNET_MESH_TransmitHandle;
-
-
-/**
- * Ask the mesh to call "notify" once it is ready to transmit the
- * given number of bytes to the specified tunnel.
- * Only one call can be active at any time, to issue another request,
- * wait for the callback or cancel the current request.
- *
- * @param tunnel tunnel to use for transmission
- * @param cork is corking allowed for this transmission?
- * @param maxdelay how long can the message wait?
- * @param notify_size how many bytes of buffer space does notify want?
- * @param notify function to call when buffer space is available;
- * will be called with NULL on timeout or if the overall queue
- * for this peer is larger than queue_size and this is currently
- * the message with the lowest priority
- * @param notify_cls closure for notify
- * @return non-NULL if the notify callback was queued,
- * NULL if we can not even queue the request (insufficient
- * memory); if NULL is returned, "notify" will NOT be called.
- */
-struct GNUNET_MESH_TransmitHandle *
-GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork,
- struct GNUNET_TIME_Relative maxdelay,
- size_t notify_size,
- GNUNET_CONNECTION_TransmitReadyNotify notify,
- void *notify_cls);
-
-
-/**
- * Cancel the specified transmission-ready notification.
- *
- * @param th handle that was returned by "notify_transmit_ready".
- */
-void
-GNUNET_MESH_notify_transmit_ready_cancel (struct GNUNET_MESH_TransmitHandle
- *th);
-
-
-/**
- * Indicate readiness to receive the next message on a tunnel.
- *
- * Should only be called once per handler called.
- *
- * @param tunnel Tunnel that will be allowed to call another handler.
- */
-void
-GNUNET_MESH_receive_done (struct GNUNET_MESH_Tunnel *tunnel);
-
-
-
-/******************************************************************************/
-/******************** MONITORING /DEBUG API *************************/
-/******************************************************************************/
-/* The following calls are not useful for normal MESH operation, but for */
-/* debug and monitoring of the mesh state. They can be safely ignored. */
-/* The API can change at any point without notice. */
-/* Please contact the developer if you consider any of this calls useful for */
-/* normal mesh applications. */
-/******************************************************************************/
-
-/**
- * Method called to retrieve information about each tunnel the mesh peer
- * is aware of.
- *
- * @param cls Closure.
- * @param tunnel_number Tunnel number.
- * @param origin that started the tunnel (owner).
- * @param target other endpoint of the tunnel
- */
-typedef void (*GNUNET_MESH_TunnelsCB) (void *cls,
- uint32_t tunnel_number,
- const struct GNUNET_PeerIdentity *origin,
- const struct GNUNET_PeerIdentity *target);
-
-
-/**
- * Method called to retrieve information about a specific tunnel the mesh peer
- * is aware of, including all transit nodes.
- *
- * @param cls Closure.
- * @param peer Peer in the tunnel's tree.
- * @param parent Parent of the current peer. All 0 when peer is root.
- */
-typedef void (*GNUNET_MESH_TunnelCB) (void *cls,
- const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_PeerIdentity *parent);
-
-
-/**
- * Request information about the running mesh peer.
- * The callback will be called for every tunnel known to the service,
- * listing all active peers that belong to the tunnel.
- *
- * If called again on the same handle, it will overwrite the previous
- * callback and cls. To retrieve the cls, monitor_cancel must be
- * called first.
- *
- * WARNING: unstable API, likely to change in the future!
- *
- * @param h Handle to the mesh peer.
- * @param callback Function to call with the requested data.
- * @param callback_cls Closure for @c callback.
- */
-void
-GNUNET_MESH_get_tunnels (struct GNUNET_MESH_Handle *h,
- GNUNET_MESH_TunnelsCB callback,
- void *callback_cls);
-
-
-/**
- * Request information about a specific tunnel of the running mesh peer.
- *
- * WARNING: unstable API, likely to change in the future!
- *
- * @param h Handle to the mesh peer.
- * @param initiator ID of the owner of the tunnel.
- * @param tunnel_number Tunnel number.
- * @param callback Function to call with the requested data.
- * @param callback_cls Closure for @c callback.
- */
-void
-GNUNET_MESH_show_tunnel (struct GNUNET_MESH_Handle *h,
- struct GNUNET_PeerIdentity *initiator,
- uint32_t tunnel_number,
- GNUNET_MESH_TunnelCB callback,
- void *callback_cls);
-
-
-/**
- * Cancel a monitor request. The monitor callback will not be called.
- *
- * WARNING: unstable API, likely to change in the future!
- *
- * @param h Mesh handle.
- *
- * @return Closure given to GNUNET_MESH_monitor, if any.
- */
-void *
-GNUNET_MESH_get_tunnels_cancel (struct GNUNET_MESH_Handle *h);
-
-
-/**
- * Create a message queue for a mesh tunnel.
- * The message queue can only be used to transmit messages,
- * not to receive them.
- *
- * @param tunnel the tunnel to create the message qeue for
- * @return a message queue to messages over the tunnel
- */
-struct GNUNET_MQ_Handle *
-GNUNET_MESH_mq_create (struct GNUNET_MESH_Tunnel *tunnel);
-
-
-#if 0 /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-/* ifndef GNUNET_MESH_SERVICE_H */
-#endif
-/* end of gnunet_mesh_service.h */
diff --git a/src/include/gnunet_mesh_service.h b/src/include/gnunet_mesh_service.h
index 3005c1239d..c64cfb64cf 100644
--- a/src/include/gnunet_mesh_service.h
+++ b/src/include/gnunet_mesh_service.h
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2009, 2010 Christian Grothoff (and other contributing authors)
+ (C) 2009, 2010, 2011, 2012, 2013 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -22,6 +22,10 @@
* @file include/gnunet_mesh_service.h
* @brief mesh service; establish tunnels to distant peers
* @author Christian Grothoff
+ *
+ * TODO:
+ * - need to do sanity check that this is consistent
+ * with current ideas for the multicast layer's needs
*/
#ifndef GNUNET_MESH_SERVICE_H
@@ -41,7 +45,7 @@ extern "C"
/**
* Version number of GNUnet-mesh API.
*/
-#define GNUNET_MESH_VERSION 0x00000000
+#define GNUNET_MESH_VERSION 0x00000001
/**
@@ -54,28 +58,27 @@ struct GNUNET_MESH_Handle;
*/
struct GNUNET_MESH_Tunnel;
+
/**
* Functions with this signature are called whenever a message is
* received.
+ *
+ * Each time the function must call GNUNET_MESH_receive_done on the tunnel
+ * in order to receive the next message. This doesn't need to be immediate:
+ * can be delayed if some processing is done on the message.
*
- * @param cls closure (set from GNUNET_MESH_connect)
- * @param tunnel connection to the other end
- * @param tunnel_ctx place to store local state associated with the tunnel
- * @param sender who sent the message
- * @param message the actual message
- * @param atsi performance data for the connection
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
+ * @param cls Closure (set from GNUNET_MESH_connect).
+ * @param tunnel Connection to the other end.
+ * @param tunnel_ctx Place to store local state associated with the tunnel.
+ * @param message The actual message.
+ *
+ * @return GNUNET_OK to keep the tunnel open,
+ * GNUNET_SYSERR to close it (signal serious error).
*/
typedef int (*GNUNET_MESH_MessageCallback) (void *cls,
- struct GNUNET_MESH_Tunnel * tunnel,
+ struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *
- sender,
- const struct GNUNET_MessageHeader *
- message,
- const struct GNUNET_ATS_Information
- * atsi);
+ const struct GNUNET_MessageHeader *message);
/**
@@ -100,7 +103,6 @@ struct GNUNET_MESH_MessageHandler
* do not have the right size.
*/
uint16_t expected_size;
-
};
@@ -115,7 +117,7 @@ struct GNUNET_MESH_MessageHandler
* @param cls closure
* @param tunnel new handle to the tunnel
* @param initiator peer that started the tunnel
- * @param atsi performance information for the tunnel
+ * @param port Port this tunnel is for.
* @return initial tunnel context for the tunnel
* (can be NULL -- that's not an error)
*/
@@ -126,17 +128,14 @@ typedef void *(GNUNET_MESH_InboundTunnelNotificationHandler) (void *cls,
const struct
GNUNET_PeerIdentity
* initiator,
- const struct
- GNUNET_ATS_Information
- * atsi);
+ uint32_t port);
/**
- * Function called whenever an inbound tunnel is destroyed. Should clean up
- * any associated state. This function is NOT called if the client has
- * explicitly asked for the tunnel to be destroyed using
- * GNUNET_MESH_tunnel_destroy. It must NOT call GNUNET_MESH_tunnel_destroy on
- * the tunnel.
+ * Function called whenever a tunnel is destroyed. Should clean up
+ * any associated state.
+ *
+ * It must NOT call GNUNET_MESH_tunnel_destroy on the tunnel.
*
* @param cls closure (set from GNUNET_MESH_connect)
* @param tunnel connection to the other end (henceforth invalid)
@@ -149,27 +148,22 @@ typedef void (GNUNET_MESH_TunnelEndHandler) (void *cls,
/**
- * Type for an application. Values defined in gnunet_applications.h
- * DEPRECATED - not present in mesh2
- */
-typedef uint32_t GNUNET_MESH_ApplicationType;
-
-
-/**
* Connect to the mesh service.
*
- * @param cfg configuration to use
- * @param cls closure for the various callbacks that follow
- * (including handlers in the handlers array)
- * @param new_tunnel function called when an *inbound* tunnel is created
- * @param cleaner function called when an *inbound* tunnel is destroyed by the
- * remote peer, it is *not* called if GNUNET_MESH_tunnel_destroy
- * is called on the tunnel
- * @param handlers callbacks for messages we care about, NULL-terminated
- * note that the mesh is allowed to drop notifications about
- * inbound messages if the client does not process them fast
- * enough (for this notification type, a bounded queue is used)
- * @param stypes list of the applications that this client claims to provide
+ * @param cfg Configuration to use.
+ * @param cls Closure for the various callbacks that follow (including
+ * handlers in the handlers array).
+ * @param new_tunnel Function called when an *inbound* tunnel is created.
+ * Can be NULL if no inbound tunnels are desired.
+ * @param cleaner Function called when a tunnel is destroyed by the remote peer.
+ * It is NOT called if GNUNET_MESH_tunnel_destroy is called on
+ * the tunnel.
+ * @param handlers Callbacks for messages we care about, NULL-terminated. Each
+ * one must call GNUNET_MESH_receive_done on the tunnel to
+ * receive the next message. Messages of a type that is not
+ * in the handlers array are ignored if received.
+ * @param ports NULL or 0-terminated array of port numbers for incoming tunnels.
+ *
* @return handle to the mesh service NULL on error
* (in this case, init is never called)
*/
@@ -178,7 +172,7 @@ GNUNET_MESH_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls,
GNUNET_MESH_InboundTunnelNotificationHandler new_tunnel,
GNUNET_MESH_TunnelEndHandler cleaner,
const struct GNUNET_MESH_MessageHandler *handlers,
- const GNUNET_MESH_ApplicationType *stypes);
+ const uint32_t *ports);
/**
@@ -194,104 +188,33 @@ GNUNET_MESH_disconnect (struct GNUNET_MESH_Handle *handle);
/**
- * Method called whenever a peer has disconnected from the tunnel.
- * Implementations of this callback must NOT call
- * GNUNET_MESH_tunnel_destroy immediately, but instead schedule those
- * to run in some other task later. However, calling
- * "GNUNET_MESH_notify_transmit_ready_cancel" is allowed.
- *
- * @param cls closure
- * @param peer peer identity the tunnel stopped working with
- */
-typedef void (*GNUNET_MESH_PeerDisconnectHandler) (void *cls,
- const struct
- GNUNET_PeerIdentity * peer);
-
-
-/**
- * Method called whenever a peer has connected to the tunnel.
- *
- * @param cls closure
- * @param peer peer identity the tunnel was created to, NULL on timeout
- * @param atsi performance data for the connection
- *
- * TODO: change to return int to let client allow the new peer or not?
- */
-typedef void (*GNUNET_MESH_PeerConnectHandler) (void *cls,
- const struct GNUNET_PeerIdentity
- * peer,
- const struct
- GNUNET_ATS_Information * atsi);
-
-
-/**
- * Announce to ther peer the availability of services described by the regex,
- * in order to be reachable to other peers via connect_by_string.
- *
- * Note that the first GNUNET_REGEX_INITIAL_BYTES characters are considered
- * to be part of a prefix, (for instance 'gnunet://').
- * If you put a variable part in there (*, +. ()), all matching strings
- * will be stored in the DHT.
- *
- * @param h Handle to mesh.
- * @param regex String with the regular expression describing local services.
- * @param compression_characters How many characters can be assigned to one
- * edge of the graph. The bigger the variability
- * of the data, the smaller this parameter should
- * be (down to 1).
- * For maximum compression, use strlen (regex)
- * or 0 (special value). Use with care!
- */
-void
-GNUNET_MESH_announce_regex (struct GNUNET_MESH_Handle *h,
- const char *regex,
- unsigned int compression_characters);
-
-
-/**
* Create a new tunnel (we're initiator and will be allowed to add/remove peers
* and to broadcast).
*
* @param h mesh handle
* @param tunnel_ctx client's tunnel context to associate with the tunnel
- * @param connect_handler function to call when peers are actually connected
- * @param disconnect_handler function to call when peers are disconnected
- * @param handler_cls closure for connect/disconnect handlers
+ * @param peer peer identity the tunnel should go to
+ * @param port Port number.
+ * @return handle to the tunnel
*/
struct GNUNET_MESH_Tunnel *
-GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h, void *tunnel_ctx,
- GNUNET_MESH_PeerConnectHandler connect_handler,
- GNUNET_MESH_PeerDisconnectHandler disconnect_handler,
- void *handler_cls);
-
-/**
- * Destroy an existing tunnel. The existing callback for the tunnel will NOT
- * be called.
- *
- * @param tunnel tunnel handle
- */
-void
-GNUNET_MESH_tunnel_destroy (struct GNUNET_MESH_Tunnel *tunnel);
+GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h,
+ void *tunnel_ctx,
+ const struct GNUNET_PeerIdentity *peer,
+ uint32_t port);
/**
- * Request that the tunnel data rate is limited to the speed of the slowest
- * receiver.
+ * Destroy an existing tunnel.
*
- * @param tunnel Tunnel affected.
- */
-void
-GNUNET_MESH_tunnel_speed_min (struct GNUNET_MESH_Tunnel *tunnel);
-
-
-/**
- * Request that the tunnel data rate is limited to the speed of the fastest
- * receiver. This is the default behavior.
- *
- * @param tunnel Tunnel affected.
+ * The existing end callback for the tunnel will be called immediately.
+ * Any pending outgoing messages will be sent but no incoming messages will be
+ * accepted and no data callbacks will be called.
+ *
+ * @param tunnel Tunnel handle, becomes invalid after this call.
*/
void
-GNUNET_MESH_tunnel_speed_max (struct GNUNET_MESH_Tunnel *tunnel);
+GNUNET_MESH_tunnel_destroy (struct GNUNET_MESH_Tunnel *tunnel);
/**
@@ -306,82 +229,6 @@ GNUNET_MESH_tunnel_buffer (struct GNUNET_MESH_Tunnel *tunnel, int buffer);
/**
- * Request that a peer should be added to the tunnel. The connect handler
- * will be called when the peer connects
- *
- * @param tunnel handle to existing tunnel
- * @param peer peer to add
- */
-void
-GNUNET_MESH_peer_request_connect_add (struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *peer);
-
-
-/**
- * Request that a peer should be removed from the tunnel. The existing
- * disconnect handler will be called ONCE if we were connected.
- *
- * @param tunnel handle to existing tunnel
- * @param peer peer to remove
- */
-void
-GNUNET_MESH_peer_request_connect_del (struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *peer);
-
-
-/**
- * Request that the mesh should try to connect to a peer supporting the given
- * message type.
- *
- * @param tunnel handle to existing tunnel
- * @param app_type application type that must be supported by the peer
- * (MESH should discover peer in proximity handling this type)
- */
-void
-GNUNET_MESH_peer_request_connect_by_type (struct GNUNET_MESH_Tunnel *tunnel,
- GNUNET_MESH_ApplicationType app_type);
-
-
-/**
- * Request that the mesh should try to connect to a peer matching the
- * description given in the service string.
- *
- * @param tunnel handle to existing tunnel
- * @param description string describing the destination node requirements
- */
-void
-GNUNET_MESH_peer_request_connect_by_string (struct GNUNET_MESH_Tunnel *tunnel,
- const char *description);
-
-
-/**
- * Request that the given peer isn't added to this tunnel in calls to
- * connect_by_* calls, (due to misbehaviour, bad performance, ...).
- *
- * @param tunnel handle to existing tunnel.
- * @param peer peer identity of the peer which should be blacklisted
- * for the tunnel.
- */
-void
-GNUNET_MESH_peer_blacklist (struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *peer);
-
-
-/**
- * Request that the given peer isn't blacklisted anymore from this tunnel,
- * and therefore can be added in future calls to connect_by_*.
- * The peer must have been previously blacklisted for this tunnel.
- *
- * @param tunnel handle to existing tunnel.
- * @param peer peer identity of the peer which shouldn't be blacklisted
- * for the tunnel anymore.
- */
-void
-GNUNET_MESH_peer_unblacklist (struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *peer);
-
-
-/**
* Handle for a transmission request.
*/
struct GNUNET_MESH_TransmitHandle;
@@ -389,15 +236,13 @@ struct GNUNET_MESH_TransmitHandle;
/**
* Ask the mesh to call "notify" once it is ready to transmit the
- * given number of bytes to the specified tunnel or target.
+ * given number of bytes to the specified tunnel.
* Only one call can be active at any time, to issue another request,
* wait for the callback or cancel the current request.
*
* @param tunnel tunnel to use for transmission
* @param cork is corking allowed for this transmission?
* @param maxdelay how long can the message wait?
- * @param target destination for the message
- * NULL for multicast to all tunnel targets
* @param notify_size how many bytes of buffer space does notify want?
* @param notify function to call when buffer space is available;
* will be called with NULL on timeout or if the overall queue
@@ -411,7 +256,6 @@ struct GNUNET_MESH_TransmitHandle;
struct GNUNET_MESH_TransmitHandle *
GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork,
struct GNUNET_TIME_Relative maxdelay,
- const struct GNUNET_PeerIdentity *target,
size_t notify_size,
GNUNET_CONNECTION_TransmitReadyNotify notify,
void *notify_cls);
@@ -428,20 +272,40 @@ GNUNET_MESH_notify_transmit_ready_cancel (struct GNUNET_MESH_TransmitHandle
/**
+ * Indicate readiness to receive the next message on a tunnel.
+ *
+ * Should only be called once per handler called.
+ *
+ * @param tunnel Tunnel that will be allowed to call another handler.
+ */
+void
+GNUNET_MESH_receive_done (struct GNUNET_MESH_Tunnel *tunnel);
+
+
+
+/******************************************************************************/
+/******************** MONITORING /DEBUG API *************************/
+/******************************************************************************/
+/* The following calls are not useful for normal MESH operation, but for */
+/* debug and monitoring of the mesh state. They can be safely ignored. */
+/* The API can change at any point without notice. */
+/* Please contact the developer if you consider any of this calls useful for */
+/* normal mesh applications. */
+/******************************************************************************/
+
+/**
* Method called to retrieve information about each tunnel the mesh peer
* is aware of.
*
* @param cls Closure.
- * @param initiator Peer that started the tunnel (owner).
* @param tunnel_number Tunnel number.
- * @param peers Array of peer identities that participate in the tunnel.
- * @param npeers Number of peers in peers.
+ * @param origin that started the tunnel (owner).
+ * @param target other endpoint of the tunnel
*/
typedef void (*GNUNET_MESH_TunnelsCB) (void *cls,
- const struct GNUNET_PeerIdentity *owner,
- unsigned int tunnel_number,
- const struct GNUNET_PeerIdentity *peers,
- unsigned int npeers);
+ uint32_t tunnel_number,
+ const struct GNUNET_PeerIdentity *origin,
+ const struct GNUNET_PeerIdentity *target);
/**
@@ -460,7 +324,7 @@ typedef void (*GNUNET_MESH_TunnelCB) (void *cls,
/**
* Request information about the running mesh peer.
* The callback will be called for every tunnel known to the service,
- * listing all active peers that blong to the tunnel.
+ * listing all active peers that belong to the tunnel.
*
* If called again on the same handle, it will overwrite the previous
* callback and cls. To retrieve the cls, monitor_cancel must be
@@ -492,7 +356,7 @@ GNUNET_MESH_get_tunnels (struct GNUNET_MESH_Handle *h,
void
GNUNET_MESH_show_tunnel (struct GNUNET_MESH_Handle *h,
struct GNUNET_PeerIdentity *initiator,
- unsigned int tunnel_number,
+ uint32_t tunnel_number,
GNUNET_MESH_TunnelCB callback,
void *callback_cls);
@@ -511,20 +375,15 @@ GNUNET_MESH_get_tunnels_cancel (struct GNUNET_MESH_Handle *h);
/**
- * Transition API for tunnel ctx management
- *
- * FIXME deprecated
- */
-void
-GNUNET_MESH_tunnel_set_data (struct GNUNET_MESH_Tunnel *tunnel, void *data);
-
-/**
- * Transition API for tunnel ctx management
- *
- * FIXME deprecated
+ * Create a message queue for a mesh tunnel.
+ * The message queue can only be used to transmit messages,
+ * not to receive them.
+ *
+ * @param tunnel the tunnel to create the message qeue for
+ * @return a message queue to messages over the tunnel
*/
-void *
-GNUNET_MESH_tunnel_get_data (struct GNUNET_MESH_Tunnel *tunnel);
+struct GNUNET_MQ_Handle *
+GNUNET_MESH_mq_create (struct GNUNET_MESH_Tunnel *tunnel);
#if 0 /* keep Emacsens' auto-indent happy */
diff --git a/src/include/gnunet_stream_lib.h b/src/include/gnunet_stream_lib.h
index f89815c57c..8ee430f5a6 100644
--- a/src/include/gnunet_stream_lib.h
+++ b/src/include/gnunet_stream_lib.h
@@ -151,7 +151,7 @@ enum GNUNET_STREAM_Option
struct GNUNET_STREAM_Socket *
GNUNET_STREAM_open (const struct GNUNET_CONFIGURATION_Handle *cfg,
const struct GNUNET_PeerIdentity *target,
- GNUNET_MESH_ApplicationType app_port,
+ uint32_t app_port,
GNUNET_STREAM_OpenCallback open_cb,
void *open_cb_cls,
...);
@@ -252,7 +252,7 @@ struct GNUNET_STREAM_ListenSocket;
*/
struct GNUNET_STREAM_ListenSocket *
GNUNET_STREAM_listen (const struct GNUNET_CONFIGURATION_Handle *cfg,
- GNUNET_MESH_ApplicationType app_port,
+ uint32_t app_port,
GNUNET_STREAM_ListenCallback listen_cb,
void *listen_cb_cls,
...);
diff --git a/src/mesh/Makefile.am b/src/mesh/Makefile.am
index c0d66ace3f..e1c607d7fc 100644
--- a/src/mesh/Makefile.am
+++ b/src/mesh/Makefile.am
@@ -20,21 +20,6 @@ plugindir = $(libdir)/gnunet
AM_CLFAGS = -g
-if HAVE_EXPERIMENTAL
- noinst_LIB_EXP = libgnunetmesh2test.a
- EXP_LIB = libgnunetmesh2.la
- EXP_LIBEXEC = gnunet-service-mesh-new
- EXP_TESTS = \
- test_mesh2_local \
- test_mesh2_small_forward \
- test_mesh2_small_signal \
- test_mesh2_small_speed \
- test_mesh2_small_speed_ack \
- test_mesh2_small_speed_nobuf \
- test_mesh2_small_speed_backwards \
- test_mesh2_small_speed_nobuf_backwards
-endif
-
libexec_PROGRAMS = \
gnunet-service-mesh $(EXP_LIBEXEC)
@@ -58,6 +43,7 @@ libgnunet_plugin_block_mesh_la_DEPENDENCIES = \
$(top_builddir)/src/block/libgnunetblock.la \
$(top_builddir)/src/util/libgnunetutil.la
+
libgnunetmesh_la_SOURCES = \
mesh_api.c mesh_common.c
libgnunetmesh_la_LIBADD = \
@@ -66,41 +52,7 @@ libgnunetmesh_la_LIBADD = \
$(LTLIBINTL)
libgnunetmesh_la_LDFLAGS = \
$(GN_LIB_LDFLAGS) $(WINFLAGS) \
- -version-info 2:1:1
-
-libgnunetmesh2_la_SOURCES = \
- mesh2_api.c mesh_common.c
-libgnunetmesh2_la_LIBADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(XLIB) \
- $(LTLIBINTL)
-libgnunetmesh2_la_LDFLAGS = \
- $(GN_LIB_LDFLAGS) $(WINFLAGS) \
- -version-info 2:2:1
-
-
-gnunet_service_mesh_SOURCES = \
- gnunet-service-mesh.c \
- mesh_tunnel_tree.c mesh_tunnel_tree.h \
- mesh_common.c
-gnunet_service_mesh_CFLAGS = $(AM_CFLAGS)
-gnunet_service_mesh_LDADD = \
- $(top_builddir)/src/statistics/libgnunetstatistics.la \
- $(top_builddir)/src/regex/libgnunetregex.la \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/core/libgnunetcore.la \
- $(top_builddir)/src/dht/libgnunetdht.la \
- $(top_builddir)/src/block/libgnunetblock.la
-gnunet_service_mesh_DEPENDENCIES = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/core/libgnunetcore.la \
- $(top_builddir)/src/dht/libgnunetdht.la \
- $(top_builddir)/src/statistics/libgnunetstatistics.la \
- $(top_builddir)/src/block/libgnunetblock.la \
- $(top_builddir)/src/regex/libgnunetregex.la
-if LINUX
-gnunet_service_mesh_LDFLAGS = -lrt
-endif
+ -version-info 3:0:0
gnunet_mesh_SOURCES = \
gnunet-mesh.c
@@ -110,25 +62,25 @@ gnunet_mesh_LDADD = \
gnunet_mesh_DEPENDENCIES = \
libgnunetmesh.la
-gnunet_service_mesh_new_SOURCES = \
- gnunet-service-mesh-new.c \
+gnunet_service_mesh_SOURCES = \
+ gnunet-service-mesh.c \
mesh_path.c \
mesh_common.c
-gnunet_service_mesh_new_CFLAGS = $(AM_CFLAGS)
-gnunet_service_mesh_new_LDADD = \
+gnunet_service_mesh_CFLAGS = $(AM_CFLAGS)
+gnunet_service_mesh_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/core/libgnunetcore.la \
$(top_builddir)/src/dht/libgnunetdht.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/block/libgnunetblock.la
-gnunet_service_mesh_new_DEPENDENCIES = \
+gnunet_service_mesh_DEPENDENCIES = \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/core/libgnunetcore.la \
$(top_builddir)/src/dht/libgnunetdht.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
$(top_builddir)/src/block/libgnunetblock.la
if LINUX
-gnunet_service_mesh_new_LDFLAGS = -lrt
+ gnunet_service_mesh_LDFLAGS = -lrt
endif
if HAVE_TESTING
@@ -144,222 +96,75 @@ libgnunetmeshtest_a_LIBADD = \
libgnunetmeshtest_a_DEPENDENCIES = \
libgnunetmesh.la
-libgnunetmesh2test_a_SOURCES = \
- mesh2_test_lib.c mesh2_test_lib.h
-libgnunetmesh2test_a_LIBADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/testbed/libgnunettestbed.la \
- $(top_builddir)/src/mesh/libgnunetmesh2.la
-libgnunetmesh2test_a_DEPENDENCIES = \
- libgnunetmesh2.la
-
if HAVE_TESTING
check_PROGRAMS = \
- test_mesh_api \
- test_mesh_tree_api \
- test_mesh_local_1 \
- test_mesh_local_2 \
- test_mesh_local_traffic_fwd \
- test_mesh_local_traffic_bck \
- test_mesh_local_traffic_both \
- test_mesh_2dtorus \
- test_mesh_small_unicast \
- test_mesh_small_signal \
- test_mesh_small_speed \
- test_mesh_small_speed_nobuf \
- test_mesh_small_speed_backwards \
- test_mesh_small_speed_nobuf_backwards \
- test_mesh_small_speed_ack \
- $(EXP_TESTS)
+ test_mesh_local \
+ test_mesh_small_forward \
+ test_mesh_small_signal \
+ test_mesh_small_speed \
+ test_mesh_small_speed_ack \
+ test_mesh_small_speed_nobuf \
+ test_mesh_small_speed_backwards \
+ test_mesh_small_speed_nobuf_backwards
endif
-test_mesh_api_SOURCES = \
- test_mesh_api.c
-test_mesh_api_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/testing/libgnunettesting.la \
- $(top_builddir)/src/mesh/libgnunetmesh.la
-test_mesh_api_DEPENDENCIES = \
- libgnunetmesh.la \
- $(top_builddir)/src/util/libgnunetutil.la
-
-test_mesh_tree_api_SOURCES = \
- test_mesh_tree_api.c
-test_mesh_tree_api_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/dht/libgnunetdht.la
-test_mesh_tree_api_DEPENDENCIES = \
- libgnunetmesh.la \
- $(top_builddir)/src/dht/libgnunetdht.la
-
-test_mesh_local_1_SOURCES = \
- test_mesh_local_1.c
-test_mesh_local_1_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/testing/libgnunettesting.la \
- $(top_builddir)/src/mesh/libgnunetmesh.la
-test_mesh_local_1_DEPENDENCIES = \
- libgnunetmesh.la
-
-test_mesh_local_2_SOURCES = \
- test_mesh_local_2.c
-test_mesh_local_2_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/testing/libgnunettesting.la \
- $(top_builddir)/src/mesh/libgnunetmesh.la
-test_mesh_local_2_DEPENDENCIES = \
- libgnunetmesh.la
-
-test_mesh_local_traffic_fwd_SOURCES = \
- test_mesh_local_traffic.c
-test_mesh_local_traffic_fwd_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/testing/libgnunettesting.la \
- $(top_builddir)/src/mesh/libgnunetmesh.la
-test_mesh_local_traffic_fwd_DEPENDENCIES = \
- libgnunetmesh.la
-
-test_mesh_local_traffic_bck_SOURCES = \
- test_mesh_local_traffic.c
-test_mesh_local_traffic_bck_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/testing/libgnunettesting.la \
- $(top_builddir)/src/mesh/libgnunetmesh.la
-test_mesh_local_traffic_bck_DEPENDENCIES = \
- libgnunetmesh.la
-
-test_mesh_local_traffic_both_SOURCES = \
- test_mesh_local_traffic.c
-test_mesh_local_traffic_both_LDADD = \
- $(top_builddir)/src/util/libgnunetutil.la \
- $(top_builddir)/src/testing/libgnunettesting.la \
- $(top_builddir)/src/mesh/libgnunetmesh.la
-test_mesh_local_traffic_both_DEPENDENCIES = \
- libgnunetmesh.la
-
-
ld_mesh_test_lib = \
- $(top_builddir)/src/mesh/libgnunetmeshtest.a \
- $(top_builddir)/src/mesh/libgnunetmesh.la \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(top_builddir)/src/testing/libgnunettesting.la \
$(top_builddir)/src/testbed/libgnunettestbed.la \
- $(top_builddir)/src/util/libgnunetutil.la
+ $(top_builddir)/src/mesh/libgnunetmesh.la \
+ $(top_builddir)/src/mesh/libgnunetmeshtest.a
dep_mesh_test_lib = \
- libgnunetmeshtest.a \
- libgnunetmesh.la
+ libgnunetmesh.la \
+ libgnunetmeshtest.a
-test_mesh_2dtorus_SOURCES = \
- test_mesh_2dtorus.c
-test_mesh_2dtorus_LDADD = $(ld_mesh_test_lib)
-test_mesh_2dtorus_DEPENDENCIES = $(dep_mesh_test_lib)
+test_mesh_local_SOURCES = \
+ test_mesh_local.c
+test_mesh_local_LDADD = $(ld_mesh_test_lib)
+test_mesh_local_DEPENDENCIES = $(dep_mesh_test_lib)
-test_mesh_small_unicast_SOURCES = \
- test_mesh_small.c
-test_mesh_small_unicast_LDADD = $(ld_mesh_test_lib)
-test_mesh_small_unicast_DEPENDENCIES = $(dep_mesh_test_lib)
+test_mesh_small_forward_SOURCES = \
+ test_mesh_small.c
+test_mesh_small_forward_LDADD = $(ld_mesh_test_lib)
+test_mesh_small_forward_DEPENDENCIES = $(dep_mesh_test_lib)
test_mesh_small_signal_SOURCES = \
- test_mesh_small.c
+ test_mesh_small.c
test_mesh_small_signal_LDADD = $(ld_mesh_test_lib)
test_mesh_small_signal_DEPENDENCIES = $(dep_mesh_test_lib)
-test_mesh_small_speed_ack_SOURCES = \
- test_mesh_small.c
-test_mesh_small_speed_ack_LDADD = $(ld_mesh_test_lib)
-test_mesh_small_speed_ack_DEPENDENCIES = $(dep_mesh_test_lib)
-
test_mesh_small_speed_SOURCES = \
- test_mesh_small.c
+ test_mesh_small.c
test_mesh_small_speed_LDADD = $(ld_mesh_test_lib)
test_mesh_small_speed_DEPENDENCIES = $(dep_mesh_test_lib)
+test_mesh_small_speed_ack_SOURCES = \
+ test_mesh_small.c
+test_mesh_small_speed_ack_LDADD = $(ld_mesh_test_lib)
+test_mesh_small_speed_ack_DEPENDENCIES = $(dep_mesh_test_lib)
+
test_mesh_small_speed_nobuf_SOURCES = \
- test_mesh_small.c
+ test_mesh_small.c
test_mesh_small_speed_nobuf_LDADD = $(ld_mesh_test_lib)
test_mesh_small_speed_nobuf_DEPENDENCIES = $(dep_mesh_test_lib)
test_mesh_small_speed_backwards_SOURCES = \
- test_mesh_small.c
+ test_mesh_small.c
test_mesh_small_speed_backwards_LDADD = $(ld_mesh_test_lib)
test_mesh_small_speed_backwards_DEPENDENCIES = $(dep_mesh_test_lib)
test_mesh_small_speed_nobuf_backwards_SOURCES = \
- test_mesh_small.c
+ test_mesh_small.c
test_mesh_small_speed_nobuf_backwards_LDADD = $(ld_mesh_test_lib)
test_mesh_small_speed_nobuf_backwards_DEPENDENCIES = $(dep_mesh_test_lib)
-ld_mesh2_test_lib = \
- $(top_builddir)/src/mesh/libgnunetmesh2test.a \
- $(top_builddir)/src/mesh/libgnunetmesh2.la \
- $(top_builddir)/src/testing/libgnunettesting.la \
- $(top_builddir)/src/testbed/libgnunettestbed.la \
- $(top_builddir)/src/util/libgnunetutil.la
-
-dep_mesh2_test_lib = \
- libgnunetmesh2test.a \
- libgnunetmesh2.la
-
-test_mesh2_local_SOURCES = \
- test_mesh2_local.c
-test_mesh2_local_LDADD = $(ld_mesh2_test_lib)
-test_mesh2_local_DEPENDENCIES = $(dep_mesh2_test_lib)
-
-test_mesh2_small_forward_SOURCES = \
- test_mesh2_small.c
-test_mesh2_small_forward_LDADD = $(ld_mesh2_test_lib)
-test_mesh2_small_forward_DEPENDENCIES = $(dep_mesh2_test_lib)
-
-test_mesh2_small_signal_SOURCES = \
- test_mesh2_small.c
-test_mesh2_small_signal_LDADD = $(ld_mesh2_test_lib)
-test_mesh2_small_signal_DEPENDENCIES = $(dep_mesh2_test_lib)
-
-test_mesh2_small_speed_SOURCES = \
- test_mesh2_small.c
-test_mesh2_small_speed_LDADD = $(ld_mesh2_test_lib)
-test_mesh2_small_speed_DEPENDENCIES = $(dep_mesh2_test_lib)
-
-test_mesh2_small_speed_ack_SOURCES = \
- test_mesh2_small.c
-test_mesh2_small_speed_ack_LDADD = $(ld_mesh2_test_lib)
-test_mesh2_small_speed_ack_DEPENDENCIES = $(dep_mesh2_test_lib)
-
-test_mesh2_small_speed_nobuf_SOURCES = \
- test_mesh2_small.c
-test_mesh2_small_speed_nobuf_LDADD = $(ld_mesh2_test_lib)
-test_mesh2_small_speed_nobuf_DEPENDENCIES = $(dep_mesh2_test_lib)
-
-test_mesh2_small_speed_backwards_SOURCES = \
- test_mesh2_small.c
-test_mesh2_small_speed_backwards_LDADD = $(ld_mesh2_test_lib)
-test_mesh2_small_speed_backwards_DEPENDENCIES = $(dep_mesh2_test_lib)
-
-test_mesh2_small_speed_nobuf_backwards_SOURCES = \
- test_mesh2_small.c
-test_mesh2_small_speed_nobuf_backwards_LDADD = $(ld_mesh2_test_lib)
-test_mesh2_small_speed_nobuf_backwards_DEPENDENCIES = $(dep_mesh2_test_lib)
-
-
if ENABLE_TEST_RUN
TESTS = \
- $(EXP_TESTS) \
- test_mesh_api \
- test_mesh_tree_api \
- test_mesh_local_1 test_mesh_local_2 \
- test_mesh_local_traffic_fwd \
- test_mesh_local_traffic_bck \
- test_mesh_local_traffic_both \
- test_mesh_2dtorus \
- test_mesh_small_unicast \
- test_mesh_small_signal \
- test_mesh_small_speed \
- test_mesh_small_speed_nobuf \
- test_mesh_small_speed_backwards
+ $(check_PROGRAMS)
endif
EXTRA_DIST = \
mesh.h mesh_protocol.h \
- test_mesh.conf \
- test_mesh_2dtorus.conf \
- test_mesh_small.conf
+ test_mesh.conf
diff --git a/src/mesh/gnunet-mesh.c b/src/mesh/gnunet-mesh.c
index 21a3f7d601..f9cc1295c6 100644
--- a/src/mesh/gnunet-mesh.c
+++ b/src/mesh/gnunet-mesh.c
@@ -73,25 +73,19 @@ shutdown_task (void *cls,
* Method called to retrieve information about each tunnel the mesh peer
* is aware of.
*
- * @param cls Closure (unused).
- * @param initiator Peer that started the tunnel (owner).
+ * @param cls Closure.
* @param tunnel_number Tunnel number.
- * @param peers Array of peer identities that participate in the tunnel.
- * @param npeers Number of peers in peers.
+ * @param origin that started the tunnel (owner).
+ * @param target other endpoint of the tunnel
*/
static void
tunnels_callback (void *cls,
- const struct GNUNET_PeerIdentity *initiator,
- unsigned int tunnel_number,
- const struct GNUNET_PeerIdentity *peers,
- unsigned int npeers)
+ uint32_t tunnel_number,
+ const struct GNUNET_PeerIdentity *origin,
+ const struct GNUNET_PeerIdentity *target)
{
- unsigned int i;
-
- fprintf (stdout, "Tunnel %s [%u]: %u peers\n",
- GNUNET_i2s_full (initiator), tunnel_number, npeers);
- for (i = 0; i < npeers; i++)
- fprintf (stdout, " * %s\n", GNUNET_i2s_full (&peers[i]));
+ fprintf (stdout, "Tunnel %s [%u]\n",
+ GNUNET_i2s_full (origin), tunnel_number);
fprintf (stdout, "\n");
}
@@ -169,7 +163,7 @@ run (void *cls, char *const *args, const char *cfgfile,
static const struct GNUNET_MESH_MessageHandler handlers[] = {
{NULL, 0, 0} /* FIXME add option to monitor msg types */
};
- GNUNET_MESH_ApplicationType apps = 0; /* FIXME add option to monitor apps */
+ /* FIXME add option to monitor apps */
if (args[0] != NULL)
{
@@ -178,10 +172,10 @@ run (void *cls, char *const *args, const char *cfgfile,
}
mh = GNUNET_MESH_connect (cfg,
NULL, /* cls */
- NULL, /* nt */
+ NULL, /* new tunnel */
NULL, /* cleaner */
handlers,
- &apps);
+ NULL);
if (NULL == mh)
GNUNET_SCHEDULER_add_now (shutdown_task, NULL);
else
diff --git a/src/mesh/gnunet-service-mesh-new.c b/src/mesh/gnunet-service-mesh-new.c
deleted file mode 100644
index 7925b5241b..0000000000
--- a/src/mesh/gnunet-service-mesh-new.c
+++ /dev/null
@@ -1,5205 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 2001-2013 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file mesh/gnunet-service-mesh-new.c
- * @brief GNUnet MESH service
- * @author Bartlomiej Polot
- *
- * TODO:
- * - relay corking down to core
- * - set ttl relative to path length
- * - add signatures
- * - add encryption
- * - keep queues until receiving ACK
- * TODO END
- */
-
-#include "platform.h"
-#include "mesh2.h"
-#include "mesh2_protocol.h"
-#include "mesh_path.h"
-#include "block_mesh.h"
-#include "gnunet_dht_service.h"
-#include "gnunet_statistics_service.h"
-
-#define MESH_BLOOM_SIZE 128
-
-#define MESH_DEBUG_DHT GNUNET_NO
-#define MESH_DEBUG_CONNECTION GNUNET_NO
-#define MESH_DEBUG_TIMING __LINUX__ && GNUNET_NO
-
-#define MESH_MAX_POLL_TIME GNUNET_TIME_relative_multiply (\
- GNUNET_TIME_UNIT_MINUTES,\
- 10)
-
-#if MESH_DEBUG_CONNECTION
-#define DEBUG_CONN(...) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
-#else
-#define DEBUG_CONN(...)
-#endif
-
-#if MESH_DEBUG_DHT
-#define DEBUG_DHT(...) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
-#else
-#define DEBUG_DHT(...)
-#endif
-
-#if MESH_DEBUG_TIMING
-#include <time.h>
-double __sum;
-uint64_t __count;
-struct timespec __mesh_start;
-struct timespec __mesh_end;
-#define INTERVAL_START clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &(__mesh_start))
-#define INTERVAL_END \
-do {\
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &(__mesh_end));\
- double __diff = __mesh_end.tv_nsec - __mesh_start.tv_nsec;\
- if (__diff < 0) __diff += 1000000000;\
- __sum += __diff;\
- __count++;\
-} while (0)
-#define INTERVAL_SHOW \
-if (0 < __count)\
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "AVG process time: %f ns\n", __sum/__count)
-#else
-#define INTERVAL_START
-#define INTERVAL_END
-#define INTERVAL_SHOW
-#endif
-
-/******************************************************************************/
-/************************ DATA STRUCTURES ****************************/
-/******************************************************************************/
-
-/** FWD declaration */
-struct MeshPeerInfo;
-struct MeshClient;
-
-
-/**
- * Struct containing info about a queued transmission to this peer
- */
-struct MeshPeerQueue
-{
- /**
- * DLL next
- */
- struct MeshPeerQueue *next;
-
- /**
- * DLL previous
- */
- struct MeshPeerQueue *prev;
-
- /**
- * Peer this transmission is directed to.
- */
- struct MeshPeerInfo *peer;
-
- /**
- * Tunnel this message belongs to.
- */
- struct MeshTunnel *tunnel;
-
- /**
- * Pointer to info stucture used as cls.
- */
- void *cls;
-
- /**
- * Type of message
- */
- uint16_t type;
-
- /**
- * Size of the message
- */
- size_t size;
-};
-
-
-/**
- * Struct containing all information regarding a given peer
- */
-struct MeshPeerInfo
-{
- /**
- * ID of the peer
- */
- GNUNET_PEER_Id id;
-
- /**
- * Last time we heard from this peer
- */
- struct GNUNET_TIME_Absolute last_contact;
-
- /**
- * Number of attempts to reconnect so far
- */
- int n_reconnect_attempts;
-
- /**
- * Paths to reach the peer, ordered by ascending hop count
- */
- struct MeshPeerPath *path_head;
-
- /**
- * Paths to reach the peer, ordered by ascending hop count
- */
- struct MeshPeerPath *path_tail;
-
- /**
- * Handle to stop the DHT search for a path to this peer
- */
- struct GNUNET_DHT_GetHandle *dhtget;
-
- /**
- * Array of tunnels this peer is the target of.
- * Most probably a small amount, therefore not a hashmap.
- * When the path to the peer changes, notify these tunnels to let them
- * re-adjust their path trees.
- */
- struct MeshTunnel **tunnels;
-
- /**
- * Number of tunnels this peers participates in
- */
- unsigned int ntunnels;
-
- /**
- * Transmission queue to core DLL head
- */
- struct MeshPeerQueue *queue_head;
-
- /**
- * Transmission queue to core DLL tail
- */
- struct MeshPeerQueue *queue_tail;
-
- /**
- * How many messages are in the queue to this peer.
- */
- unsigned int queue_n;
-
- /**
- * Handle for queued transmissions
- */
- struct GNUNET_CORE_TransmitHandle *core_transmit;
-};
-
-
-/**
- * Struct to encapsulate all the Flow Control information to a peer in the
- * context of a tunnel: Same peer in different tunnels will have independent
- * flow control structures, allowing to choke/free tunnels according to its
- * own criteria.
- */
-struct MeshFlowControl
-{
- /**
- * ID of the last packet sent towards the peer.
- */
- uint32_t last_pid_sent;
-
- /**
- * ID of the last packet received from the peer.
- */
- uint32_t last_pid_recv;
-
- /**
- * Last ACK sent to the peer (peer can't send more than this PID).
- */
- uint32_t last_ack_sent;
-
- /**
- * Last ACK sent towards the origin (for traffic towards leaf node).
- */
- uint32_t last_ack_recv;
-
- /**
- * How many payload messages are in the queue towards this peer.
- */
- uint32_t queue_n;
-
- /**
- * Task to poll the peer in case of a lost ACK causes stall.
- */
- GNUNET_SCHEDULER_TaskIdentifier poll_task;
-
- /**
- * How frequently to poll for ACKs.
- */
- struct GNUNET_TIME_Relative poll_time;
-
- /**
- * On which tunnel to poll.
- * Using an explicit poll_ctx would not help memory wise,
- * since the allocated context would have to be stored in the
- * fc struct in order to free it upon cancelling poll_task.
- */
- struct MeshTunnel *t;
-};
-
-
-/**
- * Globally unique tunnel identification (owner + number)
- * DO NOT USE OVER THE NETWORK
- */
-struct MESH_TunnelID
-{
- /**
- * Node that owns the tunnel
- */
- GNUNET_PEER_Id oid;
-
- /**
- * Tunnel number to differentiate all the tunnels owned by the node oid
- * ( tid < GNUNET_MESH_LOCAL_TUNNEL_ID_CLI )
- */
- MESH_TunnelNumber tid;
-};
-
-
-/**
- * Struct containing all information regarding a tunnel
- * For an intermediate node the improtant info used will be:
- * - id Tunnel unique identification
- * - paths[0] To know where to send it next
- * - metainfo: ready, speeds, accounting
- */
-struct MeshTunnel
-{
- /**
- * Tunnel ID
- */
- struct MESH_TunnelID id;
-
- /**
- * Port of the tunnel.
- */
- uint32_t port;
-
- /**
- * State of the tunnel.
- */
- enum MeshTunnelState state;
-
- /**
- * Local tunnel number ( >= GNUNET_MESH_LOCAL_TUNNEL_ID_CLI or 0 )
- */
- MESH_TunnelNumber local_tid;
-
- /**
- * Local tunnel number for local destination clients (incoming number)
- * ( >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV or 0). All clients share the same
- * number.
- */
- MESH_TunnelNumber local_tid_dest;
-
- /**
- * Is the tunnel bufferless (minimum latency)?
- */
- int nobuffer;
-
- /**
- * Force sending ACK? Flag to allow duplicate ACK on POLL.
- */
- int force_ack;
-
- /**
- * How many messages do we accept in the forward queue.
- */
- unsigned int queue_max;
-
- /**
- * Last time the tunnel was used
- */
- struct GNUNET_TIME_Absolute timestamp;
-
- /**
- * Destination of the tunnel.
- */
- GNUNET_PEER_Id dest;
-
- /**
- * Next hop in the tunnel. If 0, @c client must be set.
- */
- GNUNET_PEER_Id next_hop;
-
- /**
- * Previous hop in the tunnel. If 0, @c owner must be set.
- */
- GNUNET_PEER_Id prev_hop;
-
- /**
- * Flow control information about @c next_hop or @c client.
- */
- struct MeshFlowControl next_fc;
-
- /**
- * Flow control information about @c prev_hop or @c owner.
- */
- struct MeshFlowControl prev_fc;
-
- /**
- * Client owner of the tunnel, if any
- */
- struct MeshClient *owner;
-
- /**
- * Client destination of the tunnel, if any.
- */
- struct MeshClient *client;
-
- /**
- * Task to keep the used paths alive at the owner,
- * time tunnel out on all the other peers.
- */
- GNUNET_SCHEDULER_TaskIdentifier maintenance_task;
-
- /**
- * Path being used for the tunnel.
- */
- struct MeshPeerPath *path;
-
- /**
- * Flag to signal the destruction of the tunnel.
- * If this is set GNUNET_YES the tunnel will be destroyed
- * when the queue is empty.
- */
- int destroy;
-
- /**
- * Total messages pending for this tunnels, payload or not.
- */
- unsigned int pending_messages;
-};
-
-
-/**
- * Struct containing information about a client of the service
- *
- * TODO: add a list of 'waiting' ports
- */
-struct MeshClient
-{
- /**
- * Linked list next
- */
- struct MeshClient *next;
-
- /**
- * Linked list prev
- */
- struct MeshClient *prev;
-
- /**
- * Tunnels that belong to this client, indexed by local id
- */
- struct GNUNET_CONTAINER_MultiHashMap *own_tunnels;
-
- /**
- * Tunnels this client has accepted, indexed by incoming local id
- */
- struct GNUNET_CONTAINER_MultiHashMap *incoming_tunnels;
-
- /**
- * Handle to communicate with the client
- */
- struct GNUNET_SERVER_Client *handle;
-
- /**
- * Ports that this client has declared interest in.
- * Indexed by a GMC_hash32 (type), contains *Client.
- */
- struct GNUNET_CONTAINER_MultiHashMap *ports;
-
- /**
- * Whether the client is active or shutting down (don't send confirmations
- * to a client that is shutting down.
- */
- int shutting_down;
-
- /**
- * ID of the client, mainly for debug messages
- */
- unsigned int id;
-
-};
-
-
-/******************************************************************************/
-/************************ DEBUG FUNCTIONS ****************************/
-/******************************************************************************/
-
-#if MESH_DEBUG
-/**
- * GNUNET_SCHEDULER_Task for printing a message after some operation is done
- * @param cls string to print
- * @param success GNUNET_OK if the PUT was transmitted,
- * GNUNET_NO on timeout,
- * GNUNET_SYSERR on disconnect from service
- * after the PUT message was transmitted
- * (so we don't know if it was received or not)
- */
-
-#if 0
-static void
-mesh_debug (void *cls, int success)
-{
- char *s = cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%s (%d)\n", s, success);
-}
-#endif
-
-/* FIXME */
-unsigned int debug_fwd_ack;
-unsigned int debug_bck_ack;
-
-#endif
-
-/******************************************************************************/
-/*********************** GLOBAL VARIABLES ****************************/
-/******************************************************************************/
-
-/************************** Configuration parameters **************************/
-
-/**
- * How often to send tunnel keepalives. Tunnels timeout after 4 missed.
- */
-static struct GNUNET_TIME_Relative refresh_path_time;
-
-/**
- * How often to PUT own ID in the DHT.
- */
-static struct GNUNET_TIME_Relative id_announce_time;
-
-/**
- * Maximum time allowed to connect to a peer found by string.
- */
-static struct GNUNET_TIME_Relative connect_timeout;
-
-/**
- * Default TTL for payload packets.
- */
-static unsigned long long default_ttl;
-
-/**
- * DHT replication level, see DHT API: GNUNET_DHT_get_start, GNUNET_DHT_put.
- */
-static unsigned long long dht_replication_level;
-
-/**
- * How many tunnels are we willing to maintain.
- * Local tunnels are always allowed, even if there are more tunnels than max.
- */
-static unsigned long long max_tunnels;
-
-/**
- * How many messages *in total* are we willing to queue, divided by number of
- * tunnels to get tunnel queue size.
- */
-static unsigned long long max_msgs_queue;
-
-/**
- * How many peers do we want to remember?
- */
-static unsigned long long max_peers;
-
-
-/*************************** Static global variables **************************/
-
-/**
- * Hostkey generation context
- */
-static struct GNUNET_CRYPTO_EccKeyGenerationContext *keygen;
-
-/**
- * DLL with all the clients, head.
- */
-static struct MeshClient *clients_head;
-
-/**
- * DLL with all the clients, tail.
- */
-static struct MeshClient *clients_tail;
-
-/**
- * Tunnels known, indexed by MESH_TunnelID (MeshTunnel).
- */
-static struct GNUNET_CONTAINER_MultiHashMap *tunnels;
-
-/**
- * Number of tunnels known.
- */
-static unsigned long long n_tunnels;
-
-/**
- * Tunnels incoming, indexed by MESH_TunnelNumber
- * (which is greater than GNUNET_MESH_LOCAL_TUNNEL_ID_SERV).
- */
-static struct GNUNET_CONTAINER_MultiHashMap *incoming_tunnels;
-
-/**
- * Peers known, indexed by PeerIdentity (MeshPeerInfo).
- */
-static struct GNUNET_CONTAINER_MultiHashMap *peers;
-
-/*
- * Handle to communicate with transport
- */
-// static struct GNUNET_TRANSPORT_Handle *transport_handle;
-
-/**
- * Handle to communicate with core.
- */
-static struct GNUNET_CORE_Handle *core_handle;
-
-/**
- * Handle to use DHT.
- */
-static struct GNUNET_DHT_Handle *dht_handle;
-
-/**
- * Handle to server.
- */
-static struct GNUNET_SERVER_Handle *server_handle;
-
-/**
- * Handle to the statistics service.
- */
-static struct GNUNET_STATISTICS_Handle *stats;
-
-/**
- * Notification context, to send messages to local clients.
- */
-static struct GNUNET_SERVER_NotificationContext *nc;
-
-/**
- * Local peer own ID (memory efficient handle).
- */
-static GNUNET_PEER_Id myid;
-
-/**
- * Local peer own ID (full value).
- */
-static struct GNUNET_PeerIdentity my_full_id;
-
-/**
- * Own private key.
- */
-static struct GNUNET_CRYPTO_EccPrivateKey *my_private_key;
-
-/**
- * Own public key.
- */
-static struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded my_public_key;
-
-/**
- * Tunnel ID for the next created tunnel (global tunnel number).
- */
-static MESH_TunnelNumber next_tid;
-
-/**
- * Tunnel ID for the next incoming tunnel (local tunnel number).
- */
-static MESH_TunnelNumber next_local_tid;
-
-/**
- * All ports clients of this peer have opened.
- */
-static struct GNUNET_CONTAINER_MultiHashMap *ports;
-
-/**
- * Task to periodically announce itself in the network.
- */
-GNUNET_SCHEDULER_TaskIdentifier announce_id_task;
-
-/**
- * Next ID to assign to a client.
- */
-unsigned int next_client_id;
-
-
-/******************************************************************************/
-/*********************** DECLARATIONS **************************/
-/******************************************************************************/
-
-/**
- * Function to process paths received for a new peer addition. The recorded
- * paths form the initial tunnel, which can be optimized later.
- * Called on each result obtained for the DHT search.
- *
- * @param cls closure
- * @param exp when will this value expire
- * @param key key of the result
- * @param type type of the result
- * @param size number of bytes in data
- * @param data pointer to the result data
- */
-static void
-dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
- const struct GNUNET_HashCode * key,
- const struct GNUNET_PeerIdentity *get_path,
- unsigned int get_path_length,
- const struct GNUNET_PeerIdentity *put_path,
- unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
- size_t size, const void *data);
-
-
-/**
- * Retrieve the MeshPeerInfo stucture associated with the peer, create one
- * and insert it in the appropriate structures if the peer is not known yet.
- *
- * @param peer Full identity of the peer.
- *
- * @return Existing or newly created peer info.
- */
-static struct MeshPeerInfo *
-peer_get (const struct GNUNET_PeerIdentity *peer);
-
-
-/**
- * Retrieve the MeshPeerInfo stucture associated with the peer, create one
- * and insert it in the appropriate structures if the peer is not known yet.
- *
- * @param peer Short identity of the peer.
- *
- * @return Existing or newly created peer info.
- */
-static struct MeshPeerInfo *
-peer_get_short (const GNUNET_PEER_Id peer);
-
-
-/**
- * Build a PeerPath from the paths returned from the DHT, reversing the paths
- * to obtain a local peer -> destination path and interning the peer ids.
- *
- * @return Newly allocated and created path
- */
-static struct MeshPeerPath *
-path_build_from_dht (const struct GNUNET_PeerIdentity *get_path,
- unsigned int get_path_length,
- const struct GNUNET_PeerIdentity *put_path,
- unsigned int put_path_length);
-
-
-/**
- * Adds a path to the peer_infos of all the peers in the path
- *
- * @param p Path to process.
- * @param confirmed Whether we know if the path works or not.
- */
-static void
-path_add_to_peers (struct MeshPeerPath *p, int confirmed);
-
-
-
-/**
- * Search for a tunnel by global ID using full PeerIdentities.
- *
- * @param oid owner of the tunnel.
- * @param tid global tunnel number.
- *
- * @return tunnel handler, NULL if doesn't exist.
- */
-static struct MeshTunnel *
-tunnel_get (const struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid);
-
-
-/**
- * Notify a tunnel that a connection has broken that affects at least
- * some of its peers.
- *
- * @param t Tunnel affected.
- * @param p1 Peer that got disconnected from p2.
- * @param p2 Peer that got disconnected from p1.
- *
- * @return Short ID of the peer disconnected (either p1 or p2).
- * 0 if the tunnel remained unaffected.
- */
-static GNUNET_PEER_Id
-tunnel_notify_connection_broken (struct MeshTunnel *t, GNUNET_PEER_Id p1,
- GNUNET_PEER_Id p2);
-
-
-/**
- * @brief Use the given path for the tunnel.
- * Update the next and prev hops (and RCs).
- * (Re)start the path refresh in case the tunnel is locally owned.
- *
- * @param t Tunnel to update.
- * @param p Path to use.
- */
-static void
-tunnel_use_path (struct MeshTunnel *t, struct MeshPeerPath *p);
-
-/**
- * Tunnel is empty: destroy it.
- *
- * Notifies all participants (peers, cleints) about the destruction.
- *
- * @param t Tunnel to destroy.
- */
-static void
-tunnel_destroy_empty (struct MeshTunnel *t);
-
-/**
- * @brief Queue and pass message to core when possible.
- *
- * If type is payload (UNICAST, TO_ORIGIN, MULTICAST) checks for queue status
- * and accounts for it. In case the queue is full, the message is dropped and
- * a break issued.
- *
- * Otherwise, message is treated as internal and allowed to go regardless of
- * queue status.
- *
- * @param cls Closure (@c type dependant). It will be used by queue_send to
- * build the message to be sent if not already prebuilt.
- * @param type Type of the message, 0 for a raw message.
- * @param size Size of the message.
- * @param dst Neighbor to send message to.
- * @param t Tunnel this message belongs to.
- */
-static void
-queue_add (void *cls, uint16_t type, size_t size,
- struct MeshPeerInfo *dst, struct MeshTunnel *t);
-
-
-/**
- * Free a transmission that was already queued with all resources
- * associated to the request.
- *
- * @param queue Queue handler to cancel.
- * @param clear_cls Is it necessary to free associated cls?
- */
-static void
-queue_destroy (struct MeshPeerQueue *queue, int clear_cls);
-
-
-/**
- * @brief Get the next transmittable message from the queue.
- *
- * This will be the head, except in the case of being a data packet
- * not allowed by the destination peer.
- *
- * @param peer Destination peer.
- *
- * @return The next viable MeshPeerQueue element to send to that peer.
- * NULL when there are no transmittable messages.
- */
-struct MeshPeerQueue *
-queue_get_next (const struct MeshPeerInfo *peer);
-
-
-/**
- * Core callback to write a queued packet to core buffer
- *
- * @param cls Closure (peer info).
- * @param size Number of bytes available in buf.
- * @param buf Where the to write the message.
- *
- * @return number of bytes written to buf
- */
-static size_t
-queue_send (void *cls, size_t size, void *buf);
-
-
-/******************************************************************************/
-/************************ PERIODIC FUNCTIONS ****************************/
-/******************************************************************************/
-
-/**
- * Periodically announce self id in the DHT
- *
- * @param cls closure
- * @param tc task context
- */
-static void
-announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct PBlock block;
-
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- {
- announce_id_task = GNUNET_SCHEDULER_NO_TASK;
- return;
- }
- /* TODO
- * - Set data expiration in function of X
- * - Adapt X to churn
- */
- DEBUG_DHT ("DHT_put for ID %s started.\n", GNUNET_i2s (&my_full_id));
-
- block.id = my_full_id;
- block.type = htonl (0);
- GNUNET_DHT_put (dht_handle, /* DHT handle */
- &my_full_id.hashPubKey, /* Key to use */
- dht_replication_level, /* Replication level */
- GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, /* DHT options */
- GNUNET_BLOCK_TYPE_MESH_PEER, /* Block type */
- sizeof (block), /* Size of the data */
- (const char *) &block, /* Data itself */
- GNUNET_TIME_UNIT_FOREVER_ABS, /* Data expiration */
- GNUNET_TIME_UNIT_FOREVER_REL, /* Retry time */
- NULL, /* Continuation */
- NULL); /* Continuation closure */
- announce_id_task =
- GNUNET_SCHEDULER_add_delayed (id_announce_time, &announce_id, cls);
-}
-
-
-/******************************************************************************/
-/****************** GENERAL HELPER FUNCTIONS ************************/
-/******************************************************************************/
-
-
-/**
- * Check if client has registered with the service and has not disconnected
- *
- * @param client the client to check
- *
- * @return non-NULL if client exists in the global DLL
- */
-static struct MeshClient *
-client_get (struct GNUNET_SERVER_Client *client)
-{
- struct MeshClient *c;
-
- c = clients_head;
- while (NULL != c)
- {
- if (c->handle == client)
- return c;
- c = c->next;
- }
- return NULL;
-}
-
-
-/**
- * Deletes a tunnel from a client (either owner or destination). To be used on
- * tunnel destroy.
- *
- * @param c Client whose tunnel to delete.
- * @param t Tunnel which should be deleted.
- */
-static void
-client_delete_tunnel (struct MeshClient *c, struct MeshTunnel *t)
-{
- struct GNUNET_HashCode hash;
-
- if (c == t->owner)
- {
- GMC_hash32 (t->local_tid, &hash);
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_remove (c->own_tunnels,
- &hash,
- t));
- }
- else if (c == t->client)
- {
- GMC_hash32 (t->local_tid_dest, &hash);
- GNUNET_assert (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels,
- &hash,
- t));
- }
- else
- {
- GNUNET_break (0);
- }
-}
-
-/**
- * Notify the appropriate client that a new incoming tunnel was created.
- *
- * @param t Tunnel that was created.
- */
-static void
-send_client_tunnel_create (struct MeshTunnel *t)
-{
- struct GNUNET_MESH_TunnelMessage msg;
-
- if (NULL == t->client)
- return;
- msg.header.size = htons (sizeof (msg));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
- msg.tunnel_id = htonl (t->local_tid_dest);
- msg.port = htonl (t->port);
- GNUNET_PEER_resolve (t->id.oid, &msg.peer);
- GNUNET_SERVER_notification_context_unicast (nc, t->client->handle,
- &msg.header, GNUNET_NO);
-}
-
-
-/**
- * Notify dest client that the incoming tunnel is no longer valid.
- *
- * @param c Client to notify..
- * @param t Tunnel that is destroyed.
- */
-static void
-send_client_tunnel_destroy (struct MeshClient *c, struct MeshTunnel *t)
-{
- struct GNUNET_MESH_TunnelMessage msg;
-
- if (NULL == c)
- {
- GNUNET_break (0);
- return;
- }
- if (c != t->client && c != t->owner)
- {
- GNUNET_break (0);
- return;
- }
- msg.header.size = htons (sizeof (msg));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
- msg.tunnel_id = htonl (t->local_tid_dest);
- msg.port = htonl (0);
- memset(&msg.peer, 0, sizeof (msg.peer));
- GNUNET_SERVER_notification_context_unicast (nc, c->handle,
- &msg.header, GNUNET_NO);
-}
-
-
-/**
- * Iterator over all the peers to remove the oldest not-used entry.
- *
- * @param cls Closure (unsued).
- * @param key ID of the peer.
- * @param value Peer_Info of the peer.
- *
- * FIXME implement
- */
-static int
-peer_info_timeout (void *cls,
- const struct GNUNET_HashCode *key,
- void *value)
-{
- return GNUNET_YES;
-}
-
-/**
- * Retrieve the MeshPeerInfo stucture associated with the peer, create one
- * and insert it in the appropriate structures if the peer is not known yet.
- *
- * @param peer Full identity of the peer.
- *
- * @return Existing or newly created peer info.
- */
-static struct MeshPeerInfo *
-peer_get (const struct GNUNET_PeerIdentity *peer)
-{
- struct MeshPeerInfo *peer_info;
-
- peer_info = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey);
- if (NULL == peer_info)
- {
- peer_info =
- (struct MeshPeerInfo *) GNUNET_malloc (sizeof (struct MeshPeerInfo));
- if (GNUNET_CONTAINER_multihashmap_size (peers) > max_peers)
- {
- GNUNET_CONTAINER_multihashmap_iterate (peers,
- &peer_info_timeout,
- NULL);
- }
- GNUNET_CONTAINER_multihashmap_put (peers, &peer->hashPubKey, peer_info,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
- peer_info->id = GNUNET_PEER_intern (peer);
- }
- peer_info->last_contact = GNUNET_TIME_absolute_get();
-
- return peer_info;
-}
-
-
-/**
- * Retrieve the MeshPeerInfo stucture associated with the peer, create one
- * and insert it in the appropriate structures if the peer is not known yet.
- *
- * @param peer Short identity of the peer.
- *
- * @return Existing or newly created peer info.
- */
-static struct MeshPeerInfo *
-peer_get_short (const GNUNET_PEER_Id peer)
-{
- struct GNUNET_PeerIdentity id;
-
- GNUNET_PEER_resolve (peer, &id);
- return peer_get (&id);
-}
-
-
-/**
- * Choose the best path towards a peer considering the tunnel properties.
- *
- * @param peer The destination peer.
- * @param t The tunnel the path is for.
- *
- * @return Best current known path towards the peer, if any.
- */
-static struct MeshPeerPath *
-peer_get_best_path (const struct MeshPeerInfo *peer, const struct MeshTunnel *t)
-{
- struct MeshPeerPath *best_p;
- struct MeshPeerPath *p;
- unsigned int best_cost;
- unsigned int cost;
-
- best_p = p = peer->path_head;
- best_cost = cost = p->length;
- while (NULL != p)
- {
- if ((cost = p->length) < best_cost)
- {
- best_cost = cost;
- best_p = p;
- }
- p = p->next;
- }
- return best_p;
-}
-
-/**
- * Core callback to write a pre-constructed data packet to core buffer
- *
- * @param cls Closure (MeshTransmissionDescriptor with data in "data" member).
- * @param size Number of bytes available in buf.
- * @param buf Where the to write the message.
- *
- * @return number of bytes written to buf
- */
-static size_t
-send_core_data_raw (void *cls, size_t size, void *buf)
-{
- struct GNUNET_MessageHeader *msg = cls;
- size_t total_size;
-
- GNUNET_assert (NULL != msg);
- total_size = ntohs (msg->size);
-
- if (total_size > size)
- {
- GNUNET_break (0);
- return 0;
- }
- memcpy (buf, msg, total_size);
- GNUNET_free (cls);
- return total_size;
-}
-
-
-/**
- * Sends an already built message to a peer, properly registrating
- * all used resources.
- *
- * @param message Message to send. Function makes a copy of it.
- * @param peer Short ID of the neighbor whom to send the message.
- * @param t Tunnel on which this message is transmitted.
- */
-static void
-send_prebuilt_message (const struct GNUNET_MessageHeader *message,
- GNUNET_PEER_Id peer,
- struct MeshTunnel *t)
-{
- struct GNUNET_PeerIdentity id;
- struct MeshPeerInfo *neighbor;
- struct MeshPeerPath *p;
- void *data;
- size_t size;
- uint16_t type;
-
-// GNUNET_TRANSPORT_try_connect(); FIXME use?
-
- if (0 == peer)
- return;
-
- size = ntohs (message->size);
- data = GNUNET_malloc (size);
- memcpy (data, message, size);
- type = ntohs(message->type);
- if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == type ||
- GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == type)
- {
- struct GNUNET_MESH_Data *u;
-
- u = (struct GNUNET_MESH_Data *) data;
- u->ttl = htonl (ntohl (u->ttl) - 1);
- }
- GNUNET_PEER_resolve (peer, &id);
- neighbor = peer_get (&id);
- for (p = neighbor->path_head; NULL != p; p = p->next)
- {
- if (2 >= p->length)
- {
- break;
- }
- }
- if (NULL == p)
- {
-#if MESH_DEBUG
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " %s IS NOT DIRECTLY CONNECTED\n",
- GNUNET_i2s(&id));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " PATHS TO %s:\n",
- GNUNET_i2s(&id));
- for (p = neighbor->path_head; NULL != p; p = p->next)
- {
- struct GNUNET_PeerIdentity debug_id;
- unsigned int i;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " path with %u hops through:\n",
- p->length);
- for (i = 0; i < p->length; i++)
- {
- GNUNET_PEER_resolve(p->peers[i], &debug_id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " hop %u: %s\n",
- i, GNUNET_i2s(&debug_id));
- }
- }
-#endif
- GNUNET_break (0); // FIXME sometimes fails (testing disconnect?)
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- " no direct connection to %s\n",
- GNUNET_i2s (&id));
- GNUNET_free (data);
- return;
- }
- if (GNUNET_MESSAGE_TYPE_MESH_PATH_ACK == type)
- type = 0;
- queue_add (data,
- type,
- size,
- neighbor,
- t);
-}
-
-
-/**
- * Sends a CREATE PATH message for a path to a peer, properly registrating
- * all used resources.
- *
- * @param t Tunnel for which the path is created.
- */
-static void
-send_create_path (struct MeshTunnel *t)
-{
- struct MeshPeerInfo *neighbor;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send create path\n");
- neighbor = peer_get_short (t->next_hop);
- queue_add (t,
- GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE,
- sizeof (struct GNUNET_MESH_CreateTunnel) +
- (t->path->length * sizeof (struct GNUNET_PeerIdentity)),
- neighbor,
- t);
- t->state = MESH_TUNNEL_WAITING;
-}
-
-
-/**
- * Sends a PATH ACK message in reponse to a received PATH_CREATE directed to us.
- *
- * @param t Tunnel which to confirm.
- */
-static void
-send_path_ack (struct MeshTunnel *t)
-{
- struct MeshPeerInfo *peer;
-
- peer = peer_get_short (t->prev_hop);
-
- queue_add (t,
- GNUNET_MESSAGE_TYPE_MESH_PATH_ACK,
- sizeof (struct GNUNET_MESH_PathACK),
- peer,
- t);
-}
-
-
-/**
- * Try to establish a new connection to this peer in the given tunnel.
- * If the peer doesn't have any path to it yet, try to get one.
- * If the peer already has some path, send a CREATE PATH towards it.
- *
- * @param peer PeerInfo of the peer.
- * @param t Tunnel for which to create the path, if possible.
- */
-static void
-peer_connect (struct MeshPeerInfo *peer, struct MeshTunnel *t)
-{
- struct MeshPeerPath *p;
-
- if (NULL != peer->path_head)
- {
- p = peer_get_best_path (peer, t);
- tunnel_use_path (t, p);
- send_create_path (t);
- }
- else if (NULL == peer->dhtget)
- {
- struct GNUNET_PeerIdentity id;
-
- GNUNET_PEER_resolve (peer->id, &id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Starting DHT GET for peer %s\n", GNUNET_i2s (&id));
- peer->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */
- GNUNET_BLOCK_TYPE_MESH_PEER, /* type */
- &id.hashPubKey, /* key to search */
- dht_replication_level, /* replication level */
- GNUNET_DHT_RO_RECORD_ROUTE |
- GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
- NULL, /* xquery */
- 0, /* xquery bits */
- &dht_get_id_handler, peer);
- t->state = MESH_TUNNEL_SEARCHING;
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "There is no path but the DHT GET is already started.\n");
- }
-}
-
-
-/**
- * Destroy the peer_info and free any allocated resources linked to it
- *
- * @param pi The peer_info to destroy.
- *
- * @return GNUNET_OK on success
- */
-static int
-peer_info_destroy (struct MeshPeerInfo *pi)
-{
- struct GNUNET_PeerIdentity id;
- struct MeshPeerPath *p;
- struct MeshPeerPath *nextp;
- unsigned int i;
-
- GNUNET_PEER_resolve (pi->id, &id);
- GNUNET_PEER_change_rc (pi->id, -1);
-
- if (GNUNET_YES !=
- GNUNET_CONTAINER_multihashmap_remove (peers, &id.hashPubKey, pi))
- {
- GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "removing peer %s, not in hashmap\n", GNUNET_i2s (&id));
- }
- if (NULL != pi->dhtget)
- {
- GNUNET_DHT_get_stop (pi->dhtget);
- }
- p = pi->path_head;
- while (NULL != p)
- {
- nextp = p->next;
- GNUNET_CONTAINER_DLL_remove (pi->path_head, pi->path_tail, p);
- path_destroy (p);
- p = nextp;
- }
- for (i = 0; i < pi->ntunnels; i++)
- tunnel_destroy_empty (pi->tunnels[i]);
- GNUNET_array_grow (pi->tunnels, pi->ntunnels, 0);
- GNUNET_free (pi);
- return GNUNET_OK;
-}
-
-
-/**
- * Remove all paths that rely on a direct connection between p1 and p2
- * from the peer itself and notify all tunnels about it.
- *
- * @param peer PeerInfo of affected peer.
- * @param p1 GNUNET_PEER_Id of one peer.
- * @param p2 GNUNET_PEER_Id of another peer that was connected to the first and
- * no longer is.
- *
- * TODO: optimize (see below)
- */
-static void
-peer_remove_path (struct MeshPeerInfo *peer, GNUNET_PEER_Id p1,
- GNUNET_PEER_Id p2)
-{
- struct MeshPeerPath *p;
- struct MeshPeerPath *next;
- struct MeshPeerInfo *peer_d;
- GNUNET_PEER_Id d;
- unsigned int destroyed;
- unsigned int i;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer_info_remove_path\n");
- destroyed = 0;
- for (p = peer->path_head; NULL != p; p = next)
- {
- next = p->next;
- for (i = 0; i < (p->length - 1); i++)
- {
- if ((p->peers[i] == p1 && p->peers[i + 1] == p2) ||
- (p->peers[i] == p2 && p->peers[i + 1] == p1))
- {
- GNUNET_CONTAINER_DLL_remove (peer->path_head, peer->path_tail, p);
- path_destroy (p);
- destroyed++;
- break;
- }
- }
- }
- if (0 == destroyed)
- return;
-
- for (i = 0; i < peer->ntunnels; i++)
- {
- d = tunnel_notify_connection_broken (peer->tunnels[i], p1, p2);
- if (0 == d)
- continue;
-
- peer_d = peer_get_short (d);
- next = peer_get_best_path (peer_d, peer->tunnels[i]);
- tunnel_use_path (peer->tunnels[i], next);
- peer_connect (peer_d, peer->tunnels[i]);
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer_info_remove_path END\n");
-}
-
-
-/**
- * Add the path to the peer and update the path used to reach it in case this
- * is the shortest.
- *
- * @param peer_info Destination peer to add the path to.
- * @param path New path to add. Last peer must be the peer in arg 1.
- * Path will be either used of freed if already known.
- * @param trusted Do we trust that this path is real?
- */
-void
-peer_info_add_path (struct MeshPeerInfo *peer_info, struct MeshPeerPath *path,
- int trusted)
-{
- struct MeshPeerPath *aux;
- unsigned int l;
- unsigned int l2;
-
- if ((NULL == peer_info) || (NULL == path))
- {
- GNUNET_break (0);
- path_destroy (path);
- return;
- }
- if (path->peers[path->length - 1] != peer_info->id)
- {
- GNUNET_break (0);
- path_destroy (path);
- return;
- }
- if (2 >= path->length && GNUNET_NO == trusted)
- {
- /* Only allow CORE to tell us about direct paths */
- path_destroy (path);
- return;
- }
- for (l = 1; l < path->length; l++)
- {
- if (path->peers[l] == myid)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shortening path by %u\n", l);
- for (l2 = 0; l2 < path->length - l; l2++)
- {
- path->peers[l2] = path->peers[l + l2];
- }
- path->length -= l;
- l = 1;
- path->peers =
- GNUNET_realloc (path->peers, path->length * sizeof (GNUNET_PEER_Id));
- }
- }
-#if MESH_DEBUG
- {
- struct GNUNET_PeerIdentity id;
-
- GNUNET_PEER_resolve (peer_info->id, &id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "adding path [%u] to peer %s\n",
- path->length, GNUNET_i2s (&id));
- }
-#endif
- l = path_get_length (path);
- if (0 == l)
- {
- path_destroy (path);
- return;
- }
-
- GNUNET_assert (peer_info->id == path->peers[path->length - 1]);
- for (aux = peer_info->path_head; aux != NULL; aux = aux->next)
- {
- l2 = path_get_length (aux);
- if (l2 > l)
- {
- GNUNET_CONTAINER_DLL_insert_before (peer_info->path_head,
- peer_info->path_tail, aux, path);
- return;
- }
- else
- {
- if (l2 == l && memcmp (path->peers, aux->peers, l) == 0)
- {
- path_destroy (path);
- return;
- }
- }
- }
- GNUNET_CONTAINER_DLL_insert_tail (peer_info->path_head, peer_info->path_tail,
- path);
- return;
-}
-
-
-/**
- * Add the path to the origin peer and update the path used to reach it in case
- * this is the shortest.
- * The path is given in peer_info -> destination, therefore we turn the path
- * upside down first.
- *
- * @param peer_info Peer to add the path to, being the origin of the path.
- * @param path New path to add after being inversed.
- * Path will be either used or freed.
- * @param trusted Do we trust that this path is real?
- */
-static void
-peer_info_add_path_to_origin (struct MeshPeerInfo *peer_info,
- struct MeshPeerPath *path, int trusted)
-{
- path_invert (path);
- peer_info_add_path (peer_info, path, trusted);
-}
-
-
-/**
- * Add a tunnel to the list of tunnels a peer participates in.
- * Update the tunnel's destination.
- *
- * @param p Peer to add to.
- * @param t Tunnel to add.
- */
-static void
-peer_info_add_tunnel (struct MeshPeerInfo *p, struct MeshTunnel *t)
-{
- if (0 != t->dest)
- {
- GNUNET_break (t->dest == p->id);
- return;
- }
- t->dest = p->id;
- GNUNET_PEER_change_rc (t->dest, 1);
- GNUNET_array_append (p->tunnels, p->ntunnels, t);
-}
-
-
-/**
- * Remove a tunnel from the list of tunnels a peer participates in.
- * Free the tunnel's destination.
- *
- * @param p Peer to clean.
- * @param t Tunnel to remove.
- */
-static void
-peer_info_remove_tunnel (struct MeshPeerInfo *p, struct MeshTunnel *t)
-{
- unsigned int i;
-
- if (t->dest == p->id)
- {
- GNUNET_PEER_change_rc (t->dest, -1);
- t->dest = 0;
- }
- for (i = 0; i < p->ntunnels; i++)
- {
- if (p->tunnels[i] == t)
- {
- p->tunnels[i] = p->tunnels[p->ntunnels - 1];
- GNUNET_array_grow (p->tunnels, p->ntunnels, p->ntunnels - 1);
- return;
- }
- }
-}
-
-
-/**
- * Function called if the connection to the peer has been stalled for a while,
- * possibly due to a missed ACK. Poll the peer about its ACK status.
- *
- * @param cls Closure (poll ctx).
- * @param tc TaskContext.
- */
-static void
-tunnel_poll (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct MeshFlowControl *fc = cls;
- struct GNUNET_MESH_Poll msg;
- struct MeshTunnel *t = fc->t;
- GNUNET_PEER_Id peer;
-
- fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- {
- return;
- }
-
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_POLL);
- msg.header.size = htons (sizeof (msg));
- msg.tid = htonl (t->id.tid);
- GNUNET_PEER_resolve (t->id.oid, &msg.oid);
-
- if (fc == &t->prev_fc)
- {
- peer = t->prev_hop;
- }
- else if (fc == &t->next_fc)
- {
- peer = t->next_hop;
- }
- else
- {
- GNUNET_break (0);
- return;
- }
- send_prebuilt_message (&msg.header, peer, t);
- fc->poll_time = GNUNET_TIME_STD_BACKOFF (fc->poll_time);
- fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
- &tunnel_poll, fc);
-}
-
-
-/**
- * Build a PeerPath from the paths returned from the DHT, reversing the paths
- * to obtain a local peer -> destination path and interning the peer ids.
- *
- * @return Newly allocated and created path
- */
-static struct MeshPeerPath *
-path_build_from_dht (const struct GNUNET_PeerIdentity *get_path,
- unsigned int get_path_length,
- const struct GNUNET_PeerIdentity *put_path,
- unsigned int put_path_length)
-{
- struct MeshPeerPath *p;
- GNUNET_PEER_Id id;
- int i;
-
- p = path_new (1);
- p->peers[0] = myid;
- GNUNET_PEER_change_rc (myid, 1);
- i = get_path_length;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " GET has %d hops.\n", i);
- for (i--; i >= 0; i--)
- {
- id = GNUNET_PEER_intern (&get_path[i]);
- if (p->length > 0 && id == p->peers[p->length - 1])
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Optimizing 1 hop out.\n");
- GNUNET_PEER_change_rc (id, -1);
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Adding from GET: %s.\n",
- GNUNET_i2s (&get_path[i]));
- p->length++;
- p->peers = GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * p->length);
- p->peers[p->length - 1] = id;
- }
- }
- i = put_path_length;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " PUT has %d hops.\n", i);
- for (i--; i >= 0; i--)
- {
- id = GNUNET_PEER_intern (&put_path[i]);
- if (id == myid)
- {
- /* PUT path went through us, so discard the path up until now and start
- * from here to get a much shorter (and loop-free) path.
- */
- path_destroy (p);
- p = path_new (0);
- }
- if (p->length > 0 && id == p->peers[p->length - 1])
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Optimizing 1 hop out.\n");
- GNUNET_PEER_change_rc (id, -1);
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Adding from PUT: %s.\n",
- GNUNET_i2s (&put_path[i]));
- p->length++;
- p->peers = GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * p->length);
- p->peers[p->length - 1] = id;
- }
- }
-#if MESH_DEBUG
- if (get_path_length > 0)
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " (first of GET: %s)\n",
- GNUNET_i2s (&get_path[0]));
- if (put_path_length > 0)
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " (first of PUT: %s)\n",
- GNUNET_i2s (&put_path[0]));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " In total: %d hops\n",
- p->length);
- for (i = 0; i < p->length; i++)
- {
- struct GNUNET_PeerIdentity peer_id;
-
- GNUNET_PEER_resolve (p->peers[i], &peer_id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %u: %s\n", p->peers[i],
- GNUNET_i2s (&peer_id));
- }
-#endif
- return p;
-}
-
-
-/**
- * Adds a path to the peer_infos of all the peers in the path
- *
- * @param p Path to process.
- * @param confirmed Whether we know if the path works or not.
- */
-static void
-path_add_to_peers (struct MeshPeerPath *p, int confirmed)
-{
- unsigned int i;
-
- /* TODO: invert and add */
- for (i = 0; i < p->length && p->peers[i] != myid; i++) /* skip'em */ ;
- for (i++; i < p->length; i++)
- {
- struct MeshPeerInfo *aux;
- struct MeshPeerPath *copy;
-
- aux = peer_get_short (p->peers[i]);
- copy = path_duplicate (p);
- copy->length = i + 1;
- peer_info_add_path (aux, copy, p->length < 3 ? GNUNET_NO : confirmed);
- }
-}
-
-
-/**
- * Send keepalive packets for a peer
- *
- * @param cls Closure (tunnel for which to send the keepalive).
- * @param tc Notification context.
- */
-static void
-path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
-
-
-/**
- * Search for a tunnel among the incoming tunnels
- *
- * @param tid the local id of the tunnel
- *
- * @return tunnel handler, NULL if doesn't exist
- */
-static struct MeshTunnel *
-tunnel_get_incoming (MESH_TunnelNumber tid)
-{
- struct GNUNET_HashCode hash;
-
- GNUNET_assert (tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV);
- GMC_hash32 (tid, &hash);
- return GNUNET_CONTAINER_multihashmap_get (incoming_tunnels, &hash);
-}
-
-
-/**
- * Search for a tunnel among the tunnels for a client
- *
- * @param c the client whose tunnels to search in
- * @param tid the local id of the tunnel
- *
- * @return tunnel handler, NULL if doesn't exist
- */
-static struct MeshTunnel *
-tunnel_get_by_local_id (struct MeshClient *c, MESH_TunnelNumber tid)
-{
- if (tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
- {
- return tunnel_get_incoming (tid);
- }
- else
- {
- struct GNUNET_HashCode hash;
-
- GMC_hash32 (tid, &hash);
- return GNUNET_CONTAINER_multihashmap_get (c->own_tunnels, &hash);
- }
-}
-
-
-/**
- * Search for a tunnel by global ID using PEER_ID
- *
- * @param pi owner of the tunnel
- * @param tid global tunnel number
- *
- * @return tunnel handler, NULL if doesn't exist
- */
-static struct MeshTunnel *
-tunnel_get_by_pi (GNUNET_PEER_Id pi, MESH_TunnelNumber tid)
-{
- struct MESH_TunnelID id;
- struct GNUNET_HashCode hash;
-
- id.oid = pi;
- id.tid = tid;
-
- GNUNET_CRYPTO_hash (&id, sizeof (struct MESH_TunnelID), &hash);
- return GNUNET_CONTAINER_multihashmap_get (tunnels, &hash);
-}
-
-
-/**
- * Search for a tunnel by global ID using full PeerIdentities
- *
- * @param oid owner of the tunnel
- * @param tid global tunnel number
- *
- * @return tunnel handler, NULL if doesn't exist
- */
-static struct MeshTunnel *
-tunnel_get (const struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid)
-{
- return tunnel_get_by_pi (GNUNET_PEER_search (oid), tid);
-}
-
-
-/**
- * Add a client to a tunnel, initializing all needed data structures.
- *
- * @param t Tunnel to which add the client.
- * @param c Client which to add to the tunnel.
- */
-static void
-tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c)
-{
- struct GNUNET_HashCode hash;
-
- if (NULL != t->client)
- {
- GNUNET_break(0);
- return;
- }
- GMC_hash32 (t->local_tid_dest, &hash);
- if (GNUNET_OK !=
- GNUNET_CONTAINER_multihashmap_put (c->incoming_tunnels, &hash, t,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
- {
- GNUNET_break (0);
- return;
- }
- if (GNUNET_OK !=
- GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
- {
- GNUNET_break (0);
- return;
- }
- t->client = c;
-}
-
-
-static void
-tunnel_use_path (struct MeshTunnel *t, struct MeshPeerPath *p)
-{
- unsigned int own_pos;
-
- for (own_pos = 0; own_pos < p->length; own_pos++)
- {
- if (p->peers[own_pos] == myid)
- break;
- }
- if (own_pos > p->length - 1)
- {
- GNUNET_break (0);
- return;
- }
-
- if (own_pos < p->length - 1)
- t->next_hop = p->peers[own_pos + 1];
- else
- t->next_hop = p->peers[own_pos];
- GNUNET_PEER_change_rc (t->next_hop, 1);
- if (0 < own_pos)
- t->prev_hop = p->peers[own_pos - 1];
- else
- t->prev_hop = p->peers[0];
- GNUNET_PEER_change_rc (t->prev_hop, 1);
-
- if (NULL != t->path)
- path_destroy (t->path);
- t->path = path_duplicate (p);
- if (0 == own_pos)
- {
- if (GNUNET_SCHEDULER_NO_TASK != t->maintenance_task)
- GNUNET_SCHEDULER_cancel (t->maintenance_task);
- t->maintenance_task = GNUNET_SCHEDULER_add_delayed (refresh_path_time,
- &path_refresh, t);
- }
-}
-
-
-/**
- * Notifies a tunnel that a connection has broken that affects at least
- * some of its peers. Sends a notification towards the root of the tree.
- * In case the peer is the owner of the tree, notifies the client that owns
- * the tunnel and tries to reconnect.
- *
- * @param t Tunnel affected.
- * @param p1 Peer that got disconnected from p2.
- * @param p2 Peer that got disconnected from p1.
- *
- * @return Short ID of the peer disconnected (either p1 or p2).
- * 0 if the tunnel remained unaffected.
- */
-static GNUNET_PEER_Id
-tunnel_notify_connection_broken (struct MeshTunnel *t, GNUNET_PEER_Id p1,
- GNUNET_PEER_Id p2)
-{
-// if (myid != p1 && myid != p2) FIXME
-// {
-// return;
-// }
-//
-// if (tree_get_predecessor (t->tree) != 0)
-// {
-// /* We are the peer still connected, notify owner of the disconnection. */
-// struct GNUNET_MESH_PathBroken msg;
-// struct GNUNET_PeerIdentity neighbor;
-//
-// msg.header.size = htons (sizeof (msg));
-// msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN);
-// GNUNET_PEER_resolve (t->id.oid, &msg.oid);
-// msg.tid = htonl (t->id.tid);
-// msg.peer1 = my_full_id;
-// GNUNET_PEER_resolve (pid, &msg.peer2);
-// GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &neighbor);
-// send_prebuilt_message (&msg.header, &neighbor, t);
-// }
- return 0;
-}
-
-
-/**
- * Build a local ACK message and send it to a local client.
- *
- * @param t Tunnel on which to send the ACK.
- * @param c Client to whom send the ACK.
- * @param ack Value of the ACK.
- */
-static void
-send_local_ack (struct MeshTunnel *t, struct MeshClient *c, uint32_t ack)
-{
- struct GNUNET_MESH_LocalAck msg;
-
- msg.header.size = htons (sizeof (msg));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
- msg.tunnel_id = htonl (t->owner == c ? t->local_tid : t->local_tid_dest);
- msg.ack = htonl (ack);
- GNUNET_SERVER_notification_context_unicast(nc,
- c->handle,
- &msg.header,
- GNUNET_NO);
-}
-
-/**
- * Build an ACK message and queue it to send to the given peer.
- *
- * @param t Tunnel on which to send the ACK.
- * @param peer Peer to whom send the ACK.
- * @param ack Value of the ACK.
- */
-static void
-send_ack (struct MeshTunnel *t, GNUNET_PEER_Id peer, uint32_t ack)
-{
- struct GNUNET_MESH_ACK msg;
-
- GNUNET_PEER_resolve (t->id.oid, &msg.oid);
- msg.header.size = htons (sizeof (msg));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_ACK);
- msg.pid = htonl (ack);
- msg.tid = htonl (t->id.tid);
-
- send_prebuilt_message (&msg.header, peer, t);
-}
-
-
-/**
- * Send an ACK informing the predecessor about the available buffer space.
- * In case there is no predecessor, inform the owning client.
- * If buffering is off, send only on behalf of children or self if endpoint.
- * If buffering is on, send when sent to children and buffer space is free.
- * Note that although the name is fwd_ack, the FWD mean forward *traffic*,
- * the ACK itself goes "back" (towards root).
- *
- * @param t Tunnel on which to send the ACK.
- * @param type Type of message that triggered the ACK transmission.
- */
-static void
-tunnel_send_fwd_ack (struct MeshTunnel *t, uint16_t type)
-{
- uint32_t ack;
-
- /* Is it after unicast retransmission? */
- switch (type)
- {
- case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "ACK due to FWD DATA retransmission\n");
- if (GNUNET_YES == t->nobuffer)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, nobuffer\n");
- return;
- }
- break;
- case GNUNET_MESSAGE_TYPE_MESH_ACK:
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
- break;
- case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
- case GNUNET_MESSAGE_TYPE_MESH_POLL:
- t->force_ack = GNUNET_YES;
- break;
- default:
- GNUNET_break (0);
- }
-
- /* Check if we need to transmit the ACK */
- if (t->queue_max > t->next_fc.queue_n * 4 &&
- GMC_is_pid_bigger(t->prev_fc.last_ack_sent, t->prev_fc.last_pid_recv) &&
- GNUNET_NO == t->force_ack)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, buffer free\n");
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " t->qmax: %u, t->qn: %u\n",
- t->queue_max, t->next_fc.queue_n);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " t->pid: %u, t->ack: %u\n",
- t->prev_fc.last_pid_recv, t->prev_fc.last_ack_sent);
- return;
- }
-
- /* Ok, ACK might be necessary, what PID to ACK? */
- ack = t->prev_fc.last_pid_recv + t->queue_max - t->next_fc.queue_n;
- if (ack == t->prev_fc.last_ack_sent && GNUNET_NO == t->force_ack)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending FWD ACK, not needed\n");
- return;
- }
-
- t->prev_fc.last_ack_sent = ack;
- if (NULL != t->owner)
- send_local_ack (t, t->owner, ack);
- else if (0 != t->prev_hop)
- send_ack (t, t->prev_hop, ack);
- else
- GNUNET_break (0);
- debug_fwd_ack++;
- t->force_ack = GNUNET_NO;
-}
-
-
-/**
- * Send an ACK informing the children node/client about the available
- * buffer space.
- * If buffering is off, send only on behalf of root (can be self).
- * If buffering is on, send when sent to predecessor and buffer space is free.
- * Note that although the name is bck_ack, the BCK mean backwards *traffic*,
- * the ACK itself goes "forward" (towards children/clients).
- *
- * @param t Tunnel on which to send the ACK.
- * @param type Type of message that triggered the ACK transmission.
- */
-static void
-tunnel_send_bck_ack (struct MeshTunnel *t, uint16_t type)
-{
- uint32_t ack;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending BCK ACK on tunnel %u [%u] due to %s\n",
- t->id.oid, t->id.tid, GNUNET_MESH_DEBUG_M2S(type));
- /* Is it after data to_origin retransmission? */
- switch (type)
- {
- case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- if (GNUNET_YES == t->nobuffer)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Not sending ACK, nobuffer + traffic\n");
- return;
- }
- break;
- case GNUNET_MESSAGE_TYPE_MESH_ACK:
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
- break;
- case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
- case GNUNET_MESSAGE_TYPE_MESH_POLL:
- t->force_ack = GNUNET_YES;
- break;
- default:
- GNUNET_break (0);
- }
-
- /* TODO: Check if we need to transmit the ACK (as in fwd) */
-
- ack = t->next_fc.last_pid_recv + t->queue_max - t->prev_fc.queue_n;
-
- if (t->next_fc.last_ack_sent == ack && GNUNET_NO == t->force_ack)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Not sending ACK, not needed, last ack sent was %u\n",
- t->next_fc.last_ack_sent);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Sending BCK ACK %u (last sent: %u)\n",
- ack, t->next_fc.last_ack_sent);
- t->next_fc.last_ack_sent = ack;
-
- if (NULL != t->client)
- send_local_ack (t, t->client, ack);
- else if (0 != t->next_hop)
- send_ack (t, t->next_hop, ack);
- else
- GNUNET_break (0);
- t->force_ack = GNUNET_NO;
-}
-
-
-/**
- * Modify the unicast message TID from global to local and send to client.
- *
- * @param t Tunnel on which to send the message.
- * @param msg Message to modify and send.
- */
-static void
-tunnel_send_client_ucast (struct MeshTunnel *t,
- const struct GNUNET_MESH_Data *msg)
-{
- struct GNUNET_MESH_Data *copy;
- uint16_t size = ntohs (msg->header.size);
- char cbuf[size];
-
- if (size < sizeof (struct GNUNET_MESH_Data) +
- sizeof (struct GNUNET_MessageHeader))
- {
- GNUNET_break_op (0);
- return;
- }
- if (NULL == t->client)
- {
- GNUNET_break (0);
- return;
- }
- copy = (struct GNUNET_MESH_Data *) cbuf;
- memcpy (copy, msg, size);
- copy->tid = htonl (t->local_tid_dest);
- GNUNET_SERVER_notification_context_unicast (nc, t->client->handle,
- &copy->header, GNUNET_NO);
-}
-
-
-/**
- * Modify the to_origin message TID from global to local and send to client.
- *
- * @param t Tunnel on which to send the message.
- * @param msg Message to modify and send.
- */
-static void
-tunnel_send_client_to_orig (struct MeshTunnel *t,
- const struct GNUNET_MESH_Data *msg)
-{
- struct GNUNET_MESH_Data *copy;
- uint16_t size = ntohs (msg->header.size);
- char cbuf[size];
-
- if (size < sizeof (struct GNUNET_MESH_Data) +
- sizeof (struct GNUNET_MessageHeader))
- {
- GNUNET_break_op (0);
- return;
- }
- if (NULL == t->owner)
- {
- GNUNET_break (0);
- return;
- }
- copy = (struct GNUNET_MESH_Data *) cbuf;
- memcpy (cbuf, msg, size);
- copy->tid = htonl (t->local_tid);
- GNUNET_SERVER_notification_context_unicast (nc, t->owner->handle,
- &copy->header, GNUNET_NO);
-}
-
-
-/**
- * @brief Re-initiate traffic to this peer if necessary.
- *
- * Check if there is traffic queued towards this peer
- * and the core transmit handle is NULL (traffic was stalled).
- * If so, call core tmt rdy.
- *
- * @param peer_id Short ID of peer to which initiate traffic.
- */
-static void
-peer_unlock_queue(GNUNET_PEER_Id peer_id)
-{
- struct MeshPeerInfo *peer;
- struct GNUNET_PeerIdentity id;
- struct MeshPeerQueue *q;
- size_t size;
-
- peer = peer_get_short (peer_id);
- if (NULL != peer->core_transmit)
- return;
-
- q = queue_get_next (peer);
- if (NULL == q)
- {
- /* Might br multicast traffic already sent to this particular peer but
- * not to other children in this tunnel.
- * This way t->queue_n would be > 0 but the queue of this particular peer
- * would be empty.
- */
- return;
- }
- size = q->size;
- GNUNET_PEER_resolve (peer->id, &id);
- peer->core_transmit =
- GNUNET_CORE_notify_transmit_ready(core_handle,
- 0,
- 0,
- GNUNET_TIME_UNIT_FOREVER_REL,
- &id,
- size,
- &queue_send,
- peer);
- return;
-}
-
-
-/**
- * Send a message to all peers and clients in this tunnel that the tunnel
- * is no longer valid. If some peer or client should not receive the message,
- * should be zero'ed out before calling this function.
- *
- * @param t The tunnel whose peers and clients to notify.
- */
-static void
-tunnel_send_destroy (struct MeshTunnel *t)
-{
- struct GNUNET_MESH_TunnelDestroy msg;
- struct GNUNET_PeerIdentity id;
-
- msg.header.size = htons (sizeof (msg));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY);
- GNUNET_PEER_resolve (t->id.oid, &msg.oid);
- msg.tid = htonl (t->id.tid);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " sending tunnel destroy for tunnel: %s [%X]\n",
- GNUNET_i2s (&msg.oid), t->id.tid);
-
- if (NULL == t->client && 0 != t->next_hop)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " child: %u\n", t->next_hop);
- GNUNET_PEER_resolve (t->next_hop, &id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " sending forward to %s\n",
- GNUNET_i2s (&id));
- send_prebuilt_message (&msg.header, t->next_hop, t);
- }
- if (NULL == t->owner && 0 != t->prev_hop)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " parent: %u\n", t->prev_hop);
- GNUNET_PEER_resolve (t->prev_hop, &id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " sending back to %s\n",
- GNUNET_i2s (&id));
- send_prebuilt_message (&msg.header, t->prev_hop, t);
- }
- if (NULL != t->owner)
- {
- send_client_tunnel_destroy (t->owner, t);
- }
- if (NULL != t->client)
- {
- send_client_tunnel_destroy (t->client, t);
- }
-}
-
-
-/**
- * Cancel all transmissions towards a neighbor that belongs to a certain tunnel.
- *
- * @param t Tunnel which to cancel.
- * @param neighbor Short ID of the neighbor to whom cancel the transmissions.
- */
-static void
-peer_cancel_queues (GNUNET_PEER_Id neighbor, struct MeshTunnel *t)
-{
- struct MeshPeerInfo *peer_info;
- struct MeshPeerQueue *pq;
- struct MeshPeerQueue *next;
-
- if (0 == neighbor)
- return; /* Was local peer, 0'ed in tunnel_destroy_iterator */
- peer_info = peer_get_short (neighbor);
- for (pq = peer_info->queue_head; NULL != pq; pq = next)
- {
- next = pq->next;
- if (pq->tunnel == t)
- {
- if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == pq->type ||
- GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == pq->type)
- {
- /* Should have been removed on destroy children */
- GNUNET_break (0);
- }
- queue_destroy (pq, GNUNET_YES);
- }
- }
- if (NULL == peer_info->queue_head && NULL != peer_info->core_transmit)
- {
- GNUNET_CORE_notify_transmit_ready_cancel(peer_info->core_transmit);
- peer_info->core_transmit = NULL;
- }
-}
-
-
-/**
- * Destroy the tunnel.
- *
- * This function does not generate any warning traffic to clients or peers.
- *
- * Tasks:
- * Remove the tunnel from peer_info's and clients' hashmaps.
- * Cancel messages belonging to this tunnel queued to neighbors.
- * Free any allocated resources linked to the tunnel.
- *
- * @param t the tunnel to destroy
- *
- * @return GNUNET_OK on success
- */
-static int
-tunnel_destroy (struct MeshTunnel *t)
-{
- struct MeshClient *c;
- struct GNUNET_HashCode hash;
- int r;
-
- if (NULL == t)
- return GNUNET_OK;
-
- r = GNUNET_OK;
- c = t->owner;
-#if MESH_DEBUG
- {
- struct GNUNET_PeerIdentity id;
-
- GNUNET_PEER_resolve (t->id.oid, &id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "destroying tunnel %s [%x]\n",
- GNUNET_i2s (&id), t->id.tid);
- if (NULL != c)
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
- }
-#endif
-
- GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
- if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (tunnels, &hash, t))
- {
- GNUNET_break (0);
- r = GNUNET_SYSERR;
- }
-
- if (NULL != c)
- {
- GMC_hash32 (t->local_tid, &hash);
- if (GNUNET_YES !=
- GNUNET_CONTAINER_multihashmap_remove (c->own_tunnels, &hash, t))
- {
- GNUNET_break (0);
- r = GNUNET_SYSERR;
- }
- }
-
- if (NULL != t->client)
- {
- c = t->client;
- GMC_hash32 (t->local_tid_dest, &hash);
- if (GNUNET_YES !=
- GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels, &hash, t))
- {
- GNUNET_break (0);
- r = GNUNET_SYSERR;
- }
- if (GNUNET_YES !=
- GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels, &hash, t))
- {
- GNUNET_break (0);
- r = GNUNET_SYSERR;
- }
- }
-
- if (0 != t->prev_hop)
- {
- peer_cancel_queues (t->prev_hop, t);
- GNUNET_PEER_change_rc (t->prev_hop, -1);
- }
- if (0 != t->next_hop)
- {
- peer_cancel_queues (t->next_hop, t);
- GNUNET_PEER_change_rc (t->next_hop, -1);
- }
- if (0 != t->dest) {
- peer_info_remove_tunnel (peer_get_short (t->dest), t);
- }
-
- if (GNUNET_SCHEDULER_NO_TASK != t->maintenance_task)
- GNUNET_SCHEDULER_cancel (t->maintenance_task);
-
- n_tunnels--;
- GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
- path_destroy (t->path);
- GNUNET_free (t);
- return r;
-}
-
-/**
- * Tunnel is empty: destroy it.
- *
- * Notifies all participants (peers, cleints) about the destruction.
- *
- * @param t Tunnel to destroy.
- */
-static void
-tunnel_destroy_empty (struct MeshTunnel *t)
-{
- #if MESH_DEBUG
- {
- struct GNUNET_PeerIdentity id;
-
- GNUNET_PEER_resolve (t->id.oid, &id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "executing destruction of empty tunnel %s [%X]\n",
- GNUNET_i2s (&id), t->id.tid);
- }
- #endif
-
- if (GNUNET_NO == t->destroy)
- tunnel_send_destroy (t);
- if (0 == t->pending_messages)
- tunnel_destroy (t);
- else
- t->destroy = GNUNET_YES;
-}
-
-/**
- * Initialize a Flow Control structure to the initial state.
- *
- * @param fc Flow Control structure to initialize.
- */
-static void
-fc_init (struct MeshFlowControl *fc)
-{
- fc->last_pid_sent = (uint32_t) -1; /* Next (expected) = 0 */
- fc->last_pid_recv = (uint32_t) -1;
- fc->last_ack_sent = (uint32_t) -1; /* No traffic allowed yet */
- fc->last_ack_recv = (uint32_t) -1;
- fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
- fc->poll_time = GNUNET_TIME_UNIT_SECONDS;
- fc->queue_n = 0;
-}
-
-/**
- * Create a new tunnel
- *
- * @param owner Who is the owner of the tunnel (short ID).
- * @param tid Tunnel Number of the tunnel.
- * @param client Clients that owns the tunnel, NULL for foreign tunnels.
- * @param local Tunnel Number for the tunnel, for the client point of view.
- *
- * @return A new initialized tunnel. NULL on error.
- */
-static struct MeshTunnel *
-tunnel_new (GNUNET_PEER_Id owner,
- MESH_TunnelNumber tid,
- struct MeshClient *client,
- MESH_TunnelNumber local)
-{
- struct MeshTunnel *t;
- struct GNUNET_HashCode hash;
-
- if (n_tunnels >= max_tunnels && NULL == client)
- return NULL;
-
- t = GNUNET_malloc (sizeof (struct MeshTunnel));
- t->id.oid = owner;
- t->id.tid = tid;
- t->queue_max = (max_msgs_queue / max_tunnels) + 1;
- t->owner = client;
- fc_init (&t->next_fc);
- fc_init (&t->prev_fc);
- t->local_tid = local;
- n_tunnels++;
- GNUNET_STATISTICS_update (stats, "# tunnels", 1, GNUNET_NO);
-
- GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
- if (GNUNET_OK !=
- GNUNET_CONTAINER_multihashmap_put (tunnels, &hash, t,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
- {
- GNUNET_break (0);
- tunnel_destroy (t);
- if (NULL != client)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client->handle, GNUNET_SYSERR);
- }
- return NULL;
- }
-
- if (NULL != client)
- {
- GMC_hash32 (t->local_tid, &hash);
- if (GNUNET_OK !=
- GNUNET_CONTAINER_multihashmap_put (client->own_tunnels, &hash, t,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
- {
- tunnel_destroy (t);
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client->handle, GNUNET_SYSERR);
- return NULL;
- }
- }
-
- return t;
-}
-
-
-
-/**
- * Iterator for deleting each tunnel whose client endpoint disconnected.
- *
- * @param cls Closure (client that has disconnected).
- * @param key The hash of the local tunnel id (used to access the hashmap).
- * @param value The value stored at the key (tunnel to destroy).
- *
- * @return GNUNET_OK, keep iterating.
- */
-static int
-tunnel_destroy_iterator (void *cls,
- const struct GNUNET_HashCode * key,
- void *value)
-{
- struct MeshTunnel *t = value;
- struct MeshClient *c = cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Tunnel %X / %X destroy, due to client %u shutdown.\n",
- t->local_tid, t->local_tid_dest, c->id);
- client_delete_tunnel (c, t);
- if (c == t->client)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Client %u is destination.\n", c->id);
- t->client = NULL;
- if (0 != t->next_hop) { /* destroy could come before a path is used */
- GNUNET_PEER_change_rc (t->next_hop, -1);
- t->next_hop = 0;
- }
- }
- else if (c == t->owner)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Client %u is owner.\n", c->id);
- t->owner = NULL;
- if (0 != t->prev_hop) { /* destroy could come before a path is used */
- GNUNET_PEER_change_rc (t->prev_hop, -1);
- t->prev_hop = 0;
- }
- }
- else
- {
- GNUNET_break (0);
- }
- tunnel_destroy_empty (t);
-
- return GNUNET_OK;
-}
-
-
-/**
- * Timeout function, destroys tunnel if called
- *
- * @param cls Closure (tunnel to destroy).
- * @param tc TaskContext
- */
-static void
-tunnel_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct MeshTunnel *t = cls;
- struct GNUNET_PeerIdentity id;
-
- t->maintenance_task = GNUNET_SCHEDULER_NO_TASK;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- return;
- GNUNET_PEER_resolve(t->id.oid, &id);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Tunnel %s [%X] timed out. Destroying.\n",
- GNUNET_i2s(&id), t->id.tid);
- if (NULL != t->client)
- send_client_tunnel_destroy (t->client, t);
- tunnel_destroy (t); /* Do not notify other */
-}
-
-
-/**
- * Resets the tunnel timeout. Starts it if no timeout was running.
- *
- * @param t Tunnel whose timeout to reset.
- *
- * TODO use heap to improve efficiency of scheduler.
- */
-static void
-tunnel_reset_timeout (struct MeshTunnel *t)
-{
- if (NULL != t->owner || 0 != t->local_tid || 0 == t->prev_hop)
- return;
- if (GNUNET_SCHEDULER_NO_TASK != t->maintenance_task)
- GNUNET_SCHEDULER_cancel (t->maintenance_task);
- t->maintenance_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
- (refresh_path_time, 4), &tunnel_timeout, t);
-}
-
-
-/******************************************************************************/
-/**************** MESH NETWORK HANDLER HELPERS ***********************/
-/******************************************************************************/
-
-/**
- * Function to send a create path packet to a peer.
- *
- * @param cls closure
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
- */
-static size_t
-send_core_path_create (void *cls, size_t size, void *buf)
-{
- struct MeshTunnel *t = cls;
- struct GNUNET_MESH_CreateTunnel *msg;
- struct GNUNET_PeerIdentity *peer_ptr;
- struct MeshPeerPath *p = t->path;
- size_t size_needed;
- uint32_t opt;
- int i;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CREATE PATH sending...\n");
- size_needed =
- sizeof (struct GNUNET_MESH_CreateTunnel) +
- p->length * sizeof (struct GNUNET_PeerIdentity);
-
- if (size < size_needed || NULL == buf)
- {
- GNUNET_break (0);
- return 0;
- }
- msg = (struct GNUNET_MESH_CreateTunnel *) buf;
- msg->header.size = htons (size_needed);
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE);
- msg->tid = ntohl (t->id.tid);
-
- opt = 0;
- if (GNUNET_YES == t->nobuffer)
- opt |= MESH_TUNNEL_OPT_NOBUFFER;
- msg->opt = htonl (opt);
- msg->port = htonl (t->port);
-
- peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1];
- for (i = 0; i < p->length; i++)
- {
- GNUNET_PEER_resolve (p->peers[i], peer_ptr++);
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "CREATE PATH (%u bytes long) sent!\n", size_needed);
- return size_needed;
-}
-
-
-/**
- * Creates a path ack message in buf and frees all unused resources.
- *
- * @param cls closure (MeshTransmissionDescriptor)
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
- */
-static size_t
-send_core_path_ack (void *cls, size_t size, void *buf)
-{
- struct MeshTunnel *t = cls;
- struct GNUNET_MESH_PathACK *msg = buf;
-
- GNUNET_assert (NULL != t);
- if (sizeof (struct GNUNET_MESH_PathACK) > size)
- {
- GNUNET_break (0);
- return 0;
- }
- t->prev_fc.last_ack_sent = t->nobuffer ? 0 : t->queue_max - 1;
- msg->header.size = htons (sizeof (struct GNUNET_MESH_PathACK));
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_ACK);
- GNUNET_PEER_resolve (t->id.oid, &msg->oid);
- msg->tid = htonl (t->id.tid);
- msg->peer_id = my_full_id;
- msg->ack = htonl (t->prev_fc.last_ack_sent);
-
- /* TODO add signature */
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH ACK sent!\n");
- return sizeof (struct GNUNET_MESH_PathACK);
-}
-
-
-/**
- * Free a transmission that was already queued with all resources
- * associated to the request.
- *
- * @param queue Queue handler to cancel.
- * @param clear_cls Is it necessary to free associated cls?
- */
-static void
-queue_destroy (struct MeshPeerQueue *queue, int clear_cls)
-{
- struct MeshFlowControl *fc;
-
- if (GNUNET_YES == clear_cls)
- {
- switch (queue->type)
- {
- case GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY:
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, " cancelling TUNNEL_DESTROY\n");
- GNUNET_break (GNUNET_YES == queue->tunnel->destroy);
- /* fall through */
- case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- case GNUNET_MESSAGE_TYPE_MESH_ACK:
- case GNUNET_MESSAGE_TYPE_MESH_POLL:
- case GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE:
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " prebuilt message\n");
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " type %s\n",
- GNUNET_MESH_DEBUG_M2S (queue->type));
- break;
- case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " type create path\n");
- break;
- default:
- GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- " type %s unknown!\n",
- GNUNET_MESH_DEBUG_M2S (queue->type));
- }
- GNUNET_free_non_null (queue->cls);
- }
- GNUNET_CONTAINER_DLL_remove (queue->peer->queue_head,
- queue->peer->queue_tail,
- queue);
-
- /* Delete from appropriate fc in the tunnel */
- if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == queue->type ||
- GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == queue->type )
- {
- if (queue->peer->id == queue->tunnel->prev_hop)
- fc = &queue->tunnel->prev_fc;
- else if (queue->peer->id == queue->tunnel->next_hop)
- fc = &queue->tunnel->next_fc;
- else
- {
- GNUNET_break (0);
- return;
- }
- fc->queue_n--;
- }
- GNUNET_free (queue);
-}
-
-
-/**
- * @brief Get the next transmittable message from the queue.
- *
- * This will be the head, except in the case of being a data packet
- * not allowed by the destination peer.
- *
- * @param peer Destination peer.
- *
- * @return The next viable MeshPeerQueue element to send to that peer.
- * NULL when there are no transmittable messages.
- */
-struct MeshPeerQueue *
-queue_get_next (const struct MeshPeerInfo *peer)
-{
- struct MeshPeerQueue *q;
-
- struct GNUNET_MESH_Data *dmsg;
- struct MeshTunnel* t;
- uint32_t pid;
- uint32_t ack;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* selecting message\n");
- for (q = peer->queue_head; NULL != q; q = q->next)
- {
- t = q->tunnel;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "* %s\n",
- GNUNET_MESH_DEBUG_M2S (q->type));
- dmsg = (struct GNUNET_MESH_Data *) q->cls;
- pid = ntohl (dmsg->pid);
- switch (q->type)
- {
- case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- ack = t->next_fc.last_ack_recv;
- break;
- case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- ack = t->prev_fc.last_ack_recv;
- break;
- default:
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "* OK!\n");
- return q;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "* ACK: %u, PID: %u\n",
- ack, pid);
- if (GNUNET_NO == GMC_is_pid_bigger (pid, ack))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "* OK!\n");
- return q;
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "* NEXT!\n");
- }
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "* nothing found\n");
- return NULL;
-}
-
-
-static size_t
-queue_send (void *cls, size_t size, void *buf)
-{
- struct MeshPeerInfo *peer = cls;
- struct GNUNET_MessageHeader *msg;
- struct MeshPeerQueue *queue;
- struct MeshTunnel *t;
- struct GNUNET_PeerIdentity dst_id;
- struct MeshFlowControl *fc;
- size_t data_size;
- uint32_t pid;
- uint16_t type;
-
- peer->core_transmit = NULL;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* Queue send\n");
- queue = queue_get_next (peer);
-
- /* Queue has no internal mesh traffic nor sendable payload */
- if (NULL == queue)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* not ready, return\n");
- if (NULL == peer->queue_head)
- GNUNET_break (0); /* Core tmt_rdy should've been canceled */
- return 0;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* not empty\n");
-
- GNUNET_PEER_resolve (peer->id, &dst_id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "* towards %s\n",
- GNUNET_i2s (&dst_id));
- /* Check if buffer size is enough for the message */
- if (queue->size > size)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "* not enough room, reissue\n");
- peer->core_transmit =
- GNUNET_CORE_notify_transmit_ready (core_handle,
- GNUNET_NO,
- 0,
- GNUNET_TIME_UNIT_FOREVER_REL,
- &dst_id,
- queue->size,
- &queue_send,
- peer);
- return 0;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* size ok\n");
-
- t = queue->tunnel;
- GNUNET_assert (0 < t->pending_messages);
- t->pending_messages--;
- type = 0;
-
- /* Fill buf */
- switch (queue->type)
- {
- case 0:
- case GNUNET_MESSAGE_TYPE_MESH_ACK:
- case GNUNET_MESSAGE_TYPE_MESH_POLL:
- case GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN:
- case GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY:
- case GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY:
- case GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE:
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "* raw: %s\n",
- GNUNET_MESH_DEBUG_M2S (queue->type));
- /* Fall through */
- case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- data_size = send_core_data_raw (queue->cls, size, buf);
- msg = (struct GNUNET_MessageHeader *) buf;
- type = ntohs (msg->type);
- break;
- case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* path create\n");
- data_size = send_core_path_create (queue->cls, size, buf);
- break;
- case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* path ack\n");
- data_size = send_core_path_ack (queue->cls, size, buf);
- break;
- default:
- GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "* type unknown: %u\n",
- queue->type);
- data_size = 0;
- }
-
- /* Free queue, but cls was freed by send_core_* */
- queue_destroy (queue, GNUNET_NO);
-
- /* Send ACK if needed, after accounting for sent ID in fc->queue_n */
- pid = ((struct GNUNET_MESH_Data *) buf)->pid;
- switch (type)
- {
- case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- t->next_fc.last_pid_sent = pid;
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
- break;
- case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- t->prev_fc.last_pid_sent = pid;
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
- break;
- default:
- break;
- }
-
- if (GNUNET_YES == t->destroy && 0 == t->pending_messages)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* destroying tunnel!\n");
- tunnel_destroy (t);
- }
-
- /* If more data in queue, send next */
- queue = queue_get_next (peer);
- if (NULL != queue)
- {
- struct GNUNET_PeerIdentity id;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* more data!\n");
- GNUNET_PEER_resolve (peer->id, &id);
- peer->core_transmit =
- GNUNET_CORE_notify_transmit_ready(core_handle,
- 0,
- 0,
- GNUNET_TIME_UNIT_FOREVER_REL,
- &id,
- queue->size,
- &queue_send,
- peer);
- }
- else if (NULL != peer->queue_head)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "* %s stalled\n",
- GNUNET_i2s (&my_full_id));
- if (peer->id == t->next_hop)
- fc = &t->next_fc;
- else if (peer->id == t->prev_hop)
- fc = &t->prev_fc;
- else
- {
- GNUNET_break (0);
- fc = NULL;
- }
- if (NULL != fc && GNUNET_SCHEDULER_NO_TASK == fc->poll_task)
- {
- fc->t = t;
- fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
- &tunnel_poll, fc);
- }
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* Return %d\n", data_size);
- return data_size;
-}
-
-
-/**
- * @brief Queue and pass message to core when possible.
- *
- * If type is payload (UNICAST, TO_ORIGIN) checks for queue status and
- * accounts for it. In case the queue is full, the message is dropped and
- * a break issued.
- *
- * Otherwise, message is treated as internal and allowed to go regardless of
- * queue status.
- *
- * @param cls Closure (@c type dependant). It will be used by queue_send to
- * build the message to be sent if not already prebuilt.
- * @param type Type of the message, 0 for a raw message.
- * @param size Size of the message.
- * @param dst Neighbor to send message to.
- * @param t Tunnel this message belongs to.
- */
-static void
-queue_add (void *cls, uint16_t type, size_t size,
- struct MeshPeerInfo *dst, struct MeshTunnel *t)
-{
- struct MeshPeerQueue *queue;
- struct GNUNET_PeerIdentity id;
- unsigned int *n;
-
- n = NULL;
- if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == type)
- {
- n = &t->next_fc.queue_n;
- }
- else if (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == type)
- {
- n = &t->prev_fc.queue_n;
- }
- if (NULL != n)
- {
- if (*n >= t->queue_max)
- {
- GNUNET_break(0);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "queue full: %u/%u\n",
- *n, t->queue_max);
- GNUNET_STATISTICS_update(stats,
- "# messages dropped (buffer full)",
- 1, GNUNET_NO);
- return; /* Drop message */
- }
- (*n)++;
- }
- queue = GNUNET_malloc (sizeof (struct MeshPeerQueue));
- queue->cls = cls;
- queue->type = type;
- queue->size = size;
- queue->peer = dst;
- queue->tunnel = t;
- GNUNET_CONTAINER_DLL_insert_tail (dst->queue_head, dst->queue_tail, queue);
- if (NULL == dst->core_transmit)
- {
- GNUNET_PEER_resolve (dst->id, &id);
- dst->core_transmit =
- GNUNET_CORE_notify_transmit_ready (core_handle,
- 0,
- 0,
- GNUNET_TIME_UNIT_FOREVER_REL,
- &id,
- size,
- &queue_send,
- dst);
- }
- t->pending_messages++;
-}
-
-
-/******************************************************************************/
-/******************** MESH NETWORK HANDLERS **************************/
-/******************************************************************************/
-
-
-/**
- * Core handler for path creation
- *
- * @param cls closure
- * @param message message
- * @param peer peer identity this notification is about
- *
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
- */
-static int
-handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
-{
- unsigned int own_pos;
- uint16_t size;
- uint16_t i;
- MESH_TunnelNumber tid;
- struct GNUNET_MESH_CreateTunnel *msg;
- struct GNUNET_PeerIdentity *pi;
- struct MeshPeerPath *path;
- struct MeshPeerInfo *dest_peer_info;
- struct MeshPeerInfo *orig_peer_info;
- struct MeshTunnel *t;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received a path create msg [%s]\n",
- GNUNET_i2s (&my_full_id));
- size = ntohs (message->size);
- if (size < sizeof (struct GNUNET_MESH_CreateTunnel))
- {
- GNUNET_break_op (0);
- return GNUNET_OK;
- }
-
- size -= sizeof (struct GNUNET_MESH_CreateTunnel);
- if (size % sizeof (struct GNUNET_PeerIdentity))
- {
- GNUNET_break_op (0);
- return GNUNET_OK;
- }
- size /= sizeof (struct GNUNET_PeerIdentity);
- if (size < 1)
- {
- GNUNET_break_op (0);
- return GNUNET_OK;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " path has %u hops.\n", size);
- msg = (struct GNUNET_MESH_CreateTunnel *) message;
-
- tid = ntohl (msg->tid);
- pi = (struct GNUNET_PeerIdentity *) &msg[1];
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " path is for tunnel %s[%X].\n", GNUNET_i2s (pi), tid);
- t = tunnel_get (pi, tid);
- if (NULL == t) /* might be a local tunnel */
- {
- uint32_t opt;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Creating tunnel\n");
- t = tunnel_new (GNUNET_PEER_intern (pi), tid, NULL, 0);
- if (NULL == t)
- {
- GNUNET_break (0);
- return GNUNET_OK;
- }
- t->port = ntohl (msg->port);
- opt = ntohl (msg->opt);
- if (0 != (opt & MESH_TUNNEL_OPT_NOBUFFER))
- {
- t->nobuffer = GNUNET_YES;
- t->queue_max = 1;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " nobuffer:%d\n", t->nobuffer);
-
- tunnel_reset_timeout (t);
- }
- t->state = MESH_TUNNEL_WAITING;
- dest_peer_info =
- GNUNET_CONTAINER_multihashmap_get (peers, &pi[size - 1].hashPubKey);
- if (NULL == dest_peer_info)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Creating PeerInfo for destination.\n");
- dest_peer_info = GNUNET_malloc (sizeof (struct MeshPeerInfo));
- dest_peer_info->id = GNUNET_PEER_intern (&pi[size - 1]);
- GNUNET_CONTAINER_multihashmap_put (peers, &pi[size - 1].hashPubKey,
- dest_peer_info,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
- }
- orig_peer_info = GNUNET_CONTAINER_multihashmap_get (peers, &pi->hashPubKey);
- if (NULL == orig_peer_info)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Creating PeerInfo for origin.\n");
- orig_peer_info = GNUNET_malloc (sizeof (struct MeshPeerInfo));
- orig_peer_info->id = GNUNET_PEER_intern (pi);
- GNUNET_CONTAINER_multihashmap_put (peers, &pi->hashPubKey, orig_peer_info,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Creating path...\n");
- path = path_new (size);
- own_pos = 0;
- for (i = 0; i < size; i++)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ... adding %s\n",
- GNUNET_i2s (&pi[i]));
- path->peers[i] = GNUNET_PEER_intern (&pi[i]);
- if (path->peers[i] == myid)
- own_pos = i;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Own position: %u\n", own_pos);
- if (own_pos == 0 && path->peers[own_pos] != myid)
- {
- /* create path: self not found in path through self */
- GNUNET_break_op (0);
- path_destroy (path);
- tunnel_destroy (t);
- return GNUNET_OK;
- }
- path_add_to_peers (path, GNUNET_NO);
- tunnel_use_path (t, path);
-
- peer_info_add_tunnel (dest_peer_info, t);
-
- if (own_pos == size - 1)
- {
- struct MeshClient *c;
- struct GNUNET_HashCode hc;
-
- /* Find target client */
- GMC_hash32 (t->port, &hc);
- c = GNUNET_CONTAINER_multihashmap_get (ports, &hc);
- if (NULL == c)
- {
- /* TODO send reject */
- return GNUNET_OK;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " It's for us!\n");
- peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_YES);
-
- /* Assign local tid */
- while (NULL != tunnel_get_incoming (next_local_tid))
- next_local_tid = (next_local_tid + 1) | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
- t->local_tid_dest = next_local_tid++;
- next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
-
- tunnel_add_client (t, c);
- send_client_tunnel_create (t);
- send_path_ack (t);
- }
- else
- {
- struct MeshPeerPath *path2;
-
- t->next_hop = path->peers[own_pos + 1];
- GNUNET_PEER_change_rc(t->next_hop, 1);
-
- /* It's for somebody else! Retransmit. */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Retransmitting.\n");
- path2 = path_duplicate (path);
- peer_info_add_path (dest_peer_info, path2, GNUNET_NO);
- peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_NO);
- send_create_path (t);
- }
- return GNUNET_OK;
-}
-
-
-
-/**
- * Core handler for path ACKs
- *
- * @param cls closure
- * @param message message
- * @param peer peer identity this notification is about
- *
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
- */
-static int
-handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_PathACK *msg;
- struct MeshPeerInfo *peer_info;
- struct MeshPeerPath *p;
- struct MeshTunnel *t;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received a path ACK msg [%s]\n",
- GNUNET_i2s (&my_full_id));
- msg = (struct GNUNET_MESH_PathACK *) message;
- t = tunnel_get (&msg->oid, ntohl(msg->tid));
- if (NULL == t)
- {
- /* TODO notify that we don't know the tunnel */
- GNUNET_STATISTICS_update (stats, "# control on unknown tunnel", 1, GNUNET_NO);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " don't know the tunnel %s [%X]!\n",
- GNUNET_i2s (&msg->oid), ntohl(msg->tid));
- return GNUNET_OK;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %s [%X]\n",
- GNUNET_i2s (&msg->oid), ntohl(msg->tid));
-
- peer_info = peer_get (&msg->peer_id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by peer %s\n",
- GNUNET_i2s (&msg->peer_id));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " via peer %s\n",
- GNUNET_i2s (peer));
-
- /* Add path to peers? */
- p = t->path;
- if (NULL != p)
- {
- path_add_to_peers (p, GNUNET_YES);
- }
- else
- {
- GNUNET_break (0);
- }
- t->state = MESH_TUNNEL_READY;
- t->next_fc.last_ack_recv = (NULL == t->client) ? ntohl (msg->ack) : 0;
- t->prev_fc.last_ack_sent = ntohl (msg->ack);
-
- /* Message for us? */
- if (0 == memcmp (&msg->oid, &my_full_id, sizeof (struct GNUNET_PeerIdentity)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " It's for us!\n");
- if (NULL == t->owner)
- {
- GNUNET_break_op (0);
- return GNUNET_OK;
- }
- if (NULL != peer_info->dhtget)
- {
- GNUNET_DHT_get_stop (peer_info->dhtget);
- peer_info->dhtget = NULL;
- }
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK);
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK);
- return GNUNET_OK;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " not for us, retransmitting...\n");
- peer_info = peer_get (&msg->oid);
- send_prebuilt_message (message, t->prev_hop, t);
- return GNUNET_OK;
-}
-
-
-/**
- * Core handler for notifications of broken paths
- *
- * @param cls closure
- * @param message message
- * @param peer peer identity this notification is about
- *
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
- */
-static int
-handle_mesh_path_broken (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_PathBroken *msg;
- struct MeshTunnel *t;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received a PATH BROKEN msg from %s\n", GNUNET_i2s (peer));
- msg = (struct GNUNET_MESH_PathBroken *) message;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " regarding %s\n",
- GNUNET_i2s (&msg->peer1));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " regarding %s\n",
- GNUNET_i2s (&msg->peer2));
- t = tunnel_get (&msg->oid, ntohl (msg->tid));
- if (NULL == t)
- {
- GNUNET_break_op (0);
- return GNUNET_OK;
- }
- tunnel_notify_connection_broken (t, GNUNET_PEER_search (&msg->peer1),
- GNUNET_PEER_search (&msg->peer2));
- return GNUNET_OK;
-
-}
-
-
-/**
- * Core handler for tunnel destruction
- *
- * @param cls closure
- * @param message message
- * @param peer peer identity this notification is about
- *
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
- */
-static int
-handle_mesh_tunnel_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_TunnelDestroy *msg;
- struct MeshTunnel *t;
-
- msg = (struct GNUNET_MESH_TunnelDestroy *) message;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Got a TUNNEL DESTROY packet from %s\n",
- GNUNET_i2s (peer));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " for tunnel %s [%u]\n",
- GNUNET_i2s (&msg->oid), ntohl (msg->tid));
- t = tunnel_get (&msg->oid, ntohl (msg->tid));
- if (NULL == t)
- {
- /* Probably already got the message from another path,
- * destroyed the tunnel and retransmitted to children.
- * Safe to ignore.
- */
- GNUNET_STATISTICS_update (stats, "# control on unknown tunnel",
- 1, GNUNET_NO);
- return GNUNET_OK;
- }
- if (t->local_tid_dest >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "INCOMING TUNNEL %X %X\n",
- t->local_tid, t->local_tid_dest);
- }
- if (GNUNET_PEER_search (peer) == t->prev_hop)
- {
- // TODO check owner's signature
- // TODO add owner's signatue to tunnel for retransmission
- peer_cancel_queues (t->prev_hop, t);
- GNUNET_PEER_change_rc (t->prev_hop, -1);
- t->prev_hop = 0;
- }
- else if (GNUNET_PEER_search (peer) == t->next_hop)
- {
- // TODO check dest's signature
- // TODO add dest's signatue to tunnel for retransmission
- peer_cancel_queues (t->next_hop, t);
- GNUNET_PEER_change_rc (t->next_hop, -1);
- t->next_hop = 0;
- }
- else
- {
- GNUNET_break_op (0);
- // TODO check both owner AND destination's signature to see which matches
- // TODO restransmit in appropriate direction
- return GNUNET_OK;
- }
- tunnel_destroy_empty (t);
-
- // TODO: add timeout to destroy the tunnel anyway
- return GNUNET_OK;
-}
-
-
-/**
- * Core handler for mesh network traffic going from the origin to a peer
- *
- * @param cls closure
- * @param peer peer identity this notification is about
- * @param message message
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
- */
-static int
-handle_mesh_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_Data *msg;
- struct MeshTunnel *t;
- uint32_t pid;
- uint32_t ttl;
- size_t size;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a unicast packet from %s\n",
- GNUNET_i2s (peer));
- /* Check size */
- size = ntohs (message->size);
- if (size <
- sizeof (struct GNUNET_MESH_Data) +
- sizeof (struct GNUNET_MessageHeader))
- {
- GNUNET_break (0);
- return GNUNET_OK;
- }
- msg = (struct GNUNET_MESH_Data *) message;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " of type %s\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
- /* Check tunnel */
- t = tunnel_get (&msg->oid, ntohl (msg->tid));
- if (NULL == t)
- {
- /* TODO notify back: we don't know this tunnel */
- GNUNET_STATISTICS_update (stats, "# data on unknown tunnel", 1, GNUNET_NO);
- GNUNET_break_op (0);
- return GNUNET_OK;
- }
- pid = ntohl (msg->pid);
- if (t->prev_fc.last_pid_recv == pid)
- {
- GNUNET_STATISTICS_update (stats, "# duplicate PID drops", 1, GNUNET_NO);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- " Already seen pid %u, DROPPING!\n", pid);
- return GNUNET_OK;
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " pid %u not seen yet, forwarding\n", pid);
- }
-
- if (GMC_is_pid_bigger (pid, t->prev_fc.last_ack_sent))
- {
- GNUNET_STATISTICS_update (stats, "# unsolicited unicast", 1, GNUNET_NO);
- GNUNET_break_op (0);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received PID %u, ACK %u\n",
- pid, t->prev_fc.last_ack_sent);
- tunnel_send_fwd_ack(t, GNUNET_MESSAGE_TYPE_MESH_POLL);
- return GNUNET_OK;
- }
- t->prev_fc.last_pid_recv = pid;
-
- tunnel_reset_timeout (t);
- if (t->dest == myid)
- {
- /* TODO signature verification */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " it's for us! sending to clients...\n");
- GNUNET_STATISTICS_update (stats, "# unicast received", 1, GNUNET_NO);
- tunnel_send_client_ucast (t, msg);
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
- return GNUNET_OK;
- }
- if (0 == t->next_hop)
- {
- GNUNET_break (0);
- return GNUNET_OK;
- }
- ttl = ntohl (msg->ttl);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ttl: %u\n", ttl);
- if (ttl == 0)
- {
- GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
- return GNUNET_OK;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " not for us, retransmitting...\n");
-
- send_prebuilt_message (message, t->next_hop, t);
- GNUNET_STATISTICS_update (stats, "# unicast forwarded", 1, GNUNET_NO);
- return GNUNET_OK;
-}
-
-
-/**
- * Core handler for mesh network traffic toward the owner of a tunnel
- *
- * @param cls closure
- * @param message message
- * @param peer peer identity this notification is about
- *
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
- */
-static int
-handle_mesh_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_Data *msg;
- struct MeshTunnel *t;
- size_t size;
- uint32_t pid;
- uint32_t ttl;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a ToOrigin packet from %s\n",
- GNUNET_i2s (peer));
- size = ntohs (message->size);
- if (size < sizeof (struct GNUNET_MESH_Data) + /* Payload must be */
- sizeof (struct GNUNET_MessageHeader)) /* at least a header */
- {
- GNUNET_break_op (0);
- return GNUNET_OK;
- }
- msg = (struct GNUNET_MESH_Data *) message;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " of type %s\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
- t = tunnel_get (&msg->oid, ntohl (msg->tid));
- pid = ntohl (msg->pid);
-
- if (NULL == t)
- {
- /* TODO notify that we dont know this tunnel (whom)? */
- GNUNET_STATISTICS_update (stats, "# data on unknown tunnel", 1, GNUNET_NO);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received to_origin with PID %u on unknown tunnel %s [%u]\n",
- pid, GNUNET_i2s (&msg->oid), ntohl (msg->tid));
- return GNUNET_OK;
- }
-
- if (t->next_fc.last_pid_recv == pid)
- {
- /* already seen this packet, drop */
- GNUNET_STATISTICS_update (stats, "# duplicate PID drops BCK", 1, GNUNET_NO);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Already seen pid %u, DROPPING!\n", pid);
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
- return GNUNET_OK;
- }
-
- if (GMC_is_pid_bigger (pid, t->next_fc.last_ack_sent))
- {
- GNUNET_STATISTICS_update (stats, "# unsolicited to_orig", 1, GNUNET_NO);
- GNUNET_break_op (0);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received PID %u, ACK %u\n",
- pid, t->next_fc.last_ack_sent);
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
- return GNUNET_OK;
- }
- t->next_fc.last_pid_recv = pid;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " pid %u not seen yet, forwarding\n", pid);
-
- if (myid == t->id.oid)
- {
- /* TODO signature verification */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " it's for us! sending to clients...\n");
- GNUNET_STATISTICS_update (stats, "# to origin received", 1, GNUNET_NO);
- tunnel_send_client_to_orig (t, msg);
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
- return GNUNET_OK;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " not for us, retransmitting...\n");
-
- if (0 == t->prev_hop) /* No owner AND no prev hop */
- {
- if (GNUNET_YES == t->destroy)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "to orig received on a dying tunnel %s [%X]\n",
- GNUNET_i2s (&msg->oid), ntohl(msg->tid));
- return GNUNET_OK;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "unknown to origin at %s\n",
- GNUNET_i2s (&my_full_id));
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "from peer %s\n",
- GNUNET_i2s (peer));
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "on tunnel %s [%X]\n",
- GNUNET_i2s (&msg->oid), ntohl(msg->tid));
- return GNUNET_OK;
- }
- ttl = ntohl (msg->ttl);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ttl: %u\n", ttl);
- if (ttl == 0)
- {
- GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
- return GNUNET_OK;
- }
- send_prebuilt_message (message, t->prev_hop, t);
- GNUNET_STATISTICS_update (stats, "# to origin forwarded", 1, GNUNET_NO);
-
- return GNUNET_OK;
-}
-
-
-/**
- * Core handler for mesh network traffic point-to-point acks.
- *
- * @param cls closure
- * @param message message
- * @param peer peer identity this notification is about
- *
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
- */
-static int
-handle_mesh_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_ACK *msg;
- struct MeshTunnel *t;
- GNUNET_PEER_Id id;
- uint32_t ack;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got an ACK packet from %s!\n",
- GNUNET_i2s (peer));
- msg = (struct GNUNET_MESH_ACK *) message;
-
- t = tunnel_get (&msg->oid, ntohl (msg->tid));
-
- if (NULL == t)
- {
- /* TODO notify that we dont know this tunnel (whom)? */
- GNUNET_STATISTICS_update (stats, "# ack on unknown tunnel", 1, GNUNET_NO);
- return GNUNET_OK;
- }
- ack = ntohl (msg->pid);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ACK %u\n", ack);
-
- /* Is this a forward or backward ACK? */
- id = GNUNET_PEER_search (peer);
- if (t->next_hop == id)
- {
- debug_fwd_ack++;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " FWD ACK\n");
- if (GNUNET_SCHEDULER_NO_TASK != t->next_fc.poll_task &&
- GMC_is_pid_bigger (ack, t->next_fc.last_ack_recv))
- {
- GNUNET_SCHEDULER_cancel (t->next_fc.poll_task);
- t->next_fc.poll_task = GNUNET_SCHEDULER_NO_TASK;
- t->next_fc.poll_time = GNUNET_TIME_UNIT_SECONDS;
- }
- t->next_fc.last_ack_recv = ack;
- peer_unlock_queue (t->next_hop);
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
- }
- else if (t->prev_hop == id)
- {
- debug_bck_ack++;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " BCK ACK\n");
- if (GNUNET_SCHEDULER_NO_TASK != t->prev_fc.poll_task &&
- GMC_is_pid_bigger (ack, t->prev_fc.last_ack_recv))
- {
- GNUNET_SCHEDULER_cancel (t->prev_fc.poll_task);
- t->prev_fc.poll_task = GNUNET_SCHEDULER_NO_TASK;
- t->prev_fc.poll_time = GNUNET_TIME_UNIT_SECONDS;
- }
- t->prev_fc.last_ack_recv = ack;
- peer_unlock_queue (t->prev_hop);
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
- }
- else
- GNUNET_break_op (0);
- return GNUNET_OK;
-}
-
-
-/**
- * Core handler for mesh network traffic point-to-point ack polls.
- *
- * @param cls closure
- * @param message message
- * @param peer peer identity this notification is about
- *
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
- */
-static int
-handle_mesh_poll (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_Poll *msg;
- struct MeshTunnel *t;
- GNUNET_PEER_Id id;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got an POLL packet from %s!\n",
- GNUNET_i2s (peer));
-
- msg = (struct GNUNET_MESH_Poll *) message;
-
- t = tunnel_get (&msg->oid, ntohl (msg->tid));
-
- if (NULL == t)
- {
- /* TODO notify that we dont know this tunnel (whom)? */
- GNUNET_STATISTICS_update (stats, "# poll on unknown tunnel", 1, GNUNET_NO);
- GNUNET_break_op (0);
- return GNUNET_OK;
- }
-
- /* Is this a forward or backward ACK? */
- id = GNUNET_PEER_search(peer);
- if (t->next_hop == id)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " from FWD\n");
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
- }
- else if (t->prev_hop == id)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " from BCK\n");
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
- }
- else
- GNUNET_break (0);
-
- return GNUNET_OK;
-}
-
-
-/**
- * Core handler for mesh keepalives.
- *
- * @param cls closure
- * @param message message
- * @param peer peer identity this notification is about
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
- *
- * TODO: Check who we got this from, to validate route.
- */
-static int
-handle_mesh_keepalive (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_TunnelKeepAlive *msg;
- struct MeshTunnel *t;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a keepalive packet from %s\n",
- GNUNET_i2s (peer));
-
- msg = (struct GNUNET_MESH_TunnelKeepAlive *) message;
- t = tunnel_get (&msg->oid, ntohl (msg->tid));
-
- if (NULL == t)
- {
- /* TODO notify that we dont know that tunnel */
- GNUNET_STATISTICS_update (stats, "# keepalive on unknown tunnel", 1,
- GNUNET_NO);
- return GNUNET_OK;
- }
-
- tunnel_reset_timeout (t);
-
- GNUNET_STATISTICS_update (stats, "# keepalives forwarded", 1, GNUNET_NO);
- send_prebuilt_message (message, t->next_hop, t);
- return GNUNET_OK;
- }
-
-
-
-/**
- * Functions to handle messages from core
- */
-static struct GNUNET_CORE_MessageHandler core_handlers[] = {
- {&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0},
- {&handle_mesh_path_broken, GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN,
- sizeof (struct GNUNET_MESH_PathBroken)},
- {&handle_mesh_tunnel_destroy, GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY,
- sizeof (struct GNUNET_MESH_TunnelDestroy)},
- {&handle_mesh_unicast, GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0},
- {&handle_mesh_keepalive, GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE,
- sizeof (struct GNUNET_MESH_TunnelKeepAlive)},
- {&handle_mesh_to_orig, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0},
- {&handle_mesh_ack, GNUNET_MESSAGE_TYPE_MESH_ACK,
- sizeof (struct GNUNET_MESH_ACK)},
- {&handle_mesh_poll, GNUNET_MESSAGE_TYPE_MESH_POLL,
- sizeof (struct GNUNET_MESH_Poll)},
- {&handle_mesh_path_ack, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK,
- sizeof (struct GNUNET_MESH_PathACK)},
- {NULL, 0, 0}
-};
-
-
-
-/******************************************************************************/
-/**************** MESH LOCAL HANDLER HELPERS ***********************/
-/******************************************************************************/
-
-
-#if LATER
-/**
- * notify_client_connection_failure: notify a client that the connection to the
- * requested remote peer is not possible (for instance, no route found)
- * Function called when the socket is ready to queue more data. "buf" will be
- * NULL and "size" zero if the socket was closed for writing in the meantime.
- *
- * @param cls closure
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
- */
-static size_t
-notify_client_connection_failure (void *cls, size_t size, void *buf)
-{
- int size_needed;
- struct MeshPeerInfo *peer_info;
- struct GNUNET_MESH_PeerControl *msg;
- struct GNUNET_PeerIdentity id;
-
- if (0 == size && NULL == buf)
- {
- // TODO retry? cancel?
- return 0;
- }
-
- size_needed = sizeof (struct GNUNET_MESH_PeerControl);
- peer_info = (struct MeshPeerInfo *) cls;
- msg = (struct GNUNET_MESH_PeerControl *) buf;
- msg->header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DISCONNECTED);
-// msg->tunnel_id = htonl(peer_info->t->tid);
- GNUNET_PEER_resolve (peer_info->id, &id);
- memcpy (&msg->peer, &id, sizeof (struct GNUNET_PeerIdentity));
-
- return size_needed;
-}
-#endif
-
-
-/**
- * Send keepalive packets for a tunnel.
- *
- * @param cls Closure (tunnel for which to send the keepalive).
- * @param tc Notification context.
- *
- * FIXME: add a refresh reset in case of normal unicast traffic is doing the job
- */
-static void
-path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct MeshTunnel *t = cls;
- struct GNUNET_MESH_TunnelKeepAlive *msg;
- size_t size = sizeof (struct GNUNET_MESH_TunnelKeepAlive);
- char cbuf[size];
-
- t->maintenance_task = GNUNET_SCHEDULER_NO_TASK;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) ||
- NULL == t->owner || 0 == t->local_tid)
- {
- return;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "sending keepalive for tunnel %d\n", t->id.tid);
-
- msg = (struct GNUNET_MESH_TunnelKeepAlive *) cbuf;
- msg->header.size = htons (size);
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE);
- msg->oid = my_full_id;
- msg->tid = htonl (t->id.tid);
- send_prebuilt_message (&msg->header, t->next_hop, t);
-
- t->maintenance_task =
- GNUNET_SCHEDULER_add_delayed (refresh_path_time, &path_refresh, t);
-}
-
-
-/**
- * Function to process paths received for a new peer addition. The recorded
- * paths form the initial tunnel, which can be optimized later.
- * Called on each result obtained for the DHT search.
- *
- * @param cls closure
- * @param exp when will this value expire
- * @param key key of the result
- * @param get_path path of the get request
- * @param get_path_length lenght of get_path
- * @param put_path path of the put request
- * @param put_path_length length of the put_path
- * @param type type of the result
- * @param size number of bytes in data
- * @param data pointer to the result data
- */
-static void
-dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
- const struct GNUNET_HashCode * key,
- const struct GNUNET_PeerIdentity *get_path,
- unsigned int get_path_length,
- const struct GNUNET_PeerIdentity *put_path,
- unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
- size_t size, const void *data)
-{
- struct MeshPeerInfo *peer = cls;
- struct MeshPeerPath *p;
- struct GNUNET_PeerIdentity pi;
- int i;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got results from DHT!\n");
- GNUNET_PEER_resolve (peer->id, &pi);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " for %s\n", GNUNET_i2s (&pi));
-
- p = path_build_from_dht (get_path, get_path_length,
- put_path, put_path_length);
- path_add_to_peers (p, GNUNET_NO);
- path_destroy (p);
- for (i = 0; i < peer->ntunnels; i++)
- {
- struct GNUNET_PeerIdentity id;
-
- GNUNET_PEER_resolve (peer->tunnels[i]->id.oid, &id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ... tunnel %s:%X (%X / %X)\n",
- GNUNET_i2s (&id), peer->tunnels[i]->id.tid,
- peer->tunnels[i]->local_tid,
- peer->tunnels[i]->local_tid_dest);
- if (peer->tunnels[i]->state == MESH_TUNNEL_SEARCHING)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ... connect!\n");
- peer_connect (peer, peer->tunnels[i]);
- }
- }
-
- return;
-}
-
-
-/******************************************************************************/
-/********************* MESH LOCAL HANDLES **************************/
-/******************************************************************************/
-
-
-/**
- * Handler for client disconnection
- *
- * @param cls closure
- * @param client identification of the client; NULL
- * for the last call when the server is destroyed
- */
-static void
-handle_local_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
-{
- struct MeshClient *c;
- struct MeshClient *next;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "client disconnected: %p\n", client);
- if (client == NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " (SERVER DOWN)\n");
- return;
- }
-
- c = clients_head;
- while (NULL != c)
- {
- if (c->handle != client)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " ... searching %p (%u)\n",
- c->handle, c->id);
- c = c->next;
- continue;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "matching client found (%u)\n",
- c->id);
- GNUNET_SERVER_client_drop (c->handle);
- c->shutting_down = GNUNET_YES;
- GNUNET_CONTAINER_multihashmap_iterate (c->own_tunnels,
- &tunnel_destroy_iterator, c);
- GNUNET_CONTAINER_multihashmap_iterate (c->incoming_tunnels,
- &tunnel_destroy_iterator, c);
- GNUNET_CONTAINER_multihashmap_destroy (c->own_tunnels);
- GNUNET_CONTAINER_multihashmap_destroy (c->incoming_tunnels);
-
- if (NULL != c->ports)
- GNUNET_CONTAINER_multihashmap_destroy (c->ports);
- next = c->next;
- GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, c);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " CLIENT FREE at %p\n", c);
- GNUNET_free (c);
- GNUNET_STATISTICS_update (stats, "# clients", -1, GNUNET_NO);
- c = next;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "done!\n");
- return;
-}
-
-
-/**
- * Handler for new clients
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message, which includes messages the client wants
- */
-static void
-handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_ClientConnect *cc_msg;
- struct MeshClient *c;
- unsigned int size;
- uint32_t *p;
- unsigned int i;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client connected %p\n", client);
-
- /* Check data sanity */
- size = ntohs (message->size) - sizeof (struct GNUNET_MESH_ClientConnect);
- cc_msg = (struct GNUNET_MESH_ClientConnect *) message;
- if (0 != (size % sizeof (uint32_t)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- size /= sizeof (uint32_t);
-
- /* Create new client structure */
- c = GNUNET_malloc (sizeof (struct MeshClient));
- c->id = next_client_id++; /* overflow not important: just for debug */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client id %u\n", c->id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client has %u ports\n", size);
- c->handle = client;
- GNUNET_SERVER_client_keep (client);
- if (size > 0)
- {
- uint32_t u32;
- struct GNUNET_HashCode hc;
-
- p = (uint32_t *) &cc_msg[1];
- c->ports = GNUNET_CONTAINER_multihashmap_create (size, GNUNET_NO);
- for (i = 0; i < size; i++)
- {
- u32 = ntohl (p[i]);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " port: %u\n", u32);
- GMC_hash32 (u32, &hc);
-
- /* store in client's hashmap */
- GNUNET_CONTAINER_multihashmap_put (c->ports, &hc, c,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
- /* store in global hashmap */
- /* FIXME only allow one client to have the port open,
- * have a backup hashmap with waiting clients */
- GNUNET_CONTAINER_multihashmap_put (ports, &hc, c,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
- }
- }
-
- GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, c);
- c->own_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
- c->incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
- GNUNET_SERVER_notification_context_add (nc, client);
- GNUNET_STATISTICS_update (stats, "# clients", 1, GNUNET_NO);
-
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client processed\n");
-}
-
-
-/**
- * Handler for requests of new tunnels
- *
- * @param cls Closure.
- * @param client Identification of the client.
- * @param message The actual message.
- */
-static void
-handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_TunnelMessage *t_msg;
- struct MeshPeerInfo *peer_info;
- struct MeshTunnel *t;
- struct MeshClient *c;
- MESH_TunnelNumber tid;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new tunnel requested\n");
-
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
-
- /* Message size sanity check */
- if (sizeof (struct GNUNET_MESH_TunnelMessage) != ntohs (message->size))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- t_msg = (struct GNUNET_MESH_TunnelMessage *) message;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " towards %s\n",
- GNUNET_i2s (&t_msg->peer));
- /* Sanity check for tunnel numbering */
- tid = ntohl (t_msg->tunnel_id);
- if (0 == (tid & GNUNET_MESH_LOCAL_TUNNEL_ID_CLI))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- /* Sanity check for duplicate tunnel IDs */
- if (NULL != tunnel_get_by_local_id (c, tid))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Create tunnel */
- while (NULL != tunnel_get_by_pi (myid, next_tid))
- next_tid = (next_tid + 1) & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
- t = tunnel_new (myid, next_tid, c, tid);
- next_tid = (next_tid + 1) & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
- if (NULL == t)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- t->port = ntohl (t_msg->port);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CREATED TUNNEL %s[%x]:%u (%x)\n",
- GNUNET_i2s (&my_full_id), t->id.tid, t->port, t->local_tid);
-
- peer_info = peer_get (&t_msg->peer);
- peer_info_add_tunnel (peer_info, t);
- peer_connect (peer_info, t);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
-}
-
-
-/**
- * Handler for requests of deleting tunnels
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message
- */
-static void
-handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_TunnelMessage *tunnel_msg;
- struct MeshClient *c;
- struct MeshTunnel *t;
- MESH_TunnelNumber tid;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Got a DESTROY TUNNEL from client!\n");
-
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
-
- /* Message sanity check */
- if (sizeof (struct GNUNET_MESH_TunnelMessage) != ntohs (message->size))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
-
- /* Retrieve tunnel */
- tid = ntohl (tunnel_msg->tunnel_id);
- t = tunnel_get_by_local_id(c, tid);
- if (NULL == t)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " tunnel %X not found\n", tid);
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Cleanup after the tunnel */
- client_delete_tunnel (c, t);
- if (c == t->client)
- {
- t->client = NULL;
- }
- else if (c == t->owner)
- {
- peer_info_remove_tunnel (peer_get_short (t->dest), t);
- t->owner = NULL;
- }
-
- /* The tunnel will be destroyed when the last message is transmitted. */
- tunnel_destroy_empty (t);
-
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
-}
-
-
-/**
- * Handler for requests of seeting tunnel's buffering policy.
- *
- * @param cls Closure (unused).
- * @param client Identification of the client.
- * @param message The actual message.
- */
-static void
-handle_local_tunnel_buffer (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_TunnelMessage *tunnel_msg;
- struct MeshClient *c;
- struct MeshTunnel *t;
- MESH_TunnelNumber tid;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Got a BUFFER request from client!\n");
-
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
-
- tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
-
- /* Retrieve tunnel */
- tid = ntohl (tunnel_msg->tunnel_id);
- t = tunnel_get_by_local_id(c, tid);
- if (NULL == t)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " tunnel %X not found\n", tid);
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- switch (ntohs(message->type))
- {
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER:
- t->nobuffer = GNUNET_NO;
- break;
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_NOBUFFER:
- t->nobuffer = GNUNET_YES;
- break;
- default:
- GNUNET_break (0);
- }
-
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
-}
-
-
-/**
- * Handler for client traffic directed to one peer
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message
- */
-static void
-handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct MeshClient *c;
- struct MeshTunnel *t;
- struct GNUNET_MESH_Data *data_msg;
- MESH_TunnelNumber tid;
- size_t size;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Got a unicast request from a client!\n");
-
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
-
- data_msg = (struct GNUNET_MESH_Data *) message;
-
- /* Sanity check for message size */
- size = ntohs (message->size);
- if (sizeof (struct GNUNET_MESH_Data) +
- sizeof (struct GNUNET_MessageHeader) > size)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Tunnel exists? */
- tid = ntohl (data_msg->tid);
- t = tunnel_get_by_local_id (c, tid);
- if (NULL == t)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Is it a local tunnel? Then, does client own the tunnel? */
- if (t->owner->handle != client)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* PID should be as expected: client<->service communication */
- if (ntohl (data_msg->pid) != t->prev_fc.last_pid_recv + 1)
- {
- GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Unicast PID, expected %u, got %u\n",
- t->prev_fc.last_pid_recv + 1, ntohl (data_msg->pid));
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Ok, everything is correct, send the message
- * (pretend we got it from a mesh peer)
- */
- {
- /* Work around const limitation */
- char buf[ntohs (message->size)] GNUNET_ALIGN;
- struct GNUNET_MESH_Data *copy;
-
- copy = (struct GNUNET_MESH_Data *) buf;
- memcpy (buf, data_msg, size);
- copy->oid = my_full_id;
- copy->tid = htonl (t->id.tid);
- copy->ttl = htonl (default_ttl);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " calling generic handler...\n");
- handle_mesh_unicast (NULL, &my_full_id, &copy->header);
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "receive done OK\n");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
-
- return;
-}
-
-
-/**
- * Handler for client traffic directed to the origin
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message
- */
-static void
-handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_Data *data_msg;
- struct MeshFlowControl *fc;
- struct MeshClient *c;
- struct MeshTunnel *t;
- MESH_TunnelNumber tid;
- size_t size;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Got a ToOrigin request from a client!\n");
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
-
- data_msg = (struct GNUNET_MESH_Data *) message;
-
- /* Sanity check for message size */
- size = ntohs (message->size);
- if (sizeof (struct GNUNET_MESH_Data) +
- sizeof (struct GNUNET_MessageHeader) > size)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Tunnel exists? */
- tid = ntohl (data_msg->tid);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %X\n", tid);
- if (tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- t = tunnel_get_by_local_id (c, tid);
- if (NULL == t)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Tunnel %X unknown.\n", tid);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " for client %u.\n", c->id);
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* It should be sent by someone who has this as incoming tunnel. */
- if (t->client != c)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* PID should be as expected */
- fc = &t->next_fc;
- if (ntohl (data_msg->pid) != fc->last_pid_recv + 1)
- {
- GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "To Origin PID, expected %u, got %u\n",
- fc->last_pid_recv + 1,
- ntohl (data_msg->pid));
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Ok, everything is correct, send the message
- * (pretend we got it from a mesh peer)
- */
- {
- char buf[ntohs (message->size)] GNUNET_ALIGN;
- struct GNUNET_MESH_Data *copy;
-
- /* Work around 'const' limitation */
- memcpy (buf, data_msg, size);
- copy = (struct GNUNET_MESH_Data *) buf;
- GNUNET_PEER_resolve (t->id.oid, &copy->oid);
- copy->tid = htonl (t->id.tid);
- copy->ttl = htonl (default_ttl);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " calling generic handler...\n");
- handle_mesh_to_orig (NULL, &my_full_id, &copy->header);
- }
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
-
- return;
-}
-
-
-/**
- * Handler for client's ACKs for payload traffic.
- *
- * @param cls Closure (unused).
- * @param client Identification of the client.
- * @param message The actual message.
- */
-static void
-handle_local_ack (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_LocalAck *msg;
- struct MeshTunnel *t;
- struct MeshClient *c;
- MESH_TunnelNumber tid;
- uint32_t ack;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a local ACK\n");
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
-
- msg = (struct GNUNET_MESH_LocalAck *) message;
-
- /* Tunnel exists? */
- tid = ntohl (msg->tunnel_id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %X\n", tid);
- t = tunnel_get_by_local_id (c, tid);
- if (NULL == t)
- {
- GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Tunnel %X unknown.\n", tid);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " for client %u.\n", c->id);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- ack = ntohl (msg->ack);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ack);
-
- /* Does client own tunnel? I.E: Is this an ACK for BCK traffic? */
- if (t->owner == c)
- {
- /* The client owns the tunnel, ACK is for data to_origin, send BCK ACK. */
- t->prev_fc.last_ack_recv = ack;
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
- }
- else
- {
- /* The client doesn't own the tunnel, this ACK is for FWD traffic. */
- t->next_fc.last_ack_recv = ack;
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
- }
-
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
-
- return;
-}
-
-
-
-/**
- * Iterator over all tunnels to send a monitoring client info about each tunnel.
- *
- * @param cls Closure (client handle).
- * @param key Key (hashed tunnel ID, unused).
- * @param value Tunnel info.
- *
- * @return GNUNET_YES, to keep iterating.
- */
-static int
-monitor_all_tunnels_iterator (void *cls,
- const struct GNUNET_HashCode * key,
- void *value)
-{
- struct GNUNET_SERVER_Client *client = cls;
- struct MeshTunnel *t = value;
- struct GNUNET_MESH_LocalMonitor *msg;
-
- msg = GNUNET_malloc (sizeof(struct GNUNET_MESH_LocalMonitor));
- GNUNET_PEER_resolve(t->id.oid, &msg->owner);
- msg->tunnel_id = htonl (t->id.tid);
- msg->header.size = htons (sizeof (struct GNUNET_MESH_LocalMonitor));
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS);
- GNUNET_PEER_resolve (t->dest, &msg->destination);
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "* sending info about tunnel %s [%u]\n",
- GNUNET_i2s (&msg->owner), t->id.tid);
-
- GNUNET_SERVER_notification_context_unicast (nc, client,
- &msg->header, GNUNET_NO);
- return GNUNET_YES;
-}
-
-
-/**
- * Handler for client's MONITOR request.
- *
- * @param cls Closure (unused).
- * @param client Identification of the client.
- * @param message The actual message.
- */
-static void
-handle_local_get_tunnels (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct MeshClient *c;
-
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Received get tunnels request from client %u\n",
- c->id);
- GNUNET_CONTAINER_multihashmap_iterate (tunnels,
- monitor_all_tunnels_iterator,
- client);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Get tunnels request from client %u completed\n",
- c->id);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
-}
-
-
-/**
- * Handler for client's MONITOR_TUNNEL request.
- *
- * @param cls Closure (unused).
- * @param client Identification of the client.
- * @param message The actual message.
- */
-static void
-handle_local_show_tunnel (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- const struct GNUNET_MESH_LocalMonitor *msg;
- struct GNUNET_MESH_LocalMonitor *resp;
- struct MeshClient *c;
- struct MeshTunnel *t;
-
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- msg = (struct GNUNET_MESH_LocalMonitor *) message;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Received tunnel info request from client %u for tunnel %s[%X]\n",
- c->id,
- &msg->owner,
- ntohl (msg->tunnel_id));
- t = tunnel_get (&msg->owner, ntohl (msg->tunnel_id));
- if (NULL == t)
- {
- /* We don't know the tunnel FIXME */
- struct GNUNET_MESH_LocalMonitor warn;
-
- warn = *msg;
- GNUNET_SERVER_notification_context_unicast (nc, client,
- &warn.header,
- GNUNET_NO);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
-
- /* Initialize context */
- resp = GNUNET_malloc (sizeof (struct GNUNET_MESH_LocalMonitor));
- *resp = *msg;
- GNUNET_PEER_resolve (t->dest, &resp->destination);
- resp->header.size = htons (sizeof (struct GNUNET_MESH_LocalMonitor));
- GNUNET_SERVER_notification_context_unicast (nc, c->handle,
- &resp->header, GNUNET_NO);
- GNUNET_free (resp);
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Monitor tunnel request from client %u completed\n",
- c->id);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
-}
-
-
-/**
- * Functions to handle messages from clients
- */
-static struct GNUNET_SERVER_MessageHandler client_handlers[] = {
- {&handle_local_new_client, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0},
- {&handle_local_tunnel_create, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE,
- sizeof (struct GNUNET_MESH_TunnelMessage)},
- {&handle_local_tunnel_destroy, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY,
- sizeof (struct GNUNET_MESH_TunnelMessage)},
- {&handle_local_tunnel_buffer, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER,
- sizeof (struct GNUNET_MESH_TunnelMessage)},
- {&handle_local_tunnel_buffer, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_NOBUFFER,
- sizeof (struct GNUNET_MESH_TunnelMessage)},
- {&handle_local_unicast, NULL,
- GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0},
- {&handle_local_to_origin, NULL,
- GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0},
- {&handle_local_ack, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK,
- sizeof (struct GNUNET_MESH_LocalAck)},
- {&handle_local_get_tunnels, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS,
- sizeof (struct GNUNET_MessageHeader)},
- {&handle_local_show_tunnel, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL,
- sizeof (struct GNUNET_MESH_LocalMonitor)},
- {NULL, NULL, 0, 0}
-};
-
-
-/**
- * Method called whenever a given peer connects.
- *
- * @param cls closure
- * @param peer peer identity this notification is about
- */
-static void
-core_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
-{
- struct MeshPeerInfo *peer_info;
- struct MeshPeerPath *path;
-
- DEBUG_CONN ("Peer connected\n");
- DEBUG_CONN (" %s\n", GNUNET_i2s (&my_full_id));
- peer_info = peer_get (peer);
- if (myid == peer_info->id)
- {
- DEBUG_CONN (" (self)\n");
- path = path_new (1);
- }
- else
- {
- DEBUG_CONN (" %s\n", GNUNET_i2s (peer));
- path = path_new (2);
- path->peers[1] = peer_info->id;
- GNUNET_PEER_change_rc (peer_info->id, 1);
- GNUNET_STATISTICS_update (stats, "# peers", 1, GNUNET_NO);
- }
- path->peers[0] = myid;
- GNUNET_PEER_change_rc (myid, 1);
- peer_info_add_path (peer_info, path, GNUNET_YES);
- return;
-}
-
-
-/**
- * Method called whenever a peer disconnects.
- *
- * @param cls closure
- * @param peer peer identity this notification is about
- */
-static void
-core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
-{
- struct MeshPeerInfo *pi;
- struct MeshPeerQueue *q;
- struct MeshPeerQueue *n;
-
- DEBUG_CONN ("Peer disconnected\n");
- pi = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey);
- if (NULL == pi)
- {
- GNUNET_break (0);
- return;
- }
- q = pi->queue_head;
- while (NULL != q)
- {
- n = q->next;
- /* TODO try to reroute this traffic instead */
- queue_destroy(q, GNUNET_YES);
- q = n;
- }
- if (NULL != pi->core_transmit)
- {
- GNUNET_CORE_notify_transmit_ready_cancel(pi->core_transmit);
- pi->core_transmit = NULL;
- }
- peer_remove_path (pi, pi->id, myid);
- if (myid == pi->id)
- {
- DEBUG_CONN (" (self)\n");
- }
- GNUNET_STATISTICS_update (stats, "# peers", -1, GNUNET_NO);
- return;
-}
-
-
-/**
- * Install server (service) handlers and start listening to clients.
- */
-static void
-server_init (void)
-{
- GNUNET_SERVER_add_handlers (server_handle, client_handlers);
- GNUNET_SERVER_disconnect_notify (server_handle,
- &handle_local_client_disconnect, NULL);
- nc = GNUNET_SERVER_notification_context_create (server_handle, 1);
-
- clients_head = NULL;
- clients_tail = NULL;
- next_client_id = 0;
- GNUNET_SERVER_resume (server_handle);
-}
-
-
-/**
- * To be called on core init/fail.
- *
- * @param cls Closure (config)
- * @param server handle to the server for this service
- * @param identity the public identity of this peer
- */
-static void
-core_init (void *cls, struct GNUNET_CORE_Handle *server,
- const struct GNUNET_PeerIdentity *identity)
-{
- const struct GNUNET_CONFIGURATION_Handle *c = cls;
- static int i = 0;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core init\n");
- GNUNET_break (core_handle == server);
- if (0 != memcmp (identity, &my_full_id, sizeof (my_full_id)) ||
- NULL == server)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n"));
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- " core id %s\n",
- GNUNET_i2s (identity));
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- " my id %s\n",
- GNUNET_i2s (&my_full_id));
- GNUNET_CORE_disconnect (core_handle);
- core_handle = GNUNET_CORE_connect (c, /* Main configuration */
- NULL, /* Closure passed to MESH functions */
- &core_init, /* Call core_init once connected */
- &core_connect, /* Handle connects */
- &core_disconnect, /* remove peers on disconnects */
- NULL, /* Don't notify about all incoming messages */
- GNUNET_NO, /* For header only in notification */
- NULL, /* Don't notify about all outbound messages */
- GNUNET_NO, /* For header-only out notification */
- core_handlers); /* Register these handlers */
- if (10 < i++)
- GNUNET_abort();
- }
- server_init ();
- return;
-}
-
-
-/******************************************************************************/
-/************************ MAIN FUNCTIONS ****************************/
-/******************************************************************************/
-
-/**
- * Iterator over tunnel hash map entries to destroy the tunnel during shutdown.
- *
- * @param cls closure
- * @param key current key code
- * @param value value in the hash map
- * @return GNUNET_YES if we should continue to iterate,
- * GNUNET_NO if not.
- */
-static int
-shutdown_tunnel (void *cls, const struct GNUNET_HashCode * key, void *value)
-{
- struct MeshTunnel *t = value;
-
- tunnel_destroy (t);
- return GNUNET_YES;
-}
-
-/**
- * Iterator over peer hash map entries to destroy the tunnel during shutdown.
- *
- * @param cls closure
- * @param key current key code
- * @param value value in the hash map
- * @return GNUNET_YES if we should continue to iterate,
- * GNUNET_NO if not.
- */
-static int
-shutdown_peer (void *cls, const struct GNUNET_HashCode * key, void *value)
-{
- struct MeshPeerInfo *p = value;
- struct MeshPeerQueue *q;
- struct MeshPeerQueue *n;
-
- q = p->queue_head;
- while (NULL != q)
- {
- n = q->next;
- if (q->peer == p)
- {
- queue_destroy(q, GNUNET_YES);
- }
- q = n;
- }
- peer_info_destroy (p);
- return GNUNET_YES;
-}
-
-
-/**
- * Task run during shutdown.
- *
- * @param cls unused
- * @param tc unused
- */
-static void
-shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutting down\n");
-
- if (core_handle != NULL)
- {
- GNUNET_CORE_disconnect (core_handle);
- core_handle = NULL;
- }
- if (NULL != keygen)
- {
- GNUNET_CRYPTO_ecc_key_create_stop (keygen);
- keygen = NULL;
- }
- GNUNET_CONTAINER_multihashmap_iterate (tunnels, &shutdown_tunnel, NULL);
- GNUNET_CONTAINER_multihashmap_iterate (peers, &shutdown_peer, NULL);
- if (dht_handle != NULL)
- {
- GNUNET_DHT_disconnect (dht_handle);
- dht_handle = NULL;
- }
- if (nc != NULL)
- {
- GNUNET_SERVER_notification_context_destroy (nc);
- nc = NULL;
- }
- if (GNUNET_SCHEDULER_NO_TASK != announce_id_task)
- {
- GNUNET_SCHEDULER_cancel (announce_id_task);
- announce_id_task = GNUNET_SCHEDULER_NO_TASK;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n");
-}
-
-
-/**
- * Callback for hostkey read/generation.
- *
- * @param cls Closure (Configuration handle).
- * @param pk The ECC private key.
- * @param emsg Error message, if any.
- */
-static void
-key_generation_cb (void *cls,
- struct GNUNET_CRYPTO_EccPrivateKey *pk,
- const char *emsg)
-{
- const struct GNUNET_CONFIGURATION_Handle *c = cls;
-
- keygen = NULL;
- if (NULL == pk)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _("Could not access hostkey: %s. Exiting.\n"),
- emsg);
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- my_private_key = pk;
- GNUNET_CRYPTO_ecc_key_get_public (my_private_key, &my_public_key);
- GNUNET_CRYPTO_hash (&my_public_key, sizeof (my_public_key),
- &my_full_id.hashPubKey);
- myid = GNUNET_PEER_intern (&my_full_id);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Mesh for peer [%s] starting\n",
- GNUNET_i2s(&my_full_id));
-
- core_handle = GNUNET_CORE_connect (c, /* Main configuration */
- NULL, /* Closure passed to MESH functions */
- &core_init, /* Call core_init once connected */
- &core_connect, /* Handle connects */
- &core_disconnect, /* remove peers on disconnects */
- NULL, /* Don't notify about all incoming messages */
- GNUNET_NO, /* For header only in notification */
- NULL, /* Don't notify about all outbound messages */
- GNUNET_NO, /* For header-only out notification */
- core_handlers); /* Register these handlers */
- if (core_handle == NULL)
- {
- GNUNET_break (0);
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
-
- next_tid = 0;
- next_local_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
-
- announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, cls);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mesh service running\n");
-}
-
-
-/**
- * Process mesh requests.
- *
- * @param cls closure
- * @param server the initialized server
- * @param c configuration to use
- */
-static void
-run (void *cls, struct GNUNET_SERVER_Handle *server,
- const struct GNUNET_CONFIGURATION_Handle *c)
-{
- char *keyfile;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting to run\n");
- server_handle = server;
- GNUNET_SERVER_suspend (server_handle);
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_filename (c, "PEER", "PRIVATE_KEY",
- &keyfile))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _
- ("%s service is lacking key configuration settings (%s). Exiting.\n"),
- "mesh", "peer/privatekey");
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_time (c, "MESH", "REFRESH_PATH_TIME",
- &refresh_path_time))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _
- ("%s service is lacking key configuration settings (%s). Exiting.\n"),
- "mesh", "refresh path time");
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_time (c, "MESH", "ID_ANNOUNCE_TIME",
- &id_announce_time))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _
- ("%s service is lacking key configuration settings (%s). Exiting.\n"),
- "mesh", "id announce time");
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_time (c, "MESH", "CONNECT_TIMEOUT",
- &connect_timeout))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _
- ("%s service is lacking key configuration settings (%s). Exiting.\n"),
- "mesh", "connect timeout");
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_MSGS_QUEUE",
- &max_msgs_queue))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _
- ("%s service is lacking key configuration settings (%s). Exiting.\n"),
- "mesh", "max msgs queue");
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_TUNNELS",
- &max_tunnels))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _
- ("%s service is lacking key configuration settings (%s). Exiting.\n"),
- "mesh", "max tunnels");
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DEFAULT_TTL",
- &default_ttl))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _
- ("%s service is lacking key configuration settings (%s). Using default (%u).\n"),
- "mesh", "default ttl", 64);
- default_ttl = 64;
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_PEERS",
- &max_peers))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _("%s service is lacking key configuration settings (%s). Using default (%u).\n"),
- "mesh", "max peers", 1000);
- max_peers = 1000;
- }
-
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DHT_REPLICATION_LEVEL",
- &dht_replication_level))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _
- ("%s service is lacking key configuration settings (%s). Using default (%u).\n"),
- "mesh", "dht replication level", 3);
- dht_replication_level = 3;
- }
-
- tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
- incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
- peers = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
- ports = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
-
- dht_handle = GNUNET_DHT_connect (c, 64);
- if (NULL == dht_handle)
- {
- GNUNET_break (0);
- }
- stats = GNUNET_STATISTICS_create ("mesh", c);
-
- /* Scheduled the task to clean up when shutdown is called */
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
- NULL);
- keygen = GNUNET_CRYPTO_ecc_key_create_start (keyfile,
- &key_generation_cb,
- (void *) c);
- GNUNET_free (keyfile);
-}
-
-
-/**
- * The main function for the mesh service.
- *
- * @param argc number of arguments from the command line
- * @param argv command line arguments
- * @return 0 ok, 1 on error
- */
-int
-main (int argc, char *const *argv)
-{
- int ret;
- int r;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main()\n");
- r = GNUNET_SERVICE_run (argc, argv, "mesh", GNUNET_SERVICE_OPTION_NONE, &run,
- NULL);
- ret = (GNUNET_OK == r) ? 0 : 1;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "main() END\n");
-
- INTERVAL_SHOW;
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Mesh for peer [%s] FWD ACKs %u, BCK ACKs %u\n",
- GNUNET_i2s(&my_full_id), debug_fwd_ack, debug_bck_ack);
-
- return ret;
-}
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c
index 0ba69882fb..622d399b48 100644
--- a/src/mesh/gnunet-service-mesh.c
+++ b/src/mesh/gnunet-service-mesh.c
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2001-2012 Christian Grothoff (and other contributing authors)
+ (C) 2001-2013 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
@@ -23,40 +23,25 @@
* @brief GNUnet MESH service
* @author Bartlomiej Polot
*
- * STRUCTURE:
- * - DATA STRUCTURES
- * - GLOBAL VARIABLES
- * - GENERAL HELPERS
- * - PERIODIC FUNCTIONS
- * - MESH NETWORK HANDLER HELPERS
- * - MESH NETWORK HANDLES
- * - MESH LOCAL HANDLER HELPERS
- * - MESH LOCAL HANDLES
- * - MAIN FUNCTIONS (main & run)
- *
* TODO:
- * - error reporting (CREATE/CHANGE/ADD/DEL?) -- new message!
- * - partial disconnect reporting -- same as error reporting?
- * - add ping message
* - relay corking down to core
- * - set ttl relative to tree depth
- * - Add data ACK count in path ACK
- * - Make common GNUNET_MESH_Data header for unicast, to_orig, multicast
+ * - set ttl relative to path length
+ * - add signatures
+ * - add encryption
+ * - keep queues until receiving ACK
* TODO END
*/
#include "platform.h"
#include "mesh.h"
#include "mesh_protocol.h"
-#include "mesh_tunnel_tree.h"
+#include "mesh_path.h"
#include "block_mesh.h"
#include "gnunet_dht_service.h"
#include "gnunet_statistics_service.h"
-#include "gnunet_regex_service.h"
#define MESH_BLOOM_SIZE 128
-#define MESH_DEBUG_REGEX GNUNET_YES
#define MESH_DEBUG_DHT GNUNET_NO
#define MESH_DEBUG_CONNECTION GNUNET_NO
#define MESH_DEBUG_TIMING __LINUX__ && GNUNET_NO
@@ -65,7 +50,6 @@
GNUNET_TIME_UNIT_MINUTES,\
10)
-
#if MESH_DEBUG_CONNECTION
#define DEBUG_CONN(...) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
#else
@@ -78,12 +62,6 @@
#define DEBUG_DHT(...)
#endif
-#if MESH_DEBUG_REGEX
-#define DEBUG_REGEX(...) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
-#else
-#define DEBUG_REGEX(...)
-#endif
-
#if MESH_DEBUG_TIMING
#include <time.h>
double __sum;
@@ -118,28 +96,6 @@ struct MeshClient;
/**
- * Struct representing a piece of data being sent to other peers
- */
-struct MeshData
-{
- /** Tunnel it belongs to. */
- struct MeshTunnel *t;
-
- /** How many remaining neighbors still hav't got it. */
- unsigned int reference_counter;
-
- /** How many remaining neighbors we need to send this to. */
- unsigned int total_out;
-
- /** Size of the data. */
- size_t data_len;
-
- /** Data itself */
- void *data;
-};
-
-
-/**
* Struct containing info about a queued transmission to this peer
*/
struct MeshPeerQueue
@@ -182,99 +138,6 @@ struct MeshPeerQueue
/**
- * Struct to store regex information announced by clients.
- */
-struct MeshRegexDescriptor
-{
- /**
- * Regular expression itself.
- */
- char *regex;
-
- /**
- * How many characters per edge can we squeeze?
- */
- uint16_t compression;
-
- /**
- * Handle to announce the regex.
- */
- struct GNUNET_REGEX_Announcement *h;
-};
-
-
-/**
- * Struct to keep information of searches of services described by a regex
- * using a user-provided string service description.
- */
-struct MeshRegexSearchInfo
-{
- /**
- * Which tunnel is this for
- */
- struct MeshTunnel *t;
-
- /**
- * User provided description of the searched service.
- */
- char *description;
-
- /**
- * Regex search handle.
- */
- struct GNUNET_REGEX_Search *search_handle;
-
- /**
- * Peer that is connecting via connect_by_string. When connected, free ctx.
- */
- GNUNET_PEER_Id peer;
-
- /**
- * Other peers that are found but not yet being connected to.
- */
- GNUNET_PEER_Id *peers;
-
- /**
- * Number of elements in peers.
- */
- unsigned int n_peers;
-
- /**
- * Next peer to try to connect to.
- */
- unsigned int i_peer;
-
- /**
- * Timeout for a connect attempt.
- * When reached, try to connect to a different peer, if any. If not,
- * try the same peer again.
- */
- GNUNET_SCHEDULER_TaskIdentifier timeout;
-
-};
-
-
-/**
- * Struct containing all info possibly needed to build a package when called
- * back by core.
- */
-struct MeshTransmissionDescriptor
-{
- /** ID of the tunnel this packet travels in */
- struct MESH_TunnelID *origin;
-
- /** Who was this message being sent to */
- struct MeshPeerInfo *peer;
-
- /** Ultimate destination of the packet */
- GNUNET_PEER_Id destination;
-
- /** Data descriptor */
- struct MeshData* mesh_data;
-};
-
-
-/**
* Struct containing all information regarding a given peer
*/
struct MeshPeerInfo
@@ -290,11 +153,6 @@ struct MeshPeerInfo
struct GNUNET_TIME_Absolute last_contact;
/**
- * Task handler for delayed connect task;
- */
- GNUNET_SCHEDULER_TaskIdentifier connect_task;
-
- /**
* Number of attempts to reconnect so far
*/
int n_reconnect_attempts;
@@ -315,13 +173,8 @@ struct MeshPeerInfo
struct GNUNET_DHT_GetHandle *dhtget;
/**
- * Closure given to the DHT GET
- */
- struct MeshPathInfo *dhtgetcls;
-
- /**
- * Array of tunnels this peer participates in
- * (most probably a small amount, therefore not a hashmap)
+ * Array of tunnels this peer is the target of.
+ * Most probably a small amount, therefore not a hashmap.
* When the path to the peer changes, notify these tunnels to let them
* re-adjust their path trees.
*/
@@ -348,13 +201,66 @@ struct MeshPeerInfo
unsigned int queue_n;
/**
- * Handle to for queued transmissions
+ * Handle for queued transmissions
*/
struct GNUNET_CORE_TransmitHandle *core_transmit;
};
/**
+ * Struct to encapsulate all the Flow Control information to a peer in the
+ * context of a tunnel: Same peer in different tunnels will have independent
+ * flow control structures, allowing to choke/free tunnels according to its
+ * own criteria.
+ */
+struct MeshFlowControl
+{
+ /**
+ * ID of the last packet sent towards the peer.
+ */
+ uint32_t last_pid_sent;
+
+ /**
+ * ID of the last packet received from the peer.
+ */
+ uint32_t last_pid_recv;
+
+ /**
+ * Last ACK sent to the peer (peer can't send more than this PID).
+ */
+ uint32_t last_ack_sent;
+
+ /**
+ * Last ACK sent towards the origin (for traffic towards leaf node).
+ */
+ uint32_t last_ack_recv;
+
+ /**
+ * How many payload messages are in the queue towards this peer.
+ */
+ uint32_t queue_n;
+
+ /**
+ * Task to poll the peer in case of a lost ACK causes stall.
+ */
+ GNUNET_SCHEDULER_TaskIdentifier poll_task;
+
+ /**
+ * How frequently to poll for ACKs.
+ */
+ struct GNUNET_TIME_Relative poll_time;
+
+ /**
+ * On which tunnel to poll.
+ * Using an explicit poll_ctx would not help memory wise,
+ * since the allocated context would have to be stored in the
+ * fc struct in order to free it upon cancelling poll_task.
+ */
+ struct MeshTunnel *t;
+};
+
+
+/**
* Globally unique tunnel identification (owner + number)
* DO NOT USE OVER THE NETWORK
*/
@@ -388,6 +294,16 @@ struct MeshTunnel
struct MESH_TunnelID id;
/**
+ * Port of the tunnel.
+ */
+ uint32_t port;
+
+ /**
+ * State of the tunnel.
+ */
+ enum MeshTunnelState state;
+
+ /**
* Local tunnel number ( >= GNUNET_MESH_LOCAL_TUNNEL_ID_CLI or 0 )
*/
MESH_TunnelNumber local_tid;
@@ -400,77 +316,19 @@ struct MeshTunnel
MESH_TunnelNumber local_tid_dest;
/**
- * Is the speed on the tunnel limited to the slowest peer?
- */
- int speed_min;
-
- /**
* Is the tunnel bufferless (minimum latency)?
*/
int nobuffer;
/**
- * Packet ID of the last fwd packet seen (sent/retransmitted/received).
- */
- uint32_t fwd_pid;
-
- /**
- * Packet ID of the last bck packet sent (unique counter per hop).
- */
- uint32_t bck_pid;
-
- /**
- * SKIP value for this tunnel.
- */
- uint32_t skip;
-
- /**
* Force sending ACK? Flag to allow duplicate ACK on POLL.
*/
int force_ack;
/**
- * MeshTunnelChildInfo of all children, indexed by GNUNET_PEER_Id.
- * Contains the Flow Control info: FWD ACK value received,
- * last BCK ACK sent, PID and SKIP values.
- */
- struct GNUNET_CONTAINER_MultiHashMap *children_fc;
-
- /**
- * Last ACK sent towards the origin (for traffic towards leaf node).
- */
- uint32_t last_fwd_ack;
-
- /**
- * BCK ACK value received from the hop towards the owner of the tunnel,
- * (previous node / owner): up to what message PID can we sent back to him.
- */
- uint32_t bck_ack;
-
- /**
- * How many messages are in the forward queue (towards leaves).
- */
- unsigned int fwd_queue_n;
-
- /**
* How many messages do we accept in the forward queue.
*/
- unsigned int fwd_queue_max;
-
- /**
- * How many messages are in the backward queue (towards origin).
- */
- unsigned int bck_queue_n;
-
- /**
- * How many messages do we accept in the backward queue.
- */
- unsigned int bck_queue_max;
-
- /**
- * Task to poll peer in case of a stall.
- */
- GNUNET_SCHEDULER_TaskIdentifier fc_poll_bck;
+ unsigned int queue_max;
/**
* Last time the tunnel was used
@@ -478,93 +336,50 @@ struct MeshTunnel
struct GNUNET_TIME_Absolute timestamp;
/**
- * Peers in the tunnel, indexed by PeerIdentity -> (MeshPeerInfo)
- * containing peers added by id or by type, not intermediate peers.
- */
- struct GNUNET_CONTAINER_MultiHashMap *peers;
-
- /**
- * Number of peers that are connected and potentially ready to receive data
- */
- unsigned int peers_ready;
-
- /**
- * Client owner of the tunnel, if any
- */
- struct MeshClient *owner;
-
- /**
- * Clients that have been informed about and want to stay in the tunnel.
- */
- struct MeshClient **clients;
-
- /**
- * Flow control info for each client.
+ * Destination of the tunnel.
*/
- struct MeshTunnelClientInfo *clients_fc;
-
- /**
- * Number of elements in clients/clients_fc
- */
- unsigned int nclients;
-
- /**
- * Clients that have been informed but requested to leave the tunnel.
- */
- struct MeshClient **ignore;
+ GNUNET_PEER_Id dest;
/**
- * Number of elements in clients
+ * Next hop in the tunnel. If 0, @c client must be set.
*/
- unsigned int nignore;
+ GNUNET_PEER_Id next_hop;
/**
- * Blacklisted peers
+ * Previous hop in the tunnel. If 0, @c owner must be set.
*/
- GNUNET_PEER_Id *blacklisted;
+ GNUNET_PEER_Id prev_hop;
/**
- * Number of elements in blacklisted
+ * Flow control information about @c next_hop or @c client.
*/
- unsigned int nblacklisted;
+ struct MeshFlowControl next_fc;
/**
- * Bloomfilter (for peer identities) to stop circular routes
+ * Flow control information about @c prev_hop or @c owner.
*/
- char bloomfilter[MESH_BLOOM_SIZE];
-
- /**
- * Tunnel paths
- */
- struct MeshTunnelTree *tree;
-
- /**
- * Application type we are looking for in this tunnel
- */
- GNUNET_MESH_ApplicationType type;
+ struct MeshFlowControl prev_fc;
/**
- * Used to search peers offering a service
+ * Client owner of the tunnel, if any
*/
- struct GNUNET_DHT_GetHandle *dht_get_type;
+ struct MeshClient *owner;
/**
- * Handle for the regex search for a connect_by_string
+ * Client destination of the tunnel, if any.
*/
- struct MeshRegexSearchInfo *regex_search;
+ struct MeshClient *client;
/**
- * Task to keep the used paths alive
+ * Task to keep the used paths alive at the owner,
+ * time tunnel out on all the other peers.
*/
- GNUNET_SCHEDULER_TaskIdentifier path_refresh_task;
+ GNUNET_SCHEDULER_TaskIdentifier maintenance_task;
/**
- * Task to destroy the tunnel after timeout
- *
- * FIXME: merge the two? a tunnel will have either
- * a path refresh OR a timeout, never both!
+ * Path being used for the tunnel.
*/
- GNUNET_SCHEDULER_TaskIdentifier timeout_task;
+ struct MeshPeerPath *path;
/**
* Flag to signal the destruction of the tunnel.
@@ -577,163 +392,13 @@ struct MeshTunnel
* Total messages pending for this tunnels, payload or not.
*/
unsigned int pending_messages;
-
- /**
- * If the tunnel is empty, destoy it.
- */
- GNUNET_SCHEDULER_TaskIdentifier delayed_destroy;
-};
-
-
-/**
- * Info about a child node in a tunnel, needed to perform flow control.
- */
-struct MeshTunnelChildInfo
-{
- /**
- * ID of the child node.
- */
- GNUNET_PEER_Id id;
-
- /**
- * SKIP value.
- */
- uint32_t skip;
-
- /**
- * Last sent PID.
- */
- uint32_t fwd_pid;
-
- /**
- * Last received PID.
- */
- uint32_t bck_pid;
-
- /**
- * Maximum PID allowed (FWD ACK received).
- */
- uint32_t fwd_ack;
-
- /**
- * Last ACK sent to that child (BCK ACK).
- */
- uint32_t bck_ack;
-
- /**
- * Circular buffer pointing to MeshPeerQueue elements for all
- * payload traffic going to this child.
- * Size determined by the tunnel queue size (@c t->fwd_queue_max).
- */
- struct MeshPeerQueue **send_buffer;
-
- /**
- * Index of the oldest element in the send_buffer.
- */
- unsigned int send_buffer_start;
-
- /**
- * How many elements are already in the buffer.
- */
- unsigned int send_buffer_n;
-
- /**
- * Tunnel this info is about
- */
- struct MeshTunnel *t;
-
- /**
- * Task to poll peer in case of a stall.
- */
- GNUNET_SCHEDULER_TaskIdentifier fc_poll;
-
- /**
- * Time to use for next polling call.
- */
- struct GNUNET_TIME_Relative fc_poll_time;
-};
-
-
-/**
- * Info about a leaf client of a tunnel, needed to perform flow control.
- */
-struct MeshTunnelClientInfo
-{
- /**
- * PID of the last packet sent to the client (FWD).
- */
- uint32_t fwd_pid;
-
- /**
- * PID of the last packet received from the client (BCK).
- */
- uint32_t bck_pid;
-
- /**
- * Maximum PID allowed (FWD ACK received).
- */
- uint32_t fwd_ack;
-
- /**
- * Last ACK sent to that child (BCK ACK).
- */
- uint32_t bck_ack;
-};
-
-
-
-/**
- * Info collected during iteration of child nodes in order to get the ACK value
- * for a tunnel.
- */
-struct MeshTunnelChildIteratorContext
-{
- /**
- * Tunnel whose info is being collected.
- */
- struct MeshTunnel *t;
-
- /**
- * Is this context initialized? Is the value in max_child_ack valid?
- */
- int init;
-
- /**
- * Maximum child ACK so far.
- */
- uint32_t max_child_ack;
-
- /**
- * Number of children nodes
- */
- unsigned int nchildren;
-};
-
-
-/**
- * Info needed to work with tunnel paths and peers
- */
-struct MeshPathInfo
-{
- /**
- * Tunnel
- */
- struct MeshTunnel *t;
-
- /**
- * Neighbouring peer to whom we send the packet to
- */
- struct MeshPeerInfo *peer;
-
- /**
- * Path itself
- */
- struct MeshPeerPath *path;
};
/**
* Struct containing information about a client of the service
+ *
+ * TODO: add a list of 'waiting' ports
*/
struct MeshClient
{
@@ -757,24 +422,16 @@ struct MeshClient
*/
struct GNUNET_CONTAINER_MultiHashMap *incoming_tunnels;
- /**
- * Tunnels this client has rejected, indexed by incoming local id
- */
- struct GNUNET_CONTAINER_MultiHashMap *ignore_tunnels;
/**
* Handle to communicate with the client
*/
struct GNUNET_SERVER_Client *handle;
/**
- * Applications that this client has claimed to provide: H(app) = app.
- */
- struct GNUNET_CONTAINER_MultiHashMap *apps;
-
- /**
- * Messages that this client has declared interest in
+ * Ports that this client has declared interest in.
+ * Indexed by a GMC_hash32 (type), contains *Client.
*/
- struct GNUNET_CONTAINER_MultiHashMap *types;
+ struct GNUNET_CONTAINER_MultiHashMap *ports;
/**
* Whether the client is active or shutting down (don't send confirmations
@@ -786,26 +443,6 @@ struct MeshClient
* ID of the client, mainly for debug messages
*/
unsigned int id;
-
- /**
- * Regular expressions describing the services offered by this client.
- */
- struct MeshRegexDescriptor *regexes; // FIXME regex add timeout? API to remove a regex?
-
- /**
- * Number of regular expressions in regexes.
- */
- unsigned int n_regex;
-
- /**
- * Task to refresh all regular expresions in the DHT.
- */
- GNUNET_SCHEDULER_TaskIdentifier regex_announce_task;
-
- /**
- * Tmp store for partially retrieved regex.
- */
- char *partial_regex;
};
@@ -835,6 +472,7 @@ mesh_debug (void *cls, int success)
}
#endif
+/* FIXME */
unsigned int debug_fwd_ack;
unsigned int debug_bck_ack;
@@ -852,11 +490,6 @@ unsigned int debug_bck_ack;
static struct GNUNET_TIME_Relative refresh_path_time;
/**
- * How often to PUT local application numbers in the DHT.
- */
-static struct GNUNET_TIME_Relative app_announce_time;
-
-/**
* How often to PUT own ID in the DHT.
*/
static struct GNUNET_TIME_Relative id_announce_time;
@@ -904,7 +537,7 @@ static struct GNUNET_CRYPTO_EccKeyGenerationContext *keygen;
/**
* DLL with all the clients, head.
*/
-static struct MeshClient *clients;
+static struct MeshClient *clients_head;
/**
* DLL with all the clients, tail.
@@ -932,10 +565,10 @@ static struct GNUNET_CONTAINER_MultiHashMap *incoming_tunnels;
*/
static struct GNUNET_CONTAINER_MultiHashMap *peers;
-/**
- * Configuration handle
+/*
+ * Handle to communicate with transport
*/
-static const struct GNUNET_CONFIGURATION_Handle *cfg;
+// static struct GNUNET_TRANSPORT_Handle *transport_handle;
/**
* Handle to communicate with core.
@@ -993,19 +626,9 @@ static MESH_TunnelNumber next_tid;
static MESH_TunnelNumber next_local_tid;
/**
- * All application types provided by this peer: H(app) = *Client.
- */
-static struct GNUNET_CONTAINER_MultiHashMap *applications;
-
-/**
- * All message types clients of this peer are interested in.
+ * All ports clients of this peer have opened.
*/
-static struct GNUNET_CONTAINER_MultiHashMap *types;
-
-/**
- * Task to periodically announce provided applications.
- */
-GNUNET_SCHEDULER_TaskIdentifier announce_applications_task;
+static struct GNUNET_CONTAINER_MultiHashMap *ports;
/**
* Task to periodically announce itself in the network.
@@ -1046,39 +669,26 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
/**
* Retrieve the MeshPeerInfo stucture associated with the peer, create one
- * and insert it in the appropiate structures if the peer is not known yet.
+ * and insert it in the appropriate structures if the peer is not known yet.
*
* @param peer Full identity of the peer.
*
* @return Existing or newly created peer info.
*/
static struct MeshPeerInfo *
-peer_info_get (const struct GNUNET_PeerIdentity *peer);
+peer_get (const struct GNUNET_PeerIdentity *peer);
/**
* Retrieve the MeshPeerInfo stucture associated with the peer, create one
- * and insert it in the appropiate structures if the peer is not known yet.
+ * and insert it in the appropriate structures if the peer is not known yet.
*
* @param peer Short identity of the peer.
*
* @return Existing or newly created peer info.
*/
static struct MeshPeerInfo *
-peer_info_get_short (const GNUNET_PEER_Id peer);
-
-
-/**
- * Try to establish a new connection to this peer.
- * Use the best path for the given tunnel.
- * If the peer doesn't have any path to it yet, try to get one.
- * If the peer already has some path, send a CREATE PATH towards it.
- *
- * @param peer PeerInfo of the peer.
- * @param t Tunnel for which to create the path, if possible.
- */
-static void
-peer_info_connect (struct MeshPeerInfo *peer, struct MeshTunnel *t);
+peer_get_short (const GNUNET_PEER_Id peer);
/**
@@ -1104,30 +714,6 @@ static void
path_add_to_peers (struct MeshPeerPath *p, int confirmed);
-/**
- * Add a peer to a tunnel, accomodating paths accordingly and initializing all
- * needed rescources.
- * If peer already exists, reevaluate shortest path and change if different.
- *
- * @param t Tunnel we want to add a new peer to
- * @param peer PeerInfo of the peer being added
- *
- */
-static void
-tunnel_add_peer (struct MeshTunnel *t, struct MeshPeerInfo *peer);
-
-
-/**
- * Removes an explicit path from a tunnel, freeing all intermediate nodes
- * that are no longer needed, as well as nodes of no longer reachable peers.
- * The tunnel itself is also destoyed if results in a remote empty tunnel.
- *
- * @param t Tunnel from which to remove the path.
- * @param peer Short id of the peer which should be removed.
- */
-static void
-tunnel_delete_peer (struct MeshTunnel *t, GNUNET_PEER_Id peer);
-
/**
* Search for a tunnel by global ID using full PeerIdentities.
@@ -1142,15 +728,6 @@ tunnel_get (const struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid);
/**
- * Delete an active client from the tunnel.
- *
- * @param t Tunnel.
- * @param c Client.
- */
-static void
-tunnel_delete_active_client (struct MeshTunnel *t, const struct MeshClient *c);
-
-/**
* Notify a tunnel that a connection has broken that affects at least
* some of its peers.
*
@@ -1167,26 +744,25 @@ tunnel_notify_connection_broken (struct MeshTunnel *t, GNUNET_PEER_Id p1,
/**
- * Get the current ack value for a tunnel, for data going from root to leaves,
- * taking in account the tunnel mode and the status of all children and clients.
- *
- * @param t Tunnel.
- *
- * @return Maximum PID allowed.
+ * @brief Use the given path for the tunnel.
+ * Update the next and prev hops (and RCs).
+ * (Re)start the path refresh in case the tunnel is locally owned.
+ *
+ * @param t Tunnel to update.
+ * @param p Path to use.
*/
-static uint32_t
-tunnel_get_fwd_ack (struct MeshTunnel *t);
-
+static void
+tunnel_use_path (struct MeshTunnel *t, struct MeshPeerPath *p);
/**
- * Add a client to a tunnel, initializing all needed data structures.
+ * Tunnel is empty: destroy it.
*
- * @param t Tunnel to which add the client.
- * @param c Client which to add to the tunnel.
+ * Notifies all participants (peers, cleints) about the destruction.
+ *
+ * @param t Tunnel to destroy.
*/
static void
-tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c);
-
+tunnel_destroy_empty (struct MeshTunnel *t);
/**
* @brief Queue and pass message to core when possible.
@@ -1248,255 +824,12 @@ queue_get_next (const struct MeshPeerInfo *peer);
static size_t
queue_send (void *cls, size_t size, void *buf);
-/******************************************************************************/
-/************************ REGEX INTEGRATION ****************************/
-/******************************************************************************/
-
-/**
- * Cancel a mesh regex search and free resources.
- */
-static void
-regex_cancel_search (struct MeshRegexSearchInfo *regex_search)
-{
- DEBUG_REGEX ("Search for %s canelled.\n", regex_search->description);
- GNUNET_REGEX_search_cancel (regex_search->search_handle);
- if (0 < regex_search->n_peers)
- GNUNET_free (regex_search->peers);
- if (GNUNET_SCHEDULER_NO_TASK != regex_search->timeout)
- {
- GNUNET_SCHEDULER_cancel(regex_search->timeout);
- }
- GNUNET_free (regex_search);
-}
-
-
-/**
- * Function called if the connect attempt to a peer found via
- * connect_by_string times out. Try to connect to another peer, if any.
- * Otherwise try to reconnect to the same peer.
- *
- * @param cls Closure (info about regex search).
- * @param tc TaskContext.
- */
-static void
-regex_connect_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct MeshRegexSearchInfo *info = cls;
- struct MeshPeerInfo *peer_info;
- GNUNET_PEER_Id id;
- GNUNET_PEER_Id old;
-
- DEBUG_REGEX ("Regex connect timeout\n");
- info->timeout = GNUNET_SCHEDULER_NO_TASK;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- {
- DEBUG_REGEX (" due to shutdown\n");
- return;
- }
-
- old = info->peer;
- DEBUG_REGEX (" timed out: %u\n", old);
-
- if (0 < info->n_peers)
- {
- // Select next peer, put current in that spot.
- id = info->peers[info->i_peer];
- info->peers[info->i_peer] = info->peer;
- info->i_peer = (info->i_peer + 1) % info->n_peers;
- }
- else
- {
- // Try to connect to same peer again.
- id = info->peer;
- }
- DEBUG_REGEX (" trying: %u\n", id);
-
- peer_info = peer_info_get_short(id);
- tunnel_add_peer (info->t, peer_info);
- if (old != id)
- tunnel_delete_peer (info->t, old);
- peer_info_connect (peer_info, info->t);
- info->timeout = GNUNET_SCHEDULER_add_delayed (connect_timeout,
- &regex_connect_timeout,
- info);
- DEBUG_REGEX ("Regex connect timeout END\n");
-}
-
-
-/**
- * Function to process DHT string to regex matching.
- * Called on each result obtained for the DHT search.
- *
- * @param cls Closure provided in GNUNET_REGEX_search.
- * @param id Peer providing a regex that matches the string.
- * @param get_path Path of the get request.
- * @param get_path_length Lenght of get_path.
- * @param put_path Path of the put request.
- * @param put_path_length Length of the put_path.
- */
-static void
-regex_found_handler (void *cls,
- const struct GNUNET_PeerIdentity *id,
- const struct GNUNET_PeerIdentity *get_path,
- unsigned int get_path_length,
- const struct GNUNET_PeerIdentity *put_path,
- unsigned int put_path_length)
-{
- struct MeshRegexSearchInfo *info = cls;
- struct MeshPeerPath *p;
- struct MeshPeerInfo *peer_info;
-
- DEBUG_REGEX ("Got regex results from DHT!\n");
- DEBUG_REGEX (" for %s\n", info->description);
-
- peer_info = peer_info_get (id);
- p = path_build_from_dht (get_path, get_path_length,
- put_path, put_path_length);
- path_add_to_peers (p, GNUNET_NO);
- path_destroy(p);
-
- tunnel_add_peer (info->t, peer_info);
- peer_info_connect (peer_info, info->t);
- if (0 == info->peer)
- {
- info->peer = peer_info->id;
- }
- else
- {
- GNUNET_array_append (info->peers, info->n_peers, peer_info->id);
- }
-
- if (GNUNET_SCHEDULER_NO_TASK != info->timeout)
- return;
-
- info->timeout = GNUNET_SCHEDULER_add_delayed (connect_timeout,
- &regex_connect_timeout,
- info);
-
- return;
-}
-
-
-/**
- * Store the regular expression describing a local service into the DHT.
- *
- * @param regex The regular expresion.
- */
-static void
-regex_put (struct MeshRegexDescriptor *regex)
-{
- DEBUG_REGEX (" regex_put (%s) start\n", regex->regex);
- if (NULL == regex->h)
- {
- DEBUG_REGEX (" first put, creating DFA\n");
- regex->h = GNUNET_REGEX_announce (cfg,
- regex->regex,
- app_announce_time,
- regex->compression);
- }
- DEBUG_REGEX (" regex_put (%s) end\n", regex->regex);
-}
-
-
-/**
- * Periodically announce what applications are provided by local clients
- * (by regex)
- *
- * @param cls closure
- * @param tc task context
- */
-static void
-regex_announce (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct MeshClient *c = cls;
- unsigned int i;
-
- c->regex_announce_task = GNUNET_SCHEDULER_NO_TASK;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- return;
- DEBUG_REGEX ("Starting announce for regex\n");
- for (i = 0; i < c->n_regex; i++)
- regex_put (&c->regexes[i]);
- c->regex_announce_task = GNUNET_SCHEDULER_add_delayed (app_announce_time,
- &regex_announce,
- cls);
- DEBUG_REGEX ("Finished announce for regex\n");
-}
-
/******************************************************************************/
/************************ PERIODIC FUNCTIONS ****************************/
/******************************************************************************/
/**
- * Announce iterator over for each application provided by the peer
- *
- * @param cls closure
- * @param key current key code
- * @param value value in the hash map
- * @return GNUNET_YES if we should continue to
- * iterate,
- * GNUNET_NO if not.
- */
-static int
-announce_application (void *cls, const struct GNUNET_HashCode * key, void *value)
-{
- struct PBlock block;
- struct MeshClient *c;
-
- block.id = my_full_id;
- c = GNUNET_CONTAINER_multihashmap_get (applications, key);
- GNUNET_assert(NULL != c);
- block.type = (long) GNUNET_CONTAINER_multihashmap_get (c->apps, key);
- if (0 == block.type)
- {
- GNUNET_break(0);
- return GNUNET_YES;
- }
- block.type = htonl (block.type);
- DEBUG_DHT ("Putting APP key: %s\n", GNUNET_h2s (key));
- GNUNET_break (NULL !=
- GNUNET_DHT_put (dht_handle, key,
- dht_replication_level,
- GNUNET_DHT_RO_RECORD_ROUTE |
- GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
- GNUNET_BLOCK_TYPE_MESH_PEER_BY_TYPE,
- sizeof (block),
- (const char *) &block,
- GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_HOURS), /* FIXME: this should be an option */
- app_announce_time, NULL, NULL));
- return GNUNET_OK;
-}
-
-
-/**
- * Periodically announce what applications are provided by local clients
- * (by type)
- *
- * @param cls closure
- * @param tc task context
- */
-static void
-announce_applications (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- {
- announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
- return;
- }
-
- DEBUG_DHT ("Starting PUT for apps\n");
-
- GNUNET_CONTAINER_multihashmap_iterate (applications, &announce_application,
- NULL);
- announce_applications_task =
- GNUNET_SCHEDULER_add_delayed (app_announce_time, &announce_applications,
- cls);
- DEBUG_DHT ("Finished PUT for apps\n");
-}
-
-
-/**
* Periodically announce self id in the DHT
*
* @param cls closure
@@ -1519,7 +852,6 @@ announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
DEBUG_DHT ("DHT_put for ID %s started.\n", GNUNET_i2s (&my_full_id));
block.id = my_full_id;
- block.type = htonl (0);
GNUNET_DHT_put (dht_handle, /* DHT handle */
&my_full_id.hashPubKey, /* Key to use */
dht_replication_level, /* Replication level */
@@ -1540,23 +872,6 @@ announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
/****************** GENERAL HELPER FUNCTIONS ************************/
/******************************************************************************/
-/**
- * Decrements the reference counter and frees all resources if needed
- *
- * @param mesh_data Data Descriptor used in a multicast message.
- * Freed no longer needed (last message).
- */
-static void
-data_descriptor_decrement_rc (struct MeshData *mesh_data)
-{
- if (0 == --(mesh_data->reference_counter))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Last copy!\n");
- GNUNET_free (mesh_data->data);
- GNUNET_free (mesh_data);
- }
-}
-
/**
* Check if client has registered with the service and has not disconnected
@@ -1570,7 +885,7 @@ client_get (struct GNUNET_SERVER_Client *client)
{
struct MeshClient *c;
- c = clients;
+ c = clients_head;
while (NULL != c)
{
if (c->handle == client)
@@ -1582,104 +897,8 @@ client_get (struct GNUNET_SERVER_Client *client)
/**
- * Checks if a given client has subscribed to certain message type
- *
- * @param message_type Type of message to check
- * @param c Client to check
- *
- * @return GNUNET_YES or GNUNET_NO, depending on subscription status
- *
- * FIXME: use of crypto_hash slows it down
- * The hash function alone takes 8-10us out of the ~55us for the whole
- * process of retransmitting the message from one local client to another.
- * Find faster implementation!
- */
-static int
-client_is_subscribed (uint16_t message_type, struct MeshClient *c)
-{
- struct GNUNET_HashCode hc;
-
- if (NULL == c->types)
- return GNUNET_NO;
-
- GNUNET_CRYPTO_hash (&message_type, sizeof (uint16_t), &hc);
- return GNUNET_CONTAINER_multihashmap_contains (c->types, &hc);
-}
-
-
-/**
- * Check whether client wants traffic from a tunnel.
- *
- * @param c Client to check.
- * @param t Tunnel to be found.
- *
- * @return GNUNET_YES if client knows tunnel.
- *
- * TODO look in client hashmap
- */
-static int
-client_wants_tunnel (struct MeshClient *c, struct MeshTunnel *t)
-{
- unsigned int i;
-
- for (i = 0; i < t->nclients; i++)
- if (t->clients[i] == c)
- return GNUNET_YES;
- return GNUNET_NO;
-}
-
-
-/**
- * Check whether client has been informed about a tunnel.
- *
- * @param c Client to check.
- * @param t Tunnel to be found.
- *
- * @return GNUNET_YES if client knows tunnel.
- *
- * TODO look in client hashmap
- */
-static int
-client_knows_tunnel (struct MeshClient *c, struct MeshTunnel *t)
-{
- unsigned int i;
-
- for (i = 0; i < t->nignore; i++)
- if (t->ignore[i] == c)
- return GNUNET_YES;
- return client_wants_tunnel(c, t);
-}
-
-
-/**
- * Marks a client as uninterested in traffic from the tunnel, updating both
- * client and tunnel to reflect this.
- *
- * @param c Client that doesn't want traffic anymore.
- * @param t Tunnel which should be ignored.
- *
- * FIXME when to delete an incoming tunnel?
- */
-static void
-client_ignore_tunnel (struct MeshClient *c, struct MeshTunnel *t)
-{
- struct GNUNET_HashCode hash;
-
- GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
- GNUNET_break (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels,
- &hash, t));
- GNUNET_break (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_put (c->ignore_tunnels, &hash, t,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
- tunnel_delete_active_client (t, c);
- GNUNET_array_append (t->ignore, t->nignore, c);
-}
-
-
-/**
* Deletes a tunnel from a client (either owner or destination). To be used on
- * tunnel destroy, otherwise, use client_ignore_tunnel.
+ * tunnel destroy.
*
* @param c Client whose tunnel to delete.
* @param t Tunnel which should be deleted.
@@ -1691,240 +910,76 @@ client_delete_tunnel (struct MeshClient *c, struct MeshTunnel *t)
if (c == t->owner)
{
- GNUNET_CRYPTO_hash(&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
+ GMC_hash32 (t->local_tid, &hash);
GNUNET_assert (GNUNET_YES ==
GNUNET_CONTAINER_multihashmap_remove (c->own_tunnels,
&hash,
t));
}
- else
+ else if (c == t->client)
{
- GNUNET_CRYPTO_hash(&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
- // FIXME XOR?
+ GMC_hash32 (t->local_tid_dest, &hash);
GNUNET_assert (GNUNET_YES ==
GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels,
&hash,
- t) ||
- GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_remove (c->ignore_tunnels,
- &hash,
t));
}
-}
-
-
-/**
- * Notify the owner of a tunnel that a peer has disconnected.
- *
- * @param c Client (owner of tunnel).
- * @param t Tunnel this message is about.
- * @param peer_id Short ID of the disconnected peer.
- */
-void
-client_notify_peer_disconnected (struct MeshClient *c,
- struct MeshTunnel *t,
- GNUNET_PEER_Id peer_id)
-{
- struct GNUNET_MESH_PeerControl msg;
-
- if (NULL == t->owner || NULL == nc)
- return;
-
- msg.header.size = htons (sizeof (msg));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL);
- msg.tunnel_id = htonl (t->local_tid);
- GNUNET_PEER_resolve (peer_id, &msg.peer);
- GNUNET_SERVER_notification_context_unicast (nc, t->owner->handle,
- &msg.header, GNUNET_NO);
-}
-
-
-/**
- * Send the message to all clients that have subscribed to its type
- *
- * @param msg Pointer to the message itself
- * @param payload Pointer to the payload of the message.
- * @param t The tunnel to whose clients this message goes.
- *
- * @return number of clients this message was sent to
- */
-static unsigned int
-send_subscribed_clients (const struct GNUNET_MessageHeader *msg,
- const struct GNUNET_MessageHeader *payload,
- struct MeshTunnel *t)
-{
- struct MeshClient *c;
- MESH_TunnelNumber *tid;
- unsigned int count;
- uint16_t type;
- char cbuf[htons (msg->size)];
-
- type = ntohs (payload->type);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending to clients...\n");
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "message of type %s\n",
- GNUNET_MESH_DEBUG_M2S (type));
-
- memcpy (cbuf, msg, sizeof (cbuf));
- switch (htons (msg->type))
- {
- struct GNUNET_MESH_Unicast *uc;
- struct GNUNET_MESH_Multicast *mc;
- struct GNUNET_MESH_ToOrigin *to;
-
- case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- uc = (struct GNUNET_MESH_Unicast *) cbuf;
- tid = &uc->tid;
- break;
- case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
- mc = (struct GNUNET_MESH_Multicast *) cbuf;
- tid = &mc->tid;
- break;
- case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- to = (struct GNUNET_MESH_ToOrigin *) cbuf;
- tid = &to->tid;
- break;
- default:
- GNUNET_break (0);
- return 0;
- }
-
- for (count = 0, c = clients; c != NULL; c = c->next)
+ else
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client %u\n", c->id);
- if (client_is_subscribed (type, c))
- {
- if (htons (msg->type) == GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN)
- {
- if (c != t->owner)
- continue;
- *tid = htonl (t->local_tid);
- }
- else
- {
- if (GNUNET_NO == client_knows_tunnel (c, t))
- {
- /* This client doesn't know the tunnel */
- struct GNUNET_MESH_TunnelNotification tmsg;
- struct GNUNET_HashCode hash;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending tunnel create\n");
- tmsg.header.size = htons (sizeof (tmsg));
- tmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
- GNUNET_PEER_resolve (t->id.oid, &tmsg.peer);
- tmsg.tunnel_id = htonl (t->local_tid_dest);
- tmsg.opt = 0;
- if (GNUNET_YES == t->speed_min)
- tmsg.opt |= MESH_TUNNEL_OPT_SPEED_MIN;
- if (GNUNET_YES == t->nobuffer)
- tmsg.opt |= MESH_TUNNEL_OPT_NOBUFFER;
- GNUNET_SERVER_notification_context_unicast (nc, c->handle,
- &tmsg.header, GNUNET_NO);
- tunnel_add_client (t, c);
- GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber),
- &hash);
- GNUNET_break (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (
- c->incoming_tunnels, &hash, t,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
- }
- *tid = htonl (t->local_tid_dest);
- }
-
- /* Check if the client wants to get traffic from the tunnel */
- if (GNUNET_NO == client_wants_tunnel(c, t))
- continue;
- count++;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending\n");
- GNUNET_SERVER_notification_context_unicast (nc, c->handle,
- (struct GNUNET_MessageHeader
- *) cbuf, GNUNET_NO);
- }
+ GNUNET_break (0);
}
-
- return count;
-}
-
-
-/**
- * Notify the client that owns the tunnel that a peer has connected to it
- * (the requested path to it has been confirmed).
- *
- * @param t Tunnel whose owner to notify
- * @param id Short id of the peer that has connected
- */
-static void
-send_client_peer_connected (const struct MeshTunnel *t, const GNUNET_PEER_Id id)
-{
- struct GNUNET_MESH_PeerControl pc;
-
- if (NULL == t->owner || GNUNET_YES == t->destroy)
- return;
-
- pc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD);
- pc.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
- pc.tunnel_id = htonl (t->local_tid);
- GNUNET_PEER_resolve (id, &pc.peer);
- GNUNET_SERVER_notification_context_unicast (nc, t->owner->handle, &pc.header,
- GNUNET_NO);
}
-
/**
- * Notify all clients (not depending on registration status) that the incoming
- * tunnel is no longer valid.
+ * Notify the appropriate client that a new incoming tunnel was created.
*
- * @param t Tunnel that was destroyed.
+ * @param t Tunnel that was created.
*/
static void
-send_clients_tunnel_destroy (struct MeshTunnel *t)
+send_client_tunnel_create (struct MeshTunnel *t)
{
struct GNUNET_MESH_TunnelMessage msg;
+ if (NULL == t->client)
+ return;
msg.header.size = htons (sizeof (msg));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
+ msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
msg.tunnel_id = htonl (t->local_tid_dest);
- GNUNET_SERVER_notification_context_broadcast (nc, &msg.header, GNUNET_NO);
+ msg.port = htonl (t->port);
+ GNUNET_PEER_resolve (t->id.oid, &msg.peer);
+ GNUNET_SERVER_notification_context_unicast (nc, t->client->handle,
+ &msg.header, GNUNET_NO);
}
/**
- * Notify clients of tunnel disconnections, if needed.
- * In case the origin disconnects, the destination clients get a tunnel destroy
- * notification. If the last destination disconnects (only one remaining client
- * in tunnel), the origin gets a (local ID) peer disconnected.
- * Note that the function must be called BEFORE removing the client from
- * the tunnel.
+ * Notify dest client that the incoming tunnel is no longer valid.
*
- * @param t Tunnel that was destroyed.
- * @param c Client that disconnected.
+ * @param c Client to notify..
+ * @param t Tunnel that is destroyed.
*/
static void
-send_client_tunnel_disconnect (struct MeshTunnel *t, struct MeshClient *c)
+send_client_tunnel_destroy (struct MeshClient *c, struct MeshTunnel *t)
{
- unsigned int i;
+ struct GNUNET_MESH_TunnelMessage msg;
- if (c == t->owner)
+ if (NULL == c)
{
- struct GNUNET_MESH_TunnelMessage msg;
-
- msg.header.size = htons (sizeof (msg));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
- msg.tunnel_id = htonl (t->local_tid_dest);
- for (i = 0; i < t->nclients; i++)
- GNUNET_SERVER_notification_context_unicast (nc, t->clients[i]->handle,
- &msg.header, GNUNET_NO);
+ GNUNET_break (0);
+ return;
}
- // FIXME when to disconnect an incoming tunnel?
- else if (1 == t->nclients && NULL != t->owner)
+ if (c != t->client && c != t->owner)
{
- struct GNUNET_MESH_PeerControl msg;
-
- msg.header.size = htons (sizeof (msg));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL);
- msg.tunnel_id = htonl (t->local_tid);
- msg.peer = my_full_id;
- GNUNET_SERVER_notification_context_unicast (nc, t->owner->handle,
- &msg.header, GNUNET_NO);
+ GNUNET_break (0);
+ return;
}
+ msg.header.size = htons (sizeof (msg));
+ msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
+ msg.tunnel_id = htonl (t->local_tid_dest);
+ msg.port = htonl (0);
+ memset(&msg.peer, 0, sizeof (msg.peer));
+ GNUNET_SERVER_notification_context_unicast (nc, c->handle,
+ &msg.header, GNUNET_NO);
}
@@ -1947,14 +1002,14 @@ peer_info_timeout (void *cls,
/**
* Retrieve the MeshPeerInfo stucture associated with the peer, create one
- * and insert it in the appropiate structures if the peer is not known yet.
+ * and insert it in the appropriate structures if the peer is not known yet.
*
* @param peer Full identity of the peer.
*
* @return Existing or newly created peer info.
*/
static struct MeshPeerInfo *
-peer_info_get (const struct GNUNET_PeerIdentity *peer)
+peer_get (const struct GNUNET_PeerIdentity *peer)
{
struct MeshPeerInfo *peer_info;
@@ -1981,56 +1036,52 @@ peer_info_get (const struct GNUNET_PeerIdentity *peer)
/**
* Retrieve the MeshPeerInfo stucture associated with the peer, create one
- * and insert it in the appropiate structures if the peer is not known yet.
+ * and insert it in the appropriate structures if the peer is not known yet.
*
* @param peer Short identity of the peer.
*
* @return Existing or newly created peer info.
*/
static struct MeshPeerInfo *
-peer_info_get_short (const GNUNET_PEER_Id peer)
+peer_get_short (const GNUNET_PEER_Id peer)
{
struct GNUNET_PeerIdentity id;
GNUNET_PEER_resolve (peer, &id);
- return peer_info_get (&id);
+ return peer_get (&id);
}
/**
- * Iterator to remove the tunnel from the list of tunnels a peer participates
- * in.
- *
- * @param cls Closure (tunnel info)
- * @param key GNUNET_PeerIdentity of the peer (unused)
- * @param value PeerInfo of the peer
+ * Choose the best path towards a peer considering the tunnel properties.
+ *
+ * @param peer The destination peer.
+ * @param t The tunnel the path is for.
*
- * @return always GNUNET_YES, to keep iterating
+ * @return Best current known path towards the peer, if any.
*/
-static int
-peer_info_delete_tunnel (void *cls, const struct GNUNET_HashCode * key, void *value)
+static struct MeshPeerPath *
+peer_get_best_path (const struct MeshPeerInfo *peer, const struct MeshTunnel *t)
{
- struct MeshTunnel *t = cls;
- struct MeshPeerInfo *peer = value;
- unsigned int i;
+ struct MeshPeerPath *best_p;
+ struct MeshPeerPath *p;
+ unsigned int best_cost;
+ unsigned int cost;
- for (i = 0; i < peer->ntunnels; i++)
+ best_p = p = peer->path_head;
+ best_cost = cost = p->length;
+ while (NULL != p)
{
- if (0 ==
- memcmp (&peer->tunnels[i]->id, &t->id, sizeof (struct MESH_TunnelID)))
+ if ((cost = p->length) < best_cost)
{
- peer->ntunnels--;
- peer->tunnels[i] = peer->tunnels[peer->ntunnels];
- peer->tunnels =
- GNUNET_realloc (peer->tunnels,
- peer->ntunnels * sizeof(struct MeshTunnel *));
- return GNUNET_YES;
+ best_cost = cost;
+ best_p = p;
}
+ p = p->next;
}
- return GNUNET_YES;
+ return best_p;
}
-
/**
* Core callback to write a pre-constructed data packet to core buffer
*
@@ -2043,13 +1094,10 @@ peer_info_delete_tunnel (void *cls, const struct GNUNET_HashCode * key, void *va
static size_t
send_core_data_raw (void *cls, size_t size, void *buf)
{
- struct MeshTransmissionDescriptor *info = cls;
- struct GNUNET_MessageHeader *msg;
+ struct GNUNET_MessageHeader *msg = cls;
size_t total_size;
- GNUNET_assert (NULL != info);
- GNUNET_assert (NULL != info->mesh_data);
- msg = (struct GNUNET_MessageHeader *) info->mesh_data->data;
+ GNUNET_assert (NULL != msg);
total_size = ntohs (msg->size);
if (total_size > size)
@@ -2058,15 +1106,14 @@ send_core_data_raw (void *cls, size_t size, void *buf)
return 0;
}
memcpy (buf, msg, total_size);
- data_descriptor_decrement_rc (info->mesh_data);
- GNUNET_free (info);
+ GNUNET_free (cls);
return total_size;
}
/**
- * Sends an already built non-multicast message to a peer,
- * properly registrating all used resources.
+ * Sends an already built message to a peer, properly registrating
+ * all used resources.
*
* @param message Message to send. Function makes a copy of it.
* @param peer Short ID of the neighbor whom to send the message.
@@ -2074,41 +1121,35 @@ send_core_data_raw (void *cls, size_t size, void *buf)
*/
static void
send_prebuilt_message (const struct GNUNET_MessageHeader *message,
- const struct GNUNET_PeerIdentity *peer,
+ GNUNET_PEER_Id peer,
struct MeshTunnel *t)
{
- struct MeshTransmissionDescriptor *info;
+ struct GNUNET_PeerIdentity id;
struct MeshPeerInfo *neighbor;
struct MeshPeerPath *p;
+ void *data;
size_t size;
uint16_t type;
// GNUNET_TRANSPORT_try_connect(); FIXME use?
+ if (0 == peer)
+ return;
+
size = ntohs (message->size);
- info = GNUNET_malloc (sizeof (struct MeshTransmissionDescriptor));
- info->mesh_data = GNUNET_malloc (sizeof (struct MeshData));
- info->mesh_data->data = GNUNET_malloc (size);
- memcpy (info->mesh_data->data, message, size);
+ data = GNUNET_malloc (size);
+ memcpy (data, message, size);
type = ntohs(message->type);
- switch (type)
+ if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == type ||
+ GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == type)
{
- struct GNUNET_MESH_Unicast *m;
- struct GNUNET_MESH_ToOrigin *to;
+ struct GNUNET_MESH_Data *u;
- case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- m = (struct GNUNET_MESH_Unicast *) info->mesh_data->data;
- m->ttl = htonl (ntohl (m->ttl) - 1);
- break;
- case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- to = (struct GNUNET_MESH_ToOrigin *) info->mesh_data->data;
- t->bck_pid++;
- to->pid = htonl(t->bck_pid);
- }
- info->mesh_data->data_len = size;
- info->mesh_data->reference_counter = 1;
- info->mesh_data->total_out = 1;
- neighbor = peer_info_get (peer);
+ u = (struct GNUNET_MESH_Data *) data;
+ u->ttl = htonl (ntohl (u->ttl) - 1);
+ }
+ GNUNET_PEER_resolve (peer, &id);
+ neighbor = peer_get (&id);
for (p = neighbor->path_head; NULL != p; p = p->next)
{
if (2 >= p->length)
@@ -2121,10 +1162,10 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message,
#if MESH_DEBUG
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" %s IS NOT DIRECTLY CONNECTED\n",
- GNUNET_i2s(peer));
+ GNUNET_i2s(&id));
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" PATHS TO %s:\n",
- GNUNET_i2s(peer));
+ GNUNET_i2s(&id));
for (p = neighbor->path_head; NULL != p; p = p->next)
{
struct GNUNET_PeerIdentity debug_id;
@@ -2143,18 +1184,15 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message,
}
#endif
GNUNET_break (0); // FIXME sometimes fails (testing disconnect?)
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
" no direct connection to %s\n",
- GNUNET_i2s (peer));
- GNUNET_free (info->mesh_data->data);
- GNUNET_free (info->mesh_data);
- GNUNET_free (info);
+ GNUNET_i2s (&id));
+ GNUNET_free (data);
return;
}
- info->peer = neighbor;
if (GNUNET_MESSAGE_TYPE_MESH_PATH_ACK == type)
type = 0;
- queue_add (info,
+ queue_add (data,
type,
size,
neighbor,
@@ -2166,94 +1204,22 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message,
* Sends a CREATE PATH message for a path to a peer, properly registrating
* all used resources.
*
- * @param peer PeerInfo of the final peer for whom this path is being created.
- * @param p Path itself.
* @param t Tunnel for which the path is created.
*/
static void
-send_create_path (struct MeshPeerInfo *peer, struct MeshPeerPath *p,
- struct MeshTunnel *t)
+send_create_path (struct MeshTunnel *t)
{
- struct GNUNET_PeerIdentity id;
- struct MeshPathInfo *path_info;
struct MeshPeerInfo *neighbor;
- unsigned int i;
-
- if (NULL == p)
- {
- p = tree_get_path_to_peer (t->tree, peer->id);
- if (NULL == p)
- {
- GNUNET_break (0);
- return;
- }
- }
- for (i = 0; i < p->length; i++)
- {
- if (p->peers[i] == myid)
- break;
- }
- if (i >= p->length - 1)
- {
- path_destroy (p);
- GNUNET_break (0);
- return;
- }
- GNUNET_PEER_resolve (p->peers[i + 1], &id);
-
- path_info = GNUNET_malloc (sizeof (struct MeshPathInfo));
- path_info->path = p;
- path_info->t = t;
- neighbor = peer_info_get (&id);
- path_info->peer = neighbor;
- queue_add (path_info,
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Send create path\n");
+ neighbor = peer_get_short (t->next_hop);
+ queue_add (t,
GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE,
- sizeof (struct GNUNET_MESH_ManipulatePath) +
- (p->length * sizeof (struct GNUNET_PeerIdentity)),
+ sizeof (struct GNUNET_MESH_CreateTunnel) +
+ (t->path->length * sizeof (struct GNUNET_PeerIdentity)),
neighbor,
t);
-}
-
-
-/**
- * Sends a DESTROY PATH message to free resources for a path in a tunnel
- *
- * @param t Tunnel whose path to destroy.
- * @param destination Short ID of the peer to whom the path to destroy.
- */
-static void
-send_destroy_path (struct MeshTunnel *t, GNUNET_PEER_Id destination)
-{
- struct MeshPeerPath *p;
- size_t size;
-
- p = tree_get_path_to_peer (t->tree, destination);
- if (NULL == p)
- {
- GNUNET_break (0);
- return;
- }
- size = sizeof (struct GNUNET_MESH_ManipulatePath);
- size += p->length * sizeof (struct GNUNET_PeerIdentity);
- {
- struct GNUNET_MESH_ManipulatePath *msg;
- struct GNUNET_PeerIdentity *pi;
- char cbuf[size];
- unsigned int i;
-
- msg = (struct GNUNET_MESH_ManipulatePath *) cbuf;
- msg->header.size = htons (size);
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY);
- msg->tid = htonl (t->id.tid);
- pi = (struct GNUNET_PeerIdentity *) &msg[1];
- for (i = 0; i < p->length; i++)
- {
- GNUNET_PEER_resolve (p->peers[i], &pi[i]);
- }
- send_prebuilt_message (&msg->header, tree_get_first_hop (t->tree, destination), t);
- }
- path_destroy (p);
+ t->state = MESH_TUNNEL_WAITING;
}
@@ -2265,28 +1231,20 @@ send_destroy_path (struct MeshTunnel *t, GNUNET_PEER_Id destination)
static void
send_path_ack (struct MeshTunnel *t)
{
- struct MeshTransmissionDescriptor *info;
- struct GNUNET_PeerIdentity id;
- GNUNET_PEER_Id peer;
+ struct MeshPeerInfo *peer;
- peer = tree_get_predecessor (t->tree);
- GNUNET_PEER_resolve (peer, &id);
- info = GNUNET_malloc (sizeof (struct MeshTransmissionDescriptor));
- info->origin = &t->id;
- info->peer = GNUNET_CONTAINER_multihashmap_get (peers, &id.hashPubKey);
- GNUNET_assert (NULL != info->peer);
+ peer = peer_get_short (t->prev_hop);
- queue_add (info,
+ queue_add (t,
GNUNET_MESSAGE_TYPE_MESH_PATH_ACK,
sizeof (struct GNUNET_MESH_PathACK),
- info->peer,
+ peer,
t);
}
/**
- * Try to establish a new connection to this peer.
- * Use the best path for the given tunnel.
+ * Try to establish a new connection to this peer in the given tunnel.
* If the peer doesn't have any path to it yet, try to get one.
* If the peer already has some path, send a CREATE PATH towards it.
*
@@ -2294,90 +1252,39 @@ send_path_ack (struct MeshTunnel *t)
* @param t Tunnel for which to create the path, if possible.
*/
static void
-peer_info_connect (struct MeshPeerInfo *peer, struct MeshTunnel *t)
+peer_connect (struct MeshPeerInfo *peer, struct MeshTunnel *t)
{
struct MeshPeerPath *p;
- struct MeshPathInfo *path_info;
if (NULL != peer->path_head)
{
- p = tree_get_path_to_peer (t->tree, peer->id);
- if (NULL == p)
- {
- GNUNET_break (0);
- return;
- }
-
- // FIXME always send create path to self
- if (p->length > 1)
- {
- send_create_path (peer, p, t);
- }
- else
- {
- struct GNUNET_HashCode hash;
-
- path_destroy (p);
- send_client_peer_connected (t, myid);
- t->local_tid_dest = next_local_tid++;
- GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber),
- &hash);
- if (GNUNET_OK !=
- GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
- {
- GNUNET_break (0);
- return;
- }
- }
+ p = peer_get_best_path (peer, t);
+ tunnel_use_path (t, p);
+ send_create_path (t);
}
else if (NULL == peer->dhtget)
{
struct GNUNET_PeerIdentity id;
GNUNET_PEER_resolve (peer->id, &id);
- path_info = GNUNET_malloc (sizeof (struct MeshPathInfo));
- path_info->peer = peer;
- path_info->t = t;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" Starting DHT GET for peer %s\n", GNUNET_i2s (&id));
- peer->dhtgetcls = path_info;
peer->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */
GNUNET_BLOCK_TYPE_MESH_PEER, /* type */
&id.hashPubKey, /* key to search */
dht_replication_level, /* replication level */
GNUNET_DHT_RO_RECORD_ROUTE |
GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
- NULL, /* xquery */ // FIXME BLOOMFILTER
- 0, /* xquery bits */ // FIXME BLOOMFILTER SIZE
- &dht_get_id_handler, path_info);
+ NULL, /* xquery */
+ 0, /* xquery bits */
+ &dht_get_id_handler, peer);
+ t->state = MESH_TUNNEL_SEARCHING;
}
- /* Otherwise, there is no path but the DHT get is already started. */
-}
-
-
-/**
- * Task to delay the connection of a peer
- *
- * @param cls Closure (path info with tunnel and peer to connect).
- * Will be free'd on exection.
- * @param tc TaskContext
- */
-static void
-peer_info_connect_task (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct MeshPathInfo *path_info = cls;
-
- path_info->peer->connect_task = GNUNET_SCHEDULER_NO_TASK;
-
- if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
+ else
{
- GNUNET_free (cls);
- return;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "There is no path but the DHT GET is already started.\n");
}
- peer_info_connect (path_info->peer, path_info->t);
- GNUNET_free (cls);
}
@@ -2394,6 +1301,7 @@ peer_info_destroy (struct MeshPeerInfo *pi)
struct GNUNET_PeerIdentity id;
struct MeshPeerPath *p;
struct MeshPeerPath *nextp;
+ unsigned int i;
GNUNET_PEER_resolve (pi->id, &id);
GNUNET_PEER_change_rc (pi->id, -1);
@@ -2408,7 +1316,6 @@ peer_info_destroy (struct MeshPeerInfo *pi)
if (NULL != pi->dhtget)
{
GNUNET_DHT_get_stop (pi->dhtget);
- GNUNET_free (pi->dhtgetcls);
}
p = pi->path_head;
while (NULL != p)
@@ -2418,10 +1325,9 @@ peer_info_destroy (struct MeshPeerInfo *pi)
path_destroy (p);
p = nextp;
}
- if (GNUNET_SCHEDULER_NO_TASK != pi->connect_task)
- {
- GNUNET_free (GNUNET_SCHEDULER_cancel (pi->connect_task));
- }
+ for (i = 0; i < pi->ntunnels; i++)
+ tunnel_destroy_empty (pi->tunnels[i]);
+ GNUNET_array_grow (pi->tunnels, pi->ntunnels, 0);
GNUNET_free (pi);
return GNUNET_OK;
}
@@ -2439,24 +1345,21 @@ peer_info_destroy (struct MeshPeerInfo *pi)
* TODO: optimize (see below)
*/
static void
-peer_info_remove_path (struct MeshPeerInfo *peer, GNUNET_PEER_Id p1,
+peer_remove_path (struct MeshPeerInfo *peer, GNUNET_PEER_Id p1,
GNUNET_PEER_Id p2)
{
struct MeshPeerPath *p;
- struct MeshPeerPath *aux;
+ struct MeshPeerPath *next;
struct MeshPeerInfo *peer_d;
GNUNET_PEER_Id d;
unsigned int destroyed;
- unsigned int best;
- unsigned int cost;
unsigned int i;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer_info_remove_path\n");
destroyed = 0;
- p = peer->path_head;
- while (NULL != p)
+ for (p = peer->path_head; NULL != p; p = next)
{
- aux = p->next;
+ next = p->next;
for (i = 0; i < (p->length - 1); i++)
{
if ((p->peers[i] == p1 && p->peers[i + 1] == p2) ||
@@ -2468,7 +1371,6 @@ peer_info_remove_path (struct MeshPeerInfo *peer, GNUNET_PEER_Id p1,
break;
}
}
- p = aux;
}
if (0 == destroyed)
return;
@@ -2478,39 +1380,11 @@ peer_info_remove_path (struct MeshPeerInfo *peer, GNUNET_PEER_Id p1,
d = tunnel_notify_connection_broken (peer->tunnels[i], p1, p2);
if (0 == d)
continue;
- /* TODO
- * Problem: one or more peers have been deleted from the tunnel tree.
- * We don't know who they are to try to add them again.
- * We need to try to find a new path for each of the disconnected peers.
- * Some of them might already have a path to reach them that does not
- * involve p1 and p2. Adding all anew might render in a better tree than
- * the trivial immediate fix.
- *
- * Trivial immiediate fix: try to reconnect to the disconnected node. All
- * its children will be reachable trough him.
- */
- peer_d = peer_info_get_short (d);
- best = UINT_MAX;
- aux = NULL;
- for (p = peer_d->path_head; NULL != p; p = p->next)
- {
- if ((cost = tree_get_path_cost (peer->tunnels[i]->tree, p)) < best)
- {
- best = cost;
- aux = p;
- }
- }
- if (NULL != aux)
- {
- /* No callback, as peer will be already disconnected and a connection
- * scheduled by tunnel_notify_connection_broken.
- */
- tree_add_path (peer->tunnels[i]->tree, aux, NULL, NULL);
- }
- else
- {
- peer_info_connect (peer_d, peer->tunnels[i]);
- }
+
+ peer_d = peer_get_short (d);
+ next = peer_get_best_path (peer_d, peer->tunnels[i]);
+ tunnel_use_path (peer->tunnels[i], next);
+ peer_connect (peer_d, peer->tunnels[i]);
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer_info_remove_path END\n");
}
@@ -2545,13 +1419,12 @@ peer_info_add_path (struct MeshPeerInfo *peer_info, struct MeshPeerPath *path,
path_destroy (path);
return;
}
- if (path->length <= 2 && GNUNET_NO == trusted)
+ if (2 >= path->length && GNUNET_NO == trusted)
{
/* Only allow CORE to tell us about direct paths */
path_destroy (path);
return;
}
- GNUNET_assert (peer_info->id == path->peers[path->length - 1]);
for (l = 1; l < path->length; l++)
{
if (path->peers[l] == myid)
@@ -2579,7 +1452,7 @@ peer_info_add_path (struct MeshPeerInfo *peer_info, struct MeshPeerPath *path,
l = path_get_length (path);
if (0 == l)
{
- GNUNET_free (path);
+ path_destroy (path);
return;
}
@@ -2616,6 +1489,7 @@ peer_info_add_path (struct MeshPeerInfo *peer_info, struct MeshPeerPath *path,
*
* @param peer_info Peer to add the path to, being the origin of the path.
* @param path New path to add after being inversed.
+ * Path will be either used or freed.
* @param trusted Do we trust that this path is real?
*/
static void
@@ -2628,40 +1502,98 @@ peer_info_add_path_to_origin (struct MeshPeerInfo *peer_info,
/**
+ * Add a tunnel to the list of tunnels a peer participates in.
+ * Update the tunnel's destination.
+ *
+ * @param p Peer to add to.
+ * @param t Tunnel to add.
+ */
+static void
+peer_info_add_tunnel (struct MeshPeerInfo *p, struct MeshTunnel *t)
+{
+ if (0 != t->dest)
+ {
+ GNUNET_break (t->dest == p->id);
+ return;
+ }
+ t->dest = p->id;
+ GNUNET_PEER_change_rc (t->dest, 1);
+ GNUNET_array_append (p->tunnels, p->ntunnels, t);
+}
+
+
+/**
+ * Remove a tunnel from the list of tunnels a peer participates in.
+ * Free the tunnel's destination.
+ *
+ * @param p Peer to clean.
+ * @param t Tunnel to remove.
+ */
+static void
+peer_info_remove_tunnel (struct MeshPeerInfo *p, struct MeshTunnel *t)
+{
+ unsigned int i;
+
+ if (t->dest == p->id)
+ {
+ GNUNET_PEER_change_rc (t->dest, -1);
+ t->dest = 0;
+ }
+ for (i = 0; i < p->ntunnels; i++)
+ {
+ if (p->tunnels[i] == t)
+ {
+ p->tunnels[i] = p->tunnels[p->ntunnels - 1];
+ GNUNET_array_grow (p->tunnels, p->ntunnels, p->ntunnels - 1);
+ return;
+ }
+ }
+}
+
+
+/**
* Function called if the connection to the peer has been stalled for a while,
* possibly due to a missed ACK. Poll the peer about its ACK status.
*
- * @param cls Closure (cinfo).
+ * @param cls Closure (poll ctx).
* @param tc TaskContext.
*/
static void
tunnel_poll (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct MeshTunnelChildInfo *cinfo = cls;
+ struct MeshFlowControl *fc = cls;
struct GNUNET_MESH_Poll msg;
- struct GNUNET_PeerIdentity id;
- struct MeshTunnel *t;
+ struct MeshTunnel *t = fc->t;
+ GNUNET_PEER_Id peer;
- cinfo->fc_poll = GNUNET_SCHEDULER_NO_TASK;
+ fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
{
return;
}
- t = cinfo->t;
msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_POLL);
msg.header.size = htons (sizeof (msg));
msg.tid = htonl (t->id.tid);
GNUNET_PEER_resolve (t->id.oid, &msg.oid);
- msg.last_ack = htonl (cinfo->fwd_ack);
-
- GNUNET_PEER_resolve (cinfo->id, &id);
- send_prebuilt_message (&msg.header, &id, cinfo->t);
- cinfo->fc_poll_time = GNUNET_TIME_relative_min (
- MESH_MAX_POLL_TIME,
- GNUNET_TIME_relative_multiply (cinfo->fc_poll_time, 2));
- cinfo->fc_poll = GNUNET_SCHEDULER_add_delayed (cinfo->fc_poll_time,
- &tunnel_poll, cinfo);
+
+ if (fc == &t->prev_fc)
+ {
+ peer = t->prev_hop;
+ }
+ else if (fc == &t->next_fc)
+ {
+ peer = t->next_hop;
+ }
+ else
+ {
+ GNUNET_break (0);
+ return;
+ }
+ send_prebuilt_message (&msg.header, peer, t);
+ fc->poll_time = GNUNET_TIME_STD_BACKOFF (fc->poll_time);
+ fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
+ &tunnel_poll, fc);
}
@@ -2770,10 +1702,10 @@ path_add_to_peers (struct MeshPeerPath *p, int confirmed)
struct MeshPeerInfo *aux;
struct MeshPeerPath *copy;
- aux = peer_info_get_short (p->peers[i]);
+ aux = peer_get_short (p->peers[i]);
copy = path_duplicate (p);
copy->length = i + 1;
- peer_info_add_path (aux, copy, GNUNET_NO);
+ peer_info_add_path (aux, copy, p->length < 3 ? GNUNET_NO : confirmed);
}
}
@@ -2783,8 +1715,6 @@ path_add_to_peers (struct MeshPeerPath *p, int confirmed)
*
* @param cls Closure (tunnel for which to send the keepalive).
* @param tc Notification context.
- *
- * TODO: implement explicit multicast keepalive?
*/
static void
path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
@@ -2803,7 +1733,7 @@ tunnel_get_incoming (MESH_TunnelNumber tid)
struct GNUNET_HashCode hash;
GNUNET_assert (tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV);
- GNUNET_CRYPTO_hash (&tid, sizeof (MESH_TunnelNumber), &hash);
+ GMC_hash32 (tid, &hash);
return GNUNET_CONTAINER_multihashmap_get (incoming_tunnels, &hash);
}
@@ -2827,7 +1757,7 @@ tunnel_get_by_local_id (struct MeshClient *c, MESH_TunnelNumber tid)
{
struct GNUNET_HashCode hash;
- GNUNET_CRYPTO_hash (&tid, sizeof (MESH_TunnelNumber), &hash);
+ GMC_hash32 (tid, &hash);
return GNUNET_CONTAINER_multihashmap_get (c->own_tunnels, &hash);
}
}
@@ -2871,240 +1801,77 @@ tunnel_get (const struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid)
/**
- * Delete an active client from the tunnel.
- *
- * @param t Tunnel.
- * @param c Client.
- */
-static void
-tunnel_delete_active_client (struct MeshTunnel *t, const struct MeshClient *c)
-{
- unsigned int i;
-
- for (i = 0; i < t->nclients; i++)
- {
- if (t->clients[i] == c)
- {
- t->clients[i] = t->clients[t->nclients - 1];
- t->clients_fc[i] = t->clients_fc[t->nclients - 1];
- GNUNET_array_grow (t->clients, t->nclients, t->nclients - 1);
- t->nclients++;
- GNUNET_array_grow (t->clients_fc, t->nclients, t->nclients - 1);
- break;
- }
- }
-}
-
-
-/**
- * Delete an ignored client from the tunnel.
+ * Add a client to a tunnel, initializing all needed data structures.
*
- * @param t Tunnel.
- * @param c Client.
+ * @param t Tunnel to which add the client.
+ * @param c Client which to add to the tunnel.
*/
static void
-tunnel_delete_ignored_client (struct MeshTunnel *t, const struct MeshClient *c)
+tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c)
{
- unsigned int i;
+ struct GNUNET_HashCode hash;
- for (i = 0; i < t->nignore; i++)
+ if (NULL != t->client)
{
- if (t->ignore[i] == c)
- {
- t->ignore[i] = t->ignore[t->nignore - 1];
- GNUNET_array_grow (t->ignore, t->nignore, t->nignore - 1);
- break;
- }
+ GNUNET_break(0);
+ return;
}
-}
-
-
-/**
- * Delete a client from the tunnel. It should be only done on
- * client disconnection, otherwise use client_ignore_tunnel.
- *
- * @param t Tunnel.
- * @param c Client.
- */
-static void
-tunnel_delete_client (struct MeshTunnel *t, const struct MeshClient *c)
-{
- tunnel_delete_ignored_client (t, c);
- tunnel_delete_active_client (t, c);
-}
-
-
-/**
- * @brief Iterator to destroy MeshTunnelChildInfo of tunnel children.
- *
- * Destroys queue elements of all waiting transmissions and frees all memory
- * used by the struct and its elements.
- *
- * @param cls Closure (tunnel info).
- * @param key Hash of GNUNET_PEER_Id (unused).
- * @param value MeshTunnelChildInfo of the child.
- *
- * @return always GNUNET_YES, to keep iterating
- */
-static int
-tunnel_destroy_child (void *cls,
- const struct GNUNET_HashCode * key,
- void *value)
-{
- struct MeshTunnelChildInfo *cinfo = value;
- struct MeshTunnel *t = cls;
- struct MeshPeerQueue *q;
- unsigned int c;
- unsigned int i;
-
- for (c = 0; c < cinfo->send_buffer_n; c++)
+ GMC_hash32 (t->local_tid_dest, &hash);
+ if (GNUNET_OK !=
+ GNUNET_CONTAINER_multihashmap_put (c->incoming_tunnels, &hash, t,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
{
- i = (cinfo->send_buffer_start + c) % t->fwd_queue_max;
- q = cinfo->send_buffer[i];
- cinfo->send_buffer[i] = NULL;
- if (NULL != q)
- queue_destroy (q, GNUNET_YES);
- else
- GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "%u %u\n", c, cinfo->send_buffer_n);
+ GNUNET_break (0);
+ return;
}
- GNUNET_free_non_null (cinfo->send_buffer);
- if (GNUNET_SCHEDULER_NO_TASK != cinfo->fc_poll)
+ if (GNUNET_OK !=
+ GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
{
- GNUNET_SCHEDULER_cancel (cinfo->fc_poll);
- cinfo->fc_poll = GNUNET_SCHEDULER_NO_TASK;
+ GNUNET_break (0);
+ return;
}
- GNUNET_free (cinfo);
- return GNUNET_YES;
+ t->client = c;
}
-/**
- * Callback used to notify a client owner of a tunnel that a peer has
- * disconnected, most likely because of a path change.
- *
- * @param cls Closure (tunnel this notification is about).
- * @param peer_id Short ID of disconnected peer.
- */
-void
-tunnel_notify_client_peer_disconnected (void *cls, GNUNET_PEER_Id peer_id)
-{
- struct MeshTunnel *t = cls;
- struct MeshPeerInfo *peer;
- struct MeshPathInfo *path_info;
-
- client_notify_peer_disconnected (t->owner, t, peer_id);
-
- peer = peer_info_get_short (peer_id);
- path_info = GNUNET_malloc (sizeof (struct MeshPathInfo));
- path_info->peer = peer;
- path_info->t = t;
- peer->connect_task = GNUNET_SCHEDULER_add_now (&peer_info_connect_task,
- path_info);
-}
-
-
-/**
- * Add a peer to a tunnel, accomodating paths accordingly and initializing all
- * needed rescources.
- * If peer already exists, reevaluate shortest path and change if different.
- *
- * @param t Tunnel we want to add a new peer to
- * @param peer PeerInfo of the peer being added
- *
- */
static void
-tunnel_add_peer (struct MeshTunnel *t, struct MeshPeerInfo *peer)
+tunnel_use_path (struct MeshTunnel *t, struct MeshPeerPath *p)
{
- struct GNUNET_PeerIdentity id;
- struct MeshPeerPath *best_p;
- struct MeshPeerPath *p;
- unsigned int best_cost;
- unsigned int cost;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tunnel_add_peer\n");
- GNUNET_PEER_resolve (peer->id, &id);
- if (GNUNET_NO ==
- GNUNET_CONTAINER_multihashmap_contains (t->peers, &id.hashPubKey))
- {
- GNUNET_array_append (peer->tunnels, peer->ntunnels, t);
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_multihashmap_put (t->peers, &id.hashPubKey,
- peer,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
- }
+ unsigned int own_pos;
- if (NULL != (p = peer->path_head))
+ for (own_pos = 0; own_pos < p->length; own_pos++)
{
- best_p = p;
- best_cost = tree_get_path_cost (t->tree, p);
- while (NULL != p)
- {
- if ((cost = tree_get_path_cost (t->tree, p)) < best_cost)
- {
- best_cost = cost;
- best_p = p;
- }
- p = p->next;
- }
- tree_add_path (t->tree, best_p, &tunnel_notify_client_peer_disconnected, t);
- if (GNUNET_SCHEDULER_NO_TASK == t->path_refresh_task)
- t->path_refresh_task =
- GNUNET_SCHEDULER_add_delayed (refresh_path_time, &path_refresh, t);
+ if (p->peers[own_pos] == myid)
+ break;
}
- else
+ if (own_pos > p->length - 1)
{
- /* Start a DHT get */
- peer_info_connect (peer, t);
+ GNUNET_break (0);
+ return;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tunnel_add_peer END\n");
-}
-
-/**
- * Add a path to a tunnel which we don't own, just to remember the next hop.
- * If destination node was already in the tunnel, the first hop information
- * will be replaced with the new path.
- *
- * @param t Tunnel we want to add a new peer to
- * @param p Path to add
- * @param own_pos Position of local node in path.
- *
- */
-static void
-tunnel_add_path (struct MeshTunnel *t, struct MeshPeerPath *p,
- unsigned int own_pos)
-{
- struct GNUNET_PeerIdentity id;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tunnel_add_path\n");
- GNUNET_assert (0 != own_pos);
- tree_add_path (t->tree, p, NULL, NULL);
if (own_pos < p->length - 1)
+ t->next_hop = p->peers[own_pos + 1];
+ else
+ t->next_hop = p->peers[own_pos];
+ GNUNET_PEER_change_rc (t->next_hop, 1);
+ if (0 < own_pos)
+ t->prev_hop = p->peers[own_pos - 1];
+ else
+ t->prev_hop = p->peers[0];
+ GNUNET_PEER_change_rc (t->prev_hop, 1);
+
+ if (NULL != t->path)
+ path_destroy (t->path);
+ t->path = path_duplicate (p);
+ if (0 == own_pos)
{
- GNUNET_PEER_resolve (p->peers[own_pos + 1], &id);
- tree_update_first_hops (t->tree, myid, &id);
+ if (GNUNET_SCHEDULER_NO_TASK != t->maintenance_task)
+ GNUNET_SCHEDULER_cancel (t->maintenance_task);
+ t->maintenance_task = GNUNET_SCHEDULER_add_delayed (refresh_path_time,
+ &path_refresh, t);
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tunnel_add_path END\n");
-}
-
-/**
- * Add a client to a tunnel, initializing all needed data structures.
- *
- * @param t Tunnel to which add the client.
- * @param c Client which to add to the tunnel.
- */
-static void
-tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c)
-{
- struct MeshTunnelClientInfo clinfo;
-
- GNUNET_array_append (t->clients, t->nclients, c);
- clinfo.fwd_ack = t->fwd_pid + 1;
- clinfo.bck_ack = t->nobuffer ? 1 : INITIAL_WINDOW_SIZE - 1;
- clinfo.fwd_pid = t->fwd_pid;
- clinfo.bck_pid = (uint32_t) -1; // Expected next: 0
- t->nclients--;
- GNUNET_array_append (t->clients_fc, t->nclients, clinfo);
}
@@ -3125,452 +1892,27 @@ static GNUNET_PEER_Id
tunnel_notify_connection_broken (struct MeshTunnel *t, GNUNET_PEER_Id p1,
GNUNET_PEER_Id p2)
{
- GNUNET_PEER_Id pid;
-
- pid =
- tree_notify_connection_broken (t->tree, p1, p2,
- &tunnel_notify_client_peer_disconnected,
- t);
- if (myid != p1 && myid != p2)
- {
- return pid;
- }
- if (pid != myid)
- {
- if (tree_get_predecessor (t->tree) != 0)
- {
- /* We are the peer still connected, notify owner of the disconnection. */
- struct GNUNET_MESH_PathBroken msg;
- struct GNUNET_PeerIdentity neighbor;
-
- msg.header.size = htons (sizeof (msg));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN);
- GNUNET_PEER_resolve (t->id.oid, &msg.oid);
- msg.tid = htonl (t->id.tid);
- msg.peer1 = my_full_id;
- GNUNET_PEER_resolve (pid, &msg.peer2);
- GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &neighbor);
- send_prebuilt_message (&msg.header, &neighbor, t);
- }
- }
- return pid;
-}
-
-
-/**
- * Send a multicast packet to a neighbor.
- *
- * @param cls Closure (Info about the multicast packet)
- * @param neighbor_id Short ID of the neighbor to send the packet to.
- */
-static void
-tunnel_send_multicast_iterator (void *cls, GNUNET_PEER_Id neighbor_id)
-{
- struct MeshData *mdata = cls;
- struct MeshTransmissionDescriptor *info;
- struct GNUNET_PeerIdentity neighbor;
- struct GNUNET_MessageHeader *msg;
-
- info = GNUNET_malloc (sizeof (struct MeshTransmissionDescriptor));
-
- info->mesh_data = mdata;
- (mdata->reference_counter) ++;
- info->destination = neighbor_id;
- GNUNET_PEER_resolve (neighbor_id, &neighbor);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending to %s...\n",
- GNUNET_i2s (&neighbor));
- info->peer = peer_info_get (&neighbor);
- GNUNET_assert (NULL != info->peer);
- msg = (struct GNUNET_MessageHeader *) mdata->data;
- queue_add(info,
- ntohs (msg->type),
- info->mesh_data->data_len,
- info->peer,
- mdata->t);
-}
-
-
-/**
- * Queue a message in a tunnel in multicast, sending a copy to each child node
- * down the local one in the tunnel tree.
- *
- * @param t Tunnel in which to send the data.
- * @param msg Message to be sent.
- */
-static void
-tunnel_send_multicast (struct MeshTunnel *t,
- const struct GNUNET_MessageHeader *msg)
-{
- struct MeshData *mdata;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " sending a multicast packet...\n");
-
- mdata = GNUNET_malloc (sizeof (struct MeshData));
- mdata->data_len = ntohs (msg->size);
- mdata->t = t;
- mdata->data = GNUNET_malloc (mdata->data_len);
- memcpy (mdata->data, msg, mdata->data_len);
- if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_MESH_MULTICAST)
- {
- struct GNUNET_MESH_Multicast *mcast;
-
- mcast = (struct GNUNET_MESH_Multicast *) mdata->data;
- if (t->fwd_queue_n >= t->fwd_queue_max)
- {
- GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " queue full!\n");
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- " message from %s!\n",
- GNUNET_i2s(&mcast->oid));
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- " message at %s!\n",
- GNUNET_i2s(&my_full_id));
- GNUNET_free (mdata->data);
- GNUNET_free (mdata);
- return;
- }
- t->fwd_queue_n++;
- mcast->ttl = htonl (ntohl (mcast->ttl) - 1);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " data packet, ttl: %u\n",
- ntohl (mcast->ttl));
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " not a data packet, no ttl\n");
- }
-
- tree_iterate_children (t->tree, &tunnel_send_multicast_iterator, mdata);
- if (mdata->reference_counter == 0)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " no one to send data to\n");
- GNUNET_free (mdata->data);
- GNUNET_free (mdata);
- if (ntohs (msg->type) == GNUNET_MESSAGE_TYPE_MESH_MULTICAST)
- t->fwd_queue_n--;
- }
- else
- {
- mdata->total_out = mdata->reference_counter;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " sending a multicast packet done\n");
- return;
-}
-
-
-/**
- * Increase the SKIP value of all peers that
- * have not received a unicast message.
- *
- * @param cls Closure (ID of the peer that HAS received the message).
- * @param key ID of the neighbor.
- * @param value Information about the neighbor.
- *
- * @return GNUNET_YES to keep iterating.
- */
-static int
-tunnel_add_skip (void *cls,
- const struct GNUNET_HashCode * key,
- void *value)
-{
- struct GNUNET_PeerIdentity *neighbor = cls;
- struct MeshTunnelChildInfo *cinfo = value;
-
- /* TODO compare only pointers? key == neighbor? */
- if (0 == memcmp (&neighbor->hashPubKey, key, sizeof (struct GNUNET_HashCode)))
- {
- return GNUNET_YES;
- }
- cinfo->skip++;
- return GNUNET_YES;
-}
-
-
-/**
- * @brief Get neighbor's Flow Control information.
- *
- * Retrieves the MeshTunnelChildInfo containing Flow Control data about a direct
- * descendant of the local node in a certain tunnel.
- * If the info is not yet there (recently created path), creates the data struct
- * and inserts it into the tunnel info, initialized to the current tunnel ACK
- * values.
- *
- * @param t Tunnel related.
- * @param peer Neighbor whose Flow Control info is needed.
- *
- * @return Neighbor's Flow Control info.
- */
-static struct MeshTunnelChildInfo *
-tunnel_get_neighbor_fc (struct MeshTunnel *t,
- const struct GNUNET_PeerIdentity *peer)
-{
- struct MeshTunnelChildInfo *cinfo;
-
- if (NULL == t->children_fc)
- return NULL;
-
- cinfo = GNUNET_CONTAINER_multihashmap_get (t->children_fc,
- &peer->hashPubKey);
- if (NULL == cinfo)
- {
- uint32_t delta;
-
- cinfo = GNUNET_malloc (sizeof (struct MeshTunnelChildInfo));
- cinfo->id = GNUNET_PEER_intern (peer);
- cinfo->skip = t->fwd_pid;
- cinfo->t = t;
-
- delta = t->nobuffer ? 1 : INITIAL_WINDOW_SIZE;
- cinfo->fwd_ack = t->fwd_pid + delta;
- cinfo->bck_ack = delta;
- cinfo->bck_pid = -1;
-
- cinfo->fc_poll = GNUNET_SCHEDULER_NO_TASK;
- cinfo->fc_poll_time = GNUNET_TIME_UNIT_SECONDS;
-
- cinfo->send_buffer =
- GNUNET_malloc (sizeof(struct MeshPeerQueue *) * t->fwd_queue_max);
-
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CONTAINER_multihashmap_put (t->children_fc,
- &peer->hashPubKey,
- cinfo,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
- }
- return cinfo;
-}
-
-
-/**
- * Get the Flow Control info of a client.
- *
- * @param t Tunnel on which to look.
- * @param c Client whose ACK to get.
- *
- * @return ACK value.
- */
-static struct MeshTunnelClientInfo *
-tunnel_get_client_fc (struct MeshTunnel *t,
- struct MeshClient *c)
-{
- unsigned int i;
-
- for (i = 0; i < t->nclients; i++)
- {
- if (t->clients[i] != c)
- continue;
- return &t->clients_fc[i];
- }
- GNUNET_assert (0);
- return NULL; // avoid compiler / coverity complaints
-}
-
-
-/**
- * Iterator to get the appropiate ACK value from all children nodes.
- *
- * @param cls Closue (tunnel).
- * @param id Id of the child node.
- */
-static void
-tunnel_get_child_fwd_ack (void *cls,
- GNUNET_PEER_Id id)
-{
- struct GNUNET_PeerIdentity peer_id;
- struct MeshTunnelChildInfo *cinfo;
- struct MeshTunnelChildIteratorContext *ctx = cls;
- struct MeshTunnel *t = ctx->t;
- uint32_t ack;
-
- GNUNET_PEER_resolve (id, &peer_id);
- cinfo = tunnel_get_neighbor_fc (t, &peer_id);
- ack = cinfo->fwd_ack;
-
- ctx->nchildren++;
- if (GNUNET_NO == ctx->init)
- {
- ctx->max_child_ack = ack;
- ctx->init = GNUNET_YES;
- }
-
- if (GNUNET_YES == t->speed_min)
- {
- ctx->max_child_ack = ctx->max_child_ack > ack ? ack : ctx->max_child_ack;
- }
- else
- {
- ctx->max_child_ack = ctx->max_child_ack > ack ? ctx->max_child_ack : ack;
- }
-
-}
-
-
-/**
- * Get the maximum PID allowed to transmit to any
- * tunnel child of the local peer, depending on the tunnel
- * buffering/speed settings.
- *
- * @param t Tunnel.
- *
- * @return Maximum PID allowed (uint32 MAX), -1LL if node has no children.
- */
-static int64_t
-tunnel_get_children_fwd_ack (struct MeshTunnel *t)
-{
- struct MeshTunnelChildIteratorContext ctx;
- ctx.t = t;
- ctx.max_child_ack = 0;
- ctx.nchildren = 0;
- ctx.init = GNUNET_NO;
- tree_iterate_children (t->tree, tunnel_get_child_fwd_ack, &ctx);
-
- if (0 == ctx.nchildren)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " tunnel has no children, no FWD ACK\n");
- return -1LL;
- }
-
- if (GNUNET_YES == t->nobuffer && GMC_is_pid_bigger(ctx.max_child_ack, t->fwd_pid))
- ctx.max_child_ack = t->fwd_pid + 1; // Might overflow, it's ok.
-
- return (int64_t) ctx.max_child_ack;
-}
-
-
-/**
- * Set the FWD ACK value of a client in a particular tunnel.
- *
- * @param t Tunnel affected.
- * @param c Client whose ACK to set.
- * @param ack ACK value.
- */
-static void
-tunnel_set_client_fwd_ack (struct MeshTunnel *t,
- struct MeshClient *c,
- uint32_t ack)
-{
- unsigned int i;
-
- for (i = 0; i < t->nclients; i++)
- {
- if (t->clients[i] != c)
- continue;
- t->clients_fc[i].fwd_ack = ack;
- return;
- }
- GNUNET_break (0);
-}
-
-
-/**
- * Get the highest ACK value of all clients in a particular tunnel,
- * according to the buffering/speed settings.
- *
- * @param t Tunnel on which to look.
- *
- * @return Corresponding ACK value (max uint32_t).
- * If no clients are suscribed, -1LL.
- */
-static int64_t
-tunnel_get_clients_fwd_ack (struct MeshTunnel *t)
-{
- unsigned int i;
- int64_t ack;
-
- if (0 == t->nclients)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " tunnel has no clients, no FWD ACK\n");
- return -1LL;
- }
-
- for (ack = -1LL, i = 0; i < t->nclients; i++)
- {
- if (-1LL == ack ||
- (GNUNET_YES == t->speed_min &&
- GNUNET_YES == GMC_is_pid_bigger (ack, t->clients_fc[i].fwd_ack)) ||
- (GNUNET_NO == t->speed_min &&
- GNUNET_YES == GMC_is_pid_bigger (t->clients_fc[i].fwd_ack, ack)))
- {
- ack = t->clients_fc[i].fwd_ack;
- }
- }
-
- if (GNUNET_YES == t->nobuffer && GMC_is_pid_bigger(ack, t->fwd_pid))
- ack = (uint32_t) t->fwd_pid + 1; // Might overflow, it's ok.
-
- return (uint32_t) ack;
-}
-
-
-/**
- * Get the current fwd ack value for a tunnel, taking in account the tunnel
- * mode and the status of all children nodes.
- *
- * @param t Tunnel.
- *
- * @return Maximum PID allowed.
- */
-static uint32_t
-tunnel_get_fwd_ack (struct MeshTunnel *t)
-{
- uint32_t ack;
- uint32_t count;
- uint32_t buffer_free;
- int64_t child_ack;
- int64_t client_ack;
-
- count = t->fwd_pid - t->skip;
- buffer_free = t->fwd_queue_max - t->fwd_queue_n;
- child_ack = tunnel_get_children_fwd_ack (t);
- client_ack = tunnel_get_clients_fwd_ack (t);
- if (GNUNET_YES == t->nobuffer)
- {
- ack = count;
- if (-1LL == child_ack)
- child_ack = client_ack;
- if (-1LL == child_ack)
- {
- GNUNET_break (0);
- client_ack = child_ack = ack;
- }
- }
- else
- {
- ack = count + buffer_free; // Overflow? OK!
- }
- if (-1LL == child_ack)
- {
- // Node has no children, child_ack AND core buffer are irrelevant.
- if (-1LL == client_ack) // No children AND no clients? Not good!
- {
- GNUNET_STATISTICS_update (stats, "# mesh acks with no target",
- 1, GNUNET_NO);
-
- }
- return (uint32_t) client_ack;
- }
- if (-1LL == client_ack)
- {
- client_ack = ack;
- }
- if (GNUNET_YES == t->speed_min)
- {
- ack = GMC_min_pid ((uint32_t) child_ack, ack);
- ack = GMC_min_pid ((uint32_t) client_ack, ack);
- }
- else
- {
- ack = GMC_max_pid ((uint32_t) child_ack, ack);
- ack = GMC_max_pid ((uint32_t) client_ack, ack);
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "c %u, bf %u, ch %lld, cl %lld, ACK: %u\n",
- count, buffer_free, child_ack, client_ack, ack);
- return ack;
+// if (myid != p1 && myid != p2) FIXME
+// {
+// return;
+// }
+//
+// if (tree_get_predecessor (t->tree) != 0)
+// {
+// /* We are the peer still connected, notify owner of the disconnection. */
+// struct GNUNET_MESH_PathBroken msg;
+// struct GNUNET_PeerIdentity neighbor;
+//
+// msg.header.size = htons (sizeof (msg));
+// msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN);
+// GNUNET_PEER_resolve (t->id.oid, &msg.oid);
+// msg.tid = htonl (t->id.tid);
+// msg.peer1 = my_full_id;
+// GNUNET_PEER_resolve (pid, &msg.peer2);
+// GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &neighbor);
+// send_prebuilt_message (&msg.header, &neighbor, t);
+// }
+ return 0;
}
@@ -3589,7 +1931,7 @@ send_local_ack (struct MeshTunnel *t, struct MeshClient *c, uint32_t ack)
msg.header.size = htons (sizeof (msg));
msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
msg.tunnel_id = htonl (t->owner == c ? t->local_tid : t->local_tid_dest);
- msg.max_pid = htonl (ack);
+ msg.ack = htonl (ack);
GNUNET_SERVER_notification_context_unicast(nc,
c->handle,
&msg.header,
@@ -3604,7 +1946,7 @@ send_local_ack (struct MeshTunnel *t, struct MeshClient *c, uint32_t ack)
* @param ack Value of the ACK.
*/
static void
-send_ack (struct MeshTunnel *t, struct GNUNET_PeerIdentity *peer, uint32_t ack)
+send_ack (struct MeshTunnel *t, GNUNET_PEER_Id peer, uint32_t ack)
{
struct GNUNET_MESH_ACK msg;
@@ -3619,36 +1961,6 @@ send_ack (struct MeshTunnel *t, struct GNUNET_PeerIdentity *peer, uint32_t ack)
/**
- * Notify a the owner of a tunnel about how many more
- * payload packages will we accept on a given tunnel.
- *
- * @param t Tunnel on which to send the ACK.
- */
-static void
-tunnel_send_client_fwd_ack (struct MeshTunnel *t)
-{
- uint32_t ack;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending client FWD ACK on tunnel %X\n",
- t->local_tid);
-
- ack = tunnel_get_fwd_ack (t);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ack);
- if (t->last_fwd_ack == ack)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " same as last, not sending!\n");
- return;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending!\n");
- t->last_fwd_ack = ack;
- send_local_ack (t, t->owner, ack);
-}
-
-
-/**
* Send an ACK informing the predecessor about the available buffer space.
* In case there is no predecessor, inform the owning client.
* If buffering is off, send only on behalf of children or self if endpoint.
@@ -3662,19 +1974,12 @@ tunnel_send_client_fwd_ack (struct MeshTunnel *t)
static void
tunnel_send_fwd_ack (struct MeshTunnel *t, uint16_t type)
{
- struct GNUNET_PeerIdentity id;
uint32_t ack;
- if (NULL != t->owner)
- {
- tunnel_send_client_fwd_ack (t);
- return;
- }
- /* Is it after unicast / multicast retransmission? */
+ /* Is it after unicast retransmission? */
switch (type)
{
case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"ACK due to FWD DATA retransmission\n");
if (GNUNET_YES == t->nobuffer)
@@ -3686,6 +1991,7 @@ tunnel_send_fwd_ack (struct MeshTunnel *t, uint16_t type)
case GNUNET_MESSAGE_TYPE_MESH_ACK:
case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
break;
+ case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
case GNUNET_MESSAGE_TYPE_MESH_POLL:
t->force_ack = GNUNET_YES;
break;
@@ -3694,136 +2000,43 @@ tunnel_send_fwd_ack (struct MeshTunnel *t, uint16_t type)
}
/* Check if we need to transmit the ACK */
- if (t->fwd_queue_max > t->fwd_queue_n * 4 &&
- GMC_is_pid_bigger(t->last_fwd_ack, t->fwd_pid) &&
+ if (t->queue_max > t->next_fc.queue_n * 4 &&
+ GMC_is_pid_bigger(t->prev_fc.last_ack_sent, t->prev_fc.last_pid_recv) &&
GNUNET_NO == t->force_ack)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, buffer free\n");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" t->qmax: %u, t->qn: %u\n",
- t->fwd_queue_max, t->fwd_queue_n);
+ t->queue_max, t->next_fc.queue_n);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" t->pid: %u, t->ack: %u\n",
- t->fwd_pid, t->last_fwd_ack);
+ t->prev_fc.last_pid_recv, t->prev_fc.last_ack_sent);
return;
}
/* Ok, ACK might be necessary, what PID to ACK? */
- ack = tunnel_get_fwd_ack (t);
-
- /* If speed_min and not all children have ack'd, dont send yet */
- if (ack == t->last_fwd_ack && GNUNET_NO == t->force_ack)
+ ack = t->prev_fc.last_pid_recv + t->queue_max - t->next_fc.queue_n;
+ if (ack == t->prev_fc.last_ack_sent && GNUNET_NO == t->force_ack)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending FWD ACK, not ready\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Not sending FWD ACK, not needed\n");
return;
}
- t->last_fwd_ack = ack;
- GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &id);
- send_ack (t, &id, ack);
+ t->prev_fc.last_ack_sent = ack;
+ if (NULL != t->owner)
+ send_local_ack (t, t->owner, ack);
+ else if (0 != t->prev_hop)
+ send_ack (t, t->prev_hop, ack);
+ else
+ GNUNET_break (0);
debug_fwd_ack++;
t->force_ack = GNUNET_NO;
}
/**
- * Iterator to send a child node a BCK ACK to allow him to send more
- * to_origin data.
- *
- * @param cls Closure (tunnel).
- * @param id Id of the child node.
- */
-static void
-tunnel_send_child_bck_ack (void *cls,
- GNUNET_PEER_Id id)
-{
- struct MeshTunnel *t = cls;
- struct MeshTunnelChildInfo *cinfo;
- struct GNUNET_PeerIdentity peer;
- uint32_t ack;
-
- GNUNET_PEER_resolve (id, &peer);
- cinfo = tunnel_get_neighbor_fc (t, &peer);
- ack = cinfo->bck_pid + t->bck_queue_max - t->bck_queue_n;
-
- if (cinfo->bck_ack == ack && GNUNET_NO == t->force_ack)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Not sending ACK, not needed\n");
- return;
- }
- cinfo->bck_ack = ack;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Sending BCK ACK %u (last sent: %u)\n",
- ack, cinfo->bck_ack);
- send_ack (t, &peer, ack);
-}
-
-
-/**
- * @brief Send BCK ACKs to clients to allow them more to_origin traffic
- *
- * Iterates over all clients and sends BCK ACKs to the ones that need it.
- *
- * FIXME fc: what happens if we have 2 clients but q_size is 1?
- * - implement a size 1 buffer in each client_fc AND children_fc
- * to hold at least 1 message per "child".
- * problem: violates no buffer policy
- * - ack 0 and make "children" poll for transmission slots
- * problem: big overhead, extra latency even in low traffic
- * settings
- *
- * @param t Tunnel on which to send the BCK ACKs.
- */
-static void
-tunnel_send_clients_bck_ack (struct MeshTunnel *t)
-{
- unsigned int i;
- unsigned int tunnel_delta;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Sending BCK ACK to clients\n");
-
- tunnel_delta = t->bck_queue_max - t->bck_queue_n;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " tunnel delta: %u\n", tunnel_delta);
-
- /* Find client whom to allow to send to origin (with lowest buffer space) */
- for (i = 0; i < t->nclients; i++)
- {
- struct MeshTunnelClientInfo *clinfo;
- unsigned int delta;
-
- clinfo = &t->clients_fc[i];
- delta = clinfo->bck_ack - clinfo->bck_pid;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client %u delta: %u\n",
- t->clients[i]->id, delta);
-
- if ((GNUNET_NO == t->nobuffer && tunnel_delta > delta) ||
- (GNUNET_YES == t->nobuffer && 0 == delta))
- {
- uint32_t ack;
-
- ack = clinfo->bck_pid;
- ack += t->nobuffer ? 1 : tunnel_delta;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " sending ack to client %u: %u\n",
- t->clients[i]->id, ack);
- send_local_ack (t, t->clients[i], ack);
- clinfo->bck_ack = ack;
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " not sending ack to client %u (td %u, d %u)\n",
- t->clients[i]->id, tunnel_delta, delta);
- }
- }
-}
-
-
-/**
- * Send an ACK informing the children nodes and destination clients about
- * the available buffer space.
+ * Send an ACK informing the children node/client about the available
+ * buffer space.
* If buffering is off, send only on behalf of root (can be self).
* If buffering is on, send when sent to predecessor and buffer space is free.
* Note that although the name is bck_ack, the BCK mean backwards *traffic*,
@@ -3835,6 +2048,7 @@ tunnel_send_clients_bck_ack (struct MeshTunnel *t)
static void
tunnel_send_bck_ack (struct MeshTunnel *t, uint16_t type)
{
+ uint32_t ack;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sending BCK ACK on tunnel %u [%u] due to %s\n",
t->id.oid, t->id.tid, GNUNET_MESH_DEBUG_M2S(type));
@@ -3845,13 +2059,14 @@ tunnel_send_bck_ack (struct MeshTunnel *t, uint16_t type)
if (GNUNET_YES == t->nobuffer)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Not sending ACK, nobuffer\n");
+ " Not sending ACK, nobuffer + traffic\n");
return;
}
break;
case GNUNET_MESSAGE_TYPE_MESH_ACK:
case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
break;
+ case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
case GNUNET_MESSAGE_TYPE_MESH_POLL:
t->force_ack = GNUNET_YES;
break;
@@ -3859,35 +2074,120 @@ tunnel_send_bck_ack (struct MeshTunnel *t, uint16_t type)
GNUNET_break (0);
}
- tunnel_send_clients_bck_ack (t);
- tree_iterate_children (t->tree, &tunnel_send_child_bck_ack, t);
+ /* TODO: Check if we need to transmit the ACK (as in fwd) */
+
+ ack = t->next_fc.last_pid_recv + t->queue_max - t->prev_fc.queue_n;
+
+ if (t->next_fc.last_ack_sent == ack && GNUNET_NO == t->force_ack)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ " Not sending ACK, not needed, last ack sent was %u\n",
+ t->next_fc.last_ack_sent);
+ return;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ " Sending BCK ACK %u (last sent: %u)\n",
+ ack, t->next_fc.last_ack_sent);
+ t->next_fc.last_ack_sent = ack;
+
+ if (NULL != t->client)
+ send_local_ack (t, t->client, ack);
+ else if (0 != t->next_hop)
+ send_ack (t, t->next_hop, ack);
+ else
+ GNUNET_break (0);
t->force_ack = GNUNET_NO;
}
/**
+ * Modify the unicast message TID from global to local and send to client.
+ *
+ * @param t Tunnel on which to send the message.
+ * @param msg Message to modify and send.
+ */
+static void
+tunnel_send_client_ucast (struct MeshTunnel *t,
+ const struct GNUNET_MESH_Data *msg)
+{
+ struct GNUNET_MESH_Data *copy;
+ uint16_t size = ntohs (msg->header.size);
+ char cbuf[size];
+
+ if (size < sizeof (struct GNUNET_MESH_Data) +
+ sizeof (struct GNUNET_MessageHeader))
+ {
+ GNUNET_break_op (0);
+ return;
+ }
+ if (NULL == t->client)
+ {
+ GNUNET_break (0);
+ return;
+ }
+ copy = (struct GNUNET_MESH_Data *) cbuf;
+ memcpy (copy, msg, size);
+ copy->tid = htonl (t->local_tid_dest);
+ GNUNET_SERVER_notification_context_unicast (nc, t->client->handle,
+ &copy->header, GNUNET_NO);
+}
+
+
+/**
+ * Modify the to_origin message TID from global to local and send to client.
+ *
+ * @param t Tunnel on which to send the message.
+ * @param msg Message to modify and send.
+ */
+static void
+tunnel_send_client_to_orig (struct MeshTunnel *t,
+ const struct GNUNET_MESH_Data *msg)
+{
+ struct GNUNET_MESH_Data *copy;
+ uint16_t size = ntohs (msg->header.size);
+ char cbuf[size];
+
+ if (size < sizeof (struct GNUNET_MESH_Data) +
+ sizeof (struct GNUNET_MessageHeader))
+ {
+ GNUNET_break_op (0);
+ return;
+ }
+ if (NULL == t->owner)
+ {
+ GNUNET_break (0);
+ return;
+ }
+ copy = (struct GNUNET_MESH_Data *) cbuf;
+ memcpy (cbuf, msg, size);
+ copy->tid = htonl (t->local_tid);
+ GNUNET_SERVER_notification_context_unicast (nc, t->owner->handle,
+ &copy->header, GNUNET_NO);
+}
+
+
+/**
* @brief Re-initiate traffic to this peer if necessary.
*
* Check if there is traffic queued towards this peer
* and the core transmit handle is NULL (traffic was stalled).
* If so, call core tmt rdy.
*
- * @param cls Closure (unused)
* @param peer_id Short ID of peer to which initiate traffic.
*/
static void
-peer_unlock_queue(void *cls, GNUNET_PEER_Id peer_id)
+peer_unlock_queue(GNUNET_PEER_Id peer_id)
{
struct MeshPeerInfo *peer;
struct GNUNET_PeerIdentity id;
struct MeshPeerQueue *q;
size_t size;
- peer = peer_info_get_short(peer_id);
+ peer = peer_get_short (peer_id);
if (NULL != peer->core_transmit)
return;
- q = queue_get_next(peer);
+ q = queue_get_next (peer);
if (NULL == q)
{
/* Might br multicast traffic already sent to this particular peer but
@@ -3913,50 +2213,14 @@ peer_unlock_queue(void *cls, GNUNET_PEER_Id peer_id)
/**
- * @brief Allow transmission of FWD traffic on this tunnel
- *
- * Check if there is traffic queued towards any children
- * and the core transmit handle is NULL, and if so, call core tmt rdy.
- *
- * @param t Tunnel on which to unlock FWD traffic.
- */
-static void
-tunnel_unlock_fwd_queues (struct MeshTunnel *t)
-{
- if (0 == t->fwd_queue_n)
- return;
-
- tree_iterate_children (t->tree, &peer_unlock_queue, NULL);
-}
-
-
-/**
- * @brief Allow transmission of BCK traffic on this tunnel
+ * Send a message to all peers and clients in this tunnel that the tunnel
+ * is no longer valid. If some peer or client should not receive the message,
+ * should be zero'ed out before calling this function.
*
- * Check if there is traffic queued towards the root of the tree
- * and the core transmit handle is NULL, and if so, call core tmt rdy.
- *
- * @param t Tunnel on which to unlock BCK traffic.
+ * @param t The tunnel whose peers and clients to notify.
*/
static void
-tunnel_unlock_bck_queue (struct MeshTunnel *t)
-{
- if (0 == t->bck_queue_n)
- return;
-
- peer_unlock_queue(NULL, tree_get_predecessor(t->tree));
-}
-
-
-/**
- * Send a message to all peers in this tunnel that the tunnel is no longer
- * valid.
- *
- * @param t The tunnel whose peers to notify.
- * @param parent ID of the parent, in case the tree is already destroyed.
- */
-static void
-tunnel_send_destroy (struct MeshTunnel *t, GNUNET_PEER_Id parent)
+tunnel_send_destroy (struct MeshTunnel *t)
{
struct GNUNET_MESH_TunnelDestroy msg;
struct GNUNET_PeerIdentity id;
@@ -3968,50 +2232,61 @@ tunnel_send_destroy (struct MeshTunnel *t, GNUNET_PEER_Id parent)
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" sending tunnel destroy for tunnel: %s [%X]\n",
GNUNET_i2s (&msg.oid), t->id.tid);
- if (tree_count_children(t->tree) > 0)
+
+ if (NULL == t->client && 0 != t->next_hop)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending multicast to children\n");
- tunnel_send_multicast (t, &msg.header);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " child: %u\n", t->next_hop);
+ GNUNET_PEER_resolve (t->next_hop, &id);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ " sending forward to %s\n",
+ GNUNET_i2s (&id));
+ send_prebuilt_message (&msg.header, t->next_hop, t);
+ }
+ if (NULL == t->owner && 0 != t->prev_hop)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " parent: %u\n", t->prev_hop);
+ GNUNET_PEER_resolve (t->prev_hop, &id);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ " sending back to %s\n",
+ GNUNET_i2s (&id));
+ send_prebuilt_message (&msg.header, t->prev_hop, t);
+ }
+ if (NULL != t->owner)
+ {
+ send_client_tunnel_destroy (t->owner, t);
+ }
+ if (NULL != t->client)
+ {
+ send_client_tunnel_destroy (t->client, t);
}
- if (0 == parent)
- parent = tree_get_predecessor (t->tree);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " parent: %u\n", parent);
- if (0 == parent)
- return;
-
- GNUNET_PEER_resolve (parent, &id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " sending back to %s\n",
- GNUNET_i2s (&id));
- send_prebuilt_message (&msg.header, &id, t);
}
/**
- * Cancel all transmissions towards a neighbor that belong to a certain tunnel.
+ * Cancel all transmissions towards a neighbor that belongs to a certain tunnel.
*
- * @param cls Closure (Tunnel which to cancel).
- * @param neighbor_id Short ID of the neighbor to whom cancel the transmissions.
+ * @param t Tunnel which to cancel.
+ * @param neighbor Short ID of the neighbor to whom cancel the transmissions.
*/
static void
-tunnel_cancel_queues (void *cls, GNUNET_PEER_Id neighbor_id)
+peer_cancel_queues (GNUNET_PEER_Id neighbor, struct MeshTunnel *t)
{
- struct MeshTunnel *t = cls;
struct MeshPeerInfo *peer_info;
struct MeshPeerQueue *pq;
struct MeshPeerQueue *next;
- peer_info = peer_info_get_short (neighbor_id);
+ if (0 == neighbor)
+ return; /* Was local peer, 0'ed in tunnel_destroy_iterator */
+ peer_info = peer_get_short (neighbor);
for (pq = peer_info->queue_head; NULL != pq; pq = next)
{
next = pq->next;
if (pq->tunnel == t)
{
- if (GNUNET_MESSAGE_TYPE_MESH_MULTICAST == pq->type ||
- GNUNET_MESSAGE_TYPE_MESH_UNICAST == pq->type ||
+ if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == pq->type ||
GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == pq->type)
{
- // Should have been removed on destroy children
+ /* Should have been removed on destroy children */
GNUNET_break (0);
}
queue_destroy (pq, GNUNET_YES);
@@ -4024,8 +2299,16 @@ tunnel_cancel_queues (void *cls, GNUNET_PEER_Id neighbor_id)
}
}
+
/**
- * Destroy the tunnel and free any allocated resources linked to it.
+ * Destroy the tunnel.
+ *
+ * This function does not generate any warning traffic to clients or peers.
+ *
+ * Tasks:
+ * Remove the tunnel from peer_info's and clients' hashmaps.
+ * Cancel messages belonging to this tunnel queued to neighbors.
+ * Free any allocated resources linked to the tunnel.
*
* @param t the tunnel to destroy
*
@@ -4036,7 +2319,6 @@ tunnel_destroy (struct MeshTunnel *t)
{
struct MeshClient *c;
struct GNUNET_HashCode hash;
- unsigned int i;
int r;
if (NULL == t)
@@ -4065,7 +2347,7 @@ tunnel_destroy (struct MeshTunnel *t)
if (NULL != c)
{
- GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
+ GMC_hash32 (t->local_tid, &hash);
if (GNUNET_YES !=
GNUNET_CONTAINER_multihashmap_remove (c->own_tunnels, &hash, t))
{
@@ -4074,86 +2356,58 @@ tunnel_destroy (struct MeshTunnel *t)
}
}
- GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
- for (i = 0; i < t->nclients; i++)
+ if (NULL != t->client)
{
- c = t->clients[i];
+ c = t->client;
+ GMC_hash32 (t->local_tid_dest, &hash);
if (GNUNET_YES !=
GNUNET_CONTAINER_multihashmap_remove (c->incoming_tunnels, &hash, t))
{
GNUNET_break (0);
r = GNUNET_SYSERR;
}
- }
- for (i = 0; i < t->nignore; i++)
- {
- c = t->ignore[i];
- if (GNUNET_YES !=
- GNUNET_CONTAINER_multihashmap_remove (c->ignore_tunnels, &hash, t))
+ if (GNUNET_YES !=
+ GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels, &hash, t))
{
GNUNET_break (0);
r = GNUNET_SYSERR;
}
}
- (void) GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels, &hash, t);
- GNUNET_free_non_null (t->clients);
- GNUNET_free_non_null (t->ignore);
- GNUNET_free_non_null (t->clients_fc);
-
- if (NULL != t->peers)
+ if (0 != t->prev_hop)
{
- GNUNET_CONTAINER_multihashmap_iterate (t->peers, &peer_info_delete_tunnel,
- t);
- GNUNET_CONTAINER_multihashmap_destroy (t->peers);
+ peer_cancel_queues (t->prev_hop, t);
+ GNUNET_PEER_change_rc (t->prev_hop, -1);
+ }
+ if (0 != t->next_hop)
+ {
+ peer_cancel_queues (t->next_hop, t);
+ GNUNET_PEER_change_rc (t->next_hop, -1);
+ }
+ if (0 != t->dest) {
+ peer_info_remove_tunnel (peer_get_short (t->dest), t);
}
- GNUNET_CONTAINER_multihashmap_iterate (t->children_fc,
- &tunnel_destroy_child,
- t);
- GNUNET_CONTAINER_multihashmap_destroy (t->children_fc);
- t->children_fc = NULL;
-
- tree_iterate_children (t->tree, &tunnel_cancel_queues, t);
- tree_destroy (t->tree);
-
- if (NULL != t->regex_search)
- GNUNET_REGEX_search_cancel (t->regex_search->search_handle);
- if (NULL != t->dht_get_type)
- GNUNET_DHT_get_stop (t->dht_get_type);
- if (GNUNET_SCHEDULER_NO_TASK != t->timeout_task)
- GNUNET_SCHEDULER_cancel (t->timeout_task);
- if (GNUNET_SCHEDULER_NO_TASK != t->path_refresh_task)
- GNUNET_SCHEDULER_cancel (t->path_refresh_task);
+ if (GNUNET_SCHEDULER_NO_TASK != t->maintenance_task)
+ GNUNET_SCHEDULER_cancel (t->maintenance_task);
n_tunnels--;
GNUNET_STATISTICS_update (stats, "# tunnels", -1, GNUNET_NO);
+ path_destroy (t->path);
GNUNET_free (t);
return r;
}
-#define TUNNEL_DESTROY_EMPTY_TIME GNUNET_TIME_UNIT_MILLISECONDS
-
/**
* Tunnel is empty: destroy it.
*
- * @param cls Closure (Tunnel).
- * @param tc TaskContext.
+ * Notifies all participants (peers, cleints) about the destruction.
+ *
+ * @param t Tunnel to destroy.
*/
static void
-tunnel_destroy_empty_delayed (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+tunnel_destroy_empty (struct MeshTunnel *t)
{
- struct MeshTunnel *t = cls;
-
- t->delayed_destroy = GNUNET_SCHEDULER_NO_TASK;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- return;
-
- if (0 != t->nclients ||
- 0 != tree_count_children (t->tree))
- return;
-
#if MESH_DEBUG
{
struct GNUNET_PeerIdentity id;
@@ -4165,50 +2419,31 @@ tunnel_destroy_empty_delayed (void *cls,
}
#endif
- tunnel_send_destroy (t, 0);
+ if (GNUNET_NO == t->destroy)
+ tunnel_send_destroy (t);
if (0 == t->pending_messages)
tunnel_destroy (t);
else
t->destroy = GNUNET_YES;
}
-
/**
- * Schedule tunnel destruction if is empty and no new traffic comes in a time.
+ * Initialize a Flow Control structure to the initial state.
*
- * @param t Tunnel to destroy if empty.
+ * @param fc Flow Control structure to initialize.
*/
static void
-tunnel_destroy_empty (struct MeshTunnel *t)
+fc_init (struct MeshFlowControl *fc)
{
- if (GNUNET_SCHEDULER_NO_TASK != t->delayed_destroy ||
- 0 != t->nclients ||
- 0 != tree_count_children (t->tree))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "%u %u %u\n",
- t->delayed_destroy, t->nclients, tree_count_children(t->tree));
- return;
- }
-
- #if MESH_DEBUG
- {
- struct GNUNET_PeerIdentity id;
-
- GNUNET_PEER_resolve (t->id.oid, &id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "scheduling destruction of empty tunnel %s [%X]\n",
- GNUNET_i2s (&id), t->id.tid);
- }
- #endif
-
- t->delayed_destroy =
- GNUNET_SCHEDULER_add_delayed (TUNNEL_DESTROY_EMPTY_TIME,
- &tunnel_destroy_empty_delayed,
- t);
+ fc->last_pid_sent = (uint32_t) -1; /* Next (expected) = 0 */
+ fc->last_pid_recv = (uint32_t) -1;
+ fc->last_ack_sent = (uint32_t) -1; /* No traffic allowed yet */
+ fc->last_ack_recv = (uint32_t) -1;
+ fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
+ fc->poll_time = GNUNET_TIME_UNIT_SECONDS;
+ fc->queue_n = 0;
}
-
/**
* Create a new tunnel
*
@@ -4234,16 +2469,11 @@ tunnel_new (GNUNET_PEER_Id owner,
t = GNUNET_malloc (sizeof (struct MeshTunnel));
t->id.oid = owner;
t->id.tid = tid;
- t->fwd_queue_max = (max_msgs_queue / max_tunnels) + 1;
- t->bck_queue_max = t->fwd_queue_max;
- t->tree = tree_new (owner);
+ t->queue_max = (max_msgs_queue / max_tunnels) + 1;
t->owner = client;
- t->fwd_pid = (uint32_t) -1; // Next (expected) = 0
- t->bck_pid = (uint32_t) -1; // Next (expected) = 0
- t->bck_ack = INITIAL_WINDOW_SIZE - 1;
- t->last_fwd_ack = INITIAL_WINDOW_SIZE - 1;
+ fc_init (&t->next_fc);
+ fc_init (&t->prev_fc);
t->local_tid = local;
- t->children_fc = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO);
n_tunnels++;
GNUNET_STATISTICS_update (stats, "# tunnels", 1, GNUNET_NO);
@@ -4264,7 +2494,7 @@ tunnel_new (GNUNET_PEER_Id owner,
if (NULL != client)
{
- GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
+ GMC_hash32 (t->local_tid, &hash);
if (GNUNET_OK !=
GNUNET_CONTAINER_multihashmap_put (client->own_tunnels, &hash, t,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
@@ -4279,52 +2509,14 @@ tunnel_new (GNUNET_PEER_Id owner,
return t;
}
-/**
- * Callback when removing children from a tunnel tree. Notify owner.
- *
- * @param cls Closure (tunnel).
- * @param peer_id Short ID of the peer deleted.
- */
-void
-tunnel_child_removed (void *cls, GNUNET_PEER_Id peer_id)
-{
- struct MeshTunnel *t = cls;
-
- client_notify_peer_disconnected (t->owner, t, peer_id);
-}
-
-/**
- * Removes an explicit path from a tunnel, freeing all intermediate nodes
- * that are no longer needed, as well as nodes of no longer reachable peers.
- * The tunnel itself is also destoyed if results in a remote empty tunnel.
- *
- * @param t Tunnel from which to remove the path.
- * @param peer Short id of the peer which should be removed.
- */
-static void
-tunnel_delete_peer (struct MeshTunnel *t, GNUNET_PEER_Id peer)
-{
- int r;
-
- r = tree_del_peer (t->tree, peer, &tunnel_child_removed, t);
- if (GNUNET_NO == r)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Tunnel %u [%u] has no more nodes\n",
- t->id.oid, t->id.tid);
- }
-}
/**
- * tunnel_destroy_iterator: iterator for deleting each tunnel that belongs to a
- * client when the client disconnects. If the client is not the owner, the
- * owner will get notified if no more clients are in the tunnel and the client
- * get removed from the tunnel's list.
+ * Iterator for deleting each tunnel whose client endpoint disconnected.
*
- * @param cls closure (client that is disconnecting)
- * @param key the hash of the local tunnel id (used to access the hashmap)
- * @param value the value stored at the key (tunnel to destroy)
+ * @param cls Closure (client that has disconnected).
+ * @param key The hash of the local tunnel id (used to access the hashmap).
+ * @param value The value stored at the key (tunnel to destroy).
*
* @return GNUNET_OK, keep iterating.
*/
@@ -4336,18 +2528,33 @@ tunnel_destroy_iterator (void *cls,
struct MeshTunnel *t = value;
struct MeshClient *c = cls;
- send_client_tunnel_disconnect (t, c);
- if (c != t->owner)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ " Tunnel %X / %X destroy, due to client %u shutdown.\n",
+ t->local_tid, t->local_tid_dest, c->id);
+ client_delete_tunnel (c, t);
+ if (c == t->client)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client %u is destination.\n", c->id);
- tunnel_delete_client (t, c);
- client_delete_tunnel (c, t);
- tunnel_destroy_empty (t);
- return GNUNET_OK;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Client %u is destination.\n", c->id);
+ t->client = NULL;
+ if (0 != t->next_hop) { /* destroy could come before a path is used */
+ GNUNET_PEER_change_rc (t->next_hop, -1);
+ t->next_hop = 0;
+ }
+ }
+ else if (c == t->owner)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Client %u is owner.\n", c->id);
+ t->owner = NULL;
+ if (0 != t->prev_hop) { /* destroy could come before a path is used */
+ GNUNET_PEER_change_rc (t->prev_hop, -1);
+ t->prev_hop = 0;
+ }
}
- tunnel_send_destroy (t, 0);
- t->owner = NULL;
- t->destroy = GNUNET_YES;
+ else
+ {
+ GNUNET_break (0);
+ }
+ tunnel_destroy_empty (t);
return GNUNET_OK;
}
@@ -4365,17 +2572,19 @@ tunnel_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
struct MeshTunnel *t = cls;
struct GNUNET_PeerIdentity id;
- t->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+ t->maintenance_task = GNUNET_SCHEDULER_NO_TASK;
if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
return;
GNUNET_PEER_resolve(t->id.oid, &id);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Tunnel %s [%X] timed out. Destroying.\n",
GNUNET_i2s(&id), t->id.tid);
- send_clients_tunnel_destroy (t);
- tunnel_destroy (t);
+ if (NULL != t->client)
+ send_client_tunnel_destroy (t->client, t);
+ tunnel_destroy (t); /* Do not notify other */
}
+
/**
* Resets the tunnel timeout. Starts it if no timeout was running.
*
@@ -4386,9 +2595,11 @@ tunnel_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
static void
tunnel_reset_timeout (struct MeshTunnel *t)
{
- if (GNUNET_SCHEDULER_NO_TASK != t->timeout_task)
- GNUNET_SCHEDULER_cancel (t->timeout_task);
- t->timeout_task =
+ if (NULL != t->owner || 0 != t->local_tid || 0 == t->prev_hop)
+ return;
+ if (GNUNET_SCHEDULER_NO_TASK != t->maintenance_task)
+ GNUNET_SCHEDULER_cancel (t->maintenance_task);
+ t->maintenance_task =
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
(refresh_path_time, 4), &tunnel_timeout, t);
}
@@ -4409,18 +2620,17 @@ tunnel_reset_timeout (struct MeshTunnel *t)
static size_t
send_core_path_create (void *cls, size_t size, void *buf)
{
- struct MeshPathInfo *info = cls;
- struct GNUNET_MESH_ManipulatePath *msg;
+ struct MeshTunnel *t = cls;
+ struct GNUNET_MESH_CreateTunnel *msg;
struct GNUNET_PeerIdentity *peer_ptr;
- struct MeshTunnel *t = info->t;
- struct MeshPeerPath *p = info->path;
+ struct MeshPeerPath *p = t->path;
size_t size_needed;
uint32_t opt;
int i;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CREATE PATH sending...\n");
size_needed =
- sizeof (struct GNUNET_MESH_ManipulatePath) +
+ sizeof (struct GNUNET_MESH_CreateTunnel) +
p->length * sizeof (struct GNUNET_PeerIdentity);
if (size < size_needed || NULL == buf)
@@ -4428,18 +2638,16 @@ send_core_path_create (void *cls, size_t size, void *buf)
GNUNET_break (0);
return 0;
}
- msg = (struct GNUNET_MESH_ManipulatePath *) buf;
+ msg = (struct GNUNET_MESH_CreateTunnel *) buf;
msg->header.size = htons (size_needed);
msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE);
msg->tid = ntohl (t->id.tid);
opt = 0;
- if (GNUNET_YES == t->speed_min)
- opt |= MESH_TUNNEL_OPT_SPEED_MIN;
if (GNUNET_YES == t->nobuffer)
opt |= MESH_TUNNEL_OPT_NOBUFFER;
- msg->opt = htonl(opt);
- msg->reserved = 0;
+ msg->opt = htonl (opt);
+ msg->port = htonl (t->port);
peer_ptr = (struct GNUNET_PeerIdentity *) &msg[1];
for (i = 0; i < p->length; i++)
@@ -4447,9 +2655,6 @@ send_core_path_create (void *cls, size_t size, void *buf)
GNUNET_PEER_resolve (p->peers[i], peer_ptr++);
}
- path_destroy (p);
- GNUNET_free (info);
-
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"CREATE PATH (%u bytes long) sent!\n", size_needed);
return size_needed;
@@ -4457,65 +2662,6 @@ send_core_path_create (void *cls, size_t size, void *buf)
/**
- * Fill the core buffer
- *
- * @param cls closure (data itself)
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- *
- * @return number of bytes written to buf
- */
-static size_t
-send_core_data_multicast (void *cls, size_t size, void *buf)
-{
- struct MeshTransmissionDescriptor *info = cls;
- size_t total_size;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Multicast callback.\n");
- GNUNET_assert (NULL != info);
- GNUNET_assert (NULL != info->peer);
- total_size = info->mesh_data->data_len;
- GNUNET_assert (total_size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
-
- if (total_size > size)
- {
- GNUNET_break (0);
- return 0;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " copying data...\n");
- memcpy (buf, info->mesh_data->data, total_size);
-#if MESH_DEBUG
- {
- struct GNUNET_MESH_Multicast *mc;
- struct GNUNET_MessageHeader *mh;
-
- mh = buf;
- if (ntohs (mh->type) == GNUNET_MESSAGE_TYPE_MESH_MULTICAST)
- {
- mc = (struct GNUNET_MESH_Multicast *) mh;
- mh = (struct GNUNET_MessageHeader *) &mc[1];
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " multicast, payload type %s\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " multicast, payload size %u\n", ntohs (mh->size));
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " type %s\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
- }
- }
-#endif
- data_descriptor_decrement_rc (info->mesh_data);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "freeing info...\n");
- GNUNET_free (info);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "return %u\n", total_size);
- return total_size;
-}
-
-
-/**
* Creates a path ack message in buf and frees all unused resources.
*
* @param cls closure (MeshTransmissionDescriptor)
@@ -4526,22 +2672,23 @@ send_core_data_multicast (void *cls, size_t size, void *buf)
static size_t
send_core_path_ack (void *cls, size_t size, void *buf)
{
- struct MeshTransmissionDescriptor *info = cls;
+ struct MeshTunnel *t = cls;
struct GNUNET_MESH_PathACK *msg = buf;
- GNUNET_assert (NULL != info);
+ GNUNET_assert (NULL != t);
if (sizeof (struct GNUNET_MESH_PathACK) > size)
{
GNUNET_break (0);
return 0;
}
+ t->prev_fc.last_ack_sent = t->nobuffer ? 0 : t->queue_max - 1;
msg->header.size = htons (sizeof (struct GNUNET_MESH_PathACK));
msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_ACK);
- GNUNET_PEER_resolve (info->origin->oid, &msg->oid);
- msg->tid = htonl (info->origin->tid);
+ GNUNET_PEER_resolve (t->id.oid, &msg->oid);
+ msg->tid = htonl (t->id.tid);
msg->peer_id = my_full_id;
+ msg->ack = htonl (t->prev_fc.last_ack_sent);
- GNUNET_free (info);
/* TODO add signature */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH ACK sent!\n");
@@ -4559,12 +2706,7 @@ send_core_path_ack (void *cls, size_t size, void *buf)
static void
queue_destroy (struct MeshPeerQueue *queue, int clear_cls)
{
- struct MeshTransmissionDescriptor *dd;
- struct MeshPathInfo *path_info;
- struct MeshTunnelChildInfo *cinfo;
- struct GNUNET_PeerIdentity id;
- unsigned int i;
- unsigned int max;
+ struct MeshFlowControl *fc;
if (GNUNET_YES == clear_cls)
{
@@ -4575,7 +2717,6 @@ queue_destroy (struct MeshPeerQueue *queue, int clear_cls)
GNUNET_break (GNUNET_YES == queue->tunnel->destroy);
/* fall through */
case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
case GNUNET_MESSAGE_TYPE_MESH_ACK:
case GNUNET_MESSAGE_TYPE_MESH_POLL:
@@ -4584,20 +2725,16 @@ queue_destroy (struct MeshPeerQueue *queue, int clear_cls)
" prebuilt message\n");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" type %s\n",
- GNUNET_MESH_DEBUG_M2S(queue->type));
- dd = queue->cls;
- data_descriptor_decrement_rc (dd->mesh_data);
+ GNUNET_MESH_DEBUG_M2S (queue->type));
break;
case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " type create path\n");
- path_info = queue->cls;
- path_destroy (path_info->path);
break;
default:
GNUNET_break (0);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
" type %s unknown!\n",
- GNUNET_MESH_DEBUG_M2S(queue->type));
+ GNUNET_MESH_DEBUG_M2S (queue->type));
}
GNUNET_free_non_null (queue->cls);
}
@@ -4605,36 +2742,21 @@ queue_destroy (struct MeshPeerQueue *queue, int clear_cls)
queue->peer->queue_tail,
queue);
- /* Delete from child_fc in the appropiate tunnel */
- max = queue->tunnel->fwd_queue_max;
- GNUNET_PEER_resolve (queue->peer->id, &id);
- cinfo = tunnel_get_neighbor_fc (queue->tunnel, &id);
- if (NULL != cinfo)
+ /* Delete from appropriate fc in the tunnel */
+ if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == queue->type ||
+ GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == queue->type )
{
- for (i = 0; i < cinfo->send_buffer_n; i++)
+ if (queue->peer->id == queue->tunnel->prev_hop)
+ fc = &queue->tunnel->prev_fc;
+ else if (queue->peer->id == queue->tunnel->next_hop)
+ fc = &queue->tunnel->next_fc;
+ else
{
- unsigned int i2;
- i2 = (cinfo->send_buffer_start + i) % max;
- if (cinfo->send_buffer[i2] == queue)
- {
- /* Found corresponding entry in the send_buffer. Move all others back. */
- unsigned int j;
- unsigned int j2;
- unsigned int j3;
-
- for (j = i, j2 = 0, j3 = 0; j < cinfo->send_buffer_n - 1; j++)
- {
- j2 = (cinfo->send_buffer_start + j) % max;
- j3 = (cinfo->send_buffer_start + j + 1) % max;
- cinfo->send_buffer[j2] = cinfo->send_buffer[j3];
- }
-
- cinfo->send_buffer[j3] = NULL;
- cinfo->send_buffer_n--;
- }
+ GNUNET_break (0);
+ return;
}
+ fc->queue_n--;
}
-
GNUNET_free (queue);
}
@@ -4654,308 +2776,220 @@ struct MeshPeerQueue *
queue_get_next (const struct MeshPeerInfo *peer)
{
struct MeshPeerQueue *q;
- struct MeshTunnel *t;
- struct MeshTransmissionDescriptor *info;
- struct MeshTunnelChildInfo *cinfo;
- struct GNUNET_MESH_Unicast *ucast;
- struct GNUNET_MESH_ToOrigin *to_orig;
- struct GNUNET_MESH_Multicast *mcast;
- struct GNUNET_PeerIdentity id;
+
+ struct GNUNET_MESH_Data *dmsg;
+ struct MeshTunnel* t;
uint32_t pid;
uint32_t ack;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* selecting message\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* selecting message\n");
for (q = peer->queue_head; NULL != q; q = q->next)
{
t = q->tunnel;
- info = q->cls;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "********* %s\n",
- GNUNET_MESH_DEBUG_M2S(q->type));
+ "* %s\n",
+ GNUNET_MESH_DEBUG_M2S (q->type));
+ dmsg = (struct GNUNET_MESH_Data *) q->cls;
+ pid = ntohl (dmsg->pid);
switch (q->type)
{
case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- ucast = (struct GNUNET_MESH_Unicast *) info->mesh_data->data;
- pid = ntohl (ucast->pid);
- GNUNET_PEER_resolve (info->peer->id, &id);
- cinfo = tunnel_get_neighbor_fc(t, &id);
- ack = cinfo->fwd_ack;
+ ack = t->next_fc.last_ack_recv;
break;
case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- to_orig = (struct GNUNET_MESH_ToOrigin *) info->mesh_data->data;
- pid = ntohl (to_orig->pid);
- ack = t->bck_ack;
- break;
- case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
- mcast = (struct GNUNET_MESH_Multicast *) info->mesh_data->data;
- if (GNUNET_MESSAGE_TYPE_MESH_MULTICAST != ntohs(mcast->header.type))
- {
- // Not a multicast payload: multicast control traffic (destroy, etc)
- return q;
- }
- pid = ntohl (mcast->pid);
- GNUNET_PEER_resolve (info->peer->id, &id);
- cinfo = tunnel_get_neighbor_fc(t, &id);
- ack = cinfo->fwd_ack;
+ ack = t->prev_fc.last_ack_recv;
break;
default:
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "********* OK!\n");
+ "* OK!\n");
return q;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "********* ACK: %u, PID: %u\n",
- ack, pid);
- if (GNUNET_NO == GMC_is_pid_bigger(pid, ack))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "* ACK: %u, PID: %u\n",
+ ack, pid);
+ if (GNUNET_NO == GMC_is_pid_bigger (pid, ack))
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "********* OK!\n");
+ "* OK!\n");
return q;
}
else
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "********* NEXT!\n");
+ "* NEXT!\n");
}
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "********* nothing found\n");
+ "* nothing found\n");
return NULL;
}
-/**
- * Core callback to write a queued packet to core buffer
- *
- * @param cls Closure (peer info).
- * @param size Number of bytes available in buf.
- * @param buf Where the to write the message.
- *
- * @return number of bytes written to buf
- */
static size_t
queue_send (void *cls, size_t size, void *buf)
{
- struct MeshPeerInfo *peer = cls;
- struct GNUNET_MessageHeader *msg;
- struct MeshPeerQueue *queue;
- struct MeshTunnel *t;
- struct MeshTunnelChildInfo *cinfo;
- struct GNUNET_PeerIdentity dst_id;
- size_t data_size;
-
- peer->core_transmit = NULL;
- cinfo = NULL;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* Queue send\n");
- queue = queue_get_next (peer);
-
- /* Queue has no internal mesh traffic nor sendable payload */
- if (NULL == queue)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* not ready, return\n");
- if (NULL == peer->queue_head)
- GNUNET_break (0); // Should've been canceled
+ struct MeshPeerInfo *peer = cls;
+ struct GNUNET_MessageHeader *msg;
+ struct MeshPeerQueue *queue;
+ struct MeshTunnel *t;
+ struct GNUNET_PeerIdentity dst_id;
+ struct MeshFlowControl *fc;
+ size_t data_size;
+ uint32_t pid;
+ uint16_t type;
+
+ peer->core_transmit = NULL;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* Queue send\n");
+ queue = queue_get_next (peer);
+
+ /* Queue has no internal mesh traffic nor sendable payload */
+ if (NULL == queue)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* not ready, return\n");
+ if (NULL == peer->queue_head)
+ GNUNET_break (0); /* Core tmt_rdy should've been canceled */
+ return 0;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* not empty\n");
+
+ GNUNET_PEER_resolve (peer->id, &dst_id);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "* towards %s\n",
+ GNUNET_i2s (&dst_id));
+ /* Check if buffer size is enough for the message */
+ if (queue->size > size)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "* not enough room, reissue\n");
+ peer->core_transmit =
+ GNUNET_CORE_notify_transmit_ready (core_handle,
+ GNUNET_NO,
+ 0,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &dst_id,
+ queue->size,
+ &queue_send,
+ peer);
return 0;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* not empty\n");
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* size ok\n");
- GNUNET_PEER_resolve (peer->id, &dst_id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "********* towards %s\n",
- GNUNET_i2s(&dst_id));
- /* Check if buffer size is enough for the message */
- if (queue->size > size)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "********* not enough room, reissue\n");
- peer->core_transmit =
- GNUNET_CORE_notify_transmit_ready (core_handle,
- 0,
- 0,
- GNUNET_TIME_UNIT_FOREVER_REL,
- &dst_id,
- queue->size,
- &queue_send,
- peer);
- return 0;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* size ok\n");
+ t = queue->tunnel;
+ GNUNET_assert (0 < t->pending_messages);
+ t->pending_messages--;
+ type = 0;
- t = queue->tunnel;
- GNUNET_assert (0 < t->pending_messages);
- t->pending_messages--;
- if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == queue->type)
- {
- t->fwd_queue_n--;
+ /* Fill buf */
+ switch (queue->type)
+ {
+ case 0:
+ case GNUNET_MESSAGE_TYPE_MESH_ACK:
+ case GNUNET_MESSAGE_TYPE_MESH_POLL:
+ case GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN:
+ case GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY:
+ case GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY:
+ case GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE:
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "********* unicast: t->q (%u/%u)\n",
- t->fwd_queue_n, t->fwd_queue_max);
- }
- else if (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == queue->type)
- {
- t->bck_queue_n--;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* to origin\n");
- }
+ "* raw: %s\n",
+ GNUNET_MESH_DEBUG_M2S (queue->type));
+ /* Fall through */
+ case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
+ case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
+ data_size = send_core_data_raw (queue->cls, size, buf);
+ msg = (struct GNUNET_MessageHeader *) buf;
+ type = ntohs (msg->type);
+ break;
+ case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* path create\n");
+ data_size = send_core_path_create (queue->cls, size, buf);
+ break;
+ case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* path ack\n");
+ data_size = send_core_path_ack (queue->cls, size, buf);
+ break;
+ default:
+ GNUNET_break (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "* type unknown: %u\n",
+ queue->type);
+ data_size = 0;
+ }
- /* Fill buf */
- switch (queue->type)
- {
- case 0:
- case GNUNET_MESSAGE_TYPE_MESH_ACK:
- case GNUNET_MESSAGE_TYPE_MESH_POLL:
- case GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN:
- case GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY:
- case GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY:
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "********* raw: %s\n",
- GNUNET_MESH_DEBUG_M2S (queue->type));
- /* Fall through */
- case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- data_size = send_core_data_raw (queue->cls, size, buf);
- msg = (struct GNUNET_MessageHeader *) buf;
- switch (ntohs (msg->type)) // Type of preconstructed message
- {
- case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
- break;
- case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
- break;
- default:
- break;
- }
- break;
- case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* multicast\n");
- {
- struct MeshTransmissionDescriptor *info = queue->cls;
-
- if ((1 == info->mesh_data->reference_counter
- && GNUNET_YES == t->speed_min)
- ||
- (info->mesh_data->total_out == info->mesh_data->reference_counter
- && GNUNET_NO == t->speed_min))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "********* considered sent\n");
- t->fwd_queue_n--;
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "********* NOT considered sent yet\n");
- t->pending_messages++;
- }
- }
- data_size = send_core_data_multicast(queue->cls, size, buf);
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_MULTICAST);
- break;
- case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* path create\n");
- data_size = send_core_path_create (queue->cls, size, buf);
- break;
- case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* path ack\n");
- data_size = send_core_path_ack (queue->cls, size, buf);
- break;
- case GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE:
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* path keepalive\n");
- data_size = send_core_data_multicast (queue->cls, size, buf);
- break;
- default:
- GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "********* type unknown: %u\n",
- queue->type);
- data_size = 0;
- }
- switch (queue->type)
- {
- case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
- cinfo = tunnel_get_neighbor_fc (t, &dst_id);
- if (cinfo->send_buffer[cinfo->send_buffer_start] != queue)
- {
- GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "at pos %u (%p) != %p\n",
- cinfo->send_buffer_start,
- cinfo->send_buffer[cinfo->send_buffer_start],
- queue);
- }
- if (cinfo->send_buffer_n > 0)
- {
- cinfo->send_buffer[cinfo->send_buffer_start] = NULL;
- cinfo->send_buffer_n--;
- cinfo->send_buffer_start++;
- cinfo->send_buffer_start %= t->fwd_queue_max;
- }
- else
- {
- GNUNET_break (0);
- }
- break;
- default:
- break;
- }
+ /* Free queue, but cls was freed by send_core_* */
+ queue_destroy (queue, GNUNET_NO);
+
+ /* Send ACK if needed, after accounting for sent ID in fc->queue_n */
+ pid = ((struct GNUNET_MESH_Data *) buf)->pid;
+ switch (type)
+ {
+ case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
+ t->next_fc.last_pid_sent = pid;
+ tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
+ break;
+ case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
+ t->prev_fc.last_pid_sent = pid;
+ tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
+ break;
+ default:
+ break;
+ }
- /* Free queue, but cls was freed by send_core_* */
- queue_destroy (queue, GNUNET_NO);
+ if (GNUNET_YES == t->destroy && 0 == t->pending_messages)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* destroying tunnel!\n");
+ tunnel_destroy (t);
+ }
- if (GNUNET_YES == t->destroy && 0 == t->pending_messages)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* destroying tunnel!\n");
- tunnel_destroy (t);
- }
+ /* If more data in queue, send next */
+ queue = queue_get_next (peer);
+ if (NULL != queue)
+ {
+ struct GNUNET_PeerIdentity id;
- /* If more data in queue, send next */
- queue = queue_get_next(peer);
- if (NULL != queue)
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* more data!\n");
+ GNUNET_PEER_resolve (peer->id, &id);
+ peer->core_transmit =
+ GNUNET_CORE_notify_transmit_ready(core_handle,
+ 0,
+ 0,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &id,
+ queue->size,
+ &queue_send,
+ peer);
+ }
+ else if (NULL != peer->queue_head)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "* %s stalled\n",
+ GNUNET_i2s (&my_full_id));
+ if (peer->id == t->next_hop)
+ fc = &t->next_fc;
+ else if (peer->id == t->prev_hop)
+ fc = &t->prev_fc;
+ else
{
- struct GNUNET_PeerIdentity id;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* more data!\n");
- GNUNET_PEER_resolve (peer->id, &id);
- peer->core_transmit =
- GNUNET_CORE_notify_transmit_ready(core_handle,
- 0,
- 0,
- GNUNET_TIME_UNIT_FOREVER_REL,
- &id,
- queue->size,
- &queue_send,
- peer);
+ GNUNET_break (0);
+ fc = NULL;
}
- else
+ if (NULL != fc && GNUNET_SCHEDULER_NO_TASK == fc->poll_task)
{
- if (NULL != peer->queue_head)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "********* %s stalled\n",
- GNUNET_i2s(&my_full_id));
- if (NULL == cinfo)
- cinfo = tunnel_get_neighbor_fc (t, &dst_id);
- // FIXME unify bck/fwd structures, bck does not have cinfo right now
- if (NULL != cinfo && GNUNET_SCHEDULER_NO_TASK == cinfo->fc_poll)
- {
- cinfo->fc_poll = GNUNET_SCHEDULER_add_delayed (cinfo->fc_poll_time,
- &tunnel_poll, cinfo);
- }
- }
+ fc->t = t;
+ fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
+ &tunnel_poll, fc);
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "********* return %d\n", data_size);
- return data_size;
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* Return %d\n", data_size);
+ return data_size;
}
/**
* @brief Queue and pass message to core when possible.
*
- * If type is payload (UNICAST, TO_ORIGIN, MULTICAST) checks for queue status
- * and accounts for it. In case the queue is full, the message is dropped and
+ * If type is payload (UNICAST, TO_ORIGIN) checks for queue status and
+ * accounts for it. In case the queue is full, the message is dropped and
* a break issued.
*
* Otherwise, message is treated as internal and allowed to go regardless of
@@ -4973,33 +3007,30 @@ queue_add (void *cls, uint16_t type, size_t size,
struct MeshPeerInfo *dst, struct MeshTunnel *t)
{
struct MeshPeerQueue *queue;
- struct MeshTunnelChildInfo *cinfo;
struct GNUNET_PeerIdentity id;
- unsigned int *max;
unsigned int *n;
- unsigned int i;
n = NULL;
- if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == type ||
- GNUNET_MESSAGE_TYPE_MESH_MULTICAST == type)
+ if (GNUNET_MESSAGE_TYPE_MESH_UNICAST == type)
{
- n = &t->fwd_queue_n;
- max = &t->fwd_queue_max;
+ n = &t->next_fc.queue_n;
}
else if (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN == type)
{
- n = &t->bck_queue_n;
- max = &t->bck_queue_max;
+ n = &t->prev_fc.queue_n;
}
if (NULL != n)
{
- if (*n >= *max)
+ if (*n >= t->queue_max)
{
GNUNET_break(0);
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "queue full: %u/%u\n",
+ *n, t->queue_max);
GNUNET_STATISTICS_update(stats,
"# messages dropped (buffer full)",
1, GNUNET_NO);
- return; // Drop message
+ return; /* Drop message */
}
(*n)++;
}
@@ -5010,43 +3041,20 @@ queue_add (void *cls, uint16_t type, size_t size,
queue->peer = dst;
queue->tunnel = t;
GNUNET_CONTAINER_DLL_insert_tail (dst->queue_head, dst->queue_tail, queue);
- GNUNET_PEER_resolve (dst->id, &id);
if (NULL == dst->core_transmit)
{
- dst->core_transmit =
- GNUNET_CORE_notify_transmit_ready (core_handle,
- 0,
- 0,
- GNUNET_TIME_UNIT_FOREVER_REL,
- &id,
- size,
- &queue_send,
- dst);
+ GNUNET_PEER_resolve (dst->id, &id);
+ dst->core_transmit =
+ GNUNET_CORE_notify_transmit_ready (core_handle,
+ 0,
+ 0,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &id,
+ size,
+ &queue_send,
+ dst);
}
t->pending_messages++;
- if (NULL == n) // Is this internal mesh traffic?
- return;
-
- // It's payload, keep track of buffer per peer.
- cinfo = tunnel_get_neighbor_fc(t, &id);
- i = (cinfo->send_buffer_start + cinfo->send_buffer_n) % t->fwd_queue_max;
- if (NULL != cinfo->send_buffer[i])
- {
- GNUNET_break (cinfo->send_buffer_n == t->fwd_queue_max); // aka i == start
- queue_destroy (cinfo->send_buffer[cinfo->send_buffer_start], GNUNET_YES);
- cinfo->send_buffer_start++;
- cinfo->send_buffer_start %= t->fwd_queue_max;
- }
- else
- {
- cinfo->send_buffer_n++;
- }
- cinfo->send_buffer[i] = queue;
- if (cinfo->send_buffer_n > t->fwd_queue_max)
- {
- GNUNET_break (0);
- cinfo->send_buffer_n = t->fwd_queue_max;
- }
}
@@ -5073,9 +3081,8 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
uint16_t size;
uint16_t i;
MESH_TunnelNumber tid;
- struct GNUNET_MESH_ManipulatePath *msg;
+ struct GNUNET_MESH_CreateTunnel *msg;
struct GNUNET_PeerIdentity *pi;
- struct GNUNET_HashCode hash;
struct MeshPeerPath *path;
struct MeshPeerInfo *dest_peer_info;
struct MeshPeerInfo *orig_peer_info;
@@ -5085,33 +3092,33 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
"Received a path create msg [%s]\n",
GNUNET_i2s (&my_full_id));
size = ntohs (message->size);
- if (size < sizeof (struct GNUNET_MESH_ManipulatePath))
+ if (size < sizeof (struct GNUNET_MESH_CreateTunnel))
{
GNUNET_break_op (0);
return GNUNET_OK;
}
- size -= sizeof (struct GNUNET_MESH_ManipulatePath);
+ size -= sizeof (struct GNUNET_MESH_CreateTunnel);
if (size % sizeof (struct GNUNET_PeerIdentity))
{
GNUNET_break_op (0);
return GNUNET_OK;
}
size /= sizeof (struct GNUNET_PeerIdentity);
- if (size < 2)
+ if (size < 1)
{
GNUNET_break_op (0);
return GNUNET_OK;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " path has %u hops.\n", size);
- msg = (struct GNUNET_MESH_ManipulatePath *) message;
+ msg = (struct GNUNET_MESH_CreateTunnel *) message;
tid = ntohl (msg->tid);
pi = (struct GNUNET_PeerIdentity *) &msg[1];
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " path is for tunnel %s [%X].\n", GNUNET_i2s (pi), tid);
+ " path is for tunnel %s[%X].\n", GNUNET_i2s (pi), tid);
t = tunnel_get (pi, tid);
- if (NULL == t) // FIXME only for INCOMING tunnels?
+ if (NULL == t) /* might be a local tunnel */
{
uint32_t opt;
@@ -5119,45 +3126,21 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
t = tunnel_new (GNUNET_PEER_intern (pi), tid, NULL, 0);
if (NULL == t)
{
- // FIXME notify failure
+ GNUNET_break (0);
return GNUNET_OK;
}
+ t->port = ntohl (msg->port);
opt = ntohl (msg->opt);
- t->speed_min = (0 != (opt & MESH_TUNNEL_OPT_SPEED_MIN)) ?
- GNUNET_YES : GNUNET_NO;
if (0 != (opt & MESH_TUNNEL_OPT_NOBUFFER))
{
t->nobuffer = GNUNET_YES;
- t->last_fwd_ack = t->fwd_pid + 1;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " speed_min: %d, nobuffer:%d\n",
- t->speed_min, t->nobuffer);
-
- if (GNUNET_YES == t->nobuffer)
- {
- t->bck_queue_max = 1;
- t->fwd_queue_max = 1;
+ t->queue_max = 1;
}
-
- // FIXME only assign a local tid if a local client is interested (on demand)
- while (NULL != tunnel_get_incoming (next_local_tid))
- next_local_tid = (next_local_tid + 1) | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
- t->local_tid_dest = next_local_tid++;
- next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
- // FIXME end
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " nobuffer:%d\n", t->nobuffer);
tunnel_reset_timeout (t);
- GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
- if (GNUNET_OK !=
- GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
- {
- tunnel_destroy (t);
- GNUNET_break (0);
- return GNUNET_OK;
- }
}
+ t->state = MESH_TUNNEL_WAITING;
dest_peer_info =
GNUNET_CONTAINER_multihashmap_get (peers, &pi[size - 1].hashPubKey);
if (NULL == dest_peer_info)
@@ -5192,9 +3175,8 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
own_pos = i;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Own position: %u\n", own_pos);
- if (own_pos == 0)
+ if (own_pos == 0 && path->peers[own_pos] != myid)
{
- /* cannot be self, must be 'not found' */
/* create path: self not found in path through self */
GNUNET_break_op (0);
path_destroy (path);
@@ -5202,43 +3184,58 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
return GNUNET_OK;
}
path_add_to_peers (path, GNUNET_NO);
- tunnel_add_path (t, path, own_pos);
+ tunnel_use_path (t, path);
+
+ peer_info_add_tunnel (dest_peer_info, t);
+
if (own_pos == size - 1)
{
- /* It is for us! Send ack. */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " It's for us!\n");
- peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_NO);
- if (NULL == t->peers)
+ struct MeshClient *c;
+ struct GNUNET_HashCode hc;
+
+ /* Find target client */
+ GMC_hash32 (t->port, &hc);
+ c = GNUNET_CONTAINER_multihashmap_get (ports, &hc);
+ if (NULL == c)
{
- /* New tunnel! Notify clients on first payload message. */
- t->peers = GNUNET_CONTAINER_multihashmap_create (4, GNUNET_NO);
+ /* TODO send reject */
+ return GNUNET_OK;
}
- GNUNET_break (GNUNET_SYSERR !=
- GNUNET_CONTAINER_multihashmap_put (t->peers,
- &my_full_id.hashPubKey,
- peer_info_get
- (&my_full_id),
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " It's for us!\n");
+ peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_YES);
+
+ /* Assign local tid */
+ while (NULL != tunnel_get_incoming (next_local_tid))
+ next_local_tid = (next_local_tid + 1) | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
+ t->local_tid_dest = next_local_tid++;
+ next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
+
+ tunnel_add_client (t, c);
+ send_client_tunnel_create (t);
send_path_ack (t);
}
else
{
struct MeshPeerPath *path2;
+ t->next_hop = path->peers[own_pos + 1];
+ GNUNET_PEER_change_rc(t->next_hop, 1);
+
/* It's for somebody else! Retransmit. */
- path2 = path_duplicate (path);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Retransmitting.\n");
- peer_info_add_path (dest_peer_info, path2, GNUNET_NO);
path2 = path_duplicate (path);
- peer_info_add_path_to_origin (orig_peer_info, path2, GNUNET_NO);
- send_create_path (dest_peer_info, path, t);
+ peer_info_add_path (dest_peer_info, path2, GNUNET_NO);
+ peer_info_add_path_to_origin (orig_peer_info, path, GNUNET_NO);
+ send_create_path (t);
}
return GNUNET_OK;
}
+
/**
- * Core handler for path destruction
+ * Core handler for path ACKs
*
* @param cls closure
* @param message message
@@ -5248,71 +3245,72 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
-handle_mesh_path_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
+handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_MessageHeader *message)
{
- struct GNUNET_MESH_ManipulatePath *msg;
- struct GNUNET_PeerIdentity *pi;
- struct MeshPeerPath *path;
+ struct GNUNET_MESH_PathACK *msg;
+ struct MeshPeerInfo *peer_info;
+ struct MeshPeerPath *p;
struct MeshTunnel *t;
- unsigned int own_pos;
- unsigned int i;
- size_t size;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Received a PATH DESTROY msg from %s\n", GNUNET_i2s (peer));
- size = ntohs (message->size);
- if (size < sizeof (struct GNUNET_MESH_ManipulatePath))
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received a path ACK msg [%s]\n",
+ GNUNET_i2s (&my_full_id));
+ msg = (struct GNUNET_MESH_PathACK *) message;
+ t = tunnel_get (&msg->oid, ntohl(msg->tid));
+ if (NULL == t)
{
- GNUNET_break_op (0);
+ /* TODO notify that we don't know the tunnel */
+ GNUNET_STATISTICS_update (stats, "# control on unknown tunnel", 1, GNUNET_NO);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " don't know the tunnel %s [%X]!\n",
+ GNUNET_i2s (&msg->oid), ntohl(msg->tid));
return GNUNET_OK;
}
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %s [%X]\n",
+ GNUNET_i2s (&msg->oid), ntohl(msg->tid));
- size -= sizeof (struct GNUNET_MESH_ManipulatePath);
- if (size % sizeof (struct GNUNET_PeerIdentity))
+ peer_info = peer_get (&msg->peer_id);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by peer %s\n",
+ GNUNET_i2s (&msg->peer_id));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " via peer %s\n",
+ GNUNET_i2s (peer));
+
+ /* Add path to peers? */
+ p = t->path;
+ if (NULL != p)
{
- GNUNET_break_op (0);
- return GNUNET_OK;
+ path_add_to_peers (p, GNUNET_YES);
}
- size /= sizeof (struct GNUNET_PeerIdentity);
- if (size < 2)
+ else
{
- GNUNET_break_op (0);
- return GNUNET_OK;
+ GNUNET_break (0);
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " path has %u hops.\n", size);
+ t->state = MESH_TUNNEL_READY;
+ t->next_fc.last_ack_recv = (NULL == t->client) ? ntohl (msg->ack) : 0;
+ t->prev_fc.last_ack_sent = ntohl (msg->ack);
- msg = (struct GNUNET_MESH_ManipulatePath *) message;
- pi = (struct GNUNET_PeerIdentity *) &msg[1];
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " path is for tunnel %s [%X].\n", GNUNET_i2s (pi),
- msg->tid);
- t = tunnel_get (pi, ntohl (msg->tid));
- if (NULL == t)
+ /* Message for us? */
+ if (0 == memcmp (&msg->oid, &my_full_id, sizeof (struct GNUNET_PeerIdentity)))
{
- /* TODO notify back: we don't know this tunnel */
- GNUNET_break_op (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " It's for us!\n");
+ if (NULL == t->owner)
+ {
+ GNUNET_break_op (0);
+ return GNUNET_OK;
+ }
+ if (NULL != peer_info->dhtget)
+ {
+ GNUNET_DHT_get_stop (peer_info->dhtget);
+ peer_info->dhtget = NULL;
+ }
+ tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK);
+ tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_PATH_ACK);
return GNUNET_OK;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Creating path...\n");
- path = path_new (size);
- own_pos = 0;
- for (i = 0; i < size; i++)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ... adding %s\n",
- GNUNET_i2s (&pi[i]));
- path->peers[i] = GNUNET_PEER_intern (&pi[i]);
- if (path->peers[i] == myid)
- own_pos = i;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Own position: %u\n", own_pos);
- if (own_pos < path->length - 1)
- send_prebuilt_message (message, &pi[own_pos + 1], t);
- else
- send_client_tunnel_disconnect(t, NULL);
- tunnel_delete_peer (t, path->peers[path->length - 1]);
- path_destroy (path);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ " not for us, retransmitting...\n");
+ peer_info = peer_get (&msg->oid);
+ send_prebuilt_message (message, t->prev_hop, t);
return GNUNET_OK;
}
@@ -5370,8 +3368,6 @@ handle_mesh_tunnel_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
{
struct GNUNET_MESH_TunnelDestroy *msg;
struct MeshTunnel *t;
- GNUNET_PEER_Id parent;
- GNUNET_PEER_Id pid;
msg = (struct GNUNET_MESH_TunnelDestroy *) message;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -5381,7 +3377,6 @@ handle_mesh_tunnel_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
" for tunnel %s [%u]\n",
GNUNET_i2s (&msg->oid), ntohl (msg->tid));
t = tunnel_get (&msg->oid, ntohl (msg->tid));
- /* Check signature */
if (NULL == t)
{
/* Probably already got the message from another path,
@@ -5392,31 +3387,36 @@ handle_mesh_tunnel_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
1, GNUNET_NO);
return GNUNET_OK;
}
- parent = tree_get_predecessor (t->tree);
- pid = GNUNET_PEER_search (peer);
- if (pid != parent)
- {
- unsigned int nc;
-
- tree_del_peer (t->tree, pid, &tunnel_child_removed, t);
- nc = tree_count_children (t->tree);
- if (nc > 0 || NULL != t->owner || t->nclients > 0)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "still in use: %u cl, %u ch\n",
- t->nclients, nc);
- return GNUNET_OK;
- }
- }
if (t->local_tid_dest >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
{
- /* Tunnel was incoming, notify clients */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "INCOMING TUNNEL %X %X\n",
t->local_tid, t->local_tid_dest);
- send_clients_tunnel_destroy (t);
}
- tunnel_send_destroy (t, parent);
- t->destroy = GNUNET_YES;
+ if (GNUNET_PEER_search (peer) == t->prev_hop)
+ {
+ // TODO check owner's signature
+ // TODO add owner's signatue to tunnel for retransmission
+ peer_cancel_queues (t->prev_hop, t);
+ GNUNET_PEER_change_rc (t->prev_hop, -1);
+ t->prev_hop = 0;
+ }
+ else if (GNUNET_PEER_search (peer) == t->next_hop)
+ {
+ // TODO check dest's signature
+ // TODO add dest's signatue to tunnel for retransmission
+ peer_cancel_queues (t->next_hop, t);
+ GNUNET_PEER_change_rc (t->next_hop, -1);
+ t->next_hop = 0;
+ }
+ else
+ {
+ GNUNET_break_op (0);
+ // TODO check both owner AND destination's signature to see which matches
+ // TODO restransmit in appropriate direction
+ return GNUNET_OK;
+ }
+ tunnel_destroy_empty (t);
+
// TODO: add timeout to destroy the tunnel anyway
return GNUNET_OK;
}
@@ -5432,14 +3432,11 @@ handle_mesh_tunnel_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
-handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
+handle_mesh_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
const struct GNUNET_MessageHeader *message)
{
- struct GNUNET_MESH_Unicast *msg;
- struct GNUNET_PeerIdentity *neighbor;
- struct MeshTunnelChildInfo *cinfo;
+ struct GNUNET_MESH_Data *msg;
struct MeshTunnel *t;
- GNUNET_PEER_Id dest_id;
uint32_t pid;
uint32_t ttl;
size_t size;
@@ -5449,13 +3446,13 @@ handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
/* Check size */
size = ntohs (message->size);
if (size <
- sizeof (struct GNUNET_MESH_Unicast) +
+ sizeof (struct GNUNET_MESH_Data) +
sizeof (struct GNUNET_MessageHeader))
{
GNUNET_break (0);
return GNUNET_OK;
}
- msg = (struct GNUNET_MESH_Unicast *) message;
+ msg = (struct GNUNET_MESH_Data *) message;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " of type %s\n",
GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
/* Check tunnel */
@@ -5468,7 +3465,7 @@ handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
return GNUNET_OK;
}
pid = ntohl (msg->pid);
- if (t->fwd_pid == pid)
+ if (t->prev_fc.last_pid_recv == pid)
{
GNUNET_STATISTICS_update (stats, "# duplicate PID drops", 1, GNUNET_NO);
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -5481,30 +3478,34 @@ handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
" pid %u not seen yet, forwarding\n", pid);
}
- t->skip += (pid - t->fwd_pid) - 1;
- t->fwd_pid = pid;
-
- if (GMC_is_pid_bigger (pid, t->last_fwd_ack))
+ if (GMC_is_pid_bigger (pid, t->prev_fc.last_ack_sent))
{
GNUNET_STATISTICS_update (stats, "# unsolicited unicast", 1, GNUNET_NO);
GNUNET_break_op (0);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Received PID %u, ACK %u\n",
- pid, t->last_fwd_ack);
+ pid, t->prev_fc.last_ack_sent);
+ tunnel_send_fwd_ack(t, GNUNET_MESSAGE_TYPE_MESH_POLL);
return GNUNET_OK;
}
+ t->prev_fc.last_pid_recv = pid;
tunnel_reset_timeout (t);
- dest_id = GNUNET_PEER_search (&msg->destination);
- if (dest_id == myid)
+ if (t->dest == myid)
{
+ /* TODO signature verification */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" it's for us! sending to clients...\n");
GNUNET_STATISTICS_update (stats, "# unicast received", 1, GNUNET_NO);
- send_subscribed_clients (message, &msg[1].header, t);
+ tunnel_send_client_ucast (t, msg);
tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_UNICAST);
return GNUNET_OK;
}
+ if (0 == t->next_hop)
+ {
+ GNUNET_break (0);
+ return GNUNET_OK;
+ }
ttl = ntohl (msg->ttl);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ttl: %u\n", ttl);
if (ttl == 0)
@@ -5517,107 +3518,13 @@ handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" not for us, retransmitting...\n");
- neighbor = tree_get_first_hop (t->tree, dest_id);
- cinfo = tunnel_get_neighbor_fc (t, neighbor);
- cinfo->fwd_pid = pid;
- GNUNET_CONTAINER_multihashmap_iterate (t->children_fc,
- &tunnel_add_skip,
- &neighbor);
- if (GNUNET_YES == t->nobuffer &&
- GNUNET_YES == GMC_is_pid_bigger (pid, cinfo->fwd_ack))
- {
- GNUNET_STATISTICS_update (stats, "# unsolicited unicast", 1, GNUNET_NO);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, " %u > %u\n", pid, cinfo->fwd_ack);
- GNUNET_break_op (0);
- return GNUNET_OK;
- }
- send_prebuilt_message (message, neighbor, t);
+ send_prebuilt_message (message, t->next_hop, t);
GNUNET_STATISTICS_update (stats, "# unicast forwarded", 1, GNUNET_NO);
return GNUNET_OK;
}
/**
- * Core handler for mesh network traffic going from the origin to all peers
- *
- * @param cls closure
- * @param message message
- * @param peer peer identity this notification is about
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
- *
- * TODO: Check who we got this from, to validate route.
- */
-static int
-handle_mesh_data_multicast (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_Multicast *msg;
- struct MeshTunnel *t;
- size_t size;
- uint32_t pid;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a multicast packet from %s\n",
- GNUNET_i2s (peer));
- size = ntohs (message->size);
- if (sizeof (struct GNUNET_MESH_Multicast) +
- sizeof (struct GNUNET_MessageHeader) > size)
- {
- GNUNET_break_op (0);
- return GNUNET_OK;
- }
- msg = (struct GNUNET_MESH_Multicast *) message;
- t = tunnel_get (&msg->oid, ntohl (msg->tid));
-
- if (NULL == t)
- {
- /* TODO notify that we dont know that tunnel */
- GNUNET_STATISTICS_update (stats, "# data on unknown tunnel", 1, GNUNET_NO);
- GNUNET_break_op (0);
- return GNUNET_OK;
- }
- pid = ntohl (msg->pid);
- if (t->fwd_pid == pid)
- {
- /* already seen this packet, drop */
- GNUNET_STATISTICS_update (stats, "# duplicate PID drops", 1, GNUNET_NO);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Already seen pid %u, DROPPING!\n", pid);
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
- return GNUNET_OK;
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " pid %u not seen yet, forwarding\n", pid);
- }
- t->skip += (pid - t->fwd_pid) - 1;
- t->fwd_pid = pid;
- tunnel_reset_timeout (t);
-
- /* Transmit to locally interested clients */
- if (NULL != t->peers &&
- GNUNET_CONTAINER_multihashmap_contains (t->peers, &my_full_id.hashPubKey))
- {
- GNUNET_STATISTICS_update (stats, "# multicast received", 1, GNUNET_NO);
- send_subscribed_clients (message, &msg[1].header, t);
- tunnel_send_fwd_ack(t, GNUNET_MESSAGE_TYPE_MESH_MULTICAST);
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ttl: %u\n", ntohl (msg->ttl));
- if (ntohl (msg->ttl) == 0)
- {
- GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
- return GNUNET_OK;
- }
- GNUNET_STATISTICS_update (stats, "# multicast forwarded", 1, GNUNET_NO);
- tunnel_send_multicast (t, message);
- return GNUNET_OK;
-}
-
-
-/**
* Core handler for mesh network traffic toward the owner of a tunnel
*
* @param cls closure
@@ -5628,28 +3535,25 @@ handle_mesh_data_multicast (void *cls, const struct GNUNET_PeerIdentity *peer,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
-handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer,
+handle_mesh_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer,
const struct GNUNET_MessageHeader *message)
{
- struct GNUNET_MESH_ToOrigin *msg;
- struct GNUNET_PeerIdentity id;
- struct MeshPeerInfo *peer_info;
+ struct GNUNET_MESH_Data *msg;
struct MeshTunnel *t;
- struct MeshTunnelChildInfo *cinfo;
- GNUNET_PEER_Id predecessor;
size_t size;
uint32_t pid;
+ uint32_t ttl;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a ToOrigin packet from %s\n",
GNUNET_i2s (peer));
size = ntohs (message->size);
- if (size < sizeof (struct GNUNET_MESH_ToOrigin) + /* Payload must be */
+ if (size < sizeof (struct GNUNET_MESH_Data) + /* Payload must be */
sizeof (struct GNUNET_MessageHeader)) /* at least a header */
{
GNUNET_break_op (0);
return GNUNET_OK;
}
- msg = (struct GNUNET_MESH_ToOrigin *) message;
+ msg = (struct GNUNET_MESH_Data *) message;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " of type %s\n",
GNUNET_MESH_DEBUG_M2S (ntohs (msg[1].header.type)));
t = tunnel_get (&msg->oid, ntohl (msg->tid));
@@ -5665,14 +3569,7 @@ handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer,
return GNUNET_OK;
}
- cinfo = tunnel_get_neighbor_fc(t, peer);
- if (NULL == cinfo)
- {
- GNUNET_break (0);
- return GNUNET_OK;
- }
-
- if (cinfo->bck_pid == pid)
+ if (t->next_fc.last_pid_recv == pid)
{
/* already seen this packet, drop */
GNUNET_STATISTICS_update (stats, "# duplicate PID drops BCK", 1, GNUNET_NO);
@@ -5682,41 +3579,34 @@ handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer,
return GNUNET_OK;
}
+ if (GMC_is_pid_bigger (pid, t->next_fc.last_ack_sent))
+ {
+ GNUNET_STATISTICS_update (stats, "# unsolicited to_orig", 1, GNUNET_NO);
+ GNUNET_break_op (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Received PID %u, ACK %u\n",
+ pid, t->next_fc.last_ack_sent);
+ tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
+ return GNUNET_OK;
+ }
+ t->next_fc.last_pid_recv = pid;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" pid %u not seen yet, forwarding\n", pid);
- cinfo->bck_pid = pid;
- if (NULL != t->owner)
+ if (myid == t->id.oid)
{
- char cbuf[size];
- struct GNUNET_MESH_ToOrigin *copy;
-
+ /* TODO signature verification */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" it's for us! sending to clients...\n");
- /* TODO signature verification */
- memcpy (cbuf, message, size);
- copy = (struct GNUNET_MESH_ToOrigin *) cbuf;
- copy->tid = htonl (t->local_tid);
- t->bck_pid++;
- copy->pid = htonl (t->bck_pid);
GNUNET_STATISTICS_update (stats, "# to origin received", 1, GNUNET_NO);
- GNUNET_SERVER_notification_context_unicast (nc, t->owner->handle,
- &copy->header, GNUNET_NO);
+ tunnel_send_client_to_orig (t, msg);
tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
return GNUNET_OK;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" not for us, retransmitting...\n");
- peer_info = peer_info_get (&msg->oid);
- if (NULL == peer_info)
- {
- /* unknown origin of tunnel */
- GNUNET_break (0);
- return GNUNET_OK;
- }
- predecessor = tree_get_predecessor (t->tree);
- if (0 == predecessor)
+ if (0 == t->prev_hop) /* No owner AND no prev hop */
{
if (GNUNET_YES == t->destroy)
{
@@ -5732,15 +3622,20 @@ handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer,
"from peer %s\n",
GNUNET_i2s (peer));
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "for tunnel %s [%X]\n",
+ "on tunnel %s [%X]\n",
GNUNET_i2s (&msg->oid), ntohl(msg->tid));
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "current tree:\n");
- tree_debug (t->tree);
return GNUNET_OK;
}
- GNUNET_PEER_resolve (predecessor, &id);
- send_prebuilt_message (message, &id, t);
+ ttl = ntohl (msg->ttl);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ttl: %u\n", ttl);
+ if (ttl == 0)
+ {
+ GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
+ tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
+ return GNUNET_OK;
+ }
+ send_prebuilt_message (message, t->prev_hop, t);
GNUNET_STATISTICS_update (stats, "# to origin forwarded", 1, GNUNET_NO);
return GNUNET_OK;
@@ -5763,6 +3658,7 @@ handle_mesh_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
{
struct GNUNET_MESH_ACK *msg;
struct MeshTunnel *t;
+ GNUNET_PEER_Id id;
uint32_t ack;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got an ACK packet from %s!\n",
@@ -5781,30 +3677,39 @@ handle_mesh_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ACK %u\n", ack);
/* Is this a forward or backward ACK? */
- if (tree_get_predecessor(t->tree) != GNUNET_PEER_search(peer))
+ id = GNUNET_PEER_search (peer);
+ if (t->next_hop == id)
{
- struct MeshTunnelChildInfo *cinfo;
-
- debug_bck_ack++;
+ debug_fwd_ack++;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " FWD ACK\n");
- cinfo = tunnel_get_neighbor_fc (t, peer);
- cinfo->fwd_ack = ack;
- tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
- tunnel_unlock_fwd_queues (t);
- if (GNUNET_SCHEDULER_NO_TASK != cinfo->fc_poll)
+ if (GNUNET_SCHEDULER_NO_TASK != t->next_fc.poll_task &&
+ GMC_is_pid_bigger (ack, t->next_fc.last_ack_recv))
{
- GNUNET_SCHEDULER_cancel (cinfo->fc_poll);
- cinfo->fc_poll = GNUNET_SCHEDULER_NO_TASK;
- cinfo->fc_poll_time = GNUNET_TIME_UNIT_SECONDS;
+ GNUNET_SCHEDULER_cancel (t->next_fc.poll_task);
+ t->next_fc.poll_task = GNUNET_SCHEDULER_NO_TASK;
+ t->next_fc.poll_time = GNUNET_TIME_UNIT_SECONDS;
}
+ t->next_fc.last_ack_recv = ack;
+ peer_unlock_queue (t->next_hop);
+ tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
}
- else
+ else if (t->prev_hop == id)
{
+ debug_bck_ack++;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " BCK ACK\n");
- t->bck_ack = ack;
+ if (GNUNET_SCHEDULER_NO_TASK != t->prev_fc.poll_task &&
+ GMC_is_pid_bigger (ack, t->prev_fc.last_ack_recv))
+ {
+ GNUNET_SCHEDULER_cancel (t->prev_fc.poll_task);
+ t->prev_fc.poll_task = GNUNET_SCHEDULER_NO_TASK;
+ t->prev_fc.poll_time = GNUNET_TIME_UNIT_SECONDS;
+ }
+ t->prev_fc.last_ack_recv = ack;
+ peer_unlock_queue (t->prev_hop);
tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK);
- tunnel_unlock_bck_queue (t);
}
+ else
+ GNUNET_break_op (0);
return GNUNET_OK;
}
@@ -5825,6 +3730,7 @@ handle_mesh_poll (void *cls, const struct GNUNET_PeerIdentity *peer,
{
struct GNUNET_MESH_Poll *msg;
struct MeshTunnel *t;
+ GNUNET_PEER_Id id;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got an POLL packet from %s!\n",
GNUNET_i2s (peer));
@@ -5842,117 +3748,20 @@ handle_mesh_poll (void *cls, const struct GNUNET_PeerIdentity *peer,
}
/* Is this a forward or backward ACK? */
- if (tree_get_predecessor(t->tree) != GNUNET_PEER_search(peer))
+ id = GNUNET_PEER_search(peer);
+ if (t->next_hop == id)
{
- struct MeshTunnelChildInfo *cinfo;
-
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " from FWD\n");
- cinfo = tunnel_get_neighbor_fc (t, peer);
- cinfo->bck_ack = cinfo->fwd_pid; // mark as ready to send
tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
}
- else
+ else if (t->prev_hop == id)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " from BCK\n");
tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_POLL);
}
-
- return GNUNET_OK;
-}
-
-/**
- * Core handler for path ACKs
- *
- * @param cls closure
- * @param message message
- * @param peer peer identity this notification is about
- *
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
- */
-static int
-handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_PathACK *msg;
- struct GNUNET_PeerIdentity id;
- struct MeshPeerInfo *peer_info;
- struct MeshPeerPath *p;
- struct MeshTunnel *t;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received a path ACK msg [%s]\n",
- GNUNET_i2s (&my_full_id));
- msg = (struct GNUNET_MESH_PathACK *) message;
- t = tunnel_get (&msg->oid, ntohl(msg->tid));
- if (NULL == t)
- {
- /* TODO notify that we don't know the tunnel */
- GNUNET_STATISTICS_update (stats, "# control on unknown tunnel", 1, GNUNET_NO);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " don't know the tunnel %s [%X]!\n",
- GNUNET_i2s (&msg->oid), ntohl(msg->tid));
- return GNUNET_OK;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %s [%X]\n",
- GNUNET_i2s (&msg->oid), ntohl(msg->tid));
-
- peer_info = peer_info_get (&msg->peer_id);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by peer %s\n",
- GNUNET_i2s (&msg->peer_id));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " via peer %s\n",
- GNUNET_i2s (peer));
-
- if (NULL != t->regex_search && t->regex_search->peer == peer_info->id)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "connect_by_string completed, stopping search\n");
- regex_cancel_search (t->regex_search);
- t->regex_search = NULL;
- }
-
- /* Add paths to peers? */
- p = tree_get_path_to_peer (t->tree, peer_info->id);
- if (NULL != p)
- {
- path_add_to_peers (p, GNUNET_YES);
- path_destroy (p);
- }
else
- {
GNUNET_break (0);
- }
- /* Message for us? */
- if (0 == memcmp (&msg->oid, &my_full_id, sizeof (struct GNUNET_PeerIdentity)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " It's for us!\n");
- if (NULL == t->owner)
- {
- GNUNET_break_op (0);
- return GNUNET_OK;
- }
- if (NULL != t->dht_get_type)
- {
- GNUNET_DHT_get_stop (t->dht_get_type);
- t->dht_get_type = NULL;
- }
- if (tree_get_status (t->tree, peer_info->id) != MESH_PEER_READY)
- {
- tree_set_status (t->tree, peer_info->id, MESH_PEER_READY);
- send_client_peer_connected (t, peer_info->id);
- }
- if (NULL != peer_info->dhtget)
- {
- GNUNET_DHT_get_stop (peer_info->dhtget);
- peer_info->dhtget = NULL;
- }
- return GNUNET_OK;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " not for us, retransmitting...\n");
- GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &id);
- peer_info = peer_info_get (&msg->oid);
- send_prebuilt_message (message, &id, t);
return GNUNET_OK;
}
@@ -5992,7 +3801,7 @@ handle_mesh_keepalive (void *cls, const struct GNUNET_PeerIdentity *peer,
tunnel_reset_timeout (t);
GNUNET_STATISTICS_update (stats, "# keepalives forwarded", 1, GNUNET_NO);
- tunnel_send_multicast (t, message);
+ send_prebuilt_message (message, t->next_hop, t);
return GNUNET_OK;
}
@@ -6003,16 +3812,14 @@ handle_mesh_keepalive (void *cls, const struct GNUNET_PeerIdentity *peer,
*/
static struct GNUNET_CORE_MessageHandler core_handlers[] = {
{&handle_mesh_path_create, GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 0},
- {&handle_mesh_path_destroy, GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY, 0},
{&handle_mesh_path_broken, GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN,
sizeof (struct GNUNET_MESH_PathBroken)},
{&handle_mesh_tunnel_destroy, GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY,
sizeof (struct GNUNET_MESH_TunnelDestroy)},
- {&handle_mesh_data_unicast, GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0},
- {&handle_mesh_data_multicast, GNUNET_MESSAGE_TYPE_MESH_MULTICAST, 0},
+ {&handle_mesh_unicast, GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0},
{&handle_mesh_keepalive, GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE,
sizeof (struct GNUNET_MESH_TunnelKeepAlive)},
- {&handle_mesh_data_to_orig, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0},
+ {&handle_mesh_to_orig, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0},
{&handle_mesh_ack, GNUNET_MESSAGE_TYPE_MESH_ACK,
sizeof (struct GNUNET_MESH_ACK)},
{&handle_mesh_poll, GNUNET_MESSAGE_TYPE_MESH_POLL,
@@ -6028,24 +3835,6 @@ static struct GNUNET_CORE_MessageHandler core_handlers[] = {
/**************** MESH LOCAL HANDLER HELPERS ***********************/
/******************************************************************************/
-/**
- * deregister_app: iterator for removing each application registered by a client
- *
- * @param cls closure
- * @param key the hash of the application id (used to access the hashmap)
- * @param value the value stored at the key (client)
- *
- * @return GNUNET_OK on success
- */
-static int
-deregister_app (void *cls, const struct GNUNET_HashCode * key, void *value)
-{
- struct MeshClient *c = cls;
-
- GNUNET_break (GNUNET_YES ==
- GNUNET_CONTAINER_multihashmap_remove (applications, key, c));
- return GNUNET_OK;
-}
#if LATER
/**
@@ -6088,10 +3877,12 @@ notify_client_connection_failure (void *cls, size_t size, void *buf)
/**
- * Send keepalive packets for a peer
+ * Send keepalive packets for a tunnel.
*
* @param cls Closure (tunnel for which to send the keepalive).
* @param tc Notification context.
+ *
+ * FIXME: add a refresh reset in case of normal unicast traffic is doing the job
*/
static void
path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
@@ -6101,8 +3892,9 @@ path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
size_t size = sizeof (struct GNUNET_MESH_TunnelKeepAlive);
char cbuf[size];
- t->path_refresh_task = GNUNET_SCHEDULER_NO_TASK;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+ t->maintenance_task = GNUNET_SCHEDULER_NO_TASK;
+ if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) ||
+ NULL == t->owner || 0 == t->local_tid)
{
return;
}
@@ -6115,11 +3907,10 @@ path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE);
msg->oid = my_full_id;
msg->tid = htonl (t->id.tid);
- tunnel_send_multicast (t, &msg->header);
+ send_prebuilt_message (&msg->header, t->next_hop, t);
- t->path_refresh_task =
+ t->maintenance_task =
GNUNET_SCHEDULER_add_delayed (refresh_path_time, &path_refresh, t);
- tunnel_reset_timeout(t);
}
@@ -6138,8 +3929,6 @@ path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
* @param type type of the result
* @param size number of bytes in data
* @param data pointer to the result data
- *
- * TODO: re-issue the request after certain time? cancel after X results?
*/
static void
dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
@@ -6150,83 +3939,36 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
size_t size, const void *data)
{
- struct MeshPathInfo *path_info = cls;
+ struct MeshPeerInfo *peer = cls;
struct MeshPeerPath *p;
struct GNUNET_PeerIdentity pi;
int i;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got results from DHT!\n");
- GNUNET_PEER_resolve (path_info->peer->id, &pi);
+ GNUNET_PEER_resolve (peer->id, &pi);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " for %s\n", GNUNET_i2s (&pi));
p = path_build_from_dht (get_path, get_path_length,
put_path, put_path_length);
path_add_to_peers (p, GNUNET_NO);
path_destroy (p);
- for (i = 0; i < path_info->peer->ntunnels; i++)
+ for (i = 0; i < peer->ntunnels; i++)
{
- tunnel_add_peer (path_info->peer->tunnels[i], path_info->peer);
- peer_info_connect (path_info->peer, path_info->t);
- }
-
- return;
-}
-
-
-/**
- * Function to process paths received for a new peer addition. The recorded
- * paths form the initial tunnel, which can be optimized later.
- * Called on each result obtained for the DHT search.
- *
- * @param cls closure
- * @param exp when will this value expire
- * @param key key of the result
- * @param get_path path of the get request
- * @param get_path_length lenght of get_path
- * @param put_path path of the put request
- * @param put_path_length length of the put_path
- * @param type type of the result
- * @param size number of bytes in data
- * @param data pointer to the result data
- */
-static void
-dht_get_type_handler (void *cls, struct GNUNET_TIME_Absolute exp,
- const struct GNUNET_HashCode * key,
- const struct GNUNET_PeerIdentity *get_path,
- unsigned int get_path_length,
- const struct GNUNET_PeerIdentity *put_path,
- unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
- size_t size, const void *data)
-{
- const struct PBlock *pb = data;
- const struct GNUNET_PeerIdentity *pi = &pb->id;
- struct MeshTunnel *t = cls;
- struct MeshPeerInfo *peer_info;
- struct MeshPeerPath *p;
+ struct GNUNET_PeerIdentity id;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got type DHT result!\n");
- if (size != sizeof (struct PBlock))
- {
- GNUNET_break_op (0);
- return;
- }
- if (ntohl(pb->type) != t->type)
- {
- GNUNET_break_op (0);
- return;
+ GNUNET_PEER_resolve (peer->tunnels[i]->id.oid, &id);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ... tunnel %s:%X (%X / %X)\n",
+ GNUNET_i2s (&id), peer->tunnels[i]->id.tid,
+ peer->tunnels[i]->local_tid,
+ peer->tunnels[i]->local_tid_dest);
+ if (peer->tunnels[i]->state == MESH_TUNNEL_SEARCHING)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ... connect!\n");
+ peer_connect (peer, peer->tunnels[i]);
+ }
}
- GNUNET_assert (NULL != t->owner);
- peer_info = peer_info_get (pi);
- (void) GNUNET_CONTAINER_multihashmap_put (t->peers, &pi->hashPubKey,
- peer_info,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
- p = path_build_from_dht (get_path, get_path_length, put_path,
- put_path_length);
- path_add_to_peers (p, GNUNET_NO);
- path_destroy(p);
- tunnel_add_peer (t, peer_info);
- peer_info_connect (peer_info, t);
+ return;
}
@@ -6247,21 +3989,22 @@ handle_local_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
{
struct MeshClient *c;
struct MeshClient *next;
- unsigned int i;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "client disconnected\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "client disconnected: %p\n", client);
if (client == NULL)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " (SERVER DOWN)\n");
return;
}
- c = clients;
+ c = clients_head;
while (NULL != c)
{
if (c->handle != client)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ... searching\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ " ... searching %p (%u)\n",
+ c->handle, c->id);
c = c->next;
continue;
}
@@ -6269,49 +4012,24 @@ handle_local_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
c->id);
GNUNET_SERVER_client_drop (c->handle);
c->shutting_down = GNUNET_YES;
- GNUNET_assert (NULL != c->own_tunnels);
- GNUNET_assert (NULL != c->incoming_tunnels);
GNUNET_CONTAINER_multihashmap_iterate (c->own_tunnels,
&tunnel_destroy_iterator, c);
GNUNET_CONTAINER_multihashmap_iterate (c->incoming_tunnels,
&tunnel_destroy_iterator, c);
- GNUNET_CONTAINER_multihashmap_iterate (c->ignore_tunnels,
- &tunnel_destroy_iterator, c);
GNUNET_CONTAINER_multihashmap_destroy (c->own_tunnels);
GNUNET_CONTAINER_multihashmap_destroy (c->incoming_tunnels);
- GNUNET_CONTAINER_multihashmap_destroy (c->ignore_tunnels);
- /* deregister clients applications */
- if (NULL != c->apps)
- {
- GNUNET_CONTAINER_multihashmap_iterate (c->apps, &deregister_app, c);
- GNUNET_CONTAINER_multihashmap_destroy (c->apps);
- }
- if (0 == GNUNET_CONTAINER_multihashmap_size (applications) &&
- GNUNET_SCHEDULER_NO_TASK != announce_applications_task)
- {
- GNUNET_SCHEDULER_cancel (announce_applications_task);
- announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
- }
- if (NULL != c->types)
- GNUNET_CONTAINER_multihashmap_destroy (c->types);
- for (i = 0; i < c->n_regex; i++)
- {
- GNUNET_free (c->regexes[i].regex);
- if (NULL != c->regexes[i].h)
- GNUNET_REGEX_announce_cancel (c->regexes[i].h);
- }
- GNUNET_free_non_null (c->regexes);
- if (GNUNET_SCHEDULER_NO_TASK != c->regex_announce_task)
- GNUNET_SCHEDULER_cancel (c->regex_announce_task);
+ if (NULL != c->ports)
+ GNUNET_CONTAINER_multihashmap_destroy (c->ports);
next = c->next;
- GNUNET_CONTAINER_DLL_remove (clients, clients_tail, c);
+ GNUNET_CONTAINER_DLL_remove (clients_head, clients_tail, c);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " CLIENT FREE at %p\n", c);
GNUNET_free (c);
GNUNET_STATISTICS_update (stats, "# clients", -1, GNUNET_NO);
c = next;
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " done!\n");
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "done!\n");
+ return;
}
@@ -6328,85 +4046,57 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
{
struct GNUNET_MESH_ClientConnect *cc_msg;
struct MeshClient *c;
- GNUNET_MESH_ApplicationType *a;
unsigned int size;
- uint16_t ntypes;
- uint16_t *t;
- uint16_t napps;
- uint16_t i;
+ uint32_t *p;
+ unsigned int i;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client connected %p\n", client);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new client connected\n");
/* Check data sanity */
size = ntohs (message->size) - sizeof (struct GNUNET_MESH_ClientConnect);
cc_msg = (struct GNUNET_MESH_ClientConnect *) message;
- ntypes = ntohs (cc_msg->types);
- napps = ntohs (cc_msg->applications);
- if (size !=
- ntypes * sizeof (uint16_t) + napps * sizeof (GNUNET_MESH_ApplicationType))
+ if (0 != (size % sizeof (uint32_t)))
{
GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
+ size /= sizeof (uint32_t);
/* Create new client structure */
c = GNUNET_malloc (sizeof (struct MeshClient));
- c->id = next_client_id++;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " CLIENT NEW %u\n", c->id);
+ c->id = next_client_id++; /* overflow not important: just for debug */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client id %u\n", c->id);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " client has %u ports\n", size);
c->handle = client;
GNUNET_SERVER_client_keep (client);
- a = (GNUNET_MESH_ApplicationType *) &cc_msg[1];
- if (napps > 0)
+ if (size > 0)
{
- GNUNET_MESH_ApplicationType at;
+ uint32_t u32;
struct GNUNET_HashCode hc;
- c->apps = GNUNET_CONTAINER_multihashmap_create (napps, GNUNET_NO);
- for (i = 0; i < napps; i++)
+ p = (uint32_t *) &cc_msg[1];
+ c->ports = GNUNET_CONTAINER_multihashmap_create (size, GNUNET_NO);
+ for (i = 0; i < size; i++)
{
- at = ntohl (a[i]);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " app type: %u\n", at);
- GNUNET_CRYPTO_hash (&at, sizeof (at), &hc);
- /* store in clients hashmap */
- GNUNET_CONTAINER_multihashmap_put (c->apps, &hc, (void *) (long) at,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
- /* store in global hashmap, for announcements */
- GNUNET_CONTAINER_multihashmap_put (applications, &hc, c,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
- }
- if (GNUNET_SCHEDULER_NO_TASK == announce_applications_task)
- announce_applications_task =
- GNUNET_SCHEDULER_add_now (&announce_applications, NULL);
-
- }
- if (ntypes > 0)
- {
- uint16_t u16;
- struct GNUNET_HashCode hc;
+ u32 = ntohl (p[i]);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " port: %u\n", u32);
+ GMC_hash32 (u32, &hc);
- t = (uint16_t *) & a[napps];
- c->types = GNUNET_CONTAINER_multihashmap_create (ntypes, GNUNET_NO);
- for (i = 0; i < ntypes; i++)
- {
- u16 = ntohs (t[i]);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " msg type: %u\n", u16);
- GNUNET_CRYPTO_hash (&u16, sizeof (u16), &hc);
-
- /* store in clients hashmap */
- GNUNET_CONTAINER_multihashmap_put (c->types, &hc, c,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+ /* store in client's hashmap */
+ GNUNET_CONTAINER_multihashmap_put (c->ports, &hc, c,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
/* store in global hashmap */
- GNUNET_CONTAINER_multihashmap_put (types, &hc, c,
+ /* FIXME only allow one client to have the port open,
+ * have a backup hashmap with waiting clients */
+ GNUNET_CONTAINER_multihashmap_put (ports, &hc, c,
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
}
}
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " client has %u+%u subscriptions\n", napps, ntypes);
- GNUNET_CONTAINER_DLL_insert (clients, clients_tail, c);
+ GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, c);
c->own_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
c->incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
- c->ignore_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
GNUNET_SERVER_notification_context_add (nc, client);
GNUNET_STATISTICS_update (stats, "# clients", 1, GNUNET_NO);
@@ -6416,96 +4106,18 @@ handle_local_new_client (void *cls, struct GNUNET_SERVER_Client *client,
/**
- * Handler for clients announcing available services by a regular expression.
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message, which includes messages the client wants
- */
-static void
-handle_local_announce_regex (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- const struct GNUNET_MESH_RegexAnnounce *msg;
- struct MeshRegexDescriptor rd;
- struct MeshClient *c;
- char *regex;
- size_t len;
- size_t offset;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "announce regex started\n");
-
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
-
- msg = (const struct GNUNET_MESH_RegexAnnounce *) message;
-
- len = ntohs (message->size) - sizeof(struct GNUNET_MESH_RegexAnnounce);
- if (NULL != c->partial_regex)
- {
- regex = c->partial_regex;
- offset = strlen (c->partial_regex);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " continuation, already have %u bytes\n",
- offset);
- }
- else
- {
- regex = NULL;
- offset = 0;
- }
-
- regex = GNUNET_realloc (regex, offset + len + 1);
- memcpy (&regex[offset], &msg[1], len);
- regex[offset + len] = '\0';
- if (0 == ntohs (msg->last))
- {
- c->partial_regex = regex;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " not ended, stored %u bytes for later\n",
- len);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
- rd.regex = regex;
- rd.compression = ntohs (msg->compression_characters);
- rd.h = NULL;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " length %u\n", len);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " regex %s\n", regex);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " compr %u\n", ntohs (rd.compression));
- GNUNET_array_append (c->regexes, c->n_regex, rd);
- c->partial_regex = NULL;
- if (GNUNET_SCHEDULER_NO_TASK == c->regex_announce_task)
- {
- c->regex_announce_task = GNUNET_SCHEDULER_add_now (&regex_announce, c);
- }
- else
- {
- regex_put (&rd);
- }
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "announce regex processed\n");
-}
-
-
-/**
* Handler for requests of new tunnels
*
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message
+ * @param cls Closure.
+ * @param client Identification of the client.
+ * @param message The actual message.
*/
static void
handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message)
{
struct GNUNET_MESH_TunnelMessage *t_msg;
+ struct MeshPeerInfo *peer_info;
struct MeshTunnel *t;
struct MeshClient *c;
MESH_TunnelNumber tid;
@@ -6521,7 +4133,7 @@ handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client,
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
- /* Message sanity check */
+ /* Message size sanity check */
if (sizeof (struct GNUNET_MESH_TunnelMessage) != ntohs (message->size))
{
GNUNET_break (0);
@@ -6530,6 +4142,8 @@ handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client,
}
t_msg = (struct GNUNET_MESH_TunnelMessage *) message;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " towards %s\n",
+ GNUNET_i2s (&t_msg->peer));
/* Sanity check for tunnel numbering */
tid = ntohl (t_msg->tunnel_id);
if (0 == (tid & GNUNET_MESH_LOCAL_TUNNEL_ID_CLI))
@@ -6546,22 +4160,24 @@ handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client,
return;
}
+ /* Create tunnel */
while (NULL != tunnel_get_by_pi (myid, next_tid))
next_tid = (next_tid + 1) & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
- t = tunnel_new (myid, next_tid++, c, tid);
+ t = tunnel_new (myid, next_tid, c, tid);
+ next_tid = (next_tid + 1) & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
if (NULL == t)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Tunnel creation failed.\n");
GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- next_tid = next_tid & ~GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CREATED TUNNEL %s [%x] (%x)\n",
- GNUNET_i2s (&my_full_id), t->id.tid, t->local_tid);
- t->peers = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
+ t->port = ntohl (t_msg->port);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CREATED TUNNEL %s[%x]:%u (%x)\n",
+ GNUNET_i2s (&my_full_id), t->id.tid, t->port, t->local_tid);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new tunnel created\n");
+ peer_info = peer_get (&t_msg->peer);
+ peer_info_add_tunnel (peer_info, t);
+ peer_connect (peer_info, t);
GNUNET_SERVER_receive_done (client, GNUNET_OK);
return;
}
@@ -6615,80 +4231,24 @@ handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- if (c != t->owner || tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
- {
- client_ignore_tunnel (c, t);
- tunnel_destroy_empty (t);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
- }
- send_client_tunnel_disconnect (t, c);
- client_delete_tunnel (c, t);
- /* Don't try to ACK the client about the tunnel_destroy multicast packet */
- t->owner = NULL;
- tunnel_send_destroy (t, 0);
- t->destroy = GNUNET_YES;
- /* The tunnel will be destroyed when the last message is transmitted. */
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
-}
-
-
-/**
- * Handler for requests of seeting tunnel's speed.
- *
- * @param cls Closure (unused).
- * @param client Identification of the client.
- * @param message The actual message.
- */
-static void
-handle_local_tunnel_speed (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_TunnelMessage *tunnel_msg;
- struct MeshClient *c;
- struct MeshTunnel *t;
- MESH_TunnelNumber tid;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Got a SPEED request from client!\n");
-
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
+ /* Cleanup after the tunnel */
+ client_delete_tunnel (c, t);
+ if (c == t->client)
{
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
+ t->client = NULL;
}
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
-
- tunnel_msg = (struct GNUNET_MESH_TunnelMessage *) message;
-
- /* Retrieve tunnel */
- tid = ntohl (tunnel_msg->tunnel_id);
- t = tunnel_get_by_local_id(c, tid);
- if (NULL == t)
+ else if (c == t->owner)
{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " tunnel %X not found\n", tid);
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
+ peer_info_remove_tunnel (peer_get_short (t->dest), t);
+ t->owner = NULL;
}
- switch (ntohs(message->type))
- {
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_MIN:
- t->speed_min = GNUNET_YES;
- break;
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_MAX:
- t->speed_min = GNUNET_NO;
- break;
- default:
- GNUNET_break (0);
- }
+ /* The tunnel will be destroyed when the last message is transmitted. */
+ tunnel_destroy_empty (t);
+
GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
}
@@ -6750,479 +4310,6 @@ handle_local_tunnel_buffer (void *cls, struct GNUNET_SERVER_Client *client,
/**
- * Handler for connection requests to new peers
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message (PeerControl)
- */
-static void
-handle_local_connect_add (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_PeerControl *peer_msg;
- struct MeshPeerInfo *peer_info;
- struct MeshClient *c;
- struct MeshTunnel *t;
- MESH_TunnelNumber tid;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got connection request\n");
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
-
- peer_msg = (struct GNUNET_MESH_PeerControl *) message;
-
- /* Sanity check for message size */
- if (sizeof (struct GNUNET_MESH_PeerControl) != ntohs (peer_msg->header.size))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Tunnel exists? */
- tid = ntohl (peer_msg->tunnel_id);
- t = tunnel_get_by_local_id (c, tid);
- if (NULL == t)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Does client own tunnel? */
- if (t->owner->handle != client)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " for %s\n",
- GNUNET_i2s (&peer_msg->peer));
- peer_info = peer_info_get (&peer_msg->peer);
-
- tunnel_add_peer (t, peer_info);
- peer_info_connect (peer_info, t);
-
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
-}
-
-
-/**
- * Handler for disconnection requests of peers in a tunnel
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message (PeerControl)
- */
-static void
-handle_local_connect_del (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_PeerControl *peer_msg;
- struct MeshPeerInfo *peer_info;
- struct MeshClient *c;
- struct MeshTunnel *t;
- MESH_TunnelNumber tid;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a PEER DEL request\n");
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
-
- peer_msg = (struct GNUNET_MESH_PeerControl *) message;
-
- /* Sanity check for message size */
- if (sizeof (struct GNUNET_MESH_PeerControl) != ntohs (peer_msg->header.size))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Tunnel exists? */
- tid = ntohl (peer_msg->tunnel_id);
- t = tunnel_get_by_local_id (c, tid);
- if (NULL == t)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %X\n", t->id.tid);
-
- /* Does client own tunnel? */
- if (t->owner->handle != client)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " for peer %s\n",
- GNUNET_i2s (&peer_msg->peer));
- /* Is the peer in the tunnel? */
- peer_info =
- GNUNET_CONTAINER_multihashmap_get (t->peers, &peer_msg->peer.hashPubKey);
- if (NULL == peer_info)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Ok, delete peer from tunnel */
- GNUNET_CONTAINER_multihashmap_remove_all (t->peers,
- &peer_msg->peer.hashPubKey);
-
- send_destroy_path (t, peer_info->id);
- tunnel_delete_peer (t, peer_info->id);
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
-}
-
-/**
- * Handler for blacklist requests of peers in a tunnel
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message (PeerControl)
- *
- * FIXME implement DHT block bloomfilter
- */
-static void
-handle_local_blacklist (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_PeerControl *peer_msg;
- struct MeshClient *c;
- struct MeshTunnel *t;
- MESH_TunnelNumber tid;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a PEER BLACKLIST request\n");
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
-
- peer_msg = (struct GNUNET_MESH_PeerControl *) message;
-
- /* Sanity check for message size */
- if (sizeof (struct GNUNET_MESH_PeerControl) != ntohs (peer_msg->header.size))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Tunnel exists? */
- tid = ntohl (peer_msg->tunnel_id);
- t = tunnel_get_by_local_id (c, tid);
- if (NULL == t)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %X\n", t->id.tid);
-
- GNUNET_array_append(t->blacklisted, t->nblacklisted,
- GNUNET_PEER_intern(&peer_msg->peer));
-}
-
-
-/**
- * Handler for unblacklist requests of peers in a tunnel
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message (PeerControl)
- */
-static void
-handle_local_unblacklist (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_PeerControl *peer_msg;
- struct MeshClient *c;
- struct MeshTunnel *t;
- MESH_TunnelNumber tid;
- GNUNET_PEER_Id pid;
- unsigned int i;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a PEER UNBLACKLIST request\n");
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
-
- peer_msg = (struct GNUNET_MESH_PeerControl *) message;
-
- /* Sanity check for message size */
- if (sizeof (struct GNUNET_MESH_PeerControl) != ntohs (peer_msg->header.size))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Tunnel exists? */
- tid = ntohl (peer_msg->tunnel_id);
- t = tunnel_get_by_local_id (c, tid);
- if (NULL == t)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %X\n", t->id.tid);
-
- /* if peer is not known, complain */
- pid = GNUNET_PEER_search (&peer_msg->peer);
- if (0 == pid)
- {
- GNUNET_break (0);
- return;
- }
-
- /* search and remove from list */
- for (i = 0; i < t->nblacklisted; i++)
- {
- if (t->blacklisted[i] == pid)
- {
- t->blacklisted[i] = t->blacklisted[t->nblacklisted - 1];
- GNUNET_array_grow (t->blacklisted, t->nblacklisted, t->nblacklisted - 1);
- return;
- }
- }
-
- /* if peer hasn't been blacklisted, complain */
- GNUNET_break (0);
-}
-
-
-/**
- * Handler for connection requests to new peers by type
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message (ConnectPeerByType)
- */
-static void
-handle_local_connect_by_type (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_ConnectPeerByType *connect_msg;
- struct MeshClient *c;
- struct MeshTunnel *t;
- struct GNUNET_HashCode hash;
- MESH_TunnelNumber tid;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got connect by type request\n");
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
-
- connect_msg = (struct GNUNET_MESH_ConnectPeerByType *) message;
-
- /* Sanity check for message size */
- if (sizeof (struct GNUNET_MESH_ConnectPeerByType) !=
- ntohs (connect_msg->header.size))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Tunnel exists? */
- tid = ntohl (connect_msg->tunnel_id);
- t = tunnel_get_by_local_id (c, tid);
- if (NULL == t)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Does client own tunnel? */
- if (t->owner->handle != client)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Do WE have the service? */
- t->type = ntohl (connect_msg->type);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " type requested: %u\n", t->type);
- GNUNET_CRYPTO_hash (&t->type, sizeof (GNUNET_MESH_ApplicationType), &hash);
- if (GNUNET_CONTAINER_multihashmap_contains (applications, &hash) ==
- GNUNET_YES)
- {
- /* Yes! Fast forward, add ourselves to the tunnel and send the
- * good news to the client, and alert the destination client of
- * an incoming tunnel.
- *
- * FIXME send a path create to self, avoid code duplication
- */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " available locally\n");
- GNUNET_CONTAINER_multihashmap_put (t->peers, &my_full_id.hashPubKey,
- peer_info_get (&my_full_id),
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " notifying client\n");
- send_client_peer_connected (t, myid);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Done\n");
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
-
- t->local_tid_dest = next_local_tid++;
- GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber), &hash);
- GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
-
- return;
- }
- /* Ok, lets find a peer offering the service */
- if (NULL != t->dht_get_type)
- {
- GNUNET_DHT_get_stop (t->dht_get_type);
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " looking in DHT for %s\n",
- GNUNET_h2s (&hash));
- t->dht_get_type =
- GNUNET_DHT_get_start (dht_handle,
- GNUNET_BLOCK_TYPE_MESH_PEER_BY_TYPE,
- &hash,
- dht_replication_level,
- GNUNET_DHT_RO_RECORD_ROUTE |
- GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
- NULL, 0,
- &dht_get_type_handler, t);
-
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- return;
-}
-
-
-/**
- * Handler for connection requests to new peers by a string service description.
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message, which includes messages the client wants
- */
-static void
-handle_local_connect_by_string (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_ConnectPeerByString *msg;
- struct MeshRegexSearchInfo *info;
- struct MeshTunnel *t;
- struct MeshClient *c;
- MESH_TunnelNumber tid;
- const char *string;
- size_t size;
- size_t len;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Connect by string started\n");
- msg = (struct GNUNET_MESH_ConnectPeerByString *) message;
- size = htons (message->size);
-
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
-
- /* Message size sanity check */
- if (sizeof(struct GNUNET_MESH_ConnectPeerByString) >= size)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Tunnel exists? */
- tid = ntohl (msg->tunnel_id);
- t = tunnel_get_by_local_id (c, tid);
- if (NULL == t)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Does client own tunnel? */
- if (t->owner->handle != client)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " on tunnel %s [%u]\n",
- GNUNET_i2s(&my_full_id),
- t->id.tid);
-
- /* Only one connect_by_string allowed at the same time! */
- /* FIXME: allow more, return handle at api level to cancel, document */
- if (NULL != t->regex_search)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Find string itself */
- len = size - sizeof(struct GNUNET_MESH_ConnectPeerByString);
- string = (const char *) &msg[1];
-
- info = GNUNET_malloc (sizeof (struct MeshRegexSearchInfo));
- info->t = t;
- info->description = GNUNET_strndup (string, len);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " string: %s\n", info->description);
-
- t->regex_search = info;
-
- info->search_handle = GNUNET_REGEX_search (cfg,
- info->description,
- &regex_found_handler, info);
-
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "connect by string processed\n");
-}
-
-
-/**
* Handler for client traffic directed to one peer
*
* @param cls closure
@@ -7235,8 +4322,7 @@ handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client,
{
struct MeshClient *c;
struct MeshTunnel *t;
- struct MeshPeerInfo *pi;
- struct GNUNET_MESH_Unicast *data_msg;
+ struct GNUNET_MESH_Data *data_msg;
MESH_TunnelNumber tid;
size_t size;
@@ -7252,11 +4338,11 @@ handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client,
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
- data_msg = (struct GNUNET_MESH_Unicast *) message;
+ data_msg = (struct GNUNET_MESH_Data *) message;
/* Sanity check for message size */
size = ntohs (message->size);
- if (sizeof (struct GNUNET_MESH_Unicast) +
+ if (sizeof (struct GNUNET_MESH_Data) +
sizeof (struct GNUNET_MessageHeader) > size)
{
GNUNET_break (0);
@@ -7282,23 +4368,13 @@ handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client,
return;
}
- pi = GNUNET_CONTAINER_multihashmap_get (t->peers,
- &data_msg->destination.hashPubKey);
- /* Is the selected peer in the tunnel? */
- if (NULL == pi)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* PID should be as expected */
- if (ntohl (data_msg->pid) != t->fwd_pid + 1)
+ /* PID should be as expected: client<->service communication */
+ if (ntohl (data_msg->pid) != t->prev_fc.last_pid_recv + 1)
{
GNUNET_break (0);
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Unicast PID, expected %u, got %u\n",
- t->fwd_pid + 1, ntohl (data_msg->pid));
+ t->prev_fc.last_pid_recv + 1, ntohl (data_msg->pid));
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
@@ -7309,16 +4385,16 @@ handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client,
{
/* Work around const limitation */
char buf[ntohs (message->size)] GNUNET_ALIGN;
- struct GNUNET_MESH_Unicast *copy;
+ struct GNUNET_MESH_Data *copy;
- copy = (struct GNUNET_MESH_Unicast *) buf;
+ copy = (struct GNUNET_MESH_Data *) buf;
memcpy (buf, data_msg, size);
copy->oid = my_full_id;
copy->tid = htonl (t->id.tid);
copy->ttl = htonl (default_ttl);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" calling generic handler...\n");
- handle_mesh_data_unicast (NULL, &my_full_id, &copy->header);
+ handle_mesh_unicast (NULL, &my_full_id, &copy->header);
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "receive done OK\n");
GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -7338,8 +4414,8 @@ static void
handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client,
const struct GNUNET_MessageHeader *message)
{
- struct GNUNET_MESH_ToOrigin *data_msg;
- struct MeshTunnelClientInfo *clinfo;
+ struct GNUNET_MESH_Data *data_msg;
+ struct MeshFlowControl *fc;
struct MeshClient *c;
struct MeshTunnel *t;
MESH_TunnelNumber tid;
@@ -7356,11 +4432,11 @@ handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client,
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
- data_msg = (struct GNUNET_MESH_ToOrigin *) message;
+ data_msg = (struct GNUNET_MESH_Data *) message;
/* Sanity check for message size */
size = ntohs (message->size);
- if (sizeof (struct GNUNET_MESH_ToOrigin) +
+ if (sizeof (struct GNUNET_MESH_Data) +
sizeof (struct GNUNET_MessageHeader) > size)
{
GNUNET_break (0);
@@ -7388,7 +4464,7 @@ handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client,
}
/* It should be sent by someone who has this as incoming tunnel. */
- if (GNUNET_NO == client_knows_tunnel (c, t))
+ if (t->client != c)
{
GNUNET_break (0);
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
@@ -7396,38 +4472,35 @@ handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client,
}
/* PID should be as expected */
- clinfo = tunnel_get_client_fc (t, c);
- if (ntohl (data_msg->pid) != clinfo->bck_pid + 1)
+ fc = &t->next_fc;
+ if (ntohl (data_msg->pid) != fc->last_pid_recv + 1)
{
GNUNET_break (0);
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"To Origin PID, expected %u, got %u\n",
- clinfo->bck_pid + 1,
+ fc->last_pid_recv + 1,
ntohl (data_msg->pid));
GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
return;
}
- clinfo->bck_pid++;
/* Ok, everything is correct, send the message
* (pretend we got it from a mesh peer)
*/
{
char buf[ntohs (message->size)] GNUNET_ALIGN;
- struct GNUNET_MESH_ToOrigin *copy;
+ struct GNUNET_MESH_Data *copy;
- /* Work around const limitation */
- copy = (struct GNUNET_MESH_ToOrigin *) buf;
+ /* Work around 'const' limitation */
memcpy (buf, data_msg, size);
+ copy = (struct GNUNET_MESH_Data *) buf;
GNUNET_PEER_resolve (t->id.oid, &copy->oid);
copy->tid = htonl (t->id.tid);
copy->ttl = htonl (default_ttl);
- copy->pid = htonl (t->bck_pid + 1);
- copy->sender = my_full_id;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" calling generic handler...\n");
- handle_mesh_data_to_orig (NULL, &my_full_id, &copy->header);
+ handle_mesh_to_orig (NULL, &my_full_id, &copy->header);
}
GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -7436,97 +4509,6 @@ handle_local_to_origin (void *cls, struct GNUNET_SERVER_Client *client,
/**
- * Handler for client traffic directed to all peers in a tunnel
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message
- */
-static void
-handle_local_multicast (void *cls, struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
-{
- struct MeshClient *c;
- struct MeshTunnel *t;
- struct GNUNET_MESH_Multicast *data_msg;
- MESH_TunnelNumber tid;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Got a multicast request from a client!\n");
-
- /* Sanity check for client registration */
- if (NULL == (c = client_get (client)))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by client %u\n", c->id);
-
- data_msg = (struct GNUNET_MESH_Multicast *) message;
-
- /* Sanity check for message size */
- if (sizeof (struct GNUNET_MESH_Multicast) +
- sizeof (struct GNUNET_MessageHeader) > ntohs (data_msg->header.size))
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Tunnel exists? */
- tid = ntohl (data_msg->tid);
- t = tunnel_get_by_local_id (c, tid);
- if (NULL == t)
- {
- GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Tunnel %X unknown.\n", tid);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " for client %u.\n", c->id);
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* Does client own tunnel? */
- if (t->owner->handle != client)
- {
- GNUNET_break (0);
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- /* PID should be as expected */
- if (ntohl (data_msg->pid) != t->fwd_pid + 1)
- {
- GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Multicast PID, expected %u, got %u\n",
- t->fwd_pid + 1, ntohl (data_msg->pid));
- GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
- return;
- }
-
- {
- char buf[ntohs (message->size)] GNUNET_ALIGN;
- struct GNUNET_MESH_Multicast *copy;
-
- copy = (struct GNUNET_MESH_Multicast *) buf;
- memcpy (buf, message, ntohs (message->size));
- copy->oid = my_full_id;
- copy->tid = htonl (t->id.tid);
- copy->ttl = htonl (default_ttl);
- GNUNET_assert (ntohl (copy->pid) == (t->fwd_pid + 1));
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " calling generic handler...\n");
- handle_mesh_data_multicast (client, &my_full_id, &copy->header);
- }
-
- GNUNET_SERVER_receive_done (t->owner->handle, GNUNET_OK);
- return;
-}
-
-
-/**
* Handler for client's ACKs for payload traffic.
*
* @param cls Closure (unused).
@@ -7568,20 +4550,20 @@ handle_local_ack (void *cls, struct GNUNET_SERVER_Client *client,
return;
}
- ack = ntohl (msg->max_pid);
+ ack = ntohl (msg->ack);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ack);
/* Does client own tunnel? I.E: Is this an ACK for BCK traffic? */
- if (NULL != t->owner && t->owner->handle == client)
+ if (t->owner == c)
{
/* The client owns the tunnel, ACK is for data to_origin, send BCK ACK. */
- t->bck_ack = ack;
- tunnel_send_bck_ack(t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
+ t->prev_fc.last_ack_recv = ack;
+ tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
}
else
{
/* The client doesn't own the tunnel, this ACK is for FWD traffic. */
- tunnel_set_client_fwd_ack (t, c, ack);
+ t->next_fc.last_ack_recv = ack;
tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
}
@@ -7591,36 +4573,6 @@ handle_local_ack (void *cls, struct GNUNET_SERVER_Client *client,
}
-/**
- * Iterator over all peers to send a monitoring client info about a tunnel.
- *
- * @param cls Closure (message being built).
- * @param key Key (hashed tunnel ID, unused).
- * @param value Peer info.
- *
- * @return GNUNET_YES, to keep iterating.
- */
-static int
-monitor_peers_iterator (void *cls,
- const struct GNUNET_HashCode * key,
- void *value)
-{
- struct GNUNET_MESH_LocalMonitor *msg = cls;
- struct GNUNET_PeerIdentity *id;
- struct MeshPeerInfo *info = value;
-
- id = (struct GNUNET_PeerIdentity *) &msg[1];
- GNUNET_PEER_resolve (info->id, &id[msg->npeers]);
- msg->npeers++;
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "* sending info about peer %s [%u]\n",
- GNUNET_i2s (&id[msg->npeers - 1]), msg->npeers);
-
- return GNUNET_YES;
-}
-
-
/**
* Iterator over all tunnels to send a monitoring client info about each tunnel.
@@ -7639,37 +4591,21 @@ monitor_all_tunnels_iterator (void *cls,
struct GNUNET_SERVER_Client *client = cls;
struct MeshTunnel *t = value;
struct GNUNET_MESH_LocalMonitor *msg;
- uint32_t npeers;
-
- npeers = GNUNET_CONTAINER_multihashmap_size (t->peers);
- msg = GNUNET_malloc (sizeof(struct GNUNET_MESH_LocalMonitor) +
- npeers * sizeof (struct GNUNET_PeerIdentity));
+
+ msg = GNUNET_malloc (sizeof(struct GNUNET_MESH_LocalMonitor));
GNUNET_PEER_resolve(t->id.oid, &msg->owner);
msg->tunnel_id = htonl (t->id.tid);
- msg->header.size = htons (sizeof (struct GNUNET_MESH_LocalMonitor) +
- npeers * sizeof (struct GNUNET_PeerIdentity));
+ msg->header.size = htons (sizeof (struct GNUNET_MESH_LocalMonitor));
msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS);
- msg->npeers = 0;
- (void) GNUNET_CONTAINER_multihashmap_iterate (t->peers,
- monitor_peers_iterator,
- msg);
-
+ GNUNET_PEER_resolve (t->dest, &msg->destination);
+
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "* sending info about tunnel %s [%u] (%u peers)\n",
- GNUNET_i2s (&msg->owner), t->id.tid, npeers);
-
- if (msg->npeers != npeers)
- {
- GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Get tunnels fail: size %u - iter %u\n",
- npeers, msg->npeers);
- }
-
- msg->npeers = htonl (npeers);
- GNUNET_SERVER_notification_context_unicast (nc, client,
- &msg->header, GNUNET_NO);
- return GNUNET_YES;
+ "* sending info about tunnel %s [%u]\n",
+ GNUNET_i2s (&msg->owner), t->id.tid);
+
+ GNUNET_SERVER_notification_context_unicast (nc, client,
+ &msg->header, GNUNET_NO);
+ return GNUNET_YES;
}
@@ -7708,107 +4644,6 @@ handle_local_get_tunnels (void *cls, struct GNUNET_SERVER_Client *client,
/**
- * Data needed to build a Monitor_Tunnel message.
- */
-struct MeshMonitorTunnelContext
-{
- /**
- * Partial message, including peer count.
- */
- struct GNUNET_MESH_LocalMonitor *msg;
-
- /**
- * Hashmap with positions: peer->position.
- */
- struct GNUNET_CONTAINER_MultiHashMap *lookup;
-
- /**
- * Index of the parent of each peer in the message, realtive to the absolute
- * order in the array (can be in a previous message).
- */
- uint32_t parents[1024];
-
- /**
- * Peers visited so far in the tree, aka position of the current peer.
- */
- unsigned int npeers;
-
- /**
- * Client requesting the info.
- */
- struct MeshClient *c;
-};
-
-
-/**
- * Send a client a message about the structure of a tunnel.
- *
- * @param ctx Context of the tunnel iteration, with info regarding the state
- * of the execution and the number of peers visited for this message.
- */
-static void
-send_client_tunnel_info (struct MeshMonitorTunnelContext *ctx)
-{
- struct GNUNET_MESH_LocalMonitor *resp = ctx->msg;
- struct GNUNET_PeerIdentity *pid;
- unsigned int *parent;
- size_t size;
-
- size = sizeof (struct GNUNET_MESH_LocalMonitor);
- size += (sizeof (struct GNUNET_PeerIdentity) + sizeof (int)) * resp->npeers;
- resp->header.size = htons (size);
- pid = (struct GNUNET_PeerIdentity *) &resp[1];
- parent = (unsigned int *) &pid[resp->npeers];
- memcpy (parent, ctx->parents, sizeof(uint32_t) * resp->npeers);
- GNUNET_SERVER_notification_context_unicast (nc, ctx->c->handle,
- &resp->header, GNUNET_NO);
-}
-
-/**
- * Iterator over a tunnel tree to build a message containing all peers
- * the in the tunnel, including relay nodes.
- *
- * @param cls Closure (pointer to pointer of message being built).
- * @param peer Short ID of a peer.
- * @param parent Short ID of the @c peer 's parent.
- */
-static void
-tunnel_tree_iterator (void *cls,
- GNUNET_PEER_Id peer,
- GNUNET_PEER_Id parent)
-{
- struct MeshMonitorTunnelContext *ctx = cls;
- struct GNUNET_MESH_LocalMonitor *msg;
- struct GNUNET_PeerIdentity *pid;
- struct GNUNET_PeerIdentity ppid;
-
- msg = ctx->msg;
- pid = (struct GNUNET_PeerIdentity *) &msg[1];
- GNUNET_PEER_resolve (peer, &pid[msg->npeers]);
- GNUNET_CONTAINER_multihashmap_put (ctx->lookup,
- &pid[msg->npeers].hashPubKey,
- (void *) (long) ctx->npeers,
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
- GNUNET_PEER_resolve (parent, &ppid);
- ctx->parents[msg->npeers] =
- htonl ((long) GNUNET_CONTAINER_multihashmap_get (ctx->lookup,
- &ppid.hashPubKey));
-
- ctx->npeers++;
- msg->npeers++;
-
- if (sizeof (struct GNUNET_MESH_LocalMonitor) +
- (msg->npeers + 1) *
- (sizeof (struct GNUNET_PeerIdentity) + sizeof (uint32_t))
- > USHRT_MAX)
- {
- send_client_tunnel_info (ctx);
- msg->npeers = 0;
- }
-}
-
-
-/**
* Handler for client's MONITOR_TUNNEL request.
*
* @param cls Closure (unused).
@@ -7821,7 +4656,6 @@ handle_local_show_tunnel (void *cls, struct GNUNET_SERVER_Client *client,
{
const struct GNUNET_MESH_LocalMonitor *msg;
struct GNUNET_MESH_LocalMonitor *resp;
- struct MeshMonitorTunnelContext ctx;
struct MeshClient *c;
struct MeshTunnel *t;
@@ -7842,11 +4676,10 @@ handle_local_show_tunnel (void *cls, struct GNUNET_SERVER_Client *client,
t = tunnel_get (&msg->owner, ntohl (msg->tunnel_id));
if (NULL == t)
{
- /* We don't know the tunnel */
+ /* We don't know the tunnel FIXME */
struct GNUNET_MESH_LocalMonitor warn;
warn = *msg;
- warn.npeers = htonl (UINT_MAX);
GNUNET_SERVER_notification_context_unicast (nc, client,
&warn.header,
GNUNET_NO);
@@ -7855,19 +4688,12 @@ handle_local_show_tunnel (void *cls, struct GNUNET_SERVER_Client *client,
}
/* Initialize context */
- resp = GNUNET_malloc (USHRT_MAX); /* avoid realloc'ing on each step */
+ resp = GNUNET_malloc (sizeof (struct GNUNET_MESH_LocalMonitor));
*resp = *msg;
- resp->npeers = 0;
- ctx.msg = resp;
- ctx.lookup = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_YES);
- ctx.c = c;
-
- /* Collect and send information */
- tree_iterate_all (t->tree, &tunnel_tree_iterator, &ctx);
- send_client_tunnel_info (&ctx);
-
- /* Free context */
- GNUNET_CONTAINER_multihashmap_destroy (ctx.lookup);
+ GNUNET_PEER_resolve (t->dest, &resp->destination);
+ resp->header.size = htons (sizeof (struct GNUNET_MESH_LocalMonitor));
+ GNUNET_SERVER_notification_context_unicast (nc, c->handle,
+ &resp->header, GNUNET_NO);
GNUNET_free (resp);
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -7883,49 +4709,22 @@ handle_local_show_tunnel (void *cls, struct GNUNET_SERVER_Client *client,
static struct GNUNET_SERVER_MessageHandler client_handlers[] = {
{&handle_local_new_client, NULL,
GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0},
- {&handle_local_announce_regex, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_ANNOUNCE_REGEX, 0},
{&handle_local_tunnel_create, NULL,
GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE,
sizeof (struct GNUNET_MESH_TunnelMessage)},
{&handle_local_tunnel_destroy, NULL,
GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY,
sizeof (struct GNUNET_MESH_TunnelMessage)},
- {&handle_local_tunnel_speed, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_MIN,
- sizeof (struct GNUNET_MESH_TunnelMessage)},
- {&handle_local_tunnel_speed, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_MAX,
- sizeof (struct GNUNET_MESH_TunnelMessage)},
{&handle_local_tunnel_buffer, NULL,
GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER,
sizeof (struct GNUNET_MESH_TunnelMessage)},
{&handle_local_tunnel_buffer, NULL,
GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_NOBUFFER,
sizeof (struct GNUNET_MESH_TunnelMessage)},
- {&handle_local_connect_add, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD,
- sizeof (struct GNUNET_MESH_PeerControl)},
- {&handle_local_connect_del, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL,
- sizeof (struct GNUNET_MESH_PeerControl)},
- {&handle_local_blacklist, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_BLACKLIST,
- sizeof (struct GNUNET_MESH_PeerControl)},
- {&handle_local_unblacklist, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_UNBLACKLIST,
- sizeof (struct GNUNET_MESH_PeerControl)},
- {&handle_local_connect_by_type, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD_BY_TYPE,
- sizeof (struct GNUNET_MESH_ConnectPeerByType)},
- {&handle_local_connect_by_string, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD_BY_STRING, 0},
{&handle_local_unicast, NULL,
GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0},
{&handle_local_to_origin, NULL,
GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0},
- {&handle_local_multicast, NULL,
- GNUNET_MESSAGE_TYPE_MESH_MULTICAST, 0},
{&handle_local_ack, NULL,
GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK,
sizeof (struct GNUNET_MESH_LocalAck)},
@@ -7940,38 +4739,6 @@ static struct GNUNET_SERVER_MessageHandler client_handlers[] = {
/**
- * To be called on core init/fail.
- *
- * @param cls service closure
- * @param server handle to the server for this service
- * @param identity the public identity of this peer
- */
-static void
-core_init (void *cls, struct GNUNET_CORE_Handle *server,
- const struct GNUNET_PeerIdentity *identity)
-{
- static int i = 0;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core init\n");
- core_handle = server;
- if (0 != memcmp (identity, &my_full_id, sizeof (my_full_id)) ||
- NULL == server)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n"));
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- " core id %s\n",
- GNUNET_i2s (identity));
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- " my id %s\n",
- GNUNET_i2s (&my_full_id));
- GNUNET_SCHEDULER_shutdown (); // Try gracefully
- if (10 < i++)
- GNUNET_abort(); // Try harder
- }
- return;
-}
-
-
-/**
* Method called whenever a given peer connects.
*
* @param cls closure
@@ -7985,23 +4752,23 @@ core_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
DEBUG_CONN ("Peer connected\n");
DEBUG_CONN (" %s\n", GNUNET_i2s (&my_full_id));
- peer_info = peer_info_get (peer);
+ peer_info = peer_get (peer);
if (myid == peer_info->id)
{
DEBUG_CONN (" (self)\n");
- return;
+ path = path_new (1);
}
else
{
DEBUG_CONN (" %s\n", GNUNET_i2s (peer));
+ path = path_new (2);
+ path->peers[1] = peer_info->id;
+ GNUNET_PEER_change_rc (peer_info->id, 1);
+ GNUNET_STATISTICS_update (stats, "# peers", 1, GNUNET_NO);
}
- path = path_new (2);
path->peers[0] = myid;
- path->peers[1] = peer_info->id;
GNUNET_PEER_change_rc (myid, 1);
- GNUNET_PEER_change_rc (peer_info->id, 1);
peer_info_add_path (peer_info, path, GNUNET_YES);
- GNUNET_STATISTICS_update (stats, "# peers", 1, GNUNET_NO);
return;
}
@@ -8039,7 +4806,7 @@ core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
GNUNET_CORE_notify_transmit_ready_cancel(pi->core_transmit);
pi->core_transmit = NULL;
}
- peer_info_remove_path (pi, pi->id, myid);
+ peer_remove_path (pi, pi->id, myid);
if (myid == pi->id)
{
DEBUG_CONN (" (self)\n");
@@ -8049,6 +4816,69 @@ core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
}
+/**
+ * Install server (service) handlers and start listening to clients.
+ */
+static void
+server_init (void)
+{
+ GNUNET_SERVER_add_handlers (server_handle, client_handlers);
+ GNUNET_SERVER_disconnect_notify (server_handle,
+ &handle_local_client_disconnect, NULL);
+ nc = GNUNET_SERVER_notification_context_create (server_handle, 1);
+
+ clients_head = NULL;
+ clients_tail = NULL;
+ next_client_id = 0;
+ GNUNET_SERVER_resume (server_handle);
+}
+
+
+/**
+ * To be called on core init/fail.
+ *
+ * @param cls Closure (config)
+ * @param server handle to the server for this service
+ * @param identity the public identity of this peer
+ */
+static void
+core_init (void *cls, struct GNUNET_CORE_Handle *server,
+ const struct GNUNET_PeerIdentity *identity)
+{
+ const struct GNUNET_CONFIGURATION_Handle *c = cls;
+ static int i = 0;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core init\n");
+ GNUNET_break (core_handle == server);
+ if (0 != memcmp (identity, &my_full_id, sizeof (my_full_id)) ||
+ NULL == server)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n"));
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ " core id %s\n",
+ GNUNET_i2s (identity));
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ " my id %s\n",
+ GNUNET_i2s (&my_full_id));
+ GNUNET_CORE_disconnect (core_handle);
+ core_handle = GNUNET_CORE_connect (c, /* Main configuration */
+ NULL, /* Closure passed to MESH functions */
+ &core_init, /* Call core_init once connected */
+ &core_connect, /* Handle connects */
+ &core_disconnect, /* remove peers on disconnects */
+ NULL, /* Don't notify about all incoming messages */
+ GNUNET_NO, /* For header only in notification */
+ NULL, /* Don't notify about all outbound messages */
+ GNUNET_NO, /* For header-only out notification */
+ core_handlers); /* Register these handlers */
+ if (10 < i++)
+ GNUNET_abort();
+ }
+ server_init ();
+ return;
+}
+
+
/******************************************************************************/
/************************ MAIN FUNCTIONS ****************************/
/******************************************************************************/
@@ -8140,11 +4970,6 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_SCHEDULER_cancel (announce_id_task);
announce_id_task = GNUNET_SCHEDULER_NO_TASK;
}
- if (GNUNET_SCHEDULER_NO_TASK != announce_applications_task)
- {
- GNUNET_SCHEDULER_cancel (announce_applications_task);
- announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
- }
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shut down\n");
}
@@ -8162,10 +4987,8 @@ key_generation_cb (void *cls,
const char *emsg)
{
const struct GNUNET_CONFIGURATION_Handle *c = cls;
- struct MeshPeerInfo *peer;
- struct MeshPeerPath *p;
- keygen = NULL;
+ keygen = NULL;
if (NULL == pk)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -8193,7 +5016,6 @@ key_generation_cb (void *cls,
NULL, /* Don't notify about all outbound messages */
GNUNET_NO, /* For header-only out notification */
core_handlers); /* Register these handlers */
-
if (core_handle == NULL)
{
GNUNET_break (0);
@@ -8204,27 +5026,8 @@ key_generation_cb (void *cls,
next_tid = 0;
next_local_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
-
- GNUNET_SERVER_add_handlers (server_handle, client_handlers);
- nc = GNUNET_SERVER_notification_context_create (server_handle, 1);
- GNUNET_SERVER_disconnect_notify (server_handle,
- &handle_local_client_disconnect, NULL);
-
-
- clients = NULL;
- clients_tail = NULL;
- next_client_id = 0;
-
- announce_applications_task = GNUNET_SCHEDULER_NO_TASK;
announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, cls);
- /* Create a peer_info for the local peer */
- peer = peer_info_get (&my_full_id);
- p = path_new (1);
- p->peers[0] = myid;
- GNUNET_PEER_change_rc (myid, 1);
- peer_info_add_path (peer, p, GNUNET_YES);
- GNUNET_SERVER_resume (server_handle);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Mesh service running\n");
}
@@ -8242,9 +5045,9 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
{
char *keyfile;
- cfg = c;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "starting to run\n");
server_handle = server;
+ GNUNET_SERVER_suspend (server_handle);
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_filename (c, "PEER", "PRIVATE_KEY",
@@ -8271,20 +5074,6 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
}
if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_time (c, "MESH", "APP_ANNOUNCE_TIME",
- &app_announce_time))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _
- ("%s service is lacking key configuration settings (%s). Exiting.\n"),
- "mesh", "app announce time");
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "APP_ANNOUNCE_TIME %llu ms\n",
- app_announce_time.rel_value);
- if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_time (c, "MESH", "ID_ANNOUNCE_TIME",
&id_announce_time))
{
@@ -8367,8 +5156,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
peers = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
- applications = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
- types = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
+ ports = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_NO);
dht_handle = GNUNET_DHT_connect (c, 64);
if (NULL == dht_handle)
@@ -8377,7 +5165,6 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
}
stats = GNUNET_STATISTICS_create ("mesh", c);
- GNUNET_SERVER_suspend (server_handle);
/* Scheduled the task to clean up when shutdown is called */
GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
NULL);
diff --git a/src/mesh/mesh.h b/src/mesh/mesh.h
index a5a817c486..360bfabb44 100644
--- a/src/mesh/mesh.h
+++ b/src/mesh/mesh.h
@@ -38,9 +38,6 @@ extern "C"
#define MESH_DEBUG GNUNET_YES
-#define INITIAL_WINDOW_SIZE 8
-#define ACK_THRESHOLD INITIAL_WINDOW_SIZE / 2
-
#include "platform.h"
#include "gnunet_common.h"
#include "gnunet_util_lib.h"
@@ -63,18 +60,8 @@ extern "C"
*
* tunnel_create GNUNET_MESH_TunnelMessage
* tunnel_destroy GNUNET_MESH_TunnelMessage
- * tunnel_speed_max GNUNET_MESH_TunnelMessage
- * tunnel_speed_min GNUNET_MESH_TunnelMessage
* tunnel_buffer GNUNET_MESH_TunnelMessage
*
- * peer_request_connect_add GNUNET_MESH_PeerControl
- * peer_request_connect_del GNUNET_MESH_PeerControl
- * peer_request_connect_by_type GNUNET_MESH_ConnectPeerByType
- * peer_request_connect_by_string GNUNET_MESH_ConnectPeerByString
- *
- * peer_blacklist GNUNET_MESH_PeerControl
- * peer_unblacklist GNUNET_MESH_PeerControl
- *
* notify_transmit_ready None (queue / GNUNET_CLIENT_ntf_tmt_rdy)
* notify_transmit_ready_cancel None (clear of internal data structures)
*
@@ -87,8 +74,8 @@ extern "C"
* data ack GNUNET_MESH_LocalAck
*
* new incoming tunnel GNUNET_MESH_PeerControl
- * peer connects to a tunnel GNUNET_MESH_PeerControl
- * peer disconnects from a tunnel GNUNET_MESH_PeerControl
+ * peer connects to a tunnel FIXME
+ * peer disconnects from a tunnel FIXME
*/
/******************************************************************************/
@@ -122,10 +109,7 @@ struct GNUNET_MESH_ClientConnect
* sizeof(uint16_t) * types
*/
struct GNUNET_MessageHeader header;
- uint16_t applications GNUNET_PACKED;
- uint16_t types GNUNET_PACKED;
- /* uint32_t list_apps[applications] */
- /* uint16_t list_types[types] */
+ /* uint32_t list_ports[] */
};
@@ -137,6 +121,7 @@ struct GNUNET_MESH_ClientConnect
*/
typedef uint32_t MESH_TunnelNumber;
+
/**
* Message for a client to create and destroy tunnels.
*/
@@ -144,26 +129,6 @@ struct GNUNET_MESH_TunnelMessage
{
/**
* Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_[CREATE|DESTROY]
- * GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_[MAX|MIN]
- *
- * Size: sizeof(struct GNUNET_MESH_TunnelMessage)
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * ID of a tunnel controlled by this client.
- */
- MESH_TunnelNumber tunnel_id GNUNET_PACKED;
-};
-
-
-/**
- * Message for the service to let a client know about created tunnels.
- */
-struct GNUNET_MESH_TunnelNotification
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE
*
* Size: sizeof(struct GNUNET_MESH_TunnelMessage)
*/
@@ -175,60 +140,26 @@ struct GNUNET_MESH_TunnelNotification
MESH_TunnelNumber tunnel_id GNUNET_PACKED;
/**
- * Peer at the other end, if any
+ * Tunnel's peer
*/
struct GNUNET_PeerIdentity peer;
/**
- * Tunnel options (speed, buffering)
- */
- uint32_t opt;
-};
-
-/**
- * Message for announce of regular expressions.
- */
-struct GNUNET_MESH_RegexAnnounce
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_ANNOUNCE_REGEX
- *
- * Size: sizeof(struct GNUNET_MESH_RegexAnnounce) + strlen (regex)
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * How many characters do we want to put in an edge label.
- */
- uint16_t compression_characters;
-
- /**
- * Is this the last message for this regex? (for regex > 65k)
+ * Port of the tunnel.
*/
- int16_t last;
-
- /* regex payload */
+ uint32_t port GNUNET_PACKED;
};
/**
- * Message for:
- * - request adding and deleting peers from a tunnel
- * - notify the client that peers have connected:
- * -- requested
- * -- unrequested (new incoming tunnels)
- * - notify the client that peers have disconnected
+ * Message for the service to let a client know about created tunnels.
*/
-struct GNUNET_MESH_PeerControl
+struct GNUNET_MESH_TunnelNotification
{
-
/**
- * Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_[ADD|DEL|[UN]BLACKLIST]
- * (client to service, client created tunnel)
- * GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_[CONNECTED|DISCONNECTED]
- * (service to client)
+ * Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE
*
- * Size: sizeof(struct GNUNET_MESH_PeerControl)
+ * Size: sizeof(struct GNUNET_MESH_TunnelMessage)
*/
struct GNUNET_MessageHeader header;
@@ -238,55 +169,19 @@ struct GNUNET_MESH_PeerControl
MESH_TunnelNumber tunnel_id GNUNET_PACKED;
/**
- * Peer to connect/disconnect.
+ * Peer at the other end.
*/
struct GNUNET_PeerIdentity peer;
-};
-
-
-/**
- * Message for connecting to peers offering a service, by service number.
- */
-struct GNUNET_MESH_ConnectPeerByType
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT_PEER_BY_TYPE |
- * GNUNET_MESSAGE_TYPE_MESH_LOCAL_DISCONNECT_PEER_BY_TYPE
- *
- * Size: sizeof(struct GNUNET_MESH_ConnectPeerByType)
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * ID of a tunnel controlled by this client.
- */
- MESH_TunnelNumber tunnel_id GNUNET_PACKED;
/**
- * Type specification
- */
- GNUNET_MESH_ApplicationType type GNUNET_PACKED;
-};
-
-
-/**
- * Message for connecting to peers offering a service, by service string.
- */
-struct GNUNET_MESH_ConnectPeerByString
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD_BY_STRING
- *
- * Size: sizeof(struct GNUNET_MESH_ConnectPeerByString) + strlen (string)
+ * Port for this tunnel
*/
- struct GNUNET_MessageHeader header;
+ uint32_t port GNUNET_PACKED;
/**
- * ID of a tunnel controlled by this client.
+ * Tunnel options (speed, buffering)
*/
- MESH_TunnelNumber tunnel_id GNUNET_PACKED;
-
- /* String describing the service */
+ uint32_t opt GNUNET_PACKED;
};
@@ -309,7 +204,7 @@ struct GNUNET_MESH_LocalAck
/**
* ID of the last packet allowed.
*/
- uint32_t max_pid GNUNET_PACKED;
+ uint32_t ack GNUNET_PACKED;
};
@@ -329,11 +224,6 @@ struct GNUNET_MESH_LocalMonitor
MESH_TunnelNumber tunnel_id GNUNET_PACKED;
/**
- * Number of peers in the tunnel.
- */
- uint32_t npeers GNUNET_PACKED;
-
- /**
* Alignment.
*/
uint32_t reserved GNUNET_PACKED;
@@ -343,7 +233,10 @@ struct GNUNET_MESH_LocalMonitor
*/
struct GNUNET_PeerIdentity owner;
- /* struct GNUNET_PeerIdentity peers[npeers] */
+ /**
+ * ID of the destination of the tunnel (can be local peer).
+ */
+ struct GNUNET_PeerIdentity destination;
};
@@ -354,44 +247,34 @@ GNUNET_NETWORK_STRUCT_END
/******************************************************************************/
/**
- * All the states a peer participating in a tunnel can be in.
+ * All the states a tunnel can be in.
*/
-enum MeshPeerState
+enum MeshTunnelState
{
/**
* Uninitialized status, should never appear in operation.
*/
- MESH_PEER_INVALID,
-
- /**
- * Peer is the root and owner of the tree
- */
- MESH_PEER_ROOT,
-
- /**
- * Peer only retransmits traffic, is not a final destination
- */
- MESH_PEER_RELAY,
+ MESH_TUNNEL_NEW,
/**
* Path to the peer not known yet
*/
- MESH_PEER_SEARCHING,
+ MESH_TUNNEL_SEARCHING,
/**
* Request sent, not yet answered.
*/
- MESH_PEER_WAITING,
+ MESH_TUNNEL_WAITING,
/**
* Peer connected and ready to accept data
*/
- MESH_PEER_READY,
+ MESH_TUNNEL_READY,
/**
* Peer connected previosly but not responding
*/
- MESH_PEER_RECONNECTING
+ MESH_TUNNEL_RECONNECTING
};
@@ -432,6 +315,18 @@ GMC_min_pid (uint32_t a, uint32_t b);
/**
+ * Expand a 32 bit value (message type) into a hash for a MultiHashMap (fast).
+ * WARNING: do not use for anything other than MultiHashMap!
+ * does not alter anything other than bits used by idx_of !
+ *
+ * @param i 32 bit integer value.
+ * @param h Hash code to fill.
+ */
+void
+GMC_hash32 (uint32_t i, struct GNUNET_HashCode *h);
+
+
+/**
* Convert a message type into a string to help debug
* Generated with:
* FIND: "#define ([^ ]+)[ ]*([0-9]+)"
diff --git a/src/mesh/mesh2.h b/src/mesh/mesh2.h
deleted file mode 100644
index 360bfabb44..0000000000
--- a/src/mesh/mesh2.h
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 2001 - 2011 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @author Bartlomiej Polot
- * @file mesh/mesh.h
- */
-
-#ifndef MESH_H_
-#define MESH_H_
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0 /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-#include <stdint.h>
-
-#define MESH_DEBUG GNUNET_YES
-
-#include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_peer_lib.h"
-#include "gnunet_core_service.h"
-#include "gnunet_protocols.h"
-#include <gnunet_mesh_service.h>
-
-/******************************************************************************/
-/******************** MESH LOCAL MESSAGES *************************/
-/******************************************************************************/
-/* Any API call should be documented in the folowing table under API CALL.
- * Also, any message type should be documented in the following table, with the
- * associated event.
- *
- * API CALL (GNUNET_MESH_*) MESSAGE USED
- * ------------------------ ------------
- * connect GNUNET_MESH_ClientConnect
- * disconnect None (network level disconnect)
- *
- * tunnel_create GNUNET_MESH_TunnelMessage
- * tunnel_destroy GNUNET_MESH_TunnelMessage
- * tunnel_buffer GNUNET_MESH_TunnelMessage
- *
- * notify_transmit_ready None (queue / GNUNET_CLIENT_ntf_tmt_rdy)
- * notify_transmit_ready_cancel None (clear of internal data structures)
- *
- *
- * EVENT MESSAGE USED
- * ----- ------------
- * data GNUNET_MESH_Unicast OR
- * GNUNET_MESH_Multicast OR
- * GNUNET_MESH_ToOrigin
- * data ack GNUNET_MESH_LocalAck
- *
- * new incoming tunnel GNUNET_MESH_PeerControl
- * peer connects to a tunnel FIXME
- * peer disconnects from a tunnel FIXME
- */
-
-/******************************************************************************/
-/************************** CONSTANTS ******************************/
-/******************************************************************************/
-
-#define GNUNET_MESH_LOCAL_TUNNEL_ID_CLI 0x80000000
-#define GNUNET_MESH_LOCAL_TUNNEL_ID_SERV 0xB0000000
-
-#define HIGH_PID 0xFFFF0000
-#define LOW_PID 0x0000FFFF
-
-#define PID_OVERFLOW(pid, max) (pid > HIGH_PID && max < LOW_PID)
-
-/******************************************************************************/
-/************************** MESSAGES ******************************/
-/******************************************************************************/
-
-GNUNET_NETWORK_STRUCT_BEGIN
-
-/**
- * Message for a client to register to the service
- */
-struct GNUNET_MESH_ClientConnect
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT
- *
- * Size: sizeof(struct GNUNET_MESH_ClientConnect) +
- * sizeof(MESH_ApplicationType) * applications +
- * sizeof(uint16_t) * types
- */
- struct GNUNET_MessageHeader header;
- /* uint32_t list_ports[] */
-};
-
-
-/**
- * Type for tunnel numbering.
- * - Local tunnel numbers given by the service (incoming) are >= 0xB0000000
- * - Local tunnel numbers given by the client (created) are >= 0x80000000
- * - Global tunnel numbers are < 0x80000000
- */
-typedef uint32_t MESH_TunnelNumber;
-
-
-/**
- * Message for a client to create and destroy tunnels.
- */
-struct GNUNET_MESH_TunnelMessage
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_[CREATE|DESTROY]
- *
- * Size: sizeof(struct GNUNET_MESH_TunnelMessage)
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * ID of a tunnel controlled by this client.
- */
- MESH_TunnelNumber tunnel_id GNUNET_PACKED;
-
- /**
- * Tunnel's peer
- */
- struct GNUNET_PeerIdentity peer;
-
- /**
- * Port of the tunnel.
- */
- uint32_t port GNUNET_PACKED;
-};
-
-
-/**
- * Message for the service to let a client know about created tunnels.
- */
-struct GNUNET_MESH_TunnelNotification
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE
- *
- * Size: sizeof(struct GNUNET_MESH_TunnelMessage)
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * ID of a tunnel controlled by this client.
- */
- MESH_TunnelNumber tunnel_id GNUNET_PACKED;
-
- /**
- * Peer at the other end.
- */
- struct GNUNET_PeerIdentity peer;
-
- /**
- * Port for this tunnel
- */
- uint32_t port GNUNET_PACKED;
-
- /**
- * Tunnel options (speed, buffering)
- */
- uint32_t opt GNUNET_PACKED;
-};
-
-
-/**
- * Message to allow the client send more data to the service
- * (always service -> client).
- */
-struct GNUNET_MESH_LocalAck
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * ID of the tunnel allowed to send more data.
- */
- MESH_TunnelNumber tunnel_id GNUNET_PACKED;
-
- /**
- * ID of the last packet allowed.
- */
- uint32_t ack GNUNET_PACKED;
-};
-
-
-/**
- * Message to inform the client about tunnels in the service.
- */
-struct GNUNET_MESH_LocalMonitor
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_LOCAL_MONITOR[_TUNNEL]
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * ID of the tunnel allowed to send more data.
- */
- MESH_TunnelNumber tunnel_id GNUNET_PACKED;
-
- /**
- * Alignment.
- */
- uint32_t reserved GNUNET_PACKED;
-
- /**
- * ID of the owner of the tunnel (can be local peer).
- */
- struct GNUNET_PeerIdentity owner;
-
- /**
- * ID of the destination of the tunnel (can be local peer).
- */
- struct GNUNET_PeerIdentity destination;
-};
-
-
-GNUNET_NETWORK_STRUCT_END
-
-/******************************************************************************/
-/************************ ENUMERATIONS ****************************/
-/******************************************************************************/
-
-/**
- * All the states a tunnel can be in.
- */
-enum MeshTunnelState
-{
- /**
- * Uninitialized status, should never appear in operation.
- */
- MESH_TUNNEL_NEW,
-
- /**
- * Path to the peer not known yet
- */
- MESH_TUNNEL_SEARCHING,
-
- /**
- * Request sent, not yet answered.
- */
- MESH_TUNNEL_WAITING,
-
- /**
- * Peer connected and ready to accept data
- */
- MESH_TUNNEL_READY,
-
- /**
- * Peer connected previosly but not responding
- */
- MESH_TUNNEL_RECONNECTING
-};
-
-
-/**
- * Check if one pid is bigger than other, accounting for overflow.
- *
- * @param bigger Argument that should be bigger.
- * @param smaller Argument that should be smaller.
- *
- * @return True if bigger (arg1) has a higher value than smaller (arg 2).
- */
-int
-GMC_is_pid_bigger (uint32_t bigger, uint32_t smaller);
-
-
-/**
- * Get the higher ACK value out of two values, taking in account overflow.
- *
- * @param a First ACK value.
- * @param b Second ACK value.
- *
- * @return Highest ACK value from the two.
- */
-uint32_t
-GMC_max_pid (uint32_t a, uint32_t b);
-
-
-/**
- * Get the lower ACK value out of two values, taking in account overflow.
- *
- * @param a First ACK value.
- * @param b Second ACK value.
- *
- * @return Lowest ACK value from the two.
- */
-uint32_t
-GMC_min_pid (uint32_t a, uint32_t b);
-
-
-/**
- * Expand a 32 bit value (message type) into a hash for a MultiHashMap (fast).
- * WARNING: do not use for anything other than MultiHashMap!
- * does not alter anything other than bits used by idx_of !
- *
- * @param i 32 bit integer value.
- * @param h Hash code to fill.
- */
-void
-GMC_hash32 (uint32_t i, struct GNUNET_HashCode *h);
-
-
-/**
- * Convert a message type into a string to help debug
- * Generated with:
- * FIND: "#define ([^ ]+)[ ]*([0-9]+)"
- * REPLACE: " case \2: return "\1"; break;"
- *
- * @param m Message type.
- *
- * @return Human readable string description.
- */
-const char *
-GNUNET_MESH_DEBUG_M2S (uint16_t m);
-
-#if 0 /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/mesh/mesh2_api.c b/src/mesh/mesh2_api.c
deleted file mode 100644
index ef940f7e4d..0000000000
--- a/src/mesh/mesh2_api.c
+++ /dev/null
@@ -1,1787 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 2011 Christian Grothoff (and other contributing authors)
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file mesh/mesh2_api.c
- * @brief mesh2 api: client implementation of new mesh service
- * @author Bartlomiej Polot
- *
- * STRUCTURE:
- * - DATA STRUCTURES
- * - DECLARATIONS
- * - AUXILIARY FUNCTIONS
- * - RECEIVE HANDLERS
- * - SEND FUNCTIONS
- * - API CALL DEFINITIONS
- *
- * TODO: add regex to reconnect
- */
-#include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_client_lib.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_peer_lib.h"
-#include "gnunet_mesh2_service.h"
-#include "mesh2.h"
-#include "mesh2_protocol.h"
-
-#define LOG(kind,...) GNUNET_log_from (kind, "mesh2-api",__VA_ARGS__)
-#define DEBUG_ACK GNUNET_YES
-
-/******************************************************************************/
-/************************ DATA STRUCTURES ****************************/
-/******************************************************************************/
-
-/**
- * Transmission queue to the service
- */
-struct GNUNET_MESH_TransmitHandle
-{
-
- /**
- * Double Linked list
- */
- struct GNUNET_MESH_TransmitHandle *next;
-
- /**
- * Double Linked list
- */
- struct GNUNET_MESH_TransmitHandle *prev;
-
- /**
- * Tunnel this message is sent on / for (may be NULL for control messages).
- */
- struct GNUNET_MESH_Tunnel *tunnel;
-
- /**
- * Callback to obtain the message to transmit, or NULL if we
- * got the message in 'data'. Notice that messages built
- * by 'notify' need to be encapsulated with information about
- * the 'target'.
- */
- GNUNET_CONNECTION_TransmitReadyNotify notify;
-
- /**
- * Closure for 'notify'
- */
- void *notify_cls;
-
- /**
- * How long is this message valid. Once the timeout has been
- * reached, the message must no longer be sent. If this
- * is a message with a 'notify' callback set, the 'notify'
- * function should be called with 'buf' NULL and size 0.
- */
- struct GNUNET_TIME_Absolute timeout;
-
- /**
- * Task triggering a timeout, can be NO_TASK if the timeout is FOREVER.
- */
- GNUNET_SCHEDULER_TaskIdentifier timeout_task;
-
- /**
- * Size of 'data' -- or the desired size of 'notify' if 'data' is NULL.
- */
- size_t size;
-};
-
-
-/**
- * Opaque handle to the service.
- */
-struct GNUNET_MESH_Handle
-{
-
- /**
- * Handle to the server connection, to send messages later
- */
- struct GNUNET_CLIENT_Connection *client;
-
- /**
- * Set of handlers used for processing incoming messages in the tunnels
- */
- const struct GNUNET_MESH_MessageHandler *message_handlers;
-
- /**
- * Number of handlers in the handlers array.
- */
- unsigned int n_handlers;
-
- /**
- * Ports open.
- */
- const uint32_t *ports;
-
- /**
- * Number of ports.
- */
- unsigned int n_ports;
-
- /**
- * Double linked list of the tunnels this client is connected to, head.
- */
- struct GNUNET_MESH_Tunnel *tunnels_head;
-
- /**
- * Double linked list of the tunnels this client is connected to, tail.
- */
- struct GNUNET_MESH_Tunnel *tunnels_tail;
-
- /**
- * Callback for inbound tunnel creation
- */
- GNUNET_MESH_InboundTunnelNotificationHandler *new_tunnel;
-
- /**
- * Callback for inbound tunnel disconnection
- */
- GNUNET_MESH_TunnelEndHandler *cleaner;
-
- /**
- * Handle to cancel pending transmissions in case of disconnection
- */
- struct GNUNET_CLIENT_TransmitHandle *th;
-
- /**
- * Closure for all the handlers given by the client
- */
- void *cls;
-
- /**
- * Messages to send to the service, head.
- */
- struct GNUNET_MESH_TransmitHandle *th_head;
-
- /**
- * Messages to send to the service, tail.
- */
- struct GNUNET_MESH_TransmitHandle *th_tail;
-
- /**
- * tid of the next tunnel to create (to avoid reusing IDs often)
- */
- MESH_TunnelNumber next_tid;
-
- /**
- * Have we started the task to receive messages from the service
- * yet? We do this after we send the 'MESH_LOCAL_CONNECT' message.
- */
- int in_receive;
-
- /**
- * Configuration given by the client, in case of reconnection
- */
- const struct GNUNET_CONFIGURATION_Handle *cfg;
-
- /**
- * Time to the next reconnect in case one reconnect fails
- */
- struct GNUNET_TIME_Relative reconnect_time;
-
- /**
- * Task for trying to reconnect.
- */
- GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
-
- /**
- * Monitor callback
- */
- GNUNET_MESH_TunnelsCB tunnels_cb;
-
- /**
- * Monitor callback closure.
- */
- void *tunnels_cls;
-
- /**
- * Tunnel callback.
- */
- GNUNET_MESH_TunnelCB tunnel_cb;
-
- /**
- * Tunnel callback closure.
- */
- void *tunnel_cls;
-
-#if DEBUG_ACK
- unsigned int acks_sent;
- unsigned int acks_recv;
-#endif
-};
-
-
-/**
- * Description of a peer
- */
-struct GNUNET_MESH_Peer
-{
- /**
- * ID of the peer in short form
- */
- GNUNET_PEER_Id id;
-
- /**
- * Tunnel this peer belongs to
- */
- struct GNUNET_MESH_Tunnel *t;
-
- /**
- * Flag indicating whether service has informed about its connection
- */
- int connected;
-
-};
-
-
-/**
- * Opaque handle to a tunnel.
- */
-struct GNUNET_MESH_Tunnel
-{
-
- /**
- * DLL next
- */
- struct GNUNET_MESH_Tunnel *next;
-
- /**
- * DLL prev
- */
- struct GNUNET_MESH_Tunnel *prev;
-
- /**
- * Handle to the mesh this tunnel belongs to
- */
- struct GNUNET_MESH_Handle *mesh;
-
- /**
- * Local ID of the tunnel
- */
- MESH_TunnelNumber tid;
-
- /**
- * Port number.
- */
- uint32_t port;
-
- /**
- * Other end of the tunnel.
- */
- GNUNET_PEER_Id peer;
-
- /**
- * Any data the caller wants to put in here
- */
- void *ctx;
-
- /**
- * Size of packet queued in this tunnel
- */
- unsigned int packet_size;
-
- /**
- * Is the tunnel allowed to buffer?
- */
- int buffering;
-
- /**
- * Maximum allowed PID to send (last ACK recevied).
- */
- uint32_t last_ack_recv;
-
- /**
- * Last PID received from the service.
- */
- uint32_t last_pid_recv;
-
- /**
- * Last packet ID sent to the service.
- */
- uint32_t last_pid_sent;
-
- /**
- * Last ACK value sent to the service: how much are we willing to accept?
- */
- uint32_t last_ack_sent;
-};
-
-
-/**
- * Implementation state for mesh's message queue.
- */
-struct MeshMQState
-{
- /**
- * The current transmit handle, or NULL
- * if no transmit is active.
- */
- struct GNUNET_MESH_TransmitHandle *th;
-
- /**
- * Tunnel to send the data over.
- */
- struct GNUNET_MESH_Tunnel *tunnel;
-};
-
-
-/******************************************************************************/
-/*********************** DECLARATIONS *************************/
-/******************************************************************************/
-
-/**
- * Function called to send a message to the service.
- * "buf" will be NULL and "size" zero if the socket was closed for writing in
- * the meantime.
- *
- * @param cls closure, the mesh handle
- * @param size number of bytes available in buf
- * @param buf where the callee should write the connect message
- * @return number of bytes written to buf
- */
-static size_t
-send_callback (void *cls, size_t size, void *buf);
-
-
-/******************************************************************************/
-/*********************** AUXILIARY FUNCTIONS *************************/
-/******************************************************************************/
-
-/**
- * Check if transmission is a payload packet.
- *
- * @param th Transmission handle.
- *
- * @return GNUNET_YES if it is a payload packet,
- * GNUNET_NO if it is a mesh management packet.
- */
-static int
-th_is_payload (struct GNUNET_MESH_TransmitHandle *th)
-{
- return (th->notify != NULL) ? GNUNET_YES : GNUNET_NO;
-}
-
-
-/**
- * Check whether there is any message ready in the queue and find the size.
- *
- * @param h Mesh handle.
- *
- * @return The size of the first ready message in the queue,
- * 0 if there is none.
- */
-static size_t
-message_ready_size (struct GNUNET_MESH_Handle *h)
-{
- struct GNUNET_MESH_TransmitHandle *th;
- struct GNUNET_MESH_Tunnel *t;
-
- for (th = h->th_head; NULL != th; th = th->next)
- {
- t = th->tunnel;
- if (GNUNET_NO == th_is_payload (th))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# message internal\n");
- return th->size;
- }
- if (GNUNET_YES == GMC_is_pid_bigger(t->last_ack_recv, t->last_pid_sent))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# message payload ok (%u =< %u)\n",
- t->last_pid_sent + 1, t->last_ack_recv);
- return th->size;
- }
- }
- return 0;
-}
-
-
-/**
- * Get the tunnel handler for the tunnel specified by id from the given handle
- * @param h Mesh handle
- * @param tid ID of the wanted tunnel
- * @return handle to the required tunnel or NULL if not found
- */
-static struct GNUNET_MESH_Tunnel *
-retrieve_tunnel (struct GNUNET_MESH_Handle *h, MESH_TunnelNumber tid)
-{
- struct GNUNET_MESH_Tunnel *t;
-
- t = h->tunnels_head;
- while (t != NULL)
- {
- if (t->tid == tid)
- return t;
- t = t->next;
- }
- return NULL;
-}
-
-
-/**
- * Create a new tunnel and insert it in the tunnel list of the mesh handle
- * @param h Mesh handle
- * @param tid desired tid of the tunnel, 0 to assign one automatically
- * @return handle to the created tunnel
- */
-static struct GNUNET_MESH_Tunnel *
-create_tunnel (struct GNUNET_MESH_Handle *h, MESH_TunnelNumber tid)
-{
- struct GNUNET_MESH_Tunnel *t;
-
- t = GNUNET_malloc (sizeof (struct GNUNET_MESH_Tunnel));
- GNUNET_CONTAINER_DLL_insert (h->tunnels_head, h->tunnels_tail, t);
- t->mesh = h;
- if (0 == tid)
- {
- t->tid = h->next_tid;
- while (NULL != retrieve_tunnel (h, h->next_tid))
- {
- h->next_tid++;
- h->next_tid &= ~GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
- h->next_tid |= GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
- }
- }
- else
- {
- t->tid = tid;
- }
- t->last_ack_recv = (uint32_t) -1;
- t->last_pid_recv = (uint32_t) -1;
- t->last_ack_sent = (uint32_t) -1;
- t->last_pid_sent = (uint32_t) -1;
- t->buffering = GNUNET_YES;
- return t;
-}
-
-
-/**
- * Destroy the specified tunnel.
- * - Destroys all peers, calling the disconnect callback on each if needed
- * - Cancels all outgoing traffic for that tunnel, calling respective notifys
- * - Calls cleaner if tunnel was inbound
- * - Frees all memory used
- *
- * @param t Pointer to the tunnel.
- * @param call_cleaner Whether to call the cleaner handler.
- *
- * @return Handle to the required tunnel or NULL if not found.
- */
-static void
-destroy_tunnel (struct GNUNET_MESH_Tunnel *t, int call_cleaner)
-{
- struct GNUNET_MESH_Handle *h;
- struct GNUNET_MESH_TransmitHandle *th;
- struct GNUNET_MESH_TransmitHandle *next;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "destroy_tunnel %X\n", t->tid);
-
- if (NULL == t)
- {
- GNUNET_break (0);
- return;
- }
- h = t->mesh;
-
- GNUNET_CONTAINER_DLL_remove (h->tunnels_head, h->tunnels_tail, t);
-
- /* signal tunnel destruction */
- if ( (NULL != h->cleaner) && (0 != t->peer) && (GNUNET_YES == call_cleaner) )
- h->cleaner (h->cls, t, t->ctx);
-
- /* check that clients did not leave messages behind in the queue */
- for (th = h->th_head; NULL != th; th = next)
- {
- next = th->next;
- if (th->tunnel != t)
- continue;
- /* Clients should have aborted their requests already.
- * Management traffic should be ok, as clients can't cancel that */
- GNUNET_break (GNUNET_NO == th_is_payload(th));
- GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th);
-
- /* clean up request */
- if (GNUNET_SCHEDULER_NO_TASK != th->timeout_task)
- GNUNET_SCHEDULER_cancel (th->timeout_task);
- GNUNET_free (th);
- }
-
- /* if there are no more pending requests with mesh service, cancel active request */
- /* Note: this should be unnecessary... */
- if ((0 == message_ready_size (h)) && (NULL != h->th))
- {
- GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
- h->th = NULL;
- }
-
- if (0 != t->peer)
- GNUNET_PEER_change_rc (t->peer, -1);
- GNUNET_free (t);
- return;
-}
-
-
-/**
- * Notify client that the transmission has timed out
- *
- * @param cls closure
- * @param tc task context
- */
-static void
-timeout_transmission (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct GNUNET_MESH_TransmitHandle *th = cls;
- struct GNUNET_MESH_Handle *mesh;
-
- mesh = th->tunnel->mesh;
- GNUNET_CONTAINER_DLL_remove (mesh->th_head, mesh->th_tail, th);
- th->tunnel->packet_size = 0;
- if (GNUNET_YES == th_is_payload (th))
- th->notify (th->notify_cls, 0, NULL);
- GNUNET_free (th);
- if ((0 == message_ready_size (mesh)) && (NULL != mesh->th))
- {
- /* nothing ready to transmit, no point in asking for transmission */
- GNUNET_CLIENT_notify_transmit_ready_cancel (mesh->th);
- mesh->th = NULL;
- }
-}
-
-
-/**
- * Add a transmit handle to the transmission queue and set the
- * timeout if needed.
- *
- * @param h mesh handle with the queue head and tail
- * @param th handle to the packet to be transmitted
- */
-static void
-add_to_queue (struct GNUNET_MESH_Handle *h,
- struct GNUNET_MESH_TransmitHandle *th)
-{
- GNUNET_CONTAINER_DLL_insert_tail (h->th_head, h->th_tail, th);
- if (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value == th->timeout.abs_value)
- return;
- th->timeout_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining
- (th->timeout), &timeout_transmission, th);
-}
-
-
-/**
- * Auxiliary function to send an already constructed packet to the service.
- * Takes care of creating a new queue element, copying the message and
- * calling the tmt_rdy function if necessary.
- *
- * @param h mesh handle
- * @param msg message to transmit
- * @param tunnel tunnel this send is related to (NULL if N/A)
- */
-static void
-send_packet (struct GNUNET_MESH_Handle *h,
- const struct GNUNET_MessageHeader *msg,
- struct GNUNET_MESH_Tunnel *tunnel);
-
-
-/**
- * Send an ack on the tunnel to confirm the processing of a message.
- *
- * @param h Mesh handle.
- * @param t Tunnel on which to send the ACK.
- */
-static void
-send_ack (struct GNUNET_MESH_Tunnel *t)
-{
- struct GNUNET_MESH_LocalAck msg;
-
- t->last_ack_sent = t->last_pid_recv + 1;
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Sending ACK on tunnel %X: %u\n",
- t->tid, t->last_ack_sent);
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
- msg.header.size = htons (sizeof (msg));
- msg.tunnel_id = htonl (t->tid);
- msg.ack = htonl (t->last_ack_sent);
-
-#if DEBUG_ACK
- t->mesh->acks_sent++;
-#endif
-
- send_packet (t->mesh, &msg.header, t);
- return;
-}
-
-
-
-/**
- * Reconnect callback: tries to reconnect again after a failer previous
- * reconnecttion
- * @param cls closure (mesh handle)
- * @param tc task context
- */
-static void
-reconnect_cbk (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
-
-
-/**
- * Send a connect packet to the service with the applications and types
- * requested by the user.
- *
- * @param h The mesh handle.
- *
- */
-static void
-send_connect (struct GNUNET_MESH_Handle *h)
-{
- size_t size;
-
- size = sizeof (struct GNUNET_MESH_ClientConnect);
- size += h->n_ports * sizeof (uint32_t);
- {
- char buf[size] GNUNET_ALIGN;
- struct GNUNET_MESH_ClientConnect *msg;
- uint32_t *ports;
- uint16_t i;
-
- /* build connection packet */
- msg = (struct GNUNET_MESH_ClientConnect *) buf;
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT);
- msg->header.size = htons (size);
- ports = (uint32_t *) &msg[1];
- for (i = 0; i < h->n_ports; i++)
- {
- ports[i] = htonl (h->ports[i]);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " port %u\n",
- h->ports[i]);
- }
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Sending %lu bytes long message with %u ports\n",
- ntohs (msg->header.size), h->n_ports);
- send_packet (h, &msg->header, NULL);
- }
-}
-
-
-/**
- * Reconnect to the service, retransmit all infomation to try to restore the
- * original state.
- *
- * @param h handle to the mesh
- *
- * @return GNUNET_YES in case of sucess, GNUNET_NO otherwise (service down...)
- */
-static int
-do_reconnect (struct GNUNET_MESH_Handle *h)
-{
- struct GNUNET_MESH_Tunnel *t;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "*****************************\n");
- LOG (GNUNET_ERROR_TYPE_DEBUG, "******* RECONNECT *******\n");
- LOG (GNUNET_ERROR_TYPE_DEBUG, "*****************************\n");
- LOG (GNUNET_ERROR_TYPE_DEBUG, "******** on %p *******\n", h);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "*****************************\n");
-
- /* disconnect */
- if (NULL != h->th)
- {
- GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
- h->th = NULL;
- }
- if (NULL != h->client)
- {
- GNUNET_CLIENT_disconnect (h->client);
- }
-
- /* connect again */
- h->client = GNUNET_CLIENT_connect ("mesh", h->cfg);
- if (h->client == NULL)
- {
- h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
- &reconnect_cbk, h);
- h->reconnect_time =
- GNUNET_TIME_relative_min (GNUNET_TIME_UNIT_SECONDS,
- GNUNET_TIME_relative_multiply
- (h->reconnect_time, 2));
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Next retry in %s\n",
- GNUNET_STRINGS_relative_time_to_string (h->reconnect_time,
- GNUNET_NO));
- GNUNET_break (0);
- return GNUNET_NO;
- }
- else
- {
- h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
- }
- send_connect (h);
- /* Rebuild all tunnels */
- for (t = h->tunnels_head; NULL != t; t = t->next)
- {
- struct GNUNET_MESH_TunnelMessage tmsg;
-
- if (t->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
- {
- /* Tunnel was created by service (incoming tunnel) */
- /* TODO: Notify service of missing tunnel, to request
- * creator to recreate path (find a path to him via DHT?)
- */
- continue;
- }
- t->last_ack_sent = (uint32_t) -1;
- t->last_pid_sent = (uint32_t) -1;
- t->last_ack_recv = (uint32_t) -1;
- t->last_pid_recv = (uint32_t) -1;
- tmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
- tmsg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
- tmsg.tunnel_id = htonl (t->tid);
- GNUNET_PEER_resolve (t->peer, &tmsg.peer);
- send_packet (h, &tmsg.header, t);
-
- if (GNUNET_NO == t->buffering)
- GNUNET_MESH_tunnel_buffer (t, GNUNET_NO);
- }
- return GNUNET_YES;
-}
-
-/**
- * Reconnect callback: tries to reconnect again after a failer previous
- * reconnecttion
- * @param cls closure (mesh handle)
- * @param tc task context
- */
-static void
-reconnect_cbk (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct GNUNET_MESH_Handle *h = cls;
-
- h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- return;
- do_reconnect (h);
-}
-
-
-/**
- * Reconnect to the service, retransmit all infomation to try to restore the
- * original state.
- *
- * @param h handle to the mesh
- *
- * @return GNUNET_YES in case of sucess, GNUNET_NO otherwise (service down...)
- */
-static void
-reconnect (struct GNUNET_MESH_Handle *h)
-{
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Requested RECONNECT\n");
- h->in_receive = GNUNET_NO;
- if (GNUNET_SCHEDULER_NO_TASK == h->reconnect_task)
- h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
- &reconnect_cbk, h);
-}
-
-
-/******************************************************************************/
-/*********************** RECEIVE HANDLERS ****************************/
-/******************************************************************************/
-
-/**
- * Process the new tunnel notification and add it to the tunnels in the handle
- *
- * @param h The mesh handle
- * @param msg A message with the details of the new incoming tunnel
- */
-static void
-process_tunnel_created (struct GNUNET_MESH_Handle *h,
- const struct GNUNET_MESH_TunnelNotification *msg)
-{
- struct GNUNET_MESH_Tunnel *t;
- MESH_TunnelNumber tid;
-
- tid = ntohl (msg->tunnel_id);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating incoming tunnel %X\n", tid);
- if (tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
- {
- GNUNET_break (0);
- return;
- }
- if (NULL != h->new_tunnel)
- {
- t = create_tunnel (h, tid);
- t->last_ack_sent = 0;
- t->peer = GNUNET_PEER_intern (&msg->peer);
- t->mesh = h;
- t->tid = tid;
- t->port = ntohl (msg->port);
- if (0 != (msg->opt & MESH_TUNNEL_OPT_NOBUFFER))
- t->buffering = GNUNET_NO;
- else
- t->buffering = GNUNET_YES;
- LOG (GNUNET_ERROR_TYPE_DEBUG, " created tunnel %p\n", t);
- t->ctx = h->new_tunnel (h->cls, t, &msg->peer, t->port);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "User notified\n");
- }
- else
- {
- struct GNUNET_MESH_TunnelMessage d_msg;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "No handler for incoming tunnels\n");
-
- d_msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
- d_msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
- d_msg.tunnel_id = msg->tunnel_id;
-
- send_packet (h, &d_msg.header, NULL);
- }
- return;
-}
-
-
-/**
- * Process the tunnel destroy notification and free associated resources
- *
- * @param h The mesh handle
- * @param msg A message with the details of the tunnel being destroyed
- */
-static void
-process_tunnel_destroy (struct GNUNET_MESH_Handle *h,
- const struct GNUNET_MESH_TunnelMessage *msg)
-{
- struct GNUNET_MESH_Tunnel *t;
- MESH_TunnelNumber tid;
-
- tid = ntohl (msg->tunnel_id);
- t = retrieve_tunnel (h, tid);
-
- if (NULL == t)
- {
- return;
- }
- LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel %X destroyed\n", t->tid);
- destroy_tunnel (t, GNUNET_YES);
- return;
-}
-
-
-/**
- * Process the incoming data packets, call appropriate handlers.
- *
- * @param h The mesh handle
- * @param message A message encapsulating the data
- */
-static void
-process_incoming_data (struct GNUNET_MESH_Handle *h,
- const struct GNUNET_MessageHeader *message)
-{
- const struct GNUNET_MessageHeader *payload;
- const struct GNUNET_MESH_MessageHandler *handler;
- const struct GNUNET_PeerIdentity *peer;
- struct GNUNET_PeerIdentity id;
- struct GNUNET_MESH_Data *dmsg;
- struct GNUNET_MESH_Tunnel *t;
- unsigned int i;
- uint32_t pid;
- uint16_t type;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Got a data message!\n");
- type = ntohs (message->type);
- switch (type)
- {
- case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- dmsg = (struct GNUNET_MESH_Data *) message;
-
- t = retrieve_tunnel (h, ntohl (dmsg->tid));
- payload = (struct GNUNET_MessageHeader *) &dmsg[1];
- GNUNET_PEER_resolve (t->peer, &id);
- peer = &id;
- pid = ntohl (dmsg->pid);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " %s data on tunnel %s [%X]\n",
- type == GNUNET_MESSAGE_TYPE_MESH_UNICAST ? "fwd" : "bck",
- GNUNET_i2s (peer), ntohl (dmsg->tid));
- break;
- default:
- GNUNET_break (0);
- return;
- }
- LOG (GNUNET_ERROR_TYPE_DEBUG, " pid %u\n", pid);
- if (NULL == t)
- {
- /* Tunnel was ignored/destroyed, probably service didn't get it yet */
- LOG (GNUNET_ERROR_TYPE_DEBUG, " ignored!\n");
- return;
- }
- if (GNUNET_YES ==
- GMC_is_pid_bigger(pid, t->last_ack_sent))
- {
- GNUNET_break (0);
- LOG (GNUNET_ERROR_TYPE_WARNING,
- " unauthorized message! (%u, ACK %u)\n",
- pid, t->last_ack_sent);
- // FIXME fc what now? accept? reject?
- return;
- }
- t->last_pid_recv = pid;
- type = ntohs (payload->type);
- for (i = 0; i < h->n_handlers; i++)
- {
- handler = &h->message_handlers[i];
- if (handler->type == type)
- {
- if (GNUNET_OK !=
- handler->callback (h->cls, t, &t->ctx, payload))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "callback caused disconnection\n");
- GNUNET_MESH_tunnel_destroy (t);
- return;
- }
- else
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "callback completed successfully\n");
- }
- }
- }
-}
-
-
-/**
- * Process a local ACK message, enabling the client to send
- * more data to the service.
- *
- * @param h Mesh handle.
- * @param message Message itself.
- */
-static void
-process_ack (struct GNUNET_MESH_Handle *h,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_LocalAck *msg;
- struct GNUNET_MESH_Tunnel *t;
- uint32_t ack;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Got an ACK!\n");
- h->acks_recv++;
- msg = (struct GNUNET_MESH_LocalAck *) message;
-
- t = retrieve_tunnel (h, ntohl (msg->tunnel_id));
-
- if (NULL == t)
- {
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "ACK on unknown tunnel %X\n",
- ntohl (msg->tunnel_id));
- return;
- }
- ack = ntohl (msg->ack);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %X, ack %u!\n", t->tid, ack);
- if (GNUNET_YES == GMC_is_pid_bigger(ack, t->last_ack_recv))
- t->last_ack_recv = ack;
- else
- return;
- if (NULL == h->th && 0 < t->packet_size)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, " tmt rdy was NULL, requesting!\n", t->tid, ack);
- h->th =
- GNUNET_CLIENT_notify_transmit_ready (h->client, t->packet_size,
- GNUNET_TIME_UNIT_FOREVER_REL,
- GNUNET_YES, &send_callback, h);
- }
-}
-
-
-/**
- * Process a local reply about info on all tunnels, pass info to the user.
- *
- * @param h Mesh handle.
- * @param message Message itself.
- */
-static void
-process_get_tunnels (struct GNUNET_MESH_Handle *h,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_LocalMonitor *msg;
-
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Get Tunnels messasge received\n");
-
- if (NULL == h->tunnels_cb)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " ignored\n");
- return;
- }
-
- msg = (struct GNUNET_MESH_LocalMonitor *) message;
- if (ntohs (message->size) !=
- (sizeof (struct GNUNET_MESH_LocalMonitor) +
- sizeof (struct GNUNET_PeerIdentity)))
- {
- GNUNET_break_op (0);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Get tunnels message: size %hu - expected %u\n",
- ntohs (message->size),
- sizeof (struct GNUNET_MESH_LocalMonitor));
- return;
- }
- h->tunnels_cb (h->tunnels_cls,
- ntohl (msg->tunnel_id),
- &msg->owner,
- &msg->destination);
-}
-
-
-
-/**
- * Process a local monitor_tunnel reply, pass info to the user.
- *
- * @param h Mesh handle.
- * @param message Message itself.
- */
-static void
-process_show_tunnel (struct GNUNET_MESH_Handle *h,
- const struct GNUNET_MessageHeader *message)
-{
- struct GNUNET_MESH_LocalMonitor *msg;
- size_t esize;
-
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Show Tunnel messasge received\n");
-
- if (NULL == h->tunnel_cb)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, " ignored\n");
- return;
- }
-
- /* Verify message sanity */
- msg = (struct GNUNET_MESH_LocalMonitor *) message;
- esize = sizeof (struct GNUNET_MESH_LocalMonitor);
- if (ntohs (message->size) != esize)
- {
- GNUNET_break_op (0);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Show tunnel message: size %hu - expected %u\n",
- ntohs (message->size),
- esize);
-
- h->tunnel_cb (h->tunnel_cls, NULL, NULL);
- h->tunnel_cb = NULL;
- h->tunnel_cls = NULL;
-
- return;
- }
-
- h->tunnel_cb (h->tunnel_cls,
- &msg->destination,
- &msg->owner);
-}
-
-
-/**
- * Function to process all messages received from the service
- *
- * @param cls closure
- * @param msg message received, NULL on timeout or fatal error
- */
-static void
-msg_received (void *cls, const struct GNUNET_MessageHeader *msg)
-{
- struct GNUNET_MESH_Handle *h = cls;
-
- if (msg == NULL)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Mesh service disconnected, reconnecting\n", h);
- reconnect (h);
- return;
- }
- LOG (GNUNET_ERROR_TYPE_DEBUG, "\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (msg->type)));
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Received a message: %s\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (msg->type)));
- switch (ntohs (msg->type))
- {
- /* Notify of a new incoming tunnel */
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE:
- process_tunnel_created (h, (struct GNUNET_MESH_TunnelNotification *) msg);
- break;
- /* Notify of a tunnel disconnection */
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY:
- process_tunnel_destroy (h, (struct GNUNET_MESH_TunnelMessage *) msg);
- break;
- /* Notify of a new data packet in the tunnel */
- case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
- case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- process_incoming_data (h, msg);
- break;
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
- process_ack (h, msg);
- break;
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS:
- process_get_tunnels (h, msg);
- break;
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL:
- process_show_tunnel (h, msg);
- break;
- default:
- /* We shouldn't get any other packages, log and ignore */
- LOG (GNUNET_ERROR_TYPE_WARNING,
- "unsolicited message form service (type %s)\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (msg->type)));
- }
- LOG (GNUNET_ERROR_TYPE_DEBUG, "message processed\n");
- if (GNUNET_YES == h->in_receive)
- {
- GNUNET_CLIENT_receive (h->client, &msg_received, h,
- GNUNET_TIME_UNIT_FOREVER_REL);
- }
- else
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "in receive off, not calling CLIENT_receive\n");
- }
-}
-
-
-/******************************************************************************/
-/************************ SEND FUNCTIONS ****************************/
-/******************************************************************************/
-
-/**
- * Function called to send a message to the service.
- * "buf" will be NULL and "size" zero if the socket was closed for writing in
- * the meantime.
- *
- * @param cls closure, the mesh handle
- * @param size number of bytes available in buf
- * @param buf where the callee should write the connect message
- * @return number of bytes written to buf
- */
-static size_t
-send_callback (void *cls, size_t size, void *buf)
-{
- struct GNUNET_MESH_Handle *h = cls;
- struct GNUNET_MESH_TransmitHandle *th;
- struct GNUNET_MESH_TransmitHandle *next;
- struct GNUNET_MESH_Tunnel *t;
- char *cbuf = buf;
- size_t tsize;
- size_t psize;
- size_t nsize;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# Send packet() Buffer %u\n", size);
- if ((0 == size) || (NULL == buf))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# Received NULL send callback on %p\n", h);
- reconnect (h);
- h->th = NULL;
- return 0;
- }
- tsize = 0;
- next = h->th_head;
- nsize = message_ready_size (h);
- while ((NULL != (th = next)) && (0 < nsize) && (size >= nsize))
- {
- t = th->tunnel;
- if (GNUNET_YES == th_is_payload (th))
- {
- struct GNUNET_MESH_Data *dmsg;
- struct GNUNET_MessageHeader *mh;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# payload\n");
- if (GNUNET_NO == GMC_is_pid_bigger (t->last_ack_recv, t->last_pid_sent))
- {
- /* This tunnel is not ready to transmit yet, try next message */
- next = th->next;
- continue;
- }
- t->packet_size = 0;
- GNUNET_assert (size >= th->size);
- dmsg = (struct GNUNET_MESH_Data *) cbuf;
- mh = (struct GNUNET_MessageHeader *) &dmsg[1];
- psize = th->notify (th->notify_cls,
- size - sizeof (struct GNUNET_MESH_Data),
- mh);
- if (psize > 0)
- {
- psize += sizeof (struct GNUNET_MESH_Data);
- GNUNET_assert (size >= psize);
- dmsg->header.size = htons (psize);
- dmsg->tid = htonl (t->tid);
- dmsg->pid = htonl (t->last_pid_sent + 1);
- dmsg->ttl = 0;
- memset (&dmsg->oid, 0, sizeof (struct GNUNET_PeerIdentity));
- t->last_pid_sent++;
- }
- if (t->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
- {
- dmsg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# to origin, type %s\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
- }
- else
- {
- dmsg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_UNICAST);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# unicast, type %s\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
- }
- }
- else
- {
- struct GNUNET_MessageHeader *mh = (struct GNUNET_MessageHeader *) &th[1];
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# mesh traffic, type %s\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
- memcpy (cbuf, &th[1], th->size);
- psize = th->size;
- }
- if (th->timeout_task != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (th->timeout_task);
- GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th);
- GNUNET_free (th);
- next = h->th_head;
- nsize = message_ready_size (h);
- cbuf += psize;
- size -= psize;
- tsize += psize;
- }
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# total size: %u\n", tsize);
- h->th = NULL;
- size = message_ready_size (h);
- if (0 != size)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# next size: %u\n", size);
- h->th =
- GNUNET_CLIENT_notify_transmit_ready (h->client, size,
- GNUNET_TIME_UNIT_FOREVER_REL,
- GNUNET_YES, &send_callback, h);
- }
- else
- {
- if (NULL != h->th_head)
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# can't transmit any more\n");
- else
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# nothing left to transmit\n");
- }
- if (GNUNET_NO == h->in_receive)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# start receiving from service\n");
- h->in_receive = GNUNET_YES;
- GNUNET_CLIENT_receive (h->client, &msg_received, h,
- GNUNET_TIME_UNIT_FOREVER_REL);
- }
- LOG (GNUNET_ERROR_TYPE_DEBUG, "# Send packet() END\n");
- return tsize;
-}
-
-
-/**
- * Auxiliary function to send an already constructed packet to the service.
- * Takes care of creating a new queue element, copying the message and
- * calling the tmt_rdy function if necessary.
- *
- * @param h mesh handle
- * @param msg message to transmit
- * @param tunnel tunnel this send is related to (NULL if N/A)
- */
-static void
-send_packet (struct GNUNET_MESH_Handle *h,
- const struct GNUNET_MessageHeader *msg,
- struct GNUNET_MESH_Tunnel *tunnel)
-{
- struct GNUNET_MESH_TransmitHandle *th;
- size_t msize;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, " Sending message to service: %s\n",
- GNUNET_MESH_DEBUG_M2S(ntohs(msg->type)));
- msize = ntohs (msg->size);
- th = GNUNET_malloc (sizeof (struct GNUNET_MESH_TransmitHandle) + msize);
- th->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
- th->size = msize;
- th->tunnel = tunnel;
- memcpy (&th[1], msg, msize);
- add_to_queue (h, th);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " queued\n");
- if (NULL != h->th)
- return;
- LOG (GNUNET_ERROR_TYPE_DEBUG, " calling ntfy tmt rdy for %u bytes\n", msize);
- h->th =
- GNUNET_CLIENT_notify_transmit_ready (h->client, msize,
- GNUNET_TIME_UNIT_FOREVER_REL,
- GNUNET_YES, &send_callback, h);
-}
-
-
-/******************************************************************************/
-/********************** API CALL DEFINITIONS *************************/
-/******************************************************************************/
-
-struct GNUNET_MESH_Handle *
-GNUNET_MESH_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls,
- GNUNET_MESH_InboundTunnelNotificationHandler new_tunnel,
- GNUNET_MESH_TunnelEndHandler cleaner,
- const struct GNUNET_MESH_MessageHandler *handlers,
- const uint32_t *ports)
-{
- struct GNUNET_MESH_Handle *h;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_MESH_connect()\n");
- h = GNUNET_malloc (sizeof (struct GNUNET_MESH_Handle));
- LOG (GNUNET_ERROR_TYPE_DEBUG, " addr %p\n", h);
- h->cfg = cfg;
- h->new_tunnel = new_tunnel;
- h->cleaner = cleaner;
- h->client = GNUNET_CLIENT_connect ("mesh", cfg);
- if (h->client == NULL)
- {
- GNUNET_break (0);
- GNUNET_free (h);
- return NULL;
- }
- h->cls = cls;
- h->message_handlers = handlers;
- h->ports = ports;
- h->next_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
- h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
- h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
-
- /* count handlers */
- for (h->n_handlers = 0;
- handlers && handlers[h->n_handlers].type;
- h->n_handlers++) ;
- for (h->n_ports = 0;
- ports && ports[h->n_ports];
- h->n_ports++) ;
- send_connect (h);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_MESH_connect() END\n");
- return h;
-}
-
-
-void
-GNUNET_MESH_disconnect (struct GNUNET_MESH_Handle *handle)
-{
- struct GNUNET_MESH_Tunnel *t;
- struct GNUNET_MESH_Tunnel *aux;
- struct GNUNET_MESH_TransmitHandle *th;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "MESH DISCONNECT\n");
-
-#if DEBUG_ACK
- LOG (GNUNET_ERROR_TYPE_INFO, "Sent %d ACKs\n", handle->acks_sent);
- LOG (GNUNET_ERROR_TYPE_INFO, "Recv %d ACKs\n\n", handle->acks_recv);
-#endif
-
- t = handle->tunnels_head;
- while (NULL != t)
- {
- aux = t->next;
- if (t->tid < GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
- {
- GNUNET_break (0);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel %X not destroyed\n", t->tid);
- }
- destroy_tunnel (t, GNUNET_YES);
- t = aux;
- }
- while ( (th = handle->th_head) != NULL)
- {
- struct GNUNET_MessageHeader *msg;
-
- /* Make sure it is an allowed packet (everything else should have been
- * already canceled).
- */
- GNUNET_break (GNUNET_NO == th_is_payload (th));
- msg = (struct GNUNET_MessageHeader *) &th[1];
- switch (ntohs(msg->type))
- {
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT:
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY:
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS:
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL:
- break;
- default:
- GNUNET_break (0);
- LOG (GNUNET_ERROR_TYPE_ERROR, "unexpected msg %u\n",
- ntohs(msg->type));
- }
-
- GNUNET_CONTAINER_DLL_remove (handle->th_head, handle->th_tail, th);
- GNUNET_free (th);
- }
-
- if (NULL != handle->th)
- {
- GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th);
- handle->th = NULL;
- }
- if (NULL != handle->client)
- {
- GNUNET_CLIENT_disconnect (handle->client);
- handle->client = NULL;
- }
- if (GNUNET_SCHEDULER_NO_TASK != handle->reconnect_task)
- {
- GNUNET_SCHEDULER_cancel(handle->reconnect_task);
- handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
- }
- GNUNET_free (handle);
-}
-
-
-struct GNUNET_MESH_Tunnel *
-GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h,
- void *tunnel_ctx,
- const struct GNUNET_PeerIdentity *peer,
- uint32_t port)
-{
- struct GNUNET_MESH_Tunnel *t;
- struct GNUNET_MESH_TunnelMessage msg;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating new tunnel\n");
- t = create_tunnel (h, 0);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " at %p\n", t);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " number %X\n", t->tid);
- t->ctx = tunnel_ctx;
- t->peer = GNUNET_PEER_intern (peer);
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
- msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
- msg.tunnel_id = htonl (t->tid);
- msg.port = htonl (port);
- msg.peer = *peer;
- t->last_ack_sent = 0;
- send_packet (h, &msg.header, t);
- return t;
-}
-
-
-void
-GNUNET_MESH_tunnel_destroy (struct GNUNET_MESH_Tunnel *tunnel)
-{
- struct GNUNET_MESH_Handle *h;
- struct GNUNET_MESH_TunnelMessage msg;
- struct GNUNET_MESH_TransmitHandle *th;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Destroying tunnel\n");
- h = tunnel->mesh;
-
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY);
- msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
- msg.tunnel_id = htonl (tunnel->tid);
- th = h->th_head;
- while (th != NULL)
- {
- struct GNUNET_MESH_TransmitHandle *aux;
- if (th->tunnel == tunnel)
- {
- aux = th->next;
- /* FIXME call the handler? */
- if (GNUNET_YES == th_is_payload (th))
- th->notify (th->notify_cls, 0, NULL);
- GNUNET_CONTAINER_DLL_remove (h->th_head, h->th_tail, th);
- GNUNET_free (th);
- th = aux;
- }
- else
- th = th->next;
- }
-
- destroy_tunnel (tunnel, GNUNET_YES);
- send_packet (h, &msg.header, NULL);
-}
-
-
-void
-GNUNET_MESH_tunnel_buffer (struct GNUNET_MESH_Tunnel *tunnel, int buffer)
-{
- struct GNUNET_MESH_TunnelMessage msg;
- struct GNUNET_MESH_Handle *h;
-
- h = tunnel->mesh;
- tunnel->buffering = buffer;
-
- if (GNUNET_YES == buffer)
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER);
- else
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_NOBUFFER);
- msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
- msg.tunnel_id = htonl (tunnel->tid);
-
- send_packet (h, &msg.header, NULL);
-}
-
-
-struct GNUNET_MESH_TransmitHandle *
-GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork,
- struct GNUNET_TIME_Relative maxdelay,
- size_t notify_size,
- GNUNET_CONNECTION_TransmitReadyNotify notify,
- void *notify_cls)
-{
- struct GNUNET_MESH_TransmitHandle *th;
-
- GNUNET_assert (NULL != tunnel);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "MESH NOTIFY TRANSMIT READY\n");
- LOG (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %X\n", tunnel->tid);
- if (tunnel->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
- LOG (GNUNET_ERROR_TYPE_DEBUG, " to origin\n");
- else
- LOG (GNUNET_ERROR_TYPE_DEBUG, " to destination\n");
- LOG (GNUNET_ERROR_TYPE_DEBUG, " payload size %u\n", notify_size);
- GNUNET_assert (NULL != notify);
- GNUNET_assert (0 == tunnel->packet_size); // Only one data packet allowed
- th = GNUNET_malloc (sizeof (struct GNUNET_MESH_TransmitHandle));
- th->tunnel = tunnel;
- th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay);
- th->size = notify_size + sizeof (struct GNUNET_MESH_Data);
- tunnel->packet_size = th->size;
- LOG (GNUNET_ERROR_TYPE_DEBUG, " total size %u\n", th->size);
- th->notify = notify;
- th->notify_cls = notify_cls;
- add_to_queue (tunnel->mesh, th);
- if (NULL != tunnel->mesh->th)
- return th;
- if (!GMC_is_pid_bigger (tunnel->last_ack_recv, tunnel->last_pid_sent))
- return th;
- LOG (GNUNET_ERROR_TYPE_DEBUG, " call client notify tmt rdy\n");
- tunnel->mesh->th =
- GNUNET_CLIENT_notify_transmit_ready (tunnel->mesh->client, th->size,
- GNUNET_TIME_UNIT_FOREVER_REL,
- GNUNET_YES, &send_callback,
- tunnel->mesh);
- LOG (GNUNET_ERROR_TYPE_DEBUG, "MESH NOTIFY TRANSMIT READY END\n");
- return th;
-}
-
-
-void
-GNUNET_MESH_notify_transmit_ready_cancel (struct GNUNET_MESH_TransmitHandle *th)
-{
- struct GNUNET_MESH_Handle *mesh;
-
- th->tunnel->packet_size = 0;
- mesh = th->tunnel->mesh;
- if (th->timeout_task != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (th->timeout_task);
- GNUNET_CONTAINER_DLL_remove (mesh->th_head, mesh->th_tail, th);
- GNUNET_free (th);
- if ((0 == message_ready_size (mesh)) && (NULL != mesh->th))
- {
- /* queue empty, no point in asking for transmission */
- GNUNET_CLIENT_notify_transmit_ready_cancel (mesh->th);
- mesh->th = NULL;
- }
-}
-
-void
-GNUNET_MESH_receive_done (struct GNUNET_MESH_Tunnel *tunnel)
-{
- send_ack (tunnel);
-}
-
-
-/**
- * Request information about the running mesh peer.
- * The callback will be called for every tunnel known to the service,
- * listing all active peers that blong to the tunnel.
- *
- * If called again on the same handle, it will overwrite the previous
- * callback and cls. To retrieve the cls, monitor_cancel must be
- * called first.
- *
- * WARNING: unstable API, likely to change in the future!
- *
- * @param h Handle to the mesh peer.
- * @param callback Function to call with the requested data.
- * @param callback_cls Closure for @c callback.
- */
-void
-GNUNET_MESH_get_tunnels (struct GNUNET_MESH_Handle *h,
- GNUNET_MESH_TunnelsCB callback,
- void *callback_cls)
-{
- struct GNUNET_MessageHeader msg;
-
- msg.size = htons (sizeof (msg));
- msg.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS);
- send_packet (h, &msg, NULL);
- h->tunnels_cb = callback;
- h->tunnels_cls = callback_cls;
-
- return;
-}
-
-
-/**
- * Cancel a monitor request. The monitor callback will not be called.
- *
- * @param h Mesh handle.
- *
- * @return Closure given to GNUNET_MESH_monitor, if any.
- */
-void *
-GNUNET_MESH_get_tunnels_cancel (struct GNUNET_MESH_Handle *h)
-{
- void *cls;
-
- cls = h->tunnels_cls;
- h->tunnels_cb = NULL;
- h->tunnels_cls = NULL;
- return cls;
-}
-
-
-/**
- * Request information about a specific tunnel of the running mesh peer.
- *
- * WARNING: unstable API, likely to change in the future!
- * FIXME Add destination option.
- *
- * @param h Handle to the mesh peer.
- * @param initiator ID of the owner of the tunnel.
- * @param tunnel_number Tunnel number.
- * @param callback Function to call with the requested data.
- * @param callback_cls Closure for @c callback.
- */
-void
-GNUNET_MESH_show_tunnel (struct GNUNET_MESH_Handle *h,
- struct GNUNET_PeerIdentity *initiator,
- unsigned int tunnel_number,
- GNUNET_MESH_TunnelCB callback,
- void *callback_cls)
-{
- struct GNUNET_MESH_LocalMonitor msg;
-
- msg.header.size = htons (sizeof (msg));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL);
- msg.owner = *initiator;
- msg.tunnel_id = htonl (tunnel_number);
- msg.reserved = 0;
- send_packet (h, &msg.header, NULL);
- h->tunnel_cb = callback;
- h->tunnel_cls = callback_cls;
-
- return;
-}
-
-
-/**
- * Function called to notify a client about the connection
- * begin ready to queue more data. "buf" will be
- * NULL and "size" zero if the connection was closed for
- * writing in the meantime.
- *
- * @param cls closure
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
- */
-static size_t
-mesh_mq_ntr (void *cls, size_t size,
- void *buf)
-{
- struct GNUNET_MQ_Handle *mq = cls;
- struct MeshMQState *state = GNUNET_MQ_impl_state (mq);
- const struct GNUNET_MessageHeader *msg = GNUNET_MQ_impl_current (mq);
- uint16_t msize;
-
- state->th = NULL;
- if (NULL == buf)
- {
- GNUNET_MQ_inject_error (mq, GNUNET_MQ_ERROR_WRITE);
- return 0;
- }
- msize = ntohs (msg->size);
- GNUNET_assert (msize <= size);
- memcpy (buf, msg, msize);
- GNUNET_MQ_impl_send_continue (mq);
- return msize;
-}
-
-
-/**
- * Signature of functions implementing the
- * sending functionality of a message queue.
- *
- * @param mq the message queue
- * @param msg the message to send
- * @param impl_state state of the implementation
- */
-static void
-mesh_mq_send_impl (struct GNUNET_MQ_Handle *mq,
- const struct GNUNET_MessageHeader *msg, void *impl_state)
-{
- struct MeshMQState *state = impl_state;
-
- GNUNET_assert (NULL == state->th);
- GNUNET_MQ_impl_send_commit (mq);
- state->th =
- GNUNET_MESH_notify_transmit_ready (state->tunnel,
- /* FIXME: add option for corking */
- GNUNET_NO,
- GNUNET_TIME_UNIT_FOREVER_REL,
- ntohs (msg->size),
- mesh_mq_ntr, mq);
-
-}
-
-
-/**
- * Signature of functions implementing the
- * destruction of a message queue.
- * Implementations must not free 'mq', but should
- * take care of 'impl_state'.
- *
- * @param mq the message queue to destroy
- * @param impl_state state of the implementation
- */
-static void
-mesh_mq_destroy_impl (struct GNUNET_MQ_Handle *mq, void *impl_state)
-{
- struct MeshMQState *state = impl_state;
-
- if (NULL != state->th)
- GNUNET_MESH_notify_transmit_ready_cancel (state->th);
-
- GNUNET_free (state);
-}
-
-
-/**
- * Create a message queue for a mesh tunnel.
- * The message queue can only be used to transmit messages,
- * not to receive them.
- *
- * @param tunnel the tunnel to create the message qeue for
- * @return a message queue to messages over the tunnel
- */
-struct GNUNET_MQ_Handle *
-GNUNET_MESH_mq_create (struct GNUNET_MESH_Tunnel *tunnel)
-{
- struct GNUNET_MQ_Handle *mq;
- struct MeshMQState *state;
-
- state = GNUNET_new (struct MeshMQState);
- state->tunnel = tunnel;
-
- mq = GNUNET_MQ_queue_for_callbacks (mesh_mq_send_impl,
- mesh_mq_destroy_impl,
- NULL, /* FIXME: cancel impl. */
- state,
- NULL, /* no msg handlers */
- NULL, /* no err handlers */
- NULL); /* no handler cls */
- return mq;
-}
-
diff --git a/src/mesh/mesh2_protocol.h b/src/mesh/mesh2_protocol.h
deleted file mode 100644
index d35d7141ee..0000000000
--- a/src/mesh/mesh2_protocol.h
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 2001 - 2011 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @author Bartlomiej Polot
- * @file mesh/mesh_protocol.h
- */
-
-#ifndef MESH_PROTOCOL_H_
-#define MESH_PROTOCOL_H_
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0
- /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-#define MESH_TUNNEL_OPT_NOBUFFER 0x2
-
-
-/******************************************************************************/
-/******************** MESH NETWORK MESSAGES **************************/
-/******************************************************************************/
-
-GNUNET_NETWORK_STRUCT_BEGIN
-
-/**
- * Message for mesh path creation.
- */
-struct GNUNET_MESH_CreateTunnel
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE
- *
- * Size: sizeof(struct GNUNET_MESH_ManipulatePath) +
- * path_length * sizeof (struct GNUNET_PeerIdentity)
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * Global id of the tunnel this path belongs to,
- * unique in conjunction with the origin.
- */
- uint32_t tid GNUNET_PACKED;
-
- /**
- * Tunnel options (MESH_TUNNEL_OPT_*).
- */
- uint32_t opt GNUNET_PACKED;
-
- /**
- * Destination port.
- */
- uint32_t port GNUNET_PACKED;
-
- /**
- * FIXME do not add the first hop
- * path_length structs defining the *whole* path from the origin [0] to the
- * final destination [path_length-1].
- */
- /* struct GNUNET_PeerIdentity peers[path_length]; */
-};
-
-/**
- * Message for mesh path destruction.
- */
-struct GNUNET_MESH_DestroyTunnel
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY
- *
- * Size: sizeof(struct GNUNET_MESH_ManipulatePath) +
- * path_length * sizeof (struct GNUNET_PeerIdentity)
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * Global id of the tunnel this path belongs to,
- * unique in conjunction with the origin.
- */
- uint32_t tid GNUNET_PACKED;
-};
-
-
-/**
- * Message for mesh data traffic.
- */
-struct GNUNET_MESH_Data
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_UNICAST,
- * GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * TID of the tunnel
- */
- uint32_t tid GNUNET_PACKED;
-
- /**
- * Number of hops to live
- */
- uint32_t ttl GNUNET_PACKED;
-
- /**
- * Unique ID of the packet
- */
- uint32_t pid GNUNET_PACKED;
-
- /**
- * OID of the tunnel
- */
- struct GNUNET_PeerIdentity oid;
-
- /**
- * Payload follows
- */
-};
-
-
-/**
- * Message to acknowledge mesh data traffic.
- */
-struct GNUNET_MESH_ACK
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_ACK
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * TID of the tunnel
- */
- uint32_t tid GNUNET_PACKED;
-
- /**
- * OID of the tunnel
- */
- struct GNUNET_PeerIdentity oid;
-
- /**
- * Maximum packet ID authorized.
- */
- uint32_t pid;
-
-};
-
-/**
- * Message to query a peer about its Flow Control status regarding a tunnel.
- */
-struct GNUNET_MESH_Poll
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_POLL
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * TID of the tunnel
- */
- uint32_t tid GNUNET_PACKED;
-
- /**
- * OID of the tunnel
- */
- struct GNUNET_PeerIdentity oid;
-};
-
-/**
- * Message for ack'ing a path
- */
-struct GNUNET_MESH_PathACK
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_PATH_ACK
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * TID of the tunnel
- */
- uint32_t tid GNUNET_PACKED;
-
- /**
- * OID of the tunnel
- */
- struct GNUNET_PeerIdentity oid;
-
- /**
- * ID of the endpoint
- */
- struct GNUNET_PeerIdentity peer_id;
-
- /**
- * Initial ACK value for payload.
- */
- uint32_t ack GNUNET_PACKED;
-
- /* TODO: signature */
-};
-
-
-/**
- * Message for notifying a disconnection in a path
- */
-struct GNUNET_MESH_PathBroken
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_PATH_BROKEN
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * TID of the tunnel
- */
- uint32_t tid GNUNET_PACKED;
-
- /**
- * OID of the tunnel
- */
- struct GNUNET_PeerIdentity oid;
-
- /**
- * ID of the endpoint
- */
- struct GNUNET_PeerIdentity peer1;
-
- /**
- * ID of the endpoint
- */
- struct GNUNET_PeerIdentity peer2;
-
- /* TODO: signature */
-};
-
-
-/**
- * Message to destroy a tunnel
- */
-struct GNUNET_MESH_TunnelDestroy
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_TUNNEL_DESTROY
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * TID of the tunnel
- */
- uint32_t tid GNUNET_PACKED;
-
- /**
- * OID of the tunnel
- */
- struct GNUNET_PeerIdentity oid;
-
- /* TODO: signature */
-};
-
-
-/**
- * Message to destroy a tunnel
- */
-struct GNUNET_MESH_TunnelKeepAlive
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_PATH_KEEPALIVE
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * TID of the tunnel
- */
- uint32_t tid GNUNET_PACKED;
-
- /**
- * OID of the tunnel
- */
- struct GNUNET_PeerIdentity oid;
-};
-
-
-
-GNUNET_NETWORK_STRUCT_END
-
-#if 0 /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-/* ifndef MESH_PROTOCOL_H */
-#endif
-/* end of mesh_protocol.h */
diff --git a/src/mesh/mesh2_test_lib.c b/src/mesh/mesh2_test_lib.c
deleted file mode 100644
index 95de93edd8..0000000000
--- a/src/mesh/mesh2_test_lib.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 2012 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-/**
- * @file mesh/mesh2_test_lib.c
- * @author Bartlomiej Polot
- * @brief library for writing MESH tests
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "mesh2_test_lib.h"
-#include "gnunet_mesh2_service.h"
-
-/**
- * Test context for a MESH Test.
- */
-struct GNUNET_MESH_TEST_Context
-{
- /**
- * Array of running peers.
- */
- struct GNUNET_TESTBED_Peer **peers;
-
- /**
- * Array of handles to the MESH for each peer.
- */
- struct GNUNET_MESH_Handle **meshes;
-
- /**
- * Operation associated with the connection to the MESH.
- */
- struct GNUNET_TESTBED_Operation **ops;
-
- /**
- * Main function of the test to run once all MESHs are available.
- */
- GNUNET_MESH_TEST_AppMain app_main;
-
- /**
- * Closure for 'app_main'.
- */
- void *app_main_cls;
-
- /**
- * Number of peers running, size of the arrays above.
- */
- unsigned int num_peers;
-
- /**
- * Handler for incoming tunnels.
- */
- GNUNET_MESH_InboundTunnelNotificationHandler *new_tunnel;
-
- /**
- * Cleaner for destroyed incoming tunnels.
- */
- GNUNET_MESH_TunnelEndHandler *cleaner;
-
- /**
- * Message handlers.
- */
- struct GNUNET_MESH_MessageHandler* handlers;
-
- /**
- * Application ports.
- */
- const uint32_t *ports;
-
-};
-
-
-/**
- * Context for a mesh adapter callback.
- */
-struct GNUNET_MESH_TEST_AdapterContext
-{
- /**
- * Peer number for the particular peer.
- */
- unsigned int peer;
-
- /**
- * General context.
- */
- struct GNUNET_MESH_TEST_Context *ctx;
-};
-
-
-/**
- * Adapter function called to establish a connection to
- * the MESH service.
- *
- * @param cls closure
- * @param cfg configuration of the peer to connect to; will be available until
- * GNUNET_TESTBED_operation_done() is called on the operation returned
- * from GNUNET_TESTBED_service_connect()
- * @return service handle to return in 'op_result', NULL on error
- */
-static void *
-mesh_connect_adapter (void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- struct GNUNET_MESH_TEST_AdapterContext *actx = cls;
- struct GNUNET_MESH_TEST_Context *ctx = actx->ctx;
- struct GNUNET_MESH_Handle *h;
-
- h = GNUNET_MESH_connect (cfg,
- (void *) (long) actx->peer,
- ctx->new_tunnel,
- ctx->cleaner,
- ctx->handlers,
- ctx->ports);
- return h;
-}
-
-
-/**
- * Adapter function called to destroy a connection to
- * the MESH service.
- *
- * @param cls closure
- * @param op_result service handle returned from the connect adapter
- */
-static void
-mesh_disconnect_adapter (void *cls,
- void *op_result)
-{
- struct GNUNET_MESH_Handle *mesh = op_result;
- struct GNUNET_MESH_TEST_AdapterContext *actx = cls;
-
- GNUNET_free (actx);
- GNUNET_MESH_disconnect (mesh);
-}
-
-
-/**
- * Callback to be called when a service connect operation is completed.
- *
- * @param cls The callback closure from functions generating an operation.
- * @param op The operation that has been finished.
- * @param ca_result The service handle returned from
- * GNUNET_TESTBED_ConnectAdapter() (mesh handle).
- * @param emsg Error message in case the operation has failed.
- * NULL if operation has executed successfully.
- */
-static void
-mesh_connect_cb (void *cls,
- struct GNUNET_TESTBED_Operation *op,
- void *ca_result,
- const char *emsg)
-{
- struct GNUNET_MESH_TEST_Context *ctx = cls;
- unsigned int i;
-
- if (NULL != emsg)
- {
- fprintf (stderr, "Failed to connect to MESH service: %s\n",
- emsg);
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- for (i = 0; i < ctx->num_peers; i++)
- if (op == ctx->ops[i])
- ctx->meshes[i] = ca_result;
- for (i = 0; i < ctx->num_peers; i++)
- if (NULL == ctx->meshes[i])
- return; /* still some MESH connections missing */
- /* all MESH connections ready! */
- ctx->app_main (ctx->app_main_cls,
- ctx,
- ctx->num_peers,
- ctx->peers,
- ctx->meshes);
-}
-
-
-void
-GNUNET_MESH_TEST_cleanup (struct GNUNET_MESH_TEST_Context *ctx)
-{
- unsigned int i;
-
- for (i = 0; i < ctx->num_peers; i++)
- {
- GNUNET_assert (NULL != ctx->ops[i]);
- GNUNET_TESTBED_operation_done (ctx->ops[i]);
- ctx->ops[i] = NULL;
- }
- GNUNET_free (ctx->ops);
- GNUNET_free (ctx->meshes);
- GNUNET_free (ctx);
- GNUNET_SCHEDULER_shutdown ();
-}
-
-
-/**
- * Callback run when the testbed is ready (peers running and connected to
- * each other)
- *
- * @param cls Closure (context).
- * @param num_peers Number of peers that are running.
- * @param peers Handles to each one of the @c num_peers peers.
- * @param links_succeeded the number of overlay link connection attempts that
- * succeeded
- * @param links_failed the number of overlay link connection attempts that
- * failed
- */
-static void
-mesh_test_run (void *cls,
- unsigned int num_peers,
- struct GNUNET_TESTBED_Peer **peers,
- unsigned int links_succeeded,
- unsigned int links_failed)
-{
- struct GNUNET_MESH_TEST_Context *ctx = cls;
- unsigned int i;
-
- GNUNET_assert (num_peers == ctx->num_peers);
- ctx->peers = peers;
- for (i = 0; i < num_peers; i++)
- {
- struct GNUNET_MESH_TEST_AdapterContext *newctx;
- newctx = GNUNET_malloc (sizeof (struct GNUNET_MESH_TEST_AdapterContext));
- newctx->peer = i;
- newctx->ctx = ctx;
- ctx->ops[i] = GNUNET_TESTBED_service_connect (ctx,
- peers[i],
- "mesh",
- &mesh_connect_cb,
- ctx,
- &mesh_connect_adapter,
- &mesh_disconnect_adapter,
- newctx);
- }
-}
-
-
-void
-GNUNET_MESH_TEST_run (const char *testname,
- const char *cfgname,
- unsigned int num_peers,
- GNUNET_MESH_TEST_AppMain tmain,
- void *tmain_cls,
- GNUNET_MESH_InboundTunnelNotificationHandler new_tunnel,
- GNUNET_MESH_TunnelEndHandler cleaner,
- struct GNUNET_MESH_MessageHandler* handlers,
- const uint32_t *ports)
-{
- struct GNUNET_MESH_TEST_Context *ctx;
-
- ctx = GNUNET_malloc (sizeof (struct GNUNET_MESH_TEST_Context));
- ctx->num_peers = num_peers;
- ctx->ops = GNUNET_malloc (num_peers * sizeof (struct GNUNET_TESTBED_Operation *));
- ctx->meshes = GNUNET_malloc (num_peers * sizeof (struct GNUNET_MESH_Handle *));
- ctx->app_main = tmain;
- ctx->app_main_cls = tmain_cls;
- ctx->new_tunnel = new_tunnel;
- ctx->cleaner = cleaner;
- ctx->handlers = handlers;
- ctx->ports = ports;
- GNUNET_TESTBED_test_run (testname,
- cfgname,
- num_peers,
- 0LL, NULL, NULL,
- &mesh_test_run, ctx);
-}
-
-/* end of mesh_test_lib.c */
diff --git a/src/mesh/mesh2_test_lib.h b/src/mesh/mesh2_test_lib.h
deleted file mode 100644
index 096c0ebc1c..0000000000
--- a/src/mesh/mesh2_test_lib.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 2012 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-/**
- * @file mesh/mesh2_test_lib.h
- * @author Bartlomiej Polot
- * @brief library for writing MESH tests
- */
-#ifndef MESH_TEST_LIB_H
-#define MESH_TEST_LIB_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0 /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-#include "gnunet_testbed_service.h"
-#include "gnunet_mesh2_service.h"
-
-/**
- * Test context for a MESH Test.
- */
-struct GNUNET_MESH_TEST_Context;
-
-
-/**
- * Main function of a MESH test.
- *
- * @param cls Closure.
- * @param ctx Argument to give to GNUNET_MESH_TEST_cleanup on test end.
- * @param num_peers Number of peers that are running.
- * @param peers Array of peers.
- * @param meshes Handle to each of the MESHs of the peers.
- */
-typedef void (*GNUNET_MESH_TEST_AppMain) (void *cls,
- struct GNUNET_MESH_TEST_Context *ctx,
- unsigned int num_peers,
- struct GNUNET_TESTBED_Peer **peers,
- struct GNUNET_MESH_Handle **meshes);
-
-
-/**
- * Run a test using the given name, configuration file and number of
- * peers.
- * All mesh callbacks will receive the peer number as the closure.
- *
- * @param testname Name of the test (for logging).
- * @param cfgname Name of the configuration file.
- * @param num_peers Number of peers to start.
- * @param tmain Main function to run once the testbed is ready.
- * @param tmain_cls Closure for 'tmain'.
- * @param new_tunnel Handler for incoming tunnels.
- * @param cleaner Cleaner for destroyed incoming tunnels.
- * @param handlers Message handlers.
- * @param ports Ports the peers offer.
- */
-void
-GNUNET_MESH_TEST_run (const char *testname,
- const char *cfgname,
- unsigned int num_peers,
- GNUNET_MESH_TEST_AppMain tmain,
- void *tmain_cls,
- GNUNET_MESH_InboundTunnelNotificationHandler new_tunnel,
- GNUNET_MESH_TunnelEndHandler cleaner,
- struct GNUNET_MESH_MessageHandler* handlers,
- const uint32_t* ports);
-
-
-/**
- * Clean up the testbed.
- *
- * @param ctx handle for the testbed
- */
-void
-GNUNET_MESH_TEST_cleanup (struct GNUNET_MESH_TEST_Context *ctx);
-
-
-#if 0 /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-
-/* ifndef MESH_TEST_LIB_H */
-#endif
diff --git a/src/mesh/mesh_api.c b/src/mesh/mesh_api.c
index 8683d7f247..189580e505 100644
--- a/src/mesh/mesh_api.c
+++ b/src/mesh/mesh_api.c
@@ -17,7 +17,7 @@
/**
* @file mesh/mesh_api.c
- * @brief mesh api: client implementation of mesh service
+ * @brief mesh api: client implementation of new mesh service
* @author Bartlomiej Polot
*
* STRUCTURE:
@@ -40,7 +40,6 @@
#include "mesh_protocol.h"
#define LOG(kind,...) GNUNET_log_from (kind, "mesh-api",__VA_ARGS__)
-
#define DEBUG_ACK GNUNET_YES
/******************************************************************************/
@@ -95,12 +94,6 @@ struct GNUNET_MESH_TransmitHandle
GNUNET_SCHEDULER_TaskIdentifier timeout_task;
/**
- * Target of the message, 0 for multicast. This field
- * is only valid if 'notify' is non-NULL.
- */
- GNUNET_PEER_Id target;
-
- /**
* Size of 'data' -- or the desired size of 'notify' if 'data' is NULL.
*/
size_t size;
@@ -123,13 +116,20 @@ struct GNUNET_MESH_Handle
*/
const struct GNUNET_MESH_MessageHandler *message_handlers;
- /**
- * Set of applications that should be claimed to be offered at this node.
- * Note that this is just informative, the appropiate handlers must be
- * registered independently and the mapping is up to the developer of the
- * client application.
- */
- GNUNET_MESH_ApplicationType *applications;
+ /**
+ * Number of handlers in the handlers array.
+ */
+ unsigned int n_handlers;
+
+ /**
+ * Ports open.
+ */
+ const uint32_t *ports;
+
+ /**
+ * Number of ports.
+ */
+ unsigned int n_ports;
/**
* Double linked list of the tunnels this client is connected to, head.
@@ -177,16 +177,6 @@ struct GNUNET_MESH_Handle
MESH_TunnelNumber next_tid;
/**
- * Number of handlers in the handlers array.
- */
- unsigned int n_handlers;
-
- /**
- * Number of applications in the applications array.
- */
- unsigned int n_applications;
-
- /**
* Have we started the task to receive messages from the service
* yet? We do this after we send the 'MESH_LOCAL_CONNECT' message.
*/
@@ -227,16 +217,6 @@ struct GNUNET_MESH_Handle
*/
void *tunnel_cls;
- /**
- * All the peer in the tunnel so far.
- */
- struct GNUNET_PeerIdentity *peers;
-
- /**
- * How many peers we have in this tunnel so far.
- */
- unsigned int tunnel_npeers;
-
#if DEBUG_ACK
unsigned int acks_sent;
unsigned int acks_recv;
@@ -284,21 +264,6 @@ struct GNUNET_MESH_Tunnel
struct GNUNET_MESH_Tunnel *prev;
/**
- * Callback to execute when peers connect to the tunnel
- */
- GNUNET_MESH_PeerConnectHandler connect_handler;
-
- /**
- * Callback to execute when peers disconnect from the tunnel
- */
- GNUNET_MESH_PeerDisconnectHandler disconnect_handler;
-
- /**
- * Closure for the connect/disconnect handlers
- */
- void *cls;
-
- /**
* Handle to the mesh this tunnel belongs to
*/
struct GNUNET_MESH_Handle *mesh;
@@ -309,69 +274,67 @@ struct GNUNET_MESH_Tunnel
MESH_TunnelNumber tid;
/**
- * Owner of the tunnel. 0 if the tunnel is the local client.
+ * Port number.
*/
- GNUNET_PEER_Id owner;
+ uint32_t port;
/**
- * All peers added to the tunnel
+ * Other end of the tunnel.
*/
- struct GNUNET_MESH_Peer **peers;
-
- /**
- * List of application types that have been requested for this tunnel
- */
- GNUNET_MESH_ApplicationType *apps;
+ GNUNET_PEER_Id peer;
/**
* Any data the caller wants to put in here
*/
void *ctx;
- /**
- * Number of peers added to the tunnel
- */
- unsigned int npeers;
-
/**
* Size of packet queued in this tunnel
*/
unsigned int packet_size;
/**
- * Number of applications requested this tunnel
- */
- unsigned int napps;
-
- /**
- * Is the tunnel throttled to the slowest peer?
- */
- int speed_min;
-
- /**
* Is the tunnel allowed to buffer?
*/
int buffering;
/**
- * Next packet ID to send.
+ * Maximum allowed PID to send (last ACK recevied).
*/
- uint32_t next_send_pid;
+ uint32_t last_ack_recv;
/**
- * Maximum allowed PID to send (ACK recevied).
+ * Last PID received from the service.
*/
- uint32_t max_send_pid;
+ uint32_t last_pid_recv;
+
+ /**
+ * Last packet ID sent to the service.
+ */
+ uint32_t last_pid_sent;
+
+ /**
+ * Last ACK value sent to the service: how much are we willing to accept?
+ */
+ uint32_t last_ack_sent;
+};
- /**
- * Last pid received from the service.
- */
- uint32_t last_recv_pid;
+
+/**
+ * Implementation state for mesh's message queue.
+ */
+struct MeshMQState
+{
+ /**
+ * The current transmit handle, or NULL
+ * if no transmit is active.
+ */
+ struct GNUNET_MESH_TransmitHandle *th;
/**
- * Which ACK value have we last sent to the service?
+ * Tunnel to send the data over.
*/
- uint32_t max_recv_pid;
+ struct GNUNET_MESH_Tunnel *tunnel;
};
@@ -431,13 +394,13 @@ message_ready_size (struct GNUNET_MESH_Handle *h)
t = th->tunnel;
if (GNUNET_NO == th_is_payload (th))
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, " message internal\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "# message internal\n");
return th->size;
}
- if (GNUNET_NO == GMC_is_pid_bigger(t->next_send_pid, t->max_send_pid))
+ if (GNUNET_YES == GMC_is_pid_bigger(t->last_ack_recv, t->last_pid_sent))
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, " message payload ok (%u <= %u)\n",
- t->next_send_pid, t->max_send_pid);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "# message payload ok (%u =< %u)\n",
+ t->last_pid_sent + 1, t->last_ack_recv);
return th->size;
}
}
@@ -495,8 +458,10 @@ create_tunnel (struct GNUNET_MESH_Handle *h, MESH_TunnelNumber tid)
{
t->tid = tid;
}
- t->max_send_pid = INITIAL_WINDOW_SIZE - 1;
- t->last_recv_pid = (uint32_t) -1;
+ t->last_ack_recv = (uint32_t) -1;
+ t->last_pid_recv = (uint32_t) -1;
+ t->last_ack_sent = (uint32_t) -1;
+ t->last_pid_sent = (uint32_t) -1;
t->buffering = GNUNET_YES;
return t;
}
@@ -518,10 +483,8 @@ static void
destroy_tunnel (struct GNUNET_MESH_Tunnel *t, int call_cleaner)
{
struct GNUNET_MESH_Handle *h;
- struct GNUNET_PeerIdentity pi;
struct GNUNET_MESH_TransmitHandle *th;
struct GNUNET_MESH_TransmitHandle *next;
- unsigned int i;
LOG (GNUNET_ERROR_TYPE_DEBUG, "destroy_tunnel %X\n", t->tid);
@@ -532,21 +495,10 @@ destroy_tunnel (struct GNUNET_MESH_Tunnel *t, int call_cleaner)
}
h = t->mesh;
- /* disconnect all peers */
GNUNET_CONTAINER_DLL_remove (h->tunnels_head, h->tunnels_tail, t);
- for (i = 0; i < t->npeers; i++)
- {
- if ( (NULL != t->disconnect_handler) && t->peers[i]->connected)
- {
- GNUNET_PEER_resolve (t->peers[i]->id, &pi);
- t->disconnect_handler (t->cls, &pi);
- }
- GNUNET_PEER_change_rc (t->peers[i]->id, -1);
- GNUNET_free (t->peers[i]);
- }
/* signal tunnel destruction */
- if ( (NULL != h->cleaner) && (0 != t->owner) && (GNUNET_YES == call_cleaner) )
+ if ( (NULL != h->cleaner) && (0 != t->peer) && (GNUNET_YES == call_cleaner) )
h->cleaner (h->cls, t, t->ctx);
/* check that clients did not leave messages behind in the queue */
@@ -574,89 +526,14 @@ destroy_tunnel (struct GNUNET_MESH_Tunnel *t, int call_cleaner)
h->th = NULL;
}
-
- if (t->npeers > 0)
- GNUNET_free (t->peers);
- if (0 != t->owner)
- GNUNET_PEER_change_rc (t->owner, -1);
- if (0 != t->napps && t->apps)
- GNUNET_free (t->apps);
+ if (0 != t->peer)
+ GNUNET_PEER_change_rc (t->peer, -1);
GNUNET_free (t);
return;
}
/**
- * Get the peer descriptor for the peer with id from the given tunnel
- * @param t Tunnel handle
- * @param id Short form ID of the wanted peer
- * @return handle to the requested peer or NULL if not found
- */
-static struct GNUNET_MESH_Peer *
-retrieve_peer (struct GNUNET_MESH_Tunnel *t, GNUNET_PEER_Id id)
-{
- unsigned int i;
-
- for (i = 0; i < t->npeers; i++)
- if (t->peers[i]->id == id)
- return t->peers[i];
- return NULL;
-}
-
-
-/**
- * Add a peer into a tunnel
- * @param t Tunnel handle
- * @param pi Full ID of the new peer
- * @return handle to the newly created peer
- */
-static struct GNUNET_MESH_Peer *
-add_peer_to_tunnel (struct GNUNET_MESH_Tunnel *t,
- const struct GNUNET_PeerIdentity *pi)
-{
- struct GNUNET_MESH_Peer *p;
- GNUNET_PEER_Id id;
-
- if (0 != t->owner)
- {
- GNUNET_break (0);
- return NULL;
- }
- id = GNUNET_PEER_intern (pi);
-
- p = GNUNET_malloc (sizeof (struct GNUNET_MESH_Peer));
- p->id = id;
- p->t = t;
- GNUNET_array_append (t->peers, t->npeers, p);
- return p;
-}
-
-
-/**
- * Remove a peer from a tunnel
- * @param p Peer handle
- */
-static void
-remove_peer_from_tunnel (struct GNUNET_MESH_Peer *p)
-{
- unsigned int i;
-
- for (i = 0; i < p->t->npeers; i++)
- {
- if (p->t->peers[i] == p)
- break;
- }
- if (i == p->t->npeers)
- {
- GNUNET_break (0);
- return;
- }
- p->t->peers[i] = p->t->peers[p->t->npeers - 1];
- GNUNET_array_grow (p->t->peers, p->t->npeers, p->t->npeers - 1);
-}
-
-
-/**
* Notify client that the transmission has timed out
*
* @param cls closure
@@ -725,36 +602,24 @@ send_packet (struct GNUNET_MESH_Handle *h,
* @param t Tunnel on which to send the ACK.
*/
static void
-send_ack (struct GNUNET_MESH_Handle *h, struct GNUNET_MESH_Tunnel *t)
+send_ack (struct GNUNET_MESH_Tunnel *t)
{
struct GNUNET_MESH_LocalAck msg;
- uint32_t delta;
- delta = t->max_recv_pid - t->last_recv_pid;
- if (delta > ACK_THRESHOLD)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Not sending ACK on tunnel %X: ACK: %u, PID: %u, buffer %u\n",
- t->tid, t->max_recv_pid, t->last_recv_pid, delta);
- return;
- }
- if (GNUNET_YES == t->buffering)
- t->max_recv_pid = t->last_recv_pid + INITIAL_WINDOW_SIZE;
- else
- t->max_recv_pid = t->last_recv_pid + 1;
+ t->last_ack_sent = t->last_pid_recv + 1;
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Sending ACK on tunnel %X: %u\n",
- t->tid, t->max_recv_pid);
+ t->tid, t->last_ack_sent);
msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK);
msg.header.size = htons (sizeof (msg));
msg.tunnel_id = htonl (t->tid);
- msg.max_pid = htonl (t->max_recv_pid);
+ msg.ack = htonl (t->last_ack_sent);
#if DEBUG_ACK
t->mesh->acks_sent++;
#endif
- send_packet (h, &msg.header, t);
+ send_packet (t->mesh, &msg.header, t);
return;
}
@@ -783,39 +648,27 @@ send_connect (struct GNUNET_MESH_Handle *h)
size_t size;
size = sizeof (struct GNUNET_MESH_ClientConnect);
- size += h->n_applications * sizeof (GNUNET_MESH_ApplicationType);
- size += h->n_handlers * sizeof (uint16_t);
+ size += h->n_ports * sizeof (uint32_t);
{
char buf[size] GNUNET_ALIGN;
struct GNUNET_MESH_ClientConnect *msg;
- GNUNET_MESH_ApplicationType *apps;
- uint16_t napps;
- uint16_t *types;
- uint16_t ntypes;
+ uint32_t *ports;
+ uint16_t i;
/* build connection packet */
msg = (struct GNUNET_MESH_ClientConnect *) buf;
msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT);
msg->header.size = htons (size);
- apps = (GNUNET_MESH_ApplicationType *) &msg[1];
- for (napps = 0; napps < h->n_applications; napps++)
- {
- apps[napps] = htonl (h->applications[napps]);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " app %u\n",
- h->applications[napps]);
- }
- types = (uint16_t *) & apps[napps];
- for (ntypes = 0; ntypes < h->n_handlers; ntypes++)
+ ports = (uint32_t *) &msg[1];
+ for (i = 0; i < h->n_ports; i++)
{
- types[ntypes] = htons (h->message_handlers[ntypes].type);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " type %u\n",
- h->message_handlers[ntypes].type);
+ ports[i] = htonl (h->ports[i]);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " port %u\n",
+ h->ports[i]);
}
- msg->applications = htons (napps);
- msg->types = htons (ntypes);
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Sending %lu bytes long message %d types and %d apps\n",
- ntohs (msg->header.size), ntypes, napps);
+ "Sending %lu bytes long message with %u ports\n",
+ ntohs (msg->header.size), h->n_ports);
send_packet (h, &msg->header, NULL);
}
}
@@ -833,7 +686,6 @@ static int
do_reconnect (struct GNUNET_MESH_Handle *h)
{
struct GNUNET_MESH_Tunnel *t;
- unsigned int i;
LOG (GNUNET_ERROR_TYPE_DEBUG, "*****************************\n");
LOG (GNUNET_ERROR_TYPE_DEBUG, "******* RECONNECT *******\n");
@@ -878,7 +730,6 @@ do_reconnect (struct GNUNET_MESH_Handle *h)
for (t = h->tunnels_head; NULL != t; t = t->next)
{
struct GNUNET_MESH_TunnelMessage tmsg;
- struct GNUNET_MESH_PeerControl pmsg;
if (t->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
{
@@ -888,42 +739,18 @@ do_reconnect (struct GNUNET_MESH_Handle *h)
*/
continue;
}
- t->next_send_pid = 0;
- t->max_send_pid = INITIAL_WINDOW_SIZE - 1;
- t->last_recv_pid = (uint32_t) -1;
+ t->last_ack_sent = (uint32_t) -1;
+ t->last_pid_sent = (uint32_t) -1;
+ t->last_ack_recv = (uint32_t) -1;
+ t->last_pid_recv = (uint32_t) -1;
tmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
tmsg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
tmsg.tunnel_id = htonl (t->tid);
+ GNUNET_PEER_resolve (t->peer, &tmsg.peer);
send_packet (h, &tmsg.header, t);
- pmsg.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
- pmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD);
- pmsg.tunnel_id = htonl (t->tid);
-
- /* Reconnect all peers */
- /* If the tunnel was "by type", dont connect individual peers */
- for (i = 0; i < t->npeers && 0 == t->napps; i++)
- {
- GNUNET_PEER_resolve (t->peers[i]->id, &pmsg.peer);
- if (NULL != t->disconnect_handler && t->peers[i]->connected)
- t->disconnect_handler (t->cls, &pmsg.peer);
- send_packet (t->mesh, &pmsg.header, t);
- }
- /* Reconnect all types, if any */
- for (i = 0; i < t->napps; i++)
- {
- struct GNUNET_MESH_ConnectPeerByType msg;
-
- msg.header.size = htons (sizeof (struct GNUNET_MESH_ConnectPeerByType));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD_BY_TYPE);
- msg.tunnel_id = htonl (t->tid);
- msg.type = htonl (t->apps[i]);
- send_packet (t->mesh, &msg.header, t);
- }
if (GNUNET_NO == t->buffering)
GNUNET_MESH_tunnel_buffer (t, GNUNET_NO);
- if (GNUNET_YES == t->speed_min)
- GNUNET_MESH_tunnel_speed_min (t);
}
return GNUNET_YES;
}
@@ -991,29 +818,18 @@ process_tunnel_created (struct GNUNET_MESH_Handle *h,
}
if (NULL != h->new_tunnel)
{
- struct GNUNET_ATS_Information atsi;
-
t = create_tunnel (h, tid);
- t->owner = GNUNET_PEER_intern (&msg->peer);
- t->npeers = 1;
- t->peers = GNUNET_malloc (sizeof (struct GNUNET_MESH_Peer *));
- t->peers[0] = GNUNET_malloc (sizeof (struct GNUNET_MESH_Peer));
- t->peers[0]->t = t;
- t->peers[0]->connected = 1;
- t->peers[0]->id = t->owner;
- GNUNET_PEER_change_rc (t->owner, 1);
+ t->last_ack_sent = 0;
+ t->peer = GNUNET_PEER_intern (&msg->peer);
t->mesh = h;
t->tid = tid;
- if ((msg->opt & MESH_TUNNEL_OPT_NOBUFFER) != 0)
+ t->port = ntohl (msg->port);
+ if (0 != (msg->opt & MESH_TUNNEL_OPT_NOBUFFER))
t->buffering = GNUNET_NO;
else
t->buffering = GNUNET_YES;
- if ((msg->opt & MESH_TUNNEL_OPT_SPEED_MIN) != 0)
- t->speed_min = GNUNET_YES;
- atsi.type = 0;
- atsi.value = 0;
LOG (GNUNET_ERROR_TYPE_DEBUG, " created tunnel %p\n", t);
- t->ctx = h->new_tunnel (h->cls, t, &msg->peer, &atsi);
+ t->ctx = h->new_tunnel (h->cls, t, &msg->peer, t->port);
LOG (GNUNET_ERROR_TYPE_DEBUG, "User notified\n");
}
else
@@ -1052,10 +868,6 @@ process_tunnel_destroy (struct GNUNET_MESH_Handle *h,
{
return;
}
- if (0 == t->owner)
- {
- GNUNET_break (0);
- }
LOG (GNUNET_ERROR_TYPE_DEBUG, "tunnel %X destroyed\n", t->tid);
destroy_tunnel (t, GNUNET_YES);
return;
@@ -1063,81 +875,20 @@ process_tunnel_destroy (struct GNUNET_MESH_Handle *h,
/**
- * Process the new peer event and notify the upper level of it
- *
- * @param h The mesh handle
- * @param msg A message with the details of the peer event
- */
-static void
-process_peer_event (struct GNUNET_MESH_Handle *h,
- const struct GNUNET_MESH_PeerControl *msg)
-{
- struct GNUNET_MESH_Tunnel *t;
- struct GNUNET_MESH_Peer *p;
- struct GNUNET_ATS_Information atsi;
- GNUNET_PEER_Id id;
- uint16_t size;
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "processig peer event\n");
- size = ntohs (msg->header.size);
- if (size != sizeof (struct GNUNET_MESH_PeerControl))
- {
- GNUNET_break (0);
- return;
- }
- t = retrieve_tunnel (h, ntohl (msg->tunnel_id));
- if (NULL == t)
- {
- GNUNET_break (0);
- return;
- }
- id = GNUNET_PEER_search (&msg->peer);
- if ((p = retrieve_peer (t, id)) == NULL)
- p = add_peer_to_tunnel (t, &msg->peer);
- if (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD == ntohs (msg->header.type))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "adding peer\n");
- if (NULL != t->connect_handler)
- {
- atsi.type = 0;
- atsi.value = 0;
- t->connect_handler (t->cls, &msg->peer, &atsi);
- }
- p->connected = 1;
- }
- else
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "removing peer\n");
- if (NULL != t->disconnect_handler && p->connected)
- {
- t->disconnect_handler (t->cls, &msg->peer);
- }
- remove_peer_from_tunnel (p);
- GNUNET_free (p);
- }
- LOG (GNUNET_ERROR_TYPE_DEBUG, "processing peer event END\n");
-}
-
-
-/**
- * Process the incoming data packets
+ * Process the incoming data packets, call appropriate handlers.
*
* @param h The mesh handle
* @param message A message encapsulating the data
- *
- * @return GNUNET_YES if everything went fine
- * GNUNET_NO if client closed connection (h no longer valid)
*/
-static int
+static void
process_incoming_data (struct GNUNET_MESH_Handle *h,
const struct GNUNET_MessageHeader *message)
{
const struct GNUNET_MessageHeader *payload;
const struct GNUNET_MESH_MessageHandler *handler;
const struct GNUNET_PeerIdentity *peer;
- struct GNUNET_MESH_Unicast *ucast;
- struct GNUNET_MESH_Multicast *mcast;
- struct GNUNET_MESH_ToOrigin *to_orig;
+ struct GNUNET_PeerIdentity id;
+ struct GNUNET_MESH_Data *dmsg;
struct GNUNET_MESH_Tunnel *t;
unsigned int i;
uint32_t pid;
@@ -1148,72 +899,52 @@ process_incoming_data (struct GNUNET_MESH_Handle *h,
switch (type)
{
case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
- ucast = (struct GNUNET_MESH_Unicast *) message;
-
- t = retrieve_tunnel (h, ntohl (ucast->tid));
- payload = (struct GNUNET_MessageHeader *) &ucast[1];
- peer = &ucast->oid;
- pid = ntohl (ucast->pid);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " ucast on tunnel %s [%X]\n",
- GNUNET_i2s (peer), ntohl (ucast->tid));
- break;
- case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
- mcast = (struct GNUNET_MESH_Multicast *) message;
- t = retrieve_tunnel (h, ntohl (mcast->tid));
- payload = (struct GNUNET_MessageHeader *) &mcast[1];
- peer = &mcast->oid;
- pid = ntohl (mcast->pid);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " mcast on tunnel %s [%X]\n",
- GNUNET_i2s (peer), ntohl (mcast->tid));
- break;
case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- to_orig = (struct GNUNET_MESH_ToOrigin *) message;
- t = retrieve_tunnel (h, ntohl (to_orig->tid));
- payload = (struct GNUNET_MessageHeader *) &to_orig[1];
- peer = &to_orig->sender;
- pid = ntohl (to_orig->pid);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " torig on tunnel %s [%X]\n",
- GNUNET_i2s (peer), ntohl (to_orig->tid));
+ dmsg = (struct GNUNET_MESH_Data *) message;
+
+ t = retrieve_tunnel (h, ntohl (dmsg->tid));
+ payload = (struct GNUNET_MessageHeader *) &dmsg[1];
+ GNUNET_PEER_resolve (t->peer, &id);
+ peer = &id;
+ pid = ntohl (dmsg->pid);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " %s data on tunnel %s [%X]\n",
+ type == GNUNET_MESSAGE_TYPE_MESH_UNICAST ? "fwd" : "bck",
+ GNUNET_i2s (peer), ntohl (dmsg->tid));
break;
default:
GNUNET_break (0);
- return GNUNET_YES;
+ return;
}
LOG (GNUNET_ERROR_TYPE_DEBUG, " pid %u\n", pid);
if (NULL == t)
{
/* Tunnel was ignored/destroyed, probably service didn't get it yet */
LOG (GNUNET_ERROR_TYPE_DEBUG, " ignored!\n");
- return GNUNET_YES;
+ return;
}
if (GNUNET_YES ==
- GMC_is_pid_bigger(pid, t->max_recv_pid))
+ GMC_is_pid_bigger(pid, t->last_ack_sent))
{
GNUNET_break (0);
LOG (GNUNET_ERROR_TYPE_WARNING,
- " unauthorized message! (%u, max %u)\n",
- pid, t->max_recv_pid);
+ " unauthorized message! (%u, ACK %u)\n",
+ pid, t->last_ack_sent);
// FIXME fc what now? accept? reject?
- return GNUNET_YES;
+ return;
}
- t->last_recv_pid = pid;
+ t->last_pid_recv = pid;
type = ntohs (payload->type);
- send_ack (h, t);
for (i = 0; i < h->n_handlers; i++)
{
handler = &h->message_handlers[i];
if (handler->type == type)
{
- struct GNUNET_ATS_Information atsi;
-
- atsi.type = 0;
- atsi.value = 0;
if (GNUNET_OK !=
- handler->callback (h->cls, t, &t->ctx, peer, payload, &atsi))
+ handler->callback (h->cls, t, &t->ctx, payload))
{
LOG (GNUNET_ERROR_TYPE_DEBUG, "callback caused disconnection\n");
- GNUNET_MESH_disconnect (h);
- return GNUNET_NO;
+ GNUNET_MESH_tunnel_destroy (t);
+ return;
}
else
{
@@ -1222,7 +953,6 @@ process_incoming_data (struct GNUNET_MESH_Handle *h,
}
}
}
- return GNUNET_YES;
}
@@ -1254,10 +984,10 @@ process_ack (struct GNUNET_MESH_Handle *h,
ntohl (msg->tunnel_id));
return;
}
- ack = ntohl (msg->max_pid);
+ ack = ntohl (msg->ack);
LOG (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %X, ack %u!\n", t->tid, ack);
- if (GNUNET_YES == GMC_is_pid_bigger(ack, t->max_send_pid))
- t->max_send_pid = ack;
+ if (GNUNET_YES == GMC_is_pid_bigger(ack, t->last_ack_recv))
+ t->last_ack_recv = ack;
else
return;
if (NULL == h->th && 0 < t->packet_size)
@@ -1282,7 +1012,6 @@ process_get_tunnels (struct GNUNET_MESH_Handle *h,
const struct GNUNET_MessageHeader *message)
{
struct GNUNET_MESH_LocalMonitor *msg;
- uint32_t npeers;
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Get Tunnels messasge received\n");
@@ -1293,25 +1022,21 @@ process_get_tunnels (struct GNUNET_MESH_Handle *h,
}
msg = (struct GNUNET_MESH_LocalMonitor *) message;
- npeers = ntohl (msg->npeers);
if (ntohs (message->size) !=
(sizeof (struct GNUNET_MESH_LocalMonitor) +
- npeers * sizeof (struct GNUNET_PeerIdentity)))
+ sizeof (struct GNUNET_PeerIdentity)))
{
GNUNET_break_op (0);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Get tunnels message: size %hu - expected %u (%u peers)\n",
+ "Get tunnels message: size %hu - expected %u\n",
ntohs (message->size),
- sizeof (struct GNUNET_MESH_LocalMonitor) +
- npeers * sizeof (struct GNUNET_PeerIdentity),
- npeers);
+ sizeof (struct GNUNET_MESH_LocalMonitor));
return;
}
h->tunnels_cb (h->tunnels_cls,
- &msg->owner,
ntohl (msg->tunnel_id),
- (struct GNUNET_PeerIdentity *) &msg[1],
- npeers);
+ &msg->owner,
+ &msg->destination);
}
@@ -1327,11 +1052,7 @@ process_show_tunnel (struct GNUNET_MESH_Handle *h,
const struct GNUNET_MessageHeader *message)
{
struct GNUNET_MESH_LocalMonitor *msg;
- struct GNUNET_PeerIdentity *new_peers;
- uint32_t *new_parents;
size_t esize;
- uint32_t npeers;
- unsigned int i;
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Show Tunnel messasge received\n");
@@ -1343,40 +1064,25 @@ process_show_tunnel (struct GNUNET_MESH_Handle *h,
/* Verify message sanity */
msg = (struct GNUNET_MESH_LocalMonitor *) message;
- npeers = ntohl (msg->npeers);
esize = sizeof (struct GNUNET_MESH_LocalMonitor);
- esize += npeers * (sizeof (struct GNUNET_PeerIdentity) + sizeof (uint32_t));
if (ntohs (message->size) != esize)
{
GNUNET_break_op (0);
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Show tunnel message: size %hu - expected %u (%u peers)\n",
+ "Show tunnel message: size %hu - expected %u\n",
ntohs (message->size),
- esize,
- npeers);
+ esize);
h->tunnel_cb (h->tunnel_cls, NULL, NULL);
h->tunnel_cb = NULL;
h->tunnel_cls = NULL;
- h->tunnel_npeers = 0;
- GNUNET_free_non_null (h->peers);
- h->peers = NULL;
return;
}
- new_peers = (struct GNUNET_PeerIdentity *) &msg[1];
- new_parents = (uint32_t *) &new_peers[npeers];
-
- h->peers = GNUNET_realloc (h->peers, h->tunnel_npeers + npeers);
- memcpy (&h->peers[h->tunnel_npeers],
- new_peers,
- npeers * sizeof (struct GNUNET_PeerIdentity));
- h->tunnel_npeers += npeers;
- for (i = 0; i < npeers; i++)
- h->tunnel_cb (h->tunnel_cls,
- &new_peers[i],
- &h->peers[new_parents[i]]);
+ h->tunnel_cb (h->tunnel_cls,
+ &msg->destination,
+ &msg->owner);
}
@@ -1412,17 +1118,11 @@ msg_received (void *cls, const struct GNUNET_MessageHeader *msg)
case GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY:
process_tunnel_destroy (h, (struct GNUNET_MESH_TunnelMessage *) msg);
break;
- /* Notify of a new peer or a peer disconnect in the tunnel */
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD:
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL:
- process_peer_event (h, (struct GNUNET_MESH_PeerControl *) msg);
- break;
/* Notify of a new data packet in the tunnel */
case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
- if (GNUNET_NO == process_incoming_data (h, msg))
- return;
+ process_incoming_data (h, msg);
break;
case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
process_ack (h, msg);
@@ -1480,10 +1180,10 @@ send_callback (void *cls, size_t size, void *buf)
size_t nsize;
LOG (GNUNET_ERROR_TYPE_DEBUG, "\n");
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Send packet() Buffer %u\n", size);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "# Send packet() Buffer %u\n", size);
if ((0 == size) || (NULL == buf))
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Received NULL send callback on %p\n", h);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "# Received NULL send callback on %p\n", h);
reconnect (h);
h->th = NULL;
return 0;
@@ -1496,95 +1196,52 @@ send_callback (void *cls, size_t size, void *buf)
t = th->tunnel;
if (GNUNET_YES == th_is_payload (th))
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, " payload\n");
- if (GNUNET_YES == GMC_is_pid_bigger(t->next_send_pid, t->max_send_pid))
+ struct GNUNET_MESH_Data *dmsg;
+ struct GNUNET_MessageHeader *mh;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "# payload\n");
+ if (GNUNET_NO == GMC_is_pid_bigger (t->last_ack_recv, t->last_pid_sent))
{
/* This tunnel is not ready to transmit yet, try next message */
next = th->next;
continue;
}
t->packet_size = 0;
- if (t->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
+ GNUNET_assert (size >= th->size);
+ dmsg = (struct GNUNET_MESH_Data *) cbuf;
+ mh = (struct GNUNET_MessageHeader *) &dmsg[1];
+ psize = th->notify (th->notify_cls,
+ size - sizeof (struct GNUNET_MESH_Data),
+ mh);
+ if (psize > 0)
{
- /* traffic to origin */
- struct GNUNET_MESH_ToOrigin to;
- struct GNUNET_MessageHeader *mh;
-
- GNUNET_assert (size >= th->size);
- mh = (struct GNUNET_MessageHeader *) &cbuf[sizeof (to)];
- psize = th->notify (th->notify_cls, size - sizeof (to), mh);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " to origin, type %s\n",
- GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
- if (psize > 0)
- {
- psize += sizeof (to);
- GNUNET_assert (size >= psize);
- to.header.size = htons (psize);
- to.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
- to.tid = htonl (t->tid);
- to.pid = htonl (t->next_send_pid);
- to.ttl = 0;
- memset (&to.oid, 0, sizeof (struct GNUNET_PeerIdentity));
- memset (&to.sender, 0, sizeof (struct GNUNET_PeerIdentity));
- memcpy (cbuf, &to, sizeof (to));
- }
+ psize += sizeof (struct GNUNET_MESH_Data);
+ GNUNET_assert (size >= psize);
+ dmsg->header.size = htons (psize);
+ dmsg->tid = htonl (t->tid);
+ dmsg->pid = htonl (t->last_pid_sent + 1);
+ dmsg->ttl = 0;
+ memset (&dmsg->oid, 0, sizeof (struct GNUNET_PeerIdentity));
+ t->last_pid_sent++;
}
- else if (th->target == 0)
+ if (t->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
{
- /* multicast */
- struct GNUNET_MESH_Multicast mc;
- struct GNUNET_MessageHeader *mh;
-
- GNUNET_assert (size >= th->size);
- mh = (struct GNUNET_MessageHeader *) &cbuf[sizeof (mc)];
- psize = th->notify (th->notify_cls, size - sizeof (mc), mh);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " multicast, type %s\n",
+ dmsg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "# to origin, type %s\n",
GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
- if (psize > 0)
- {
- psize += sizeof (mc);
- GNUNET_assert (size >= psize);
- mc.header.size = htons (psize);
- mc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_MULTICAST);
- mc.tid = htonl (t->tid);
- mc.pid = htonl (t->next_send_pid);
- mc.ttl = 0;
- memset (&mc.oid, 0, sizeof (struct GNUNET_PeerIdentity));
- memcpy (cbuf, &mc, sizeof (mc));
- }
}
else
{
- /* unicast */
- struct GNUNET_MESH_Unicast uc;
- struct GNUNET_MessageHeader *mh;
-
- GNUNET_assert (size >= th->size);
- mh = (struct GNUNET_MessageHeader *) &cbuf[sizeof (uc)];
- psize = th->notify (th->notify_cls, size - sizeof (uc), mh);
- LOG (GNUNET_ERROR_TYPE_DEBUG, " unicast, type %s\n",
+ dmsg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_UNICAST);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "# unicast, type %s\n",
GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
- if (psize > 0)
- {
- psize += sizeof (uc);
- GNUNET_assert (size >= psize);
- uc.header.size = htons (psize);
- uc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_UNICAST);
- uc.tid = htonl (t->tid);
- uc.pid = htonl (t->next_send_pid);
- uc.ttl = 0;
- memset (&uc.oid, 0, sizeof (struct GNUNET_PeerIdentity));
- GNUNET_PEER_resolve (th->target, &uc.destination);
- memcpy (cbuf, &uc, sizeof (uc));
- }
}
- t->next_send_pid++;
}
else
{
struct GNUNET_MessageHeader *mh = (struct GNUNET_MessageHeader *) &th[1];
- LOG (GNUNET_ERROR_TYPE_DEBUG, " mesh traffic, type %s\n",
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "# mesh traffic, type %s\n",
GNUNET_MESH_DEBUG_M2S (ntohs (mh->type)));
memcpy (cbuf, &th[1], th->size);
psize = th->size;
@@ -1599,12 +1256,12 @@ send_callback (void *cls, size_t size, void *buf)
size -= psize;
tsize += psize;
}
- LOG (GNUNET_ERROR_TYPE_DEBUG, " total size: %u\n", tsize);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "# total size: %u\n", tsize);
h->th = NULL;
size = message_ready_size (h);
if (0 != size)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, " next size: %u\n", size);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "# next size: %u\n", size);
h->th =
GNUNET_CLIENT_notify_transmit_ready (h->client, size,
GNUNET_TIME_UNIT_FOREVER_REL,
@@ -1613,18 +1270,18 @@ send_callback (void *cls, size_t size, void *buf)
else
{
if (NULL != h->th_head)
- LOG (GNUNET_ERROR_TYPE_DEBUG, " can't transmit any more\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "# can't transmit any more\n");
else
- LOG (GNUNET_ERROR_TYPE_DEBUG, " nothing left to transmit\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "# nothing left to transmit\n");
}
if (GNUNET_NO == h->in_receive)
{
- LOG (GNUNET_ERROR_TYPE_DEBUG, " start receiving from service\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "# start receiving from service\n");
h->in_receive = GNUNET_YES;
GNUNET_CLIENT_receive (h->client, &msg_received, h,
GNUNET_TIME_UNIT_FOREVER_REL);
}
- LOG (GNUNET_ERROR_TYPE_DEBUG, "Send packet() END\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "# Send packet() END\n");
return tsize;
}
@@ -1670,33 +1327,14 @@ send_packet (struct GNUNET_MESH_Handle *h,
/********************** API CALL DEFINITIONS *************************/
/******************************************************************************/
-/**
- * Connect to the mesh service.
- *
- * @param cfg configuration to use
- * @param cls closure for the various callbacks that follow
- * (including handlers in the handlers array)
- * @param new_tunnel function called when an *inbound* tunnel is created
- * @param cleaner function called when an *inbound* tunnel is destroyed by the
- * remote peer, it is *not* called if GNUNET_MESH_tunnel_destroy
- * is called on the tunnel
- * @param handlers callbacks for messages we care about, NULL-terminated
- * note that the mesh is allowed to drop notifications about
- * inbound messages if the client does not process them fast
- * enough (for this notification type, a bounded queue is used)
- * @param stypes list of the applications that this client claims to provide
- * @return handle to the mesh service NULL on error
- * (in this case, init is never called)
- */
struct GNUNET_MESH_Handle *
GNUNET_MESH_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls,
GNUNET_MESH_InboundTunnelNotificationHandler new_tunnel,
GNUNET_MESH_TunnelEndHandler cleaner,
const struct GNUNET_MESH_MessageHandler *handlers,
- const GNUNET_MESH_ApplicationType *stypes)
+ const uint32_t *ports)
{
struct GNUNET_MESH_Handle *h;
- size_t size;
LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_MESH_connect()\n");
h = GNUNET_malloc (sizeof (struct GNUNET_MESH_Handle));
@@ -1713,38 +1351,24 @@ GNUNET_MESH_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, void *cls,
}
h->cls = cls;
h->message_handlers = handlers;
+ h->ports = ports;
h->next_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_CLI;
h->reconnect_time = GNUNET_TIME_UNIT_MILLISECONDS;
h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
- /* count apps */
- for (h->n_applications = 0;
- stypes && stypes[h->n_applications];
- h->n_applications++) ;
- if (0 < h->n_applications)
- {
- size = h->n_applications * sizeof (GNUNET_MESH_ApplicationType *);
- h->applications = GNUNET_malloc (size);
- memcpy (h->applications, stypes, size);
- }
/* count handlers */
for (h->n_handlers = 0;
handlers && handlers[h->n_handlers].type;
h->n_handlers++) ;
+ for (h->n_ports = 0;
+ ports && ports[h->n_ports];
+ h->n_ports++) ;
send_connect (h);
LOG (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_MESH_connect() END\n");
return h;
}
-/**
- * Disconnect from the mesh service. All tunnels will be destroyed. All tunnel
- * disconnect callbacks will be called on any still connected peers, notifying
- * about their disconnection. The registered inbound tunnel cleaner will be
- * called should any inbound tunnels still exist.
- *
- * @param handle connection to mesh to disconnect
- */
void
GNUNET_MESH_disconnect (struct GNUNET_MESH_Handle *handle)
{
@@ -1812,75 +1436,15 @@ GNUNET_MESH_disconnect (struct GNUNET_MESH_Handle *handle)
GNUNET_SCHEDULER_cancel(handle->reconnect_task);
handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
}
- GNUNET_free_non_null (handle->applications);
GNUNET_free (handle);
}
-/**
- * Announce to ther peer the availability of services described by the regex,
- * in order to be reachable to other peers via connect_by_string.
- *
- * Note that the first 8 characters are considered to be part of a prefix,
- * (for instance 'gnunet://'). If you put a variable part in there (*, +. ()),
- * all matching strings will be stored in the DHT.
- *
- * @param h Handle to mesh.
- * @param regex String with the regular expression describing local services.
- * @param compression_characters How many characters can be assigned to one
- * edge of the graph. The bigger the variability
- * of the data, the smaller this parameter should
- * be (down to 1).
- * For maximum compression, use strlen (regex)
- * or 0 (special value). Use with care!
- */
-void
-GNUNET_MESH_announce_regex (struct GNUNET_MESH_Handle *h,
- const char *regex,
- unsigned int compression_characters)
-{
- struct GNUNET_MESH_RegexAnnounce *msg;
- size_t payload;
- size_t len;
- size_t msgsize;
- size_t offset;
- char buffer[UINT16_MAX];
-
- len = strlen (regex);
- payload = UINT16_MAX - sizeof(struct GNUNET_MESH_RegexAnnounce);
- msg = (struct GNUNET_MESH_RegexAnnounce *) buffer;
- msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_ANNOUNCE_REGEX);
- msg->compression_characters = htons (compression_characters);
- offset = 0;
- do
- {
- msgsize = (len - offset > payload) ? payload : len - offset;
- memcpy (&msg[1], &regex[offset], msgsize);
- offset += msgsize;
- msgsize += sizeof(struct GNUNET_MESH_RegexAnnounce);
-
- msg->header.size = htons (msgsize);
- msg->last = htons (offset >= len);
-
- send_packet (h, &msg->header, NULL);
- } while (len > offset);
-}
-
-/**
- * Create a new tunnel (we're initiator and will be allowed to add/remove peers
- * and to broadcast).
- *
- * @param h mesh handle
- * @param tunnel_ctx client's tunnel context to associate with the tunnel
- * @param connect_handler function to call when peers are actually connected
- * @param disconnect_handler function to call when peers are disconnected
- * @param handler_cls closure for connect/disconnect handlers
- */
struct GNUNET_MESH_Tunnel *
-GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h, void *tunnel_ctx,
- GNUNET_MESH_PeerConnectHandler connect_handler,
- GNUNET_MESH_PeerDisconnectHandler disconnect_handler,
- void *handler_cls)
+GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h,
+ void *tunnel_ctx,
+ const struct GNUNET_PeerIdentity *peer,
+ uint32_t port)
{
struct GNUNET_MESH_Tunnel *t;
struct GNUNET_MESH_TunnelMessage msg;
@@ -1889,24 +1453,19 @@ GNUNET_MESH_tunnel_create (struct GNUNET_MESH_Handle *h, void *tunnel_ctx,
t = create_tunnel (h, 0);
LOG (GNUNET_ERROR_TYPE_DEBUG, " at %p\n", t);
LOG (GNUNET_ERROR_TYPE_DEBUG, " number %X\n", t->tid);
- t->connect_handler = connect_handler;
- t->disconnect_handler = disconnect_handler;
- t->cls = handler_cls;
t->ctx = tunnel_ctx;
+ t->peer = GNUNET_PEER_intern (peer);
msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE);
msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
msg.tunnel_id = htonl (t->tid);
+ msg.port = htonl (port);
+ msg.peer = *peer;
+ t->last_ack_sent = 0;
send_packet (h, &msg.header, t);
return t;
}
-/**
- * Destroy an existing tunnel. The existing callback for the tunnel will NOT
- * be called.
- *
- * @param tunnel tunnel handle
- */
void
GNUNET_MESH_tunnel_destroy (struct GNUNET_MESH_Tunnel *tunnel)
{
@@ -1938,62 +1497,11 @@ GNUNET_MESH_tunnel_destroy (struct GNUNET_MESH_Tunnel *tunnel)
th = th->next;
}
- destroy_tunnel (tunnel, GNUNET_NO);
+ destroy_tunnel (tunnel, GNUNET_YES);
send_packet (h, &msg.header, NULL);
}
-/**
- * Request that the tunnel data rate is limited to the speed of the slowest
- * receiver.
- *
- * @param tunnel Tunnel affected.
- */
-void
-GNUNET_MESH_tunnel_speed_min (struct GNUNET_MESH_Tunnel *tunnel)
-{
- struct GNUNET_MESH_TunnelMessage msg;
- struct GNUNET_MESH_Handle *h;
-
- h = tunnel->mesh;
- tunnel->speed_min = GNUNET_YES;
-
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_MIN);
- msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
- msg.tunnel_id = htonl (tunnel->tid);
-
- send_packet (h, &msg.header, NULL);
-}
-
-
-/**
- * Request that the tunnel data rate is limited to the speed of the fastest
- * receiver. This is the default behavior.
- *
- * @param tunnel Tunnel affected.
- */
-void
-GNUNET_MESH_tunnel_speed_max (struct GNUNET_MESH_Tunnel *tunnel)
-{
- struct GNUNET_MESH_TunnelMessage msg;
- struct GNUNET_MESH_Handle *h;
-
- h = tunnel->mesh;
- tunnel->speed_min = GNUNET_NO;
-
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_MAX);
- msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
- msg.tunnel_id = htonl (tunnel->tid);
-
- send_packet (h, &msg.header, NULL);
-}
-/**
- * Turn on/off the buffering status of the tunnel.
- *
- * @param tunnel Tunnel affected.
- * @param buffer GNUNET_YES to turn buffering on (default),
- * GNUNET_NO otherwise.
- */
void
GNUNET_MESH_tunnel_buffer (struct GNUNET_MESH_Tunnel *tunnel, int buffer)
{
@@ -2002,7 +1510,6 @@ GNUNET_MESH_tunnel_buffer (struct GNUNET_MESH_Tunnel *tunnel, int buffer)
h = tunnel->mesh;
tunnel->buffering = buffer;
- tunnel->max_send_pid = tunnel->next_send_pid;
if (GNUNET_YES == buffer)
msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER);
@@ -2015,267 +1522,39 @@ GNUNET_MESH_tunnel_buffer (struct GNUNET_MESH_Tunnel *tunnel, int buffer)
}
-/**
- * Request that a peer should be added to the tunnel. The existing
- * connect handler will be called ONCE with either success or failure.
- * This function should NOT be called again with the same peer before the
- * connect handler is called.
- * FIXME: I think the above documentation is false. I think it should
- * read: "The connect handler will be called once the peer was actually
- * successfully added to the multicast group. This function should
- * not be called twice for the same peer (unless, of course,
- * the peer was removed using GNUNET_MESH_peer_Request_connect_del in
- * the meantime).
- *
- * @param tunnel handle to existing tunnel
- * @param peer peer to add
- */
-void
-GNUNET_MESH_peer_request_connect_add (struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *peer)
-{
- struct GNUNET_MESH_PeerControl msg;
- GNUNET_PEER_Id peer_id;
- unsigned int i;
-
- peer_id = GNUNET_PEER_intern (peer);
- for (i = 0; i < tunnel->npeers; i++)
- {
- if (tunnel->peers[i]->id == peer_id)
- {
- /* Peer already exists in tunnel */
- GNUNET_PEER_change_rc (peer_id, -1);
- GNUNET_break (0);
- return;
- }
- }
- if (NULL == add_peer_to_tunnel (tunnel, peer))
- return;
-
- msg.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD);
- msg.tunnel_id = htonl (tunnel->tid);
- msg.peer = *peer;
- send_packet (tunnel->mesh, &msg.header, tunnel);
-}
-
-
-/**
- * Request that a peer should be removed from the tunnel. The existing
- * disconnect handler will be called ONCE if we were connected.
- *
- * @param tunnel handle to existing tunnel
- * @param peer peer to remove
- */
-void
-GNUNET_MESH_peer_request_connect_del (struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *peer)
-{
- struct GNUNET_MESH_PeerControl msg;
- GNUNET_PEER_Id peer_id;
- unsigned int i;
-
- peer_id = GNUNET_PEER_search (peer);
- if (0 == peer_id)
- {
- GNUNET_break (0);
- return;
- }
- for (i = 0; i < tunnel->npeers; i++)
- if (tunnel->peers[i]->id == peer_id)
- break;
- if (i == tunnel->npeers)
- {
- GNUNET_break (0);
- return;
- }
- if (NULL != tunnel->disconnect_handler && tunnel->peers[i]->connected == 1)
- tunnel->disconnect_handler (tunnel->cls, peer);
- GNUNET_PEER_change_rc (peer_id, -1);
- GNUNET_free (tunnel->peers[i]);
- tunnel->peers[i] = tunnel->peers[tunnel->npeers - 1];
- GNUNET_array_grow (tunnel->peers, tunnel->npeers, tunnel->npeers - 1);
-
- msg.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL);
- msg.tunnel_id = htonl (tunnel->tid);
- memcpy (&msg.peer, peer, sizeof (struct GNUNET_PeerIdentity));
- send_packet (tunnel->mesh, &msg.header, tunnel);
-}
-
-
-/**
- * Request that the mesh should try to connect to a peer supporting the given
- * message type.
- *
- * @param tunnel handle to existing tunnel
- * @param app_type application type that must be supported by the peer (MESH
- * should discover peer in proximity handling this type)
- */
-void
-GNUNET_MESH_peer_request_connect_by_type (struct GNUNET_MESH_Tunnel *tunnel,
- GNUNET_MESH_ApplicationType app_type)
-{
- struct GNUNET_MESH_ConnectPeerByType msg;
-
- GNUNET_array_append (tunnel->apps, tunnel->napps, app_type);
-
- LOG (GNUNET_ERROR_TYPE_DEBUG, "* CONNECT BY TYPE *\n");
- msg.header.size = htons (sizeof (struct GNUNET_MESH_ConnectPeerByType));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD_BY_TYPE);
- msg.tunnel_id = htonl (tunnel->tid);
- msg.type = htonl (app_type);
- send_packet (tunnel->mesh, &msg.header, tunnel);
-}
-
-
-/**
- * Request that the mesh should try to connect to a peer matching the
- * description given in the service string.
- *
- * FIXME: allow multiple? how to deal with reconnect?
- *
- * @param tunnel handle to existing tunnel
- * @param description string describing the destination node requirements
- */
-void
-GNUNET_MESH_peer_request_connect_by_string (struct GNUNET_MESH_Tunnel *tunnel,
- const char *description)
-{
- struct GNUNET_MESH_ConnectPeerByString *m;
- size_t len;
- size_t msgsize;
-
- len = strlen (description);
- msgsize = sizeof(struct GNUNET_MESH_ConnectPeerByString) + len;
- GNUNET_assert (UINT16_MAX > msgsize);
- {
- char buffer[msgsize];
-
- m = (struct GNUNET_MESH_ConnectPeerByString *) buffer;
- m->header.size = htons (msgsize);
- m->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD_BY_STRING);
- m->tunnel_id = htonl (tunnel->tid);
- memcpy(&m[1], description, len);
-
- send_packet (tunnel->mesh, &m->header, tunnel);
- }
-}
-
-
-/**
- * Request that the given peer isn't added to this tunnel in calls to
- * connect_by_* calls, (due to misbehaviour, bad performance, ...).
- *
- * @param tunnel handle to existing tunnel.
- * @param peer peer identity of the peer which should be blacklisted
- * for the tunnel.
- */
-void
-GNUNET_MESH_peer_blacklist (struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *peer)
-{
- struct GNUNET_MESH_PeerControl msg;
-
- msg.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_BLACKLIST);
- msg.tunnel_id = htonl (tunnel->tid);
- msg.peer = *peer;
- send_packet (tunnel->mesh, &msg.header, tunnel);
-
- return;
-}
-
-
-/**
- * Request that the given peer isn't blacklisted anymore from this tunnel,
- * and therefore can be added in future calls to connect_by_*.
- * The peer must have been previously blacklisted for this tunnel.
- *
- * @param tunnel handle to existing tunnel.
- * @param peer peer identity of the peer which shouldn't be blacklisted
- * for the tunnel anymore.
- */
-void
-GNUNET_MESH_peer_unblacklist (struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *peer)
-{
- struct GNUNET_MESH_PeerControl msg;
-
- msg.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_UNBLACKLIST);
- msg.tunnel_id = htonl (tunnel->tid);
- msg.peer = *peer;
- send_packet (tunnel->mesh, &msg.header, tunnel);
-
- return;
-}
-
-
-/**
- * Ask the mesh to call "notify" once it is ready to transmit the
- * given number of bytes to the specified tunnel or target.
- * Only one call can be active at any time, to issue another request,
- * wait for the callback or cancel the current request.
- *
- * @param tunnel tunnel to use for transmission
- * @param cork is corking allowed for this transmission?
- * @param maxdelay how long can the message wait?
- * @param target destination for the message
- * NULL for multicast to all tunnel targets
- * @param notify_size how many bytes of buffer space does notify want?
- * @param notify function to call when buffer space is available;
- * will be called with NULL on timeout or if the overall queue
- * for this peer is larger than queue_size and this is currently
- * the message with the lowest priority
- * @param notify_cls closure for notify
- * @return non-NULL if the notify callback was queued,
- * NULL if we can not even queue the request (insufficient
- * memory); if NULL is returned, "notify" will NOT be called.
- */
struct GNUNET_MESH_TransmitHandle *
GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork,
struct GNUNET_TIME_Relative maxdelay,
- const struct GNUNET_PeerIdentity *target,
size_t notify_size,
GNUNET_CONNECTION_TransmitReadyNotify notify,
void *notify_cls)
{
struct GNUNET_MESH_TransmitHandle *th;
- size_t overhead;
GNUNET_assert (NULL != tunnel);
LOG (GNUNET_ERROR_TYPE_DEBUG, "MESH NOTIFY TRANSMIT READY\n");
LOG (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %X\n", tunnel->tid);
if (tunnel->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
LOG (GNUNET_ERROR_TYPE_DEBUG, " to origin\n");
- else if (NULL != target)
- LOG (GNUNET_ERROR_TYPE_DEBUG, " target %s\n", GNUNET_i2s (target));
else
- LOG (GNUNET_ERROR_TYPE_DEBUG, " target multicast\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " to destination\n");
LOG (GNUNET_ERROR_TYPE_DEBUG, " payload size %u\n", notify_size);
GNUNET_assert (NULL != notify);
GNUNET_assert (0 == tunnel->packet_size); // Only one data packet allowed
th = GNUNET_malloc (sizeof (struct GNUNET_MESH_TransmitHandle));
th->tunnel = tunnel;
th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay);
- th->target = GNUNET_PEER_intern (target);
- if (tunnel->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
- overhead = sizeof (struct GNUNET_MESH_ToOrigin);
- else if (NULL == target)
- overhead = sizeof (struct GNUNET_MESH_Multicast);
- else
- overhead = sizeof (struct GNUNET_MESH_Unicast);
- tunnel->packet_size = th->size = notify_size + overhead;
+ th->size = notify_size + sizeof (struct GNUNET_MESH_Data);
+ tunnel->packet_size = th->size;
LOG (GNUNET_ERROR_TYPE_DEBUG, " total size %u\n", th->size);
th->notify = notify;
th->notify_cls = notify_cls;
add_to_queue (tunnel->mesh, th);
if (NULL != tunnel->mesh->th)
return th;
- if (GMC_is_pid_bigger(tunnel->next_send_pid, tunnel->max_send_pid))
+ if (!GMC_is_pid_bigger (tunnel->last_ack_recv, tunnel->last_pid_sent))
return th;
- LOG (GNUNET_ERROR_TYPE_DEBUG, " call notify tmt rdy\n");
+ LOG (GNUNET_ERROR_TYPE_DEBUG, " call client notify tmt rdy\n");
tunnel->mesh->th =
GNUNET_CLIENT_notify_transmit_ready (tunnel->mesh->client, th->size,
GNUNET_TIME_UNIT_FOREVER_REL,
@@ -2286,11 +1565,6 @@ GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork,
}
-/**
- * Cancel the specified transmission-ready notification.
- *
- * @param th handle that was returned by "notify_transmit_ready".
- */
void
GNUNET_MESH_notify_transmit_ready_cancel (struct GNUNET_MESH_TransmitHandle *th)
{
@@ -2310,6 +1584,12 @@ GNUNET_MESH_notify_transmit_ready_cancel (struct GNUNET_MESH_TransmitHandle *th)
}
}
+void
+GNUNET_MESH_receive_done (struct GNUNET_MESH_Tunnel *tunnel)
+{
+ send_ack (tunnel);
+}
+
/**
* Request information about the running mesh peer.
@@ -2366,6 +1646,7 @@ GNUNET_MESH_get_tunnels_cancel (struct GNUNET_MESH_Handle *h)
* Request information about a specific tunnel of the running mesh peer.
*
* WARNING: unstable API, likely to change in the future!
+ * FIXME Add destination option.
*
* @param h Handle to the mesh peer.
* @param initiator ID of the owner of the tunnel.
@@ -2384,7 +1665,6 @@ GNUNET_MESH_show_tunnel (struct GNUNET_MESH_Handle *h,
msg.header.size = htons (sizeof (msg));
msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL);
- msg.npeers = htonl (0);
msg.owner = *initiator;
msg.tunnel_id = htonl (tunnel_number);
msg.reserved = 0;
@@ -2397,21 +1677,111 @@ GNUNET_MESH_show_tunnel (struct GNUNET_MESH_Handle *h,
/**
- * Transition API for tunnel ctx management
+ * Function called to notify a client about the connection
+ * begin ready to queue more data. "buf" will be
+ * NULL and "size" zero if the connection was closed for
+ * writing in the meantime.
+ *
+ * @param cls closure
+ * @param size number of bytes available in buf
+ * @param buf where the callee should write the message
+ * @return number of bytes written to buf
*/
-void
-GNUNET_MESH_tunnel_set_data (struct GNUNET_MESH_Tunnel *tunnel, void *data)
+static size_t
+mesh_mq_ntr (void *cls, size_t size,
+ void *buf)
{
- tunnel->ctx = data;
+ struct GNUNET_MQ_Handle *mq = cls;
+ struct MeshMQState *state = GNUNET_MQ_impl_state (mq);
+ const struct GNUNET_MessageHeader *msg = GNUNET_MQ_impl_current (mq);
+ uint16_t msize;
+
+ state->th = NULL;
+ if (NULL == buf)
+ {
+ GNUNET_MQ_inject_error (mq, GNUNET_MQ_ERROR_WRITE);
+ return 0;
+ }
+ msize = ntohs (msg->size);
+ GNUNET_assert (msize <= size);
+ memcpy (buf, msg, msize);
+ GNUNET_MQ_impl_send_continue (mq);
+ return msize;
}
+
/**
- * Transition API for tunnel ctx management
+ * Signature of functions implementing the
+ * sending functionality of a message queue.
+ *
+ * @param mq the message queue
+ * @param msg the message to send
+ * @param impl_state state of the implementation
*/
-void *
-GNUNET_MESH_tunnel_get_data (struct GNUNET_MESH_Tunnel *tunnel)
+static void
+mesh_mq_send_impl (struct GNUNET_MQ_Handle *mq,
+ const struct GNUNET_MessageHeader *msg, void *impl_state)
{
- return tunnel->ctx;
+ struct MeshMQState *state = impl_state;
+
+ GNUNET_assert (NULL == state->th);
+ GNUNET_MQ_impl_send_commit (mq);
+ state->th =
+ GNUNET_MESH_notify_transmit_ready (state->tunnel,
+ /* FIXME: add option for corking */
+ GNUNET_NO,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ ntohs (msg->size),
+ mesh_mq_ntr, mq);
+
}
+/**
+ * Signature of functions implementing the
+ * destruction of a message queue.
+ * Implementations must not free 'mq', but should
+ * take care of 'impl_state'.
+ *
+ * @param mq the message queue to destroy
+ * @param impl_state state of the implementation
+ */
+static void
+mesh_mq_destroy_impl (struct GNUNET_MQ_Handle *mq, void *impl_state)
+{
+ struct MeshMQState *state = impl_state;
+
+ if (NULL != state->th)
+ GNUNET_MESH_notify_transmit_ready_cancel (state->th);
+
+ GNUNET_free (state);
+}
+
+
+/**
+ * Create a message queue for a mesh tunnel.
+ * The message queue can only be used to transmit messages,
+ * not to receive them.
+ *
+ * @param tunnel the tunnel to create the message qeue for
+ * @return a message queue to messages over the tunnel
+ */
+struct GNUNET_MQ_Handle *
+GNUNET_MESH_mq_create (struct GNUNET_MESH_Tunnel *tunnel)
+{
+ struct GNUNET_MQ_Handle *mq;
+ struct MeshMQState *state;
+
+ state = GNUNET_new (struct MeshMQState);
+ state->tunnel = tunnel;
+
+ mq = GNUNET_MQ_queue_for_callbacks (mesh_mq_send_impl,
+ mesh_mq_destroy_impl,
+ NULL, /* FIXME: cancel impl. */
+ state,
+ NULL, /* no msg handlers */
+ NULL, /* no err handlers */
+ NULL); /* no handler cls */
+ return mq;
+}
+
diff --git a/src/mesh/mesh_path.c b/src/mesh/mesh_path.c
index 05444655aa..1a3d40f9fe 100644
--- a/src/mesh/mesh_path.c
+++ b/src/mesh/mesh_path.c
@@ -24,7 +24,7 @@
* @author Bartlomiej Polot
*/
-#include "mesh2.h"
+#include "mesh.h"
#include "mesh_path.h"
diff --git a/src/mesh/mesh_path.h b/src/mesh/mesh_path.h
index c3f3264b00..74a35b2257 100644
--- a/src/mesh/mesh_path.h
+++ b/src/mesh/mesh_path.h
@@ -35,7 +35,7 @@ extern "C"
#endif
#endif
-#include "mesh2.h"
+#include "mesh.h"
/******************************************************************************/
/************************ DATA STRUCTURES ****************************/
diff --git a/src/mesh/mesh_protocol.h b/src/mesh/mesh_protocol.h
index 01f7f3487d..d35d7141ee 100644
--- a/src/mesh/mesh_protocol.h
+++ b/src/mesh/mesh_protocol.h
@@ -35,7 +35,6 @@ extern "C"
#endif
#endif
-#define MESH_TUNNEL_OPT_SPEED_MIN 0x1
#define MESH_TUNNEL_OPT_NOBUFFER 0x2
@@ -46,12 +45,12 @@ extern "C"
GNUNET_NETWORK_STRUCT_BEGIN
/**
- * Message for mesh path management
+ * Message for mesh path creation.
*/
-struct GNUNET_MESH_ManipulatePath
+struct GNUNET_MESH_CreateTunnel
{
/**
- * Type: GNUNET_MESSAGE_TYPE_MESH_PATH_[CREATE|CHANGE|ADD|DESTROY]
+ * Type: GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE
*
* Size: sizeof(struct GNUNET_MESH_ManipulatePath) +
* path_length * sizeof (struct GNUNET_PeerIdentity)
@@ -70,11 +69,12 @@ struct GNUNET_MESH_ManipulatePath
uint32_t opt GNUNET_PACKED;
/**
- * 64 bit alignment padding.
+ * Destination port.
*/
- uint32_t reserved GNUNET_PACKED;
+ uint32_t port GNUNET_PACKED;
/**
+ * FIXME do not add the first hop
* path_length structs defining the *whole* path from the origin [0] to the
* final destination [path_length-1].
*/
@@ -82,89 +82,34 @@ struct GNUNET_MESH_ManipulatePath
};
/**
- * Message for mesh data traffic to all tunnel targets.
+ * Message for mesh path destruction.
*/
-struct GNUNET_MESH_Multicast
+struct GNUNET_MESH_DestroyTunnel
{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_MULTICAST
- */
- struct GNUNET_MessageHeader header;
-
- /**
- * TID of the tunnel
- */
- uint32_t tid GNUNET_PACKED;
-
- /**
- * Number of hops to live
- */
- uint32_t ttl GNUNET_PACKED;
-
- /**
- * Unique ID of the packet
- */
- uint32_t pid GNUNET_PACKED;
-
- /**
- * OID of the tunnel
- */
- struct GNUNET_PeerIdentity oid;
-
- /**
- * Payload follows
- */
-};
-
-
-/**
- * Message for mesh data traffic to a particular destination from origin.
- */
-struct GNUNET_MESH_Unicast
-{
- /**
- * Type: GNUNET_MESSAGE_TYPE_MESH_UNICAST
- */
+ /**
+ * Type: GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY
+ *
+ * Size: sizeof(struct GNUNET_MESH_ManipulatePath) +
+ * path_length * sizeof (struct GNUNET_PeerIdentity)
+ */
struct GNUNET_MessageHeader header;
-
- /**
- * TID of the tunnel
- */
+
+ /**
+ * Global id of the tunnel this path belongs to,
+ * unique in conjunction with the origin.
+ */
uint32_t tid GNUNET_PACKED;
-
- /**
- * Number of hops to live
- */
- uint32_t ttl GNUNET_PACKED;
-
- /**
- * Unique ID of the packet
- */
- uint32_t pid GNUNET_PACKED;
-
- /**
- * OID of the tunnel
- */
- struct GNUNET_PeerIdentity oid;
-
- /**
- * Destination.
- */
- struct GNUNET_PeerIdentity destination;
-
- /**
- * Payload follows
- */
};
/**
- * Message for mesh data traffic from a tunnel participant to origin.
+ * Message for mesh data traffic.
*/
-struct GNUNET_MESH_ToOrigin
+struct GNUNET_MESH_Data
{
/**
- * Type: GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN
+ * Type: GNUNET_MESSAGE_TYPE_MESH_UNICAST,
+ * GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN
*/
struct GNUNET_MessageHeader header;
@@ -189,11 +134,6 @@ struct GNUNET_MESH_ToOrigin
struct GNUNET_PeerIdentity oid;
/**
- * Sender of the message.
- */
- struct GNUNET_PeerIdentity sender;
-
- /**
* Payload follows
*/
};
@@ -245,11 +185,6 @@ struct GNUNET_MESH_Poll
* OID of the tunnel
*/
struct GNUNET_PeerIdentity oid;
-
- /**
- * Last ACK received.
- */
- uint32_t last_ack;
};
/**
@@ -277,6 +212,11 @@ struct GNUNET_MESH_PathACK
*/
struct GNUNET_PeerIdentity peer_id;
+ /**
+ * Initial ACK value for payload.
+ */
+ uint32_t ack GNUNET_PACKED;
+
/* TODO: signature */
};
diff --git a/src/mesh/mesh_test_lib.c b/src/mesh/mesh_test_lib.c
index 7c4d884a66..e9ccb631fa 100644
--- a/src/mesh/mesh_test_lib.c
+++ b/src/mesh/mesh_test_lib.c
@@ -78,9 +78,9 @@ struct GNUNET_MESH_TEST_Context
struct GNUNET_MESH_MessageHandler* handlers;
/**
- * Application types.
+ * Application ports.
*/
- const GNUNET_MESH_ApplicationType* stypes;
+ const uint32_t *ports;
};
@@ -125,7 +125,7 @@ mesh_connect_adapter (void *cls,
ctx->new_tunnel,
ctx->cleaner,
ctx->handlers,
- ctx->stypes);
+ ctx->ports);
return h;
}
@@ -190,11 +190,6 @@ mesh_connect_cb (void *cls,
}
-/**
- * Clean up the testbed.
- *
- * @param ctx handle for the testbed
- */
void
GNUNET_MESH_TEST_cleanup (struct GNUNET_MESH_TEST_Context *ctx)
{
@@ -255,21 +250,6 @@ mesh_test_run (void *cls,
}
-/**
- * Run a test using the given name, configuration file and number of
- * peers.
- * All mesh callbacks will receive the peer number as the closure.
- *
- * @param testname Name of the test (for logging).
- * @param cfgname Name of the configuration file.
- * @param num_peers Number of peers to start.
- * @param tmain Main function to run once the testbed is ready.
- * @param tmain_cls Closure for 'tmain'.
- * @param new_tunnel Handler for incoming tunnels.
- * @param cleaner Cleaner for destroyed incoming tunnels.
- * @param handlers Message handlers.
- * @param stypes Application types.
- */
void
GNUNET_MESH_TEST_run (const char *testname,
const char *cfgname,
@@ -279,7 +259,7 @@ GNUNET_MESH_TEST_run (const char *testname,
GNUNET_MESH_InboundTunnelNotificationHandler new_tunnel,
GNUNET_MESH_TunnelEndHandler cleaner,
struct GNUNET_MESH_MessageHandler* handlers,
- const GNUNET_MESH_ApplicationType* stypes)
+ const uint32_t *ports)
{
struct GNUNET_MESH_TEST_Context *ctx;
@@ -292,7 +272,7 @@ GNUNET_MESH_TEST_run (const char *testname,
ctx->new_tunnel = new_tunnel;
ctx->cleaner = cleaner;
ctx->handlers = handlers;
- ctx->stypes = stypes;
+ ctx->ports = ports;
GNUNET_TESTBED_test_run (testname,
cfgname,
num_peers,
diff --git a/src/mesh/mesh_test_lib.h b/src/mesh/mesh_test_lib.h
index 554d06541e..4dd2151b8a 100644
--- a/src/mesh/mesh_test_lib.h
+++ b/src/mesh/mesh_test_lib.h
@@ -71,7 +71,7 @@ typedef void (*GNUNET_MESH_TEST_AppMain) (void *cls,
* @param new_tunnel Handler for incoming tunnels.
* @param cleaner Cleaner for destroyed incoming tunnels.
* @param handlers Message handlers.
- * @param stypes Application types.
+ * @param ports Ports the peers offer.
*/
void
GNUNET_MESH_TEST_run (const char *testname,
@@ -82,7 +82,7 @@ GNUNET_MESH_TEST_run (const char *testname,
GNUNET_MESH_InboundTunnelNotificationHandler new_tunnel,
GNUNET_MESH_TunnelEndHandler cleaner,
struct GNUNET_MESH_MessageHandler* handlers,
- const GNUNET_MESH_ApplicationType* stypes);
+ const uint32_t* ports);
/**
diff --git a/src/mesh/plugin_block_mesh.c b/src/mesh/plugin_block_mesh.c
index 3d99201f78..cbfd57eb4a 100644
--- a/src/mesh/plugin_block_mesh.c
+++ b/src/mesh/plugin_block_mesh.c
@@ -149,7 +149,6 @@ block_plugin_mesh_get_key (void *cls, enum GNUNET_BLOCK_Type type,
struct GNUNET_HashCode * key)
{
const struct PBlock *pb;
- GNUNET_MESH_ApplicationType app_type;
pb = block;
switch (type)
@@ -159,10 +158,6 @@ block_plugin_mesh_get_key (void *cls, enum GNUNET_BLOCK_Type type,
return GNUNET_SYSERR;
*key = pb->id.hashPubKey;
return GNUNET_OK;
- case GNUNET_BLOCK_TYPE_MESH_PEER_BY_TYPE:
- app_type = ntohl (pb->type);
- GNUNET_CRYPTO_hash (&app_type, sizeof(GNUNET_MESH_ApplicationType), key);
- return GNUNET_OK;
default:
GNUNET_break (0);
return GNUNET_SYSERR;
diff --git a/src/mesh/test_mesh.conf b/src/mesh/test_mesh.conf
index 3b35a16b46..58dff5adce 100644
--- a/src/mesh/test_mesh.conf
+++ b/src/mesh/test_mesh.conf
@@ -1,17 +1,15 @@
-[fs]
-AUTOSTART = NO
-
-[resolver]
-AUTOSTART = NO
+[PATHS]
+SERVICEHOME = /tmp/test-mesh/
[mesh]
-AUTOSTART = YES
+BINARY = gnunet-service-mesh-new
+AUTOSTART = NO
ACCEPT_FROM = 127.0.0.1;
HOSTNAME = localhost
PORT = 10511
-# PREFIX = valgrind --leak-check=full
-# PREFIX = xterm -geometry 100x85 -T peer1 -e gdb --args
-REFRESH_PATH_TIME = 3 s
+#PREFIX = valgrind --leak-check=full
+#PREFIX = xterm -geometry 100x85 -T peer1 -e gdb --args
+REFRESH_PATH_TIME = 2 s
APP_ANNOUNCE_TIME = 5 s
ID_ANNOUNCE_TIME = 5 s
CONNECT_TIMEOUT = 30 s
@@ -20,6 +18,16 @@ DHT_REPLICATION_LEVEL = 3
MAX_TUNNELS = 10
MAX_MSGS_QUEUE = 20
+[testbed]
+NUM_PEERS = 5
+OVERLAY_TOPOLOGY = LINE
+
+[fs]
+AUTOSTART = NO
+
+[resolver]
+AUTOSTART = NO
+
[vpn]
AUTOSTART = NO
PORT = 10012
@@ -30,6 +38,8 @@ ACCEPT_FROM6 = ::1;
ACCEPT_FROM = 127.0.0.1;
HOSTNAME = localhost
PORT = 12100
+DISABLE_TRY_CONNECT = YES
+FORCE_NSE = 3
[block]
plugins = dht test
@@ -53,7 +63,7 @@ WAN_QUOTA_IN = 3932160
PORT = 12092
[arm]
-DEFAULTSERVICES = core
+DEFAULTSERVICES = core mesh
PORT = 12366
[transport-tcp]
@@ -66,9 +76,6 @@ WEAKRANDOM = YES
[gnunetd]
HOSTKEY = $SERVICEHOME/.hostkey
-[PATHS]
-SERVICEHOME = /tmp/test-mesh/
-
[dns]
AUTOSTART = NO
diff --git a/src/mesh/test_mesh2.conf b/src/mesh/test_mesh2.conf
deleted file mode 100644
index 58dff5adce..0000000000
--- a/src/mesh/test_mesh2.conf
+++ /dev/null
@@ -1,89 +0,0 @@
-[PATHS]
-SERVICEHOME = /tmp/test-mesh/
-
-[mesh]
-BINARY = gnunet-service-mesh-new
-AUTOSTART = NO
-ACCEPT_FROM = 127.0.0.1;
-HOSTNAME = localhost
-PORT = 10511
-#PREFIX = valgrind --leak-check=full
-#PREFIX = xterm -geometry 100x85 -T peer1 -e gdb --args
-REFRESH_PATH_TIME = 2 s
-APP_ANNOUNCE_TIME = 5 s
-ID_ANNOUNCE_TIME = 5 s
-CONNECT_TIMEOUT = 30 s
-DEFAULT_TTL = 16
-DHT_REPLICATION_LEVEL = 3
-MAX_TUNNELS = 10
-MAX_MSGS_QUEUE = 20
-
-[testbed]
-NUM_PEERS = 5
-OVERLAY_TOPOLOGY = LINE
-
-[fs]
-AUTOSTART = NO
-
-[resolver]
-AUTOSTART = NO
-
-[vpn]
-AUTOSTART = NO
-PORT = 10012
-
-[dht]
-AUTOSTART = YES
-ACCEPT_FROM6 = ::1;
-ACCEPT_FROM = 127.0.0.1;
-HOSTNAME = localhost
-PORT = 12100
-DISABLE_TRY_CONNECT = YES
-FORCE_NSE = 3
-
-[block]
-plugins = dht test
-
-[dhtcache]
-QUOTA = 1 MB
-DATABASE = sqlite
-
-[transport]
-PLUGINS = tcp
-ACCEPT_FROM6 = ::1;
-ACCEPT_FROM = 127.0.0.1;
-NEIGHBOUR_LIMIT = 50
-PORT = 12365
-
-[ats]
-WAN_QUOTA_OUT = 3932160
-WAN_QUOTA_IN = 3932160
-
-[core]
-PORT = 12092
-
-[arm]
-DEFAULTSERVICES = core mesh
-PORT = 12366
-
-[transport-tcp]
-TIMEOUT = 300 s
-PORT = 12368
-
-[TESTING]
-WEAKRANDOM = YES
-
-[gnunetd]
-HOSTKEY = $SERVICEHOME/.hostkey
-
-[dns]
-AUTOSTART = NO
-
-[nse]
-AUTOSTART = NO
-
-[namestore]
-AUTOSTART = NO
-
-[consensus]
-AUTOSTART = NO
diff --git a/src/mesh/test_mesh2_small.c b/src/mesh/test_mesh2_small.c
deleted file mode 100644
index 0a184d56f0..0000000000
--- a/src/mesh/test_mesh2_small.c
+++ /dev/null
@@ -1,833 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 2011 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-/**
- * @file mesh/test_mesh2_small.c
- *
- * @brief Test for the mesh service: retransmission of traffic.
- */
-#include <stdio.h>
-#include "platform.h"
-#include "mesh2_test_lib.h"
-#include "gnunet_mesh2_service.h"
-#include <gauger.h>
-
-
-/**
- * How namy messages to send
- */
-#define TOTAL_PACKETS 1000
-
-/**
- * How long until we give up on connecting the peers?
- */
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120)
-
-/**
- * Time to wait for stuff that should be rather fast
- */
-#define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 20)
-
-/**
- * DIFFERENT TESTS TO RUN
- */
-#define SETUP 0
-#define FORWARD 1
-#define SPEED 3
-#define SPEED_ACK 4
-#define SPEED_NOBUF 6
-#define P2P_SIGNAL 10
-
-/**
- * Which test are we running?
- */
-static int test;
-
-/**
- * String with test name
- */
-char *test_name;
-
-/**
- * Flag to send traffic leaf->root in speed tests to test BCK_ACK logic.
- */
-static int test_backwards = GNUNET_NO;
-
-/**
- * How many events have happened
- */
-static int ok;
-
- /**
- * Each peer is supposed to generate the following callbacks:
- * 1 incoming tunnel (@dest)
- * 1 connected peer (@orig)
- * 1 received data packet (@dest)
- * 1 received data packet (@orig)
- * 1 received tunnel destroy (@dest)
- * _________________________________
- * 5 x ok expected per peer
- */
-int ok_goal;
-
-
-/**
- * Size of each test packet
- */
-size_t size_payload = sizeof (struct GNUNET_MessageHeader) + sizeof (uint32_t);
-
-/**
- * Operation to get peer ids.
- */
-struct GNUNET_TESTBED_Operation *t_op[2];
-
-/**
- * Peer ids.
- */
-struct GNUNET_PeerIdentity *p_id[2];
-
-/**
- * Peer ids counter.
- */
-unsigned int p_ids;
-
-/**
- * Is the setup initialized?
- */
-static int initialized;
-
-/**
- * Peers that have responded
- */
-static int peers_responded;
-
-/**
- * Number of payload packes sent
- */
-static int data_sent;
-
-/**
- * Number of payload packets received
- */
-static int data_received;
-
-/**
- * Number of payload packed explicitly (app level) acknowledged
- */
-static int data_ack;
-
-/**
- * Total number of currently running peers.
- */
-static unsigned long long peers_running;
-
-/**
- * Test context (to shut down).
- */
-struct GNUNET_MESH_TEST_Context *test_ctx;
-
-/**
- * Task called to disconnect peers.
- */
-static GNUNET_SCHEDULER_TaskIdentifier disconnect_task;
-
-/**
- * Task To perform tests
- */
-static GNUNET_SCHEDULER_TaskIdentifier test_task;
-
-/**
- * Task called to shutdown test.
- */
-static GNUNET_SCHEDULER_TaskIdentifier shutdown_handle;
-
-/**
- * Mesh handle for the root peer
- */
-static struct GNUNET_MESH_Handle *h1;
-
-/**
- * Mesh handle for the first leaf peer
- */
-static struct GNUNET_MESH_Handle *h2;
-
-/**
- * Tunnel handle for the root peer
- */
-static struct GNUNET_MESH_Tunnel *t;
-
-/**
- * Tunnel handle for the first leaf peer
- */
-static struct GNUNET_MESH_Tunnel *incoming_t;
-
-/**
- * Time we started the data transmission (after tunnel has been established
- * and initilized).
- */
-static struct GNUNET_TIME_Absolute start_time;
-
-
-/**
- * Show the results of the test (banwidth acheived) and log them to GAUGER
- */
-static void
-show_end_data (void)
-{
- static struct GNUNET_TIME_Absolute end_time;
- static struct GNUNET_TIME_Relative total_time;
-
- end_time = GNUNET_TIME_absolute_get();
- total_time = GNUNET_TIME_absolute_get_difference(start_time, end_time);
- FPRINTF (stderr, "\nResults of test \"%s\"\n", test_name);
- FPRINTF (stderr, "Test time %llu ms\n",
- (unsigned long long) total_time.rel_value);
- FPRINTF (stderr, "Test bandwidth: %f kb/s\n",
- 4 * TOTAL_PACKETS * 1.0 / total_time.rel_value); // 4bytes * ms
- FPRINTF (stderr, "Test throughput: %f packets/s\n\n",
- TOTAL_PACKETS * 1000.0 / total_time.rel_value); // packets * ms
- GAUGER ("MESH", test_name,
- TOTAL_PACKETS * 1000.0 / total_time.rel_value,
- "packets/s");
-}
-
-
-/**
- * Shut down peergroup, clean up.
- *
- * @param cls Closure (unused).
- * @param tc Task Context.
- */
-static void
-shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending test.\n");
- shutdown_handle = GNUNET_SCHEDULER_NO_TASK;
-}
-
-
-/**
- * Disconnect from mesh services af all peers, call shutdown.
- *
- * @param cls Closure (unused).
- * @param tc Task Context.
- */
-static void
-disconnect_mesh_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- long line = (long) cls;
- unsigned int i;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "disconnecting mesh service of peers, called from line %ld\n",
- line);
- disconnect_task = GNUNET_SCHEDULER_NO_TASK;
- for (i = 0; i < 2; i++)
- {
- GNUNET_TESTBED_operation_done (t_op[i]);
- }
- if (NULL != t)
- {
- GNUNET_MESH_tunnel_destroy (t);
- t = NULL;
- }
- if (NULL != incoming_t)
- {
- GNUNET_MESH_tunnel_destroy (incoming_t);
- incoming_t = NULL;
- }
- GNUNET_MESH_TEST_cleanup (test_ctx);
- if (GNUNET_SCHEDULER_NO_TASK != shutdown_handle)
- {
- GNUNET_SCHEDULER_cancel (shutdown_handle);
- }
- shutdown_handle = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL);
-}
-
-
-/**
- * Abort test: schedule disconnect and shutdown immediately
- *
- * @param line Line in the code the abort is requested from (__LINE__).
- */
-static void
-abort_test (long line)
-{
- if (disconnect_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (disconnect_task);
- disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_mesh_peers,
- (void *) line);
- }
-}
-
-/**
- * Transmit ready callback.
- *
- * @param cls Closure (message type).
- * @param size Size of the tranmist buffer.
- * @param buf Pointer to the beginning of the buffer.
- *
- * @return Number of bytes written to buf.
- */
-static size_t
-tmt_rdy (void *cls, size_t size, void *buf);
-
-
-/**
- * Task to schedule a new data transmission.
- *
- * @param cls Closure (peer #).
- * @param tc Task Context.
- */
-static void
-data_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct GNUNET_MESH_TransmitHandle *th;
- struct GNUNET_MESH_Tunnel *tunnel;
-
- if ((GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason) != 0)
- return;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data task\n");
- if (GNUNET_YES == test_backwards)
- {
- tunnel = incoming_t;
- }
- else
- {
- tunnel = t;
- }
- th = GNUNET_MESH_notify_transmit_ready (tunnel, GNUNET_NO,
- GNUNET_TIME_UNIT_FOREVER_REL,
- size_payload, &tmt_rdy, (void *) 1L);
- if (NULL == th)
- {
- unsigned long i = (unsigned long) cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Retransmission\n");
- if (0 == i)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, " in 1 ms\n");
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
- &data_task, (void *)1UL);
- }
- else
- {
- i++;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "in %u ms\n", i);
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(
- GNUNET_TIME_UNIT_MILLISECONDS,
- i),
- &data_task, (void *)i);
- }
- }
-}
-
-
-/**
- * Transmit ready callback
- *
- * @param cls Closure (message type).
- * @param size Size of the buffer we have.
- * @param buf Buffer to copy data to.
- */
-size_t
-tmt_rdy (void *cls, size_t size, void *buf)
-{
- struct GNUNET_MessageHeader *msg = buf;
- uint32_t *data;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " tmt_rdy called\n");
- if (size < size_payload || NULL == buf)
- {
- GNUNET_break (0);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "size %u, buf %p, data_sent %u, data_received %u\n",
- size,
- buf,
- data_sent,
- data_received);
- return 0;
- }
- msg->size = htons (size);
- msg->type = htons ((long) cls);
- data = (uint32_t *) &msg[1];
- *data = htonl (data_sent);
- if (SPEED == test && GNUNET_YES == initialized)
- {
- data_sent++;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Sent packet %d\n", data_sent);
- if (data_sent < TOTAL_PACKETS)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- " Scheduling packet %d\n", data_sent + 1);
- GNUNET_SCHEDULER_add_now(&data_task, NULL);
- }
- }
- return size_payload;
-}
-
-
-/**
- * Function is called whenever a message is received.
- *
- * @param cls closure (set from GNUNET_MESH_connect)
- * @param tunnel connection to the other end
- * @param tunnel_ctx place to store local state associated with the tunnel
- * @param message the actual message
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
- */
-int
-data_callback (void *cls, struct GNUNET_MESH_Tunnel *tunnel, void **tunnel_ctx,
- const struct GNUNET_MessageHeader *message)
-{
- long client = (long) cls;
- long expected_target_client;
- uint32_t *data;
-
- ok++;
-
- GNUNET_MESH_receive_done (tunnel);
-
- if ((ok % 20) == 0)
- {
- if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
- {
- GNUNET_SCHEDULER_cancel (disconnect_task);
- disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
- &disconnect_mesh_peers,
- (void *) __LINE__);
- }
- }
-
- switch (client)
- {
- case 0L:
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Root client got a message!\n");
- peers_responded++;
- break;
- case 4L:
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Leaf client %li got a message.\n",
- client);
- client = 4L;
- break;
- default:
- GNUNET_assert (0);
- break;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: (%d/%d)\n", ok, ok_goal);
- data = (uint32_t *) &message[1];
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, " payload: (%u)\n", ntohl (*data));
- if (SPEED == test && GNUNET_YES == test_backwards)
- {
- expected_target_client = 0L;
- }
- else
- {
- expected_target_client = 4L;
- }
-
- if (GNUNET_NO == initialized)
- {
- initialized = GNUNET_YES;
- start_time = GNUNET_TIME_absolute_get ();
- if (SPEED == test)
- {
- GNUNET_assert (4L == client);
- GNUNET_SCHEDULER_add_now (&data_task, NULL);
- return GNUNET_OK;
- }
- }
-
- if (client == expected_target_client) // Normally 3 or 4
- {
- data_received++;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- " received data %u\n", data_received);
- if (SPEED != test || (ok_goal - 2) == ok)
- {
- GNUNET_MESH_notify_transmit_ready (tunnel, GNUNET_NO,
- GNUNET_TIME_UNIT_FOREVER_REL,
- size_payload, &tmt_rdy, (void *) 1L);
- return GNUNET_OK;
- }
- else
- {
- if (data_received < TOTAL_PACKETS)
- return GNUNET_OK;
- }
- }
- else // Normally 0
- {
- if (test == SPEED_ACK || test == SPEED)
- {
- data_ack++;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- " received ack %u\n", data_ack);
- GNUNET_MESH_notify_transmit_ready (tunnel, GNUNET_NO,
- GNUNET_TIME_UNIT_FOREVER_REL,
- size_payload, &tmt_rdy, (void *) 1L);
- if (data_ack < TOTAL_PACKETS && SPEED != test)
- return GNUNET_OK;
- if (ok == 2 && SPEED == test)
- return GNUNET_OK;
- show_end_data();
- }
- if (test == P2P_SIGNAL)
- {
- GNUNET_MESH_tunnel_destroy (incoming_t);
- incoming_t = NULL;
- }
- else
- {
- GNUNET_MESH_tunnel_destroy (t);
- t = NULL;
- }
- }
-
- if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
- {
- GNUNET_SCHEDULER_cancel (disconnect_task);
- disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
- &disconnect_mesh_peers,
- (void *) __LINE__);
- }
-
- return GNUNET_OK;
-}
-
-
-/**
- * Handlers, for diverse services
- */
-static struct GNUNET_MESH_MessageHandler handlers[] = {
- {&data_callback, 1, sizeof (struct GNUNET_MessageHeader)},
- {NULL, 0, 0}
-};
-
-
-/**
- * Method called whenever another peer has added us to a tunnel
- * the other peer initiated.
- *
- * @param cls Closure.
- * @param tunnel New handle to the tunnel.
- * @param initiator Peer that started the tunnel.
- * @param port Port this tunnels is connected to.
- * @return Initial tunnel context for the tunnel
- * (can be NULL -- that's not an error).
- */
-static void *
-incoming_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *initiator,
- uint32_t port)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Incoming tunnel from %s to peer %d\n",
- GNUNET_i2s (initiator), (long) cls);
- ok++;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok);
- if ((long) cls == 4L)
- incoming_t = tunnel;
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Incoming tunnel for unknown client %lu\n", (long) cls);
- GNUNET_break(0);
- }
- if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
- {
- GNUNET_SCHEDULER_cancel (disconnect_task);
- disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
- &disconnect_mesh_peers,
- (void *) __LINE__);
- }
-
- return NULL;
-}
-
-/**
- * Function called whenever an inbound tunnel is destroyed. Should clean up
- * any associated state.
- *
- * @param cls closure (set from GNUNET_MESH_connect)
- * @param tunnel connection to the other end (henceforth invalid)
- * @param tunnel_ctx place where local state associated
- * with the tunnel is stored
- */
-static void
-tunnel_cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel,
- void *tunnel_ctx)
-{
- long i = (long) cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "Incoming tunnel disconnected at peer %d\n",
- i);
- if (4L == i)
- {
- ok++;
- incoming_t = NULL;
- }
- else if (0L == i && P2P_SIGNAL == test)
- {
- ok ++;
- }
- else
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Unknown peer! %d\n", i);
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok);
-
- if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
- {
- GNUNET_SCHEDULER_cancel (disconnect_task);
- disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_mesh_peers,
- (void *) __LINE__);
- }
-
- return;
-}
-
-
-/**
- * START THE TESTCASE ITSELF, AS WE ARE CONNECTED TO THE MESH SERVICES.
- *
- * Testcase continues when the root receives confirmation of connected peers,
- * on callback funtion ch.
- *
- * @param cls Closure (unsued).
- * @param tc Task Context.
- */
-static void
-do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test_task\n");
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "add peer 2\n");
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "schedule timeout in TIMEOUT\n");
- if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
- {
- GNUNET_SCHEDULER_cancel (disconnect_task);
- }
- t = GNUNET_MESH_tunnel_create (h1, NULL, p_id[1], 1);
- if (SPEED_NOBUF == test)
- {
- GNUNET_MESH_tunnel_buffer(t, GNUNET_NO);
- test = SPEED;
- }
-
- disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
- &disconnect_mesh_peers,
- (void *) __LINE__);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending data initializer...\n");
- peers_responded = 0;
- data_ack = 0;
- data_received = 0;
- data_sent = 0;
- GNUNET_MESH_notify_transmit_ready (t, GNUNET_NO,
- GNUNET_TIME_UNIT_FOREVER_REL,
- size_payload, &tmt_rdy, (void *) 1L);
-}
-
-/**
- * Callback to be called when the requested peer information is available
- *
- * @param cls the closure from GNUNET_TESTBED_peer_get_information()
- * @param op the operation this callback corresponds to
- * @param pinfo the result; will be NULL if the operation has failed
- * @param emsg error message if the operation has failed;
- * NULL if the operation is successfull
- */
-static void
-pi_cb (void *cls,
- struct GNUNET_TESTBED_Operation *op,
- const struct GNUNET_TESTBED_PeerInformation *pinfo,
- const char *emsg)
-{
- long i = (long) cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "id callback for %ld\n", i);
-
- if (NULL == pinfo || NULL != emsg)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "pi_cb: %s\n", emsg);
- abort_test (__LINE__);
- return;
- }
- p_id[i] = pinfo->result.id;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " id: %s\n", GNUNET_i2s (p_id[i]));
- p_ids++;
- if (p_ids < 2)
- return;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got all IDs, starting test\n");
- test_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
- &do_test, NULL);
-}
-
-/**
- * test main: start test when all peers are connected
- *
- * @param cls Closure.
- * @param ctx Argument to give to GNUNET_MESH_TEST_cleanup on test end.
- * @param num_peers Number of peers that are running.
- * @param peers Array of peers.
- * @param meshes Handle to each of the MESHs of the peers.
- */
-static void
-tmain (void *cls,
- struct GNUNET_MESH_TEST_Context *ctx,
- unsigned int num_peers,
- struct GNUNET_TESTBED_Peer **peers,
- struct GNUNET_MESH_Handle **meshes)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test main\n");
- ok = 0;
- test_ctx = ctx;
- peers_running = num_peers;
- h1 = meshes[0];
- h2 = meshes[num_peers - 1];
- disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
- &disconnect_mesh_peers,
- (void *) __LINE__);
- shutdown_handle = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
- &shutdown_task, NULL);
- t_op[0] = GNUNET_TESTBED_peer_get_information (peers[0],
- GNUNET_TESTBED_PIT_IDENTITY,
- &pi_cb, (void *) 0L);
- t_op[1] = GNUNET_TESTBED_peer_get_information (peers[num_peers - 1],
- GNUNET_TESTBED_PIT_IDENTITY,
- &pi_cb, (void *) 1L);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "requested peer ids\n");
-}
-
-
-/**
- * Main: start test
- */
-int
-main (int argc, char *argv[])
-{
- initialized = GNUNET_NO;
- uint32_t ports[2];
-
- GNUNET_log_setup ("test", "DEBUG", NULL);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start\n");
- if (strstr (argv[0], "_small_forward") != NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "FORWARD\n");
- test = FORWARD;
- test_name = "unicast2";
- ok_goal = 4;
- }
- else if (strstr (argv[0], "_small_signal") != NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SIGNAL\n");
- test = P2P_SIGNAL;
- test_name = "signal2";
- ok_goal = 4;
- }
- else if (strstr (argv[0], "_small_speed_ack") != NULL)
- {
- /* Each peer is supposed to generate the following callbacks:
- * 1 incoming tunnel (@dest)
- * TOTAL_PACKETS received data packet (@dest)
- * TOTAL_PACKETS received data packet (@orig)
- * 1 received tunnel destroy (@dest)
- * _________________________________
- * 5 x ok expected per peer
- */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SPEED_ACK\n");
- test = SPEED_ACK;
- test_name = "speed2 ack";
- ok_goal = TOTAL_PACKETS * 2 + 2;
- }
- else if (strstr (argv[0], "_small_speed") != NULL)
- {
- /* Each peer is supposed to generate the following callbacks:
- * 1 incoming tunnel (@dest)
- * 1 initial packet (@dest)
- * TOTAL_PACKETS received data packet (@dest)
- * 1 received data packet (@orig)
- * 1 received tunnel destroy (@dest)
- * _________________________________
- */
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SPEED\n");
- ok_goal = TOTAL_PACKETS + 4;
- if (strstr (argv[0], "_nobuf") != NULL)
- {
- test = SPEED_NOBUF;
- test_name = "speed2 nobuf";
- }
- else
- {
- test = SPEED;
- test_name = "speed2";
- }
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "UNKNOWN\n");
- test = SETUP;
- ok_goal = 0;
- }
-
- if (strstr (argv[0], "backwards") != NULL)
- {
- char *aux;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "BACKWARDS (LEAF TO ROOT)\n");
- test_backwards = GNUNET_YES;
- aux = GNUNET_malloc (32);
- sprintf (aux, "backwards %s", test_name);
- test_name = aux;
- }
-
- p_ids = 0;
- ports[0] = 1;
- ports[1] = 0;
- GNUNET_MESH_TEST_run ("test_mesh2_small",
- "test_mesh2.conf",
- 5,
- &tmain,
- NULL, /* tmain cls */
- &incoming_tunnel,
- &tunnel_cleaner,
- handlers,
- ports);
-
- if (ok_goal > ok)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "FAILED! (%d/%d)\n", ok, ok_goal);
- return 1;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "success\n");
- return 0;
-}
-
-/* end of test_mesh_small.c */
-
diff --git a/src/mesh/test_mesh_2dtorus.c b/src/mesh/test_mesh_2dtorus.c
deleted file mode 100644
index 4b6affcc8e..0000000000
--- a/src/mesh/test_mesh_2dtorus.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 2011 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-/**
- * @file mesh/test_mesh_2dtorus.c
- *
- * @brief Test for creating a 2dtorus.
- */
-#include "platform.h"
-#include "mesh_test_lib.h"
-#include "gnunet_mesh_service.h"
-
-#define REMOVE_DIR GNUNET_YES
-
-/**
- * How long until we give up on connecting the peers?
- */
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1500)
-
-/**
- * Time to wait for stuff that should be rather fast
- */
-#define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
-
-
-/**
- * How many events have happened
- */
-static int ok;
-
-/**
- * Total number of currently running peers.
- */
-static unsigned long long peers_running;
-
-/**
- * Task to time out.
- */
-static GNUNET_SCHEDULER_TaskIdentifier timeout_task;
-
-
-static void
-shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutting down test\n");
-}
-
-
-/**
- * test main: start test when all peers are connected
- *
- * @param cls Closure.
- * @param ctx Argument to give to GNUNET_MESH_TEST_cleanup on test end.
- * @param num_peers Number of peers that are running.
- * @param peers Array of peers.
- * @param meshes Handle to each of the MESHs of the peers.
- */
-static void
-tmain (void *cls,
- struct GNUNET_MESH_TEST_Context *ctx,
- unsigned int num_peers,
- struct GNUNET_TESTBED_Peer **peers,
- struct GNUNET_MESH_Handle **meshes)
-{
- if (16 != num_peers)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "running peers mismatch, aborting test!\n");
- ok--;
- GNUNET_MESH_TEST_cleanup (ctx);
- return;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "testbed started successfully with ?? connections\n");
- peers_running = num_peers;
- timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
- &shutdown_task, ctx);
- ok = GNUNET_OK;
- GNUNET_MESH_TEST_cleanup (ctx);
-}
-
-
-/**
- * Main: start test
- */
-int
-main (int argc, char *argv[])
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Start\n");
- ok = GNUNET_SYSERR;
-
- GNUNET_MESH_TEST_run ("test_mesh_2dtorus",
- "test_mesh_2dtorus.conf",
- 16,
- &tmain,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
- );
-
- if (GNUNET_OK != ok)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "FAILED!\n");
- return 1;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "success\n");
- return 0;
-}
-
-/* end of test_mesh_2dtorus.c */
diff --git a/src/mesh/test_mesh_2dtorus.conf b/src/mesh/test_mesh_2dtorus.conf
deleted file mode 100644
index 708ab0a504..0000000000
--- a/src/mesh/test_mesh_2dtorus.conf
+++ /dev/null
@@ -1,71 +0,0 @@
-[PATHS]
-SERVICEHOME = /tmp/test_mesh_small/
-
-[mesh]
-PORT = 10005
-ACCEPT_FROM = 127.0.0.1;
-HOSTNAME = localhost
-DHT_REPLICATION_LEVEL = 10
-# PREFIX = valgrind --leak-check=full
-# PREFIX = xterm -geometry 100x85 -T peer1 -e gdb --args
-
-[testing]
-WEAKRANDOM = YES
-
-[testbed]
-NUM_PEERS = 16
-OVERLAY_TOPOLOGY = 2D_TORUS
-
-[arm]
-PORT = 10010
-DEFAULTSERVICES = core dht mesh
-
-[statistics]
-AUTOSTART = YES
-PORT = 10000
-
-[dht]
-AUTOSTART = YES
-ACCEPT_FROM6 = ::1;
-ACCEPT_FROM = 127.0.0.1;
-HOSTNAME = localhost
-PORT = 10001
-DISABLE_TRY_CONNECT = YES
-
-[nse]
-WORKBITS = 0
-
-[dns]
-AUTOSTART = NO
-PORT = 10011
-
-[vpn]
-AUTOSTART = NO
-PORT = 10012
-
-[transport]
-PORT = 10002
-AUTOSTART = YES
-
-[nat]
-DISABLEV6 = YES
-BINDTO = 127.0.0.1
-ENABLE_UPNP = NO
-BEHIND_NAT = NO
-ALLOW_NAT = NO
-INTERNAL_ADDRESS = 127.0.0.1
-EXTERNAL_ADDRESS = 127.0.0.1
-RETURN_LOCAL_ADDRESSES = YES
-USE_LOCALADDR = YES
-
-[ats]
-WAN_QUOTA_IN = 1 GB
-WAN_QUOTA_OUT = 1 GB
-
-[core]
-AUTOSTART = YES
-PORT = 10003
-
-[peerinfo]
-AUTOSTART = YES
-PORT = 10004
diff --git a/src/mesh/test_mesh_api.c b/src/mesh/test_mesh_api.c
deleted file mode 100644
index 349ec80f0e..0000000000
--- a/src/mesh/test_mesh_api.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 2011 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file mesh/test_mesh_api.c
- * @brief test mesh api: dummy test of callbacks
- * @author Bartlomiej Polot
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_testing_lib.h"
-#include "gnunet_dht_service.h"
-#include "gnunet_mesh_service.h"
-
-static struct GNUNET_MESH_Handle *mesh;
-
-static struct GNUNET_MESH_Tunnel *t;
-
-static int result;
-
-static GNUNET_SCHEDULER_TaskIdentifier abort_task;
-
-
-/**
- * Function is called whenever a message is received.
- *
- * @param cls closure (set from GNUNET_MESH_connect)
- * @param tunnel connection to the other end
- * @param tunnel_ctx place to store local state associated with the tunnel
- * @param sender who sent the message
- * @param message the actual message
- * @param atsi performance data for the connection
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
- */
-static int
-callback (void *cls, struct GNUNET_MESH_Tunnel *tunnel, void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi)
-{
- return GNUNET_OK;
-}
-
-
-static struct GNUNET_MESH_MessageHandler handlers[] = {
- { &callback, 1, 0 },
- { NULL, 0, 0 }
-};
-
-
-static void
-do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- if (NULL != t)
- {
- GNUNET_MESH_tunnel_destroy (t);
- }
- if (0 != abort_task)
- {
- GNUNET_SCHEDULER_cancel (abort_task);
- }
- if (NULL != mesh)
- {
- GNUNET_MESH_disconnect (mesh);
- }
-}
-
-
-static void
-do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- result = GNUNET_SYSERR;
- abort_task = 0;
- do_shutdown (cls, tc);
-}
-
-
-static void
-run (void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg,
- struct GNUNET_TESTING_Peer *peer)
-{
- static const GNUNET_MESH_ApplicationType app[] =
- { 1, 2, 3, 4, 5, 6, 7, 8, 0 };
-
- mesh = GNUNET_MESH_connect (cfg, NULL, NULL, NULL, handlers, app);
- if (NULL == mesh)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "test: Couldn't connect to mesh :(\n");
- result = GNUNET_SYSERR;
- return;
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: YAY! CONNECTED TO MESH :D\n");
- }
- t = GNUNET_MESH_tunnel_create (mesh, NULL, NULL, NULL, NULL);
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS, 5), &do_shutdown,
- NULL);
- abort_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS, 20), &do_abort,
- NULL);
-}
-
-
-int
-main (int argc, char *argv[])
-{
- result = GNUNET_OK;
- if (0 != GNUNET_TESTING_peer_run ("test-mesh-api",
- "test_mesh.conf",
- &run, NULL))
- return 1;
- return (result == GNUNET_OK) ? 0 : 1;
-}
-
-/* end of test_mesh_api.c */
-
diff --git a/src/mesh/test_mesh2_local.c b/src/mesh/test_mesh_local.c
index 483135afa6..058f02af6a 100644
--- a/src/mesh/test_mesh2_local.c
+++ b/src/mesh/test_mesh_local.c
@@ -19,8 +19,8 @@
*/
/**
- * @file mesh/test_mesh2_local.c
- * @brief test mesh2 local: test of mesh2 tunnels with just one peer
+ * @file mesh/test_mesh_local.c
+ * @brief test mesh local: test of mesh tunnels with just one peer
* @author Bartlomiej Polot
*/
@@ -28,7 +28,7 @@
#include "gnunet_util_lib.h"
#include "gnunet_dht_service.h"
#include "gnunet_testing_lib.h"
-#include "gnunet_mesh2_service.h"
+#include "gnunet_mesh_service.h"
struct GNUNET_TESTING_Peer *me;
@@ -286,7 +286,7 @@ int
main (int argc, char *argv[])
{
if (0 != GNUNET_TESTING_peer_run ("test-mesh-local",
- "test_mesh2.conf",
+ "test_mesh.conf",
&run, NULL))
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "run failed\n");
diff --git a/src/mesh/test_mesh_local_1.c b/src/mesh/test_mesh_local_1.c
deleted file mode 100644
index 4f40688f57..0000000000
--- a/src/mesh/test_mesh_local_1.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 2011 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file mesh/test_mesh_local_1.c
- * @brief test mesh local: test of tunnels with just one peer
- * @author Bartlomiej Polot
- */
-
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_dht_service.h"
-#include "gnunet_testing_lib.h"
-#include "gnunet_mesh_service.h"
-
-
-static struct GNUNET_MESH_Handle *mesh_peer_1;
-
-static struct GNUNET_MESH_Handle *mesh_peer_2;
-
-static struct GNUNET_MESH_Tunnel *t;
-
-static unsigned int one = 1;
-
-static unsigned int two = 2;
-
-static int result = GNUNET_OK;
-
-static GNUNET_SCHEDULER_TaskIdentifier abort_task;
-
-static GNUNET_SCHEDULER_TaskIdentifier shutdown_task;
-
-
-/**
- * Shutdown nicely
- */
-static void
-do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: shutdown\n");
- if (0 != abort_task)
- {
- GNUNET_SCHEDULER_cancel (abort_task);
- }
- if (NULL != t)
- {
- GNUNET_MESH_tunnel_destroy(t);
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: D1\n");
- if (NULL != mesh_peer_1)
- {
- GNUNET_MESH_disconnect (mesh_peer_1);
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: D2\n");
- if (NULL != mesh_peer_2)
- {
- GNUNET_MESH_disconnect (mesh_peer_2);
- }
-}
-
-
-/**
- * Something went wrong and timed out. Kill everything and set error flag
- */
-static void
-do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: ABORT\n");
- result = GNUNET_SYSERR;
- abort_task = 0;
- if (GNUNET_SCHEDULER_NO_TASK != shutdown_task)
- {
- GNUNET_SCHEDULER_cancel (shutdown_task);
- shutdown_task = GNUNET_SCHEDULER_NO_TASK;
- }
- do_shutdown (cls, tc);
-}
-
-
-/**
- * Function is called whenever a message is received.
- *
- * @param cls closure (set from GNUNET_MESH_connect)
- * @param tunnel connection to the other end
- * @param tunnel_ctx place to store local state associated with the tunnel
- * @param sender who sent the message
- * @param message the actual message
- * @param atsi performance data for the connection
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
- */
-static int
-data_callback (void *cls, struct GNUNET_MESH_Tunnel *tunnel, void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Data callback\n");
- if (GNUNET_SCHEDULER_NO_TASK != shutdown_task)
- GNUNET_SCHEDULER_cancel (shutdown_task);
- shutdown_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS, 2), &do_shutdown,
- NULL);
- return GNUNET_OK;
-}
-
-
-/**
- * Method called whenever another peer has added us to a tunnel
- * the other peer initiated.
- *
- * @param cls closure
- * @param tunnel new handle to the tunnel
- * @param initiator peer that started the tunnel
- * @param atsi performance information for the tunnel
- * @return initial tunnel context for the tunnel (can be NULL -- that's not an error)
- */
-static void *
-inbound_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *initiator,
- const struct GNUNET_ATS_Information *atsi)
-{
- unsigned int id = *(unsigned int *) cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: received incoming tunnel\n");
- if (id != 1)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "test: received incoming tunnel on peer 2\n");
- result = GNUNET_SYSERR;
- }
- return NULL;
-}
-
-
-/**
- * Function called whenever an inbound tunnel is destroyed. Should clean up
- * any associated state.
- *
- * @param cls closure (set from GNUNET_MESH_connect)
- * @param tunnel connection to the other end (henceforth invalid)
- * @param tunnel_ctx place where local state associated
- * with the tunnel is stored
- */
-static void
-inbound_end (void *cls, const struct GNUNET_MESH_Tunnel *tunnel,
- void *tunnel_ctx)
-{
- unsigned int id = *(unsigned int *) cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: incoming tunnel closed\n");
- if (id != 1)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "test: received closing tunnel on peer 2\n");
- result = GNUNET_SYSERR;
- }
-}
-
-
-/**
- * Method called whenever a peer has connected to the tunnel.
- *
- * @param cls closure
- * @param peer peer identity the tunnel stopped working with
- */
-static void
-peer_conected (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_ATS_Information *atsi)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: peer connected\n");
- if (GNUNET_SCHEDULER_NO_TASK != shutdown_task)
- GNUNET_SCHEDULER_cancel(shutdown_task);
- shutdown_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
- &do_shutdown, NULL);
-}
-
-
-/**
- * Method called whenever a peer has connected to the tunnel.
- *
- * @param cls closure
- * @param peer peer identity the tunnel was created to, NULL on timeout
- * @param atsi performance data for the connection
- */
-static void
-peer_disconnected (void *cls, const struct GNUNET_PeerIdentity *peer)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: peer disconnected\n");
-}
-
-
-/**
- * Handler array for traffic received on peer1
- */
-static struct GNUNET_MESH_MessageHandler handlers1[] = {
- {&data_callback, 1, 0},
- {NULL, 0, 0}
-};
-
-
-/**
- * Handler array for traffic received on peer2 (none expected)
- */
-static struct GNUNET_MESH_MessageHandler handlers2[] = { {NULL, 0, 0} };
-
-
-/**
- * Start looking for a peer by type
- */
-static void
-do_find (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: CONNECT BY TYPE\n");
- GNUNET_MESH_peer_request_connect_by_type (t, 1);
-}
-
-
-/**
- * Initialize framework and start test
- */
-static void
-run (void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg,
- struct GNUNET_TESTING_Peer *peer)
-{
- static const GNUNET_MESH_ApplicationType app1[] = { 1, 0 };
- static const GNUNET_MESH_ApplicationType app2[] = { 0 };
-
- abort_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS, 20), &do_abort,
- NULL);
- mesh_peer_1 = GNUNET_MESH_connect (cfg, /* configuration */
- (void *) &one, /* cls */
- &inbound_tunnel, /* inbound new hndlr */
- &inbound_end, /* inbound end hndlr */
- handlers1, /* traffic handlers */
- app1); /* apps offered */
-
- mesh_peer_2 = GNUNET_MESH_connect (cfg, /* configuration */
- (void *) &two, /* cls */
- &inbound_tunnel, /* inbound new hndlr */
- &inbound_end, /* inbound end hndlr */
- handlers2, /* traffic handlers */
- app2); /* apps offered */
- if (NULL == mesh_peer_1 || NULL == mesh_peer_2)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "test: Couldn't connect to mesh :(\n");
- result = GNUNET_SYSERR;
- return;
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: YAY! CONNECTED TO MESH :D\n");
- }
- t = GNUNET_MESH_tunnel_create (mesh_peer_2, NULL, &peer_conected,
- &peer_disconnected, (void *) &two);
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &do_find, NULL);
-}
-
-
-/**
- * Main
- */
-int
-main (int argc, char *argv[])
-{
- if (0 != GNUNET_TESTING_peer_run ("test-mesh-local-1",
- "test_mesh.conf",
- &run, NULL))
- return 1;
- return (result == GNUNET_OK) ? 0 : 1;
-}
-
-/* end of test_mesh_local_1.c */
diff --git a/src/mesh/test_mesh_local_2.c b/src/mesh/test_mesh_local_2.c
deleted file mode 100644
index 935c3b2eb2..0000000000
--- a/src/mesh/test_mesh_local_2.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 2011 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file mesh/test_mesh_local.c
- * @brief test mesh local: test of tunnels with just one peer
- * @author Bartlomiej Polot
- */
-
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_testing_lib.h"
-#include "gnunet_dht_service.h"
-#include "gnunet_mesh_service.h"
-
-static struct GNUNET_MESH_Handle *mesh_peer_1;
-
-static struct GNUNET_MESH_Handle *mesh_peer_2;
-
-static struct GNUNET_MESH_Tunnel *t;
-
-static unsigned int one = 1;
-
-static unsigned int two = 2;
-
-static int result = GNUNET_OK;
-
-static GNUNET_SCHEDULER_TaskIdentifier abort_task;
-
-static GNUNET_SCHEDULER_TaskIdentifier test_task;
-
-
-/**
- * Shutdown nicely
- */
-static void
-do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: shutdown\n");
- if (0 != abort_task)
- {
- GNUNET_SCHEDULER_cancel (abort_task);
- }
- if (NULL != t)
- {
- GNUNET_MESH_tunnel_destroy(t);
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: D1\n");
- if (NULL != mesh_peer_1)
- {
- GNUNET_MESH_disconnect (mesh_peer_1);
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: D2\n");
- if (NULL != mesh_peer_2)
- {
- GNUNET_MESH_disconnect (mesh_peer_2);
- }
-}
-
-
-/**
- * Something went wrong and timed out. Kill everything and set error flag
- */
-static void
-do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: ABORT\n");
- if (0 != test_task)
- {
- GNUNET_SCHEDULER_cancel (test_task);
- }
- result = GNUNET_SYSERR;
- abort_task = 0;
- do_shutdown (cls, tc);
-}
-
-
-/**
- * Function is called whenever a message is received.
- *
- * @param cls closure (set from GNUNET_MESH_connect)
- * @param tunnel connection to the other end
- * @param tunnel_ctx place to store local state associated with the tunnel
- * @param sender who sent the message
- * @param message the actual message
- * @param atsi performance data for the connection
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
- */
-static int
-data_callback (void *cls, struct GNUNET_MESH_Tunnel *tunnel, void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Data callback\n");
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS, 2), &do_shutdown,
- NULL);
- return GNUNET_OK;
-}
-
-
-/**
- * Method called whenever another peer has added us to a tunnel
- * the other peer initiated.
- *
- * @param cls closure
- * @param tunnel new handle to the tunnel
- * @param initiator peer that started the tunnel
- * @param atsi performance information for the tunnel
- * @return initial tunnel context for the tunnel (can be NULL -- that's not an error)
- */
-static void *
-inbound_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *initiator,
- const struct GNUNET_ATS_Information *atsi)
-{
- unsigned int id = *(unsigned int *) cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: received incoming tunnel\n");
- if (id != 1)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "test: received incoming tunnel on peer 2\n");
- result = GNUNET_SYSERR;
- }
- return NULL;
-}
-
-
-/**
- * Function called whenever an inbound tunnel is destroyed. Should clean up
- * any associated state.
- *
- * @param cls closure (set from GNUNET_MESH_connect)
- * @param tunnel connection to the other end (henceforth invalid)
- * @param tunnel_ctx place where local state associated
- * with the tunnel is stored
- */
-static void
-inbound_end (void *cls, const struct GNUNET_MESH_Tunnel *tunnel,
- void *tunnel_ctx)
-{
- unsigned int id = *(unsigned int *) cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: incoming tunnel closed\n");
- if (id != 1)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "test: received closing tunnel on peer 2\n");
- result = GNUNET_SYSERR;
- }
-}
-
-
-/**
- * Method called whenever a peer has disconnected from the tunnel.
- *
- * @param cls closure
- * @param peer peer identity the tunnel stopped working with
- */
-static void
-peer_conected (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_ATS_Information *atsi)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: peer connected\n");
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &do_shutdown, NULL);
-}
-
-
-/**
- * Method called whenever a peer has connected to the tunnel.
- *
- * @param cls closure
- * @param peer peer identity the tunnel was created to, NULL on timeout
- * @param atsi performance data for the connection
- */
-static void
-peer_disconnected (void *cls, const struct GNUNET_PeerIdentity *peer)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: peer disconnected\n");
-}
-
-
-/**
- * Handler array for traffic received on peer1
- */
-static struct GNUNET_MESH_MessageHandler handlers1[] = {
- {&data_callback, 1, 0},
- {NULL, 0, 0}
-};
-
-
-/**
- * Handler array for traffic received on peer2 (none expected)
- */
-static struct GNUNET_MESH_MessageHandler handlers2[] = { {NULL, 0, 0} };
-
-
-/**
- * Start looking for a peer by type
- */
-static void
-do_connect_peer_1 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- const struct GNUNET_CONFIGURATION_Handle *cfg = cls;
- static const GNUNET_MESH_ApplicationType app1[] = { 1, 0 };
-
- test_task = GNUNET_SCHEDULER_NO_TASK;
- mesh_peer_1 = GNUNET_MESH_connect (cfg, /* configuration */
- (void *) &one, /* cls */
- &inbound_tunnel, /* inbound new hndlr */
- &inbound_end, /* inbound end hndlr */
- handlers1, /* traffic handlers */
- app1); /* apps offered */
-}
-
-
-/**
- * Initialize framework and start test
- */
-static void
-run (void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg,
- struct GNUNET_TESTING_Peer *peer)
-{
- static const GNUNET_MESH_ApplicationType app2[] = { 0 };
-
- abort_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS, 20), &do_abort,
- NULL);
- mesh_peer_2 = GNUNET_MESH_connect (cfg, /* configuration */
- (void *) &two, /* cls */
- &inbound_tunnel, /* inbound new hndlr */
- &inbound_end, /* inbound end hndlr */
- handlers2, /* traffic handlers */
- app2); /* apps offered */
- if (NULL == mesh_peer_2)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "test: Couldn't connect to mesh :(\n");
- result = GNUNET_SYSERR;
- return;
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: YAY! CONNECTED TO MESH :D\n");
- }
- t = GNUNET_MESH_tunnel_create (mesh_peer_2, NULL, &peer_conected,
- &peer_disconnected, (void *) &two);
- GNUNET_MESH_peer_request_connect_by_type (t, 1);
- test_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS, 5),
- &do_connect_peer_1, (void*) cfg);
-}
-
-
-/**
- * Main
- */
-int
-main (int argc, char *argv[])
-{
- if (0 != GNUNET_TESTING_peer_run ("test-mesh-local-2",
- "test_mesh.conf",
- &run, NULL))
- return 1;
- return (result == GNUNET_OK) ? 0 : 1;
-}
-
-/* end of test_mesh_local_2.c */
diff --git a/src/mesh/test_mesh_local_traffic.c b/src/mesh/test_mesh_local_traffic.c
deleted file mode 100644
index cd54ea8eb3..0000000000
--- a/src/mesh/test_mesh_local_traffic.c
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 2012 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file mesh/test_mesh_local_traffic.c
- * @brief test mesh local traffic: test of tunnels with just one peer
- * @author Bartlomiej Polot
- */
-
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_mesh_service.h"
-#include "gnunet_testing_lib.h"
-#include <gauger.h>
-
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
-
-#define TARGET 1000
-
-/**
- * DIFFERENT TESTS TO RUN
- */
-#define FWD 0
-#define BCK 1
-#define BOTH 2
-
-
-GNUNET_NETWORK_STRUCT_BEGIN
-
-struct test_traffic_message
-{
- struct GNUNET_MessageHeader header;
- uint32_t data GNUNET_PACKED;
-};
-
-GNUNET_NETWORK_STRUCT_END
-
-
-/** Which test to run, based on executable name */
-static int test;
-
-static int started;
-
-/** How many packets to send from root to leaf */
-static unsigned int to_send_fwd;
-
-/** How many packets to send from leaf to root */
-static unsigned int to_send_bck;
-
-static unsigned int sent_fwd = 0;
-
-static unsigned int got_fwd = 0;
-
-static unsigned int sent_bck = 0;
-
-static unsigned int got_bck = 0;
-
-static struct GNUNET_MESH_Handle *mesh_peer_1;
-
-static struct GNUNET_MESH_Handle *mesh_peer_2;
-
-static struct GNUNET_MESH_Tunnel *t_fwd;
-
-static struct GNUNET_MESH_Tunnel *t_bck;
-
-static unsigned int one = 1;
-
-static unsigned int two = 2;
-
-static int result = GNUNET_SYSERR;
-
-static GNUNET_SCHEDULER_TaskIdentifier abort_task;
-
-static GNUNET_SCHEDULER_TaskIdentifier shutdown_task;
-
-static struct GNUNET_TIME_Absolute start_time;
-
-static struct GNUNET_TIME_Absolute end_time;
-
-static struct GNUNET_PeerIdentity peer_id;
-
-
-/**
- * Shutdown nicely
- */
-static void
-do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutdown\n");
- if (0 != abort_task)
- {
- GNUNET_SCHEDULER_cancel (abort_task);
- }
- if (NULL != t_fwd)
- {
- GNUNET_MESH_tunnel_destroy(t_fwd);
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "D1\n");
- if (NULL != mesh_peer_1)
- {
- GNUNET_MESH_disconnect (mesh_peer_1);
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "D2\n");
- if (NULL != mesh_peer_2)
- {
- GNUNET_MESH_disconnect (mesh_peer_2);
- }
-}
-
-
-/**
- * Something went wrong and timed out. Kill everything and set error flag
- */
-static void
-do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "ABORT\n");
- result = GNUNET_SYSERR;
- abort_task = 0;
- if (GNUNET_SCHEDULER_NO_TASK != shutdown_task)
- {
- GNUNET_SCHEDULER_cancel (shutdown_task);
- shutdown_task = GNUNET_SCHEDULER_NO_TASK;
- }
- do_shutdown (cls, tc);
-}
-
-static void
-finish(void)
-{
- if (GNUNET_SCHEDULER_NO_TASK != shutdown_task)
- GNUNET_SCHEDULER_cancel(shutdown_task);
- shutdown_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
- &do_shutdown, NULL);
-}
-
-
-/**
- * Transmit ready callback.
- *
- * @param cls Closure (peer number of peer sending the data).
- * @param size Buffer size.
- * @param buf Buffer.
- */
-static size_t
-tmt_rdy (void *cls, size_t size, void *buf)
-{
- unsigned int peer_number = *(unsigned int *) cls;
- struct GNUNET_MessageHeader *m = buf;
- struct GNUNET_MESH_Tunnel *t;
- struct test_traffic_message *msg = buf;
- size_t msize = sizeof (struct test_traffic_message);
- unsigned int *sent;
- unsigned int target;
- char *s;
-
- if (0 == size || NULL == buf)
- return 0;
-
- if (1 == peer_number)
- {
- sent = &sent_fwd;
- target = to_send_fwd;
- t = t_fwd;
- s = "FWD";
- }
- else if (2 == peer_number)
- {
- sent = &sent_bck;
- target = to_send_bck;
- t = t_bck;
- s = "BCK";
- }
- else
- GNUNET_abort();
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending %s data packet # %4u\n",
- s, *sent);
- GNUNET_assert (size >= msize);
- if (GNUNET_YES == started)
- {
- (*sent)++;
- if (target > *sent) {
- GNUNET_MESH_notify_transmit_ready (t, GNUNET_NO,
- GNUNET_TIME_UNIT_FOREVER_REL,
- &peer_id, msize, &tmt_rdy, cls);
- }
- }
- m->size = htons (msize);
- m->type = htons (1);
- msg->data = htonl (*sent - 1);
- return msize;
-}
-
-
-/**
- * Function is called whenever a message is received.
- *
- * @param cls closure (set from GNUNET_MESH_connect)
- * @param tunnel connection to the other end
- * @param tunnel_ctx place to store local state associated with the tunnel
- * @param sender who sent the message
- * @param message the actual message
- * @param atsi performance data for the connection
- * @return GNUNET_OK to keep the connection open,
- * GNUNET_SYSERR to close it (signal serious error)
- */
-static int
-data_callback (void *cls, struct GNUNET_MESH_Tunnel *tunnel, void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi)
-{
- struct test_traffic_message *msg;
- unsigned int *peer_number = cls;
- unsigned int *got;
- unsigned int target;
-
- if (GNUNET_NO == started)
- {
- GNUNET_break (2 == *peer_number);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got initial data packet\n");
- started = GNUNET_YES;
- start_time = GNUNET_TIME_absolute_get();
- if (FWD != test) // Send leaf -> root
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending first BCK data\n");
- GNUNET_MESH_notify_transmit_ready (t_bck, GNUNET_NO,
- GNUNET_TIME_UNIT_FOREVER_REL,
- NULL,
- sizeof (struct test_traffic_message),
- &tmt_rdy, &two);
- }
- if (BCK != test) // Send root -> leaf
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending first FWD data\n");
- GNUNET_MESH_notify_transmit_ready (t_fwd, GNUNET_NO,
- GNUNET_TIME_UNIT_FOREVER_REL,
- &peer_id,
- sizeof (struct test_traffic_message),
- &tmt_rdy, &one);
- }
- return GNUNET_OK;
- }
-
- if (*peer_number == 1)
- {
- got = &got_bck;
- target = to_send_bck;
- }
- else if (*peer_number == 2)
- {
- got = &got_fwd;
- target = to_send_fwd;
- }
- else
- {
- GNUNET_abort();
- }
- msg = (struct test_traffic_message *) message;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got data packet # %u [%u]\n",
- ntohl (msg->data), *got + 1);
- (*got)++;
- if (target == *got)
- {
- if (to_send_bck == sent_bck && to_send_fwd == sent_fwd) {
- end_time = GNUNET_TIME_absolute_get();
- result = GNUNET_OK;
- finish();
- }
- return GNUNET_OK;
- }
- if (GNUNET_SCHEDULER_NO_TASK != shutdown_task)
- GNUNET_SCHEDULER_cancel (shutdown_task);
- shutdown_task =
- GNUNET_SCHEDULER_add_delayed (TIMEOUT, &do_shutdown,
- NULL);
- return GNUNET_OK;
-}
-
-
-/**
- * Method called whenever another peer has added us to a tunnel
- * the other peer initiated.
- *
- * @param cls closure
- * @param tunnel new handle to the tunnel
- * @param initiator peer that started the tunnel
- * @param atsi performance information for the tunnel
- * @return initial tunnel context for the tunnel (can be NULL -- that's not an error)
- */
-static void *
-inbound_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *initiator,
- const struct GNUNET_ATS_Information *atsi)
-{
- unsigned int id = *(unsigned int *) cls;
-
- t_bck = tunnel;
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "received incoming tunnel %p\n", tunnel);
- if (id != 2)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "received incoming tunnel on peer 1\n");
- result = GNUNET_SYSERR;
- }
- return NULL;
-}
-
-
-/**
- * Function called whenever an inbound tunnel is destroyed. Should clean up
- * any associated state.
- *
- * @param cls closure (set from GNUNET_MESH_connect)
- * @param tunnel connection to the other end (henceforth invalid)
- * @param tunnel_ctx place where local state associated
- * with the tunnel is stored
- */
-static void
-inbound_end (void *cls, const struct GNUNET_MESH_Tunnel *tunnel,
- void *tunnel_ctx)
-{
- unsigned int id = *(unsigned int *) cls;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "incoming tunnel closed\n");
- if (id != 2)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "received closing tunnel on peer 1\n");
- result = GNUNET_SYSERR;
- }
-}
-
-
-/**
- * Method called whenever a peer has connected to the tunnel.
- *
- * @param cls Closure.
- * @param peer Peer identity of connected peer.
- */
-static void
-peer_connected (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_ATS_Information *atsi)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer connected\n");
- peer_id = *peer;
- /* Force an inbound tunnel notification on peer 2 */
- GNUNET_MESH_notify_transmit_ready (t_fwd, GNUNET_NO, GNUNET_TIME_UNIT_FOREVER_REL,
- peer, sizeof (struct test_traffic_message),
- &tmt_rdy, &one);
-}
-
-
-/**
- * Method called whenever a peer has connected to the tunnel.
- *
- * @param cls closure
- * @param peer peer identity the tunnel was created to, NULL on timeout
- * @param atsi performance data for the connection
- */
-static void
-peer_disconnected (void *cls, const struct GNUNET_PeerIdentity *peer)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer disconnected\n");
-}
-
-
-/**
- * Handler array for traffic received on peer1
- */
-static struct GNUNET_MESH_MessageHandler handlers[] = {
- {&data_callback, 1, sizeof (struct test_traffic_message)},
- {NULL, 0, 0}
-};
-
-
-/**
- * Handler array for traffic received on peer2 (none expected)
- */
-static struct GNUNET_MESH_MessageHandler handlers_null[] = { {NULL, 0, 0} };
-
-
-/**
- * Initialize framework and start test
- */
-static void
-run (void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg,
- struct GNUNET_TESTING_Peer *peer)
-{
- static const GNUNET_MESH_ApplicationType app1[] = { 0 };
- static const GNUNET_MESH_ApplicationType app2[] = { 1, 0 };
-
- abort_task =
- GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
- (GNUNET_TIME_UNIT_SECONDS, 20), &do_abort,
- NULL);
- mesh_peer_1 = GNUNET_MESH_connect (cfg, /* configuration */
- (void *) &one, /* cls */
- NULL, /* inbound new hndlr */
- NULL, /* inbound end hndlr */
- /* traffic handlers */
- test == FWD ? handlers_null : handlers,
- app1); /* apps offered */
-
- mesh_peer_2 = GNUNET_MESH_connect (cfg, /* configuration */
- (void *) &two, /* cls */
- &inbound_tunnel, /* inbound new hndlr */
- &inbound_end, /* inbound end hndlr */
- handlers, /* traffic handlers */
- app2); /* apps offered */
- if (NULL == mesh_peer_1 || NULL == mesh_peer_2)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Couldn't connect to mesh\n");
- result = GNUNET_SYSERR;
- return;
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected to mesh\n");
- }
- t_fwd = GNUNET_MESH_tunnel_create (mesh_peer_1, NULL, &peer_connected,
- &peer_disconnected, (void *) &two);
- GNUNET_MESH_peer_request_connect_by_type (t_fwd, 1);
-}
-
-
-/**
- * Main
- */
-int
-main (int argc, char *argv[])
-{
- if (strstr (argv[0], "test_mesh_local_traffic_fwd") != NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "FWD\n");
- test = FWD;
- to_send_fwd = TARGET;
- }
- else if (strstr (argv[0], "test_mesh_local_traffic_bck") != NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "BCK\n");
- test = BCK;
- to_send_bck = TARGET;
- }
- else if (strstr (argv[0], "test_mesh_local_traffic_both") != NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "BOTH\n");
- test = BOTH;
- to_send_bck = to_send_fwd = TARGET;
- }
- else
- {
- return 1;
- }
-
- if (0 != GNUNET_TESTING_peer_run ("test-mesh-local-traffic",
- "test_mesh.conf",
- &run, NULL))
- return 1;
- if (result != GNUNET_OK)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "Failed.\nFWD expected: %u, Sent: %u, Got: %u\n",
- to_send_fwd, sent_fwd, got_fwd);
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "BCK expected: %u, Sent: %u, Got: %u\n",
- to_send_bck, sent_bck, got_bck);
- return 1;
- }
- else
- {
- struct GNUNET_TIME_Relative total_time;
- unsigned int total_traffic;
- char *name;
-
- total_traffic = BOTH == test ? 2 * TARGET : TARGET;
- switch (test)
- {
- case FWD:
- name = "Local traffic Root to Leaf";
- break;
- case BCK:
- name = "Local traffic Leaf to Root";
- break;
- case BOTH:
- name = "Local traffic bidirectional";
- break;
- default:
- GNUNET_assert (0);
- }
-
- total_time = GNUNET_TIME_absolute_get_difference(start_time, end_time);
- FPRINTF (stderr, "\nTest time %llu ms\n",
- (unsigned long long) total_time.rel_value);
- FPRINTF (stderr, "Test payload bandwidth: %f kb/s\n",
- total_traffic * 4.0 / total_time.rel_value); // 4bytes * kb/ms
- FPRINTF (stderr, "Test throughput: %f packets/s\n\n",
- total_traffic * 1000.0 / total_time.rel_value); // 1000 packets * ms
- GAUGER ("MESH",
- name,
- total_traffic * 1000.0 / total_time.rel_value,
- "packets/s");
- }
- return 0;
-}
-
-/* end of test_mesh_local_traffic.c */
diff --git a/src/mesh/test_mesh_small.c b/src/mesh/test_mesh_small.c
index efe939876f..81f9c566c3 100644
--- a/src/mesh/test_mesh_small.c
+++ b/src/mesh/test_mesh_small.c
@@ -48,11 +48,9 @@
* DIFFERENT TESTS TO RUN
*/
#define SETUP 0
-#define UNICAST 1
-#define MULTICAST 2
+#define FORWARD 1
#define SPEED 3
#define SPEED_ACK 4
-#define SPEED_MIN 5
#define SPEED_NOBUF 6
#define P2P_SIGNAL 10
@@ -97,12 +95,12 @@ size_t size_payload = sizeof (struct GNUNET_MessageHeader) + sizeof (uint32_t);
/**
* Operation to get peer ids.
*/
-struct GNUNET_TESTBED_Operation *t_op[3];
+struct GNUNET_TESTBED_Operation *t_op[2];
/**
* Peer ids.
*/
-struct GNUNET_PeerIdentity *p_id[3];
+struct GNUNET_PeerIdentity *p_id[2];
/**
* Peer ids counter.
@@ -115,11 +113,6 @@ unsigned int p_ids;
static int initialized;
/**
- * Peers that have been connected
- */
-static int peers_in_tunnel;
-
-/**
* Peers that have responded
*/
static int peers_responded;
@@ -175,11 +168,6 @@ static struct GNUNET_MESH_Handle *h1;
static struct GNUNET_MESH_Handle *h2;
/**
- * Mesh handle for the second leaf peer
- */
-static struct GNUNET_MESH_Handle *h3;
-
-/**
* Tunnel handle for the root peer
*/
static struct GNUNET_MESH_Tunnel *t;
@@ -190,11 +178,6 @@ static struct GNUNET_MESH_Tunnel *t;
static struct GNUNET_MESH_Tunnel *incoming_t;
/**
- * Tunnel handle for the second leaf peer
- */
-static struct GNUNET_MESH_Tunnel *incoming_t2;
-
-/**
* Time we started the data transmission (after tunnel has been established
* and initilized).
*/
@@ -251,16 +234,14 @@ disconnect_mesh_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
long line = (long) cls;
unsigned int i;
- for (i = 0; i < 3; i++)
- if (NULL != t_op[i])
- {
- GNUNET_TESTBED_operation_done (t_op[i]);
- t_op[i] = NULL;
- }
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"disconnecting mesh service of peers, called from line %ld\n",
line);
disconnect_task = GNUNET_SCHEDULER_NO_TASK;
+ for (i = 0; i < 2; i++)
+ {
+ GNUNET_TESTBED_operation_done (t_op[i]);
+ }
if (NULL != t)
{
GNUNET_MESH_tunnel_destroy (t);
@@ -271,11 +252,6 @@ disconnect_mesh_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
GNUNET_MESH_tunnel_destroy (incoming_t);
incoming_t = NULL;
}
- if (NULL != incoming_t2)
- {
- GNUNET_MESH_tunnel_destroy (incoming_t2);
- incoming_t2 = NULL;
- }
GNUNET_MESH_TEST_cleanup (test_ctx);
if (GNUNET_SCHEDULER_NO_TASK != shutdown_handle)
{
@@ -290,16 +266,15 @@ disconnect_mesh_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
*
* @param line Line in the code the abort is requested from (__LINE__).
*/
-void
+static void
abort_test (long line)
{
if (disconnect_task != GNUNET_SCHEDULER_NO_TASK)
{
GNUNET_SCHEDULER_cancel (disconnect_task);
+ disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_mesh_peers,
+ (void *) line);
}
- disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
- &disconnect_mesh_peers,
- (void *) line);
}
/**
@@ -326,7 +301,6 @@ data_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_MESH_TransmitHandle *th;
struct GNUNET_MESH_Tunnel *tunnel;
- struct GNUNET_PeerIdentity *destination;
if ((GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason) != 0)
return;
@@ -335,18 +309,14 @@ data_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
if (GNUNET_YES == test_backwards)
{
tunnel = incoming_t;
- destination = p_id[0];
}
else
{
tunnel = t;
- destination = p_id[2];
}
th = GNUNET_MESH_notify_transmit_ready (tunnel, GNUNET_NO,
GNUNET_TIME_UNIT_FOREVER_REL,
- destination,
- size_payload,
- &tmt_rdy, (void *) 1L);
+ size_payload, &tmt_rdy, (void *) 1L);
if (NULL == th)
{
unsigned long i = (unsigned long) cls;
@@ -423,17 +393,13 @@ tmt_rdy (void *cls, size_t size, void *buf)
* @param cls closure (set from GNUNET_MESH_connect)
* @param tunnel connection to the other end
* @param tunnel_ctx place to store local state associated with the tunnel
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
int
data_callback (void *cls, struct GNUNET_MESH_Tunnel *tunnel, void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi)
+ const struct GNUNET_MessageHeader *message)
{
long client = (long) cls;
long expected_target_client;
@@ -441,15 +407,17 @@ data_callback (void *cls, struct GNUNET_MESH_Tunnel *tunnel, void **tunnel_ctx,
ok++;
+ GNUNET_MESH_receive_done (tunnel);
+
if ((ok % 20) == 0)
{
if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
{
GNUNET_SCHEDULER_cancel (disconnect_task);
+ disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
+ &disconnect_mesh_peers,
+ (void *) __LINE__);
}
- disconnect_task =
- GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &disconnect_mesh_peers,
- (void *) __LINE__);
}
switch (client)
@@ -457,10 +425,7 @@ data_callback (void *cls, struct GNUNET_MESH_Tunnel *tunnel, void **tunnel_ctx,
case 0L:
GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Root client got a message!\n");
peers_responded++;
- if (test == MULTICAST && peers_responded < 2)
- return GNUNET_OK;
break;
- case 3L:
case 4L:
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Leaf client %li got a message.\n",
@@ -503,9 +468,8 @@ data_callback (void *cls, struct GNUNET_MESH_Tunnel *tunnel, void **tunnel_ctx,
if (SPEED != test || (ok_goal - 2) == ok)
{
GNUNET_MESH_notify_transmit_ready (tunnel, GNUNET_NO,
- GNUNET_TIME_UNIT_FOREVER_REL, sender,
- size_payload,
- &tmt_rdy, (void *) 1L);
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ size_payload, &tmt_rdy, (void *) 1L);
return GNUNET_OK;
}
else
@@ -522,9 +486,8 @@ data_callback (void *cls, struct GNUNET_MESH_Tunnel *tunnel, void **tunnel_ctx,
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
" received ack %u\n", data_ack);
GNUNET_MESH_notify_transmit_ready (tunnel, GNUNET_NO,
- GNUNET_TIME_UNIT_FOREVER_REL, sender,
- size_payload,
- &tmt_rdy, (void *) 1L);
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ size_payload, &tmt_rdy, (void *) 1L);
if (data_ack < TOTAL_PACKETS && SPEED != test)
return GNUNET_OK;
if (ok == 2 && SPEED == test)
@@ -546,10 +509,10 @@ data_callback (void *cls, struct GNUNET_MESH_Tunnel *tunnel, void **tunnel_ctx,
if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
{
GNUNET_SCHEDULER_cancel (disconnect_task);
+ disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
+ &disconnect_mesh_peers,
+ (void *) __LINE__);
}
- disconnect_task =
- GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &disconnect_mesh_peers,
- (void *) __LINE__);
return GNUNET_OK;
}
@@ -568,17 +531,17 @@ static struct GNUNET_MESH_MessageHandler handlers[] = {
* Method called whenever another peer has added us to a tunnel
* the other peer initiated.
*
- * @param cls closure
- * @param tunnel new handle to the tunnel
- * @param initiator peer that started the tunnel
- * @param atsi performance information for the tunnel
- * @return initial tunnel context for the tunnel
- * (can be NULL -- that's not an error)
+ * @param cls Closure.
+ * @param tunnel New handle to the tunnel.
+ * @param initiator Peer that started the tunnel.
+ * @param port Port this tunnels is connected to.
+ * @return Initial tunnel context for the tunnel
+ * (can be NULL -- that's not an error).
*/
static void *
incoming_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
const struct GNUNET_PeerIdentity *initiator,
- const struct GNUNET_ATS_Information *atsi)
+ uint32_t port)
{
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
"Incoming tunnel from %s to peer %d\n",
@@ -587,8 +550,6 @@ incoming_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok);
if ((long) cls == 4L)
incoming_t = tunnel;
- else if ((long) cls == 3L)
- incoming_t2 = tunnel;
else
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -598,10 +559,10 @@ incoming_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
{
GNUNET_SCHEDULER_cancel (disconnect_task);
+ disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
+ &disconnect_mesh_peers,
+ (void *) __LINE__);
}
- disconnect_task =
- GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &disconnect_mesh_peers,
- (void *) __LINE__);
return NULL;
}
@@ -629,129 +590,22 @@ tunnel_cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel,
ok++;
incoming_t = NULL;
}
- else if (3L == i)
+ else if (0L == i && P2P_SIGNAL == test)
{
- ok++;
- incoming_t2 = NULL;
+ ok ++;
}
else
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Unknown peer! %d\n", i);
GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok);
- peers_in_tunnel--;
- if (peers_in_tunnel > 0)
- return;
if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
{
GNUNET_SCHEDULER_cancel (disconnect_task);
- }
- disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_mesh_peers,
- (void *) __LINE__);
-
- return;
-}
-
-
-/**
- * Method called whenever a tunnel falls apart.
- *
- * @param cls closure
- * @param peer peer identity the tunnel stopped working with
- */
-static void
-dh (void *cls, const struct GNUNET_PeerIdentity *peer)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "peer %s disconnected\n",
- GNUNET_i2s (peer));
- if (P2P_SIGNAL == test)
- {
- ok ++;
- if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
- {
- GNUNET_SCHEDULER_cancel (disconnect_task);
- }
disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_mesh_peers,
(void *) __LINE__);
}
- return;
-}
-
-
-/**
- * Method called whenever a peer connects to a tunnel.
- *
- * @param cls closure
- * @param peer peer identity the tunnel was created to, NULL on timeout
- * @param atsi performance data for the connection
- */
-static void
-ch (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_ATS_Information *atsi)
-{
- long i = (long) cls;
-
- struct GNUNET_PeerIdentity *dest;
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "%ld peer %s connected\n", i, GNUNET_i2s (peer));
-
- if (0 == memcmp (p_id[2], peer, sizeof (struct GNUNET_PeerIdentity)) &&
- i == 0L)
- {
- ok++;
- }
- if (test == MULTICAST &&
- 0 == memcmp (p_id[1], peer, sizeof (struct GNUNET_PeerIdentity)) &&
- i == 0L)
- {
- ok++;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok);
- switch (test)
- {
- case UNICAST:
- case P2P_SIGNAL:
- case SPEED:
- case SPEED_ACK:
- // incoming_t is NULL unless we send a relevant data packet
- dest = p_id[2];
- break;
- case MULTICAST:
- peers_in_tunnel++;
- if (peers_in_tunnel < 2)
- return;
- dest = NULL;
- break;
- default:
- GNUNET_assert (0);
- return;
- }
- if (GNUNET_SCHEDULER_NO_TASK != disconnect_task)
- {
- GNUNET_SCHEDULER_cancel (disconnect_task);
- disconnect_task =
- GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &disconnect_mesh_peers,
- (void *) __LINE__);
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending data initializer...\n");
- peers_responded = 0;
- data_ack = 0;
- data_received = 0;
- data_sent = 0;
- GNUNET_MESH_notify_transmit_ready (t, GNUNET_NO,
- GNUNET_TIME_UNIT_FOREVER_REL, dest,
- size_payload,
- &tmt_rdy, (void *) 1L);
- }
- else
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Disconnect already run?\n");
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Aborting...\n");
- }
return;
}
@@ -770,14 +624,6 @@ do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test_task\n");
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "add peer 2\n");
- GNUNET_MESH_peer_request_connect_add (t, p_id[2]);
-
- if (test == MULTICAST)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "add peer 3\n");
- GNUNET_MESH_peer_request_connect_add (t, p_id[1]);
- }
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"schedule timeout in TIMEOUT\n");
@@ -785,21 +631,37 @@ do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
GNUNET_SCHEDULER_cancel (disconnect_task);
}
- disconnect_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
+ t = GNUNET_MESH_tunnel_create (h1, NULL, p_id[1], 1);
+ if (SPEED_NOBUF == test)
+ {
+ GNUNET_MESH_tunnel_buffer(t, GNUNET_NO);
+ test = SPEED;
+ }
+
+ disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
&disconnect_mesh_peers,
(void *) __LINE__);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending data initializer...\n");
+ peers_responded = 0;
+ data_ack = 0;
+ data_received = 0;
+ data_sent = 0;
+ GNUNET_MESH_notify_transmit_ready (t, GNUNET_NO,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ size_payload, &tmt_rdy, (void *) 1L);
}
/**
* Callback to be called when the requested peer information is available
*
- * @param cls the closure from GNUNET_TETSBED_peer_get_information()
+ * @param cls the closure from GNUNET_TESTBED_peer_get_information()
* @param op the operation this callback corresponds to
* @param pinfo the result; will be NULL if the operation has failed
* @param emsg error message if the operation has failed;
* NULL if the operation is successfull
*/
-void
+static void
pi_cb (void *cls,
struct GNUNET_TESTBED_Operation *op,
const struct GNUNET_TESTBED_PeerInformation *pinfo,
@@ -808,6 +670,7 @@ pi_cb (void *cls,
long i = (long) cls;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "id callback for %ld\n", i);
+
if (NULL == pinfo || NULL != emsg)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "pi_cb: %s\n", emsg);
@@ -817,7 +680,7 @@ pi_cb (void *cls,
p_id[i] = pinfo->result.id;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " id: %s\n", GNUNET_i2s (p_id[i]));
p_ids++;
- if ((MULTICAST == test && p_ids < 3) || p_ids < 2)
+ if (p_ids < 2)
return;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got all IDs, starting test\n");
test_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
@@ -846,18 +709,6 @@ tmain (void *cls,
peers_running = num_peers;
h1 = meshes[0];
h2 = meshes[num_peers - 1];
- t = GNUNET_MESH_tunnel_create (h1, NULL, &ch, &dh, (void *) 0L);
- if (SPEED_MIN == test)
- {
- GNUNET_MESH_tunnel_speed_min(t);
- test = SPEED;
- }
- if (SPEED_NOBUF == test)
- {
- GNUNET_MESH_tunnel_buffer(t, GNUNET_NO);
- test = SPEED;
- }
- peers_in_tunnel = 0;
disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME,
&disconnect_mesh_peers,
(void *) __LINE__);
@@ -866,20 +717,9 @@ tmain (void *cls,
t_op[0] = GNUNET_TESTBED_peer_get_information (peers[0],
GNUNET_TESTBED_PIT_IDENTITY,
&pi_cb, (void *) 0L);
- t_op[2] = GNUNET_TESTBED_peer_get_information (peers[num_peers - 1],
+ t_op[1] = GNUNET_TESTBED_peer_get_information (peers[num_peers - 1],
GNUNET_TESTBED_PIT_IDENTITY,
- &pi_cb, (void *) 2L);
- if (MULTICAST == test)
- {
- h3 = meshes[num_peers - 2];
- t_op[1] = GNUNET_TESTBED_peer_get_information (peers[num_peers - 2],
- GNUNET_TESTBED_PIT_IDENTITY,
- &pi_cb, (void *) 1L);
- }
- else
- {
- t_op[1] = NULL;
- }
+ &pi_cb, (void *) 1L);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "requested peer ids\n");
}
@@ -891,36 +731,29 @@ int
main (int argc, char *argv[])
{
initialized = GNUNET_NO;
+ uint32_t ports[2];
GNUNET_log_setup ("test", "DEBUG", NULL);
-
+
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start\n");
- if (strstr (argv[0], "test_mesh_small_unicast") != NULL)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "UNICAST\n");
- test = UNICAST;
- test_name = "unicast";
- ok_goal = 5;
- }
- else if (strstr (argv[0], "test_mesh_small_multicast") != NULL)
+ if (strstr (argv[0], "_small_forward") != NULL)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MULTICAST\n");
- test = MULTICAST;
- test_name = "multicast";
- ok_goal = 10;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "FORWARD\n");
+ test = FORWARD;
+ test_name = "unicast2";
+ ok_goal = 4;
}
- else if (strstr (argv[0], "test_mesh_small_signal") != NULL)
+ else if (strstr (argv[0], "_small_signal") != NULL)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SIGNAL\n");
test = P2P_SIGNAL;
- test_name = "signal";
- ok_goal = 5;
+ test_name = "signal2";
+ ok_goal = 4;
}
- else if (strstr (argv[0], "test_mesh_small_speed_ack") != NULL)
+ else if (strstr (argv[0], "_small_speed_ack") != NULL)
{
/* Each peer is supposed to generate the following callbacks:
* 1 incoming tunnel (@dest)
- * 1 connected peer (@orig)
* TOTAL_PACKETS received data packet (@dest)
* TOTAL_PACKETS received data packet (@orig)
* 1 received tunnel destroy (@dest)
@@ -929,14 +762,13 @@ main (int argc, char *argv[])
*/
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SPEED_ACK\n");
test = SPEED_ACK;
- test_name = "speed ack";
- ok_goal = TOTAL_PACKETS * 2 + 3;
+ test_name = "speed2 ack";
+ ok_goal = TOTAL_PACKETS * 2 + 2;
}
- else if (strstr (argv[0], "test_mesh_small_speed") != NULL)
+ else if (strstr (argv[0], "_small_speed") != NULL)
{
/* Each peer is supposed to generate the following callbacks:
* 1 incoming tunnel (@dest)
- * 1 connected peer (@orig)
* 1 initial packet (@dest)
* TOTAL_PACKETS received data packet (@dest)
* 1 received data packet (@orig)
@@ -944,21 +776,16 @@ main (int argc, char *argv[])
* _________________________________
*/
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SPEED\n");
- ok_goal = TOTAL_PACKETS + 5;
- if (strstr (argv[0], "_min") != NULL)
- {
- test = SPEED_MIN;
- test_name = "speed min";
- }
- else if (strstr (argv[0], "_nobuf") != NULL)
+ ok_goal = TOTAL_PACKETS + 4;
+ if (strstr (argv[0], "_nobuf") != NULL)
{
test = SPEED_NOBUF;
- test_name = "speed nobuf";
+ test_name = "speed2 nobuf";
}
else
{
test = SPEED;
- test_name = "speed";
+ test_name = "speed2";
}
}
else
@@ -980,15 +807,17 @@ main (int argc, char *argv[])
}
p_ids = 0;
+ ports[0] = 1;
+ ports[1] = 0;
GNUNET_MESH_TEST_run ("test_mesh_small",
- "test_mesh_small.conf",
+ "test_mesh.conf",
5,
&tmain,
- NULL,
+ NULL, /* tmain cls */
&incoming_tunnel,
&tunnel_cleaner,
handlers,
- NULL);
+ ports);
if (ok_goal > ok)
{
@@ -1001,3 +830,4 @@ main (int argc, char *argv[])
}
/* end of test_mesh_small.c */
+
diff --git a/src/mesh/test_mesh_small.conf b/src/mesh/test_mesh_small.conf
deleted file mode 100644
index 943ef3638a..0000000000
--- a/src/mesh/test_mesh_small.conf
+++ /dev/null
@@ -1,78 +0,0 @@
-[PATHS]
-SERVICEHOME = /tmp/test_mesh_small/
-
-[mesh]
-PORT = 10005
-ACCEPT_FROM = 127.0.0.1;
-HOSTNAME = localhost
-REFRESH_PATH_TIME = 5 s
-APP_ANNOUNCE_TIME = 2 s
-ID_ANNOUNCE_TIME = 2 s
-CONNECT_TIMEOUT = 30 s
-DEFAULT_TTL = 64
-DHT_REPLICAITON_LEVEL = 3
-# PREFIX = valgrind --leak-check=full --suppressions=valgrind-mesh.supp
-# PREFIX = xterm -geometry 100x85 -T peer1 -e gdb --args
-
-[testbed]
-NUM_PEERS = 5
-OVERLAY_TOPOLOGY = LINE
-
-[arm]
-PORT = 10010
-DEFAULTSERVICES = core dht mesh
-
-[statistics]
-AUTOSTART = YES
-PORT = 10000
-
-[dht]
-AUTOSTART = YES
-ACCEPT_FROM6 = ::1;
-ACCEPT_FROM = 127.0.0.1;
-HOSTNAME = localhost
-PORT = 10001
-
-[nse]
-WORKBITS = 0
-INTERVAL = 60 s
-WORKDELAY = 500 ms
-
-[dns]
-AUTOSTART = NO
-PORT = 10011
-
-[vpn]
-AUTOSTART = NO
-PORT = 10012
-
-[transport]
-PORT = 10002
-AUTOSTART = YES
-
-[nat]
-DISABLEV6 = YES
-BINDTO = 127.0.0.1
-ENABLE_UPNP = NO
-BEHIND_NAT = NO
-ALLOW_NAT = NO
-INTERNAL_ADDRESS = 127.0.0.1
-EXTERNAL_ADDRESS = 127.0.0.1
-RETURN_LOCAL_ADDRESSES = YES
-USE_LOCALADDR = YES
-
-[ats]
-WAN_QUOTA_IN = 1 GB
-WAN_QUOTA_OUT = 1 GB
-
-[core]
-AUTOSTART = YES
-PORT = 10003
-
-[peerinfo]
-AUTOSTART = YES
-PORT = 10004
-
-[testing]
-WEAKRANDOM = YES
-
diff --git a/src/mesh/test_mesh_tree_api.c b/src/mesh/test_mesh_tree_api.c
deleted file mode 100644
index 3bdb82e0fc..0000000000
--- a/src/mesh/test_mesh_tree_api.c
+++ /dev/null
@@ -1,409 +0,0 @@
-/*
- This file is part of GNUnet.
- (C) 2011 Christian Grothoff (and other contributing authors)
-
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file mesh/test_mesh_tree_api.c
- * @brief test mesh tree api: test of tree & path management api
- * @author Bartlomiej Polot
- */
-
-#include "platform.h"
-#include "gnunet_common.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_dht_service.h"
-#include "gnunet_mesh_service.h"
-#include "mesh.h"
-#ifndef MESH_TUNNEL_TREE_C
-#include "mesh_tunnel_tree.c"
-#define MESH_TUNNEL_TREE_C
-#endif
-
-static int failed;
-static int cb_call;
-static struct GNUNET_PeerIdentity *pi[10];
-static struct MeshTunnelTree *tree;
-
-
-/**
- * Whole tree iterator.
- *
- * @param cls Closure (unused).
- * @param peer_id Short ID of the node.
- * @param parent_id Short ID of the parent node.
- */
-static void
-tree_cb (void *cls, GNUNET_PEER_Id peer_id, GNUNET_PEER_Id parent_id)
-{
- fprintf (stdout, "%u -> %u\n", peer_id, parent_id);;
-}
-
-
-/**
- * Node children iterator.
- *
- * @param cls Closure (unused).
- * @param peer_idShort ID of the child.
- */
-static void
-cb (void *cls, GNUNET_PEER_Id peer_id)
-{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: CB: Disconnected %u\n", peer_id);
- if (0 == cb_call)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: and it shouldn't!\n");
- failed++;
- }
- cb_call--;
-}
-
-
-/**
- * Print debug information about the state of the tree.
- *
- * @param tree Tree to debug-print.
- */
-static void
-test_debug (struct MeshTunnelTree *tree)
-{
- tree_debug (tree);
- tree_iterate_all (tree, &tree_cb, NULL);
-}
-
-
-/**
- * Check if a node has all expected properties.
- *
- * @param peer_id Short ID of the peer to test.
- * @param status Expected status of the peer.
- * @param children Expected number of children of the peer.
- * @param first_hop Short ID of the expected first hop towards the peer.
- */
-static void
-test_assert (GNUNET_PEER_Id peer_id, enum MeshPeerState status,
- unsigned int children, GNUNET_PEER_Id first_hop)
-{
- struct MeshTunnelTreeNode *n;
- struct MeshTunnelTreeNode *c;
- unsigned int i;
- int pre_failed;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Checking peer %u\n", peer_id);
- pre_failed = failed;
- n = tree_find_peer (tree, peer_id);
- if (n->peer != peer_id)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Retrieved peer has wrong ID! (Got %u, expected %u)\n", n->peer,
- peer_id);
- failed++;
- }
- if (n->status != status)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Retrieved peer has wrong status! (Got %u, expected %u)\n",
- n->status, status);
- failed++;
- }
- for (c = n->children_head, i = 0; NULL != c; c = c->next, i++) ;
- if (i != children)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Retrieved peer wrong has number of children! (Got %u, expected %u)\n",
- i, children);
- failed++;
- }
- if (0 != first_hop &&
- GNUNET_PEER_search (tree_get_first_hop (tree, peer_id)) != first_hop)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "Wrong first hop! (Got %u, expected %u)\n",
- GNUNET_PEER_search (tree_get_first_hop (tree, peer_id)),
- first_hop);
- failed++;
- }
- if (pre_failed != failed)
- {
- struct GNUNET_PeerIdentity id;
-
- GNUNET_PEER_resolve (peer_id, &id);
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "*** Peer %s (%u) has failed %d checks!\n", GNUNET_i2s (&id),
- peer_id, failed - pre_failed);
- }
-}
-
-
-/**
- * Clean up and free all memory.
- */
-static void
-finish (void)
-{
- unsigned int i;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Finishing...\n");
- for (i = 0; i < 10; i++)
- {
- GNUNET_free (pi[i]);
- }
-}
-
-/**
- * Convert an integer int to a peer identity
- */
-static struct GNUNET_PeerIdentity *
-get_pi (uint32_t id)
-{
- struct GNUNET_PeerIdentity *pi;
-
- pi = GNUNET_malloc (sizeof (struct GNUNET_PeerIdentity));
- pi->hashPubKey.bits[0] = id + 1;
- return pi;
-}
-
-
-int
-main (int argc, char *argv[])
-{
- struct MeshTunnelTreeNode *node;
- struct MeshPeerPath *path;
- struct MeshPeerPath *path1;
- unsigned int i;
-
- failed = 0;
- cb_call = 0;
- GNUNET_log_setup ("test_mesh_api_tree",
- "WARNING",
- NULL);
- for (i = 0; i < 10; i++)
- {
- pi[i] = get_pi (i);
- GNUNET_break (i + 1 == GNUNET_PEER_intern (pi[i]));
- GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Peer %u: %s\n", i + 1,
- GNUNET_h2s (&pi[i]->hashPubKey));
- }
- tree = tree_new (1);
- tree->me = tree->root;
- path = path_new (5);
- path->peers[0] = 1;
- path->peers[1] = 2;
- path->peers[2] = 3;
- path->peers[3] = 4;
- path->length = 4;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Adding first path: 1 2 3 4\n");
- tree_add_path (tree, path, &cb, NULL);
- test_debug (tree);
- path1 = tree_get_path_to_peer (tree, 4);
- if (NULL == path1 || path->length != path1->length ||
- memcmp (path->peers, path1->peers, path->length) != 0)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Retrieved path != original\n");
- failed++;
- }
- path_destroy (path1);
- test_assert (4, MESH_PEER_SEARCHING, 0, 2);
- test_assert (3, MESH_PEER_RELAY, 1, 0);
- test_assert (2, MESH_PEER_RELAY, 1, 0);
- test_assert (1, MESH_PEER_ROOT, 1, 0);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Adding second path: 1 2 3\n");
- path->length--;
- tree_add_path (tree, path, &cb, NULL);
- test_debug (tree);
-
- test_assert (4, MESH_PEER_SEARCHING, 0, 2);
- test_assert (3, MESH_PEER_SEARCHING, 1, 2);
- test_assert (2, MESH_PEER_RELAY, 1, 0);
- test_assert (1, MESH_PEER_ROOT, 1, 0);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Adding third path 1 2 3 5\n");
- path->length++;
- path->peers[3] = 5;
- tree_add_path (tree, path, &cb, NULL);
- test_debug (tree);
-
- test_assert (5, MESH_PEER_SEARCHING, 0, 2);
- test_assert (4, MESH_PEER_SEARCHING, 0, 2);
- test_assert (3, MESH_PEER_SEARCHING, 2, 2);
- test_assert (2, MESH_PEER_RELAY, 1, 0);
- test_assert (1, MESH_PEER_ROOT, 1, 0);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Calculating costs...\n");
- for (i = 1; i < 5; i++)
- {
- path->length = i;
- if (tree_get_path_cost (tree, path) != 0)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "test: length %u cost failed!\n",
- i);
- failed++;
- }
- }
- path->length++;
- path->peers[4] = 6;
- if (tree_get_path_cost (tree, path) != 1)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "test: length %u cost failed!\n", i);
- failed++;
- }
- path->peers[3] = 7;
- if (tree_get_path_cost (tree, path) != 2)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "test: length %u cost failed!\n", i);
- failed++;
- }
- path->length--;
- if (tree_get_path_cost (tree, path) != 1)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "test: length %u cost failed!\n", i);
- failed++;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Deleting third path (5)\n");
- tree_set_status (tree, 5, MESH_PEER_READY);
- cb_call = 1;
- node = tree_del_path (tree, 5, &cb, NULL);
- test_debug (tree);
- if (cb_call != 0)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%u callbacks missed!\n", cb_call);
- failed++;
- }
- if (node->peer != 5)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Retrieved peer != original\n");
- failed++;
- }
-
- test_assert (4, MESH_PEER_SEARCHING, 0, 2);
- test_assert (3, MESH_PEER_SEARCHING, 1, 2);
- test_assert (2, MESH_PEER_RELAY, 1, 0);
- test_assert (1, MESH_PEER_ROOT, 1, 0);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Destroying node copy...\n");
- GNUNET_free (node);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "test: Adding new shorter first path...\n");
- path->length = 2;
- path->peers[1] = 4;
- cb_call = 1;
- tree_find_peer (tree, 4)->status = MESH_PEER_READY;
- tree_add_path (tree, path, &cb, NULL);
- test_debug (tree);
- if (cb_call != 0)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%u callbacks missed!\n", cb_call);
- failed++;
- }
-
- test_assert (4, MESH_PEER_SEARCHING, 0, 4);
- test_assert (3, MESH_PEER_SEARCHING, 0, 2);
- test_assert (2, MESH_PEER_RELAY, 1, 0);
- test_assert (1, MESH_PEER_ROOT, 2, 0);
-
- GNUNET_free (path->peers);
- GNUNET_free (path);
- tree_destroy (tree);
-
- /****************************************************************************/
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test:\n");
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Testing relay trees\n");
- for (i = 0; i < 10; i++)
- {
- GNUNET_break (i + 1 == GNUNET_PEER_intern (pi[i]));
- }
- tree = tree_new (2);
- path = path_new (8);
- path->peers[0] = 2;
- path->peers[1] = 1;
- path->peers[2] = 3;
- path->length = 3;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Adding first path: 2 1 3\n");
- tree_add_path (tree, path, &cb, NULL);
- test_debug (tree);
-
- test_assert (3, MESH_PEER_SEARCHING, 0, 3);
- test_assert (1, MESH_PEER_RELAY, 1, 0);
- test_assert (2, MESH_PEER_ROOT, 1, 0);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Adding long path: 2 1 4 5 3\n");
- path->peers[2] = 4;
- path->peers[3] = 5;
- path->peers[4] = 3;
- path->length = 5;
- tree_add_path (tree, path, &cb, NULL);
- test_debug (tree);
-
- test_assert (3, MESH_PEER_SEARCHING, 0, 4);
- test_assert (5, MESH_PEER_RELAY, 1, 4);
- test_assert (4, MESH_PEER_RELAY, 1, 4);
- test_assert (1, MESH_PEER_RELAY, 1, 0);
- test_assert (2, MESH_PEER_ROOT, 1, 0);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "test: Even longer path: 2 6 1 7 8 4 5 3\n");
- path->peers[0] = 2;
- path->peers[1] = 6;
- path->peers[2] = 1;
- path->peers[3] = 7;
- path->peers[4] = 8;
- path->peers[5] = 4;
- path->peers[6] = 5;
- path->peers[7] = 3;
- path->length = 8;
- tree_add_path (tree, path, &cb, NULL);
- test_debug (tree);
-
- test_assert (3, MESH_PEER_SEARCHING, 0, 7);
- test_assert (5, MESH_PEER_RELAY, 1, 7);
- test_assert (4, MESH_PEER_RELAY, 1, 7);
- test_assert (8, MESH_PEER_RELAY, 1, 7);
- test_assert (7, MESH_PEER_RELAY, 1, 7);
- test_assert (1, MESH_PEER_RELAY, 1, 0);
- test_assert (6, MESH_PEER_RELAY, 1, 0);
- test_assert (2, MESH_PEER_ROOT, 1, 0);
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Adding first path: 2 1 3\n");
- path->peers[1] = 1;
- path->peers[2] = 3;
- path->length = 3;
- tree_add_path (tree, path, &cb, NULL);
- test_debug (tree);
-
- test_assert (3, MESH_PEER_SEARCHING, 0, 3);
- test_assert (1, MESH_PEER_RELAY, 1, 0);
- test_assert (2, MESH_PEER_ROOT, 1, 0);
-
- GNUNET_free (path->peers);
- GNUNET_free (path);
- tree_destroy (tree);
- finish ();
- if (failed > 0)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "%u tests failed\n", failed);
- return 1;
- }
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: OK\n");
-
- return 0;
-}
diff --git a/src/pt/gnunet-daemon-pt.c b/src/pt/gnunet-daemon-pt.c
index 8044f930c8..466584f0f7 100644
--- a/src/pt/gnunet-daemon-pt.c
+++ b/src/pt/gnunet-daemon-pt.c
@@ -33,6 +33,8 @@
#include "gnunet_statistics_service.h"
#include "gnunet_applications.h"
+#define PORT_PT 4242 // FIXME
+
/**
* After how long do we time out if we could not get an IP from VPN or MESH?
@@ -548,11 +550,11 @@ transmit_dns_request_to_mesh (void *cls,
return 0;
mlen = ntohs (rc->mesh_message->size);
if (mlen > size)
- {
+ {
mesh_th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel,
GNUNET_NO,
TIMEOUT,
- NULL, mlen,
+ mlen,
&transmit_dns_request_to_mesh,
NULL);
return 0;
@@ -571,7 +573,7 @@ transmit_dns_request_to_mesh (void *cls,
mesh_th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel,
GNUNET_NO,
TIMEOUT,
- NULL, ntohs (rc->mesh_message->size),
+ ntohs (rc->mesh_message->size),
&transmit_dns_request_to_mesh,
NULL);
return mlen;
@@ -670,7 +672,7 @@ dns_pre_request_handler (void *cls,
mesh_th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel,
GNUNET_NO,
TIMEOUT,
- NULL, mlen,
+ mlen,
&transmit_dns_request_to_mesh,
NULL);
}
@@ -682,18 +684,15 @@ dns_pre_request_handler (void *cls,
* @param cls closure, NULL
* @param tunnel connection to the other end
* @param tunnel_ctx pointer to our 'struct TunnelState *'
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
+ *
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
receive_dns_response (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_TUN_DnsHeader dns;
size_t mlen;
@@ -772,10 +771,12 @@ abort_all_requests ()
/**
* Method called whenever a peer has disconnected from the tunnel.
*
+ * FIXME merge with inbound cleaner
+ *
* @param cls closure
* @param peer peer identity the tunnel stopped working with
*/
-static void
+void
mesh_disconnect_handler (void *cls,
const struct
GNUNET_PeerIdentity * peer)
@@ -797,11 +798,13 @@ mesh_disconnect_handler (void *cls,
/**
* Method called whenever a peer has connected to the tunnel.
*
+ * FIXME find anouther way (in tmt_ready_callback ?)
+ *
* @param cls closure
* @param peer peer identity the tunnel was created to, NULL on timeout
* @param atsi performance data for the connection
*/
-static void
+void
mesh_connect_handler (void *cls,
const struct GNUNET_PeerIdentity
* peer,
@@ -916,9 +919,6 @@ run (void *cls, char *const *args GNUNET_UNUSED,
{&receive_dns_response, GNUNET_MESSAGE_TYPE_VPN_DNS_FROM_INTERNET, 0},
{NULL, 0, 0}
};
- static GNUNET_MESH_ApplicationType mesh_types[] = {
- GNUNET_APPLICATION_TYPE_END
- };
dns_pre_handle
= GNUNET_DNS_connect (cfg,
@@ -932,8 +932,8 @@ run (void *cls, char *const *args GNUNET_UNUSED,
GNUNET_SCHEDULER_shutdown ();
return;
}
- mesh_handle = GNUNET_MESH_connect (cfg, NULL, NULL, NULL,
- mesh_handlers, mesh_types);
+ mesh_handle = GNUNET_MESH_connect (cfg, NULL, NULL, NULL, // FIXME use end handler
+ mesh_handlers, NULL);
if (NULL == mesh_handle)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -944,11 +944,10 @@ run (void *cls, char *const *args GNUNET_UNUSED,
}
mesh_tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
NULL,
- &mesh_connect_handler,
- &mesh_disconnect_handler,
- NULL);
- GNUNET_MESH_peer_request_connect_by_type (mesh_tunnel,
- GNUNET_APPLICATION_TYPE_INTERNET_RESOLVER);
+ NULL, /* FIXME peer ID*/
+ PORT_PT);
+// GNUNET_MESH_peer_request_connect_by_type (mesh_tunnel, FIXME use regex
+// GNUNET_APPLICATION_TYPE_INTERNET_RESOLVER);
}
}
diff --git a/src/set/Makefile.am b/src/set/Makefile.am
index 68ed551904..f373be20df 100644
--- a/src/set/Makefile.am
+++ b/src/set/Makefile.am
@@ -50,7 +50,7 @@ gnunet_service_set_SOURCES = \
gnunet_service_set_LDADD = \
$(top_builddir)/src/util/libgnunetutil.la \
$(top_builddir)/src/core/libgnunetcore.la \
- $(top_builddir)/src/mesh/libgnunetmesh2.la \
+ $(top_builddir)/src/mesh/libgnunetmesh.la \
$(GN_LIBINTL)
libgnunetset_la_SOURCES = \
diff --git a/src/set/gnunet-service-set.h b/src/set/gnunet-service-set.h
index 26b1d361e5..74cbf584e5 100644
--- a/src/set/gnunet-service-set.h
+++ b/src/set/gnunet-service-set.h
@@ -33,7 +33,7 @@
#include "gnunet_applications.h"
#include "gnunet_util_lib.h"
#include "gnunet_core_service.h"
-#include "gnunet_mesh2_service.h"
+#include "gnunet_mesh_service.h"
#include "gnunet_set_service.h"
#include "set.h"
diff --git a/src/stream/stream_api.c b/src/stream/stream_api.c
index b221d3a1df..f8c0af1cf6 100644
--- a/src/stream/stream_api.c
+++ b/src/stream/stream_api.c
@@ -42,6 +42,8 @@
#include "gnunet_stream_lib.h"
#include "stream.h"
+#define STREAM_PORT 4242
+
/**
* Generic logging shorthand
*/
@@ -311,9 +313,9 @@ struct GNUNET_STREAM_Socket
int transmit_closed;
/**
- * The application port number (type: uint32_t)
+ * The application port number
*/
- GNUNET_MESH_ApplicationType port;
+ uint32_t port;
/**
* The write sequence number to be set incase of testing
@@ -416,7 +418,7 @@ struct GNUNET_STREAM_ListenSocket
/**
* The service port
*/
- GNUNET_MESH_ApplicationType port;
+ uint32_t port;
/**
* The id of the lockmanager timeout task
@@ -651,7 +653,6 @@ send_message_notify (void *cls, size_t size, void *buf)
GNUNET_MESH_notify_transmit_ready (socket->tunnel,
GNUNET_NO, /* Corking */
socket->mesh_retry_timeout,
- &socket->other_peer,
ntohs (head->message->size),
&send_message_notify,
socket);
@@ -679,7 +680,6 @@ send_message_notify (void *cls, size_t size, void *buf)
GNUNET_MESH_notify_transmit_ready (socket->tunnel,
GNUNET_NO, /* Corking */
socket->mesh_retry_timeout,
- &socket->other_peer,
ntohs (head->message->size),
&send_message_notify,
socket);
@@ -739,7 +739,6 @@ queue_message (struct GNUNET_STREAM_Socket *socket,
GNUNET_MESH_notify_transmit_ready (socket->tunnel,
GNUNET_NO, /* Corking */
socket->mesh_retry_timeout,
- &socket->other_peer,
ntohs (message->size),
&send_message_notify,
socket);
@@ -1159,18 +1158,14 @@ read_io_timeout (void *cls,
*
* @param socket the socket through which the ack was received
* @param tunnel connection to the other end
- * @param sender who sent the message
* @param msg the data message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
handle_data (struct GNUNET_STREAM_Socket *socket,
struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_STREAM_DataMessage *msg,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_STREAM_DataMessage *msg)
{
const void *payload;
struct GNUNET_TIME_Relative ack_deadline_rel;
@@ -1185,14 +1180,6 @@ handle_data (struct GNUNET_STREAM_Socket *socket,
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- if (0 != memcmp (sender, &socket->other_peer,
- sizeof (struct GNUNET_PeerIdentity)))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "%s: Received DATA from non-confirming peer\n",
- GNUNET_i2s (&socket->other_peer));
- return GNUNET_YES;
- }
switch (socket->state)
{
case STATE_ESTABLISHED:
@@ -1333,9 +1320,7 @@ handle_data (struct GNUNET_STREAM_Socket *socket,
* @param cls the socket (set from GNUNET_MESH_connect)
* @param tunnel connection to the other end
* @param tunnel_ctx place to store local state associated with the tunnel
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -1343,14 +1328,12 @@ static int
client_handle_data (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = cls;
- return handle_data (socket, tunnel, sender,
- (const struct GNUNET_STREAM_DataMessage *) message, atsi);
+ return handle_data (socket, tunnel,
+ (const struct GNUNET_STREAM_DataMessage *) message);
}
@@ -1598,9 +1581,7 @@ control_retransmission_task (void *cls,
* @param cls the socket (set from GNUNET_MESH_connect)
* @param tunnel connection to the other end
* @param tunnel_ctx this is NULL
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -1608,22 +1589,12 @@ static int
client_handle_hello_ack (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = cls;
const struct GNUNET_STREAM_HelloAckMessage *ack_msg;
struct GNUNET_STREAM_HelloAckMessage *reply;
- if (0 != memcmp (sender, &socket->other_peer,
- sizeof (struct GNUNET_PeerIdentity)))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "%s: Received HELLO_ACK from non-confirming peer\n",
- GNUNET_i2s (&socket->other_peer));
- return GNUNET_YES;
- }
ack_msg = (const struct GNUNET_STREAM_HelloAckMessage *) message;
LOG (GNUNET_ERROR_TYPE_DEBUG, "%s: Received HELLO_ACK from %s\n",
GNUNET_i2s (&socket->other_peer), GNUNET_i2s (&socket->other_peer));
@@ -1661,9 +1632,7 @@ client_handle_hello_ack (void *cls,
* @param cls the socket (set from GNUNET_MESH_connect)
* @param tunnel connection to the other end
* @param tunnel_ctx this is NULL
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -1671,9 +1640,7 @@ static int
client_handle_reset (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
// struct GNUNET_STREAM_Socket *socket = cls;
@@ -1743,18 +1710,14 @@ do_transmit_shutdown (struct GNUNET_STREAM_Socket *socket)
*
* @param socket the socket through which the ack was received
* @param tunnel connection to the other end
- * @param sender who sent the message
* @param msg the transmit close message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
handle_transmit_close (struct GNUNET_STREAM_Socket *socket,
struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *msg,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *msg)
{
struct GNUNET_MessageHeader *reply;
@@ -1802,9 +1765,7 @@ handle_transmit_close (struct GNUNET_STREAM_Socket *socket,
* @param cls the socket (set from GNUNET_MESH_connect)
* @param tunnel connection to the other end
* @param tunnel_ctx this is NULL
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -1812,17 +1773,13 @@ static int
client_handle_transmit_close (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = cls;
return handle_transmit_close (socket,
tunnel,
- sender,
- (struct GNUNET_MessageHeader *)message,
- atsi);
+ (struct GNUNET_MessageHeader *)message);
}
@@ -1853,9 +1810,7 @@ call_cont_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
*
* @param socket the socket
* @param tunnel connection to the other end
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @param operation the close operation which is being ACK'ed
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
@@ -1863,9 +1818,7 @@ call_cont_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
static int
handle_generic_close_ack (struct GNUNET_STREAM_Socket *socket,
struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *sender,
const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi,
int operation)
{
struct GNUNET_STREAM_ShutdownHandle *shutdown_handle;
@@ -1971,9 +1924,7 @@ handle_generic_close_ack (struct GNUNET_STREAM_Socket *socket,
* @param cls the socket (set from GNUNET_MESH_connect)
* @param tunnel connection to the other end
* @param tunnel_ctx this is NULL
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -1981,18 +1932,14 @@ static int
client_handle_transmit_close_ack (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = cls;
return handle_generic_close_ack (socket,
tunnel,
- sender,
(const struct GNUNET_MessageHeader *)
message,
- atsi,
SHUT_WR);
}
@@ -2002,18 +1949,14 @@ client_handle_transmit_close_ack (void *cls,
*
* @param socket the socket
* @param tunnel connection to the other end
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
handle_receive_close (struct GNUNET_STREAM_Socket *socket,
struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_MessageHeader *receive_close_ack;
@@ -2061,9 +2004,7 @@ handle_receive_close (struct GNUNET_STREAM_Socket *socket,
* @param cls the socket (set from GNUNET_MESH_connect)
* @param tunnel connection to the other end
* @param tunnel_ctx this is NULL
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -2071,18 +2012,14 @@ static int
client_handle_receive_close (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = cls;
return
handle_receive_close (socket,
tunnel,
- sender,
- (const struct GNUNET_MessageHeader *) message,
- atsi);
+ (const struct GNUNET_MessageHeader *) message);
}
@@ -2092,9 +2029,7 @@ client_handle_receive_close (void *cls,
* @param cls the socket (set from GNUNET_MESH_connect)
* @param tunnel connection to the other end
* @param tunnel_ctx this is NULL
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -2102,18 +2037,14 @@ static int
client_handle_receive_close_ack (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = cls;
return handle_generic_close_ack (socket,
tunnel,
- sender,
(const struct GNUNET_MessageHeader *)
message,
- atsi,
SHUT_RD);
}
@@ -2123,18 +2054,14 @@ client_handle_receive_close_ack (void *cls,
*
* @param socket the socket
* @param tunnel connection to the other end
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
handle_close (struct GNUNET_STREAM_Socket *socket,
struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_MessageHeader *close_ack;
@@ -2172,9 +2099,7 @@ handle_close (struct GNUNET_STREAM_Socket *socket,
* @param cls the socket (set from GNUNET_MESH_connect)
* @param tunnel connection to the other end
* @param tunnel_ctx this is NULL
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -2182,17 +2107,13 @@ static int
client_handle_close (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = cls;
return handle_close (socket,
tunnel,
- sender,
- (const struct GNUNET_MessageHeader *) message,
- atsi);
+ (const struct GNUNET_MessageHeader *) message);
}
@@ -2202,9 +2123,7 @@ client_handle_close (void *cls,
* @param cls the socket (set from GNUNET_MESH_connect)
* @param tunnel connection to the other end
* @param tunnel_ctx this is NULL
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -2212,18 +2131,14 @@ static int
client_handle_close_ack (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = cls;
return handle_generic_close_ack (socket,
tunnel,
- sender,
(const struct GNUNET_MessageHeader *)
message,
- atsi,
SHUT_RDWR);
}
@@ -2237,9 +2152,7 @@ client_handle_close_ack (void *cls,
* @param cls the closure
* @param tunnel connection to the other end
* @param tunnel_ctx the socket
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -2247,17 +2160,13 @@ static int
server_handle_data (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
return handle_data (socket,
tunnel,
- sender,
- (const struct GNUNET_STREAM_DataMessage *)message,
- atsi);
+ (const struct GNUNET_STREAM_DataMessage *)message);
}
@@ -2267,9 +2176,7 @@ server_handle_data (void *cls,
* @param cls the closure
* @param tunnel connection to the other end
* @param tunnel_ctx the socket
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -2277,9 +2184,7 @@ static int
server_handle_hello (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
const struct GNUNET_STREAM_HelloMessage *hello;
@@ -2287,14 +2192,6 @@ server_handle_hello (void *cls,
uint32_t port;
hello = (const struct GNUNET_STREAM_HelloMessage *) message;
- if (0 != memcmp (sender,
- &socket->other_peer,
- sizeof (struct GNUNET_PeerIdentity)))
- {
- LOG_DEBUG ("%s: Received HELLO from non-confirming peer\n",
- GNUNET_i2s (&socket->other_peer));
- return GNUNET_YES;
- }
GNUNET_assert (GNUNET_MESSAGE_TYPE_STREAM_HELLO == ntohs (message->type));
GNUNET_assert (socket->tunnel == tunnel);
LOG_DEBUG ("%1$s: Received HELLO from %1$s\n",
@@ -2342,9 +2239,7 @@ server_handle_hello (void *cls,
* @param cls the closure
* @param tunnel connection to the other end
* @param tunnel_ctx the socket
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -2352,9 +2247,7 @@ static int
server_handle_hello_ack (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
const struct GNUNET_STREAM_HelloAckMessage *ack_message;
@@ -2393,9 +2286,7 @@ server_handle_hello_ack (void *cls,
* @param cls the closure
* @param tunnel connection to the other end
* @param tunnel_ctx the socket
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -2403,9 +2294,7 @@ static int
server_handle_reset (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
// struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
/* FIXME */
@@ -2419,9 +2308,7 @@ server_handle_reset (void *cls,
* @param cls the closure
* @param tunnel connection to the other end
* @param tunnel_ctx the socket
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -2429,13 +2316,11 @@ static int
server_handle_transmit_close (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
- return handle_transmit_close (socket, tunnel, sender, message, atsi);
+ return handle_transmit_close (socket, tunnel, message);
}
@@ -2445,9 +2330,7 @@ server_handle_transmit_close (void *cls,
* @param cls the closure
* @param tunnel connection to the other end
* @param tunnel_ctx the socket
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -2455,14 +2338,11 @@ static int
server_handle_transmit_close_ack (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
- return handle_generic_close_ack (socket, tunnel, sender, message, atsi,
- SHUT_WR);
+ return handle_generic_close_ack (socket, tunnel, message, SHUT_WR);
}
@@ -2472,9 +2352,7 @@ server_handle_transmit_close_ack (void *cls,
* @param cls the closure
* @param tunnel connection to the other end
* @param tunnel_ctx the socket
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -2482,13 +2360,11 @@ static int
server_handle_receive_close (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
- return handle_receive_close (socket, tunnel, sender, message, atsi);
+ return handle_receive_close (socket, tunnel, message);
}
@@ -2498,9 +2374,7 @@ server_handle_receive_close (void *cls,
* @param cls the closure
* @param tunnel connection to the other end
* @param tunnel_ctx the socket
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -2508,14 +2382,11 @@ static int
server_handle_receive_close_ack (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
- return handle_generic_close_ack (socket, tunnel, sender, message, atsi,
- SHUT_RD);
+ return handle_generic_close_ack (socket, tunnel, message, SHUT_RD);
}
@@ -2526,9 +2397,7 @@ server_handle_receive_close_ack (void *cls,
* GNUNET_STREAM_listen)
* @param tunnel connection to the other end
* @param tunnel_ctx the socket
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -2536,13 +2405,11 @@ static int
server_handle_close (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
- return handle_close (socket, tunnel, sender, message, atsi);
+ return handle_close (socket, tunnel, message);
}
@@ -2552,9 +2419,7 @@ server_handle_close (void *cls,
* @param cls the closure
* @param tunnel connection to the other end
* @param tunnel_ctx the socket
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -2562,14 +2427,11 @@ static int
server_handle_close_ack (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
- return handle_generic_close_ack (socket, tunnel, sender, message, atsi,
- SHUT_RDWR);
+ return handle_generic_close_ack (socket, tunnel, message, SHUT_RDWR);
}
@@ -2578,18 +2440,14 @@ server_handle_close_ack (void *cls,
*
* @param socket the socket through which the ack was received
* @param tunnel connection to the other end
- * @param sender who sent the message
* @param ack the acknowledgment message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
handle_ack (struct GNUNET_STREAM_Socket *socket,
struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_STREAM_AckMessage *ack,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_STREAM_AckMessage *ack)
{
struct GNUNET_STREAM_WriteHandle *write_handle;
uint64_t ack_bitmap;
@@ -2597,15 +2455,6 @@ handle_ack (struct GNUNET_STREAM_Socket *socket,
int need_retransmission;
uint32_t sequence_difference;
- if (0 != memcmp (sender,
- &socket->other_peer,
- sizeof (struct GNUNET_PeerIdentity)))
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG,
- "%s: Received ACK from non-confirming peer\n",
- GNUNET_i2s (&socket->other_peer));
- return GNUNET_YES;
- }
switch (socket->state)
{
case (STATE_ESTABLISHED):
@@ -2734,9 +2583,7 @@ handle_ack (struct GNUNET_STREAM_Socket *socket,
* @param cls the 'struct GNUNET_STREAM_Socket'
* @param tunnel connection to the other end
* @param tunnel_ctx unused
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -2744,15 +2591,13 @@ static int
client_handle_ack (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = cls;
const struct GNUNET_STREAM_AckMessage *ack;
ack = (const struct GNUNET_STREAM_AckMessage *) message;
- return handle_ack (socket, tunnel, sender, ack, atsi);
+ return handle_ack (socket, tunnel, ack);
}
@@ -2762,9 +2607,7 @@ client_handle_ack (void *cls,
* @param cls the server's listen socket
* @param tunnel connection to the other end
* @param tunnel_ctx pointer to the 'struct GNUNET_STREAM_Socket*'
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
@@ -2772,14 +2615,12 @@ static int
server_handle_ack (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information*atsi)
+ const struct GNUNET_MessageHeader *message)
{
struct GNUNET_STREAM_Socket *socket = *tunnel_ctx;
const struct GNUNET_STREAM_AckMessage *ack = (const struct GNUNET_STREAM_AckMessage *) message;
- return handle_ack (socket, tunnel, sender, ack, atsi);
+ return handle_ack (socket, tunnel, ack);
}
@@ -2847,8 +2688,10 @@ static struct GNUNET_MESH_MessageHandler server_message_handlers[] = {
* @param cls the socket for which this tunnel is created
* @param peer the peer identity of the target
* @param atsi performance data for the connection
+ *
+ * FIXME static
*/
-static void
+void
mesh_peer_connect_callback (void *cls,
const struct GNUNET_PeerIdentity *peer,
const struct GNUNET_ATS_Information * atsi)
@@ -2887,8 +2730,10 @@ mesh_peer_connect_callback (void *cls,
*
* @param cls the socket associated which this tunnel
* @param peer the peer identity of the target
+ *
+ * FIXME static
*/
-static void
+void
mesh_peer_disconnect_callback (void *cls,
const struct GNUNET_PeerIdentity *peer)
{
@@ -2906,7 +2751,7 @@ mesh_peer_disconnect_callback (void *cls,
* @param cls closure
* @param tunnel new handle to the tunnel
* @param initiator peer that started the tunnel
- * @param atsi performance information for the tunnel
+ * @param port incoming port
* @return initial tunnel context for the tunnel
* (can be NULL -- that's not an error)
*/
@@ -2914,7 +2759,7 @@ static void *
new_tunnel_notify (void *cls,
struct GNUNET_MESH_Tunnel *tunnel,
const struct GNUNET_PeerIdentity *initiator,
- const struct GNUNET_ATS_Information *atsi)
+ uint32_t port)
{
struct GNUNET_STREAM_ListenSocket *lsocket = cls;
struct GNUNET_STREAM_Socket *socket;
@@ -3067,7 +2912,7 @@ lock_status_change_cb (void *cls, const char *domain, uint32_t lock,
}
if (NULL == lsocket->mesh)
{
- GNUNET_MESH_ApplicationType ports[] = {lsocket->port, 0};
+ uint32_t ports[] = {lsocket->port, 0};
lsocket->mesh = GNUNET_MESH_connect (lsocket->cfg,
lsocket, /* Closure */
@@ -3109,7 +2954,7 @@ lock_status_change_cb (void *cls, const char *domain, uint32_t lock,
struct GNUNET_STREAM_Socket *
GNUNET_STREAM_open (const struct GNUNET_CONFIGURATION_Handle *cfg,
const struct GNUNET_PeerIdentity *target,
- GNUNET_MESH_ApplicationType app_port,
+ uint32_t app_port,
GNUNET_STREAM_OpenCallback open_cb,
void *open_cb_cls,
...)
@@ -3177,13 +3022,10 @@ GNUNET_STREAM_open (const struct GNUNET_CONFIGURATION_Handle *cfg,
/* Now create the mesh tunnel to target */
LOG (GNUNET_ERROR_TYPE_DEBUG, "Creating MESH Tunnel\n");
socket->tunnel = GNUNET_MESH_tunnel_create (socket->mesh,
- NULL, /* Tunnel context */
- &mesh_peer_connect_callback,
- &mesh_peer_disconnect_callback,
- socket);
+ socket, /* Tunnel context */
+ &socket->other_peer,
+ STREAM_PORT);
GNUNET_assert (NULL != socket->tunnel);
- GNUNET_MESH_peer_request_connect_add (socket->tunnel,
- &socket->other_peer);
socket->stat_handle = GNUNET_STATISTICS_create ("stream", cfg);
LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
return socket;
@@ -3388,7 +3230,7 @@ GNUNET_STREAM_close (struct GNUNET_STREAM_Socket *socket)
*/
struct GNUNET_STREAM_ListenSocket *
GNUNET_STREAM_listen (const struct GNUNET_CONFIGURATION_Handle *cfg,
- GNUNET_MESH_ApplicationType app_port,
+ uint32_t app_port,
GNUNET_STREAM_ListenCallback listen_cb,
void *listen_cb_cls,
...)
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c
index bc2327e96a..7844df15b1 100644
--- a/src/vpn/gnunet-service-vpn.c
+++ b/src/vpn/gnunet-service-vpn.c
@@ -50,6 +50,8 @@
#define MAX_MESSAGE_QUEUE_SIZE 4
+#define PORT_VPN 42
+
/**
* State we keep for each of our tunnels.
*/
@@ -601,10 +603,12 @@ destroy_tunnel_task (void *cls,
/**
* Method called whenever a peer has disconnected from the tunnel.
*
+ * FIXME merge with inbound_cleaner
+ *
* @param cls closure
* @param peer peer identity the tunnel stopped working with
*/
-static void
+void
tunnel_peer_disconnect_handler (void *cls,
const struct
GNUNET_PeerIdentity * peer)
@@ -635,11 +639,13 @@ tunnel_peer_disconnect_handler (void *cls,
* Method called whenever a peer has connected to the tunnel. Notifies
* the waiting client that the tunnel is now up.
*
+ * FIXME merge with tunnel_create
+ *
* @param cls closure
* @param peer peer identity the tunnel was created to, NULL on timeout
* @param atsi performance data for the connection
*/
-static void
+void
tunnel_peer_connect_handler (void *cls,
const struct GNUNET_PeerIdentity
* peer,
@@ -699,7 +705,6 @@ send_to_peer_notify_callback (void *cls, size_t size, void *buf)
ts->th = GNUNET_MESH_notify_transmit_ready (ts->tunnel,
GNUNET_NO /* cork */,
GNUNET_TIME_UNIT_FOREVER_REL,
- NULL,
tnq->len,
&send_to_peer_notify_callback,
ts);
@@ -751,7 +756,6 @@ send_to_tunnel (struct TunnelMessageQueueEntry *tnq,
ts->th = GNUNET_MESH_notify_transmit_ready (ts->tunnel,
GNUNET_NO /* cork */,
GNUNET_TIME_UNIT_FOREVER_REL,
- NULL,
tnq->len,
&send_to_peer_notify_callback,
ts);
@@ -782,11 +786,8 @@ handle_regex_result (void *cls,
ts->search = NULL;
ts->tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
ts,
- &tunnel_peer_connect_handler,
- &tunnel_peer_disconnect_handler,
- ts);
- GNUNET_MESH_peer_request_connect_add (ts->tunnel,
- id);
+ id,
+ PORT_VPN);
}
@@ -826,9 +827,8 @@ create_tunnel_to_destination (struct DestinationEntry *de,
{
ts->tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
ts,
- &tunnel_peer_connect_handler,
- &tunnel_peer_disconnect_handler,
- ts);
+ &de->details.service_destination.target,
+ PORT_VPN);
if (NULL == ts->tunnel)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
@@ -840,8 +840,6 @@ create_tunnel_to_destination (struct DestinationEntry *de,
"Creating tunnel to peer %s offering service %s\n",
GNUNET_i2s (&de->details.service_destination.target),
GNUNET_h2s (&de->details.service_destination.service_descriptor));
- GNUNET_MESH_peer_request_connect_add (ts->tunnel,
- &de->details.service_destination.target);
}
else
{
@@ -1741,17 +1739,15 @@ make_up_icmpv6_payload (struct TunnelState *ts,
* @param cls closure, NULL
* @param tunnel connection to the other end
* @param tunnel_ctx pointer to our 'struct TunnelState *'
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
+ *
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
receive_icmp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
- void **tunnel_ctx, const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
+ void **tunnel_ctx,
+ const struct GNUNET_MessageHeader *message)
{
struct TunnelState *ts = *tunnel_ctx;
const struct GNUNET_EXIT_IcmpToVPNMessage *i2v;
@@ -2082,17 +2078,15 @@ receive_icmp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
* @param cls closure, NULL
* @param tunnel connection to the other end
* @param tunnel_ctx pointer to our 'struct TunnelState *'
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
+ *
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
- void **tunnel_ctx, const struct GNUNET_PeerIdentity *sender,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
+ void **tunnel_ctx,
+ const struct GNUNET_MessageHeader *message)
{
struct TunnelState *ts = *tunnel_ctx;
const struct GNUNET_EXIT_UdpReplyMessage *reply;
@@ -2239,18 +2233,15 @@ receive_udp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
* @param cls closure, NULL
* @param tunnel connection to the other end
* @param tunnel_ctx pointer to our 'struct TunnelState *'
- * @param sender who sent the message
* @param message the actual message
- * @param atsi performance data for the connection
+ *
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
receive_tcp_back (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel,
void **tunnel_ctx,
- const struct GNUNET_PeerIdentity *sender GNUNET_UNUSED,
- const struct GNUNET_MessageHeader *message,
- const struct GNUNET_ATS_Information *atsi GNUNET_UNUSED)
+ const struct GNUNET_MessageHeader *message)
{
struct TunnelState *ts = *tunnel_ctx;
const struct GNUNET_EXIT_TcpDataMessage *data;
@@ -2842,32 +2833,11 @@ service_redirect_to_service (void *cls GNUNET_UNUSED, struct GNUNET_SERVER_Clien
}
-
-/**
- * Function called for inbound tunnels. As we don't offer
- * any mesh services, this function should never be called.
- *
- * @param cls closure
- * @param tunnel new handle to the tunnel
- * @param initiator peer that started the tunnel
- * @param atsi performance information for the tunnel
- * @return initial tunnel context for the tunnel
- * (can be NULL -- that's not an error)
- */
-static void *
-inbound_tunnel_cb (void *cls, struct GNUNET_MESH_Tunnel *tunnel,
- const struct GNUNET_PeerIdentity *initiator,
- const struct GNUNET_ATS_Information *atsi)
-{
- /* How can and why should anyone open an inbound tunnel to vpn? */
- GNUNET_break (0);
- return NULL;
-}
-
-
/**
* Function called whenever an inbound tunnel is destroyed. Should clean up
* any associated state.
+ *
+ * FIXME now its also user for disconnections
*
* @param cls closure (set from GNUNET_MESH_connect)
* @param tunnel connection to the other end (henceforth invalid)
@@ -3081,9 +3051,6 @@ run (void *cls,
{ &receive_icmp_back, GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_VPN, 0},
{NULL, 0, 0}
};
- static const GNUNET_MESH_ApplicationType types[] = {
- GNUNET_APPLICATION_TYPE_END
- };
char *ifname;
char *ipv6addr;
char *ipv6prefix_s;
@@ -3209,10 +3176,10 @@ run (void *cls,
mesh_handle =
GNUNET_MESH_connect (cfg_, NULL,
- &inbound_tunnel_cb,
+ NULL,
&tunnel_cleaner,
mesh_handlers,
- types);
+ NULL);
helper_handle = GNUNET_HELPER_start (GNUNET_NO,
"gnunet-helper-vpn", vpn_argv,
&message_token, NULL, NULL);