/**
 * Callback method used with libcurl
 * Method is called when libcurl needs to write data during sending
 *
 * @param stream pointer where to write data
 * @param size size of an individual element
 * @param nmemb count of elements that can be written to the buffer
 * @param cls destination pointer, passed to the libcurl handle
 * @return bytes read from stream
 */
static size_t
client_receive (void *stream, size_t size, size_t nmemb, void *cls)
{
  struct Session *s = cls;
  struct GNUNET_TIME_Absolute now;
  size_t len = size * nmemb;
  struct Plugin *plugin = s->plugin;

  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
                   "Client: Received %Zu bytes from peer `%s'\n", len,
                   GNUNET_i2s (&s->target));
  now = GNUNET_TIME_absolute_get ();
  if (now.abs_value < s->next_receive.abs_value)
  {
    struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get ();
    struct GNUNET_TIME_Relative delta =
        GNUNET_TIME_absolute_get_difference (now, s->next_receive);
    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name,
                     "Client: %p No inbound bandwidth available! Next read was delayed for %llu ms\n",
                     s->client_get, delta.rel_value);
    if (s->recv_wakeup_task != GNUNET_SCHEDULER_NO_TASK)
    {
      GNUNET_SCHEDULER_cancel (s->recv_wakeup_task);
      s->recv_wakeup_task = GNUNET_SCHEDULER_NO_TASK;
    }
    s->recv_wakeup_task =
        GNUNET_SCHEDULER_add_delayed (delta, &client_wake_up, s);
    return CURLPAUSE_ALL;
  }
  if (NULL == s->msg_tk)
    s->msg_tk = GNUNET_SERVER_mst_create (&client_receive_mst_cb, s);
  GNUNET_SERVER_mst_receive (s->msg_tk, s, stream, len, GNUNET_NO, GNUNET_NO);
  return len;
}
Esempio n. 2
0
static void
pow_cb (void *cls, struct GNUNET_SENSOR_crypto_pow_block *block)
{
  struct GNUNET_TIME_Absolute end_time;
  struct GNUNET_TIME_Relative duration;

  pow_task = NULL;
  end_time = GNUNET_TIME_absolute_get();
  duration = GNUNET_TIME_absolute_get_difference (block->timestamp, end_time);
  printf(".");
  performed_iterations++;
  total_duration = GNUNET_TIME_relative_add (total_duration, duration);
  if (ITERATIONS == performed_iterations)
  {
    total_duration = GNUNET_TIME_relative_divide (total_duration, ITERATIONS);
    printf ("Matching bits %d: %s\n", current_matching_bits,
             GNUNET_STRINGS_relative_time_to_string(total_duration, GNUNET_NO));
    total_duration = GNUNET_TIME_UNIT_ZERO;
    performed_iterations = 0;
    if (MATCHING_BITS_END == current_matching_bits)
    {
      ok = 0;
      GNUNET_SCHEDULER_cancel (shutdown_task);
      GNUNET_SCHEDULER_add_now (do_shutdown, NULL);
      return;
    }
    current_matching_bits ++;
  }
  GNUNET_SCHEDULER_add_now (&pow_start, NULL);
}
/**
 * Iterate over the expired items stored in the datastore.
 * Delete all expired items; once we have processed all
 * expired items, re-schedule the "delete_expired" task.
 *
 * @param cls not used
 * @param key key for the content
 * @param size number of bytes in data
 * @param data content stored
 * @param type type of the content
 * @param priority priority of the content
 * @param anonymity anonymity-level for the content
 * @param expiration expiration time for the content
 * @param uid unique identifier for the datum;
 *        maybe 0 if no unique identifier is available
 *
 * @return GNUNET_SYSERR to abort the iteration, GNUNET_OK to continue
 *         (continue on call to "next", of course),
 *         GNUNET_NO to delete the item and continue (if supported)
 */
static int
expired_processor (void *cls, const struct GNUNET_HashCode * key, uint32_t size,
                   const void *data, enum GNUNET_BLOCK_Type type,
                   uint32_t priority, uint32_t anonymity,
                   struct GNUNET_TIME_Absolute expiration, uint64_t uid)
{
  struct GNUNET_TIME_Absolute now;

