/**
 * Construct our HELLO message from all of the addresses of
 * all of the transports.
 *
 * @param cls unused
 * @param tc scheduler context
 */
static void
refresh_hello_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct GeneratorContext gc;
  int friend_only;

  hello_task = GNUNET_SCHEDULER_NO_TASK;
  gc.addr_pos = oal_head;
  gc.expiration = GNUNET_TIME_relative_to_absolute (hello_expiration);


  friend_only = GNUNET_HELLO_is_friend_only (our_hello);
  GNUNET_free (our_hello);
  our_hello = GNUNET_HELLO_create (&GST_my_public_key, &address_generator, &gc, friend_only);
  GNUNET_assert (NULL != our_hello);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Refreshed my %s `%s', new size is %d\n",
              (GNUNET_YES == GNUNET_HELLO_is_friend_only (our_hello)) ? "friend-only" : "public",
              "HELLO", GNUNET_HELLO_size (our_hello));
  GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# refreshed my HELLO"), 1,
                            GNUNET_NO);
  if (NULL != hello_cb)
    hello_cb (hello_cb_cls, GST_hello_get ());
  GNUNET_PEERINFO_add_peer (GST_peerinfo, our_hello, NULL, NULL);
  hello_task =
      GNUNET_SCHEDULER_add_delayed (HELLO_REFRESH_PERIOD, &refresh_hello_task,
                                    NULL);

}
Esempio n. 2
0
/**
 * Parse a hello URI string to a hello message.
 *
 * @param uri URI string to parse
 * @param pubkey Pointer to struct where public key is parsed
 * @param hello Pointer to struct where hello message is parsed
 * @param plugins_find Function to find transport plugins by name
 * @return GNUNET_OK on success, GNUNET_SYSERR if the URI was invalid, GNUNET_NO on other errors
 */
int
GNUNET_HELLO_parse_uri (const char *uri,
                        struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pubkey,
                        struct GNUNET_HELLO_Message **hello,
                        GNUNET_HELLO_TransportPluginsFind plugins_find)
{
  const char *pks;
  const char *exc;
  struct GNUNET_HELLO_ParseUriContext ctx;

  if (0 != strncmp (uri,
		    GNUNET_HELLO_URI_PREFIX,
		    strlen (GNUNET_HELLO_URI_PREFIX)))
    return GNUNET_SYSERR;
  pks = &uri[strlen (GNUNET_HELLO_URI_PREFIX)];
  exc = strstr (pks, "!");

  if (GNUNET_OK !=
      GNUNET_STRINGS_string_to_data (pks,
                                     (NULL == exc) ? strlen (pks) : (exc - pks),
                                     (unsigned char *) pubkey,
                                     sizeof (*pubkey)))
    return GNUNET_SYSERR;

  ctx.pos = exc;
  ctx.ret = GNUNET_OK;
  ctx.plugins_find = plugins_find;
  *hello = GNUNET_HELLO_create (pubkey, &add_address_to_hello, &ctx);

  return ctx.ret;
}
/**
 * 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. 4
0
/**
 * Construct a HELLO message by merging the
 * addresses in two existing HELLOs (which
 * must be for the same peer).
 *
 * @param h1 first HELLO message
 * @param h2 the second HELLO message
 * @return the combined hello message
 */
struct GNUNET_HELLO_Message *
GNUNET_HELLO_merge (const struct GNUNET_HELLO_Message *h1,
                    const struct GNUNET_HELLO_Message *h2)
{
  struct MergeContext mc = { h1, h2, NULL, NULL, 0, 0, 0 };

  return GNUNET_HELLO_create (&h1->publicKey, &merge_addr, &mc);
}
/**
 * Initialize the HELLO module.
 *
 * @param friend_only use a friend only hello
 * @param cb function to call whenever our HELLO changes
 * @param cb_cls closure for cb
 */
void
GST_hello_start (int friend_only, GST_HelloCallback cb, void *cb_cls)
{
  hello_cb = cb;
  hello_cb_cls = cb_cls;
  our_hello = GNUNET_HELLO_create (&GST_my_public_key, NULL, NULL, friend_only);
  GNUNET_assert (NULL != our_hello);
  refresh_hello ();
}
Esempio n. 6
0
static void
add_peer ()
{
  struct GNUNET_HELLO_Message *h2;
  size_t agc;

  agc = 2;
  memset (&pid, 32, sizeof (pid));
  h2 = GNUNET_HELLO_create (&pid.public_key, &address_generator, &agc, GNUNET_NO);
  GNUNET_PEERINFO_add_peer (h, h2, NULL, NULL);
  GNUNET_free (h2);

}
Esempio n. 7
0
/**
 * Parse the PUT URI given at the command line and add it to our peerinfo 
 * database.
 *
 * @param put_uri URI string to parse
 * @return GNUNET_OK on success, GNUNET_SYSERR if the URI was invalid, GNUNET_NO on other errors
 */
static int
parse_hello_uri (const char *put_uri)
{
  const char *pks;
  const char *exc;
  struct GNUNET_HELLO_Message *hello;
  struct GNUNET_PEERINFO_HelloAddressParsingContext ctx;

  if (0 != strncmp (put_uri,
		    HELLO_URI_PREFIX,
		    strlen (HELLO_URI_PREFIX)))
    return GNUNET_SYSERR;
  pks = &put_uri[strlen (HELLO_URI_PREFIX)];
  exc = strstr (pks, "!");

  if (GNUNET_OK != GNUNET_STRINGS_string_to_data (pks,
						  (NULL == exc) ? strlen (pks) : (exc - pks),
						  (unsigned char *) &my_public_key, 
						  sizeof (my_public_key)))
    return GNUNET_SYSERR;
  ctx.pos = exc;
  ctx.ret = GNUNET_OK;
  hello = GNUNET_HELLO_create (&my_public_key, &add_address_to_hello, &ctx);

  if (NULL != hello)
  {
    /* WARNING: this adds the address from URI WITHOUT verification! */
    if (GNUNET_OK == ctx.ret)    
      ac = GNUNET_PEERINFO_add_peer (peerinfo, hello, &add_continuation, NULL);
    else
      tt = GNUNET_SCHEDULER_add_now (&state_machine, NULL);
    GNUNET_free (hello);
  }

  /* wait 1s to give peerinfo operation a chance to succeed */
  /* FIXME: current peerinfo API sucks to require this; not to mention
     that we get no feedback to determine if the operation actually succeeded */
  return ctx.ret;
}
Esempio n. 8
0
int
main (int argc, char *argv[])
{
  struct GNUNET_DISK_FileHandle *fh;
  struct GNUNET_HELLO_Message *orig;
  struct GNUNET_HELLO_Message *result;
  struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk;
  uint64_t fsize;

  GNUNET_log_setup ("gnunet-hello", "INFO", NULL);
  if (argc != 2)
  {
    FPRINTF (stderr,
	     "%s",
	     _("Call with name of HELLO file to modify.\n"));
    return 1;
  }
  if (GNUNET_OK != GNUNET_DISK_file_size (argv[1], &fsize, GNUNET_YES, GNUNET_YES))
  {
    FPRINTF (stderr,
	     _("Error accessing file `%s': %s\n"),
	     argv[1],
	     STRERROR (errno));
    return 1;
  }
  if (fsize > 65536)
  {
    FPRINTF (stderr,
	     _("File `%s' is too big to be a HELLO\n"),
	     argv[1]);
    return 1;
  }
  if (fsize < sizeof (struct GNUNET_MessageHeader))
  {
    FPRINTF (stderr,
	     _("File `%s' is too small to be a HELLO\n"),
	     argv[1]);
    return 1;
  }
  fh = GNUNET_DISK_file_open (argv[1], 
			      GNUNET_DISK_OPEN_READ,
			      GNUNET_DISK_PERM_USER_READ);
  if (NULL == fh)
  {
    FPRINTF (stderr,
	     _("Error opening file `%s': %s\n"),
	     argv[1],
	     STRERROR (errno));
    return 1;
  }
  {
    char buf[fsize] GNUNET_ALIGN;
    
    GNUNET_assert (fsize == 
		   GNUNET_DISK_file_read (fh, buf, fsize));
    GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
    orig = (struct GNUNET_HELLO_Message *) buf;
    if ( (fsize != GNUNET_HELLO_size (orig)) ||
	 (GNUNET_OK != GNUNET_HELLO_get_key (orig, &pk)) )
    {
      FPRINTF (stderr,
	       _("Did not find well-formed HELLO in file `%s'\n"),
	       argv[1]);
      return 1;
    }
    result = GNUNET_HELLO_create (&pk, &add_from_hello, &orig);
    GNUNET_assert (NULL != result);
     fh = GNUNET_DISK_file_open (argv[1], 
				 GNUNET_DISK_OPEN_WRITE,
				 GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE);
     if (NULL == fh)
     {
       FPRINTF (stderr,
		_("Error opening file `%s': %s\n"),
		argv[1],
		STRERROR (errno));
       GNUNET_free (result);
       return 1;
     }
     fsize = GNUNET_HELLO_size (result);
     if (fsize != GNUNET_DISK_file_write (fh,
					  result,
					  fsize))
     {
       FPRINTF (stderr,
		_("Error writing HELLO to file `%s': %s\n"),
		argv[1],
		STRERROR (errno));
       (void) GNUNET_DISK_file_close (fh);
       return 1;
     }
    GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
  }
  return 0;
}
/**
 * We've received a PONG.  Check if it matches a pending PING and
 * mark the respective address as confirmed.
 *
 * @param sender peer sending the PONG
 * @param hdr the PONG
 */
