GNUnet 0.26.2-125-g53de64302
 
Loading...
Searching...
No Matches
json_gnsrecord.c
Go to the documentation of this file.
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2009-2013 GNUnet e.V.
4
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.
9
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.
14
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/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
26#include "platform.h"
27#include "gnunet_util_lib.h"
28#include "gnunet_json_lib.h"
31
32#define GNUNET_JSON_GNSRECORD_VALUE "value"
33#define GNUNET_JSON_GNSRECORD_RECORD_DATA "data"
34#define GNUNET_JSON_GNSRECORD_TYPE "record_type"
35#define GNUNET_JSON_GNSRECORD_RELATIVE_EXPIRATION_TIME "relative_expiration"
36#define GNUNET_JSON_GNSRECORD_ABSOLUTE_EXPIRATION_TIME "absolute_expiration"
37#define GNUNET_JSON_GNSRECORD_FLAG_MAINTENANCE "is_maintenance"
38#define GNUNET_JSON_GNSRECORD_FLAG_PRIVATE "is_private"
39#define GNUNET_JSON_GNSRECORD_FLAG_SUPPLEMENTAL "is_supplemental"
40#define GNUNET_JSON_GNSRECORD_FLAG_RELATIVE "is_relative_expiration"
41#define GNUNET_JSON_GNSRECORD_FLAG_SHADOW "is_shadow"
42#define GNUNET_JSON_GNSRECORD_RECORD_NAME "record_name"
43
45{
46 char **name;
47
48 unsigned int *rd_count;
49
51};
52
53
54static void
55cleanup_recordinfo (struct GnsRecordInfo *gnsrecord_info)
56{
57 if (NULL != *(gnsrecord_info->rd))
58 {
59 for (int i = 0; i < *(gnsrecord_info->rd_count); i++)
60 {
61 char *tmp;
62
63 tmp = (char*) (*(gnsrecord_info->rd))[i].data;
64 GNUNET_free (tmp);
65 }
66 GNUNET_free (*(gnsrecord_info->rd));
67 }
68 GNUNET_free (*(gnsrecord_info->name));
69}
70
71
80static int
82{
83 struct GNUNET_TIME_Absolute abs_exp;
84 struct GNUNET_TIME_Relative rel_exp;
85 const char *value;
86 const char *record_type;
87 int maintenance;
88 int private;
89 int supplemental;
90 int is_rel_exp;
91 int shadow;
92 int unpack_state = 0;
93 json_error_t err;
94
95 // interpret single gns record
96 unpack_state = json_unpack_ex (data,
97 &err,
98 0,
99 "{s:s, s:s, s:I, s:b, s:b, s:b, s:b, s:b}",
101 &value,
103 &record_type,
105 &rel_exp.rel_value_us,
107 &maintenance,
109 &private,
111 &supplemental,
113 &is_rel_exp,
115 &shadow);
116 if (0 != unpack_state)
117 {
119 "Error gnsdata object has a wrong format: `%s'!\n",
120 err.text);
121 unpack_state = json_unpack_ex (data,
122 &err,
123 0,
124 "{s:s, s:s, s:I, s:b, s:b, s:b, s:b, s:b}",
126 &value,
128 &record_type,
130 &abs_exp.abs_value_us,
132 &maintenance,
134 &private,
136 &supplemental,
138 &is_rel_exp,
140 &shadow);
141 if ((0 != unpack_state) || (is_rel_exp))
142 {
144 "Error gnsdata object has a wrong format: `%s'!\n",
145 (is_rel_exp) ? "No relative expiration given" : err.text);
146 return GNUNET_SYSERR;
147 }
149 }
150 else
151 {
153 }
155 if (UINT32_MAX == rd->record_type)
156 {
157 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unsupported type\n");
158 return GNUNET_SYSERR;
159 }
161 value,
162 (void **) &rd->data,
163 &rd->data_size))
164 {
165 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Value invalid for record type\n");
166 return GNUNET_SYSERR;
167 }
168
169 if (is_rel_exp)
171 if (1 == maintenance)
173 if (1 == private)
175 if (1 == supplemental)
177 if (1 == shadow)
179 return GNUNET_OK;
180}
181
182
191static int
192parse_record_data (struct GnsRecordInfo *gnsrecord_info, json_t *data)
193{
194 GNUNET_assert (NULL != data);
195 if (! json_is_array (data))
196 {
198 "Error gns record data JSON is not an array!\n");
199 return GNUNET_SYSERR;
200 }
201 *(gnsrecord_info->rd_count) = json_array_size (data);
202 *(gnsrecord_info->rd) = GNUNET_malloc (sizeof(struct GNUNET_GNSRECORD_Data)
203 * json_array_size (data));
204 {
205 size_t index;
206 json_t *value;
207 json_array_foreach (data, index, value)
208 {
209 if (GNUNET_OK != parse_record (value, &(*(gnsrecord_info->rd))[index]))
210 return GNUNET_SYSERR;
211 }
212 }
213 return GNUNET_OK;
214}
215
216
217static int
219 json_t *root,
220 struct GNUNET_JSON_Specification *spec)
221{
222 struct GnsRecordInfo *gnsrecord_info;
223 int unpack_state = 0;
224 const char *name;
225 json_t *data;
226
227 GNUNET_assert (NULL != root);
228 if (! json_is_object (root))
229 {
231 "Error record JSON is not an object!\n");
232 return GNUNET_SYSERR;
233 }
234 // interpret single gns record
235 unpack_state = json_unpack (root,
236 "{s:s, s:o!}",
238 &name,
240 &data);
241 if (0 != unpack_state)
242 {
244 "Error namestore records object has a wrong format!\n");
245 return GNUNET_SYSERR;
246 }
247 gnsrecord_info = (struct GnsRecordInfo *) spec->ptr;
248 *(gnsrecord_info->name) = GNUNET_strdup (name);
249 if (GNUNET_OK != parse_record_data (gnsrecord_info, data))
250 {
251 cleanup_recordinfo (gnsrecord_info);
252 return GNUNET_SYSERR;
253 }
254 return GNUNET_OK;
255}
256
257
264static void
266{
267 struct GnsRecordInfo *gnsrecord_info = (struct GnsRecordInfo *) spec->ptr;
268
269 GNUNET_free (gnsrecord_info);
270}
271
272
281 unsigned int *rd_count,
282 char **name)
283{
284 struct GnsRecordInfo *gnsrecord_info = GNUNET_new (struct GnsRecordInfo);
286 .cleaner = &clean_gnsrecordobject,
287 .cls = NULL,
288 .field = NULL,
289 .ptr = (struct GnsRecordInfo *)
290 gnsrecord_info,
291 .ptr_size = 0,
292 .size_ptr = NULL };
293
294 gnsrecord_info->rd = rd;
295 gnsrecord_info->name = name;
296 gnsrecord_info->rd_count = rd_count;
297 return ret;
298}
299
300
308json_t *
310 const struct GNUNET_GNSRECORD_Data *rd,
311 unsigned int rd_count)
312{
313 const char *record_type_str;
314 char *value_str;
315 json_t *data;
316 json_t *record;
317 json_t *records;
318
319 data = json_object ();
320 if (NULL == data)
321 {
322 GNUNET_break (0);
323 return NULL;
324 }
325 if (0 !=
326 json_object_set_new (data,
327 "record_name",
328 json_string (rname)))
329 {
330 GNUNET_break (0);
331 json_decref (data);
332 return NULL;
333 }
334 records = json_array ();
335 if (NULL == records)
336 {
337 GNUNET_break (0);
338 json_decref (data);
339 return NULL;
340 }
341 for (int i = 0; i < rd_count; i++)
342 {
343 value_str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
344 rd[i].data,
345 rd[i].data_size);
346 record_type_str = GNUNET_GNSRECORD_number_to_typename (rd[i].record_type);
348 "Packing %s %s %" PRIu64 " %d\n",
349 value_str, record_type_str, rd[i].expiration_time, rd[i].flags);
350 record = json_pack (
351 "{s:s, s:s, s:I, s:b, s:b, s:b, s:b, s:b}",
353 GNUNET_JSON_GNSRECORD_TYPE, record_type_str,
368 GNUNET_free (value_str);
369 if (NULL == record)
370 {
371 GNUNET_break (0);
372 json_decref (records);
373 json_decref (data);
374 return NULL;
375 }
376 if (0 !=
377 json_array_append_new (records,
378 record))
379 {
380 GNUNET_break (0);
381 json_decref (records);
382 json_decref (data);
383 return NULL;
384 }
385 }
386 if (0 !=
387 json_object_set_new (data,
388 "data",
389 records))
390 {
391 GNUNET_break (0);
392 json_decref (data);
393 return NULL;
394 }
395 return data;
396}
static int ret
Final status code.
Definition gnunet-arm.c:93
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
static char * data
The data to insert into the dht.
static char * name
Name (label) of the records to list.
static unsigned int rd_count
Number of records for currently parsed set.
static struct GNUNET_GNSRECORD_Data rd[50]
The record data under a single label.
static char * value
Value of the record to add/remove.
static size_t data_size
Number of bytes in data.
static unsigned int records
Number of records we found.
API that can be used to manipulate JSON GNS record data.
API that can be used to manipulate GNS record data.
functions to parse JSON objects into GNUnet objects
json_t * GNUNET_GNSRECORD_JSON_from_gnsrecord(const char *rname, const struct GNUNET_GNSRECORD_Data *rd, unsigned int rd_count)
Convert GNS record to JSON.
const char * GNUNET_GNSRECORD_number_to_typename(uint32_t type)
Convert a type number to the corresponding type string (e.g.
Definition gnsrecord.c:219
uint32_t GNUNET_GNSRECORD_typename_to_number(const char *dns_typename)
Convert a type name (e.g.
Definition gnsrecord.c:192
int GNUNET_GNSRECORD_string_to_value(uint32_t type, const char *s, void **data, size_t *data_size)
Convert human-readable version of the value s of a record of type type to the respective binary repre...
Definition gnsrecord.c:169
struct GNUNET_JSON_Specification GNUNET_GNSRECORD_JSON_spec_gnsrecord(struct GNUNET_GNSRECORD_Data **rd, unsigned int *rd_count, char **name)
JSON Specification for GNS Records.
char * GNUNET_GNSRECORD_value_to_string(uint32_t type, const void *data, size_t data_size)
Convert the binary value data of a record of type type to a human-readable string.
Definition gnsrecord.c:147
@ GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION
This expiration time of the record is a relative time (not an absolute time).
@ GNUNET_GNSRECORD_RF_SUPPLEMENTAL
This is a supplemental record.
@ GNUNET_GNSRECORD_RF_MAINTENANCE
Maintenance records.
@ GNUNET_GNSRECORD_RF_SHADOW
This record should not be used unless all (other) records in the set with an absolute expiration time...
@ GNUNET_GNSRECORD_RF_PRIVATE
This is a private record of this peer and it should thus not be published.
#define GNUNET_log(kind,...)
@ GNUNET_OK
@ GNUNET_SYSERR
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur.
@ GNUNET_ERROR_TYPE_ERROR
@ GNUNET_ERROR_TYPE_DEBUG
#define GNUNET_strdup(a)
Wrapper around GNUNET_xstrdup_.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_free(ptr)
Wrapper around free.
#define GNUNET_JSON_GNSRECORD_FLAG_SHADOW
static int parse_record_data(struct GnsRecordInfo *gnsrecord_info, json_t *data)
Parse given JSON object to gns record.
#define GNUNET_JSON_GNSRECORD_VALUE
#define GNUNET_JSON_GNSRECORD_FLAG_PRIVATE
#define GNUNET_JSON_GNSRECORD_FLAG_MAINTENANCE
#define GNUNET_JSON_GNSRECORD_ABSOLUTE_EXPIRATION_TIME
#define GNUNET_JSON_GNSRECORD_FLAG_SUPPLEMENTAL
static void clean_gnsrecordobject(void *cls, struct GNUNET_JSON_Specification *spec)
Cleanup data left from parsing the record.
#define GNUNET_JSON_GNSRECORD_RELATIVE_EXPIRATION_TIME
#define GNUNET_JSON_GNSRECORD_FLAG_RELATIVE
static int parse_record(json_t *data, struct GNUNET_GNSRECORD_Data *rd)
Parse given JSON object to gns record.
#define GNUNET_JSON_GNSRECORD_RECORD_NAME
#define GNUNET_JSON_GNSRECORD_TYPE
static int parse_gnsrecordobject(void *cls, json_t *root, struct GNUNET_JSON_Specification *spec)
static void cleanup_recordinfo(struct GnsRecordInfo *gnsrecord_info)
#define GNUNET_JSON_GNSRECORD_RECORD_DATA
uint32_t record_type
Type of the GNS/DNS record.
const void * data
Binary value stored in the DNS record.
size_t data_size
Number of bytes in data.
enum GNUNET_GNSRECORD_Flags flags
Flags for the record.
uint64_t expiration_time
Expiration time for the DNS record.
Entry in parser specification for GNUNET_JSON_parse().
void * ptr
Pointer, details specific to the parser.
GNUNET_JSON_Parser parser
Function for how to parse this type of entry.
Time for absolute times used by GNUnet, in microseconds.
uint64_t abs_value_us
The actual value.
Time for relative time used by GNUnet, in microseconds.
uint64_t rel_value_us
The actual value.
struct GNUNET_GNSRECORD_Data ** rd
unsigned int * rd_count