  if (key == NULL)
  {
    expired_kill_task =
        GNUNET_SCHEDULER_add_delayed_with_priority (MAX_EXPIRE_DELAY,
						    GNUNET_SCHEDULER_PRIORITY_IDLE,
						    &delete_expired, NULL);
    return GNUNET_SYSERR;
  }
  now = GNUNET_TIME_absolute_get ();
  if (expiration.abs_value_us > now.abs_value_us)
  {
    /* finished processing */
    expired_kill_task =
        GNUNET_SCHEDULER_add_delayed_with_priority (MAX_EXPIRE_DELAY,
						    GNUNET_SCHEDULER_PRIORITY_IDLE,
						    &delete_expired, NULL);
    return GNUNET_SYSERR;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Deleting content `%s' of type %u that expired %s ago\n",
              GNUNET_h2s (key), type,
	      GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_difference (expiration,
											   now),
						      GNUNET_YES));
  min_expiration = now;
  GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes expired"), size,
                            GNUNET_YES);
  GNUNET_CONTAINER_bloomfilter_remove (filter, key);
  expired_kill_task =
      GNUNET_SCHEDULER_add_delayed_with_priority (MIN_EXPIRE_DELAY,
						  GNUNET_SCHEDULER_PRIORITY_IDLE,
						  &delete_expired, NULL);
  return GNUNET_NO;
}
Esempio n. 4
0
/**
 * Show the results of the test (banwidth acheived) and log them to GAUGER
 */
static void
show_end_data (void)
{
  static struct GNUNET_TIME_Absolute end_time;
  static struct GNUNET_TIME_Relative total_time;

  end_time = GNUNET_TIME_absolute_get();
  total_time = GNUNET_TIME_absolute_get_difference(start_time, end_time);
  FPRINTF (stderr, "\nResults of test \"%s\"\n", test_name);
  FPRINTF (stderr, "Test time %s\n",
	   GNUNET_STRINGS_relative_time_to_string (total_time,
						   GNUNET_YES));
  FPRINTF (stderr, "Test bandwidth: %f kb/s\n",
	   4 * TOTAL_PACKETS * 1.0 / (total_time.rel_value_us / 1000)); // 4bytes * ms
  FPRINTF (stderr, "Test throughput: %f packets/s\n\n",
	   TOTAL_PACKETS * 1000.0 / (total_time.rel_value_us / 1000)); // packets * ms
  GAUGER ("CADET", test_name,
          TOTAL_PACKETS * 1000.0 / (total_time.rel_value_us / 1000),
          "packets/s");
}
Esempio n. 5
0
static int
expire_blocks (void *cls,
               const struct GNUNET_HashCode *key,
               void *value)
{
  struct Plugin *plugin = cls;
  struct FlatFileEntry *entry = value;
  struct GNUNET_TIME_Absolute now;
  struct GNUNET_TIME_Absolute expiration;

  now = GNUNET_TIME_absolute_get ();
  expiration = GNUNET_TIME_absolute_ntoh (entry->block->expiration_time);

  if (0 == GNUNET_TIME_absolute_get_difference (now,
                                                expiration).rel_value_us)
  {
    GNUNET_CONTAINER_multihashmap_remove_all (plugin->hm, key);
  }
  return GNUNET_YES;
}
void
GNUNET_ATS_TEST_traffic_handle_pong (struct BenchmarkPartner *p)
{
  struct GNUNET_TIME_Relative left;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
      "Master [%u]: Received PONG from [%u], next message\n", p->me->no,
      p->dest->no);

  p->messages_received++;
  p->bytes_received += TEST_MESSAGE_SIZE;
  p->me->total_messages_received++;
  p->me->total_bytes_received += TEST_MESSAGE_SIZE;
  p->total_app_rtt += GNUNET_TIME_absolute_get_difference(p->last_message_sent,
      GNUNET_TIME_absolute_get()).rel_value_us;

  /* Schedule next send event */
  if (NULL == p->tg)
    return;

  left = GNUNET_TIME_absolute_get_remaining(p->tg->next_ping_transmission);
  if (UINT32_MAX == p->tg->base_rate)
  {
    p->tg->send_task = GNUNET_SCHEDULER_add_now (&comm_schedule_send, p);
  }
  else if (0 == left.rel_value_us)
  {
    p->tg->send_task = GNUNET_SCHEDULER_add_now (&comm_schedule_send, p);
  }
  else
  {
    /* Enforce minimum transmission rate 1 msg / sec */
    if (GNUNET_TIME_UNIT_SECONDS.rel_value_us == (left = GNUNET_TIME_relative_min (left, GNUNET_TIME_UNIT_SECONDS)).rel_value_us)
      GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
          "Enforcing minimum send rate between master [%u] and slave [%u]\n",
          p->me->no, p->dest->no);
    p->tg->send_task = GNUNET_SCHEDULER_add_delayed (left,
        &comm_schedule_send, p);
  }
}
Esempio n. 7
0
/**
 * Log all data now
 *
 * @param l logging handle to use
 */
void
GNUNET_ATS_TEST_logging_now (struct LoggingHandle *l)
{
  struct LoggingPeer *bp;
  struct PeerLoggingTimestep *mlt;
  struct PeerLoggingTimestep *prev_log_mlt;
  struct PartnerLoggingTimestep *slt;
  struct PartnerLoggingTimestep *prev_log_slt;
  struct BenchmarkPartner *p;
  struct GNUNET_TIME_Relative delta;
  int c_s;
  int c_m;
  unsigned int app_rtt;
  double mult;

  if (GNUNET_YES != l->running)
    return;

  for (c_m = 0; c_m < l->num_masters; c_m++)
  {
    bp = &l->lp[c_m];
    mlt = GNUNET_new (struct PeerLoggingTimestep);
    GNUNET_CONTAINER_DLL_insert_tail(l->lp[c_m].head, l->lp[c_m].tail, mlt);
    prev_log_mlt = mlt->prev;

    /* Collect data */
    /* Current master state */
    mlt->timestamp = GNUNET_TIME_absolute_get();
    mlt->total_bytes_sent = bp->peer->total_bytes_sent;
    mlt->total_messages_sent = bp->peer->total_messages_sent;
    mlt->total_bytes_received = bp->peer->total_bytes_received;
    mlt->total_messages_received = bp->peer->total_messages_received;

    /* Throughput */
    if (NULL == prev_log_mlt)
     {
       /* Get difference to start */
       delta = GNUNET_TIME_absolute_get_difference (l->lp[c_m].start, mlt->timestamp);
     }
     else
     {
       /* Get difference to last timestep */
       delta = GNUNET_TIME_absolute_get_difference (mlt->prev->timestamp, mlt->timestamp);
     }

     /* Multiplication factor for throughput calculation */
     mult = (double) GNUNET_TIME_UNIT_SECONDS.rel_value_us / (delta.rel_value_us);

     /* Total throughput */
     if (NULL != prev_log_mlt)
     {
       if (mlt->total_bytes_sent - mlt->prev->total_bytes_sent > 0)
       {
         mlt->total_throughput_send = mult * (mlt->total_bytes_sent - mlt->prev->total_bytes_sent);
       }
       else
       {
         mlt->total_throughput_send = 0;
        // mlt->total_throughput_send = prev_log_mlt->total_throughput_send; /* no msgs send */
       }

       if (mlt->total_bytes_received - mlt->prev->total_bytes_received > 0)
       {
         mlt->total_throughput_recv = mult * (mlt->total_bytes_received - mlt->prev->total_bytes_received);
       }
       else
       {
         mlt->total_throughput_send = 0;
         //mlt->total_throughput_recv = prev_log_mlt->total_throughput_recv; /* no msgs received */
       }
     }
     else
     {
       mlt->total_throughput_send = mult * mlt->total_bytes_sent;
       mlt->total_throughput_send = mult * mlt->total_bytes_received;
     }

    if (GNUNET_YES == l->verbose)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
          "Master[%u] delta: %llu us, bytes (sent/received): %u / %u; throughput send/recv: %u / %u\n", c_m,
          delta.rel_value_us,
          mlt->total_bytes_sent,
          mlt->total_bytes_received,
          mlt->total_throughput_send,
          mlt->total_throughput_recv);
    }

    mlt->slaves_log = GNUNET_malloc (bp->peer->num_partners *
        sizeof (struct PartnerLoggingTimestep));

    for (c_s = 0; c_s < bp->peer->num_partners; c_s++)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
          "Collect logging data master[%u] slave [%u]\n", c_m, c_s);

      p = &bp->peer->partners[c_s];
      slt = &mlt->slaves_log[c_s];

      slt->slave = p->dest;
      /* Bytes sent from master to this slave */
      slt->total_bytes_sent = p->bytes_sent;
      /* Messages sent from master to this slave */
      slt->total_messages_sent = p->messages_sent;
      /* Bytes master received from this slave */
      slt->total_bytes_received = p->bytes_received;
      /* Messages master received from this slave */
      slt->total_messages_received = p->messages_received;
      slt->total_app_rtt = p->total_app_rtt;
      /* ats performance information */
      slt->ats_delay = p->props.delay;
      slt->ats_distance = p->props.distance;
      slt->ats_network_type = p->props.scope;
      slt->ats_utilization_in = p->props.utilization_out;
      slt->ats_utilization_out = p->props.utilization_out;
      slt->bandwidth_in = p->bandwidth_in;
      slt->bandwidth_out = p->bandwidth_out;
      slt->pref_bandwidth = p->pref_bandwidth;
      slt->pref_delay = p->pref_delay;

      /* Total application level rtt  */
      if (NULL == prev_log_mlt)
      {
        if (0 != slt->total_messages_sent)
          app_rtt = slt->total_app_rtt / slt->total_messages_sent;
        else
          app_rtt = 0;
      }
      else
      {
        prev_log_slt =  &prev_log_mlt->slaves_log[c_s];
        if ((slt->total_messages_sent - prev_log_slt->total_messages_sent) > 0)
          app_rtt = (slt->total_app_rtt - prev_log_slt->total_app_rtt) /
                  (slt->total_messages_sent - prev_log_slt->total_messages_sent);
        else
        {
          app_rtt = prev_log_slt->app_rtt; /* No messages were */
        }
      }
      slt->app_rtt = app_rtt;

      /* Partner throughput */
      if (NULL != prev_log_mlt)
      {
        prev_log_slt =  &prev_log_mlt->slaves_log[c_s];
        if (slt->total_bytes_sent > prev_log_slt->total_bytes_sent)
          slt->throughput_sent = mult * (slt->total_bytes_sent - prev_log_slt->total_bytes_sent);
        else
          slt->throughput_sent = 0;

        if (slt->total_bytes_received > prev_log_slt->total_bytes_received)
          slt->throughput_recv = mult *
              (slt->total_bytes_received - prev_log_slt->total_bytes_received);
        else
          slt->throughput_recv = 0;
      }
      else
      {
        slt->throughput_sent = mult * slt->total_bytes_sent;
        slt->throughput_recv = mult * slt->total_bytes_received;
      }

      if (GNUNET_YES == l->verbose)
      {
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
            "Master [%u] -> Slave [%u]: delta: %llu us, bytes (sent/received): %u / %u; throughput send/recv: %u / %u\n",
            c_m, c_s,
            delta.rel_value_us,
            mlt->total_bytes_sent,
            mlt->total_bytes_received,
            slt->throughput_sent,
            slt->throughput_recv);
      }
      else
        GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
          "Master [%u]: slave [%u]\n",
          bp->peer->no, p->dest->no);
    }
  }
}
Esempio n. 8
0
void
GNUNET_ATS_TEST_logging_write_to_file (struct LoggingHandle *l,
    char *experiment_name, int plots)
{
  struct GNUNET_DISK_FileHandle *f[l->num_slaves];
  struct GNUNET_DISK_FileHandle *f_m;
  char *tmp_exp_name;
  char *filename_master;
  char *filename_slaves[l->num_slaves];
  char *data;
  struct PeerLoggingTimestep *cur_lt;
  struct PartnerLoggingTimestep *plt;
  struct GNUNET_TIME_Absolute timestamp;
  int c_m;
  int c_s;


  timestamp = GNUNET_TIME_absolute_get();

  tmp_exp_name = experiment_name;
  for (c_m = 0; c_m < l->num_masters; c_m++)
  {
    GNUNET_asprintf (&filename_master, "%s_%llu_master%u_%s",
        experiment_name, timestamp.abs_value_us, c_m, l->name);
    fprintf (stderr, "Writing data for master %u to file `%s'\n",
        c_m,filename_master);

