aboutsummaryrefslogtreecommitdiff
path: root/src/hello
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-01-12 14:34:56 +0100
committerChristian Grothoff <christian@grothoff.org>2022-02-19 12:39:55 +0100
commit3e3081cfd22f5dacbeaba2843131c4aec530b562 (patch)
treec382476a75516d9becf1f813c994f5d571f95c2d /src/hello
parentcd84bf32e23b4396583a8fa1bfe4a00c1fba3715 (diff)
downloadgnunet-3e3081cfd22f5dacbeaba2843131c4aec530b562.tar.gz
gnunet-3e3081cfd22f5dacbeaba2843131c4aec530b562.zip
incomplete first hack of new hello-uri lib
Diffstat (limited to 'src/hello')
-rw-r--r--src/hello/Makefile.am11
-rw-r--r--src/hello/hello-uri.c391
2 files changed, 397 insertions, 5 deletions
diff --git a/src/hello/Makefile.am b/src/hello/Makefile.am
index 6a250e42f..f97ede97c 100644
--- a/src/hello/Makefile.am
+++ b/src/hello/Makefile.am
@@ -11,7 +11,8 @@ lib_LTLIBRARIES = libgnunethello.la
11libgnunethello_la_SOURCES = \ 11libgnunethello_la_SOURCES = \
12 hello.c \ 12 hello.c \
13 address.c \ 13 address.c \
14 hello-ng.c 14 hello-ng.c \
15 hello-uri.c
15libgnunethello_la_LIBADD = \ 16libgnunethello_la_LIBADD = \
16 $(top_builddir)/src/util/libgnunetutil.la $(XLIB) \ 17 $(top_builddir)/src/util/libgnunetutil.la $(XLIB) \
17 $(LTLIBINTL) 18 $(LTLIBINTL)
@@ -36,25 +37,25 @@ test_hello_SOURCES = \
36 test_hello.c 37 test_hello.c
37test_hello_LDADD = \ 38test_hello_LDADD = \
38 libgnunethello.la \ 39 libgnunethello.la \
39 $(top_builddir)/src/util/libgnunetutil.la 40 $(top_builddir)/src/util/libgnunetutil.la
40 41
41test_hello_ng_SOURCES = \ 42test_hello_ng_SOURCES = \
42 test_hello-ng.c 43 test_hello-ng.c
43test_hello_ng_LDADD = \ 44test_hello_ng_LDADD = \
44 libgnunethello.la \ 45 libgnunethello.la \
45 $(top_builddir)/src/util/libgnunetutil.la 46 $(top_builddir)/src/util/libgnunetutil.la
46 47
47 48
48test_friend_hello_SOURCES = \ 49test_friend_hello_SOURCES = \
49 test_friend_hello.c 50 test_friend_hello.c
50test_friend_hello_LDADD = \ 51test_friend_hello_LDADD = \
51 libgnunethello.la \ 52 libgnunethello.la \
52 $(top_builddir)/src/util/libgnunetutil.la 53 $(top_builddir)/src/util/libgnunetutil.la
53 54
54gnunet_hello_SOURCES = \ 55gnunet_hello_SOURCES = \
55 gnunet-hello.c 56 gnunet-hello.c
56gnunet_hello_LDADD = \ 57gnunet_hello_LDADD = \
57 libgnunethello.la \ 58 libgnunethello.la \
58 $(top_builddir)/src/util/libgnunetutil.la 59 $(top_builddir)/src/util/libgnunetutil.la
59gnunet_hello_LDFLAGS = \ 60gnunet_hello_LDFLAGS = \
60 $(GN_LIBINTL) 61 $(GN_LIBINTL)
diff --git a/src/hello/hello-uri.c b/src/hello/hello-uri.c
new file mode 100644
index 000000000..347c4bf0c
--- /dev/null
+++ b/src/hello/hello-uri.c
@@ -0,0 +1,391 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2022 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
21/**
22 * @file hello/hello-uri.c
23 * @brief helper library for handling URI-based HELLOs
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_signatures.h"
28#include "gnunet_hello_uri_lib.h"
29#include "gnunet_protocols.h"
30#include "gnunet_util_lib.h"
31
32GNUNET_NETWORK_STRUCT_BEGIN
33
34/**
35 * Binary block we sign when we sign an address.
36 */
37struct HelloUriMessage
38{
39 /**
40 * Purpose must be #GNUNET_MESSAGE_TYPE_HELLO_URI
41 */
42 struct GNUNET_MessageHeader header;
43
44 /**
45 * Reserved. 0.
46 */
47 uint16_t reserved GNUNET_PACKED;
48
49 /**
50 * Number of URLs encoded after the end of the struct, in NBO.
51 */
52 uint16_t url_counter GNUNET_PACKED;
53
54 /**
55 * Public key of the peer.
56 */
57 struct GNUNET_PeerIdentity pid;
58};
59GNUNET_NETWORK_STRUCT_END
60
61
62/**
63 * Address of a peer.
64 */
65struct Address
66{
67 /**
68 * Kept in a DLL.
69 */
70 struct Address *next;
71
72 /**
73 * Kept in a DLL.
74 */
75 struct Address *prev;
76
77 /**
78 * Actual URI, allocated at the end of this struct.
79 */
80 const char *uri;
81
82 /**
83 * Length of @a uri including 0-terminator.
84 */
85 size_t uri_len;
86};
87
88
89/**
90 * Context for building (or parsing) HELLO URIs.
91 */
92struct GNUNET_HELLO_Builder
93{
94 /**
95 * Public key of the peer.
96 */
97 struct GNUNET_PeerIdentity pid;
98
99 /**
100 * Head of the addresses DLL.
101 */
102 struct Address *a_head;
103
104 /**
105 * Tail of the addresses DLL.
106 */
107 struct Address *a_tail;
108
109 /**
110 * Length of the @a a_head DLL.
111 */
112 unsigned int a_length;
113
114};
115
116
117struct GNUNET_HELLO_Builder *
118GNUNET_HELLO_builder_new (const struct GNUNET_PeerIdentity *pid)
119{
120 struct GNUNET_HELLO_Builder *builder;
121
122 builder = GNUNET_new (struct GNUNET_HELLO_Builder);
123 builder->pid = *pid;
124 return builder;
125}
126
127
128void
129GNUNET_HELLO_builder_free (struct GNUNET_HELLO_Builder *builder)
130{
131 struct Address *a;
132
133 while (NULL != (a = builder->a_head))
134 {
135 GNUNET_CONTAINER_DLL_remove (builder->a_head,
136 builder->a_tail,
137 a);
138 builder->a_length--;
139 GNUNET_free (a);
140 }
141 GNUNET_assert (0 == builder->a_length);
142 GNUNET_free (builder);
143}
144
145
146struct GNUNET_HELLO_Builder *
147GNUNET_HELLO_builder_from_msg (const struct GNUNET_MessageHeader *msg)
148{
149 const struct HelloUriMessage *h;
150 struct GNUNET_HELLO_Builder *b;
151 uint16_t size = ntohs (msg->size);
152 const char *pos;
153
154 if (GNUNET_MESSAGE_TYPE_HELLO_URI != ntohs (msg->type))
155 {
156 GNUNET_break (0);
157 return NULL;
158 }
159 if (sizeof (struct HelloUriMessage) < size)
160 {
161 GNUNET_break_op (0);
162 return NULL;
163 }
164 h = (const struct HelloUriMessage *) msg;
165 pos = (const char *) &h[1];
166 size -= sizeof (*h);
167 b = GNUNET_HELLO_builder_new (&h->pid);
168 for (unsigned int i = 0; i<ntohs (h->url_counter); i++)
169 {
170 const char *end = memchr (pos,
171 '\0',
172 size);
173
174 if (NULL == end)
175 {
176 GNUNET_break_op (0);
177 GNUNET_HELLO_builder_free (b);
178 return NULL;
179 }
180 if (GNUNET_OK !=
181 GNUNET_HELLO_builder_add_address (b,
182 pos))
183 {
184 GNUNET_break_op (0);
185 GNUNET_HELLO_builder_free (b);
186 return NULL;
187 }
188 end++; /* skip '\0' */
189 size -= (end - pos);
190 pos = end;
191 }
192 if (0 != size)
193 {
194 GNUNET_break_op (0);
195 GNUNET_HELLO_builder_free (b);
196 return NULL;
197 }
198 return b;
199}
200
201
202struct GNUNET_HELLO_Builder *
203GNUNET_HELLO_builder_from_block (const void *block,
204 size_t block_size)
205{
206 const struct GNUNET_PeerIdentity *pid = block;
207 struct GNUNET_HELLO_Builder *b;
208
209 if (block_size < sizeof (*pid))
210 {
211 GNUNET_break_op (0);
212 return NULL;
213 }
214 b = GNUNET_HELLO_builder_new (pid);
215 block += sizeof (*pid);
216 block_size -= sizeof (*pid);
217 while (block_size > 0)
218 {
219 const void *end = memchr (block,
220 '\0',
221 block_size);
222
223 if (NULL == end)
224 {
225 GNUNET_break_op (0);
226 GNUNET_HELLO_builder_free (b);
227 return NULL;
228 }
229 if (GNUNET_OK !=
230 GNUNET_HELLO_builder_add_address (b,
231 block))
232 {
233 GNUNET_break_op (0);
234 GNUNET_HELLO_builder_free (b);
235 return NULL;
236 }
237 end++;
238 block_size -= (end - block);
239 block = end;
240 }
241 return b;
242}
243
244
245struct GNUNET_HELLO_Builder *
246GNUNET_HELLO_builder_from_url (const char *url)
247{
248 // FIXME!
249 return NULL;
250}
251
252
253struct GNUNET_MQ_Envelope *
254GNUNET_HELLO_builder_to_env (struct GNUNET_HELLO_Builder *builder)
255{
256 struct GNUNET_MQ_Envelope *env;
257 struct HelloUriMessage *msg;
258 size_t blen;
259
260 blen = 0;
261 GNUNET_assert (GNUNET_NO ==
262 GNUNET_HELLO_builder_to_block (builder,
263 NULL,
264 &blen));
265 env = GNUNET_MQ_msg_extra (msg,
266 blen,
267 GNUNET_MESSAGE_TYPE_HELLO_URI);
268 msg->pid = builder->pid;
269 GNUNET_assert (GNUNET_OK ==
270 GNUNET_HELLO_builder_to_block (builder,
271 &msg[1],
272 &blen));
273 return env;
274}
275
276
277char *
278GNUNET_HELLO_builder_to_url (struct GNUNET_HELLO_Builder *builder)
279{
280 // FIXME!
281 return NULL;
282}
283
284
285enum GNUNET_GenericReturnValue
286GNUNET_HELLO_builder_to_block (struct GNUNET_HELLO_Builder *builder,
287 void *block,
288 size_t *block_size)
289{
290 size_t needed = sizeof (struct GNUNET_PeerIdentity);
291 char *pos;
292
293 for (struct Address *a = builder->a_head;
294 NULL != a;
295 a = a->next)
296 {
297 GNUNET_assert (needed + a->uri_len > needed);
298 needed += a->uri_len;
299 }
300 if ( (NULL == block) ||
301 (needed < *block_size) )
302 {
303 *block_size = needed;
304 return GNUNET_NO;
305 }
306 memcpy (block,
307 &builder->pid,
308 sizeof (builder->pid));
309 pos = block + sizeof (builder->pid);
310 for (struct Address *a = builder->a_head;
311 NULL != a;
312 a = a->next)
313 {
314 memcpy (pos,
315 a->uri,
316 a->uri_len);
317 pos += a->uri_len;
318 }
319 *block_size = needed;
320 return GNUNET_OK;
321}
322
323
324enum GNUNET_GenericReturnValue
325GNUNET_HELLO_builder_add_address (struct GNUNET_HELLO_Builder *builder,
326 const char *address)
327{
328 size_t alen = strlen (address) + 1;
329 struct Address *a;
330
331 /* check for duplicates */
332 for (a = builder->a_head;
333 NULL != a;
334 a = a->next)
335 if (0 == strcmp (address,
336 a->uri))
337 return GNUNET_NO;
338 a = GNUNET_malloc (sizeof (struct Address) + alen);
339 a->uri_len = alen;
340 memcpy (&a[1],
341 address,
342 alen);
343 a->uri = (const char *) &a[1];
344 GNUNET_CONTAINER_DLL_insert (builder->a_head,
345 builder->a_tail,
346 a);
347 return GNUNET_OK;
348}
349
350
351enum GNUNET_GenericReturnValue
352GNUNET_HELLO_builder_del_address (struct GNUNET_HELLO_Builder *builder,
353 const char *address)
354{
355 struct Address *a;
356
357 /* check for duplicates */
358 for (a = builder->a_head;
359 NULL != a;
360 a = a->next)
361 if (0 == strcmp (address,
362 a->uri))
363 break;
364 if (NULL == a)
365 return GNUNET_NO;
366 GNUNET_CONTAINER_DLL_remove (builder->a_head,
367 builder->a_tail,
368 a);
369 GNUNET_free (a);
370 return GNUNET_OK;
371}
372
373
374void
375GNUNET_HELLO_builder_iterate (const struct GNUNET_HELLO_Builder *builder,
376 struct GNUNET_PeerIdentity *pid,
377 GNUNET_HELLO_UriCallback uc,
378 void *uc_cls)
379{
380 struct Address *nxt;
381
382 *pid = builder->pid;
383 for (struct Address *a = builder->a_head;
384 NULL != a;
385 a = nxt)
386 {
387 nxt = a->next;
388 uc (uc_cls,
389 a->uri);
390 }
391}