GNUnet  0.11.x
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 #include "gnunet_dnsparser_lib.h"
35 #include "gnunet_tun_lib.h"
36 
37 
38 #define LOG(kind, ...) GNUNET_log_from (kind, "gnsrecord", __VA_ARGS__)
39 
44 #define DEBUG_GNSRECORDS 0
45 
47 
48 
53 {
59 
64 
69 
73  uint32_t flags GNUNET_PACKED;
74 };
75 
77 
78 
87 ssize_t
88 GNUNET_GNSRECORD_records_get_size (unsigned int rd_count,
89  const struct GNUNET_GNSRECORD_Data *rd)
90 {
91  size_t ret;
92 
93  if (0 == rd_count)
94  return 0;
95 
96  ret = sizeof(struct NetworkRecord) * rd_count;
97  for (unsigned int i = 0; i < rd_count; i++)
98  {
99  if ((ret + rd[i].data_size) < ret)
100  {
101  GNUNET_break (0);
102  return -1;
103  }
104  ret += rd[i].data_size;
105 #if DEBUG_GNSRECORDS
106  {
107  char *str;
108 
110  rd[i].data,
111  rd[i].data_size);
112  if (NULL == str)
113  {
114  GNUNET_break_op (0);
115  return -1;
116  }
117  GNUNET_free (str);
118  }
119 #endif
120  }
121  if (ret > SSIZE_MAX)
122  {
123  GNUNET_break (0);
124  return -1;
125  }
126  // Do not pad PKEY
129  return ret;ret--;
135  ret |= ret >> 1;
136  ret |= ret >> 2;
137  ret |= ret >> 4;
138  ret |= ret >> 8;
139  ret |= ret >> 16;
140  ret++;
141  return (ssize_t) ret;
142 }
143 
144 
154 ssize_t
155 GNUNET_GNSRECORD_records_serialize (unsigned int rd_count,
156  const struct GNUNET_GNSRECORD_Data *rd,
157  size_t dest_size,
158  char *dest)
159 {
160  struct NetworkRecord rec;
161  size_t off;
162 
163  off = 0;
164  for (unsigned int i = 0; i < rd_count; i++)
165  {
167  "Serializing record %u with flags %d and expiration time %llu\n",
168  i,
169  rd[i].flags,
170  (unsigned long long) rd[i].expiration_time);
171  rec.expiration_time = GNUNET_htonll (rd[i].expiration_time);
172  rec.data_size = htonl ((uint32_t) rd[i].data_size);
173  rec.record_type = htonl (rd[i].record_type);
174  rec.flags = htonl (rd[i].flags);
175  if ((off + sizeof(rec) > dest_size) ||
176  (off + sizeof(rec) < off))
177  {
178  GNUNET_break (0);
179  return -1;
180  }
181  GNUNET_memcpy (&dest[off],
182  &rec,
183  sizeof(rec));
184  off += sizeof(rec);
185  if ((off + rd[i].data_size > dest_size) ||
186  (off + rd[i].data_size < off))
187  {
188  GNUNET_break (0);
189  return -1;
190  }
191  GNUNET_memcpy (&dest[off],
192  rd[i].data,
193  rd[i].data_size);
194  off += rd[i].data_size;
195 #if DEBUG_GNSRECORDS
196  {
197  char *str;
198 
199  str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
200  rd[i].data,
201  rd[i].data_size);
202  if (NULL == str)
203  {
204  GNUNET_break_op (0);
205  return -1;
206  }
207  GNUNET_free (str);
208  }
209 #endif
210  }
211  memset (&dest[off],
212  0,
213  dest_size - off);
214  return dest_size;
215 }
216 
217 
227 int
229  const char *src,
230  unsigned int rd_count,
231  struct GNUNET_GNSRECORD_Data *dest)
232 {
233  struct NetworkRecord rec;
234  size_t off;
235 
236  off = 0;
237  for (unsigned int i = 0; i < rd_count; i++)
238  {
239  if ((off + sizeof(rec) > len) ||
240  (off + sizeof(rec) < off))
241  {
242  GNUNET_break_op (0);
243  return GNUNET_SYSERR;
244  }
245  GNUNET_memcpy (&rec,
246  &src[off],
247  sizeof(rec));
249  dest[i].data_size = ntohl ((uint32_t) rec.data_size);
250  dest[i].record_type = ntohl (rec.record_type);
251  dest[i].flags = ntohl (rec.flags);
252  off += sizeof(rec);
253  if ((off + dest[i].data_size > len) ||
254  (off + dest[i].data_size < off))
255  {
256  GNUNET_break_op (0);
257  return GNUNET_SYSERR;
258  }
259  dest[i].data = &src[off];
260  off += dest[i].data_size;
261 #if GNUNET_EXTRA_LOGGING
262  {
263  char *str;
264 
266  dest[i].data,
267  dest[i].data_size);
268  if (NULL == str)
269  {
270  GNUNET_break_op (0);
271  return GNUNET_SYSERR;
272  }
273  GNUNET_free (str);
274  }
275 #endif
277  "Deserialized record %u with flags %d and expiration time %llu\n",
278  i,
279  dest[i].flags,
280  (unsigned long long) dest[i].expiration_time);
281  }
282  return GNUNET_OK;
283 }
284 
285 
286 /* 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...
uint32_t data_size
Number of bytes in &#39;data&#39;, network byte order.
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.
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.
uint32_t flags
Flags for the record, network byte order.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
size_t data_size
Number of bytes in 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.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
#define GNUNET_NETWORK_STRUCT_BEGIN
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32.
const void * data
Binary value stored in the DNS record.
#define LOG(kind,...)
#define GNUNET_break_op(cond)
Use this for assertion violations caused by other peers (i.e.
uint64_t expiration_time
Expiration time for the DNS record.
uint64_t expiration_time
Expiration time for the DNS record; relative or absolute depends on flags, network byte order...
uint64_t GNUNET_htonll(uint64_t n)
Convert unsigned 64-bit integer to network byte order.
Definition: common_endian.c:36
#define GNUNET_NETWORK_STRUCT_END
Define as empty, GNUNET_PACKED should suffice, but this won&#39;t work on W32;.
uint32_t record_type
Type of the GNS/DNS record.
#define GNUNET_PACKED
gcc-ism to get packed structs.
uint32_t record_type
Type of the GNS/DNS record, network byte order.
enum GNUNET_GNSRECORD_Flags flags
Flags for the record.
#define GNUNET_GNSRECORD_TYPE_EDKEY
Record type for EDKEY zone delegations.
uint32_t data
The data value.
char * GNUNET_GNSRECORD_value_to_string(uint32_t type, const void *data, size_t data_size)
Convert the &#39;value&#39; of a record to a string.
Definition: gnsrecord.c:156
Internal format of a record in the serialized form.
uint64_t GNUNET_ntohll(uint64_t n)
Convert unsigned 64-bit integer to host byte order.
Definition: common_endian.c:53
#define GNUNET_free(ptr)
Wrapper around free.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...