Ejemplo n.º 1
0
/**
 * Cancel iteration over all indexed files.
 *
 * @param gic operation to cancel
 */
void
GNUNET_FS_get_indexed_files_cancel (struct GNUNET_FS_GetIndexedContext *gic)
{
  GNUNET_CLIENT_disconnect (gic->client);
  GNUNET_free (gic);
}
Ejemplo n.º 2
0
/**
 * Get namespace name, metadata and rank
 * This is a wrapper around internal read_info() call, and ensures that
 * returned data is not invalid (not NULL).
 *
 * @param cfg configuration
 * @param nsid cryptographic ID of the namespace
 * @param ret_meta a location to store metadata pointer. NULL, if metadata
 *        is not needed. Destroy with GNUNET_CONTAINER_meta_data_destroy().
 * @param ret_rank a location to store rank. NULL, if rank not needed.
 * @param ret_name a location to store human-readable name. Name is not unique.
 *        NULL, if name is not needed. Free with GNUNET_free().
 * @param name_is_a_dup is set to GNUNET_YES, if ret_name was filled with
 *        a duplicate of a "no-name" placeholder
 * @return GNUNET_OK on success. GNUENT_SYSERR if the data was
 *         unobtainable (in that case ret_* are filled with placeholders - 
 *         empty metadata container, rank -1 and a "no-name" name).
 */
int
GNUNET_PSEUDONYM_get_info (const struct GNUNET_CONFIGURATION_Handle *cfg,
    const struct GNUNET_HashCode * nsid, struct GNUNET_CONTAINER_MetaData **ret_meta,
    int32_t *ret_rank, char **ret_name, int *name_is_a_dup)
{
  struct GNUNET_CONTAINER_MetaData *meta;
  char *name;
  int32_t rank = -1;

  meta = NULL;
  name = NULL;
  if (GNUNET_OK == read_info (cfg, nsid, &meta, &rank, &name))
  {
    if ((meta != NULL) && (name == NULL))
      name =
          GNUNET_CONTAINER_meta_data_get_first_by_types (meta,
                                                         EXTRACTOR_METATYPE_TITLE,
                                                         EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME,
                                                         EXTRACTOR_METATYPE_FILENAME,
                                                         EXTRACTOR_METATYPE_DESCRIPTION,
                                                         EXTRACTOR_METATYPE_SUBJECT,
                                                         EXTRACTOR_METATYPE_PUBLISHER,
                                                         EXTRACTOR_METATYPE_AUTHOR_NAME,
                                                         EXTRACTOR_METATYPE_COMMENT,
                                                         EXTRACTOR_METATYPE_SUMMARY,
                                                         -1);
    if (ret_name != NULL)
    {
      if (name == NULL)
      {
        name = GNUNET_strdup (_("no-name"));
        if (name_is_a_dup != NULL)
          *name_is_a_dup = GNUNET_YES;
      }
      else if (name_is_a_dup != NULL)
        *name_is_a_dup = GNUNET_NO;
      *ret_name = name;
    }
    else if (name != NULL)
      GNUNET_free (name);

    if (ret_meta != NULL)
    {
      if (meta == NULL)
        meta = GNUNET_CONTAINER_meta_data_create ();
      *ret_meta = meta;
    }
    else if (meta != NULL)
      GNUNET_CONTAINER_meta_data_destroy (meta);

    if (ret_rank != NULL)
      *ret_rank = rank;

    return GNUNET_OK;
  }
  if (ret_name != NULL)
    *ret_name = GNUNET_strdup (_("no-name"));
  if (ret_meta != NULL)
    *ret_meta = GNUNET_CONTAINER_meta_data_create ();
  if (ret_rank != NULL)
    *ret_rank = -1;
  if (name_is_a_dup != NULL)
    *name_is_a_dup = GNUNET_YES;
  return GNUNET_SYSERR;
}
static void
end (void *cls)
{
  if (NULL != zi)
  {
    GNUNET_NAMESTORE_zone_iteration_stop (zi);
    zi = NULL;
  }
  if (endbadly_task != NULL)
  {
    GNUNET_SCHEDULER_cancel (endbadly_task);
    endbadly_task = NULL;
  }

  if (privkey != NULL)
    GNUNET_free (privkey);
  privkey = NULL;

  if (privkey2 != NULL)
    GNUNET_free (privkey2);
  privkey2 = NULL;

  GNUNET_free (s_name_1);
  GNUNET_free (s_name_2);
  GNUNET_free (s_name_3);
  if (s_rd_1 != NULL)
  {
    GNUNET_free ((void *)s_rd_1->data);
    GNUNET_free (s_rd_1);
  }
  if (s_rd_2 != NULL)
  {
    GNUNET_free ((void *)s_rd_2->data);
    GNUNET_free (s_rd_2);
  }
  if (s_rd_3 != NULL)
  {
    GNUNET_free ((void *)s_rd_3->data);
    GNUNET_free (s_rd_3);
  }
  if (nsh != NULL)
    GNUNET_NAMESTORE_disconnect (nsh);
  nsh = NULL;
}
Ejemplo n.º 4
0
/**
 * Initialize the database connections and associated
 * data structures (create tables and indices
 * as needed as well).
 *
 * @param plugin the plugin context (state for this module)
 * @return GNUNET_OK on success
 */
static int
database_setup (struct Plugin *plugin)
{
  char *filename;

  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (plugin->cfg, "peerstore-sqlite",
                                               "FILENAME", &filename))
  {
    GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "peerstore-sqlite",
                               "FILENAME");
    return GNUNET_SYSERR;
  }
  if (GNUNET_OK != GNUNET_DISK_file_test (filename))
  {
    if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (filename))
    {
      GNUNET_break (0);
      GNUNET_free (filename);
      return GNUNET_SYSERR;
    }
  }
  /* filename should be UTF-8-encoded. If it isn't, it's a bug */
  plugin->fn = filename;
  /* Open database and precompile statements */
  if (SQLITE_OK != sqlite3_open (plugin->fn, &plugin->dbh))
  {
    LOG (GNUNET_ERROR_TYPE_ERROR, _("Unable to initialize SQLite: %s.\n"),
         sqlite3_errmsg (plugin->dbh));
    return GNUNET_SYSERR;
  }
  sql_exec (plugin->dbh, "PRAGMA temp_store=MEMORY");
  sql_exec (plugin->dbh, "PRAGMA synchronous=OFF");
  sql_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF");
  sql_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL");
  sql_exec (plugin->dbh, "PRAGMA encoding=\"UTF-8\"");
  sql_exec (plugin->dbh, "PRAGMA page_size=4096");
  sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS);
  /* Create tables */
  sql_exec (plugin->dbh,
            "CREATE TABLE IF NOT EXISTS peerstoredata (\n"
            "  sub_system TEXT NOT NULL,\n" "  peer_id BLOB NOT NULL,\n"
            "  key TEXT NOT NULL,\n" "  value BLOB NULL,\n"
            "  expiry sqlite3_uint64 NOT NULL" ");");
  sqlite3_create_function (plugin->dbh, "UINT64_LT", 2, SQLITE_UTF8, NULL,
                           &sqlite3_lessthan, NULL, NULL);
  /* Create Indices */
  if (SQLITE_OK !=
      sqlite3_exec (plugin->dbh,
                    "CREATE INDEX IF NOT EXISTS peerstoredata_key_index ON peerstoredata (sub_system, peer_id, key)",
                    NULL, NULL, NULL))
  {
    LOG (GNUNET_ERROR_TYPE_ERROR, _("Unable to create indices: %s.\n"),
         sqlite3_errmsg (plugin->dbh));
    return GNUNET_SYSERR;
  }
  /* Prepare statements */

  sql_prepare (plugin->dbh,
               "INSERT INTO peerstoredata (sub_system, peer_id, key, value, expiry) VALUES (?,?,?,?,?);",
               &plugin->insert_peerstoredata);
  sql_prepare (plugin->dbh,
               "SELECT * FROM peerstoredata" " WHERE sub_system = ?",
               &plugin->select_peerstoredata);
  sql_prepare (plugin->dbh,
               "SELECT * FROM peerstoredata" " WHERE sub_system = ?"
               " AND peer_id = ?", &plugin->select_peerstoredata_by_pid);
  sql_prepare (plugin->dbh,
               "SELECT * FROM peerstoredata" " WHERE sub_system = ?"
               " AND key = ?", &plugin->select_peerstoredata_by_key);
  sql_prepare (plugin->dbh,
               "SELECT * FROM peerstoredata" " WHERE sub_system = ?"
               " AND peer_id = ?" " AND key = ?",
               &plugin->select_peerstoredata_by_all);
  sql_prepare (plugin->dbh,
               "DELETE FROM peerstoredata" " WHERE UINT64_LT(expiry, ?)",
               &plugin->expire_peerstoredata);
  sql_prepare (plugin->dbh,
               "DELETE FROM peerstoredata" " WHERE sub_system = ?"
               " AND peer_id = ?" " AND key = ?",
               &plugin->delete_peerstoredata);
  return GNUNET_OK;
}
Ejemplo n.º 5
0
/**
 * Convert human-readable version of a 'value' of a record to the binary
 * representation.
 *
 * @param type type of the record
 * @param s human-readable string
 * @param data set to value in binary encoding (will be allocated)
 * @param data_size set to number of bytes in data
 * @return GNUNET_OK on success
 */
