/**
 * Try to read the HELLO in the given filename and discard expired addresses.
 * 
 * @param fn name of the file
 * @return HELLO of the file, NULL on error
 */
static struct GNUNET_HELLO_Message *
read_host_file (const char *fn)
{
  char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
  const struct GNUNET_HELLO_Message *hello;
  struct GNUNET_HELLO_Message *hello_clean;
  int size;
  struct GNUNET_TIME_Absolute now;

  if (GNUNET_YES != GNUNET_DISK_file_test (fn))
    return NULL;
  size = GNUNET_DISK_fn_read (fn, buffer, sizeof (buffer));
  hello = (const struct GNUNET_HELLO_Message *) buffer;
  if ((size < sizeof (struct GNUNET_MessageHeader)) ||
      (size != ntohs ((((const struct GNUNET_MessageHeader *) hello)->size)))
      || (size != GNUNET_HELLO_size (hello)))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		_("Failed to parse HELLO in file `%s'\n"),
		fn);
    return NULL;
  }
  now = GNUNET_TIME_absolute_get ();
  hello_clean =
    GNUNET_HELLO_iterate_addresses (hello, GNUNET_YES, &discard_expired,
				    &now);
  return hello_clean; 
}
/**
 * We've received a HELLO, check which addresses are new and trigger
 * validation.
 *
 * @param hello the HELLO we received
 */
void
GST_validation_handle_hello (const struct GNUNET_MessageHeader *hello)
{
  const struct GNUNET_HELLO_Message *hm =
      (const struct GNUNET_HELLO_Message *) hello;
  struct ValidateAddressContext vac;
  struct GNUNET_HELLO_Message *h;

  if ((GNUNET_OK != GNUNET_HELLO_get_id (hm, &vac.pid)) ||
      (GNUNET_OK != GNUNET_HELLO_get_key (hm, &vac.public_key)))
  {
    /* malformed HELLO */
    GNUNET_break (0);
    return;
  }
  if (0 ==
      memcmp (&GST_my_identity, &vac.pid, sizeof (struct GNUNET_PeerIdentity)))
    return;
  /* Add peer identity without addresses to peerinfo service */
  h = GNUNET_HELLO_create (&vac.public_key, NULL, NULL);
  GNUNET_PEERINFO_add_peer (GST_peerinfo, h, NULL, NULL);
#if VERBOSE_VALIDATION
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              _("Adding `%s' without addresses for peer `%s'\n"), "HELLO",
              GNUNET_i2s (&vac.pid));
#endif
  GNUNET_free (h);
  GNUNET_assert (NULL ==
                 GNUNET_HELLO_iterate_addresses (hm, GNUNET_NO,
                                                 &validate_address_iterator,
                                                 &vac));
}
Esempio n. 3
0
/**
 * Function called for peers that we know about.
 *
 * @param peer id of the peer, NULL for last call
 * @param hello hello message for the peer (can be NULL)
 * @param err_msg NULL if successful, otherwise contains error message
 */
void NetworkManager::peerinfoProcessor(const struct GNUNET_PeerIdentity *peer,
                                       const struct GNUNET_HELLO_Message *hello,
                                       const char *err_msg)
{

    if(peer == NULL)
    {
        qWarning() << QString("Got a NULL peer in peerinfoProcessor. %1").arg(err_msg ? err_msg : "");
        return;
    }


    const char* key = GNUNET_i2s_full (peer);
    QString peerIdStr(key);


    if(!theApp->models()->networkModel())
    {
        qWarning() << tr("Got a info about a peer while the network model was not created");
        return;
    }


    //If is myself, update my Hello string to display to the user.
    if(theApp->gnunet()->myPublicKeyStr() == peerIdStr)
    {
        if(!hello)
        {
            qWarning() << tr("Got a info about myself without a hello");
            return;
        }

        //Save my hello URL
        char *uri = GNUNET_HELLO_compose_uri(hello, &m_gnunetTransportPlugins->GPI_plugins_find);
        setMyHelloStr(QString(uri));
        return;
    }


    Peer* newPeer = NULL;

    //See if peer already exists.If not, create a new one.
    if(!theApp->models()->networkModel()->contains(peerIdStr)) {
        newPeer = theApp->models()->networkModel()->addNewPeer(peer, peerIdStr);
    } else {
        newPeer =theApp->models()->networkModel()->getPeer(peerIdStr);
    }

    Q_ASSERT(newPeer);



    if(hello){
        GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO,
                                    &peerAddressCallback, newPeer);
    }

}
Esempio n. 4
0
/**
 * Print information about the peer.
 * Currently prints the GNUNET_PeerIdentity and the transport address.
 *
 * @param cls the 'struct PrintContext'
 * @param peer identity of the peer 
 * @param hello addresses of the peer
 * @param err_msg error message
 */
