- fix
[oweals/gnunet.git] / src / transport / gnunet-service-transport_manipulation.c
index 5e52799df54c75cc83fe65421a6dd18d24096c94..c034569032a960be1d04b94089a0546561123872 100644 (file)
 #define DELAY 0
 #define DISTANCE 1
 
+
+enum TRAFFIC_METRIC_DIRECTION
+{
+       TM_SEND = 0,
+       TM_RECEIVE = 1,
+       TM_BOTH = 2
+};
+
 struct GST_ManipulationHandle man_handle;
 
 
@@ -47,12 +55,22 @@ struct GST_ManipulationHandle
        /**
         * General inbound delay
         */
-       struct GNUNET_TIME_Relative delay_in;
+       struct GNUNET_TIME_Relative delay_recv;
 
        /**
         * General outbound delay
         */
-       struct GNUNET_TIME_Relative delay_out;
+       struct GNUNET_TIME_Relative delay_send;
+
+       /**
+        * General inbound distance
+        */
+        unsigned long long  distance_recv;
+
+       /**
+        * General outbound distance
+        */
+        unsigned long long distance_send;
 
 };
 
@@ -153,16 +171,64 @@ 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;
        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);
 
+       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);
+
+                                       switch (type) {
+                                               case GNUNET_ATS_QUALITY_NET_DELAY:
+                                                       if ((TM_RECEIVE == direction) || (TM_BOTH == direction))
+                                                                       man_handle.delay_recv.rel_value = value;
+                                                       if ((TM_SEND == direction) || (TM_BOTH == direction))
+                                                                       man_handle.delay_send.rel_value = value;
+                                                       break;
+                                               case GNUNET_ATS_QUALITY_NET_DISTANCE:
+                                                       if ((TM_RECEIVE == direction) || (TM_BOTH == direction))
+                                                                       man_handle.distance_recv = value;
+                                                       if ((TM_SEND == direction) || (TM_BOTH == direction))
+                                                                       man_handle.distance_send = value;
+                                                       break;
+                                               default:
+                                                       break;
+                                       }
+
+                       }
+                       return;
+       }
+
        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received traffic metrics for peer `%s'\n",
                        GNUNET_i2s(&tm->peer));
 
@@ -187,10 +253,10 @@ GST_manipulation_set_metric (void *cls, struct GNUNET_SERVER_Client *client,
                        value = htonl (ats[c].value);
                        switch (type) {
                                case GNUNET_ATS_QUALITY_NET_DELAY:
-                                       set_delay (tmp, &tm->peer, ntohs (tm->direction), value);
+                                       set_delay (tmp, &tm->peer, direction, value);
                                        break;
                                case GNUNET_ATS_QUALITY_NET_DISTANCE:
-                                       set_distance (tmp, &tm->peer, ntohs (tm->direction), value);
+                                       set_distance (tmp, &tm->peer, direction, value);
                                        break;
                                default:
                                        break;
@@ -254,10 +320,10 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target, const void *msg
                                        return;
                        }
        }
-       else if (man_handle.delay_out.rel_value != 0)
+       else if (man_handle.delay_send.rel_value != 0)
        {
                        /* We have a delay */
-                       delay = man_handle.delay_out;
+                       delay = man_handle.delay_send;
                        dqe = GNUNET_malloc (sizeof (struct DelayQueueEntry) + msg_size);
                        dqe->tmp = tmp;
                        dqe->sent_at = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), delay);
@@ -278,29 +344,37 @@ GST_manipulation_send (const struct GNUNET_PeerIdentity *target, const void *msg
 }
 
 struct GNUNET_TIME_Relative
-GST_manipulation_recv (void *cls, const struct GNUNET_PeerIdentity *peer,
+GST_manipulation_recv (void *cls,
+               const struct GNUNET_PeerIdentity *peer,
     const struct GNUNET_MessageHeader *message,
-    const struct GNUNET_ATS_Information *ats,
-    uint32_t ats_count, struct Session *session,
+    struct Session *session,
     const char *sender_address,
     uint16_t sender_address_len)
 {
        struct TM_Peer *tmp;
-       int d;
-       struct GNUNET_ATS_Information ats_new[ats_count];
+       //int d;
+       //struct GNUNET_ATS_Information ats_new[ats_count];
        struct GNUNET_TIME_Relative quota_delay;
        struct GNUNET_TIME_Relative m_delay;
 
-       if (man_handle.delay_in.rel_value > GNUNET_TIME_UNIT_ZERO.rel_value)
-               m_delay = man_handle.delay_in; /* Global delay */
+       if (man_handle.delay_recv.rel_value > GNUNET_TIME_UNIT_ZERO.rel_value)
+               m_delay = man_handle.delay_recv; /* Global delay */
        else
                m_delay = GNUNET_TIME_UNIT_ZERO;
 
+#if 0
        for (d = 0; d < ats_count; d++)
+       {
                ats_new[d] = ats[d];
+               if ((ntohl(ats[d].type) == GNUNET_ATS_QUALITY_NET_DISTANCE) &&
+                               (man_handle.distance_recv > 0))
+                       ats_new[d].value = htonl(man_handle.distance_recv); /* Global inbound distance */
+       }
+#endif
 
        if (NULL != (tmp = GNUNET_CONTAINER_multihashmap_get (man_handle.peers, &peer->hashPubKey)))
        {
+#if 0
                        /* Manipulate distance */
                        for (d = 0; d < ats_count; d++)
                        {
@@ -310,36 +384,52 @@ GST_manipulation_recv (void *cls, const struct GNUNET_PeerIdentity *peer,
                                                 (UINT32_MAX != tmp->metrics[TM_RECEIVE][DISTANCE]))
                                                        ats_new[d].value = htonl(tmp->metrics[TM_RECEIVE][DISTANCE]);
                        }
+#endif
                        /* Manipulate receive delay */
                        if (UINT32_MAX != tmp->metrics[TM_RECEIVE][DELAY])
                                        m_delay.rel_value = tmp->metrics[TM_RECEIVE][DELAY]; /* Peer specific delay */
        }
 
-       quota_delay = GST_receive_callback (cls, peer, message, ats_new, ats_count,
+       quota_delay = GST_receive_callback (cls, peer, message,
                        session, sender_address, sender_address_len);
        if (quota_delay.rel_value > m_delay.rel_value)
                return quota_delay;
        else
                return m_delay;
+
 }
 
 void
 GST_manipulation_init (const struct GNUNET_CONFIGURATION_Handle *GST_cfg)
 {
 
+       if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (GST_cfg,
+                       "transport", "MANIPULATE_DISTANCE_IN", &man_handle.distance_recv))
+               GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Setting inbound distance_in to %u\n",
+                               (unsigned long long) man_handle.distance_recv);
+       else
+               man_handle.distance_recv = 0;
+
+       if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (GST_cfg,
+                       "transport", "MANIPULATE_DISTANCE_OUT", &man_handle.distance_send))
+               GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Setting outbound distance_in to %u\n",
+                               (unsigned long long) man_handle.distance_send);
+       else
+               man_handle.distance_send = 0;
+
        if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (GST_cfg,
-                       "transport", "MANIPULATE_DELAY_IN", &man_handle.delay_in))
+                       "transport", "MANIPULATE_DELAY_IN", &man_handle.delay_recv))
                GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Delaying inbound traffic for %llu ms\n",
-                               (unsigned long long) man_handle.delay_in.rel_value);
+                               (unsigned long long) man_handle.delay_recv.rel_value);
        else
-               man_handle.delay_in.rel_value = 0;
+               man_handle.delay_recv.rel_value = 0;
 
        if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (GST_cfg,
-                       "transport", "MANIPULATE_DELAY_OUT", &man_handle.delay_out))
+                       "transport", "MANIPULATE_DELAY_OUT", &man_handle.delay_send))
                GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Delaying outbound traffic for %llu ms\n",
-                       (unsigned long long) man_handle.delay_out.rel_value);
+                       (unsigned long long) man_handle.delay_send.rel_value);
        else
-               man_handle.delay_out.rel_value = 0;
+               man_handle.delay_send.rel_value = 0;
 
        man_handle.peers = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
 }