int
GNUNET_NAMESTORE_string_to_value (uint32_t type,
				  const char *s,
				  void **data,
				  size_t *data_size)
{
  struct in_addr value_a;
  struct in6_addr value_aaaa;
  struct GNUNET_CRYPTO_ShortHashCode pkey;
  struct soa_data *soa;
  struct vpn_data *vpn;
  struct tlsa_data *tlsa;
  char result[253 + 1];
  char soa_rname[253 + 1];
  char soa_mname[253 + 1];
  char s_peer[103 + 1];
  char s_serv[253 + 1];
  unsigned int soa_serial;
  unsigned int soa_refresh;
  unsigned int soa_retry;
  unsigned int soa_expire;
  unsigned int soa_min;
  uint16_t mx_pref;
  uint16_t mx_pref_n;
  unsigned int proto;
  
  switch (type)
  {
  case 0:
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		_("Unsupported record type %d\n"),
		(int) type);
    return GNUNET_SYSERR;
  case GNUNET_DNSPARSER_TYPE_A:
    if (1 != inet_pton (AF_INET, s, &value_a))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Unable to parse IPv4 address `%s'\n"),
		  s);
      return GNUNET_SYSERR;
    }
    *data = GNUNET_malloc (sizeof (struct in_addr));
    memcpy (*data, &value_a, sizeof (value_a));
    *data_size = sizeof (value_a);
    return GNUNET_OK;
  case GNUNET_DNSPARSER_TYPE_NS:
    *data = GNUNET_strdup (s);
    *data_size = strlen (s) + 1;
    return GNUNET_OK;
  case GNUNET_DNSPARSER_TYPE_CNAME:
    *data = GNUNET_strdup (s);
    *data_size = strlen (s) + 1;
    return GNUNET_OK;
  case GNUNET_DNSPARSER_TYPE_SOA:
    if (7 != SSCANF (s, 
		     "rname=%253s mname=%253s %u,%u,%u,%u,%u",
		     soa_rname, soa_mname,
		     &soa_serial, &soa_refresh, &soa_retry, &soa_expire, &soa_min))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Unable to parse SOA record `%s'\n"),
		  s);
      return GNUNET_SYSERR;
    }
    *data_size = sizeof (struct soa_data)+strlen(soa_rname)+strlen(soa_mname)+2;
    *data = GNUNET_malloc (*data_size);
    soa = (struct soa_data*)*data;
    soa->serial = htonl(soa_serial);
    soa->refresh = htonl(soa_refresh);
    soa->retry = htonl(soa_retry);
    soa->expire = htonl(soa_expire);
    soa->minimum = htonl(soa_min);
    strcpy((char*)&soa[1], soa_rname);
    strcpy((char*)&soa[1]+strlen(*data)+1, soa_mname);
    return GNUNET_OK;
  case GNUNET_DNSPARSER_TYPE_PTR:
    *data = GNUNET_strdup (s);
    *data_size = strlen (s);
    return GNUNET_OK;
  case GNUNET_DNSPARSER_TYPE_MX:
    if (2 != SSCANF(s, "%hu,%253s", &mx_pref, result))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Unable to parse MX record `%s'\n"),
		  s);
      return GNUNET_SYSERR;
    }
    *data_size = sizeof (uint16_t)+strlen(result)+1;
    *data = GNUNET_malloc (*data_size);
    mx_pref_n = htons(mx_pref);
    memcpy(*data, &mx_pref_n, sizeof (uint16_t));
    strcpy((*data)+sizeof (uint16_t), result);
    return GNUNET_OK;
  case GNUNET_DNSPARSER_TYPE_TXT:
    *data = GNUNET_strdup (s);
    *data_size = strlen (s);
    return GNUNET_OK;
  case GNUNET_DNSPARSER_TYPE_AAAA:
    if (1 != inet_pton (AF_INET6, s, &value_aaaa))    
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Unable to parse IPv6 address `%s'\n"),
		  s);
      return GNUNET_SYSERR;
    }
    *data = GNUNET_malloc (sizeof (struct in6_addr));
    *data_size = sizeof (struct in6_addr);
    memcpy (*data, &value_aaaa, sizeof (value_aaaa));
    return GNUNET_OK;
  case GNUNET_NAMESTORE_TYPE_PKEY:
    if (GNUNET_OK !=
	GNUNET_CRYPTO_short_hash_from_string (s, &pkey))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Unable to parse PKEY record `%s'\n"),
		  s);
      return GNUNET_SYSERR;
    }
    *data = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_ShortHashCode));
    memcpy (*data, &pkey, sizeof (pkey));
    *data_size = sizeof (struct GNUNET_CRYPTO_ShortHashCode);
    return GNUNET_OK;
  case GNUNET_NAMESTORE_TYPE_PSEU:
    *data = GNUNET_strdup (s);
    *data_size = strlen (s);
    return GNUNET_OK;
  case GNUNET_NAMESTORE_TYPE_LEHO:
    *data = GNUNET_strdup (s);
    *data_size = strlen (s);
    return GNUNET_OK;
  case GNUNET_NAMESTORE_TYPE_VPN:
    if (3 != SSCANF (s,"%u %103s %253s",
		     &proto, s_peer, s_serv))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Unable to parse VPN record string `%s'\n"),
		  s);
      return GNUNET_SYSERR;
    }
    *data_size = sizeof (struct vpn_data) + strlen (s_serv) + 1;
    *data = vpn = GNUNET_malloc (*data_size);
    if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char*)&s_peer,
						     &vpn->peer))
    {
      GNUNET_free (vpn);
      *data_size = 0;
      return GNUNET_SYSERR;
    }
    vpn->proto = htons ((uint16_t) proto);
    strcpy ((char*)&vpn[1], s_serv);
    return GNUNET_OK;
  case GNUNET_DNSPARSER_TYPE_TLSA:
    *data_size = sizeof (struct tlsa_data) + strlen (s) - 6;
    *data = tlsa = GNUNET_malloc (*data_size);
    if (4 != SSCANF (s, "%c %c %c %s",
		     &tlsa->usage,
		     &tlsa->selector,
		     &tlsa->matching_type,
		     (char*)&tlsa[1]))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Unable to parse TLSA record string `%s'\n"), 
		  s);
      *data_size = 0;
      GNUNET_free (tlsa);
      return GNUNET_SYSERR;
    }
    return GNUNET_OK;
  default:
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		_("Unsupported record type %d\n"),
		(int) type);
    return GNUNET_SYSERR;
  }
}
Ejemplo n.º 6
0
/**
 * Function called when we receive a message from the VPN service.
 *
 * @param cls the 'struct GNUNET_VPN_Handle'
 * @param msg message received, NULL on timeout or fatal error
 */
static void 
receive_response (void *cls,
		  const struct GNUNET_MessageHeader* msg)
{
  struct GNUNET_VPN_Handle *vh = cls;
  const struct RedirectToIpResponseMessage *rm;
  struct GNUNET_VPN_RedirectionRequest *rr;
  size_t msize;
  size_t alen;
  int af;

  if (NULL == msg) 
  {
    reconnect (vh);
    return;
  }
  if ( (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_VPN_CLIENT_USE_IP) ||
       (sizeof (struct RedirectToIpResponseMessage) > (msize = ntohs (msg->size))) )
  {
    GNUNET_break (0);
    reconnect (vh);
    return;
  }
  rm = (const struct RedirectToIpResponseMessage *) msg;
  af = (int) ntohl (rm->result_af);
  switch (af)
  {
  case AF_UNSPEC:
    alen = 0;
    break;
  case AF_INET:
    alen = sizeof (struct in_addr);
    break;
  case AF_INET6:
    alen = sizeof (struct in6_addr);
    break;
  default:
    GNUNET_break (0);
    reconnect (vh);
    return;
  }
  if ( (msize != alen + sizeof (struct RedirectToIpResponseMessage)) ||
       (0 == rm->request_id) )
  {
    GNUNET_break (0);
    reconnect (vh);
    return;
  }  
  GNUNET_CLIENT_receive (vh->client,
			 &receive_response, vh,
			 GNUNET_TIME_UNIT_FOREVER_REL);      
  for (rr = vh->rr_head; NULL != rr; rr = rr->next)
  {
    if (rr->request_id == rm->request_id)
    {
      GNUNET_CONTAINER_DLL_remove (vh->rr_head,
				   vh->rr_tail,
				   rr);
      rr->cb (rr->cb_cls,
	      af,
	      (af == AF_UNSPEC) ? NULL : &rm[1]);
      GNUNET_free (rr);
      break;
    }
  }
}
Ejemplo n.º 7
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]);
        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;%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_cost_lan,
            plt->ats_cost_wan,
            plt->ats_cost_wlan,
            plt->ats_delay,
            plt->ats_distance,
            plt->ats_network_type,
            plt->ats_utilization_up,
            plt->ats_utilization_down,
            plt->pref_bandwidth,
            plt->pref_delay);

        if (l->verbose)
          fprintf (stderr,
              "\t Slave [%u]: %u %u %u ; %u %u %u rtt %u delay %u 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,
              plt->ats_delay,
              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);
        return;
      }
      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 (GNUNET_ERROR_TYPE_ERROR,
          "Cannot close log file `%s'\n", 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);
    }
  }

}
/**
 * Solves the MLP problem
 *
 * @param mlp the MLP Handle
 * @param ctx solution context
 * @return GNUNET_OK if could be solved, GNUNET_SYSERR on failure
 */
int
GAS_mlp_solve_problem (struct GAS_MLP_Handle *mlp, struct GAS_MLP_SolutionContext *ctx)
{
  int res;
  /* Check if solving is already running */
  if (GNUNET_YES == mlp->semaphore)
  {
    if (mlp->mlp_task != GNUNET_SCHEDULER_NO_TASK)
    {
      GNUNET_SCHEDULER_cancel(mlp->mlp_task);
      mlp->mlp_task = GNUNET_SCHEDULER_NO_TASK;
    }
    mlp->mlp_task = GNUNET_SCHEDULER_add_delayed (mlp->exec_interval, &mlp_scheduler, mlp);
    return GNUNET_SYSERR;
  }
  mlp->semaphore = GNUNET_YES;

  mlp->last_execution = GNUNET_TIME_absolute_get ();

  ctx->lp_result = GNUNET_SYSERR;
  ctx->mlp_result = GNUNET_SYSERR;
  ctx->lp_duration = GNUNET_TIME_UNIT_FOREVER_REL;
  ctx->mlp_duration = GNUNET_TIME_UNIT_FOREVER_REL;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Solve LP problem\n");
#if WRITE_MLP
  char * name;
  static int i;
  i++;
  GNUNET_asprintf(&name, "problem_%i", i);
  glp_write_lp (mlp->prob, 0, name);
  GNUNET_free (name);
# endif

  res = mlp_solve_lp_problem (mlp, ctx);
  ctx->lp_result = res;
  if (res != GNUNET_OK)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "LP Problem solving failed\n");
    mlp->semaphore = GNUNET_NO;
    return GNUNET_SYSERR;
  }

#if WRITE_MLP
  GNUNET_asprintf(&name, "problem_%i_lp_solution", i);
  glp_print_sol (mlp->prob,  name);
  GNUNET_free (name);
# endif


  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Solve MLP problem\n");
  res = mlp_solve_mlp_problem (mlp, ctx);
  ctx->mlp_result = res;
  if (res != GNUNET_OK)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP Problem solving failed\n");
    mlp->semaphore = GNUNET_NO;
    return GNUNET_SYSERR;
  }
#if WRITE_MLP
  GNUNET_asprintf(&name, "problem_%i_mlp_solution", i);
  glp_print_mip (mlp->prob, name);
  GNUNET_free (name);
# endif

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Problem solved %s (LP duration %llu / MLP duration %llu)\n",
      (GNUNET_OK == res) ? "successfully" : "failed", ctx->lp_duration.rel_value, ctx->mlp_duration.rel_value);
  /* Process result */
  struct ATS_Peer *p = NULL;
  struct ATS_Address *a = NULL;
  struct MLP_information *mlpi = NULL;

  for (p = mlp->peer_head; p != NULL; p = p->next)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s'\n", GNUNET_i2s (&p->id));
    for (a = p->head; a != NULL; a = a->next)
    {
      double b = 0.0;
      double n = 0.0;

      mlpi = a->mlp_information;

      b = glp_mip_col_val(mlp->prob, mlpi->c_b);
      mlpi->b = b;

      n = glp_mip_col_val(mlp->prob, mlpi->c_n);
      if (n == 1.0)
        mlpi->n = GNUNET_YES;
      else
        mlpi->n = GNUNET_NO;

      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tAddress %s %f\n",
          (n == 1.0) ? "[x]" : "[ ]", b);
    }
  }

  if (mlp->mlp_task != GNUNET_SCHEDULER_NO_TASK)
  {
    GNUNET_SCHEDULER_cancel(mlp->mlp_task);
    mlp->mlp_task = GNUNET_SCHEDULER_NO_TASK;
  }
  mlp->mlp_task = GNUNET_SCHEDULER_add_delayed (mlp->exec_interval, &mlp_scheduler, mlp);
  mlp->semaphore = GNUNET_NO;
  return res;
}
/**
 * Init the MLP problem solving component
 *
 * @param cfg the GNUNET_CONFIGURATION_Handle handle
 * @param stats the GNUNET_STATISTICS handle
 * @param max_duration maximum numbers of iterations for the LP/MLP Solver
 * @param max_iterations maximum time limit for the LP/MLP Solver
 * @return struct GAS_MLP_Handle * on success, NULL on fail
 */
struct GAS_MLP_Handle *
GAS_mlp_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
              const struct GNUNET_STATISTICS_Handle *stats,
              struct GNUNET_TIME_Relative max_duration,
              unsigned int max_iterations)
{
  struct GAS_MLP_Handle * mlp = GNUNET_malloc (sizeof (struct GAS_MLP_Handle));

  double D;
  double R;
  double U;
  unsigned long long tmp;
  unsigned int b_min;
  unsigned int n_min;
  struct GNUNET_TIME_Relative i_exec;
  int c;
  char * quota_out_str;
  char * quota_in_str;

  /* Init GLPK environment */
  int res = glp_init_env();
  switch (res) {
    case 0:
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GLPK: `%s'\n",
          "initialization successful");
      break;
    case 1:
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GLPK: `%s'\n",
          "environment is already initialized");
      break;
    case 2:
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not init GLPK: `%s'\n",
          "initialization failed (insufficient memory)");
      GNUNET_free(mlp);
      return NULL;
      break;
    case 3:
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not init GLPK: `%s'\n",
          "initialization failed (unsupported programming model)");
      GNUNET_free(mlp);
      return NULL;
      break;
    default:
      break;
  }

  /* Create initial MLP problem */
  mlp->prob = glp_create_prob();
  GNUNET_assert (mlp->prob != NULL);

  mlp->BIG_M = (double) BIG_M_VALUE;

  /* Get diversity coefficient from configuration */
  if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats",
                                                      "COEFFICIENT_D",
                                                      &tmp))
    D = (double) tmp / 100;
  else
    D = 1.0;

  /* Get proportionality coefficient from configuration */
  if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats",
                                                      "COEFFICIENT_R",
                                                      &tmp))
    R = (double) tmp / 100;
  else
    R = 1.0;

  /* Get utilization coefficient from configuration */
  if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats",
                                                      "COEFFICIENT_U",
                                                      &tmp))
    U = (double) tmp / 100;
  else
    U = 1.0;

  /* Get quality metric coefficients from configuration */
  int i_delay = -1;
  int i_distance = -1;
  int q[GNUNET_ATS_QualityPropertiesCount] = GNUNET_ATS_QualityProperties;
  for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
  {
    /* initialize quality coefficients with default value 1.0 */
    mlp->co_Q[c] = 1.0;

    mlp->q[c] = q[c];
    if (q[c] == GNUNET_ATS_QUALITY_NET_DELAY)
      i_delay = c;
    if (q[c] == GNUNET_ATS_QUALITY_NET_DISTANCE)
      i_distance = c;
  }

  if ((i_delay != -1) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats",
                                                      "COEFFICIENT_QUALITY_DELAY",
                                                      &tmp)))

    mlp->co_Q[i_delay] = (double) tmp / 100;
  else
    mlp->co_Q[i_delay] = 1.0;

  if ((i_distance != -1) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats",
                                                      "COEFFICIENT_QUALITY_DISTANCE",
                                                      &tmp)))
    mlp->co_Q[i_distance] = (double) tmp / 100;
  else
    mlp->co_Q[i_distance] = 1.0;

  /* Get minimum bandwidth per used address from configuration */
  if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats",
                                                      "MIN_BANDWIDTH",
                                                      &tmp))
    b_min = tmp;
  else
  {
    b_min = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
  }

  /* Get minimum number of connections from configuration */
  if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats",
                                                      "MIN_CONNECTIONS",
                                                      &tmp))
    n_min = tmp;
  else
    n_min = 4;

  /* Init network quotas */
  int quotas[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType;
  for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++)
  {
    mlp->quota_index[c] = quotas[c];
    static char * entry_in = NULL;
    static char * entry_out = NULL;
    unsigned long long quota_in = 0;
    unsigned long long quota_out = 0;

    switch (quotas[c]) {
      case GNUNET_ATS_NET_UNSPECIFIED:
        entry_out = "UNSPECIFIED_QUOTA_OUT";
        entry_in = "UNSPECIFIED_QUOTA_IN";
        break;
      case GNUNET_ATS_NET_LOOPBACK:
        entry_out = "LOOPBACK_QUOTA_OUT";
        entry_in = "LOOPBACK_QUOTA_IN";
        break;
      case GNUNET_ATS_NET_LAN:
        entry_out = "LAN_QUOTA_OUT";
        entry_in = "LAN_QUOTA_IN";
        break;
      case GNUNET_ATS_NET_WAN:
        entry_out = "WAN_QUOTA_OUT";
        entry_in = "WAN_QUOTA_IN";
        break;
      case GNUNET_ATS_NET_WLAN:
        entry_out = "WLAN_QUOTA_OUT";
        entry_in = "WLAN_QUOTA_IN";
        break;
      default:
        break;
    }

    if ((entry_in == NULL) || (entry_out == NULL))
      continue;

    if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_out, &quota_out_str))
    {
      if (0 == strcmp(quota_out_str, BIG_M_STRING) ||
          (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, &quota_out)))
        quota_out = mlp->BIG_M;

      GNUNET_free (quota_out_str);
      quota_out_str = NULL;
    }
    else if (GNUNET_ATS_NET_UNSPECIFIED == quotas[c])
    {
      quota_out = mlp->BIG_M;
    }
    else
    {
      quota_out = mlp->BIG_M;
    }

    if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_in, &quota_in_str))
    {
      if (0 == strcmp(quota_in_str, BIG_M_STRING) ||
          (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &quota_in)))
        quota_in = mlp->BIG_M;

      GNUNET_free (quota_in_str);
      quota_in_str = NULL;
    }
    else if (GNUNET_ATS_NET_UNSPECIFIED == quotas[c])
    {
      quota_in = mlp->BIG_M;
    }
    else
    {
      quota_in = mlp->BIG_M;
    }

    /* Check if defined quota could make problem unsolvable */
    if (((n_min * b_min) > quota_out) && (GNUNET_ATS_NET_UNSPECIFIED != quotas[c]))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Inconsistent quota configuration value `%s': " 
		  "outbound quota (%u Bps) too small for combination of minimum connections and minimum bandwidth per peer (%u * %u Bps = %u)\n", entry_out, quota_out, n_min, b_min, n_min * b_min);

      GAS_mlp_done(mlp);
      mlp = NULL;
      return NULL;
    }

    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found `%s' quota %llu and `%s' quota %llu\n",
                entry_out, quota_out, entry_in, quota_in);
    GNUNET_STATISTICS_update ((struct GNUNET_STATISTICS_Handle *) stats, entry_out, quota_out, GNUNET_NO);
    GNUNET_STATISTICS_update ((struct GNUNET_STATISTICS_Handle *) stats, entry_in, quota_in, GNUNET_NO);
    mlp->quota_out[c] = quota_out;
    mlp->quota_in[c] = quota_in;
  }

  /* Get minimum number of connections from configuration */
  if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (cfg, "ats",
                                                        "ATS_EXEC_INTERVAL",
                                                        &i_exec))
    mlp->exec_interval = i_exec;
  else
    mlp->exec_interval = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 30);

  mlp->stats = (struct GNUNET_STATISTICS_Handle *) stats;
  mlp->max_iterations = max_iterations;
  mlp->max_exec_duration = max_duration;
  mlp->auto_solve = GNUNET_YES;

  /* Redirect GLPK output to GNUnet logging */
  glp_error_hook((void *) mlp, &mlp_term_hook);

  /* Init LP solving parameters */
  glp_init_smcp(&mlp->control_param_lp);

  mlp->control_param_lp.msg_lev = GLP_MSG_OFF;