    f_m = GNUNET_DISK_file_open (filename_master,
        GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
        GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
    if (NULL == f_m)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open log file `%s'\n", filename_master);
      GNUNET_free (filename_master);
      return;
    }

    GNUNET_asprintf (&data, "# master %u; experiment : %s\n"
        "timestamp; timestamp delta; #messages sent; #bytes sent; #throughput sent; #messages received; #bytes received; #throughput received; \n" ,
        c_m,  experiment_name);
    if (GNUNET_SYSERR == GNUNET_DISK_file_write(f_m, data, strlen(data)))
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
          "Cannot write data to log file `%s'\n",filename_master);
    GNUNET_free (data);

    for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++)
    {
      GNUNET_asprintf (&filename_slaves[c_s], "%s_%llu_master%u_slave_%u_%s",
          tmp_exp_name, timestamp.abs_value_us, c_m, c_s, l->name);

      fprintf (stderr, "Writing data for master %u slave %u to file `%s'\n",
          c_m, c_s, filename_slaves[c_s]);

      f[c_s] = GNUNET_DISK_file_open (filename_slaves[c_s],
          GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE,
          GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
      if (NULL == f[c_s])
      {
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot open log file `%s'\n", filename_slaves[c_s]);
        GNUNET_free (filename_slaves[c_s]);
        GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close(f_m));
        GNUNET_free (filename_master);
        return;
      }

      /* Header */
      GNUNET_asprintf (&data, "# master %u; slave %u ; experiment : %s\n"
          "timestamp; timestamp delta; #messages sent; #bytes sent; #throughput sent; #messages received; #bytes received; #throughput received; " \
          "rtt; bw in; bw out; ats_cost_lan; ats_cost_wlan; ats_delay; ats_distance; ats_network_type; ats_utilization_up ;ats_utilization_down;" \
          "pref bandwidth; pref delay\n",
          c_m, c_s, experiment_name);
      if (GNUNET_SYSERR == GNUNET_DISK_file_write(f[c_s], data, strlen(data)))
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
            "Cannot write data to log file `%s'\n",filename_slaves[c_s]);
      GNUNET_free (data);
    }

    for (cur_lt = l->lp[c_m].head; NULL != cur_lt; cur_lt = cur_lt->next)
    {
      if (l->verbose)
        fprintf (stderr,
           "Master [%u]: timestamp %llu %llu ; %u %u %u ; %u %u %u\n",
           l->lp[c_m].peer->no,
           (long long unsigned int) cur_lt->timestamp.abs_value_us,
           (long long unsigned int) GNUNET_TIME_absolute_get_difference(l->lp[c_m].start,
               cur_lt->timestamp).rel_value_us / 1000,
           cur_lt->total_messages_sent,
           cur_lt->total_bytes_sent,
           cur_lt->total_throughput_send,
           cur_lt->total_messages_received,
           cur_lt->total_bytes_received,
           cur_lt->total_throughput_recv);

      /* Assembling master string */
      GNUNET_asprintf (&data, "%llu;%llu;%u;%u;%u;%u;%u;%u;\n",
          (long long unsigned int) cur_lt->timestamp.abs_value_us,
          (long long unsigned int) GNUNET_TIME_absolute_get_difference(l->lp[c_m].start,
              cur_lt->timestamp).rel_value_us / 1000,
          cur_lt->total_messages_sent,
          cur_lt->total_bytes_sent,
          cur_lt->total_throughput_send,
          cur_lt->total_messages_received,
          cur_lt->total_bytes_received,
          cur_lt->total_throughput_recv);

      if (GNUNET_SYSERR == GNUNET_DISK_file_write(f_m, data, strlen(data)))
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
            "Cannot write data to master file %u\n", c_m);
      GNUNET_free (data);


      for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++)
      {
        plt = &cur_lt->slaves_log[c_s];
        /* Log partners */

        /* Assembling slave string */
        GNUNET_asprintf(&data,
            "%llu;%llu;%u;%u;%u;%u;%u;%u;%.3f;%u;%u;%u;%u;%u;%u;%u;%.3f;%.3f\n",
            (long long unsigned int) cur_lt->timestamp.abs_value_us,
            (long long unsigned int) GNUNET_TIME_absolute_get_difference(l->lp[c_m].start,
                cur_lt->timestamp).rel_value_us / 1000,
            plt->total_messages_sent,
            plt->total_bytes_sent,
            plt->throughput_sent,
            plt->total_messages_received,
            plt->total_bytes_received,
            plt->throughput_recv,
            (double) plt->app_rtt / 1000,
            plt->bandwidth_in,
            plt->bandwidth_out,
            plt->ats_delay,
            plt->ats_distance,
            plt->ats_network_type,
            plt->ats_utilization_out,
            plt->ats_utilization_in,
            plt->pref_bandwidth,
            plt->pref_delay);

        if (l->verbose)
          fprintf (stderr,
              "\t Slave [%u]: %u %u %u ; %u %u %u rtt %u delay %llu bw_in %u bw_out %u \n",
              plt->slave->no,
              plt->total_messages_sent,
              plt->total_bytes_sent,
              plt->throughput_sent,
              plt->total_messages_received,
              plt->total_bytes_received,
              plt->throughput_recv,
              plt->app_rtt,
              (long long unsigned int) plt->ats_delay.rel_value_us,
              plt->bandwidth_in,
              plt->bandwidth_out);

        if (GNUNET_SYSERR == GNUNET_DISK_file_write(f[c_s], data, strlen(data)))
          GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
              "Cannot write data to log file `%s'\n", filename_slaves[c_s]);
        GNUNET_free (data);

      }
    }

    for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++)
    {
      if (GNUNET_SYSERR == GNUNET_DISK_file_close(f[c_s]))
      {
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
            "Cannot close log file for master[%u] slave[%u]\n", c_m, c_s);
        continue;
      }
      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
          "Data file successfully written to log file for `%s'\n",
          filename_slaves[c_s]);
    }

    if (GNUNET_SYSERR == GNUNET_DISK_file_close(f_m))
    {
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
                                "close",
                                filename_master);
      GNUNET_free (filename_master);
      return;
    }
    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
        "Data file successfully written to log file for master `%s'\n", filename_master);

    if (GNUNET_YES == plots)
    {
      write_throughput_gnuplot_script (filename_master, &l->lp[c_m], filename_slaves, l->num_slaves);
      write_rtt_gnuplot_script (filename_master, &l->lp[c_m], filename_slaves, l->num_slaves);
      write_bw_gnuplot_script (filename_master, &l->lp[c_m], filename_slaves, l->num_slaves);
    }
  }
  GNUNET_free (filename_master);
}
Esempio n. 9
0
int
main (int argc, char *argv[])
{
  struct GNUNET_TIME_Absolute now;
  struct GNUNET_TIME_AbsoluteNBO nown;
  struct GNUNET_TIME_Absolute future;
  struct GNUNET_TIME_Absolute past;
  struct GNUNET_TIME_Absolute last;
  struct GNUNET_TIME_Absolute forever;
  struct GNUNET_TIME_Absolute zero;
  struct GNUNET_TIME_Relative rel;
  struct GNUNET_TIME_Relative relForever;
  struct GNUNET_TIME_Relative relUnit;
  struct GNUNET_TIME_RelativeNBO reln;
  unsigned int i;

  GNUNET_log_setup ("test-time", "WARNING", NULL);
  forever = GNUNET_TIME_UNIT_FOREVER_ABS;
  relForever = GNUNET_TIME_UNIT_FOREVER_REL;
  relUnit = GNUNET_TIME_UNIT_MILLISECONDS;
  zero.abs_value_us = 0;

  last = now = GNUNET_TIME_absolute_get ();
  while (now.abs_value_us == last.abs_value_us)
    now = GNUNET_TIME_absolute_get ();
  GNUNET_assert (now.abs_value_us > last.abs_value_us);

  /* test overflow checking in multiply */
  rel = GNUNET_TIME_UNIT_MILLISECONDS;
  GNUNET_log_skip (1, GNUNET_NO);
  for (i = 0; i < 55; i++)
    rel = GNUNET_TIME_relative_multiply (rel, 2);
  GNUNET_log_skip (0, GNUNET_NO);
  GNUNET_assert (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us);
  /*check zero */
  rel.rel_value_us = (UINT64_MAX) - 1024;
  GNUNET_assert (GNUNET_TIME_UNIT_ZERO.rel_value_us ==
                 GNUNET_TIME_relative_multiply (rel, 0).rel_value_us);

  /* test infinity-check for relative to absolute */
  GNUNET_log_skip (1, GNUNET_NO);
  last = GNUNET_TIME_relative_to_absolute (rel);
  GNUNET_assert (last.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us);
  GNUNET_log_skip (0, GNUNET_YES);

  /* check relative to absolute */
  rel.rel_value_us = 1000000;
  GNUNET_assert (GNUNET_TIME_absolute_get ().abs_value_us <
                 GNUNET_TIME_relative_to_absolute (rel).abs_value_us);
  /*check forever */
  rel.rel_value_us = UINT64_MAX;
  GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us ==
                 GNUNET_TIME_relative_to_absolute (rel).abs_value_us);
  /* check overflow for r2a */
  rel.rel_value_us = (UINT64_MAX) - 1024;
  GNUNET_log_skip (1, GNUNET_NO);
  last = GNUNET_TIME_relative_to_absolute (rel);
  GNUNET_log_skip (0, GNUNET_NO);
  GNUNET_assert (last.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us);

  /* check overflow for relative add */
  GNUNET_log_skip (1, GNUNET_NO);
  rel = GNUNET_TIME_relative_add (rel, rel);
  GNUNET_log_skip (0, GNUNET_NO);
  GNUNET_assert (rel.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us);

  GNUNET_log_skip (1, GNUNET_NO);
  rel = GNUNET_TIME_relative_add (relForever, relForever);
  GNUNET_log_skip (0, GNUNET_NO);
  GNUNET_assert (rel.rel_value_us == relForever.rel_value_us);

  GNUNET_log_skip (1, GNUNET_NO);
  rel = GNUNET_TIME_relative_add (relUnit, relUnit);
  GNUNET_assert (rel.rel_value_us == 2 * relUnit.rel_value_us);

  /* check relation check in get_duration */
  future.abs_value_us = now.abs_value_us + 1000000;
  GNUNET_assert (GNUNET_TIME_absolute_get_difference (now, future).rel_value_us ==
                 1000000);
  GNUNET_assert (GNUNET_TIME_absolute_get_difference (future, now).rel_value_us ==
                 0);

  GNUNET_assert (GNUNET_TIME_absolute_get_difference (zero, forever).rel_value_us
                 == forever.abs_value_us);

  past.abs_value_us = now.abs_value_us - 1000000;
  rel = GNUNET_TIME_absolute_get_duration (future);
  GNUNET_assert (rel.rel_value_us == 0);
  rel = GNUNET_TIME_absolute_get_duration (past);
  GNUNET_assert (rel.rel_value_us >= 1000000);

  /* check get remaining */
  rel = GNUNET_TIME_absolute_get_remaining (now);
  GNUNET_assert (rel.rel_value_us == 0);
  rel = GNUNET_TIME_absolute_get_remaining (past);
  GNUNET_assert (rel.rel_value_us == 0);
  rel = GNUNET_TIME_absolute_get_remaining (future);
  GNUNET_assert (rel.rel_value_us > 0);
  GNUNET_assert (rel.rel_value_us <= 1000000);
  forever = GNUNET_TIME_UNIT_FOREVER_ABS;
  GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us ==
                 GNUNET_TIME_absolute_get_remaining (forever).rel_value_us);

  /* check endianess */
  reln = GNUNET_TIME_relative_hton (rel);
  GNUNET_assert (rel.rel_value_us == GNUNET_TIME_relative_ntoh (reln).rel_value_us);
  nown = GNUNET_TIME_absolute_hton (now);
  GNUNET_assert (now.abs_value_us == GNUNET_TIME_absolute_ntoh (nown).abs_value_us);

  /* check absolute addition */
  future = GNUNET_TIME_absolute_add (now, GNUNET_TIME_UNIT_SECONDS);
  GNUNET_assert (future.abs_value_us == now.abs_value_us + 1000 * 1000LL);

  future = GNUNET_TIME_absolute_add (forever, GNUNET_TIME_UNIT_ZERO);
  GNUNET_assert (future.abs_value_us == forever.abs_value_us);

  rel.rel_value_us = (UINT64_MAX) - 1024;
  now.abs_value_us = rel.rel_value_us;
  future = GNUNET_TIME_absolute_add (now, rel);
  GNUNET_assert (future.abs_value_us == forever.abs_value_us);

  /* check zero */
  future = GNUNET_TIME_absolute_add (now, GNUNET_TIME_UNIT_ZERO);
  GNUNET_assert (future.abs_value_us == now.abs_value_us);

  GNUNET_assert (forever.abs_value_us ==
                 GNUNET_TIME_absolute_subtract (forever,
                                                GNUNET_TIME_UNIT_MINUTES).abs_value_us);
  /*check absolute subtract */
  now.abs_value_us = 50000;
  rel.rel_value_us = 100000;
  GNUNET_assert (GNUNET_TIME_UNIT_ZERO_ABS.abs_value_us ==
                 (GNUNET_TIME_absolute_subtract (now, rel)).abs_value_us);
  rel.rel_value_us = 10000;
  GNUNET_assert (40000 == (GNUNET_TIME_absolute_subtract (now, rel)).abs_value_us);

  /*check relative divide */
  GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us ==
                 (GNUNET_TIME_relative_divide (rel, 0)).rel_value_us);

  rel = GNUNET_TIME_UNIT_FOREVER_REL;
  GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us ==
                 (GNUNET_TIME_relative_divide (rel, 2)).rel_value_us);

  rel = GNUNET_TIME_relative_divide (relUnit, 2);
  GNUNET_assert (rel.rel_value_us == relUnit.rel_value_us / 2);


  /* check Return absolute time of 0ms */
  zero = GNUNET_TIME_UNIT_ZERO_ABS;

  /* check GNUNET_TIME_calculate_eta */
  last.abs_value_us = GNUNET_TIME_absolute_get ().abs_value_us - 1024;
  forever = GNUNET_TIME_UNIT_FOREVER_ABS;
  forever.abs_value_us = forever.abs_value_us - 1024;
  GNUNET_assert (GNUNET_TIME_UNIT_ZERO_ABS.abs_value_us ==
                 GNUNET_TIME_calculate_eta (forever, 50000, 100000).rel_value_us);
  /* check zero */
  GNUNET_log_skip (1, GNUNET_NO);
  GNUNET_assert (GNUNET_TIME_UNIT_ZERO.rel_value_us ==
                 (GNUNET_TIME_calculate_eta (last, 60000, 50000)).rel_value_us);
  GNUNET_log_skip (0, GNUNET_YES);
  /*check forever */
  GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us ==
                 (GNUNET_TIME_calculate_eta (last, 0, 50000)).rel_value_us);

  /*check relative subtract */
  now = GNUNET_TIME_absolute_get ();
  rel.rel_value_us = now.abs_value_us;
  relForever.rel_value_us = rel.rel_value_us + 1024;
  GNUNET_assert (1024 ==
                 GNUNET_TIME_relative_subtract (relForever, rel).rel_value_us);
  /*check zero */
  GNUNET_assert (GNUNET_TIME_UNIT_ZERO.rel_value_us ==
                 GNUNET_TIME_relative_subtract (rel, relForever).rel_value_us);
  /*check forever */
  rel.rel_value_us = UINT64_MAX;
  GNUNET_assert (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us ==
                 GNUNET_TIME_relative_subtract (rel, relForever).rel_value_us);

  /*check GNUNET_TIME_relative_min */
  now = GNUNET_TIME_absolute_get ();
  rel.rel_value_us = now.abs_value_us;
  relForever.rel_value_us = rel.rel_value_us - 1024;
  GNUNET_assert (relForever.rel_value_us ==
                 GNUNET_TIME_relative_min (rel, relForever).rel_value_us);

  /*check GNUNET_TIME_relative_max */
  GNUNET_assert (rel.rel_value_us ==
                 GNUNET_TIME_relative_max (rel, relForever).rel_value_us);

  /*check GNUNET_TIME_absolute_min */
  now = GNUNET_TIME_absolute_get ();
  last.abs_value_us = now.abs_value_us - 1024;
  GNUNET_assert (last.abs_value_us ==
                 GNUNET_TIME_absolute_min (now, last).abs_value_us);

  /*check  GNUNET_TIME_absolute_max */
  GNUNET_assert (now.abs_value_us ==
                 GNUNET_TIME_absolute_max (now, last).abs_value_us);

  return 0;
}
/**
 * Solves the MLP problem
 *
 * @param mlp the MLP Handle
 * @param s_ctx context to return results
 * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
 */