static void
print_peer_info (void *cls, const struct GNUNET_PeerIdentity *peer,
                 const struct GNUNET_HELLO_Message *hello, const char *err_msg)
{
  struct GNUNET_CRYPTO_HashAsciiEncoded enc;
  struct PrintContext *pc;

  if (NULL == peer)
  {
    pic = NULL; /* end of iteration */
    if (NULL != err_msg)
    {
      FPRINTF (stderr, 
	       _("Error in communication with PEERINFO service: %s\n"),
	       err_msg);
    }
    if (NULL == pc_head)
      tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL);
    return;
  }
  if ((GNUNET_YES == be_quiet) || (NULL == hello))
  {
    GNUNET_CRYPTO_hash_to_enc (&peer->hashPubKey, &enc);
    printf ("%s\n", (const char *) &enc);
    return;
  }
  pc = GNUNET_malloc (sizeof (struct PrintContext));
  GNUNET_CONTAINER_DLL_insert (pc_head,
			       pc_tail, 
			       pc);
  pc->peer = *peer;
  GNUNET_HELLO_iterate_addresses (hello, 
				  GNUNET_NO, 
				  &count_address, 
				  pc);
  if (0 == pc->off)
  {
    dump_pc (pc);
    return;
  }
  pc->address_list_size = pc->off;
  pc->address_list = GNUNET_malloc (sizeof (struct AddressRecord) * pc->off);
  GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, 
				  &print_address, pc);
}
Esempio n. 5
0
/**
 * When does the last address in the given HELLO expire?
 *
 * @param msg HELLO to inspect
 * @return time the last address expires, 0 if there are no addresses in the HELLO
 */
struct GNUNET_TIME_Absolute
GNUNET_HELLO_get_last_expiration (const struct GNUNET_HELLO_Message *msg)
{
  struct GNUNET_TIME_Absolute ret;

  ret.abs_value = 0;
  GNUNET_HELLO_iterate_addresses (msg, GNUNET_NO, &find_min_expire, &ret);
  return ret;
}
Esempio n. 6
0
static size_t
merge_addr (void *cls, size_t max, void *buf)
{
  struct MergeContext *mc = cls;

  if (mc->h1 == NULL)
    return 0;
  mc->ret = 0;
  mc->max = max;
  mc->buf = buf;
  mc->take_equal = GNUNET_NO;
  mc->other = mc->h2;
  GNUNET_HELLO_iterate_addresses (mc->h1, GNUNET_NO, &copy_latest, mc);
  mc->take_equal = GNUNET_YES;
  mc->other = mc->h1;
  GNUNET_HELLO_iterate_addresses (mc->h2, GNUNET_NO, &copy_latest, mc);
  mc->h1 = NULL;
  return mc->ret;
}
/**
 * We've gotten a HELLO from another peer.  Consider it for
 * advertising.
 *
 * @param hello the HELLO we got
 */