#if VERBOSE_GLPK
  mlp->control_param_lp.msg_lev = GLP_MSG_ALL;
#endif

  mlp->control_param_lp.it_lim = max_iterations;
  mlp->control_param_lp.tm_lim = max_duration.rel_value;

  /* Init MLP solving parameters */
  glp_init_iocp(&mlp->control_param_mlp);

  mlp->control_param_mlp.msg_lev = GLP_MSG_OFF;
#if VERBOSE_GLPK
  mlp->control_param_mlp.msg_lev = GLP_MSG_ALL;
#endif
  mlp->control_param_mlp.tm_lim = max_duration.rel_value;

  mlp->last_execution = GNUNET_TIME_UNIT_FOREVER_ABS;

  mlp->co_D = D;
  mlp->co_R = R;
  mlp->co_U = U;
  mlp->b_min = b_min;
  mlp->n_min = n_min;
  mlp->m_q = GNUNET_ATS_QualityPropertiesCount;
  mlp->semaphore = GNUNET_NO;
  return mlp;
}
Ejemplo n.º 10
0
/**
 * Iterate over all entries in a directory.  Note that directories
 * are structured such that it is possible to iterate over the
 * individual blocks as well as over the entire directory.  Thus
 * a client can call this function on the buffer in the
 * GNUNET_FS_ProgressCallback.  Also, directories can optionally
 * include the contents of (small) files embedded in the directory
 * itself; for those files, the processor may be given the
 * contents of the file directly by this function.
 * <p>
 *
 * Note that this function maybe called on parts of directories.  Thus
 * parser errors should not be reported _at all_ (with GNUNET_break).
 * Still, if some entries can be recovered despite these parsing
 * errors, the function should try to do this.
 *
 * @param size number of bytes in data
 * @param data pointer to the beginning of the directory
 * @param offset offset of data in the directory
 * @param dep function to call on each entry
 * @param dep_cls closure for dep
 * @return GNUNET_OK if this could be a block in a directory,
 *         GNUNET_NO if this could be part of a directory (but not 100% OK)
 *         GNUNET_SYSERR if 'data' does not represent a directory
 */
int
GNUNET_FS_directory_list_contents (size_t size, const void *data,
                                   uint64_t offset,
                                   GNUNET_FS_DirectoryEntryProcessor dep,
                                   void *dep_cls)
{
  struct GetFullDataClosure full_data;
  const char *cdata = data;
  char *emsg;
  uint64_t pos;
  uint64_t align;
  uint32_t mdSize;
  uint64_t epos;
  struct GNUNET_FS_Uri *uri;
  struct GNUNET_CONTAINER_MetaData *md;
  char *filename;

  if ((offset == 0) &&
      ((size < 8 + sizeof (uint32_t)) ||
       (0 != memcmp (cdata, GNUNET_FS_DIRECTORY_MAGIC, 8))))
    return GNUNET_SYSERR;
  pos = offset;
  if (offset == 0)
  {
    GNUNET_memcpy (&mdSize, &cdata[8], sizeof (uint32_t));
    mdSize = ntohl (mdSize);
    if (mdSize > size - 8 - sizeof (uint32_t))
    {
      /* invalid size */
      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                  _("MAGIC mismatch.  This is not a GNUnet directory.\n"));
      return GNUNET_SYSERR;
    }
    md = GNUNET_CONTAINER_meta_data_deserialize (&cdata[8 + sizeof (uint32_t)],
                                                 mdSize);
    if (md == NULL)
    {
      GNUNET_break (0);
      return GNUNET_SYSERR;     /* malformed ! */
    }
    dep (dep_cls, NULL, NULL, md, 0, NULL);
    GNUNET_CONTAINER_meta_data_destroy (md);
    pos = 8 + sizeof (uint32_t) + mdSize;
  }
  while (pos < size)
  {
    /* find end of URI */
    if (cdata[pos] == '\0')
    {
      /* URI is never empty, must be end of block,
       * skip to next alignment */
      align = ((pos / DBLOCK_SIZE) + 1) * DBLOCK_SIZE;
      if (align == pos)
      {
        /* if we were already aligned, still skip a block! */
        align += DBLOCK_SIZE;
      }
      pos = align;
      if (pos >= size)
      {
        /* malformed - or partial download... */
        break;
      }
    }
    epos = pos;
    while ((epos < size) && (cdata[epos] != '\0'))
      epos++;
    if (epos >= size)
      return GNUNET_NO;         /* malformed - or partial download */

    uri = GNUNET_FS_uri_parse (&cdata[pos], &emsg);
    pos = epos + 1;
    if (uri == NULL)
    {
      GNUNET_free (emsg);
      pos--;                    /* go back to '\0' to force going to next alignment */
      continue;
    }
    if (GNUNET_FS_uri_test_ksk (uri))
    {
      GNUNET_FS_uri_destroy (uri);
      GNUNET_break (0);
      return GNUNET_NO;         /* illegal in directory! */
    }

    GNUNET_memcpy (&mdSize, &cdata[pos], sizeof (uint32_t));
    mdSize = ntohl (mdSize);
    pos += sizeof (uint32_t);
    if (pos + mdSize > size)
    {
      GNUNET_FS_uri_destroy (uri);
      return GNUNET_NO;         /* malformed - or partial download */
    }

    md = GNUNET_CONTAINER_meta_data_deserialize (&cdata[pos], mdSize);
    if (md == NULL)
    {
      GNUNET_FS_uri_destroy (uri);
      GNUNET_break (0);
      return GNUNET_NO;         /* malformed ! */
    }
    pos += mdSize;
    filename =
        GNUNET_CONTAINER_meta_data_get_by_type (md,
                                                EXTRACTOR_METATYPE_GNUNET_ORIGINAL_FILENAME);
    full_data.size = 0;
    full_data.data = NULL;
    GNUNET_CONTAINER_meta_data_iterate (md, &find_full_data, &full_data);
    if (dep != NULL)
    {
      dep (dep_cls, filename, uri, md, full_data.size, full_data.data);
    }
    GNUNET_free_non_null (full_data.data);
    GNUNET_free_non_null (filename);
    GNUNET_CONTAINER_meta_data_destroy (md);
    GNUNET_FS_uri_destroy (uri);
  }
  return GNUNET_OK;
}
Ejemplo n.º 11
0
/**
 * Notify the plan about a peer being no longer available;
 * destroy all entries associated with this peer.
 *
 * @param cp connected peer
 */
void
GSF_plan_notify_peer_disconnect_ (const struct GSF_ConnectedPeer *cp)
{
  const struct GNUNET_PeerIdentity *id;
  struct PeerPlan *pp;
  struct GSF_RequestPlan *rp;
  struct GSF_PendingRequestData *prd;
  struct GSF_PendingRequestPlanBijection *bi;

  id = GSF_connected_peer_get_identity2_ (cp);
  pp = GNUNET_CONTAINER_multihashmap_get (plans, &id->hashPubKey);
  if (NULL == pp)
    return;                     /* nothing was ever planned for this peer */
  GNUNET_assert (GNUNET_YES ==
                 GNUNET_CONTAINER_multihashmap_remove (plans, &id->hashPubKey,
                                                       pp));
  if (NULL != pp->pth)
  {
    GSF_peer_transmit_cancel_ (pp->pth);
    pp->pth = NULL;
  }
  if (GNUNET_SCHEDULER_NO_TASK != pp->task)
  {
    GNUNET_SCHEDULER_cancel (pp->task);
    pp->task = GNUNET_SCHEDULER_NO_TASK;
  }
  while (NULL != (rp = GNUNET_CONTAINER_heap_remove_root (pp->priority_heap)))
  {
    GNUNET_break (GNUNET_YES ==
                  GNUNET_CONTAINER_multihashmap_remove (pp->plan_map,
                                                        get_rp_key (rp), rp));
    while (NULL != (bi = rp->pe_head))
    {
      GNUNET_CONTAINER_MDLL_remove (PE, rp->pe_head, rp->pe_tail, bi);
      prd = GSF_pending_request_get_data_ (bi->pr);
      GNUNET_CONTAINER_MDLL_remove (PR, prd->pr_head, prd->pr_tail, bi);
      GNUNET_free (bi);
    }
    plan_count--;
    GNUNET_free (rp);
  }
  GNUNET_CONTAINER_heap_destroy (pp->priority_heap);
  while (NULL != (rp = GNUNET_CONTAINER_heap_remove_root (pp->delay_heap)))
  {
    GNUNET_break (GNUNET_YES ==
                  GNUNET_CONTAINER_multihashmap_remove (pp->plan_map,
                                                        get_rp_key (rp), rp));
    while (NULL != (bi = rp->pe_head))
    {
      prd = GSF_pending_request_get_data_ (bi->pr);
      GNUNET_CONTAINER_MDLL_remove (PE, rp->pe_head, rp->pe_tail, bi);
      GNUNET_CONTAINER_MDLL_remove (PR, prd->pr_head, prd->pr_tail, bi);
      GNUNET_free (bi);
    }
    plan_count--;
    GNUNET_free (rp);
  }
  GNUNET_STATISTICS_set (GSF_stats, gettext_noop ("# query plan entries"),
                         plan_count, GNUNET_NO);
  GNUNET_CONTAINER_heap_destroy (pp->delay_heap);
  GNUNET_CONTAINER_multihashmap_destroy (pp->plan_map);
  GNUNET_free (pp);
}
Ejemplo n.º 12
0
/**
 * Handler for #GNUNET_MESSAGE_TYPE_TESTBED_CREATEPEER messages
 *
 * @param cls identification of the client
 * @param msg the actual message
 */
