gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r16352 - in gnunet/src: include mesh


From: gnunet
Subject: [GNUnet-SVN] r16352 - in gnunet/src: include mesh
Date: Thu, 4 Aug 2011 01:31:50 +0200

Author: bartpolot
Date: 2011-08-04 01:31:50 +0200 (Thu, 04 Aug 2011)
New Revision: 16352

Modified:
   gnunet/src/include/gnunet_protocols.h
   gnunet/src/mesh/gnunet-service-mesh.c
   gnunet/src/mesh/mesh_protocol.h
Log:
Added real ACK for path acknowledgement


Modified: gnunet/src/include/gnunet_protocols.h
===================================================================
--- gnunet/src/include/gnunet_protocols.h       2011-08-03 21:06:53 UTC (rev 
16351)
+++ gnunet/src/include/gnunet_protocols.h       2011-08-03 23:31:50 UTC (rev 
16352)
@@ -825,6 +825,10 @@
  */
 #define GNUNET_MESSAGE_TYPE_DATA_MESSAGE_TO_ORIGIN      262
 
+/**
+ * Send origin an ACK that the path is complete
+ */
+#define GNUNET_MESSAGE_TYPE_PATH_ACK                    263
 
 /**
  * We need flow control

Modified: gnunet/src/mesh/gnunet-service-mesh.c
===================================================================
--- gnunet/src/mesh/gnunet-service-mesh.c       2011-08-03 21:06:53 UTC (rev 
16351)
+++ gnunet/src/mesh/gnunet-service-mesh.c       2011-08-03 23:31:50 UTC (rev 
16352)
@@ -245,7 +245,7 @@
     struct GNUNET_TIME_Absolute timestamp;
 
     /**
-     * Peers in the tunnelindexed by PeerIdentity (MeshPeerInfo)
+     * Peers in the tunnel, indexed by PeerIdentity -> (MeshPeerInfo)
      */
     struct GNUNET_CONTAINER_MultiHashMap* peers;
 
@@ -339,6 +339,11 @@
 static struct GNUNET_DHT_Handle         *dht_handle;
 
 /**
+ * Handle to server
+ */
+static struct GNUNET_SERVER_Handle      *server_handle;
+
+/**
  * Local peer own ID (memory efficient handle)
  */
 static GNUNET_PEER_Id                   myid;
@@ -735,28 +740,29 @@
 {
     /** ID of the tunnel this packet travels in */
     struct MESH_TunnelID        *origin;
-    
+
     /** Ultimate destination of the packet */
     GNUNET_PEER_Id              destination;
-    
+
     /** Number of identical messages sent to different hops (multicast) */
     unsigned int                copies;
-    
+
     /** Size of the data */
     size_t                      size;
-    
+
     /** Client that asked for the transmission, if any */
     struct GNUNET_SERVER_Client *client;
-    
+
     /** Who was this message directed to */
     struct MeshPeerInfo         *peer;
-    
+
     /** Which handler was used to request the transmission */
     unsigned int                handler_n;
-    
+
     /* Data at the end */
 };
 
+#if LATER
 /**
  * Function called to notify a client about the socket
  * being ready to queue more data.  "buf" will be
@@ -797,8 +803,8 @@
     GNUNET_free(info);
     return total_size;
 }
+#endif
 
-
 /**
  * Function called to notify a client about the socket
  * being ready to queue more data.  "buf" will be
@@ -863,7 +869,10 @@
     GNUNET_assert(NULL != info);
     total_size = info->size + sizeof(struct GNUNET_MESH_DataMessageMulticast);
     GNUNET_assert(total_size < GNUNET_SERVER_MAX_MESSAGE_SIZE); 
-    
+
+    if (info->peer) {
+        info->peer->core_transmit[info->handler_n] = NULL;
+    }
     if (total_size > size) {
         GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
                    "not enough buffer to send data futher\n");
@@ -890,6 +899,39 @@
  * NULL and "size" zero if the socket was closed for
  * writing in the meantime.
  *
+ * @param cls closure (MeshDataDescriptor)
+ * @param size number of bytes available in buf
+ * @param buf where the callee should write the message
+ * @return number of bytes written to buf
+ */
+static size_t
+send_core_path_ack (void *cls, size_t size, void *buf) {
+    struct MeshDataDescriptor                   *info = cls;
+    struct GNUNET_MESH_PathACK                  *msg = buf;
+
+    GNUNET_assert(NULL != info);
+    if (info->peer) {
+        info->peer->core_transmit[info->handler_n] = NULL;
+    }
+    if (sizeof(struct GNUNET_MESH_PathACK) > size) {
+        GNUNET_break(0);
+        return 0;
+    }
+    msg->header.size = htons(sizeof(struct GNUNET_MESH_PathACK));
+    msg->header.type = htons(GNUNET_MESSAGE_TYPE_PATH_ACK);
+    GNUNET_PEER_resolve(info->origin->oid, &msg->oid);
+    msg->tid = htonl(info->origin->tid);
+
+    return sizeof(struct GNUNET_MESH_PathACK);
+}
+
+
+/**
+ * Function called to notify a client about the socket
+ * being ready to queue more data.  "buf" will be
+ * NULL and "size" zero if the socket was closed for
+ * writing in the meantime.
+ *
  * @param cls closure (data itself)
  * @param size number of bytes available in buf
  * @param buf where the callee should write the message
@@ -969,35 +1011,34 @@
 
 
 /**
- * Iterator over hash map peer entries to resend a data packet to all peers
- * down the tunnel.
+ * Iterator over hash map peer entries collect all neighbors who to resend the
+ * data to.
  *
- * @param cls closure (original message)
+ * @param cls closure (**GNUNET_PEER_Id to store hops to send packet)
  * @param key current key code (peer id hash)
  * @param value value in the hash map (peer_info)
  * @return GNUNET_YES if we should continue to iterate, GNUNET_NO if not.
  */
