gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [gnunet] branch master updated (52255b0df -> ec8163cd8)


From: gnunet
Subject: [GNUnet-SVN] [gnunet] branch master updated (52255b0df -> ec8163cd8)
Date: Mon, 23 Jan 2017 14:42:40 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a change to branch master
in repository gnunet.

    from 52255b0df remove actually problematic client_allowed check
     new 64f375591 allow more than one ACK being given to us at a time
     new 60ebf6feb fix shutdown sequence, start to handle loopback
     new 990c75c9d fix unaligned access
     new 4b15b9528 more implementation of loopback handling
     new 160c8ce43 get rid of redundant, confusing state
     new d8d28a68f add generated file to ignore list
     new fdcb76490 handle disconnect properly in test
     new e1ea3b20c beautify disconnect logic a bit
     new f34dc8903 another special case for loopback
     new f39a99866 towards path desirability calculations
     new 55990396c use correct header size calculation in test
     new a970ad152 add sender argument to GCCH_handle_local_data so we can 
implement loopback
     new 098777821 avoid asserting in API on timeout destruction
     new ec8163cd8 more work on loopback, this time payload transmission (for 
now without flow control)

The 14 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/cadet/cadet_api.c                        |  56 +++----
 src/cadet/gnunet-service-cadet-new.c         |  42 +++--
 src/cadet/gnunet-service-cadet-new.h         |   5 +
 src/cadet/gnunet-service-cadet-new_channel.c | 236 ++++++++++++++++++---------
 src/cadet/gnunet-service-cadet-new_channel.h |  16 +-
 src/cadet/gnunet-service-cadet-new_paths.c   |  21 ++-
 src/cadet/gnunet-service-cadet-new_tunnels.c |  24 +++
 src/cadet/test_cadet_single.c                |  37 +++--
 src/nat/gnunet-service-nat.c                 |  22 ++-
 src/util/.gitignore                          |   1 +
 10 files changed, 296 insertions(+), 164 deletions(-)

diff --git a/src/cadet/cadet_api.c b/src/cadet/cadet_api.c
index 750e70e29..de10d5809 100644
--- a/src/cadet/cadet_api.c
+++ b/src/cadet/cadet_api.c
@@ -256,11 +256,6 @@ struct GNUNET_CADET_Channel
   void *ctx;
 
   /**
-   * Size of packet queued in this channel
-   */
-  unsigned int packet_size;
-
-  /**
    * Channel options: reliability, etc.
    */
   enum GNUNET_CADET_ChannelOption options;
@@ -268,7 +263,7 @@ struct GNUNET_CADET_Channel
   /**
    * Are we allowed to send to the service?
    */
-  int allow_send;
+  unsigned int allow_send;
 
 };
 
@@ -413,7 +408,6 @@ create_channel (struct GNUNET_CADET_Handle *h,
   {
     ch->ccn = ccn;
   }
-  ch->allow_send = GNUNET_NO;
   return ch;
 }
 
@@ -481,7 +475,6 @@ destroy_channel (struct GNUNET_CADET_Channel *ch,
   if (0 != ch->peer)
     GNUNET_PEER_change_rc (ch->peer, -1);
   GNUNET_free (ch);
-
 }
 
 
@@ -568,10 +561,11 @@ request_data (void *cls)
        "Requesting Data: %u bytes\n",
        th->size);
 
-  GNUNET_assert (GNUNET_YES == th->channel->allow_send);
-  th->channel->allow_send = GNUNET_NO;
+  GNUNET_assert (0 < th->channel->allow_send);
+  th->channel->allow_send--;
+  /* NOTE: we may be allowed to send another packet immediately,
+     albeit the current logic waits for the ACK. */
   th->request_data_task = NULL;
