diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gns/Makefile.am | 62 | ||||
-rw-r--r-- | src/gns/gns.h | 93 | ||||
-rw-r--r-- | src/gns/gns_api.c | 400 | ||||
-rw-r--r-- | src/gns/gnunet-gns-add.c | 8 | ||||
-rw-r--r-- | src/gns/gnunet-service-gns.c | 22 | ||||
-rw-r--r-- | src/include/gnunet_gns_service.h | 57 |
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 @@ | |||
1 | INCLUDES = -I$(top_srcdir)/src/include | ||
2 | |||
3 | if MINGW | ||
4 | WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols | ||
5 | endif | ||
6 | |||
7 | if USE_COVERAGE | ||
8 | AM_CFLAGS = --coverage -O0 | ||
9 | endif | ||
10 | |||
11 | pkgcfgdir= $(pkgdatadir)/config.d/ | ||
12 | |||
13 | plugindir = $(libdir)/gnunet | ||
14 | |||
15 | pkgcfg_DATA = \ | ||
16 | dns.conf | ||
17 | |||
18 | lib_LTLIBRARIES = \ | ||
19 | libgnunetgns.la | ||
20 | |||
21 | bin_PROGRAMS = \ | ||
22 | gnunet-service-gns $(HIJACKBIN) | ||
23 | |||
24 | noinst_PROGRAMS = \ | ||
25 | gnunet-gns-lookup gnunet-gns-add | ||
26 | |||
27 | #check_SCRIPTS = \ | ||
28 | # test_gnunet_dns.sh | ||
29 | |||
30 | |||
31 | gnunet_gns_add_SOURCES = \ | ||
32 | gnunet-gns-add.c | ||
33 | gnunet_gns_add_LDADD = \ | ||
34 | $(top_builddir)/src/gns/libgnunetgns.la \ | ||
35 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
36 | $(GN_LIBINTL) | ||
37 | gnunet_dns_add_DEPENDENCIES = \ | ||
38 | libgnunetgns.la | ||
39 | |||
40 | gnunet_service_gns_SOURCES = \ | ||
41 | gnunet-service-gns.c | ||
42 | gnunet_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 | |||
50 | libgnunetgns_la_SOURCES = \ | ||
51 | gns_api.c gns.h | ||
52 | libgnunetgns_la_LIBADD = \ | ||
53 | $(top_builddir)/src/util/libgnunetutil.la $(XLIB) | ||
54 | libgnunetgns_la_LDFLAGS = \ | ||
55 | $(GN_LIB_LDFLAGS) | ||
56 | |||
57 | if ENABLE_TEST_RUN | ||
58 | TESTS = $(check_PROGRAMS) $(check_SCRIPTS) | ||
59 | endif | ||
60 | |||
61 | EXTRA_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 | |||
29 | GNUNET_NETWORK_STRUCT_BEGIN | ||
30 | |||
31 | |||
32 | /** | ||
33 | * Message from client to GNS service to lookup records. | ||
34 | */ | ||
35 | struct 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 | */ | ||
64 | struct 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 | |||
91 | GNUNET_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 | */ | ||
48 | struct 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 | */ | ||
145 | struct 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 | */ | ||
209 | static void | ||
210 | process_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 | */ | ||
294 | static size_t | ||
295 | transmit_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 | */ | ||
303 | static void | ||
304 | message_handler (void *cls, const struct GNUNET_MessageHeader *msg); | ||
305 | |||
306 | /** | ||
307 | * Try to send messages from list of messages to send | ||
308 | */ | ||
309 | static void | ||
310 | process_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 | */ | ||
342 | static size_t | ||
343 | transmit_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 | */ | ||
406 | static int | ||
407 | process_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 | */ | ||
454 | static void | ||
455 | message_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 | */ |
200 | struct GNUNET_GNS_Handle * | 502 | struct GNUNET_GNS_Handle * |
@@ -225,7 +527,7 @@ GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
225 | void | 527 | void |
226 | GNUNET_GNS_disconnect (struct GNUNET_GNS_Handle *handle) | 528 | GNUNET_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 | */ |
248 | void | 542 | void |
249 | GNUNET_GNS_add_record (struct GNUNET_GNS_Handle *handle, const GNUNET_HashCode * key, | 543 | GNUNET_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 * | |||
287 | struct GNUNET_GNS_LookupHandle * | 573 | struct GNUNET_GNS_LookupHandle * |
288 | GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, | 574 | GNUNET_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, | |||
305 | void | 623 | void |
306 | GNUNET_GNS_lookup_stop (struct GNUNET_GNS_LookupHandle *lookup_handle) | 624 | GNUNET_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 | */ |
42 | const struct GNUNET_CONFIGURATION_Handle *GDS_cfg; | 42 | const 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; | |||
49 | struct GNUNET_GNS_LookupHandle; | 49 | struct GNUNET_GNS_LookupHandle; |
50 | 50 | ||
51 | /** | 51 | /** |
52 | * A single GNS record. | ||
53 | */ | ||
54 | struct GNUNET_GNS_Record; | ||
55 | |||
56 | /** | ||
57 | * Records types | ||
58 | */ | ||
59 | enum 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 | */ |
57 | struct GNUNET_GNS_Handle * | 74 | struct GNUNET_GNS_Handle * |
58 | GNUNET_GNS_connect (const struct GNUNET_CONFIGURATION_Handle *cfg); | 75 | GNUNET_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 | */ |
88 | void | 106 | void |
89 | GNUNET_GNS_add (struct GNUNET_GNS_Handle *handle, const GNUNET_HashCode * key, | 107 | GNUNET_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 | */ |
113 | typedef void (*GNUNET_GNS_LookupIterator) (void *cls, | 126 | typedef 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, | |||
142 | struct GNUNET_GNS_LookupHandle * | 150 | struct GNUNET_GNS_LookupHandle * |
143 | GNUNET_GNS_lookup_start (struct GNUNET_GNS_Handle *handle, | 151 | GNUNET_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 | ||