summaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/Makefile.am2
-rw-r--r--src/transport/gnunet-communicator-unix.c27
-rw-r--r--src/transport/gnunet-service-tng.c512
-rw-r--r--src/transport/transport.h101
-rw-r--r--src/transport/transport_api2_communication.c66
-rw-r--r--src/transport/transport_api2_core.c2
-rw-r--r--src/transport/transport_api_core.c1
7 files changed, 611 insertions, 100 deletions
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index da79773be..ab4ef4bfa 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -328,7 +328,7 @@ gnunet_service_transport_CFLAGS = \
gnunet_service_tng_SOURCES = \
gnunet-service-tng.c
gnunet_service_tng_LDADD = \
- $(top_builddir)/src/ats/libgnunetats.la \
+ $(top_builddir)/src/ats/libgnunetatstransport.la \
$(top_builddir)/src/peerstore/libgnunetpeerstore.la \
$(top_builddir)/src/hello/libgnunethello.la \
$(top_builddir)/src/statistics/libgnunetstatistics.la \
diff --git a/src/transport/gnunet-communicator-unix.c b/src/transport/gnunet-communicator-unix.c
index e8a1cf0b2..57fa22ecf 100644
--- a/src/transport/gnunet-communicator-unix.c
+++ b/src/transport/gnunet-communicator-unix.c
@@ -983,6 +983,29 @@ do_shutdown (void *cls)
/**
+ * Function called when the transport service has received an
+ * acknowledgement for this communicator (!) via a different return
+ * path.
+ *
+ * Not applicable for UNIX.
+ *
+ * @param cls closure
+ * @param sender which peer sent the notification
+ * @param msg payload
+ */
+static void
+enc_notify_cb (void *cls,
+ const struct GNUNET_PeerIdentity *sender,
+ const struct GNUNET_MessageHeader *msg)
+{
+ (void) cls;
+ (void) sender;
+ (void) msg;
+ GNUNET_break_op (0);
+}
+
+
+/**
* Setup communicator and launch network interactions.
*
* @param cls NULL (always)
@@ -1087,7 +1110,9 @@ run (void *cls,
COMMUNICATOR_ADDRESS_PREFIX,
GNUNET_TRANSPORT_CC_RELIABLE,
&mq_init,
- NULL);
+ NULL,
+ &enc_notify_cb,
+ NULL);
if (NULL == ch)
{
GNUNET_break (0);
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index 3630e6af0..85ac3da83 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -16,32 +16,70 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
- * @file transport/gnunet-service-transport.c
- * @brief main for gnunet-service-transport
+ * @file transport/gnunet-service-tng.c
+ * @brief main for gnunet-service-tng
* @author Christian Grothoff
*
* TODO:
- * - design ATS-NG API
* - figure out how to transmit (selective) ACKs in case of uni-directional
* communicators (with/without core? DV-only?) When do we use ACKs?
- * How/where do we distinguish between TCP/HTTP and unreliable communicators?
- * => Should communicator provide reliable/unreliable ("flags") information?
+ * => communicators use selective ACKs for flow control
+ * => transport uses message-level ACKs for RTT, fragment confirmation
+ * => integrate DV into transport, use neither core nor communicators
+ * but rather give communicators transport-encapsulated messages
+ * (which could be core-data, background-channel traffic, or
+ * transport-to-transport traffic)
+ *
+ * Implement:
* - manage fragmentation/defragmentation, retransmission, track RTT, loss, etc.
+ *
+ * Easy:
+ * - use ATS bandwidth allocation callback and schedule transmissions!
+ *
+ * Plan:
* - inform ATS about RTT, goodput/loss, overheads, etc.
- * - ask ATS about bandwidth allocation!
+ *
+ * Later:
* - change transport-core API to provide proper flow control in both
* directions, allow multiple messages per peer simultaneously (tag
* confirmations with unique message ID), and replace quota-out with
* proper flow control;
+ *
+ * Design realizations / discussion:
+ * - communicators do flow control by calling MQ "notify sent"
+ * when 'ready'. They determine flow implicitly (i.e. TCP blocking)
+ * or explicitly via background channel FC ACKs. As long as the
+ * channel is not full, they may 'notify sent' even if the other
+ * peer has not yet confirmed receipt. The other peer confirming
+ * is _only_ for FC, not for more reliable transmission; reliable
+ * transmission (i.e. of fragments) is left to _transport_.
+ * - ACKs sent back in uni-directional communicators are done via
+ * the background channel API; here transport _may_ initially
+ * broadcast (with bounded # hops) if no path is known;
+ * - transport should _integrate_ DV-routing and build a view of
+ * the network; then background channel traffic can be
+ * routed via DV as well as explicit "DV" traffic.
+ * - background channel is also used for ACKs and NAT traversal support
+ * - transport service is responsible for AEAD'ing the background
+ * channel, timestamps and monotonic time are used against replay
+ * of old messages -> peerstore needs to be supplied with
+ * "latest timestamps seen" data
+ * - if transport implements DV, we likely need a 3rd peermap
+ * in addition to ephemerals and (direct) neighbours
+ * => in this data structure, we should track ATS metrics (distance, RTT, etc.)
+ * as well as latest timestamps seen, goodput, fragments for transmission, etc.
+ * ==> check if stuff needs to be moved out of "Neighbour"
+ * - transport should encapsualte core-level messages and do its
+ * own ACKing for RTT/goodput/loss measurements _and_ fragment
+ * for retransmission
*/
#include "platform.h"
#include "gnunet_util_lib.h"
#include "gnunet_statistics_service.h"
-#include "gnunet_transport_service.h"
#include "gnunet_transport_monitor_service.h"
#include "gnunet_peerstore_service.h"
-#include "gnunet_ats_service.h"
-#include "gnunet-service-transport.h"
+#include "gnunet_hello_lib.h"
+#include "gnunet_ats_transport_service.h"
#include "transport.h"
@@ -60,6 +98,122 @@
#define MAX_PENDING (128 * 1024)
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Outer layer of an encapsulated backchannel message.
+ */
+struct TransportBackchannelEncapsulationMessage
+{
+ /**
+ * Type is #GNUNET_MESSAGE_TYPE_TRANSPORT_BACKCHANNEL_ENCAPSULATION.
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Distance the backchannel message has traveled, to be updated at
+ * each hop. Used to bound the number of hops in case a backchannel
+ * message is broadcast and thus travels without routing
+ * information (during initial backchannel discovery).
+ */
+ uint32_t distance;
+
+ /**
+ * Target's peer identity (as backchannels may be transmitted
+ * indirectly, or even be broadcast).
+ */
+ struct GNUNET_PeerIdentity target;
+
+ /**
+ * Ephemeral key setup by the sender for @e target, used
+ * to encrypt the payload.
+ */
+ struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
+
+ /**
+ * HMAC over the ciphertext of the encrypted, variable-size
+ * body that follows. Verified via DH of @e target and
+ * @e ephemeral_key
+ */
+ struct GNUNET_HashCode hmac;
+
+ /* Followed by encrypted, variable-size payload */
+};
+
+
+/**
+ * Message by which a peer confirms that it is using an
+ * ephemeral key.
+ */
+struct EphemeralConfirmation
+{
+
+ /**
+ * Purpose is #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL
+ */
+ struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
+
+ /**
+ * How long is this signature over the ephemeral key
+ * valid?
+ */
+ struct GNUNET_TIME_AbsoluteNBO ephemeral_validity;
+
+ /**
+ * Ephemeral key setup by the sender for @e target, used
+ * to encrypt the payload.
+ */
+ struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
+
+};
+
+/**
+ * Plaintext of the variable-size payload that is encrypted
+ * within a `struct TransportBackchannelEncapsulationMessage`
+ */
+struct TransportBackchannelRequestPayload
+{
+
+ /**
+ * Sender's peer identity.
+ */
+ struct GNUNET_PeerIdentity sender;
+
+ /**
+ * Signature of the sender over an
+ * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL.
+ */
+ struct GNUNET_CRYPTO_EddsaSignature sender_sig;
+
+ /**
+ * How long is this signature over the ephemeral key
+ * valid?
+ */
+ struct GNUNET_TIME_AbsoluteNBO ephemeral_validity;
+
+ /**
+ * Current monotonic time of the sending transport service. Used to
+ * detect replayed messages. Note that the receiver should remember
+ * a list of the recently seen timestamps and only reject messages
+ * if the timestamp is in the list, or the list is "full" and the
+ * timestamp is smaller than the lowest in the list. This list of
+ * timestamps per peer should be persisted to guard against replays
+ * after restarts.
+ */
+ struct GNUNET_TIME_AbsoluteNBO monotonic_time;
+
+ /* Followed by a `struct GNUNET_MessageHeader` with a message
+ for a communicator */
+
+ /* Followed by a 0-termianted string specifying the name of
+ the communicator which is to receive the message */
+
+};
+
+GNUNET_NETWORK_STRUCT_END
+
+
+
/**
* What type of client is the `struct TransportClient` about?
*/
@@ -88,6 +242,42 @@ enum ClientType
/**
+ * Entry in our cache of ephemeral keys we currently use.
+ */
+struct EphemeralCacheEntry
+{
+
+ /**
+ * Target's peer identity (we don't re-use ephemerals
+ * to limit linkability of messages).
+ */
+ struct GNUNET_PeerIdentity target;
+
+ /**
+ * Signature affirming @e ephemeral_key of type
+ * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_EPHEMERAL
+ */
+ struct GNUNET_CRYPTO_EddsaSignature sender_sig;
+
+ /**
+ * How long is @e sender_sig valid
+ */
+ struct GNUNET_TIME_Absolute ephemeral_validity;
+
+ /**
+ * Our ephemeral key.
+ */
+ struct GNUNET_CRYPTO_EcdhePublicKey ephemeral_key;
+
+ /**
+ * Node in the ephemeral cache for this entry.
+ * Used for expiration.
+ */
+ struct GNUNET_CONTAINER_HeapNode *hn;
+};
+
+
+/**
* Client connected to the transport service.
*/
struct TransportClient;
@@ -100,72 +290,73 @@ struct Neighbour;
/**
- * List of available queues for a particular neighbour.
+ * An ATS session is a message queue provided by a communicator
+ * via which we can reach a particular neighbour.
*/
-struct Queue
+struct GNUNET_ATS_Session
{
/**
* Kept in a MDLL.
*/
- struct Queue *next_neighbour;
+ struct GNUNET_ATS_Session *next_neighbour;
/**
* Kept in a MDLL.
*/
- struct Queue *prev_neighbour;
+ struct GNUNET_ATS_Session *prev_neighbour;
/**
* Kept in a MDLL.
*/
- struct Queue *prev_client;
+ struct GNUNET_ATS_Session *prev_client;
/**
* Kept in a MDLL.
*/
- struct Queue *next_client;
+ struct GNUNET_ATS_Session *next_client;
/**
- * Which neighbour is this queue for?
+ * Which neighbour is this ATS session for?
*/
struct Neighbour *neighbour;
/**
- * Which communicator offers this queue?
+ * Which communicator offers this ATS session?
*/
struct TransportClient *tc;
/**
- * Address served by the queue.
+ * Address served by the ATS session.
*/
const char *address;
/**
- * Our current RTT estimate for this queue.
+ * Our current RTT estimate for this ATS session.
*/
struct GNUNET_TIME_Relative rtt;
/**
- * Unique identifier of this queue with the communicator.
+ * Unique identifier of this ATS session with the communicator.
*/
uint32_t qid;
/**
- * Maximum transmission unit supported by this queue.
+ * Maximum transmission unit supported by this ATS session.
*/
uint32_t mtu;
/**
- * Distance to the target of this queue.
+ * Distance to the target of this ATS session.
*/
uint32_t distance;
/**
- * Network type offered by this queue.
+ * Network type offered by this ATS session.
*/
enum GNUNET_NetworkType nt;
/**
- * Connection status for this queue.
+ * Connection status for this ATS session.
*/
enum GNUNET_TRANSPORT_ConnectionStatus cs;
@@ -179,7 +370,15 @@ struct Queue
*/
uint32_t num_bytes_pending;
- // FIXME: add ATS-specific fields here!
+ /**
+ * How much outbound bandwidth do we have available for this session?
+ */
+ struct GNUNET_BANDWIDTH_Tracker tracker_out;
+
+ /**
+ * How much inbound bandwidth do we have available for this session?
+ */
+ struct GNUNET_BANDWIDTH_Tracker tracker_in;
};
@@ -205,14 +404,14 @@ struct Neighbour
struct PendingMessage *pending_msg_tail;
/**
- * Head of DLL of queues to this peer.
+ * Head of DLL of ATS sessions to this peer.
*/
- struct Queue *queue_head;
+ struct GNUNET_ATS_Session *session_head;
/**
- * Tail of DLL of queues to this peer.
+ * Tail of DLL of ATS sessions to this peer.
*/
- struct Queue *queue_tail;
+ struct GNUNET_ATS_Session *session_tail;
/**
* Quota at which CORE is allowed to transmit to this peer
@@ -411,12 +610,12 @@ struct TransportClient
/**
* Head of DLL of queues offered by this communicator.
*/
- struct Queue *queue_head;
+ struct GNUNET_ATS_Session *session_head;
/**
* Tail of DLL of queues offered by this communicator.
*/
- struct Queue *queue_tail;
+ struct GNUNET_ATS_Session *session_tail;
/**
* Head of list of the addresses of this peer offered by this communicator.
@@ -453,22 +652,22 @@ static struct TransportClient *clients_tail;
/**
* Statistics handle.
*/
-struct GNUNET_STATISTICS_Handle *GST_stats;
+static struct GNUNET_STATISTICS_Handle *GST_stats;
/**
* Configuration handle.
*/
-const struct GNUNET_CONFIGURATION_Handle *GST_cfg;
+static const struct GNUNET_CONFIGURATION_Handle *GST_cfg;
/**
* Our public key.
*/
-struct GNUNET_PeerIdentity GST_my_identity;
+static struct GNUNET_PeerIdentity GST_my_identity;
/**
* Our private key.
*/
-struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key;
+static struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key;
/**
* Map from PIDs to `struct Neighbour` entries. A peer is
@@ -481,6 +680,42 @@ static struct GNUNET_CONTAINER_MultiPeerMap *neighbours;
*/
static struct GNUNET_PEERSTORE_Handle *peerstore;
+/**
+ * Heap sorting `struct EphemeralCacheEntry` by their
+ * key/signature validity.
+ */
+static struct GNUNET_CONTAINER_Heap *ephemeral_heap;
+
+/**
+ * Hash map for looking up `struct EphemeralCacheEntry`s
+ * by peer identity. (We may have ephemerals in our
+ * cache for which we do not have a neighbour entry,
+ * and similar many neighbours may not need ephemerals,
+ * so we use a second map.)
+ */
+static struct GNUNET_CONTAINER_MultiPeerMap *ephemeral_map;
+
+/**
+ * Our connection to ATS for allocation and bootstrapping.
+ */
+static struct GNUNET_ATS_TransportHandle *ats;
+
+
+/**
+ * Free cached ephemeral key.
+ *
+ * @param ece cached signature to free
+ */
+static void
+free_ephemeral (struct EphemeralCacheEntry *ece)
+{
+ GNUNET_CONTAINER_multipeermap_remove (ephemeral_map,
+ &ece->target,
+ ece);
+ GNUNET_CONTAINER_heap_remove_node (ece->hn);
+ GNUNET_free (ece);
+}
+
/**
* Lookup neighbour record for peer @a pid.
@@ -654,7 +889,7 @@ client_connect_cb (void *cls,
static void
free_neighbour (struct Neighbour *neighbour)
{
- GNUNET_assert (NULL == neighbour->queue_head);
+ GNUNET_assert (NULL == neighbour->session_head);
GNUNET_assert (GNUNET_YES ==
GNUNET_CONTAINER_multipeermap_remove (neighbours,
&neighbour->pid,
@@ -743,7 +978,7 @@ cores_send_disconnect_info (const struct GNUNET_PeerIdentity *pid)
* @param queue the queue to free
*/
static void
-free_queue (struct Queue *queue)
+free_queue (struct GNUNET_ATS_Session *queue)
{
struct Neighbour *neighbour = queue->neighbour;
struct TransportClient *tc = queue->tc;
@@ -753,20 +988,22 @@ free_queue (struct Queue *queue)
};
GNUNET_CONTAINER_MDLL_remove (neighbour,
- neighbour->queue_head,
- neighbour->queue_tail,
+ neighbour->session_head,
+ neighbour->session_tail,
queue);
GNUNET_CONTAINER_MDLL_remove (client,
- tc->details.communicator.queue_head,
- tc->details.communicator.queue_tail,
+ tc->details.communicator.session_head,
+ tc->details.communicator.session_tail,
queue);
notify_monitors (&neighbour->pid,
queue->address,
queue->nt,
&me);
+ GNUNET_BANDWIDTH_tracker_notification_stop (&queue->tracker_in);
+ GNUNET_BANDWIDTH_tracker_notification_stop (&queue->tracker_out);
GNUNET_free (queue);
- if (NULL == neighbour->queue_head)
+ if (NULL == neighbour->session_head)
{
cores_send_disconnect_info (&neighbour->pid);
free_neighbour (neighbour);
@@ -844,10 +1081,10 @@ client_disconnect_cb (void *cls,
break;
case CT_COMMUNICATOR:
{
- struct Queue *q;
+ struct GNUNET_ATS_Session *q;
struct AddressListEntry *ale;
- while (NULL != (q = tc->details.communicator.queue_head))
+ while (NULL != (q = tc->details.communicator.session_head))
free_queue (q);
while (NULL != (ale = tc->details.communicator.addr_head))
free_address_list_entry (ale);
@@ -1356,6 +1593,34 @@ check_add_queue_message (void *cls,
/**
+ * Bandwidth tracker informs us that the delay until we
+ * can transmit again changed.
+ *
+ * @param cls a `struct GNUNET_ATS_Session` for which the delay changed
+ */
+static void
+tracker_update_cb (void *cls)
+{
+ struct GNUNET_ATS_Session *queue = cls;
+
+ // FIXME: re-schedule transmission tasks if applicable!
+}
+
+
+/**
+ * Bandwidth tracker informs us that excessive bandwidth was allocated
+ * which is not being used.
+ *
+ * @param cls a `struct GNUNET_ATS_Session` for which the excess was noted
+ */
+static void
+tracker_excess_cb (void *cls)
+{
+ /* FIXME: what do we do? */
+}
+
+
+/**
* New queue became available. Process the request.
*
* @param cls the client
@@ -1366,7 +1631,7 @@ handle_add_queue_message (void *cls,
const struct GNUNET_TRANSPORT_AddQueueMessage *aqm)
{
struct TransportClient *tc = cls;
- struct Queue *queue;
+ struct GNUNET_ATS_Session *queue;
struct Neighbour *neighbour;
const char *addr;
uint16_t addr_len;
@@ -1388,7 +1653,7 @@ handle_add_queue_message (void *cls,
addr_len = ntohs (aqm->header.size) - sizeof (*aqm);
addr = (const char *) &aqm[1];
- queue = GNUNET_malloc (sizeof (struct Queue) + addr_len);
+ queue = GNUNET_malloc (sizeof (struct GNUNET_ATS_Session) + addr_len);
queue->tc = tc;
queue->address = (const char *) &queue[1];
queue->rtt = GNUNET_TIME_UNIT_FOREVER_REL;
@@ -1398,6 +1663,20 @@ handle_add_queue_message (void *cls,
queue->nt = (enum GNUNET_NetworkType) ntohl (aqm->nt);
queue->cs = (enum GNUNET_TRANSPORT_ConnectionStatus) ntohl (aqm->cs);
queue->neighbour = neighbour;
+ GNUNET_BANDWIDTH_tracker_init2 (&queue->tracker_in,
+ &tracker_update_cb,
+ queue,
+ GNUNET_BANDWIDTH_ZERO,
+ 0 /* FIXME: max carry in seconds! */,
+ &tracker_excess_cb,
+ queue);
+ GNUNET_BANDWIDTH_tracker_init2 (&queue->tracker_out,
+ &tracker_update_cb,
+ queue,
+ GNUNET_BANDWIDTH_ZERO,
+ 0 /* FIXME: max carry in seconds! */,
+ &tracker_excess_cb,
+ queue);
memcpy (&queue[1],
addr,
addr_len);
@@ -1414,12 +1693,12 @@ handle_add_queue_message (void *cls,
&me);
}
GNUNET_CONTAINER_MDLL_insert (neighbour,
- neighbour->queue_head,
- neighbour->queue_tail,
+ neighbour->session_head,
+ neighbour->session_tail,
queue);
GNUNET_CONTAINER_MDLL_insert (client,
- tc->details.communicator.queue_head,
- tc->details.communicator.queue_tail,
+ tc->details.communicator.session_head,
+ tc->details.communicator.session_tail,
queue);
// FIXME: possibly transmit queued messages?
GNUNET_SERVICE_client_continue (tc->client);
@@ -1444,7 +1723,7 @@ handle_del_queue_message (void *cls,
GNUNET_SERVICE_client_drop (tc->client);
return;
}
- for (struct Queue *queue = tc->details.communicator.queue_head;
+ for (struct GNUNET_ATS_Session *queue = tc->details.communicator.session_head;
NULL != queue;
queue = queue->next_client)
{
@@ -1504,7 +1783,7 @@ notify_client_queues (void *cls,
struct Neighbour *neighbour = value;
GNUNET_assert (CT_MONITOR == tc->type);
- for (struct Queue *q = neighbour->queue_head;
+ for (struct GNUNET_ATS_Session *q = neighbour->session_head;
NULL != q;
q = q->next_neighbour)
{
@@ -1555,6 +1834,74 @@ handle_monitor_start (void *cls,
/**
+ * Signature of a function called by ATS with the current bandwidth
+ * allocation to be used as determined by ATS.
+ *
+ * @param cls closure, NULL
+ * @param session session this is about
+ * @param bandwidth_out assigned outbound bandwidth for the connection,
+ * 0 to signal disconnect
+ * @param bandwidth_in assigned inbound bandwidth for the connection,
+ * 0 to signal disconnect
+ */
+static void
+ats_allocation_cb (void *cls,
+ struct GNUNET_ATS_Session *session,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
+{
+ (void) cls;
+ GNUNET_BANDWIDTH_tracker_update_quota (&session->tracker_out,
+ bandwidth_out);
+ GNUNET_BANDWIDTH_tracker_update_quota (&session->tracker_in,
+ bandwidth_in);
+}
+
+
+/**
+ * Find transport client providing communication service
+ * for the protocol @a prefix.
+ *
+ * @param prefix communicator name
+ * @return NULL if no such transport client is available
+ */
+static struct TransportClient *
+lookup_communicator (const char *prefix)
+{
+ GNUNET_break (0); // FIXME: implement
+ return NULL;
+}
+
+
+/**
+ * Signature of a function called by ATS suggesting transport to
+ * try connecting with a particular address.
+ *
+ * @param cls closure, NULL
+ * @param pid target peer
+ * @param address the address to try
+ */
+static void
+ats_suggestion_cb (void *cls,
+ const struct GNUNET_PeerIdentity *pid,
+ const char *address)
+{
+ struct TransportClient *tc;
+ char *prefix;
+
+ (void) cls;
+ prefix = NULL; // FIXME
+ tc = lookup_communicator (prefix);
+ if (NULL == tc)
+ {
+ // STATS...
+ return;
+ }
+ // FIXME: forward suggestion to tc
+}
+
+
+/**
* Free neighbour entry.
*
* @param cls NULL
@@ -1579,6 +1926,28 @@ free_neighbour_cb (void *cls,
/**
+ * Free ephemeral entry.
+ *
+ * @param cls NULL
+ * @param pid unused
+ * @param value a `struct Neighbour`
+ * @return #GNUNET_OK (always)
+ */
+static int
+free_ephemeral_cb (void *cls,
+ const struct GNUNET_PeerIdentity *pid,
+ void *value)
+{
+ struct EphemeralCacheEntry *ece = value;
+
+ (void) cls;
+ (void) pid;
+ free_ephemeral (ece);
+ return GNUNET_OK;
+}
+
+
+/**
* Function called when the service shuts down. Unloads our plugins
* and cancels pending validations.
*
@@ -1592,6 +1961,11 @@ do_shutdown (void *cls)
GNUNET_CONTAINER_multipeermap_iterate (neighbours,
&free_neighbour_cb,
NULL);
+ if (NULL != ats)
+ {
+ GNUNET_ATS_transport_done (ats);
+ ats = NULL;
+ }
if (NULL != peerstore)
{
GNUNET_PEERSTORE_disconnect (peerstore,
@@ -1610,6 +1984,14 @@ do_shutdown (void *cls)
GST_my_private_key = NULL;
}
GNUNET_CONTAINER_multipeermap_destroy (neighbours);
+ neighbours = NULL;
+ GNUNET_CONTAINER_multipeermap_iterate (ephemeral_map,
+ &free_ephemeral_cb,
+ NULL);
+ GNUNET_CONTAINER_multipeermap_destroy (ephemeral_map);
+ ephemeral_map = NULL;
+ GNUNET_CONTAINER_heap_destroy (ephemeral_heap);
+ ephemeral_heap = NULL;
}
@@ -1630,6 +2012,9 @@ run (void *cls,
GST_cfg = c;
neighbours = GNUNET_CONTAINER_multipeermap_create (1024,
GNUNET_YES);
+ ephemeral_map = GNUNET_CONTAINER_multipeermap_create (32,
+ GNUNET_YES);
+ ephemeral_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
GST_my_private_key = GNUNET_CRYPTO_eddsa_key_create_from_configuration (GST_cfg);
if (NULL == GST_my_private_key)
{
@@ -1643,19 +2028,28 @@ run (void *cls,
GNUNET_log(GNUNET_ERROR_TYPE_INFO,
"My identity is `%s'\n",
GNUNET_i2s_full (&GST_my_identity));
-
GST_stats = GNUNET_STATISTICS_create ("transport",
GST_cfg);
GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
NULL);
peerstore = GNUNET_PEERSTORE_connect (GST_cfg);
if (NULL == peerstore)
- {
- GNUNET_break (0);
- GNUNET_SCHEDULER_shutdown ();
- return;
- }
- /* start subsystems */
+ {
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
+ ats = GNUNET_ATS_transport_init (GST_cfg,
+ &ats_allocation_cb,
+ NULL,
+ &ats_suggestion_cb,
+ NULL);
+ if (NULL == ats)
+ {
+ GNUNET_break (0);
+ GNUNET_SCHEDULER_shutdown ();
+ return;
+ }
}
diff --git a/src/transport/transport.h b/src/transport/transport.h
index df1321d1a..3c5fe72de 100644
--- a/src/transport/transport.h
+++ b/src/transport/transport.h
@@ -26,7 +26,6 @@
#include "gnunet_crypto_lib.h"
#include "gnunet_time_lib.h"
-#include "gnunet_transport_service.h"
#include "gnunet_constants.h"
#define DEBUG_TRANSPORT GNUNET_EXTRA_LOGGING
@@ -79,6 +78,7 @@ typedef void
GNUNET_NETWORK_STRUCT_BEGIN
+
/**
* Message from the transport service to the library
* asking to check if both processes agree about this
@@ -241,61 +241,67 @@ struct SendOkMessage
};
+
/**
- * Message used to notify the transport API about an address to string
- * conversion. Message is followed by the string with the humand-readable
- * address. For each lookup, multiple results may be returned. The
- * last message must have a @e res of #GNUNET_OK and an @e addr_len
- * of zero.
+ * Message used to notify the transport service about a message
+ * to be transmitted to another peer. The actual message follows.
*/
-struct AddressToStringResultMessage
+struct OutboundMessage
{
/**
- * Type will be #GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY
+ * Type will be #GNUNET_MESSAGE_TYPE_TRANSPORT_SEND
*/
struct GNUNET_MessageHeader header;
/**
- * #GNUNET_OK if the conversion succeeded,
- * #GNUNET_SYSERR if it failed
+ * Always zero.
*/
- uint32_t res GNUNET_PACKED;
+ uint32_t reserved GNUNET_PACKED;
/**
- * Length of the following string, zero if @e is #GNUNET_SYSERR
+ * Allowed delay.
*/
- uint32_t addr_len GNUNET_PACKED;
+ struct GNUNET_TIME_RelativeNBO timeout;
+
+ /**
+ * Which peer should receive the message?
+ */
+ struct GNUNET_PeerIdentity peer;
+
};
+
+
+#if !(defined(GNUNET_TRANSPORT_COMMUNICATION_VERSION)||defined(GNUNET_TRANSPORT_CORE_VERSION))
+
+
/**
- * Message used to notify the transport service about a message
- * to be transmitted to another peer. The actual message follows.
+ * Message used to notify the transport API about an address to string
+ * conversion. Message is followed by the string with the humand-readable
+ * address. For each lookup, multiple results may be returned. The
+ * last message must have a @e res of #GNUNET_OK and an @e addr_len
+ * of zero.
*/
-struct OutboundMessage
+struct AddressToStringResultMessage
{
/**
- * Type will be #GNUNET_MESSAGE_TYPE_TRANSPORT_SEND
+ * Type will be #GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY
*/
struct GNUNET_MessageHeader header;
/**
- * Always zero.
- */
- uint32_t reserved GNUNET_PACKED;
-
- /**
- * Allowed delay.
+ * #GNUNET_OK if the conversion succeeded,
+ * #GNUNET_SYSERR if it failed
*/
- struct GNUNET_TIME_RelativeNBO timeout;
+ uint32_t res GNUNET_PACKED;
/**
- * Which peer should receive the message?
+ * Length of the following string, zero if @e is #GNUNET_SYSERR
*/
- struct GNUNET_PeerIdentity peer;
-
+ uint32_t addr_len GNUNET_PACKED;
};
@@ -639,13 +645,7 @@ struct TransportPluginMonitorMessage
};
-
-
-
-
-
-
-
+#else
/* *********************** TNG messages ***************** */
@@ -950,6 +950,35 @@ struct GNUNET_TRANSPORT_SendMessageToAck
};
+/**
+ * Message from communicator to transport service asking for
+ * transmission of a backchannel message with the given peer @e pid
+ * and communicator.
+ */
+struct GNUNET_TRANSPORT_CommunicatorBackchannel
+{
+ /**
+ * Type will be #GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * Always zero, for alignment.
+ */
+ uint32_t reserved;
+
+ /**
+ * Target peer.
+ */
+ struct GNUNET_PeerIdentity pid;
+
+ /* Followed by a `struct GNUNET_MessageHeader` with the encapsulated
+ message to the communicator */
+
+ /* Followed by the 0-terminated string specifying the desired
+ communicator */
+};
+
/**
@@ -1028,9 +1057,7 @@ struct GNUNET_TRANSPORT_MonitorData
};
-
-
-
+#endif
GNUNET_NETWORK_STRUCT_END
diff --git a/src/transport/transport_api2_communication.c b/src/transport/transport_api2_communication.c
index ffd7f208e..a8237f18f 100644
--- a/src/transport/transport_api2_communication.c
+++ b/src/transport/transport_api2_communication.c
@@ -25,6 +25,7 @@
#include "gnunet_util_lib.h"
#include "gnunet_protocols.h"
#include "gnunet_transport_communication_service.h"
+#include "gnunet_ats_transport_service.h"
#include "transport.h"
@@ -178,6 +179,18 @@ struct GNUNET_TRANSPORT_CommunicatorHandle
void *mq_init_cls;
/**
+ * Function to call when the transport service receives messages
+ * for a communicator (i.e. for NAT traversal or for non-bidirectional
+ * communicators).
+ */
+ GNUNET_TRANSPORT_CommunicatorNotify notify_cb;
+
+ /**
+ * Closure for @e notify_Cb.
+ */
+ void *notify_cb_cls;
+
+ /**
* Queue to talk to the transport service.
*/
struct GNUNET_MQ_Handle *mq;
@@ -744,6 +757,7 @@ reconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
GNUNET_MESSAGE_TYPE_TRANSPORT_SEND_MSG,
struct GNUNET_TRANSPORT_SendMessageTo,
ch),
+ // FIXME: handle backchannel notifications!
GNUNET_MQ_handler_end()
};
struct GNUNET_TRANSPORT_CommunicatorAvailableMessage *cam;
@@ -790,6 +804,8 @@ reconnect (struct GNUNET_TRANSPORT_CommunicatorHandle *ch)
* the address of another peer, can be NULL if the
* communicator only supports receiving messages
* @param mq_init_cls closure for @a mq_init
+ * @param notify_cb function to pass backchannel messages to communicator
+ * @param notify_cb_cls closure for @a notify_cb
* @return NULL on error
*/
struct GNUNET_TRANSPORT_CommunicatorHandle *
@@ -798,7 +814,9 @@ GNUNET_TRANSPORT_communicator_connect (const struct GNUNET_CONFIGURATION_Handle
const char *addr_prefix,
enum GNUNET_TRANSPORT_CommunicatorCharacteristics cc,
GNUNET_TRANSPORT_CommunicatorMqInit mq_init,
- void *mq_init_cls)
+ void *mq_init_cls,
+ GNUNET_TRANSPORT_CommunicatorNotify notify_cb,
+ void *notify_cb_cls)
{
struct GNUNET_TRANSPORT_CommunicatorHandle *ch;
@@ -808,6 +826,8 @@ GNUNET_TRANSPORT_communicator_connect (const struct GNUNET_CONFIGURATION_Handle
ch->addr_prefix = addr_prefix;
ch->mq_init = mq_init;
ch->mq_init_cls = mq_init_cls;
+ ch->notify_cb = notify_cb;
+ ch->notify_cb_cls = notify_cb_cls;
ch->cc = cc;
reconnect (ch);
if (GNUNET_OK !=
@@ -1041,4 +1061,48 @@ GNUNET_TRANSPORT_communicator_address_remove (struct GNUNET_TRANSPORT_AddressIde
}
+/* ************************* Backchannel *************************** */
+
+
+/**
+ * The communicator asks the transport service to route a message via
+ * a different path to another communicator service at another peer.
+ * This must only be done for special control traffic (as there is no
+ * flow control for this API), such as acknowledgements, and generally
+ * only be done if the communicator is uni-directional (i.e. cannot
+ * send the message back itself).
+ *
+ * @param ch handle of this communicator
+ * @param pid peer to send the message to
+ * @param comm name of the communicator to send the message to
+ * @param header header of the message to transmit and pass via the
+ * notify-API to @a pid's communicator @a comm
+ */
+void
+GNUNET_TRANSPORT_communicator_notify (struct GNUNET_TRANSPORT_CommunicatorHandle *ch,
+ const struct GNUNET_PeerIdentity *pid,
+ const char *comm,
+ const struct GNUNET_MessageHeader *header)
+{
+ struct GNUNET_MQ_Envelope *env;
+ struct GNUNET_TRANSPORT_CommunicatorBackchannel *cb;
+ size_t slen = strlen (comm) + 1;
+ uint16_t mlen = ntohs (header->size);
+
+ GNUNET_assert (mlen + slen + sizeof (*cb) < UINT16_MAX);
+ env = GNUNET_MQ_msg_extra (cb,
+ slen + mlen,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_COMMUNICATOR_BACKCHANNEL);
+ cb->pid = *pid;
+ memcpy (&cb[1],
+ header,
+ mlen);
+ memcpy (((char *)&cb[1]) + mlen,
+ comm,
+ slen);
+ GNUNET_MQ_send (ch->mq,
+ env);
+}
+
+
/* end of transport_api2_communication.c */
diff --git a/src/transport/transport_api2_core.c b/src/transport/transport_api2_core.c
index 78d8dcce0..d81a6f730 100644
--- a/src/transport/transport_api2_core.c
+++ b/src/transport/transport_api2_core.c
@@ -11,7 +11,7 @@
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Affero General Public License for more details.
-
+
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
diff --git a/src/transport/transport_api_core.c b/src/transport/transport_api_core.c
index 2e897d94a..06d459f4e 100644
--- a/src/transport/transport_api_core.c
+++ b/src/transport/transport_api_core.c
@@ -28,6 +28,7 @@
#include "gnunet_hello_lib.h"
#include "gnunet_protocols.h"
#include "gnunet_transport_core_service.h"
+#include "gnunet_transport_service.h"
#include "transport.h"
#define LOG(kind,...) GNUNET_log_from (kind, "transport-api-core",__VA_ARGS__)