void
GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender,
                            const struct GNUNET_MessageHeader *hdr)
{
  const struct TransportPongMessage *pong;
  struct ValidationEntry *ve;
  const char *tname;
  const char *addr;
  size_t addrlen;
  size_t slen;
  size_t size;
  struct GNUNET_HELLO_Message *hello;
  struct GNUNET_HELLO_Address address;

  if (ntohs (hdr->size) < sizeof (struct TransportPongMessage))
  {
    GNUNET_break_op (0);
    return;
  }
  GNUNET_STATISTICS_update (GST_stats,
                            gettext_noop ("# PONG messages received"), 1,
                            GNUNET_NO);

  pong = (const struct TransportPongMessage *) hdr;
  tname = (const char *) &pong[1];
  size = ntohs (hdr->size) - sizeof (struct TransportPongMessage);
  addr = memchr (tname, '\0', size);
  if (NULL == addr)
  {
    GNUNET_break_op (0);
    return;
  }
  addr++;
  slen = strlen (tname) + 1;
  addrlen = size - slen;
  address.peer = *sender;
  address.address = addr;
  address.address_length = addrlen;
  address.transport_name = tname;
  ve = find_validation_entry (NULL, &address);
  if ((NULL == ve) || (ve->expecting_pong == GNUNET_NO))
  {
    GNUNET_STATISTICS_update (GST_stats,
                              gettext_noop
                              ("# PONGs dropped, no matching pending validation"),
                              1, GNUNET_NO);
    return;
  }
  /* now check that PONG is well-formed */
  if (0 != memcmp (&ve->pid, sender, sizeof (struct GNUNET_PeerIdentity)))
  {
    GNUNET_break_op (0);
    return;
  }

  if (GNUNET_OK !=
      GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN,
                                &pong->purpose, &pong->signature,
                                &ve->public_key))
  {
    GNUNET_break_op (0);
    return;
  }

  if (GNUNET_TIME_absolute_get_remaining
      (GNUNET_TIME_absolute_ntoh (pong->expiration)).rel_value == 0)
  {
    GNUNET_STATISTICS_update (GST_stats,
                              gettext_noop
                              ("# PONGs dropped, signature expired"), 1,
                              GNUNET_NO);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Address validated for peer `%s' with plugin `%s': `%s'\n",

              GNUNET_i2s (sender), tname, GST_plugins_a2s (ve->address));
  /* validity achieved, remember it! */
  ve->expecting_pong = GNUNET_NO;
  ve->valid_until = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION);
  ve->latency = GNUNET_TIME_absolute_get_duration (ve->send_time);
  {
    struct GNUNET_ATS_Information ats;

    ats.type = htonl (GNUNET_ATS_QUALITY_NET_DELAY);
    ats.value = htonl ((uint32_t) ve->latency.rel_value);
    GNUNET_ATS_address_update (GST_ats, ve->address, NULL, &ats, 1);
  }
  /* build HELLO to store in PEERINFO */
  ve->copied = GNUNET_NO;
  hello = GNUNET_HELLO_create (&ve->public_key, &add_valid_peer_address, ve);
  GNUNET_PEERINFO_add_peer (GST_peerinfo, hello, NULL, NULL);
  GNUNET_free (hello);
}