gnunet-svn
[Top][All Lists]
Advanced

[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 *) &copy[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 *) &copy[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, &copy->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, &copy->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 *) &copy[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, &copy->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,




reply via email to

[Prev in Thread] Current Thread [Next in Thread]