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.
*
{&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,