GNUnet 0.21.0
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
50{
56
61
66
71
72};
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 }
107 GNUNET_free (str);
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 }
188 GNUNET_free (str);
189 }
190#endif
191 }
192 memset (&dest[off],
193 0,
194 dest_size - off);
195 return dest_size;
196}
197
198unsigned int
200 const char *src)
201{
202 struct NetworkRecord rec;
203 struct NetworkRecord rec_zero;
204 size_t off;
205 unsigned int rd_count = 0;
206
207 memset (&rec_zero, 0, sizeof (rec_zero));
208
209 off = 0;
210 for (off = 0; (off + sizeof(rec) <= len) && (off + sizeof(rec) >= off);)
211 {
212 GNUNET_memcpy (&rec,
213 &src[off],
214 sizeof(rec));
215 /*
216 * If we have found a byte string of zeroes, we have reached
217 * the padding
218 */
219 if (0 == GNUNET_memcmp (&rec, &rec_zero))
220 break;
221 off += sizeof(rec);
222 if ((off + ntohs ((uint16_t) rec.data_size) > len) ||
223 (off + ntohs ((uint16_t) rec.data_size) < off))
224 {
225 GNUNET_break_op (0);
226 return 0;
227 }
228 off += ntohs ((uint16_t) rec.data_size);
229 rd_count++;
230 }
231 return rd_count;
232}
233
243int
245 const char *src,
246 unsigned int rd_count,
248{
249 struct NetworkRecord rec;
250 size_t off;
251
252 off = 0;
253 for (unsigned int i = 0; i < rd_count; i++)
254 {
255 if ((off + sizeof(rec) > len) ||
256 (off + sizeof(rec) < off))
257 {
258 GNUNET_break_op (0);
259 return GNUNET_SYSERR;
260 }
261 GNUNET_memcpy (&rec,
262 &src[off],
263 sizeof(rec));
264 dest[i].expiration_time = GNUNET_ntohll (rec.expiration_time);
265 dest[i].data_size = ntohs ((uint16_t) rec.data_size);
266 dest[i].record_type = ntohl (rec.record_type);
267 dest[i].flags = ntohs (rec.flags);
268 off += sizeof(rec);
269 if ((off + dest[i].data_size > len) ||
270 (off + dest[i].data_size < off))
271 {
272 GNUNET_break_op (0);
273 return GNUNET_SYSERR;
274 }
275 dest[i].data = &src[off];
276 off += dest[i].data_size;
277#if GNUNET_EXTRA_LOGGING
278 {
279 char *str;
280
282 dest[i].data,
283 dest[i].data_size);
284 if (NULL == str)
285 {
286 GNUNET_break_op (0);
287 return GNUNET_SYSERR;
288 }
289 GNUNET_free (str);
290 }
291#endif
293 "Deserialized record %u with flags %d and expiration time %llu\n",
294 i,
295 dest[i].flags,
296 (unsigned long long) dest[i].expiration_time);
297 }
298 return GNUNET_OK;
299}
300
301
302/* end of gnsrecord_serialization.c */
#define LOG(kind,...)
static int ret
Final status code.
Definition: gnunet-arm.c:94
static char * data
The data to insert into the dht.
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.
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.
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:155
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won't work on W32.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:54
#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.
Definition: common_endian.c:37
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#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_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.
#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)
uint32_t record_type
Type of the GNS/DNS record.
size_t data_size
Number of bytes in data.
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.