-static int iterate_resend_multicast (void *cls,
-                                     const GNUNET_HashCode * key,
-                                     void *value)
+static int iterate_collect_neighbors (void *cls,
+                                      const GNUNET_HashCode * key,
+                                      void *value)
 {
-    struct GNUNET_MESH_DataMessageMulticast     *msg = cls;
-    struct GNUNET_PeerIdentity                  id;
     struct MeshPeerInfo                         *peer_info = value;
+    GNUNET_PEER_Id                              **neighbors = cls;
+    GNUNET_PEER_Id                              id;
+    unsigned int                                i;
 
     if (peer_info->id == myid) {
-//         TODO retransmit to interested clients
         return GNUNET_YES;
     }
-    GNUNET_PEER_resolve(get_first_hop(peer_info->path), &id);
-    GNUNET_CORE_notify_transmit_ready(core_handle,
-                                      0,
-                                      0,
-                                      GNUNET_TIME_UNIT_FOREVER_REL,
-                                      &id,
-                                      ntohs(msg->header.size),
-                                      &send_core_data_raw,
-                                      msg);
+    id = get_first_hop(peer_info->path);
+    for (i = 0; *neighbors[i] != 0; i++) {
+        if (*neighbors[i] == id) return GNUNET_YES;
+    }
+    *neighbors = GNUNET_realloc(*neighbors, (i + 2) * sizeof(GNUNET_PEER_Id));
+    *neighbors[i] = id;
+    *neighbors[i + 1] = 0;
+
     return GNUNET_YES;
 }
 
