|
@@ -34,66 +34,36 @@
|
|
|
#include "gnunet-service-transport.h"
|
|
|
#include "transport.h"
|
|
|
|
|
|
-enum TRAFFIC_METRIC_DIRECTION
|
|
|
-{
|
|
|
- TM_SEND = 0, TM_RECEIVE = 1, TM_BOTH = 2
|
|
|
-};
|
|
|
-
|
|
|
|
|
|
/**
|
|
|
* Struct containing information about manipulations to a specific peer
|
|
|
*/
|
|
|
-struct TM_Peer;
|
|
|
-
|
|
|
-/**
|
|
|
- * Manipulation entry
|
|
|
- */
|
|
|
-struct PropManipulationEntry
|
|
|
+struct TM_Peer
|
|
|
{
|
|
|
/**
|
|
|
- * Next in DLL
|
|
|
- */
|
|
|
- struct PropManipulationEntry *next;
|
|
|
-
|
|
|
- /**
|
|
|
- * Previous in DLL
|
|
|
- */
|
|
|
- struct PropManipulationEntry *prev;
|
|
|
-
|
|
|
- /**
|
|
|
- * ATS type in HBO
|
|
|
+ * Peer ID
|
|
|
*/
|
|
|
- uint32_t type;
|
|
|
+ struct GNUNET_PeerIdentity peer;
|
|
|
|
|
|
/**
|
|
|
- * Value in HBO
|
|
|
+ * How long to delay incoming messages for this peer.
|
|
|
*/
|
|
|
- uint32_t metrics[TM_BOTH];
|
|
|
+ struct GNUNET_TIME_Relative delay_in;
|
|
|
|
|
|
-};
|
|
|
-
|
|
|
-/**
|
|
|
- * Struct containing information about manipulations to a specific peer
|
|
|
- */
|
|
|
-struct TM_Peer
|
|
|
-{
|
|
|
/**
|
|
|
- * Peer ID
|
|
|
+ * How long to delay outgoing messages for this peer.
|
|
|
*/
|
|
|
- struct GNUNET_PeerIdentity peer;
|
|
|
-
|
|
|
- struct PropManipulationEntry *head;
|
|
|
- struct PropManipulationEntry *tail;
|
|
|
+ struct GNUNET_TIME_Relative delay_out;
|
|
|
|
|
|
/**
|
|
|
- * Peer specific manipulation metrics
|
|
|
+ * Manipulated properties to use for this peer.
|
|
|
*/
|
|
|
- uint32_t metrics[TM_BOTH][GNUNET_ATS_QualityPropertiesCount];
|
|
|
+ struct GNUNET_ATS_Properties properties;
|
|
|
|
|
|
/**
|
|
|
* Task to schedule delayed sendding
|
|
|
*/
|
|
|
- struct GNUNET_SCHEDULER_Task * send_delay_task;
|
|
|
+ struct GNUNET_SCHEDULER_Task *send_delay_task;
|
|
|
|
|
|
/**
|
|
|
* Send queue DLL head
|
|
@@ -107,19 +77,6 @@ struct TM_Peer
|
|
|
};
|
|
|
|
|
|
|
|
|
-struct GST_ManipulationHandle
|
|
|
-{
|
|
|
- /**
|
|
|
- * Hashmap contain all peers currently manipulated
|
|
|
- */
|
|
|
- struct GNUNET_CONTAINER_MultiPeerMap *peers;
|
|
|
-
|
|
|
- /**
|
|
|
- * Peer containing information for general manipulation
|
|
|
- */
|
|
|
- struct TM_Peer general;
|
|
|
-};
|
|
|
-
|
|
|
/**
|
|
|
* Entry in the delay queue for an outbound delayed message
|
|
|
*/
|
|
@@ -136,9 +93,10 @@ struct DelayQueueEntry
|
|
|
struct DelayQueueEntry *next;
|
|
|
|
|
|
/**
|
|
|
- * Peer this entry is belonging to
|
|
|
- * if (NULL == tmp): enqueued in generic DLL and scheduled by generic_send_delay_task
|
|
|
- * else: enqueued in tmp->send_head and tmp->send_tail and scheduled by tmp->send_delay_task
|
|
|
+ * Peer this entry is belonging to if (NULL == tmp): enqueued in
|
|
|
+ * generic DLL and scheduled by generic_send_delay_task else:
|
|
|
+ * enqueued in tmp->send_head and tmp->send_tail and scheduled by
|
|
|
+ * tmp->send_delay_task
|
|
|
*/
|
|
|
struct TM_Peer *tmp;
|
|
|
|
|
@@ -178,91 +136,35 @@ struct DelayQueueEntry
|
|
|
void *cont_cls;
|
|
|
};
|
|
|
|
|
|
-struct GST_ManipulationHandle man_handle;
|
|
|
-
|
|
|
/**
|
|
|
- * DLL head for delayed messages based on general delay
|
|
|
+ * Hashmap contain all peers currently manipulated
|
|
|
*/
|
|
|
-struct DelayQueueEntry *generic_dqe_head;
|
|
|
+static struct GNUNET_CONTAINER_MultiPeerMap *peers;
|
|
|
|
|
|
/**
|
|
|
- * DLL tail for delayed messages based on general delay
|
|
|
+ * Inbound delay to apply to all peers.
|
|
|
*/
|
|
|
-struct DelayQueueEntry *generic_dqe_tail;
|
|
|
+static struct GNUNET_TIME_Relative delay_in;
|
|
|
|
|
|
/**
|
|
|
- * Task to schedule delayed sending based on general delay
|
|
|
+ * Outbound delay to apply to all peers.
|
|
|
*/
|
|
|
-struct GNUNET_SCHEDULER_Task * generic_send_delay_task;
|
|
|
-
|
|
|
-
|
|
|
-static void
|
|
|
-set_metric(struct TM_Peer *dest, int direction, uint32_t type, uint32_t value)
|
|
|
-{
|
|
|
- struct PropManipulationEntry *cur;
|
|
|
- for (cur = dest->head; NULL != cur; cur = cur->next)
|
|
|
- {
|
|
|
- if (cur->type == type)
|
|
|
- break;
|
|
|
- }
|
|
|
- if (NULL == cur)
|
|
|
- {
|
|
|
- cur = GNUNET_new (struct PropManipulationEntry);
|
|
|
- GNUNET_CONTAINER_DLL_insert(dest->head, dest->tail, cur);
|
|
|
- cur->type = type;
|
|
|
- cur->metrics[TM_SEND] = UINT32_MAX;
|
|
|
- cur->metrics[TM_RECEIVE] = UINT32_MAX;
|
|
|
- }
|
|
|
-
|
|
|
- switch (direction)
|
|
|
- {
|
|
|
- case TM_BOTH:
|
|
|
- cur->metrics[TM_SEND] = value;
|
|
|
- cur->metrics[TM_RECEIVE] = value;
|
|
|
- break;
|
|
|
- case TM_SEND:
|
|
|
- cur->metrics[TM_SEND] = value;
|
|
|
- break;
|
|
|
- case TM_RECEIVE:
|
|
|
- cur->metrics[TM_RECEIVE] = value;
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-static uint32_t
|
|
|
-find_metric(struct TM_Peer *dest, uint32_t type, int direction)
|
|
|
-{
|
|
|
- struct PropManipulationEntry *cur;
|
|
|
-
|
|
|
- for (cur = dest->head; NULL != cur; cur = cur->next)
|
|
|
- {
|
|
|
- if (cur->type == type)
|
|
|
- return cur->metrics[direction];
|
|
|
-
|
|
|
- }
|
|
|
- return UINT32_MAX;
|
|
|
-}
|
|
|
+static struct GNUNET_TIME_Relative delay_out;
|
|
|
|
|
|
+/**
|
|
|
+ * DLL head for delayed messages based on general delay
|
|
|
+ */
|
|
|
+static struct DelayQueueEntry *generic_dqe_head;
|
|
|
|
|
|
/**
|
|
|
- * Clean up metrics for a peer
|
|
|
+ * DLL tail for delayed messages based on general delay
|
|
|
*/
|
|
|
-static void
|
|
|
-free_metric(struct TM_Peer *dest)
|
|
|
-{
|
|
|
- struct PropManipulationEntry *cur;
|
|
|
- struct PropManipulationEntry *next;
|
|
|
+static struct DelayQueueEntry *generic_dqe_tail;
|
|
|
|
|
|
- for (cur = dest->head; NULL != cur; cur = next)
|
|
|
- {
|
|
|
- next = cur->next;
|
|
|
- GNUNET_CONTAINER_DLL_remove(dest->head, dest->tail, cur);
|
|
|
- GNUNET_free(cur);
|
|
|
- }
|
|
|
-}
|
|
|
+/**
|
|
|
+ * Task to schedule delayed sending based on general delay
|
|
|
+ */
|
|
|
+static struct GNUNET_SCHEDULER_Task *generic_send_delay_task;
|
|
|
|
|
|
|
|
|
/**
|
|
@@ -273,134 +175,106 @@ free_metric(struct TM_Peer *dest)
|
|
|
* @param message containing information
|
|
|
*/
|
|
|
void
|
|
|
-GST_manipulation_set_metric(void *cls, struct GNUNET_SERVER_Client *client,
|
|
|
- const struct GNUNET_MessageHeader *message)
|
|
|
+GST_manipulation_set_metric (void *cls,
|
|
|
+ struct GNUNET_SERVER_Client *client,
|
|
|
+ const struct GNUNET_MessageHeader *message)
|
|
|
{
|
|
|
- struct TrafficMetricMessage *tm = (struct TrafficMetricMessage *) message;
|
|
|
- struct GNUNET_PeerIdentity dummy;
|
|
|
- struct GNUNET_ATS_Information *ats;
|
|
|
+ const struct TrafficMetricMessage *tm;
|
|
|
+ static struct GNUNET_PeerIdentity zero;
|
|
|
struct TM_Peer *tmp;
|
|
|
- uint32_t type;
|
|
|
- uint32_t value;
|
|
|
- uint16_t direction;
|
|
|
- int c;
|
|
|
- int c2;
|
|
|
-
|
|
|
- if (0 == ntohs(tm->ats_count))
|
|
|
- GNUNET_SERVER_receive_done(client, GNUNET_SYSERR);
|
|
|
-
|
|
|
- direction = TM_BOTH;
|
|
|
- switch (ntohs(tm->direction))
|
|
|
- {
|
|
|
- case 1:
|
|
|
- direction = TM_SEND;
|
|
|
- break;
|
|
|
- case 2:
|
|
|
- direction = TM_RECEIVE;
|
|
|
- break;
|
|
|
- case 3:
|
|
|
- direction = TM_BOTH;
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- memset(&dummy, '\0', sizeof(struct GNUNET_PeerIdentity));
|
|
|
- if (0 == memcmp(&tm->peer, &dummy, sizeof(struct GNUNET_PeerIdentity)))
|
|
|
- {
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
|
|
|
- "Received traffic metrics for all peers \n");
|
|
|
-
|
|
|
- ats = (struct GNUNET_ATS_Information *) &tm[1];
|
|
|
- for (c = 0; c < ntohs(tm->ats_count); c++)
|
|
|
- {
|
|
|
- type = htonl(ats[c].type);
|
|
|
- value = htonl(ats[c].value);
|
|
|
- set_metric(&man_handle.general, direction, type, value);
|
|
|
- }
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
|
|
|
- "Received traffic metrics for peer `%s'\n", GNUNET_i2s(&tm->peer));
|
|
|
-
|
|
|
- if (NULL
|
|
|
- == (tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, &tm->peer)))
|
|
|
- {
|
|
|
- tmp = GNUNET_new (struct TM_Peer);
|
|
|
- tmp->peer = (tm->peer);
|
|
|
- for (c = 0; c < TM_BOTH; c++)
|
|
|
- {
|
|
|
- for (c2 = 0; c2 < GNUNET_ATS_QualityPropertiesCount; c2++)
|
|
|
- {
|
|
|
- tmp->metrics[c][c2] = UINT32_MAX;
|
|
|
- }
|
|
|
- }
|
|
|
- GNUNET_CONTAINER_multipeermap_put(man_handle.peers, &tm->peer, tmp,
|
|
|
- GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
|
|
|
- }
|
|
|
|
|
|
- ats = (struct GNUNET_ATS_Information *) &tm[1];
|
|
|
- for (c = 0; c < ntohs(tm->ats_count); c++)
|
|
|
- {
|
|
|
- type = htonl(ats[c].type);
|
|
|
- value = htonl(ats[c].value);
|
|
|
- set_metric(tmp, direction, type, value);
|
|
|
- }
|
|
|
-
|
|
|
- GNUNET_SERVER_receive_done(client, GNUNET_OK);
|
|
|
+ tm = (const struct TrafficMetricMessage *) message;
|
|
|
+ if (0 == memcmp (&tm->peer,
|
|
|
+ &zero,
|
|
|
+ sizeof(struct GNUNET_PeerIdentity)))
|
|
|
+ {
|
|
|
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
|
|
+ "Received traffic metrics for all peers\n");
|
|
|
+ delay_in = GNUNET_TIME_relative_ntoh (tm->delay_in);
|
|
|
+ delay_out = GNUNET_TIME_relative_ntoh (tm->delay_out);
|
|
|
+ GNUNET_SERVER_receive_done (client,
|
|
|
+ GNUNET_OK);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
|
|
+ "Received traffic metrics for peer `%s'\n",
|
|
|
+ GNUNET_i2s(&tm->peer));
|
|
|
+ if (NULL ==
|
|
|
+ (tmp = GNUNET_CONTAINER_multipeermap_get (peers,
|
|
|
+ &tm->peer)))
|
|
|
+ {
|
|
|
+ tmp = GNUNET_new (struct TM_Peer);
|
|
|
+ tmp->peer = tm->peer;
|
|
|
+ GNUNET_CONTAINER_multipeermap_put (peers,
|
|
|
+ &tm->peer,
|
|
|
+ tmp,
|
|
|
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
|
|
|
+ }
|
|
|
+ GNUNET_ATS_properties_ntoh (&tmp->properties,
|
|
|
+ &tm->properties);
|
|
|
+ tmp->delay_in = GNUNET_TIME_relative_ntoh (tm->delay_in);
|
|
|
+ tmp->delay_out = GNUNET_TIME_relative_ntoh (tm->delay_out);
|
|
|
+ GNUNET_SERVER_receive_done (client,
|
|
|
+ GNUNET_OK);
|
|
|
}
|
|
|
|
|
|
|
|
|
+/**
|
|
|
+ * We have delayed transmission, now it is time to send the
|
|
|
+ * message.
|
|
|
+ *
|
|
|
+ * @param cls the `struct DelayQueueEntry` to transmit
|
|
|
+ * @param tc unused
|
|
|
+ */
|
|
|
static void
|
|
|
-send_delayed(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
|
|
|
+send_delayed (void *cls,
|
|
|
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
|
|
|
{
|
|
|
struct DelayQueueEntry *dqe = cls;
|
|
|
struct DelayQueueEntry *next;
|
|
|
struct TM_Peer *tmp = dqe->tmp;
|
|
|
struct GNUNET_TIME_Relative delay;
|
|
|
|
|
|
+ GNUNET_break (GNUNET_YES ==
|
|
|
+ GST_neighbours_test_connected (&dqe->id));
|
|
|
if (NULL != tmp)
|
|
|
+ {
|
|
|
+ tmp->send_delay_task = NULL;
|
|
|
+ GNUNET_CONTAINER_DLL_remove (tmp->send_head,
|
|
|
+ tmp->send_tail,
|
|
|
+ dqe);
|
|
|
+ next = tmp->send_head;
|
|
|
+ if (NULL != next)
|
|
|
{
|
|
|
- GNUNET_break (GNUNET_YES ==
|
|
|
- GST_neighbours_test_connected (&dqe->id));
|
|
|
- tmp->send_delay_task = NULL;
|
|
|
- GNUNET_CONTAINER_DLL_remove (tmp->send_head,
|
|
|
- tmp->send_tail,
|
|
|
- dqe);
|
|
|
- GST_neighbours_send (&dqe->id,
|
|
|
- dqe->msg,
|
|
|
- dqe->msg_size,
|
|
|
- dqe->timeout,
|
|
|
- dqe->cont,
|
|
|
- dqe->cont_cls);
|
|
|
-
|
|
|
- next = tmp->send_head;
|
|
|
- if (NULL != next)
|
|
|
- {
|
|
|
- /* More delayed messages */
|
|
|
- delay = GNUNET_TIME_absolute_get_remaining(next->sent_at);
|
|
|
- tmp->send_delay_task = GNUNET_SCHEDULER_add_delayed(delay,
|
|
|
- &send_delayed, next);
|
|
|
- }
|
|
|
+ /* More delayed messages */
|
|
|
+ delay = GNUNET_TIME_absolute_get_remaining(next->sent_at);
|
|
|
+ tmp->send_delay_task = GNUNET_SCHEDULER_add_delayed(delay,
|
|
|
+ &send_delayed, next);
|
|
|
}
|
|
|
+ }
|
|
|
else
|
|
|
+ {
|
|
|
+ /* Remove from generic queue */
|
|
|
+ generic_send_delay_task = NULL;
|
|
|
+ GNUNET_CONTAINER_DLL_remove (generic_dqe_head,
|
|
|
+ generic_dqe_tail,
|
|
|
+ dqe);
|
|
|
+ next = generic_dqe_head;
|
|
|
+ if (NULL != next)
|
|
|
{
|
|
|
- /* Remove from generic queue */
|
|
|
- GNUNET_break(GNUNET_YES == GST_neighbours_test_connected (&dqe->id));
|
|
|
- generic_send_delay_task = NULL;
|
|
|
- GNUNET_CONTAINER_DLL_remove(generic_dqe_head, generic_dqe_tail, dqe);
|
|
|
- GST_neighbours_send(&dqe->id, dqe->msg, dqe->msg_size, dqe->timeout,
|
|
|
- dqe->cont, dqe->cont_cls);
|
|
|
- next = generic_dqe_head;
|
|
|
- if (NULL != next)
|
|
|
- {
|
|
|
- /* More delayed messages */
|
|
|
- delay = GNUNET_TIME_absolute_get_remaining(next->sent_at);
|
|
|
- generic_send_delay_task = GNUNET_SCHEDULER_add_delayed(delay,
|
|
|
- &send_delayed, next);
|
|
|
- }
|
|
|
+ /* More delayed messages */
|
|
|
+ delay = GNUNET_TIME_absolute_get_remaining(next->sent_at);
|
|
|
+ generic_send_delay_task = GNUNET_SCHEDULER_add_delayed (delay,
|
|
|
+ &send_delayed,
|
|
|
+ next);
|
|
|
}
|
|
|
+ }
|
|
|
+ GST_neighbours_send (&dqe->id,
|
|
|
+ dqe->msg,
|
|
|
+ dqe->msg_size,
|
|
|
+ dqe->timeout,
|
|
|
+ dqe->cont,
|
|
|
+ dqe->cont_cls);
|
|
|
GNUNET_free(dqe);
|
|
|
}
|
|
|
|
|
@@ -427,41 +301,14 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target,
|
|
|
struct TM_Peer *tmp;
|
|
|
struct DelayQueueEntry *dqe;
|
|
|
struct GNUNET_TIME_Relative delay;
|
|
|
- int do_delay;
|
|
|
|
|
|
- do_delay = GNUNET_NO;
|
|
|
if (NULL != (tmp =
|
|
|
- GNUNET_CONTAINER_multipeermap_get (man_handle.peers,
|
|
|
+ GNUNET_CONTAINER_multipeermap_get (peers,
|
|
|
target)))
|
|
|
- {
|
|
|
- GNUNET_break (GNUNET_YES ==
|
|
|
- GST_neighbours_test_connected(target));
|
|
|
- /* check for peer-specific delay */
|
|
|
- if (UINT32_MAX !=
|
|
|
- find_metric (tmp,
|
|
|
- GNUNET_ATS_QUALITY_NET_DELAY,
|
|
|
- TM_SEND))
|
|
|
- {
|
|
|
- /* We have a delay */
|
|
|
- delay.rel_value_us = find_metric(tmp, GNUNET_ATS_QUALITY_NET_DELAY,
|
|
|
- TM_SEND);
|
|
|
- do_delay = GNUNET_YES;
|
|
|
- }
|
|
|
- }
|
|
|
- else if (UINT32_MAX !=
|
|
|
- find_metric(&man_handle.general,
|
|
|
- GNUNET_ATS_QUALITY_NET_DELAY,
|
|
|
- TM_SEND))
|
|
|
- {
|
|
|
- GNUNET_break (GNUNET_YES ==
|
|
|
- GST_neighbours_test_connected (target));
|
|
|
- /* We have a delay */
|
|
|
- delay.rel_value_us = find_metric (&man_handle.general,
|
|
|
- GNUNET_ATS_QUALITY_NET_DELAY,
|
|
|
- TM_SEND);
|
|
|
- do_delay = GNUNET_YES;
|
|
|
- }
|
|
|
- if (GNUNET_NO == do_delay)
|
|
|
+ delay = tmp->delay_out;
|
|
|
+ else
|
|
|
+ delay = delay_out;
|
|
|
+ if (0 == delay.rel_value_us)
|
|
|
{
|
|
|
/* Normal sending */
|
|
|
GST_neighbours_send (target,
|
|
@@ -516,46 +363,22 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target,
|
|
|
* Function that will be called to manipulate ATS information according to
|
|
|
* current manipulation settings
|
|
|
*
|
|
|
- * @param peer the peer
|
|
|
* @param address binary address
|
|
|
* @param session the session
|
|
|
- * @param ats the ats information
|
|
|
- * @param ats_count the number of ats information
|
|
|
+ * @param prop[IN|OUT] metrics to modify
|
|
|
*/
|
|
|
-struct GNUNET_ATS_Information *
|
|
|
+void
|
|
|
GST_manipulation_manipulate_metrics (const struct GNUNET_HELLO_Address *address,
|
|
|
struct Session *session,
|
|
|
- const struct GNUNET_ATS_Information *ats,
|
|
|
- uint32_t ats_count)
|
|
|
+ struct GNUNET_ATS_Properties *prop)
|
|
|
{
|
|
|
const struct GNUNET_PeerIdentity *peer = &address->peer;
|
|
|
- struct GNUNET_ATS_Information *ats_new;
|
|
|
struct TM_Peer *tmp;
|
|
|
- uint32_t m_tmp;
|
|
|
- uint32_t g_tmp;
|
|
|
- uint32_t d;
|
|
|
-
|
|
|
- if (0 == ats_count)
|
|
|
- return NULL;
|
|
|
- ats_new = GNUNET_malloc (sizeof (struct GNUNET_ATS_Information) * ats_count);
|
|
|
- tmp = GNUNET_CONTAINER_multipeermap_get (man_handle.peers, peer);
|
|
|
- for (d = 0; d < ats_count; d++)
|
|
|
- {
|
|
|
- ats_new[d] = ats[d];
|
|
|
- m_tmp = UINT32_MAX;
|
|
|
- if (NULL != tmp)
|
|
|
- m_tmp = find_metric (tmp, ntohl(ats[d].type),
|
|
|
- TM_RECEIVE);
|
|
|
- g_tmp = find_metric (&man_handle.general,
|
|
|
- ntohl(ats[d].type),
|
|
|
- TM_RECEIVE);
|
|
|
-
|
|
|
- if (UINT32_MAX != g_tmp)
|
|
|
- ats_new[d].value = htonl(g_tmp);
|
|
|
- if (UINT32_MAX != m_tmp)
|
|
|
- ats_new[d].value = htonl(m_tmp);
|
|
|
- }
|
|
|
- return ats_new;
|
|
|
+
|
|
|
+ tmp = GNUNET_CONTAINER_multipeermap_get (peers,
|
|
|
+ peer);
|
|
|
+ if (NULL != tmp)
|
|
|
+ *prop = tmp->properties;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -576,32 +399,22 @@ GST_manipulation_recv (void *cls,
|
|
|
const struct GNUNET_MessageHeader *message)
|
|
|
{
|
|
|
struct TM_Peer *tmp;
|
|
|
- uint32_t p_recv_delay;
|
|
|
- uint32_t g_recv_delay;
|
|
|
struct GNUNET_TIME_Relative quota_delay;
|
|
|
struct GNUNET_TIME_Relative m_delay;
|
|
|
|
|
|
- g_recv_delay = find_metric(&man_handle.general, GNUNET_ATS_QUALITY_NET_DELAY,
|
|
|
- TM_RECEIVE);
|
|
|
- if ((g_recv_delay >= GNUNET_TIME_UNIT_ZERO.rel_value_us)
|
|
|
- && (UINT32_MAX != g_recv_delay))
|
|
|
- m_delay.rel_value_us = g_recv_delay; /* Global delay */
|
|
|
+ if (NULL !=
|
|
|
+ (tmp = GNUNET_CONTAINER_multipeermap_get (peers,
|
|
|
+ &address->peer)))
|
|
|
+ m_delay = tmp->delay_in;
|
|
|
else
|
|
|
- m_delay = GNUNET_TIME_UNIT_ZERO;
|
|
|
-
|
|
|
- if (NULL != (tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, &address->peer)))
|
|
|
- {
|
|
|
- /* Manipulate receive delay */
|
|
|
- p_recv_delay = find_metric(tmp, GNUNET_ATS_QUALITY_NET_DELAY, TM_RECEIVE);
|
|
|
- if (UINT32_MAX != p_recv_delay)
|
|
|
- m_delay.rel_value_us = p_recv_delay; /* Peer specific delay */
|
|
|
- }
|
|
|
-
|
|
|
- quota_delay = GST_receive_callback(cls, address, session, message);
|
|
|
-
|
|
|
- if (quota_delay.rel_value_us > m_delay.rel_value_us)
|
|
|
- m_delay = quota_delay;
|
|
|
-
|
|
|
+ m_delay = delay_in;
|
|
|
+
|
|
|
+ quota_delay = GST_receive_callback (cls,
|
|
|
+ address,
|
|
|
+ session,
|
|
|
+ message);
|
|
|
+ m_delay = GNUNET_TIME_relative_max (m_delay,
|
|
|
+ quota_delay);
|
|
|
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
|
|
|
"Delaying next receive for peer `%s' for %s\n",
|
|
|
GNUNET_i2s (&address->peer),
|
|
@@ -613,63 +426,110 @@ GST_manipulation_recv (void *cls,
|
|
|
|
|
|
/**
|
|
|
* Initialize traffic manipulation
|
|
|
- *
|
|
|
- * @param GST_cfg configuration handle
|
|
|
*/
|
|
|
void
|
|
|
-GST_manipulation_init(const struct GNUNET_CONFIGURATION_Handle *GST_cfg)
|
|
|
+GST_manipulation_init ()
|
|
|
{
|
|
|
- unsigned long long tmp;
|
|
|
struct GNUNET_TIME_Relative delay;
|
|
|
|
|
|
if ( (GNUNET_OK ==
|
|
|
- GNUNET_CONFIGURATION_get_value_number(GST_cfg,
|
|
|
- "transport",
|
|
|
- "MANIPULATE_DISTANCE_IN",
|
|
|
- &tmp)) &&
|
|
|
- (tmp > 0) )
|
|
|
+ GNUNET_CONFIGURATION_get_value_time (GST_cfg,
|
|
|
+ "transport",
|
|
|
+ "MANIPULATE_DELAY_IN",
|
|
|
+ &delay)) &&
|
|
|
+ (delay.rel_value_us > 0) )
|
|
|
{
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_INFO,
|
|
|
- "Setting inbound distance_in to %llu\n",
|
|
|
- (unsigned long long) tmp);
|
|
|
- set_metric (&man_handle.general,
|
|
|
- TM_RECEIVE,
|
|
|
- GNUNET_ATS_QUALITY_NET_DISTANCE,
|
|
|
- tmp);
|
|
|
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
|
|
+ "Delaying inbound traffic for %s\n",
|
|
|
+ GNUNET_STRINGS_relative_time_to_string (delay,
|
|
|
+ GNUNET_YES));
|
|
|
+ delay_in = delay;
|
|
|
}
|
|
|
+ if ( (GNUNET_OK ==
|
|
|
+ GNUNET_CONFIGURATION_get_value_time (GST_cfg,
|
|
|
+ "transport",
|
|
|
+ "MANIPULATE_DELAY_OUT",
|
|
|
+ &delay)) &&
|
|
|
+ (delay.rel_value_us > 0) )
|
|
|
+ {
|
|
|
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
|
|
|
+ "Delaying outbound traffic for %s\n",
|
|
|
+ GNUNET_STRINGS_relative_time_to_string (delay,
|
|
|
+ GNUNET_YES));
|
|
|
+ delay_out = delay;
|
|
|
+ }
|
|
|
+ peers = GNUNET_CONTAINER_multipeermap_create (4,
|
|
|
+ GNUNET_NO);
|
|
|
+}
|
|
|
|
|
|
- if ((GNUNET_OK
|
|
|
- == GNUNET_CONFIGURATION_get_value_number(GST_cfg, "transport",
|
|
|
- "MANIPULATE_DISTANCE_OUT", &tmp)) && (tmp > 0))
|
|
|
- {
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_INFO,
|
|
|
- "Setting outbound distance_in to %llu\n", (unsigned long long) tmp);
|
|
|
- set_metric(&man_handle.general, TM_SEND, GNUNET_ATS_QUALITY_NET_DISTANCE,
|
|
|
- tmp);
|
|
|
- }
|
|
|
|
|
|
- if ((GNUNET_OK
|
|
|
- == GNUNET_CONFIGURATION_get_value_time(GST_cfg, "transport",
|
|
|
- "MANIPULATE_DELAY_IN", &delay)) && (delay.rel_value_us > 0))
|
|
|
+/**
|
|
|
+ * Notify manipulation about disconnect so it can discard queued messages
|
|
|
+ *
|
|
|
+ * @param peer the disconnecting peer
|
|
|
+ */
|
|
|
+void
|
|
|
+GST_manipulation_peer_disconnect (const struct GNUNET_PeerIdentity *peer)
|
|
|
+{
|
|
|
+ struct TM_Peer *tmp;
|
|
|
+ struct DelayQueueEntry *dqe;
|
|
|
+ struct DelayQueueEntry *next;
|
|
|
+
|
|
|
+ tmp = GNUNET_CONTAINER_multipeermap_get (peers,
|
|
|
+ peer);
|
|
|
+ if (NULL != tmp)
|
|
|
+ {
|
|
|
+ while (NULL != (dqe = tmp->send_head))
|
|
|
{
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_INFO,
|
|
|
- "Delaying inbound traffic for %s\n", GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES));
|
|
|
- set_metric(&man_handle.general, TM_RECEIVE, GNUNET_ATS_QUALITY_NET_DELAY,
|
|
|
- delay.rel_value_us);
|
|
|
+ GNUNET_CONTAINER_DLL_remove (tmp->send_head,
|
|
|
+ tmp->send_tail,
|
|
|
+ dqe);
|
|
|
+ if (NULL != dqe->cont)
|
|
|
+ dqe->cont (dqe->cont_cls,
|
|
|
+ GNUNET_SYSERR,
|
|
|
+ dqe->msg_size,
|
|
|
+ 0);
|
|
|
+ GNUNET_free(dqe);
|
|
|
}
|
|
|
- if ((GNUNET_OK
|
|
|
- == GNUNET_CONFIGURATION_get_value_time(GST_cfg, "transport",
|
|
|
- "MANIPULATE_DELAY_OUT", &delay)) && (delay.rel_value_us > 0))
|
|
|
+ }
|
|
|
+ next = generic_dqe_head;
|
|
|
+ while (NULL != (dqe = next))
|
|
|
+ {
|
|
|
+ next = dqe->next;
|
|
|
+ if (0 == memcmp(peer, &dqe->id, sizeof(dqe->id)))
|
|
|
{
|
|
|
- GNUNET_log(GNUNET_ERROR_TYPE_INFO,
|
|
|
- "Delaying outbound traffic for %s\n", GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES));
|
|
|
- set_metric(&man_handle.general, TM_SEND, GNUNET_ATS_QUALITY_NET_DELAY,
|
|
|
- delay.rel_value_us);
|
|
|
+ GNUNET_CONTAINER_DLL_remove (generic_dqe_head,
|
|
|
+ generic_dqe_tail,
|
|
|
+ dqe);
|
|
|
+ if (NULL != dqe->cont)
|
|
|
+ dqe->cont (dqe->cont_cls,
|
|
|
+ GNUNET_SYSERR,
|
|
|
+ dqe->msg_size,
|
|
|
+ 0);
|
|
|
+ GNUNET_free(dqe);
|
|
|
}
|
|
|
- man_handle.peers = GNUNET_CONTAINER_multipeermap_create(10, GNUNET_NO);
|
|
|
+ }
|
|
|
+ if (NULL != generic_send_delay_task)
|
|
|
+ {
|
|
|
+ GNUNET_SCHEDULER_cancel (generic_send_delay_task);
|
|
|
+ generic_send_delay_task = NULL;
|
|
|
+ if (NULL != generic_dqe_head)
|
|
|
+ generic_send_delay_task
|
|
|
+ = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining(generic_dqe_head->sent_at),
|
|
|
+ &send_delayed,
|
|
|
+ generic_dqe_head);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
|
+/**
|
|
|
+ * Free manipulation information about a peer.
|
|
|
+ *
|
|
|
+ * @param cls NULL
|
|
|
+ * @param key peer the info is about
|
|
|
+ * @param value a `struct TM_Peer` to free
|
|
|
+ * @return #GNUNET_OK (continue to iterate)
|
|
|
+ */
|
|
|
static int
|
|
|
free_tmps (void *cls,
|
|
|
const struct GNUNET_PeerIdentity *key,
|
|
@@ -678,13 +538,10 @@ free_tmps (void *cls,
|
|
|
struct TM_Peer *tmp = value;
|
|
|
struct DelayQueueEntry *dqe;
|
|
|
|
|
|
- if (NULL == tmp)
|
|
|
- return GNUNET_OK;
|
|
|
GNUNET_break (GNUNET_YES ==
|
|
|
- GNUNET_CONTAINER_multipeermap_remove (man_handle.peers,
|
|
|
+ GNUNET_CONTAINER_multipeermap_remove (peers,
|
|
|
key,
|
|
|
value));
|
|
|
- free_metric (tmp);
|
|
|
while (NULL != (dqe = tmp->send_head))
|
|
|
{
|
|
|
GNUNET_CONTAINER_DLL_remove (tmp->send_head,
|
|
@@ -699,89 +556,27 @@ free_tmps (void *cls,
|
|
|
}
|
|
|
if (NULL != tmp->send_delay_task)
|
|
|
{
|
|
|
- GNUNET_SCHEDULER_cancel(tmp->send_delay_task);
|
|
|
+ GNUNET_SCHEDULER_cancel (tmp->send_delay_task);
|
|
|
tmp->send_delay_task = NULL;
|
|
|
}
|
|
|
- GNUNET_free(tmp);
|
|
|
+ GNUNET_free (tmp);
|
|
|
return GNUNET_OK;
|
|
|
}
|
|
|
|
|
|
|
|
|
-/**
|
|
|
- * Notify manipulation about disconnect so it can discard queued messages
|
|
|
- *
|
|
|
- * @param peer the disconnecting peer
|
|
|
- */
|
|
|
-void
|
|
|
-GST_manipulation_peer_disconnect (const struct GNUNET_PeerIdentity *peer)
|
|
|
-{
|
|
|
- struct TM_Peer *tmp;
|
|
|
- struct DelayQueueEntry *dqe;
|
|
|
- struct DelayQueueEntry *next;
|
|
|
-
|
|
|
- if (NULL != (tmp = GNUNET_CONTAINER_multipeermap_get(man_handle.peers, peer)))
|
|
|
- {
|
|
|
- while (NULL != (dqe = tmp->send_head))
|
|
|
- {
|
|
|
- GNUNET_CONTAINER_DLL_remove (tmp->send_head,
|
|
|
- tmp->send_tail,
|
|
|
- dqe);
|
|
|
- if (NULL != dqe->cont)
|
|
|
- dqe->cont (dqe->cont_cls,
|
|
|
- GNUNET_SYSERR,
|
|
|
- dqe->msg_size,
|
|
|
- 0);
|
|
|
- GNUNET_free(dqe);
|
|
|
- }
|
|
|
- }
|
|
|
- else if (UINT32_MAX != find_metric (&man_handle.general,
|
|
|
- GNUNET_ATS_QUALITY_NET_DELAY,
|
|
|
- TM_SEND))
|
|
|
- {
|
|
|
- next = generic_dqe_head;
|
|
|
- while (NULL != (dqe = next))
|
|
|
- {
|
|
|
- next = dqe->next;
|
|
|
- if (0 == memcmp(peer, &dqe->id, sizeof(dqe->id)))
|
|
|
- {
|
|
|
- GNUNET_CONTAINER_DLL_remove (generic_dqe_head,
|
|
|
- generic_dqe_tail,
|
|
|
- dqe);
|
|
|
- if (NULL != dqe->cont)
|
|
|
- dqe->cont (dqe->cont_cls,
|
|
|
- GNUNET_SYSERR,
|
|
|
- dqe->msg_size,
|
|
|
- 0);
|
|
|
- GNUNET_free(dqe);
|
|
|
- }
|
|
|
- }
|
|
|
- if (NULL != generic_send_delay_task)
|
|
|
- {
|
|
|
- GNUNET_SCHEDULER_cancel (generic_send_delay_task);
|
|
|
- generic_send_delay_task = NULL;
|
|
|
- if (NULL != generic_dqe_head)
|
|
|
- generic_send_delay_task
|
|
|
- = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining(generic_dqe_head->sent_at),
|
|
|
- &send_delayed,
|
|
|
- generic_dqe_head);
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
/**
|
|
|
* Stop traffic manipulation
|
|
|
*/
|
|
|
void
|
|
|
-GST_manipulation_stop()
|
|
|
+GST_manipulation_stop ()
|
|
|
{
|
|
|
struct DelayQueueEntry *cur;
|
|
|
|
|
|
- GNUNET_CONTAINER_multipeermap_iterate (man_handle.peers,
|
|
|
+ GNUNET_CONTAINER_multipeermap_iterate (peers,
|
|
|
&free_tmps,
|
|
|
NULL);
|
|
|
- GNUNET_CONTAINER_multipeermap_destroy (man_handle.peers);
|
|
|
-
|
|
|
+ GNUNET_CONTAINER_multipeermap_destroy (peers);
|
|
|
+ peers = NULL;
|
|
|
while (NULL != (cur = generic_dqe_head))
|
|
|
{
|
|
|
GNUNET_CONTAINER_DLL_remove (generic_dqe_head,
|
|
@@ -799,8 +594,6 @@ GST_manipulation_stop()
|
|
|
GNUNET_SCHEDULER_cancel (generic_send_delay_task);
|
|
|
generic_send_delay_task = NULL;
|
|
|
}
|
|
|
- free_metric (&man_handle.general);
|
|
|
- man_handle.peers = NULL;
|
|
|
}
|
|
|
|
|
|
/* end of file gnunet-service-transport_manipulation.c */
|