void
handle_peer_create (void *cls,
                    const struct GNUNET_TESTBED_PeerCreateMessage *msg)
{
  struct GNUNET_SERVICE_Client *client = cls;
  struct GNUNET_MQ_Envelope *env;
  struct GNUNET_TESTBED_PeerCreateSuccessEventMessage *reply;
  struct GNUNET_CONFIGURATION_Handle *cfg;
  struct ForwardedOperationContext *fo_ctxt;
  struct Route *route;
  struct Peer *peer;
  char *emsg;
  uint32_t host_id;
  uint32_t peer_id;

  host_id = ntohl (msg->host_id);
  peer_id = ntohl (msg->peer_id);
  if (VALID_PEER_ID (peer_id))
  {
    (void) GNUNET_asprintf (&emsg,
                            "Peer with ID %u already exists",
                            peer_id);
    GST_send_operation_fail_msg (client,
                                 GNUNET_ntohll (msg->operation_id),
                                 emsg);
    GNUNET_free (emsg);
    GNUNET_SERVICE_client_continue (client);
    return;
  }
  if (UINT32_MAX == peer_id)
  {
    GST_send_operation_fail_msg (client,
                                 GNUNET_ntohll (msg->operation_id),
                                 "Cannot create peer with given ID");
    GNUNET_SERVICE_client_continue (client);
    return;
  }
  if (host_id == GST_context->host_id)
  {
    /* We are responsible for this peer */
    cfg = GNUNET_TESTBED_extract_config_ (&msg->header);
    if (NULL == cfg)
    {
      GNUNET_break (0);
      GNUNET_SERVICE_client_drop (client);
      return;
    }
    GNUNET_CONFIGURATION_set_value_number (cfg,
                                           "TESTBED",
                                           "PEERID",
                                           (unsigned long long) peer_id);

    GNUNET_CONFIGURATION_set_value_number (cfg,
                                           "PATHS",
                                           "PEERID",
                                           (unsigned long long) peer_id);
    peer = GNUNET_new (struct Peer);
    peer->is_remote = GNUNET_NO;
    peer->details.local.cfg = cfg;
    peer->id = peer_id;
    LOG_DEBUG ("Creating peer with id: %u\n",
               (unsigned int) peer->id);
    peer->details.local.peer =
        GNUNET_TESTING_peer_configure (GST_context->system,
                                       peer->details.local.cfg, peer->id,
                                       NULL /* Peer id */ ,
                                       &emsg);
    if (NULL == peer->details.local.peer)
    {
      LOG (GNUNET_ERROR_TYPE_WARNING,
           "Configuring peer failed: %s\n",
           emsg);
      GNUNET_free (emsg);
      GNUNET_free (peer);
      GNUNET_break (0);
      GNUNET_SERVICE_client_drop (client);
      return;
    }
    peer->details.local.is_running = GNUNET_NO;
    peer_list_add (peer);
    env = GNUNET_MQ_msg (reply,
                         GNUNET_MESSAGE_TYPE_TESTBED_CREATE_PEER_SUCCESS);
    reply->peer_id = msg->peer_id;
    reply->operation_id = msg->operation_id;
    GNUNET_MQ_send (GNUNET_SERVICE_client_get_mq (client),
                    env);
    GNUNET_SERVICE_client_continue (client);
    return;
  }
Ejemplo n.º 13
0
/**
 * Test if the service is running.  If we are given a UNIXPATH or a local address,
 * we do this NOT by trying to connect to the service, but by trying to BIND to
 * the same port.  If the BIND fails, we know the service is running.
 *
 * @param service name of the service to wait for
 * @param cfg configuration to use
 * @param timeout how long to wait at most
 * @param task task to run if service is running
 *        (reason will be "PREREQ_DONE" (service running)
 *         or "TIMEOUT" (service not known to be running))
 * @param task_cls closure for task
 */
void
GNUNET_CLIENT_service_test (const char *service,
                            const struct GNUNET_CONFIGURATION_Handle *cfg,
                            struct GNUNET_TIME_Relative timeout,
                            GNUNET_SCHEDULER_Task task, void *task_cls)
{
  char *hostname;
  unsigned long long port;
  struct GNUNET_NETWORK_Handle *sock;
  struct GNUNET_CLIENT_Connection *client;

  LOG (GNUNET_ERROR_TYPE_DEBUG, "Testing if service `%s' is running.\n",
       service);
#ifdef AF_UNIX
  {
    /* probe UNIX support */
    struct sockaddr_un s_un;
    size_t slen;
    char *unixpath;

    unixpath = NULL;
    if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service, "UNIXPATH", &unixpath)) && (0 < strlen (unixpath)))  /* We have a non-NULL unixpath, does that mean it's valid? */
    {
      if (strlen (unixpath) >= sizeof (s_un.sun_path))
      {
        LOG (GNUNET_ERROR_TYPE_WARNING,
             _("UNIXPATH `%s' too long, maximum length is %llu\n"), unixpath,
             (unsigned long long) sizeof (s_un.sun_path));
	unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
        LOG (GNUNET_ERROR_TYPE_INFO,
             _("Using `%s' instead\n"), unixpath);
      }
    }
    if (NULL != unixpath)
    {
      sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0);
      if (NULL != sock)
      {
	memset (&s_un, 0, sizeof (s_un));
	s_un.sun_family = AF_UNIX;
	slen = strlen (unixpath) + 1;
	if (slen >= sizeof (s_un.sun_path))
	  slen = sizeof (s_un.sun_path) - 1;
	memcpy (s_un.sun_path, unixpath, slen);
	s_un.sun_path[slen] = '\0';
	slen = sizeof (struct sockaddr_un);
#if LINUX
	s_un.sun_path[0] = '\0';
#endif
#if HAVE_SOCKADDR_IN_SIN_LEN
	s_un.sun_len = (u_char) slen;
#endif
	if (GNUNET_OK !=
	    GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_un,
					slen))
        {
	  /* failed to bind => service must be running */
	  GNUNET_free (unixpath);
	  (void) GNUNET_NETWORK_socket_close (sock);
	  GNUNET_SCHEDULER_add_continuation (task, task_cls,
					     GNUNET_SCHEDULER_REASON_PREREQ_DONE);
	  return;
	}
	(void) GNUNET_NETWORK_socket_close (sock);        
        /* let's try IP */
      }
    }
    GNUNET_free_non_null (unixpath);
  }
#endif

  hostname = NULL;
  if ((GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_number (cfg, service, "PORT", &port)) ||
      (port > 65535) ||
      (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_string (cfg, service, "HOSTNAME",
                                              &hostname)))
  {
    /* UNIXPATH failed (if possible) AND IP failed => error */
    service_test_error (task, task_cls);
    return;
  }

  if (0 == strcmp ("localhost", hostname)
#if !LINUX
      && 0
#endif
      )
  {
    /* can test using 'bind' */
    struct sockaddr_in s_in;

    memset (&s_in, 0, sizeof (s_in));
#if HAVE_SOCKADDR_IN_SIN_LEN
    s_in.sin_len = sizeof (struct sockaddr_in);
#endif
    s_in.sin_family = AF_INET;
    s_in.sin_port = htons (port);

    sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
    if (NULL != sock)
    {
      if (GNUNET_OK !=
          GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in,
                                      sizeof (s_in)))
      {
        /* failed to bind => service must be running */
        GNUNET_free (hostname);
        (void) GNUNET_NETWORK_socket_close (sock);
        GNUNET_SCHEDULER_add_continuation (task, task_cls,
                                           GNUNET_SCHEDULER_REASON_PREREQ_DONE);
        return;
      }
      (void) GNUNET_NETWORK_socket_close (sock);
    }
  }

  if (0 == strcmp ("ip6-localhost", hostname)
#if !LINUX
      && 0
#endif
      )
  {
    /* can test using 'bind' */
    struct sockaddr_in6 s_in6;

    memset (&s_in6, 0, sizeof (s_in6));
#if HAVE_SOCKADDR_IN_SIN_LEN
    s_in6.sin6_len = sizeof (struct sockaddr_in6);
#endif
    s_in6.sin6_family = AF_INET6;
    s_in6.sin6_port = htons (port);

    sock = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0);
    if (NULL != sock)
    {
      if (GNUNET_OK !=
          GNUNET_NETWORK_socket_bind (sock, (const struct sockaddr *) &s_in6,
                                      sizeof (s_in6)))
      {
        /* failed to bind => service must be running */
        GNUNET_free (hostname);
        (void) GNUNET_NETWORK_socket_close (sock);
        GNUNET_SCHEDULER_add_continuation (task, task_cls,
                                           GNUNET_SCHEDULER_REASON_PREREQ_DONE);
        return;
      }
      (void) GNUNET_NETWORK_socket_close (sock);
    }
  }

  if (((0 == strcmp ("localhost", hostname)) ||
       (0 == strcmp ("ip6-localhost", hostname)))
#if !LINUX
      && 0
#endif
      )
  {
    /* all binds succeeded => claim service not running right now */
    GNUNET_free_non_null (hostname);
    service_test_error (task, task_cls);
    return;
  }
  GNUNET_free_non_null (hostname);

  /* non-localhost, try 'connect' method */
  client = GNUNET_CLIENT_connect (service, cfg);
  if (NULL == client)
  {
    LOG (GNUNET_ERROR_TYPE_INFO,
         _("Could not connect to service `%s', must not be running.\n"),
         service);
    service_test_error (task, task_cls);
    return;
  }
  client->test_cb = task;
  client->test_cb_cls = task_cls;
  client->test_deadline = GNUNET_TIME_relative_to_absolute (timeout);
  if (NULL == GNUNET_CLIENT_notify_transmit_ready (client,
						   sizeof (struct GNUNET_MessageHeader),
						   timeout, GNUNET_YES, &write_test,
						   client))
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
         _("Failure to transmit request to service `%s'\n"), service);
    service_test_error (task, task_cls);
    GNUNET_CLIENT_disconnect (client);
    return;
  }
}
Ejemplo n.º 14
0
/**
 * Try to connect to the service.
 *
 * @param service_name name of service to connect to
 * @param cfg configuration to use
 * @param attempt counter used to alternate between IP and UNIX domain sockets
 * @return NULL on error
 */
static struct GNUNET_CONNECTION_Handle *
do_connect (const char *service_name,
            const struct GNUNET_CONFIGURATION_Handle *cfg, unsigned int attempt)
{
  struct GNUNET_CONNECTION_Handle *connection;
  char *hostname;
  unsigned long long port;

  connection = NULL;
  if (0 == (attempt % 2))
  {
    /* on even rounds, try UNIX first */
    connection = try_unixpath (service_name, cfg);
    if (NULL != connection)
      return connection;
  }
  if (GNUNET_YES ==
      GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT"))
  {
    if ((GNUNET_OK !=
	 GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "PORT", &port))
	|| (port > 65535) ||
	(GNUNET_OK !=
	 GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "HOSTNAME",
						&hostname)))
    {
      LOG (GNUNET_ERROR_TYPE_WARNING,
	   _
	   ("Could not determine valid hostname and port for service `%s' from configuration.\n"),
	   service_name);
      return NULL;
    }
    if (0 == strlen (hostname))
    {
      GNUNET_free (hostname);
      LOG (GNUNET_ERROR_TYPE_WARNING,
	   _("Need a non-empty hostname for service `%s'.\n"), service_name);
      return NULL;
    }
  }
  else
  {
    /* unspecified means 0 (disabled) */
    port = 0;
    hostname = NULL;
  }
  if (0 == port)
  {
    /* if port is 0, try UNIX */
    connection = try_unixpath (service_name, cfg);
    if (NULL != connection)
      return connection;
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Port is 0 for service `%s', UNIXPATH did not work, returning NULL!\n",
         service_name);
    GNUNET_free_non_null (hostname);
    return NULL;
  }
  connection = GNUNET_CONNECTION_create_from_connect (cfg, hostname, port);
  GNUNET_free (hostname);
  return connection;
}
static void
check (void *cls, char *const *args, const char *cfgfile,
       const struct GNUNET_CONFIGURATION_Handle *cfg)
{
#if !HAVE_LIBGLPK
  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GLPK not installed!");
  ret = 1;
  return;
#endif
  struct ATS_Address addr[10];
  struct ATS_PreferedAddress *res[10];
  struct MLP_information *mlpi;
  struct GAS_MLP_SolutionContext ctx;

  stats = GNUNET_STATISTICS_create("ats", cfg);

  addresses = GNUNET_CONTAINER_multihashmap_create (10);

  mlp = GAS_mlp_init (cfg, NULL, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS);
  mlp->auto_solve = GNUNET_NO;

  struct GNUNET_PeerIdentity p[10];

  /* Creating peer 1 */
  GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_WEAK, &p[0].hashPubKey);

  /* Creating peer 1 address 1 */
  addr[0].peer.hashPubKey = p[0].hashPubKey;
  struct GNUNET_ATS_Information a1_ats[3];
  set_ats (&a1_ats[0], GNUNET_ATS_QUALITY_NET_DISTANCE, 1);
  set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 0);
  set_ats (&a1_ats[2], GNUNET_ATS_ARRAY_TERMINATOR, 0);
  create_address (&addr[0], "dummy", 3, &a1_ats[0]);
  addr[0].atsp_network_type = GNUNET_ATS_NET_LAN;

  GNUNET_CONTAINER_multihashmap_put(addresses, &addr[0].peer.hashPubKey, &addr[0], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);

  /* Add peer 1 address 1 */
  GAS_mlp_address_update (mlp, addresses, &addr[0]);
  mlpi = addr[0].mlp_information;

  GNUNET_assert (mlp != NULL);
  GNUNET_assert (mlp->addr_in_problem == 1);

  /* Update an peer 1 address 1  */
  set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 20);
  GAS_mlp_address_update (mlp, addresses, &addr[0]);
  GNUNET_assert (mlp->addr_in_problem == 1);


  /* Update an peer 1 address 1  */
  set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 10);
  GAS_mlp_address_update (mlp, addresses, &addr[0]);
  GNUNET_assert (mlp->addr_in_problem == 1);

  /* Update an peer 1 address 1  */
  set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 10);
  GAS_mlp_address_update (mlp, addresses, &addr[0]);
  GNUNET_assert (mlp->addr_in_problem == 1);

  /* Update an peer 1 address 1  */
  set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 30);
  GAS_mlp_address_update (mlp, addresses, &addr[0]);
  GNUNET_assert (mlp->addr_in_problem == 1);


  GNUNET_assert (GNUNET_OK == GAS_mlp_solve_problem(mlp, &ctx));
  GNUNET_assert (GNUNET_OK == ctx.lp_result);
  GNUNET_assert (GNUNET_OK == ctx.mlp_result);

  res[0] = GAS_mlp_get_preferred_address(mlp, addresses, &p[0]);
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Preferred address `%s' outbound bandwidth: %u Bps\n",res[0]->address->plugin, res[0]->bandwidth_out);
  GNUNET_free (res[0]);

  /* Delete an address */
  GNUNET_CONTAINER_multihashmap_remove (addresses, &addr[0].peer.hashPubKey, &addr[0]);
  GAS_mlp_address_delete (mlp, addresses, &addr[0]);

  GNUNET_assert (mlp->addr_in_problem == 0);

  GAS_mlp_done (mlp);

  GNUNET_free (addr[0].plugin);
  GNUNET_CONTAINER_multihashmap_destroy (addresses);
  GNUNET_STATISTICS_destroy(stats, GNUNET_NO);

  ret = 0;
  return;
}
static void
update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address)
{
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality metrics for peer `%s'\n",
      GNUNET_i2s (&address->peer));

  GNUNET_assert (NULL != address);
  GNUNET_assert (NULL != address->mlp_information);
  GNUNET_assert (NULL != address->ats);

  struct MLP_information *mlpi = address->mlp_information;
  struct GNUNET_ATS_Information *ats = address->ats;
  GNUNET_assert (mlpi != NULL);

  int c;
  for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
  {
    int index = mlp_lookup_ats(address, mlp->q[c]);

    if (index == GNUNET_SYSERR)
      continue;

    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s' value `%s': %f\n",
        GNUNET_i2s (&address->peer),
        mlp_ats_to_string(mlp->q[c]),
        (double) ats[index].value);

    int i = mlpi->q_avg_i[c];
    double * qp = mlpi->q[c];
    qp[i] = (double) ats[index].value;

    int t;
    for (t = 0; t < MLP_AVERAGING_QUEUE_LENGTH; t++)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' queue[%u]: %f\n",
        GNUNET_i2s (&address->peer),
        mlp_ats_to_string(mlp->q[c]),
        t,
        qp[t]);
    }

    if (mlpi->q_avg_i[c] + 1 < (MLP_AVERAGING_QUEUE_LENGTH))
      mlpi->q_avg_i[c] ++;
    else
      mlpi->q_avg_i[c] = 0;


    int c2;
    int c3;
    double avg = 0.0;
    switch (mlp->q[c])
    {
      case GNUNET_ATS_QUALITY_NET_DELAY:
        c3 = 0;
        for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++)
        {
          if (mlpi->q[c][c2] != -1)
          {
            double * t2 = mlpi->q[c] ;
            avg += t2[c2];
            c3 ++;
          }
        }
        if ((c3 > 0) && (avg > 0))
          /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/
          mlpi->q_averaged[c] = (double) c3 / avg;
        else
          mlpi->q_averaged[c] = 0.0;

        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, average: %f, weight: %f\n",
          GNUNET_i2s (&address->peer),
          mlp_ats_to_string(mlp->q[c]),
          avg,
          avg / (double) c3,
          mlpi->q_averaged[c]);

        break;
      case GNUNET_ATS_QUALITY_NET_DISTANCE:
        c3 = 0;
        for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++)
        {
          if (mlpi->q[c][c2] != -1)
          {
            double * t2 = mlpi->q[c] ;
            avg += t2[c2];
            c3 ++;
          }
        }
        if ((c3 > 0) && (avg > 0))
          /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/
          mlpi->q_averaged[c] = (double) c3 / avg;
        else
          mlpi->q_averaged[c] = 0.0;

        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, average: %f, weight: %f\n",
          GNUNET_i2s (&address->peer),
          mlp_ats_to_string(mlp->q[c]),
          avg,
          avg / (double) c3,
          mlpi->q_averaged[c]);

        break;
      default:
        break;
    }

    if ((mlpi->c_b != 0) && (mlpi->r_q[c] != 0))
    {

      /* Get current number of columns */
      int found = GNUNET_NO;
      int cols = glp_get_num_cols(mlp->prob);
      int *ind = GNUNET_malloc (cols * sizeof (int) + 1);
      double *val = GNUNET_malloc (cols * sizeof (double) + 1);

      /* Get the matrix row of quality */
      int length = glp_get_mat_row(mlp->prob, mlp->r_q[c], ind, val);
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "cols %i, length %i c_b %i\n", cols, length, mlpi->c_b);
      int c4;
      /* Get the index if matrix row of quality */
      for (c4 = 1; c4 <= length; c4++ )
      {
        if (mlpi->c_b == ind[c4])
        {
          /* Update the value */
          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality `%s' column `%s' row `%s' : %f -> %f\n",
              mlp_ats_to_string(mlp->q[c]),
              glp_get_col_name (mlp->prob, ind[c4]),
              glp_get_row_name (mlp->prob, mlp->r_q[c]),
              val[c4],
              mlpi->q_averaged[c]);
          val[c4] = mlpi->q_averaged[c];
          found = GNUNET_YES;
          break;
        }
      }

      if (found == GNUNET_NO)
        {

          ind[length+1] = mlpi->c_b;
          val[length+1] = mlpi->q_averaged[c];
          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%i ind[%i] val[%i]:  %i %f\n", length+1,  length+1, length+1, mlpi->c_b, mlpi->q_averaged[c]);
          glp_set_mat_row (mlp->prob, mlpi->r_q[c], length+1, ind, val);
        }
      else
        {
        /* Get the index if matrix row of quality */
        glp_set_mat_row (mlp->prob, mlpi->r_q[c], length, ind, val);
        }

      GNUNET_free (ind);
      GNUNET_free (val);
    }
  }
}
/**
 * Callback called from the zone iterator when we iterate over
 * the empty zone.  Check that we got no records and then
 * start the actual tests by filling the zone.
 */
