2 This file is part of GNUnet.
3 (C) 2009, 2010 Christian Grothoff (and other contributing authors)
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., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
23 * @brief library to access the GNS service
24 * @author Martin Schanzenbach
28 #include "gnunet_util_lib.h"
29 #include "gnunet_constants.h"
30 #include "gnunet_arm_service.h"
31 #include "gnunet_hello_lib.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_dht_service.h"
35 #define DEBUG_GNS_API GNUNET_EXTRA_LOGGING
37 #define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__)
40 * Handle to a Lookup request
42 struct GNUNET_GNS_LookupHandle
46 * Iterator to call on data receipt
48 GNUNET_GNS_LookupIterator iter;
51 * Closure for the iterator callback
56 * Main handle to this GNS api
58 struct GNUNET_GNS_Handle *gns_handle;
61 * Key that this get request is for
66 * Unique identifier for this request (for key collisions).
74 * Connection to the GNS service.
76 struct GNUNET_GNS_Handle
80 * Configuration to use.
82 const struct GNUNET_CONFIGURATION_Handle *cfg;
85 * Socket (if available).
87 struct GNUNET_CLIENT_Connection *client;
90 * Currently pending transmission request (or NULL).
92 struct GNUNET_CLIENT_TransmitHandle *th;
94 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
97 * How quickly should we retry? Used for exponential back-off on
100 struct GNUNET_TIME_Relative retry_time;
103 * Generator for unique ids.
108 * Did we start our receive loop yet?
115 * Try to (re)connect to the GNS service.
117 * @return GNUNET_YES on success, GNUNET_NO on failure.
120 try_connect (struct GNUNET_GNS_Handle *handle)
122 if (handle->client != NULL)
124 handle->in_receive = GNUNET_NO;
125 handle->client = GNUNET_CLIENT_connect ("gns", handle->cfg);
126 if (handle->client == NULL)
128 LOG (GNUNET_ERROR_TYPE_WARNING,
129 _("Failed to connect to the GNS service!\n"));
136 * Try reconnecting to the GNS service.
138 * @param cls GNUNET_GNS_Handle
139 * @param tc scheduler context
142 try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
144 struct GNUNET_GNS_Handle *handle = cls;
147 LOG (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting with GNS %p\n", handle);
149 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
150 if (handle->retry_time.rel_value < GNUNET_CONSTANTS_SERVICE_RETRY.rel_value)
151 handle->retry_time = GNUNET_CONSTANTS_SERVICE_RETRY;
153 handle->retry_time = GNUNET_TIME_relative_multiply (handle->retry_time, 2);
154 if (handle->retry_time.rel_value > GNUNET_CONSTANTS_SERVICE_TIMEOUT.rel_value)
155 handle->retry_time = GNUNET_CONSTANTS_SERVICE_TIMEOUT;
156 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
157 if (GNUNET_YES != try_connect (handle))
160 LOG (GNUNET_ERROR_TYPE_DEBUG, "GNS reconnect failed(!)\n");
164 GNUNET_CONTAINER_multihashmap_iterate (handle->active_requests,
165 &add_request_to_pending, handle);
166 process_pending_messages (handle);
171 * Try reconnecting to the GNS service.
173 * @param handle handle to gns to (possibly) disconnect and reconnect
176 do_disconnect (struct GNUNET_GNS_Handle *handle)
178 if (handle->client == NULL)
180 GNUNET_assert (handle->reconnect_task == GNUNET_SCHEDULER_NO_TASK);
181 if (NULL != handle->th)
182 GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th);
184 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
185 "Disconnecting from GNS service, will try to reconnect in %llu ms\n",
186 (unsigned long long) handle->retry_time.rel_value);
187 GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO);
188 handle->client = NULL;
189 handle->reconnect_task =
190 GNUNET_SCHEDULER_add_delayed (handle->retry_time, &try_reconnect, handle);
195 * Initialize the connection with the GNS service.
197 * @param cfg configuration to use
198 * @return handle to the GNS service, or NULL on error
200 struct GNUNET_GNS_Handle *
201 GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
204 struct GNUNET_GNS_Handle *handle;
206 handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_Handle));
209 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
210 handle->active_requests = GNUNET_CONTAINER_multihashmap_create (ht_len);
211 if (GNUNET_NO == try_connect (handle))
213 GNUNET_GNS_disconnect (handle);
221 * Shutdown connection with the GNS service.
223 * @param handle handle of the GNS connection to stop
226 GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle)
233 * Add a new record to the GNS.
235 * @param handle handle to GNS service
236 * @param key the key to store under
237 * @param desired_replication_level estimate of how many
238 * nearest peers this request should reach
239 * @param options routing options for this message
240 * @param type type of the value
241 * @param size number of bytes in data; must be less than 64k
242 * @param data the data to store
243 * @param exp desired expiration time for the value
244 * @param timeout how long to wait for transmission of this request
245 * @param cont continuation to call when done (transmitting request to service)
246 * @param cont_cls closure for cont
249 GNUNET_GNS_add_record (struct GNUNET_GNS_Handle *handle, const GNUNET_HashCode * key,
250 uint32_t desired_replication_level,
251 enum GNUNET_DHT_RouteOption options,
252 enum GNUNET_BLOCK_Type type, size_t size, const char *data,
253 struct GNUNET_TIME_Absolute exp,
254 struct GNUNET_TIME_Relative timeout, GNUNET_SCHEDULER_Task cont,
257 /* add record to local db, dht; sign etc */
262 * Perform an asynchronous Lookup operation on the GNS.
264 * @param handle handle to the GNS service
265 * @param timeout how long to wait for transmission of this request to the service
266 * @param type expected type of the response object
267 * @param key the key to look up
268 * @param desired_replication_level estimate of how many
269 nearest peers this request should reach
270 * @param options routing options for this message
271 * @param xquery extended query data (can be NULL, depending on type)
272 * @param xquery_size number of bytes in xquery
273 * @param iter function to call on each result
274 * @param iter_cls closure for iter
275 * @return handle to stop the async get
277 struct GNUNET_GNS_LookupHandle *
278 GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle,
279 struct GNUNET_TIME_Relative timeout,
280 enum GNUNET_BLOCK_Type type, const GNUNET_HashCode * key,
281 uint32_t desired_replication_level,
282 enum GNUNET_DHT_RouteOption options, const void *xquery,
283 size_t xquery_size, GNUNET_GNS_LookupIterator iter,
286 /* look for local entries, start dht lookup, return lookup_handle */
291 * Stop async GNS lookup.
293 * @param lookup_handle handle to the GNS lookup operation to stop
296 GNUNET_GNS_lookup_stop (struct GNUNET_GNS_LookupHandle *lookup_handle)
298 struct GNUNET_DHT_Handle *handle;
299 /* TODO Stop dht lookups */
303 /* end of gns_api.c */