[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r27784 - in gnunet/src: fs include mesh pt set stream util
From: |
gnunet |
Subject: |
[GNUnet-SVN] r27784 - in gnunet/src: fs include mesh pt set stream util vpn |
Date: |
Mon, 8 Jul 2013 13:04:32 +0200 |
Author: bartpolot
Date: 2013-07-08 13:04:32 +0200 (Mon, 08 Jul 2013)
New Revision: 27784
Modified:
gnunet/src/fs/gnunet-service-fs_mesh.c
gnunet/src/include/gnunet_mesh_service.h
gnunet/src/include/gnunet_protocols.h
gnunet/src/mesh/gnunet-service-mesh.c
gnunet/src/mesh/mesh.h
gnunet/src/mesh/mesh_api.c
gnunet/src/mesh/mesh_protocol.h
gnunet/src/pt/gnunet-daemon-pt.c
gnunet/src/set/gnunet-service-set.c
gnunet/src/stream/stream_api.c
gnunet/src/util/peer.c
gnunet/src/vpn/gnunet-service-vpn.c
Log:
Added mesh reliable tunnels
Modified: gnunet/src/fs/gnunet-service-fs_mesh.c
===================================================================
--- gnunet/src/fs/gnunet-service-fs_mesh.c 2013-07-08 09:52:01 UTC (rev
27783)
+++ gnunet/src/fs/gnunet-service-fs_mesh.c 2013-07-08 11:04:32 UTC (rev
27784)
@@ -452,9 +452,11 @@
&move_to_pending,
sh);
sh->mesh = GNUNET_MESH_tunnel_create (listen_socket,
- sh,
+ sh,
&sh->target,
-
GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER);
+
GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER,
+ GNUNET_YES,
+ GNUNET_YES);
}
@@ -743,7 +745,9 @@
sh->mesh = GNUNET_MESH_tunnel_create (listen_socket,
sh,
&sh->target,
-
GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER);
+
GNUNET_APPLICATION_TYPE_FS_BLOCK_TRANSFER,
+ GNUNET_YES,
+ GNUNET_YES);
GNUNET_assert (GNUNET_OK ==
GNUNET_CONTAINER_multihashmap_put (mesh_map,
&sh->target.hashPubKey,
Modified: gnunet/src/include/gnunet_mesh_service.h
===================================================================
--- gnunet/src/include/gnunet_mesh_service.h 2013-07-08 09:52:01 UTC (rev
27783)
+++ gnunet/src/include/gnunet_mesh_service.h 2013-07-08 11:04:32 UTC (rev
27784)
@@ -195,13 +195,18 @@
* @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.
+ * @param buffer Flag for buffering on relay nodes.
+ * @param reliable Flag for end-to-end reliability.
+ *
* @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);
+ uint32_t port,
+ int buffer,
+ int reliable);
/**
@@ -218,28 +223,35 @@
/**
- * 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.
+ * Struct to retrieve info about a tunnel.
*/
-void
-GNUNET_MESH_tunnel_buffer (struct GNUNET_MESH_Tunnel *tunnel, int buffer);
+struct MeshTunnelInfo {
+ /**
+ * Property, as listed in src/mesh/mesh.h (GNUNET_MESH_OPTION_*)
+ */
+ unsigned int prop;
+ /**
+ * Value, of type dependant on @c prop.
+ */
+ void *value;
+};
+
+
/**
- * Turn on/off the reliability of the tunnel.
+ * Get information about a tunnel.
*
- * If reliability is on, mesh will resend lost messages, similar to TCP.
- * If reliability is off, mesh just do best effort, similar to UDP.
+ * 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.
*
- * @param tunnel Tunnel affected.
- * @param reliable GNUNET_YES to turn reliability on,
- * GNUNET_NO to have a best effort tunnel (default).
+ * @return Allocated, {0, NULL} terminated set of tunnel properties.
*/
-void
-GNUNET_MESH_tunnel_reliable (struct GNUNET_MESH_Tunnel *tunnel, int reliable);
+struct MeshTunnelInfo *
+GNUNET_MESH_tunnel_get_info (struct GNUNET_MESH_Tunnel *tunnel);
/**
Modified: gnunet/src/include/gnunet_protocols.h
===================================================================
--- gnunet/src/include/gnunet_protocols.h 2013-07-08 09:52:01 UTC (rev
27783)
+++ gnunet/src/include/gnunet_protocols.h 2013-07-08 11:04:32 UTC (rev
27784)
@@ -792,9 +792,9 @@
#define GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE 256
/**
- * Request the modification of an existing path
+ * Send origin an ACK that the path is complete
*/
-#define GNUNET_MESSAGE_TYPE_MESH_PATH_CHANGE 257
+#define GNUNET_MESSAGE_TYPE_MESH_PATH_ACK 257
/**
* Notify that a connection of a path is no longer valid
@@ -817,9 +817,9 @@
#define GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN 262
/**
- * Send origin an ACK that the path is complete
+ * Confirm data end-to-end.
*/
-#define GNUNET_MESSAGE_TYPE_MESH_PATH_ACK 263
+#define GNUNET_MESSAGE_TYPE_MESH_DATA_ACK 263
/**
* Avoid path timeouts
@@ -862,51 +862,6 @@
#define GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_DESTROY 274
/**
- * Ask the mesh service to add a peer to an existing tunnel
- */
-#define GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD 275
-
-/**
- * Ask the mesh service to remove a peer from a tunnel
- */
-#define GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL 276
-
-/**
- * Ask the mesh service to add a peer offering a service to an existing tunnel
- */
-#define GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD_BY_TYPE 277
-
-/**
- * Ask the mesh service to add a peer described by a service string
- */
-#define GNUNET_MESSAGE_TYPE_MESH_LOCAL_ANNOUNCE_REGEX 278
-
-/**
- * Ask the mesh service to add a peer described by a service string
- */
-#define GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD_BY_STRING 279
-
-/**
- * Set tunnel to reliable.
- */
-#define GNUNET_MESSAGE_TYPE_MESH_LOCAL_RELIABLE 282
-
-/**
- * Set tunnel to best effort.
- */
-#define GNUNET_MESSAGE_TYPE_MESH_LOCAL_UNRELIABLE 283
-
-/**
- * Set tunnel buffering on.
- */
-#define GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER 284
-
-/**
- * Set tunnel buffering off.
- */
-#define GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_NOBUFFER 285
-
-/**
* Local ACK for data.
*/
#define GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK 286
Modified: gnunet/src/mesh/gnunet-service-mesh.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh.c 2013-07-08 09:52:01 UTC (rev
27783)
+++ gnunet/src/mesh/gnunet-service-mesh.c 2013-07-08 11:04:32 UTC (rev
27784)
@@ -23,12 +23,14 @@
* @brief GNUnet MESH service
* @author Bartlomiej Polot
*
+ * FIXME in progress:
+ * - keep queues until receiving ACK
+ *
* TODO:
* - relay corking down to core
* - set ttl relative to path length
* - add signatures
* - add encryption
- * - keep queues until receiving ACK
* TODO END
*/
@@ -280,6 +282,39 @@
/**
+ * Info needed to retry a message in case it gets lost.
+ */
+struct MeshSentMessage {
+
+ /**
+ * Tunnel this message is in.
+ */
+ struct MeshTunnel *t;
+
+ /**
+ * ID of the message (ACK needed to free)
+ */
+ uint32_t id;
+
+ /**
+ * Task to resend/poll in case no ACK is received.
+ */
+ GNUNET_SCHEDULER_TaskIdentifier retry_task; // FIXME move to per tunnel
timer?
+
+ /**
+ * Counter for exponential backoff.
+ */
+ struct GNUNET_TIME_Relative retry_timer;
+
+ /**
+ * Is this a forward or backward going message?
+ */
+ int is_forward;
+
+ /* struct GNUNET_MESH_Data with payload */
+};
+
+/**
* Struct containing all information regarding a tunnel
* For an intermediate node the improtant info used will be:
* - id Tunnel unique identification
@@ -397,6 +432,18 @@
* Total messages pending for this tunnels, payload or not.
*/
unsigned int pending_messages;
+
+ /**
+ * Messages sent and not yet ACK'd.
+ * Only present (non-NULL) at the owner of a tunnel.
+ */
+ struct GNUNET_CONTAINER_MultiHashMap32 *sent_messages_fwd;
+
+ /**
+ * Messages sent and not yet ACK'd.
+ * Only present (non-NULL) at the destination of a tunnel.
+ */
+ struct GNUNET_CONTAINER_MultiHashMap32 *sent_messages_bck;
};
@@ -1998,10 +2045,13 @@
}
break;
case GNUNET_MESSAGE_TYPE_MESH_ACK:
+ if (NULL != t->owner && GNUNET_YES == t->reliable)
+ return;
case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
break;
case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
case GNUNET_MESSAGE_TYPE_MESH_POLL:
+ case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
t->force_ack = GNUNET_YES;
break;
default:
@@ -2073,10 +2123,13 @@
}
break;
case GNUNET_MESSAGE_TYPE_MESH_ACK:
+ if (NULL != t->client && GNUNET_YES == t->reliable)
+ return;
case GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK:
break;
case GNUNET_MESSAGE_TYPE_MESH_PATH_ACK:
case GNUNET_MESSAGE_TYPE_MESH_POLL:
+ case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
t->force_ack = GNUNET_YES;
break;
default:
@@ -2176,6 +2229,35 @@
/**
+ * We haven't received an ACK after a certain time: restransmit the message.
+ *
+ * @param cls Closure (MeshSentMessage with the message to restransmit)
+ * @param tc TaskContext.
+ */
+static void
+tunnel_retransmit_message (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct MeshSentMessage *copy = cls;
+ struct GNUNET_MESH_Data *payload;
+ GNUNET_PEER_Id hop;
+
+ copy->retry_task = GNUNET_SCHEDULER_NO_TASK;
+ if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+ return;
+
+ payload = (struct GNUNET_MESH_Data *) ©[1];
+ hop = copy->is_forward ? copy->t->next_hop : copy->t->prev_hop;
+ send_prebuilt_message (&payload->header, hop, copy->t);
+ GNUNET_STATISTICS_update (stats, "# unicast retransmitted", 1, GNUNET_NO);
+ copy->retry_timer = GNUNET_TIME_STD_BACKOFF (copy->retry_timer);
+ copy->retry_task = GNUNET_SCHEDULER_add_delayed (copy->retry_timer,
+ &tunnel_retransmit_message,
+ cls);
+}
+
+
+/**
* @brief Re-initiate traffic to this peer if necessary.
*
* Check if there is traffic queued towards this peer
@@ -2519,7 +2601,20 @@
}
+/**
+ * Set options in a tunnel, extracted from a bit flag field
+ *
+ * @param t Tunnel to set options to.
+ * @param options Bit array in host byte order.
+ */
+static void
+tunnel_set_options (struct MeshTunnel *t, uint32_t options)
+{
+ t->nobuffer = options & GNUNET_MESH_OPTION_NOBUFFER;
+ t->reliable = options & GNUNET_MESH_OPTION_RELIABLE;
+}
+
/**
* Iterator for deleting each tunnel whose client endpoint disconnected.
*
@@ -2654,7 +2749,9 @@
opt = 0;
if (GNUNET_YES == t->nobuffer)
- opt |= MESH_TUNNEL_OPT_NOBUFFER;
+ opt |= GNUNET_MESH_OPTION_NOBUFFER;
+ if (GNUNET_YES == t->reliable)
+ opt |= GNUNET_MESH_OPTION_RELIABLE;
msg->opt = htonl (opt);
msg->port = htonl (t->port);
@@ -3148,11 +3245,15 @@
}
t->port = ntohl (msg->port);
opt = ntohl (msg->opt);
- if (0 != (opt & MESH_TUNNEL_OPT_NOBUFFER))
+ if (0 != (opt & GNUNET_MESH_OPTION_NOBUFFER))
{
t->nobuffer = GNUNET_YES;
t->queue_max = 1;
}
+ if (0 != (opt & GNUNET_MESH_OPTION_RELIABLE))
+ {
+ t->reliable = GNUNET_YES;
+ }
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " nobuffer:%d\n", t->nobuffer);
tunnel_reset_timeout (t);
@@ -3228,6 +3329,10 @@
t->local_tid_dest = next_local_tid++;
next_local_tid = next_local_tid | GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
+ if (GNUNET_YES == t->reliable)
+ t->sent_messages_bck =
+ GNUNET_CONTAINER_multihashmap32_create (t->queue_max);
+
tunnel_add_client (t, c);
send_client_tunnel_create (t);
send_path_ack (t);
@@ -3660,6 +3765,86 @@
/**
+ * Core handler for mesh network traffic end-to-end 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_data_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_MessageHeader *message)
+{
+ struct GNUNET_MESH_DataACK *msg;
+ struct GNUNET_CONTAINER_MultiHashMap32 *hm;
+ struct MeshSentMessage *copy;
+ struct MeshTunnel *t;
+ GNUNET_PEER_Id id;
+ uint32_t ack;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a DATA ACK message from %s!\n",
+ GNUNET_i2s (peer));
+ msg = (struct GNUNET_MESH_DataACK *) 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)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " FWD ACK\n");
+ if (NULL == t->owner)
+ {
+ send_prebuilt_message (message, t->prev_hop, t);
+ return GNUNET_OK;
+ }
+ hm = t->sent_messages_fwd;
+ tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_DATA_ACK);
+ }
+ else if (t->prev_hop == id)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " BCK ACK\n");
+ if (NULL == t->client)
+ {
+ send_prebuilt_message (message, t->next_hop, t);
+ return GNUNET_OK;
+ }
+ hm = t->sent_messages_bck;
+ tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_DATA_ACK);
+ }
+ else
+ GNUNET_break_op (0);
+
+ copy = GNUNET_CONTAINER_multihashmap32_get (hm, ack);
+ if (NULL == copy)
+ {
+ GNUNET_break (0); // FIXME needed?
+ return GNUNET_OK;
+ }
+ GNUNET_break (GNUNET_YES ==
+ GNUNET_CONTAINER_multihashmap32_remove (hm, ack, copy));
+ if (GNUNET_SCHEDULER_NO_TASK != copy->retry_task)
+ {
+ GNUNET_SCHEDULER_cancel (copy->retry_task);
+ }
+ else
+ GNUNET_break (0);
+ GNUNET_free (copy);
+ return GNUNET_OK;
+}
+
+/**
* Core handler for mesh network traffic point-to-point acks.
*
* @param cls closure
@@ -3834,9 +4019,11 @@
{&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_to_orig, GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN, 0},
+ {&handle_mesh_data_ack, GNUNET_MESSAGE_TYPE_MESH_DATA_ACK,
+ sizeof (struct GNUNET_MESH_DataACK)},
{&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,
@@ -4189,6 +4376,10 @@
return;
}
t->port = ntohl (t_msg->port);
+ tunnel_set_options (t, ntohl (t_msg->options));
+ if (GNUNET_YES == t->reliable)
+ t->sent_messages_fwd =
+ GNUNET_CONTAINER_multihashmap32_create (t->queue_max);
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);
@@ -4270,120 +4461,6 @@
/**
- * 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 requests of seeting tunnel's reliability policy.
- *
- * @param cls Closure (unused).
- * @param client Identification of the client.
- * @param message The actual message.
- */
-static void
-handle_local_tunnel_reliability (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_RELIABLE:
- t->reliable = GNUNET_YES;
- break;
- case GNUNET_MESSAGE_TYPE_MESH_LOCAL_UNRELIABLE:
- t->reliable = GNUNET_NO;
- break;
- default:
- GNUNET_break (0);
- }
-
- GNUNET_SERVER_receive_done (client, GNUNET_OK);
-}
-
-
-/**
* Handler for client traffic directed to one peer
*
* @param cls closure
@@ -4457,18 +4534,34 @@
* (pretend we got it from a mesh peer)
*/
{
- /* Work around const limitation */
- char buf[ntohs (message->size)] GNUNET_ALIGN;
- struct GNUNET_MESH_Data *copy;
+ struct MeshSentMessage *copy;
+ struct GNUNET_MESH_Data *payload;
- 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);
+ copy = GNUNET_malloc (sizeof (struct MeshSentMessage) + size);
+ copy->id = ntohl (data_msg->pid);
+ copy->is_forward = GNUNET_YES;
+ copy->retry_timer = GNUNET_TIME_UNIT_MINUTES;
+ copy->retry_task = GNUNET_SCHEDULER_add_delayed (copy->retry_timer,
+
&tunnel_retransmit_message,
+ copy);
+ if (GNUNET_OK !=
+ GNUNET_CONTAINER_multihashmap32_put (t->sent_messages_fwd,
+ copy->id,
+ copy,
+
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ payload = (struct GNUNET_MESH_Data *) ©[1];
+ memcpy (payload, data_msg, size);
+ payload->oid = my_full_id;
+ payload->tid = htonl (t->id.tid);
+ payload->ttl = htonl (default_ttl);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" calling generic handler...\n");
- handle_mesh_unicast (NULL, &my_full_id, ©->header);
+ handle_mesh_unicast (NULL, &my_full_id, &payload->header);
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "receive done OK\n");
GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -4562,19 +4655,35 @@
* (pretend we got it from a mesh peer)
*/
{
- char buf[ntohs (message->size)] GNUNET_ALIGN;
- struct GNUNET_MESH_Data *copy;
+ struct MeshSentMessage *copy;
+ struct GNUNET_MESH_Data *payload;
- /* Work around 'const' limitation */
- memcpy (buf, data_msg, size);
- copy = (struct GNUNET_MESH_Data *) buf;
- GNUNET_PEER_resolve (t->id.oid, ©->oid);
- copy->tid = htonl (t->id.tid);
- copy->ttl = htonl (default_ttl);
+ copy = GNUNET_malloc (sizeof (struct MeshSentMessage) + size);
+ copy->id = ntohl (data_msg->pid);
+ copy->is_forward = GNUNET_NO;
+ copy->retry_timer = GNUNET_TIME_UNIT_MINUTES;
+ copy->retry_task = GNUNET_SCHEDULER_add_delayed (copy->retry_timer,
+
&tunnel_retransmit_message,
+ copy);
+ if (GNUNET_OK !=
+ GNUNET_CONTAINER_multihashmap32_put (t->sent_messages_bck,
+ copy->id,
+ copy,
+
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ payload = (struct GNUNET_MESH_Data *) ©[1];
+ memcpy (payload, data_msg, size);
+ GNUNET_PEER_resolve (t->id.oid, &payload->oid);
+ payload->tid = htonl (t->id.tid);
+ payload->ttl = htonl (default_ttl);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
" calling generic handler...\n");
- handle_mesh_to_orig (NULL, &my_full_id, ©->header);
+ handle_mesh_to_orig (NULL, &my_full_id, &payload->header);
}
GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -4789,18 +4898,6 @@
{&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_tunnel_reliability, NULL,
- GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER,
- sizeof (struct GNUNET_MESH_TunnelMessage)},
- {&handle_local_tunnel_reliability, 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,
Modified: gnunet/src/mesh/mesh.h
===================================================================
--- gnunet/src/mesh/mesh.h 2013-07-08 09:52:01 UTC (rev 27783)
+++ gnunet/src/mesh/mesh.h 2013-07-08 11:04:32 UTC (rev 27784)
@@ -88,6 +88,12 @@
#define HIGH_PID 0xFFFF0000
#define LOW_PID 0x0000FFFF
+/**
+ * Value in tunnel info: *int (GNUNET_YES/GNUNET_NO)
+ */
+#define GNUNET_MESH_OPTION_NOBUFFER 0x1
+#define GNUNET_MESH_OPTION_RELIABLE 0x2
+
#define PID_OVERFLOW(pid, max) (pid > HIGH_PID && max < LOW_PID)
/******************************************************************************/
@@ -148,6 +154,11 @@
* Port of the tunnel.
*/
uint32_t port GNUNET_PACKED;
+
+ /**
+ * Options.
+ */
+ int32_t options GNUNET_PACKED;
};
Modified: gnunet/src/mesh/mesh_api.c
===================================================================
--- gnunet/src/mesh/mesh_api.c 2013-07-08 09:52:01 UTC (rev 27783)
+++ gnunet/src/mesh/mesh_api.c 2013-07-08 11:04:32 UTC (rev 27784)
@@ -734,6 +734,7 @@
for (t = h->tunnels_head; NULL != t; t = t->next)
{
struct GNUNET_MESH_TunnelMessage tmsg;
+ uint32_t options;
if (t->tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
{
@@ -751,13 +752,16 @@
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);
+ options = 0;
if (GNUNET_NO == t->buffering)
- GNUNET_MESH_tunnel_buffer (t, GNUNET_NO);
+ options |= GNUNET_MESH_OPTION_NOBUFFER;
if (GNUNET_YES == t->reliable)
- GNUNET_MESH_tunnel_reliable (t, GNUNET_YES);
+ options |= GNUNET_MESH_OPTION_RELIABLE;
+
+ tmsg.options = htonl (options);
+ send_packet (h, &tmsg.header, t);
}
return GNUNET_YES;
}
@@ -831,10 +835,14 @@
t->mesh = h;
t->tid = tid;
t->port = ntohl (msg->port);
- if (0 != (msg->opt & MESH_TUNNEL_OPT_NOBUFFER))
+ if (0 != (msg->opt & GNUNET_MESH_OPTION_NOBUFFER))
t->buffering = GNUNET_NO;
else
t->buffering = GNUNET_YES;
+ if (0 != (msg->opt & GNUNET_MESH_OPTION_RELIABLE))
+ t->reliable = GNUNET_YES;
+ else
+ t->reliable = GNUNET_NO;
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");
@@ -1446,11 +1454,26 @@
}
+/**
+ * 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.
+ * @param buffer Flag for buffering on relay nodes.
+ * @param reliable Flag for end-to-end reliability.
+ *
+ * @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)
+ uint32_t port,
+ int buffer,
+ int reliable)
{
struct GNUNET_MESH_Tunnel *t;
struct GNUNET_MESH_TunnelMessage msg;
@@ -1508,56 +1531,33 @@
}
-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);
-}
-
-
/**
- * Turn on/off the reliability of the tunnel.
+ * Get information about a tunnel.
*
- * If reliability is on, mesh will resend lost messages, similar to TCP.
- * If reliability is off, mesh just do best effort, similar to UDP.
+ * 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.
*
- * @param tunnel Tunnel affected.
- * @param reliable GNUNET_YES to turn reliability on,
- * GNUNET_NO to have a best effort tunnel (default).
+ * @return Allocated, {0, NULL} terminated set of tunnel properties.
*/
-void
-GNUNET_MESH_tunnel_reliable (struct GNUNET_MESH_Tunnel *tunnel, int reliable)
+struct MeshTunnelInfo *
+GNUNET_MESH_tunnel_get_info (struct GNUNET_MESH_Tunnel *tunnel)
{
- struct GNUNET_MESH_TunnelMessage msg;
- struct GNUNET_MESH_Handle *h;
+ struct MeshTunnelInfo *ret;
- h = tunnel->mesh;
- tunnel->reliable = reliable;
+ ret = GNUNET_malloc (sizeof (struct MeshTunnelInfo) * 3);
+ ret[0].prop = GNUNET_MESH_OPTION_NOBUFFER;
+ ret[0].value = &tunnel->buffering; // FIXME return ¬buffering ("nobuffer")
+ ret[1].prop = GNUNET_MESH_OPTION_RELIABLE;
+ ret[1].value = &tunnel->reliable;
+ ret[2].prop = 0;
+ ret[2].value = NULL;
- if (GNUNET_YES == reliable)
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_RELIABLE);
- else
- msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_UNRELIABLE);
- msg.header.size = htons (sizeof (struct GNUNET_MESH_TunnelMessage));
- msg.tunnel_id = htonl (tunnel->tid);
-
- send_packet (h, &msg.header, NULL);
+ return ret;
}
-
struct GNUNET_MESH_TransmitHandle *
GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork,
struct GNUNET_TIME_Relative maxdelay,
Modified: gnunet/src/mesh/mesh_protocol.h
===================================================================
--- gnunet/src/mesh/mesh_protocol.h 2013-07-08 09:52:01 UTC (rev 27783)
+++ gnunet/src/mesh/mesh_protocol.h 2013-07-08 11:04:32 UTC (rev 27784)
@@ -35,9 +35,6 @@
#endif
#endif
-#define MESH_TUNNEL_OPT_NOBUFFER 0x2
-
-
/******************************************************************************/
/******************** MESH NETWORK MESSAGES
**************************/
/******************************************************************************/
@@ -64,7 +61,7 @@
uint32_t tid GNUNET_PACKED;
/**
- * Tunnel options (MESH_TUNNEL_OPT_*).
+ * Tunnel options (GNUNET_MESH_OPTION_*).
*/
uint32_t opt GNUNET_PACKED;
@@ -140,6 +137,40 @@
/**
+ * Message to acknowledge end-to-end data.
+ */
+struct GNUNET_MESH_DataACK
+{
+ /**
+ * Type: GNUNET_MESSAGE_TYPE_MESH_DATA_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 acknowledged.
+ */
+ uint32_t pid;
+
+ /**
+ * Bitfield of already-received newer messages // TODO implement and use
+ * pid + 1 @ LSB
+ * pid + 32 @ MSB
+ */
+ uint32_t futures;
+};
+
+
+/**
* Message to acknowledge mesh data traffic.
*/
struct GNUNET_MESH_ACK
@@ -163,9 +194,9 @@
* Maximum packet ID authorized.
*/
uint32_t pid;
-
};
+
/**
* Message to query a peer about its Flow Control status regarding a tunnel.
*/
Modified: gnunet/src/pt/gnunet-daemon-pt.c
===================================================================
--- gnunet/src/pt/gnunet-daemon-pt.c 2013-07-08 09:52:01 UTC (rev 27783)
+++ gnunet/src/pt/gnunet-daemon-pt.c 2013-07-08 11:04:32 UTC (rev 27784)
@@ -943,9 +943,11 @@
return;
}
mesh_tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
- NULL,
+ NULL,
NULL, /* FIXME peer ID*/
- PORT_PT);
+ PORT_PT,
+ GNUNET_YES,
+ GNUNET_NO);
// GNUNET_MESH_peer_request_connect_by_type (mesh_tunnel, FIXME use regex
//
GNUNET_APPLICATION_TYPE_INTERNET_RESOLVER);
}
Modified: gnunet/src/set/gnunet-service-set.c
===================================================================
--- gnunet/src/set/gnunet-service-set.c 2013-07-08 09:52:01 UTC (rev 27783)
+++ gnunet/src/set/gnunet-service-set.c 2013-07-08 11:04:32 UTC (rev 27784)
@@ -655,7 +655,9 @@
spec->peer = msg->target_peer;
tunnel = GNUNET_MESH_tunnel_create (mesh, tc, &msg->target_peer,
- GNUNET_APPLICATION_TYPE_SET);
+ GNUNET_APPLICATION_TYPE_SET,
+ GNUNET_YES,
+ GNUNET_YES);
switch (set->operation)
{
Modified: gnunet/src/stream/stream_api.c
===================================================================
--- gnunet/src/stream/stream_api.c 2013-07-08 09:52:01 UTC (rev 27783)
+++ gnunet/src/stream/stream_api.c 2013-07-08 11:04:32 UTC (rev 27784)
@@ -3024,7 +3024,7 @@
socket->tunnel = GNUNET_MESH_tunnel_create (socket->mesh,
socket, /* Tunnel context */
&socket->other_peer,
- STREAM_PORT);
+ STREAM_PORT, 1, 0);
GNUNET_assert (NULL != socket->tunnel);
socket->stat_handle = GNUNET_STATISTICS_create ("stream", cfg);
LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
Modified: gnunet/src/util/peer.c
===================================================================
--- gnunet/src/util/peer.c 2013-07-08 09:52:01 UTC (rev 27783)
+++ gnunet/src/util/peer.c 2013-07-08 11:04:32 UTC (rev 27784)
@@ -227,7 +227,7 @@
if (0 == id)
{
memset (pid, 0, sizeof (struct GNUNET_PeerIdentity));
- GNUNET_break (0);
+ GNUNET_assert (0);
return;
}
GNUNET_assert (id < size);
Modified: gnunet/src/vpn/gnunet-service-vpn.c
===================================================================
--- gnunet/src/vpn/gnunet-service-vpn.c 2013-07-08 09:52:01 UTC (rev 27783)
+++ gnunet/src/vpn/gnunet-service-vpn.c 2013-07-08 11:04:32 UTC (rev 27784)
@@ -785,9 +785,11 @@
GNUNET_REGEX_search_cancel (ts->search);
ts->search = NULL;
ts->tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
- ts,
+ ts,
id,
- PORT_VPN);
+ PORT_VPN,
+ GNUNET_YES,
+ GNUNET_NO);
}
@@ -827,8 +829,10 @@
{
ts->tunnel = GNUNET_MESH_tunnel_create (mesh_handle,
ts,
-
&de->details.service_destination.target,
- PORT_VPN);
+ &de->details.service_destination.target,
+ PORT_VPN,
+ GNUNET_YES,
+ GNUNET_NO);
if (NULL == ts->tunnel)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r27784 - in gnunet/src: fs include mesh pt set stream util vpn,
gnunet <=