static void
consider_for_advertising (const struct GNUNET_HELLO_Message *hello)
{
  int have_address;
  struct GNUNET_PeerIdentity pid;
  struct GNUNET_TIME_Absolute dt;
  struct GNUNET_HELLO_Message *nh;
  struct Peer *peer;
  uint16_t size;

  if (GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid))
  {
    GNUNET_break (0);
    return;
  }
  if (0 == memcmp (&pid, &my_identity, sizeof (struct GNUNET_PeerIdentity)))
    return;                     /* that's me! */
  have_address = GNUNET_NO;
  GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &address_iterator,
                                  &have_address);
  if (GNUNET_NO == have_address)
    return;                     /* no point in advertising this one... */
  peer = GNUNET_CONTAINER_multihashmap_get (peers, &pid.hashPubKey);
  if (NULL == peer)
  {
    peer = make_peer (&pid, hello, GNUNET_NO);
  }
  else if (peer->hello != NULL)
  {
    dt = GNUNET_HELLO_equals (peer->hello, hello, GNUNET_TIME_absolute_get ());
    if (dt.abs_value == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value)
      return;                   /* nothing new here */
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Found `%s' from peer `%s' for advertising\n", "HELLO",
              GNUNET_i2s (&pid));
  if (peer->hello != NULL)
  {
    nh = GNUNET_HELLO_merge (peer->hello, hello);
    GNUNET_free (peer->hello);
    peer->hello = nh;
  }
  else
  {
    size = GNUNET_HELLO_size (hello);
    peer->hello = GNUNET_malloc (size);
    memcpy (peer->hello, hello, size);
  }
  if (peer->filter != NULL)
    GNUNET_CONTAINER_bloomfilter_free (peer->filter);
  setup_filter (peer);
  /* since we have a new HELLO to pick from, re-schedule all
   * HELLO requests that are not bound by the HELLO send rate! */
  GNUNET_CONTAINER_multihashmap_iterate (peers, &reschedule_hellos, peer);
}
Esempio n. 8
0
/**
 * Test if two HELLO messages contain the same addresses.
 * If they only differ in expiration time, the lowest
 * expiration time larger than 'now' where they differ
 * is returned.
 *
 * @param h1 first HELLO message
 * @param h2 the second HELLO message
 * @param now time to use for deciding which addresses have
 *            expired and should not be considered at all
 * @return absolute time forever if the two HELLOs are
 *         totally identical; smallest timestamp >= now if
 *         they only differ in timestamps;
 *         zero if the some addresses with expirations >= now
 *         do not match at all
 */
struct GNUNET_TIME_Absolute
GNUNET_HELLO_equals (const struct GNUNET_HELLO_Message *h1,
                     const struct GNUNET_HELLO_Message *h2,
                     struct GNUNET_TIME_Absolute now)
{
  struct EqualsContext ec;

  if (0 !=
      memcmp (&h1->publicKey, &h2->publicKey,
              sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))
    return GNUNET_TIME_UNIT_ZERO_ABS;
  ec.expiration_limit = now;
  ec.result = GNUNET_TIME_UNIT_FOREVER_ABS;
  ec.h2 = h2;
  GNUNET_HELLO_iterate_addresses (h1, GNUNET_NO, &find_matching, &ec);
  if (ec.result.abs_value == GNUNET_TIME_UNIT_ZERO.rel_value)
    return ec.result;
  ec.h2 = h1;
  GNUNET_HELLO_iterate_addresses (h2, GNUNET_NO, &find_matching, &ec);
  return ec.result;
}
/**
 * Function called for any HELLO known to PEERINFO.
 *
 * @param cls unused
 * @param peer id of the peer, NULL for last call
 * @param hello hello message for the peer (can be NULL)
 * @param err_msg error message
 */