static void
empty_zone_proc (void *cls,
		 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
		 const char *label,
		 unsigned int rd_count,
		 const struct GNUNET_GNSRECORD_Data *rd)
{
  char *hostkey_file;

  GNUNET_assert (nsh == cls);
  if (NULL != zone)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Expected empty zone but received zone private key\n"));
      GNUNET_break (0);
      if (endbadly_task != NULL)
    	GNUNET_SCHEDULER_cancel (endbadly_task);
      endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
      return;
    }
  if ((NULL != label) || (NULL != rd) || (0 != rd_count))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Expected no zone content but received data\n"));
      GNUNET_break (0);
      if (endbadly_task != NULL)
    	GNUNET_SCHEDULER_cancel (endbadly_task);
      endbadly_task = GNUNET_SCHEDULER_add_now (&endbadly, NULL);
      return;
    }


  zi = NULL;
  GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
      "N0UJMP015AFUNR2BTNM3FKPBLG38913BL8IDMCO2H0A1LIB81960.zkey");
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
  privkey = GNUNET_CRYPTO_ecdsa_key_create_from_file(hostkey_file);
  GNUNET_free (hostkey_file);
  GNUNET_assert (privkey != NULL);

  GNUNET_asprintf(&hostkey_file,"zonefiles%s%s",DIR_SEPARATOR_STR,
      "HGU0A0VCU334DN7F2I9UIUMVQMM7JMSD142LIMNUGTTV9R0CF4EG.zkey");
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Using zonekey file `%s' \n", hostkey_file);
  privkey2 = GNUNET_CRYPTO_ecdsa_key_create_from_file(hostkey_file);
  GNUNET_free (hostkey_file);
  GNUNET_assert (privkey2 != NULL);

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Created record 1\n");

  GNUNET_asprintf(&s_name_1, "dummy1");
  s_rd_1 = create_record(1);
  GNUNET_NAMESTORE_records_store(nsh, privkey, s_name_1,
  		1, s_rd_1, &put_cont, NULL);

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Created record 2 \n");
  GNUNET_asprintf(&s_name_2, "dummy2");
  s_rd_2 = create_record(1);
  GNUNET_NAMESTORE_records_store(nsh, privkey, s_name_2,
  		1, s_rd_2, &put_cont, NULL);

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Created record 3\n");

  /* name in different zone */
  GNUNET_asprintf(&s_name_3, "dummy3");
  s_rd_3 = create_record(1);
  GNUNET_NAMESTORE_records_store(nsh, privkey2, s_name_3,
  		1, s_rd_3, &put_cont, NULL);
}
/**
 * Add constraints that are iterating over "forall addresses"
 * and collects all existing peers for "forall peers" constraints
 *
 * @param cls GAS_MLP_Handle
 * @param key Hashcode
 * @param value ATS_Address
 *
 * @return GNUNET_OK to continue
 */
static int
create_constraint_it (void *cls, const GNUNET_HashCode * key, void *value)
{
  struct GAS_MLP_Handle *mlp = cls;
  struct ATS_Address *address = value;
  struct MLP_information *mlpi;
  unsigned int row_index;
  char *name;

  GNUNET_assert (address->mlp_information != NULL);
  mlpi = (struct MLP_information *) address->mlp_information;

  /* c 1) bandwidth capping
   * b_t  + (-M) * n_t <= 0
   */
  row_index = glp_add_rows (mlp->prob, 1);
  mlpi->r_c1 = row_index;
  /* set row name */
  GNUNET_asprintf(&name, "c1_%s_%s", GNUNET_i2s(&address->peer), address->plugin);
  glp_set_row_name (mlp->prob, row_index, name);
  GNUNET_free (name);
  /* set row bounds: <= 0 */
  glp_set_row_bnds (mlp->prob, row_index, GLP_UP, 0.0, 0.0);
  mlp->ia[mlp->ci] = row_index;
  mlp->ja[mlp->ci] = mlpi->c_b;
  mlp->ar[mlp->ci] = 1;
  mlp->ci++;

  mlp->ia[mlp->ci] = row_index;
  mlp->ja[mlp->ci] = mlpi->c_n;
  mlp->ar[mlp->ci] = -mlp->BIG_M;
  mlp->ci++;

  /* c 3) minimum bandwidth
   * b_t + (-n_t * b_min) >= 0
   */

  row_index = glp_add_rows (mlp->prob, 1);
  /* set row name */
  GNUNET_asprintf(&name, "c3_%s_%s", GNUNET_i2s(&address->peer), address->plugin);
  glp_set_row_name (mlp->prob, row_index, name);
  GNUNET_free (name);
  mlpi->r_c3 = row_index;
  /* set row bounds: >= 0 */
  glp_set_row_bnds (mlp->prob, row_index, GLP_LO, 0.0, 0.0);

  mlp->ia[mlp->ci] = row_index;
  mlp->ja[mlp->ci] = mlpi->c_b;
  mlp->ar[mlp->ci] = 1;
  mlp->ci++;

  mlp->ia[mlp->ci] = row_index;
  mlp->ja[mlp->ci] = mlpi->c_n;
  mlp->ar[mlp->ci] = - (double) mlp->b_min;
  mlp->ci++;

  /* c 4) minimum connections
   * (1)*n_1 + ... + (1)*n_m >= n_min
   */
  mlp->ia[mlp->ci] = mlp->r_c4;
  mlp->ja[mlp->ci] = mlpi->c_n;
  mlp->ar[mlp->ci] = 1;
  mlp->ci++;

  /* c 6) maximize diversity
   * (1)*n_1 + ... + (1)*n_m - d == 0
   */
  mlp->ia[mlp->ci] = mlp->r_c6;
  mlp->ja[mlp->ci] = mlpi->c_n;
  mlp->ar[mlp->ci] = 1;
  mlp->ci++;

  /* c 10) obey network specific quotas
   * (1)*b_1 + ... + (1)*b_m <= quota_n
   */

  int cur_row = 0;
  int c;
  for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++)
    {
    if (mlp->quota_index[c] == address->atsp_network_type)
    {
      cur_row = mlp->r_quota[c];
      break;
    }
  }

  if (cur_row != 0)
  {
    mlp->ia[mlp->ci] = cur_row;
    mlp->ja[mlp->ci] = mlpi->c_b;
    mlp->ar[mlp->ci] = 1;
    mlp->ci++;
  }
  else
  {
    GNUNET_break (0);
  }

  return GNUNET_OK;
}
Ejemplo n.º 19
0
static void
write_throughput_gnuplot_script (char * fn, struct LoggingPeer *lp, char **fs, int slaves)
{
  struct GNUNET_DISK_FileHandle *f;
  char * gfn;
  char *data;
  int c_s;

  GNUNET_asprintf (&gfn, "gnuplot_throughput_%s",fn);
  fprintf (stderr, "Writing throughput plot for master %u and %u slaves to `%s'\n",
      lp->peer->no, slaves, gfn);

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

  /* Write header */
  if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, THROUGHPUT_TEMPLATE,
      strlen(THROUGHPUT_TEMPLATE)))
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
        "Cannot write data to plot file `%s'\n", gfn);

  /* Write master data */
  GNUNET_asprintf (&data,
      "plot '%s' using 2:%u with lines title 'Master %u send total', \\\n" \
      "'%s' using 2:%u with lines title 'Master %u receive total', \\\n",
      fn, LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_SENT, lp->peer->no,
      fn, LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_RECV, lp->peer->no);
  if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, data, strlen(data)))
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn);
  GNUNET_free (data);

  for (c_s = 0; c_s < slaves; c_s++)
  {
    GNUNET_asprintf (&data, "'%s' using 2:%u with lines title 'Master %u - Slave %u send', \\\n" \
        "'%s' using 2:%u with lines title 'Master %u - Slave %u receive'%s\n",
        fs[c_s],
        LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_SENT,
        lp->peer->no,
        lp->peer->partners[c_s].dest->no,
        fs[c_s],
        LOG_ITEMS_TIME + LOG_ITEM_THROUGHPUT_RECV,
        lp->peer->no,
        lp->peer->partners[c_s].dest->no,
        (c_s < lp->peer->num_partners -1) ? ", \\" : "\n pause -1");
    if (GNUNET_SYSERR == GNUNET_DISK_file_write(f, data, strlen(data)))
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot write data to plot file `%s'\n", gfn);
    GNUNET_free (data);
  }

  if (GNUNET_SYSERR == GNUNET_DISK_file_close(f))
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
        "Cannot close gnuplot file `%s'\n", gfn);
  else
    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
        "Data successfully written to plot file `%s'\n", gfn);
  GNUNET_free (gfn);
}
static void
mlp_add_constraints_all_addresses (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHashMap * addresses)
{
  unsigned int n_addresses;
  int c;
  char *name;

  /* Problem matrix*/
  n_addresses = GNUNET_CONTAINER_multihashmap_size(addresses);

  /* Required indices in the constrain matrix
   *
   * feasibility constraints:
   *
   * c 1) bandwidth capping
   * #rows: |n_addresses|
   * #indices: 2 * |n_addresses|
   *
   * c 2) one active address per peer
   * #rows: |peers|
   * #indices: |n_addresses|
   *
   * c 3) minium bandwidth assigned
   * #rows: |n_addresses|
   * #indices: 2 * |n_addresses|
   *
   * c 4) minimum number of active connections
   * #rows: 1
   * #indices: |n_addresses|
   *
   * c 5) maximum ressource consumption
   * #rows: |ressources|
   * #indices: |n_addresses|
   *
   * c 10) obey network specific quota
   * #rows: |network types
   * #indices: |n_addresses|
   *
   * Sum for feasibility constraints:
   * #rows: 3 * |n_addresses| +  |ressources| + |peers| + 1
   * #indices: 7 * |n_addresses|
   *
   * optimality constraints:
   *
   * c 6) diversity
   * #rows: 1
   * #indices: |n_addresses| + 1
   *
   * c 7) quality
   * #rows: |quality properties|
   * #indices: |n_addresses| + |quality properties|
   *
   * c 8) utilization
   * #rows: 1
   * #indices: |n_addresses| + 1
   *
   * c 9) relativity
   * #rows: |peers|
   * #indices: |n_addresses| + |peers|
   * */

  /* last +1 caused by glpk index starting with one: [1..pi]*/
  int pi = ((7 * n_addresses) + (5 * n_addresses +  mlp->m_q + mlp->c_p + 2) + 1);
  mlp->cm_size = pi;
  mlp->ci = 1;

  /* row index */
  int *ia = GNUNET_malloc (pi * sizeof (int));
  mlp->ia = ia;

  /* column index */
  int *ja = GNUNET_malloc (pi * sizeof (int));
  mlp->ja = ja;

  /* coefficient */
  double *ar= GNUNET_malloc (pi * sizeof (double));
  mlp->ar = ar;

  /* Adding constraint rows
   * This constraints are kind of "for all addresses"
   * Feasibility constraints:
   *
   * c 1) bandwidth capping
   * c 3) minimum bandwidth
   * c 4) minimum number of connections
   * c 6) maximize diversity
   * c 10) obey network specific quota
   */

  /* Row for c4) minimum connection */
  int min = mlp->n_min;
  /* Number of minimum connections is min(|Peers|, n_min) */
  if (mlp->n_min > mlp->c_p)
    min = mlp->c_p;

  mlp->r_c4 = glp_add_rows (mlp->prob, 1);
  glp_set_row_name (mlp->prob, mlp->r_c4, "c4");
  glp_set_row_bnds (mlp->prob, mlp->r_c4, GLP_LO, min, min);

  /* Add row for c6) */

  mlp->r_c6 = glp_add_rows (mlp->prob, 1);
  /* Set type type to fix */
  glp_set_row_bnds (mlp->prob, mlp->r_c6, GLP_FX, 0.0, 0.0);
  /* Setting -D */
  ia[mlp->ci] = mlp->r_c6 ;
  ja[mlp->ci] = mlp->c_d;
  ar[mlp->ci] = -1;
  mlp->ci++;

  /* Add rows for c 10) */
  for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++)
  {
    mlp->r_quota[c] = glp_add_rows (mlp->prob, 1);
    char * text;
    GNUNET_asprintf(&text, "quota_ats_%i", mlp->quota_index[c]);
    glp_set_row_name (mlp->prob, mlp->r_quota[c], text);
    GNUNET_free (text);
    /* Set bounds to 0 <= x <= quota_out */
    glp_set_row_bnds (mlp->prob, mlp->r_quota[c], GLP_UP, 0.0, mlp->quota_out[c]);
  }

  GNUNET_CONTAINER_multihashmap_iterate (addresses, create_constraint_it, mlp);

  /* Adding constraint rows
   * This constraints are kind of "for all peers"
   * Feasibility constraints:
   *
   * c 2) 1 address per peer
   * sum (n_p1_1 + ... + n_p1_n) = 1
   *
   * c 8) utilization
   * sum (f_p * b_p1_1 + ... + f_p * b_p1_n) - u = 0
   *
   * c 9) relativity
   * V p : sum (bt_1 + ... +bt_n) - f_p * r = 0
   * */

  /* Adding rows for c 8) */
  mlp->r_c8 = glp_add_rows (mlp->prob, mlp->c_p);
  glp_set_row_name (mlp->prob, mlp->r_c8, "c8");
  /* Set row bound == 0 */
  glp_set_row_bnds (mlp->prob, mlp->r_c8, GLP_FX, 0.0, 0.0);
  /* -u */

  ia[mlp->ci] = mlp->r_c8;
  ja[mlp->ci] = mlp->c_u;
  ar[mlp->ci] = -1;
  mlp->ci++;

  struct ATS_Peer * peer = mlp->peer_head;
  /* For all peers */
  while (peer != NULL)
  {
    struct ATS_Address *addr = peer->head;
    struct MLP_information *mlpi = NULL;

    /* Adding rows for c 2) */
    peer->r_c2 = glp_add_rows (mlp->prob, 1);
    GNUNET_asprintf(&name, "c2_%s", GNUNET_i2s(&peer->id));
    glp_set_row_name (mlp->prob, peer->r_c2, name);
    GNUNET_free (name);
    /* Set row bound == 1 */
    glp_set_row_bnds (mlp->prob, peer->r_c2, GLP_FX, 1.0, 1.0);

    /* Adding rows for c 9) */
#if ENABLE_C9
    peer->r_c9 = glp_add_rows (mlp->prob, 1);
    GNUNET_asprintf(&name, "c9_%s", GNUNET_i2s(&peer->id));
    glp_set_row_name (mlp->prob, peer->r_c9, name);
    GNUNET_free (name);
    /* Set row bound == 0 */
    glp_set_row_bnds (mlp->prob, peer->r_c9, GLP_LO, 0.0, 0.0);

    /* Set -r */
    ia[mlp->ci] = peer->r_c9;
    ja[mlp->ci] = mlp->c_r;
    ar[mlp->ci] = -peer->f;
    mlp->ci++;
#endif
    /* For all addresses of this peer */
    while (addr != NULL)
    {
      mlpi = (struct MLP_information *) addr->mlp_information;

      /* coefficient for c 2) */
      ia[mlp->ci] = peer->r_c2;
      ja[mlp->ci] = mlpi->c_n;
      ar[mlp->ci] = 1;
      mlp->ci++;

      /* coefficient for c 8) */
      ia[mlp->ci] = mlp->r_c8;
      ja[mlp->ci] = mlpi->c_b;
      ar[mlp->ci] = peer->f;
      mlp->ci++;

#if ENABLE_C9
      /* coefficient for c 9) */
      ia[mlp->ci] = peer->r_c9;
      ja[mlp->ci] = mlpi->c_b;
      ar[mlp->ci] = 1;
      mlp->ci++;
#endif

      addr = addr->next;
    }
    peer = peer->next;
  }

  /* c 7) For all quality metrics */
  for (c = 0; c < mlp->m_q; c++)
  {
    struct ATS_Peer *tp;
    struct ATS_Address *ta;
    struct MLP_information * mlpi;
    double value = 1.0;

    /* Adding rows for c 7) */
    mlp->r_q[c] = glp_add_rows (mlp->prob, 1);
    GNUNET_asprintf(&name, "c7_q%i_%s", c, mlp_ats_to_string(mlp->q[c]));
    glp_set_row_name (mlp->prob, mlp->r_q[c], name);
    GNUNET_free (name);
    /* Set row bound == 0 */
    glp_set_row_bnds (mlp->prob, mlp->r_q[c], GLP_FX, 0.0, 0.0);

    ia[mlp->ci] = mlp->r_q[c];
    ja[mlp->ci] = mlp->c_q[c];
    ar[mlp->ci] = -1;
    mlp->ci++;

    for (tp = mlp->peer_head; tp != NULL; tp = tp->next)
      for (ta = tp->head; ta != NULL; ta = ta->next)
        {
          mlpi = ta->mlp_information;
          value = mlpi->q_averaged[c];

          mlpi->r_q[c] = mlp->r_q[c];

          ia[mlp->ci] = mlp->r_q[c];
          ja[mlp->ci] = mlpi->c_b;
          ar[mlp->ci] = tp->f_q[c] * value;
          mlp->ci++;
        }
  }
}
Ejemplo n.º 21
0
/**
 * Iterate over the records given an optional peer id
 * and/or key.
 *
 * @param cls closure (internal context for the plugin)
 * @param sub_system name of sub system
 * @param peer Peer identity (can be NULL)
 * @param key entry key string (can be NULL)
 * @param iter function to call asynchronously with the results, terminated
 * by a NULL result
 * @param iter_cls closure for @a iter
 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error and iter is not
 * called
 */
