From cf6288e9f0e48c3f838078b231256183a19ff8bf Mon Sep 17 00:00:00 2001 From: Ji Lu Date: Thu, 10 Dec 2009 20:59:46 +0000 Subject: [PATCH] --- src/transport/gnunet-service-transport.c | 73 ++++++++++++ src/transport/transport.h | 5 + src/transport/transport_api_address_lookup.c | 116 +++++++++++++++++++ 3 files changed, 194 insertions(+) create mode 100644 src/transport/transport_api_address_lookup.c diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index 5c5c64dbc..b93ced56f 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c @@ -2451,6 +2451,79 @@ handle_try_connect (void *cls, 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 diff --git a/src/transport/transport.h b/src/transport/transport.h index 5de46b38f..fed4bf162 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h @@ -246,6 +246,11 @@ struct AddressLookupMessage */ struct GNUNET_MessageHeader header; + /** + * timeout to give up. + */ + struct GNUNET_TIME_AbosluteNBO tiemout; + /** * Length of the (binary) address in bytes, in big-endian. */ diff --git a/src/transport/transport_api_address_lookup.c b/src/transport/transport_api_address_lookup.c new file mode 100644 index 000000000..1c0cf7340 --- /dev/null +++ b/src/transport/transport_api_address_lookup.c @@ -0,0 +1,116 @@ +#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); +} -- 2.25.1