GNUnet 0.28.0-dev.3-7-g31e20e2e6
 
Loading...
Searching...
No Matches
gnsrecord_serialization.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
28#include "platform.h"
29#include "gnunet_util_lib.h"
30#include "gnunet_constants.h"
31#include "gnunet_signatures.h"
32#include "gnunet_arm_service.h"
34
35#define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
36
41#define DEBUG_GNSRECORDS 0
42
44
45
73
75
76
77ssize_t
79 const struct GNUNET_GNSRECORD_Data *rd)
80{
81 size_t ret;
82
83 if (0 == rd_count)
84 return 0;
85
86 ret = sizeof(struct NetworkRecord) * rd_count;
87 for (unsigned int i = 0; i < rd_count; i++)
88 {
89 if ((ret + rd[i].data_size) < ret)
90 {
91 GNUNET_break (0);
92 return -1;
93 }
94 ret += rd[i].data_size;
95#if DEBUG_GNSRECORDS
96 {
97 char *str;
98
100 rd[i].data,
101 rd[i].data_size);
102 if (NULL == str)
103 {
104 GNUNET_break_op (0);
105 return -1;
106 }
108 }
109#endif
110 }
111 if (ret > SSIZE_MAX)
112 {
113 GNUNET_break (0);
114 return -1;
115 }
116 // Do not pad PKEY
119 return ret;
ret--;
125 ret |= ret >> 1;
126 ret |= ret >> 2;
127 ret |= ret >> 4;
128 ret |= ret >> 8;
129 ret |= ret >> 16;
130 ret++;
131 return (ssize_t) ret;
132}
133
134
135ssize_t
137 const struct GNUNET_GNSRECORD_Data *rd,
138 size_t dest_size,
139 char *dest)
140{
141 struct NetworkRecord rec;
142 size_t off;
143
144 off = 0;
145 for (unsigned int i = 0; i < rd_count; i++)
146 {
148 "Serializing record %u with flags %d and expiration time %llu\n",
149 i,
150 rd[i].flags,
151 (unsigned long long) rd[i].expiration_time);
153 rec.data_size = htons ((uint16_t) rd[i].data_size);
154 rec.record_type = htonl (rd[i].record_type);
155 rec.flags = htons (rd[i].flags);
156 if ((off + sizeof(rec) > dest_size) ||
157 (off + sizeof(rec) < off))
158 {
159 GNUNET_break (0);
160 return -1;
161 }
162 GNUNET_memcpy (&dest[off],
163 &rec,
164 sizeof(rec));
165 off += sizeof(rec);
166 if ((off + rd[i].data_size > dest_size) ||
167 (off + rd[i].data_size < off))
168 {
169 GNUNET_break (0);
170 return -1;
171 }
172 GNUNET_memcpy (&dest[off],
173 rd[i].data,
174 rd[i].data_size);
175 off += rd[i].data_size;
176#if DEBUG_GNSRECORDS
177 {
178 char *str;
179
181 rd[i].data,
182 rd[i].data_size);
183 if (NULL == str)
184 {
185 GNUNET_break_op (0);
186 return -1;
187 }
189 }
190#endif
191 }
192 memset (&dest[off],
193 0,
194 dest_size - off);
195 return dest_size;
196}
197
198
199unsigned int
201 const char *src)
202{
203 struct NetworkRecord rec;
204 struct NetworkRecord rec_zero;
205 size_t off;
206 unsigned int rd_count = 0;
207
208 memset (&rec_zero, 0, sizeof (rec_zero));
209
210 off = 0;
211 for (off = 0; (off + sizeof(rec) <= len) && (off + sizeof(rec) >= off);)
212 {
213 GNUNET_memcpy (&rec,
214 &src[off],
215 sizeof(rec));
216 /*
217 * If we have found a byte string of zeroes, we have reached
218 * the padding
219 */
220 if (0 == GNUNET_memcmp (&rec, &rec_zero))
221 break;
222 off += sizeof(rec);
223 if ((off + ntohs ((uint16_t) rec.data_size) > len) ||
224 (off + ntohs ((uint16_t) rec.data_size) < off))
225 {
226 GNUNET_break_op (0);
227 return 0;
228 }
229 off += ntohs ((uint16_t) rec.data_size);
230 rd_count++;
231 }
232 return rd_count;
233}
234
235
245int
247 const char *src,
248 unsigned int rd_count,
249 struct GNUNET_GNSRECORD_Data *dest)
250{
251 struct NetworkRecord rec;
252 size_t off;
253
254 off = 0;
255 for (unsigned int i = 0; i < rd_count; i++)
256 {
257 if ((off + sizeof(rec) > len) ||
258 (off + sizeof(rec) < off))
259 {
260 GNUNET_break_op (0);
261 return GNUNET_SYSERR;
262 }
263 GNUNET_memcpy (&rec,
264 &src[off],
265 sizeof(rec));
266 dest[i].expiration_time = GNUNET_ntohll (rec.expiration_time);
267 dest[i].data_size = ntohs ((uint16_t) rec.data_size);
268 dest[i].record_type = ntohl (rec.record_type);
269 dest[i].flags = ntohs (rec.flags);
270 off += sizeof(rec);
271 if ((off + dest[i].data_size > len) ||
272 (off + dest[i].data_size < off))
273 {
274 GNUNET_break_op (0);
275 return GNUNET_SYSERR;
276 }
277 dest[i].data = &src[off];
278 off += dest[i].data_size;
279#if GNUNET_EXTRA_LOGGING
280 {
281 char *str;
282
284 dest[i].data,
285 dest[i].data_size);
286 if (NULL == str)
287 {
288 GNUNET_break_op (0);
289 return GNUNET_SYSERR;
290 }
292 }
293#endif
295 "Deserialized record %u with flags %d and expiration time %llu\n",
296 i,
297 dest[i].flags,
298 (unsigned long long) dest[i].expiration_time);
299 }
300 return GNUNET_OK;
301}
302
303
306 unsigned int rd_count,
307 const struct GNUNET_GNSRECORD_Data rd[rd_count],
308 unsigned char *rdata,
309 size_t rdata_len)
310{
311 ssize_t rdata_len_expected = GNUNET_GNSRECORD_records_get_size (rd_count,
312 rd);
314 struct GNUNET_TIME_Absolute now;
315
316 if (rdata_len < 0)
317 {
318 GNUNET_break (0);
319 return GNUNET_SYSERR;
320 }
321 if (rdata_len > GNUNET_GNSRECORD_MAX_BLOCK_SIZE)
322 {
323 GNUNET_break (0);
324 return GNUNET_SYSERR;
325 }
326 if (rdata_len_expected > rdata_len)
327 {
328 GNUNET_break (0);
329 return GNUNET_SYSERR;
330 }
331 /* convert relative to absolute times */
333 for (unsigned int i = 0; i < rd_count; i++)
334 {
335 rdc[i] = rd[i];
336 if (0 != (rd[i].flags & GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION))
337 {
338 struct GNUNET_TIME_Relative t;
339
340 /* encrypted blocks must never have relative expiration times, convert! */
341 rdc[i].flags &= ~GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION;
342 t.rel_value_us = rdc[i].expiration_time;
344 }
345 }
346 GNUNET_assert (rdata_len ==
348 rdc,
349 rdata_len,
350 (char*) rdata));
351 return GNUNET_OK;
352}
353
354
355/* end of gnsrecord_serialization.c */
#define LOG(kind,...)
#define GNUNET_GNSRECORD_TYPE_PKEY
WARNING: This header is generated! In order to add GNS record types, you must register them in GANA,...
#define GNUNET_GNSRECORD_TYPE_EDKEY
GNS zone delegation (EDKEY)
static int ret
Final status code.
Definition gnunet-arm.c:93
static char * data
The data to insert into the dht.
static struct GNUNET_SCHEDULER_Task * t
Main task.
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 size_t data_size
Number of bytes in data.
API that can be used to manipulate GNS record data.
#define GNUNET_GNSRECORD_MAX_BLOCK_SIZE
Maximum size of a value that can be stored in a GNS block.
int GNUNET_GNSRECORD_records_deserialize(size_t len, const char *src, unsigned int rd_count, struct GNUNET_GNSRECORD_Data *dest)
Deserialize the given records to the given destination.
ssize_t GNUNET_GNSRECORD_records_serialize(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd, size_t dest_size, char *dest)
Serialize the given records to the given destination buffer.
unsigned int GNUNET_GNSRECORD_records_deserialize_get_size(size_t len, const char *src)
GNUNET_NETWORK_STRUCT_END ssize_t GNUNET_GNSRECORD_records_get_size(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data *rd)
Calculate how many bytes we will need to serialize the given records.
enum GNUNET_GenericReturnValue GNUNET_GNSRECORD_record_data_to_rdata(unsigned int rd_count, const struct GNUNET_GNSRECORD_Data rd[rd_count], unsigned char *rdata, size_t rdata_len)
Serialize the record set into an RFC9498-compliant RDATA octet string.
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).
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
#define GNUNET_NZL(l)
Macro used to avoid using 0 for the length of a variable-size array (Non-Zero-Length).
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32;.
#define GNUNET_memcmp(a, b)
Compare memory in a and b, where both must be of the same pointer type.
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
GNUNET_GenericReturnValue
Named constants for return values.
#define GNUNET_PACKED
gcc-ism to get packed structs.
@ GNUNET_OK
@ GNUNET_SYSERR
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
#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_DEBUG
#define GNUNET_free(ptr)
Wrapper around free.
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition time.c:111
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_add(struct GNUNET_TIME_Absolute start, struct GNUNET_TIME_Relative duration)
Add a given relative duration to the given start time.
Definition time.c:452
uint32_t record_type
Type of the GNS/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.
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.
Internal format of a record in the serialized form.
uint64_t expiration_time
Expiration time for the DNS record; relative or absolute depends on flags, network byte order.
uint32_t record_type
Type of the GNS/DNS record, network byte order.
uint16_t flags
Flags for the record, network byte order.
uint16_t data_size
Number of bytes in 'data', network byte order.
const char * str
Definition time.c:1252