-fix
[oweals/gnunet.git] / src / gns / namestore_stub_api.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009, 2010 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 License 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 License for more details.
14
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.
19 */
20
21 /**
22  * @file gns/namestore_stub_api.c
23  * @brief stub library to access the NAMESTORE service
24  * @author Martin Schanzenbach
25  */
26
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_constants.h"
30 #include "gnunet_arm_service.h"
31 #include "gnunet_namestore_service.h"
32
33 #define DEBUG_GNS_API GNUNET_EXTRA_LOGGING
34
35 #define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__)
36
37 /**
38  * A QueueEntry.
39  */
40 struct GNUNET_NAMESTORE_QueueEntry
41 {
42   char *data; /*stub data pointer*/
43 };
44
45 /**
46  * Connection to the NAMESTORE service.
47  */
48 struct GNUNET_NAMESTORE_Handle
49 {
50
51   /**
52    * Configuration to use.
53    */
54   const struct GNUNET_CONFIGURATION_Handle *cfg;
55
56   /**
57    * Socket (if available).
58    */
59   struct GNUNET_CLIENT_Connection *client;
60
61   /**
62    * Currently pending transmission request (or NULL).
63    */
64   struct GNUNET_CLIENT_TransmitHandle *th;
65
66   /* dll to use for records */
67   struct GNUNET_NAMESTORE_SimpleRecord * records_head;
68   struct GNUNET_NAMESTORE_SimpleRecord * records_tail;
69
70   uint32_t locked;
71
72 };
73
74 struct GNUNET_NAMESTORE_ZoneIterator
75 {
76   struct GNUNET_NAMESTORE_Handle *handle;
77   GNUNET_NAMESTORE_RecordProcessor proc;
78   void* proc_cls;
79   const GNUNET_HashCode * zone;
80   uint32_t no_flags;
81   uint32_t flags;
82   struct GNUNET_NAMESTORE_Handle *h;
83 };
84
85 struct GNUNET_NAMESTORE_SimpleRecord
86 {
87   /**
88    * DLL
89    */
90   struct GNUNET_NAMESTORE_SimpleRecord *next;
91
92   /**
93    * DLL
94    */
95   struct GNUNET_NAMESTORE_SimpleRecord *prev;
96   
97   const char *name;
98   const GNUNET_HashCode *zone;
99   const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key;
100   uint32_t rd_count;
101   struct GNUNET_NAMESTORE_RecordData rd[100];
102 };
103
104
105 /**
106  * Initialize the connection with the NAMESTORE service.
107  *
108  * @param cfg configuration to use
109  * @return handle to the GNS service, or NULL on error
110  */
111 struct GNUNET_NAMESTORE_Handle *
112 GNUNET_NAMESTORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
113 {
114   struct GNUNET_NAMESTORE_Handle *handle;
115
116   handle = GNUNET_malloc (sizeof (struct GNUNET_NAMESTORE_Handle));
117   handle->cfg = cfg;
118   handle->records_head = NULL;
119   handle->records_tail = NULL;
120   return handle;
121 }
122
123 /**
124  * Shutdown connection with the NAMESTORE service.
125  *
126  * @param handle handle of the NAMESTORE connection to stop
127  */
128 void
129 GNUNET_NAMESTORE_disconnect (struct GNUNET_NAMESTORE_Handle *handle, int drop)
130 {
131   GNUNET_free(handle);
132 }
133
134 /**
135  * Store an item in the namestore.  If the item is already present,
136  * the expiration time is updated to the max of the existing time and
137  * the new time.  The operation must fail if there is no matching
138  * entry in the signature tree.
139  *
140  * @param h handle to the namestore
141  * @param zone hash of the public key of the zone
142  * @param name name that is being mapped (at most 255 characters long)
143  * @param record_type type of the record (A, AAAA, PKEY, etc.)
144  * @param expiration expiration time for the content
145  * @param flags flags for the content
146  * @param data_size number of bytes in data
147  * @param data value, semantics depend on 'record_type' (see RFCs for DNS and 
148  *             GNS specification for GNS extensions)
149  * @param cont continuation to call when done
150  * @param cont_cls closure for cont
151  * @return handle to abort the request
152  */
153 struct GNUNET_NAMESTORE_QueueEntry *
154 GNUNET_NAMESTORE_record_put (struct GNUNET_NAMESTORE_Handle *h,
155            const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key,
156                              const char *name,
157                              struct GNUNET_TIME_Absolute expiration,
158                              unsigned int rd_count,
159            const struct GNUNET_NAMESTORE_RecordData *rd,
160            const struct GNUNET_CRYPTO_RsaSignature *signature,
161            GNUNET_NAMESTORE_ContinuationWithStatus cont,
162                              void *cont_cls)
163 {
164   struct GNUNET_NAMESTORE_QueueEntry *qe;
165   qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
166   struct GNUNET_NAMESTORE_SimpleRecord* sr;
167   GNUNET_HashCode *zone;
168   int i;
169
170   zone = GNUNET_malloc(sizeof(GNUNET_HashCode));
171   GNUNET_CRYPTO_hash(public_key,
172                      sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
173                      zone);
174
175   sr = h->records_head;
176   for (; sr != NULL; sr = sr->next)
177   {
178     if (GNUNET_CRYPTO_hash_cmp(zone, sr->zone) == 0)
179     {
180       GNUNET_log(GNUNET_ERROR_TYPE_INFO, "records for %s already present ow\n",
181                  name);
182       sr->rd_count = rd_count;
183       for (i=0; i<rd_count; i++)
184       {
185         sr->rd[i] = rd[i];
186       }
187       //Expiration, Signature etc
188       return qe;
189     }
190   }
191   GNUNET_log(GNUNET_ERROR_TYPE_INFO, "new records for %s\n", name);
192   // Not present
193   sr = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_SimpleRecord));
194   sr->rd_count = rd_count;
195   sr->name = GNUNET_malloc(strlen(name));
196   sr->zone = zone;
197   sr->zone_key = public_key; //pkey FIXME;
198   sr->next = NULL;
199   sr->prev = NULL;
200   strcpy((char*)sr->name, name);
201   
202   GNUNET_log(GNUNET_ERROR_TYPE_INFO, "copying \n");
203   for (i=0; i<rd_count; i++)
204     sr->rd[i] = rd[i];
205   GNUNET_log(GNUNET_ERROR_TYPE_INFO, "done \n");
206   
207   if (h->records_head == NULL && h->records_tail == NULL)
208   {
209     h->records_head = sr;
210     h->records_tail = sr;
211   }
212   else
213   {
214     GNUNET_CONTAINER_DLL_insert(h->records_head, h->records_tail, sr);
215   }
216
217   return qe;
218 }
219
220 int
221 GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key,
222                                    const char *name,
223                                    unsigned int rd_count,
224                                    const struct GNUNET_NAMESTORE_RecordData *rd,
225                                    const struct GNUNET_CRYPTO_RsaSignature *signature)
226 {
227   return GNUNET_OK;
228 }
229
230 struct GNUNET_NAMESTORE_QueueEntry *
231 GNUNET_NAMESTORE_record_create (struct GNUNET_NAMESTORE_Handle *h,
232                              const struct GNUNET_CRYPTO_RsaPrivateKey *key,
233                              const char *name,
234            const struct GNUNET_NAMESTORE_RecordData *rd,
235            GNUNET_NAMESTORE_ContinuationWithStatus cont,
236                              void *cont_cls)
237 {
238   struct GNUNET_NAMESTORE_QueueEntry *qe;
239   qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
240   struct GNUNET_NAMESTORE_SimpleRecord* sr;
241
242   GNUNET_HashCode *zone_hash;
243   
244   //memleakage.. but only stub so w/e
245   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *pkey;
246   pkey = GNUNET_malloc(sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
247   GNUNET_CRYPTO_rsa_key_get_public (key, pkey);
248
249   zone_hash = GNUNET_malloc(sizeof(GNUNET_HashCode));
250
251   GNUNET_CRYPTO_hash(pkey, GNUNET_CRYPTO_RSA_KEY_LENGTH, zone_hash);
252   
253   sr = h->records_head;
254   for (; sr != NULL; sr = sr->next)
255   {
256     if (strcmp(sr->name, name) && (sr->zone == zone_hash))
257     {
258       //Dangerous
259       memcpy (&(sr->rd[sr->rd_count-1]), rd,
260               sizeof(struct GNUNET_NAMESTORE_RecordData));
261
262       sr->rd_count++;
263       return qe;
264     }
265   }
266       
267   sr = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_SimpleRecord));
268   
269   sr->rd_count = 1;
270   sr->name = GNUNET_malloc(strlen(name));
271   sr->zone = zone_hash;
272   sr->zone_key = pkey;
273   sr->next = NULL;
274   sr->prev = NULL;
275   strcpy((char*)sr->name, name);
276
277   memcpy (&(sr->rd), rd,
278           sizeof(struct GNUNET_NAMESTORE_RecordData));
279   if (h->records_head == NULL && h->records_tail == NULL)
280   {
281     h->records_head = sr;
282     h->records_tail = sr;
283   }
284   else
285   {
286     GNUNET_CONTAINER_DLL_insert(h->records_head, h->records_tail, sr);
287   }
288
289   return qe;
290 }
291
292 /**
293  * Explicitly remove some content from the database.  The
294  * "cont"inuation will be called with status "GNUNET_OK" if content
295  * was removed, "GNUNET_NO" if no matching entry was found and
296  * "GNUNET_SYSERR" on all other types of errors.
297  *
298  * @param h handle to the namestore
299  * @param zone hash of the public key of the zone
300  * @param name name that is being mapped (at most 255 characters long)
301  * @param record_type type of the record (A, AAAA, PKEY, etc.)
302  * @param size number of bytes in data
303  * @param data content stored
304  * @param cont continuation to call when done
305  * @param cont_cls closure for cont
306  * @return handle to abort the request
307  */
308 struct GNUNET_NAMESTORE_QueueEntry *
309 GNUNET_NAMESTORE_record_remove (struct GNUNET_NAMESTORE_Handle *h,
310                                 const struct GNUNET_CRYPTO_RsaPrivateKey *pkey,
311                                 const char *name,
312                                 const struct GNUNET_NAMESTORE_RecordData *rd,
313         GNUNET_NAMESTORE_ContinuationWithStatus cont,
314                                 void *cont_cls)
315 {
316   struct GNUNET_NAMESTORE_QueueEntry *qe;
317   qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
318   
319   //FIXME
320   return qe;
321 }
322
323 /**
324  * Get a result for a particular key from the namestore.  The processor
325  * will only be called once.
326  *
327  * @param h handle to the namestore
328  * @param zone zone to look up a record from
329  * @param name name to look up
330  * @param record_type desired record type
331  * @param proc function to call on each matching value;
332  *        will be called once with a NULL value at the end
333  * @param proc_cls closure for proc
334  * @return a handle that can be used to
335  *         cancel
336  */
337 struct GNUNET_NAMESTORE_QueueEntry *
338 GNUNET_NAMESTORE_lookup_record (struct GNUNET_NAMESTORE_Handle *h, 
339                               const GNUNET_HashCode *zone,
340                               const char *name,
341                               uint32_t record_type,
342                               GNUNET_NAMESTORE_RecordProcessor proc, void *proc_cls)
343 {
344   struct GNUNET_NAMESTORE_QueueEntry *qe;
345   qe = GNUNET_malloc(sizeof (struct GNUNET_NAMESTORE_QueueEntry));
346   struct GNUNET_NAMESTORE_SimpleRecord *sr;
347   
348   GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Looking up %s\n", name);
349   sr = h->records_head;
350   for (; sr != NULL; sr = sr->next)
351   {
352     GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Got %s\n", sr->name);
353     if ((strcmp(sr->name, name) == 0) &&
354         (GNUNET_CRYPTO_hash_cmp(sr->zone, zone)))
355     {
356       GNUNET_log(GNUNET_ERROR_TYPE_INFO,
357                  "Found match for %s with %d entries\n",
358                  sr->name, sr->rd_count);
359       //Simply always return all records
360       proc(proc_cls, sr->zone_key, GNUNET_TIME_UNIT_FOREVER_ABS, //FIXME
361            name, sr->rd_count, sr->rd, NULL);
362       return qe;
363     }
364     GNUNET_log(GNUNET_ERROR_TYPE_INFO, "No match\n");
365   }
366   proc(proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, name, 0, NULL, NULL);
367   //FIXME
368   return qe;
369 }
370
371 struct GNUNET_NAMESTORE_ZoneIterator *
372 GNUNET_NAMESTORE_zone_iteration_start(struct GNUNET_NAMESTORE_Handle *h,
373                                       const GNUNET_HashCode *zone,
374                                       enum GNUNET_NAMESTORE_RecordFlags must_have_flags,
375                                       enum GNUNET_NAMESTORE_RecordFlags must_not_have_flags,
376                                       GNUNET_NAMESTORE_RecordProcessor proc,
377                                       void *proc_cls)
378 {
379   struct GNUNET_NAMESTORE_ZoneIterator *it;
380   h->locked = 1;
381   it = GNUNET_malloc(sizeof(struct GNUNET_NAMESTORE_ZoneIterator));
382   it->h = h;
383   it->proc = proc;
384   it->proc_cls = proc_cls;
385   it->zone = zone;
386   it->no_flags = must_not_have_flags;
387   it->flags = must_have_flags;
388   GNUNET_NAMESTORE_zone_iterator_next(it);
389   return it;
390 }
391
392 void
393 GNUNET_NAMESTORE_zone_iterator_next(struct GNUNET_NAMESTORE_ZoneIterator *it)
394 {
395   struct GNUNET_NAMESTORE_SimpleRecord *sr;
396   
397   if (it->h->locked == 0)
398     return;
399
400   sr = it->h->records_head;
401   for (; sr != NULL; sr = sr->next)
402   {
403     if (GNUNET_CRYPTO_hash_cmp(sr->zone, it->zone))
404     {
405       //Simply always return all records
406       //check flags
407       it->proc(it->proc_cls, sr->zone_key, GNUNET_TIME_UNIT_FOREVER_ABS, //FIXME
408            sr->name, sr->rd_count, sr->rd, NULL);
409     }
410   }
411   it->proc(it->proc_cls, NULL, GNUNET_TIME_UNIT_ZERO_ABS, NULL, 0, NULL, NULL);
412 }
413
414 void
415 GNUNET_NAMESTORE_zone_iteration_stop(struct GNUNET_NAMESTORE_ZoneIterator *it)
416 {
417   it->h->locked = 0;
418   GNUNET_free(it);
419 }
420
421 /**
422  * Cancel a namestore operation.  The final callback from the
423  * operation must not have been done yet.
424  *
425  * @param qe operation to cancel
426  */
427 void
428 GNUNET_NAMESTORE_cancel (struct GNUNET_NAMESTORE_QueueEntry *qe)
429 {
430   if (qe)
431     GNUNET_free(qe);
432 }
433
434
435
436
437 /* end of namestore_stub_api.c */