aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gnsrecord/gnsrecord_crypto.c233
-rw-r--r--src/include/gnunet_gnsrecord_lib.h40
-rw-r--r--src/zonemaster/gnunet-service-zonemaster.c311
-rw-r--r--src/zonemaster/zonemaster.conf.in1
4 files changed, 472 insertions, 113 deletions
diff --git a/src/gnsrecord/gnsrecord_crypto.c b/src/gnsrecord/gnsrecord_crypto.c
index 6c1bc6045..d794c9cb4 100644
--- a/src/gnsrecord/gnsrecord_crypto.c
+++ b/src/gnsrecord/gnsrecord_crypto.c
@@ -95,7 +95,8 @@ eddsa_symmetric_decrypt (
95 if (ctlen < 0) 95 if (ctlen < 0)
96 return GNUNET_SYSERR; 96 return GNUNET_SYSERR;
97 if (0 != crypto_secretbox_open_detached (result, 97 if (0 != crypto_secretbox_open_detached (result,
98 ((unsigned char*) block) + crypto_secretbox_MACBYTES, // Ciphertext 98 ((unsigned char*) block)
99 + crypto_secretbox_MACBYTES, // Ciphertext
99 block, // Tag 100 block, // Tag
100 ctlen, 101 ctlen,
101 nonce, key)) 102 nonce, key))
@@ -193,6 +194,116 @@ block_get_size_ecdsa (const struct GNUNET_GNSRECORD_Data *rd,
193 return len; 194 return len;
194} 195}
195 196
197enum GNUNET_GenericReturnValue
198block_sign_ecdsa (const struct
199 GNUNET_CRYPTO_EcdsaPrivateKey *key,
200 const struct
201 GNUNET_CRYPTO_EcdsaPublicKey *pkey,
202 const char *label,
203 struct GNUNET_GNSRECORD_Block *block)
204{
205 struct GNRBlockPS *gnr_block;
206 struct GNUNET_GNSRECORD_EcdsaBlock *ecblock;
207 size_t size = ntohl (block->size) - sizeof (*block) + sizeof (*gnr_block);
208
209 gnr_block = GNUNET_malloc (size);
210 ecblock = &(block)->ecdsa_block;
211 gnr_block->purpose.size = htonl (size);
212 gnr_block->purpose.purpose =
213 htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
214 gnr_block->expiration_time = ecblock->expiration_time;
215 /* encrypt and sign */
216 GNUNET_memcpy (&gnr_block[1], &ecblock[1],
217 size - sizeof (*gnr_block));
218 GNUNET_CRYPTO_ecdsa_public_key_derive (pkey,
219 label,
220 "gns",
221 &ecblock->derived_key);
222 if (GNUNET_OK !=
223 GNUNET_CRYPTO_ecdsa_sign_derived (key,
224 label,
225 "gns",
226 &gnr_block->purpose,
227 &ecblock->signature))
228 {
229 GNUNET_break (0);
230 GNUNET_free (gnr_block);
231 return GNUNET_SYSERR;
232 }
233 GNUNET_free (gnr_block);
234 return GNUNET_OK;
235}
236
237
238enum GNUNET_GenericReturnValue
239block_sign_eddsa (const struct
240 GNUNET_CRYPTO_EddsaPrivateKey *key,
241 const struct
242 GNUNET_CRYPTO_EddsaPublicKey *pkey,
243 const char *label,
244 struct GNUNET_GNSRECORD_Block *block)
245{
246 struct GNRBlockPS *gnr_block;
247 struct GNUNET_GNSRECORD_EddsaBlock *edblock;
248 size_t size = ntohl (block->size) - sizeof (*block) + sizeof (*gnr_block);
249 gnr_block = GNUNET_malloc (size);
250 edblock = &(block)->eddsa_block;
251 gnr_block->purpose.size = htonl (size);
252 gnr_block->purpose.purpose =
253 htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
254 gnr_block->expiration_time = edblock->expiration_time;
255 GNUNET_memcpy (&gnr_block[1], &edblock[1],
256 size - sizeof (*gnr_block));
257 /* encrypt and sign */
258 GNUNET_CRYPTO_eddsa_public_key_derive (pkey,
259 label,
260 "gns",
261 &edblock->derived_key);
262 GNUNET_CRYPTO_eddsa_sign_derived (key,
263 label,
264 "gns",
265 &gnr_block->purpose,
266 &edblock->signature);
267 GNUNET_free (gnr_block);
268 return GNUNET_OK;
269}
270
271
272enum GNUNET_GenericReturnValue
273GNUNET_GNSRECORD_block_sign (const struct
274 GNUNET_IDENTITY_PrivateKey *key,
275 const char *label,
276 struct GNUNET_GNSRECORD_Block *block)
277{
278 struct GNUNET_IDENTITY_PublicKey pkey;
279 enum GNUNET_GenericReturnValue res = GNUNET_SYSERR;
280 char *norm_label;
281
282 GNUNET_IDENTITY_key_get_public (key,
283 &pkey);
284 norm_label = GNUNET_GNSRECORD_string_normalize (label);
285
286 switch (ntohl (key->type))
287 {
288 case GNUNET_GNSRECORD_TYPE_PKEY:
289 res = block_sign_ecdsa (&key->ecdsa_key,
290 &pkey.ecdsa_key,
291 norm_label,
292 block);
293 break;
294 case GNUNET_GNSRECORD_TYPE_EDKEY:
295 res = block_sign_eddsa (&key->eddsa_key,
296 &pkey.eddsa_key,
297 norm_label,
298 block);
299 break;
300 default:
301 GNUNET_assert (0);
302 }
303 GNUNET_free (norm_label);
304 return res;
305}
306
196 307
197/** 308/**
198 * Sign name and records 309 * Sign name and records
@@ -204,6 +315,7 @@ block_get_size_ecdsa (const struct GNUNET_GNSRECORD_Data *rd,
204 * @param rd record data 315 * @param rd record data
205 * @param rd_count number of records 316 * @param rd_count number of records
206 * @param block the block result. Must be allocated sufficiently. 317 * @param block the block result. Must be allocated sufficiently.
318 * @param sign sign the block GNUNET_NO if block will be signed later.
207 * @return GNUNET_SYSERR on error (otherwise GNUNET_OK) 319 * @return GNUNET_SYSERR on error (otherwise GNUNET_OK)
208 */ 320 */
209static enum GNUNET_GenericReturnValue 321static enum GNUNET_GenericReturnValue
@@ -213,12 +325,12 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
213 const char *label, 325 const char *label,
214 const struct GNUNET_GNSRECORD_Data *rd, 326 const struct GNUNET_GNSRECORD_Data *rd,
215 unsigned int rd_count, 327 unsigned int rd_count,
216 struct GNUNET_GNSRECORD_Block **block) 328 struct GNUNET_GNSRECORD_Block **block,
329 int sign)
217{ 330{
218 ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, 331 ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
219 rd); 332 rd);
220 struct GNUNET_GNSRECORD_EcdsaBlock *ecblock; 333 struct GNUNET_GNSRECORD_EcdsaBlock *ecblock;
221 struct GNRBlockPS *gnr_block;
222 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2]; 334 unsigned char ctr[GNUNET_CRYPTO_AES_KEY_LENGTH / 2];
223 unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH]; 335 unsigned char skey[GNUNET_CRYPTO_AES_KEY_LENGTH];
224 struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; 336 struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)];
@@ -251,7 +363,7 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
251 } 363 }
252 /* serialize */ 364 /* serialize */
253 *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len); 365 *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len);
254 (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block) + payload_len); 366 (*block)->size = htonl (sizeof (struct GNUNET_GNSRECORD_Block) + payload_len);
255 { 367 {
256 char payload[payload_len]; 368 char payload[payload_len];
257 369
@@ -260,19 +372,9 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
260 rdc, 372 rdc,
261 payload_len, 373 payload_len,
262 payload)); 374 payload));
263 gnr_block = GNUNET_malloc (sizeof (struct GNRBlockPS) + payload_len);
264 ecblock = &(*block)->ecdsa_block; 375 ecblock = &(*block)->ecdsa_block;
265 (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY); 376 (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
266 gnr_block->purpose.size = htonl (sizeof(struct GNRBlockPS) + payload_len); 377 ecblock->expiration_time = GNUNET_TIME_absolute_hton (expire);
267 gnr_block->purpose.purpose =
268 htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
269 gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire);
270 ecblock->expiration_time = gnr_block->expiration_time;
271 /* encrypt and sign */
272 GNUNET_CRYPTO_ecdsa_public_key_derive (pkey,
273 label,
274 "gns",
275 &ecblock->derived_key);
276 GNR_derive_block_aes_key (ctr, 378 GNR_derive_block_aes_key (ctr,
277 skey, 379 skey,
278 label, 380 label,
@@ -284,21 +386,16 @@ block_create_ecdsa (const struct GNUNET_CRYPTO_EcdsaPrivateKey *key,
284 skey, 386 skey,
285 ctr, 387 ctr,
286 &ecblock[1])); 388 &ecblock[1]));
287 GNUNET_memcpy (&gnr_block[1], &ecblock[1], payload_len);
288 } 389 }
390 if (GNUNET_YES != sign)
391 return GNUNET_OK;
289 if (GNUNET_OK != 392 if (GNUNET_OK !=
290 GNUNET_CRYPTO_ecdsa_sign_derived (key, 393 block_sign_ecdsa (key, pkey, label, *block))
291 label,
292 "gns",
293 &gnr_block->purpose,
294 &ecblock->signature))
295 { 394 {
296 GNUNET_break (0); 395 GNUNET_break (0);
297 GNUNET_free (*block); 396 GNUNET_free (*block);
298 GNUNET_free (gnr_block);
299 return GNUNET_SYSERR; 397 return GNUNET_SYSERR;
300 } 398 }
301 GNUNET_free (gnr_block);
302 return GNUNET_OK; 399 return GNUNET_OK;
303} 400}
304 401
@@ -327,6 +424,7 @@ block_get_size_eddsa (const struct GNUNET_GNSRECORD_Data *rd,
327 * @param rd record data 424 * @param rd record data
328 * @param rd_count number of records 425 * @param rd_count number of records
329 * @param block where to store the block. Must be allocated sufficiently. 426 * @param block where to store the block. Must be allocated sufficiently.
427 * @param sign GNUNET_YES if block shall be signed as well
330 * @return GNUNET_SYSERR on error (otherwise GNUNET_OK) 428 * @return GNUNET_SYSERR on error (otherwise GNUNET_OK)
331 */ 429 */
332enum GNUNET_GenericReturnValue 430enum GNUNET_GenericReturnValue
@@ -336,12 +434,12 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
336 const char *label, 434 const char *label,
337 const struct GNUNET_GNSRECORD_Data *rd, 435 const struct GNUNET_GNSRECORD_Data *rd,
338 unsigned int rd_count, 436 unsigned int rd_count,
339 struct GNUNET_GNSRECORD_Block **block) 437 struct GNUNET_GNSRECORD_Block **block,
438 int sign)
340{ 439{
341 ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count, 440 ssize_t payload_len = GNUNET_GNSRECORD_records_get_size (rd_count,
342 rd); 441 rd);
343 struct GNUNET_GNSRECORD_EddsaBlock *edblock; 442 struct GNUNET_GNSRECORD_EddsaBlock *edblock;
344 struct GNRBlockPS *gnr_block;
345 unsigned char nonce[crypto_secretbox_NONCEBYTES]; 443 unsigned char nonce[crypto_secretbox_NONCEBYTES];
346 unsigned char skey[crypto_secretbox_KEYBYTES]; 444 unsigned char skey[crypto_secretbox_KEYBYTES];
347 struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)]; 445 struct GNUNET_GNSRECORD_Data rdc[GNUNET_NZL (rd_count)];
@@ -375,8 +473,8 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
375 /* serialize */ 473 /* serialize */
376 *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block) 474 *block = GNUNET_malloc (sizeof (struct GNUNET_GNSRECORD_Block)
377 + payload_len + crypto_secretbox_MACBYTES); 475 + payload_len + crypto_secretbox_MACBYTES);
378 (*block)->size = htonl(sizeof (struct GNUNET_GNSRECORD_Block) 476 (*block)->size = htonl (sizeof (struct GNUNET_GNSRECORD_Block)
379 + payload_len + crypto_secretbox_MACBYTES); 477 + payload_len + crypto_secretbox_MACBYTES);
380 { 478 {
381 char payload[payload_len]; 479 char payload[payload_len];
382 480
@@ -385,24 +483,9 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
385 rdc, 483 rdc,
386 payload_len, 484 payload_len,
387 payload)); 485 payload));
388 gnr_block = GNUNET_malloc (sizeof (struct GNRBlockPS)
389 + payload_len
390 + crypto_secretbox_MACBYTES);
391 edblock = &(*block)->eddsa_block; 486 edblock = &(*block)->eddsa_block;
392 (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY); 487 (*block)->type = htonl (GNUNET_GNSRECORD_TYPE_EDKEY);
393 gnr_block->purpose.size = 488 edblock->expiration_time = GNUNET_TIME_absolute_hton (expire);
394 htonl (sizeof(struct GNRBlockPS)
395 + payload_len
396 + crypto_secretbox_MACBYTES);
397 gnr_block->purpose.purpose =
398 htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
399 gnr_block->expiration_time = GNUNET_TIME_absolute_hton (expire);
400 edblock->expiration_time = gnr_block->expiration_time;
401 /* encrypt and sign */
402 GNUNET_CRYPTO_eddsa_public_key_derive (pkey,
403 label,
404 "gns",
405 &edblock->derived_key);
406 GNR_derive_block_xsalsa_key (nonce, 489 GNR_derive_block_xsalsa_key (nonce,
407 skey, 490 skey,
408 label, 491 label,
@@ -414,14 +497,9 @@ block_create_eddsa (const struct GNUNET_CRYPTO_EddsaPrivateKey *key,
414 skey, 497 skey,
415 nonce, 498 nonce,
416 &edblock[1])); 499 &edblock[1]));
417 GNUNET_memcpy (&gnr_block[1], &edblock[1], 500 if (GNUNET_YES != sign)
418 payload_len + crypto_secretbox_MACBYTES); 501 return GNUNET_OK;
419 502 block_sign_eddsa (key, pkey, label, *block);
420 GNUNET_CRYPTO_eddsa_sign_derived (key,
421 label,
422 "gns",
423 &gnr_block->purpose,
424 &edblock->signature);
425 } 503 }
426 return GNUNET_OK; 504 return GNUNET_OK;
427} 505}
@@ -477,7 +555,8 @@ GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
477 norm_label, 555 norm_label,
478 rd, 556 rd,
479 rd_count, 557 rd_count,
480 result); 558 result,
559 GNUNET_YES);
481 break; 560 break;
482 case GNUNET_GNSRECORD_TYPE_EDKEY: 561 case GNUNET_GNSRECORD_TYPE_EDKEY:
483 res = block_create_eddsa (&key->eddsa_key, 562 res = block_create_eddsa (&key->eddsa_key,
@@ -486,7 +565,8 @@ GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
486 norm_label, 565 norm_label,
487 rd, 566 rd,
488 rd_count, 567 rd_count,
489 result); 568 result,
569 GNUNET_YES);
490 break; 570 break;
491 default: 571 default:
492 GNUNET_assert (0); 572 GNUNET_assert (0);
@@ -513,13 +593,14 @@ struct KeyCacheLine
513}; 593};
514 594
515 595
516enum GNUNET_GenericReturnValue 596static enum GNUNET_GenericReturnValue
517GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey, 597block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
518 struct GNUNET_TIME_Absolute expire, 598 struct GNUNET_TIME_Absolute expire,
519 const char *label, 599 const char *label,
520 const struct GNUNET_GNSRECORD_Data *rd, 600 const struct GNUNET_GNSRECORD_Data *rd,
521 unsigned int rd_count, 601 unsigned int rd_count,
522 struct GNUNET_GNSRECORD_Block **result) 602 struct GNUNET_GNSRECORD_Block **result,
603 int sign)
523{ 604{
524 const struct GNUNET_CRYPTO_EcdsaPrivateKey *key; 605 const struct GNUNET_CRYPTO_EcdsaPrivateKey *key;
525 struct GNUNET_CRYPTO_EddsaPublicKey edpubkey; 606 struct GNUNET_CRYPTO_EddsaPublicKey edpubkey;
@@ -552,7 +633,8 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
552 norm_label, 633 norm_label,
553 rd, 634 rd,
554 rd_count, 635 rd_count,
555 result); 636 result,
637 sign);
556 } 638 }
557 else if (GNUNET_IDENTITY_TYPE_EDDSA == ntohl (pkey->type)) 639 else if (GNUNET_IDENTITY_TYPE_EDDSA == ntohl (pkey->type))
558 { 640 {
@@ -564,13 +646,40 @@ GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
564 norm_label, 646 norm_label,
565 rd, 647 rd,
566 rd_count, 648 rd_count,
567 result); 649 result,
650 sign);
568 } 651 }
569 GNUNET_free (norm_label); 652 GNUNET_free (norm_label);
570 return res; 653 return res;
571} 654}
572 655
573 656
657
658enum GNUNET_GenericReturnValue
659GNUNET_GNSRECORD_block_create_unsigned (const struct
660 GNUNET_IDENTITY_PrivateKey *pkey,
661 struct GNUNET_TIME_Absolute expire,
662 const char *label,
663 const struct GNUNET_GNSRECORD_Data *rd,
664 unsigned int rd_count,
665 struct GNUNET_GNSRECORD_Block **result)
666{
667 return block_create2 (pkey, expire, label, rd, rd_count, result, GNUNET_NO);
668}
669
670
671
672enum GNUNET_GenericReturnValue
673GNUNET_GNSRECORD_block_create2 (const struct GNUNET_IDENTITY_PrivateKey *pkey,
674 struct GNUNET_TIME_Absolute expire,
675 const char *label,
676 const struct GNUNET_GNSRECORD_Data *rd,
677 unsigned int rd_count,
678 struct GNUNET_GNSRECORD_Block **result)
679{
680 return block_create2 (pkey, expire, label, rd, rd_count, result, GNUNET_YES);
681}
682
574/** 683/**
575 * Check if a signature is valid. This API is used by the GNS Block 684 * Check if a signature is valid. This API is used by the GNS Block
576 * to validate signatures received from the network. 685 * to validate signatures received from the network.
diff --git a/src/include/gnunet_gnsrecord_lib.h b/src/include/gnunet_gnsrecord_lib.h
index 357f87587..85a42d459 100644
--- a/src/include/gnunet_gnsrecord_lib.h
+++ b/src/include/gnunet_gnsrecord_lib.h
@@ -150,7 +150,7 @@ enum GNUNET_GNSRECORD_Filter
150 * Filter public records. 150 * Filter public records.
151 * FIXME: Not implemented 151 * FIXME: Not implemented
152 */ 152 */
153 //GNUNET_NAMESTORE_FILTER_OMIT_PUBLIC = 4, 153 // GNUNET_NAMESTORE_FILTER_OMIT_PUBLIC = 4,
154}; 154};
155 155
156 156
@@ -554,6 +554,19 @@ GNUNET_GNSRECORD_block_calculate_size (const struct
554 const struct GNUNET_GNSRECORD_Data *rd, 554 const struct GNUNET_GNSRECORD_Data *rd,
555 unsigned int rd_count); 555 unsigned int rd_count);
556 556
557/**
558 * Sign a block create with #GNUNET_GNSRECORD_block_create_unsigned
559 *
560 * @param key the private key
561 * @param label the label of the block
562 * @param block the unsigned block
563 * @return GNUNET_OK on success
564 */
565enum GNUNET_GenericReturnValue
566GNUNET_GNSRECORD_block_sign (const struct
567 GNUNET_IDENTITY_PrivateKey *key,
568 const char *label,
569 struct GNUNET_GNSRECORD_Block *block);
557 570
558/** 571/**
559 * Sign name and records 572 * Sign name and records
@@ -576,6 +589,31 @@ GNUNET_GNSRECORD_block_create (const struct GNUNET_IDENTITY_PrivateKey *key,
576 589
577 590
578/** 591/**
592 * Create name and records but do not sign!
593 * Sign later with #GNUNET_GNSRECORD_block_sign().
594 * Cache derived public key (also keeps the
595 * private key in static memory, so do not use this function if
596 * keeping the private key in the process'es RAM is a major issue).
597 *
598 * @param key the private key
599 * @param expire block expiration
600 * @param label the name for the records
601 * @param rd record data
602 * @param rd_count number of records in @a rd
603 * @param result the block buffer. Will be allocated.
604 * @return GNUNET_OK on success.
605 */
606enum GNUNET_GenericReturnValue
607GNUNET_GNSRECORD_block_create_unsigned (const struct
608 GNUNET_IDENTITY_PrivateKey *key,
609 struct GNUNET_TIME_Absolute expire,
610 const char *label,
611 const struct GNUNET_GNSRECORD_Data *rd,
612 unsigned int rd_count,
613 struct GNUNET_GNSRECORD_Block **result);
614
615
616/**
579 * Sign name and records, cache derived public key (also keeps the 617 * Sign name and records, cache derived public key (also keeps the
580 * private key in static memory, so do not use this function if 618 * private key in static memory, so do not use this function if
581 * keeping the private key in the process'es RAM is a major issue). 619 * keeping the private key in the process'es RAM is a major issue).
diff --git a/src/zonemaster/gnunet-service-zonemaster.c b/src/zonemaster/gnunet-service-zonemaster.c
index f5c1d781b..42b3abf91 100644
--- a/src/zonemaster/gnunet-service-zonemaster.c
+++ b/src/zonemaster/gnunet-service-zonemaster.c
@@ -97,6 +97,81 @@
97#define DHT_GNS_REPLICATION_LEVEL 5 97#define DHT_GNS_REPLICATION_LEVEL 5
98 98
99/** 99/**
100 * Our workers
101 */
102static pthread_t * worker;
103
104/**
105 * Lock for the open jobs queue.
106 */
107static pthread_mutex_t jobs_lock;
108
109/**
110 * Lock for the finished results queue.
111 */
112static pthread_mutex_t results_lock;
113
114/**
115 * For threads to know we are shutting down
116 */
117static int in_shutdown = GNUNET_NO;
118
119/**
120 * Our notification pipe
121 */
122static struct GNUNET_DISK_PipeHandle *notification_pipe;
123
124/**
125 * Pipe read task
126 */
127static struct GNUNET_SCHEDULER_Task *pipe_read_task;
128
129struct OpenSignJob
130{
131
132 struct OpenSignJob *next;
133
134 struct OpenSignJob *prev;
135
136 struct GNUNET_IDENTITY_PrivateKey zone;
137
138 struct GNUNET_GNSRECORD_Block *block;
139
140 struct GNUNET_GNSRECORD_Block *block_priv;
141
142 struct DhtPutActivity *ma;
143
144 size_t block_size;
145
146 struct GNUNET_TIME_Absolute expire_pub;
147
148 char *label;
149
150};
151
152
153/**
154 * DLL
155 */
156static struct OpenSignJob *jobs_head;
157
158/**
159 * DLL
160 */
161static struct OpenSignJob *jobs_tail;
162
163/**
164 * DLL
165 */
166static struct OpenSignJob *results_head;
167
168/**
169 * DLL
170 */
171static struct OpenSignJob *results_tail;
172
173
174/**
100 * Handle for DHT PUT activity triggered from the namestore monitor. 175 * Handle for DHT PUT activity triggered from the namestore monitor.
101 */ 176 */
102struct DhtPutActivity 177struct DhtPutActivity
@@ -319,8 +394,13 @@ shutdown_task (void *cls)
319 struct CacheOperation *cop; 394 struct CacheOperation *cop;
320 395
321 (void) cls; 396 (void) cls;
397 in_shutdown == GNUNET_YES;
322 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 398 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
323 "Shutting down!\n"); 399 "Shutting down!\n");
400 if (NULL != notification_pipe)
401 GNUNET_DISK_pipe_close (notification_pipe);
402 if (NULL != pipe_read_task)
403 GNUNET_SCHEDULER_cancel (pipe_read_task);
324 while (NULL != (cop = cop_head)) 404 while (NULL != (cop = cop_head))
325 { 405 {
326 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 406 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
@@ -332,7 +412,8 @@ shutdown_task (void *cls)
332 412
333 while (NULL != (ma = it_head)) 413 while (NULL != (ma = it_head))
334 { 414 {
335 GNUNET_DHT_put_cancel (ma->ph); 415 if (NULL != ma->ph)
416 GNUNET_DHT_put_cancel (ma->ph);
336 dht_queue_length--; 417 dht_queue_length--;
337 GNUNET_CONTAINER_DLL_remove (it_head, 418 GNUNET_CONTAINER_DLL_remove (it_head,
338 it_tail, 419 it_tail,
@@ -682,6 +763,16 @@ dht_put_continuation (void *cls)
682 GNUNET_free (ma); 763 GNUNET_free (ma);
683} 764}
684 765
766static void
767free_job (struct OpenSignJob *job)
768{
769 if (job->block != job->block_priv)
770 GNUNET_free (job->block_priv);
771 GNUNET_free (job->block);
772 if (NULL != job->label)
773 GNUNET_free (job->label);
774 GNUNET_free (job);
775}
685 776
686 777
687/** 778/**
@@ -760,35 +851,86 @@ perform_dht_put (const struct GNUNET_IDENTITY_PrivateKey *key,
760 else 851 else
761 block_priv = block; 852 block_priv = block;
762 block_size = GNUNET_GNSRECORD_block_get_size (block); 853 block_size = GNUNET_GNSRECORD_block_get_size (block);
763 GNUNET_GNSRECORD_query_from_private_key (key, 854 GNUNET_assert (0 == pthread_mutex_lock (&jobs_lock));
764 label, 855 struct OpenSignJob *job = GNUNET_new (struct OpenSignJob);
856 job->block = GNUNET_malloc (block_size); // FIXME this does not need to be copied, can be freed by worker
857 memcpy (job->block, block, block_size);
858 job->block_size = block_size;
859 job->block_priv = block_priv;
860 job->zone = *key;
861 job->ma = ma;
862 job->label = GNUNET_strdup (label);
863 job->expire_pub = expire_pub;
864 GNUNET_CONTAINER_DLL_insert (jobs_head, jobs_tail, job);
865 GNUNET_assert (0 == pthread_mutex_unlock (&jobs_lock));
866 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
867 "Storing %u record(s) for label `%s' in DHT with expiration `%s'\n",
868 rd_public_count,
869 label,
870 GNUNET_STRINGS_absolute_time_to_string (expire));
871 num_public_records++;
872}
873
874static void
875notification_pipe_cb (void *cls);
876
877static void
878initiate_put_from_pipe_trigger (void *cls)
879{
880 struct GNUNET_HashCode query;
881 struct OpenSignJob *job;
882
883 pipe_read_task = NULL;
884 GNUNET_assert (0 == pthread_mutex_lock (&results_lock));
885 job = results_head;
886 if (NULL == job)
887 {
888 GNUNET_assert (0 == pthread_mutex_unlock (&results_lock));
889 const struct GNUNET_DISK_FileHandle *np_fh = GNUNET_DISK_pipe_handle (
890 notification_pipe,
891 GNUNET_DISK_PIPE_END_READ);
892 pipe_read_task =
893 GNUNET_SCHEDULER_add_read_file (
894 GNUNET_TIME_UNIT_FOREVER_REL,
895 np_fh,
896 notification_pipe_cb,
897 NULL);
898 return;
899 }
900 GNUNET_CONTAINER_DLL_remove (results_head, results_tail, job);
901 GNUNET_assert (0 == pthread_mutex_unlock (&results_lock));
902 GNUNET_GNSRECORD_query_from_private_key (&job->zone,
903 job->label,
765 &query); 904 &query);
766 GNUNET_STATISTICS_update (statistics, 905 GNUNET_STATISTICS_update (statistics,
767 "DHT put operations initiated", 906 "DHT put operations initiated",
768 1, 907 1,
769 GNUNET_NO); 908 GNUNET_NO);
770 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 909 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
771 "Storing %u record(s) for label `%s' in DHT with expiration `%s' under key %s\n", 910 "Storing record(s) for label `%s' in DHT under key %s\n",
772 rd_public_count, 911 job->label,
773 label,
774 GNUNET_STRINGS_absolute_time_to_string (expire),
775 GNUNET_h2s (&query)); 912 GNUNET_h2s (&query));
776 num_public_records++; 913 job->ma->ph = GNUNET_DHT_put (dht_handle,
777 ret = GNUNET_DHT_put (dht_handle, 914 &query,
778 &query, 915 DHT_GNS_REPLICATION_LEVEL,
779 DHT_GNS_REPLICATION_LEVEL, 916 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
780 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, 917 GNUNET_BLOCK_TYPE_GNS_NAMERECORD,
781 GNUNET_BLOCK_TYPE_GNS_NAMERECORD, 918 job->block_size,
782 block_size, 919 job->block,
783 block, 920 job->expire_pub,
784 expire_pub, 921 &dht_put_continuation,
785 &dht_put_continuation, 922 job->ma);
786 ma); 923 if (NULL == job->ma->ph)
787 refresh_block (block_priv); 924 {
788 if (block != block_priv) 925 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
789 GNUNET_free (block_priv); 926 "Could not perform DHT PUT, is the DHT running?\n");
790 GNUNET_free (block); 927 GNUNET_free (job->ma);
791 return ret; 928 free_job (job);
929 return;
930 }
931 refresh_block (job->block_priv);
932 free_job (job);
933 return;
792} 934}
793 935
794 936
@@ -907,45 +1049,29 @@ put_gns_record (void *cls,
907 /* We got a set of records to publish */ 1049 /* We got a set of records to publish */
908 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1050 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
909 "Starting DHT PUT\n"); 1051 "Starting DHT PUT\n");
910
911 ma = GNUNET_new (struct DhtPutActivity);
912 ma->start_date = GNUNET_TIME_absolute_get ();
913 ma->ph = perform_dht_put (key,
914 label,
915 rd,
916 rd_count,
917 expire,
918 ma);
919 put_cnt++; 1052 put_cnt++;
920 if (0 == put_cnt % DELTA_INTERVAL) 1053 if (0 == put_cnt % DELTA_INTERVAL)
921 update_velocity (DELTA_INTERVAL); 1054 update_velocity (DELTA_INTERVAL);
922 check_zone_namestore_next (); 1055 check_zone_namestore_next ();
923 if (NULL == ma->ph) 1056 if (dht_queue_length >= DHT_QUEUE_LIMIT)
924 { 1057 {
925 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1058 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
926 "Could not perform DHT PUT, is the DHT running?\n"); 1059 "DHT PUT queue length exceeded (%u), aborting PUT\n",
927 GNUNET_free (ma); 1060 DHT_QUEUE_LIMIT);
928 return; 1061 return;
929 } 1062 }
1063
1064 ma = GNUNET_new (struct DhtPutActivity);
1065 perform_dht_put (key,
1066 label,
1067 rd,
1068 rd_count,
1069 expire,
1070 ma);
930 dht_queue_length++; 1071 dht_queue_length++;
931 GNUNET_CONTAINER_DLL_insert_tail (it_head, 1072 GNUNET_CONTAINER_DLL_insert_tail (it_head,
932 it_tail, 1073 it_tail,
933 ma); 1074 ma);
934 if (dht_queue_length > DHT_QUEUE_LIMIT)
935 {
936 ma = it_head;
937 GNUNET_CONTAINER_DLL_remove (it_head,
938 it_tail,
939 ma);
940 GNUNET_DHT_put_cancel (ma->ph);
941 dht_queue_length--;
942 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
943 "DHT PUT unconfirmed after %s, aborting PUT\n",
944 GNUNET_STRINGS_relative_time_to_string (
945 GNUNET_TIME_absolute_get_duration (ma->start_date),
946 GNUNET_YES));
947 GNUNET_free (ma);
948 }
949} 1075}
950 1076
951/** 1077/**
@@ -1075,9 +1201,18 @@ perform_dht_put_monitor (const struct GNUNET_IDENTITY_PrivateKey *key,
1075 else 1201 else
1076 block_priv = block; 1202 block_priv = block;
1077 block_size = GNUNET_GNSRECORD_block_get_size (block); 1203 block_size = GNUNET_GNSRECORD_block_get_size (block);
1204 GNUNET_assert (0 == pthread_mutex_lock (&jobs_lock));
1205 struct OpenSignJob *job = GNUNET_new (struct OpenSignJob);
1206 job->block = GNUNET_malloc (block_size); // FIXME this does not need to be copied, can be freed by worker
1207 memcpy (job->block, block, block_size);
1208 job->zone = *key;
1209 job->label = GNUNET_strdup (label);
1210 GNUNET_CONTAINER_DLL_insert (jobs_head, jobs_tail, job);
1211 GNUNET_assert (0 == pthread_mutex_unlock (&jobs_lock));
1078 GNUNET_GNSRECORD_query_from_private_key (key, 1212 GNUNET_GNSRECORD_query_from_private_key (key,
1079 label, 1213 label,
1080 &query); 1214 &query);
1215 GNUNET_assert (0 == pthread_mutex_unlock (&jobs_lock));
1081 GNUNET_STATISTICS_update (statistics, 1216 GNUNET_STATISTICS_update (statistics,
1082 "DHT put operations initiated", 1217 "DHT put operations initiated",
1083 1, 1218 1,
@@ -1196,6 +1331,48 @@ handle_monitor_error (void *cls)
1196 GNUNET_NO); 1331 GNUNET_NO);
1197} 1332}
1198 1333
1334static void*
1335sign_worker (void *)
1336{
1337 struct OpenSignJob *job;
1338 const struct GNUNET_DISK_FileHandle *fh;
1339
1340 fh = GNUNET_DISK_pipe_handle (notification_pipe, GNUNET_DISK_PIPE_END_WRITE);
1341 while (GNUNET_YES != in_shutdown)
1342 {
1343 GNUNET_assert (0 == pthread_mutex_lock (&jobs_lock));
1344 if (NULL != jobs_head)
1345 {
1346 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1347 "Taking on Job for %s\n", jobs_head->label);
1348 job = jobs_head;
1349 GNUNET_CONTAINER_DLL_remove (jobs_head, jobs_tail, job);
1350 }
1351 GNUNET_assert (0 == pthread_mutex_unlock (&jobs_lock));
1352 if (NULL != job)
1353 {
1354 GNUNET_assert (0 == pthread_mutex_lock (&results_lock));
1355 GNUNET_CONTAINER_DLL_insert (results_head, results_tail, job);
1356 GNUNET_assert (0 == pthread_mutex_unlock (&results_lock));
1357 job = NULL;
1358 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1359 "Done, notifying main thread throug pipe!\n");
1360 GNUNET_DISK_file_write (fh, "!", 1);
1361 }
1362 else {
1363 sleep (1);
1364 }
1365 }
1366 return NULL;
1367}
1368
1369static void
1370notification_pipe_cb (void *cls)
1371{
1372 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1373 "Received wake up notification through pipe, checking results\n");
1374 GNUNET_SCHEDULER_add_now (&initiate_put_from_pipe_trigger, NULL);
1375}
1199 1376
1200/** 1377/**
1201 * Perform zonemaster duties: watch namestore, publish records. 1378 * Perform zonemaster duties: watch namestore, publish records.
@@ -1305,6 +1482,40 @@ run (void *cls,
1305 1482
1306 GNUNET_SCHEDULER_add_shutdown (&shutdown_task, 1483 GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
1307 NULL); 1484 NULL);
1485
1486 notification_pipe = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE);
1487 const struct GNUNET_DISK_FileHandle *np_fh = GNUNET_DISK_pipe_handle (
1488 notification_pipe,
1489 GNUNET_DISK_PIPE_END_READ);
1490 pipe_read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1491 np_fh,
1492 notification_pipe_cb, NULL);
1493
1494 long long unsigned int worker_count = 1;
1495 if (GNUNET_OK !=
1496 GNUNET_CONFIGURATION_get_value_number (c,
1497 "zonemaster",
1498 "WORKER_COUNT",
1499 &worker_count))
1500 {
1501 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1502 "Number of workers not defined falling back to 1\n");
1503 }
1504 worker = GNUNET_malloc (sizeof (pthread_t) * worker_count);
1505 /** Start worker */
1506 for (int i = 0; i < worker_count; i++)
1507 {
1508 if (0 !=
1509 pthread_create (&worker[i],
1510 NULL,
1511 &sign_worker,
1512 NULL))
1513 {
1514 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
1515 "pthread_create");
1516 GNUNET_SCHEDULER_shutdown ();
1517 }
1518 }
1308} 1519}
1309 1520
1310 1521
diff --git a/src/zonemaster/zonemaster.conf.in b/src/zonemaster/zonemaster.conf.in
index 560239944..9c920c476 100644
--- a/src/zonemaster/zonemaster.conf.in
+++ b/src/zonemaster/zonemaster.conf.in
@@ -6,6 +6,7 @@ HOSTNAME = localhost
6BINARY = gnunet-service-zonemaster 6BINARY = gnunet-service-zonemaster
7UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-zonemaster.sock 7UNIXPATH = $GNUNET_USER_RUNTIME_DIR/gnunet-service-zonemaster.sock
8@JAVAPORT@PORT = 2123 8@JAVAPORT@PORT = 2123
9WORKER_COUNT = 10
9 10
10# Do we require users that want to access GNS to run this process 11# Do we require users that want to access GNS to run this process
11# (usually not a good idea) 12# (usually not a good idea)