aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gnunet-service-gns.c
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2012-02-23 15:03:53 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2012-02-23 15:03:53 +0000
commit49a261c6967a57fe5ddc0c25d4edcacb94bcd598 (patch)
treea2b63d941eceb0ef8d3912fc08cd2f4dbc7a442a /src/gns/gnunet-service-gns.c
parent0cabde03978a09aa336071eab6aedfb0aa68672f (diff)
downloadgnunet-49a261c6967a57fe5ddc0c25d4edcacb94bcd598.tar.gz
gnunet-49a261c6967a57fe5ddc0c25d4edcacb94bcd598.zip
-make it compile against new api, added parser utils borrowed from dnsparser
Diffstat (limited to 'src/gns/gnunet-service-gns.c')
-rw-r--r--src/gns/gnunet-service-gns.c279
1 files changed, 122 insertions, 157 deletions
diff --git a/src/gns/gnunet-service-gns.c b/src/gns/gnunet-service-gns.c
index 198e4c33b..cb82439c4 100644
--- a/src/gns/gnunet-service-gns.c
+++ b/src/gns/gnunet-service-gns.c
@@ -52,7 +52,7 @@ struct GNUNET_GNS_QueryRecordList
52 struct GNUNET_GNS_QueryRecordList * next; 52 struct GNUNET_GNS_QueryRecordList * next;
53 struct GNUNET_GNS_QueryRecordList * prev; 53 struct GNUNET_GNS_QueryRecordList * prev;
54 54
55 struct GNUNET_DNSPARSER_Record * record; 55 GNUNET_GNS_Record * record;
56}; 56};
57 57
58/** 58/**
@@ -103,8 +103,6 @@ struct GNUNET_DNS_Handle *dns_handle;
103 */ 103 */
104struct GNUNET_DHT_Handle *dht_handle; 104struct GNUNET_DHT_Handle *dht_handle;
105 105
106struct GNUNET_TIME_Relative dht_update_interval;
107
108/** 106/**
109 * Our zone's private key 107 * Our zone's private key
110 */ 108 */
@@ -115,6 +113,8 @@ struct GNUNET_CRYPTO_RsaPrivateKey *zone_key;
115 */ 113 */
116struct GNUNET_NAMESTORE_Handle *namestore_handle; 114struct GNUNET_NAMESTORE_Handle *namestore_handle;
117 115
116struct GNUNET_NAMESTORE_ZoneIterator *namestore_iter;
117
118/** 118/**
119 * The configuration the GNS service is running with 119 * The configuration the GNS service is running with
120 */ 120 */
@@ -136,6 +136,12 @@ GNUNET_HashCode zone_hash;
136const char* gnunet_tld = ".gnunet"; 136const char* gnunet_tld = ".gnunet";
137 137
138/** 138/**
139 * Useful for zone update for DHT put
140 */
141static int num_public_records = 3600;
142struct GNUNET_TIME_Relative dht_update_interval;
143
144/**
139 * Task run during shutdown. 145 * Task run during shutdown.
140 * 146 *
141 * @param cls unused 147 * @param cls unused
@@ -313,20 +319,24 @@ resolve_name(struct GNUNET_GNS_PendingQuery *query, GNUNET_HashCode *zone);
313 * @param data the record data 319 * @param data the record data
314 */ 320 */
315void 321void
316process_authority_lookup(void* cls, const GNUNET_HashCode *zone, 322process_authority_lookup(void* cls,
317 const char *name, uint32_t record_type, 323 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key,
318 struct GNUNET_TIME_Absolute expiration, 324 struct GNUNET_TIME_Absolute expiration,
319 enum GNUNET_NAMESTORE_RecordFlags flags, 325 const char *name,
320 size_t size, const void *data) 326 unsigned int rd_count,
327 const struct GNUNET_NAMESTORE_RecordData *rd,
328 const struct GNUNET_CRYPTO_RsaSignature *signature)
321{ 329{
322 struct GNUNET_GNS_PendingQuery *query; 330 struct GNUNET_GNS_PendingQuery *query;
331 GNUNET_HashCode zone;
323 332
324 query = (struct GNUNET_GNS_PendingQuery *)cls; 333 query = (struct GNUNET_GNS_PendingQuery *)cls;
334 GNUNET_CRYPTO_hash(key, GNUNET_CRYPTO_RSA_KEY_LENGTH, &zone);
325 335
326 /** 336 /**
327 * No authority found in namestore. 337 * No authority found in namestore.
328 */ 338 */
329 if (NULL == data) 339 if (rd_count == 0)
330 { 340 {
331 if (query->authority_found) 341 if (query->authority_found)
332 { 342 {
@@ -337,11 +347,10 @@ process_authority_lookup(void* cls, const GNUNET_HashCode *zone,
337 347
338 /** 348 /**
339 * We did not find an authority in the namestore 349 * We did not find an authority in the namestore
340 * _IF_ the current authoritative zone is us. 350 * _IF_ the current authoritative zone is us we cannot resolve
341 * we cannot resolve 351 * _ELSE_ we can still check the dht
342 * _ELSE_ we cannot still check the dht
343 */ 352 */
344 if (GNUNET_CRYPTO_hash_cmp(zone, &zone_hash)) 353 if (GNUNET_CRYPTO_hash_cmp(&zone, &zone_hash))
345 { 354 {
346 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Authority unknown\n"); 355 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Authority unknown\n");
347 //FIXME return NX answer 356 //FIXME return NX answer
@@ -351,14 +360,23 @@ process_authority_lookup(void* cls, const GNUNET_HashCode *zone,
351 resolve_authority_dht(query, name); 360 resolve_authority_dht(query, name);
352 return; 361 return;
353 } 362 }
354 363
364 //Note only 1 pkey should have been returned.. anything else would be strange
355 /** 365 /**
356 * We found an authority that may be able to help us 366 * We found an authority that may be able to help us
357 * move on with query 367 * move on with query
358 */ 368 */
359 query->authority_found = 1; 369 GNUNET_GNS_Record *record
360 GNUNET_HashCode *key = (GNUNET_HashCode*) data; //FIXME i assume this works 370 = GNUNET_malloc(sizeof(GNUNET_GNS_Record));
361 query->authority = key; 371
372
373 //FIXME todo
374 //parse_record(rd[0]->data, rd[0]->data_size, 0, record);
375 //FIXME this cast will not work we have to define how a PKEY record looks like
376 //In reality this also returns a pubkey not a hash
377 GNUNET_HashCode *k = (GNUNET_HashCode*)record->data.raw.data;
378 query->authority = k;
379 resolve_name(query, query->authority);
362 380
363} 381}
364 382
@@ -449,40 +467,38 @@ reply_to_dns(struct GNUNET_GNS_PendingQuery *answer)
449 * @param data the record data 467 * @param data the record data
450 */ 468 */
451static void 469static void
452process_authoritative_result(void* cls, const GNUNET_HashCode *zone, 470process_authoritative_result(void* cls,
453 const char *name, uint32_t record_type, 471 const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key,
454 struct GNUNET_TIME_Absolute expiration, 472 struct GNUNET_TIME_Absolute expiration,
455 enum GNUNET_NAMESTORE_RecordFlags flags, 473 const char *name, unsigned int rd_count,
456 size_t size, const void *data) 474 const struct GNUNET_NAMESTORE_RecordData *rd,
475 const struct GNUNET_CRYPTO_RsaSignature *signature)
457{ 476{
458 struct GNUNET_GNS_PendingQuery *query; 477 struct GNUNET_GNS_PendingQuery *query;
459 struct GNUNET_GNS_QueryRecordList *qrecord; 478 struct GNUNET_GNS_QueryRecordList *qrecord;
460 struct GNUNET_DNSPARSER_Record *record; 479 struct GNUNET_DNSPARSER_Record *record;
480 GNUNET_HashCode zone;
461 query = (struct GNUNET_GNS_PendingQuery *) cls; 481 query = (struct GNUNET_GNS_PendingQuery *) cls;
482 GNUNET_CRYPTO_hash(key, GNUNET_CRYPTO_RSA_KEY_LENGTH, &zone);
462 483
484 //FIXME Handle results in rd
463 485
464 if (NULL == data) 486 if (rd_count == 0)
465 { 487 {
466 /** 488 /**
467 * FIXME 489 * FIXME
468 * Lookup terminated 490 * Lookup terminated and no results
469 * Do we have what we need to answer? 491 * -> DHT Phase unless data is recent
470 * If not -> DHT Phase
471 * if full_name == next_name and not anwered we cannot resolve 492 * if full_name == next_name and not anwered we cannot resolve
472 */ 493 */
473 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 494 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
474 "Namestore lookup terminated. (answered=%d)", query->answered); 495 "Namestore lookup terminated. without results\n");
475 if (query->answered) 496
476 {
477 reply_to_dns(query);
478 return;
479 }
480
481 /** 497 /**
482 * if this is not our zone we cannot rely on the namestore to be 498 * if this is not our zone we cannot rely on the namestore to be
483 * complete. -> Query DHT 499 * complete. -> Query DHT
484 */ 500 */
485 if (!GNUNET_CRYPTO_hash_cmp(zone, &zone_hash)) 501 if (!GNUNET_CRYPTO_hash_cmp(&zone, &zone_hash))
486 { 502 {
487 //FIXME todo 503 //FIXME todo
488 resolve_name_dht(query, name); 504 resolve_name_dht(query, name);
@@ -500,54 +516,36 @@ process_authoritative_result(void* cls, const GNUNET_HashCode *zone,
500 { 516 {
501 /** 517 /**
502 * Record found 518 * Record found
519 *
520 * FIXME Check record expiration and dht expiration
521 * consult dht if necessary
503 */ 522 */
504 GNUNET_log(GNUNET_ERROR_TYPE_INFO, 523 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
505 "Processing additional result for %s from namestore\n", name); 524 "Processing additional result for %s from namestore\n", name);
506 525 int i;
507 qrecord = GNUNET_malloc(sizeof(struct GNUNET_GNS_QueryRecordList)); 526 for (i=0; i<rd_count;i++)
508 record = GNUNET_malloc(sizeof(struct GNUNET_DNSPARSER_Record));
509 qrecord->record = record;
510
511 record->name = (char*)query->original_name;
512
513 /**
514 * FIXME for gns records this requires the dnsparser to be modified!
515 * or use RAW. But RAW data need serialization!
516 * maybe store record data appropriately in namestore to avoid a
517 * huge switch statement?
518 */
519 if (record_type == GNUNET_DNSPARSER_TYPE_A)
520 {
521 record->data.raw.data = (char*)data;
522 record->data.raw.data_len = size;
523 }
524 record->expiration_time = expiration;
525 record->type = record_type;
526 record->class = GNUNET_DNSPARSER_CLASS_INTERNET; /* srsly? */
527
528 //FIXME authoritative answer if we find a result in namestore
529 if (flags == GNUNET_NAMESTORE_RF_AUTHORITY)
530 { 527 {
531 //query->num_authority_records++; 528 // A time will come when this has to be freed
529 qrecord = GNUNET_malloc(sizeof(struct GNUNET_GNS_QueryRecordList));
530 record = GNUNET_malloc(sizeof(struct GNUNET_DNSPARSER_Record));
531 qrecord->record = record;
532
533 //fixme into gns_util
534 //parse_record(rd[i]->data, rd[i]->data_size, 0, record);
535 GNUNET_CONTAINER_DLL_insert(query->records_head,
536 query->records_tail,
537 qrecord);
538 query->num_records++;
539
540 //TODO really?
541 //we need to resolve to the original name in the end though...
542 //record->name = (char*)query->original_name;
532 } 543 }
533 544
534 /**
535 * This seems to take into account that the result could
536 * be different in name and or record type...
537 * but to me this does not make sense
538 */
539 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Found answer to query!\n"); 545 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Found answer to query!\n");
540 query->answered = 1; 546 query->answered = 1;
541 547
542 query->num_records++; 548 reply_to_dns(query);
543
544 /**
545 * FIXME watch for leaks
546 * properly free pendingquery when the time comes
547 */
548 GNUNET_CONTAINER_DLL_insert(query->records_head,
549 query->records_tail,
550 qrecord);
551 } 549 }
552} 550}
553 551
@@ -749,40 +747,41 @@ put_some_records(void)
749 /* put a few records into namestore */ 747 /* put a few records into namestore */
750 char* ipA = "1.2.3.4"; 748 char* ipA = "1.2.3.4";
751 char* ipB = "5.6.7.8"; 749 char* ipB = "5.6.7.8";
752 struct in_addr *alice = GNUNET_malloc(sizeof(struct in_addr)); 750 GNUNET_GNS_Record *alice = GNUNET_malloc(sizeof(GNUNET_GNS_Record));
753 struct in_addr *bob = GNUNET_malloc(sizeof(struct in_addr)); 751 GNUNET_GNS_Record *bob = GNUNET_malloc(sizeof(GNUNET_GNS_Record));
754 GNUNET_assert(1 == inet_pton (AF_INET, ipA, alice)); 752 struct GNUNET_NAMESTORE_RecordData *rda = NULL;
755 GNUNET_assert(1 == inet_pton (AF_INET, ipB, bob)); 753 struct GNUNET_NAMESTORE_RecordData *rdb = NULL;
756 GNUNET_NAMESTORE_record_put (namestore_handle, 754 rda = GNUNET_malloc(sizeof(struct GNUNET_NAMESTORE_RecordData));
757 &zone_hash, 755
756 //FIXME here we would have to parse the gns record and put it into
757 //the rd struct
758
759 //FIXME this is not enough! but too mucht atm
760 GNUNET_assert(1 == inet_pton (AF_INET, ipA, alice->data.raw.data));
761 GNUNET_assert(1 == inet_pton (AF_INET, ipB, bob->data.raw.data));
762
763 GNUNET_NAMESTORE_record_create (namestore_handle,
764 zone_key,
758 "alice", 765 "alice",
759 GNUNET_GNS_RECORD_TYPE_A, 766 rda,
760 GNUNET_TIME_absolute_get_forever(),
761 GNUNET_NAMESTORE_RF_AUTHORITY,
762 sizeof(struct in_addr),
763 alice,
764 NULL, 767 NULL,
765 NULL); 768 NULL);
766 GNUNET_NAMESTORE_record_put (namestore_handle, 769 GNUNET_NAMESTORE_record_create (namestore_handle,
767 &zone_hash, 770 zone_key,
768 "bob", 771 "bob",
769 GNUNET_GNS_RECORD_TYPE_A, 772 rdb,
770 GNUNET_TIME_absolute_get_forever(),
771 GNUNET_NAMESTORE_RF_AUTHORITY,
772 sizeof(struct in_addr),
773 bob,
774 NULL, 773 NULL,
775 NULL); 774 NULL);
776} 775}
777 776
778//Prototype... needed in put function 777void
779static void 778update_zone_dht_next(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
780update_zone_dht(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); 779{
780 GNUNET_NAMESTORE_zone_iterator_next(namestore_iter);
781}
781 782
782/** 783/**
783 * Function used to put all records successively into the DHT. 784 * Function used to put all records successively into the DHT.
784 * FIXME also serializes records. maybe do this somewhere else...
785 * FIXME don't store private records (maybe zone transfer does this)
786 * 785 *
787 * @param cls the closure (NULL) 786 * @param cls the closure (NULL)
788 * @param zone our root zone hash 787 * @param zone our root zone hash
@@ -795,77 +794,37 @@ update_zone_dht(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
795 * @param record_data the record data 794 * @param record_data the record data
796 */ 795 */
797void 796void
798put_gns_record(void *cls, const GNUNET_HashCode *zone, const char *name, 797put_gns_record(void *cls,
799 uint32_t record_type, struct GNUNET_TIME_Absolute expiration, 798 const const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *key,
800 enum GNUNET_NAMESTORE_RecordFlags flags, 799 struct GNUNET_TIME_Absolute expiration,
801 size_t size, const void *record_data) 800 const char *name,
801 unsigned int rd_count,
802 const struct GNUNET_NAMESTORE_RecordData *rd,
803 const struct GNUNET_CRYPTO_RsaSignature *signature)
802{ 804{
803 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Putting a record into the DHT\n"); 805 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Putting records into the DHT\n");
804 struct GNUNET_TIME_Relative timeout; 806 struct GNUNET_TIME_Relative timeout;
805
806 char* data;
807 char* data_ptr;
808 struct GNUNET_TIME_AbsoluteNBO exp_nbo;
809 exp_nbo = GNUNET_TIME_absolute_hton (expiration);
810 uint32_t namelen = htonl(strlen(name));
811 uint16_t flags_nbo = htons(flags);
812 GNUNET_HashCode name_hash; 807 GNUNET_HashCode name_hash;
813 GNUNET_HashCode xor_hash; 808 GNUNET_HashCode xor_hash;
814 809
815 /** 810 if (NULL == name) //We're done
816 * I guess this can be done prettier 811 {
817 * FIXME extract into function, maybe even into different file 812 GNUNET_NAMESTORE_zone_iteration_stop (namestore_iter);
818 */ 813 return;
819 size_t record_len = sizeof(size_t) + sizeof(uint32_t) + 814 }
820 sizeof(uint16_t) +
821 sizeof(uint32_t) + strlen(name) + size;
822
823 record_type = htonl(record_type);
824
825 data = GNUNET_malloc(record_len);
826
827 /* -_- */
828 data_ptr = data;
829 memcpy(data_ptr, &namelen, sizeof(size_t));
830 data_ptr += sizeof(size_t);
831
832 memcpy(data_ptr, name, namelen);
833 data_ptr += namelen;
834
835 memcpy(data_ptr, &record_type, sizeof(uint32_t));
836 data_ptr += sizeof(uint32_t);
837
838 memcpy(data_ptr, &exp_nbo, sizeof(struct GNUNET_TIME_AbsoluteNBO));
839 data_ptr += sizeof(struct GNUNET_TIME_AbsoluteNBO);
840
841 memcpy(data_ptr, &flags_nbo, sizeof(uint16_t));
842 data_ptr += sizeof(uint16_t);
843
844 memcpy(data_ptr, &size, sizeof(uint32_t));
845 data_ptr += sizeof(uint32_t);
846
847 /**
848 * FIXME note that this only works with raw data in nbo
849 * write helper function that converts properly and returns buffer
850 */
851 memcpy(data_ptr, record_data, size);
852 data_ptr += size;
853 /*Doing this made me sad...*/
854
855 /** 815 /**
856 * FIXME magic number 20 move to config file 816 * FIXME magic number 20 move to config file
857 */ 817 */
858 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 20); 818 timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 20);
859
860 GNUNET_CRYPTO_hash(name, strlen(name), &name_hash); 819 GNUNET_CRYPTO_hash(name, strlen(name), &name_hash);
861 GNUNET_CRYPTO_hash_xor(&zone_hash, &name_hash, &xor_hash); 820 GNUNET_CRYPTO_hash_xor(&zone_hash, &name_hash, &xor_hash);
862 GNUNET_DHT_put (dht_handle, &xor_hash, 821 GNUNET_DHT_put (dht_handle, &xor_hash,
863 5, //replication level 822 5, //replication level
864 GNUNET_DHT_RO_NONE, 823 GNUNET_DHT_RO_NONE,
865 GNUNET_BLOCK_TYPE_TEST, //FIXME todo block plugin 824 GNUNET_BLOCK_TYPE_TEST, //FIXME todo block plugin
866 (data_ptr-data), 825 rd->data_size,
867 data, 826 rd->data,
868 expiration, //FIXME from record makes sense? is absolute? 827 expiration,
869 timeout, 828 timeout,
870 NULL, //FIXME continuation needed? success check? yes ofc 829 NULL, //FIXME continuation needed? success check? yes ofc
871 NULL); //cls for cont 830 NULL); //cls for cont
@@ -874,7 +833,7 @@ put_gns_record(void *cls, const GNUNET_HashCode *zone, const char *name,
874 * Reschedule periodic put 833 * Reschedule periodic put
875 */ 834 */
876 GNUNET_SCHEDULER_add_delayed (dht_update_interval, 835 GNUNET_SCHEDULER_add_delayed (dht_update_interval,
877 &update_zone_dht, 836 &update_zone_dht_next,
878 NULL); 837 NULL);
879 838
880} 839}
@@ -886,12 +845,17 @@ put_gns_record(void *cls, const GNUNET_HashCode *zone, const char *name,
886 * @param tc task context 845 * @param tc task context
887 */ 846 */
888static void 847static void
889update_zone_dht(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 848update_zone_dht_start(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
890{ 849{
891 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Update zone!\n"); 850 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Update zone!\n");
892 GNUNET_NAMESTORE_zone_transfer (namestore_handle, &zone_hash, 851 dht_update_interval = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS,
893 &put_gns_record, 852 (3600/num_public_records));
894 NULL); 853 namestore_iter = GNUNET_NAMESTORE_zone_iteration_start (namestore_handle,
854 &zone_hash,
855 GNUNET_NAMESTORE_RF_AUTHORITY,
856 GNUNET_NAMESTORE_RF_PRIVATE,
857 &put_gns_record,
858 NULL);
895} 859}
896 860
897/** 861/**
@@ -960,11 +924,12 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
960 /** 924 /**
961 * Schedule periodic put 925 * Schedule periodic put
962 * for our records 926 * for our records
927 * We have roughly an hour for all records;
963 */ 928 */
964 dht_update_interval = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 929 dht_update_interval = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS,
965 60); //FIXME from cfg 930 60); //FIXME from cfg
966 GNUNET_SCHEDULER_add_delayed (dht_update_interval, 931 GNUNET_SCHEDULER_add_delayed (dht_update_interval,
967 &update_zone_dht, 932 &update_zone_dht_start,
968 NULL); 933 NULL);
969 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "GNS Init done!\n"); 934 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "GNS Init done!\n");
970 935