int
mlp_solve_mlp_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *s_ctx)
{
  int res;
  struct GNUNET_TIME_Relative duration;
  struct GNUNET_TIME_Absolute end;
  struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get();

  /* solve MLP problem */
  res = glp_intopt(mlp->prob, &mlp->control_param_mlp);

  if (res == 0)
  {
    /* The MLP problem instance has been successfully solved. */
  }
  else if (res == GLP_EITLIM)
  {
    /* simplex iteration limit has been exceeded. */
    // TODO Increase iteration limit?
  }
  else if (res == GLP_ETMLIM)
  {
    /* Time limit has been exceeded.  */
    // TODO Increase time limit?
  }
  else
  {
    /* Problem was ill-defined, no way to handle that */
    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
        "ats-mlp",
        "Solving MLP problem failed:  %s\n", mlp_solve_to_string(res));
    return GNUNET_SYSERR;
  }

  end = GNUNET_TIME_absolute_get ();
  duration = GNUNET_TIME_absolute_get_difference (start, end);
  mlp->mlp_solved++;
  mlp->mlp_total_duration =+ duration.rel_value;
  s_ctx->mlp_duration = duration;

  GNUNET_STATISTICS_update (mlp->stats,"# MLP problem solved", 1, GNUNET_NO);
  GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time (ms)", duration.rel_value, GNUNET_NO);
  GNUNET_STATISTICS_set (mlp->stats,"# MLP execution time average (ms)",
                         mlp->mlp_total_duration / mlp->mlp_solved,  GNUNET_NO);

  /* Analyze problem status  */
  res = glp_mip_status(mlp->prob);
  switch (res) {
    /* solution is optimal */
    case GLP_OPT:
    /* solution is feasible */
    case GLP_FEAS:
      break;

    /* Problem was ill-defined, no way to handle that */
    default:
      GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
          "ats-mlp",
          "Solving MLP problem failed, %s\n\n", mlp_status_to_string(res));
      return GNUNET_SYSERR;
      break;
  }

  return GNUNET_OK;
}
/**
 * Solves the LP problem
 *
 * @param mlp the MLP Handle
 * @param s_ctx context to return results
 * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
 */
