aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorng0 <ng0@n0.is>2019-04-25 22:30:04 +0000
committerng0 <ng0@n0.is>2019-04-25 22:30:04 +0000
commita097690795f4f814de7cdbc97ef95fb899eeacd3 (patch)
tree0d5a4a652a93201099aa45a2325849b6459eef3a
parentd039e80999f8df49d7b683e60af4145aacd18f83 (diff)
parent1a94233aed0b6f195c1c9cb8827d7fd5ae9b8b30 (diff)
downloadgnunet-a097690795f4f814de7cdbc97ef95fb899eeacd3.tar.gz
gnunet-a097690795f4f814de7cdbc97ef95fb899eeacd3.zip
Merge branch 'master' of gnunet.org:gnunet
-rw-r--r--src/identity/Makefile.am5
-rw-r--r--src/identity/plugin_rest_identity.c9
-rw-r--r--src/include/gnunet_peerstore_service.h8
-rw-r--r--src/json/json_gnsrecord.c48
-rw-r--r--src/namestore/plugin_rest_namestore.c414
-rw-r--r--src/transport/gnunet-service-tng.c495
6 files changed, 611 insertions, 368 deletions
diff --git a/src/identity/Makefile.am b/src/identity/Makefile.am
index 5c1af8e19..b4e62f595 100644
--- a/src/identity/Makefile.am
+++ b/src/identity/Makefile.am
@@ -14,7 +14,7 @@ endif
14 14
15if HAVE_MHD 15if HAVE_MHD
16if HAVE_JSON 16if HAVE_JSON
17REST_PLUGIN = libgnunet_plugin_rest_identity.la 17plugin_LTLIBRARIES = libgnunet_plugin_rest_identity.la
18endif 18endif
19endif 19endif
20 20
@@ -26,8 +26,7 @@ pkgcfg_DATA = \
26 identity.conf 26 identity.conf
27 27
28lib_LTLIBRARIES = \ 28lib_LTLIBRARIES = \
29 libgnunetidentity.la \ 29 libgnunetidentity.la
30 $(REST_PLUGIN)
31 30
32 31
33libgnunet_plugin_rest_identity_la_SOURCES = \ 32libgnunet_plugin_rest_identity_la_SOURCES = \
diff --git a/src/identity/plugin_rest_identity.c b/src/identity/plugin_rest_identity.c
index 3bfca3121..89f590d3e 100644
--- a/src/identity/plugin_rest_identity.c
+++ b/src/identity/plugin_rest_identity.c
@@ -490,15 +490,6 @@ ego_get_all (struct GNUNET_REST_RequestHandle *con_handle,
490 json_decref (json_ego); 490 json_decref (json_ego);
491 } 491 }
492 492
493 if ((size_t) 0 == json_array_size (json_root))
494 {
495 json_decref (json_root);
496 handle->response_code = MHD_HTTP_NOT_FOUND;
497 handle->emsg = GNUNET_strdup(GNUNET_REST_IDENTITY_NOT_FOUND);
498 GNUNET_SCHEDULER_add_now (&do_error, handle);
499 return;
500 }
501
502 result_str = json_dumps (json_root, 0); 493 result_str = json_dumps (json_root, 0);
503 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); 494 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
504 resp = GNUNET_REST_create_response (result_str); 495 resp = GNUNET_REST_create_response (result_str);
diff --git a/src/include/gnunet_peerstore_service.h b/src/include/gnunet_peerstore_service.h
index b20c1f3c7..ad80a3fa3 100644
--- a/src/include/gnunet_peerstore_service.h
+++ b/src/include/gnunet_peerstore_service.h
@@ -61,6 +61,14 @@ extern "C" {
61 "transport-backchannel-monotonic-time" 61 "transport-backchannel-monotonic-time"
62 62
63/** 63/**
64 * Key used to store sender's monotonic time from DV learn
65 * messages.
66 */
67#define GNUNET_PEERSTORE_TRANSPORT_DVLEARN_MONOTIME \
68 "transport-dv-learn-monotonic-time"
69
70
71/**
64 * Options for storing values in PEERSTORE 72 * Options for storing values in PEERSTORE
65 */ 73 */
66enum GNUNET_PEERSTORE_StoreOption 74enum GNUNET_PEERSTORE_StoreOption
diff --git a/src/json/json_gnsrecord.c b/src/json/json_gnsrecord.c
index 83ea367d5..cbdc0ff91 100644
--- a/src/json/json_gnsrecord.c
+++ b/src/json/json_gnsrecord.c
@@ -45,11 +45,12 @@
45 */ 45 */
46static int 46static int
47parse_gnsrecordobject (void *cls, 47parse_gnsrecordobject (void *cls,
48 json_t *root, 48 json_t *root,
49 struct GNUNET_JSON_Specification *spec) 49 struct GNUNET_JSON_Specification *spec)
50{ 50{
51 struct GNUNET_GNSRECORD_Data *gnsrecord_object; 51 struct GNUNET_GNSRECORD_Data *gnsrecord_object;
52 struct GNUNET_TIME_Absolute abs_expiration_time; 52 struct GNUNET_TIME_Absolute abs_expiration_time;
53 struct GNUNET_TIME_Relative rel_expiration_time;
53 int unpack_state=0; 54 int unpack_state=0;
54 const char *value; 55 const char *value;
55 const char *expiration_time; 56 const char *expiration_time;
@@ -63,21 +64,21 @@ parse_gnsrecordobject (void *cls,
63 if(!json_is_object(root)) 64 if(!json_is_object(root))
64 { 65 {
65 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 66 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
66 "Error json is not array nor object!\n"); 67 "Error json is not array nor object!\n");
67 return GNUNET_SYSERR; 68 return GNUNET_SYSERR;
68 } 69 }
69 //interpret single gns record 70 //interpret single gns record
70 unpack_state = json_unpack(root, 71 unpack_state = json_unpack(root,
71 "{s:s, s:s, s:s, s?:i, s:s!}", 72 "{s:s, s:s, s:s, s?:i, s:s!}",
72 GNUNET_JSON_GNSRECORD_VALUE, &value, 73 GNUNET_JSON_GNSRECORD_VALUE, &value,
73 GNUNET_JSON_GNSRECORD_TYPE, &record_type, 74 GNUNET_JSON_GNSRECORD_TYPE, &record_type,
74 GNUNET_JSON_GNSRECORD_EXPIRATION_TIME, &expiration_time, 75 GNUNET_JSON_GNSRECORD_EXPIRATION_TIME, &expiration_time,
75 GNUNET_JSON_GNSRECORD_FLAG, &flag, 76 GNUNET_JSON_GNSRECORD_FLAG, &flag,
76 GNUNET_JSON_GNSRECORD_RECORD_NAME, &name); 77 GNUNET_JSON_GNSRECORD_RECORD_NAME, &name);
77 if (0 != unpack_state) 78 if (0 != unpack_state)
78 { 79 {
79 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 80 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
80 "Error json object has a wrong format!\n"); 81 "Error json object has a wrong format!\n");
81 return GNUNET_SYSERR; 82 return GNUNET_SYSERR;
82 } 83 }
83 gnsrecord_object = GNUNET_new (struct GNUNET_GNSRECORD_Data); 84 gnsrecord_object = GNUNET_new (struct GNUNET_GNSRECORD_Data);
@@ -90,9 +91,9 @@ parse_gnsrecordobject (void *cls,
90 } 91 }
91 if (GNUNET_OK 92 if (GNUNET_OK
92 != GNUNET_GNSRECORD_string_to_value (gnsrecord_object->record_type, 93 != GNUNET_GNSRECORD_string_to_value (gnsrecord_object->record_type,
93 value, 94 value,
94 &rdata, 95 &rdata,
95 &rdata_size)) 96 &rdata_size))
96 { 97 {
97 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Value invalid for record type\n"); 98 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,"Value invalid for record type\n");
98 GNUNET_free(gnsrecord_object); 99 GNUNET_free(gnsrecord_object);
@@ -107,25 +108,20 @@ parse_gnsrecordobject (void *cls,
107 gnsrecord_object->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us; 108 gnsrecord_object->expiration_time = GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us;
108 } 109 }
109 else if (GNUNET_OK 110 else if (GNUNET_OK
110 == GNUNET_STRINGS_fancy_time_to_absolute (expiration_time, 111 == GNUNET_STRINGS_fancy_time_to_absolute (expiration_time,
111 &abs_expiration_time)) 112 &abs_expiration_time))
112 { 113 {
113 gnsrecord_object->expiration_time = abs_expiration_time.abs_value_us; 114 gnsrecord_object->expiration_time = abs_expiration_time.abs_value_us;
114 } 115 }
115 else 116 else if (GNUNET_OK
117 == GNUNET_STRINGS_fancy_time_to_relative (expiration_time,
118 &rel_expiration_time))
116 { 119 {
117 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Expiration time invalid\n"); 120 gnsrecord_object->expiration_time = rel_expiration_time.rel_value_us;
118 GNUNET_free_non_null(rdata);
119 GNUNET_free(gnsrecord_object);
120 return GNUNET_SYSERR;
121 } 121 }
122 // check if flag is a valid enum value 122 else
123 if ((GNUNET_GNSRECORD_RF_NONE != flag)
124 && (GNUNET_GNSRECORD_RF_PRIVATE != flag)
125 && (GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION != flag)
126 && (GNUNET_GNSRECORD_RF_SHADOW_RECORD) != flag)
127 { 123 {
128 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Flag invalid\n"); 124 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Expiration time invalid\n");
129 GNUNET_free_non_null(rdata); 125 GNUNET_free_non_null(rdata);
130 GNUNET_free(gnsrecord_object); 126 GNUNET_free(gnsrecord_object);
131 return GNUNET_SYSERR; 127 return GNUNET_SYSERR;
diff --git a/src/namestore/plugin_rest_namestore.c b/src/namestore/plugin_rest_namestore.c
index 26a037eae..46e5a590f 100644
--- a/src/namestore/plugin_rest_namestore.c
+++ b/src/namestore/plugin_rest_namestore.c
@@ -86,7 +86,7 @@ const struct GNUNET_CONFIGURATION_Handle *cfg;
86/** 86/**
87 * HTTP methods allows for this plugin 87 * HTTP methods allows for this plugin
88 */ 88 */
89static char* allow_methods; 89static char *allow_methods;
90 90
91/** 91/**
92 * @brief struct returned by the initialization function of the plugin 92 * @brief struct returned by the initialization function of the plugin
@@ -201,7 +201,7 @@ struct RequestHandle
201 * Rest connection 201 * Rest connection
202 */ 202 */
203 struct GNUNET_REST_RequestHandle *rest_handle; 203 struct GNUNET_REST_RequestHandle *rest_handle;
204 204
205 /** 205 /**
206 * Desired timeout for the lookup (default is no timeout). 206 * Desired timeout for the lookup (default is no timeout).
207 */ 207 */
@@ -236,7 +236,6 @@ struct RequestHandle
236 * Response code 236 * Response code
237 */ 237 */
238 int response_code; 238 int response_code;
239
240}; 239};
241 240
242/** 241/**
@@ -250,51 +249,49 @@ cleanup_handle (void *cls)
250 struct EgoEntry *ego_entry; 249 struct EgoEntry *ego_entry;
251 struct EgoEntry *ego_tmp; 250 struct EgoEntry *ego_tmp;
252 251
253 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 252 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
254 "Cleaning up\n");
255 if (NULL != handle->timeout_task) 253 if (NULL != handle->timeout_task)
256 { 254 {
257 GNUNET_SCHEDULER_cancel (handle->timeout_task); 255 GNUNET_SCHEDULER_cancel (handle->timeout_task);
258 handle->timeout_task = NULL; 256 handle->timeout_task = NULL;
259 } 257 }
260 if (NULL != handle->record_name) 258 if (NULL != handle->record_name)
261 GNUNET_free(handle->record_name); 259 GNUNET_free (handle->record_name);
262 if (NULL != handle->url) 260 if (NULL != handle->url)
263 GNUNET_free(handle->url); 261 GNUNET_free (handle->url);
264 if (NULL != handle->emsg) 262 if (NULL != handle->emsg)
265 GNUNET_free(handle->emsg); 263 GNUNET_free (handle->emsg);
266 if (NULL != handle->rd) 264 if (NULL != handle->rd)
267 { 265 {
268 if (NULL != handle->rd->data) 266 if (NULL != handle->rd->data)
269 GNUNET_free((void*)handle->rd->data); 267 GNUNET_free ((void *) handle->rd->data);
270 GNUNET_free(handle->rd); 268 GNUNET_free (handle->rd);
271 } 269 }
272 if (NULL != handle->timeout_task) 270 if (NULL != handle->timeout_task)
273 GNUNET_SCHEDULER_cancel(handle->timeout_task); 271 GNUNET_SCHEDULER_cancel (handle->timeout_task);
274 if (NULL != handle->list_it) 272 if (NULL != handle->list_it)
275 GNUNET_NAMESTORE_zone_iteration_stop(handle->list_it); 273 GNUNET_NAMESTORE_zone_iteration_stop (handle->list_it);
276 if (NULL != handle->add_qe) 274 if (NULL != handle->add_qe)
277 GNUNET_NAMESTORE_cancel(handle->add_qe); 275 GNUNET_NAMESTORE_cancel (handle->add_qe);
278 if (NULL != handle->identity_handle) 276 if (NULL != handle->identity_handle)
279 GNUNET_IDENTITY_disconnect(handle->identity_handle); 277 GNUNET_IDENTITY_disconnect (handle->identity_handle);
280 if (NULL != handle->ns_handle) 278 if (NULL != handle->ns_handle)
281 { 279 {
282 GNUNET_NAMESTORE_disconnect(handle->ns_handle); 280 GNUNET_NAMESTORE_disconnect (handle->ns_handle);
283 } 281 }
284 282
285 for (ego_entry = handle->ego_head; 283 for (ego_entry = handle->ego_head; NULL != ego_entry;)
286 NULL != ego_entry;)
287 { 284 {
288 ego_tmp = ego_entry; 285 ego_tmp = ego_entry;
289 ego_entry = ego_entry->next; 286 ego_entry = ego_entry->next;
290 GNUNET_free(ego_tmp->identifier); 287 GNUNET_free (ego_tmp->identifier);
291 GNUNET_free(ego_tmp->keystring); 288 GNUNET_free (ego_tmp->keystring);
292 GNUNET_free(ego_tmp); 289 GNUNET_free (ego_tmp);
293 } 290 }
294 291
295 if(NULL != handle->resp_object) 292 if (NULL != handle->resp_object)
296 { 293 {
297 json_decref(handle->resp_object); 294 json_decref (handle->resp_object);
298 } 295 }
299 296
300 GNUNET_free (handle); 297 GNUNET_free (handle);
@@ -311,21 +308,21 @@ do_error (void *cls)
311{ 308{
312 struct RequestHandle *handle = cls; 309 struct RequestHandle *handle = cls;
313 struct MHD_Response *resp; 310 struct MHD_Response *resp;
314 json_t *json_error = json_object(); 311 json_t *json_error = json_object ();
315 char *response; 312 char *response;
316 313
317 if (NULL == handle->emsg) 314 if (NULL == handle->emsg)
318 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_ERROR_UNKNOWN); 315 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_ERROR_UNKNOWN);
319 316
320 json_object_set_new(json_error,"error", json_string(handle->emsg)); 317 json_object_set_new (json_error, "error", json_string (handle->emsg));
321 318
322 if (0 == handle->response_code) 319 if (0 == handle->response_code)
323 handle->response_code = MHD_HTTP_OK; 320 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
324 response = json_dumps (json_error, 0); 321 response = json_dumps (json_error, 0);
325 resp = GNUNET_REST_create_response (response); 322 resp = GNUNET_REST_create_response (response);
326 handle->proc (handle->proc_cls, resp, handle->response_code); 323 handle->proc (handle->proc_cls, resp, handle->response_code);
327 json_decref(json_error); 324 json_decref (json_error);
328 GNUNET_free(response); 325 GNUNET_free (response);
329 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); 326 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
330} 327}
331 328
@@ -339,18 +336,17 @@ do_error (void *cls)
339 * @param name the name of an identity (only one can be NULL) 336 * @param name the name of an identity (only one can be NULL)
340 * @return EgoEntry or NULL if not found 337 * @return EgoEntry or NULL if not found
341 */ 338 */
342struct EgoEntry* 339struct EgoEntry *
343get_egoentry_namestore(struct RequestHandle *handle, char *name) 340get_egoentry_namestore (struct RequestHandle *handle, char *name)
344{ 341{
345 struct EgoEntry *ego_entry; 342 struct EgoEntry *ego_entry;
346 if (NULL != name) 343 if (NULL != name)
347 { 344 {
348 for (ego_entry = handle->ego_head; 345 for (ego_entry = handle->ego_head; NULL != ego_entry;
349 NULL != ego_entry; 346 ego_entry = ego_entry->next)
350 ego_entry = ego_entry->next)
351 { 347 {
352 if (0 != strcasecmp (name, ego_entry->identifier)) 348 if (0 != strcasecmp (name, ego_entry->identifier))
353 continue; 349 continue;
354 return ego_entry; 350 return ego_entry;
355 } 351 }
356 } 352 }
@@ -367,7 +363,7 @@ static void
367namestore_iteration_error (void *cls) 363namestore_iteration_error (void *cls)
368{ 364{
369 struct RequestHandle *handle = cls; 365 struct RequestHandle *handle = cls;
370 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_FAILED); 366 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_FAILED);
371 GNUNET_SCHEDULER_add_now (&do_error, handle); 367 GNUNET_SCHEDULER_add_now (&do_error, handle);
372 return; 368 return;
373} 369}
@@ -391,11 +387,11 @@ create_finished (void *cls, int32_t success, const char *emsg)
391 { 387 {
392 if (NULL != emsg) 388 if (NULL != emsg)
393 { 389 {
394 handle->emsg = GNUNET_strdup(emsg); 390 handle->emsg = GNUNET_strdup (emsg);
395 GNUNET_SCHEDULER_add_now (&do_error, handle); 391 GNUNET_SCHEDULER_add_now (&do_error, handle);
396 return; 392 return;
397 } 393 }
398 handle->emsg = GNUNET_strdup("Error storing records"); 394 handle->emsg = GNUNET_strdup ("Error storing records");
399 GNUNET_SCHEDULER_add_now (&do_error, handle); 395 GNUNET_SCHEDULER_add_now (&do_error, handle);
400 return; 396 return;
401 } 397 }
@@ -421,7 +417,7 @@ del_finished (void *cls, int32_t success, const char *emsg)
421 if (GNUNET_NO == success) 417 if (GNUNET_NO == success)
422 { 418 {
423 handle->response_code = MHD_HTTP_NOT_FOUND; 419 handle->response_code = MHD_HTTP_NOT_FOUND;
424 handle->emsg = GNUNET_strdup("No record found"); 420 handle->emsg = GNUNET_strdup ("No record found");
425 GNUNET_SCHEDULER_add_now (&do_error, handle); 421 GNUNET_SCHEDULER_add_now (&do_error, handle);
426 return; 422 return;
427 } 423 }
@@ -429,11 +425,11 @@ del_finished (void *cls, int32_t success, const char *emsg)
429 { 425 {
430 if (NULL != emsg) 426 if (NULL != emsg)
431 { 427 {
432 handle->emsg = GNUNET_strdup(emsg); 428 handle->emsg = GNUNET_strdup (emsg);
433 GNUNET_SCHEDULER_add_now (&do_error, handle); 429 GNUNET_SCHEDULER_add_now (&do_error, handle);
434 return; 430 return;
435 } 431 }
436 handle->emsg = GNUNET_strdup("Deleting record failed"); 432 handle->emsg = GNUNET_strdup ("Deleting record failed");
437 GNUNET_SCHEDULER_add_now (&do_error, handle); 433 GNUNET_SCHEDULER_add_now (&do_error, handle);
438 return; 434 return;
439 } 435 }
@@ -460,10 +456,10 @@ namestore_list_finished (void *cls)
460 handle->list_it = NULL; 456 handle->list_it = NULL;
461 457
462 if (NULL == handle->resp_object) 458 if (NULL == handle->resp_object)
463 handle->resp_object = json_array(); 459 handle->resp_object = json_array ();
464 460
465 result_str = json_dumps (handle->resp_object, 0); 461 result_str = json_dumps (handle->resp_object, 0);
466 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); 462 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
467 resp = GNUNET_REST_create_response (result_str); 463 resp = GNUNET_REST_create_response (result_str);
468 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 464 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
469 GNUNET_free_non_null (result_str); 465 GNUNET_free_non_null (result_str);
@@ -478,26 +474,26 @@ namestore_list_finished (void *cls)
478 */ 474 */
479static void 475static void
480namestore_list_iteration (void *cls, 476namestore_list_iteration (void *cls,
481 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, 477 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
482 const char *rname, 478 const char *rname,
483 unsigned int rd_len, 479 unsigned int rd_len,
484 const struct GNUNET_GNSRECORD_Data *rd) 480 const struct GNUNET_GNSRECORD_Data *rd)
485{ 481{
486 struct RequestHandle *handle = cls; 482 struct RequestHandle *handle = cls;
487 json_t *record_obj; 483 json_t *record_obj;
488 484
489 if (NULL == handle->resp_object) 485 if (NULL == handle->resp_object)
490 handle->resp_object = json_array(); 486 handle->resp_object = json_array ();
491 487
492 for (unsigned int i = 0; i < rd_len; i++) 488 for (unsigned int i = 0; i < rd_len; i++)
493 { 489 {
494 if ( (GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) && 490 if ((GNUNET_GNSRECORD_TYPE_NICK == rd[i].record_type) &&
495 (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT)) ) 491 (0 != strcmp (rname, GNUNET_GNS_EMPTY_LABEL_AT)))
496 continue; 492 continue;
497 493
498 record_obj = GNUNET_JSON_from_gns_record(rname,rd); 494 record_obj = GNUNET_JSON_from_gns_record (rname, &rd[i]);
499 495
500 if(NULL == record_obj) 496 if (NULL == record_obj)
501 continue; 497 continue;
502 498
503 json_array_append (handle->resp_object, record_obj); 499 json_array_append (handle->resp_object, record_obj);
@@ -518,32 +514,33 @@ namestore_list_iteration (void *cls,
518 */ 514 */
519static void 515static void
520default_ego_get (void *cls, 516default_ego_get (void *cls,
521 struct GNUNET_IDENTITY_Ego *ego, 517 struct GNUNET_IDENTITY_Ego *ego,
522 void **ctx, 518 void **ctx,
523 const char *identifier) 519 const char *identifier)
524{ 520{
525 struct RequestHandle *handle = cls; 521 struct RequestHandle *handle = cls;
526 handle->op = NULL; 522 handle->op = NULL;
527 523
528 if (ego == NULL) 524 if (ego == NULL)
529 { 525 {
530 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_NO_DEFAULT_ZONE); 526 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_NO_DEFAULT_ZONE);
531 GNUNET_SCHEDULER_add_now (&do_error, handle); 527 GNUNET_SCHEDULER_add_now (&do_error, handle);
532 return; 528 return;
533 } 529 }
534 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego); 530 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego);
535 531
536 handle->list_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, 532 handle->list_it =
537 handle->zone_pkey, 533 GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle,
538 &namestore_iteration_error, 534 handle->zone_pkey,
539 handle, 535 &namestore_iteration_error,
540 &namestore_list_iteration, 536 handle,
541 handle, 537 &namestore_list_iteration,
542 &namestore_list_finished, 538 handle,
543 handle); 539 &namestore_list_finished,
540 handle);
544 if (NULL == handle->list_it) 541 if (NULL == handle->list_it)
545 { 542 {
546 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_FAILED); 543 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_FAILED);
547 GNUNET_SCHEDULER_add_now (&do_error, handle); 544 GNUNET_SCHEDULER_add_now (&do_error, handle);
548 return; 545 return;
549 } 546 }
@@ -559,8 +556,8 @@ default_ego_get (void *cls,
559 */ 556 */
560void 557void
561namestore_get (struct GNUNET_REST_RequestHandle *con_handle, 558namestore_get (struct GNUNET_REST_RequestHandle *con_handle,
562 const char* url, 559 const char *url,
563 void *cls) 560 void *cls)
564{ 561{
565 struct RequestHandle *handle = cls; 562 struct RequestHandle *handle = cls;
566 struct EgoEntry *ego_entry; 563 struct EgoEntry *ego_entry;
@@ -569,44 +566,45 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle,
569 egoname = NULL; 566 egoname = NULL;
570 ego_entry = NULL; 567 ego_entry = NULL;
571 568
572 //set zone to name if given 569 // set zone to name if given
573 if (strlen (GNUNET_REST_API_NS_NAMESTORE) < strlen (handle->url)) 570 if (strlen (GNUNET_REST_API_NS_NAMESTORE) < strlen (handle->url))
574 { 571 {
575 egoname = &handle->url[strlen (GNUNET_REST_API_NS_NAMESTORE)+1]; 572 egoname = &handle->url[strlen (GNUNET_REST_API_NS_NAMESTORE) + 1];
576 ego_entry = get_egoentry_namestore(handle, egoname); 573 ego_entry = get_egoentry_namestore (handle, egoname);
577 574
578 if (NULL == ego_entry) 575 if (NULL == ego_entry)
579 { 576 {
580 handle->response_code = MHD_HTTP_NOT_FOUND; 577 handle->response_code = MHD_HTTP_NOT_FOUND;
581 handle->emsg = GNUNET_strdup(GNUNET_REST_IDENTITY_NOT_FOUND); 578 handle->emsg = GNUNET_strdup (GNUNET_REST_IDENTITY_NOT_FOUND);
582 GNUNET_SCHEDULER_add_now (&do_error, handle); 579 GNUNET_SCHEDULER_add_now (&do_error, handle);
583 return; 580 return;
584 } 581 }
585 } 582 }
586 if ( NULL != ego_entry ) 583 if (NULL != ego_entry)
587 { 584 {
588 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego); 585 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
589 } 586 }
590 587
591 if (NULL == handle->zone_pkey) 588 if (NULL == handle->zone_pkey)
592 { 589 {
593 handle->op = GNUNET_IDENTITY_get (handle->identity_handle, 590 handle->op = GNUNET_IDENTITY_get (handle->identity_handle,
594 "namestore", 591 "namestore",
595 &default_ego_get, 592 &default_ego_get,
596 handle); 593 handle);
597 return; 594 return;
598 } 595 }
599 handle->list_it = GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle, 596 handle->list_it =
600 handle->zone_pkey, 597 GNUNET_NAMESTORE_zone_iteration_start (handle->ns_handle,
601 &namestore_iteration_error, 598 handle->zone_pkey,
602 handle, 599 &namestore_iteration_error,
603 &namestore_list_iteration, 600 handle,
604 handle, 601 &namestore_list_iteration,
605 &namestore_list_finished, 602 handle,
606 handle); 603 &namestore_list_finished,
604 handle);
607 if (NULL == handle->list_it) 605 if (NULL == handle->list_it)
608 { 606 {
609 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_FAILED); 607 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_FAILED);
610 GNUNET_SCHEDULER_add_now (&do_error, handle); 608 GNUNET_SCHEDULER_add_now (&do_error, handle);
611 return; 609 return;
612 } 610 }
@@ -624,31 +622,68 @@ namestore_get (struct GNUNET_REST_RequestHandle *con_handle,
624 */ 622 */
625static void 623static void
626default_ego_post (void *cls, 624default_ego_post (void *cls,
627 struct GNUNET_IDENTITY_Ego *ego, 625 struct GNUNET_IDENTITY_Ego *ego,
628 void **ctx, 626 void **ctx,
629 const char *identifier) 627 const char *identifier)
630{ 628{
631 struct RequestHandle *handle = cls; 629 struct RequestHandle *handle = cls;
632 handle->op = NULL; 630 handle->op = NULL;
633 631
634 if (ego == NULL) 632 if (ego == NULL)
635 { 633 {
636 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_NO_DEFAULT_ZONE); 634 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_NO_DEFAULT_ZONE);
637 GNUNET_SCHEDULER_add_now (&do_error, handle); 635 GNUNET_SCHEDULER_add_now (&do_error, handle);
638 return; 636 return;
639 } 637 }
640 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego); 638 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego);
641 639
642 handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, 640 handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle,
643 handle->zone_pkey, 641 handle->zone_pkey,
644 handle->record_name, 642 handle->record_name,
645 1, 643 1,
646 handle->rd, 644 handle->rd,
647 &create_finished, 645 &create_finished,
648 handle); 646 handle);
647 if (NULL == handle->add_qe)
648 {
649 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_FAILED);
650 GNUNET_SCHEDULER_add_now (&do_error, handle);
651 return;
652 }
653}
654
655
656static void
657ns_lookup_error_cb (void *cls)
658{
659 struct RequestHandle *handle = cls;
660 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_FAILED);
661 GNUNET_SCHEDULER_add_now (&do_error, handle);
662}
663
664
665static void
666ns_lookup_cb (void *cls,
667 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
668 const char *label,
669 unsigned int rd_count,
670 const struct GNUNET_GNSRECORD_Data *rd)
671{
672 struct RequestHandle *handle = cls;
673 struct GNUNET_GNSRECORD_Data rd_new[rd_count + 1];
674 for (int i = 0; i < rd_count; i++)
675 rd_new[i] = rd[i];
676 rd_new[rd_count] = *handle->rd;
677 handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle,
678 handle->zone_pkey,
679 handle->record_name,
680 rd_count + 1,
681 rd_new,
682 &create_finished,
683 handle);
649 if (NULL == handle->add_qe) 684 if (NULL == handle->add_qe)
650 { 685 {
651 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_FAILED); 686 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_FAILED);
652 GNUNET_SCHEDULER_add_now (&do_error, handle); 687 GNUNET_SCHEDULER_add_now (&do_error, handle);
653 return; 688 return;
654 } 689 }
@@ -664,8 +699,8 @@ default_ego_post (void *cls,
664 */ 699 */
665void 700void
666namestore_add (struct GNUNET_REST_RequestHandle *con_handle, 701namestore_add (struct GNUNET_REST_RequestHandle *con_handle,
667 const char* url, 702 const char *url,
668 void *cls) 703 void *cls)
669{ 704{
670 struct RequestHandle *handle = cls; 705 struct RequestHandle *handle = cls;
671 struct GNUNET_GNSRECORD_Data *gns_record; 706 struct GNUNET_GNSRECORD_Data *gns_record;
@@ -676,50 +711,49 @@ namestore_add (struct GNUNET_REST_RequestHandle *con_handle,
676 json_error_t err; 711 json_error_t err;
677 char term_data[handle->rest_handle->data_size + 1]; 712 char term_data[handle->rest_handle->data_size + 1];
678 713
679 struct GNUNET_JSON_Specification gnsspec[] = { 714 struct GNUNET_JSON_Specification gnsspec[] =
680 GNUNET_JSON_spec_gnsrecord_data(&gns_record), 715 {GNUNET_JSON_spec_gnsrecord_data (&gns_record), GNUNET_JSON_spec_end ()};
681 GNUNET_JSON_spec_end ()
682 };
683 716
684 if (0 >= handle->rest_handle->data_size) 717 if (0 >= handle->rest_handle->data_size)
685 { 718 {
686 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_NO_DATA); 719 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_NO_DATA);
687 GNUNET_SCHEDULER_add_now (&do_error, handle); 720 GNUNET_SCHEDULER_add_now (&do_error, handle);
688 return; 721 return;
689 } 722 }
690 term_data[handle->rest_handle->data_size] = '\0'; 723 term_data[handle->rest_handle->data_size] = '\0';
691 GNUNET_memcpy(term_data, handle->rest_handle->data, 724 GNUNET_memcpy (term_data,
692 handle->rest_handle->data_size); 725 handle->rest_handle->data,
726 handle->rest_handle->data_size);
693 data_js = json_loads (term_data, JSON_DECODE_ANY, &err); 727 data_js = json_loads (term_data, JSON_DECODE_ANY, &err);
694 if (GNUNET_OK != GNUNET_JSON_parse (data_js, gnsspec, NULL, NULL)) 728 if (GNUNET_OK != GNUNET_JSON_parse (data_js, gnsspec, NULL, NULL))
695 { 729 {
696 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_INVALID_DATA); 730 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_INVALID_DATA);
697 GNUNET_SCHEDULER_add_now (&do_error, handle); 731 GNUNET_SCHEDULER_add_now (&do_error, handle);
698 GNUNET_JSON_parse_free(gnsspec); 732 GNUNET_JSON_parse_free (gnsspec);
699 json_decref (data_js); 733 json_decref (data_js);
700 return; 734 return;
701 } 735 }
702 handle->rd = gns_record; 736 handle->rd = gns_record;
703 737
704 name_json = json_object_get(data_js, "record_name"); 738 name_json = json_object_get (data_js, "record_name");
705 if (!json_is_string(name_json)) 739 if (! json_is_string (name_json))
706 { 740 {
707 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_INVALID_DATA); 741 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_INVALID_DATA);
708 GNUNET_SCHEDULER_add_now (&do_error, handle); 742 GNUNET_SCHEDULER_add_now (&do_error, handle);
709 json_decref (data_js); 743 json_decref (data_js);
710 return; 744 return;
711 } 745 }
712 handle->record_name = GNUNET_strdup(json_string_value(name_json)); 746 handle->record_name = GNUNET_strdup (json_string_value (name_json));
713 if(NULL == handle->record_name) 747 if (NULL == handle->record_name)
714 { 748 {
715 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_INVALID_DATA); 749 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_INVALID_DATA);
716 GNUNET_SCHEDULER_add_now (&do_error, handle); 750 GNUNET_SCHEDULER_add_now (&do_error, handle);
717 json_decref (data_js); 751 json_decref (data_js);
718 return; 752 return;
719 } 753 }
720 if (0 >= strlen(handle->record_name)) 754 if (0 >= strlen (handle->record_name))
721 { 755 {
722 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_INVALID_DATA); 756 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_INVALID_DATA);
723 GNUNET_SCHEDULER_add_now (&do_error, handle); 757 GNUNET_SCHEDULER_add_now (&do_error, handle);
724 json_decref (data_js); 758 json_decref (data_js);
725 return; 759 return;
@@ -729,42 +763,42 @@ namestore_add (struct GNUNET_REST_RequestHandle *con_handle,
729 egoname = NULL; 763 egoname = NULL;
730 ego_entry = NULL; 764 ego_entry = NULL;
731 765
732 //set zone to name if given 766 // set zone to name if given
733 if (strlen (GNUNET_REST_API_NS_NAMESTORE) < strlen (handle->url)) 767 if (strlen (GNUNET_REST_API_NS_NAMESTORE) < strlen (handle->url))
734 { 768 {
735 egoname = &handle->url[strlen (GNUNET_REST_API_NS_NAMESTORE)+1]; 769 egoname = &handle->url[strlen (GNUNET_REST_API_NS_NAMESTORE) + 1];
736 ego_entry = get_egoentry_namestore(handle, egoname); 770 ego_entry = get_egoentry_namestore (handle, egoname);
737 771
738 if (NULL == ego_entry) 772 if (NULL == ego_entry)
739 { 773 {
740 handle->response_code = MHD_HTTP_NOT_FOUND; 774 handle->response_code = MHD_HTTP_NOT_FOUND;
741 handle->emsg = GNUNET_strdup(GNUNET_REST_IDENTITY_NOT_FOUND); 775 handle->emsg = GNUNET_strdup (GNUNET_REST_IDENTITY_NOT_FOUND);
742 GNUNET_SCHEDULER_add_now (&do_error, handle); 776 GNUNET_SCHEDULER_add_now (&do_error, handle);
743 return; 777 return;
744 } 778 }
745 } 779 }
746 if (NULL != ego_entry) 780 if (NULL != ego_entry)
747 { 781 {
748 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego); 782 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
749 } 783 }
750 if (NULL == handle->zone_pkey) 784 if (NULL == handle->zone_pkey)
751 { 785 {
752 handle->op = GNUNET_IDENTITY_get (handle->identity_handle, 786 handle->op = GNUNET_IDENTITY_get (handle->identity_handle,
753 "namestore", 787 "namestore",
754 &default_ego_post, 788 &default_ego_post,
755 handle); 789 handle);
756 return; 790 return;
757 } 791 }
758 handle->add_qe = GNUNET_NAMESTORE_records_store (handle->ns_handle, 792 handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle,
759 handle->zone_pkey, 793 handle->zone_pkey,
760 handle->record_name, 794 handle->record_name,
761 1, 795 &ns_lookup_error_cb,
762 handle->rd, 796 handle,
763 &create_finished, 797 &ns_lookup_cb,
764 handle); 798 handle);
765 if (NULL == handle->add_qe) 799 if (NULL == handle->add_qe)
766 { 800 {
767 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_FAILED); 801 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_FAILED);
768 GNUNET_SCHEDULER_add_now (&do_error, handle); 802 GNUNET_SCHEDULER_add_now (&do_error, handle);
769 return; 803 return;
770 } 804 }
@@ -782,16 +816,16 @@ namestore_add (struct GNUNET_REST_RequestHandle *con_handle,
782 */ 816 */
783static void 817static void
784default_ego_delete (void *cls, 818default_ego_delete (void *cls,
785 struct GNUNET_IDENTITY_Ego *ego, 819 struct GNUNET_IDENTITY_Ego *ego,
786 void **ctx, 820 void **ctx,
787 const char *identifier) 821 const char *identifier)
788{ 822{
789 struct RequestHandle *handle = cls; 823 struct RequestHandle *handle = cls;
790 handle->op = NULL; 824 handle->op = NULL;
791 825
792 if (ego == NULL) 826 if (ego == NULL)
793 { 827 {
794 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_NO_DEFAULT_ZONE); 828 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_NO_DEFAULT_ZONE);
795 GNUNET_SCHEDULER_add_now (&do_error, handle); 829 GNUNET_SCHEDULER_add_now (&do_error, handle);
796 return; 830 return;
797 } 831 }
@@ -801,12 +835,12 @@ default_ego_delete (void *cls,
801 handle->zone_pkey, 835 handle->zone_pkey,
802 handle->record_name, 836 handle->record_name,
803 0, 837 0,
804 NULL, 838 NULL,
805 &del_finished, 839 &del_finished,
806 handle); 840 handle);
807 if (NULL == handle->add_qe) 841 if (NULL == handle->add_qe)
808 { 842 {
809 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_FAILED); 843 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_FAILED);
810 GNUNET_SCHEDULER_add_now (&do_error, handle); 844 GNUNET_SCHEDULER_add_now (&do_error, handle);
811 return; 845 return;
812 } 846 }
@@ -822,8 +856,8 @@ default_ego_delete (void *cls,
822 */ 856 */
823void 857void
824namestore_delete (struct GNUNET_REST_RequestHandle *con_handle, 858namestore_delete (struct GNUNET_REST_RequestHandle *con_handle,
825 const char* url, 859 const char *url,
826 void *cls) 860 void *cls)
827{ 861{
828 struct RequestHandle *handle = cls; 862 struct RequestHandle *handle = cls;
829 struct GNUNET_HashCode key; 863 struct GNUNET_HashCode key;
@@ -833,43 +867,42 @@ namestore_delete (struct GNUNET_REST_RequestHandle *con_handle,
833 egoname = NULL; 867 egoname = NULL;
834 ego_entry = NULL; 868 ego_entry = NULL;
835 869
836 //set zone to name if given 870 // set zone to name if given
837 if (strlen (GNUNET_REST_API_NS_NAMESTORE) < strlen (handle->url)) 871 if (strlen (GNUNET_REST_API_NS_NAMESTORE) < strlen (handle->url))
838 { 872 {
839 egoname = &handle->url[strlen (GNUNET_REST_API_NS_NAMESTORE)+1]; 873 egoname = &handle->url[strlen (GNUNET_REST_API_NS_NAMESTORE) + 1];
840 ego_entry = get_egoentry_namestore(handle, egoname); 874 ego_entry = get_egoentry_namestore (handle, egoname);
841 875
842 if (NULL == ego_entry) 876 if (NULL == ego_entry)
843 { 877 {
844 handle->response_code = MHD_HTTP_NOT_FOUND; 878 handle->response_code = MHD_HTTP_NOT_FOUND;
845 handle->emsg = GNUNET_strdup(GNUNET_REST_IDENTITY_NOT_FOUND); 879 handle->emsg = GNUNET_strdup (GNUNET_REST_IDENTITY_NOT_FOUND);
846 GNUNET_SCHEDULER_add_now (&do_error, handle); 880 GNUNET_SCHEDULER_add_now (&do_error, handle);
847 return; 881 return;
848 } 882 }
849 } 883 }
850 if ( NULL != ego_entry ) 884 if (NULL != ego_entry)
851 { 885 {
852 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego); 886 handle->zone_pkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
853 } 887 }
854 888
855 GNUNET_CRYPTO_hash ("record_name", strlen ("record_name"), &key); 889 GNUNET_CRYPTO_hash ("record_name", strlen ("record_name"), &key);
856 if ( GNUNET_NO 890 if (GNUNET_NO ==
857 == GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map, 891 GNUNET_CONTAINER_multihashmap_contains (con_handle->url_param_map, &key))
858 &key))
859 { 892 {
860 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_INVALID_DATA); 893 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_INVALID_DATA);
861 GNUNET_SCHEDULER_add_now (&do_error, handle); 894 GNUNET_SCHEDULER_add_now (&do_error, handle);
862 return; 895 return;
863 } 896 }
864 handle->record_name = GNUNET_strdup( 897 handle->record_name = GNUNET_strdup (
865 GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, &key)); 898 GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, &key));
866 899
867 if (NULL == handle->zone_pkey) 900 if (NULL == handle->zone_pkey)
868 { 901 {
869 handle->op = GNUNET_IDENTITY_get (handle->identity_handle, 902 handle->op = GNUNET_IDENTITY_get (handle->identity_handle,
870 "namestore", 903 "namestore",
871 &default_ego_delete, 904 &default_ego_delete,
872 handle); 905 handle);
873 return; 906 return;
874 } 907 }
875 908
@@ -877,19 +910,18 @@ namestore_delete (struct GNUNET_REST_RequestHandle *con_handle,
877 handle->zone_pkey, 910 handle->zone_pkey,
878 handle->record_name, 911 handle->record_name,
879 0, 912 0,
880 NULL, 913 NULL,
881 &del_finished, 914 &del_finished,
882 handle); 915 handle);
883 if (NULL == handle->add_qe) 916 if (NULL == handle->add_qe)
884 { 917 {
885 handle->emsg = GNUNET_strdup(GNUNET_REST_NAMESTORE_FAILED); 918 handle->emsg = GNUNET_strdup (GNUNET_REST_NAMESTORE_FAILED);
886 GNUNET_SCHEDULER_add_now (&do_error, handle); 919 GNUNET_SCHEDULER_add_now (&do_error, handle);
887 return; 920 return;
888 } 921 }
889} 922}
890 923
891 924
892
893/** 925/**
894 * Respond to OPTIONS request 926 * Respond to OPTIONS request
895 * 927 *
@@ -899,17 +931,15 @@ namestore_delete (struct GNUNET_REST_RequestHandle *con_handle,
899 */ 931 */
900static void 932static void
901options_cont (struct GNUNET_REST_RequestHandle *con_handle, 933options_cont (struct GNUNET_REST_RequestHandle *con_handle,
902 const char* url, 934 const char *url,
903 void *cls) 935 void *cls)
904{ 936{
905 struct MHD_Response *resp; 937 struct MHD_Response *resp;
906 struct RequestHandle *handle = cls; 938 struct RequestHandle *handle = cls;
907 939
908 //independent of path return all options 940 // independent of path return all options
909 resp = GNUNET_REST_create_response (NULL); 941 resp = GNUNET_REST_create_response (NULL);
910 MHD_add_response_header (resp, 942 MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
911 "Access-Control-Allow-Methods",
912 allow_methods);
913 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 943 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
914 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); 944 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
915 return; 945 return;
@@ -925,18 +955,15 @@ static void
925init_cont (struct RequestHandle *handle) 955init_cont (struct RequestHandle *handle)
926{ 956{
927 struct GNUNET_REST_RequestHandlerError err; 957 struct GNUNET_REST_RequestHandlerError err;
928 static const struct GNUNET_REST_RequestHandler handlers[] = { 958 static const struct GNUNET_REST_RequestHandler handlers[] =
929 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get}, 959 {{MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_NAMESTORE, &namestore_get},
930 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add}, 960 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_NAMESTORE, &namestore_add},
931 {MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete}, 961 {MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_NAMESTORE, &namestore_delete},
932 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont}, 962 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_NAMESTORE, &options_cont},
933 GNUNET_REST_HANDLER_END 963 GNUNET_REST_HANDLER_END};
934 }; 964
935 965 if (GNUNET_NO ==
936 if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle, 966 GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle))
937 handlers,
938 &err,
939 handle))
940 { 967 {
941 handle->response_code = err.error_code; 968 handle->response_code = err.error_code;
942 GNUNET_SCHEDULER_add_now (&do_error, handle); 969 GNUNET_SCHEDULER_add_now (&do_error, handle);
@@ -988,20 +1015,20 @@ id_connect_cb (void *cls,
988 if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) 1015 if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
989 { 1016 {
990 handle->state = ID_REST_STATE_POST_INIT; 1017 handle->state = ID_REST_STATE_POST_INIT;
991 init_cont(handle); 1018 init_cont (handle);
992 return; 1019 return;
993 } 1020 }
994 if (ID_REST_STATE_INIT == handle->state) 1021 if (ID_REST_STATE_INIT == handle->state)
995 { 1022 {
996 ego_entry = GNUNET_new(struct EgoEntry); 1023 ego_entry = GNUNET_new (struct EgoEntry);
997 GNUNET_IDENTITY_ego_get_public_key (ego, &pk); 1024 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
998 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); 1025 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
999 ego_entry->ego = ego; 1026 ego_entry->ego = ego;
1000 GNUNET_asprintf (&ego_entry->identifier, "%s", name); 1027 GNUNET_asprintf (&ego_entry->identifier, "%s", name);
1001 GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head, handle->ego_tail, 1028 GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head,
1002 ego_entry); 1029 handle->ego_tail,
1030 ego_entry);
1003 } 1031 }
1004
1005} 1032}
1006 1033
1007 1034
@@ -1017,31 +1044,30 @@ id_connect_cb (void *cls,
1017 * @return GNUNET_OK if request accepted 1044 * @return GNUNET_OK if request accepted
1018 */ 1045 */
1019static void 1046static void
1020rest_process_request(struct GNUNET_REST_RequestHandle *rest_handle, 1047rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
1021 GNUNET_REST_ResultProcessor proc, 1048 GNUNET_REST_ResultProcessor proc,
1022 void *proc_cls) 1049 void *proc_cls)
1023{ 1050{
1024 struct RequestHandle *handle = GNUNET_new (struct RequestHandle); 1051 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1025 1052
1026 handle->response_code = 0; 1053 handle->response_code = 0;
1027 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 1054 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1028 handle->proc_cls = proc_cls; 1055 handle->proc_cls = proc_cls;
1029 handle->proc = proc; 1056 handle->proc = proc;
1030 handle->rest_handle = rest_handle; 1057 handle->rest_handle = rest_handle;
1031 handle->zone_pkey = NULL; 1058 handle->zone_pkey = NULL;
1032 1059
1033 handle->url = GNUNET_strdup (rest_handle->url); 1060 handle->url = GNUNET_strdup (rest_handle->url);
1034 if (handle->url[strlen (handle->url)-1] == '/') 1061 if (handle->url[strlen (handle->url) - 1] == '/')
1035 handle->url[strlen (handle->url)-1] = '\0'; 1062 handle->url[strlen (handle->url) - 1] = '\0';
1036 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); 1063 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
1037 1064
1038 handle->ns_handle = GNUNET_NAMESTORE_connect (cfg); 1065 handle->ns_handle = GNUNET_NAMESTORE_connect (cfg);
1039 handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &id_connect_cb, handle); 1066 handle->identity_handle =
1067 GNUNET_IDENTITY_connect (cfg, &id_connect_cb, handle);
1040 handle->timeout_task = 1068 handle->timeout_task =
1041 GNUNET_SCHEDULER_add_delayed (handle->timeout, 1069 GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_error, handle);
1042 &do_error, 1070
1043 handle);
1044
1045 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); 1071 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
1046} 1072}
1047 1073
@@ -1060,7 +1086,7 @@ libgnunet_plugin_rest_namestore_init (void *cls)
1060 1086
1061 cfg = cls; 1087 cfg = cls;
1062 if (NULL != plugin.cfg) 1088 if (NULL != plugin.cfg)
1063 return NULL; /* can only initialize once! */ 1089 return NULL; /* can only initialize once! */
1064 memset (&plugin, 0, sizeof (struct Plugin)); 1090 memset (&plugin, 0, sizeof (struct Plugin));
1065 plugin.cfg = cfg; 1091 plugin.cfg = cfg;
1066 api = GNUNET_new (struct GNUNET_REST_Plugin); 1092 api = GNUNET_new (struct GNUNET_REST_Plugin);
@@ -1075,8 +1101,7 @@ libgnunet_plugin_rest_namestore_init (void *cls)
1075 MHD_HTTP_METHOD_DELETE, 1101 MHD_HTTP_METHOD_DELETE,
1076 MHD_HTTP_METHOD_OPTIONS); 1102 MHD_HTTP_METHOD_OPTIONS);
1077 1103
1078 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1104 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _ ("Namestore REST API initialized\n"));
1079 _("Namestore REST API initialized\n"));
1080 return api; 1105 return api;
1081} 1106}
1082 1107
@@ -1096,8 +1121,7 @@ libgnunet_plugin_rest_namestore_done (void *cls)
1096 1121
1097 GNUNET_free_non_null (allow_methods); 1122 GNUNET_free_non_null (allow_methods);
1098 GNUNET_free (api); 1123 GNUNET_free (api);
1099 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1124 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Namestore REST plugin is finished\n");
1100 "Namestore REST plugin is finished\n");
1101 return NULL; 1125 return NULL;
1102} 1126}
1103 1127
diff --git a/src/transport/gnunet-service-tng.c b/src/transport/gnunet-service-tng.c
index 2f7129478..d3c3defec 100644
--- a/src/transport/gnunet-service-tng.c
+++ b/src/transport/gnunet-service-tng.c
@@ -24,15 +24,7 @@
24 * 24 *
25 * TODO: 25 * TODO:
26 * Implement next: 26 * Implement next:
27 * - FIXME: handle_client_send(): pick DVH path, and box
28 * message accordingly (if applicable, see FIXMEs)
29 * - proper use/initialization of timestamps in messages exchanged
30 * during DV learning
31 * - persistence of monotonic time from DVInit to prevent
32 * replay attacks using DVInit messages
33 * - dv hop-by-hop signature verification (at least at initiator) 27 * - dv hop-by-hop signature verification (at least at initiator)
34 * - persistence of monotonic time obtained from other peers
35 * in PEERSTORE (by message type) -- done for backchannel, needed elsewhere?
36 * - change transport-core API to provide proper flow control in both 28 * - change transport-core API to provide proper flow control in both
37 * directions, allow multiple messages per peer simultaneously (tag 29 * directions, allow multiple messages per peer simultaneously (tag
38 * confirmations with unique message ID), and replace quota-out with 30 * confirmations with unique message ID), and replace quota-out with
@@ -720,6 +712,20 @@ struct TransportDVLearnMessage
720 struct GNUNET_TIME_RelativeNBO non_network_delay; 712 struct GNUNET_TIME_RelativeNBO non_network_delay;
721 713
722 /** 714 /**
715 * Time at the initiator when generating the signature.
716 *
717 * Note that the receiver MUST IGNORE the absolute time, and only interpret
718 * the value as a mononic time and reject "older" values than the last one
719 * observed. This is necessary as we do not want to require synchronized
720 * clocks and may not have a bidirectional communication channel.
721 *
722 * Even with this, there is no real guarantee against replay achieved here,
723 * unless the latest timestamp is persisted. Persistence should be
724 * provided via PEERSTORE if possible.
725 */
726 struct GNUNET_TIME_AbsoluteNBO monotonic_time;
727
728 /**
723 * Signature of this hop over the path, of purpose 729 * Signature of this hop over the path, of purpose
724 * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR 730 * #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR
725 */ 731 */
@@ -923,6 +929,41 @@ enum ClientType
923 929
924 930
925/** 931/**
932 * Which transmission options are allowable for transmission?
933 * Interpreted bit-wise!
934 */
935enum RouteMessageOptions
936{
937 /**
938 * Only confirmed, non-DV direct neighbours.
939 */
940 RMO_NONE = 0,
941
942 /**
943 * We are allowed to use DV routing for this @a hdr
944 */
945 RMO_DV_ALLOWED = 1,
946
947 /**
948 * We are allowed to use unconfirmed queues or DV routes for this message
949 */
950 RMO_UNCONFIRMED_ALLOWED = 2,
951
952 /**
953 * Reliable and unreliable, DV and non-DV are all acceptable.
954 */
955 RMO_ANYTHING_GOES = (RMO_DV_ALLOWED | RMO_UNCONFIRMED_ALLOWED),
956
957 /**
958 * If we have multiple choices, it is OK to send this message
959 * over multiple channels at the same time to improve loss tolerance.
960 * (We do at most 2 transmissions.)
961 */
962 RMO_REDUNDANT = 4
963};
964
965
966/**
926 * When did we launch this DV learning activity? 967 * When did we launch this DV learning activity?
927 */ 968 */
928struct LearnLaunchEntry 969struct LearnLaunchEntry
@@ -1629,6 +1670,18 @@ struct Neighbour
1629 struct GNUNET_SCHEDULER_Task *timeout_task; 1670 struct GNUNET_SCHEDULER_Task *timeout_task;
1630 1671
1631 /** 1672 /**
1673 * Handle for an operation to fetch @e last_dv_learn_monotime information from
1674 * the PEERSTORE, or NULL.
1675 */
1676 struct GNUNET_PEERSTORE_IterateContext *get;
1677
1678 /**
1679 * Handle to a PEERSTORE store operation to store this @e pid's @e
1680 * @e last_dv_learn_monotime. NULL if no PEERSTORE operation is pending.
1681 */
1682 struct GNUNET_PEERSTORE_StoreContext *sc;
1683
1684 /**
1632 * Quota at which CORE is allowed to transmit to this peer 1685 * Quota at which CORE is allowed to transmit to this peer
1633 * (note that the value CORE should actually be told is this 1686 * (note that the value CORE should actually be told is this
1634 * value plus the respective value in `struct DistanceVector`). 1687 * value plus the respective value in `struct DistanceVector`).
@@ -1643,6 +1696,12 @@ struct Neighbour
1643 struct GNUNET_BANDWIDTH_Value32NBO quota_out; 1696 struct GNUNET_BANDWIDTH_Value32NBO quota_out;
1644 1697
1645 /** 1698 /**
1699 * Latest DVLearn monotonic time seen from this peer. Initialized only
1700 * if @e dl_monotime_available is #GNUNET_YES.
1701 */
1702 struct GNUNET_TIME_Absolute last_dv_learn_monotime;
1703
1704 /**
1646 * What is the earliest timeout of any message in @e pending_msg_tail? 1705 * What is the earliest timeout of any message in @e pending_msg_tail?
1647 */ 1706 */
1648 struct GNUNET_TIME_Absolute earliest_timeout; 1707 struct GNUNET_TIME_Absolute earliest_timeout;
@@ -1652,6 +1711,12 @@ struct Neighbour
1652 * CORE? 1711 * CORE?
1653 */ 1712 */
1654 int core_visible; 1713 int core_visible;
1714
1715 /**
1716 * Do we have the lastest value for @e last_dv_learn_monotime from
1717 * PEERSTORE yet, or are we still waiting for a reply of PEERSTORE?
1718 */
1719 int dv_monotime_available;
1655}; 1720};
1656 1721
1657 1722
@@ -2851,7 +2916,20 @@ free_neighbour (struct Neighbour *neighbour)
2851 free_dv_route (dv); 2916 free_dv_route (dv);
2852 } 2917 }
2853 if (NULL != neighbour->reassembly_timeout_task) 2918 if (NULL != neighbour->reassembly_timeout_task)
2919 {
2854 GNUNET_SCHEDULER_cancel (neighbour->reassembly_timeout_task); 2920 GNUNET_SCHEDULER_cancel (neighbour->reassembly_timeout_task);
2921 neighbour->reassembly_timeout_task = NULL;
2922 }
2923 if (NULL != neighbour->get)
2924 {
2925 GNUNET_PEERSTORE_iterate_cancel (neighbour->get);
2926 neighbour->get = NULL;
2927 }
2928 if (NULL != neighbour->sc)
2929 {
2930 GNUNET_PEERSTORE_store_cancel (neighbour->sc);
2931 neighbour->sc = NULL;
2932 }
2855 GNUNET_free (neighbour); 2933 GNUNET_free (neighbour);
2856} 2934}
2857 2935
@@ -3453,6 +3531,130 @@ check_queue_timeouts (void *cls)
3453 3531
3454 3532
3455/** 3533/**
3534 * Create a DV Box message.
3535 *
3536 * @param total_hops how many hops did the message take so far
3537 * @param num_hops length of the @a hops array
3538 * @param origin origin of the message
3539 * @param hops next peer(s) to the destination, including destination
3540 * @param payload payload of the box
3541 * @param payload_size number of bytes in @a payload
3542 * @return boxed message (caller must #GNUNET_free() it).
3543 */
3544static struct TransportDVBoxMessage *
3545create_dv_box (uint16_t total_hops,
3546 const struct GNUNET_PeerIdentity *origin,
3547 const struct GNUNET_PeerIdentity *target,
3548 uint16_t num_hops,
3549 const struct GNUNET_PeerIdentity *hops,
3550 const void *payload,
3551 uint16_t payload_size)
3552{
3553 struct TransportDVBoxMessage *dvb;
3554 struct GNUNET_PeerIdentity *dhops;
3555
3556 GNUNET_assert (UINT16_MAX <
3557 sizeof (struct TransportDVBoxMessage) +
3558 sizeof (struct GNUNET_PeerIdentity) * (num_hops + 1) +
3559 payload_size);
3560 dvb = GNUNET_malloc (sizeof (struct TransportDVBoxMessage) +
3561 sizeof (struct GNUNET_PeerIdentity) * (num_hops + 1) +
3562 payload_size);
3563 dvb->header.size =
3564 htons (sizeof (struct TransportDVBoxMessage) +
3565 sizeof (struct GNUNET_PeerIdentity) * (num_hops + 1) + payload_size);
3566 dvb->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX);
3567 dvb->total_hops = htons (total_hops);
3568 dvb->num_hops = htons (num_hops + 1);
3569 dvb->origin = *origin;
3570 dhops = (struct GNUNET_PeerIdentity *) &dvb[1];
3571 memcpy (dhops, hops, num_hops * sizeof (struct GNUNET_PeerIdentity));
3572 dhops[num_hops] = *target;
3573 memcpy (&dhops[num_hops + 1], payload, payload_size);
3574 return dvb;
3575}
3576
3577
3578/**
3579 * Pick @a hops_array_length random DV paths satisfying @a options
3580 *
3581 * @param dv data structure to pick paths from
3582 * @param options constraints to satisfy
3583 * @param hops_array[out] set to the result
3584 * @param hops_array_length length of the @a hops_array
3585 * @return number of entries set in @a hops_array
3586 */
3587static unsigned int
3588pick_random_dv_hops (const struct DistanceVector *dv,
3589 enum RouteMessageOptions options,
3590 struct DistanceVectorHop **hops_array,
3591 unsigned int hops_array_length)
3592{
3593 uint64_t choices[hops_array_length];
3594 uint64_t num_dv;
3595 unsigned int dv_count;
3596
3597 /* Pick random vectors, but weighted by distance, giving more weight
3598 to shorter vectors */
3599 num_dv = 0;
3600 dv_count = 0;
3601 for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
3602 pos = pos->next_dv)
3603 {
3604 if ((0 == (options & RMO_UNCONFIRMED_ALLOWED)) &&
3605 (GNUNET_TIME_absolute_get_remaining (pos->path_valid_until)
3606 .rel_value_us == 0))
3607 continue; /* pos unconfirmed and confirmed required */
3608 num_dv += MAX_DV_HOPS_ALLOWED - pos->distance;
3609 dv_count++;
3610 }
3611 if (0 == dv_count)
3612 return 0;
3613 if (dv_count <= hops_array_length)
3614 {
3615 dv_count = 0;
3616 for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
3617 pos = pos->next_dv)
3618 hops_array[dv_count++] = pos;
3619 return dv_count;
3620 }
3621 for (unsigned int i = 0; i < hops_array_length; i++)
3622 {
3623 int ok = GNUNET_NO;
3624 while (GNUNET_NO == ok)
3625 {
3626 choices[i] =
3627 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, num_dv);
3628 ok = GNUNET_YES;
3629 for (unsigned int j = 0; j < i; j++)
3630 if (choices[i] == choices[j])
3631 {
3632 ok = GNUNET_NO;
3633 break;
3634 }
3635 }
3636 }
3637 dv_count = 0;
3638 num_dv = 0;
3639 for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
3640 pos = pos->next_dv)
3641 {
3642 uint32_t delta = MAX_DV_HOPS_ALLOWED - pos->distance;
3643
3644 if ((0 == (options & RMO_UNCONFIRMED_ALLOWED)) &&
3645 (GNUNET_TIME_absolute_get_remaining (pos->path_valid_until)
3646 .rel_value_us == 0))
3647 continue; /* pos unconfirmed and confirmed required */
3648 for (unsigned int i = 0; i < hops_array_length; i++)
3649 if ((num_dv <= choices[i]) && (num_dv + delta > choices[i]))
3650 hops_array[dv_count++] = pos;
3651 num_dv += delta;
3652 }
3653 return dv_count;
3654}
3655
3656
3657/**
3456 * Client asked for transmission to a peer. Process the request. 3658 * Client asked for transmission to a peer. Process the request.
3457 * 3659 *
3458 * @param cls the client 3660 * @param cls the client
@@ -3471,6 +3673,7 @@ handle_client_send (void *cls, const struct OutboundMessage *obm)
3471 int was_empty; 3673 int was_empty;
3472 const void *payload; 3674 const void *payload;
3473 size_t payload_size; 3675 size_t payload_size;
3676 struct TransportDVBoxMessage *dvb;
3474 3677
3475 GNUNET_assert (CT_CORE == tc->type); 3678 GNUNET_assert (CT_CORE == tc->type);
3476 obmm = (const struct GNUNET_MessageHeader *) &obm[1]; 3679 obmm = (const struct GNUNET_MessageHeader *) &obm[1];
@@ -3504,18 +3707,26 @@ handle_client_send (void *cls, const struct OutboundMessage *obm)
3504 } 3707 }
3505 if (NULL == target) 3708 if (NULL == target)
3506 { 3709 {
3507 // FIXME: overall, similar logic exists already for DV boxing, 3710 unsigned int res;
3508 // re-use! 3711 struct DistanceVectorHop *dvh;
3509 3712
3510 // FIXME: dvh = pick_dv_hop (dv); 3713 res = pick_random_dv_hops (dv, RMO_NONE, &dvh, 1);
3714 GNUNET_assert (1 == res);
3511 target = dvh->next_hop; 3715 target = dvh->next_hop;
3512 // FIXME: dv box message here! 3716 dvb = create_dv_box (0,
3513 // FIXME: set payload & payload_size to box (and free box below!) 3717 &GST_my_identity,
3718 &obm->peer,
3719 dvh->distance,
3720 dvh->path,
3721 &obm[1],
3722 bytes_msg);
3723 payload = dvb;
3724 payload_size = ntohs (dvb->header.size);
3514 } 3725 }
3515 else 3726 else
3516 { 3727 {
3517 dvh = NULL; 3728 dvh = NULL;
3518 // box = NULL; 3729 dvb = NULL;
3519 payload = &obm[1]; 3730 payload = &obm[1];
3520 payload_size = bytes_msg; 3731 payload_size = bytes_msg;
3521 } 3732 }
@@ -3527,8 +3738,9 @@ handle_client_send (void *cls, const struct OutboundMessage *obm)
3527 pm->bytes_msg = payload_size; 3738 pm->bytes_msg = payload_size;
3528 pm->timeout = 3739 pm->timeout =
3529 GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_ntoh (obm->timeout)); 3740 GNUNET_TIME_relative_to_absolute (GNUNET_TIME_relative_ntoh (obm->timeout));
3530 memcpy (&pm[1], &obm[1], payload_size); 3741 memcpy (&pm[1], payload, payload_size);
3531 // FIXME: GNUNET_free_non_null (box); 3742 GNUNET_free_non_null (dvb);
3743 dvb = NULL;
3532 pm->dvh = dvh; 3744 pm->dvh = dvh;
3533 if (NULL != dvh) 3745 if (NULL != dvh)
3534 { 3746 {
@@ -3810,41 +4022,6 @@ queue_send_msg (struct Queue *queue,
3810 4022
3811 4023
3812/** 4024/**
3813 * Which transmission options are allowable for transmission?
3814 * Interpreted bit-wise!
3815 */
3816enum RouteMessageOptions
3817{
3818 /**
3819 * Only confirmed, non-DV direct neighbours.
3820 */
3821 RMO_NONE = 0,
3822
3823 /**
3824 * We are allowed to use DV routing for this @a hdr
3825 */
3826 RMO_DV_ALLOWED = 1,
3827
3828 /**
3829 * We are allowed to use unconfirmed queues or DV routes for this message
3830 */
3831 RMO_UNCONFIRMED_ALLOWED = 2,
3832
3833 /**
3834 * Reliable and unreliable, DV and non-DV are all acceptable.
3835 */
3836 RMO_ANYTHING_GOES = (RMO_DV_ALLOWED | RMO_UNCONFIRMED_ALLOWED),
3837
3838 /**
3839 * If we have multiple choices, it is OK to send this message
3840 * over multiple channels at the same time to improve loss tolerance.
3841 * (We do at most 2 transmissions.)
3842 */
3843 RMO_REDUNDANT = 4
3844};
3845
3846
3847/**
3848 * Pick a queue of @a n under constraints @a options and schedule 4025 * Pick a queue of @a n under constraints @a options and schedule
3849 * transmission of @a hdr. 4026 * transmission of @a hdr.
3850 * 4027 *
@@ -3927,22 +4104,17 @@ forward_via_dvh (const struct DistanceVectorHop *dvh,
3927 const struct GNUNET_MessageHeader *payload, 4104 const struct GNUNET_MessageHeader *payload,
3928 enum RouteMessageOptions options) 4105 enum RouteMessageOptions options)
3929{ 4106{
3930 uint16_t mlen = ntohs (payload->size); 4107 struct TransportDVBoxMessage *dvb;
3931 char boxram[sizeof (struct TransportDVBoxMessage) +
3932 (dvh->distance + 1) * sizeof (struct GNUNET_PeerIdentity) +
3933 mlen] GNUNET_ALIGN;
3934 struct TransportDVBoxMessage *box = (struct TransportDVBoxMessage *) boxram;
3935 struct GNUNET_PeerIdentity *path = (struct GNUNET_PeerIdentity *) &box[1];
3936 4108
3937 box->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX); 4109 dvb = create_dv_box (0,
3938 box->header.size = htons (sizeof (boxram)); 4110 &GST_my_identity,
3939 box->total_hops = htons (0); 4111 &dvh->dv->target,
3940 box->num_hops = htons (dvh->distance + 1); 4112 dvh->distance,
3941 box->origin = GST_my_identity; 4113 dvh->path,
3942 memcpy (path, dvh->path, dvh->distance * sizeof (struct GNUNET_PeerIdentity)); 4114 payload,
3943 path[dvh->distance] = dvh->dv->target; 4115 ntohs (payload->size));
3944 memcpy (&path[dvh->distance + 1], payload, mlen); 4116 route_via_neighbour (dvh->next_hop, &dvb->header, options);
3945 route_via_neighbour (dvh->next_hop, &box->header, options); 4117 GNUNET_free (dvb);
3946} 4118}
3947 4119
3948 4120
@@ -3960,52 +4132,15 @@ route_via_dv (const struct DistanceVector *dv,
3960 const struct GNUNET_MessageHeader *hdr, 4132 const struct GNUNET_MessageHeader *hdr,
3961 enum RouteMessageOptions options) 4133 enum RouteMessageOptions options)
3962{ 4134{
3963 struct DistanceVectorHop *h1; 4135 struct DistanceVectorHop *hops[2];
3964 struct DistanceVectorHop *h2; 4136 unsigned int res;
3965 uint64_t num_dv;
3966 uint64_t choice1;
3967 uint64_t choice2;
3968
3969 /* Pick random vectors, but weighted by distance, giving more weight
3970 to shorter vectors */
3971 num_dv = 0;
3972 for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
3973 pos = pos->next_dv)
3974 {
3975 if ((0 == (options & RMO_UNCONFIRMED_ALLOWED)) &&
3976 (GNUNET_TIME_absolute_get_remaining (pos->path_valid_until)
3977 .rel_value_us == 0))
3978 continue; /* pos unconfirmed and confirmed required */
3979 num_dv += MAX_DV_HOPS_ALLOWED - pos->distance;
3980 }
3981 if (0 == num_dv)
3982 {
3983 GNUNET_break (0);
3984 return;
3985 }
3986 choice1 = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, num_dv);
3987 choice2 = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, num_dv);
3988 num_dv = 0;
3989 h1 = NULL;
3990 h2 = NULL;
3991 for (struct DistanceVectorHop *pos = dv->dv_head; NULL != pos;
3992 pos = pos->next_dv)
3993 {
3994 uint32_t delta = MAX_DV_HOPS_ALLOWED - pos->distance;
3995 4137
3996 if ((0 == (options & RMO_UNCONFIRMED_ALLOWED)) && 4138 res = pick_random_dv_hops (dv,
3997 (GNUNET_TIME_absolute_get_remaining (pos->path_valid_until) 4139 options,
3998 .rel_value_us == 0)) 4140 hops,
3999 continue; /* pos unconfirmed and confirmed required */ 4141 (0 == (options & RMO_REDUNDANT)) ? 1 : 2);
4000 if ((num_dv <= choice1) && (num_dv + delta > choice1)) 4142 for (unsigned int i = 0; i < res; i++)
4001 h1 = pos; 4143 forward_via_dvh (hops[i], hdr, options & (~RMO_REDUNDANT));
4002 if ((num_dv <= choice2) && (num_dv + delta > choice2))
4003 h2 = pos;
4004 num_dv += delta;
4005 }
4006 forward_via_dvh (h1, hdr, options & (~RMO_REDUNDANT));
4007 if (0 == (options & RMO_REDUNDANT))
4008 forward_via_dvh (h2, hdr, options & (~RMO_REDUNDANT));
4009} 4144}
4010 4145
4011 4146
@@ -5912,6 +6047,7 @@ forward_dv_learn (const struct GNUNET_PeerIdentity *next_hop,
5912/** 6047/**
5913 * Check signature of type #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR 6048 * Check signature of type #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR
5914 * 6049 *
6050 * @param sender_monotonic_time monotonic time of the initiator
5915 * @param init the signer 6051 * @param init the signer
5916 * @param challenge the challenge that was signed 6052 * @param challenge the challenge that was signed
5917 * @param init_sig signature presumably by @a init 6053 * @param init_sig signature presumably by @a init
@@ -5919,6 +6055,7 @@ forward_dv_learn (const struct GNUNET_PeerIdentity *next_hop,
5919 */ 6055 */
5920static int 6056static int
5921validate_dv_initiator_signature ( 6057validate_dv_initiator_signature (
6058 struct GNUNET_TIME_AbsoluteNBO sender_monotonic_time,
5922 const struct GNUNET_PeerIdentity *init, 6059 const struct GNUNET_PeerIdentity *init,
5923 const struct ChallengeNonceP *challenge, 6060 const struct ChallengeNonceP *challenge,
5924 const struct GNUNET_CRYPTO_EddsaSignature *init_sig) 6061 const struct GNUNET_CRYPTO_EddsaSignature *init_sig)
@@ -5926,6 +6063,7 @@ validate_dv_initiator_signature (
5926 struct DvInitPS ip = {.purpose.purpose = htonl ( 6063 struct DvInitPS ip = {.purpose.purpose = htonl (
5927 GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR), 6064 GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR),
5928 .purpose.size = htonl (sizeof (ip)), 6065 .purpose.size = htonl (sizeof (ip)),
6066 .monotonic_time = sender_monotonic_time,
5929 .challenge = *challenge}; 6067 .challenge = *challenge};
5930 6068
5931 if ( 6069 if (
@@ -6132,6 +6270,24 @@ calculate_fork_degree (unsigned int hops_taken,
6132 6270
6133 6271
6134/** 6272/**
6273 * Function called when peerstore is done storing a DV monotonic time.
6274 *
6275 * @param cls a `struct Neighbour`
6276 * @param success #GNUNET_YES if peerstore was successful
6277 */
6278static void
6279neighbour_store_dvmono_cb (void *cls, int success)
6280{
6281 struct Neighbour *n = cls;
6282
6283 n->sc = NULL;
6284 if (GNUNET_YES != success)
6285 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
6286 "Failed to store other peer's monotonic time in peerstore!\n");
6287}
6288
6289
6290/**
6135 * Communicator gave us a DV learn message. Process the request. 6291 * Communicator gave us a DV learn message. Process the request.
6136 * 6292 *
6137 * @param cls a `struct CommunicatorMessageContext` (must call 6293 * @param cls a `struct CommunicatorMessageContext` (must call
@@ -6150,6 +6306,7 @@ handle_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
6150 int do_fwd; 6306 int do_fwd;
6151 int did_initiator; 6307 int did_initiator;
6152 struct GNUNET_TIME_Absolute in_time; 6308 struct GNUNET_TIME_Absolute in_time;
6309 struct Neighbour *n;
6153 6310
6154 nhops = ntohs (dvl->bidirectional); /* 0 = sender is initiator */ 6311 nhops = ntohs (dvl->bidirectional); /* 0 = sender is initiator */
6155 bi_history = ntohs (dvl->bidirectional); 6312 bi_history = ntohs (dvl->bidirectional);
@@ -6184,15 +6341,44 @@ handle_dv_learn (void *cls, const struct TransportDVLearnMessage *dvl)
6184 /* continue communicator here, everything else can happen asynchronous! */ 6341 /* continue communicator here, everything else can happen asynchronous! */
6185 finish_cmc_handling (cmc); 6342 finish_cmc_handling (cmc);
6186 6343
6187 /* OPTIMIZE-FIXME: Technically, we only need to bother checking 6344 n = lookup_neighbour (&dvl->initiator);
6188 the initiator signature if we send the message back to the initiator... 6345 if (NULL != n)
6189 */
6190 if (GNUNET_OK != validate_dv_initiator_signature (&dvl->initiator,
6191 &dvl->challenge,
6192 &dvl->init_sig))
6193 { 6346 {
6194 GNUNET_break_op (0); 6347 if ((n->dv_monotime_available == GNUNET_YES) &&
6195 return; 6348 (GNUNET_TIME_absolute_ntoh (dvl->monotonic_time).abs_value_us <
6349 n->last_dv_learn_monotime.abs_value_us))
6350 {
6351 GNUNET_STATISTICS_update (GST_stats,
6352 "# DV learn discarded due to time travel",
6353 1,
6354 GNUNET_NO);
6355 return;
6356 }
6357 if (GNUNET_OK != validate_dv_initiator_signature (dvl->monotonic_time,
6358 &dvl->initiator,
6359 &dvl->challenge,
6360 &dvl->init_sig))
6361 {
6362 GNUNET_break_op (0);
6363 return;
6364 }
6365 n->last_dv_learn_monotime = GNUNET_TIME_absolute_ntoh (dvl->monotonic_time);
6366 if (GNUNET_YES == n->dv_monotime_available)
6367 {
6368 if (NULL != n->sc)
6369 GNUNET_PEERSTORE_store_cancel (n->sc);
6370 n->sc =
6371 GNUNET_PEERSTORE_store (peerstore,
6372 "transport",
6373 &dvl->initiator,
6374 GNUNET_PEERSTORE_TRANSPORT_DVLEARN_MONOTIME,
6375 &dvl->monotonic_time,
6376 sizeof (dvl->monotonic_time),
6377 GNUNET_TIME_UNIT_FOREVER_ABS,
6378 GNUNET_PEERSTORE_STOREOPTION_REPLACE,
6379 &neighbour_store_dvmono_cb,
6380 n);
6381 }
6196 } 6382 }
6197 // FIXME: asynchronously (!) verify hop-by-hop signatures! 6383 // FIXME: asynchronously (!) verify hop-by-hop signatures!
6198 // => if signature verification load too high, implement random drop 6384 // => if signature verification load too high, implement random drop
@@ -6418,25 +6604,16 @@ forward_dv_box (struct Neighbour *next_hop,
6418 uint16_t payload_size) 6604 uint16_t payload_size)
6419{ 6605{
6420 struct TransportDVBoxMessage *dvb; 6606 struct TransportDVBoxMessage *dvb;
6421 struct GNUNET_PeerIdentity *dhops;
6422 6607
6423 GNUNET_assert (UINT16_MAX < sizeof (struct TransportDVBoxMessage) + 6608 dvb = create_dv_box (total_hops,
6424 sizeof (struct GNUNET_PeerIdentity) * num_hops + 6609 origin,
6425 payload_size); 6610 &hops[num_hops - 1] /* == target */,
6426 dvb = GNUNET_malloc (sizeof (struct TransportDVBoxMessage) + 6611 num_hops - 1 /* do not count target twice */,
6427 sizeof (struct GNUNET_PeerIdentity) * num_hops + 6612 hops,
6613 payload,
6428 payload_size); 6614 payload_size);
6429 dvb->header.size =
6430 htons (sizeof (struct TransportDVBoxMessage) +
6431 sizeof (struct GNUNET_PeerIdentity) * num_hops + payload_size);
6432 dvb->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DV_BOX);
6433 dvb->total_hops = htons (total_hops);
6434 dvb->num_hops = htons (num_hops);
6435 dvb->origin = *origin;
6436 dhops = (struct GNUNET_PeerIdentity *) &dvb[1];
6437 memcpy (dhops, hops, num_hops * sizeof (struct GNUNET_PeerIdentity));
6438 memcpy (&dhops[num_hops], payload, payload_size);
6439 route_message (&next_hop->pid, &dvb->header, RMO_NONE); 6615 route_message (&next_hop->pid, &dvb->header, RMO_NONE);
6616 GNUNET_free (dvb);
6440} 6617}
6441 6618
6442 6619
@@ -7974,10 +8151,13 @@ start_dv_learn (void *cls)
7974 dvl.num_hops = htons (0); 8151 dvl.num_hops = htons (0);
7975 dvl.bidirectional = htons (0); 8152 dvl.bidirectional = htons (0);
7976 dvl.non_network_delay = GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_ZERO); 8153 dvl.non_network_delay = GNUNET_TIME_relative_hton (GNUNET_TIME_UNIT_ZERO);
8154 dvl.monotonic_time =
8155 GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get_monotonic (GST_cfg));
7977 { 8156 {
7978 struct DvInitPS dvip = {.purpose.purpose = htonl ( 8157 struct DvInitPS dvip = {.purpose.purpose = htonl (
7979 GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR), 8158 GNUNET_SIGNATURE_PURPOSE_TRANSPORT_DV_INITIATOR),
7980 .purpose.size = htonl (sizeof (dvip)), 8159 .purpose.size = htonl (sizeof (dvip)),
8160 .monotonic_time = dvl.monotonic_time,
7981 .challenge = lle->challenge}; 8161 .challenge = lle->challenge};
7982 8162
7983 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (GST_my_private_key, 8163 GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_sign (GST_my_private_key,
@@ -8039,6 +8219,44 @@ check_validation_request_pending (void *cls,
8039 8219
8040 8220
8041/** 8221/**
8222 * Function called with the monotonic time of a DV initiator
8223 * by PEERSTORE. Updates the time.
8224 *
8225 * @param cls a `struct Neighbour`
8226 * @param record the information found, NULL for the last call
8227 * @param emsg error message
8228 */
8229static void
8230neighbour_dv_monotime_cb (void *cls,
8231 const struct GNUNET_PEERSTORE_Record *record,
8232 const char *emsg)
8233{
8234 struct Neighbour *n = cls;
8235 struct GNUNET_TIME_AbsoluteNBO *mtbe;
8236 struct GNUNET_TIME_Absolute mt;
8237
8238 (void) emsg;
8239 if (NULL == record)
8240 {
8241 /* we're done with #neighbour_dv_monotime_cb() invocations,
8242 continue normal processing */
8243 n->get = NULL;
8244 n->dv_monotime_available = GNUNET_YES;
8245 return;
8246 }
8247 if (sizeof (*mtbe) != record->value_size)
8248 {
8249 GNUNET_break (0);
8250 return;
8251 }
8252 mtbe = record->value;
8253 n->last_dv_learn_monotime =
8254 GNUNET_TIME_absolute_max (n->last_dv_learn_monotime,
8255 GNUNET_TIME_absolute_ntoh (*mtbe));
8256}
8257
8258
8259/**
8042 * New queue became available. Process the request. 8260 * New queue became available. Process the request.
8043 * 8261 *
8044 * @param cls the client 8262 * @param cls the client
@@ -8074,6 +8292,13 @@ handle_add_queue_message (void *cls,
8074 &neighbour->pid, 8292 &neighbour->pid,
8075 neighbour, 8293 neighbour,
8076 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 8294 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
8295 neighbour->get =
8296 GNUNET_PEERSTORE_iterate (peerstore,
8297 "transport",
8298 &neighbour->pid,
8299 GNUNET_PEERSTORE_TRANSPORT_DVLEARN_MONOTIME,
8300 &neighbour_dv_monotime_cb,
8301 neighbour);
8077 } 8302 }
8078 addr_len = ntohs (aqm->header.size) - sizeof (*aqm); 8303 addr_len = ntohs (aqm->header.size) - sizeof (*aqm);
8079 addr = (const char *) &aqm[1]; 8304 addr = (const char *) &aqm[1];