GNUnet  0.10.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 {
54 
60 
65 
70 
74  uint32_t flags GNUNET_PACKED;
75 
76 };
77 
79 
80 
89 ssize_t
90 GNUNET_GNSRECORD_records_get_size (unsigned int rd_count,
91  const struct GNUNET_GNSRECORD_Data *rd)
92 {
93  size_t ret;
94 
95  if (0 == rd_count)
96  return 0;
97 
98  ret = sizeof (struct NetworkRecord) * rd_count;
99  for (unsigned int i=0;i<rd_count;i++)
100  {
101  if ((ret + rd[i].data_size) < ret)
102  {
103  GNUNET_break (0);
104  return -1;
105  }
106  ret += rd[i].data_size;
107 #if DEBUG_GNSRECORDS
108  {
109  char *str;
110 
112  rd[i].data,
113  rd[i].data_size);
114  if (NULL == str)
115  {
116  GNUNET_break_op (0);
117  return -1;
118  }
119  GNUNET_free (str);
120  }
121 #endif
122  }
123  if (ret > SSIZE_MAX)
124  {
125  GNUNET_break (0);
126  return -1;
127  }
128  //Do not pad PKEY
130  return ret;
136  ret--;
137  ret |= ret >> 1;
138  ret |= ret >> 2;
139  ret |= ret >> 4;
140  ret |= ret >> 8;
141  ret |= ret >> 16;
142  ret++;
143  return (ssize_t) ret;
144 }
145 
146 
156 ssize_t
157 GNUNET_GNSRECORD_records_serialize (unsigned int rd_count,
158  const struct GNUNET_GNSRECORD_Data *rd,
159  size_t dest_size,
160  char *dest)
161 {
162  struct NetworkRecord rec;
163  size_t off;
164 
165  off = 0;
166  for (unsigned int i=0;i<rd_count;i++)
167  {
169  "Serializing record %u with flags %d and expiration time %llu\n",
170  i,
171  rd[i].flags,
172  (unsigned long long) rd[i].expiration_time);
173  rec.expiration_time = GNUNET_htonll (rd[i].expiration_time);
174  rec.data_size = htonl ((uint32_t) rd[i].data_size);
175  rec.record_type = htonl (rd[i].record_type);
176  rec.flags = htonl (rd[i].flags);
177  if ( (off + sizeof (rec) > dest_size) ||
178  (off + sizeof (rec) < off) )
179  {
180  GNUNET_break (0);
181  return -1;
182  }
183  GNUNET_memcpy (&dest[off],
184  &rec,
185  sizeof (rec));
186  off += sizeof (rec);
187  if ( (off + rd[i].data_size > dest_size) ||
188  (off + rd[i].data_size < off) )
189  {
190  GNUNET_break (0);
191  return -1;
192  }
193  GNUNET_memcpy (&dest[off],
194  rd[i].data,
195  rd[i].data_size);
196  off += rd[i].data_size;
197 #if DEBUG_GNSRECORDS
198  {
199  char *str;
200 
201  str = GNUNET_GNSRECORD_value_to_string (rd[i].record_type,
202  rd[i].data,
203  rd[i].data_size);
204  if (NULL == str)
205  {
206  GNUNET_break_op (0);
207  return -1;
208  }
209  GNUNET_free (str);
210  }
211 #endif
212  }
213  memset (&dest[off],
214  0,
215  dest_size-off);
216  return dest_size;
217 }
218 
219 
229 int
231  const char *src,
232  unsigned int rd_count,
233  struct GNUNET_GNSRECORD_Data *dest)
234 {
235  struct NetworkRecord rec;
236  size_t off;
237 
238  off = 0;
239  for (unsigned int i=0;i<rd_count;i++)
240  {
241  if ( (off + sizeof (rec) > len) ||
242  (off + sizeof (rec) < off) )
243  {
244  GNUNET_break_op (0);
245  return GNUNET_SYSERR;
246  }
247  GNUNET_memcpy (&rec,
248  &src[off],
249  sizeof (rec));
251  dest[i].data_size = ntohl ((uint32_t) rec.data_size);
252  dest[i].record_type = ntohl (rec.record_type);
253  dest[i].flags = ntohl (rec.flags);
254  off += sizeof (rec);
255  if ( (off + dest[i].data_size > len) ||
256  (off + dest[i].data_size < off) )
257  {
258  GNUNET_break_op (0);
259  return GNUNET_SYSERR;
260  }
261  dest[i].data = &src[off];
262  off += dest[i].data_size;
263 #if GNUNET_EXTRA_LOGGING
264  {
265  char *str;
266 
268  dest[i].data,
269  dest[i].data_size);
270  if (NULL == str)
271  {
272  GNUNET_break_op (0);
273  return GNUNET_SYSERR;
274  }
275  GNUNET_free (str);
276  }
277 #endif
279  "Deserialized record %u with flags %d and expiration time %llu\n",
280  i,
281  dest[i].flags,
282  (unsigned long long) dest[i].expiration_time);
283  }
284  return GNUNET_OK;
285 }
286 
287 
288 /* end of gnsrecord_serialization.c */
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_OK
Named constants for return values.
Definition: gnunet_common.h:78
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.
static int ret
Final status code.
Definition: gnunet-arm.c:89
#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.
#define GNUNET_memcpy(dst, src, n)
const void * data
Binary value stored in the DNS record.
#define LOG(kind,...)
#define GNUNET_GNSRECORD_TYPE_PKEY
Record type for GNS zone transfer ("PKEY").
#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:35
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
#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.
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:143
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:48
#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...