static int
mlp_solve_lp_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *s_ctx)
{
  int res;
  struct GNUNET_TIME_Relative duration;
  struct GNUNET_TIME_Absolute end;
  struct GNUNET_TIME_Absolute start = GNUNET_TIME_absolute_get();

  /* LP presolver?
   * Presolver is required if the problem was modified and an existing
   * valid basis is now invalid */
  if (mlp->presolver_required == GNUNET_YES)
    mlp->control_param_lp.presolve = GLP_ON;
  else
    mlp->control_param_lp.presolve = GLP_OFF;

  /* Solve LP problem to have initial valid solution */
lp_solv:
  res = glp_simplex(mlp->prob, &mlp->control_param_lp);
  if (res == 0)
  {
    /* The LP problem instance has been successfully solved. */
  }
  else if (res == GLP_EITLIM)
  {
    /* simplex iteration limit has been exceeded. */
    // TODO Increase iteration limit?
  }
  else if (res == GLP_ETMLIM)
  {
    /* Time limit has been exceeded.  */
    // TODO Increase time limit?
  }
  else
  {
    /* Problem was ill-defined, retry with presolver */
    if (mlp->presolver_required == GNUNET_NO)
    {
      mlp->presolver_required = GNUNET_YES;
      goto lp_solv;
    }
    else
    {
      /* Problem was ill-defined, no way to handle that */
      GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
          "ats-mlp",
          "Solving LP problem failed: %i %s\n", res, mlp_solve_to_string(res));
      return GNUNET_SYSERR;
    }
  }

  end = GNUNET_TIME_absolute_get ();
  duration = GNUNET_TIME_absolute_get_difference (start, end);
  mlp->lp_solved++;
  mlp->lp_total_duration =+ duration.rel_value;
  s_ctx->lp_duration = duration;

  GNUNET_STATISTICS_update (mlp->stats,"# LP problem solved", 1, GNUNET_NO);
  GNUNET_STATISTICS_set (mlp->stats,"# LP execution time (ms)", duration.rel_value, GNUNET_NO);
  GNUNET_STATISTICS_set (mlp->stats,"# LP execution time average (ms)",
                         mlp->lp_total_duration / mlp->lp_solved,  GNUNET_NO);

  /* Analyze problem status  */
  res = glp_get_status (mlp->prob);
  switch (res) {
    /* solution is optimal */
    case GLP_OPT:
    /* solution is feasible */
    case GLP_FEAS:
      break;

    /* Problem was ill-defined, no way to handle that */
    default:
      GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
          "ats-mlp",
          "Solving LP problem failed, no solution: %s\n", mlp_status_to_string(res));
      return GNUNET_SYSERR;
      break;
  }

  /* solved sucessfully, no presolver required next time */
  mlp->presolver_required = GNUNET_NO;

  return GNUNET_OK;
}
static void
run (void *cls, char *const *args, const char *cfgfile,
     const struct GNUNET_CONFIGURATION_Handle *cfg)
{
  size_t len;
  int c;

  int rd_count = 3;
  size_t data_len;
  struct GNUNET_NAMESTORE_RecordData src[rd_count];

  memset(src, '\0', rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData));

  data_len = 0;
  for (c = 0; c < rd_count; c++)
  {
    src[c].record_type = c+1;
    src[c].data_size = data_len;
    src[c].data = GNUNET_malloc (data_len);

    /* Setting data to data_len * record_type */
    memset ((char *) src[c].data, 'a', data_len);
    data_len += 10;
  }
  res = 0;

  len = GNUNET_NAMESTORE_records_get_size(rd_count, src);
  char rd_ser[len];
  GNUNET_assert (len == GNUNET_NAMESTORE_records_serialize(rd_count, src, len, rd_ser));

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Serialized data len: %u\n",len);

  GNUNET_assert (rd_ser != NULL);

  struct GNUNET_NAMESTORE_RecordData dst[rd_count];
  GNUNET_assert (GNUNET_OK == GNUNET_NAMESTORE_records_deserialize (len, rd_ser, rd_count, dst));

  GNUNET_assert (dst != NULL);

  for (c = 0; c < rd_count; c++)
  {
    if (src[c].data_size != dst[c].data_size)
    {
      GNUNET_break (0);
      res = 1;
    }
    if (0 != GNUNET_TIME_absolute_get_difference(src[c].expiration, dst[c].expiration).rel_value)
    {
      GNUNET_break (0);
      res = 1;
    }
    if (src[c].flags != dst[c].flags)
    {
      GNUNET_break (0);
      res = 1;
    }
    if (src[c].record_type != dst[c].record_type)
    {
      GNUNET_break (0);
      res = 1;
    }

    size_t data_size = src[c].data_size;
    char data[data_size];
    memset (data, 'a', data_size);
    if (0 != memcmp (data, dst[c].data, data_size))
    {
      GNUNET_break (0);
      res = 1;
    }
    if (0 != memcmp (data, src[c].data, data_size))
    {
      GNUNET_break (0);
      res = 1;
    }
    if (0 != memcmp (src[c].data, dst[c].data, src[c].data_size))
    {
      GNUNET_break (0);
      res = 1;
    }

    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Element [%i]: EQUAL\n", c);
  }

  for (c = 0; c < rd_count; c++)
  {
    GNUNET_free ((void *)src[c].data);
  }
}
/**
 * Find a "good" address to use for a peer.  If we already have an existing
 * address, we stick to it.  Otherwise, we pick by lowest distance and then
 * by lowest latency.
 *
 * @param cls the 'struct ATS_Address**' where we store the result
 * @param key unused
 * @param value another 'struct ATS_Address*' to consider using
 * @return GNUNET_OK (continue to iterate)
 */