static void
process_peerinfo_hello (void *cls, const struct GNUNET_PeerIdentity *peer,
                        const struct GNUNET_HELLO_Message *hello,
                        const char *err_msg)
{
  GNUNET_assert (NULL != peer);
  if (NULL == hello)
    return;
  GNUNET_assert (NULL ==
                 GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO,
                                                 &add_valid_address,
                                                 (void *) hello));
}
static void
process (void *cls,
         const struct GNUNET_PeerIdentity *peer,
         const struct GNUNET_HELLO_Message *hello,
         const char *err_msg)
{
  static unsigned int calls = 0;
  int addr;

  if (err_msg != NULL)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Error in communication with PEERINFO service\n"));
  }
  if (NULL != peer)
  {
    addr = 0;
    if (NULL != hello)
    {
      GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &addr_cb, &addr);
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                  "Got information about peer `%s' with %u addresses \n",
                  GNUNET_i2s (peer), addr);
      calls++;
    }
    else
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  "Fail: Got information about peer `%s' without HELLO \n",
                  GNUNET_i2s (peer));
  }
  else
  {
    if (0 == calls)
    {
      fprintf (stderr,
               "Failed: got no callbacks!\n");
      global_ret = 1;
    }
    else
      {
        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                    "Got %u callbacks\n", calls);
        global_ret = 0;
      }
  }
}
Esempio n. 11
0
/**
 * Compose a hello URI string from a hello message.
 *
 * @param hello Hello message
 * @param plugins_find Function to find transport plugins by name
 * @return Hello URI string
 */
char *
GNUNET_HELLO_compose_uri (const struct GNUNET_HELLO_Message *hello,
                          GNUNET_HELLO_TransportPluginsFind plugins_find)
{
  struct GNUNET_HELLO_ComposeUriContext ctx;
  ctx.plugins_find = plugins_find;

  char *pkey = GNUNET_CRYPTO_rsa_public_key_to_string (&(hello->publicKey));
  GNUNET_asprintf (&(ctx.uri),
                   "%s%s",
                   GNUNET_HELLO_URI_PREFIX,
                   pkey);
  GNUNET_free (pkey);

  GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &add_address_to_uri, &ctx);
  return ctx.uri;
}
Esempio n. 12
0
/**
 * Add addresses from the address list to the HELLO.
 *
 * @param cls the HELLO with the addresses to add
 * @param max maximum space available
 * @param buf where to add the addresses
 * @return number of bytes added, 0 to terminate
 */
static size_t
add_from_hello (void *cls, size_t max, void *buf)
{
  struct GNUNET_HELLO_Message **orig = cls;
  struct AddContext ac;

  if (NULL == *orig)
    return 0; /* already done */
  ac.buf = buf;
  ac.max = max;
  ac.ret = 0;
  GNUNET_assert (NULL ==
		 GNUNET_HELLO_iterate_addresses (*orig, 
						 GNUNET_NO, &add_to_buf,
						 &ac));
  *orig = NULL;
  return ac.ret;
}
Esempio n. 13
0
/**
 * Iterate over addresses in "new_hello" that
 * are NOT already present in "old_hello".
 *
 * @param new_hello a HELLO message
 * @param old_hello a HELLO message
 * @param expiration_limit ignore addresses in old_hello
 *        that expired before the given time stamp
 * @param it iterator to call on each address
 * @param it_cls closure for it
 */
void
GNUNET_HELLO_iterate_new_addresses (const struct GNUNET_HELLO_Message
                                    *new_hello,
                                    const struct GNUNET_HELLO_Message
                                    *old_hello,
                                    struct GNUNET_TIME_Absolute
                                    expiration_limit,
                                    GNUNET_HELLO_AddressIterator it,
                                    void *it_cls)
{
  struct DeltaContext dc;

  dc.expiration_limit = expiration_limit;
  dc.it = it;
  dc.it_cls = it_cls;
  dc.old_hello = old_hello;
  GNUNET_HELLO_iterate_addresses (new_hello, GNUNET_NO, &delta_match, &dc);
}
Esempio n. 14
0
static int
find_matching (void *cls, const struct GNUNET_HELLO_Address *address,
               struct GNUNET_TIME_Absolute expiration)
{
  struct EqualsContext *ec = cls;