-  th->channel->packet_size = 0;
   remove_from_queue (th);
 
   env = GNUNET_MQ_msg_extra (msg,
@@ -621,7 +615,6 @@ handle_channel_created (void *cls,
     void *ctx;
 
     ch = create_channel (h, ccn);
-    ch->allow_send = GNUNET_NO;
     ch->peer = GNUNET_PEER_intern (&msg->peer);
     ch->cadet = h;
     ch->ccn = ccn;
@@ -788,6 +781,7 @@ handle_local_ack (void *cls,
   struct GNUNET_CADET_Handle *h = cls;
   struct GNUNET_CADET_Channel *ch;
   struct GNUNET_CADET_ClientChannelNumber ccn;
+  struct GNUNET_CADET_TransmitHandle *th;
 
   ccn = message->ccn;
   ch = retrieve_channel (h, ccn);
@@ -801,26 +795,19 @@ handle_local_ack (void *cls,
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Got an ACK on channel %X!\n",
        ntohl (ch->ccn.channel_of_client));
-  ch->allow_send = GNUNET_YES;
-  if (0 < ch->packet_size)
+  ch->allow_send++;
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Checking for pending data\n");
+  for (th = h->th_head; NULL != th; th = th->next)
   {
-    struct GNUNET_CADET_TransmitHandle *th;
-    struct GNUNET_CADET_TransmitHandle *next;
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "  pending data, sending %u bytes!\n",
-         ch->packet_size);
-    for (th = h->th_head; NULL != th; th = next)
+    if ( (th->channel == ch) &&
+         (NULL == th->request_data_task) )
     {
-      next = th->next;
-      if (th->channel == ch)
-      {
-        GNUNET_assert (NULL == th->request_data_task);
-        th->request_data_task = GNUNET_SCHEDULER_add_now (&request_data, th);
-        break;
-      }
+      th->request_data_task
+        = GNUNET_SCHEDULER_add_now (&request_data,
+                                    th);
+      break;
     }
-    /* Complain if we got thru all th without sending anything, ch was wrong */
-    GNUNET_break (NULL != th);
   }
 }
 
@@ -1379,7 +1366,7 @@ reconnect (struct GNUNET_CADET_Handle *h)
 
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Requested RECONNECT, destroying all channels\n");
-  for (ch = h->channels_head; NULL != ch; ch = h->channels_head)
+  while (NULL != (ch = h->channels_head))
     destroy_channel (ch, GNUNET_YES);
   if (NULL == h->reconnect_task)
     h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->reconnect_time,
@@ -1612,7 +1599,6 @@ GNUNET_CADET_channel_create (struct GNUNET_CADET_Handle 
*h,
   msg->port = *port;
   msg->peer = *peer;
   msg->opt = htonl (options);
-  ch->allow_send = GNUNET_NO;
   GNUNET_MQ_send (h->mq,
                   env);
   return ch;
@@ -1726,8 +1712,6 @@ GNUNET_CADET_notify_transmit_ready (struct 
GNUNET_CADET_Channel *channel,
     LOG (GNUNET_ERROR_TYPE_DEBUG, "    to destination\n");
   LOG (GNUNET_ERROR_TYPE_DEBUG, "    payload size %u\n", notify_size);
   GNUNET_assert (NULL != notify);
-  GNUNET_assert (0 == channel->packet_size); // Only one data packet allowed
-
   if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us != maxdelay.rel_value_us)
   {
     LOG (GNUNET_ERROR_TYPE_WARNING,
@@ -1737,11 +1721,10 @@ GNUNET_CADET_notify_transmit_ready (struct 
GNUNET_CADET_Channel *channel,
   th = GNUNET_new (struct GNUNET_CADET_TransmitHandle);
   th->channel = channel;
   th->size = notify_size;
-  channel->packet_size = th->size;
   LOG (GNUNET_ERROR_TYPE_DEBUG, "    total size %u\n", th->size);
   th->notify = notify;
   th->notify_cls = notify_cls;
-  if (GNUNET_YES == channel->allow_send)
+  if (0 != channel->allow_send)
     th->request_data_task = GNUNET_SCHEDULER_add_now (&request_data, th);
   else
     add_to_queue (channel->cadet, th);
@@ -1757,9 +1740,8 @@ GNUNET_CADET_notify_transmit_ready_cancel (struct 
GNUNET_CADET_TransmitHandle *t
   if (NULL != th->request_data_task)
   {
     GNUNET_SCHEDULER_cancel (th->request_data_task);
+    th->request_data_task = NULL;
   }
-  th->request_data_task = NULL;
-
   remove_from_queue (th);
   GNUNET_free (th);
 }
diff --git a/src/cadet/gnunet-service-cadet-new.c 
b/src/cadet/gnunet-service-cadet-new.c
index bb251c307..ef0870158 100644
--- a/src/cadet/gnunet-service-cadet-new.c
+++ b/src/cadet/gnunet-service-cadet-new.c
@@ -131,7 +131,7 @@ struct GNUNET_PeerIdentity my_full_id;
 struct GNUNET_CRYPTO_EddsaPrivateKey *my_private_key;
 
 /**
- * Signal that shutdown is happening: prevent recover measures.
+ * Signal that shutdown is happening: prevent recovery measures.
  */
 int shutting_down;
 
@@ -356,17 +356,11 @@ destroy_paths_now (void *cls,
 
 
 /**
- * Task run during shutdown.
- *
- * @param cls unused
+ * Shutdown everything once the clients have disconnected.
  */
 static void
-shutdown_task (void *cls)
+shutdown_rest ()
 {
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Shutting down\n");
-  shutting_down = GNUNET_YES;
-  GCO_shutdown ();
   if (NULL != stats)
   {
     GNUNET_STATISTICS_destroy (stats,
@@ -414,6 +408,23 @@ shutdown_task (void *cls)
 
 
 /**
+ * Task run during shutdown.
+ *
+ * @param cls unused
+ */
+static void
+shutdown_task (void *cls)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Shutting down\n");
+  shutting_down = GNUNET_YES;
+  GCO_shutdown ();
+  if (NULL == clients_head)
+    shutdown_rest ();
+}
+
+
+/**
  * We had a remote connection @a value to port @a port before
  * client @a cls opened port @a port.  Bind them now.
  *
@@ -608,7 +619,8 @@ handle_channel_destroy (void *cls,
                  GNUNET_CONTAINER_multihashmap32_remove (c->channels,
                                                          ntohl 
(msg->ccn.channel_of_client),
                                                          ch));
-  GCCH_channel_local_destroy (ch);
+  GCCH_channel_local_destroy (ch,
+                              c);
   GNUNET_SERVICE_client_continue (c->client);
 }
 
@@ -703,6 +715,7 @@ handle_data (void *cls,
        GCCH_2s (ch));
   if (GNUNET_OK !=
       GCCH_handle_local_data (ch,
+                              c,
                               buf,
                               payload_size))
   {
@@ -1196,10 +1209,8 @@ channel_destroy_iterator (void *cls,
                  GNUNET_CONTAINER_multihashmap32_remove (c->channels,
                                                          key,
                                                          ch));
-  if (key < GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
-    GCCH_channel_local_destroy (ch);
-  else
-    GCCH_channel_incoming_destroy (ch);
+  GCCH_channel_local_destroy (ch,
+                              c);
   return GNUNET_OK;
 }
 
@@ -1275,6 +1286,9 @@ client_disconnect_cb (void *cls,
                             -1,
                             GNUNET_NO);
   GNUNET_free (c);
+  if ( (NULL == clients_head) &&
+       (GNUNET_YES == shutting_down) )
+    shutdown_rest ();
 }
 
 
diff --git a/src/cadet/gnunet-service-cadet-new.h 
b/src/cadet/gnunet-service-cadet-new.h
index cb289e9c3..4a76c578b 100644
--- a/src/cadet/gnunet-service-cadet-new.h
+++ b/src/cadet/gnunet-service-cadet-new.h
@@ -225,6 +225,11 @@ extern unsigned long long ratchet_messages;
  */
 extern struct GNUNET_TIME_Relative ratchet_time;
 
+/**
+ * Signal that shutdown is happening: prevent recovery measures.
+ */
+extern int shutting_down;
+
 
 /**
  * Send a message to a client.
diff --git a/src/cadet/gnunet-service-cadet-new_channel.c 
b/src/cadet/gnunet-service-cadet-new_channel.c
index f45c5e5ce..673921458 100644
--- a/src/cadet/gnunet-service-cadet-new_channel.c
+++ b/src/cadet/gnunet-service-cadet-new_channel.c
@@ -271,10 +271,16 @@ struct CadetChannel
   struct GNUNET_CADET_ChannelTunnelNumber ctn;
 
   /**
-   * Local tunnel number for local client owning the channel.
-   * ( >= #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI or 0 )
+   * Local tunnel number for local client @e owner owning the channel.
+   * ( >= #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
    */
-  struct GNUNET_CADET_ClientChannelNumber ccn;
+  struct GNUNET_CADET_ClientChannelNumber ccn_owner;
+
+  /**
+   * Local tunnel number for local client @e dest owning the channel.
+   * (< #GNUNET_CADET_LOCAL_CHANNEL_ID_CLI)
+   */
+  struct GNUNET_CADET_ClientChannelNumber ccn_dest;
 
   /**
    * Channel state.
@@ -302,6 +308,11 @@ struct CadetChannel
   int out_of_order;
 
   /**
+   * Is this channel a loopback channel, where the destination is us again?
+   */
+  int is_loopback;
+
+  /**
    * Flag to signal the destruction of the channel.  If this is set to
    * #GNUNET_YES the channel will be destroyed once the queue is
    * empty.
@@ -325,11 +336,12 @@ GCCH_2s (const struct CadetChannel *ch)
 
   GNUNET_snprintf (buf,
                    sizeof (buf),
-                   "Channel %s:%s ctn:%X(%X)",
+                   "Channel %s:%s ctn:%X(%X/%X)",
                    GNUNET_i2s (GCP_get_id (GCT_get_destination (ch->t))),
                    GNUNET_h2s (&ch->port),
                    ch->ctn,
-                   ntohl (ch->ccn.channel_of_client));
+                   ntohl (ch->ccn_owner.channel_of_client),
+                   ntohl (ch->ccn_dest.channel_of_client));
   return buf;
 }
 
@@ -395,9 +407,13 @@ channel_destroy (struct CadetChannel *ch)
     GNUNET_SCHEDULER_cancel (ch->retry_control_task);
     ch->retry_control_task = NULL;
   }
-  GCT_remove_channel (ch->t,
-                      ch,
-                      ch->ctn);
+  if (GNUNET_NO == ch->is_loopback)
+  {
+    GCT_remove_channel (ch->t,
+                        ch,
+                        ch->ctn);
+    ch->t = NULL;
+  }
   GNUNET_free (ch);
 }
 
@@ -521,13 +537,40 @@ GCCH_channel_local_new (struct CadetClient *owner,
   ch->out_of_order = (0 != (options & GNUNET_CADET_OPTION_OUT_OF_ORDER));
   ch->max_pending_messages = (ch->nobuffer) ? 1 : 32; /* FIXME: 32!? Do not 
hardcode! */
   ch->owner = owner;
-  ch->ccn = ccn;
+  ch->ccn_owner = ccn;
   ch->port = *port;
-  ch->t = GCP_get_tunnel (destination,
-                          GNUNET_YES);
-  ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME;
-  ch->ctn = GCT_add_channel (ch->t,
-                             ch);
+  if (0 == memcmp (&my_full_id,
+                   GCP_get_id (destination),
+                   sizeof (struct GNUNET_PeerIdentity)))
+  {
+    ch->is_loopback = GNUNET_YES;
+    ch->dest = GNUNET_CONTAINER_multihashmap_get (open_ports,
+                                                  port);
+    if (NULL == ch->dest)
+    {
+      /* port closed, wait for it to possibly open */
+      (void) GNUNET_CONTAINER_multihashmap_put (loose_channels,
+                                                port,
+                                                ch,
+                                                
GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
+           "Created loose incoming loopback channel to port %s\n",
+           GNUNET_h2s (&ch->port));
+    }
+    else
+    {
+      GCCH_bind (ch,
+                 ch->dest);
+    }
+  }
+  else
+  {
+    ch->t = GCP_get_tunnel (destination,
+                            GNUNET_YES);
+    ch->retry_time = CADET_INITIAL_RETRANSMIT_TIME;
+    ch->ctn = GCT_add_channel (ch->t,
+                               ch);
+  }
   GNUNET_STATISTICS_update (stats,
                             "# channels",
                             1,
@@ -537,7 +580,7 @@ GCCH_channel_local_new (struct CadetClient *owner,
        GNUNET_h2s (port),
        GCP_2s (destination),
        GSC_2s (owner),
-       GCT_2s (ch->t));
+       (GNUNET_YES == ch->is_loopback) ? "loopback" : GCT_2s (ch->t));
   return ch;
 }
 
@@ -643,9 +686,9 @@ send_ack_cb (void *cls)
 
 
 /**
- * Compute and send the current ACK to the other peer.
+ * Compute and send the current 
#GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK to the other peer.
  *
- * @param ch channel to send the ACK for
+ * @param ch channel to send the 
#GNUNET_MESSAGE_TYPE_CADET_CHANNEL_APP_DATA_ACK for
  */
 static void
 send_channel_data_ack (struct CadetChannel *ch)
@@ -667,7 +710,7 @@ send_channel_data_ack (struct CadetChannel *ch)
 
 
 /**
- * Send our initial ACK to the client confirming that the
+ * Send our initial #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK to the client 
confirming that the
  * connection is up.
  *
  * @param cls the `struct CadetChannel`
@@ -729,7 +772,7 @@ GCCH_handle_duplicate_open (struct CadetChannel *ch)
 
 
 /**
- * Send a LOCAL ACK to the client to solicit more messages.
+ * Send a #GNUNET_MESSAGE_TYPE_CADET_LOCAL ACK to the client to solicit more 
messages.
  *
  * @param ch channel the ack is for
  * @param c client to send the ACK to
@@ -743,7 +786,7 @@ send_ack_to_client (struct CadetChannel *ch,
 
   env = GNUNET_MQ_msg (ack,
                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
-  ack->ccn = ch->ccn;
+  ack->ccn = (c == ch->owner) ? ch->ccn_owner : ch->ccn_dest;
   GSC_send_to_client (c,
                       env);
 }
@@ -785,22 +828,35 @@ GCCH_bind (struct CadetChannel *ch,
   if (ch->out_of_order)
     options |= GNUNET_CADET_OPTION_OUT_OF_ORDER;
   ch->dest = c;
-  ch->ccn = GSC_bind (c,
-                      ch,
-                      GCT_get_destination (ch->t),
-                      &ch->port,
-                      options);
+  ch->ccn_dest = GSC_bind (c,
+                           ch,
+                           (GNUNET_YES == ch->is_loopback)
+                           ? GCP_get (&my_full_id,
+                                      GNUNET_YES)
+                           : GCT_get_destination (ch->t),
+                           &ch->port,
+                           options);
   ch->mid_recv.mid = htonl (1); /* The CONNECT counts as message 0! */
-
-  /* notify other peer that we accepted the connection */
-  ch->retry_control_task
-    = GNUNET_SCHEDULER_add_now (&send_open_ack,
-                                ch);
+  if (GNUNET_YES == ch->is_loopback)
+  {
+    ch->state = CADET_CHANNEL_OPEN_SENT;
+    GCCH_handle_channel_open_ack (ch);
+  }
+  else
+  {
+    /* notify other peer that we accepted the connection */
+    ch->retry_control_task
+      = GNUNET_SCHEDULER_add_now (&send_open_ack,
+                                  ch);
+  }
   /* give client it's initial supply of ACKs */
   env = GNUNET_MQ_msg (tcm,
                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_CHANNEL_CREATE);
-  tcm->ccn = ch->ccn;
-  tcm->peer = *GCP_get_id (GCT_get_destination (ch->t));
+  tcm->ccn = ch->ccn_dest;
+  if (GNUNET_YES == ch->is_loopback)
+    tcm->peer = my_full_id;
+  else
+    tcm->peer = *GCP_get_id (GCT_get_destination (ch->t));
   tcm->port = ch->port;
   tcm->opt = htonl (options);
   GSC_send_to_client (ch->dest,
@@ -812,17 +868,27 @@ GCCH_bind (struct CadetChannel *ch,
 
 
 /**
- * Destroy locally created channel.  Called by the
- * local client, so no need to tell the client.
+ * Destroy locally created channel.  Called by the local client, so no
+ * need to tell the client.
  *
  * @param ch channel to destroy
+ * @param c client that caused the destruction
  */
 void
-GCCH_channel_local_destroy (struct CadetChannel *ch)
+GCCH_channel_local_destroy (struct CadetChannel *ch,
+                            struct CadetClient *c)
 {
   LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Local client asks for destruction of %s which it initiated\n",
+       "%s asks for destruction of %s\n",
+       GSC_2s (c),
        GCCH_2s (ch));
+  GNUNET_assert (NULL != c);
+  if (c == ch->owner)
+    ch->owner = NULL;
+  else if (c == ch->dest)
+    ch->dest = NULL;
+  else
+    GNUNET_assert (0);
   if (GNUNET_YES == ch->destroy)
   {
     /* other end already destroyed, with the local client gone, no need
@@ -830,9 +896,12 @@ GCCH_channel_local_destroy (struct CadetChannel *ch)
     channel_destroy (ch);
     return;
   }
-  if (NULL != ch->head_sent)
+  if ( (NULL != ch->head_sent) ||
+       (NULL != ch->owner) ||
+       (NULL != ch->dest) )
   {
-    /* allow send queue to train first */
+    /* Wait for other end to destroy us as well,
+       and otherwise allow send queue to be transmitted first */
     ch->destroy = GNUNET_YES;
     return;
   }
@@ -840,39 +909,7 @@ GCCH_channel_local_destroy (struct CadetChannel *ch)
   if (CADET_CHANNEL_NEW != ch->state)
     GCT_send_channel_destroy (ch->t,
                               ch->ctn);
-  /* Now finish our clean up */
-  channel_destroy (ch);
-}
-
-
-/**
- * Destroy channel that was incoming.  Called by the
- * local client, so no need to tell the client.
- *
- * @param ch channel to destroy
- */
-void
-GCCH_channel_incoming_destroy (struct CadetChannel *ch)
-{
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Local client asks for destruction of %s which it accepted\n",
-       GCCH_2s (ch));
-  if (GNUNET_YES == ch->destroy)
-  {
-    /* other end already destroyed, with the remote client gone, no need
-       to finish transmissions, just destroy immediately. */
-    channel_destroy (ch);
-    return;
-  }
-  if (NULL != ch->head_recv)
-  {
-    /* allow local client to see all data first */
-    ch->destroy = GNUNET_YES;
-    return;
-  }
   /* Nothing left to do, just finish destruction */
-  GCT_send_channel_destroy (ch->t,
-                            ch->ctn);
   channel_destroy (ch);
 }
 
@@ -902,8 +939,11 @@ GCCH_handle_channel_open_ack (struct CadetChannel *ch)
     LOG (GNUNET_ERROR_TYPE_DEBUG,
          "Received channel OPEN_ACK for waiting %s, entering READY state\n",
          GCCH_2s (ch));
-    GNUNET_SCHEDULER_cancel (ch->retry_control_task);
-    ch->retry_control_task = NULL;
+    if (NULL != ch->retry_control_task) /* can be NULL if ch->is_loopback */
+    {
+      GNUNET_SCHEDULER_cancel (ch->retry_control_task);
+      ch->retry_control_task = NULL;
+    }
     ch->state = CADET_CHANNEL_READY;
     /* On first connect, send client as many ACKs as we allow messages
        to be buffered! */
@@ -975,6 +1015,7 @@ GCCH_handle_channel_plaintext_data (struct CadetChannel 
*ch,
   struct CadetOutOfOrderMessage *com;
   size_t payload_size;
 
+  GNUNET_assert (GNUNET_NO == ch->is_loopback);
   payload_size = ntohs (msg->header.size) - sizeof (*msg);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Receicved %u bytes of application data on %s\n",
@@ -983,7 +1024,7 @@ GCCH_handle_channel_plaintext_data (struct CadetChannel 
*ch,
   env = GNUNET_MQ_msg_extra (ld,
                              payload_size,
                              GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
-  ld->ccn = ch->ccn;
+  ld->ccn = (NULL == ch->dest) ? ch->ccn_owner : ch->ccn_dest;
   GNUNET_memcpy (&ld[1],
                  &msg[1],
                  payload_size);
@@ -1054,6 +1095,7 @@ GCCH_handle_channel_plaintext_data_ack (struct 
CadetChannel *ch,
 {
   struct CadetReliableMessage *crm;
 
+  GNUNET_break (GNUNET_NO == ch->is_loopback);
   if (GNUNET_NO == ch->reliable)
   {
     /* not expecting ACKs on unreliable channel, odd */
@@ -1104,12 +1146,26 @@ GCCH_handle_channel_plaintext_data_ack (struct 
CadetChannel *ch,
 void
 GCCH_handle_remote_destroy (struct CadetChannel *ch)
 {
+  GNUNET_assert (GNUNET_NO == ch->is_loopback);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Received remote channel DESTROY for %s\n",
        GCCH_2s (ch));
+  if (GNUNET_YES == ch->destroy)
+  {
+    /* Local client already gone, this is instant-death. */
+    channel_destroy (ch);
+    return;
+  }
+  if (NULL != ch->head_recv)
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "Lost end of transmission due to remote shutdown on channel %s\n",
+         GCCH_2s (ch));
+    /* FIXME: change API to notify client about truncated transmission! */
+  }
   ch->destroy = GNUNET_YES;
   GSC_handle_remote_channel_destroy ((NULL != ch->owner) ? ch->owner : 
ch->dest,
-                                     ch->ccn,
+                                     (NULL != ch->owner) ? ch->ccn_owner : 
ch->ccn_dest,
                                      ch);
   channel_destroy (ch);
 }
@@ -1190,8 +1246,8 @@ GCCH_check_allow_client (struct CadetChannel *ch)
        GCCH_2s (ch));
   env = GNUNET_MQ_msg (msg,
                        GNUNET_MESSAGE_TYPE_CADET_LOCAL_ACK);
-  msg->ccn = ch->ccn;
-  GSC_send_to_client (ch->owner ? ch->owner : ch->dest,
+  msg->ccn = (NULL != ch->owner) ? ch->ccn_owner : ch->ccn_dest;
+  GSC_send_to_client ((NULL != ch->owner) ? ch->owner : ch->dest,
                       env);
 }
 
@@ -1271,6 +1327,7 @@ data_sent_cb (void *cls)
  * buffer space in the tunnel.
  *
  * @param ch Channel.
+ * @param sender client sending the data
  * @param buf payload to transmit.
  * @param buf_len number of bytes in @a buf
  * @return #GNUNET_OK if everything goes well,
@@ -1278,6 +1335,7 @@ data_sent_cb (void *cls)
  */
 int
 GCCH_handle_local_data (struct CadetChannel *ch,
+                        struct CadetClient *sender,
                         const char *buf,
                         size_t buf_len)
 {
@@ -1290,6 +1348,28 @@ GCCH_handle_local_data (struct CadetChannel *ch,
   }
   ch->pending_messages++;
 
+  if (GNUNET_YES == ch->is_loopback)
+  {
+    struct CadetClient *receiver;
+    struct GNUNET_MQ_Envelope *env;
+    struct GNUNET_CADET_LocalData *ld;
+
+    env = GNUNET_MQ_msg_extra (ld,
+                               buf_len,
+                               GNUNET_MESSAGE_TYPE_CADET_LOCAL_DATA);
+    receiver = (ch->owner == sender) ? ch->dest : ch->owner;
+    ld->ccn = (ch->owner == sender) ? ch->ccn_dest : ch->ccn_owner;
+    GNUNET_memcpy (&ld[1],
+                   buf,
+                   buf_len);
+    /* FIXME: this does not provide for flow control! */
+    GSC_send_to_client (receiver,
+                        env);
+    send_ack_to_client (ch,
+                        sender);
+    return GNUNET_OK;
+  }
+
   /* Everything is correct, send the message. */
   crm = GNUNET_malloc (sizeof (*crm) + buf_len);
   crm->ch = ch;
@@ -1426,7 +1506,7 @@ GCCH_debug (struct CadetChannel *ch,
           "CHN origin %s ready %s local-id: %u\n",
           GSC_2s (ch->owner),
           ch->client_ready ? "YES" : "NO",
-          ntohl (ch->ccn.channel_of_client));
+          ntohl (ch->ccn_owner.channel_of_client));
   }
   if (NULL != ch->dest)
   {
@@ -1434,7 +1514,7 @@ GCCH_debug (struct CadetChannel *ch,
           "CHN destination %s ready %s local-id: %u\n",
           GSC_2s (ch->dest),
           ch->client_ready ? "YES" : "NO",
-          ntohl (ch->ccn.channel_of_client));
+          ntohl (ch->ccn_dest.channel_of_client));
   }
   LOG2 (level,
         "CHN  Message IDs recv: %d (%LLX), send: %d\n",
diff --git a/src/cadet/gnunet-service-cadet-new_channel.h 
b/src/cadet/gnunet-service-cadet-new_channel.h
index 3a931499e..99124f651 100644
--- a/src/cadet/gnunet-service-cadet-new_channel.h
+++ b/src/cadet/gnunet-service-cadet-new_channel.h
@@ -113,9 +113,11 @@ GCCH_bind (struct CadetChannel *ch,
  * local client, so no need to tell the client.
  *
  * @param ch channel to destroy
+ * @param c client that caused the destruction
  */
 void
-GCCH_channel_local_destroy (struct CadetChannel *ch);
+GCCH_channel_local_destroy (struct CadetChannel *ch,
+                            struct CadetClient *c);
 
 
 /**
@@ -150,16 +152,6 @@ GCCH_channel_incoming_new (struct CadetTunnel *t,
 
 
 /**
- * Destroy channel that was incoming.  Called by the
- * local client, so no need to tell the client.
- *
- * @param ch channel to destroy
- */
-void
-GCCH_channel_incoming_destroy (struct CadetChannel *ch);
-
-
-/**
  * We got a #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN message again for
  * this channel.  If the binding was successful, (re)transmit the
  * #GNUNET_MESSAGE_TYPE_CADET_CHANNEL_OPEN_ACK.
@@ -228,6 +220,7 @@ GCCH_handle_remote_destroy (struct CadetChannel *ch);
  * buffer space in the tunnel.
  *
  * @param ch Channel.
+ * @param sender client sending the data
  * @param buf payload to transmit.
  * @param buf_len number of bytes in @a buf
  * @return #GNUNET_OK if everything goes well,
@@ -235,6 +228,7 @@ GCCH_handle_remote_destroy (struct CadetChannel *ch);
  */
 int
 GCCH_handle_local_data (struct CadetChannel *ch,
+                        struct CadetClient *sender,
                         const char *buf,
                         size_t buf_len);
 
diff --git a/src/cadet/gnunet-service-cadet-new_paths.c 
b/src/cadet/gnunet-service-cadet-new_paths.c
index 976020bea..685656ec3 100644
--- a/src/cadet/gnunet-service-cadet-new_paths.c
+++ b/src/cadet/gnunet-service-cadet-new_paths.c
@@ -68,6 +68,19 @@ struct CadetPeerPath
 
 
 /**
+ * Calculate the path's desirability score.
+ *
+ * @param path path to calculate the score for
+ */
+static void
+recalculate_path_desirability (struct CadetPeerPath *path)
+{
+  /* FIXME: update path desirability! */
+  GNUNET_break (0); // not implemented
+}
+
+
+/**
  * Return how much we like keeping the path.  This is an aggregate
  * score based on various factors, including the age of the path
  * (older == better), and the value of this path to all of its ajacent
@@ -261,8 +274,7 @@ GCPP_update_score (struct CadetPeerPath *path,
     else
       entry->score += delta;
   }
-
-  /* FIXME: update path desirability! */
+  recalculate_path_desirability (path);
 }
 
 
@@ -387,7 +399,7 @@ extend_path (struct CadetPeerPath *path,
     struct CadetPeerPathEntry *entry = path->entries[old_len + i];
 
     path->entries_length = old_len + i + 1;
-    /* FIXME: note that path->desirability is used, but not yet updated here! 
*/
+    recalculate_path_desirability (path);
     hn = GCP_attach_path (peers[i],
                           path,
                           old_len + (unsigned int) i,
@@ -519,7 +531,7 @@ GCPP_try_path_from_dht (const struct GNUNET_PeerIdentity 
*get_path,
     struct CadetPeerPathEntry *entry = path->entries[i];
 
     path->entries_length = i + 1;
-    /* FIXME: note that path->desirability is used, but not yet initialized 
here! */
+    recalculate_path_desirability (path);
     hn = GCP_attach_path (cpath[i],
                           path,
                           (unsigned int) i,
@@ -634,6 +646,7 @@ GCPP_get_path_from_route (unsigned int path_length,
                         entry,
                         i);
   }
+  recalculate_path_desirability (path);
   LOG (GNUNET_ERROR_TYPE_DEBUG,
        "Created new path %s to create inverse for incoming connection\n",
        GCPP_2s (path));
diff --git a/src/cadet/gnunet-service-cadet-new_tunnels.c 
b/src/cadet/gnunet-service-cadet-new_tunnels.c
index 20ab8f4e9..b85f1b321 100644
--- a/src/cadet/gnunet-service-cadet-new_tunnels.c
+++ b/src/cadet/gnunet-service-cadet-new_tunnels.c
@@ -1624,6 +1624,26 @@ GCT_remove_channel (struct CadetTunnel *t,
 
 
 /**
+ * Destroy remaining channels during shutdown.
+ *
+ * @param cls the `struct CadetTunnel` of the channel
+ * @param key key of the channel
+ * @param value the `struct CadetChannel`
+ * @return #GNUNET_OK (continue to iterate)
+ */
+static int
+destroy_remaining_channels (void *cls,
+                            uint32_t key,
+                            void *value)
+{
+  struct CadetChannel *ch = value;
+
+  GCCH_handle_remote_destroy (ch);
+  return GNUNET_OK;
+}
+
+
+/**
  * Destroys the tunnel @a t now, without delay. Used during shutdown.
  *
  * @param t tunnel to destroy
@@ -1631,6 +1651,10 @@ GCT_remove_channel (struct CadetTunnel *t,
 void
 GCT_destroy_tunnel_now (struct CadetTunnel *t)
 {
+  GNUNET_assert (GNUNET_YES == shutting_down);
+  GNUNET_CONTAINER_multihashmap32_iterate (t->channels,
+                                           &destroy_remaining_channels,
+                                           t);
   GNUNET_assert (0 ==
                  GNUNET_CONTAINER_multihashmap32_size (t->channels));
   if (NULL != t->destroy_task)
diff --git a/src/cadet/test_cadet_single.c b/src/cadet/test_cadet_single.c
index 9bfaeda0d..a2716127d 100644
--- a/src/cadet/test_cadet_single.c
+++ b/src/cadet/test_cadet_single.c
@@ -49,6 +49,8 @@ static struct GNUNET_SCHEDULER_Task *connect_task;
 
 static unsigned int repetition;
 
+static struct GNUNET_CADET_TransmitHandle *nth;
+
 
 /* forward declaration */
 static size_t
@@ -62,6 +64,11 @@ static void
 do_shutdown (void *cls)
 {
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "shutdown\n");
+  if (NULL != nth)
+  {
+    GNUNET_CADET_notify_transmit_ready_cancel (nth);
+    nth = NULL;
+  }
   if (NULL != abort_task)
   {
     GNUNET_SCHEDULER_cancel (abort_task);
@@ -131,11 +138,11 @@ data_callback (void *cls, struct GNUNET_CADET_Channel 
*channel,
       my_channel = ch1;
     else
       my_channel = ch2;
-    GNUNET_CADET_notify_transmit_ready (my_channel, GNUNET_NO,
-                                       GNUNET_TIME_UNIT_FOREVER_REL,
-                                       sizeof (struct GNUNET_MessageHeader)
-                                       + DATA_SIZE,
-                                       &do_send, NULL);
+    nth = GNUNET_CADET_notify_transmit_ready (my_channel, GNUNET_NO,
+                                              GNUNET_TIME_UNIT_FOREVER_REL,
+                                              sizeof (struct 
GNUNET_MessageHeader)
+                                              + DATA_SIZE,
+                                              &do_send, NULL);
     GNUNET_CADET_receive_done (channel);
     return GNUNET_OK;
   }
@@ -190,13 +197,18 @@ channel_end (void *cls, const struct GNUNET_CADET_Channel 
*channel,
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "incoming channel closed at peer %ld\n",
               id);
-  if (REPETITIONS == repetition && channel == ch2)
+  if ( (REPETITIONS == repetition) &&
+       (channel == ch2) )
   {
-    ch2 = NULL;
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "everything fine! finishing!\n");
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                "everything fine! finishing!\n");
     result = GNUNET_OK;
     GNUNET_SCHEDULER_shutdown ();
   }
+  if (channel == ch2)
+    ch2 = NULL;
+  if (channel == ch1)
+    ch1 = NULL;
 }
 
 
@@ -223,13 +235,14 @@ do_send (void *cls, size_t size, void *buf)
 {
   struct GNUNET_MessageHeader *m = buf;
 
+  nth = NULL;
   if (NULL == buf)
   {
     GNUNET_break (0);
     result = GNUNET_SYSERR;
     return 0;
   }
-  m->size = htons (sizeof (struct GNUNET_MessageHeader));
+  m->size = htons (sizeof (struct GNUNET_MessageHeader) + DATA_SIZE);
   m->type = htons (1);
   memset (&m[1], 0, DATA_SIZE);
   GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader) + DATA_SIZE);
@@ -252,9 +265,9 @@ do_connect (void *cls)
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "CONNECT BY PORT\n");
   ch1 = GNUNET_CADET_channel_create (cadet, NULL, &id, GC_u2h (1),
                                      GNUNET_CADET_OPTION_DEFAULT);
-  GNUNET_CADET_notify_transmit_ready (ch1, GNUNET_NO,
-                                     GNUNET_TIME_UNIT_FOREVER_REL,
-                                     size, &do_send, NULL);
+  nth = GNUNET_CADET_notify_transmit_ready (ch1, GNUNET_NO,
+                                            GNUNET_TIME_UNIT_FOREVER_REL,
+                                            size, &do_send, NULL);
 }
 
 
diff --git a/src/nat/gnunet-service-nat.c b/src/nat/gnunet-service-nat.c
index 98d87262e..bfe212308 100644
--- a/src/nat/gnunet-service-nat.c
+++ b/src/nat/gnunet-service-nat.c
@@ -1434,8 +1434,8 @@ handle_register (void *cls,
   off = (const char *) &message[1];
   for (unsigned int i=0;i<ch->num_caddrs;i++)
   {
-    size_t alen;
     const struct sockaddr *sa = (const struct sockaddr *) off;
+    size_t alen;
     uint16_t port;
     int is_nat;
 
@@ -1450,22 +1450,28 @@ handle_register (void *cls,
     {
     case AF_INET:
       {
-       const struct sockaddr_in *s4 = (const struct sockaddr_in *) sa;
+        struct sockaddr_in s4;
 
+        GNUNET_memcpy (&s4,
+                       off,
+                       sizeof (struct sockaddr_in));
        alen = sizeof (struct sockaddr_in);
-       if (is_nat_v4 (&s4->sin_addr))
+       if (is_nat_v4 (&s4.sin_addr))
          is_nat = GNUNET_YES;
-       port = ntohs (s4->sin_port);
+       port = ntohs (s4.sin_port);
       }
       break;
     case AF_INET6:
       {
-       const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) sa;
+        struct sockaddr_in6 s6;
 
+        GNUNET_memcpy (&s6,
+                       off,
+                       sizeof (struct sockaddr_in6));
        alen = sizeof (struct sockaddr_in6);
-       if (is_nat_v6 (&s6->sin6_addr))
+       if (is_nat_v6 (&s6.sin6_addr))
          is_nat = GNUNET_YES;
-       port = ntohs (s6->sin6_port);
+       port = ntohs (s6.sin6_port);
       }
       break;
 #if AF_UNIX
@@ -1483,7 +1489,7 @@ handle_register (void *cls,
     GNUNET_assert (alen <= left);
     GNUNET_assert (alen <= sizeof (struct sockaddr_storage));
     GNUNET_memcpy (&ch->caddrs[i].ss,
-                  sa,
+                  off,
                   alen);
 
     /* If applicable, try UPNPC NAT punching */
diff --git a/src/util/.gitignore b/src/util/.gitignore
index 87b379746..f207e07bf 100644
--- a/src/util/.gitignore
+++ b/src/util/.gitignore
@@ -62,3 +62,4 @@ test_speedup
 test_strings
 test_strings_to_data
 test_time
+test_socks.nc

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

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