81f66ca0d53aa65b72dffa013c731c3df5905096
[oweals/gnunet.git] / src / identity / identity_api.c
1 /*
2      This file is part of GNUnet.
3      (C) 2013 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public Liceidentity as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
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 Liceidentity for more details.
14
15      You should have received a copy of the GNU General Public Liceidentity
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.
19 */
20
21 /**
22  * @file identity/identity_api.c
23  * @brief api to get information from the network size estimation service
24  * @author Nathan Evans
25  */
26 #include "platform.h"
27 #include "gnunet_client_lib.h"
28 #include "gnunet_constants.h"
29 #include "gnunet_container_lib.h"
30 #include "gnunet_arm_service.h"
31 #include "gnunet_hello_lib.h"
32 #include "gnunet_protocols.h"
33 #include "gnunet_server_lib.h"
34 #include "gnunet_time_lib.h"
35 #include "gnunet_identity_service.h"
36 #include "identity.h"
37
38 #define LOG(kind,...) GNUNET_log_from (kind, "identity-api",__VA_ARGS__)
39
40 /** 
41  * Handle for a pseudonym.
42  */
43 struct GNUNET_IDENTITY_Pseudonym
44 {
45 };
46
47
48 /**
49  * Handle for the service.
50  */
51 struct GNUNET_IDENTITY_Handle
52 {
53   /**
54    * Configuration to use.
55    */
56   const struct GNUNET_CONFIGURATION_Handle *cfg;
57
58   /**
59    * Socket (if available).
60    */
61   struct GNUNET_CLIENT_Connection *client;
62
63   /**
64    * Currently pending transmission request.
65    */
66   struct GNUNET_CLIENT_TransmitHandle *th;
67
68   /**
69    * Task doing exponential back-off trying to reconnect.
70    */
71   GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
72
73   /**
74    * Time for next connect retry.
75    */
76   struct GNUNET_TIME_Relative reconnect_delay;
77
78 };
79
80
81 /**
82  * Try again to connect to network size estimation service.
83  *
84  * @param cls the handle to the transport service
85  * @param tc scheduler context
86  */
87 static void
88 reconnect (void *cls,
89            const struct GNUNET_SCHEDULER_TaskContext *tc);
90
91
92 /**
93  * Type of a function to call when we receive a message
94  * from the service.
95  *
96  * @param cls closure
97  * @param msg message received, NULL on timeout or fatal error
98  */
99 static void
100 message_handler (void *cls, 
101                  const struct GNUNET_MessageHeader *msg)
102 {
103   struct GNUNET_IDENTITY_Handle *h = cls;
104   const struct GNUNET_IDENTITY_ClientMessage *client_msg;
105
106   if (msg == NULL)
107   {
108     /* Error, timeout, death */
109     GNUNET_CLIENT_disconnect (h->client);
110     h->client = NULL;
111     h->reconnect_task =
112         GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect, h);
113     return;
114   }
115   // FIXME: process...
116   GNUNET_CLIENT_receive (h->client, &message_handler, h,
117                          GNUNET_TIME_UNIT_FOREVER_REL);
118 }
119
120
121
122 /**
123  * Reschedule a connect attempt to the service.
124  *
125  * @param h transport service to reconnect
126  */
127 static void
128 reschedule_connect (struct GNUNET_IDENTITY_Handle *h)
129 {
130   GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK);
131
132   if (NULL != h->th)
133   {
134     GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
135     h->th = NULL;
136   }
137   if (NULL != h->client)
138   {
139     GNUNET_CLIENT_disconnect (h->client);
140     h->client = NULL;
141   }
142
143   LOG (GNUNET_ERROR_TYPE_DEBUG,
144        "Scheduling task to reconnect to identity service in %llu ms.\n",
145        h->reconnect_delay.rel_value);
146   h->reconnect_task =
147       GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect, h);
148   h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
149 }
150
151
152 /**
153  * Transmit START message to service.
154  *
155  * @param cls unused
156  * @param size number of bytes available in buf
157  * @param buf where to copy the message
158  * @return number of bytes copied to buf
159  */
160 static size_t
161 send_start (void *cls, 
162             size_t size, 
163             void *buf)
164 {
165   return 0;
166 }
167
168
169 /**
170  * Try again to connect to network size estimation service.
171  *
172  * @param cls the handle to the transport service
173  * @param tc scheduler context
174  */
175 static void
176 reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
177 {
178   struct GNUNET_IDENTITY_Handle *h = cls;
179
180   h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
181   if ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
182   {
183     /* shutdown, just give up */
184     return;
185   }
186   LOG (GNUNET_ERROR_TYPE_DEBUG,
187        "Connecting to network size estimation service.\n");
188   GNUNET_assert (h->client == NULL);
189   h->client = GNUNET_CLIENT_connect ("identity", h->cfg);
190   GNUNET_assert (h->client != NULL);
191
192   h->th =
193       GNUNET_CLIENT_notify_transmit_ready (h->client,
194                                            sizeof (struct GNUNET_MessageHeader),
195                                            GNUNET_TIME_UNIT_FOREVER_REL,
196                                            GNUNET_NO, &send_start, h);
197   GNUNET_assert (h->th != NULL);
198 }
199
200
201 /**
202  * Connect to the identity service.
203  *
204  * @param cfg the configuration to use
205  * @param cb function to call on all identity events, can be NULL
206  * @param cb_cls closure for 'cb'
207  * @return handle to use
208  */
209 struct GNUNET_IDENTITY_Handle *
210 GNUNET_IDENTITY_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
211                          GNUNET_IDENTITY_Callback cb,
212                          void *cb_cls)
213 {
214   struct GNUNET_IDENTITY_Handle *ret;
215
216   ret = GNUNET_malloc (sizeof (struct GNUNET_IDENTITY_Handle));
217   ret->cfg = cfg;
218   ret->reconnect_delay = GNUNET_TIME_UNIT_ZERO;
219   ret->reconnect_task = GNUNET_SCHEDULER_add_now (&reconnect, ret);
220   return ret;
221 }
222
223
224 /**
225  * Obtain the ECC key associated with a pseudonym.
226  *
227  * @param pseudonym the pseudonym
228  * @return associated ECC key, valid as long as the pseudonym is valid
229  */
230 const struct GNUNET_CRYPTO_EccPrivateKey *
231 GNUNET_IDENTITY_pseudonym_get_key (struct GNUNET_IDENTITY_Pseudonym *pseudonym)
232 {
233   return NULL;
234 }
235
236
237 /**
238  * Obtain the identity that is currently preferred/default
239  * for a service.
240  *
241  * @param id identity service to query
242  * @param service_name for which service is an identity wanted
243  * @param cb function to call with the result (will only be called once)
244  * @param cb_cls closure for cb
245  * @return handle to abort the operation
246  */
247 struct GNUNET_IDENTITY_Operation *
248 GNUNET_IDENTITY_get (struct GNUNET_IDENTITY_Handle *id,
249                      const char *service_name,
250                      GNUNET_IDENTITY_Callback cb,
251                      void *cb_cls)
252 {
253   return NULL;
254 }
255
256
257 /**
258  * Set the preferred/default identity for a service.
259  *
260  * @param id identity service to inform
261  * @param service_name for which service is an identity set
262  * @param pseu new default identity to be set for this service
263  * @param cont function to call once the operation finished
264  * @param cont_cls closure for cont
265  * @return handle to abort the operation
266  */
267 struct GNUNET_IDENTITY_Operation *
268 GNUNET_IDENTITY_set (struct GNUNET_IDENTITY_Handle *id,
269                      const char *service_name,
270                      struct GNUNET_IDENTITY_Pseudonym *pseu,
271                      GNUNET_IDENTITY_Continuation cont,
272                      void *cont_cls)
273 {
274   return NULL;
275 }
276
277
278 /** 
279  * Create a new identity with the given identifier.
280  *
281  * @param id identity service to use
282  * @param identifier desired identifier
283  * @param cb function to call with the result (will only be called once)
284  * @param cb_cls closure for cb
285  * @return handle to abort the operation
286  */
287 struct GNUNET_IDENTITY_Operation *
288 GNUNET_IDENTITY_create (struct GNUNET_IDENTITY_Handle *id,
289                         const char *identifier,
290                         GNUNET_IDENTITY_Callback cb,
291                         void *cb_cls)
292 {
293   return NULL;
294 }
295
296
297 /** 
298  * Renames an existing identity.
299  *
300  * @param id identity service to use
301  * @param old_identifier old identifier
302  * @param new_identifier desired new identifier
303  * @param cb function to call with the result (will only be called once)
304  * @param cb_cls closure for cb
305  * @return handle to abort the operation
306  */
307 struct GNUNET_IDENTITY_Operation *
308 GNUNET_IDENTITY_rename (struct GNUNET_IDENTITY_Handle *id,
309                         const char *old_identifier,
310                         const char *new_identifier,
311                         GNUNET_IDENTITY_Continuation cb,
312                         void *cb_cls)
313 {
314   return NULL;
315 }
316
317
318 /** 
319  * Delete an existing identity.
320  *
321  * @param id identity service to use
322  * @param identifier identifier of the identity to delete
323  * @param cb function to call with the result (will only be called once)
324  * @param cb_cls closure for cb
325  * @return handle to abort the operation
326  */
327 struct GNUNET_IDENTITY_Operation *
328 GNUNET_IDENTITY_delete (struct GNUNET_IDENTITY_Handle *id,
329                         const char *identifier,
330                         GNUNET_IDENTITY_Continuation cb,
331                         void *cb_cls)
332 {
333   return NULL;
334 }
335
336
337 /**
338  * Cancel an identity operation. Note that the operation MAY still
339  * be executed; this merely cancels the continuation; if the request
340  * was already transmitted, the service may still choose to complete
341  * the operation.
342  *
343  * @param op operation to cancel
344  */
345 void
346 GNUNET_IDENITY_cancel (struct GNUNET_IDENTITY_Operation *op)
347 {
348 }
349
350
351 /**
352  * Disconnect from identity service
353  *
354  * @param h handle to destroy
355  */
356 void
357 GNUNET_IDENTITY_disconnect (struct GNUNET_IDENTITY_Handle *h)
358 {
359   GNUNET_assert (NULL != h);
360   if (h->reconnect_task != GNUNET_SCHEDULER_NO_TASK)
361   {
362     GNUNET_SCHEDULER_cancel (h->reconnect_task);
363     h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
364   }
365   if (h->th != NULL)
366   {
367     GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
368     h->th = NULL;
369   }
370   if (h->client != NULL)
371   {
372     GNUNET_CLIENT_disconnect (h->client);
373     h->client = NULL;
374   }
375   GNUNET_free (h);
376 }
377
378 /* end of identity_api.c */