#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); }