0.9.0pre2:
+* BIG CORE REFACTORING:
+ - get testcases to pass again (!)
+ - fix transport service API (ATS!)
+ - fix transport plugin API (ATS!)
+ - actually transmit ATS data through core API
+ - fix FS 'latency' ATS function
+ - fix DV
* Integration test:
- test bootstrapping via hostlist + transport/core/dht connect
peerinfo-tool \
core \
testing \
- dv \
+ $(dv) \
dht \
hostlist \
topology \
libgnunetcore.la
libgnunetcore_la_SOURCES = \
- core_api.c core.h \
- core_api_peer_get_info.c \
- core_api_peer_request.c \
- core_api_iterate_peers.c
+ core_api.c core.h
libgnunetcore_la_LIBADD = \
$(top_builddir)/src/util/libgnunetutil.la \
$(GN_LIBINTL) $(XLIB)
* @file core/core.h
* @brief common internal definitions for core service
* @author Christian Grothoff
+ *
+ * TODO:
+ * - bound message queue size
+ * - on disconnect from core, signal disconnect for all peers
+ * and clean up peer records
+ * - create / destroy peer records on connect/disconnect events
+ * - implement iterator API
+ * - implement re-configure API
+ * - check on peer-related events that connection is known
+ * (if not, GNUNET_break + reconnect)
+ * - handle atsi records
*/
#include "gnunet_bandwidth_lib.h"
#include "gnunet_crypto_lib.h"
struct GNUNET_MessageHeader header;
/**
- * Distance to the peer.
+ * Number of ATS key-value pairs that follow this struct
+ * (excluding the 0-terminator).
*/
- uint32_t distance GNUNET_PACKED;
+ uint32_t ats_count GNUNET_PACKED;
/**
* Currently observed latency.
*/
struct GNUNET_PeerIdentity peer;
+ /**
+ * First of the ATS information blocks (we must have at least
+ * one due to the 0-termination requirement).
+ */
+ struct GNUNET_TRANSPORT_ATS_Information ats;
+
};
struct GNUNET_MessageHeader header;
/**
- * Distance to the peer.
- */
- uint32_t distance GNUNET_PACKED;
-
- /**
- * Currently observed latency.
+ * Number of ATS key-value pairs that follow this struct
+ * (excluding the 0-terminator).
*/
- struct GNUNET_TIME_RelativeNBO latency;
+ uint32_t ats_count GNUNET_PACKED;
/**
* When the peer would time out (unless we see activity)
*/
struct GNUNET_PeerIdentity peer;
+ /**
+ * First of the ATS information blocks (we must have at least
+ * one due to the 0-termination requirement).
+ */
+ struct GNUNET_TRANSPORT_ATS_Information ats;
+
};
};
-
/**
* Message sent by the service to clients to notify them about
* messages being received or transmitted. This overall message is
struct GNUNET_MessageHeader header;
/**
- * Distance to the peer.
+ * Number of ATS key-value pairs that follow this struct
+ * (excluding the 0-terminator).
*/
- uint32_t distance GNUNET_PACKED;
+ uint32_t ats_count GNUNET_PACKED;
/**
* Currently observed latency.
*/
struct GNUNET_PeerIdentity peer;
+ /**
+ * First of the ATS information blocks (we must have at least
+ * one due to the 0-termination requirement).
+ */
+ struct GNUNET_TRANSPORT_ATS_Information ats;
+
};
struct GNUNET_MessageHeader header;
/**
- * Always zero.
+ * Unique request ID.
*/
- uint32_t reserved GNUNET_PACKED;
+ uint32_t rim_id GNUNET_PACKED;
/**
* Limit the number of bytes of outbound traffic to this
int32_t reserved_amount GNUNET_PACKED;
/**
- * Available bandwidth in for this peer.
- * 0 if we have been disconnected.
+ * Unique request ID.
*/
- struct GNUNET_BANDWIDTH_Value32NBO bw_in;
+ uint32_t rim_id GNUNET_PACKED;
/**
* Available bandwidth out for this peer,
uint64_t preference;
/**
- * Identity of the receiver or sender.
+ * Identity of the peer.
+ */
+ struct GNUNET_PeerIdentity peer;
+
+};
+
+
+/**
+ * Client notifying core about the maximum-priority
+ * message it has in the queue for a particular target.
+ */
+struct SendMessageRequest
+{
+ /**
+ * Header with type GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * How important is this message?
+ */
+ uint32_t priority GNUNET_PACKED;
+
+ /**
+ * By what time would the sender really like to see this
+ * message transmitted?
+ */
+ struct GNUNET_TIME_AbsoluteNBO deadline;
+
+ /**
+ * Identity of the intended target.
+ */
+ struct GNUNET_PeerIdentity peer;
+
+ /**
+ * How large is the client's message queue for this peer?
+ */
+ uint32_t queue_size GNUNET_PACKED;
+
+ /**
+ * How large is the message?
+ */
+ uint16_t size GNUNET_PACKED;
+
+ /**
+ * Counter for this peer to match SMRs to replies.
+ */
+ uint16_t smr_id GNUNET_PACKED;
+
+};
+
+
+/**
+ * Core notifying client that it is allowed to now
+ * transmit a message to the given target
+ * (response to GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST).
+ */
+struct SendMessageReady
+{
+ /**
+ * Header with type GNUNET_MESSAGE_TYPE_CORE_SEND_READY
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * How many bytes are allowed for transmission?
+ * Guaranteed to be at least as big as the requested size,
+ * or ZERO if the request is rejected (will timeout,
+ * peer disconnected, queue full, etc.).
+ */
+ uint16_t size GNUNET_PACKED;
+
+ /**
+ * smr_id from the request.
+ */
+ uint16_t smr_id GNUNET_PACKED;
+
+ /**
+ * Identity of the intended target.
*/
struct GNUNET_PeerIdentity peer;
/**
- * Client asking core to transmit a particular message to
- * a particular target.
+ * Client asking core to transmit a particular message to a particular
+ * target (responsde to GNUNET_MESSAGE_TYPE_CORE_SEND_READY).
*/
struct SendMessage
{
* @brief core service; this is the main API for encrypted P2P
* communications
* @author Christian Grothoff
+ *
+ * TODO:
+ * - implement atsi parsing and passing
*/
#include "platform.h"
#include "gnunet_constants.h"
#include "core.h"
+/**
+ * Information we track for each peer.
+ */
+struct PeerRecord
+{
+
+ /**
+ * We generally do NOT keep peer records in a DLL; this
+ * DLL is only used IF this peer's 'pending_head' message
+ * is ready for transmission.
+ */
+ struct PeerRecord *prev;
+
+ /**
+ * We generally do NOT keep peer records in a DLL; this
+ * DLL is only used IF this peer's 'pending_head' message
+ * is ready for transmission.
+ */
+ struct PeerRecord *next;
+
+ /**
+ * Peer the record is about.
+ */
+ struct GNUNET_PeerIdentity peer;
+
+ /**
+ * Corresponding core handle.
+ */
+ struct GNUNET_CORE_Handle *ch;
+
+ /**
+ * Head of doubly-linked list of pending requests.
+ * Requests are sorted by deadline *except* for HEAD,
+ * which is only modified upon transmission to core.
+ */
+ struct GNUNET_CORE_TransmitHandle *pending_head;
+
+ /**
+ * Tail of doubly-linked list of pending requests.
+ */
+ struct GNUNET_CORE_TransmitHandle *pending_tail;
+
+ /**
+ * Pending callback waiting for peer information, or NULL for none.
+ */
+ GNUNET_CORE_PeerConfigurationInfoCallback pcic;
+
+ /**
+ * Closure for pcic.
+ */
+ void *pcic_cls;
+
+ /**
+ * Request information ID for the given pcic (needed in case a
+ * request is cancelled after being submitted to core and a new
+ * one is generated; in this case, we need to avoid matching the
+ * reply to the first (cancelled) request to the second request).
+ */
+ uint32_t rim_id;
+
+ /**
+ * ID of timeout task for the 'pending_head' handle
+ * which is the one with the smallest timeout.
+ */
+ GNUNET_SCHEDULER_TaskIdentifier timeout_task;
+
+ /**
+ * Current size of the queue of pending requests.
+ */
+ unsigned int queue_size;
+
+ /**
+ * SendMessageRequest ID generator for this peer.
+ */
+ uint16_t smr_id_gen;
+
+};
+
+
+/**
+ * Entry in a doubly-linked list of control messages to be transmitted
+ * to the core service. Control messages include traffic allocation,
+ * connection requests and of course our initial 'init' request.
+ *
+ * The actual message is allocated at the end of this struct.
+ */
+struct ControlMessage
+{
+ /**
+ * This is a doubly-linked list.
+ */
+ struct ControlMessage *next;
+
+ /**
+ * This is a doubly-linked list.
+ */
+ struct ControlMessage *prev;
+
+ /**
+ * Function to run after successful transmission (or call with
+ * reason 'TIMEOUT' on error).
+ */
+ GNUNET_SCHEDULER_Task cont;
+
+ /**
+ * Closure for 'cont'.
+ */
+ void *cont_cls;
+
+};
+
+
+
/**
* Context for the core service connection.
*/
struct GNUNET_CORE_Handle
{
-
/**
* Configuration we're using.
*/
const struct GNUNET_CORE_MessageHandler *handlers;
/**
- * Our connection to the service for notifications.
+ * Our connection to the service.
*/
- struct GNUNET_CLIENT_Connection *client_notifications;
+ struct GNUNET_CLIENT_Connection *client;
/**
* Handle for our current transmission request.
/**
* Head of doubly-linked list of pending requests.
*/
- struct GNUNET_CORE_TransmitHandle *pending_head;
+ struct ControlMessage *pending_head;
/**
* Tail of doubly-linked list of pending requests.
*/
- struct GNUNET_CORE_TransmitHandle *pending_tail;
+ struct ControlMessage *pending_tail;
/**
- * Currently submitted request (or NULL)
+ * Head of doubly-linked list of peers that are core-approved
+ * to send their next message.
*/
- struct GNUNET_CORE_TransmitHandle *submitted;
+ struct PeerRecord *ready_peer_head;
/**
- * Currently submitted request based on solicitation (or NULL)
+ * Tail of doubly-linked list of peers that are core-approved
+ * to send their next message.
*/
- struct GNUNET_CORE_TransmitHandle *solicit_transmit_req;
+ struct PeerRecord *ready_peer_tail;
/**
- * Buffer where we store a message for transmission in response
- * to a traffic solicitation (or NULL).
+ * Hash map listing all of the peers that we are currently
+ * connected to.
*/
- char *solicit_buffer;
+ struct GNUNET_CONTAINER_MultiHashMap *peers;
/**
- * How long to wait until we time out the connection attempt?
+ * ID of reconnect task (if any).
*/
- struct GNUNET_TIME_Absolute startup_timeout;
+ GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
/**
- * ID of reconnect task (if any).
+ * Request information ID generator.
*/
- GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
+ uint32_t rim_id_gen;
/**
- * Number of messages we should queue per target.
+ * Number of messages we are allowed to queue per target.
*/
unsigned int queue_size;
* requests?
*/
int currently_down;
+
};
struct GNUNET_CORE_TransmitHandle *prev;
/**
- * Corresponding core handle.
+ * Corresponding peer record.
*/
- struct GNUNET_CORE_Handle *ch;
+ struct PeerRecord *peer;
+
+ /**
+ * Corresponding SEND_REQUEST message. Only non-NULL
+ * while SEND_REQUEST message is pending.
+ */
+ struct ControlMessage *cm;
/**
* Function that will be called to get the actual request
*/
void *get_message_cls;
- /**
- * If this entry is for a transmission request, pointer
- * to the notify callback; otherwise NULL.
- */
- GNUNET_CONNECTION_TransmitReadyNotify notify;
-
- /**
- * Closure for notify.
- */
- void *notify_cls;
-
- /**
- * Peer the request is about.
- */
- struct GNUNET_PeerIdentity peer;
-
/**
* Timeout for this handle.
*/
struct GNUNET_TIME_Absolute timeout;
- /**
- * ID of timeout task.
- */
- GNUNET_SCHEDULER_TaskIdentifier timeout_task;
-
/**
* How important is this message?
*/
*/
uint16_t msize;
+ /**
+ * Send message request ID for this request.
+ */
+ uint16_t smr_id;
};
+/**
+ * Our current client connection went down. Clean it up
+ * and try to reconnect!
+ *
+ * @param h our handle to the core service
+ */
static void
-reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+reconnect (struct GNUNET_CORE_Handle *h);
/**
- * Function called when we are ready to transmit our
- * "START" message (or when this operation timed out).
+ * Task schedule to try to re-connect to core.
*
- * @param cls closure
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
+ * @param cls the 'struct GNUNET_CORE_Handle'
+ * @param tc task context
*/
-static size_t transmit_start (void *cls, size_t size, void *buf);
+static void
+reconnect_task (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct GNUNET_CORE_Handle *h = cls;
+
+ h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
+ reconnect (h);
+}
/**
- * Our current client connection went down. Clean it up
- * and try to reconnect!
+ * Check the list of pending requests, send the next
+ * one to the core.
*
- * @param h our handle to the core service
+ * @param h core handle
*/
static void
-reconnect (struct GNUNET_CORE_Handle *h)
+trigger_next_request (struct GNUNET_CORE_Handle *h);
+
+
+/**
+ * The given request hit its timeout. Remove from the
+ * doubly-linked list and call the respective continuation.
+ *
+ * @param cls the transmit handle of the request that timed out
+ * @param tc context, can be NULL (!)
+ */
+static void
+transmission_timeout (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc);
+
+
+/**
+ * Control message was sent, mark it as such.
+ *
+ * @param cls the 'struct GNUNET_CORE_TransmitHandle*'
+ * @param tc scheduler context
+ */
+static void
+mark_control_message_sent (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
{
-#if DEBUG_CORE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Reconnecting to CORE service\n");
-#endif
- if (h->client_notifications != NULL)
- GNUNET_CLIENT_disconnect (h->client_notifications, GNUNET_NO);
- h->currently_down = GNUNET_YES;
- h->client_notifications = GNUNET_CLIENT_connect ("core", h->cfg);
- if (h->client_notifications == NULL)
- h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
- &reconnect_task,
- h);
- else
- h->cth = GNUNET_CLIENT_notify_transmit_ready (h->client_notifications,
- sizeof (struct InitMessage) +
- sizeof (uint16_t) * h->hcnt,
- GNUNET_TIME_UNIT_SECONDS,
- GNUNET_NO,
- &transmit_start, h);
+ struct GNUNET_CORE_TransmitHandle *th = cls;
+
+ th->cm = NULL;
+}
+
+
+/**
+ * Send a control message to the peer asking for transmission
+ * of the message in the given peer record.
+ *
+ * @param pr peer to request transmission to
+ */
+static void
+request_next_transmission (struct PeerRecord *pr)
+{
+ struct GNUNET_CORE_Handle *h = pr->ch;
+ struct ControlMessage *cm;
+ struct SendMessageRequest *smr;
+ struct GNUNET_CORE_TransmitHandle *th;
+
+ if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (pr->timeout_task);
+ pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (NULL == (th = pr->pending_head))
+ {
+ trigger_next_request (h);
+ return;
+ }
+ GNUNET_assert (pr->prev == NULL);
+ GNUNET_assert (pr->next == NULL);
+ pr->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (th->timeout),
+ &transmission_timeout,
+ pr);
+ cm = GNUNET_malloc (sizeof (struct ControlMessage) +
+ sizeof (struct SendMessageRequest));
+ cm->cont = &mark_control_message_sent;
+ cm->cont_cls = th;
+ th->cm = cm;
+ smr = (struct SendMessageRequest*) &cm[1];
+ smr->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST);
+ smr->header.size = htons (sizeof (struct SendMessageRequest));
+ smr->priority = htonl (th->priority);
+ smr->deadline = GNUNET_TIME_absolute_hton (th->timeout);
+ smr->peer = pr->peer;
+ smr->queue_size = htonl (pr->queue_size);
+ smr->size = htons (th->msize);
+ smr->smr_id = htons (th->smr_id = pr->smr_id_gen++);
+ GNUNET_CONTAINER_DLL_insert_after (h->pending_head,
+ h->pending_tail,
+ h->pending_tail,
+ cm);
+ trigger_next_request (h);
}
* @param tc context, can be NULL (!)
*/
static void
-timeout_request (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
+transmission_timeout (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct GNUNET_CORE_TransmitHandle *th = cls;
+ struct PeerRecord *pr = cls;
+ struct GNUNET_CORE_TransmitHandle *th;
- th->timeout_task = GNUNET_SCHEDULER_NO_TASK;
- GNUNET_CONTAINER_DLL_remove (th->ch->pending_head,
- th->ch->pending_tail,
+ pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+ th = pr->pending_head;
+ GNUNET_CONTAINER_DLL_remove (pr->pending_head,
+ pr->pending_tail,
th);
+ pr->queue_size--;
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Signalling timeout of request for transmission to CORE service\n");
#endif
GNUNET_assert (0 == th->get_message (th->get_message_cls, 0, NULL));
+ request_next_transmission (pr);
}
/**
- * Function called when we are ready to transmit a request from our
- * request list (or when this operation timed out).
- *
- * @param cls closure
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
+ * Transmit the next message to the core service.
*/
static size_t
-request_start (void *cls, size_t size, void *buf)
+transmit_message (void *cls,
+ size_t size,
+ void *buf)
{
struct GNUNET_CORE_Handle *h = cls;
+ struct ControlMessage *cm;
struct GNUNET_CORE_TransmitHandle *th;
+ struct PeerRecord *pr;
+ struct SendMessage *sm;
+ const struct GNUNET_MessageHeader *hdr;
+ uint16_t msize;
size_t ret;
- h->cth = NULL;
- th = h->pending_head;
- if (th == NULL)
- return 0;
+ h->cth = NULL;
if (buf == NULL)
{
- if (th->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+ reconnect (h);
+ return 0;
+ }
+ /* first check for control messages */
+ if (NULL != (cm = h->pending_head))
+ {
+ hdr = (const struct GNUNET_MessageHeader*) &cm[1];
+ msize = ntohs (hdr->size);
+ if (size < msize)
{
- GNUNET_SCHEDULER_cancel(th->timeout_task);
- th->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+ trigger_next_request (h);
+ return 0;
}
- timeout_request (th, NULL);
- return 0;
+ memcpy (buf, hdr, msize);
+ GNUNET_CONTAINER_DLL_remove (h->pending_head,
+ h->pending_tail,
+ cm);
+ if (NULL != cm->cont)
+ GNUNET_SCHEDULER_add_now (cm->cont, cm->cont_cls);
+ GNUNET_free (cm);
+ trigger_next_request (h);
+ return msize;
}
- GNUNET_CONTAINER_DLL_remove (h->pending_head,
- h->pending_tail,
- th);
- GNUNET_assert (h->submitted == NULL);
- h->submitted = th;
- GNUNET_assert (size >= th->msize);
- ret = th->get_message (th->get_message_cls, size, buf);
- GNUNET_assert (ret <= size);
+ /* now check for 'ready' P2P messages */
+ if (NULL != (pr = h->ready_peer_head))
+ {
+ th = pr->pending_head;
+ if (size < th->msize + sizeof (struct SendMessage))
+ {
+ trigger_next_request (h);
+ return 0;
+ }
+ GNUNET_CONTAINER_DLL_remove (h->ready_peer_head,
+ h->ready_peer_tail,
+ pr);
+ GNUNET_CONTAINER_DLL_remove (pr->pending_head,
+ pr->pending_tail,
+ th);
+ pr->queue_size--;
+ if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (pr->timeout_task);
+ pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ sm = (struct SendMessage *) buf;
+ sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND);
+ sm->priority = htonl (th->priority);
+ sm->deadline = GNUNET_TIME_absolute_hton (th->timeout);
+ sm->peer = pr->peer;
+ ret = th->get_message (th->get_message_cls,
+ size - sizeof (struct SendMessage),
+ &sm[1]);
+
+ if (0 == ret)
+ {
#if DEBUG_CORE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Transmitting %u bytes to core\n",
- ret);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Size of clients message to peer %s is 0!\n",
+ GNUNET_i2s(&pr->peer));
#endif
- return ret;
+ /* client decided to send nothing! */
+ request_next_transmission (pr);
+ return 0;
+ }
+#if DEBUG_CORE
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Produced SEND message to core with %u bytes payload\n",
+ (unsigned int) ret);
+#endif
+ GNUNET_assert (ret >= sizeof (struct GNUNET_MessageHeader));
+ if (ret + sizeof (struct SendMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ {
+ GNUNET_break (0);
+ request_next_transmission (pr);
+ return 0;
+ }
+ ret += sizeof (struct SendMessage);
+ sm->header.size = htons (ret);
+ GNUNET_assert (ret <= size);
+ GNUNET_free (th);
+ request_next_transmission (pr);
+ return ret;
+ }
+ return 0;
}
/**
* Check the list of pending requests, send the next
* one to the core.
+ *
+ * @param h core handle
*/
static void
trigger_next_request (struct GNUNET_CORE_Handle *h)
{
+ uint16_t msize;
+
+ if (GNUNET_YES == h->currently_down)
+ return;
+ if (NULL != h->cth)
+ return;
+ if (h->pending_head != NULL)
+ msize = ntohs (((struct GNUNET_MessageHeader*) &h->pending_head[1])->size);
+ else if (h->ready_peer_head != NULL)
+ msize = h->ready_peer_head->pending_head->msize + sizeof (struct SendMessage);
+ else
+ return; /* no pending message */
+ h->cth = GNUNET_CLIENT_notify_transmit_ready (h->client,
+ msize,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ GNUNET_NO,
+ &transmit_message, h);
+}
+
+
+
+
+/**
+ * Notify clients about disconnect and free
+ * the entry for connected peer.
+ *
+ * @param cls the 'struct GNUNET_CORE_Handle*'
+ * @param key the peer identity (not used)
+ * @param value the 'struct PeerRecord' to free.
+ * @return GNUNET_YES (continue)
+ */
+static int
+disconnect_and_free_peer_entry (void *cls,
+ const GNUNET_HashCode *key,
+ void *value)
+{
+ struct GNUNET_CORE_Handle *h = cls;
struct GNUNET_CORE_TransmitHandle *th;
+ struct PeerRecord *pr = value;
- if (h->currently_down)
+ while (NULL != (th = pr->pending_head))
{
-#if DEBUG_CORE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "In trigger_next_request, connection currently down...\n");
-#endif
- return; /* connection temporarily down */
+ GNUNET_CONTAINER_DLL_remove (pr->pending_head,
+ pr->pending_tail,
+ th);
+ pr->queue_size--;
+ GNUNET_assert (0 ==
+ th->get_message (th->get_message_cls,
+ 0, NULL));
+ GNUNET_free (th);
}
- if (NULL == (th = h->pending_head))
- return; /* no requests pending */
- GNUNET_assert (NULL == h->cth);
- h->cth = GNUNET_CLIENT_notify_transmit_ready (h->client_notifications,
- th->msize,
- GNUNET_TIME_absolute_get_remaining
- (th->timeout),
- GNUNET_NO,
- &request_start,
- h);
+ if (pr->pcic != NULL)
+ {
+ // FIXME: call pcic callback!
+ }
+ if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (pr->timeout_task);
+ pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ GNUNET_assert (pr->queue_size == 0);
+ if ( (pr->prev != NULL) ||
+ (pr->next != NULL) ||
+ (h->ready_peer_head == pr) )
+ GNUNET_CONTAINER_DLL_remove (h->ready_peer_head,
+ h->ready_peer_tail,
+ pr);
+ if (h->disconnects != NULL)
+ h->disconnects (h->cls,
+ &pr->peer);
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CONTAINER_multihashmap_remove (h->peers,
+ key,
+ pr));
+ GNUNET_assert (pr->pending_head == NULL);
+ GNUNET_assert (pr->pending_tail == NULL);
+ GNUNET_assert (pr->ch = h);
+ GNUNET_assert (pr->queue_size == 0);
+ GNUNET_assert (pr->timeout_task == GNUNET_SCHEDULER_NO_TASK);
+ GNUNET_free (pr);
+ return GNUNET_YES;
}
* @param msg the message received from the core service
*/
static void
-main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
+main_notify_handler (void *cls,
+ const struct GNUNET_MessageHeader *msg)
{
struct GNUNET_CORE_Handle *h = cls;
- unsigned int hpos;
+ const struct InitReplyMessage *m;
const struct ConnectNotifyMessage *cnm;
const struct DisconnectNotifyMessage *dnm;
const struct NotifyTrafficMessage *ntm;
const struct GNUNET_MessageHeader *em;
+ const struct ConfigurationInfoMessage *cim;
const struct PeerStatusNotifyMessage *psnm;
+ const struct SendMessageReady *smr;
+ const struct GNUNET_CORE_MessageHandler *mh;
+ GNUNET_CORE_StartupCallback init;
+ GNUNET_CORE_PeerConfigurationInfoCallback pcic;
+ struct GNUNET_PeerIdentity my_identity;
+ struct PeerRecord *pr;
+ struct GNUNET_CORE_TransmitHandle *th;
+ unsigned int hpos;
+ int trigger;
uint16_t msize;
uint16_t et;
- const struct GNUNET_CORE_MessageHandler *mh;
if (msg == NULL)
{
#endif
switch (ntohs (msg->type))
{
+ case GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY:
+ if (ntohs (msg->size) != sizeof (struct InitReplyMessage))
+ {
+ GNUNET_break (0);
+ reconnect (h);
+ return;
+ }
+ m = (const struct InitReplyMessage *) msg;
+ GNUNET_break (0 == ntohl (m->reserved));
+ /* start our message processing loop */
+#if DEBUG_CORE
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Successfully connected to core service, starting processing loop.\n");
+#endif
+ if (GNUNET_YES == h->currently_down)
+ {
+ h->currently_down = GNUNET_NO;
+ trigger_next_request (h);
+ }
+ if (NULL != (init = h->init))
+ {
+ /* mark so we don't call init on reconnect */
+ h->init = NULL;
+ GNUNET_CRYPTO_hash (&m->publicKey,
+ sizeof (struct
+ GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
+ &my_identity.hashPubKey);
+ init (h->cls, h, &my_identity, &m->publicKey);
+ }
+ break;
case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT:
- if (NULL == h->connects)
- {
- GNUNET_break (0);
- break;
- }
if (msize != sizeof (struct ConnectNotifyMessage))
{
GNUNET_break (0);
break;
}
cnm = (const struct ConnectNotifyMessage *) msg;
- h->connects (h->cls,
- &cnm->peer,
- GNUNET_TIME_relative_ntoh (cnm->latency),
- ntohl (cnm->distance));
+ pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
+ &cnm->peer.hashPubKey);
+ if (pr != NULL)
+ {
+ GNUNET_break (0);
+ reconnect (h);
+ return;
+ }
+ pr = GNUNET_malloc (sizeof (struct PeerRecord));
+ pr->peer = cnm->peer;
+ pr->ch = h;
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CONTAINER_multihashmap_put (h->peers,
+ &cnm->peer.hashPubKey,
+ pr,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
+ if (NULL != h->connects)
+ h->connects (h->cls,
+ &cnm->peer,
+ NULL /* FIXME: atsi! */);
break;
case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT:
- if (NULL == h->disconnects)
- {
- GNUNET_break (0);
- break;
- }
if (msize != sizeof (struct DisconnectNotifyMessage))
{
GNUNET_break (0);
break;
}
dnm = (const struct DisconnectNotifyMessage *) msg;
- h->disconnects (h->cls,
- &dnm->peer);
+ pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
+ &dnm->peer.hashPubKey);
+ if (pr == NULL)
+ {
+ GNUNET_break (0);
+ reconnect (h);
+ return;
+ }
+ trigger = ( (pr->prev != NULL) ||
+ (pr->next != NULL) ||
+ (h->ready_peer_head == pr) );
+ disconnect_and_free_peer_entry (h, &dnm->peer.hashPubKey, pr);
+ if (trigger)
+ trigger_next_request (h);
break;
case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE:
if (NULL == h->status_events)
break;
}
psnm = (const struct PeerStatusNotifyMessage *) msg;
+ pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
+ &psnm->peer.hashPubKey);
+ if (pr == NULL)
+ {
+ GNUNET_break (0);
+ reconnect (h);
+ return;
+ }
h->status_events (h->cls,
&psnm->peer,
- GNUNET_TIME_relative_ntoh (psnm->latency),
- ntohl (psnm->distance),
psnm->bandwidth_in,
psnm->bandwidth_out,
- GNUNET_TIME_absolute_ntoh (psnm->timeout));
+ GNUNET_TIME_absolute_ntoh (psnm->timeout),
+ NULL /* FIXME: atsi */);
break;
case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND:
if (msize <
ntohs (em->size),
GNUNET_i2s (&ntm->peer));
#endif
+ pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
+ &ntm->peer.hashPubKey);
+ if (pr == NULL)
+ {
+ GNUNET_break (0);
+ reconnect (h);
+ return;
+ }
if ((GNUNET_NO == h->inbound_hdr_only) &&
(msize != ntohs (em->size) + sizeof (struct NotifyTrafficMessage)))
{
}
if (GNUNET_OK !=
h->handlers[hpos].callback (h->cls, &ntm->peer, em,
- GNUNET_TIME_relative_ntoh (ntm->latency),
- ntohl (ntm->distance)))
+ NULL /* FIXME: atsi */))
{
/* error in processing, do not process other messages! */
break;
}
if (NULL != h->inbound_notify)
h->inbound_notify (h->cls, &ntm->peer, em,
- GNUNET_TIME_relative_ntoh (ntm->latency),
- ntohl (ntm->distance));
+ NULL /* FIXME: atsi */);
break;
case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND:
if (msize <
}
ntm = (const struct NotifyTrafficMessage *) msg;
em = (const struct GNUNET_MessageHeader *) &ntm[1];
- if ((GNUNET_NO == h->outbound_hdr_only) &&
+ pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
+ &ntm->peer.hashPubKey);
+ if (pr == NULL)
+ {
+ GNUNET_break (0);
+ reconnect (h);
+ return;
+ }
+ if ((GNUNET_NO == h->outbound_hdr_only) &&
(msize != ntohs (em->size) + sizeof (struct NotifyTrafficMessage)))
{
GNUNET_break (0);
break;
}
h->outbound_notify (h->cls, &ntm->peer, em,
- GNUNET_TIME_relative_ntoh (ntm->latency),
- ntohl (ntm->distance));
+ NULL /* FIXME: atsi? */);
+ break;
+ case GNUNET_MESSAGE_TYPE_CORE_SEND_READY:
+ if (msize != sizeof (struct SendMessageReady))
+ {
+ GNUNET_break (0);
+ break;
+ }
+ smr = (const struct SendMessageReady *) msg;
+ pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
+ &smr->peer.hashPubKey);
+ if (pr == NULL)
+ {
+ GNUNET_break (0);
+ reconnect (h);
+ return;
+ }
+ th = pr->pending_head;
+ if (ntohs (smr->smr_id) != th->smr_id)
+ {
+ /* READY message is for expired or cancelled message,
+ ignore! (we should have already sent another request) */
+ break;
+ }
+ if ( (pr->prev != NULL) ||
+ (pr->next != NULL) ||
+ (h->ready_peer_head == pr) )
+ {
+ /* we should not already be on the ready list... */
+ GNUNET_break (0);
+ reconnect (h);
+ return;
+ }
+ GNUNET_CONTAINER_DLL_insert (h->ready_peer_head,
+ h->ready_peer_tail,
+ pr);
+ trigger_next_request (h);
+ break;
+ case GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO:
+ if (ntohs (msg->size) != sizeof (struct ConfigurationInfoMessage))
+ {
+ GNUNET_break (0);
+ break;
+ }
+ cim = (const struct ConfigurationInfoMessage*) msg;
+ pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
+ &cim->peer.hashPubKey);
+ if (pr == NULL)
+ {
+ GNUNET_break (0);
+ reconnect (h);
+ return;
+ }
+ if (pr->rim_id != ntohl (cim->rim_id))
+ break;
+ pcic = pr->pcic;
+ pr->pcic = NULL;
+ if (pcic != NULL)
+ pcic (pr->pcic_cls,
+ &pr->peer,
+ cim->bw_out,
+ ntohl (cim->reserved_amount),
+ GNUNET_ntohll (cim->preference));
break;
default:
GNUNET_break (0);
break;
}
- GNUNET_CLIENT_receive (h->client_notifications,
+ GNUNET_CLIENT_receive (h->client,
&main_notify_handler, h, GNUNET_TIME_UNIT_FOREVER_REL);
}
/**
- * Function called when we are ready to transmit our
- * "START" message (or when this operation timed out).
- *
- * @param cls closure
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
- */
-static size_t transmit_start (void *cls, size_t size, void *buf);
-
-
-/**
- * Function called on the first message received from
- * the service (contains our public key, etc.).
- * Should trigger calling the init callback
- * and then start our regular message processing.
+ * Task executed once we are done transmitting the INIT message.
+ * Starts our 'receive' loop.
*
- * @param cls closure
- * @param msg message received, NULL on timeout or fatal error
+ * @param cls the 'struct GNUNET_CORE_Handle'
+ * @param tc task context
*/
static void
-init_reply_handler (void *cls, const struct GNUNET_MessageHeader *msg)
+init_done_task (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct GNUNET_CORE_Handle *h = cls;
- const struct InitReplyMessage *m;
- GNUNET_CORE_StartupCallback init;
- struct GNUNET_PeerIdentity my_identity;
- if ((msg == NULL) ||
- (ntohs (msg->size) != sizeof (struct InitReplyMessage)) ||
- (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY))
+ if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE))
{
- if (msg != NULL)
+ if (h->client != NULL)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- _
- ("Error connecting to core service (failed to receive `%s' message, got message of type %u and size %u).\n"),
- "INIT_REPLY",
- ntohs (msg->type),
- ntohs (msg->size));
- GNUNET_break (0);
+ GNUNET_CLIENT_disconnect (h->client, GNUNET_NO);
+ h->client = NULL;
}
- else
- {
-#if DEBUG_CORE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- _("Failed to connect to core service, will retry.\n"));
-#endif
- }
- transmit_start (h, 0, NULL);
+ h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
+ &reconnect_task,
+ h);
return;
}
- m = (const struct InitReplyMessage *) msg;
- GNUNET_break (0 == ntohl (m->reserved));
- /* start our message processing loop */
-#if DEBUG_CORE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Successfully connected to core service, starting processing loop.\n");
-#endif
- h->currently_down = GNUNET_NO;
- trigger_next_request (h);
- GNUNET_CLIENT_receive (h->client_notifications,
- &main_notify_handler, h, GNUNET_TIME_UNIT_FOREVER_REL);
- if (NULL != (init = h->init))
- {
- /* mark so we don't call init on reconnect */
- h->init = NULL;
- GNUNET_CRYPTO_hash (&m->publicKey,
- sizeof (struct
- GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
- &my_identity.hashPubKey);
- init (h->cls, h, &my_identity, &m->publicKey);
- }
-}
-
-
-static void
-reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct GNUNET_CORE_Handle *h = cls;
- h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
- reconnect (h);
+ GNUNET_CLIENT_receive (h->client,
+ &main_notify_handler,
+ h,
+ GNUNET_TIME_UNIT_FOREVER_REL);
}
/**
- * Function called when we are ready to transmit our
- * "START" message (or when this operation timed out).
+ * Our current client connection went down. Clean it up
+ * and try to reconnect!
*
- * @param cls closure
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
+ * @param h our handle to the core service
*/
-static size_t
-transmit_start (void *cls, size_t size, void *buf)
+static void
+reconnect (struct GNUNET_CORE_Handle *h)
{
- struct GNUNET_CORE_Handle *h = cls;
+ struct ControlMessage *cm;
struct InitMessage *init;
- uint16_t *ts;
- uint16_t msize;
uint32_t opt;
+ uint16_t msize;
+ uint16_t *ts;
unsigned int hpos;
- struct GNUNET_TIME_Relative delay;
- h->cth = NULL;
- if (size == 0)
+#if DEBUG_CORE
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Reconnecting to CORE service\n");
+#endif
+ if (h->client != NULL)
{
- if ((h->init == NULL) ||
- (GNUNET_TIME_absolute_get ().abs_value < h->startup_timeout.abs_value))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _("Failed to connect to core service, retrying.\n"));
- delay = GNUNET_TIME_absolute_get_remaining (h->startup_timeout);
- if ((h->init == NULL) || (delay.rel_value > 1000))
- delay = GNUNET_TIME_UNIT_SECONDS;
- if (h->init == NULL)
- h->startup_timeout =
- GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
- h->reconnect_task =
- GNUNET_SCHEDULER_add_delayed (delay, &reconnect_task, h);
- return 0;
- }
- /* timeout on initial connect */
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _("Failed to connect to core service, giving up.\n"));
- h->init (h->cls, NULL, NULL, NULL);
- GNUNET_CORE_disconnect (h);
- return 0;
+ GNUNET_CLIENT_disconnect (h->client, GNUNET_NO);
+ h->client = NULL;
+ GNUNET_CONTAINER_multihashmap_iterate (h->peers,
+ &disconnect_and_free_peer_entry,
+ h);
+ }
+ h->currently_down = GNUNET_YES;
+ h->client = GNUNET_CLIENT_connect ("core", h->cfg);
+ if (h->client == NULL)
+ {
+ h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
+ &reconnect_task,
+ h);
+ return;
}
msize = h->hcnt * sizeof (uint16_t) + sizeof (struct InitMessage);
- GNUNET_assert (size >= msize);
- init = buf;
+ cm = GNUNET_malloc (sizeof (struct ControlMessage) +
+ msize);
+ cm->cont = &init_done_task;
+ cm->cont_cls = h;
+ init = (struct InitMessage*) &cm[1];
init->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT);
init->header.size = htons (msize);
- opt = GNUNET_CORE_OPTION_NOTHING;
- if (h->connects != NULL)
- opt |= GNUNET_CORE_OPTION_SEND_CONNECT;
- if (h->disconnects != NULL)
- opt |= GNUNET_CORE_OPTION_SEND_DISCONNECT;
+ opt = GNUNET_CORE_OPTION_SEND_CONNECT | GNUNET_CORE_OPTION_SEND_DISCONNECT;
if (h->status_events != NULL)
opt |= GNUNET_CORE_OPTION_SEND_STATUS_CHANGE;
if (h->inbound_notify != NULL)
opt |= GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND;
}
init->options = htonl (opt);
- ts = (uint16_t *) & init[1];
+ ts = (uint16_t *) &init[1];
for (hpos = 0; hpos < h->hcnt; hpos++)
ts[hpos] = htons (h->handlers[hpos].type);
- GNUNET_CLIENT_receive (h->client_notifications,
- &init_reply_handler,
- h,
- GNUNET_TIME_absolute_get_remaining
- (h->startup_timeout));
- return sizeof (struct InitMessage) + h->hcnt * sizeof (uint16_t);
+ GNUNET_CONTAINER_DLL_insert (h->pending_head,
+ h->pending_tail,
+ cm);
+ trigger_next_request (h);
}
+
/**
* Connect to the core service. Note that the connection may
* complete (or fail) asynchronously.
*
* @param cfg configuration to use
* @param queue_size size of the per-peer message queue
- * @param timeout after how long should we give up trying to connect to the core service?
* @param cls closure for the various callbacks that follow (including handlers in the handlers array)
* @param init callback to call on timeout or once we have successfully
* connected to the core service; note that timeout is only meaningful if init is not NULL
struct GNUNET_CORE_Handle *
GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
unsigned int queue_size,
- struct GNUNET_TIME_Relative timeout,
void *cls,
GNUNET_CORE_StartupCallback init,
GNUNET_CORE_ConnectEventHandler connects,
h = GNUNET_malloc (sizeof (struct GNUNET_CORE_Handle));
h->cfg = cfg;
+ h->queue_size = queue_size;
h->cls = cls;
h->init = init;
h->connects = connects;
h->inbound_hdr_only = inbound_hdr_only;
h->outbound_hdr_only = outbound_hdr_only;
h->handlers = handlers;
- h->queue_size = queue_size;
- h->client_notifications = GNUNET_CLIENT_connect ("core", cfg);
- if (h->client_notifications == NULL)
- {
- GNUNET_free (h);
- return NULL;
- }
- h->startup_timeout = GNUNET_TIME_relative_to_absolute (timeout);
h->hcnt = 0;
while (handlers[h->hcnt].callback != NULL)
h->hcnt++;
GNUNET_assert (h->hcnt <
(GNUNET_SERVER_MAX_MESSAGE_SIZE -
sizeof (struct InitMessage)) / sizeof (uint16_t));
-#if DEBUG_CORE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Trying to connect to core service in next %llu ms.\n",
- timeout.rel_value);
-#endif
- h->cth =
- GNUNET_CLIENT_notify_transmit_ready (h->client_notifications,
- sizeof (struct InitMessage) +
- sizeof (uint16_t) * h->hcnt, timeout,
- GNUNET_YES,
- &transmit_start, h);
+ reconnect (h);
return h;
}
/**
- * Disconnect from the core service.
+ * Disconnect from the core service. This function can only
+ * be called *after* all pending 'GNUNET_CORE_notify_transmit_ready'
+ * requests have been explicitly cancelled.
*
* @param handle connection to core to disconnect
*/
void
GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle)
{
- if (handle->cth != NULL)
- GNUNET_CLIENT_notify_transmit_ready_cancel (handle->cth);
- if (handle->solicit_transmit_req != NULL)
- GNUNET_CORE_notify_transmit_ready_cancel (handle->solicit_transmit_req);
+ struct ControlMessage *cm;
+
if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (handle->reconnect_task);
- if (handle->client_notifications != NULL)
- GNUNET_CLIENT_disconnect (handle->client_notifications, GNUNET_NO);
- GNUNET_break (handle->pending_head == NULL);
- GNUNET_free_non_null (handle->solicit_buffer);
- GNUNET_free (handle);
-}
-
-
-/**
- * Build the message requesting data transmission.
- */
-static size_t
-produce_send (void *cls, size_t size, void *buf)
-{
- struct GNUNET_CORE_TransmitHandle *th = cls;
- struct GNUNET_CORE_Handle *h;
- struct SendMessage *sm;
- size_t dt;
- GNUNET_CONNECTION_TransmitReadyNotify notify;
- void *notify_cls;
-
- h = th->ch;
- if (buf == NULL)
{
- /* timeout or error */
-#if DEBUG_CORE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "P2P transmission request for `%4s' timed out.\n",
- GNUNET_i2s(&th->peer));
-#endif
- GNUNET_assert (0 == th->notify (th->notify_cls, 0, NULL));
- GNUNET_CORE_notify_transmit_ready_cancel (th);
- if ((h->pending_head == th) && (h->cth != NULL)) /* Request hasn't been canceled yet! */
- {
- GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth);
- h->cth = NULL;
- trigger_next_request (h);
- }
- /* Otherwise this request timed out, but another is actually queued for sending, so don't try to send another! */
- return 0;
+ GNUNET_SCHEDULER_cancel (handle->reconnect_task);
+ handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
}
- sm = (struct SendMessage *) buf;
- sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND);
- sm->priority = htonl (th->priority);
- sm->deadline = GNUNET_TIME_absolute_hton (th->timeout);
- sm->peer = th->peer;
- notify = th->notify;
- notify_cls = th->notify_cls;
- GNUNET_CORE_notify_transmit_ready_cancel (th);
- trigger_next_request (h);
- size = GNUNET_MIN (size,
- GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE);
- GNUNET_assert (size >= sizeof (struct SendMessage));
- dt = notify (notify_cls, size - sizeof (struct SendMessage), &sm[1]);
- if (0 == dt)
+ if (handle->cth != NULL)
{
-#if DEBUG_CORE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Size of clients message to peer %s is 0!\n",
- GNUNET_i2s(&sm->peer));
-#endif
- /* client decided to send nothing! */
- return 0;
+ GNUNET_CLIENT_notify_transmit_ready_cancel (handle->cth);
+ handle->cth = NULL;
}
-#if DEBUG_CORE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Produced SEND message to core with %u bytes payload\n",
- dt);
-#endif
- GNUNET_assert (dt >= sizeof (struct GNUNET_MessageHeader));
- if (dt + sizeof (struct SendMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ if (handle->client != NULL)
{
- GNUNET_break (0);
- return 0;
+ GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO);
+ handle->client = NULL;
}
-#if DEBUG_CORE
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Preparing for P2P transmission of %u bytes to `%4s'.\n",
- dt,
- GNUNET_i2s(&sm->peer));
-#endif
- sm->header.size = htons (dt + sizeof (struct SendMessage));
- GNUNET_assert (dt + sizeof (struct SendMessage) <= size);
- return dt + sizeof (struct SendMessage);
+ while (NULL != (cm = handle->pending_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (handle->pending_head,
+ handle->pending_tail,
+ cm);
+ GNUNET_free (cm);
+ }
+ GNUNET_CONTAINER_multihashmap_iterate (handle->peers,
+ &disconnect_and_free_peer_entry,
+ handle);
+ GNUNET_CONTAINER_multihashmap_destroy (handle->peers);
+ GNUNET_break (handle->ready_peer_head == NULL);
+ GNUNET_free (handle);
}
*/
struct GNUNET_CORE_TransmitHandle *
GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle,
- unsigned int priority,
+ uint32_t priority,
struct GNUNET_TIME_Relative maxdelay,
const struct GNUNET_PeerIdentity *target,
size_t notify_size,
GNUNET_CONNECTION_TransmitReadyNotify notify,
void *notify_cls)
{
+ struct PeerRecord *pr;
struct GNUNET_CORE_TransmitHandle *th;
+ struct GNUNET_CORE_TransmitHandle *pos;
+ struct GNUNET_CORE_TransmitHandle *prev;
+ struct GNUNET_CORE_TransmitHandle *minp;
+ pr = GNUNET_CONTAINER_multihashmap_get (handle->peers,
+ &target->hashPubKey);
+ if (NULL == pr)
+ {
+ /* attempt to send to peer that is not connected */
+ GNUNET_break (0);
+ return NULL;
+ }
GNUNET_assert (notify_size + sizeof (struct SendMessage) <
GNUNET_SERVER_MAX_MESSAGE_SIZE);
th = GNUNET_malloc (sizeof (struct GNUNET_CORE_TransmitHandle));
- th->ch = handle;
- GNUNET_CONTAINER_DLL_insert_after (handle->pending_head,
- handle->pending_tail,
- handle->pending_tail,
- th);
- th->get_message = &produce_send;
- th->get_message_cls = th;
- th->notify = notify;
- th->notify_cls = notify_cls;
- th->peer = *target;
+ th->peer = pr;
+ th->get_message = notify;
+ th->get_message_cls = notify_cls;
th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay);
- th->timeout_task = GNUNET_SCHEDULER_add_delayed (maxdelay,
- &timeout_request, th);
th->priority = priority;
- th->msize = sizeof (struct SendMessage) + notify_size;
+ th->msize = notify_size;
+ /* bound queue size */
+ if (pr->queue_size == handle->queue_size)
+ {
+ /* find lowest-priority entry */
+ minp = pr->pending_head;
+ prev = minp->next;
+ while (prev != NULL)
+ {
+ if (prev->priority < minp->priority)
+ minp = prev;
+ prev = prev->next;
+ }
+ if (minp == NULL)
+ {
+ GNUNET_break (handle->queue_size != 0);
+ GNUNET_break (pr->queue_size == 0);
+ return NULL;
+ }
+ if (priority <= minp->priority)
+ return NULL; /* priority too low */
+ GNUNET_CONTAINER_DLL_remove (pr->pending_head,
+ pr->pending_tail,
+ minp);
+ pr->queue_size--;
+ GNUNET_assert (0 ==
+ minp->get_message (minp->get_message_cls,
+ 0, NULL));
+ GNUNET_free (minp);
+ }
+
+ /* Order entries by deadline, but SKIP 'HEAD' if
+ we're in the 'ready_peer_*' DLL */
+ pos = pr->pending_head;
+ if ( (pr->prev != NULL) ||
+ (pr->next != NULL) ||
+ (pr == handle->ready_peer_head) )
+ {
+ GNUNET_assert (pos != NULL);
+ pos = pos->next; /* skip head */
+ }
+
+ /* insertion sort */
+ prev = pos;
+ while ( (pos != NULL) &&
+ (pos->timeout.abs_value < th->timeout.abs_value) )
+ {
+ prev = pos;
+ pos = pos->next;
+ }
+ GNUNET_CONTAINER_DLL_insert_after (pr->pending_head,
+ pr->pending_tail,
+ prev,
+ th);
+ pr->queue_size++;
/* was the request queue previously empty? */
- if ( (handle->pending_head == th) &&
- (handle->cth == NULL) )
- trigger_next_request (handle);
+ if (pr->pending_head == th)
+ request_next_transmission (pr);
return th;
}
/**
* Cancel the specified transmission-ready notification.
- *s
+ *
* @param th handle that was returned by "notify_transmit_ready".
*/
void
GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle
*th)
{
- struct GNUNET_CORE_Handle *h = th->ch;
+ struct PeerRecord *pr = th->peer;
+ struct GNUNET_CORE_Handle *h = pr->ch;
+ int was_head;
- if (h->submitted == th)
- h->submitted = NULL;
- else
- GNUNET_CONTAINER_DLL_remove (h->pending_head,
- h->pending_tail,
- th);
- if (th->timeout_task != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (th->timeout_task);
+ was_head = (pr->pending_head == th);
+ GNUNET_CONTAINER_DLL_remove (pr->pending_head,
+ pr->pending_tail,
+ th);
+ if (th->cm != NULL)
+ {
+ /* we're currently in the control queue, remove */
+ GNUNET_CONTAINER_DLL_remove (h->pending_head,
+ h->pending_tail,
+ th->cm);
+ GNUNET_free (th->cm);
+ }
GNUNET_free (th);
+ if (was_head)
+ {
+ if ( (pr->prev != NULL) ||
+ (pr->next != NULL) ||
+ (pr == h->ready_peer_head) )
+ {
+ /* the request that was 'approved' by core was
+ cancelled before it could be transmitted; remove
+ us from the 'ready' list */
+ GNUNET_CONTAINER_DLL_remove (h->ready_peer_head,
+ h->ready_peer_tail,
+ pr);
+ }
+ request_next_transmission (pr);
+ }
+}
+
+
+/* ****************** GNUNET_CORE_peer_request_connect ******************** */
+
+/**
+ * Handle for a request to the core to connect to
+ * a particular peer. Can be used to cancel the request
+ * (before the 'cont'inuation is called).
+ */
+struct GNUNET_CORE_PeerRequestHandle
+{
+
+ /**
+ * Link to control message.
+ */
+ struct ControlMessage *cm;
+
+ /**
+ * Core handle used.
+ */
+ struct GNUNET_CORE_Handle *h;
+
+ /**
+ * Continuation to run when done.
+ */
+ GNUNET_SCHEDULER_Task cont;
+
+ /**
+ * Closure for 'cont'.
+ */
+ void *cont_cls;
+
+};
+
+
+
+/**
+ * Continuation called when the control message was transmitted.
+ * Calls the original continuation and frees the remaining
+ * resources.
+ *
+ * @param cls the 'struct GNUNET_CORE_PeerRequestHandle'
+ * @param tc scheduler context
+ */
+static void
+peer_request_connect_cont (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct GNUNET_CORE_PeerRequestHandle *ret = cls;
+
+ if (ret->cont != NULL)
+ ret->cont (ret->cont_cls, tc);
+ GNUNET_free (ret);
+}
+
+
+/**
+ * Request that the core should try to connect to a particular peer.
+ * Once the request has been transmitted to the core, the continuation
+ * function will be called. Note that this does NOT mean that a
+ * connection was successfully established -- it only means that the
+ * core will now try. Successful establishment of the connection
+ * will be signalled to the 'connects' callback argument of
+ * 'GNUNET_CORE_connect' only. If the core service does not respond
+ * to our connection attempt within the given time frame, 'cont' will
+ * be called with the TIMEOUT reason code.
+ *
+ * @param h core handle
+ * @param timeout how long to try to talk to core
+ * @param peer who should we connect to
+ * @param cont function to call once the request has been completed (or timed out)
+ * @param cont_cls closure for cont
+ * @return NULL on error (cont will not be called), otherwise handle for cancellation
+ */
+struct GNUNET_CORE_PeerRequestHandle *
+GNUNET_CORE_peer_request_connect (struct GNUNET_CORE_Handle *h,
+ struct GNUNET_TIME_Relative timeout,
+ const struct GNUNET_PeerIdentity * peer,
+ GNUNET_SCHEDULER_Task cont,
+ void *cont_cls)
+{
+ struct GNUNET_CORE_PeerRequestHandle *ret;
+ struct ControlMessage *cm;
+ struct ConnectMessage *msg;
+
+ cm = GNUNET_malloc (sizeof (struct ControlMessage) +
+ sizeof (struct ConnectMessage));
+ msg = (struct ConnectMessage*) &cm[1];
+ msg->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT);
+ msg->header.size = htons (sizeof (struct ConnectMessage));
+ msg->reserved = htonl (0);
+ msg->timeout = GNUNET_TIME_relative_hton (timeout);
+ msg->peer = *peer;
+ GNUNET_CONTAINER_DLL_insert (h->pending_head,
+ h->pending_tail,
+ cm);
+ ret = GNUNET_malloc (sizeof (struct GNUNET_CORE_PeerRequestHandle));
+ ret->h = h;
+ ret->cm = cm;
+ ret->cont = cont;
+ ret->cont_cls = cont_cls;
+ cm->cont = &peer_request_connect_cont;
+ cm->cont_cls = ret;
+ if (h->pending_head == cm)
+ trigger_next_request (h);
+ return ret;
+}
+
+
+/**
+ * Cancel a pending request to connect to a particular peer. Must not
+ * be called after the 'cont' function was invoked.
+ *
+ * @param req request handle that was returned for the original request
+ */
+void
+GNUNET_CORE_peer_request_connect_cancel (struct GNUNET_CORE_PeerRequestHandle *req)
+{
+ struct GNUNET_CORE_Handle *h = req->h;
+ struct ControlMessage *cm = req->cm;
+
+ GNUNET_CONTAINER_DLL_remove (h->pending_head,
+ h->pending_tail,
+ cm);
+ GNUNET_free (cm);
+ GNUNET_free (req);
+}
+
+
+/* ****************** GNUNET_CORE_peer_change_preference ******************** */
+
+
+struct GNUNET_CORE_InformationRequestContext
+{
+
+ /**
+ * Our connection to the service.
+ */
+ struct GNUNET_CORE_Handle *h;
+
+ /**
+ * Function to call with the information.
+ */
+ GNUNET_CORE_PeerConfigurationInfoCallback info;
+
+ /**
+ * Closure for info.
+ */
+ void *info_cls;
+
+ /**
+ * Link to control message, NULL if CM was sent.
+ */
+ struct ControlMessage *cm;
+
+ /**
+ * Link to peer record.
+ */
+ struct PeerRecord *pr;
+};
+
+
+/**
+ * CM was sent, remove link so we don't double-free.
+ *
+ * @param cls the 'struct GNUNET_CORE_InformationRequestContext'
+ * @param tc scheduler context
+ */
+static void
+change_preference_send_continuation (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct GNUNET_CORE_InformationRequestContext *irc = cls;
+
+ irc->cm = NULL;
+}
+
+
+/**
+ * Obtain statistics and/or change preferences for the given peer.
+ *
+ * @param h core handle
+ * @param peer identifies the peer
+ * @param timeout after how long should we give up (and call "info" with NULL
+ * for "peer" to signal an error)?
+ * @param bw_out set to the current bandwidth limit (sending) for this peer,
+ * caller should set "bw_out" to "-1" to avoid changing
+ * the current value; otherwise "bw_out" will be lowered to
+ * the specified value; passing a pointer to "0" can be used to force
+ * us to disconnect from the peer; "bw_out" might not increase
+ * as specified since the upper bound is generally
+ * determined by the other peer!
+ * @param amount reserve N bytes for receiving, negative
+ * amounts can be used to undo a (recent) reservation;
+ * @param preference increase incoming traffic share preference by this amount;
+ * in the absence of "amount" reservations, we use this
+ * preference value to assign proportional bandwidth shares
+ * to all connected peers
+ * @param info function to call with the resulting configuration information
+ * @param info_cls closure for info
+ * @return NULL on error
+ */
+struct GNUNET_CORE_InformationRequestContext *
+GNUNET_CORE_peer_change_preference (struct GNUNET_CORE_Handle *h,
+ const struct GNUNET_PeerIdentity *peer,
+ struct GNUNET_TIME_Relative timeout,
+ struct GNUNET_BANDWIDTH_Value32NBO bw_out,
+ int32_t amount,
+ uint64_t preference,
+ GNUNET_CORE_PeerConfigurationInfoCallback info,
+ void *info_cls)
+{
+ struct GNUNET_CORE_InformationRequestContext *irc;
+ struct PeerRecord *pr;
+ struct RequestInfoMessage *rim;
+ struct ControlMessage *cm;
+
+ pr = GNUNET_CONTAINER_multihashmap_get (h->peers,
+ &peer->hashPubKey);
+ if (NULL == pr)
+ {
+ /* attempt to change preference on peer that is not connected */
+ GNUNET_break (0);
+ return NULL;
+ }
+ if (pr->pcic != NULL)
+ {
+ /* second change before first one is done */
+ GNUNET_break (0);
+ return NULL;
+ }
+ irc = GNUNET_malloc (sizeof (struct GNUNET_CORE_InformationRequestContext));
+ irc->h = h;
+ irc->info = info;
+ irc->info_cls = info_cls;
+ cm = GNUNET_malloc (sizeof (struct ControlMessage) +
+ sizeof (struct RequestInfoMessage));
+ cm->cont = &change_preference_send_continuation;
+ cm->cont_cls = irc;
+ irc->cm = cm;
+ rim = (struct RequestInfoMessage*) &cm[1];
+ rim->header.size = htons (sizeof (struct RequestInfoMessage));
+ rim->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO);
+ rim->rim_id = htonl (pr->rim_id = h->rim_id_gen++);
+ rim->limit_outbound = bw_out;
+ rim->reserve_inbound = htonl (amount);
+ rim->preference_change = GNUNET_htonll(preference);
+ rim->peer = *peer;
+ GNUNET_CONTAINER_DLL_insert (h->pending_head,
+ h->pending_tail,
+ cm);
+ pr->pcic = info;
+ pr->pcic_cls = info_cls;
+ return irc;
+}
+
+
+/**
+ * Cancel request for getting information about a peer.
+ * Note that an eventual change in preference, trust or bandwidth
+ * assignment MAY have already been committed at the time,
+ * so cancelling a request is NOT sure to undo the original
+ * request. The original request may or may not still commit.
+ * The only thing cancellation ensures is that the callback
+ * from the original request will no longer be called.
+ *
+ * @param irc context returned by the original GNUNET_CORE_peer_get_info call
+ */
+void
+GNUNET_CORE_peer_change_preference_cancel (struct GNUNET_CORE_InformationRequestContext *irc)
+{
+ struct GNUNET_CORE_Handle *h = irc->h;
+ struct PeerRecord *pr = irc->pr;
+
+ if (irc->cm != NULL)
+ {
+ GNUNET_CONTAINER_DLL_remove (h->pending_head,
+ h->pending_tail,
+ irc->cm);
+ GNUNET_free (irc->cm);
+ }
+ pr->pcic = NULL;
+ pr->pcic_cls = NULL;
+ GNUNET_free (irc);
+}
+
+
+/* ********************* GNUNET_CORE_iterate_peers *********************** */
+
+/**
+ * Context for 'iterate_peers' helper function.
+ */
+struct IterationContext
+{
+ /**
+ * Callback to call.
+ */
+ GNUNET_CORE_ConnectEventHandler peer_cb;
+
+ /**
+ * Closure for 'peer_cb'.
+ */
+ void *cb_cls;
+};
+
+
+/**
+ * Call callback for each peer.
+ *
+ * @param cls the 'struct IterationContext'
+ * @param hc peer identity, not used
+ * @param value the 'struct PeerRecord'
+ * @return GNUNET_YES (continue iteration)
+ */
+static int
+iterate_peers (void *cls,
+ const GNUNET_HashCode *hc,
+ void *value)
+{
+ struct IterationContext *ic = cls;
+ struct PeerRecord *pr = value;
+
+ ic->peer_cb (ic->cb_cls,
+ &pr->peer,
+ NULL /* FIXME: pass atsi? */);
+ return GNUNET_YES;
+}
+
+
+/**
+ * Obtain statistics and/or change preferences for the given peer.
+ *
+ * @param h handle to core
+ * @param peer_cb function to call with the peer information
+ * @param cb_cls closure for peer_cb
+ * @return GNUNET_OK if iterating, GNUNET_SYSERR on error
+ */
+int
+GNUNET_CORE_iterate_peers (struct GNUNET_CORE_Handle *h,
+ GNUNET_CORE_ConnectEventHandler peer_cb,
+ void *cb_cls)
+{
+ struct IterationContext ic;
+
+ ic.peer_cb = peer_cb;
+ ic.cb_cls = cb_cls;
+ GNUNET_CONTAINER_multihashmap_iterate (h->peers,
+ &iterate_peers,
+ &ic);
+ return GNUNET_OK;
}
+++ /dev/null
-/*
- This file is part of GNUnet.
- (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 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file core/core_api_iterate_peers.c
- * @brief implementation of the peer_iterate function
- * @author Christian Grothoff
- * @author Nathan Evans
- */
-#include "platform.h"
-#include "gnunet_core_service.h"
-#include "core.h"
-
-
-struct GNUNET_CORE_RequestContext
-{
-
- /**
- * Our connection to the service.
- */
- struct GNUNET_CLIENT_Connection *client;
-
- /**
- * Handle for transmitting a request.
- */
- struct GNUNET_CLIENT_TransmitHandle *th;
-
- /**
- * Function called with the peer.
- */
- GNUNET_CORE_ConnectEventHandler peer_cb;
-
- /**
- * Closure for peer_cb.
- */
- void *cb_cls;
-
-};
-
-
-/**
- * Receive reply from core service with information about a peer.
- *
- * @param cls our 'struct GNUNET_CORE_RequestContext *'
- * @param msg NULL on error or last entry
- */
-static void
-receive_info (void *cls,
- const struct GNUNET_MessageHeader *msg)
-{
- struct GNUNET_CORE_RequestContext *request_context = cls;
- const struct ConnectNotifyMessage *connect_message;
-
-
- /* Handle last message or error case, disconnect and clean up */
- if ( (msg == NULL) ||
- ((ntohs (msg->type) == GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT) &&
- (ntohs (msg->size) == sizeof (struct GNUNET_MessageHeader))) )
- {
- if (request_context->peer_cb != NULL)
- request_context->peer_cb (request_context->cb_cls,
- NULL, GNUNET_TIME_relative_get_zero(), 0);
- GNUNET_CLIENT_disconnect (request_context->client, GNUNET_NO);
- GNUNET_free (request_context);
- return;
- }
-
- /* Handle incorrect message type or size, disconnect and clean up */
- if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT) ||
- (ntohs (msg->size) != sizeof (struct ConnectNotifyMessage)) )
- {
- GNUNET_break (0);
- if (request_context->peer_cb != NULL)
- request_context->peer_cb (request_context->cb_cls,
- NULL, GNUNET_TIME_relative_get_zero(), 0);
- GNUNET_CLIENT_disconnect (request_context->client, GNUNET_NO);
- GNUNET_free (request_context);
- return;
- }
-
- /* Normal case */
- connect_message = (const struct ConnectNotifyMessage *) msg;
- if (request_context->peer_cb != NULL)
- request_context->peer_cb (request_context->cb_cls,
- &connect_message->peer,
- GNUNET_TIME_relative_ntoh(connect_message->latency),
- ntohl (connect_message->distance));
-
- GNUNET_CLIENT_receive(request_context->client, &receive_info, request_context, GNUNET_TIME_relative_get_forever());
-}
-
-/**
- * Function called to notify a client about the socket
- * begin ready to queue more data. "buf" will be
- * NULL and "size" zero if the socket was closed for
- * writing in the meantime.
- *
- * @param cls closure
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
- */
-static size_t
-transmit_request(void *cls,
- size_t size, void *buf)
-{
- struct GNUNET_MessageHeader *msg;
- if ((size < sizeof(struct GNUNET_MessageHeader)) || (buf == NULL))
- return 0;
-
- msg = (struct GNUNET_MessageHeader *)buf;
- msg->size = htons (sizeof (struct GNUNET_MessageHeader));
- msg->type = htons (GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS);
- return sizeof(struct GNUNET_MessageHeader);
-}
-
-/**
- * Obtain statistics and/or change preferences for the given peer.
- *
- * @param cfg configuration to use
- * @param peer_cb function to call with the peer information
- * @param cb_cls closure for peer_cb
- * @return GNUNET_OK if iterating, GNUNET_SYSERR on error
- */
-int
-GNUNET_CORE_iterate_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
- GNUNET_CORE_ConnectEventHandler peer_cb,
- void *cb_cls)
-{
- struct GNUNET_CORE_RequestContext *request_context;
- struct GNUNET_CLIENT_Connection *client;
-
- client = GNUNET_CLIENT_connect ("core", cfg);
- if (client == NULL)
- return GNUNET_SYSERR;
- request_context = GNUNET_malloc (sizeof (struct GNUNET_CORE_RequestContext));
- request_context->client = client;
- request_context->peer_cb = peer_cb;
- request_context->cb_cls = cb_cls;
-
- /*GNUNET_assert (GNUNET_OK == GNUNET_CLIENT_transmit_and_get_response (client,
- &request_message,
- GNUNET_TIME_relative_get_forever(),
- GNUNET_YES,
- &receive_info,
- request_context));*/
- request_context->th = GNUNET_CLIENT_notify_transmit_ready(client, sizeof(struct GNUNET_MessageHeader), GNUNET_TIME_relative_get_forever(), GNUNET_YES, &transmit_request, NULL);
- GNUNET_CLIENT_receive(client, &receive_info, request_context, GNUNET_TIME_relative_get_forever());
- return GNUNET_OK;
-}
-
-/* end of core_api_iterate_peers.c */
+++ /dev/null
-/*
- This file is part of GNUnet.
- (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 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file core/core_api_peer_get_info.c
- * @brief implementation of the peer_change_preference functions
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "gnunet_core_service.h"
-#include "core.h"
-
-
-struct GNUNET_CORE_InformationRequestContext
-{
-
- /**
- * Our connection to the service.
- */
- struct GNUNET_CLIENT_Connection *client;
-
- /**
- * Function to call with the information.
- */
- GNUNET_CORE_PeerConfigurationInfoCallback info;
-
- /**
- * Closure for info.
- */
- void *info_cls;
-
-};
-
-
-/**
- * Receive reply from core service with information about a peer.
- *
- * @param cls our 'struct GNUNET_CORE_InformationRequestContext *'
- * @param msg NULL on error (i.e. timeout)
- */
-static void
-receive_info (void *cls,
- const struct GNUNET_MessageHeader *msg)
-{
- struct GNUNET_CORE_InformationRequestContext *irc = cls;
- const struct ConfigurationInfoMessage *cim;
- static struct GNUNET_BANDWIDTH_Value32NBO zbw; /* zero bandwidth */
-
- if (msg == NULL)
- {
- if (irc->info != NULL)
- irc->info (irc->info_cls,
- NULL, zbw, zbw, 0, 0);
- GNUNET_CLIENT_disconnect (irc->client, GNUNET_NO);
- GNUNET_free (irc);
- return;
- }
- if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO) ||
- (ntohs (msg->size) != sizeof (struct ConfigurationInfoMessage)) )
- {
- GNUNET_break (0);
- if (irc->info != NULL)
- irc->info (irc->info_cls,
- NULL, zbw, zbw, 0, 0);
- GNUNET_CLIENT_disconnect (irc->client, GNUNET_NO);
- GNUNET_free (irc);
- return;
- }
- cim = (const struct ConfigurationInfoMessage*) msg;
- if (irc->info != NULL)
- irc->info (irc->info_cls,
- &cim->peer,
- cim->bw_in,
- cim->bw_out,
- ntohl (cim->reserved_amount),
- GNUNET_ntohll (cim->preference));
- GNUNET_CLIENT_disconnect (irc->client, GNUNET_NO);
- GNUNET_free (irc);
-}
-
-
-/**
- * Obtain statistics and/or change preferences for the given peer.
- *
- * @param cfg configuration to use
- * @param peer identifies the peer
- * @param timeout after how long should we give up (and call "info" with NULL
- * for "peer" to signal an error)?
- * @param bw_out set to the current bandwidth limit (sending) for this peer,
- * caller should set "bw_out" to "-1" to avoid changing
- * the current value; otherwise "bw_out" will be lowered to
- * the specified value; passing a pointer to "0" can be used to force
- * us to disconnect from the peer; "bw_out" might not increase
- * as specified since the upper bound is generally
- * determined by the other peer!
- * @param amount reserve N bytes for receiving, negative
- * amounts can be used to undo a (recent) reservation;
- * @param preference increase incoming traffic share preference by this amount;
- * in the absence of "amount" reservations, we use this
- * preference value to assign proportional bandwidth shares
- * to all connected peers
- * @param info function to call with the resulting configuration information
- * @param info_cls closure for info
- * @return NULL on error
- */
-struct GNUNET_CORE_InformationRequestContext *
-GNUNET_CORE_peer_change_preference (const struct GNUNET_CONFIGURATION_Handle *cfg,
- const struct GNUNET_PeerIdentity *peer,
- struct GNUNET_TIME_Relative timeout,
- struct GNUNET_BANDWIDTH_Value32NBO bw_out,
- int32_t amount,
- uint64_t preference,
- GNUNET_CORE_PeerConfigurationInfoCallback info,
- void *info_cls)
-{
- struct GNUNET_CORE_InformationRequestContext *irc;
- struct RequestInfoMessage rim;
- struct GNUNET_CLIENT_Connection *client;
- int retry;
-
- client = GNUNET_CLIENT_connect ("core", cfg);
- if (client == NULL)
- return NULL;
- irc = GNUNET_malloc (sizeof (struct GNUNET_CORE_InformationRequestContext));
- irc->client = client;
- irc->info = info;
- irc->info_cls = info_cls;
- rim.header.size = htons (sizeof (struct RequestInfoMessage));
- rim.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO);
- rim.reserved = htonl (0);
- rim.limit_outbound = bw_out;
- rim.reserve_inbound = htonl (amount);
- rim.preference_change = GNUNET_htonll(preference);
- rim.peer = *peer;
- retry = ( (amount == 0) && (preference == 0) ) ? GNUNET_YES : GNUNET_NO;
- GNUNET_assert (GNUNET_OK == GNUNET_CLIENT_transmit_and_get_response (client,
- &rim.header,
- timeout,
- retry,
- &receive_info,
- irc));
- return irc;
-}
-
-
-/**
- * Cancel request for getting information about a peer.
- *
- * @param irc context returned by the original GNUNET_CORE_peer_get_info call
- */
-void
-GNUNET_CORE_peer_change_preference_cancel (struct GNUNET_CORE_InformationRequestContext *irc)
-{
- GNUNET_CLIENT_disconnect (irc->client, GNUNET_NO);
- GNUNET_free (irc);
-}
-
-/* end of core_api_peer_get_info.c */
+++ /dev/null
-/*
- This file is part of GNUnet.
- (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 3, or (at your
- option) any later version.
-
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file core/core_api_peer_request.c
- * @brief implementation of the peer_request functions
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "gnunet_core_service.h"
-#include "core.h"
-
-
-/**
- * Handle for a request to the core to connect to
- * a particular peer. Can be used to cancel the request
- * (before the 'cont'inuation is called).
- */
-struct GNUNET_CORE_PeerRequestHandle
-{
-
- /**
- * Our connection to the service.
- */
- struct GNUNET_CLIENT_Connection *client;
-
-
- /**
- * Function to call once done.
- */
- GNUNET_SCHEDULER_Task cont;
-
- /**
- * Closure for 'cont'.
- */
- void *cont_cls;
-
- /**
- * When to time out.
- */
- struct GNUNET_TIME_Absolute timeout;
-
- /**
- * Identity of the peer to connect to.
- */
- struct GNUNET_PeerIdentity peer;
-
- /**
- * Message type to use.
- */
- uint16_t type;
-};
-
-
-/**
- * Transmit the request to the core service.
- *
- * @param cls our 'struct GNUNET_CORE_PeerRequestHandle'
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
- */
-static size_t
-send_request (void *cls,
- size_t size,
- void *buf)
-{
- struct GNUNET_CORE_PeerRequestHandle * prh = cls;
- struct ConnectMessage msg;
-
- if (buf == NULL)
- {
- if (prh->cont != NULL)
- GNUNET_SCHEDULER_add_continuation (prh->cont,
- prh->cont_cls,
- GNUNET_SCHEDULER_REASON_TIMEOUT);
- GNUNET_CLIENT_disconnect (prh->client, GNUNET_NO);
- GNUNET_free (prh);
- return 0;
- }
- GNUNET_assert (size >= sizeof (struct ConnectMessage));
- msg.header.type = htons (prh->type);
- msg.header.size = htons (sizeof (struct ConnectMessage));
- msg.reserved = htonl (0);
- msg.timeout = GNUNET_TIME_relative_hton (GNUNET_TIME_absolute_get_remaining (prh->timeout));
- msg.peer = prh->peer;
- memcpy (buf, &msg, sizeof (msg));
- if (prh->cont != NULL)
- {
- GNUNET_SCHEDULER_add_continuation (prh->cont,
- prh->cont_cls,
- GNUNET_SCHEDULER_REASON_PREREQ_DONE);
- }
- GNUNET_CLIENT_disconnect (prh->client, GNUNET_YES);
- GNUNET_free (prh);
- return sizeof (msg);
-}
-
-
-/**
- * Request that the core should try to connect to a particular peer.
- * Once the request has been transmitted to the core, the continuation
- * function will be called. Note that this does NOT mean that a
- * connection was successfully established -- it only means that the
- * core will now try. Successful establishment of the connection
- * will be signalled to the 'connects' callback argument of
- * 'GNUNET_CORE_connect' only. If the core service does not respond
- * to our connection attempt within the given time frame, 'cont' will
- * be called with the TIMEOUT reason code.
- *
- * @param cfg configuration to use
- * @param timeout how long to try to talk to core
- * @param peer who should we connect to
- * @param cont function to call once the request has been completed (or timed out)
- * @param cont_cls closure for cont
- * @return NULL on error (cont will not be called), otherwise handle for cancellation
- */
-struct GNUNET_CORE_PeerRequestHandle *
-GNUNET_CORE_peer_request_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
- struct GNUNET_TIME_Relative timeout,
- const struct GNUNET_PeerIdentity * peer,
- GNUNET_SCHEDULER_Task cont,
- void *cont_cls)
-{
- struct GNUNET_CORE_PeerRequestHandle *ret;
- struct GNUNET_CLIENT_Connection *client;
-
- client = GNUNET_CLIENT_connect ("core", cfg);
- if (client == NULL)
- return NULL;
- ret = GNUNET_malloc (sizeof (struct GNUNET_CORE_PeerRequestHandle));
- ret->client = client;
- ret->cont = cont;
- ret->cont_cls = cont_cls;
- ret->peer = *peer;
- ret->type = GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT;
- ret->timeout = GNUNET_TIME_relative_to_absolute (timeout);
- GNUNET_CLIENT_notify_transmit_ready (client,
- sizeof (struct ConnectMessage),
- timeout,
- GNUNET_YES,
- &send_request,
- ret);
- return ret;
-}
-
-
-/**
- * Cancel a pending request to connect to a particular peer. Must not
- * be called after the 'cont' function was invoked.
- *
- * @param req request handle that was returned for the original request
- */
-void
-GNUNET_CORE_peer_request_connect_cancel (struct GNUNET_CORE_PeerRequestHandle *req)
-{
- GNUNET_CLIENT_disconnect (req->client, GNUNET_NO);
- GNUNET_free (req);
-}
-
-
-/* end of core_api_peer_request.c */
};
+/**
+ * Record kept for each request for transmission issued by a
+ * client that is still pending.
+ */
+struct ClientActiveRequest;
+
+/**
+ * Data kept per neighbouring peer.
+ */
struct Neighbour
{
/**
*/
struct MessageEntry *encrypted_tail;
+ /**
+ * Head of list of requests from clients for transmission to
+ * this peer.
+ */
+ struct ClientActiveRequest *active_client_request_head;
+
+ /**
+ * Tail of list of requests from clients for transmission to
+ * this peer.
+ */
+ struct ClientActiveRequest *active_client_request_tail;
+
/**
* Handle for pending requests for transmission to this peer
* with the transport service. NULL if no request is pending.
*/
struct GNUNET_TIME_Absolute last_activity;
- /**
- * Last latency observed from this peer.
- */
- struct GNUNET_TIME_Relative last_latency;
-
/**
* At what frequency are we currently re-trying SET_KEY messages?
*/
*/
uint32_t ping_challenge;
- /**
- * What was the last distance to this peer as reported by the transports?
- */
- uint32_t last_distance;
-
/**
* What is our connection status?
*/
*/
const uint16_t *types;
+ /**
+ * Map of peer identities to active transmission requests of this
+ * client to the peer (of type 'struct ClientActiveRequest').
+ */
+ struct GNUNET_CONTAINER_MultiHashMap *requests;
+
/**
* Options for messages this client cares about,
* see GNUNET_CORE_OPTION_ values.
};
+/**
+ * Record kept for each request for transmission issued by a
+ * client that is still pending.
+ */
+struct ClientActiveRequest
+{
+
+ /**
+ * Active requests are kept in a doubly-linked list of
+ * the respective target peer.
+ */
+ struct ClientActiveRequest *next;
+
+ /**
+ * Active requests are kept in a doubly-linked list of
+ * the respective target peer.
+ */
+ struct ClientActiveRequest *prev;
+
+ /**
+ * Handle to the client.
+ */
+ struct Client *client;
+
+ /**
+ * By what time would the client want to see this message out?
+ */
+ struct GNUNET_TIME_Absolute deadline;
+
+ /**
+ * How important is this request.
+ */
+ uint32_t priority;
+
+ /**
+ * How many more requests does this client have?
+ */
+ uint32_t queue_size;
+
+ /**
+ * How many bytes does the client intend to send?
+ */
+ uint16_t msize;
+
+ /**
+ * Unique request ID (in big endian).
+ */
+ uint16_t smr_id;
+
+};
+
+
+
/**
* Our public key.
*/
#endif
psnm.header.size = htons (sizeof (struct PeerStatusNotifyMessage));
psnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE);
- psnm.distance = htonl (n->last_distance);
- psnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
psnm.timeout = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_add (n->last_activity,
GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT));
psnm.bandwidth_in = n->bw_in;
GNUNET_NO);
}
+
/**
- * Handle CORE_ITERATE_PEERS request.
+ * Go over our message queue and if it is not too long, go
+ * over the pending requests from clients for this
+ * neighbour and send some clients a 'READY' notification.
+ *
+ * @param n which peer to process
*/
static void
-handle_client_iterate_peers (void *cls,
- struct GNUNET_SERVER_Client *client,
- const struct GNUNET_MessageHeader *message)
+schedule_peer_messages (struct Neighbour *n)
{
- struct Neighbour *n;
- struct ConnectNotifyMessage cnm;
- struct GNUNET_MessageHeader done_msg;
- struct GNUNET_SERVER_TransmitContext *tc;
-
- /* notify new client about existing neighbours */
- cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
- cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
- done_msg.size = htons (sizeof (struct GNUNET_MessageHeader));
- done_msg.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
- tc = GNUNET_SERVER_transmit_context_create (client);
- n = neighbours;
- while (n != NULL)
+ struct SendMessageReady smr;
+ struct ClientActiveRequest *car;
+ struct ClientActiveRequest *pos;
+ struct Client *c;
+ struct MessageEntry *mqe;
+ unsigned int queue_size;
+
+ /* check if neighbour queue is empty enough! */
+ queue_size = 0;
+ mqe = n->messages;
+ while (mqe != NULL)
{
- if (n->status == PEER_STATE_KEY_CONFIRMED)
- {
-#if DEBUG_CORE_CLIENT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Sending `%s' message to client.\n", "NOTIFY_CONNECT");
-#endif
- cnm.distance = htonl (n->last_distance);
- cnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
- cnm.peer = n->peer;
- GNUNET_SERVER_transmit_context_append_message (tc, &cnm.header);
- /*send_to_client (c, &cnm.header, GNUNET_NO);*/
- }
- n = n->next;
+ queue_size++;
+ mqe = mqe->next;
+ }
+ if (queue_size >= MAX_PEER_QUEUE_SIZE)
+ return; /* queue still full */
+ /* find highest priority request */
+ pos = n->active_client_request_head;
+ car = NULL;
+ while (pos != NULL)
+ {
+ if ( (car == NULL) ||
+ (pos->priority > car->priority) )
+ car = pos;
+ pos = pos->next;
}
+ if (car == NULL)
+ return; /* no pending requests */
+ c = car->client;
+ GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
+ n->active_client_request_tail,
+ car);
+ GNUNET_CONTAINER_multihashmap_remove (c->requests,
+ &n->peer.hashPubKey,
+ car);
+ smr.header.size = htons (sizeof (struct SendMessageReady));
+ smr.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND_READY);
+ smr.size = htons (car->msize);
+ smr.smr_id = car->smr_id;
+ smr.peer = n->peer;
+ send_to_client (c, &smr.header, GNUNET_NO);
+ GNUNET_free (car);
+}
- GNUNET_SERVER_transmit_context_append_message (tc, &done_msg);
- GNUNET_SERVER_transmit_context_run (tc,
- GNUNET_TIME_UNIT_FOREVER_REL);
+
+/**
+ * Handle CORE_SEND_REQUEST message.
+ */
+static void
+handle_client_send_request (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
+{
+ const struct SendMessageRequest *req;
+ struct Neighbour *n;
+ struct Client *c;
+ struct ClientActiveRequest *car;
+
+ req = (const struct SendMessageRequest*) message;
+ n = find_neighbour (&req->peer);
+ if ( (n == NULL) ||
+ (GNUNET_YES != n->is_connected) )
+ {
+ /* neighbour must have disconnected since request was issued,
+ ignore (client will realize it once it processes the
+ disconnect notification) */
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# send requests dropped (disconnected)"),
+ 1,
+ GNUNET_NO);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+ c = clients;
+ while ( (c != NULL) &&
+ (c->client_handle != client) )
+ c = c->next;
+ if (c == NULL)
+ {
+ /* client did not send INIT first! */
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ if (c->requests == NULL)
+ c->requests = GNUNET_CONTAINER_multihashmap_create (16);
+ car = GNUNET_CONTAINER_multihashmap_get (c->requests,
+ &req->peer.hashPubKey);
+ if (car == NULL)
+ {
+ /* create new entry */
+ car = GNUNET_malloc (sizeof (struct ClientActiveRequest));
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CONTAINER_multihashmap_put (c->requests,
+ &req->peer.hashPubKey,
+ car,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
+ GNUNET_CONTAINER_DLL_insert (n->active_client_request_head,
+ n->active_client_request_tail,
+ car);
+ car->client = c;
+ }
+ car->deadline = GNUNET_TIME_absolute_ntoh (req->deadline);
+ car->priority = ntohl (req->priority);
+ car->queue_size = ntohl (req->queue_size);
+ car->msize = ntohs (req->size);
+ car->smr_id = req->smr_id;
+ schedule_peer_messages (n);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Sending `%s' message to client.\n", "NOTIFY_CONNECT");
#endif
- cnm.distance = htonl (n->last_distance);
- cnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
cnm.peer = n->peer;
send_to_client (c, &cnm.header, GNUNET_NO);
}
}
+/**
+ * Free client request records.
+ *
+ * @param cls NULL
+ * @param key identity of peer for which this is an active request
+ * @param value the 'struct ClientActiveRequest' to free
+ * @return GNUNET_YES (continue iteration)
+ */
+static int
+destroy_active_client_request (void *cls,
+ const GNUNET_HashCode *key,
+ void *value)
+{
+ struct ClientActiveRequest *car = cls;
+ struct Neighbour *n;
+ struct GNUNET_PeerIdentity peer;
+
+ peer.hashPubKey = *key;
+ n = find_neighbour (&peer);
+ GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
+ n->active_client_request_tail,
+ car);
+ GNUNET_free (car);
+ return GNUNET_YES;
+}
+
+
/**
* A client disconnected, clean up.
*
while (pos != NULL)
{
if (client == pos->client_handle)
- {
- if (prev == NULL)
- clients = pos->next;
- else
- prev->next = pos->next;
- GNUNET_free (pos);
- return;
- }
+ break;
prev = pos;
pos = pos->next;
}
- /* client never sent INIT */
+ if (pos == NULL)
+ {
+ /* client never sent INIT */
+ return;
+ }
+ if (prev == NULL)
+ clients = pos->next;
+ else
+ prev->next = pos->next;
+ if (pos->requests != NULL)
+ {
+ GNUNET_CONTAINER_multihashmap_iterate (pos->requests,
+ &destroy_active_client_request,
+ NULL);
+ GNUNET_CONTAINER_multihashmap_destroy (pos->requests);
+ }
+ GNUNET_free (pos);
}
(int) got_reserv);
#endif
cim.reserved_amount = htonl (got_reserv);
- cim.bw_in = n->bw_in;
+ cim.rim_id = rcm->rim_id;
cim.bw_out = n->bw_out;
cim.preference = n->current_preference;
}
free_neighbour (struct Neighbour *n)
{
struct MessageEntry *m;
+ struct ClientActiveRequest *car;
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
m);
GNUNET_free (m);
}
+ while (NULL != (car = n->active_client_request_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
+ n->active_client_request_tail,
+ car);
+ GNUNET_CONTAINER_multihashmap_remove (car->client->requests,
+ &n->peer.hashPubKey,
+ car);
+ GNUNET_free (car);
+ }
if (NULL != n->th)
{
GNUNET_TRANSPORT_notify_transmit_ready_cancel (n->th);
return 0;
}
ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND);
- ntm->distance = htonl (n->last_distance);
- ntm->latency = GNUNET_TIME_relative_hton (n->last_latency);
ntm->peer = n->peer;
pos = n->messages;
prev = NULL;
struct MessageEntry *pos;
struct GNUNET_TIME_Absolute now;
struct GNUNET_TIME_Relative delta;
+ int disc;
+ disc = GNUNET_NO;
now = GNUNET_TIME_absolute_get ();
prev = NULL;
pos = n->messages;
n->messages = next;
else
prev->next = next;
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# messages discarded (expired prior to transmission)"),
+ 1,
+ GNUNET_NO);
+ disc = GNUNET_YES;
GNUNET_free (pos);
}
else
prev = pos;
pos = next;
}
+ if (GNUNET_YES == disc)
+ schedule_peer_messages (n);
}
n->encrypted_tail,
me);
process_encrypted_neighbour_queue (n);
+ schedule_peer_messages (n);
}
(unsigned int) msize,
GNUNET_i2s (&sm->peer));
#endif
- /* bound queue size */
discard_expired_messages (n);
+ /* bound queue size */
+ /* NOTE: this entire block to bound the queue size should be
+ obsolete with the new client-request code and the
+ 'schedule_peer_messages' mechanism; we still have this code in
+ here for now as a sanity check for the new mechanmism;
+ ultimately, we should probably simply reject SEND messages that
+ are not 'approved' (or provide a new core API for very unreliable
+ delivery that always sends with priority 0). Food for thought. */
min_prio = UINT32_MAX;
min_prio_entry = NULL;
min_prio_prev = NULL;
/* queue full */
if (ntohl(sm->priority) <= min_prio)
{
- /* discard new entry */
+ /* discard new entry; this should no longer happen! */
+ GNUNET_break (0);
#if DEBUG_CORE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Queue full (%u/%u), discarding new request (%u bytes of type %u)\n",
(unsigned int) msize,
(unsigned int) ntohs (message->type));
#endif
- GNUNET_STATISTICS_update (stats, gettext_noop ("# discarded CORE_SEND requests"), 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# discarded CORE_SEND requests"),
+ 1, GNUNET_NO);
if (client != NULL)
GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
cnm.header.size = htons (sizeof (struct ConnectNotifyMessage));
cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT);
- cnm.distance = htonl (n->last_distance);
- cnm.latency = GNUNET_TIME_relative_hton (n->last_latency);
cnm.peer = n->peer;
send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_CONNECT);
process_encrypted_neighbour_queue (n);
ntm = (struct NotifyTrafficMessage *) buf;
ntm->header.size = htons (msize + sizeof (struct NotifyTrafficMessage));
ntm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND);
- ntm->distance = htonl (sender->last_distance);
- ntm->latency = GNUNET_TIME_relative_hton (sender->last_latency);
ntm->peer = sender->peer;
memcpy (&ntm[1], m, msize);
send_to_client (client, &ntm->header, GNUNET_YES);
n = find_neighbour (peer);
if (n == NULL)
n = create_neighbour (peer);
- changed = (latency.rel_value != n->last_latency.rel_value) || (distance != n->last_distance);
- n->last_latency = latency;
- n->last_distance = distance;
+ changed = GNUNET_YES; /* FIXME... */
up = (n->status == PEER_STATE_KEY_CONFIRMED);
type = ntohs (message->type);
size = ntohs (message->size);
1,
GNUNET_NO);
n->is_connected = GNUNET_YES;
- n->last_latency = latency;
- n->last_distance = distance;
GNUNET_BANDWIDTH_tracker_init (&n->available_send_window,
n->bw_out,
MAX_WINDOW_TIME_S);
{
struct DisconnectNotifyMessage cnm;
struct Neighbour *n;
+ struct ClientActiveRequest *car;
struct GNUNET_TIME_Relative left;
#if DEBUG_CORE
send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_DISCONNECT);
}
n->is_connected = GNUNET_NO;
+ while (NULL != (car = n->active_client_request_head))
+ {
+ GNUNET_CONTAINER_DLL_remove (n->active_client_request_head,
+ n->active_client_request_tail,
+ car);
+ GNUNET_CONTAINER_multihashmap_remove (car->client->requests,
+ &n->peer.hashPubKey,
+ car);
+ GNUNET_free (car);
+ }
+
GNUNET_STATISTICS_update (stats,
gettext_noop ("# peers connected (transport)"),
-1,
{&handle_client_request_info, NULL,
GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO,
sizeof (struct RequestInfoMessage)},
- {&handle_client_iterate_peers, NULL,
- GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS,
- sizeof (struct GNUNET_MessageHeader)},
+ {&handle_client_send_request, NULL,
+ GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST,
+ sizeof (struct SendMessageRequest)},
{&handle_client_send, NULL,
GNUNET_MESSAGE_TYPE_CORE_SEND, 0},
{&handle_client_request_connect, NULL,
#define START_ARM GNUNET_YES
-/**
- * How long until we give up on transmitting the message?
- */
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60)
-
#define MTYPE 12345
struct PeerContext
static void
connect_notify (void *cls,
const struct GNUNET_PeerIdentity *peer,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
struct PeerContext *pc = cls;
GNUNET_assert (pc->connect_status == 0);
inbound_notify (void *cls,
const struct GNUNET_PeerIdentity *other,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Core provides inbound data from `%4s'.\n", GNUNET_i2s (other));
outbound_notify (void *cls,
const struct GNUNET_PeerIdentity *other,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Core notifies about outbound data for `%4s'.\n",
process_mtype (void *cls,
const struct GNUNET_PeerIdentity *peer,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Receiving message from `%4s'.\n", GNUNET_i2s (peer));
OKPP;
/* connect p2 */
GNUNET_CORE_connect (p2.cfg, 1,
- TIMEOUT,
&p2,
&init_notify,
&connect_notify,
setup_peer (&p1, "test_core_api_peer1.conf");
setup_peer (&p2, "test_core_api_peer2.conf");
GNUNET_CORE_connect (p1.cfg, 1,
- TIMEOUT,
&p1,
&init_notify,
&connect_notify,
static void
connect_notify (void *cls,
const struct GNUNET_PeerIdentity *peer,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
struct PeerContext *pc = cls;
GNUNET_assert (pc->connect_status == 0);
inbound_notify (void *cls,
const struct GNUNET_PeerIdentity *other,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
#if VERBOSE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
outbound_notify (void *cls,
const struct GNUNET_PeerIdentity *other,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
#if VERBOSE
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
process_mtype (void *cls,
const struct GNUNET_PeerIdentity *peer,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
static int n;
unsigned int s;
OKPP;
/* connect p2 */
GNUNET_CORE_connect (p2.cfg, 1,
- TIMEOUT,
&p2,
&init_notify,
&connect_notify,
setup_peer (&p1, "test_core_api_peer1.conf");
setup_peer (&p2, "test_core_api_peer2.conf");
GNUNET_CORE_connect (p1.cfg, 1,
- TIMEOUT,
&p1,
&init_notify,
&connect_notify,
#define START_ARM GNUNET_YES
-
-/**
- * How long until we give up on transmitting the message?
- */
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120)
-
#define MTYPE 12345
struct PeerContext
static void
connect_notify (void *cls,
const struct GNUNET_PeerIdentity *peer,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
}
inbound_notify (void *cls,
const struct GNUNET_PeerIdentity *other,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
return GNUNET_OK;
}
outbound_notify (void *cls,
const struct GNUNET_PeerIdentity *other,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
return GNUNET_OK;
}
{
/* connect p2 */
GNUNET_CORE_connect (p2.cfg, 1,
- TIMEOUT,
&p2,
&init_notify,
&connect_notify,
setup_peer (&p1, "test_core_api_peer1.conf");
setup_peer (&p2, "test_core_api_peer2.conf");
GNUNET_CORE_connect (p1.cfg, 1,
- TIMEOUT,
&p1,
&init_notify,
&connect_notify,
inbound_notify (void *cls,
const struct GNUNET_PeerIdentity *other,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
total_bytes_recv += ntohs (message->size);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
outbound_notify (void *cls,
const struct GNUNET_PeerIdentity *other,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
#if DEBUG_CONNECTIONS
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
measurement_end (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct GNUNET_TIME_Relative duration;
-
- measure_task = GNUNET_SCHEDULER_NO_TASK;
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- return;
-
- if (err_task != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (err_task);
- if (send_task != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (send_task);
-
- GNUNET_STATISTICS_get(p1.stats,"core","# discarded CORE_SEND requests",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p1);
- GNUNET_STATISTICS_get(p1.stats,"core","# discarded CORE_SEND requests",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p2);
- GNUNET_STATISTICS_get(p1.stats,"core","# discarded lower priority CORE_SEND requests",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p1);
- GNUNET_STATISTICS_get(p1.stats,"core","# discarded lower priority CORE_SEND requests",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p2);
-
- GNUNET_STATISTICS_get(p1.stats,"core","# discarded CORE_SEND request bytes",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p1);
- GNUNET_STATISTICS_get(p1.stats,"core","# discarded CORE_SEND request bytes",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p2);
- GNUNET_STATISTICS_get(p1.stats,"core","# discarded lower priority CORE_SEND request bytes",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p1);
- GNUNET_STATISTICS_get(p1.stats,"core","# discarded lower priority CORE_SEND request bytes",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p2);
- measurement_running = GNUNET_NO;
- duration = GNUNET_TIME_absolute_get_difference(start_time, GNUNET_TIME_absolute_get());
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- "\nQuota compliance: \n"\
- "Receive rate: %10llu kB/s\n"
- "Send rate : %10llu kB/s\n"\
- "Quota : %10llu kB/s\n",
- (total_bytes_recv/(duration.rel_value / 1000)/1024),
- (total_bytes_sent/(duration.rel_value / 1000)/1024),current_quota_p1_in/1024);
-
-
- GNUNET_SCHEDULER_add_now (&terminate_task, NULL);
+ struct GNUNET_TIME_Relative duration;
+
+ measure_task = GNUNET_SCHEDULER_NO_TASK;
+ if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+ return;
+
+ if (err_task != GNUNET_SCHEDULER_NO_TASK)
+ GNUNET_SCHEDULER_cancel (err_task);
+ if (send_task != GNUNET_SCHEDULER_NO_TASK)
+ GNUNET_SCHEDULER_cancel (send_task);
+
+ GNUNET_STATISTICS_get(p1.stats,"core","# discarded CORE_SEND requests",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p1);
+ GNUNET_STATISTICS_get(p1.stats,"core","# discarded CORE_SEND requests",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p2);
+ GNUNET_STATISTICS_get(p1.stats,"core","# discarded lower priority CORE_SEND requests",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p1);
+ GNUNET_STATISTICS_get(p1.stats,"core","# discarded lower priority CORE_SEND requests",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p2);
+
+ GNUNET_STATISTICS_get(p1.stats,"core","# discarded CORE_SEND request bytes",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p1);
+ GNUNET_STATISTICS_get(p1.stats,"core","# discarded CORE_SEND request bytes",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p2);
+ GNUNET_STATISTICS_get(p1.stats,"core","# discarded lower priority CORE_SEND request bytes",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p1);
+ GNUNET_STATISTICS_get(p1.stats,"core","# discarded lower priority CORE_SEND request bytes",GNUNET_TIME_UNIT_SECONDS, &next_fin, &check_2, &p2);
+ measurement_running = GNUNET_NO;
+ duration = GNUNET_TIME_absolute_get_difference(start_time, GNUNET_TIME_absolute_get());
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "\nQuota compliance: \n" \
+ "Receive rate: %10llu kB/s\n"
+ "Send rate : %10llu kB/s\n" \
+ "Quota : %10llu kB/s\n",
+ (total_bytes_recv/(duration.rel_value / 1000)/1024),
+ (total_bytes_sent/(duration.rel_value / 1000)/1024),
+ current_quota_p1_in/1024);
+ GNUNET_SCHEDULER_add_now (&terminate_task, NULL);
}
static size_t
send_tsk (void *cls,
const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- send_task = GNUNET_SCHEDULER_NO_TASK;
-
- ch = GNUNET_CORE_notify_transmit_ready (p1.ch,
- 0,
- FAST_TIMEOUT,
- &p2.id,
- sizeof (struct TestMessage) + MEASUREMENT_MSG_SIZE,
- &transmit_ready, &p1);
+ send_task = GNUNET_SCHEDULER_NO_TASK;
+
+ ch = GNUNET_CORE_notify_transmit_ready (p1.ch,
+ 0,
+ FAST_TIMEOUT,
+ &p2.id,
+ sizeof (struct TestMessage) + MEASUREMENT_MSG_SIZE,
+ &transmit_ready, &p1);
}
-static void measure (unsigned long long quota_p1, unsigned long long quota_p2 )
+
+static void
+measure (unsigned long long quota_p1, unsigned long long quota_p2)
{
#if VERBOSE
if ((is_asymmetric_send_constant == GNUNET_YES) || (is_asymmetric_recv_constant == GNUNET_YES))
total_bytes = 0;
total_bytes_sent = 0;
ch = GNUNET_CORE_notify_transmit_ready (p1.ch,
- 0,
- TIMEOUT,
- &p2.id,
- sizeof (struct TestMessage) + MEASUREMENT_MSG_SIZE,
- &transmit_ready, &p1);
+ 0,
+ TIMEOUT,
+ &p2.id,
+ sizeof (struct TestMessage) + MEASUREMENT_MSG_SIZE,
+ &transmit_ready, &p1);
}
static int tr_n;
process_mtype (void *cls,
const struct GNUNET_PeerIdentity *peer,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
static int n;
unsigned int s;
OKPP;
/* connect p2 */
GNUNET_CORE_connect (p2.cfg, 1,
- TIMEOUT,
&p2,
&init_notify,
&connect_notify,
setup_peer (&p1, "test_core_quota_peer1.conf");
setup_peer (&p2, "test_core_quota_peer2.conf");
GNUNET_CORE_connect (p1.cfg, 1,
- TIMEOUT,
&p1,
&init_notify,
&connect_notify,
{
int ret;
- GNUNET_log_setup ("test-core-api",
+ GNUNET_log_setup ("test-core-quota-compliance",
#if VERBOSE
"DEBUG",
#else
log_topology_cb (void *cls,
const struct GNUNET_PeerIdentity *first,
const struct GNUNET_PeerIdentity *second,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance,
const char *emsg)
{
struct TopologyIteratorContext *topo_ctx = cls;
count_peers_churn_cb (void *cls,
const struct GNUNET_PeerIdentity *first,
const struct GNUNET_PeerIdentity *second,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance,
const char *emsg)
{
struct FindPeerContext *find_peer_context = cls;
count_peers_cb (void *cls,
const struct GNUNET_PeerIdentity *first,
const struct GNUNET_PeerIdentity *second,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance,
const char *emsg)
{
struct FindPeerContext *find_peer_context = cls;
struct GNUNET_CORE_InformationRequestContext *info_ctx;
/**
- * What is the average latency for replies received?
+ * What is the identity of the peer?
*/
- struct GNUNET_TIME_Relative latency;
+ struct GNUNET_PeerIdentity id;
+#if 0
/**
- * What is the identity of the peer?
+ * What is the average latency for replies received?
*/
- struct GNUNET_PeerIdentity id;
+ struct GNUNET_TIME_Relative latency;
/**
* Transport level distance to peer.
*/
unsigned int distance;
+#endif
/**
* Holds matching bits from peer to current target,
*
* @param cls closure
* @param peer identifies the peer
- * @param bpm_in set to the current bandwidth limit (receiving) for this peer
* @param bpm_out set to the current bandwidth limit (sending) for this peer
* @param amount set to the amount that was actually reserved or unreserved;
* either the full requested amount or zero (no partial reservations)
static void
update_core_preference_finish (void *cls,
const struct GNUNET_PeerIdentity * peer,
- struct GNUNET_BANDWIDTH_Value32NBO bpm_in,
struct GNUNET_BANDWIDTH_Value32NBO bpm_out,
int amount, uint64_t preference)
{
matching = 63;
}
preference = 1LL << matching;
- peer->info_ctx = GNUNET_CORE_peer_change_preference (cfg,
+ peer->info_ctx = GNUNET_CORE_peer_change_preference (coreAPI,
&peer->id,
GNUNET_TIME_relative_get_forever(),
GNUNET_BANDWIDTH_value_init (UINT32_MAX),
* @param peer GNUNET_PeerIdentity of the peer to add
* @param bucket the already figured out bucket to add
* the peer to
- * @param latency the core reported latency of this peer
- * @param distance the transport level distance to this peer
+ * @param atsi performance information
*
* @return the newly added PeerInfo
*/
static struct PeerInfo *
add_peer(const struct GNUNET_PeerIdentity *peer,
unsigned int bucket,
- struct GNUNET_TIME_Relative latency,
- unsigned int distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
struct PeerInfo *new_peer;
GNUNET_assert(bucket < MAX_BUCKETS);
GNUNET_assert(peer != NULL);
new_peer = GNUNET_malloc(sizeof(struct PeerInfo));
+#if 0
new_peer->latency = latency;
new_peer->distance = distance;
+#endif
memcpy(&new_peer->id, peer, sizeof(struct GNUNET_PeerIdentity));
static struct PeerInfo *
try_add_peer(const struct GNUNET_PeerIdentity *peer,
unsigned int bucket,
- struct GNUNET_TIME_Relative latency,
- unsigned int distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
int peer_bucket;
struct PeerInfo *new_peer;
peer_bucket = find_current_bucket(&peer->hashPubKey);
GNUNET_assert(peer_bucket >= lowest_bucket);
- new_peer = add_peer(peer, peer_bucket, latency, distance);
+ new_peer = add_peer(peer, peer_bucket, atsi);
if ((k_buckets[lowest_bucket].peers_size) >= bucket_size)
enable_next_bucket();
{
increment_stats(STAT_HELLOS_PROVIDED);
GNUNET_TRANSPORT_offer_hello(transport_handle, hello_msg);
- GNUNET_CORE_peer_request_connect(cfg, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5), &new_peer, NULL, NULL);
+ GNUNET_CORE_peer_request_connect(coreAPI,
+ GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5), &new_peer, NULL, NULL);
}
}
}
{
increment_stats(STAT_HELLOS_PROVIDED);
GNUNET_TRANSPORT_offer_hello(transport_handle, other_hello);
- GNUNET_CORE_peer_request_connect(cfg, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5), &peer_id, NULL, NULL);
+ GNUNET_CORE_peer_request_connect(coreAPI,
+ GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 5), &peer_id, NULL, NULL);
route_message (find_msg, msg_ctx);
GNUNET_free (other_hello);
return;
handle_dht_p2p_route_request (void *cls,
const struct GNUNET_PeerIdentity *peer,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency, uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
#if DEBUG_DHT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
handle_dht_p2p_route_result (void *cls,
const struct GNUNET_PeerIdentity *peer,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency, uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
#if DEBUG_DHT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
*
* @param cls closure
* @param peer peer identity this notification is about
- * @param latency reported latency of the connection with peer
- * @param distance reported distance (DV) to peer
+ * @param atsi performance data
*/
-void handle_core_connect (void *cls,
- const struct GNUNET_PeerIdentity * peer,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+static void
+handle_core_connect (void *cls,
+ const struct GNUNET_PeerIdentity * peer,
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
struct PeerInfo *ret;
GNUNET_DATACACHE_put(datacache, &peer->hashPubKey, sizeof(struct GNUNET_PeerIdentity), (const char *)peer, GNUNET_BLOCK_TYPE_DHT_HELLO, GNUNET_TIME_absolute_get_forever());
ret = try_add_peer(peer,
find_current_bucket(&peer->hashPubKey),
- latency,
- distance);
+ atsi);
if (ret != NULL)
{
newly_found_peers++;
* @param cls closure
* @param peer peer identity this notification is about
*/
-void handle_core_disconnect (void *cls,
- const struct
- GNUNET_PeerIdentity * peer)
+static void
+handle_core_disconnect (void *cls,
+ const struct
+ GNUNET_PeerIdentity * peer)
{
struct PeerInfo *to_remove;
int current_bucket;
GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
coreAPI = GNUNET_CORE_connect (cfg, /* Main configuration */
1, /* queue size */
- GNUNET_TIME_UNIT_FOREVER_REL,
NULL, /* Closure passed to DHT functions */
&core_init, /* Call core_init once connected */
&handle_core_connect, /* Handle connects */
bin_PROGRAMS = \
gnunet-service-dv
-
+
gnunet_service_dv_SOURCES = \
gnunet-service-dv.c
gnunet_service_dv_LDADD = \
* @param latency the latency of the connection we received the message from
* @param distance the distance to the immediate peer
*/
-static int handle_dv_data_message (void *cls,
- const struct GNUNET_PeerIdentity * peer,
- const struct GNUNET_MessageHeader * message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+static int
+handle_dv_data_message (void *cls,
+ const struct GNUNET_PeerIdentity * peer,
+ const struct GNUNET_MessageHeader * message,
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
const p2p_dv_MESSAGE_Data *incoming = (const p2p_dv_MESSAGE_Data *) message;
const struct GNUNET_MessageHeader *packed_message;
static int handle_dv_gossip_message (void *cls,
const struct GNUNET_PeerIdentity *peer,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance);
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi);
static int handle_dv_disconnect_message (void *cls,
const struct GNUNET_PeerIdentity *peer,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance);
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi);
/** End forward declarations **/
* not added)
*/
static struct DistantNeighbor *
-addUpdateNeighbor (const struct GNUNET_PeerIdentity * peer, struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pkey,
+addUpdateNeighbor (const struct GNUNET_PeerIdentity * peer,
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pkey,
unsigned int referrer_peer_id,
struct DirectNeighbor *referrer, unsigned int cost)
{
#if DEBUG_DV_MESSAGES
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "%s: learned about peer %llu from which we have a previous unknown message, processing!\n", my_short_id, referrer_peer_id);
#endif
- handle_dv_data_message(NULL, &referrer->pending_messages[i].sender, referrer->pending_messages[i].message, referrer->pending_messages[i].latency, referrer->pending_messages[i].distance);
+ handle_dv_data_message(NULL, &referrer->pending_messages[i].sender,
+ referrer->pending_messages[i].message,
+ referrer->pending_messages[i].latency,
+ referrer->pending_messages[i].distance);
GNUNET_free(referrer->pending_messages[i].message);
referrer->pending_messages[i].sender_id = 0;
}
* @param cls closure
* @param peer peer which sent the message (immediate sender)
* @param message the message
- * @param latency the latency of the connection we received the message from
- * @param distance the distance to the immediate peer
+ * @param atsi performance data
*/
static int handle_dv_disconnect_message (void *cls,
const struct GNUNET_PeerIdentity *peer,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
struct DirectNeighbor *referrer;
struct DistantNeighbor *distant;
* @param cls closure
* @param peer peer which sent the message (immediate sender)
* @param message the message
- * @param latency the latency of the connection we received the message from
- * @param distance the distance to the immediate peer
+ * @param atsi performance data
*/
-static int handle_dv_gossip_message (void *cls,
- const struct GNUNET_PeerIdentity *peer,
- const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+static int
+handle_dv_gossip_message (void *cls,
+ const struct GNUNET_PeerIdentity *peer,
+ const struct GNUNET_MessageHeader *message,
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
struct DirectNeighbor *referrer;
p2p_dv_MESSAGE_NeighborInfo *enc_message = (p2p_dv_MESSAGE_NeighborInfo *)message;
*
* @return GNUNET_YES to continue iteration, GNUNET_NO otherwise
*/
-static int add_all_extended_peers (void *cls,
- const GNUNET_HashCode * key,
- void *value)
+static int
+add_all_extended_peers (void *cls,
+ const GNUNET_HashCode * key,
+ void *value)
{
struct NeighborSendContext *send_context = (struct NeighborSendContext *)cls;
struct DistantNeighbor *distant = (struct DistantNeighbor *)value;
* iterate,
* GNUNET_NO if not.
*/
-static int gossip_all_to_all_iterator (void *cls,
- const GNUNET_HashCode * key,
- void *abs_value)
+static int
+gossip_all_to_all_iterator (void *cls,
+ const GNUNET_HashCode * key,
+ void *abs_value)
{
struct DirectNeighbor *direct = abs_value;
*
* @return GNUNET_YES to continue iteration, GNUNET_NO otherwise
*/
-static int add_all_direct_neighbors (void *cls,
- const GNUNET_HashCode * key,
- void *value)
+static int
+add_all_direct_neighbors (void *cls,
+ const GNUNET_HashCode * key,
+ void *value)
{
struct DirectNeighbor *direct = (struct DirectNeighbor *)value;
struct DirectNeighbor *to = (struct DirectNeighbor *)cls;
*
* @param cls closure
* @param peer peer identity this notification is about
- * @param latency reported latency of the connection with peer
- * @param distance reported distance (DV) to peer
+ * @param atsi performance data
*/
-void handle_core_connect (void *cls,
- const struct GNUNET_PeerIdentity * peer,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+static void
+handle_core_connect (void *cls,
+ const struct GNUNET_PeerIdentity * peer,
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
struct DirectNeighbor *neighbor;
struct DistantNeighbor *about;
coreAPI =
GNUNET_CORE_connect (cfg,
1,
- GNUNET_TIME_relative_get_forever(),
NULL, /* FIXME: anything we want to pass around? */
&core_init,
&handle_core_connect,
}
+/**
+ * Find latency information in 'atsi'.
+ *
+ * @param atsi performance data
+ * @return connection latency
+ */
+static struct GNUNET_TIME_Relative
+get_latency (const struct GNUNET_TRANSPORT_ATS_Information *atsi)
+{
+ /* FIXME: extract latency data from 'atsi' */
+ return GNUNET_TIME_UNIT_SECONDS;
+}
+
+
/**
* Method called whenever a given peer connects.
*
* @param cls closure, not used
* @param peer peer identity this notification is about
- * @param latency reported latency of the connection with 'other'
- * @param distance reported distance (DV) to 'other'
+ * @param atsi performance information
*/
static void
peer_connect_handler (void *cls,
const struct
GNUNET_PeerIdentity * peer,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
struct ConnectedPeer *cp;
struct MigrationReadyBlock *pos;
char *fn;
uint32_t trust;
+ struct GNUNET_TIME_Relative latency;
+ latency = get_latency (atsi);
cp = GNUNET_CONTAINER_multihashmap_get (connected_peers,
&peer->hashPubKey);
if (NULL != cp)
*
* @param cls closure
* @param peer peer identity this notification is about
- * @param latency reported latency of the connection with 'other'
- * @param distance reported distance (DV) to 'other'
* @param bandwidth_in available amount of inbound bandwidth
* @param bandwidth_out available amount of outbound bandwidth
* @param timeout absolute time when this peer will time out
* unless we see some further activity from it
+ * @param atsi status information
*/
static void
peer_status_handler (void *cls,
const struct
GNUNET_PeerIdentity * peer,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance,
struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
- struct GNUNET_TIME_Absolute timeout)
+ struct GNUNET_TIME_Absolute timeout,
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
struct ConnectedPeer *cp;
+ struct GNUNET_TIME_Relative latency;
+ latency = get_latency (atsi);
cp = GNUNET_CONTAINER_multihashmap_get (connected_peers,
&peer->hashPubKey);
if (cp == NULL)
*
* @param cls the requests "struct PendingRequest*"
* @param peer identifies the peer
- * @param bpm_in set to the current bandwidth limit (receiving) for this peer
* @param bpm_out set to the current bandwidth limit (sending) for this peer
* @param amount set to the amount that was actually reserved or unreserved
* @param preference current traffic preference for the given peer
target_reservation_cb (void *cls,
const struct
GNUNET_PeerIdentity * peer,
- struct GNUNET_BANDWIDTH_Value32NBO bpm_in,
struct GNUNET_BANDWIDTH_Value32NBO bpm_out,
int amount,
uint64_t preference)
cp = GNUNET_CONTAINER_multihashmap_get (connected_peers,
&psc.target.hashPubKey);
GNUNET_assert (NULL != cp);
- pr->irc = GNUNET_CORE_peer_change_preference (cfg,
+ pr->irc = GNUNET_CORE_peer_change_preference (core,
&psc.target,
GNUNET_CONSTANTS_SERVICE_TIMEOUT,
GNUNET_BANDWIDTH_value_init (UINT32_MAX),
/* force forwarding */
static struct GNUNET_BANDWIDTH_Value32NBO zerobw;
target_reservation_cb (pr, &psc.target,
- zerobw, zerobw, 0, 0.0);
+ zerobw, 0, 0.0);
}
}
* @param other the other peer involved (sender or receiver, NULL
* for loopback messages where we are both sender and receiver)
* @param message the actual message
- * @param latency reported latency of the connection with 'other'
- * @param distance reported distance (DV) to 'other'
+ * @param atsi performance information
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
handle_p2p_put (void *cls,
const struct GNUNET_PeerIdentity *other,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
const struct PutMessage *put;
uint16_t msize;
* @param other the other peer involved (sender or receiver, NULL
* for loopback messages where we are both sender and receiver)
* @param message the actual message
- * @param latency reported latency of the connection with 'other'
- * @param distance reported distance (DV) to 'other'
+ * @param atsi performance information
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
handle_p2p_migration_stop (void *cls,
const struct GNUNET_PeerIdentity *other,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
struct ConnectedPeer *cp;
const struct MigrationStopMessage *msm;
* @param other the other peer involved (sender or receiver, NULL
* for loopback messages where we are both sender and receiver)
* @param message the actual message
- * @param latency reported latency of the connection with 'other'
- * @param distance reported distance (DV) to 'other'
+ * @param atsi performance information
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
handle_p2p_get (void *cls,
const struct GNUNET_PeerIdentity *other,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
struct PendingRequest *pr;
struct ConnectedPeer *cp;
requests_by_expiration_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
core = GNUNET_CORE_connect (cfg,
1, /* larger? */
- GNUNET_TIME_UNIT_FOREVER_REL,
NULL,
NULL,
&peer_connect_handler,
* Core handler for p2p hostlist advertisements
*/
static int advertisement_handler (void *cls,
- const struct GNUNET_PeerIdentity * peer,
- const struct GNUNET_MessageHeader * message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_PeerIdentity * peer,
+ const struct GNUNET_MessageHeader * message,
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
GNUNET_assert (NULL != client_adv_handler);
- return (*client_adv_handler) (cls, peer, message, latency, distance);
+ return (*client_adv_handler) (cls, peer, message, atsi);
}
*
* @param cls closure
* @param peer peer identity this notification is about
- * @param latency reported latency of the connection with 'other'
- * @param distance reported distance (DV) to 'other'
+ * @param atsi performance data
*/
static void
connect_handler (void *cls,
const struct
GNUNET_PeerIdentity * peer,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"A new peer connected, notifying client and server\n");
if ( NULL != client_ch)
- (*client_ch) (cls, peer, latency, distance);
+ (*client_ch) (cls, peer, atsi);
#if HAVE_MHD
if ( NULL != server_ch)
- (*server_ch) (cls, peer, latency, distance);
+ (*server_ch) (cls, peer, atsi);
#endif
}
core = GNUNET_CORE_connect (cfg,
1,
- GNUNET_TIME_UNIT_FOREVER_REL,
NULL,
&core_init,
&connect_handler, &disconnect_handler, NULL,
*
* @param cls closure
* @param peer peer identity this notification is about
- * @param latency reported latency of the connection with 'other'
- * @param distance reported distance (DV) to 'other'
+ * @param atsi performance data
*/
static void
handler_connect (void *cls,
const struct
GNUNET_PeerIdentity * peer,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
GNUNET_assert (stat_connection_count < UINT_MAX);
stat_connection_count++;
* @param cls closure (always NULL)
* @param peer the peer sending the message
* @param message the actual message
- * @param latency latency
- * @param distance distance
+ * @param atsi performance data
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
static int
handler_advertisement (void *cls,
- const struct GNUNET_PeerIdentity * peer,
- const struct GNUNET_MessageHeader * message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_PeerIdentity * peer,
+ const struct GNUNET_MessageHeader * message,
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
size_t size;
size_t uri_size;
*
* @param cls closure
* @param peer peer identity this notification is about
- * @param latency reported latency of the connection with 'other'
- * @param distance reported distance (DV) to 'other'
+ * @param atsi performance data
*/
static void
connect_handler (void *cls,
const struct
GNUNET_PeerIdentity * peer,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
size_t size;
/**
* Core handler for p2p hostlist advertisements
*/
-static int ad_arrive_handler (void *cls,
- const struct GNUNET_PeerIdentity * peer,
- const struct GNUNET_MessageHeader * message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+static int
+ad_arrive_handler (void *cls,
+ const struct GNUNET_PeerIdentity * peer,
+ const struct GNUNET_MessageHeader * message,
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
char *hostname;
char *expected_uri;
p->core = GNUNET_CORE_connect (p->cfg,
1,
- GNUNET_TIME_UNIT_FOREVER_REL,
NULL,
NULL,
NULL, NULL, NULL,
#endif
#include "gnunet_util_lib.h"
+#include "gnunet_transport_service.h"
/**
* Version number of GNUnet-core API.
*
* @param cls closure
* @param peer peer identity this notification is about
- * @param latency reported latency of the connection with 'other'
- * @param distance reported distance (DV) to 'other'
+ * @param atsi performance data for the connection
*/
typedef void (*GNUNET_CORE_ConnectEventHandler) (void *cls,
const struct
- GNUNET_PeerIdentity * peer,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance);
+ GNUNET_PeerIdentity *peer,
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi);
+
/**
* Method called whenever a given peer has a status change.
*
* @param cls closure
* @param peer peer identity this notification is about
- * @param latency reported latency of the connection with 'other'
- * @param distance reported distance (DV) to 'other'
- * @param bandwidth_in available amount of inbound bandwidth
- * @param bandwidth_out available amount of outbound bandwidth
* @param timeout absolute time when this peer will time out
* unless we see some further activity from it
+ * @param bandwidth_in available amount of inbound bandwidth
+ * @param bandwidth_out available amount of outbound bandwidth
+ * @param atsi performance data for the connection
*/
typedef void (*GNUNET_CORE_PeerStatusEventHandler) (void *cls,
const struct
GNUNET_PeerIdentity * peer,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance,
struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
- struct GNUNET_TIME_Absolute timeout);
+ struct GNUNET_TIME_Absolute timeout,
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi);
/**
*/
typedef void (*GNUNET_CORE_DisconnectEventHandler) (void *cls,
const struct
- GNUNET_PeerIdentity * peer);
+ GNUNET_PeerIdentity *peer);
/**
* Functions with this signature are called whenever a message is
* received or transmitted.
*
- * @param cls closure
+ * @param cls closure (set from GNUNET_CORE_connect)
* @param peer the other peer involved (sender or receiver, NULL
* for loopback messages where we are both sender and receiver)
* @param message the actual message
- * @param latency reported latency of the connection with 'other'
- * @param distance reported distance (DV) to 'other'
+ * @param atsi performance data for the connection
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
typedef int
(*GNUNET_CORE_MessageCallback) (void *cls,
- const struct GNUNET_PeerIdentity * other,
- const struct GNUNET_MessageHeader *
- message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance);
+ const struct GNUNET_PeerIdentity *other,
+ const struct GNUNET_MessageHeader *message,
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi);
/**
*
* @param cfg configuration to use
* @param queue_size size of the per-peer message queue
- * @param timeout after how long should we give up trying to connect to the core service?
* @param cls closure for the various callbacks that follow (including handlers in the handlers array)
* @param init callback to call on timeout or once we have successfully
* connected to the core service; note that timeout is only meaningful if init is not NULL
struct GNUNET_CORE_Handle *
GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
unsigned int queue_size,
- struct GNUNET_TIME_Relative timeout,
void *cls,
GNUNET_CORE_StartupCallback init,
GNUNET_CORE_ConnectEventHandler connects,
/**
- * Disconnect from the core service.
+ * Disconnect from the core service. This function can only
+ * be called *after* all pending 'GNUNET_CORE_notify_transmit_ready'
+ * requests have been explicitly cancelled.
*
* @param handle connection to core to disconnect
*/
* to our connection attempt within the given time frame, 'cont' will
* be called with the TIMEOUT reason code.
*
- * @param cfg configuration to use
+ * @param h core handle
* @param timeout how long to try to talk to core
* @param peer who should we connect to
* @param cont function to call once the request has been completed (or timed out)
* @return NULL on error (cont will not be called), otherwise handle for cancellation
*/
struct GNUNET_CORE_PeerRequestHandle *
-GNUNET_CORE_peer_request_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
+GNUNET_CORE_peer_request_connect (struct GNUNET_CORE_Handle *h,
struct GNUNET_TIME_Relative timeout,
const struct GNUNET_PeerIdentity * peer,
GNUNET_SCHEDULER_Task cont,
/**
- * Function called with statistics about the given peer.
+ * Function called with perference change information about the given peer.
*
* @param cls closure
* @param peer identifies the peer
- * @param bpm_in set to the current bandwidth limit (receiving) for this peer
- * @param bpm_out set to the current bandwidth limit (sending) for this peer
- * @param latency current latency estimate, "FOREVER" if we have been
- * disconnected
+ * @param bandwidth_out available amount of outbound bandwidth
* @param amount set to the amount that was actually reserved or unreserved;
* either the full requested amount or zero (no partial reservations)
* @param preference current traffic preference for the given peer
(*GNUNET_CORE_PeerConfigurationInfoCallback) (void *cls,
const struct
GNUNET_PeerIdentity * peer,
- struct GNUNET_BANDWIDTH_Value32NBO bpm_in,
- struct GNUNET_BANDWIDTH_Value32NBO bpm_out,
+ struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
int amount,
uint64_t preference);
/**
* Obtain statistics and/or change preferences for the given peer.
+ * You can only have one such pending request per peer.
*
- * @param cfg configuration to use
+ * @param h core handle
* @param peer identifies the peer
* @param timeout after how long should we give up (and call "info" with NULL
* for "peer" to signal an error)?
* @return NULL on error
*/
struct GNUNET_CORE_InformationRequestContext *
-GNUNET_CORE_peer_change_preference (const struct GNUNET_CONFIGURATION_Handle *cfg,
+GNUNET_CORE_peer_change_preference (struct GNUNET_CORE_Handle *h,
const struct GNUNET_PeerIdentity *peer,
struct GNUNET_TIME_Relative timeout,
struct GNUNET_BANDWIDTH_Value32NBO bw_out,
/**
* Cancel request for getting information about a peer.
+ * Note that an eventual change in preference, trust or bandwidth
+ * assignment MAY have already been committed at the time,
+ * so cancelling a request is NOT sure to undo the original
+ * request. The original request may or may not still commit.
+ * The only thing cancellation ensures is that the callback
+ * from the original request will no longer be called.
*
* @param irc context returned by the original GNUNET_CORE_peer_get_info call
*/
void
GNUNET_CORE_peer_change_preference_cancel (struct GNUNET_CORE_InformationRequestContext *irc);
+
/**
- * Obtain statistics and/or change preferences for the given peer.
+ * Iterate over all connected peers.
*
- * @param cfg configuration to use
+ * @param h core handle
* @param peer_cb function to call with the peer information
* @param cb_cls closure for peer_cb
- * @return GNUNET_OK if iterating, GNUNET_SYSERR on error
+ * @return GNUNET_OK on success, GNUNET_SYSERR on errors
*/
int
-GNUNET_CORE_iterate_peers (const struct GNUNET_CONFIGURATION_Handle *cfg,
+GNUNET_CORE_iterate_peers (struct GNUNET_CORE_Handle *h,
GNUNET_CORE_ConnectEventHandler peer_cb,
void *cb_cls);
+
/**
* Handle for a transmission request.
*/
#define GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO 73
/**
- * Request from client with message to transmit.
+ * Request from client to transmit message.
*/
-#define GNUNET_MESSAGE_TYPE_CORE_SEND 74
+#define GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST 74
/**
- * Request from client asking to connect to a peer.
+ * Confirmation from core that message can now be sent
+ */
+#define GNUNET_MESSAGE_TYPE_CORE_SEND_READY 75
+
+/**
+ * Client with message to transmit (after SEND_READY confirmation
+ * was received).
*/
-#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT 75
+#define GNUNET_MESSAGE_TYPE_CORE_SEND 76
/**
- * Request from client asking to call back with all connected peers.
+ * Request from client asking to connect to a peer.
*/
-#define GNUNET_MESSAGE_TYPE_CORE_ITERATE_PEERS 76
+#define GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT 77
+
/**
* Session key exchange between peers.
typedef void (*GNUNET_TESTING_NotifyTopology)(void *cls,
const struct GNUNET_PeerIdentity *first,
const struct GNUNET_PeerIdentity *second,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance,
const char *emsg);
/**
#include "gnunet_statistics_service.h"
#include "gnunet_transport_service.h"
-
-/**
- * The structs defined here are used by the transport plugin to tell ATS about
- * the transport's properties like cost and quality and on the other side
- * the structs are used by highlevel components to communicate the constraints
- * they have for a transport to ATS
- *
- * +---+
- * +-----------+ Constraints | | Plugin properties +---------+
- * | Highlevel |------------> |ATS| <------------------|Transport|
- * | Component | ATS struct | | ATS struct | Plugin |
- * +-----------+ | | +---------+
- * +---+
- *
- */
-
-#define GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR 0
-
-/**
- * Enum defining all known property types for ATS
- * Enum values are used in the GNUNET_TRANSPORT_ATS_Information struct as (key,value)-pair
- *
- * Cost are always stored in uint32_t, so all units used to define costs
- * have to be normalized to fit in uint32_t [0 .. 4.294.967.295]
- *
- * To keep the elements ordered
- * 1..1024 : Values with a relation to cost
- * 1025..2048 : Values with a relation to quality
- * 2049..3072 : Values with a relation to availability
- *
- */
-enum GNUNET_TRANSPORT_ATS_Property
-{
-
- /* Cost related values */
- /* =================== */
-
- /**
- * Volume based cost in financial units to transmit data
- *
- * Note: This value is not bound to a specific currency or unit and only
- * used locally.
- * "cent" just refers the smallest amount of money in the respective
- * currency.
- *
- * Unit: [cent/MB]
- *
- * Interpretation: less is better
- *
- * Examples:
- * LAN: 0 [cent/MB]
- * 2G : 10 [cent/MB]
- */
- GNUNET_TRANSPORT_ATS_COST_FINANCIAL_PER_VOLUME = 1,
-
- /**
- * Time based cost in financial units to transmit data
- *
- * Note: This value is not bound to a specific currency or unit and only
- * used locally.
- * "cent" just refers the smallest amount of money in the respective
- * currency.
- *
- * Unit: [cent/h]
- *
- * Interpretation: less is better
- *
- * Examples:
- * LAN : 0 [cent/h]
- * Dialup: 10 [cent/h]
- */
- GNUNET_TRANSPORT_ATS_COST_FINANCIAL_PER_TIME = 2,
-
- /**
- * Computational costs
- *
- * Effort of preparing data to be sent with this transport
- * Includes encoding, encryption and conversion of data
- * Partial values can be summed up: c_sum = c_enc + c_enc + c_conv
- * Resulting values depend on local system properties, e.g. CPU
- *
- * Unit: [ms/GB]
- *
- * Interpretation: less is better
- *
- * Examples:
- *
- * HTTPS with AES CBC-256: 7,382
- * HTTPS with AES CBC-128: 5,279
- * HTTPS with RC4-1024: 2,652
- */
- GNUNET_TRANSPORT_ATS_COST_COMPUTATIONAL = 3,
-
- /**
- * Energy consumption
- *
- * Energy consumption using this transport when sending with a certain
- * power at a certain bitrate. This is only an approximation based on:
- * Energy consumption E = P / D
- *
- * with:
- * Power P in Watt (J/s)
- * Datarate D in MBit/s
- *
- * Conversion between power P and dBm used by WLAN in radiotap's dBm TX power:
- *
- * Lp(dbm) = 10 log10 (P/ 1mW)
- *
- * => P = 1 mW * 10^(Lp(dbm)/10)
- *
- * Unit: [mJ/MB]
- *
- * Interpretation: less is better
- *
- * Examples:
- *
- * LAN: 0
- * WLAN: 89 (600 mW @ 802.11g /w 54 MBit/s)
- * Bluetooth: 267 (100 mW @ BT2.0 EDR /w 3 MBit/s)
- */
- GNUNET_TRANSPORT_ATS_COST_ENERGY_CONSUMPTION = 4,
-
- /**
- * Connect cost
- * How many bytes are transmitted to initiate a new connection using
- * this transport?
- *
- * Unit: [bytes]
- *
- * Interpretation: less is better
- *
- * Examples:
- *
- * UDP (No connection) :
- * 0 bytes
- * TCP (TCP 3-Way handshake):
- * 220 bytes Ethernet, 172 bytes TCP/IP, 122 bytes TCP
- * HTTP (TCP + Header) :
- * 477 bytes Ethernet, 429 bytes TCP/IP, 374 bytes TCP, 278 bytes HTTP
- * HTTPS HTTP+TLS Handshake:
- * 2129 bytes Ethernet, 1975 bytes TCP/IP, 1755 bytes TCP, 1403 bytes HTTPS
- *
- * */
- GNUNET_TRANSPORT_ATS_COST_CONNECT = 5,
-
- /**
- * Bandwidth cost
- *
- * How many bandwidth is available to consume?
- * Used to calculate which impact sending data with this transport has
- *
- * Unit: [kB/s]
- *
- * Interpretation: more is better
- *
- * Examples:
- * LAN: 12,800 (100 MBit/s)
- * WLAN: 6,912 (54 MBit/s)
- * Dial-up: 8 (64 Kbit/s)
- *
- */
- GNUNET_TRANSPORT_ATS_COST_BANDWITH_AVAILABLE = 6,
-
- /**
- * Network overhead
- *
- * How many bytes are sent over the wire when 1 kilobyte (1024 bytes)
- * of application data is transmitted?
- * A factor used with connect cost, bandwidth cost and energy cost
- * to describe the overhead produced by the transport protocol
- *
- * Unit: [bytes/kb]
- *
- * Interpretation: less is better
- *
- * Examples:
- *
- * TCP/IPv4 over Ethernet: 1024 + 38 + 20 + 20 = 1102 [bytes/kb]
- * TCP/IPv6 over Ethernet: 1024 + 38 + 20 + 40 = 1122 [bytes/kb]
- * UDP/IPv4 over Ethernet: 1024 + 38 + 20 + 8 = 1090 [bytes/kb]
- * UDP/IPv6 over Ethernet: 1024 + 38 + 40 + 8 = 1110 [bytes/kb]
- */
- GNUNET_TRANSPORT_ATS_COST_NETWORK_OVERHEAD = 7,
-
-
- /* Quality related values */
- /* ====================== */
-
- /* Physical layer quality properties */
-
- /**
- * Signal strength on physical layer
- *
- * Unit: [dBm]
- */
- GNUNET_TRANSPORT_ATS_QUALITY_PHY_SIGNAL_STRENGTH = 1025,
-
- /**
- * Collision rate on physical layer
- *
- * Unit: [B/s]
- */
- GNUNET_TRANSPORT_ATS_QUALITY_PHY_COLLISION_RATE = 1026,
-
- /**
- * Error rate on physical layer
- *
- * Unit: [B/s]
- */
- GNUNET_TRANSPORT_ATS_QUALITY_PHY_ERROR_RATE = 1027,
-
- /* Network layer quality properties */
-
- /**
- * Delay
- * Time between when the time packet is sent and the packet arrives
- *
- * Unit: [μs]
- *
- * Examples:
- *
- * LAN : 180
- * Dialup: 4000
- * WLAN : 7000
- */
- GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY = 1028,
-
- /**
- * Jitter
- * Time variations of the delay
- * 1st derivative of a delay function
- *
- * Unit: [μs]
- */
- GNUNET_TRANSPORT_ATS_QUALITY_NET_JITTER = 1029,
-
- /**
- * Error rate on network layer
- *
- * Unit: [B/s]
- *
- * Examples:
- *
- * LAN : 0
- * WLAN : 400
- * Bluetooth : 100
- * Note: This numbers are just assumptions as an example, not
- * measured or somehow determined
- */
- GNUNET_TRANSPORT_ATS_QUALITY_NET_ERRORRATE = 1030,
-
- /**
- * Drop rate on network layer
- * Bytes actively dismissed by a network component during transmission
- * Reasons for dropped data can be full queues, congestion, quota violations...
- *
- * Unit: [B/s]
- *
- * Examples:
- *
- * LAN : 0
- * WLAN : 400
- * Bluetooth : 100
- * Note: This numbers are just assumptions as an example, not
- * measured or somehow determined
- */
- GNUNET_TRANSPORT_ATS_QUALITY_NET_DROPRATE = 1031,
-
- /**
- * Loss rate on network layer
- * Bytes lost during transmission
- * Reasons can be collisions, ...
- *
- * Unit: [B/s]
- *
- * Examples:
- *
- * LAN : 0
- * WLAN : 40
- * Bluetooth : 10
- * Note: This numbers are just assumptions as an example, not measured
- * or somehow determined
- */
- GNUNET_TRANSPORT_ATS_QUALITY_NET_LOSSRATE = 1032,
-
- /**
- * Throughput on network layer
- *
- * Unit: [kB/s]
- *
- * Examples:
- *
- * LAN : 3400
- * WLAN : 1200
- * Dialup: 4
- *
- */
- GNUNET_TRANSPORT_ATS_QUALITY_NET_THROUGHPUT = 1033,
-
- /* Availability related values */
- /* =========================== */
-
- /**
- * Is a peer reachable?
- */
- GNUNET_TRANSPORT_ATS_AVAILABILITY_REACHABLE = 2048,
-
- /**
- * Is there a connection established to a peer using this transport
- */
- GNUNET_TRANSPORT_ATS_AVAILABILITY_CONNECTED = 2049
-};
-
-/**
- * This structure will be used by plugins to communicate costs to ATS or by
- * higher level components to tell ATS their constraints.
- * Always a pair of (GNUNET_TRANSPORT_ATS_Property, uint32_t value).
- * Value is always uint32_t, so all units used to define costs have to
- * be normalized to fit uint32_t.
- */
-struct GNUNET_TRANSPORT_ATS_Information
-{
- /**
- * ATS property type
- */
- uint32_t type;
-
- /**
- * ATS property value
- */
- uint32_t value;
-};
-
-
-
/**
* Opaque pointer that plugins can use to distinguish specific
* connections to a given peer. Typically used by stateful plugins to
*/
#define GNUNET_TRANSPORT_VERSION 0x00000000
+
+/**
+ * Enum defining all known property types for ATS Enum values are used
+ * in the GNUNET_TRANSPORT_ATS_Information struct as
+ * (key,value)-pairs.
+ *
+ * Cost are always stored in uint32_t, so all units used to define costs
+ * have to be normalized to fit in uint32_t [0 .. 4.294.967.295]
+ *
+ * To keep the elements ordered
+ * 1..1024 : Values with a relation to cost
+ * 1025..2048 : Values with a relation to quality
+ * 2049..3072 : Values with a relation to availability
+ *
+ */
+enum GNUNET_TRANSPORT_ATS_Property
+{
+
+ /**
+ * End of the array.
+ */
+ GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR = 0,
+
+ /* Cost related values */
+ /* =================== */
+
+ /**
+ * Volume based cost in financial units to transmit data
+ *
+ * Note: This value is not bound to a specific currency or unit and only
+ * used locally.
+ * "cent" just refers the smallest amount of money in the respective
+ * currency.
+ *
+ * Unit: [cent/MB]
+ *
+ * Interpretation: less is better
+ *
+ * Examples:
+ * LAN: 0 [cent/MB]
+ * 2G : 10 [cent/MB]
+ */
+ GNUNET_TRANSPORT_ATS_COST_FINANCIAL_PER_VOLUME = 1,
+
+ /**
+ * Time based cost in financial units to transmit data
+ *
+ * Note: This value is not bound to a specific currency or unit and only
+ * used locally.
+ * "cent" just refers the smallest amount of money in the respective
+ * currency.
+ *
+ * Unit: [cent/h]
+ *
+ * Interpretation: less is better
+ *
+ * Examples:
+ * LAN : 0 [cent/h]
+ * Dialup: 10 [cent/h]
+ */
+ GNUNET_TRANSPORT_ATS_COST_FINANCIAL_PER_TIME = 2,
+
+ /**
+ * Computational costs
+ *
+ * Effort of preparing data to be sent with this transport
+ * Includes encoding, encryption and conversion of data
+ * Partial values can be summed up: c_sum = c_enc + c_enc + c_conv
+ * Resulting values depend on local system properties, e.g. CPU
+ *
+ * Unit: [ms/GB]
+ *
+ * Interpretation: less is better
+ *
+ * Examples:
+ *
+ * HTTPS with AES CBC-256: 7,382
+ * HTTPS with AES CBC-128: 5,279
+ * HTTPS with RC4-1024: 2,652
+ */
+ GNUNET_TRANSPORT_ATS_COST_COMPUTATIONAL = 3,
+
+ /**
+ * Energy consumption
+ *
+ * Energy consumption using this transport when sending with a certain
+ * power at a certain bitrate. This is only an approximation based on:
+ * Energy consumption E = P / D
+ *
+ * with:
+ * Power P in Watt (J/s)
+ * Datarate D in MBit/s
+ *
+ * Conversion between power P and dBm used by WLAN in radiotap's dBm TX power:
+ *
+ * Lp(dbm) = 10 log10 (P/ 1mW)
+ *
+ * => P = 1 mW * 10^(Lp(dbm)/10)
+ *
+ * Unit: [mJ/MB]
+ *
+ * Interpretation: less is better
+ *
+ * Examples:
+ *
+ * LAN: 0
+ * WLAN: 89 (600 mW @ 802.11g /w 54 MBit/s)
+ * Bluetooth: 267 (100 mW @ BT2.0 EDR /w 3 MBit/s)
+ */
+ GNUNET_TRANSPORT_ATS_COST_ENERGY_CONSUMPTION = 4,
+
+ /**
+ * Connect cost
+ * How many bytes are transmitted to initiate a new connection using
+ * this transport?
+ *
+ * Unit: [bytes]
+ *
+ * Interpretation: less is better
+ *
+ * Examples:
+ *
+ * UDP (No connection) :
+ * 0 bytes
+ * TCP (TCP 3-Way handshake):
+ * 220 bytes Ethernet, 172 bytes TCP/IP, 122 bytes TCP
+ * HTTP (TCP + Header) :
+ * 477 bytes Ethernet, 429 bytes TCP/IP, 374 bytes TCP, 278 bytes HTTP
+ * HTTPS HTTP+TLS Handshake:
+ * 2129 bytes Ethernet, 1975 bytes TCP/IP, 1755 bytes TCP, 1403 bytes HTTPS
+ *
+ * */
+ GNUNET_TRANSPORT_ATS_COST_CONNECT = 5,
+
+ /**
+ * Bandwidth cost
+ *
+ * How many bandwidth is available to consume?
+ * Used to calculate which impact sending data with this transport has
+ *
+ * Unit: [kB/s]
+ *
+ * Interpretation: more is better
+ *
+ * Examples:
+ * LAN: 12,800 (100 MBit/s)
+ * WLAN: 6,912 (54 MBit/s)
+ * Dial-up: 8 (64 Kbit/s)
+ *
+ */
+ GNUNET_TRANSPORT_ATS_COST_BANDWITH_AVAILABLE = 6,
+
+ /**
+ * Network overhead
+ *
+ * How many bytes are sent over the wire when 1 kilobyte (1024 bytes)
+ * of application data is transmitted?
+ * A factor used with connect cost, bandwidth cost and energy cost
+ * to describe the overhead produced by the transport protocol
+ *
+ * Unit: [bytes/kb]
+ *
+ * Interpretation: less is better
+ *
+ * Examples:
+ *
+ * TCP/IPv4 over Ethernet: 1024 + 38 + 20 + 20 = 1102 [bytes/kb]
+ * TCP/IPv6 over Ethernet: 1024 + 38 + 20 + 40 = 1122 [bytes/kb]
+ * UDP/IPv4 over Ethernet: 1024 + 38 + 20 + 8 = 1090 [bytes/kb]
+ * UDP/IPv6 over Ethernet: 1024 + 38 + 40 + 8 = 1110 [bytes/kb]
+ */
+ GNUNET_TRANSPORT_ATS_COST_NETWORK_OVERHEAD = 7,
+
+
+ /* Quality related values */
+ /* ====================== */
+
+ /* Physical layer quality properties */
+
+ /**
+ * Signal strength on physical layer
+ *
+ * Unit: [dBm]
+ */
+ GNUNET_TRANSPORT_ATS_QUALITY_PHY_SIGNAL_STRENGTH = 1025,
+
+ /**
+ * Collision rate on physical layer
+ *
+ * Unit: [B/s]
+ */
+ GNUNET_TRANSPORT_ATS_QUALITY_PHY_COLLISION_RATE = 1026,
+
+ /**
+ * Error rate on physical layer
+ *
+ * Unit: [B/s]
+ */
+ GNUNET_TRANSPORT_ATS_QUALITY_PHY_ERROR_RATE = 1027,
+
+ /* Network layer quality properties */
+
+ /**
+ * Delay
+ * Time between when the time packet is sent and the packet arrives
+ *
+ * Unit: [μs]
+ *
+ * Examples:
+ *
+ * LAN : 180
+ * Dialup: 4000
+ * WLAN : 7000
+ */
+ GNUNET_TRANSPORT_ATS_QUALITY_NET_DELAY = 1028,
+
+ /**
+ * Jitter
+ * Time variations of the delay
+ * 1st derivative of a delay function
+ *
+ * Unit: [μs]
+ */
+ GNUNET_TRANSPORT_ATS_QUALITY_NET_JITTER = 1029,
+
+ /**
+ * Error rate on network layer
+ *
+ * Unit: [B/s]
+ *
+ * Examples:
+ *
+ * LAN : 0
+ * WLAN : 400
+ * Bluetooth : 100
+ * Note: This numbers are just assumptions as an example, not
+ * measured or somehow determined
+ */
+ GNUNET_TRANSPORT_ATS_QUALITY_NET_ERRORRATE = 1030,
+
+ /**
+ * Drop rate on network layer
+ * Bytes actively dismissed by a network component during transmission
+ * Reasons for dropped data can be full queues, congestion, quota violations...
+ *
+ * Unit: [B/s]
+ *
+ * Examples:
+ *
+ * LAN : 0
+ * WLAN : 400
+ * Bluetooth : 100
+ * Note: This numbers are just assumptions as an example, not
+ * measured or somehow determined
+ */
+ GNUNET_TRANSPORT_ATS_QUALITY_NET_DROPRATE = 1031,
+
+ /**
+ * Loss rate on network layer
+ * Bytes lost during transmission
+ * Reasons can be collisions, ...
+ *
+ * Unit: [B/s]
+ *
+ * Examples:
+ *
+ * LAN : 0
+ * WLAN : 40
+ * Bluetooth : 10
+ * Note: This numbers are just assumptions as an example, not measured
+ * or somehow determined
+ */
+ GNUNET_TRANSPORT_ATS_QUALITY_NET_LOSSRATE = 1032,
+
+ /**
+ * Throughput on network layer
+ *
+ * Unit: [kB/s]
+ *
+ * Examples:
+ *
+ * LAN : 3400
+ * WLAN : 1200
+ * Dialup: 4
+ *
+ */
+ GNUNET_TRANSPORT_ATS_QUALITY_NET_THROUGHPUT = 1033,
+
+ /* Availability related values */
+ /* =========================== */
+
+ /**
+ * Is a peer reachable?
+ */
+ GNUNET_TRANSPORT_ATS_AVAILABILITY_REACHABLE = 2048,
+
+ /**
+ * Is there a connection established to a peer using this transport
+ */
+ GNUNET_TRANSPORT_ATS_AVAILABILITY_CONNECTED = 2049
+
+};
+
+
+/**
+ * struct used to communicate the transport's properties like cost and
+ * quality of service as well as high-level constraints on resource
+ * consumption.
+ *
+ * +---+
+ * +-----------+ Constraints | | Plugin properties +---------+
+ * | Highlevel |------------> |ATS| <------------------|Transport|
+ * | Component | ATS struct | | ATS struct | Plugin |
+ * +-----------+ | | +---------+
+ * +---+
+ *
+ * This structure will be used by transport plugins to communicate
+ * costs to ATS or by higher level components to tell ATS their
+ * constraints. Always a pair of (GNUNET_TRANSPORT_ATS_Property,
+ * uint32_t value). Value is always uint32_t, so all units used to
+ * define costs have to be normalized to fit uint32_t.
+ */
+struct GNUNET_TRANSPORT_ATS_Information
+{
+ /**
+ * ATS property type, in network byte order.
+ */
+ uint32_t type;
+
+ /**
+ * ATS property value, in network byte order.
+ */
+ uint32_t value;
+};
+
+
+
+
/**
* Function called by the transport for each received message.
*
static void topology_cb (void *cls,
const struct GNUNET_PeerIdentity *first,
const struct GNUNET_PeerIdentity *second,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance,
const char *emsg)
{
FILE *outfile = cls;
process_mtype (void *cls,
const struct GNUNET_PeerIdentity *peer,
const struct GNUNET_MessageHeader *message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
char *dotOutFileNameFinished;
FILE *dotOutFileFinished;
*/
pos->peer2handle = GNUNET_CORE_connect (pos->peer2->cfg,
1,
- TIMEOUT,
pos,
&init_notify_peer2,
NULL,
*/
pos->peer1handle = GNUNET_CORE_connect (pos->peer1->cfg,
1,
- TIMEOUT,
pos,
&init_notify_peer1,
NULL, NULL,
d->phase = SP_START_CORE;
d->server = GNUNET_CORE_connect (d->cfg,
1,
+#if NO_MORE_TIMEOUT_FIXME
ARM_START_WAIT,
+#endif
d,
&testing_init,
NULL, NULL, NULL,
{
if (ctx->cb != NULL)
{
- ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, ctx->distance, ctx->d1->cfg,
- ctx->d2->cfg, ctx->d1, ctx->d2, NULL);
+ ctx->cb (ctx->cb_cls,
+ &ctx->d1->id,
+ &ctx->d2->id,
+ ctx->distance,
+ ctx->d1->cfg,
+ ctx->d2->cfg,
+ ctx->d1,
+ ctx->d2,
+ NULL);
}
}
else if (remaining.rel_value > 0)
*
* @param cls our "struct ConnectContext"
* @param peer identity of the peer that has connected
- * @param latency the round trip latency of the connection to this peer
- * @param distance distance the transport level distance to this peer
+ * @param atsi performance information
*
*/
static void
-connect_notify (void *cls, const struct GNUNET_PeerIdentity * peer, struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+connect_notify (void *cls,
+ const struct GNUNET_PeerIdentity * peer,
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
struct ConnectContext *ctx = cls;
if (memcmp(&ctx->d2->id, peer, sizeof(struct GNUNET_PeerIdentity)) == 0)
{
ctx->connected = GNUNET_YES;
- ctx->distance = distance;
+ ctx->distance = 0; /* FIXME: distance */
GNUNET_SCHEDULER_cancel(ctx->timeout_task);
ctx->timeout_task = GNUNET_SCHEDULER_add_now (¬ify_connect_result,
ctx);
}
-
}
#if CONNECT_CORE2
*
* @param cls our "struct ConnectContext"
* @param peer identity of the peer that has connected
- * @param latency the round trip latency of the connection to this peer
- * @param distance distance the transport level distance to this peer
+ * @param atsi performance information
*
*/
static void
-connect_notify_core2 (void *cls, const struct GNUNET_PeerIdentity * peer, struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+connect_notify_core2 (void *cls,
+ const struct GNUNET_PeerIdentity * peer,
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
struct ConnectContext *ctx = cls;
if (memcmp(&ctx->d2->id, peer, sizeof(struct GNUNET_PeerIdentity)) == 0)
{
ctx->connected = GNUNET_YES;
- ctx->distance = distance;
+ ctx->distance = 0; /* FIXME: distance */
GNUNET_SCHEDULER_cancel(ctx->timeout_task);
ctx->timeout_task = GNUNET_SCHEDULER_add_now (¬ify_connect_result,
ctx);
GNUNET_assert(hello != NULL);
GNUNET_TRANSPORT_offer_hello (ctx->d2th, hello);
- ctx->connect_request_handle = GNUNET_CORE_peer_request_connect (ctx->d2->cfg,
+ ctx->connect_request_handle = GNUNET_CORE_peer_request_connect (ctx->d2->server,
GNUNET_TIME_relative_divide(ctx->relative_timeout,
ctx->max_connect_attempts + 1),
&ctx->d1->id,
ctx->d1core = GNUNET_CORE_connect (d1->cfg,
1,
+#if NO_MORE_TIMEOUT_FIXME
timeout,
+#endif
ctx,
NULL,
&connect_notify, NULL, NULL,
#if CONNECT_CORE2
ctx->d2core = GNUNET_CORE_connect (d2->cfg,
1,
+#if NO_MORE_TIMEOUT_FIXME
timeout,
+#endif
ctx,
NULL,
NULL, NULL, NULL,
ctx->d1core = GNUNET_CORE_connect (ctx->d1->cfg,
1,
+#if NO_MORE_TIMEOUT_FIXME
GNUNET_TIME_absolute_get_remaining(ctx->timeout),
+#endif
ctx,
NULL,
&connect_notify, NULL, NULL,
static void
internal_topology_callback(void *cls,
const struct GNUNET_PeerIdentity *peer,
- struct GNUNET_TIME_Relative latency, uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
struct CoreContext *core_ctx = cls;
struct TopologyIterateContext *iter_ctx = core_ctx->iter_context;
}
else
{
- iter_ctx->topology_cb(iter_ctx->cls, &core_ctx->daemon->id, peer, latency, distance, NULL);
+ iter_ctx->topology_cb(iter_ctx->cls, &core_ctx->daemon->id,
+ peer, NULL);
}
if (iter_ctx->completed == iter_ctx->total)
{
- iter_ctx->topology_cb(iter_ctx->cls, NULL, NULL, GNUNET_TIME_relative_get_zero(), 0, NULL);
+ iter_ctx->topology_cb(iter_ctx->cls, NULL, NULL,
+ NULL);
/* Once all are done, free the iteration context */
GNUNET_free(iter_ctx);
}
_("Creating connection, outstanding_connections is %d\n"), outstanding_connects);
#endif
topology_context->connected++;
- if (GNUNET_OK != GNUNET_CORE_iterate_peers (core_context->daemon->cfg, &internal_topology_callback, core_context))
- internal_topology_callback(core_context, NULL, GNUNET_TIME_relative_get_zero(), 0);
+ if (GNUNET_OK != GNUNET_CORE_iterate_peers (core_context->daemon->server, &internal_topology_callback, core_context))
+ internal_topology_callback(core_context, NULL, NULL);
}
}
}
if (total_count == 0)
{
- cb(cls, NULL, NULL, GNUNET_TIME_relative_get_zero(), 0, "Cannot iterate over topology, no running peers!");
+ cb(cls, NULL, NULL, "Cannot iterate over topology, no running peers!");
GNUNET_free(topology_context);
}
else
gettext_noop ("# connect requests issued to core"),
1,
GNUNET_NO);
- pos->connect_req = GNUNET_CORE_peer_request_connect (cfg,
+ pos->connect_req = GNUNET_CORE_peer_request_connect (handle,
GNUNET_TIME_UNIT_MINUTES,
&pos->pid,
&connect_completed_callback,
*
* @param cls closure
* @param peer peer identity this notification is about
- * @param latency reported latency of the connection with 'other'
- * @param distance reported distance (DV) to 'other'
+ * @param atsi performance data
*/
static void
connect_notify (void *cls,
const struct
GNUNET_PeerIdentity * peer,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
struct Peer *pos;
* @param other the other peer involved (sender or receiver, NULL
* for loopback messages where we are both sender and receiver)
* @param message the actual HELLO message
- * @param latency reported latency of the connection with 'other'
- * @param distance reported distance (DV) to 'other'
+ * @param atsi performance data
* @return GNUNET_OK to keep the connection open,
* GNUNET_SYSERR to close it (signal serious error)
*/
const struct GNUNET_PeerIdentity * other,
const struct GNUNET_MessageHeader *
message,
- struct GNUNET_TIME_Relative latency,
- uint32_t distance)
+ const struct GNUNET_TRANSPORT_ATS_Information *atsi)
{
struct Peer *peer;
struct GNUNET_PeerIdentity pid;
NULL);
handle = GNUNET_CORE_connect (cfg,
1,
- GNUNET_TIME_UNIT_FOREVER_REL,
NULL,
&core_init,
&connect_notify,