  if (expiration.abs_value < ec->expiration_limit.abs_value)
    return GNUNET_YES;
  ec->address = address;
  ec->expiration = expiration;
  ec->found = GNUNET_NO;
  GNUNET_HELLO_iterate_addresses (ec->h2, GNUNET_NO, &find_other_matching, ec);
  if (ec->found == GNUNET_NO)
  {
    ec->result = GNUNET_TIME_UNIT_ZERO_ABS;
    return GNUNET_SYSERR;
  }
  return GNUNET_OK;
}
Esempio n. 15
0
static int
delta_match (void *cls, const struct GNUNET_HELLO_Address *address,
             struct GNUNET_TIME_Absolute expiration)
{
  struct DeltaContext *dc = cls;
  int ret;
  struct ExpireContext ec;

  ec.address = address;
  ec.found = GNUNET_NO;
  GNUNET_HELLO_iterate_addresses (dc->old_hello, GNUNET_NO, &get_match_exp,
                                  &ec);
  if ((ec.found == GNUNET_YES) &&
      ((ec.expiration.abs_value > expiration.abs_value) ||
       (ec.expiration.abs_value >= dc->expiration_limit.abs_value)))
    return GNUNET_YES;          /* skip */
  ret = dc->it (dc->it_cls, address, expiration);
  return ret;
}
Esempio n. 16
0
static void
process (void *cls, const struct GNUNET_PeerIdentity *peer,
         const struct GNUNET_HELLO_Message *hello, const char *err_msg)
{
  unsigned int agc;

  if (err_msg != NULL)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Error in communication with PEERINFO service\n"));
  }

  if (peer == NULL)
  {
    ic = NULL;
    if ((3 == global_ret) && (retries < 50))
    {
      /* try again */
      retries++;
      add_peer ();
      ic = GNUNET_PEERINFO_iterate (h, GNUNET_NO, NULL,
                                    &process,
                                    cls);
      return;
    }
    GNUNET_assert (peer == NULL);
    GNUNET_assert (2 == global_ret);
    GNUNET_PEERINFO_disconnect (h);
    h = NULL;
    global_ret = 0;
    return;
  }
  if (hello != NULL)
  {
    GNUNET_assert (3 == global_ret);
    agc = 3;
    GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO,
                                    &check_it, &agc);
    GNUNET_assert (agc == 0);
    global_ret = 2;
  }
}
Esempio n. 17
0
static int
copy_latest (void *cls, const struct GNUNET_HELLO_Address *address,
             struct GNUNET_TIME_Absolute expiration)
{
  struct MergeContext *mc = cls;
  struct ExpireContext ec;

  ec.address = address;
  ec.found = GNUNET_NO;
  GNUNET_HELLO_iterate_addresses (mc->other, GNUNET_NO, &get_match_exp, &ec);
  if ((ec.found == GNUNET_NO) ||
      (ec.expiration.abs_value < expiration.abs_value) ||
      ((ec.expiration.abs_value == expiration.abs_value) &&
       (mc->take_equal == GNUNET_YES)))
  {
    mc->ret +=
        GNUNET_HELLO_add_address (address, expiration, &mc->buf[mc->ret],
                                  mc->max - mc->ret);
  }
  return GNUNET_OK;
}
Esempio n. 18
0
/**
 * Print URI of the peer.
 *
 * @param cls the 'struct GetUriContext'
 * @param peer identity of the peer (unused)
 * @param hello addresses of the peer
 * @param err_msg error message
 */
static void
print_my_uri (void *cls, const struct GNUNET_PeerIdentity *peer,
              const struct GNUNET_HELLO_Message *hello, 
	      const char *err_msg)
{
  struct GetUriContext *guc = cls;

  if (peer == NULL)
  {
    pic = NULL;
    if (err_msg != NULL)
      FPRINTF (stderr,
	       _("Error in communication with PEERINFO service: %s\n"), 
	       err_msg);
    GNUNET_free_non_null (guc->uri);
    GNUNET_free (guc);  
    tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL);
    return;
  } 
  if (NULL != hello)
    GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &compose_uri, guc);   
  printf ("%s\n", (const char *) guc->uri);
}
/**
 * @brief delete expired HELLO entries in data/hosts/
 *
 * @param cls pointer to current time (struct GNUNET_TIME_Absolute)
 * @param fn filename to test to see if the HELLO expired
 * @return GNUNET_OK (continue iteration)
 */
