- "Processing `%s' message for `%4s'\n",
- "HELLO", GNUNET_i2s (&target));
-#endif
- /* check if a HELLO for this peer is already on the validation list */
- e = pending_validations;
- while (e != NULL)
- {
- if (0 == memcmp (&e->publicKey,
- &publicKey,
- sizeof (struct
- GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)))
- {
- /* TODO: call to stats? */
-#if DEBUG_TRANSPORT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "`%s' message for peer `%4s' is already pending; ignoring new message\n",
- "HELLO", GNUNET_i2s (&target));
-#endif
- return GNUNET_OK;
- }
- e = e->next;
- }
- chvc = GNUNET_malloc (sizeof (struct CheckHelloValidatedContext) + hsize);
- chvc->plugin = plugin;
- chvc->hello = (struct GNUNET_HELLO_Message *) &chvc[1];
- memcpy (chvc->hello, hello, hsize);
- /* finally, check if HELLO was previously validated
- (continuation will then schedule actual validation) */
- GNUNET_PEERINFO_for_all (cfg,
- sched,
- &target,
- 0,
- HELLO_VERIFICATION_TIMEOUT,
- &check_hello_validated, chvc);
- return GNUNET_OK;
-}
-
-
-/**
- * Handle PING-message. If the plugin that gave us the message is
- * able to queue the PONG immediately, we only queue one PONG.
- * Otherwise we send at most TWO PONG messages, one via an unconfirmed
- * transport and one via a confirmed transport. Both addresses are
- * selected randomly among those available.
- *
- * @param plugin plugin that gave us the message
- * @param sender claimed sender of the PING
- * @param plugin_context context that might be used to send response
- * @param message the actual message
- */
-static void
-process_ping (struct TransportPlugin *plugin,
- const struct GNUNET_PeerIdentity *sender,
- void *plugin_context,
- const struct GNUNET_MessageHeader *message)
-{
- const struct ValidationChallengeMessage *vcm;
- struct ValidationChallengeResponse vcr;
- uint16_t msize;
- struct NeighbourList *n;
-
-#if DEBUG_TRANSPORT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
- "Processing PING\n");
-#endif
- msize = ntohs (message->size);
- if (msize < sizeof (struct ValidationChallengeMessage))
- {
- GNUNET_break_op (0);
- return;
- }
- vcm = (const struct ValidationChallengeMessage *) message;
- if (0 != memcmp (&vcm->target,
- &my_identity, sizeof (struct GNUNET_PeerIdentity)))
- {
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- _("Received `%s' message not destined for me!\n"), "PING");
- /* TODO: call statistics */
- return;
- }
- if ((ntohl (vcm->purpose.size) !=
- msize - sizeof (struct GNUNET_MessageHeader))
- || (ntohl (vcm->purpose.purpose) !=
- GNUNET_SIGNATURE_PURPOSE_TRANSPORT_HELLO))
- {
- GNUNET_break_op (0);
- return;
- }
- msize -= sizeof (struct ValidationChallengeMessage);
- if (GNUNET_OK !=
- plugin->api->address_suggested (plugin->api->cls, &vcm[1], msize))
- {
- GNUNET_break_op (0);
- return;
- }
- vcr.header.size = htons (sizeof (struct ValidationChallengeResponse));
- vcr.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
- vcr.challenge = vcm->challenge;
- vcr.sender = my_identity;
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CRYPTO_rsa_sign (my_private_key,
- &vcm->purpose, &vcr.signature));
-#if EXTRA_CHECKS
- GNUNET_assert (GNUNET_OK ==
- GNUNET_CRYPTO_rsa_verify
- (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_HELLO, &vcm->purpose,
- &vcr.signature, &my_public_key));
-#endif
-#if DEBUG_TRANSPORT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
- "Trying to transmit PONG using inbound connection\n");
-#endif
- n = find_neighbour (sender);
- if (n == NULL)
- {
- GNUNET_break (0);
- return;
- }
- transmit_to_peer (NULL, &vcr.header, GNUNET_YES, n);
-}
-
-
-/**
- * Handle PONG-message.
- *
- * @param message the actual message
- */
-static void
-process_pong (struct TransportPlugin *plugin,
- const struct GNUNET_MessageHeader *message)
-{
- const struct ValidationChallengeResponse *vcr;
- struct ValidationList *pos;
- struct GNUNET_PeerIdentity peer;
- struct ValidationAddress *va;
- int all_done;
- int matched;
-
-#if DEBUG_TRANSPORT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
- "Processing PONG\n");
-#endif
- vcr = (const struct ValidationChallengeResponse *) message;
- pos = pending_validations;
- while (pos != NULL)
- {
- GNUNET_CRYPTO_hash (&pos->publicKey,
- sizeof (struct
- GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
- &peer.hashPubKey);
- if (0 ==
- memcmp (&peer, &vcr->sender, sizeof (struct GNUNET_PeerIdentity)))
- break;
- pos = pos->next;
- }
- if (pos == NULL)
- {
- /* TODO: call statistics (unmatched PONG) */
- GNUNET_log (GNUNET_ERROR_TYPE_INFO,
- _
- ("Received `%s' message but have no record of a matching `%s' message. Ignoring.\n"),
- "PONG", "PING");
- return;
- }
- all_done = GNUNET_YES;
- matched = GNUNET_NO;
- va = pos->addresses;
- while (va != NULL)
- {
- if (va->msg->challenge == vcr->challenge)
- {
- if (GNUNET_OK !=
- GNUNET_CRYPTO_rsa_verify
- (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_HELLO, &va->msg->purpose,
- &vcr->signature, &pos->publicKey))
- {
- /* this could rarely happen if we used the same
- challenge number for the peer for two different
- transports / addresses, but the likelihood is
- very small... */
- GNUNET_break_op (0);
- }
- else
- {
-#if DEBUG_TRANSPORT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Confirmed validity of peer address.\n");