static int
peerstore_sqlite_iterate_records (void *cls, const char *sub_system,
                                  const struct GNUNET_PeerIdentity *peer,
                                  const char *key,
                                  GNUNET_PEERSTORE_Processor iter,
                                  void *iter_cls)
{
  struct Plugin *plugin = cls;
  sqlite3_stmt *stmt;
  int err = 0;
  int sret;
  struct GNUNET_PEERSTORE_Record *ret;

  LOG (GNUNET_ERROR_TYPE_DEBUG, "Executing iterate request on sqlite db.\n");
  if (NULL == peer && NULL == key)
  {
    stmt = plugin->select_peerstoredata;
    err =
        (SQLITE_OK !=
         sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1,
                            SQLITE_STATIC));
  }
  else if (NULL == key)
  {
    stmt = plugin->select_peerstoredata_by_pid;
    err =
        (SQLITE_OK !=
         sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1,
                            SQLITE_STATIC)) ||
        (SQLITE_OK !=
         sqlite3_bind_blob (stmt, 2, peer, sizeof (struct GNUNET_PeerIdentity),
                            SQLITE_STATIC));
  }
  else if (NULL == peer)
  {
    stmt = plugin->select_peerstoredata_by_key;
    err =
        (SQLITE_OK !=
         sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1,
                            SQLITE_STATIC)) ||
        (SQLITE_OK !=
         sqlite3_bind_text (stmt, 2, key, strlen (key) + 1, SQLITE_STATIC));
  }
  else
  {
    stmt = plugin->select_peerstoredata_by_all;
    err =
        (SQLITE_OK !=
         sqlite3_bind_text (stmt, 1, sub_system, strlen (sub_system) + 1,
                            SQLITE_STATIC)) ||
        (SQLITE_OK !=
         sqlite3_bind_blob (stmt, 2, peer, sizeof (struct GNUNET_PeerIdentity),
                            SQLITE_STATIC)) ||
        (SQLITE_OK !=
         sqlite3_bind_text (stmt, 3, key, strlen (key) + 1, SQLITE_STATIC));
  }

  if (err)
  {
    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                "sqlite3_bind_XXXX");
    if (SQLITE_OK != sqlite3_reset (stmt))
      LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                  "sqlite3_reset");
    return GNUNET_SYSERR;
  }
  while (SQLITE_ROW == (sret = sqlite3_step (stmt)))
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG, "Returning a matched record.\n");
    ret = GNUNET_new (struct GNUNET_PEERSTORE_Record);

    ret->sub_system = (char *) sqlite3_column_text (stmt, 0);
    ret->peer = (struct GNUNET_PeerIdentity *) sqlite3_column_blob (stmt, 1);
    ret->key = (char *) sqlite3_column_text (stmt, 2);
    ret->value = (void *) sqlite3_column_blob (stmt, 3);
    ret->value_size = sqlite3_column_bytes (stmt, 3);
    ret->expiry = GNUNET_new (struct GNUNET_TIME_Absolute);

    ret->expiry->abs_value_us = (uint64_t) sqlite3_column_int64 (stmt, 4);
    if (NULL != iter)
      iter (iter_cls, ret, NULL);
    GNUNET_free (ret->expiry);
    GNUNET_free (ret);
  }
  if (SQLITE_DONE != sret)
  {
    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
    err = 1;
  }
  if (SQLITE_OK != sqlite3_reset (stmt))
  {
    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                "sqlite3_reset");
    err = 1;
  }
  if (NULL != iter)
  {
    iter (iter_cls, NULL, err ? "sqlite error" : NULL);
  }
  return GNUNET_OK;
}
/**
 * Create the MLP problem
 *
 * @param mlp the MLP handle
 * @param addresses the hashmap containing all adresses
 * @return GNUNET_OK or GNUNET_SYSERR
 */
static int
mlp_create_problem (struct GAS_MLP_Handle *mlp, struct GNUNET_CONTAINER_MultiHashMap * addresses)
{
  int res = GNUNET_OK;
  int col;
  int c;
  char *name;

  GNUNET_assert (mlp->prob == NULL);

  /* create the glpk problem */
  mlp->prob = glp_create_prob ();

  /* Set a problem name */
  glp_set_prob_name (mlp->prob, "gnunet ats bandwidth distribution");

  /* Set optimization direction to maximize */
  glp_set_obj_dir (mlp->prob, GLP_MAX);

  /* Adding invariant columns */

  /* Diversity d column  */
  col = glp_add_cols (mlp->prob, 1);
  mlp->c_d = col;
  /* Column name */
  glp_set_col_name (mlp->prob, col, "d");
  /* Column objective function coefficient */
  glp_set_obj_coef (mlp->prob, col, mlp->co_D);
  /* Column lower bound = 0.0 */
  glp_set_col_bnds (mlp->prob, col, GLP_LO, 0.0, 0.0);

  /* Utilization u column  */
  col = glp_add_cols (mlp->prob, 1);
  mlp->c_u = col;
  /* Column name */
  glp_set_col_name (mlp->prob, col, "u");
  /* Column objective function coefficient */
  glp_set_obj_coef (mlp->prob, col, mlp->co_U);
  /* Column lower bound = 0.0 */
  glp_set_col_bnds (mlp->prob, col, GLP_LO, 0.0, 0.0);

#if ENABLE_C9
  /* Relativity r column  */
  col = glp_add_cols (mlp->prob, 1);
  mlp->c_r = col;
  /* Column name */
  glp_set_col_name (mlp->prob, col, "r");
  /* Column objective function coefficient */
  glp_set_obj_coef (mlp->prob, col, mlp->co_R);
  /* Column lower bound = 0.0 */
  glp_set_col_bnds (mlp->prob, col, GLP_LO, 0.0, 0.0);
#endif

  /* Quality metric columns */
  col = glp_add_cols(mlp->prob, mlp->m_q);
  for (c = 0; c < mlp->m_q; c++)
  {
    mlp->c_q[c] = col + c;
    GNUNET_asprintf (&name, "q_%u", mlp->q[c]);
    glp_set_col_name (mlp->prob, col + c, name);
    /* Column lower bound = 0.0 */
    glp_set_col_bnds (mlp->prob, col + c, GLP_LO, 0.0, 0.0);
    GNUNET_free (name);
    /* Coefficient == Qm */
    glp_set_obj_coef (mlp->prob, col + c, mlp->co_Q[c]);
  }

  /* Add columns for addresses */
  GNUNET_CONTAINER_multihashmap_iterate (addresses, create_columns_it, mlp);

  /* Add constraints */
  mlp_add_constraints_all_addresses (mlp, addresses);

  /* Load the matrix */
  glp_load_matrix(mlp->prob, (mlp->ci-1), mlp->ia, mlp->ja, mlp->ar);

  return res;
}
Ejemplo n.º 23
0
/**
 * Convert the 'value' of a record to a string.
 *
 * @param type type of the record
 * @param data value in binary encoding
 * @param data_size number of bytes in data
 * @return NULL on error, otherwise human-readable representation of the value
 */