static int
discard_hosts_helper (void *cls, const char *fn)
{
  struct GNUNET_TIME_Absolute *now = cls;
  char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
  const struct GNUNET_HELLO_Message *hello;
  struct GNUNET_HELLO_Message *new_hello;
  int size;

  size = GNUNET_DISK_fn_read (fn, buffer, sizeof (buffer));
  if (size < sizeof (struct GNUNET_MessageHeader))
  {
    if (0 != UNLINK (fn))
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING |
                                GNUNET_ERROR_TYPE_BULK, "unlink", fn);
    return GNUNET_OK;
  }
  hello = (const struct GNUNET_HELLO_Message *) buffer;
  new_hello =
      GNUNET_HELLO_iterate_addresses (hello, GNUNET_YES, &discard_expired, now);
  if (new_hello != NULL)
  {
    GNUNET_DISK_fn_write (fn, new_hello, GNUNET_HELLO_size (new_hello),
                          GNUNET_DISK_PERM_USER_READ |
                          GNUNET_DISK_PERM_USER_WRITE |
                          GNUNET_DISK_PERM_GROUP_READ |
                          GNUNET_DISK_PERM_OTHER_READ);
    GNUNET_free (new_hello);
  }
  else
  {
    if (0 != UNLINK (fn))
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING |
                                GNUNET_ERROR_TYPE_BULK, "unlink", fn);
  }
  return GNUNET_OK;
}
/**
 * Callback that processes each of the known HELLOs for the
 * hostlist response construction.
 *
 * @param cls closure, NULL
 * @param peer id of the peer, NULL for last call
 * @param hello hello message for the peer (can be NULL)
 * @param err_msg message
 */
static void
host_processor (void *cls,
                const struct GNUNET_PeerIdentity *peer,
                const struct GNUNET_HELLO_Message *hello,
                const char *err_msg)
{
  size_t old;
  size_t s;
  int has_addr;

  if (NULL != err_msg)
  {
    GNUNET_assert (NULL == peer);
    builder->pitr = NULL;
    GNUNET_free_non_null (builder->data);
    GNUNET_free (builder);
    builder = NULL;
    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                _("Error in communication with PEERINFO service: %s\n"),
                err_msg);
    return;
  }
  if (NULL == peer)
  {
    builder->pitr = NULL;
    finish_response ();
    return;
  }
  if (NULL == hello)
    return;
  has_addr = GNUNET_NO;
  GNUNET_HELLO_iterate_addresses (hello,
                                  GNUNET_NO,
                                  &check_has_addr,
                                  &has_addr);
  if (GNUNET_NO == has_addr)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "HELLO for peer `%4s' has no address, not suitable for hostlist!\n",
                GNUNET_i2s (peer));
    GNUNET_STATISTICS_update (stats,
                              gettext_noop
                              ("HELLOs without addresses encountered (ignored)"),
                              1, GNUNET_NO);
    return;
  }
  old = builder->size;
  s = GNUNET_HELLO_size (hello);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Received %u bytes of `%s' from peer `%s' for hostlist.\n",
              (unsigned int) s,
              "HELLO",
              GNUNET_i2s (peer));
  if ( (old + s >= GNUNET_MAX_MALLOC_CHECKED) ||
       (old + s >= MAX_BYTES_PER_HOSTLISTS) )
  {
    /* too large, skip! */
    GNUNET_STATISTICS_update (stats,
                              gettext_noop
                              ("bytes not included in hostlist (size limit)"),
                              s, GNUNET_NO);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
              "Adding peer `%s' to hostlist (%u bytes)\n",
              GNUNET_i2s (peer),
              (unsigned int) s);
  GNUNET_array_grow (builder->data,
                     builder->size,
                     old + s);
  memcpy (&builder->data[old],
          hello,
          s);
}
Esempio n. 21
0
/**
 * Try to read the HELLOs in the given filename and discard expired
 * addresses.  Removes the file if one the HELLO is malformed.  If all
 * addresses are expired, the HELLO is also removed (but the HELLO
 * with the public key is still returned if it was found and valid).
 * The file can contain multiple HELLO messages.
 *
 * @param fn name of the file
 * @param unlink_garbage if #GNUNET_YES, try to remove useless files
 * @param r ReadHostFileContext to store the resutl
 */
