diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-08-13 19:14:19 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-08-13 19:14:19 +0000 |
commit | 5f5f1974b15c646bde44583aede2433254138661 (patch) | |
tree | 6197cc994723c804e261ff15c9a04e800f3988ee /src/gns/gnunet-service-gns.c | |
parent | adc6e4a5804d4cb43516383ff1d97065df0d0fd9 (diff) | |
download | gnunet-5f5f1974b15c646bde44583aede2433254138661.tar.gz gnunet-5f5f1974b15c646bde44583aede2433254138661.zip |
-more coding towards working new GNS service
Diffstat (limited to 'src/gns/gnunet-service-gns.c')
-rw-r--r-- | src/gns/gnunet-service-gns.c | 494 |
1 files changed, 217 insertions, 277 deletions
diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c index 822cc7d12..be41f8c84 100644 --- a/src/gns/gnunet-service-gns.c +++ b/src/gns/gnunet-service-gns.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2009, 2010, 2011, 2012 Christian Grothoff (and other contributing authors) | 3 | (C) 2011-2013 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published |
@@ -50,7 +50,7 @@ | |||
50 | 50 | ||
51 | /** | 51 | /** |
52 | * The default put interval for the zone iteration. In case | 52 | * The default put interval for the zone iteration. In case |
53 | * No option is found | 53 | * no option is found |
54 | */ | 54 | */ |
55 | #define DEFAULT_ZONE_PUBLISH_TIME_WINDOW GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4) | 55 | #define DEFAULT_ZONE_PUBLISH_TIME_WINDOW GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 4) |
56 | 56 | ||
@@ -60,6 +60,16 @@ | |||
60 | */ | 60 | */ |
61 | #define LATE_ITERATION_SPEEDUP_FACTOR 2 | 61 | #define LATE_ITERATION_SPEEDUP_FACTOR 2 |
62 | 62 | ||
63 | /** | ||
64 | * How long until a DHT PUT attempt should time out? | ||
65 | */ | ||
66 | #define DHT_OPERATION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) | ||
67 | |||
68 | /** | ||
69 | * What replication level do we use for DHT PUT operations? | ||
70 | */ | ||
71 | #define DHT_GNS_REPLICATION_LEVEL 5 | ||
72 | |||
63 | 73 | ||
64 | /** | 74 | /** |
65 | * Handle to a lookup operation from api | 75 | * Handle to a lookup operation from api |
@@ -68,39 +78,30 @@ struct ClientLookupHandle | |||
68 | { | 78 | { |
69 | 79 | ||
70 | /** | 80 | /** |
71 | * Handle to the requesting client | 81 | * We keep these in a DLL. |
72 | */ | 82 | */ |
73 | struct GNUNET_SERVER_Client *client; | 83 | struct ClientLookupHandle *next; |
74 | 84 | ||
75 | /** | 85 | /** |
76 | * optional zone private key used for shorten | 86 | * We keep these in a DLL. |
77 | */ | 87 | */ |
78 | struct GNUNET_CRYPTO_EccPrivateKey *shorten_key; | 88 | struct ClientLookupHandle *prev; |
79 | 89 | ||
80 | /** | 90 | /** |
81 | * the name to look up | 91 | * Handle to the requesting client |
82 | */ | 92 | */ |
83 | char *name; | 93 | struct GNUNET_SERVER_Client *client; |
84 | 94 | ||
85 | /** | 95 | /** |
86 | * The zone we look up in | 96 | * Active handle for the lookup. |
87 | */ | 97 | */ |
88 | struct GNUNET_CRYPTO_ShortHashCode zone; | 98 | struct GNS_ResolverHandle *lookup; |
89 | 99 | ||
90 | /** | 100 | /** |
91 | * request id | 101 | * request id |
92 | */ | 102 | */ |
93 | uint32_t request_id; | 103 | uint32_t request_id; |
94 | 104 | ||
95 | /** | ||
96 | * GNUNET_YES if we only want to lookup from local cache | ||
97 | */ | ||
98 | int only_cached; | ||
99 | |||
100 | /** | ||
101 | * request type | ||
102 | */ | ||
103 | int type; | ||
104 | }; | 105 | }; |
105 | 106 | ||
106 | 107 | ||
@@ -110,9 +111,9 @@ struct ClientLookupHandle | |||
110 | static struct GNUNET_DHT_Handle *dht_handle; | 111 | static struct GNUNET_DHT_Handle *dht_handle; |
111 | 112 | ||
112 | /** | 113 | /** |
113 | * Our zone's private key | 114 | * Active DHT put operation (or NULL) |
114 | */ | 115 | */ |
115 | static struct GNUNET_CRYPTO_EccPrivateKey *zone_key; | 116 | static struct GNUNET_DHT_PutHandle *active_put; |
116 | 117 | ||
117 | /** | 118 | /** |
118 | * Our handle to the namestore service | 119 | * Our handle to the namestore service |
@@ -130,9 +131,14 @@ static struct GNUNET_NAMESTORE_ZoneIterator *namestore_iter; | |||
130 | static struct GNUNET_SERVER_NotificationContext *nc; | 131 | static struct GNUNET_SERVER_NotificationContext *nc; |
131 | 132 | ||
132 | /** | 133 | /** |
133 | * Our zone hash | 134 | * Head of the DLL. |
135 | */ | ||
136 | static struct ClientLookupHandle *clh_head; | ||
137 | |||
138 | /** | ||
139 | * Tail of the DLL. | ||
134 | */ | 140 | */ |
135 | static struct GNUNET_CRYPTO_ShortHashCode zone_hash; | 141 | static struct ClientLookupHandle *clh_tail; |
136 | 142 | ||
137 | /** | 143 | /** |
138 | * Useful for zone update for DHT put | 144 | * Useful for zone update for DHT put |
@@ -160,13 +166,7 @@ static struct GNUNET_TIME_Relative zone_publish_time_window; | |||
160 | static GNUNET_SCHEDULER_TaskIdentifier zone_publish_task; | 166 | static GNUNET_SCHEDULER_TaskIdentifier zone_publish_task; |
161 | 167 | ||
162 | /** | 168 | /** |
163 | * GNUNET_YES if automatic pkey import for name shortening | 169 | * #GNUNET_YES if zone has never been published before |
164 | * is enabled | ||
165 | */ | ||
166 | static int auto_import_pkey; | ||
167 | |||
168 | /** | ||
169 | * GNUNET_YES if zone has never been published before | ||
170 | */ | 170 | */ |
171 | static int first_zone_iteration; | 171 | static int first_zone_iteration; |
172 | 172 | ||
@@ -176,12 +176,12 @@ static int first_zone_iteration; | |||
176 | static struct GNUNET_TIME_Relative default_lookup_timeout; | 176 | static struct GNUNET_TIME_Relative default_lookup_timeout; |
177 | 177 | ||
178 | /** | 178 | /** |
179 | * GNUNET_YES if ipv6 is supported | 179 | * #GNUNET_YES if ipv6 is supported |
180 | */ | 180 | */ |
181 | static int v6_enabled; | 181 | static int v6_enabled; |
182 | 182 | ||
183 | /** | 183 | /** |
184 | * GNUNET_YES if ipv4 is supported | 184 | * #GNUNET_YES if ipv4 is supported |
185 | */ | 185 | */ |
186 | static int v4_enabled; | 186 | static int v4_enabled; |
187 | 187 | ||
@@ -200,13 +200,20 @@ static struct GNUNET_STATISTICS_Handle *statistics; | |||
200 | static void | 200 | static void |
201 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 201 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
202 | { | 202 | { |
203 | struct ClientShortenHandle *csh_tmp; | 203 | struct ClientLookupHandle *clh; |
204 | 204 | ||
205 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 205 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
206 | "Shutting down!\n"); | 206 | "Shutting down!\n"); |
207 | GNUNET_SERVER_notification_context_destroy (nc); | 207 | GNUNET_SERVER_notification_context_destroy (nc); |
208 | gns_interceptor_stop (); | 208 | while (NULL != (clh = clh_head)) |
209 | gns_resolver_cleanup (); | 209 | { |
210 | GNS_resolver_lookup_cancel (clh->lookup); | ||
211 | GNUNET_CONTAINER_DLL_remove (clh_head, clh_tail, clh); | ||
212 | GNUNET_free (clh); | ||
213 | } | ||
214 | |||
215 | GNS_interceptor_done (); | ||
216 | GNS_resolver_done (); | ||
210 | if (NULL != statistics) | 217 | if (NULL != statistics) |
211 | { | 218 | { |
212 | GNUNET_STATISTICS_destroy (statistics, GNUNET_NO); | 219 | GNUNET_STATISTICS_destroy (statistics, GNUNET_NO); |
@@ -227,6 +234,11 @@ shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
227 | GNUNET_NAMESTORE_disconnect (namestore_handle); | 234 | GNUNET_NAMESTORE_disconnect (namestore_handle); |
228 | namestore_handle = NULL; | 235 | namestore_handle = NULL; |
229 | } | 236 | } |
237 | if (NULL != active_put) | ||
238 | { | ||
239 | GNUNET_DHT_put_cancel (active_put); | ||
240 | active_put = NULL; | ||
241 | } | ||
230 | if (NULL != dht_handle) | 242 | if (NULL != dht_handle) |
231 | { | 243 | { |
232 | GNUNET_DHT_disconnect (dht_handle); | 244 | GNUNET_DHT_disconnect (dht_handle); |
@@ -262,36 +274,65 @@ publish_zone_dht_start (void *cls, | |||
262 | 274 | ||
263 | 275 | ||
264 | /** | 276 | /** |
277 | * Continuation called from DHT once the PUT operation is done. | ||
278 | * | ||
279 | * @param cls closure, NULL | ||
280 | * @param success #GNUNET_OK on success | ||
281 | */ | ||
282 | static void | ||
283 | dht_put_continuation (void *cls, | ||
284 | int success) | ||
285 | { | ||
286 | struct GNUNET_TIME_Relative next_put_interval; | ||
287 | |||
288 | num_public_records++; | ||
289 | if ( (num_public_records > last_num_public_records) && | ||
290 | (GNUNET_NO == first_zone_iteration) ) | ||
291 | { | ||
292 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
293 | "Last record count was lower than current record count. Reducing interval.\n"); | ||
294 | put_interval = GNUNET_TIME_relative_divide (zone_publish_time_window, | ||
295 | num_public_records); | ||
296 | next_put_interval = GNUNET_TIME_relative_divide (put_interval, | ||
297 | LATE_ITERATION_SPEEDUP_FACTOR); | ||
298 | } | ||
299 | else | ||
300 | next_put_interval = put_interval; | ||
301 | |||
302 | GNUNET_STATISTICS_set (statistics, | ||
303 | "Current zone iteration interval (ms)", | ||
304 | next_put_interval.rel_value_us / 1000LL, | ||
305 | GNUNET_NO); | ||
306 | zone_publish_task = GNUNET_SCHEDULER_add_delayed (next_put_interval, | ||
307 | &publish_zone_dht_next, | ||
308 | NULL); | ||
309 | } | ||
310 | |||
311 | |||
312 | /** | ||
265 | * Function used to put all records successively into the DHT. | 313 | * Function used to put all records successively into the DHT. |
266 | * | 314 | * |
267 | * @param cls the closure (NULL) | 315 | * @param cls the closure (NULL) |
268 | * @param key the public key of the authority (ours) | 316 | * @param key the private key of the authority (ours) |
269 | * @param expiration lifetime of the namestore entry | 317 | * @param name the name of the records, NULL once the iteration is done |
270 | * @param name the name of the records | 318 | * @param rd_count the number of records in @a rd |
271 | * @param rd_count the number of records in data | ||
272 | * @param rd the record data | 319 | * @param rd the record data |
273 | * @param signature the signature for the record data | ||
274 | */ | 320 | */ |
275 | static void | 321 | static void |
276 | put_gns_record (void *cls, | 322 | put_gns_record (void *cls, |
277 | const struct GNUNET_CRYPTO_EccPublicKey *key, | 323 | const struct GNUNET_CRYPTO_EccPrivateKey *key, |
278 | struct GNUNET_TIME_Absolute expiration, | ||
279 | const char *name, | 324 | const char *name, |
280 | unsigned int rd_count, | 325 | unsigned int rd_count, |
281 | const struct GNUNET_NAMESTORE_RecordData *rd, | 326 | const struct GNUNET_NAMESTORE_RecordData *rd) |
282 | const struct GNUNET_CRYPTO_EccSignature *signature) | ||
283 | { | 327 | { |
284 | struct GNSNameRecordBlock *nrb; | 328 | struct GNUNET_NAMESTORE_Block *block; |
285 | struct GNUNET_CRYPTO_ShortHashCode zhash; | 329 | struct GNUNET_HashCode query; |
286 | struct GNUNET_HashCode dht_key; | 330 | struct GNUNET_TIME_Absolute expire; |
287 | uint32_t rd_payload_length; | 331 | size_t block_size; |
288 | char* nrb_data = NULL; | ||
289 | size_t namelen; | ||
290 | struct GNUNET_TIME_Relative next_put_interval; | ||
291 | 332 | ||
292 | if (NULL == name) | 333 | if (NULL == name) |
293 | { | 334 | { |
294 | /* we're done */ | 335 | /* we're done with one iteration, calculate when to do the next one */ |
295 | namestore_iter = NULL; | 336 | namestore_iter = NULL; |
296 | last_num_public_records = num_public_records; | 337 | last_num_public_records = num_public_records; |
297 | first_zone_iteration = GNUNET_NO; | 338 | first_zone_iteration = GNUNET_NO; |
@@ -304,7 +345,7 @@ put_gns_record (void *cls, | |||
304 | */ | 345 | */ |
305 | put_interval = zone_publish_time_window; | 346 | put_interval = zone_publish_time_window; |
306 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, | 347 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, |
307 | "No records in db.\n"); | 348 | "No records in namestore database.\n"); |
308 | } | 349 | } |
309 | else | 350 | else |
310 | { | 351 | { |
@@ -322,126 +363,62 @@ put_gns_record (void *cls, | |||
322 | put_interval.rel_value_us / 1000LL, | 363 | put_interval.rel_value_us / 1000LL, |
323 | GNUNET_NO); | 364 | GNUNET_NO); |
324 | GNUNET_STATISTICS_update (statistics, | 365 | GNUNET_STATISTICS_update (statistics, |
325 | "Number of zone iterations", 1, GNUNET_NO); | 366 | "Number of zone iterations", |
367 | 1, | ||
368 | GNUNET_NO); | ||
326 | GNUNET_STATISTICS_set (statistics, | 369 | GNUNET_STATISTICS_set (statistics, |
327 | "Number of public records in DHT", | 370 | "Number of public records in DHT", |
328 | last_num_public_records, | 371 | last_num_public_records, |
329 | GNUNET_NO); | 372 | GNUNET_NO); |
330 | if (0 == num_public_records) | 373 | if (0 == num_public_records) |
331 | zone_publish_task = GNUNET_SCHEDULER_add_delayed (put_interval, | 374 | zone_publish_task = GNUNET_SCHEDULER_add_delayed (put_interval, |
332 | &publish_zone_dht_start, | 375 | &publish_zone_dht_start, |
333 | NULL); | 376 | NULL); |
334 | else | 377 | else |
335 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start, NULL); | 378 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start, |
379 | NULL); | ||
336 | return; | 380 | return; |
337 | } | 381 | } |
338 | 382 | ||
339 | namelen = strlen (name) + 1; | 383 | /* FIXME: filter out records that are not public! */ |
384 | |||
385 | /* We got a set of records to publish */ | ||
340 | if (0 == rd_count) | 386 | if (0 == rd_count) |
341 | { | 387 | { |
342 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
343 | "No records for name `%s'! Skipping.\n", | ||
344 | name); | ||
345 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_next, | 388 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_next, |
346 | NULL); | 389 | NULL); |
347 | return; | 390 | return; |
348 | } | 391 | } |
349 | if (NULL == signature) | 392 | expire = GNUNET_NAMESTORE_record_get_expiration_time (rd_count, |
393 | rd); | ||
394 | block = GNUNET_NAMESTORE_block_create (key, | ||
395 | expire, | ||
396 | name, | ||
397 | rd, | ||
398 | rd_count); | ||
399 | block_size = ntohl (block->purpose.size) | ||
400 | + sizeof (struct GNUNET_CRYPTO_EccSignature) | ||
401 | + sizeof (struct GNUNET_CRYPTO_EccPublicKey); | ||
402 | GNUNET_NAMESTORE_query_from_private_key (key, | ||
403 | name, | ||
404 | &query); | ||
405 | |||
406 | active_put = GNUNET_DHT_put (dht_handle, &query, | ||
407 | DHT_GNS_REPLICATION_LEVEL, | ||
408 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, | ||
409 | GNUNET_BLOCK_TYPE_GNS_NAMERECORD, | ||
410 | block_size, | ||
411 | block, | ||
412 | expire, | ||
413 | DHT_OPERATION_TIMEOUT, | ||
414 | &dht_put_continuation, | ||
415 | NULL); | ||
416 | if (NULL == active_put) | ||
350 | { | 417 | { |
351 | GNUNET_break (0); | 418 | GNUNET_break (0); |
352 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_next, | 419 | dht_put_continuation (NULL, GNUNET_NO); |
353 | NULL); | ||
354 | return; | ||
355 | } | ||
356 | |||
357 | /* TODO 2) AB: New publishing | ||
358 | * | ||
359 | * - Use new signature S_d | ||
360 | * - Obtain new derived public key V = H(H(i,Q) * Q) | ||
361 | * - Obtain HKDF(i,Q) | ||
362 | * - Compute encrypte record block E with HKDF(i,Q) (rd, rd_count) | ||
363 | * - Create block B = |V,E,S_d| | ||
364 | * - Compute new DHT key H(V) in TODO 3) | ||
365 | * | ||
366 | * -> Put (H(V), B) | ||
367 | */ | ||
368 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
369 | "Putting records for `%s' into the DHT\n", name); | ||
370 | rd_payload_length = GNUNET_NAMESTORE_records_get_size (rd_count, rd); | ||
371 | nrb = GNUNET_malloc (rd_payload_length + namelen | ||
372 | + sizeof (struct GNSNameRecordBlock)); | ||
373 | nrb->signature = *signature; | ||
374 | nrb->public_key = *key; | ||
375 | nrb->rd_count = htonl (rd_count); | ||
376 | memcpy (&nrb[1], name, namelen); | ||
377 | nrb_data = (char *) &nrb[1]; | ||
378 | nrb_data += namelen; | ||
379 | rd_payload_length += sizeof(struct GNSNameRecordBlock) + namelen; | ||
380 | GNUNET_CRYPTO_short_hash (key, | ||
381 | sizeof (struct GNUNET_CRYPTO_EccPublicKey), | ||
382 | &zhash); | ||
383 | if (-1 == GNUNET_NAMESTORE_records_serialize (rd_count, | ||
384 | rd, | ||
385 | rd_payload_length, | ||
386 | nrb_data)) | ||
387 | { | ||
388 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
389 | _("Records for name `%s' in zone %s too large to fit into DHT"), | ||
390 | name, | ||
391 | GNUNET_short_h2s (&zhash)); | ||
392 | GNUNET_free (nrb); | ||
393 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_next, | ||
394 | NULL); | ||
395 | return; | ||
396 | } | ||
397 | /* TODO AB: Here records are put in the DHT: modify dht_key to H(key) = H(H(name,zone) * zone) */ | ||
398 | GNUNET_GNS_get_key_for_record (name, &zhash, &dht_key); | ||
399 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
400 | "putting %u records from zone %s for `%s' under key: %s with size %u and timeout %s\n", | ||
401 | rd_count, | ||
402 | GNUNET_short_h2s (&zhash), | ||
403 | name, | ||
404 | GNUNET_h2s (&dht_key), | ||
405 | (unsigned int) rd_payload_length, | ||
406 | GNUNET_STRINGS_relative_time_to_string (DHT_OPERATION_TIMEOUT, GNUNET_YES)); | ||
407 | |||
408 | GNUNET_STATISTICS_update (statistics, | ||
409 | "Record bytes put into DHT", | ||
410 | rd_payload_length, GNUNET_NO); | ||
411 | |||
412 | (void) GNUNET_DHT_put (dht_handle, &dht_key, | ||
413 | DHT_GNS_REPLICATION_LEVEL, | ||
414 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, | ||
415 | GNUNET_BLOCK_TYPE_GNS_NAMERECORD, | ||
416 | rd_payload_length, | ||
417 | (char*)nrb, | ||
418 | expiration, | ||
419 | DHT_OPERATION_TIMEOUT, | ||
420 | NULL, | ||
421 | NULL); | ||
422 | GNUNET_free (nrb); | ||
423 | |||
424 | num_public_records++; | ||
425 | if ( (num_public_records > last_num_public_records) | ||
426 | && (GNUNET_NO == first_zone_iteration) ) | ||
427 | { | ||
428 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
429 | "Last record count was lower than current record count. Reducing interval.\n"); | ||
430 | put_interval = GNUNET_TIME_relative_divide (zone_publish_time_window, | ||
431 | num_public_records); | ||
432 | next_put_interval = GNUNET_TIME_relative_divide (put_interval, | ||
433 | LATE_ITERATION_SPEEDUP_FACTOR); | ||
434 | } | 420 | } |
435 | else | 421 | GNUNET_free (block); |
436 | next_put_interval = put_interval; | ||
437 | |||
438 | GNUNET_STATISTICS_set (statistics, | ||
439 | "Current zone iteration interval (ms)", | ||
440 | next_put_interval.rel_value_us / 1000LL, | ||
441 | GNUNET_NO); | ||
442 | zone_publish_task = GNUNET_SCHEDULER_add_delayed (next_put_interval, | ||
443 | &publish_zone_dht_next, | ||
444 | NULL); | ||
445 | } | 422 | } |
446 | 423 | ||
447 | 424 | ||
@@ -463,8 +440,6 @@ publish_zone_dht_start (void *cls, | |||
463 | num_public_records = 0; | 440 | num_public_records = 0; |
464 | namestore_iter = GNUNET_NAMESTORE_zone_iteration_start (namestore_handle, | 441 | namestore_iter = GNUNET_NAMESTORE_zone_iteration_start (namestore_handle, |
465 | NULL, /* All zones */ | 442 | NULL, /* All zones */ |
466 | GNUNET_NAMESTORE_RF_AUTHORITY, | ||
467 | GNUNET_NAMESTORE_RF_PRIVATE, | ||
468 | &put_gns_record, | 443 | &put_gns_record, |
469 | NULL); | 444 | NULL); |
470 | } | 445 | } |
@@ -485,40 +460,39 @@ send_lookup_response (void* cls, | |||
485 | uint32_t rd_count, | 460 | uint32_t rd_count, |
486 | const struct GNUNET_NAMESTORE_RecordData *rd) | 461 | const struct GNUNET_NAMESTORE_RecordData *rd) |
487 | { | 462 | { |
488 | struct ClientLookupHandle* clh = cls; | 463 | struct ClientLookupHandle *clh = cls; |
489 | struct GNUNET_GNS_ClientLookupResultMessage *rmsg; | 464 | struct GNUNET_GNS_ClientLookupResultMessage *rmsg; |
490 | size_t len; | 465 | size_t len; |
491 | 466 | ||
492 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending `%s' message with %d results\n", | 467 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
493 | "LOOKUP_RESULT", rd_count); | 468 | "Sending `%s' message with %d results\n", |
469 | "LOOKUP_RESULT", | ||
470 | rd_count); | ||
494 | 471 | ||
495 | len = GNUNET_NAMESTORE_records_get_size (rd_count, rd); | 472 | len = GNUNET_NAMESTORE_records_get_size (rd_count, rd); |
496 | rmsg = GNUNET_malloc (len + sizeof (struct GNUNET_GNS_ClientLookupResultMessage)); | 473 | rmsg = GNUNET_malloc (len + sizeof (struct GNUNET_GNS_ClientLookupResultMessage)); |
497 | 474 | rmsg->header.type = htons (GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT); | |
475 | rmsg->header.size = htons (len + sizeof(struct GNUNET_GNS_ClientLookupResultMessage)); | ||
498 | rmsg->id = clh->request_id; | 476 | rmsg->id = clh->request_id; |
499 | rmsg->rd_count = htonl(rd_count); | 477 | rmsg->rd_count = htonl (rd_count); |
500 | rmsg->header.type = htons(GNUNET_MESSAGE_TYPE_GNS_LOOKUP_RESULT); | 478 | GNUNET_NAMESTORE_records_serialize (rd_count, rd, len, |
501 | rmsg->header.size = | 479 | (char*) &rmsg[1]); |
502 | htons(len+sizeof(struct GNUNET_GNS_ClientLookupResultMessage)); | 480 | GNUNET_SERVER_notification_context_unicast (nc, |
503 | 481 | clh->client, | |
504 | GNUNET_NAMESTORE_records_serialize (rd_count, rd, len, (char*)&rmsg[1]); | 482 | &rmsg->header, |
505 | 483 | GNUNET_NO); | |
506 | GNUNET_SERVER_notification_context_unicast (nc, clh->client, | 484 | GNUNET_free (rmsg); |
507 | (const struct GNUNET_MessageHeader *) rmsg, | 485 | GNUNET_SERVER_receive_done (clh->client, |
508 | GNUNET_NO); | 486 | GNUNET_OK); |
509 | GNUNET_SERVER_receive_done (clh->client, GNUNET_OK); | 487 | GNUNET_CONTAINER_DLL_remove (clh_head, clh_tail, clh); |
510 | |||
511 | GNUNET_free(rmsg); | ||
512 | GNUNET_free(clh->name); | ||
513 | |||
514 | if (NULL != clh->shorten_key) | ||
515 | GNUNET_CRYPTO_ecc_key_free (clh->shorten_key); | ||
516 | GNUNET_free (clh); | 488 | GNUNET_free (clh); |
517 | GNUNET_STATISTICS_update (statistics, | 489 | GNUNET_STATISTICS_update (statistics, |
518 | "Completed lookups", 1, GNUNET_NO); | 490 | "Completed lookups", 1, |
519 | if (NULL != rd) | 491 | GNUNET_NO); |
520 | GNUNET_STATISTICS_update (statistics, | 492 | GNUNET_STATISTICS_update (statistics, |
521 | "Records resolved", rd_count, GNUNET_NO); | 493 | "Records resolved", |
494 | rd_count, | ||
495 | GNUNET_NO); | ||
522 | } | 496 | } |
523 | 497 | ||
524 | 498 | ||
@@ -531,22 +505,21 @@ send_lookup_response (void* cls, | |||
531 | */ | 505 | */ |
532 | static void | 506 | static void |
533 | handle_lookup (void *cls, | 507 | handle_lookup (void *cls, |
534 | struct GNUNET_SERVER_Client * client, | 508 | struct GNUNET_SERVER_Client *client, |
535 | const struct GNUNET_MessageHeader * message) | 509 | const struct GNUNET_MessageHeader *message) |
536 | { | 510 | { |
537 | size_t namelen; | 511 | char name[GNUNET_DNSPARSER_MAX_NAME_LENGTH + 1]; |
538 | char name[GNUNET_DNSPARSER_MAX_NAME_LENGTH]; | ||
539 | struct ClientLookupHandle *clh; | 512 | struct ClientLookupHandle *clh; |
540 | char* nameptr = name; | 513 | char *nameptr = name; |
541 | const char *utf_in; | 514 | const char *utf_in; |
542 | int only_cached; | ||
543 | const struct GNUNET_CRYPTO_EccPrivateKey *key; | 515 | const struct GNUNET_CRYPTO_EccPrivateKey *key; |
544 | uint16_t msg_size; | 516 | uint16_t msg_size; |
545 | const struct GNUNET_GNS_ClientLookupMessage *sh_msg; | 517 | const struct GNUNET_GNS_ClientLookupMessage *sh_msg; |
546 | 518 | ||
547 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 519 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
548 | "Received `%s' message\n", "LOOKUP"); | 520 | "Received `%s' message\n", |
549 | msg_size = ntohs(message->size); | 521 | "LOOKUP"); |
522 | msg_size = ntohs (message->size); | ||
550 | if (msg_size < sizeof (struct GNUNET_GNS_ClientLookupMessage)) | 523 | if (msg_size < sizeof (struct GNUNET_GNS_ClientLookupMessage)) |
551 | { | 524 | { |
552 | GNUNET_break (0); | 525 | GNUNET_break (0); |
@@ -556,88 +529,48 @@ handle_lookup (void *cls, | |||
556 | sh_msg = (const struct GNUNET_GNS_ClientLookupMessage *) message; | 529 | sh_msg = (const struct GNUNET_GNS_ClientLookupMessage *) message; |
557 | GNUNET_SERVER_notification_context_add (nc, client); | 530 | GNUNET_SERVER_notification_context_add (nc, client); |
558 | if (GNUNET_YES == ntohl (sh_msg->have_key)) | 531 | if (GNUNET_YES == ntohl (sh_msg->have_key)) |
559 | { | ||
560 | key = &sh_msg->shorten_key; | 532 | key = &sh_msg->shorten_key; |
561 | } | ||
562 | else | 533 | else |
563 | { | ||
564 | key = NULL; | 534 | key = NULL; |
565 | } | ||
566 | utf_in = (const char *) &sh_msg[1]; | 535 | utf_in = (const char *) &sh_msg[1]; |
567 | if ('\0' != utf_in[msg_size - sizeof (struct GNUNET_GNS_ClientLookupMessage) - 1]) | 536 | if ( ('\0' != utf_in[msg_size - sizeof (struct GNUNET_GNS_ClientLookupMessage) - 1]) || |
537 | (strlen (utf_in) > GNUNET_DNSPARSER_MAX_NAME_LENGTH) ) | ||
568 | { | 538 | { |
569 | GNUNET_break (0); | 539 | GNUNET_break (0); |
570 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); | 540 | GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); |
571 | return; | 541 | return; |
572 | } | 542 | } |
573 | GNUNET_STRINGS_utf8_tolower (utf_in, &nameptr); | 543 | GNUNET_STRINGS_utf8_tolower (utf_in, &nameptr); |
574 | 544 | ||
575 | namelen = strlen (name) + 1; | 545 | clh = GNUNET_new (struct ClientLookupHandle); |
576 | clh = GNUNET_malloc (sizeof (struct ClientLookupHandle)); | 546 | GNUNET_CONTAINER_DLL_insert (clh_head, clh_tail, clh); |
577 | memset (clh, 0, sizeof (struct ClientLookupHandle)); | ||
578 | clh->client = client; | 547 | clh->client = client; |
579 | clh->name = GNUNET_malloc (namelen); | ||
580 | strcpy (clh->name, name); | ||
581 | clh->request_id = sh_msg->id; | 548 | clh->request_id = sh_msg->id; |
582 | clh->type = ntohl (sh_msg->type); | 549 | if ( (GNUNET_DNSPARSER_TYPE_A == ntohl (sh_msg->type)) && |
583 | if (NULL != key) | 550 | (GNUNET_OK != v4_enabled) ) |
584 | { | 551 | { |
585 | clh->shorten_key = GNUNET_new (struct GNUNET_CRYPTO_EccPrivateKey); | ||
586 | *clh->shorten_key = *key; | ||
587 | } | ||
588 | only_cached = ntohl (sh_msg->only_cached); | ||
589 | |||
590 | if (strlen (name) > GNUNET_DNSPARSER_MAX_NAME_LENGTH) { | ||
591 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 552 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
592 | "LOOKUP: %s is too long", name); | 553 | "LOOKUP: Query for A record but AF_INET not supported!"); |
593 | clh->name = NULL; | ||
594 | send_lookup_response (clh, 0, NULL); | ||
595 | return; | ||
596 | } | ||
597 | |||
598 | if ((GNUNET_DNSPARSER_TYPE_A == clh->type) && | ||
599 | (GNUNET_OK != v4_enabled)) | ||
600 | { | ||
601 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
602 | "LOOKUP: Query for A record but AF_INET not supported!"); | ||
603 | clh->name = NULL; | ||
604 | send_lookup_response (clh, 0, NULL); | 554 | send_lookup_response (clh, 0, NULL); |
605 | return; | 555 | return; |
606 | } | 556 | } |
607 | 557 | if ( (GNUNET_DNSPARSER_TYPE_AAAA == ntohl (sh_msg->type)) && | |
608 | if ((GNUNET_DNSPARSER_TYPE_AAAA == clh->type) && | 558 | (GNUNET_OK != v6_enabled) ) |
609 | (GNUNET_OK != v6_enabled)) | ||
610 | { | 559 | { |
611 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 560 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
612 | "LOOKUP: Query for AAAA record but AF_INET6 not supported!"); | 561 | "LOOKUP: Query for AAAA record but AF_INET6 not supported!"); |
613 | clh->name = NULL; | ||
614 | send_lookup_response (clh, 0, NULL); | 562 | send_lookup_response (clh, 0, NULL); |
615 | return; | 563 | return; |
616 | } | 564 | } |
617 | 565 | clh->lookup = GNS_resolver_lookup (&sh_msg->zone, | |
618 | if (GNUNET_NO == ntohl (sh_msg->have_zone)) | 566 | ntohl (sh_msg->type), |
619 | clh->zone = zone_hash; /* Default zone */ | 567 | name, |
620 | else | 568 | key, |
621 | clh->zone = sh_msg->zone; | 569 | ntohl (sh_msg->only_cached), |
622 | 570 | &send_lookup_response, clh); | |
623 | if (GNUNET_YES == auto_import_pkey) | ||
624 | { | ||
625 | gns_resolver_lookup_record (clh->zone, clh->zone, clh->type, clh->name, | ||
626 | clh->shorten_key, | ||
627 | default_lookup_timeout, | ||
628 | clh->only_cached, | ||
629 | &send_lookup_response, clh); | ||
630 | } | ||
631 | else | ||
632 | { | ||
633 | gns_resolver_lookup_record (clh->zone, clh->zone, clh->type, name, | ||
634 | NULL, | ||
635 | default_lookup_timeout, | ||
636 | only_cached, | ||
637 | &send_lookup_response, clh); | ||
638 | } | ||
639 | GNUNET_STATISTICS_update (statistics, | 571 | GNUNET_STATISTICS_update (statistics, |
640 | "Record lookup attempts", 1, GNUNET_NO); | 572 | "Lookup attempts", |
573 | 1, GNUNET_NO); | ||
641 | } | 574 | } |
642 | 575 | ||
643 | 576 | ||
@@ -656,9 +589,10 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
656 | { &handle_lookup, NULL, GNUNET_MESSAGE_TYPE_GNS_LOOKUP, 0}, | 589 | { &handle_lookup, NULL, GNUNET_MESSAGE_TYPE_GNS_LOOKUP, 0}, |
657 | {NULL, NULL, 0, 0} | 590 | {NULL, NULL, 0, 0} |
658 | }; | 591 | }; |
659 | struct GNUNET_CRYPTO_EccPublicKey pkey; | 592 | struct GNUNET_CRYPTO_EccPublicKey dns_root; |
660 | unsigned long long max_parallel_bg_queries = 0; | 593 | unsigned long long max_parallel_bg_queries = 0; |
661 | int ignore_pending = GNUNET_NO; | 594 | int ignore_pending = GNUNET_NO; |
595 | char *dns_root_name; | ||
662 | 596 | ||
663 | v6_enabled = GNUNET_NETWORK_test_pf (PF_INET6); | 597 | v6_enabled = GNUNET_NETWORK_test_pf (PF_INET6); |
664 | v4_enabled = GNUNET_NETWORK_test_pf (PF_INET); | 598 | v4_enabled = GNUNET_NETWORK_test_pf (PF_INET); |
@@ -672,15 +606,6 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
672 | return; | 606 | return; |
673 | } | 607 | } |
674 | 608 | ||
675 | auto_import_pkey = GNUNET_NO; | ||
676 | if (GNUNET_YES == | ||
677 | GNUNET_CONFIGURATION_get_value_yesno (c, "gns", | ||
678 | "AUTO_IMPORT_PKEY")) | ||
679 | { | ||
680 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
681 | "Automatic PKEY import is enabled.\n"); | ||
682 | auto_import_pkey = GNUNET_YES; | ||
683 | } | ||
684 | put_interval = INITIAL_PUT_INTERVAL; | 609 | put_interval = INITIAL_PUT_INTERVAL; |
685 | zone_publish_time_window = DEFAULT_ZONE_PUBLISH_TIME_WINDOW; | 610 | zone_publish_time_window = DEFAULT_ZONE_PUBLISH_TIME_WINDOW; |
686 | 611 | ||
@@ -734,7 +659,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
734 | } | 659 | } |
735 | 660 | ||
736 | if (GNUNET_SYSERR == | 661 | if (GNUNET_SYSERR == |
737 | gns_resolver_init (namestore_handle, dht_handle, zone_hash, c, | 662 | GNS_resolver_init (namestore_handle, dht_handle, |
663 | c, | ||
738 | max_parallel_bg_queries, | 664 | max_parallel_bg_queries, |
739 | ignore_pending)) | 665 | ignore_pending)) |
740 | { | 666 | { |
@@ -744,31 +670,45 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
744 | return; | 670 | return; |
745 | } | 671 | } |
746 | 672 | ||
747 | if (GNUNET_YES == | 673 | if (GNUNET_OK == |
748 | GNUNET_CONFIGURATION_get_value_yesno (c, "gns", "HIJACK_DNS")) | 674 | GNUNET_CONFIGURATION_get_value_string (c, "gns", "DNS_ROOT", |
675 | &dns_root_name)) | ||
749 | { | 676 | { |
677 | if (GNUNET_OK != | ||
678 | GNUNET_CRYPTO_ecc_public_key_from_string (dns_root_name, | ||
679 | strlen (dns_root_name), | ||
680 | &dns_root)) | ||
681 | { | ||
682 | GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, | ||
683 | "gns", "DNS_ROOT", | ||
684 | _("valid public key required")); | ||
685 | GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); | ||
686 | GNUNET_free (dns_root_name); | ||
687 | return; | ||
688 | } | ||
750 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 689 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
751 | "DNS hijacking enabled. Connecting to DNS service.\n"); | 690 | "DNS hijacking with root `%s' enabled. Connecting to DNS service.\n", |
752 | 691 | dns_root_name); | |
692 | GNUNET_free (dns_root_name); | ||
753 | if (GNUNET_SYSERR == | 693 | if (GNUNET_SYSERR == |
754 | gns_interceptor_init (zone_hash, zone_key, c)) | 694 | GNS_interceptor_init (&dns_root, c)) |
755 | { | 695 | { |
756 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | 696 | GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); |
757 | "Failed to enable the DNS interceptor!\n"); | 697 | return; |
758 | } | 698 | } |
759 | } | 699 | } |
700 | /* FIXME: install client disconnect handle to clean up pending | ||
701 | lookups on client disconnect! */ | ||
760 | 702 | ||
761 | /** | 703 | /* Schedule periodic put for our records. */ |
762 | * Schedule periodic put for our records We have roughly an hour for | ||
763 | * all records; | ||
764 | */ | ||
765 | first_zone_iteration = GNUNET_YES; | 704 | first_zone_iteration = GNUNET_YES; |
766 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start, NULL); | ||
767 | GNUNET_SERVER_add_handlers (server, handlers); | 705 | GNUNET_SERVER_add_handlers (server, handlers); |
768 | statistics = GNUNET_STATISTICS_create ("gns", c); | 706 | statistics = GNUNET_STATISTICS_create ("gns", c); |
769 | nc = GNUNET_SERVER_notification_context_create (server, 1); | 707 | nc = GNUNET_SERVER_notification_context_create (server, 1); |
770 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, | 708 | zone_publish_task = GNUNET_SCHEDULER_add_now (&publish_zone_dht_start, |
771 | NULL); | 709 | NULL); |
710 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | ||
711 | &shutdown_task, NULL); | ||
772 | } | 712 | } |
773 | 713 | ||
774 | 714 | ||