/** * Insert a peer in our list */ void NetworkManager::putHelloSlot (QString helloUrl) { struct GNUNET_HELLO_Message *hello = NULL; const char *put_uri = helloUrl.toUtf8().constData(); GNUNET_CRYPTO_EddsaPublicKey mypublickey = theApp->gnunet()->myPeer()->public_key; int ret = GNUNET_HELLO_parse_uri(put_uri, &mypublickey, &hello, &m_gnunetTransportPlugins->GPI_plugins_find); if (NULL != hello) { // WARNING: this adds the address from URI WITHOUT verification! if (GNUNET_OK == ret) GNUNET_PEERINFO_add_peer (m_peerInfo, hello, &add_continuation, NULL); GNUNET_free (hello); } else { qWarning() << tr("Failed to process the url"); } }
/** * 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); }
/** * 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)); }
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); }
/** * 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) { struct GNUNET_HELLO_Message *hello; int ret = GNUNET_HELLO_parse_uri(put_uri, &my_public_key, &hello, &GPI_plugins_find); if (NULL != hello) { /* WARNING: this adds the address from URI WITHOUT verification! */ if (GNUNET_OK == 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 ret; }
/** * 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; }
/** * 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); }