@@ -1125,21 +1166,31 @@
         return 0;
     }
     if (own_pos == size - 1) { /* it is for us! */
-//         struct MeshDataDescriptor *info;
-        
-        /* FIXME: implement real dedicated ACK */
-//         add_path_to_origin(orig_peer_info, path);           /* inverts 
path!  */
-//         GNUNET_PEER_resolve(get_first_hop(path), &id); /* path is inverted 
:) */
-//         info = GNUNET_malloc(sizeof(struct MeshDataDescriptor));
-//         info->origin = &t->id;
-//         GNUNET_CORE_notify_transmit_ready(core_handle,
-//                                 0,
-//                                 0,
-//                                 GNUNET_TIME_UNIT_FOREVER_REL,
-//                                 &id,
-//                                 sizeof(struct GNUNET_MessageHeader),
-//                                 &send_core_data_to_origin,
-//                                 info);
+        struct MeshDataDescriptor       *info;
+        unsigned int                    j;
+
+        add_path_to_origin(orig_peer_info, path);           /* inverts path!  
*/
+        GNUNET_PEER_resolve(get_first_hop(path), &id); /* path is inverted :) 
*/
+        info = GNUNET_malloc(sizeof(struct MeshDataDescriptor));
+        info->origin = &t->id;
+        info->peer = GNUNET_CONTAINER_multihashmap_get(peers, &id.hashPubKey);
+        GNUNET_assert(info->peer);
+        for (j = 0; info->peer->core_transmit[j]; j++) {
+            if (j == 9) {
+                GNUNET_break(0);
+                return GNUNET_OK;
+            }
+        }
+        info->handler_n = j;
+        info->peer->core_transmit[j] = GNUNET_CORE_notify_transmit_ready(
+                                            core_handle,
+                                            0,
+                                            100,
+                                            GNUNET_TIME_UNIT_FOREVER_REL,
+                                            &id,
+                                            sizeof(struct 
GNUNET_MessageHeader),
+                                            &send_core_path_ack,
+                                            info);
     } else {
         add_path_to_peer(dest_peer_info, path);
         GNUNET_PEER_resolve(get_first_hop(path), &id);
@@ -1248,9 +1299,18 @@
                           *atsi)
 {
     struct GNUNET_MESH_DataMessageMulticast    *msg;
+    struct GNUNET_PeerIdentity                  id;
     struct MeshTunnel                           *t;
+    struct MeshClient                           *c;
+    struct MeshDataDescriptor                   *dd;
+    struct GNUNET_SERVER_NotificationContext    *nc;
+    GNUNET_PEER_Id                              *neighbors;
     size_t                                      size;
+    uint16_t                                    type;
+    uint16_t                                    i;
+    uint16_t                                    j;
 
+
     size = ntohs(message->size);
     if (size < sizeof(struct GNUNET_MESH_DataMessageMulticast)) {
         GNUNET_break_op (0);
@@ -1263,10 +1323,56 @@
         return GNUNET_OK;
     }
 
+    /* Transmit to locally interested clients */
+    GNUNET_PEER_resolve(myid, &id);
+    if (GNUNET_CONTAINER_multihashmap_contains(t->peers, &id.hashPubKey)) {
+        type = ntohs(msg[1].header.type);
+        nc = GNUNET_SERVER_notification_context_create(server_handle, 10U);
+        for (c = clients; c != NULL; c = c->next) {
+            for (i = 0; i < c->type_counter; i++) {
+                if (c->types[i] == type) {
+                    GNUNET_SERVER_notification_context_add(nc, c->handle);
+                }
+            }
+        }
+    }
+
+    /* Retransmit to other peers */
+    neighbors = GNUNET_malloc(sizeof(GNUNET_PEER_Id));
+    neighbors[0] = 0;
     GNUNET_CONTAINER_multihashmap_iterate(t->peers,
-                                          &iterate_resend_multicast,
-                                          msg);
-
+                                          &iterate_collect_neighbors,
+                                          &neighbors);
+    if (!neighbors[0]) {
+        return GNUNET_OK;
+    }
+    size -= sizeof(struct GNUNET_MESH_DataMessageMulticast);
+    dd = GNUNET_malloc(sizeof(struct MeshDataDescriptor) + size);
+    dd->origin = &t->id;
+    dd->copies = 0;
+    for (i = 0; 0 != neighbors[i]; i++) {
+        GNUNET_PEER_resolve(neighbors[i], &id);
+        dd->copies++;
+        dd->destination = neighbors[i];
+        dd->peer = GNUNET_CONTAINER_multihashmap_get(peers, &id.hashPubKey);
+        GNUNET_assert(dd->peer);
+        for (j = 0; dd->peer->core_transmit[j]; j++) {
+            if (j == 9) {
+                GNUNET_break(0);
+                return GNUNET_OK;
+            }
+        }
+        dd->handler_n = j;
+        dd->peer->core_transmit[j] = GNUNET_CORE_notify_transmit_ready(
+                                        core_handle,
+                                        0,
+                                        0,
+                                        GNUNET_TIME_UNIT_FOREVER_REL,
+                                        &id,
+                                        ntohs(msg->header.size),
+                                        &send_core_data_multicast,
+                                        dd);
+    }
     return GNUNET_OK;
 }
 
@@ -2237,6 +2343,7 @@
                 "starting to run\n");
     GNUNET_SERVER_add_handlers (server, plugin_handlers);
     GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
+    server_handle = server;
     core_handle = GNUNET_CORE_connect (c,               /* Main configuration 
*/
                             CORE_QUEUE_SIZE,                    /* queue size 
*/
                             NULL,         /* Closure passed to MESH functions 
*/

Modified: gnunet/src/mesh/mesh_protocol.h
===================================================================
--- gnunet/src/mesh/mesh_protocol.h     2011-08-03 21:06:53 UTC (rev 16351)
+++ gnunet/src/mesh/mesh_protocol.h     2011-08-03 23:31:50 UTC (rev 16352)
@@ -151,7 +151,32 @@
      */
 };
 
+
 /**
+ * Message for ack'ing a path
+ */
+struct GNUNET_MESH_PathACK
+{
+    /**
+     * Type: GNUNET_MESSAGE_TYPE_PATH_ACK
+     */
+    struct GNUNET_MessageHeader header;
+
+    /**
+     * TID of the tunnel
+     */
+    uint32_t                    tid GNUNET_PACKED;
+
+    /**
+     * OID of the tunnel
+     */
+    struct GNUNET_PeerIdentity  oid;
+
+    /* TODO: signature */
+};
+
+
+/**
  * Message for mesh flow control
  */
 struct GNUNET_MESH_SpeedNotify




reply via email to

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