static void
read_host_file (const char *fn,
                int unlink_garbage,
                struct ReadHostFileContext *r)
{
  char buffer[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1] GNUNET_ALIGN;
  unsigned int size_total;
  struct GNUNET_TIME_Absolute now;
  unsigned int left;
  const struct GNUNET_HELLO_Message *hello;
  struct GNUNET_HELLO_Message *hello_clean;
  unsigned read_pos;
  int size_hello;

  r->friend_only_hello = NULL;
  r->hello = NULL;

  if (GNUNET_YES != GNUNET_DISK_file_test (fn))
    return;
  size_total = GNUNET_DISK_fn_read (fn, buffer, sizeof (buffer));
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Read %u bytes from `%s'\n",
              size_total,
              fn);
  if (size_total < sizeof (struct GNUNET_MessageHeader))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		_("Failed to parse HELLO in file `%s': %s\n"),
		fn, "Fail has invalid size");
    if ( (GNUNET_YES == unlink_garbage) &&
	 (0 != UNLINK (fn)) &&
	 (ENOENT != errno) )
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
                                "unlink",
                                fn);
    return;
  }

  read_pos = 0;
  while (read_pos < size_total)
  {
    hello = (const struct GNUNET_HELLO_Message *) &buffer[read_pos];
    size_hello = GNUNET_HELLO_size (hello);
    if ( (0 == size_hello) ||
         (size_total - read_pos < size_hello) )
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Failed to parse HELLO in file `%s'\n"),
                  fn);
      if (0 == read_pos)
      {
        if ((GNUNET_YES == unlink_garbage) &&
            (0 != UNLINK (fn)) &&
            (ENOENT != errno) )
          GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
                                    "unlink",
                                    fn);
      }
      else
      {
        if ((GNUNET_YES == unlink_garbage) &&
            (0 != TRUNCATE (fn, read_pos)) &&
            (ENOENT != errno) )
          GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
                                    "truncate",
                                    fn);
      }
      return;
    }

    now = GNUNET_TIME_absolute_get ();
    hello_clean = GNUNET_HELLO_iterate_addresses (hello, GNUNET_YES,
						  &discard_expired, &now);
    if (NULL == hello_clean)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                  _("Failed to parse HELLO in file `%s'\n"),
                  fn);
      if ((GNUNET_YES == unlink_garbage) &&
          (0 != UNLINK (fn)) &&
          (ENOENT != errno) )
        GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
                                  "unlink",
                                  fn);
      return;
    }
    left = 0;
    (void) GNUNET_HELLO_iterate_addresses (hello_clean, GNUNET_NO,
					   &count_addresses, &left);

    if (0 == left)
    {
      GNUNET_free (hello_clean);
      break;
    }

    if (GNUNET_NO == GNUNET_HELLO_is_friend_only (hello_clean))
    {
      if (NULL == r->hello)
	r->hello = hello_clean;
      else
      {
	GNUNET_break (0);
	GNUNET_free (r->hello);
	r->hello = hello_clean;
      }
    }
    else
    {
      if (NULL == r->friend_only_hello)
	r->friend_only_hello = hello_clean;
      else
      {
	GNUNET_break (0);
	GNUNET_free (r->friend_only_hello);
	r->friend_only_hello = hello_clean;
      }
    }
    read_pos += size_hello;
  }

  if (0 == left)
  {
    /* no addresses left, remove from disk */
    if ( (GNUNET_YES == unlink_garbage) &&
         (0 != UNLINK (fn)) )
      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
                                "unlink",
                                fn);
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Found `%s' and `%s' HELLO message in file\n",
	      (NULL != r->hello) ? "public" : "NON-public",
	      (NULL != r->friend_only_hello) ? "friend only" : "NO friend only");
}