diff options
author | Christian Grothoff <christian@grothoff.org> | 2022-01-12 14:34:56 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2022-02-19 12:39:55 +0100 |
commit | 3e3081cfd22f5dacbeaba2843131c4aec530b562 (patch) | |
tree | c382476a75516d9becf1f813c994f5d571f95c2d /src/hello | |
parent | cd84bf32e23b4396583a8fa1bfe4a00c1fba3715 (diff) | |
download | gnunet-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.am | 11 | ||||
-rw-r--r-- | src/hello/hello-uri.c | 391 |
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 | |||
11 | libgnunethello_la_SOURCES = \ | 11 | libgnunethello_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 | ||
15 | libgnunethello_la_LIBADD = \ | 16 | libgnunethello_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 |
37 | test_hello_LDADD = \ | 38 | test_hello_LDADD = \ |
38 | libgnunethello.la \ | 39 | libgnunethello.la \ |
39 | $(top_builddir)/src/util/libgnunetutil.la | 40 | $(top_builddir)/src/util/libgnunetutil.la |
40 | 41 | ||
41 | test_hello_ng_SOURCES = \ | 42 | test_hello_ng_SOURCES = \ |
42 | test_hello-ng.c | 43 | test_hello-ng.c |
43 | test_hello_ng_LDADD = \ | 44 | test_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 | ||
48 | test_friend_hello_SOURCES = \ | 49 | test_friend_hello_SOURCES = \ |
49 | test_friend_hello.c | 50 | test_friend_hello.c |
50 | test_friend_hello_LDADD = \ | 51 | test_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 | ||
54 | gnunet_hello_SOURCES = \ | 55 | gnunet_hello_SOURCES = \ |
55 | gnunet-hello.c | 56 | gnunet-hello.c |
56 | gnunet_hello_LDADD = \ | 57 | gnunet_hello_LDADD = \ |
57 | libgnunethello.la \ | 58 | libgnunethello.la \ |
58 | $(top_builddir)/src/util/libgnunetutil.la | 59 | $(top_builddir)/src/util/libgnunetutil.la |
59 | gnunet_hello_LDFLAGS = \ | 60 | gnunet_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 | |||
32 | GNUNET_NETWORK_STRUCT_BEGIN | ||
33 | |||
34 | /** | ||
35 | * Binary block we sign when we sign an address. | ||
36 | */ | ||
37 | struct 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 | }; | ||
59 | GNUNET_NETWORK_STRUCT_END | ||
60 | |||
61 | |||
62 | /** | ||
63 | * Address of a peer. | ||
64 | */ | ||
65 | struct 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 | */ | ||
92 | struct 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 | |||
117 | struct GNUNET_HELLO_Builder * | ||
118 | GNUNET_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 | |||
128 | void | ||
129 | GNUNET_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 | |||
146 | struct GNUNET_HELLO_Builder * | ||
147 | GNUNET_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 | |||
202 | struct GNUNET_HELLO_Builder * | ||
203 | GNUNET_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 | |||
245 | struct GNUNET_HELLO_Builder * | ||
246 | GNUNET_HELLO_builder_from_url (const char *url) | ||
247 | { | ||
248 | // FIXME! | ||
249 | return NULL; | ||
250 | } | ||
251 | |||
252 | |||
253 | struct GNUNET_MQ_Envelope * | ||
254 | GNUNET_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 | |||
277 | char * | ||
278 | GNUNET_HELLO_builder_to_url (struct GNUNET_HELLO_Builder *builder) | ||
279 | { | ||
280 | // FIXME! | ||
281 | return NULL; | ||
282 | } | ||
283 | |||
284 | |||
285 | enum GNUNET_GenericReturnValue | ||
286 | GNUNET_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 | |||
324 | enum GNUNET_GenericReturnValue | ||
325 | GNUNET_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 | |||
351 | enum GNUNET_GenericReturnValue | ||
352 | GNUNET_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 | |||
374 | void | ||
375 | GNUNET_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 | } | ||