diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-07-10 15:53:47 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-07-10 15:53:47 +0000 |
commit | 03c0c96010a94747b774def37aaed903ed21d5b9 (patch) | |
tree | 799d07d572db5fc59627d22555540b53202fc766 | |
parent | 740d5d09795fd087c11c7a4281d29425cc5ae866 (diff) | |
download | gnunet-gtk-03c0c96010a94747b774def37aaed903ed21d5b9.tar.gz gnunet-gtk-03c0c96010a94747b774def37aaed903ed21d5b9.zip |
-fix #2931
-rw-r--r-- | src/setup/gnunet-setup-gns.c | 237 |
1 files changed, 189 insertions, 48 deletions
diff --git a/src/setup/gnunet-setup-gns.c b/src/setup/gnunet-setup-gns.c index 5fddfaa3..a08033ee 100644 --- a/src/setup/gnunet-setup-gns.c +++ b/src/setup/gnunet-setup-gns.c | |||
@@ -182,7 +182,7 @@ enum LIST_COLUMNS | |||
182 | 182 | ||
183 | 183 | ||
184 | /** | 184 | /** |
185 | * Closure for 'check_name_validity_and_remove_proc'. | 185 | * Closure for 'operation_done_cont'. |
186 | */ | 186 | */ |
187 | struct OperationContext | 187 | struct OperationContext |
188 | { | 188 | { |
@@ -206,6 +206,50 @@ struct OperationContext | |||
206 | 206 | ||
207 | 207 | ||
208 | /** | 208 | /** |
209 | * Closure for 'merge_with_existing_records'. | ||
210 | */ | ||
211 | struct MoveOperationContext | ||
212 | { | ||
213 | |||
214 | /** | ||
215 | * Kept in a DLL. | ||
216 | */ | ||
217 | struct MoveOperationContext *next; | ||
218 | |||
219 | /** | ||
220 | * Kept in a DLL. | ||
221 | */ | ||
222 | struct MoveOperationContext *prev; | ||
223 | |||
224 | /** | ||
225 | * Associated namestore operation. | ||
226 | */ | ||
227 | struct GNUNET_NAMESTORE_QueueEntry *qe; | ||
228 | |||
229 | /** | ||
230 | * Info from editing dialog. | ||
231 | */ | ||
232 | struct EditDialogContext *edc; | ||
233 | |||
234 | /** | ||
235 | * Private key of target zone. | ||
236 | */ | ||
237 | struct GNUNET_CRYPTO_EccPrivateKey *pk; | ||
238 | |||
239 | /** | ||
240 | * Data to free. | ||
241 | */ | ||
242 | void *data; | ||
243 | |||
244 | /** | ||
245 | * Record to merge. | ||
246 | */ | ||
247 | struct GNUNET_NAMESTORE_RecordData rd; | ||
248 | |||
249 | }; | ||
250 | |||
251 | |||
252 | /** | ||
209 | * Information we keep per name. | 253 | * Information we keep per name. |
210 | */ | 254 | */ |
211 | struct RecordInfo | 255 | struct RecordInfo |
@@ -264,6 +308,16 @@ static struct OperationContext *oc_head; | |||
264 | static struct OperationContext *oc_tail; | 308 | static struct OperationContext *oc_tail; |
265 | 309 | ||
266 | /** | 310 | /** |
311 | * Head of linked list of active operations. | ||
312 | */ | ||
313 | static struct MoveOperationContext *moc_head; | ||
314 | |||
315 | /** | ||
316 | * Tail of linked list of active operations. | ||
317 | */ | ||
318 | static struct MoveOperationContext *moc_tail; | ||
319 | |||
320 | /** | ||
267 | * Name of our zone as a string. | 321 | * Name of our zone as a string. |
268 | */ | 322 | */ |
269 | static char *zone_as_string; | 323 | static char *zone_as_string; |
@@ -557,11 +611,39 @@ operation_done_cont (void *cls, | |||
557 | 611 | ||
558 | 612 | ||
559 | /** | 613 | /** |
614 | * Release the record info. | ||
615 | * | ||
616 | * @param cls NULL | ||
617 | * @param key unused | ||
618 | * @param value a RecordInfo to release | ||
619 | * @return GNUNET_OK (continue to iterate) | ||
620 | */ | ||
621 | static int | ||
622 | release_ri (void *cls, | ||
623 | const struct GNUNET_HashCode *key, | ||
624 | void *value) | ||
625 | { | ||
626 | struct RecordInfo *ri = value; | ||
627 | |||
628 | gtk_tree_row_reference_free (ri->rr); | ||
629 | GNUNET_free_non_null (ri->data); | ||
630 | GNUNET_free (ri->name); | ||
631 | GNUNET_break (GNUNET_YES == | ||
632 | GNUNET_CONTAINER_multihashmap_remove (n2r, key, ri)); | ||
633 | GNUNET_free (ri); | ||
634 | return GNUNET_OK; | ||
635 | } | ||
636 | |||
637 | |||
638 | /** | ||
560 | * Clear all entries in the zone view and hide the tree view. | 639 | * Clear all entries in the zone view and hide the tree view. |
561 | */ | 640 | */ |
562 | static void | 641 | static void |
563 | clear_zone_view () | 642 | clear_zone_view () |
564 | { | 643 | { |
644 | GNUNET_CONTAINER_multihashmap_iterate (n2r, | ||
645 | &release_ri, | ||
646 | NULL); | ||
565 | gtk_widget_hide (GTK_WIDGET (GNUNET_SETUP_get_object ("GNUNET_setup_gns_zone_selection_hbuttonbox"))); | 647 | gtk_widget_hide (GTK_WIDGET (GNUNET_SETUP_get_object ("GNUNET_setup_gns_zone_selection_hbuttonbox"))); |
566 | gtk_widget_show (GTK_WIDGET (GNUNET_SETUP_get_object ("GNUNET_setup_gns_status_label"))); | 648 | gtk_widget_show (GTK_WIDGET (GNUNET_SETUP_get_object ("GNUNET_setup_gns_status_label"))); |
567 | gtk_widget_hide (GTK_WIDGET (GNUNET_SETUP_get_object ("GNUNET_setup_gns_main_scrolledwindow"))); | 649 | gtk_widget_hide (GTK_WIDGET (GNUNET_SETUP_get_object ("GNUNET_setup_gns_main_scrolledwindow"))); |
@@ -626,6 +708,56 @@ free_edit_dialog_context (struct EditDialogContext *edc) | |||
626 | } | 708 | } |
627 | 709 | ||
628 | 710 | ||
711 | |||
712 | /** | ||
713 | * Process a record that was stored in the namestore. | ||
714 | * | ||
715 | * @param cls closure | ||
716 | * @param zone_key public key of the zone | ||
717 | * @param freshness when does the corresponding block in the DHT expire (until | ||
718 | * when should we never do a DHT lookup for the same name again)?; | ||
719 | * GNUNET_TIME_UNIT_ZERO_ABS if there are no records of any type in the namestore, | ||
720 | * or the expiration time of the block in the namestore (even if there are zero | ||
721 | * records matching the desired record type) | ||
722 | * @param name name that is being mapped (at most 255 characters long) | ||
723 | * @param rd_count number of entries in 'rd' array | ||
724 | * @param rd array of records with data to store | ||
725 | * @param signature signature of the record block, NULL if signature is unavailable (i.e. | ||
726 | * because the user queried for a particular record type only) | ||
727 | */ | ||
728 | static void | ||
729 | merge_with_existing_records (void *cls, | ||
730 | const struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded *zone_key, | ||
731 | struct GNUNET_TIME_Absolute freshness, | ||
732 | const char *name, | ||
733 | unsigned int rd_count, | ||
734 | const struct GNUNET_NAMESTORE_RecordData *rd, | ||
735 | const struct GNUNET_CRYPTO_EccSignature *signature) | ||
736 | { | ||
737 | struct MoveOperationContext *moc = cls; | ||
738 | struct EditDialogContext *edc = moc->edc; | ||
739 | struct GNUNET_NAMESTORE_RecordData rd_new[rd_count + 1]; | ||
740 | struct OperationContext *oc; | ||
741 | |||
742 | GNUNET_CONTAINER_DLL_remove (moc_head, moc_tail, moc); | ||
743 | memcpy (rd_new, rd, rd_count * sizeof (struct GNUNET_NAMESTORE_RecordData)); | ||
744 | rd_new[rd_count] = moc->rd; | ||
745 | /* FIXME: sanity-check merge... */ | ||
746 | oc = GNUNET_new (struct OperationContext); | ||
747 | GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc); | ||
748 | oc->qe = GNUNET_NAMESTORE_record_put_by_authority (namestore, | ||
749 | moc->pk, | ||
750 | edc->name, | ||
751 | rd_count + 1, | ||
752 | rd_new, | ||
753 | &operation_done_cont, oc); | ||
754 | GNUNET_CRYPTO_ecc_key_free (moc->pk); | ||
755 | GNUNET_free (moc->data); | ||
756 | GNUNET_free (moc); | ||
757 | free_edit_dialog_context (edc); | ||
758 | } | ||
759 | |||
760 | |||
629 | /** | 761 | /** |
630 | * The edit dialog completed; update the namestore and the | 762 | * The edit dialog completed; update the namestore and the |
631 | * view based on the new values in 'edc'. | 763 | * view based on the new values in 'edc'. |
@@ -745,26 +877,11 @@ edit_dialog_continuation (struct EditDialogContext *edc, | |||
745 | { | 877 | { |
746 | char *keyfile; | 878 | char *keyfile; |
747 | struct GNUNET_CRYPTO_EccPrivateKey *pk; | 879 | struct GNUNET_CRYPTO_EccPrivateKey *pk; |
748 | 880 | struct MoveOperationContext *moc; | |
749 | /* zone changed, remove record from old zone, add to new zone! */ | 881 | struct GNUNET_CRYPTO_ShortHashCode target_zone_hash; |
750 | if (GNUNET_YES == edc->old_record_in_namestore) | 882 | struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded pubkey; |
751 | { | 883 | |
752 | /* remove item from tree view and namestore */ | 884 | /* determine target zone */ |
753 | struct GNUNET_NAMESTORE_RecordData rd_new[rd_count - 1]; | ||
754 | |||
755 | GNUNET_assert (NULL != ri); | ||
756 | memcpy (rd_new, rd_old, (rd_count - 1) * sizeof (struct GNUNET_NAMESTORE_RecordData)); | ||
757 | rd_new[edc->off] = rd_old[rd_count - 1]; | ||
758 | oc = GNUNET_new (struct OperationContext); | ||
759 | GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc); | ||
760 | oc->qe = GNUNET_NAMESTORE_record_put_by_authority (namestore, | ||
761 | pkey, edc->name, | ||
762 | rd_count + 1, | ||
763 | rd_new, | ||
764 | &operation_done_cont, oc); | ||
765 | } | ||
766 | |||
767 | /* now add item to target zone */ | ||
768 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, | 885 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, |
769 | "gns", | 886 | "gns", |
770 | edc->new_zone_option, | 887 | edc->new_zone_option, |
@@ -787,10 +904,41 @@ edit_dialog_continuation (struct EditDialogContext *edc, | |||
787 | NULL); | 904 | NULL); |
788 | break; | 905 | break; |
789 | } | 906 | } |
790 | GNUNET_break (0); // not implemented | 907 | GNUNET_CRYPTO_ecc_key_get_public (pk, &pubkey); |
791 | /* FIXME: get target zone records, merge with new one, commit! */ | 908 | GNUNET_CRYPTO_short_hash (&pubkey, |
792 | GNUNET_CRYPTO_ecc_key_free (pk); | 909 | sizeof (struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded), |
793 | break; | 910 | &target_zone_hash); |
911 | moc = GNUNET_new (struct MoveOperationContext); | ||
912 | moc->data = data; | ||
913 | moc->rd = rd; | ||
914 | moc->edc = edc; | ||
915 | moc->pk = pk; | ||
916 | GNUNET_CONTAINER_DLL_insert (moc_head, moc_tail, moc); | ||
917 | moc->qe = GNUNET_NAMESTORE_lookup_record (namestore, | ||
918 | &target_zone_hash, | ||
919 | edc->name, | ||
920 | 0 /* all */, | ||
921 | &merge_with_existing_records, | ||
922 | moc); | ||
923 | /* zone changed, remove record from old zone, add to new zone! */ | ||
924 | if (GNUNET_YES == edc->old_record_in_namestore) | ||
925 | { | ||
926 | /* remove item from tree view and namestore */ | ||
927 | struct GNUNET_NAMESTORE_RecordData rd_new[rd_count - 1]; | ||
928 | |||
929 | GNUNET_assert (NULL != ri); | ||
930 | memcpy (rd_new, rd_old, (rd_count - 1) * sizeof (struct GNUNET_NAMESTORE_RecordData)); | ||
931 | rd_new[edc->off] = rd_old[rd_count - 1]; | ||
932 | oc = GNUNET_new (struct OperationContext); | ||
933 | GNUNET_CONTAINER_DLL_insert (oc_head, oc_tail, oc); | ||
934 | oc->qe = GNUNET_NAMESTORE_record_put_by_authority (namestore, | ||
935 | pkey, edc->name, | ||
936 | rd_count - 1, | ||
937 | rd_new, | ||
938 | &operation_done_cont, oc); | ||
939 | |||
940 | } | ||
941 | return; | ||
794 | } | 942 | } |
795 | break; | 943 | break; |
796 | default: | 944 | default: |
@@ -840,6 +988,10 @@ launch_edit_dialog (gint n_type, | |||
840 | edc->n_exp_time = rd_old[off].expiration_time; | 988 | edc->n_exp_time = rd_old[off].expiration_time; |
841 | edc->old_record_in_namestore = GNUNET_YES; | 989 | edc->old_record_in_namestore = GNUNET_YES; |
842 | } | 990 | } |
991 | else | ||
992 | { | ||
993 | edc->n_exp_time = 1000LL * (time (NULL) + 365 * 24 * 60 * 60); /* + 1y */ | ||
994 | } | ||
843 | edc->ri = ri; | 995 | edc->ri = ri; |
844 | edc->off = off; | 996 | edc->off = off; |
845 | edc->name = GNUNET_strdup (name); | 997 | edc->name = GNUNET_strdup (name); |
@@ -1794,29 +1946,6 @@ GNUNET_SETUP_gns_init () | |||
1794 | 1946 | ||
1795 | 1947 | ||
1796 | /** | 1948 | /** |
1797 | * Release the record info. | ||
1798 | * | ||
1799 | * @param cls NULL | ||
1800 | * @param key unused | ||
1801 | * @param value a RecordInfo to release | ||
1802 | * @return GNUNET_OK (continue to iterate) | ||
1803 | */ | ||
1804 | static int | ||
1805 | release_ri (void *cls, | ||
1806 | const struct GNUNET_HashCode *key, | ||
1807 | void *value) | ||
1808 | { | ||
1809 | struct RecordInfo *ri = value; | ||
1810 | |||
1811 | gtk_tree_row_reference_free (ri->rr); | ||
1812 | GNUNET_free_non_null (ri->data); | ||
1813 | GNUNET_free (ri->name); | ||
1814 | GNUNET_free (ri); | ||
1815 | return GNUNET_OK; | ||
1816 | } | ||
1817 | |||
1818 | |||
1819 | /** | ||
1820 | * Disconnect from the namestore and clean up the main | 1949 | * Disconnect from the namestore and clean up the main |
1821 | * GNS tree view. | 1950 | * GNS tree view. |
1822 | */ | 1951 | */ |
@@ -1824,6 +1953,7 @@ void | |||
1824 | GNUNET_SETUP_gns_done () | 1953 | GNUNET_SETUP_gns_done () |
1825 | { | 1954 | { |
1826 | struct OperationContext *oc; | 1955 | struct OperationContext *oc; |
1956 | struct MoveOperationContext *moc; | ||
1827 | 1957 | ||
1828 | gtk_widget_show (GTK_WIDGET (GNUNET_SETUP_get_object ("GNUNET_setup_gns_status_label"))); | 1958 | gtk_widget_show (GTK_WIDGET (GNUNET_SETUP_get_object ("GNUNET_setup_gns_status_label"))); |
1829 | gtk_widget_hide (GTK_WIDGET (GNUNET_SETUP_get_object ("GNUNET_setup_gns_main_scrolledwindow"))); | 1959 | gtk_widget_hide (GTK_WIDGET (GNUNET_SETUP_get_object ("GNUNET_setup_gns_main_scrolledwindow"))); |
@@ -1840,6 +1970,17 @@ GNUNET_SETUP_gns_done () | |||
1840 | GNUNET_NAMESTORE_cancel (oc->qe); | 1970 | GNUNET_NAMESTORE_cancel (oc->qe); |
1841 | GNUNET_free (oc); | 1971 | GNUNET_free (oc); |
1842 | } | 1972 | } |
1973 | while (NULL != (moc = moc_head)) | ||
1974 | { | ||
1975 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1976 | _("A pending namestore operation was not transmitted to the namestore.\n")); | ||
1977 | GNUNET_CONTAINER_DLL_remove (moc_head, moc_tail, moc); | ||
1978 | GNUNET_NAMESTORE_cancel (moc->qe); | ||
1979 | GNUNET_CRYPTO_ecc_key_free (moc->pk); | ||
1980 | free_edit_dialog_context (moc->edc); | ||
1981 | GNUNET_free (moc->data); | ||
1982 | GNUNET_free (moc); | ||
1983 | } | ||
1843 | if (NULL != n2r) | 1984 | if (NULL != n2r) |
1844 | { | 1985 | { |
1845 | GNUNET_CONTAINER_multihashmap_iterate (n2r, | 1986 | GNUNET_CONTAINER_multihashmap_iterate (n2r, |