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 it
6 under the terms of the GNU General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
16 * @file transport/transport_api_address_to_string.c
17 * @author Christian Grothoff
18 * @brief enable clients to convert addresses to human readable strings
21 #include "gnunet_util_lib.h"
22 #include "gnunet_arm_service.h"
23 #include "gnunet_hello_lib.h"
24 #include "gnunet_protocols.h"
25 #include "gnunet_transport_service.h"
26 #include "transport.h"
29 * Context for the address lookup.
31 struct GNUNET_TRANSPORT_AddressToStringContext
34 * Function to call with the human-readable address.
36 GNUNET_TRANSPORT_AddressToStringCallback cb;
44 * Connection to the service.
46 struct GNUNET_MQ_Handle *mq;
52 * Function called with responses from the service.
54 * @param cls our `struct GNUNET_TRANSPORT_AddressToStringContext *`
55 * @param msg message with the human-readable address
56 * @return #GNUNET_OK if message is well-formed
59 check_reply (void *cls,
60 const struct AddressToStringResultMessage *atsm)
62 uint16_t size = ntohs (atsm->header.size) - sizeof (*atsm);
67 result = (int) ntohl (atsm->res);
68 addr_len = ntohl (atsm->addr_len);
69 if (GNUNET_SYSERR == result)
73 if (GNUNET_OK != result)
80 address = (const char *) &atsm[1];
81 if ( (addr_len > size) ||
82 (address[addr_len -1] != '\0') )
93 * Function called with responses from the service.
95 * @param cls our `struct GNUNET_TRANSPORT_AddressToStringContext *`
96 * @param msg message with the human-readable address
99 handle_reply (void *cls,
100 const struct AddressToStringResultMessage *atsm)
102 struct GNUNET_TRANSPORT_AddressToStringContext *alucb = cls;
103 uint16_t size = ntohs (atsm->header.size) - sizeof (*atsm);
107 result = (int) ntohl (atsm->res);
108 if (GNUNET_SYSERR == result)
110 /* expect more replies; as this is not the last
111 call, we must pass the empty string for the address */
112 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
113 "Address resolution failed\n");
114 alucb->cb (alucb->cb_cls,
121 /* we are done (successfully, without communication errors) */
122 alucb->cb (alucb->cb_cls,
125 GNUNET_TRANSPORT_address_to_string_cancel (alucb);
128 address = (const char *) &atsm[1];
129 /* return normal reply to caller, also expect more replies */
130 alucb->cb (alucb->cb_cls,
137 * Generic error handler, called with the appropriate
138 * error code and the same closure specified at the creation of
140 * Not every message queue implementation supports an error handler.
142 * @param cls the `struct GNUNET_TRANSPORT_AddressToStringContext *`
143 * @param error error code
146 mq_error_handler (void *cls,
147 enum GNUNET_MQ_Error error)
149 struct GNUNET_TRANSPORT_AddressToStringContext *alucb = cls;
151 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
152 "Disconnected from transport, address resolution failed\n");
153 alucb->cb (alucb->cb_cls,
156 GNUNET_TRANSPORT_address_to_string_cancel (alucb);
161 * Convert a binary address into a human readable address.
163 * @param cfg configuration to use
164 * @param address address to convert (binary format)
165 * @param numeric should (IP) addresses be displayed in numeric form
166 * (otherwise do reverse DNS lookup)
167 * @param timeout how long is the lookup allowed to take at most
168 * @param aluc function to call with the results
169 * @param aluc_cls closure for @a aluc
170 * @return handle to cancel the operation, NULL on error
172 struct GNUNET_TRANSPORT_AddressToStringContext *
173 GNUNET_TRANSPORT_address_to_string (const struct GNUNET_CONFIGURATION_Handle *cfg,
174 const struct GNUNET_HELLO_Address *address,
176 struct GNUNET_TIME_Relative timeout,
177 GNUNET_TRANSPORT_AddressToStringCallback aluc,
180 struct GNUNET_TRANSPORT_AddressToStringContext *alc
181 = GNUNET_new (struct GNUNET_TRANSPORT_AddressToStringContext);
182 struct GNUNET_MQ_MessageHandler handlers[] = {
183 GNUNET_MQ_hd_var_size (reply,
184 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING_REPLY,
185 struct AddressToStringResultMessage,
187 GNUNET_MQ_handler_end ()
191 struct AddressLookupMessage *msg;
192 struct GNUNET_MQ_Envelope *env;
195 alen = address->address_length;
196 slen = strlen (address->transport_name) + 1;
197 if ( (alen + slen >= GNUNET_MAX_MESSAGE_SIZE
198 - sizeof (struct AddressLookupMessage)) ||
199 (alen >= GNUNET_MAX_MESSAGE_SIZE) ||
200 (slen >= GNUNET_MAX_MESSAGE_SIZE) )
207 alc->cb_cls = aluc_cls;
208 alc->mq = GNUNET_CLIENT_connect (cfg,
219 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
220 "Client tries to resolve for peer `%s' address plugin %s len %u\n",
221 GNUNET_i2s (&address->peer),
222 address->transport_name,
223 (unsigned int) address->address_length);
224 env = GNUNET_MQ_msg_extra (msg,
226 GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_TO_STRING);
227 msg->numeric_only = htons ((int16_t) numeric);
228 msg->addrlen = htons ((uint16_t) alen);
229 msg->timeout = GNUNET_TIME_relative_hton (timeout);
230 addrbuf = (char *) &msg[1];
231 GNUNET_memcpy (addrbuf,
234 GNUNET_memcpy (&addrbuf[alen],
235 address->transport_name,
237 GNUNET_MQ_send (alc->mq,
244 * Cancel request for address conversion.
246 * @param alc the context handle
249 GNUNET_TRANSPORT_address_to_string_cancel (struct GNUNET_TRANSPORT_AddressToStringContext *alc)
251 GNUNET_MQ_destroy (alc->mq);
256 /* end of transport_api_address_to_string.c */