static int
find_address_it (void *cls, const GNUNET_HashCode * key, void *value)
{
  struct ATS_Address **ap = cls;
  struct ATS_Address *aa = (struct ATS_Address *) value;
  struct ATS_Address *ab = *ap;
  struct GNUNET_TIME_Absolute now;

  now = GNUNET_TIME_absolute_get();

  if (aa->blocked_until.abs_value == GNUNET_TIME_absolute_max (now, aa->blocked_until).abs_value)
  {
    /* This address is blocked for suggestion */
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Address %p blocked for suggestion for %llu ms \n",
                aa,
                GNUNET_TIME_absolute_get_difference(now, aa->blocked_until).rel_value);
    return GNUNET_OK;
  }

  aa->block_interval = GNUNET_TIME_relative_add (aa->block_interval, ATS_BLOCKING_DELTA);
  aa->blocked_until = GNUNET_TIME_absolute_add (now, aa->block_interval);

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Address %p ready for suggestion, block interval now %llu \n", aa, aa->block_interval);

  /* FIXME this is a hack */


  if (NULL != ab)
  {
    if ((0 == strcmp (ab->plugin, "tcp")) &&
        (0 == strcmp (aa->plugin, "tcp")))
    {
      if ((0 != ab->addr_len) &&
          (0 == aa->addr_len))
      {
        /* saved address was an outbound address, but we have an inbound address */
        *ap = aa;
        return GNUNET_OK;
      }
      if (0 == ab->addr_len)
      {
        /* saved address was an inbound address, so do not overwrite */
        return GNUNET_OK;
      }
    }
  }
  /* FIXME end of hack */

  if (NULL == ab)
  {
    *ap = aa;
    return GNUNET_OK;
  }
  if ((ntohl (ab->assigned_bw_in.value__) == 0) &&
      (ntohl (aa->assigned_bw_in.value__) > 0))
  {
    /* stick to existing connection */
    *ap = aa;
    return GNUNET_OK;
  }
  if (ab->atsp_distance > aa->atsp_distance)
  {
    /* user shorter distance */
    *ap = aa;
    return GNUNET_OK;
  }
  if (ab->atsp_latency.rel_value > aa->atsp_latency.rel_value)
  {
    /* user lower latency */
    *ap = aa;
    return GNUNET_OK;
  }
  /* don't care */
  return GNUNET_OK;
}
Esempio n. 14
0
/**
 * Information callback for the solver
 *
 * @param op the solver operation
 * @param stat status of the solver operation
 * @param add additional solver information
 */
