aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2012-02-16 14:21:22 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2012-02-16 14:21:22 +0000
commitbd742f26f08fed45b48eeb1567447acd7a77d350 (patch)
tree4f526d6824b91946d3ec52b8e2d95292b75adea0 /src
parent758f38a2171dadd20328c7db93164bbcd46b72dc (diff)
downloadgnunet-bd742f26f08fed45b48eeb1567447acd7a77d350.tar.gz
gnunet-bd742f26f08fed45b48eeb1567447acd7a77d350.zip
- added makefile, borrowed lots of code from dht for client handling
Diffstat (limited to 'src')
-rw-r--r--src/gns/Makefile.am62
-rw-r--r--src/gns/gns.h93
-rw-r--r--src/gns/gns_api.c400
-rw-r--r--src/gns/gnunet-gns-add.c8
-rw-r--r--src/gns/gnunet-service-gns.c22
-rw-r--r--src/include/gnunet_gns_service.h57
6 files changed, 563 insertions, 79 deletions
diff --git a/src/gns/Makefile.am b/src/gns/Makefile.am
new file mode 100644
index 000000000..aab5d5fba
--- /dev/null
+++ b/src/gns/Makefile.am
@@ -0,0 +1,62 @@
1INCLUDES = -I$(top_srcdir)/src/include
2
3if MINGW
4 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
5endif
6
7if USE_COVERAGE
8 AM_CFLAGS = --coverage -O0
9endif
10
11pkgcfgdir= $(pkgdatadir)/config.d/
12
13plugindir = $(libdir)/gnunet
14
15pkgcfg_DATA = \
16 dns.conf
17
18lib_LTLIBRARIES = \
19 libgnunetgns.la
20
21bin_PROGRAMS = \
22 gnunet-service-gns $(HIJACKBIN)
23
24noinst_PROGRAMS = \
25 gnunet-gns-lookup gnunet-gns-add
26
27#check_SCRIPTS = \
28# test_gnunet_dns.sh
29
30
31gnunet_gns_add_SOURCES = \
32 gnunet-gns-add.c
33gnunet_gns_add_LDADD = \
34 $(top_builddir)/src/gns/libgnunetgns.la \
35 $(top_builddir)/src/util/libgnunetutil.la \
36 $(GN_LIBINTL)
37gnunet_dns_add_DEPENDENCIES = \
38 libgnunetgns.la
39
40gnunet_service_gns_SOURCES = \
41 gnunet-service-gns.c
42gnunet_service_gns_LDADD = \
43 $(top_builddir)/src/tun/libgnunettun.la \
44 $(top_builddir)/src/mesh/libgnunetmesh.la \
45 $(top_builddir)/src/statistics/libgnunetstatistics.la \
46 $(top_builddir)/src/util/libgnunetutil.la \
47 $(top_builddir)/src/dns/libgnunetdns.la \
48 $(GN_LIBINTL)
49
50libgnunetgns_la_SOURCES = \
51 gns_api.c gns.h
52libgnunetgns_la_LIBADD = \
53 $(top_builddir)/src/util/libgnunetutil.la $(XLIB)
54libgnunetgns_la_LDFLAGS = \
55 $(GN_LIB_LDFLAGS)
56
57if ENABLE_TEST_RUN
58TESTS = $(check_PROGRAMS) $(check_SCRIPTS)
59endif
60
61EXTRA_DIST = \
62 $(check_SCRIPTS)
diff --git a/src/gns/gns.h b/src/gns/gns.h
new file mode 100644
index 000000000..e35df7858
--- /dev/null
+++ b/src/gns/gns.h
@@ -0,0 +1,93 @@
1/*
2 This file is part of GNUnet
3 (C) 2012 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 2, 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/gns.h
23 * @brief IPC messages between GNS API and GNS service
24 * @author Martin Schanzenbach
25 */
26#ifndef GNS_H
27#define GNS_H
28
29GNUNET_NETWORK_STRUCT_BEGIN
30
31
32/**
33 * Message from client to GNS service to lookup records.
34 */
35struct GNUNET_GNS_ClientLookupMessage
36{
37 /**
38 * Header of type GNUNET_MESSAGE_TYPE_GNS_CLIENT_LOOKUP
39 */
40 struct GNUNET_MessageHeader header;
41
42 /**
43 * Unique identifier for this request (for key collisions).
44 */
45 uint64_t unique_id;
46
47 /**
48 * the type of record to look up
49 */
50 int type;
51
52 /**
53 * Length of name to lookup
54 */
55 uint32_t namelen;
56
57 /* Followed by the name to look up */
58};
59
60
61/**
62 * Message from GNS service to client: new results.
63 */
64struct GNUNET_GNS_ClientResultMessage
65{
66 /**
67 * Header of type GNUNET_MESSAGE_TYPE_GNS_CLIENT_RESULT
68 */
69 struct GNUNET_MessageHeader header;
70
71 /**
72 * Unique identifier for this request (for key collisions).
73 */
74 uint64_t unique_id;
75
76 /**
77 * A key. TODO some uid
78 */
79 GNUNET_HashCode key;
80
81 /**
82 * The number of records contained in response
83 */
84 uint32_t num_records;
85
86 /* followed by num_records GNUNET_GNS_Records*/
87
88};
89
90
91GNUNET_NETWORK_STRUCT_END
92
93#endif
diff --git a/src/gns/gns_api.c b/src/gns/gns_api.c
index e6b1b9513..ed0b447a7 100644
--- a/src/gns/gns_api.c
+++ b/src/gns/gns_api.c
@@ -31,11 +31,79 @@
31#include "gnunet_hello_lib.h" 31#include "gnunet_hello_lib.h"
32#include "gnunet_protocols.h" 32#include "gnunet_protocols.h"
33#include "gnunet_dht_service.h" 33#include "gnunet_dht_service.h"
34#include "gns.h"
35#include "gnunet_gns_service.h"
34 36
35#define DEBUG_GNS_API GNUNET_EXTRA_LOGGING 37#define DEBUG_GNS_API GNUNET_EXTRA_LOGGING
36 38
37#define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__) 39#define LOG(kind,...) GNUNET_log_from (kind, "gns-api",__VA_ARGS__)
38 40
41/* TODO into gnunet_protocols */
42#define GNUNET_MESSAGE_TYPE_GNS_CLIENT_LOOKUP 23
43#define GNUNET_MESSAGE_TYPE_GNS_CLIENT_RESULT 24
44
45/**
46 * Entry in our list of messages to be (re-)transmitted.
47 */
48struct PendingMessage
49{
50 /**
51 * This is a doubly-linked list.
52 */
53 struct PendingMessage *prev;
54
55 /**
56 * This is a doubly-linked list.
57 */
58 struct PendingMessage *next;
59
60 /**
61 * Message that is pending, allocated at the end
62 * of this struct.
63 */
64 const struct GNUNET_MessageHeader *msg;
65
66 /**
67 * Handle to the GNS API context.
68 */
69 struct GNUNET_GNS_Handle *handle;
70
71 /**
72 * Continuation to call when the request has been
73 * transmitted (for the first time) to the service; can be NULL.
74 */
75 GNUNET_SCHEDULER_Task cont;
76
77 /**
78 * Closure for 'cont'.
79 */
80 void *cont_cls;
81
82 /**
83 * Timeout task for this message
84 */
85 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
86
87 /**
88 * Unique ID for this request
89 */
90 uint64_t unique_id;
91
92 /**
93 * Free the saved message once sent, set to GNUNET_YES for messages
94 * that do not receive responses; GNUNET_NO if this pending message
95 * is aliased from a 'struct GNUNET_DHT_RouteHandle' and will be freed
96 * from there.
97 */
98
99 int free_on_send;
100 /**
101 * GNUNET_YES if this message is in our pending queue right now.
102 */
103 int in_pending_queue;
104
105};
106
39/** 107/**
40 * Handle to a Lookup request 108 * Handle to a Lookup request
41 */ 109 */
@@ -67,8 +135,17 @@ struct GNUNET_GNS_LookupHandle
67 */ 135 */
68 uint64_t unique_id; 136 uint64_t unique_id;
69 137
138 struct PendingMessage *message;
139
70}; 140};
71 141
142/**
143 * A GNS Record.
144 */
145struct GNUNET_GNS_Record
146{
147 enum GNUNET_GNS_RecordType type;
148};
72 149
73/** 150/**
74 * Connection to the GNS service. 151 * Connection to the GNS service.
@@ -91,6 +168,21 @@ struct GNUNET_GNS_Handle
91 */ 168 */
92 struct GNUNET_CLIENT_TransmitHandle *th; 169 struct GNUNET_CLIENT_TransmitHandle *th;
93 170
171 /**
172 * Head of linked list of messages we would like to transmit.
173 */
174 struct PendingMessage *pending_head;
175
176 /**
177 * Tail of linked list of messages we would like to transmit.
178 */
179 struct PendingMessage *pending_tail;
180
181 /**
182 * Hash map containing the current outstanding unique requests.
183 */
184 struct GNUNET_CONTAINER_MultiHashMap *active_requests;
185
94 GNUNET_SCHEDULER_TaskIdentifier reconnect_task; 186 GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
95 187
96 /** 188 /**
@@ -110,6 +202,12 @@ struct GNUNET_GNS_Handle
110 int in_receive; 202 int in_receive;
111}; 203};
112 204
205/**
206 * Try to send messages from list of messages to send
207 * @param handle GNS_Handle
208 */
209static void
210process_pending_messages (struct GNUNET_GNS_Handle *handle);
113 211
114/** 212/**
115 * Try to (re)connect to the GNS service. 213 * Try to (re)connect to the GNS service.
@@ -143,7 +241,7 @@ try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
143{ 241{
144 struct GNUNET_GNS_Handle *handle = cls; 242 struct GNUNET_GNS_Handle *handle = cls;
145 243
146#if DEBUG_DHT 244#if DEBUG_GNS
147 LOG (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting with GNS %p\n", handle); 245 LOG (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting with GNS %p\n", handle);
148#endif 246#endif
149 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; 247 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
@@ -156,7 +254,7 @@ try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
156 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; 254 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
157 if (GNUNET_YES != try_connect (handle)) 255 if (GNUNET_YES != try_connect (handle))
158 { 256 {
159#if DEBUG_DHT 257#if DEBUG_GNS
160 LOG (GNUNET_ERROR_TYPE_DEBUG, "GNS reconnect failed(!)\n"); 258 LOG (GNUNET_ERROR_TYPE_DEBUG, "GNS reconnect failed(!)\n");
161#endif 259#endif
162 return; 260 return;
@@ -190,11 +288,215 @@ do_disconnect (struct GNUNET_GNS_Handle *handle)
190 GNUNET_SCHEDULER_add_delayed (handle->retry_time, &try_reconnect, handle); 288 GNUNET_SCHEDULER_add_delayed (handle->retry_time, &try_reconnect, handle);
191} 289}
192 290
291/**
292 * Transmit the next pending message, called by notify_transmit_ready
293 */
294static size_t
295transmit_pending (void *cls, size_t size, void *buf);
296
297/**
298 * Handler for messages received from the GNS service
299 *
300 * @param cls the 'struct GNUNET_GNS_Handle'
301 * @param msg the incoming message
302 */
303static void
304message_handler (void *cls, const struct GNUNET_MessageHeader *msg);
305
306/**
307 * Try to send messages from list of messages to send
308 */
309static void
310process_pending_messages (struct GNUNET_GNS_Handle *handle)
311{
312 struct PendingMessage *head;
313
314 if (handle->client == NULL)
315 {
316 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
317 "process_pending_messages called, but client is null, reconnecting\n");
318 do_disconnect (handle);
319 return;
320 }
321 if (handle->th != NULL)
322 return;
323 if (NULL == (head = handle->pending_head))
324 return;
325 handle->th =
326 GNUNET_CLIENT_notify_transmit_ready (handle->client,
327 ntohs (head->msg->size),
328 GNUNET_TIME_UNIT_FOREVER_REL,
329 GNUNET_YES, &transmit_pending,
330 handle);
331 if (NULL != handle->th)
332 return;
333 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
334 "notify_transmit_ready returned NULL, reconnecting\n");
335 do_disconnect (handle);
336}
337
338
339/**
340 * Transmit the next pending message, called by notify_transmit_ready
341 */
342static size_t
343transmit_pending (void *cls, size_t size, void *buf)
344{
345 struct GNUNET_GNS_Handle *handle = cls;
346 struct PendingMessage *head;
347 size_t tsize;
348
349 handle->th = NULL;
350 if (buf == NULL)
351 {
352#if DEBUG_GNS
353 LOG (GNUNET_ERROR_TYPE_DEBUG,
354 "Transmission to GNS service failed! Reconnecting!\n");
355#endif
356 do_disconnect (handle);
357 return 0;
358 }
359 if (NULL == (head = handle->pending_head))
360 return 0;
361
362 tsize = ntohs (head->msg->size);
363 if (size < tsize)
364 {
365 process_pending_messages (handle);
366 return 0;
367 }
368 memcpy (buf, head->msg, tsize);
369 GNUNET_CONTAINER_DLL_remove (handle->pending_head, handle->pending_tail,
370 head);
371 head->in_pending_queue = GNUNET_NO;
372 if (head->timeout_task != GNUNET_SCHEDULER_NO_TASK)
373 {
374 GNUNET_SCHEDULER_cancel (head->timeout_task);
375 head->timeout_task = GNUNET_SCHEDULER_NO_TASK;
376 }
377 if (GNUNET_YES == head->free_on_send)
378 GNUNET_free (head);
379 process_pending_messages (handle);
380#if DEBUG_GNS
381 LOG (GNUNET_ERROR_TYPE_DEBUG,
382 "Forwarded request of %u bytes to GNS service\n", (unsigned int) tsize);
383#endif
384 if (GNUNET_NO == handle->in_receive)
385 {
386#if DEBUG_GNS
387 LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting to process replies from GNS\n");
388#endif
389 handle->in_receive = GNUNET_YES;
390 GNUNET_CLIENT_receive (handle->client, &message_handler, handle,
391 GNUNET_TIME_UNIT_FOREVER_REL);
392 }
393 return tsize;
394}
395
396/**
397 * Process a given reply that might match the given
398 * request.
399 *
400 * @param cls the 'struct GNUNET_GNS_ClientResultMessage'
401 * @param key query of the request
402 * @param value the 'struct GNUNET_GNS_LookupHandle' of a request matching the same key
403 * @return GNUNET_YES to continue to iterate over all results,
404 * GNUNET_NO if the reply is malformed
405 */
406static int
407process_reply (void *cls, const GNUNET_HashCode * key, void *value)
408{
409 const struct GNUNET_GNS_ClientResultMessage *gns_msg = cls;
410 struct GNUNET_GNS_LookupHandle *lookup_handle = value;
411 const struct GNUNET_GNS_Record *records;
412 uint32_t num_records;
413 size_t meta_length;
414 size_t msize;
415
416 if (gns_msg->unique_id != lookup_handle->unique_id)
417 {
418 /* UID mismatch */
419#if DEBUG_GNS
420 LOG (GNUNET_ERROR_TYPE_DEBUG,
421 "Ignoring reply for %s: UID mismatch: %llu/%llu\n", GNUNET_h2s (key),
422 gns_msg->unique_id, lookup_handle->unique_id);
423#endif
424 return GNUNET_YES;
425 }
426 msize = ntohs (gns_msg->header.size);
427 num_records = ntohl (gns_msg->num_records);
428 meta_length =
429 sizeof (struct GNUNET_GNS_ClientResultMessage) +
430 sizeof (struct GNUNET_GNS_Record) * (num_records);
431 if ((msize < meta_length) ||
432 (num_records >
433 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_GNS_Record)))
434 {
435 GNUNET_break (0);
436 return GNUNET_NO;
437 }
438#if DEBUG_GNS
439 LOG (GNUNET_ERROR_TYPE_DEBUG, "Giving %u byte reply for %s to application\n",
440 (unsigned int) (msize - meta_length), GNUNET_h2s (key));
441#endif
442 records = (const struct GNUNET_GNS_Record *) &gns_msg[1];
443 lookup_handle->iter (lookup_handle->iter_cls, key, records, num_records);
444 return GNUNET_YES;
445}
446
447
448/**
449 * Handler for messages received from the GNS service
450 *
451 * @param cls the 'struct GNUNET_GNS_Handle'
452 * @param msg the incoming message
453 */
454static void
455message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
456{
457 struct GNUNET_GNS_Handle *handle = cls;
458 const struct GNUNET_GNS_ClientResultMessage *gns_msg;
459
460 if (msg == NULL)
461 {
462#if DEBUG_GNS
463 LOG (GNUNET_ERROR_TYPE_DEBUG,
464 "Error receiving data from GNS service, reconnecting\n");
465#endif
466 do_disconnect (handle);
467 return;
468 }
469 if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_GNS_CLIENT_RESULT)
470 {
471 GNUNET_break (0);
472 do_disconnect (handle);
473 return;
474 }
475 if (ntohs (msg->size) < sizeof (struct GNUNET_GNS_ClientResultMessage))
476 {
477 GNUNET_break (0);
478 do_disconnect (handle);
479 return;
480 }
481 gns_msg = (const struct GNUNET_GNS_ClientResultMessage *) msg;
482#if DEBUG_GNS
483 LOG (GNUNET_ERROR_TYPE_DEBUG, "Received reply for `%s' from GNS service %p\n",
484 &gns_msg->name, handle);
485#endif
486 /* TODO uniquely identify requests... maybe hash(name) or uid */
487 GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_requests,
488 &gns_msg->key, &process_reply,
489 (void *) gns_msg);
490 GNUNET_CLIENT_receive (handle->client, &message_handler, handle,
491 GNUNET_TIME_UNIT_FOREVER_REL);
492}
493
193 494
194/** 495/**
195 * Initialize the connection with the GNS service. 496 * Initialize the connection with the GNS service.
196 * 497 *
197 * @param cfg configuration to use 498 * @param cfg configuration to use
499 * @param ht_len size of the internal hash table to use for parallel requests
198 * @return handle to the GNS service, or NULL on error 500 * @return handle to the GNS service, or NULL on error
199 */ 501 */
200struct GNUNET_GNS_Handle * 502struct GNUNET_GNS_Handle *
@@ -225,7 +527,7 @@ GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
225void 527void
226GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle) 528GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle)
227{ 529{
228 /* disco from GNS */ 530 /* disco from GNS */
229} 531}
230 532
231 533
@@ -233,38 +535,28 @@ GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle)
233 * Add a new record to the GNS. 535 * Add a new record to the GNS.
234 * 536 *
235 * @param handle handle to GNS service 537 * @param handle handle to GNS service
236 * @param key the key to store under 538 * @param record the record to store
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 539 * @param exp desired expiration time for the value
244 * @param timeout how long to wait for transmission of this request 540 * @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
247 */ 541 */
248void 542void
249GNUNET_GNS_add_record (struct GNUNET_GNS_Handle *handle, const GNUNET_HashCode * key, 543GNUNET_GNS_add_record (struct GNUNET_GNS_Handle *handle,
250 uint32_t desired_replication_level, 544 const char* name,
251 enum GNUNET_DHT_RouteOption options, 545 enum GNUNET_GNS_RecordType type,
252 enum GNUNET_BLOCK_Type type, size_t size, const char *data, 546 size_t size, const char *data,
253 struct GNUNET_TIME_Absolute exp, 547 struct GNUNET_TIME_Absolute exp,
254 struct GNUNET_TIME_Relative timeout, GNUNET_SCHEDULER_Task cont, 548 struct GNUNET_TIME_Relative timeout)
255 void *cont_cls)
256{ 549{
257 /** 550 /**
258 * build add record message 551 * build add record message
259 */ 552 */
260 struct GNUNET_GNS_Record *record; 553 struct GNUNET_GNS_Record *record;
261
262 record = GNUNET_malloc(sizeof (struct GNUNET_GNS_Record));
263 /* TODO fill */
264 queue_record_msg(handle, record);
265}
266
267 554
555 record = GNUNET_malloc(sizeof (struct GNUNET_GNS_Record));
556 /**
557 * TODO
558 * queue_record_msg(handle, record);
559 **/
268} 560}
269 561
270 562
@@ -273,13 +565,7 @@ GNUNET_GNS_add_record (struct GNUNET_GNS_Handle *handle, const GNUNET_HashCode *
273 * 565 *
274 * @param handle handle to the GNS service 566 * @param handle handle to the GNS service
275 * @param timeout how long to wait for transmission of this request to the service 567 * @param timeout how long to wait for transmission of this request to the service
276 * @param type expected type of the response object 568 * @param name the name to look up
277 * @param key the key to look up
278 * @param desired_replication_level estimate of how many
279 nearest peers this request should reach
280 * @param options routing options for this message
281 * @param xquery extended query data (can be NULL, depending on type)
282 * @param xquery_size number of bytes in xquery
283 * @param iter function to call on each result 569 * @param iter function to call on each result
284 * @param iter_cls closure for iter 570 * @param iter_cls closure for iter
285 * @return handle to stop the async get 571 * @return handle to stop the async get
@@ -287,13 +573,45 @@ GNUNET_GNS_add_record (struct GNUNET_GNS_Handle *handle, const GNUNET_HashCode *
287struct GNUNET_GNS_LookupHandle * 573struct GNUNET_GNS_LookupHandle *
288GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, 574GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle,
289 struct GNUNET_TIME_Relative timeout, 575 struct GNUNET_TIME_Relative timeout,
290 enum GNUNET_BLOCK_Type type, const GNUNET_HashCode * key, 576 const char * name,
291 uint32_t desired_replication_level, 577 enum GNUNET_GNS_RecordType type,
292 enum GNUNET_DHT_RouteOption options, const void *xquery, 578 GNUNET_GNS_LookupIterator iter,
293 size_t xquery_size, GNUNET_GNS_LookupIterator iter,
294 void *iter_cls) 579 void *iter_cls)
295{ 580{
296 /* IPC to look for local entries, start dht lookup, return lookup_handle */ 581 /* IPC to look for local entries, start dht lookup, return lookup_handle */
582 struct GNUNET_GNS_ClientLookupMessage *lookup_msg;
583 struct GNUNET_GNS_LookupHandle *lookup_handle;
584 size_t msize;
585 struct PendingMessage *pending;
586
587 msize = sizeof (struct GNUNET_GNS_ClientLookupMessage) + strlen(name);
588#if DEBUG_GNS
589 LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting lookup for %s in GNS %p\n",
590 name, handle);
591#endif
592 pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
593 lookup_msg = (struct GNUNET_GNS_ClientLookupMessage *) &pending[1];
594 pending->msg = &lookup_msg->header;
595 pending->handle = handle;
596 pending->free_on_send = GNUNET_NO;
597 lookup_msg->header.size = htons (msize);
598 lookup_msg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_CLIENT_LOOKUP);
599 lookup_msg->namelen = strlen(name);
600 memcpy(&lookup_msg[1], name, strlen(name));
601 handle->uid_gen++;
602 lookup_msg->unique_id = handle->uid_gen;
603 GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail,
604 pending);
605 pending->in_pending_queue = GNUNET_YES;
606 lookup_handle = GNUNET_malloc (sizeof (struct GNUNET_GNS_LookupHandle));
607 lookup_handle->iter = iter;
608 lookup_handle->iter_cls = iter_cls;
609 lookup_handle->message = pending;
610 lookup_handle->unique_id = lookup_msg->unique_id;
611 GNUNET_CONTAINER_multihashmap_put (handle->active_requests, key, lookup_handle,
612 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
613 process_pending_messages (handle);
614 return lookup_handle;
297} 615}
298 616
299 617
@@ -305,7 +623,7 @@ GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle,
305void 623void
306GNUNET_GNS_lookup_stop (struct GNUNET_GNS_LookupHandle *lookup_handle) 624GNUNET_GNS_lookup_stop (struct GNUNET_GNS_LookupHandle *lookup_handle)
307{ 625{
308 /* TODO Stop dht lookups */ 626 /* TODO Stop dht lookups */
309} 627}
310 628
311 629
diff --git a/src/gns/gnunet-gns-add.c b/src/gns/gnunet-gns-add.c
index bc4843a96..bb1d7e1f4 100644
--- a/src/gns/gnunet-gns-add.c
+++ b/src/gns/gnunet-gns-add.c
@@ -134,9 +134,6 @@ run (void *cls, char *const *args, const char *cfgfile,
134 else if (verbose) 134 else if (verbose)
135 FPRINTF (stderr, _("Connected to %s service!\n"), "GNS"); 135 FPRINTF (stderr, _("Connected to %s service!\n"), "GNS");
136 136
137 if (query_type == GNUNET_BLOCK_TYPE_ANY) /* Type of data not set */
138 query_type = GNUNET_BLOCK_TYPE_TEST;
139
140 timeout = 137 timeout =
141 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, timeout_request); 138 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, timeout_request);
142 expiration = 139 expiration =
@@ -147,9 +144,8 @@ run (void *cls, char *const *args, const char *cfgfile,
147 if (verbose) 144 if (verbose)
148 FPRINTF (stderr, _("Issuing add request for `%s' with data `%s'!\n"), 145 FPRINTF (stderr, _("Issuing add request for `%s' with data `%s'!\n"),
149 record_key, data); 146 record_key, data);
150 GNUNET_GNS_add (gns_handle, &record_key, replication, GNUNET_DHT_RO_NONE, record_type, 147 GNUNET_GNS_add_record (gns_handle, &record_key, record_type,
151 strlen (data), data, expiration, timeout, &message_sent_cont, 148 strlen (data), data, expiration, timeout);
152 NULL);
153 149
154} 150}
155 151
diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c
index ba368122c..25e066d00 100644
--- a/src/gns/gnunet-service-gns.c
+++ b/src/gns/gnunet-service-gns.c
@@ -39,7 +39,7 @@ struct GNUNET_DNS_Handle *dns_handler;
39/** 39/**
40 * The configuration the GNS service is running with 40 * The configuration the GNS service is running with
41 */ 41 */
42const struct GNUNET_CONFIGURATION_Handle *GDS_cfg; 42const struct GNUNET_CONFIGURATION_Handle *GNS_cfg;
43 43
44/** 44/**
45 * Task run during shutdown. 45 * Task run during shutdown.
@@ -76,7 +76,6 @@ handle_dns_request(void *cls,
76 * Maybe provide both, useful for cli app 76 * Maybe provide both, useful for cli app
77 **/ 77 **/
78 struct GNUNET_DNSPARSER_Packet *p; 78 struct GNUNET_DNSPARSER_Packet *p;
79 char buf[INET6_ADDRSTRLEN];
80 int namelen; 79 int namelen;
81 80
82 p = GNUNET_DNSPARSER_parse (request, request_length); 81 p = GNUNET_DNSPARSER_parse (request, request_length);
@@ -86,13 +85,22 @@ handle_dns_request(void *cls,
86 GNUNET_DNS_request_forward (rh); 85 GNUNET_DNS_request_forward (rh);
87 return; 86 return;
88 } 87 }
89 /* TODO factor out */ 88 /**
89 * TODO factor out
90 * Check tld and decide if we or
91 * legacy dns is responsible
92 **/
90 for (i=0;i<p->num_queries;i++) 93 for (i=0;i<p->num_queries;i++)
91 { 94 {
92 namelen = strlen(&p->queries[i]->name); 95 namelen = strlen(&p->queries[i]->name);
93 if (namelen >= 7) 96 if (namelen >= 7)
94 { 97 {
95 if (0 == strcmp(&p->queries[i]->name, ".gnunet")) 98 /**
99 * TODO off by 1?
100 * Move our tld/root to config file
101 * Generate fake DNS reply that replaces .gnunet with .org
102 **/
103 if (0 == strcmp((&p->queries[i]->name)+(namelen-7), ".gnunet"))
96 { 104 {
97 GNUNET_DNS_request_answer(rh, 0 /*length*/, NULL/*reply*/); 105 GNUNET_DNS_request_answer(rh, 0 /*length*/, NULL/*reply*/);
98 } 106 }
@@ -119,9 +127,9 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
119 /* The IPC message types */ 127 /* The IPC message types */
120 static const struct GNUNET_SERVER_MessageHandler handlers[] = { 128 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
121 /* callback, cls, type, size */ 129 /* callback, cls, type, size */
122 {&handle_record_lookup, NULL, GNUNET_MESSAGE_TYPE_GNS_RECORD_LOOKUP, 130 {&handle_client_record_lookup, NULL, GNUNET_MESSAGE_TYPE_GNS_RECORD_LOOKUP,
123 sizeof (struct GNUNET_GNS_Lookup)}, 131 sizeof (struct GNUNET_GNS_Lookup)},
124 {&handle_record_add, NULL, GNUNET_MESSAGE_TYPE_GNS_RECORD_ADD, 132 {&handle_client_record_add, NULL, GNUNET_MESSAGE_TYPE_GNS_RECORD_ADD,
125 sizeof (struct GNUNET_GNS_Record)}, 133 sizeof (struct GNUNET_GNS_Record)},
126 {NULL, NULL, 0, 0} 134 {NULL, NULL, 0, 0}
127 }; 135 };
@@ -144,7 +152,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
144 * Esp the lookup would require to keep track of the clients' context 152 * Esp the lookup would require to keep track of the clients' context
145 * See dht. 153 * See dht.
146 * GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL); 154 * GNUNET_SERVER_disconnect_notify (server, &client_disconnect, NULL);
147 * */ 155 **/
148} 156}
149 157
150 158
diff --git a/src/include/gnunet_gns_service.h b/src/include/gnunet_gns_service.h
index 405fcd2fc..235785116 100644
--- a/src/include/gnunet_gns_service.h
+++ b/src/include/gnunet_gns_service.h
@@ -49,13 +49,31 @@ struct GNUNET_GNS_Handle;
49struct GNUNET_GNS_LookupHandle; 49struct GNUNET_GNS_LookupHandle;
50 50
51/** 51/**
52 * A single GNS record.
53 */
54struct GNUNET_GNS_Record;
55
56/**
57 * Records types
58 */
59enum GNUNET_GNS_RecordType
60{
61 GNUNET_GNS_RECORD_A,
62 GNUNET_GNS_RECORD_AAAA,
63 GNUNET_GNS_RECORD_MX,
64 GNUNET_GNS_RECORD_PKEY
65};
66
67/**
52 * Initialize the connection with the GNS service. 68 * Initialize the connection with the GNS service.
53 * 69 *
54 * @param cfg configuration to use 70 * @param cfg configuration to use
71 * @param ht_len size of the internal hash table to use for parallel lookups
55 * @return NULL on error 72 * @return NULL on error
56 */ 73 */
57struct GNUNET_GNS_Handle * 74struct GNUNET_GNS_Handle *
58GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); 75GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg
76 unsigned int ht_len);
59 77
60 78
61/** 79/**
@@ -86,13 +104,12 @@ GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle);
86 * @param cont_cls closure for cont 104 * @param cont_cls closure for cont
87 */ 105 */
88void 106void
89GNUNET_GNS_add (struct GNUNET_GNS_Handle *handle, const GNUNET_HashCode * key, 107GNUNET_GNS_add_record (struct GNUNET_GNS_Handle *handle,
90 uint32_t desired_replication_level, 108 const char* name,
91 enum GNUNET_DHT_RouteOption options, 109 enum GNUNET_GNS_RecordType type,
92 enum GNUNET_BLOCK_Type type, size_t size, const char *data, 110 size_t size, const char *data,
93 struct GNUNET_TIME_Absolute exp, 111 struct GNUNET_TIME_Absolute exp,
94 struct GNUNET_TIME_Relative timeout, GNUNET_SCHEDULER_Task cont, 112 struct GNUNET_TIME_Relative timeout);
95 void *cont_cls);
96 113
97 114
98/** 115/**
@@ -102,23 +119,14 @@ GNUNET_GNS_add (struct GNUNET_GNS_Handle *handle, const GNUNET_HashCode * key,
102 * @param cls closure 119 * @param cls closure
103 * @param exp when will this value expire 120 * @param exp when will this value expire
104 * @param key key of the result 121 * @param key key of the result
105 * @param get_path peers on reply path (or NULL if not recorded) 122 * @param records the records in reply
106 * @param get_path_length number of entries in get_path 123 * @param num_records the number of records in reply
107 * @param put_path peers on the PUT path (or NULL if not recorded)
108 * @param put_path_length number of entries in get_path
109 * @param type type of the result 124 * @param type type of the result
110 * @param size number of bytes in data
111 * @param data pointer to the result data
112 */ 125 */
113typedef void (*GNUNET_GNS_LookupIterator) (void *cls, 126typedef void (*GNUNET_GNS_LookupIterator) (void *cls,
114 struct GNUNET_TIME_Absolute exp,
115 const GNUNET_HashCode * key, 127 const GNUNET_HashCode * key,
116 const struct GNUNET_PeerIdentity * 128 const struct GNUNET_GNS_Record *record,
117 get_path, unsigned int get_path_length, 129 unsigned int num_records);
118 const struct GNUNET_PeerIdentity *
119 put_path, unsigned int put_path_length,
120 enum GNUNET_BLOCK_Type type,
121 size_t size, const void *data);
122 130
123 131
124 132
@@ -142,10 +150,9 @@ typedef void (*GNUNET_GNS_LookupIterator) (void *cls,
142struct GNUNET_GNS_LookupHandle * 150struct GNUNET_GNS_LookupHandle *
143GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, 151GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle,
144 struct GNUNET_TIME_Relative timeout, 152 struct GNUNET_TIME_Relative timeout,
145 enum GNUNET_BLOCK_Type type, const GNUNET_HashCode * key, 153 const char * name,
146 uint32_t desired_replication_level, 154 enum GNUNET_GNS_RecordType type,
147 enum GNUNET_DHT_RouteOption options, const void *xquery, 155 GNUNET_GNS_LookupIterator iter,
148 size_t xquery_size, GNUNET_GNS_LookupIterator iter,
149 void *iter_cls); 156 void *iter_cls);
150 157
151 158