diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-02-22 12:30:47 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-02-22 12:30:47 +0000 |
commit | c5f55d213332c2bfd6668d0da0b05d2ebe53a8df (patch) | |
tree | 0b29b65c9aea98608180d4dd670ea9bb08fb1c12 /src/namestore/plugin_namestore_sqlite.c | |
parent | 52ab0e8c9a2f62cb5cb1eb90a5258a985a3999f4 (diff) | |
download | gnunet-c5f55d213332c2bfd6668d0da0b05d2ebe53a8df.tar.gz gnunet-c5f55d213332c2bfd6668d0da0b05d2ebe53a8df.zip |
-namestore might just work now
Diffstat (limited to 'src/namestore/plugin_namestore_sqlite.c')
-rw-r--r-- | src/namestore/plugin_namestore_sqlite.c | 215 |
1 files changed, 140 insertions, 75 deletions
diff --git a/src/namestore/plugin_namestore_sqlite.c b/src/namestore/plugin_namestore_sqlite.c index 10ee62403..9a218f4bc 100644 --- a/src/namestore/plugin_namestore_sqlite.c +++ b/src/namestore/plugin_namestore_sqlite.c | |||
@@ -362,7 +362,7 @@ database_setup (struct Plugin *plugin) | |||
362 | &plugin->iterate_records) != SQLITE_OK) || | 362 | &plugin->iterate_records) != SQLITE_OK) || |
363 | (sq_prepare | 363 | (sq_prepare |
364 | (plugin->dbh, | 364 | (plugin->dbh, |
365 | "SELECT node_parent_offset,node_hashcodes FROM ns090nodes " | 365 | "SELECT node_parent_offset,node_location_offset,node_hashcodes FROM ns090nodes " |
366 | "WHERE zone_hash=? AND zone_revision=? AND node_location_depth=? AND node_location_offset<=? ORDER BY node_location_offset DESC LIMIT 1", | 366 | "WHERE zone_hash=? AND zone_revision=? AND node_location_depth=? AND node_location_offset<=? ORDER BY node_location_offset DESC LIMIT 1", |
367 | &plugin->get_node) != SQLITE_OK) || | 367 | &plugin->get_node) != SQLITE_OK) || |
368 | (sq_prepare | 368 | (sq_prepare |
@@ -585,77 +585,6 @@ namestore_sqlite_put_node (void *cls, | |||
585 | } | 585 | } |
586 | } | 586 | } |
587 | 587 | ||
588 | |||
589 | /** | ||
590 | * Store a zone signature in the datastore. If a signature for the zone with a | ||
591 | * lower depth exists, the old signature is removed. If a signature for an | ||
592 | * older revision of the zone exists, this will delete all records, nodes | ||
593 | * and signatures for the older revision of the zone. | ||
594 | * | ||
595 | * @param cls closure (internal context for the plugin) | ||
596 | * @param zone_key public key of the zone | ||
597 | * @param loc location in the B-tree (top of the tree, offset 0, depth at 'maximum') | ||
598 | * @param top_sig signature at the top, NULL if 'loc.depth > 0' | ||
599 | * @param root_hash top level hash that is signed | ||
600 | * @param zone_time time the zone was signed | ||
601 | * @return GNUNET_OK on success | ||
602 | */ | ||
603 | static int | ||
604 | namestore_sqlite_put_signature (void *cls, | ||
605 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, | ||
606 | const struct GNUNET_NAMESTORE_SignatureLocation *loc, | ||
607 | const struct GNUNET_CRYPTO_RsaSignature *top_sig, | ||
608 | const GNUNET_HashCode *root_hash, | ||
609 | struct GNUNET_TIME_Absolute zone_time) | ||
610 | { | ||
611 | struct Plugin *plugin = cls; | ||
612 | int n; | ||
613 | GNUNET_HashCode zone; | ||
614 | |||
615 | GNUNET_CRYPTO_hash (zone_key, | ||
616 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | ||
617 | &zone); | ||
618 | /* FIXME: get "old" signature, if older revision, delete all existing | ||
619 | records/nodes for the zone, if same revision, delete only the signature */ | ||
620 | |||
621 | |||
622 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->put_signature, 1, &zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || | ||
623 | (SQLITE_OK != sqlite3_bind_int (plugin->put_signature, 2, loc->revision)) || | ||
624 | (SQLITE_OK != sqlite3_bind_int64 (plugin->put_signature, 3, zone_time.abs_value)) || | ||
625 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_signature, 4, root_hash, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || | ||
626 | (SQLITE_OK != sqlite3_bind_int (plugin->put_signature, 5, loc->depth)) || | ||
627 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_signature, 6, zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), SQLITE_STATIC))|| | ||
628 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_signature, 7, top_sig, sizeof (struct GNUNET_CRYPTO_RsaSignature), SQLITE_STATIC)) ) | ||
629 | { | ||
630 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
631 | "sqlite3_bind_XXXX"); | ||
632 | if (SQLITE_OK != sqlite3_reset (plugin->put_signature)) | ||
633 | LOG_SQLITE (plugin, | ||
634 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
635 | "sqlite3_reset"); | ||
636 | return GNUNET_SYSERR; | ||
637 | |||
638 | } | ||
639 | n = sqlite3_step (plugin->put_signature); | ||
640 | if (SQLITE_OK != sqlite3_reset (plugin->put_signature)) | ||
641 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
642 | "sqlite3_reset"); | ||
643 | switch (n) | ||
644 | { | ||
645 | case SQLITE_DONE: | ||
646 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Signature stored\n"); | ||
647 | return GNUNET_OK; | ||
648 | case SQLITE_BUSY: | ||
649 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, | ||
650 | "sqlite3_step"); | ||
651 | return GNUNET_NO; | ||
652 | default: | ||
653 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
654 | "sqlite3_step"); | ||
655 | return GNUNET_SYSERR; | ||
656 | } | ||
657 | } | ||
658 | |||
659 | 588 | ||
660 | /** | 589 | /** |
661 | * Iterate over the results for a particular key and zone in the | 590 | * Iterate over the results for a particular key and zone in the |
@@ -745,6 +674,7 @@ namestore_sqlite_get_node (void *cls, | |||
745 | size_t hashcodes_size; | 674 | size_t hashcodes_size; |
746 | const GNUNET_HashCode *hashcodes; | 675 | const GNUNET_HashCode *hashcodes; |
747 | struct GNUNET_NAMESTORE_SignatureLocation ploc; | 676 | struct GNUNET_NAMESTORE_SignatureLocation ploc; |
677 | struct GNUNET_NAMESTORE_SignatureLocation rloc; | ||
748 | 678 | ||
749 | GNUNET_assert (NULL != cb); | 679 | GNUNET_assert (NULL != cb); |
750 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->get_node, 1, zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || | 680 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->get_node, 1, zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || |
@@ -761,14 +691,17 @@ namestore_sqlite_get_node (void *cls, | |||
761 | return GNUNET_SYSERR; | 691 | return GNUNET_SYSERR; |
762 | 692 | ||
763 | } | 693 | } |
694 | rloc.revision = loc->revision; | ||
695 | rloc.depth = loc->depth; | ||
764 | ploc.revision = loc->revision; | 696 | ploc.revision = loc->revision; |
765 | ploc.depth = loc->depth + 1; | 697 | ploc.depth = loc->depth + 1; |
766 | ret = GNUNET_NO; | 698 | ret = GNUNET_NO; |
767 | if (SQLITE_ROW == (ret = sqlite3_step (plugin->get_node))) | 699 | if (SQLITE_ROW == (ret = sqlite3_step (plugin->get_node))) |
768 | { | 700 | { |
769 | ploc.offset = sqlite3_column_int64 (plugin->get_node, 1); | 701 | ploc.offset = sqlite3_column_int64 (plugin->get_node, 1); |
770 | hashcodes = sqlite3_column_blob (plugin->get_node, 2); | 702 | rloc.offset = sqlite3_column_int64 (plugin->get_node, 2); |
771 | hashcodes_size = sqlite3_column_bytes (plugin->get_node, 2); | 703 | hashcodes = sqlite3_column_blob (plugin->get_node, 3); |
704 | hashcodes_size = sqlite3_column_bytes (plugin->get_node, 3); | ||
772 | if (0 != (hashcodes_size % sizeof (GNUNET_HashCode))) | 705 | if (0 != (hashcodes_size % sizeof (GNUNET_HashCode))) |
773 | { | 706 | { |
774 | GNUNET_break (0); | 707 | GNUNET_break (0); |
@@ -779,7 +712,7 @@ namestore_sqlite_get_node (void *cls, | |||
779 | ret = GNUNET_OK; | 712 | ret = GNUNET_OK; |
780 | cb (cb_cls, | 713 | cb (cb_cls, |
781 | zone, | 714 | zone, |
782 | loc, | 715 | &rloc, |
783 | &ploc, | 716 | &ploc, |
784 | hashcodes_size / sizeof (GNUNET_HashCode), | 717 | hashcodes_size / sizeof (GNUNET_HashCode), |
785 | hashcodes); | 718 | hashcodes); |
@@ -927,6 +860,138 @@ namestore_sqlite_delete_zone (void *cls, | |||
927 | 860 | ||
928 | 861 | ||
929 | /** | 862 | /** |
863 | * Context for 'delete_old_zone_information'. | ||
864 | */ | ||
865 | struct DeleteContext | ||
866 | { | ||
867 | /** | ||
868 | * Plugin handle. | ||
869 | */ | ||
870 | struct Plugin *plugin; | ||
871 | |||
872 | /** | ||
873 | * Hash of the public key of the zone (to avoid having to | ||
874 | * recalculate it). | ||
875 | */ | ||
876 | const GNUNET_HashCode *zone; | ||
877 | |||
878 | /** | ||
879 | * Revision to compare against. | ||
880 | */ | ||
881 | uint32_t revision; | ||
882 | |||
883 | }; | ||
884 | |||
885 | |||
886 | /** | ||
887 | * Function called on the current signature in the database for | ||
888 | * a zone. If the revision given in the closure is more recent, | ||
889 | * delete all information about the zone. Otherwise, only delete | ||
890 | * the signature. | ||
891 | * | ||
892 | * @param cls a 'struct DeleteContext' with a revision to compare against | ||
893 | * @param zone public key of the zone | ||
894 | * @param loc location of the root in the B-tree (depth, revision) | ||
895 | * @param top_sig signature signing the zone | ||
896 | * @param zone_time time the signature was created | ||
897 | * @param root_hash top level hash that is being signed | ||
898 | */ | ||
899 | static void | ||
900 | delete_old_zone_information (void *cls, | ||
901 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, | ||
902 | const struct GNUNET_NAMESTORE_SignatureLocation *loc, | ||
903 | const struct GNUNET_CRYPTO_RsaSignature *top_sig, | ||
904 | struct GNUNET_TIME_Absolute zone_time, | ||
905 | const GNUNET_HashCode *root_hash) | ||
906 | { | ||
907 | struct DeleteContext *dc = cls; | ||
908 | |||
909 | run_delete_statement (dc->plugin, dc->zone, dc->plugin->delete_zone_signatures); | ||
910 | if (loc->revision == dc->revision) | ||
911 | return; | ||
912 | run_delete_statement (dc->plugin, dc->zone, dc->plugin->delete_zone_records); | ||
913 | run_delete_statement (dc->plugin, dc->zone, dc->plugin->delete_zone_nodes); | ||
914 | } | ||
915 | |||
916 | |||
917 | /** | ||
918 | * Store a zone signature in the datastore. If a signature for the zone with a | ||
919 | * lower depth exists, the old signature is removed. If a signature for an | ||
920 | * older revision of the zone exists, this will delete all records, nodes | ||
921 | * and signatures for the older revision of the zone. | ||
922 | * | ||
923 | * @param cls closure (internal context for the plugin) | ||
924 | * @param zone_key public key of the zone | ||
925 | * @param loc location in the B-tree (top of the tree, offset 0, depth at 'maximum') | ||
926 | * @param top_sig signature at the top, NULL if 'loc.depth > 0' | ||
927 | * @param root_hash top level hash that is signed | ||
928 | * @param zone_time time the zone was signed | ||
929 | * @return GNUNET_OK on success | ||
930 | */ | ||
931 | static int | ||
932 | namestore_sqlite_put_signature (void *cls, | ||
933 | const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *zone_key, | ||
934 | const struct GNUNET_NAMESTORE_SignatureLocation *loc, | ||
935 | const struct GNUNET_CRYPTO_RsaSignature *top_sig, | ||
936 | const GNUNET_HashCode *root_hash, | ||
937 | struct GNUNET_TIME_Absolute zone_time) | ||
938 | { | ||
939 | struct Plugin *plugin = cls; | ||
940 | int n; | ||
941 | GNUNET_HashCode zone; | ||
942 | struct DeleteContext dc; | ||
943 | |||
944 | GNUNET_CRYPTO_hash (zone_key, | ||
945 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | ||
946 | &zone); | ||
947 | /* get "old" signature, if older revision, delete all existing | ||
948 | records/nodes for the zone, if same revision, delete only the signature */ | ||
949 | dc.plugin = plugin; | ||
950 | dc.zone = &zone; | ||
951 | dc.revision = loc->revision; | ||
952 | (void) namestore_sqlite_get_signature (plugin, | ||
953 | &zone, | ||
954 | &delete_old_zone_information, | ||
955 | &dc); | ||
956 | if ((SQLITE_OK != sqlite3_bind_blob (plugin->put_signature, 1, &zone, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || | ||
957 | (SQLITE_OK != sqlite3_bind_int (plugin->put_signature, 2, loc->revision)) || | ||
958 | (SQLITE_OK != sqlite3_bind_int64 (plugin->put_signature, 3, zone_time.abs_value)) || | ||
959 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_signature, 4, root_hash, sizeof (GNUNET_HashCode), SQLITE_STATIC)) || | ||
960 | (SQLITE_OK != sqlite3_bind_int (plugin->put_signature, 5, loc->depth)) || | ||
961 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_signature, 6, zone_key, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), SQLITE_STATIC))|| | ||
962 | (SQLITE_OK != sqlite3_bind_blob (plugin->put_signature, 7, top_sig, sizeof (struct GNUNET_CRYPTO_RsaSignature), SQLITE_STATIC)) ) | ||
963 | { | ||
964 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
965 | "sqlite3_bind_XXXX"); | ||
966 | if (SQLITE_OK != sqlite3_reset (plugin->put_signature)) | ||
967 | LOG_SQLITE (plugin, | ||
968 | GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
969 | "sqlite3_reset"); | ||
970 | return GNUNET_SYSERR; | ||
971 | |||
972 | } | ||
973 | n = sqlite3_step (plugin->put_signature); | ||
974 | if (SQLITE_OK != sqlite3_reset (plugin->put_signature)) | ||
975 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
976 | "sqlite3_reset"); | ||
977 | switch (n) | ||
978 | { | ||
979 | case SQLITE_DONE: | ||
980 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Signature stored\n"); | ||
981 | return GNUNET_OK; | ||
982 | case SQLITE_BUSY: | ||
983 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, | ||
984 | "sqlite3_step"); | ||
985 | return GNUNET_NO; | ||
986 | default: | ||
987 | LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, | ||
988 | "sqlite3_step"); | ||
989 | return GNUNET_SYSERR; | ||
990 | } | ||
991 | } | ||
992 | |||
993 | |||
994 | /** | ||
930 | * Entry point for the plugin. | 995 | * Entry point for the plugin. |
931 | * | 996 | * |
932 | * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*" | 997 | * @param cls the "struct GNUNET_NAMESTORE_PluginEnvironment*" |