GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
+static void
+transmit_address_to_client (void *cls, const char *address)
+{
+ struct GNUNET_SERVER_TransmitContext *tc = cls;
+ size_t slen;
+
+ if (NULL == address)
+ slen = 0;
+ else
+ slen = strlen (address) + 1;
+ GNUNET_SERVER_transmit_context_append (tc, address, slen,
+ GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY);
+ if (NULL == address)
+ GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL);
+}
+
+/**
+ * Handle AddressLookup-message.
+ *
+ * @param cls closure (always NULL)
+ * @param client identification of the client
+ * @param message the actual message
+ */
+static void
+handle_addressLookUp (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
+{
+ const struct AddressLookupMessage *alum;
+ struct TransportPlugin *lsPlugin;
+ const char *nameTransport;
+ const char *address;
+ uint16_t size;
+ struct GNUNET_MessageHeader reply;
+ struct GNUNET_SERVER_TransmitContext *tc;
+
+ size = ntohs (message->size);
+ if (size < sizeof(struct AddressLookupMessage))
+ {
+ GNUNET_break_op (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ alum = (const struct AddressLookupMessage *) message;
+ uint32_t addressLen = ntohl(alum->addrlen);
+ if (size <= sizeof(struct AddressLookupMessage) + addressLen)
+ {
+ GNUNET_break_op (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ address = (const char *)&alum[1];
+ nameTransport = (const char*)&addr[addressLen];
+ if (nameTransport [size - sizeof (struct AddressLookupMessage) - addressLen -1] != '\0')
+ {
+ GNUNET_break_op (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ struct GNUNET_TIME_Absolute timeout= GNUNET_TIME_absolute_ntoh(bbalum->timeout);
+ struct GNUNET_TIME_Relative rtimeout = GNUNET_TIME_absolute_get_remaining(timeout);
+ lsPlugin = find_transport(nameTransport);
+ if (NULL == lsPlugin)
+ {
+ tc = GNUNET_SERVER_transmit_context_create (client);
+ GNUNET_SERVER_transmit_context_append (tc, NULL, 0, GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY);
+ GNUNET_SERVER_transmit_context_run (tc, rtimeout);
+ return;
+ }
+ tc = GNUNET_SERVER_transmit_context_create (client);
+ lsPlugin->api->address_pretty_printer(cls, nameTransport,
+ addr, alum->addrlen, GNUNET_YES, rtimeout, &transmit_address_to_client, tc);
+}
/**
* List of handlers for the messages understood by this
--- /dev/null
+#include "platform.h"
+#include "gnunet_client_lib.h"
+#include "gnunet_arm_service.h"
+#include "gnunet_hello_lib.h"
+#include "gnunet_protocols.h"
+#include "gnunet_server_lib.h"
+#include "gnunet_time_lib.h"
+#include "gnunet_transport_service.h"
+#include "transport.h"
+
+// FIXME: document
+struct AddressLookUpCB {
+ GNUNET_TRANSPORT_AddressLookUpCallback cb;
+ void *cls;
+ struct GNUNET_TIME_Absolute timeout;
+ struct GNUNET_CLIENT_Connection *client;
+};
+
+
+// FIXME: document
+static void
+address_response_processor(void *cls, const struct
+ GNUNET_MessageHeader * msg)
+{
+ struct AddressLookUpCB *alucb = cls;
+ const char *address;
+ uint16_t size;
+
+ if (msg == NULL)
+ {
+ /* timeout */
+ alucb->cb (alucb->cls, NULL);
+ GNUNET_CLIENT_disconnect (alucb->client);
+ GNUNET_free (alucb);
+ return;
+ }
+ size = ntohs(msg->size);
+ if (size == sizeof(struct GNUNET_MessageHeader))
+ {
+ /* last reply */
+ address = NULL;
+ }
+ else
+ {
+ address = (const char*) &msg[1];
+ if (address[size - sizeof(struct GNUNET_MessageHeader) - 1] != '\0')
+ {
+ /* invalid reply */
+ GNUNET_break_op (0);
+ alucb->cb (alucb->cls, NULL);
+ GNUNET_CLIENT_disconnect (alucb->client);
+ GNUNET_free (alucb);
+ return;
+ }
+ else
+ {
+ /* expect more replies */
+ GNUNET_CLIENT_receive (alucb->client, &address_response_processor, alucb,
+ GNUNET_TIME_absolute_get_remaining (alucb->timeout));
+ }
+ }
+ alucb->cb (alucb->cls, address);
+ if (address == NULL)
+ {
+ /* done! */
+ GNUNET_CLIENT_disconnect (alucb->client);
+ GNUNET_free (alucb);
+ }
+}
+
+void
+GNUNET_TRANSPORT_address_lookup (struct GNUNET_SCHEDULER_Handle *sched,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ const char * address,
+ size_t addressLen,
+ const char * nameTrans,
+ struct GNUNET_TIME_Relative timeout,
+ GNUNET_TRANSPORT_AddressLookUpCallback aluc,
+ void *aluc_cls)
+{
+ size_t len = sizeof (struct AddressLookupMessage) + addressLen + strlen (nameTrans) + 1;
+ struct AddressLookupMessage *msg;
+ struct GNUNET_TIME_Absolute abs_timeout;
+ struct AddressLookUpCB *aluCB;
+ struct GNUNET_CLIENT_Connection *client;
+
+ if (len >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+ {
+ GNUNET_break (0);
+ aluc (aluc_cls, NULL);
+ return;
+ }
+ client = GNUNET_CLIENT_connect (sched, "transport", cfg);
+ if (client == NULL)
+ {
+ aluc (aluc_cls, NULL);
+ return;
+ }
+ abs_timeout = GNUNET_TIME_relative_to_absolute(timeout);
+ msg = GNUNET_malloc (len);
+ msg->header->size = htons (len);
+ msg->header->type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_LOOKUP);
+ msg->timeout = GNUNET_TIME_absolute_hton(abs_timeout);
+ msg->addrlen = htonl (addressLen);
+ char *addrbuf = (char*) &msg[1];
+ memcpy (addrbuf, address, addressLen);
+ char *tbuf = &addrbuf[addressLen];
+ memcpy (tbuf, nameTrans, strlen(nameTrans) + 1);
+ aluCB = GNUNET_malloc (sizeof (struct AddressLookUpCB));
+ aluCB->cb = aluc;
+ aluCB->cb_cls = aluc_cls;
+ aluCB->timeout = abs_timeout;
+ aluCB->client = client;
+ GNUNET_CLIENT_transmit_and_get_response(client, msg->header, timeout, GNUNET_YES, &address_response_processor, aluCB);
+ GNUNET_free(msg);
+}