+/*
+ * We have received a PING message from someone. Need to send a PONG message
+ * in response to the peer by any means necessary. Of course, with something
+ * like TCP where a connection exists, we may want to send it that way. But
+ * we may not be able to make that distinction...
+ */
+static int handle_ping(void *cls, const struct GNUNET_MessageHeader *message,
+ const struct GNUNET_PeerIdentity *peer,
+ const char *sender_address,
+ size_t sender_address_len)
+{
+ struct TransportPlugin *plugin = cls;
+ struct TransportPingMessage *ping;
+ struct TransportPongMessage *pong;
+ uint16_t msize;
+
+ pong = GNUNET_malloc(sizeof(struct TransportPongMessage));
+
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
+ "Processing `%s' from `%s'\n",
+ "PING", GNUNET_a2s ((const struct sockaddr *)sender_address, sender_address_len));
+#endif
+
+ msize = ntohs (message->size);
+ if (msize < sizeof (struct TransportPingMessage))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ ping = (struct TransportPingMessage *) message;
+ if (0 != memcmp (&ping->target,
+ plugin->env.my_identity,
+ sizeof (struct GNUNET_PeerIdentity)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ _("Received `%s' message not destined for me!\n"), "PING");
+ return GNUNET_SYSERR;
+ }
+
+ msize -= sizeof (struct TransportPingMessage);
+/*
+ * if (GNUNET_OK != tcp_plugin_address_suggested (plugin, &vcm[1], msize))
+ {
+ GNUNET_break_op (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+
+ if (GNUNET_OK != GNUNET_SERVER_client_get_address (client, &addr, &addrlen))
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+*/
+ pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + sender_address_len);
+ pong->header.size = htons (sizeof (struct TransportPongMessage) + sender_address_len);
+ pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
+ pong->purpose.size =
+ htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
+ sizeof (uint32_t) +
+ sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded) + sender_address_len);
+ pong->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_TCP_PING);
+ pong->challenge = ping->challenge;
+
+ memcpy(&pong->signer, &my_public_key, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
+ memcpy (&pong[1], sender_address, sender_address_len);
+ GNUNET_assert (GNUNET_OK ==
+ GNUNET_CRYPTO_rsa_sign (my_private_key,
+ &pong->purpose, &pong->signature));
+
+ transmit_to_peer(NULL, TRANSPORT_DEFAULT_PRIORITY, &pong->header, GNUNET_NO, find_neighbor(peer, NULL, 0));
+ /* plugin->api->send(); */ /* We can't directly send back along received address, because
+ the port we saw for the peer (for TCP especially) will not
+ likely be the open port on the other side! */
+ GNUNET_free(pong);
+ return GNUNET_OK;
+}