static void
solver_info_cb (void *cls,
    enum GAS_Solver_Operation op,
    enum GAS_Solver_Status stat,
    enum GAS_Solver_Additional_Information add)
{
  char *add_info;
  switch (add) {
    case GAS_INFO_NONE:
      add_info = "GAS_INFO_NONE";
      break;
    case GAS_INFO_FULL:
      add_info = "GAS_INFO_MLP_FULL";
      break;
    case GAS_INFO_UPDATED:
      add_info = "GAS_INFO_MLP_UPDATED";
      break;
    case GAS_INFO_PROP_ALL:
      add_info = "GAS_INFO_PROP_ALL";
      break;
    case GAS_INFO_PROP_SINGLE:
      add_info = "GAS_INFO_PROP_SINGLE";
      break;
    default:
      add_info = "INVALID";
      break;
  }

  struct Result *tmp;
  switch (op)
  {
    case GAS_OP_SOLVE_START:
      GNUNET_log(GNUNET_ERROR_TYPE_INFO,
          "Solver notifies `%s' with result `%s' `%s'\n", "GAS_OP_SOLVE_START",
          (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
      if (GNUNET_NO == ph.expecting_solution)
      {
        /* We do not expect a solution at the moment */
        GNUNET_break (0);
        return;
      }

      if ((GAS_STAT_SUCCESS == stat) && (NULL == ph.current_result))
      {
        tmp = GNUNET_new (struct Result);
        /* Create new result */
        if ((add == GAS_INFO_UPDATED) || (GNUNET_YES == ph.performed_update))
        {
          ph.current_result = tmp;
          //fprintf (stderr,"UPDATE %u %u\n",ph.current_iteration-1, ph.current_p);
          ph.iterations_results[ph.current_iteration-1].update_results_array[ph.current_p] = tmp;
        }
        else
        {
          ph.current_result = tmp;
          //fprintf (stderr,"FULL %u %u\n",ph.current_iteration-1, ph.current_p);
          ph.iterations_results[ph.current_iteration-1].results_array[ph.current_p] = tmp;
        }

        ph.current_result->addresses = ph.current_a;
        ph.current_result->peers = ph.current_p;
        ph.current_result->s_total = GNUNET_TIME_absolute_get();
        ph.current_result->d_total_full = GNUNET_TIME_UNIT_FOREVER_REL;
        ph.current_result->d_setup_full = GNUNET_TIME_UNIT_FOREVER_REL;
        ph.current_result->d_lp_full = GNUNET_TIME_UNIT_FOREVER_REL;
        ph.current_result->d_mlp_full = GNUNET_TIME_UNIT_FOREVER_REL;
        ph.current_result->info = add;
        if ((add == GAS_INFO_UPDATED) || (GNUNET_YES == ph.performed_update))
        {
          ph.current_result->update = GNUNET_YES;
        }
        else
        {
          ph.current_result->update = GNUNET_NO;
        }

      }
      return;
    case GAS_OP_SOLVE_STOP:
      GNUNET_log(GNUNET_ERROR_TYPE_INFO,
          "Solver notifies `%s' with result `%s', `%s'\n", "GAS_OP_SOLVE_STOP",
          (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
      if ((GNUNET_NO == ph.expecting_solution) || (NULL == ph.current_result))
      {
        /* We do not expect a solution at the moment */
        GNUNET_break (0);
        return;
      }

      if (GAS_STAT_SUCCESS == stat)
        ph.current_result->valid = GNUNET_YES;
      else
        ph.current_result->valid = GNUNET_NO;

      if (NULL != ph.current_result)
      {
        /* Finalize result */
        ph.current_result->e_total = GNUNET_TIME_absolute_get ();
        ph.current_result->d_total_full = GNUNET_TIME_absolute_get_difference (
            ph.current_result->s_total, ph.current_result->e_total);
      }
      ph.current_result = NULL;
      return;

    case GAS_OP_SOLVE_SETUP_START:
      GNUNET_log(GNUNET_ERROR_TYPE_INFO,
          "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_START",
          (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
      if ((GNUNET_NO == ph.expecting_solution) || (NULL == ph.current_result))
      {
        GNUNET_break(0);
        return;
      }

      if (GAS_STAT_SUCCESS == stat)
        ph.current_result->valid = GNUNET_YES;
      else
        ph.current_result->valid = GNUNET_NO;

      ph.current_result->s_setup = GNUNET_TIME_absolute_get ();
      return;

    case GAS_OP_SOLVE_SETUP_STOP:
      GNUNET_log(GNUNET_ERROR_TYPE_INFO,
          "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_STOP",
          (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
      if ((GNUNET_NO == ph.expecting_solution) || (NULL == ph.current_result))
      {
        GNUNET_break(0);
        return;
      }

      if (GAS_STAT_SUCCESS == stat)
        ph.current_result->valid = GNUNET_YES;
      else
        ph.current_result->valid = GNUNET_NO;

      ph.current_result->e_setup = GNUNET_TIME_absolute_get ();
      ph.current_result->d_setup_full = GNUNET_TIME_absolute_get_difference (
          ph.current_result->s_setup, ph.current_result->e_setup);
      return;

    case GAS_OP_SOLVE_MLP_LP_START:
      GNUNET_log(GNUNET_ERROR_TYPE_INFO,
          "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_START",
          (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
      if ((GNUNET_NO == ph.expecting_solution) || (NULL == ph.current_result))
      {
        GNUNET_break(0);
        return;
      }

      if (GAS_STAT_SUCCESS == stat)
        ph.current_result->valid = GNUNET_YES;
      else
        ph.current_result->valid = GNUNET_NO;

      ph.current_result->s_lp = GNUNET_TIME_absolute_get ();
      return;
    case GAS_OP_SOLVE_MLP_LP_STOP:
      GNUNET_log(GNUNET_ERROR_TYPE_INFO,
          "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_STOP",
          (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
      if ((GNUNET_NO == ph.expecting_solution) || (NULL == ph.current_result))
      {
        GNUNET_break(0);
        return;
      }

      if (GAS_STAT_SUCCESS == stat)
        ph.current_result->valid = GNUNET_YES;
      else
        ph.current_result->valid = GNUNET_NO;

      ph.current_result->e_lp = GNUNET_TIME_absolute_get ();
      ph.current_result->d_lp_full = GNUNET_TIME_absolute_get_difference (
          ph.current_result->s_lp, ph.current_result->e_lp);
      return;

    case GAS_OP_SOLVE_MLP_MLP_START:
      GNUNET_log(GNUNET_ERROR_TYPE_INFO,
          "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_START",
          (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
      if ((GNUNET_NO == ph.expecting_solution) || (NULL == ph.current_result))
      {
        GNUNET_break(0);
        return;
      }

      if (GAS_STAT_SUCCESS == stat)
        ph.current_result->valid = GNUNET_YES;
      else
        ph.current_result->valid = GNUNET_NO;

      ph.current_result->s_mlp = GNUNET_TIME_absolute_get ();
      return;
    case GAS_OP_SOLVE_MLP_MLP_STOP:
      GNUNET_log(GNUNET_ERROR_TYPE_INFO,
          "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_STOP",
          (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
      if ((GNUNET_NO == ph.expecting_solution) || (NULL == ph.current_result))
      {
        GNUNET_break(0);
        return;
      }

      if (GAS_STAT_SUCCESS == stat)
        ph.current_result->valid = GNUNET_YES;
      else
        ph.current_result->valid = GNUNET_NO;

      ph.current_result->e_mlp = GNUNET_TIME_absolute_get ();
      ph.current_result->d_mlp_full = GNUNET_TIME_absolute_get_difference (
      ph.current_result->s_mlp, ph.current_result->e_mlp);
      return;
    case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START:
      GNUNET_log(GNUNET_ERROR_TYPE_INFO,
          "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START",
          (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
      return;
    case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP:
      GNUNET_log(GNUNET_ERROR_TYPE_INFO,
          "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP",
          (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
      if (GAS_STAT_SUCCESS != stat)
      {
        GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
            "Solver `%s' failed to update problem with %u peers and %u address!\n",
            ph.ats_string, ph.current_p, ph.current_a);
      }

      return;
    default:
      break;
    }
/**
 * This function updates the old token with new attributes,
 * removes deleted attributes and expiration times.
 *
 * @param cls the ego entry
 * @param tc task context
 */
static void
handle_token_update (void *cls,
                     const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  char *token_header;
  char *token_payload;
  char *token_payload_json;
  char *new_token;
  char *new_payload_str;
  char *new_payload_base64;
  char *sig_str;
  char *key;
  char *padding;
  const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
  struct EgoEntry *ego_entry = cls;
  struct GNUNET_GNSRECORD_Data token_record;
  struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
  struct GNUNET_CRYPTO_EcdsaSignature sig;
  struct GNUNET_HashCode key_hash;
  struct GNUNET_TIME_Relative token_rel_exp;
  struct GNUNET_TIME_Relative token_ttl;
  struct GNUNET_TIME_Absolute token_exp;
  struct GNUNET_TIME_Absolute token_nbf;
  struct GNUNET_TIME_Absolute new_exp;
  struct GNUNET_TIME_Absolute new_iat;
  struct GNUNET_TIME_Absolute new_nbf;
  json_t *payload_json;
  json_t *value;
  json_t *cur_value;
  json_t *new_payload_json;
  json_t *token_nbf_json;
  json_t *token_exp_json;
  json_error_t json_err;

  priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);

  //Note: We need the token expiration time here. Not the record expiration
  //time.
  //There are two types of tokens: Token that expire on GNS level with
  //an absolute expiration time. Those are basically tokens that will
  //be automatically revoked on (record)expiration.
  //Tokens stored with relative expiration times will expire on the token level (token expiration)
  //but this service will reissue new tokens that can be retrieved from GNS
  //automatically.

  token_header = strtok (token, ".");

  token_payload = strtok (NULL, ".");

  GNUNET_STRINGS_base64_decode (token_payload,
                                strlen (token_payload),
                                &token_payload_json);

  payload_json = json_loads (token_payload_json, JSON_DECODE_ANY, &json_err);
  GNUNET_free (token_payload_json);

  token_exp_json = json_object_get (payload_json, "exp");
  token_nbf_json = json_object_get (payload_json, "nbf");
  token_exp.abs_value_us = json_integer_value(token_exp_json);
  token_nbf.abs_value_us = json_integer_value(token_nbf_json);
  token_rel_exp = GNUNET_TIME_absolute_get_difference (token_nbf, token_exp);

  token_ttl = GNUNET_TIME_absolute_get_remaining (token_exp);
  if (0 != GNUNET_TIME_absolute_get_remaining (token_exp).rel_value_us)
  {
    //This token is not yet expired! Save and skip
    if (min_rel_exp.rel_value_us > token_ttl.rel_value_us)
    {
      min_rel_exp = token_ttl;
    }
    json_decref (payload_json);
    GNUNET_free (token);
    token = NULL;
    GNUNET_free (label);
    label = NULL;
    GNUNET_NAMESTORE_zone_iterator_next (ns_it);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Token is expired. Create a new one\n");
  new_exp = GNUNET_TIME_relative_to_absolute (token_rel_exp);
  new_nbf = GNUNET_TIME_absolute_get ();
  new_iat = new_nbf;
  new_payload_json = json_object();
  json_object_foreach(payload_json, key, value) {
    if (0 == strcmp (key, "exp"))
    {
      json_object_set_new (new_payload_json, key, json_integer (new_exp.abs_value_us));
    }
    else if (0 == strcmp (key, "nbf"))
    {
      json_object_set_new (new_payload_json, key, json_integer (new_nbf.abs_value_us));
    }
    else if (0 == strcmp (key, "iat"))
    {
      json_object_set_new (new_payload_json, key, json_integer (new_iat.abs_value_us));
    }
    else if ((0 == strcmp (key, "iss"))
             || (0 == strcmp (key, "aud"))
             || (0 == strcmp (key, "sub"))
             || (0 == strcmp (key, "rnl")))
    {
      json_object_set (new_payload_json, key, value);
    }
    else {
      GNUNET_CRYPTO_hash (key,
                          strlen (key),
                          &key_hash);
      //Check if attr still exists. omit of not
      if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (ego_entry->attr_map,
                                                               &key_hash))
      {
        cur_value = GNUNET_CONTAINER_multihashmap_get (ego_entry->attr_map,
                                                       &key_hash);
        json_object_set (new_payload_json, key, cur_value);
      }
    }
  }

  // reassemble and set
  new_payload_str = json_dumps (new_payload_json, JSON_COMPACT);
  json_decref (payload_json);
  json_decref (new_payload_json);
  GNUNET_STRINGS_base64_encode (new_payload_str,
                                strlen (new_payload_str),
                                &new_payload_base64);
  //Remove padding
  padding = strtok(new_payload_base64, "=");
  while (NULL != padding)
    padding = strtok(NULL, "=");

  GNUNET_asprintf (&new_token, "%s,%s", token_header, new_payload_base64);
  purpose =
    GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
                   strlen (new_token));
  purpose->size =
    htonl (strlen (new_token) + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose));
  purpose->purpose = htonl(GNUNET_SIGNATURE_PURPOSE_GNUID_TOKEN);
  memcpy (&purpose[1], new_token, strlen (new_token));
  if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_sign (priv_key,
                                             purpose,
                                             &sig))
    GNUNET_break(0);
  GNUNET_free (new_token);
  sig_str = GNUNET_STRINGS_data_to_string_alloc (&sig,
                                                 sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
  GNUNET_asprintf (&new_token, "%s.%s.%s",
                   token_header, new_payload_base64, sig_str);
  GNUNET_free (sig_str);
  GNUNET_free (new_payload_str);
  GNUNET_free (new_payload_base64);
  GNUNET_free (purpose);

  token_record.data = new_token;
  token_record.data_size = strlen (new_token);
  token_record.expiration_time = new_exp.abs_value_us;
  token_record.record_type = GNUNET_GNSRECORD_TYPE_ID_TOKEN;
  token_record.flags = GNUNET_GNSRECORD_RF_NONE | GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
  ns_qe = GNUNET_NAMESTORE_records_store (ns_handle,
                                          priv_key,
                                          label,
                                          1,
                                          &token_record,
                                          &store_token_cont,
                                          ego_entry);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, ">>> Updating Token w/ %s\n", new_token);
  GNUNET_free (new_token);
  GNUNET_free (token);
  token = NULL;
  GNUNET_free (label);
  label = NULL;
}