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 
52 struct NetworkRecord {
58 
63 
68 
72  uint32_t flags GNUNET_PACKED;
73 };
74 
76 
77 
86 ssize_t
87 GNUNET_GNSRECORD_records_get_size(unsigned int rd_count,
88  const struct GNUNET_GNSRECORD_Data *rd)
89 {
90  size_t ret;
91 
92  if (0 == rd_count)
93  return 0;
94 
95  ret = sizeof(struct NetworkRecord) * rd_count;
96  for (unsigned int i = 0; i < rd_count; i++)
97  {
98  if ((ret + rd[i].data_size) < ret)
99  {
100  GNUNET_break(0);
101  return -1;
102  }
103  ret += rd[i].data_size;
104 #if DEBUG_GNSRECORDS
105  {
106  char *str;
107 
109  rd[i].data,
110  rd[i].data_size);
111  if (NULL == str)
112  {
113  GNUNET_break_op(0);
114  return -1;
115  }
116  GNUNET_free(str);
117  }
118 #endif
119  }
120  if (ret > SSIZE_MAX)
121  {
122  GNUNET_break(0);
123  return -1;
124  }
125  //Do not pad PKEY
127  return ret;
133  ret--;
134  ret |= ret >> 1;
135  ret |= ret >> 2;
136  ret |= ret >> 4;
137  ret |= ret >> 8;
138  ret |= ret >> 16;
139  ret++;
140  return (ssize_t)ret;
141 }
142 
143 
153 ssize_t
155  const struct GNUNET_GNSRECORD_Data *rd,
156  size_t dest_size,
157  char *dest)
158 {
159  struct NetworkRecord rec;
160  size_t off;
161 
162  off = 0;
163  for (unsigned int i = 0; i < rd_count; i++)
164  {
166  "Serializing record %u with flags %d and expiration time %llu\n",
167  i,
168  rd[i].flags,
169  (unsigned long long)rd[i].expiration_time);
170  rec.expiration_time = GNUNET_htonll(rd[i].expiration_time);
171  rec.data_size = htonl((uint32_t)rd[i].data_size);
172  rec.record_type = htonl(rd[i].record_type);
173  rec.flags = htonl(rd[i].flags);
174  if ((off + sizeof(rec) > dest_size) ||
175  (off + sizeof(rec) < off))
176  {
177  GNUNET_break(0);
178  return -1;
179  }
180  GNUNET_memcpy(&dest[off],
181  &rec,
182  sizeof(rec));
183  off += sizeof(rec);
184  if ((off + rd[i].data_size > dest_size) ||
185  (off + rd[i].data_size < off))
186  {
187  GNUNET_break(0);
188  return -1;
189  }
190  GNUNET_memcpy(&dest[off],
191  rd[i].data,
192  rd[i].data_size);
193  off += rd[i].data_size;
194 #if DEBUG_GNSRECORDS
195  {
196  char *str;
197 
198  str = GNUNET_GNSRECORD_value_to_string(rd[i].record_type,
199  rd[i].data,
200  rd[i].data_size);
201  if (NULL == str)
202  {
203  GNUNET_break_op(0);
204  return -1;
205  }
206  GNUNET_free(str);
207  }
208 #endif
209  }
210  memset(&dest[off],
211  0,
212  dest_size - off);
213  return dest_size;
214 }
215 
216 
226 int
228  const char *src,
229  unsigned int rd_count,
230  struct GNUNET_GNSRECORD_Data *dest)
231 {
232  struct NetworkRecord rec;
233  size_t off;
234 
235  off = 0;
236  for (unsigned int i = 0; i < rd_count; i++)
237  {
238  if ((off + sizeof(rec) > len) ||
239  (off + sizeof(rec) < off))
240  {
241  GNUNET_break_op(0);
242  return GNUNET_SYSERR;
243  }
244  GNUNET_memcpy(&rec,
245  &src[off],
246  sizeof(rec));
248  dest[i].data_size = ntohl((uint32_t)rec.data_size);
249  dest[i].record_type = ntohl(rec.record_type);
250  dest[i].flags = ntohl(rec.flags);
251  off += sizeof(rec);
252  if ((off + dest[i].data_size > len) ||
253  (off + dest[i].data_size < off))
254  {
255  GNUNET_break_op(0);
256  return GNUNET_SYSERR;
257  }
258  dest[i].data = &src[off];
259  off += dest[i].data_size;
260 #if GNUNET_EXTRA_LOGGING
261  {
262  char *str;
263 
265  dest[i].data,
266  dest[i].data_size);
267  if (NULL == str)
268  {
269  GNUNET_break_op(0);
270  return GNUNET_SYSERR;
271  }
272  GNUNET_free(str);
273  }
274 #endif
276  "Deserialized record %u with flags %d and expiration time %llu\n",
277  i,
278  dest[i].flags,
279  (unsigned long long)dest[i].expiration_time);
280  }
281  return GNUNET_OK;
282 }
283 
284 
285 /* 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_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
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.
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:76
#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:142
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...