/*
This file is part of GNUnet
- (C) 2009 Christian Grothoff (and other contributing authors)
+ (C) 2009, 2010 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2, or (at your
+ by the Free Software Foundation; either version 3, or (at your
option) any later version.
GNUnet is distributed in the hope that it will be useful, but
* Note that the destructors of transport plugins will
* be given the value returned by the constructor
* and is expected to return a NULL pointer.
- *
- * TODO:
- * - consider moving DATA message (latency measurement)
- * to service; avoids encapsulation overheads and
- * would enable latency measurements for non-bidi
- * transports.
- * -
- *
* @author Christian Grothoff
*/
#ifndef PLUGIN_TRANSPORT_H
#include "gnunet_configuration_lib.h"
#include "gnunet_scheduler_lib.h"
+#include "gnunet_statistics_service.h"
#include "gnunet_transport_service.h"
/**
- * Opaque internal context for a particular peer of the transport
- * service. Plugins will be given a pointer to this type and, if
- * cheaply possible, should pass this pointer back to the transport
- * service whenever additional messages from the same peer are
- * received.
+ * Opaque pointer that plugins can use to distinguish specific
+ * connections to a given peer. Typically used by stateful plugins to
+ * allow the service to refer to specific streams instead of a more
+ * general notion of "some connection" to the given peer. This is
+ * useful since sometimes (i.e. for inbound TCP connections) a
+ * connection may not have an address that can be used for meaningful
+ * distinction between sessions to the same peer.
*/
-struct ReadyList;
+struct Session;
/**
- * Function called by the transport for each received message.
- * This function should also be called with "NULL" for the
- * message to signal that the other peer disconnected.
- *
+ * Every 'struct Session' must begin with this header.
+ */
+struct SessionHeader
+{
+
+ /**
+ * Cached signature for PONG generation for the session. Do not use
+ * in the plugin!
+ */
+ struct GNUNET_CRYPTO_RsaSignature pong_signature;
+
+ /**
+ * Expiration time for signature. Do not use in the plugin!
+ */
+ struct GNUNET_TIME_Absolute pong_sig_expires;
+
+};
+
+/**
+ * Function that will be called whenever the plugin internally
+ * cleans up a session pointer and hence the service needs to
+ * discard all of those sessions as well. Plugins that do not
+ * use sessions can simply omit calling this function and always
+ * use NULL wherever a session pointer is needed.
+ *
* @param cls closure
- * @param plugin_context value to pass to this plugin
- * to respond to the given peer (use is optional,
- * but may speed up processing)
- * @param service_context value passed to the transport-service
- * to identify the neighbour; will be NULL on the first
- * call for a given peer
- * @param latency estimated latency for communicating with the
- * given peer; should be set to GNUNET_TIME_UNIT_FOREVER_REL
- * until the transport has seen messages transmitted in
- * BOTH directions (and hence been able to do an actual
- * round-trip observation); a non-FOREVER latency is also used
- * by the transport to know that communication in both directions
- * using this one plugin actually works
- * @param peer (claimed) identity of the other peer
- * @param message the message, NULL if peer was disconnected
- * @return the new service_context that the plugin should use
- * for future receive calls for messages from this
- * particular peer
+ * @param peer which peer was the session for
+ * @param session which session is being destoyed
*/
-typedef struct ReadyList *
- (*GNUNET_TRANSPORT_PluginReceiveCallback) (void *cls,
- void *plugin_context,
- struct ReadyList *
- service_context,
- struct GNUNET_TIME_Relative
- latency,
- const struct GNUNET_PeerIdentity
- * peer,
- const struct GNUNET_MessageHeader
- * message);
+typedef void (*GNUNET_TRANSPORT_SessionEnd) (void *cls,
+ const struct GNUNET_PeerIdentity *peer,
+ struct Session *session);
/**
- * Function that will be called if we receive a validation
- * of an address challenge that we transmitted to another
- * peer. Note that the validation should only be considered
- * acceptable if the challenge matches AND if the sender
- * address is at least a plausible address for this peer
- * (otherwise we may be seeing a MiM attack).
+ * Function called by the transport for each received message.
+ * This function should also be called with "NULL" for the
+ * message to signal that the other peer disconnected.
*
* @param cls closure
- * @param name name of the transport that generated the address
- * @param peer who responded to our challenge
- * @param challenge the challenge number we presumably used
- * @param sender_addr string describing our sender address (as observed
- * by the other peer in human-readable format)
+ * @param peer (claimed) identity of the other peer
+ * @param message the message, NULL if we only care about
+ * learning about the delay until we should receive again -- FIXME!
+ * @param distance in overlay hops; use 1 unless DV (or 0 if message == NULL)
+ * @param session identifier used for this session (NULL for plugins
+ * that do not offer bi-directional communication to the sender
+ * using the same "connection")
+ * @param sender_address binary address of the sender (if we established the
+ * connection or are otherwise sure of it; should be NULL
+ * for inbound TCP/UDP connections since it it not clear
+ * that we could establish ourselves a connection to that
+ * IP address and get the same system)
+ * @param sender_address_len number of bytes in sender_address
+ * @return how long the plugin should wait until receiving more data
+ * (plugins that do not support this, can ignore the return value)
*/
-typedef void (*GNUNET_TRANSPORT_ValidationNotification) (void *cls,
- const char *name,
- const struct GNUNET_PeerIdentity *peer,
- uint32_t challenge,
- const char *sender_addr);
-
+typedef struct GNUNET_TIME_Relative (*GNUNET_TRANSPORT_PluginReceiveCallback) (void *cls,
+ const struct
+ GNUNET_PeerIdentity *
+ peer,
+ const struct
+ GNUNET_MessageHeader *
+ message,
+ uint32_t distance,
+ struct Session *session,
+ const char *sender_address,
+ uint16_t sender_address_len);
/**
typedef void (*GNUNET_TRANSPORT_AddressNotification) (void *cls,
const char *name,
const void *addr,
- size_t addrlen,
+ uint16_t addrlen,
struct
GNUNET_TIME_Relative
expires);
/**
- * Function that will be called for each address obtained from the HELLO.
- *
- * @param cls closure
- * @param name name of the transport that generated the address
- * @param addr one of the addresses of the host, NULL for the last address
- * the specific address format depends on the transport
- * @param addrlen length of the address
- */
-typedef void (*GNUNET_TRANSPORT_AddressCallback) (void *cls,
- const char *name,
- const void *addr,
- size_t addrlen);
-
-
-/**
- * Function that allows a transport to query the known
- * network addresses for a given peer.
- *
+ * Function that will be called whenever the plugin receives data over
+ * the network and wants to determine how long it should wait until
+ * the next time it reads from the given peer. Note that some plugins
+ * (such as UDP) may not be able to wait (for a particular peer), so
+ * the waiting part is optional. Plugins that can wait should call
+ * this function, sleep the given amount of time, and call it again
+ * (with zero bytes read) UNTIL it returns zero and only then read.
+ *
* @param cls closure
- * @param timeout after how long should we time out?
- * @param target which peer are we looking for?
- * @param iter function to call for each known address
- * @param iter_cls closure for iter
+ * @param peer which peer did we read data from
+ * @param amount_recved number of bytes read (can be zero)
+ * @return how long to wait until reading more from this peer
+ * (to enforce inbound quotas)
*/
-typedef void (*GNUNET_TRANSPORT_LookupAddress) (void *cls,
- struct GNUNET_TIME_Relative
- timeout,
- const struct
- GNUNET_PeerIdentity * target,
- GNUNET_TRANSPORT_AddressCallback
- iter, void *iter_cls);
+typedef struct GNUNET_TIME_Relative (*GNUNET_TRANSPORT_TrafficReport) (void *cls,
+ const struct
+ GNUNET_PeerIdentity *peer,
+ size_t amount_recved);
/**
struct GNUNET_SCHEDULER_Handle *sched;
/**
- * Our public key.
+ * Identity of this peer.
*/
- struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *my_public_key;
+ const struct GNUNET_PeerIdentity *my_identity;
/**
- * Our private key.
+ * Pointer (!) to our HELLO message. Note that the address
+ * referred to "*our_hello" might change over time.
*/
- struct GNUNET_CRYPTO_RsaPrivateKey *my_private_key;
+ struct GNUNET_HELLO_Message *const*our_hello;
/**
- * Identity of this peer.
+ * Closure for the various callbacks.
*/
- const struct GNUNET_PeerIdentity *my_identity;
+ void *cls;
/**
- * Closure for the various callbacks.
+ * Handle for reporting statistics.
*/
- void *cls;
+ struct GNUNET_STATISTICS_Handle *stats;
/**
* Function that should be called by the transport plugin
*/
GNUNET_TRANSPORT_PluginReceiveCallback receive;
- /**
- * Address lookup function.
- */
- GNUNET_TRANSPORT_LookupAddress lookup;
-
/**
* Function that must be called by each plugin to notify the
* transport service about the addresses under which the transport
GNUNET_TRANSPORT_AddressNotification notify_address;
/**
- * Function that must be called by each plugin to notify the
- * transport service about a successful validation of an
- * address of another peer (or at least likely successful
- * validation).
+ * Inform service about traffic received, get information
+ * about when we might be willing to receive more.
*/
- GNUNET_TRANSPORT_ValidationNotification notify_validation;
+ GNUNET_TRANSPORT_TrafficReport traffic_report;
/**
- * What is the default quota (in terms of incoming bytes per
- * ms) for new connections?
+ * Function that must be called by the plugin when a non-NULL
+ * session handle stops being valid (is destroyed).
*/
- uint32_t default_quota_in;
+ GNUNET_TRANSPORT_SessionEnd session_end;
/**
* What is the maximum number of connections that this transport
};
-/**
- * Function that can be used by the transport service to validate
- * the address of another peer. Even if
- * we already have a connection to this peer, this function is
- * required to establish a new one.
- *
- * @param cls closure
- * @param target who should receive this message
- * @param challenge challenge code to use
- * @param timeout how long should we try to transmit these?
- * @param addrlen length of the address
- * @param addr the address
- * @return GNUNET_OK on success, GNUNET_SYSERR if the address
- * format is invalid
- */
-typedef int
- (*GNUNET_TRANSPORT_ValidationFunction) (void *cls,
- const struct
- GNUNET_PeerIdentity * target,
- uint32_t challenge,
- struct GNUNET_TIME_Relative
- timeout, const void *addr,
- size_t addrlen);
-
/**
* Function called by the GNUNET_TRANSPORT_TransmitFunction
* upon "completion".
*
* @param cls closure
- * @param service_context value passed to the transport-service
- * to identify the neighbour
* @param target who was the recipient of the message?
* @param result GNUNET_OK on success
* GNUNET_SYSERR if the target disconnected;
*/
typedef void
(*GNUNET_TRANSPORT_TransmitContinuation) (void *cls,
- struct ReadyList *
- service_context,
const struct GNUNET_PeerIdentity *
target, int result);
+
/**
* Function that can be used by the transport service to transmit
* a message using the plugin. Note that in the case of a
* a fresh connection to another peer.
*
* @param cls closure
- * @param plugin_context value we were asked to pass to this plugin
- * to respond to the given peer (use is optional,
- * but may speed up processing), can be NULL
- * @param service_context value passed to the transport-service
- * to identify the neighbour; NULL is used to indicate
- * an urgent message. If the urgent message can not be
- * scheduled for immediate transmission, the plugin is to
- * call the continuation with failure immediately
* @param target who should receive this message
- * @param priority how important is the message?
- * @param msg the message to transmit
- * @param timeout how long to wait at most for the transmission
+ * @param msgbuf the message to transmit
+ * @param msgbuf_size number of bytes in 'msgbuf'
+ * @param priority how important is the message (most plugins will
+ * ignore message priority and just FIFO)
+ * @param timeout how long to wait at most for the transmission (does not
+ * require plugins to discard the message after the timeout,
+ * just advisory for the desired delay; most plugins will ignore
+ * this as well)
+ * @param session which session must be used (or NULL for "any")
+ * @param addr the address to use (can be NULL if the plugin
+ * is "on its own" (i.e. re-use existing TCP connection))
+ * @param addrlen length of the address in bytes
+ * @param force_address GNUNET_YES if the plugin MUST use the given address,
+ * GNUNET_NO means the plugin may use any other address and
+ * GNUNET_SYSERR means that only reliable existing
+ * bi-directional connections should be used (regardless
+ * of address)
* @param cont continuation to call once the message has
* been transmitted (or if the transport is ready
* for the next transmission call; or if the
* peer disconnected...); can be NULL
* @param cont_cls closure for cont
- * @return plugin_context that should be used next time for
- * sending messages to the specified peer
+ * @return number of bytes used (on the physical network, with overheads);
+ * -1 on hard errors (i.e. address invalid); 0 is a legal value
+ * and does NOT mean that the message was not transmitted (DV)
*/
-typedef void *
+typedef ssize_t
(*GNUNET_TRANSPORT_TransmitFunction) (void *cls,
- void *plugin_context,
- struct ReadyList * service_context,
const struct GNUNET_PeerIdentity *
target,
- unsigned int priority,
- const struct GNUNET_MessageHeader *
- msg,
+ const char *msgbuf,
+ size_t msgbuf_size,
+ uint32_t priority,
struct GNUNET_TIME_Relative timeout,
- GNUNET_TRANSPORT_TransmitContinuation
+ struct Session *session,
+ const void *addr,
+ size_t addrlen,
+ int force_address,
+ GNUNET_TRANSPORT_TransmitContinuation
cont, void *cont_cls);
* closed after a getting this call.
*
* @param cls closure
- * @param plugin_context value we were asked to pass to this plugin
- * to respond to the given peer (use is optional,
- * but may speed up processing), can be NULL (if
- * NULL was returned from the transmit function); note
- * that use of NULL is dangerous since then this call may
- * cancel any session with the target peer (including
- * HELLO validation sessions), which is likely not what
- * is intended.
- * @param service_context must correspond to the service context
- * of the corresponding Transmit call; the plugin should
- * not cancel a send call made with a different service
- * context pointer! Never NULL.
* @param target peer for which the last transmission is
* to be cancelled
*/
typedef void
- (*GNUNET_TRANSPORT_CancelFunction) (void *cls,
- void *plugin_context,
- struct ReadyList * service_context,
- const struct GNUNET_PeerIdentity *
- target);
+ (*GNUNET_TRANSPORT_DisconnectFunction) (void *cls,
+ const struct GNUNET_PeerIdentity *
+ target);
/**
/**
- * Set a quota for receiving data from the given peer; this is a
- * per-transport limit. The transport should limit its read/select
- * calls to stay below the quota (in terms of incoming data).
+ * Another peer has suggested an address for this peer and transport
+ * plugin. Check that this could be a valid address. This function
+ * is not expected to 'validate' the address in the sense of trying to
+ * connect to it but simply to see if the binary format is technically
+ * legal for establishing a connection to this peer (and make sure that
+ * the address really corresponds to our network connection/settings
+ * and not some potential man-in-the-middle).
*
- * @param cls closure
- * @param peer the peer for whom the quota is given
- * @param quota_in quota for receiving/sending data in bytes per ms
+ * @param addr pointer to the address
+ * @param addrlen length of addr
+ * @return GNUNET_OK if this is a plausible address for this peer
+ * and transport, GNUNET_SYSERR if not
*/
-typedef void
- (*GNUNET_TRANSPORT_SetQuota) (void *cls,
- const struct GNUNET_PeerIdentity * target,
- uint32_t quota_in);
+typedef int
+(*GNUNET_TRANSPORT_CheckAddress) (void *cls,
+ const void *addr, size_t addrlen);
/**
- * Another peer has suggested an address for this
- * peer and transport plugin. Check that this could be a valid
- * address. If so, consider adding it to the list
- * of addresses.
+ * Function called for a quick conversion of the binary address to
+ * a numeric address. Note that the caller must not free the
+ * address and that the next call to this function is allowed
+ * to override the address again.
*
- * @param addr pointer to the address
- * @param addrlen length of addr
- * @return GNUNET_OK if this is a plausible address for this peer
- * and transport
+ * @param cls closure
+ * @param addr binary address
+ * @param addr_len length of the address
+ * @return string representing the same address
*/
-typedef int
- (*GNUNET_TRANSPORT_SuggestAddress) (void *cls,
- const void *addr, size_t addrlen);
+typedef const char* (*GNUNET_TRANSPORT_AddressToString) (void *cls,
+ const void *addr,
+ size_t addrlen);
+
/**
* Each plugin is required to return a pointer to a struct of this
*/
void *cls;
- /**
- * Function used to send a single message to a particular
- * peer using the specified address. Used to validate
- * HELLOs.
- */
- GNUNET_TRANSPORT_ValidationFunction validate;
-
/**
* Function that the transport service will use to transmit data to
- * another peer. May be null for plugins that only support
+ * another peer. May be NULL for plugins that only support
* receiving data. After this call, the plugin call the specified
* continuation with success or error before notifying us about the
* target having disconnected.
GNUNET_TRANSPORT_TransmitFunction send;
/**
- * Function that can be used to force the plugin to disconnect
- * from the given peer and cancel all previous transmissions
- * (and their continuationc).
+ * Function that can be used to force the plugin to disconnect from
+ * the given peer and cancel all previous transmissions (and their
+ * continuations). Note that if the transport does not have
+ * sessions / persistent connections (for example, UDP), this
+ * function may very well do nothing.
*/
- GNUNET_TRANSPORT_CancelFunction cancel;
+ GNUNET_TRANSPORT_DisconnectFunction disconnect;
/**
* Function to pretty-print addresses. NOTE: this function is not
GNUNET_TRANSPORT_AddressPrettyPrinter address_pretty_printer;
/**
- * Function that the transport service can use to try to enforce a
- * quota for the number of bytes received via this transport.
- * Transports that can not refuse incoming data (such as UDP)
- * are free to ignore these calls.
+ * Function that will be called to check if a binary address
+ * for this plugin is well-formed and corresponds to an
+ * address for THIS peer (as per our configuration). Naturally,
+ * if absolutely necessary, plugins can be a bit conservative in
+ * their answer, but in general plugins should make sure that the
+ * address does not redirect traffic to a 3rd party that might
+ * try to man-in-the-middle our traffic.
*/
- GNUNET_TRANSPORT_SetQuota set_receive_quota;
+ GNUNET_TRANSPORT_CheckAddress check_address;
/**
- * Function that will be called if another peer suggested that
- * we should use a particular address (since he is reaching
- * us at that address) for this transport.
+ * Function that will be called to convert a binary address
+ * to a string (numeric conversion only).
*/
- GNUNET_TRANSPORT_SuggestAddress address_suggested;
+ GNUNET_TRANSPORT_AddressToString address_to_string;
- /**
- * Relative cost of this transport compared to others. This
- * is supposed to be a static cost estimate which determines
- * which plugins should not even be attempted if other,
- * cheaper transports are already working. The idea is that
- * the costs have roughly this relationship:
- * <pre>
- * TCP < UDP < HTTP == HTTPS < SMTP
- * </pre>
- */
- unsigned int cost_estimate;
};