GNUnet  0.19.4
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"
33 #include "gnunet_gnsrecord_lib.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 
65  uint16_t flags GNUNET_PACKED;
66 
71 
72 };
73 
75 
76 
77 ssize_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 
135 ssize_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 
198 unsigned 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 
243 int
245  const char *src,
246  unsigned int rd_count,
247  struct GNUNET_GNSRECORD_Data *dest)
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 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
Record type for EDKEY zone delegations.
#define LOG(kind,...)
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
static size_t data_size
Number of bytes in data.
Definition: gnunet-abd.c:187
uint32_t data
The data value.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
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.
API that can be used to manipulate GNS record data.
char * GNUNET_GNSRECORD_value_to_string(uint32_t type, const void *data, size_t data_size)
Convert the 'value' of a record to a string.
Definition: gnsrecord.c:155
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.
#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.
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.