From 6af64edc4f4d40d9c4dfb4c03103dd45d1622438 Mon Sep 17 00:00:00 2001 From: Bart Polot Date: Mon, 5 Aug 2013 09:48:32 +0000 Subject: [PATCH] - wip --- src/mesh/gnunet-service-mesh-enc.c | 197 +++++++++++++++++++++++++++-- 1 file changed, 189 insertions(+), 8 deletions(-) diff --git a/src/mesh/gnunet-service-mesh-enc.c b/src/mesh/gnunet-service-mesh-enc.c index 3b63f517e..91ec2feca 100644 --- a/src/mesh/gnunet-service-mesh-enc.c +++ b/src/mesh/gnunet-service-mesh-enc.c @@ -4712,6 +4712,191 @@ handle_mesh_connection_destroy (void *cls, return GNUNET_OK; } + +/** + * Generic handler for mesh network encrypted traffic. + * + * @param peer Peer identity this notification is about. + * @param message Data message. + * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; + * + * @return GNUNET_OK to keep the connection open, + * GNUNET_SYSERR to close it (signal serious error) + */ +static int +handle_mesh_encrypted (const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MESH_Encrypted *msg, + int fwd) +{ + struct MeshTunnel *t; + struct MeshConnection *c; + GNUNET_PEER_Id hop; + uint32_t pid; + uint32_t ttl; + uint16_t type; + size_t size; + + /* Check size */ + size = ntohs (msg->header.size); + if (size < + sizeof (struct GNUNET_MESH_Encrypted) + + sizeof (struct GNUNET_MessageHeader)) + { + GNUNET_break (0); + return GNUNET_OK; + } + type = ntohs (msg->header.type); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a %s message from %s\n", + GNUNET_MESH_DEBUG_M2S (type), GNUNET_i2s (peer)); + + /* Check connection */ + c = connection_get (&msg->tid, ntohl (msg->cid)); + if (NULL == c) + { + GNUNET_STATISTICS_update (stats, "# unknown connection", 1, GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "WARNING connection unknown\n"); + return GNUNET_OK; + } + t = c->t; + + /* Initialize FWD/BCK data */ + pid = ntohl (msg->pid); + if (GMC_is_pid_bigger (pid, fc->last_ack_sent)) + { + GNUNET_STATISTICS_update (stats, "# unsolicited data", 1, GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "WARNING Received PID %u, (prev %u), ACK %u\n", + pid, fc->last_pid_recv, fc->last_ack_sent); + return GNUNET_OK; + } + if (NULL != c) + tunnel_change_state (t, MESH_TUNNEL_READY); + tunnel_reset_timeout (t, fwd); + if (NULL != c) + { + /* TODO signature verification */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " it's for us! sending to client\n"); + GNUNET_STATISTICS_update (stats, "# data received", 1, GNUNET_NO); + if (GMC_is_pid_bigger (pid, fc->last_pid_recv)) + { + uint32_t mid; + + mid = ntohl (msg->mid); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + " pid %u (mid %u) not seen yet\n", pid, mid); + fc->last_pid_recv = pid; + + if (GNUNET_NO == t->reliable || + ( !GMC_is_pid_bigger (rel->mid_recv, mid) && + GMC_is_pid_bigger (rel->mid_recv + 64, mid) ) ) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "!!! RECV %u\n", ntohl (msg->mid)); + if (GNUNET_YES == t->reliable) + { + /* Is this the exact next expected messasge? */ + if (mid == rel->mid_recv) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "as expected\n"); + rel->mid_recv++; + tunnel_send_client_data (t, msg, fwd); + tunnel_send_client_buffered_data (t, c, rel); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "save for later\n"); + tunnel_add_buffered_data (t, msg, rel); + } + } + else /* Tunnel unreliable, send to clients directly */ + { + tunnel_send_client_data (t, msg, fwd); + } + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + " MID %u not expected (%u - %u), dropping!\n", + ntohl (msg->mid), rel->mid_recv, rel->mid_recv + 64); + } + } + else + { +// GNUNET_STATISTICS_update (stats, "# duplicate PID", 1, GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + " Pid %u not expected (%u+), dropping!\n", + pid, fc->last_pid_recv + 1); + } + tunnel_send_ack (t, type, fwd); + return GNUNET_OK; + } + fc->last_pid_recv = pid; + if (0 == hop) + { + GNUNET_STATISTICS_update (stats, "# data on dying tunnel", 1, GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "data on dying tunnel %s[%X]\n", + GNUNET_PEER_resolve2 (t->id.oid), ntohl (msg->tid)); + return GNUNET_OK; /* Next hop has destoyed the tunnel, drop */ + } + 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_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK, fwd); + return GNUNET_OK; + } + + if (myid != hop) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " not for us, retransmitting...\n"); + send_prebuilt_message (message, hop, t); + GNUNET_STATISTICS_update (stats, "# unicast forwarded", 1, GNUNET_NO); + } + return GNUNET_OK; +} + + +/** + * Core handler for mesh network traffic going orig->dest. + * + * @param cls Closure (unused). + * @param message Message received. + * @param peer Peer who sent the message. + * + * @return GNUNET_OK to keep the connection open, + * GNUNET_SYSERR to close it (signal serious error) + */ +static int +handle_mesh_fwd (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *message) +{ + return handle_mesh_encrypted (peer, + (struct GNUNET_MESH_Encrypted *)message, + GNUNET_YES); +} + +/** + * Core handler for mesh network traffic going dest->orig. + * + * @param cls Closure (unused). + * @param message Message received. + * @param peer Peer who sent the message. + * + * @return GNUNET_OK to keep the connection open, + * GNUNET_SYSERR to close it (signal serious error) + */ +static int +handle_mesh_bck (void *cls, const struct GNUNET_PeerIdentity *peer, + const struct GNUNET_MessageHeader *message) +{ + return handle_mesh_encrypted (peer, + (struct GNUNET_MESH_Encrypted *)message, + GNUNET_NO); +} + + /** * Core handler for mesh network traffic point-to-point acks. * @@ -4913,15 +5098,11 @@ static struct GNUNET_CORE_MessageHandler core_handlers[] = { {&handle_mesh_connection_ack, GNUNET_MESSAGE_TYPE_MESH_CONNECTION_ACK, sizeof (struct GNUNET_MESH_ConnectionACK)}, {&handle_mesh_connection_broken, GNUNET_MESSAGE_TYPE_MESH_CONNECTION_BROKEN, - sizeof (struct GNUNET_MESH_ConnectionBroken)}, + sizeof (struct GNUNET_MESH_ConnectionBroken)}, {&handle_mesh_connection_destroy, GNUNET_MESSAGE_TYPE_MESH_CONNECTION_DESTROY, - sizeof (struct GNUNET_MESH_ConnectionDestroy)}, - {&handle_mesh_unicast, GNUNET_MESSAGE_TYPE_MESH_UNICAST, 0}, - {&handle_mesh_to_orig, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0}, - {&handle_mesh_data_ack, GNUNET_MESSAGE_TYPE_MESH_UNICAST_ACK, - sizeof (struct GNUNET_MESH_DataACK)}, - {&handle_mesh_data_ack, GNUNET_MESSAGE_TYPE_MESH_TO_ORIG_ACK, - sizeof (struct GNUNET_MESH_DataACK)}, + sizeof (struct GNUNET_MESH_ConnectionDestroy)}, + {&handle_mesh_fwd, GNUNET_MESSAGE_TYPE_MESH_FWD, 0}, + {&handle_mesh_bck, GNUNET_MESSAGE_TYPE_MESH_BCK, 0}, {&handle_mesh_keepalive, GNUNET_MESSAGE_TYPE_MESH_FWD_KEEPALIVE, sizeof (struct GNUNET_MESH_TunnelKeepAlive)}, {&handle_mesh_keepalive, GNUNET_MESSAGE_TYPE_MESH_BCK_KEEPALIVE, -- 2.25.1