if (NULL == t)
return "T(NULL)";
-
GNUNET_snprintf (buf,
sizeof (buf),
"T(%s)",
- GCP_2s (t->destination));
+ GNUNET_i2s (GCP_get_id (t->destination)));
return buf;
}
}
+/**
+ * Our tunnel became ready for the first time, notify channels
+ * that have been waiting.
+ *
+ * @param cls our tunnel, not used
+ * @param key unique ID of the channel, not used
+ * @param value the `struct CadetChannel` to notify
+ * @return #GNUNET_OK (continue to iterate)
+ */
+static int
+notify_tunnel_up_cb (void *cls,
+ uint32_t key,
+ void *value)
+{
+ struct CadetChannel *ch = value;
+
+ GCCH_tunnel_up (ch);
+ return GNUNET_OK;
+}
+
+
/**
* Change the tunnel encryption state.
* If the encryption state changes to OK, stop the rekey task.
GNUNET_SCHEDULER_cancel (t->kx_task);
t->kx_task = NULL;
}
+ if (CADET_TUNNEL_KEY_REKEY != old)
+ {
+ /* notify all channels that have been waiting */
+ GNUNET_CONTAINER_multihashmap32_iterate (t->channels,
+ ¬ify_tunnel_up_cb,
+ t);
+ }
+
/* FIXME: schedule rekey task! */
}
}
/**
- * Add a channel to a tunnel.
+ * Add a channel to a tunnel, and notify channel that we are ready
+ * for transmission if we are already up. Otherwise that notification
+ * will be done later in #notify_tunnel_up_cb().
*
* @param t Tunnel.
* @param ch Channel
"Adding channel %s to tunnel %s\n",
GCCH_2s (ch),
GCT_2s (t));
+ if ( (CADET_TUNNEL_KEY_OK == t->estate) ||
+ (CADET_TUNNEL_KEY_REKEY == t->estate) )
+ GCCH_tunnel_up (ch);
return ctn;
}
}
GNUNET_MST_destroy (t->mst);
GNUNET_MQ_destroy (t->mq);
+ while (NULL != t->ax.skipped_head)
+ delete_skipped_key (t,
+ t->ax.skipped_head);
+ GNUNET_assert (0 == t->ax.skipped);
+ GNUNET_free_non_null (t->ax.kx_0);
GNUNET_free_non_null (t->ax.DHRs);
GNUNET_free (t);
}
if (NULL == t->kx_task)
{
t->kx_task
- = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (t->next_kx_attempt),
- &retry_kx,
- t);
+ = GNUNET_SCHEDULER_add_at (t->next_kx_attempt,
+ &retry_kx,
+ t);
}
break;
case CADET_TUNNEL_KEY_OK:
}
-/**
- * Function called to maintain the connections underlying our tunnel.
- * Tries to maintain (incl. tear down) connections for the tunnel, and
- * if there is a significant change, may trigger transmissions.
- *
- * Basically, needs to check if there are connections that perform
- * badly, and if so eventually kill them and trigger a replacement.
- * The strategy is to open one more connection than
- * #DESIRED_CONNECTIONS_PER_TUNNEL, and then periodically kick out the
- * least-performing one, and then inquire for new ones.
- *
- * @param cls the `struct CadetTunnel`
- */
-static void
-maintain_connections_cb (void *cls)
-{
- struct CadetTunnel *t = cls;
-
- t->maintain_connections_task = NULL;
- GNUNET_break (0); // FIXME: implement!
-}
-
-
/**
* Consider using the path @a p for the tunnel @a t.
* The tunnel destination is at offset @a off in path @a p.
ps = GCC_get_path (ct->cc);
if (ps == path)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Ignoring duplicate path %s for tunnel %s.\n",
+ GCPP_2s (path),
+ GCT_2s (t));
return GNUNET_YES; /* duplicate */
+ }
min_length = GNUNET_MIN (min_length,
GCPP_get_length (ps));
max_desire = GNUNET_MAX (max_desire,
}
+/**
+ * Function called to maintain the connections underlying our tunnel.
+ * Tries to maintain (incl. tear down) connections for the tunnel, and
+ * if there is a significant change, may trigger transmissions.
+ *
+ * Basically, needs to check if there are connections that perform
+ * badly, and if so eventually kill them and trigger a replacement.
+ * The strategy is to open one more connection than
+ * #DESIRED_CONNECTIONS_PER_TUNNEL, and then periodically kick out the
+ * least-performing one, and then inquire for new ones.
+ *
+ * @param cls the `struct CadetTunnel`
+ */
+static void
+maintain_connections_cb (void *cls)
+{
+ struct CadetTunnel *t = cls;
+
+ t->maintain_connections_task = NULL;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Performing connection maintenance for tunnel %s.\n",
+ GCT_2s (t));
+
+ (void) GCP_iterate_paths (t->destination,
+ &consider_path_cb,
+ t);
+
+ GNUNET_break (0); // FIXME: implement!
+}
+
+
/**
* Consider using the path @a p for the tunnel @a t.
* The tunnel destination is at offset @a off in path @a p.
t = GNUNET_new (struct CadetTunnel);
new_ephemeral (t);
+ t->ax.kx_0 = GNUNET_CRYPTO_ecdhe_key_create ();
t->destination = destination;
t->channels = GNUNET_CONTAINER_multihashmap32_create (8);
- (void) GCP_iterate_paths (destination,
- &consider_path_cb,
- t);
t->maintain_connections_task
= GNUNET_SCHEDULER_add_now (&maintain_connections_cb,
t);