char *
GNUNET_NAMESTORE_value_to_string (uint32_t type,
				  const void *data,
				  size_t data_size)
{
  uint16_t mx_pref;
  const struct soa_data *soa;
  const struct vpn_data *vpn;
  const struct srv_data *srv;
  const struct tlsa_data *tlsa;
  struct GNUNET_CRYPTO_ShortHashAsciiEncoded enc;
  struct GNUNET_CRYPTO_HashAsciiEncoded s_peer;
  const char *cdata;
  char* vpn_str;
  char* srv_str;
  char* tlsa_str;
  char* result;
  const char* soa_rname;
  const char* soa_mname;
  char tmp[INET6_ADDRSTRLEN];

  switch (type)
  {
  case 0:
    return NULL;
  case GNUNET_DNSPARSER_TYPE_A:
    if (data_size != sizeof (struct in_addr))
      return NULL;
    if (NULL == inet_ntop (AF_INET, data, tmp, sizeof (tmp)))
      return NULL;
    return GNUNET_strdup (tmp);
  case GNUNET_DNSPARSER_TYPE_NS:
    return GNUNET_strndup (data, data_size);
  case GNUNET_DNSPARSER_TYPE_CNAME:
    return GNUNET_strndup (data, data_size);
  case GNUNET_DNSPARSER_TYPE_SOA:
    if (data_size <= sizeof (struct soa_data))
      return NULL;
    soa = data;
    soa_rname = (const char*) &soa[1];
    soa_mname = memchr (soa_rname, 0, data_size - sizeof (struct soa_data) - 1);
    if (NULL == soa_mname)
      return NULL;
    soa_mname++;
    if (NULL == memchr (soa_mname, 0, 
			data_size - (sizeof (struct soa_data) + strlen (soa_rname) + 1)))
      return NULL;
    GNUNET_asprintf (&result, 
		     "rname=%s mname=%s %lu,%lu,%lu,%lu,%lu",
		     soa_rname, soa_mname,
		     ntohl (soa->serial), 
		     ntohl (soa->refresh),
		     ntohl (soa->retry), 
		     ntohl (soa->expire),
		     ntohl (soa->minimum));
    return result;
  case GNUNET_DNSPARSER_TYPE_PTR:
    return GNUNET_strndup (data, data_size);
  case GNUNET_DNSPARSER_TYPE_MX:
    mx_pref = ntohs(*((uint16_t*)data));
    if (GNUNET_asprintf(&result, "%hu,%s", mx_pref, data+sizeof(uint16_t))
        != 0)
      return result;
    else
    {
      GNUNET_free (result);
      return NULL;
    }
  case GNUNET_DNSPARSER_TYPE_TXT:
    return GNUNET_strndup (data, data_size);
  case GNUNET_DNSPARSER_TYPE_AAAA:
    if (data_size != sizeof (struct in6_addr))
      return NULL;
    if (NULL == inet_ntop (AF_INET6, data, tmp, sizeof (tmp)))
      return NULL;
    return GNUNET_strdup (tmp);
  case GNUNET_NAMESTORE_TYPE_PKEY:
    if (data_size != sizeof (struct GNUNET_CRYPTO_ShortHashCode))
      return NULL;
    GNUNET_CRYPTO_short_hash_to_enc (data,
				     &enc);
    return GNUNET_strdup ((const char*) enc.short_encoding);
  case GNUNET_NAMESTORE_TYPE_PSEU:
    return GNUNET_strndup (data, data_size);
  case GNUNET_NAMESTORE_TYPE_LEHO:
    return GNUNET_strndup (data, data_size);
  case GNUNET_NAMESTORE_TYPE_VPN:
    cdata = data;
    if ( (data_size <= sizeof (struct vpn_data)) ||
	 ('\0' != cdata[data_size - 1]) )
      return NULL; /* malformed */
    vpn = data;
    GNUNET_CRYPTO_hash_to_enc (&vpn->peer, &s_peer);
    if (0 == GNUNET_asprintf (&vpn_str, "%u %s %s",
			      (unsigned int) ntohs (vpn->proto),
			      (const char*) &s_peer,
			      (const char*) &vpn[1]))
    {
      GNUNET_free (vpn_str);
      return NULL;
    }
    return vpn_str;
  case GNUNET_DNSPARSER_TYPE_SRV:
    cdata = data;
    if ( (data_size <= sizeof (struct srv_data)) ||
	 ('\0' != cdata[data_size - 1]) )
      return NULL; /* malformed */
    srv = data;

    if (0 == GNUNET_asprintf (&srv_str, 
			      "%d %d %d %s",
			      ntohs (srv->prio),
			      ntohs (srv->weight),
			      ntohs (srv->port),
			      (const char *)&srv[1]))
    {
      GNUNET_free (srv_str);
      return NULL;
    }
    return srv_str;
  case GNUNET_DNSPARSER_TYPE_TLSA:
    cdata = data;
    if ( (data_size <= sizeof (struct tlsa_data)) ||
	 ('\0' != cdata[data_size - 1]) )
      return NULL; /* malformed */
    tlsa = data;
    if (0 == GNUNET_asprintf (&tlsa_str, 
			      "%c %c %c %s",
			      tlsa->usage,
			      tlsa->selector,
			      tlsa->matching_type,
			      (const char *) &tlsa[1]))
    {
      GNUNET_free (tlsa_str);
      return NULL;
    }
    return tlsa_str;
  default:
    GNUNET_break (0);
  }
  GNUNET_break (0); // not implemented
  return NULL;
}
Ejemplo n.º 24
0
/**
 * Publish a UBlock.
 *
 * @param h handle to the file sharing subsystem
 * @param dsh datastore handle to use for storage operation
 * @param label identifier to use
 * @param ulabel update label to use, may be an empty string for none
 * @param ns namespace to publish in
 * @param meta metadata to use
 * @param uri URI to refer to in the UBlock
 * @param bo per-block options
 * @param options publication options
 * @param cont continuation
 * @param cont_cls closure for @a cont
 * @return NULL on error (@a cont will still be called)
 */
