aboutsummaryrefslogtreecommitdiff
path: root/src/setup/gnunet-setup-gns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/setup/gnunet-setup-gns.c')
-rw-r--r--src/setup/gnunet-setup-gns.c237
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 */
187struct OperationContext 187struct OperationContext
188{ 188{
@@ -206,6 +206,50 @@ struct OperationContext
206 206
207 207
208/** 208/**
209 * Closure for 'merge_with_existing_records'.
210 */
211struct 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 */
211struct RecordInfo 255struct RecordInfo
@@ -264,6 +308,16 @@ static struct OperationContext *oc_head;
264static struct OperationContext *oc_tail; 308static struct OperationContext *oc_tail;
265 309
266/** 310/**
311 * Head of linked list of active operations.
312 */
313static struct MoveOperationContext *moc_head;
314
315/**
316 * Tail of linked list of active operations.
317 */
318static struct MoveOperationContext *moc_tail;
319
320/**
267 * Name of our zone as a string. 321 * Name of our zone as a string.
268 */ 322 */
269static char *zone_as_string; 323static 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 */
621static int
622release_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 */
562static void 641static void
563clear_zone_view () 642clear_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 */
728static void
729merge_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 */
1804static int
1805release_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
1824GNUNET_SETUP_gns_done () 1953GNUNET_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,