2 This file is part of GNUnet.
3 Copyright (C) 2009-2014, 2016 GNUnet e.V.
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
21 * @file transport/transport_api_address_to_string.c
22 * @author Christian Grothoff
23 * @brief enable clients to convert addresses to human readable strings
26 #include "gnunet_util_lib.h"
27 #include "gnunet_arm_service.h"
28 #include "gnunet_hello_lib.h"
29 #include "gnunet_protocols.h"
30 #include "gnunet_transport_service.h"
31 #include "transport.h"
34 * Context for the address lookup.
36 struct GNUNET_TRANSPORT_AddressToStringContext
39 * Function to call with the human-readable address.
41 GNUNET_TRANSPORT_AddressToStringCallback cb;
49 * Connection to the service.
51 struct GNUNET_MQ_Handle *mq;
57 * Function called with responses from the service.
59 * @param cls our `struct GNUNET_TRANSPORT_AddressToStringContext *`
60 * @param msg message with the human-readable address
61 * @return #GNUNET_OK if message is well-formed
64 check_reply (void *cls,
65 const struct AddressToStringResultMessage *atsm)
67 uint16_t size = ntohs (atsm->header.size) - sizeof (*atsm);
72 result = (int) ntohl (atsm->res);
73 addr_len = ntohl (atsm->addr_len);
74 if (GNUNET_SYSERR == result)
78 if (GNUNET_OK != result)
85 address = (const char *) &atsm[1];
86 if ( (addr_len > size) ||
87 (address[addr_len -1] != '\0') )
98 * Function called with responses from the service.
100 * @param cls our `struct GNUNET_TRANSPORT_AddressToStringContext *`
101 * @param msg message with the human-readable address
104 handle_reply (void *cls,
105 const struct AddressToStringResultMessage *atsm)
107 struct GNUNET_TRANSPORT_AddressToStringContext *alucb = cls;
108 uint16_t size = ntohs (atsm->header.size) - sizeof (*atsm);
112 result = (int) ntohl (atsm->res);
113 if (GNUNET_SYSERR == result)
115 /* expect more replies; as this is not the last
116 call, we must pass the empty string for the address */
117 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
118 "Address resolution failed\n");
119 alucb->cb (alucb->cb_cls,
126 /* we are done (successfully, without communication errors) */
127 alucb->cb (alucb->cb_cls,
130 GNUNET_TRANSPORT_address_to_string_cancel (alucb);
133 address = (const char *) &atsm[1];
134 /* return normal reply to caller, also expect more replies */
135 alucb->cb (alucb->cb_cls,
142 * Generic error handler, called with the appropriate
143 * error code and the same closure specified at the creation of
145 * Not every message queue implementation supports an error handler.
147 * @param cls the `struct GNUNET_TRANSPORT_AddressToStringContext *`
148 * @param error error code
151 mq_error_handler (void *cls,
152 enum GNUNET_MQ_Error error)
154 struct GNUNET_TRANSPORT_AddressToStringContext *alucb = cls;
156 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
157 "Disconnected from transport, address resolution failed\n");
158 alucb->cb (alucb->cb_cls,
161 GNUNET_TRANSPORT_address_to_string_cancel (alucb);
166 * Convert a binary address into a human readable address.
168 * @param cfg configuration to use
169 * @param address address to convert (binary format)
170 * @param numeric should (IP) addresses be displayed in numeric form
171 * (otherwise do reverse DNS lookup)
172 * @param timeout how long is the lookup allowed to take at most
173 * @param aluc function to call with the results
174 * @param aluc_cls closure for @a aluc
175 * @return handle to cancel the operation, NULL on error
177 struct GNUNET_TRANSPORT_AddressToStringContext *
178 GNUNET_TRANSPORT_address_to_string (const struct GNUNET_CONFIGURATION_Handle *cfg,
179 const struct GNUNET_HELLO_Address *address,
181 struct GNUNET_TIME_Relative timeout,
182 GNUNET_TRANSPORT_AddressToStringCallback aluc,
185 GNUNET_MQ_hd_var_size (reply,
186 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY,
187 struct AddressToStringResultMessage);
188 struct GNUNET_TRANSPORT_AddressToStringContext *alc
189 = GNUNET_new (struct GNUNET_TRANSPORT_AddressToStringContext);
190 struct GNUNET_MQ_MessageHandler handlers[] = {
191 make_reply_handler (alc),
192 GNUNET_MQ_handler_end ()
196 struct AddressLookupMessage *msg;
197 struct GNUNET_MQ_Envelope *env;
200 alen = address->address_length;
201 slen = strlen (address->transport_name) + 1;
202 if ( (alen + slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE
203 - sizeof (struct AddressLookupMessage)) ||
204 (alen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
205 (slen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) )
212 alc->cb_cls = aluc_cls;
213 alc->mq = GNUNET_CLIENT_connecT (cfg,
224 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
225 "Client tries to resolve for peer `%s' address plugin %s len %u\n",
226 GNUNET_i2s (&address->peer),
227 address->transport_name,
228 (unsigned int) address->address_length);
229 env = GNUNET_MQ_msg_extra (msg,
231 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING);
232 msg->numeric_only = htons ((int16_t) numeric);
233 msg->addrlen = htons ((uint16_t) alen);
234 msg->timeout = GNUNET_TIME_relative_hton (timeout);
235 addrbuf = (char *) &msg[1];
236 GNUNET_memcpy (addrbuf,
239 GNUNET_memcpy (&addrbuf[alen],
240 address->transport_name,
242 GNUNET_MQ_send (alc->mq,
249 * Cancel request for address conversion.
251 * @param alc the context handle
254 GNUNET_TRANSPORT_address_to_string_cancel (struct GNUNET_TRANSPORT_AddressToStringContext *alc)
256 GNUNET_MQ_destroy (alc->mq);
261 /* end of transport_api_address_to_string.c */