struct GNUNET_FS_PublishUblockContext *
GNUNET_FS_publish_ublock_ (struct GNUNET_FS_Handle *h,
			   struct GNUNET_DATASTORE_Handle *dsh,
			   const char *label,
			   const char *ulabel,
			   const struct GNUNET_CRYPTO_EcdsaPrivateKey *ns,
			   const struct GNUNET_CONTAINER_MetaData *meta,
			   const struct GNUNET_FS_Uri *uri,
			   const struct GNUNET_FS_BlockOptions *bo,
			   enum GNUNET_FS_PublishOptions options,
			   GNUNET_FS_UBlockContinuation cont, void *cont_cls)
{
  struct GNUNET_FS_PublishUblockContext *uc;
  struct GNUNET_HashCode query;
  struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
  struct GNUNET_CRYPTO_SymmetricSessionKey skey;
  struct GNUNET_CRYPTO_EcdsaPrivateKey *nsd;
  struct GNUNET_CRYPTO_EcdsaPublicKey pub;
  char *uris;
  size_t size;
  char *kbe;
  char *sptr;
  ssize_t mdsize;
  size_t slen;
  size_t ulen;
  struct UBlock *ub_plain;
  struct UBlock *ub_enc;

  /* compute ublock to publish */
  if (NULL == meta)
    mdsize = 0;
  else
    mdsize = GNUNET_CONTAINER_meta_data_get_serialized_size (meta);
  GNUNET_assert (mdsize >= 0);
  uris = GNUNET_FS_uri_to_string (uri);
  slen = strlen (uris) + 1;
  if (NULL == ulabel)
    ulen = 1;
  else
    ulen = strlen (ulabel) + 1;
  size = mdsize + sizeof (struct UBlock) + slen + ulen;
  if (size > MAX_UBLOCK_SIZE)
  {
    size = MAX_UBLOCK_SIZE;
    mdsize = size - sizeof (struct UBlock) - (slen + ulen);
  }
  ub_plain = GNUNET_malloc (size);
  kbe = (char *) &ub_plain[1];
  if (NULL != ulabel)
    memcpy (kbe, ulabel, ulen);
  kbe += ulen;
  memcpy (kbe, uris, slen);
  kbe += slen;
  GNUNET_free (uris);
  sptr = kbe;
  if (NULL != meta)
    mdsize =
      GNUNET_CONTAINER_meta_data_serialize (meta, &sptr, mdsize,
					    GNUNET_CONTAINER_META_DATA_SERIALIZE_PART);
  if (-1 == mdsize)
  {
    GNUNET_break (0);
    GNUNET_free (ub_plain);
    cont (cont_cls, _("Internal error."));
    return NULL;
  }
  size = sizeof (struct UBlock) + slen + mdsize + ulen;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Publishing under identifier `%s'\n",
              label);
  /* get public key of the namespace */
  GNUNET_CRYPTO_ecdsa_key_get_public (ns,
				    &pub);
  derive_ublock_encryption_key (&skey, &iv,
				label, &pub);

  /* encrypt ublock */
  ub_enc = GNUNET_malloc (size);
  GNUNET_CRYPTO_symmetric_encrypt (&ub_plain[1],
			     ulen + slen + mdsize,
			     &skey, &iv,
                             &ub_enc[1]);
  GNUNET_free (ub_plain);
  ub_enc->purpose.size = htonl (ulen + slen + mdsize +
				sizeof (struct UBlock)
				- sizeof (struct GNUNET_CRYPTO_EcdsaSignature));
  ub_enc->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_FS_UBLOCK);

  /* derive signing-key from 'label' and public key of the namespace */
  nsd = GNUNET_CRYPTO_ecdsa_private_key_derive (ns, label, "fs-ublock");
  GNUNET_CRYPTO_ecdsa_key_get_public (nsd,
				    &ub_enc->verification_key);
  GNUNET_assert (GNUNET_OK ==
		 GNUNET_CRYPTO_ecdsa_sign (nsd,
					 &ub_enc->purpose,
					 &ub_enc->signature));
  GNUNET_CRYPTO_hash (&ub_enc->verification_key,
		      sizeof (ub_enc->verification_key),
		      &query);
  GNUNET_free (nsd);

  uc = GNUNET_new (struct GNUNET_FS_PublishUblockContext);
  uc->cont = cont;
  uc->cont_cls = cont_cls;
  uc->qre =
    GNUNET_DATASTORE_put (dsh, 0, &query,
			  ulen + slen + mdsize + sizeof (struct UBlock),
			  ub_enc, GNUNET_BLOCK_TYPE_FS_UBLOCK,
			  bo->content_priority, bo->anonymity_level,
			  bo->replication_level, bo->expiration_time,
			  -2, 1, GNUNET_CONSTANTS_SERVICE_TIMEOUT,
			  &ublock_put_cont, uc);
  return uc;
}
Ejemplo n.º 25
0
/**
 * Iterator over hash map peer entries and frees all data in it.
 * Used prior to destroying a hashmap. Makes you miss anonymous functions in C.
 *
 * @param cls closure
 * @param key current key code (will no longer contain valid data!!)
 * @param value value in the hash map (treated as void *)
 * @return GNUNET_YES if we should continue to iterate, GNUNET_NO if not.
 */
static int
iterate_free (void *cls, const struct GNUNET_HashCode * key, void *value)
{
  GNUNET_free (value);
  return GNUNET_YES;
}
Ejemplo n.º 26
0
/**
 * Abort UBlock publishing operation.
 *
 * @param uc operation to abort.
 */
void
GNUNET_FS_publish_ublock_cancel_ (struct GNUNET_FS_PublishUblockContext *uc)
{
  GNUNET_DATASTORE_cancel (uc->qre);
  GNUNET_free (uc);
}
Ejemplo n.º 27
0
Archivo: dv_api.c Proyecto: tg-x/gnunet
/**
 * Handles a message sent from the DV service to us.
 * Parse it out and give it to the plugin.
 *
 * @param cls the handle to the DV API
 * @param msg the message that was received
 */
static void
handle_message_receipt (void *cls,
			const struct GNUNET_MessageHeader *msg)
{
  struct GNUNET_DV_ServiceHandle *sh = cls;
  const struct GNUNET_DV_ConnectMessage *cm;
  const struct GNUNET_DV_DistanceUpdateMessage *dum;
  const struct GNUNET_DV_DisconnectMessage *dm;
  const struct GNUNET_DV_ReceivedMessage *rm;
  const struct GNUNET_MessageHeader *payload;
  const struct GNUNET_DV_AckMessage *ack;
  struct GNUNET_DV_TransmitHandle *th;
  struct GNUNET_DV_TransmitHandle *tn;
  struct ConnectedPeer *peer;

  if (NULL == msg)
  {
    /* Connection closed */
    reconnect (sh);
    return;
  }
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Received message of type %u with %u bytes from DV service\n",
       (unsigned int) ntohs (msg->type),
       (unsigned int) ntohs (msg->size));
  switch (ntohs (msg->type))
  {
  case GNUNET_MESSAGE_TYPE_DV_CONNECT:
    if (ntohs (msg->size) != sizeof (struct GNUNET_DV_ConnectMessage))
    {
      GNUNET_break (0);
      reconnect (sh);
      return;
    }
    cm = (const struct GNUNET_DV_ConnectMessage *) msg;
    peer = GNUNET_CONTAINER_multipeermap_get (sh->peers,
                                              &cm->peer);
    if (NULL != peer)
    {
      GNUNET_break (0);
      reconnect (sh);
      return;
    }
    peer = GNUNET_new (struct ConnectedPeer);
    peer->pid = cm->peer;
    GNUNET_assert (GNUNET_OK ==
                   GNUNET_CONTAINER_multipeermap_put (sh->peers,
                                                      &peer->pid,
                                                      peer,
                                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
    sh->connect_cb (sh->cls,
		    &cm->peer,
		    ntohl (cm->distance),
                    (enum GNUNET_ATS_Network_Type) ntohl (cm->network));
    break;
  case GNUNET_MESSAGE_TYPE_DV_DISTANCE_CHANGED:
    if (ntohs (msg->size) != sizeof (struct GNUNET_DV_DistanceUpdateMessage))
    {
      GNUNET_break (0);
      reconnect (sh);
      return;
    }
    dum = (const struct GNUNET_DV_DistanceUpdateMessage *) msg;
    sh->distance_cb (sh->cls,
		     &dum->peer,
		     ntohl (dum->distance),
                     (enum GNUNET_ATS_Network_Type) ntohl (dum->network));
    break;
  case GNUNET_MESSAGE_TYPE_DV_DISCONNECT:
    if (ntohs (msg->size) != sizeof (struct GNUNET_DV_DisconnectMessage))
    {
      GNUNET_break (0);
      reconnect (sh);
      return;
    }
    dm = (const struct GNUNET_DV_DisconnectMessage *) msg;
    peer = GNUNET_CONTAINER_multipeermap_get (sh->peers,
                                              &dm->peer);
    if (NULL == peer)
    {
      GNUNET_break (0);
      reconnect (sh);
      return;
    }
    tn = sh->th_head;
    while (NULL != (th = tn))
    {
      tn = th->next;
      if (peer == th->target)
      {
        GNUNET_CONTAINER_DLL_remove (sh->th_head,
                                     sh->th_tail,
                                     th);
        th->cb (th->cb_cls, GNUNET_SYSERR);
        GNUNET_free (th);
      }
    }
    cleanup_send_cb (sh, &dm->peer, peer);
    break;
  case GNUNET_MESSAGE_TYPE_DV_RECV:
    if (ntohs (msg->size) < sizeof (struct GNUNET_DV_ReceivedMessage) + sizeof (struct GNUNET_MessageHeader))
    {
      GNUNET_break (0);
      reconnect (sh);
      return;
    }
    rm = (const struct GNUNET_DV_ReceivedMessage *) msg;
    payload = (const struct GNUNET_MessageHeader *) &rm[1];
    if (ntohs (msg->size) != sizeof (struct GNUNET_DV_ReceivedMessage) + ntohs (payload->size))
    {
      GNUNET_break (0);
      reconnect (sh);
      return;
    }
    if (NULL ==
        GNUNET_CONTAINER_multipeermap_get (sh->peers,
                                           &rm->sender))
    {
      GNUNET_break (0);
      reconnect (sh);
      return;
    }
    sh->message_cb (sh->cls,
		    &rm->sender,
		    ntohl (rm->distance),
		    payload);
    break;
  case GNUNET_MESSAGE_TYPE_DV_SEND_ACK:
  case GNUNET_MESSAGE_TYPE_DV_SEND_NACK:
    if (ntohs (msg->size) != sizeof (struct GNUNET_DV_AckMessage))
    {
      GNUNET_break (0);
      reconnect (sh);
      return;
    }
    ack = (const struct GNUNET_DV_AckMessage *) msg;
    peer = GNUNET_CONTAINER_multipeermap_get (sh->peers,
                                              &ack->target);
    if (NULL == peer)
      break; /* this happens, just ignore */
    for (th = peer->head; NULL != th; th = th->next)
    {
      if (th->uid != ntohl (ack->uid))
        continue;
      LOG (GNUNET_ERROR_TYPE_DEBUG,
           "Matched ACK for message to peer %s\n",
           GNUNET_i2s (&ack->target));
      GNUNET_CONTAINER_DLL_remove (peer->head,
                                   peer->tail,
                                   th);
      th->cb (th->cb_cls,
              (ntohs (ack->header.type) == GNUNET_MESSAGE_TYPE_DV_SEND_ACK)
              ? GNUNET_OK
              : GNUNET_SYSERR);
      GNUNET_free (th);
      break;
    }
    break;
  default:
    reconnect (sh);
    break;
  }
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Received message, continuing receive loop for %p\n",
       sh->client);
  GNUNET_CLIENT_receive (sh->client,
			 &handle_message_receipt, sh,
                         GNUNET_TIME_UNIT_FOREVER_REL);
}
Ejemplo n.º 28
0
/**
 * Main function that will be run by the scheduler.
 *
 * @param cls closure
 * @param args remaining command-line arguments
 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
 * @param cfg configuration
 */
static void
run (void *cls,
     char *const *args,
     const char *cfgfile,
     const struct GNUNET_CONFIGURATION_Handle *config)
{
  struct GNUNET_CRYPTO_EddsaPrivateKey *pk;
  char *pids;

  cfg = config;

  /* load proof of work */
  if (NULL == pwfn)
  {
    if (GNUNET_OK !=
        GNUNET_CONFIGURATION_get_value_filename (cfg, "NSE",
                                                 "PROOFFILE",
                                                 &pwfn))
    {
      GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
                                 "NSE", "PROOFFILE");
      GNUNET_SCHEDULER_shutdown ();
      return;
    }
  }
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
              "Proof of Work file: %s\n",
              pwfn);
  if ( (GNUNET_YES != GNUNET_DISK_file_test (pwfn)) ||
       (sizeof (proof) !=
        GNUNET_DISK_fn_read (pwfn, &proof, sizeof (proof))))
    proof = 0;

  /* load private key */
  if (NULL == pkfn)
  {
    if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "PEER",
                                                              "PRIVATE_KEY",
                                                              &pkfn))
    {
      GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
                                 "PEER", "PRIVATE_KEY");
      return;
    }
  }
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Private Key file: %s\n", pkfn);
  if (NULL == (pk = GNUNET_CRYPTO_eddsa_key_create_from_file (pkfn)))
  {
    FPRINTF (stderr, _("Loading hostkey from `%s' failed.\n"), pkfn);
    GNUNET_free (pkfn);
    return;
  }
  GNUNET_free (pkfn);
  GNUNET_CRYPTO_eddsa_key_get_public (pk, &pub);
  GNUNET_free (pk);
  pids = GNUNET_CRYPTO_eddsa_public_key_to_string (&pub);
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
              "Peer ID: %s\n",
              pids);
  GNUNET_free (pids);

  /* get target bit amount */
  if (0 == nse_work_required)
  {
    if (GNUNET_OK !=
        GNUNET_CONFIGURATION_get_value_number (cfg, "NSE", "WORKBITS",
                                               &nse_work_required))
    {
      GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKBITS");
      GNUNET_SCHEDULER_shutdown ();
      return;
    }
    if (nse_work_required >= sizeof (struct GNUNET_HashCode) * 8)
    {
      GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "NSE", "WORKBITS",
                                _("Value is too large.\n"));
      GNUNET_SCHEDULER_shutdown ();
      return;
    } else if (0 == nse_work_required)
    {
      write_proof ();
      GNUNET_SCHEDULER_shutdown ();
      return;
    }
  }
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
              "Bits: %llu\n",
              nse_work_required);

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Delay between tries: %s\n",
              GNUNET_STRINGS_relative_time_to_string (proof_find_delay, 1));
  GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE,
                                      &find_proof, NULL);
}
static void
notify_receive (void *cls, const struct GNUNET_PeerIdentity *peer,
                const struct GNUNET_MessageHeader *message,
                const struct GNUNET_ATS_Information *ats, uint32_t ats_count)
{
  struct PeerContext *p = cls;
  struct PeerContext *t = NULL;
  int c;

  if (0 == memcmp (peer, &p1->id, sizeof (struct GNUNET_PeerIdentity)))
    t = p1;
  if (0 == memcmp (peer, &p2->id, sizeof (struct GNUNET_PeerIdentity)))
    t = p2;
  GNUNET_assert (t != NULL);

  char *ps = GNUNET_strdup (GNUNET_i2s (&p->id));

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Peer %u (`%4s') received message of type %d and size %u size from peer %u (`%4s')!\n",
              p->no, ps, ntohs (message->type), ntohs (message->size), t->no,
              GNUNET_i2s (&t->id));
  GNUNET_free (ps);

  if ((TEST_MESSAGE_TYPE == ntohs (message->type)) &&
      (TEST_MESSAGE_SIZE == ntohs (message->size)))
  {
    ok = 0;

  }
  else
  {
    GNUNET_break (0);
    ok = 1;
    end ();
    return;
  }

  if (0 == messages_recv)
  {
  	/* Received non-delayed message */
  	dur_normal = GNUNET_TIME_absolute_get_duration(start_normal);
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Received non-delayed message %u after %llu\n",
                messages_recv,
                (long long unsigned int) dur_normal.rel_value);
    send_task = GNUNET_SCHEDULER_add_now (&sendtask, NULL);
  }
  if (1 == messages_recv)
  {
  	/* Received manipulated message */
    	dur_delayed = GNUNET_TIME_absolute_get_duration(start_delayed);
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                  "Received delayed message %u after %llu\n",
                  messages_recv,
                  (long long unsigned int) dur_delayed.rel_value);
      if (dur_delayed.rel_value < 1000)
      {
				GNUNET_break (0);
				ok += 1;
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                    "Delayed message was not delayed correctly: took only %llu\n",
                    (long long unsigned int) dur_delayed.rel_value);
      }
      for (c = 0; c < ats_count; c++)
      {
      	if (ntohl (ats[c].type) == GNUNET_ATS_QUALITY_NET_DISTANCE)
        {
      			if (ntohl (ats[c].value) == 10)
      				ok += 0;
      			else
      			{
    					GNUNET_break (0);
    					ok += 1;
      			}
        }
      }
      /* shutdown */
      end ();
  }
  messages_recv ++;
}
Ejemplo n.º 30
0
/**
 * Parse name inside of a DNS query or record.
 *
 * @param udp_payload entire UDP payload
 * @param udp_payload_length length of @a udp_payload
 * @param off pointer to the offset of the name to parse in the udp_payload (to be
 *                    incremented by the size of the name)
 * @param depth current depth of our recursion (to prevent stack overflow)
 * @return name as 0-terminated C string on success, NULL if the payload is malformed
 */
static char *
parse_name (const char *udp_payload,
	    size_t udp_payload_length,
	    size_t *off,
	    unsigned int depth)
{
  const uint8_t *input = (const uint8_t *) udp_payload;
  char *ret;
  char *tmp;
  char *xstr;
  uint8_t len;
  size_t xoff;
  char *utf8;
  Idna_rc rc;

  ret = GNUNET_strdup ("");
  while (1)
  {
    if (*off >= udp_payload_length)
    {
      GNUNET_break_op (0);
      goto error;
    }
    len = input[*off];
    if (0 == len)
    {
      (*off)++;
      break;
    }
    if (len < 64)
    {
      if (*off + 1 + len > udp_payload_length)
      {
	GNUNET_break_op (0);
	goto error;
      }
      GNUNET_asprintf (&tmp,
		       "%.*s",
		       (int) len,
		       &udp_payload[*off + 1]);
      if (IDNA_SUCCESS !=
	  (rc = idna_to_unicode_8z8z (tmp, &utf8, IDNA_ALLOW_UNASSIGNED)))
      {
	GNUNET_log (GNUNET_ERROR_TYPE_INFO,
		    _("Failed to convert DNS IDNA name `%s' to UTF-8: %s\n"),
		    tmp,
		    idna_strerror (rc));
	GNUNET_free (tmp);
	GNUNET_asprintf (&tmp,
			 "%s%.*s.",
			 ret,
			 (int) len,
			 &udp_payload[*off + 1]);
      }
      else
      {
	GNUNET_free (tmp);
	GNUNET_asprintf (&tmp,
			 "%s%s.",
			 ret,
			 utf8);
#if WINDOWS
	idn_free (utf8);
#else
	free (utf8);
#endif
      }
      GNUNET_free (ret);
      ret = tmp;
      *off += 1 + len;
    }
    else if ((64 | 128) == (len & (64 | 128)) )
    {
      if (depth > 32)
      {
	GNUNET_break_op (0);
	goto error; /* hard bound on stack to prevent "infinite" recursion, disallow! */
      }
      /* pointer to string */
      if (*off + 1 > udp_payload_length)
      {
	GNUNET_break_op (0);
	goto error;
      }
      xoff = ((len - (64 | 128)) << 8) + input[*off+1];
      xstr = parse_name (udp_payload,
			 udp_payload_length,
			 &xoff,
			 depth + 1);
      if (NULL == xstr)
      {
	GNUNET_break_op (0);
	goto error;
      }
      GNUNET_asprintf (&tmp,
		       "%s%s.",
		       ret,
		       xstr);
      GNUNET_free (ret);
      GNUNET_free (xstr);
      ret = tmp;
      if (strlen (ret) > udp_payload_length)
      {
	GNUNET_break_op (0);
	goto error; /* we are looping (building an infinite string) */
      }
      *off += 2;
      /* pointers always terminate names */
      break;
    }
    else
    {
      /* neither pointer nor inline string, not supported... */
      GNUNET_break_op (0);
      goto error;
    }
  }
  if (0 < strlen(ret))
    ret[strlen(ret)-1] = '\0'; /* eat tailing '.' */
  return ret;
 error:
  GNUNET_break_op (0);
  GNUNET_free (ret);
  return NULL;
}