/**
* Callback called when a queued message is sent.
*
- * Calculates the average time
+ * Calculates the average time and connection packet tracking.
*
* @param cls Closure.
* @param c Connection this message was on.
struct MeshFlowControl *fc;
double usecsperbyte;
+ fc = fwd ? &c->fwd_fc : &c->bck_fc;
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "! Q_N- %p %u\n", fc, fc->queue_n);
+ fc->queue_n--;
+ c->pending_messages--;
+ if (GNUNET_YES == c->destroy && 0 == c->pending_messages)
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "! destroying connection!\n");
+ GMC_destroy (c);
+ }
+ /* Send ACK if needed, after accounting for sent ID in fc->queue_n */
+ switch (type)
+ {
+ case GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED:
+ fc->last_pid_sent++;
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "! accounting pid %u\n", fc->last_pid_sent);
+// send_ack (c, ch, fwd);
+ break;
+ default:
+ break;
+ }
+
if (NULL == c->perf)
- return; /* Only endpoints are interested in this. */
+ return; /* Only endpoints are interested in timing. */
LOG (GNUNET_ERROR_TYPE_DEBUG, "! message sent!\n");
p = c->perf;
}
p->idx = (p->idx + 1) % AVG_MSGS;
- fc = fwd ? &c->fwd_fc : &c->bck_fc;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "! Q_N- %p %u\n", fc, fc->queue_n);
- fc->queue_n--;
- c->pending_messages--;
- if (GNUNET_YES == c->destroy && 0 == c->pending_messages)
- {
- LOG (GNUNET_ERROR_TYPE_DEBUG, "! destroying connection!\n");
- GMC_destroy (c);
- }
- /* Send ACK if needed, after accounting for sent ID in fc->queue_n */
- switch (type)
- {
- case GNUNET_MESSAGE_TYPE_MESH_FWD:
- case GNUNET_MESSAGE_TYPE_MESH_BCK:
- fc->last_pid_sent++;
- LOG (GNUNET_ERROR_TYPE_DEBUG, "! accounting pid %u\n", fc->last_pid_sent);
-// send_ack (c, ch, fwd);
- break;
- default:
- break;
- }
// if (NULL != c->t)
// {
// c->t->pending_messages--;
fwd ? "FWD" : "BCK", GNUNET_h2s (&c->id));
/* Check if we need to transmit the ACK */
- if (prev_fc->last_ack_sent - prev_fc->last_pid_recv > 3)
+ delta = prev_fc->last_ack_sent - prev_fc->last_pid_recv;
+ if (3 < delta && buffer < delta)
{
LOG (GNUNET_ERROR_TYPE_DEBUG, "Not sending ACK, buffer > 3\n");
LOG (GNUNET_ERROR_TYPE_DEBUG,
- " last pid recv: %u, last ack sent: %u\n",
- prev_fc->last_pid_recv, prev_fc->last_ack_sent);
+ " last pid recv: %u, last ack sent: %u\n",
+ prev_fc->last_pid_recv, prev_fc->last_ack_sent);
return;
}
/* Ok, ACK might be necessary, what PID to ACK? */
- delta = next_fc->queue_max - next_fc->queue_n;
- ack = prev_fc->last_pid_recv + delta;
+ ack = prev_fc->last_pid_recv + buffer;
LOG (GNUNET_ERROR_TYPE_DEBUG, " ACK %u\n", ack);
LOG (GNUNET_ERROR_TYPE_DEBUG,
- " last pid %u, last ack %u, qmax %u, q %u\n",
- prev_fc->last_pid_recv, prev_fc->last_ack_sent,
- next_fc->queue_max, next_fc->queue_n);
+ " last pid %u, last ack %u, qmax %u, q %u\n",
+ prev_fc->last_pid_recv, prev_fc->last_ack_sent,
+ next_fc->queue_max, next_fc->queue_n);
if (ack == prev_fc->last_ack_sent)
{
LOG (GNUNET_ERROR_TYPE_DEBUG, "Not sending FWD ACK, not needed\n");
}
+/**
+ * Bind the connection to the peer and the tunnel to that peer.
+ *
+ * If the peer has no tunnel, create one. Update tunnel and connection
+ * data structres to reflect new status.
+ *
+ * @param c Connection.
+ * @param peer Peer.
+ */
+static void
+add_to_peer (struct MeshConnection *c, struct MeshPeer *peer)
+{
+ GMP_add_tunnel (peer);
+ c->t = GMP_get_tunnel (peer);
+ GMT_add_connection (c->t, c);
+}
+
/******************************************************************************/
/******************************** API ***********************************/
/******************************************************************************/
/* create path: self not found in path through self */
GNUNET_break_op (0);
path_destroy (path);
- GMC_destroy (c);
return GNUNET_OK;
}
LOG (GNUNET_ERROR_TYPE_DEBUG, " Own position: %u\n", own_pos);
LOG (GNUNET_ERROR_TYPE_DEBUG, " It's for us!\n");
GMP_add_path_to_origin (orig_peer, path, GNUNET_YES);
- GMP_add_tunnel (orig_peer);
- GMP_add_connection (orig_peer, c);
+ add_to_peer (c, orig_peer);
if (MESH_TUNNEL3_NEW == GMT_get_state (c->t))
GMT_change_state (c->t, MESH_TUNNEL3_WAITING);
*
* @param peer Peer identity this notification is about.
* @param message Encrypted 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)
+ const struct GNUNET_MESH_Encrypted *msg)
{
struct MeshConnection *c;
struct MeshPeer *neighbor;
struct MeshFlowControl *fc;
+ GNUNET_PEER_Id peer_id;
uint32_t pid;
uint32_t ttl;
uint16_t type;
size_t size;
+ int fwd;
/* Check size */
size = ntohs (msg->header.size);
return GNUNET_OK;
}
- fc = fwd ? &c->bck_fc : &c->fwd_fc;
-
/* Check if origin is as expected */
- neighbor = get_hop (c, !fwd);
- if (GNUNET_PEER_search (peer) != GMP_get_short_id (neighbor))
+ neighbor = get_prev_hop (c);
+ peer_id = GNUNET_PEER_search (peer);
+ if (peer_id == GMP_get_short_id (neighbor))
{
- GNUNET_break_op (0);
- return GNUNET_OK;
+ fwd = GNUNET_YES;
+ }
+ else
+ {
+ neighbor = get_next_hop (c);
+ if (peer_id == GMP_get_short_id (neighbor))
+ {
+ fwd = GNUNET_NO;
+ }
+ else
+ {
+ GNUNET_break_op (0);
+ return GNUNET_OK;
+ }
}
+ fc = fwd ? &c->bck_fc : &c->fwd_fc;
/* Check PID */
pid = ntohl (msg->pid);
}
fc->last_pid_recv = pid;
GMT_handle_encrypted (c->t, msg, fwd);
- send_ack (c, NULL, fwd);
+ GMC_send_ack (c, NULL, fwd);
return GNUNET_OK;
}
{
GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
LOG (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
- send_ack (c, NULL, fwd);
+ GMC_send_ack (c, NULL, fwd);
return GNUNET_OK;
}
GNUNET_STATISTICS_update (stats, "# messages forwarded", 1, GNUNET_NO);
/**
- * 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)
- */
-int
-GMC_handle_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.
+ * Core handler for encrypted mesh network traffic (channel mgmt, data).
*
* @param cls Closure (unused).
* @param message Message received.
* GNUNET_SYSERR to close it (signal serious error)
*/
int
-GMC_handle_bck (void *cls, const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message)
+GMC_handle_encrypted (void *cls, const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_MessageHeader *message)
{
return handle_mesh_encrypted (peer,
- (struct GNUNET_MESH_Encrypted *)message,
- GNUNET_NO);
+ (struct GNUNET_MESH_Encrypted *)message);
}
pid, fc->last_pid_recv);
fc->last_pid_recv = pid;
fwd = fc == &c->fwd_fc;
- send_ack (c, NULL, fwd);
+ GMC_send_ack (c, NULL, fwd);
return GNUNET_OK;
}
LOG (GNUNET_ERROR_TYPE_DEBUG,
"send ack %s on %p %p\n",
fwd ? "FWD" : "BCK", c, ch);
+
+ /* Get available bufffer space */
if (NULL == c || GMC_is_terminal (c, fwd))
{
struct MeshTunnel3 *t;
}
LOG (GNUNET_ERROR_TYPE_DEBUG, " buffer available: %u\n", buffer);
+ /* Send available buffer space */
if ( (NULL != ch && GMCH_is_origin (ch, fwd)) ||
(NULL != c && GMC_is_origin (c, fwd)) )
{
{
GNUNET_assert (NULL != ch);
LOG (GNUNET_ERROR_TYPE_DEBUG, " really sending!\n");
- send_local_ack (ch, fwd);
+ GMCH_send_data_ack (ch, fwd);
}
}
else if (NULL == c)
{
LOG (GNUNET_ERROR_TYPE_DEBUG, " sending on all connections\n");
GNUNET_assert (NULL != ch);
- channel_send_connections_ack (ch, buffer, fwd);
+ GMT_send_acks (GMCH_get_tunnel (ch), buffer, fwd);
}
else
{
void
GMC_init (const struct GNUNET_CONFIGURATION_Handle *c)
{
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "init\n");
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_number (c, "MESH", "MAX_MSGS_QUEUE",
&max_msgs_queue))
void
GMC_shutdown (void)
{
+ GNUNET_CONTAINER_multihashmap_destroy (connections);
}
return (fc->queue_max - fc->queue_n);
}
+/**
+ * Get how many messages have we allowed to send to us from a direction..
+ *
+ * @param c Connection.
+ * @param fwd Are we asking about traffic from FWD (BCK messages)?
+ *
+ * @return last_ack_sent - last_pid_recv
+ */
+unsigned int
+GMC_get_allowed (struct MeshConnection *c, int fwd)
+{
+ struct MeshFlowControl *fc;
+
+ fc = fwd ? &c->fwd_fc : &c->bck_fc;
+ if (GMC_is_pid_bigger(fc->last_pid_recv, fc->last_ack_sent))
+ {
+ return 0;
+ }
+ return (fc->last_ack_sent - fc->last_pid_recv);
+}
+
/**
* Get messages queued in a connection.
*
}
+/**
+ * Allow the connection to advertise a buffer of the given size.
+ *
+ * The connection will send an @c fwd ACK message (so: in direction !fwd)
+ * allowing up to last_pid_recv + buffer.
+ *
+ * @param c Connection.
+ * @param buffer How many more messages the connection can accept.
+ * @param fwd Is this about FWD traffic? (The ack will go dest->root).
+ */
+void
+GMC_allow (struct MeshConnection *c, unsigned int buffer, int fwd)
+{
+ connection_send_ack (c, buffer, fwd);
+}
+
+
/**
* Send a notification that a connection is broken.
*
struct GNUNET_MESH_ConnectionBroken *bmsg;
uint32_t ttl;
- case GNUNET_MESSAGE_TYPE_MESH_FWD:
- case GNUNET_MESSAGE_TYPE_MESH_BCK:
+ case GNUNET_MESSAGE_TYPE_MESH_ENCRYPTED:
emsg = (struct GNUNET_MESH_Encrypted *) data;
ttl = ntohl (emsg->ttl);
if (0 == ttl)