2 This file is part of GNUnet.
3 Copyright (C) 2009, 2010, 2012, 2013 GNUnet e.V.
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
22 * @file fs/fs_publish_ksk.c
23 * @brief publish a URI under a keyword in GNUnet
24 * @see https://gnunet.org/encoding and #2564
25 * @author Krista Bennett
26 * @author Christian Grothoff
30 #include "gnunet_constants.h"
31 #include "gnunet_signatures.h"
32 #include "gnunet_util_lib.h"
33 #include "gnunet_fs_service.h"
36 #include "fs_publish_ublock.h"
39 * Context for the KSK publication.
41 struct GNUNET_FS_PublishKskContext {
45 struct GNUNET_FS_Uri *ksk_uri;
50 struct GNUNET_FS_Uri *uri;
55 struct GNUNET_CONTAINER_MetaData *meta;
60 struct GNUNET_FS_Handle *h;
63 * UBlock publishing operation that is active.
65 struct GNUNET_FS_PublishUblockContext *uc;
68 * Handle to the datastore, NULL if we are just simulating.
70 struct GNUNET_DATASTORE_Handle *dsh;
75 struct GNUNET_SCHEDULER_Task * ksk_task;
78 * Function to call once we're done.
80 GNUNET_FS_PublishContinuation cont;
88 * When should the KBlocks expire?
90 struct GNUNET_FS_BlockOptions bo;
95 enum GNUNET_FS_PublishOptions options;
98 * Keyword that we are currently processing.
105 * Continuation of #GNUNET_FS_publish_ksk() that performs
106 * the actual publishing operation (iterating over all
109 * @param cls closure of type `struct PublishKskContext *`
112 publish_ksk_cont(void *cls);
116 * Function called by the datastore API with
117 * the result from the PUT request.
119 * @param cls closure of type `struct GNUNET_FS_PublishKskContext *`
120 * @param msg error message (or NULL)
123 kb_put_cont(void *cls,
126 struct GNUNET_FS_PublishKskContext *pkc = cls;
131 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
132 "KBlock PUT operation failed: %s\n", msg);
133 pkc->cont(pkc->cont_cls, NULL, msg);
134 GNUNET_FS_publish_ksk_cancel(pkc);
137 pkc->ksk_task = GNUNET_SCHEDULER_add_now(&publish_ksk_cont, pkc);
142 * Continuation of #GNUNET_FS_publish_ksk() that performs the actual
143 * publishing operation (iterating over all of the keywords).
145 * @param cls closure of type `struct GNUNET_FS_PublishKskContext *`
148 publish_ksk_cont(void *cls)
150 struct GNUNET_FS_PublishKskContext *pkc = cls;
153 pkc->ksk_task = NULL;
154 if ((pkc->i == pkc->ksk_uri->data.ksk.keywordCount) ||
157 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
158 "KSK PUT operation complete\n");
159 pkc->cont(pkc->cont_cls, pkc->ksk_uri,
161 GNUNET_FS_publish_ksk_cancel(pkc);
164 keyword = pkc->ksk_uri->data.ksk.keywords[pkc->i++];
165 pkc->uc = GNUNET_FS_publish_ublock_(pkc->h,
167 keyword + 1 /* skip '+' */,
169 GNUNET_CRYPTO_ecdsa_key_get_anonymous(),
179 * Publish a CHK under various keywords on GNUnet.
181 * @param h handle to the file sharing subsystem
182 * @param ksk_uri keywords to use
183 * @param meta metadata to use
184 * @param uri URI to refer to in the KBlock
185 * @param bo per-block options
186 * @param options publication options
187 * @param cont continuation
188 * @param cont_cls closure for cont
189 * @return NULL on error ('cont' will still be called)
191 struct GNUNET_FS_PublishKskContext *
192 GNUNET_FS_publish_ksk(struct GNUNET_FS_Handle *h,
193 const struct GNUNET_FS_Uri *ksk_uri,
194 const struct GNUNET_CONTAINER_MetaData *meta,
195 const struct GNUNET_FS_Uri *uri,
196 const struct GNUNET_FS_BlockOptions *bo,
197 enum GNUNET_FS_PublishOptions options,
198 GNUNET_FS_PublishContinuation cont, void *cont_cls)
200 struct GNUNET_FS_PublishKskContext *pkc;
202 GNUNET_assert(NULL != uri);
203 pkc = GNUNET_new(struct GNUNET_FS_PublishKskContext);
206 pkc->options = options;
208 pkc->cont_cls = cont_cls;
209 pkc->meta = GNUNET_CONTAINER_meta_data_duplicate(meta);
210 if (0 == (options & GNUNET_FS_PUBLISH_OPTION_SIMULATE_ONLY))
212 pkc->dsh = GNUNET_DATASTORE_connect(h->cfg);
213 if (NULL == pkc->dsh)
217 _("Could not connect to datastore."));
222 pkc->uri = GNUNET_FS_uri_dup(uri);
223 pkc->ksk_uri = GNUNET_FS_uri_dup(ksk_uri);
224 pkc->ksk_task = GNUNET_SCHEDULER_add_now(&publish_ksk_cont, pkc);
230 * Abort the KSK publishing operation.
232 * @param pkc context of the operation to abort.
235 GNUNET_FS_publish_ksk_cancel(struct GNUNET_FS_PublishKskContext *pkc)
237 if (NULL != pkc->ksk_task)
239 GNUNET_SCHEDULER_cancel(pkc->ksk_task);
240 pkc->ksk_task = NULL;
244 GNUNET_FS_publish_ublock_cancel_(pkc->uc);
247 if (NULL != pkc->dsh)
249 GNUNET_DATASTORE_disconnect(pkc->dsh, GNUNET_NO);
252 GNUNET_CONTAINER_meta_data_destroy(pkc->meta);
253 GNUNET_FS_uri_destroy(pkc->ksk_uri);
254 GNUNET_FS_uri_destroy(pkc->uri);
259 /* end of fs_publish_ksk.c */