diff options
Diffstat (limited to 'src/messenger')
78 files changed, 0 insertions, 16822 deletions
diff --git a/src/messenger/.gitignore b/src/messenger/.gitignore deleted file mode 100644 index ed78c5562..000000000 --- a/src/messenger/.gitignore +++ /dev/null | |||
@@ -1,14 +0,0 @@ | |||
1 | gnunet-service-messenger | ||
2 | gnunet-messenger | ||
3 | test_messenger_api | ||
4 | test_messenger_anonymous | ||
5 | test_messenger_sync_client | ||
6 | test_messenger_async_client | ||
7 | test_messenger_worst_client | ||
8 | test_messenger_sync_p2p | ||
9 | test_messenger_async_p2p | ||
10 | test_messenger_worst_p2p | ||
11 | test_messenger_server | ||
12 | test_messenger_growth | ||
13 | test_messenger_ring | ||
14 | test_messenger_adapt | ||
diff --git a/src/messenger/Makefile.am b/src/messenger/Makefile.am deleted file mode 100644 index 4be11f3aa..000000000 --- a/src/messenger/Makefile.am +++ /dev/null | |||
@@ -1,235 +0,0 @@ | |||
1 | # This Makefile.am is in the public domain | ||
2 | AM_CPPFLAGS = -I$(top_srcdir)/src/include | ||
3 | |||
4 | if USE_COVERAGE | ||
5 | AM_CFLAGS = --coverage -O0 | ||
6 | XLIB = -lgcov | ||
7 | endif | ||
8 | |||
9 | pkgcfgdir= $(pkgdatadir)/config.d/ | ||
10 | |||
11 | libexecdir= $(pkglibdir)/libexec/ | ||
12 | |||
13 | plugin_LTLIBRARIES = \ | ||
14 | libgnunet_plugin_gnsrecord_messenger.la | ||
15 | |||
16 | |||
17 | libgnunet_plugin_gnsrecord_messenger_la_SOURCES = \ | ||
18 | plugin_gnsrecord_messenger.c | ||
19 | libgnunet_plugin_gnsrecord_messenger_la_LIBADD = \ | ||
20 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
21 | $(LTLIBINTL) | ||
22 | libgnunet_plugin_gnsrecord_messenger_la_LDFLAGS = \ | ||
23 | $(GN_PLUGIN_LDFLAGS) | ||
24 | |||
25 | |||
26 | pkgcfg_DATA = \ | ||
27 | messenger.conf | ||
28 | |||
29 | plugindir = $(libdir)/gnunet | ||
30 | |||
31 | AM_CLFAGS = -g | ||
32 | |||
33 | libexec_PROGRAMS = \ | ||
34 | gnunet-service-messenger \ | ||
35 | $(EXP_LIBEXEC) | ||
36 | |||
37 | bin_PROGRAMS = \ | ||
38 | gnunet-messenger | ||
39 | |||
40 | lib_LTLIBRARIES = \ | ||
41 | libgnunetmessenger.la \ | ||
42 | $(EXP_LIB) | ||
43 | |||
44 | libgnunetmessenger_la_SOURCES = \ | ||
45 | messenger_api.c \ | ||
46 | messenger_api_ego.h \ | ||
47 | messenger_api_contact.c messenger_api_contact.h \ | ||
48 | messenger_api_contact_store.c messenger_api_contact_store.h \ | ||
49 | messenger_api_message.c messenger_api_message.h \ | ||
50 | messenger_api_list_tunnels.c messenger_api_list_tunnels.h \ | ||
51 | messenger_api_util.c messenger_api_util.h \ | ||
52 | messenger_api_handle.c messenger_api_handle.h \ | ||
53 | messenger_api_room.c messenger_api_room.h | ||
54 | libgnunetmessenger_la_LIBADD = \ | ||
55 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
56 | $(top_builddir)/src/cadet/libgnunetcadet.la \ | ||
57 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
58 | $(XLIB) \ | ||
59 | $(LTLIBINTL) | ||
60 | libgnunetmessenger_la_LDFLAGS = \ | ||
61 | $(GN_LIB_LDFLAGS) \ | ||
62 | -version-info 0:0:0 | ||
63 | |||
64 | gnunet_messenger_SOURCES = \ | ||
65 | gnunet-messenger.c | ||
66 | gnunet_messenger_LDADD = \ | ||
67 | libgnunetmessenger.la \ | ||
68 | $(top_builddir)/src/util/libgnunetutil.la | ||
69 | gnunet_messenger_LDFLAGS = \ | ||
70 | $(GN_LIBINTL) | ||
71 | |||
72 | gnunet_service_messenger_SOURCES = \ | ||
73 | gnunet-service-messenger.c gnunet-service-messenger.h \ | ||
74 | gnunet-service-messenger_service.c gnunet-service-messenger_service.h \ | ||
75 | gnunet-service-messenger_list_handles.c gnunet-service-messenger_list_handles.h \ | ||
76 | gnunet-service-messenger_list_messages.c gnunet-service-messenger_list_messages.h \ | ||
77 | gnunet-service-messenger_member_session.c gnunet-service-messenger_member_session.h \ | ||
78 | gnunet-service-messenger_member.c gnunet-service-messenger_member.h \ | ||
79 | gnunet-service-messenger_member_store.c gnunet-service-messenger_member_store.h \ | ||
80 | gnunet-service-messenger_message_handle.c gnunet-service-messenger_message_handle.h \ | ||
81 | gnunet-service-messenger_message_kind.c gnunet-service-messenger_message_kind.h \ | ||
82 | gnunet-service-messenger_message_recv.c gnunet-service-messenger_message_recv.h \ | ||
83 | gnunet-service-messenger_message_send.c gnunet-service-messenger_message_send.h \ | ||
84 | gnunet-service-messenger_message_state.c gnunet-service-messenger_message_state.h \ | ||
85 | gnunet-service-messenger_message_store.c gnunet-service-messenger_message_store.h \ | ||
86 | gnunet-service-messenger_operation_store.c gnunet-service-messenger_operation_store.h \ | ||
87 | gnunet-service-messenger_operation.c gnunet-service-messenger_operation.h \ | ||
88 | gnunet-service-messenger_basement.c gnunet-service-messenger_basement.h \ | ||
89 | gnunet-service-messenger_ego_store.c gnunet-service-messenger_ego_store.h \ | ||
90 | gnunet-service-messenger_handle.c gnunet-service-messenger_handle.h \ | ||
91 | gnunet-service-messenger_room.c gnunet-service-messenger_room.h \ | ||
92 | gnunet-service-messenger_tunnel.c gnunet-service-messenger_tunnel.h | ||
93 | gnunet_service_messenger_LDADD = \ | ||
94 | libgnunetmessenger.la \ | ||
95 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
96 | $(top_builddir)/src/cadet/libgnunetcadet.la \ | ||
97 | $(top_builddir)/src/identity/libgnunetidentity.la \ | ||
98 | $(GN_LIBINTL) | ||
99 | |||
100 | check_PROGRAMS = \ | ||
101 | test_messenger_api \ | ||
102 | test_messenger_anonymous \ | ||
103 | test_messenger_sync_client \ | ||
104 | test_messenger_async_client \ | ||
105 | test_messenger_worst_client \ | ||
106 | test_messenger_sync_p2p \ | ||
107 | test_messenger_async_p2p \ | ||
108 | test_messenger_worst_p2p \ | ||
109 | test_messenger_server \ | ||
110 | test_messenger_growth \ | ||
111 | test_messenger_ring \ | ||
112 | test_messenger_adapt | ||
113 | |||
114 | if ENABLE_TEST_RUN | ||
115 | AM_TESTS_ENVIRONMENT=export GNUNET_PREFIX=$${GNUNET_PREFIX:-@libdir@};export PATH=$${GNUNET_PREFIX:-@prefix@}/bin:$$PATH;unset XDG_DATA_HOME;unset XDG_CONFIG_HOME; | ||
116 | TESTS = \ | ||
117 | $(check_PROGRAMS) | ||
118 | endif | ||
119 | |||
120 | test_messenger_api_SOURCES = \ | ||
121 | test_messenger.c | ||
122 | test_messenger_api_LDADD = \ | ||
123 | libgnunetmessenger.la \ | ||
124 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
125 | $(top_builddir)/src/util/libgnunetutil.la | ||
126 | |||
127 | test_messenger_anonymous_SOURCES = \ | ||
128 | test_messenger_anonymous.c | ||
129 | test_messenger_anonymous_LDADD = \ | ||
130 | libgnunetmessenger.la \ | ||
131 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
132 | $(top_builddir)/src/util/libgnunetutil.la | ||
133 | |||
134 | test_messenger_sync_client_SOURCES = \ | ||
135 | test_messenger_sync_client.c \ | ||
136 | testing_messenger_barrier.c testing_messenger_barrier.h \ | ||
137 | testing_messenger_setup.c testing_messenger_setup.h | ||
138 | test_messenger_sync_client_LDADD = \ | ||
139 | libgnunetmessenger.la \ | ||
140 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
141 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
142 | $(top_builddir)/src/util/libgnunetutil.la | ||
143 | |||
144 | test_messenger_async_client_SOURCES = \ | ||
145 | test_messenger_async_client.c \ | ||
146 | testing_messenger_barrier.c testing_messenger_barrier.h \ | ||
147 | testing_messenger_setup.c testing_messenger_setup.h | ||
148 | test_messenger_async_client_LDADD = \ | ||
149 | libgnunetmessenger.la \ | ||
150 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
151 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
152 | $(top_builddir)/src/util/libgnunetutil.la | ||
153 | |||
154 | test_messenger_worst_client_SOURCES = \ | ||
155 | test_messenger_worst_client.c \ | ||
156 | testing_messenger_barrier.c testing_messenger_barrier.h \ | ||
157 | testing_messenger_setup.c testing_messenger_setup.h | ||
158 | test_messenger_worst_client_LDADD = \ | ||
159 | libgnunetmessenger.la \ | ||
160 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
161 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
162 | $(top_builddir)/src/util/libgnunetutil.la | ||
163 | |||
164 | test_messenger_sync_p2p_SOURCES = \ | ||
165 | test_messenger_sync_p2p.c \ | ||
166 | testing_messenger_barrier.c testing_messenger_barrier.h \ | ||
167 | testing_messenger_setup.c testing_messenger_setup.h | ||
168 | test_messenger_sync_p2p_LDADD = \ | ||
169 | libgnunetmessenger.la \ | ||
170 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
171 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
172 | $(top_builddir)/src/util/libgnunetutil.la | ||
173 | |||
174 | test_messenger_async_p2p_SOURCES = \ | ||
175 | test_messenger_async_p2p.c \ | ||
176 | testing_messenger_barrier.c testing_messenger_barrier.h \ | ||
177 | testing_messenger_setup.c testing_messenger_setup.h | ||
178 | test_messenger_async_p2p_LDADD = \ | ||
179 | libgnunetmessenger.la \ | ||
180 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
181 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
182 | $(top_builddir)/src/util/libgnunetutil.la | ||
183 | |||
184 | test_messenger_worst_p2p_SOURCES = \ | ||
185 | test_messenger_worst_p2p.c \ | ||
186 | testing_messenger_barrier.c testing_messenger_barrier.h \ | ||
187 | testing_messenger_setup.c testing_messenger_setup.h | ||
188 | test_messenger_worst_p2p_LDADD = \ | ||
189 | libgnunetmessenger.la \ | ||
190 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
191 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
192 | $(top_builddir)/src/util/libgnunetutil.la | ||
193 | |||
194 | test_messenger_server_SOURCES = \ | ||
195 | test_messenger_server.c \ | ||
196 | testing_messenger_barrier.c testing_messenger_barrier.h \ | ||
197 | testing_messenger_setup.c testing_messenger_setup.h | ||
198 | test_messenger_server_LDADD = \ | ||
199 | libgnunetmessenger.la \ | ||
200 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
201 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
202 | $(top_builddir)/src/util/libgnunetutil.la | ||
203 | |||
204 | test_messenger_growth_SOURCES = \ | ||
205 | test_messenger_growth.c \ | ||
206 | testing_messenger_barrier.c testing_messenger_barrier.h \ | ||
207 | testing_messenger_setup.c testing_messenger_setup.h | ||
208 | test_messenger_growth_LDADD = \ | ||
209 | libgnunetmessenger.la \ | ||
210 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
211 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
212 | $(top_builddir)/src/util/libgnunetutil.la | ||
213 | |||
214 | test_messenger_ring_SOURCES = \ | ||
215 | test_messenger_ring.c \ | ||
216 | testing_messenger_barrier.c testing_messenger_barrier.h \ | ||
217 | testing_messenger_setup.c testing_messenger_setup.h | ||
218 | test_messenger_ring_LDADD = \ | ||
219 | libgnunetmessenger.la \ | ||
220 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
221 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
222 | $(top_builddir)/src/util/libgnunetutil.la | ||
223 | |||
224 | test_messenger_adapt_SOURCES = \ | ||
225 | test_messenger_adapt.c \ | ||
226 | testing_messenger_barrier.c testing_messenger_barrier.h \ | ||
227 | testing_messenger_setup.c testing_messenger_setup.h | ||
228 | test_messenger_adapt_LDADD = \ | ||
229 | libgnunetmessenger.la \ | ||
230 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
231 | $(top_builddir)/src/testing/libgnunettesting.la \ | ||
232 | $(top_builddir)/src/util/libgnunetutil.la | ||
233 | |||
234 | EXTRA_DIST = \ | ||
235 | test_messenger_api.conf | ||
diff --git a/src/messenger/gnunet-messenger.c b/src/messenger/gnunet-messenger.c deleted file mode 100644 index e2d106be8..000000000 --- a/src/messenger/gnunet-messenger.c +++ /dev/null | |||
@@ -1,334 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-messenger.c | ||
23 | * @brief Print information about messenger groups. | ||
24 | */ | ||
25 | |||
26 | #include <stdio.h> | ||
27 | |||
28 | #include "platform.h" | ||
29 | #include "gnunet_util_lib.h" | ||
30 | #include "gnunet_messenger_service.h" | ||
31 | |||
32 | struct GNUNET_MESSENGER_Handle *messenger; | ||
33 | |||
34 | /** | ||
35 | * Function called whenever a message is received or sent. | ||
36 | * | ||
37 | * @param[in/out] cls Closure | ||
38 | * @param[in] room Room | ||
39 | * @param[in] sender Sender of message | ||
40 | * @param[in] message Message | ||
41 | * @param[in] hash Hash of message | ||
42 | * @param[in] flags Flags of message | ||
43 | */ | ||
44 | void | ||
45 | on_message (void *cls, | ||
46 | struct GNUNET_MESSENGER_Room *room, | ||
47 | const struct GNUNET_MESSENGER_Contact *sender, | ||
48 | const struct GNUNET_MESSENGER_Message *message, | ||
49 | const struct GNUNET_HashCode *hash, | ||
50 | enum GNUNET_MESSENGER_MessageFlags flags) | ||
51 | { | ||
52 | const char *sender_name = GNUNET_MESSENGER_contact_get_name (sender); | ||
53 | |||
54 | if (!sender_name) | ||
55 | sender_name = "anonymous"; | ||
56 | |||
57 | printf ("[%s] ", GNUNET_sh2s(&(message->header.sender_id))); | ||
58 | |||
59 | if (flags & GNUNET_MESSENGER_FLAG_PRIVATE) | ||
60 | printf ("*"); | ||
61 | |||
62 | switch (message->header.kind) | ||
63 | { | ||
64 | case GNUNET_MESSENGER_KIND_JOIN: | ||
65 | { | ||
66 | printf ("* '%s' joined the room!\n", sender_name); | ||
67 | break; | ||
68 | } | ||
69 | case GNUNET_MESSENGER_KIND_NAME: | ||
70 | { | ||
71 | printf ("* '%s' gets renamed to '%s'\n", sender_name, message->body.name.name); | ||
72 | break; | ||
73 | } | ||
74 | case GNUNET_MESSENGER_KIND_LEAVE: | ||
75 | { | ||
76 | printf ("* '%s' leaves the room!\n", sender_name); | ||
77 | break; | ||
78 | } | ||
79 | case GNUNET_MESSENGER_KIND_PEER: | ||
80 | { | ||
81 | printf ("* '%s' opened the room on: %s\n", sender_name, GNUNET_i2s_full (&(message->body.peer.peer))); | ||
82 | break; | ||
83 | } | ||
84 | case GNUNET_MESSENGER_KIND_TEXT: | ||
85 | { | ||
86 | if (flags & GNUNET_MESSENGER_FLAG_SENT) | ||
87 | printf (">"); | ||
88 | else | ||
89 | printf ("<"); | ||
90 | |||
91 | printf (" '%s' says: \"%s\"\n", sender_name, message->body.text.text); | ||
92 | break; | ||
93 | } | ||
94 | default: | ||
95 | { | ||
96 | printf ("~ message: %s\n", GNUNET_MESSENGER_name_of_kind(message->header.kind)); | ||
97 | break; | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | |||
102 | struct GNUNET_SCHEDULER_Task *read_task; | ||
103 | |||
104 | /** | ||
105 | * Task to shut down this application. | ||
106 | * | ||
107 | * @param[in/out] cls Closure | ||
108 | */ | ||
109 | static void | ||
110 | shutdown_hook (void *cls) | ||
111 | { | ||
112 | struct GNUNET_MESSENGER_Room *room = cls; | ||
113 | |||
114 | if (read_task) | ||
115 | GNUNET_SCHEDULER_cancel (read_task); | ||
116 | |||
117 | if (room) | ||
118 | GNUNET_MESSENGER_close_room (room); | ||
119 | |||
120 | if (messenger) | ||
121 | GNUNET_MESSENGER_disconnect (messenger); | ||
122 | } | ||
123 | |||
124 | static void | ||
125 | listen_stdio (void *cls); | ||
126 | |||
127 | #define MAX_BUFFER_SIZE 60000 | ||
128 | |||
129 | static int | ||
130 | iterate_send_private_message (void *cls, | ||
131 | struct GNUNET_MESSENGER_Room *room, | ||
132 | const struct GNUNET_MESSENGER_Contact *contact) | ||
133 | { | ||
134 | struct GNUNET_MESSENGER_Message *message = cls; | ||
135 | |||
136 | if (GNUNET_MESSENGER_contact_get_key(contact)) | ||
137 | GNUNET_MESSENGER_send_message (room, message, contact); | ||
138 | |||
139 | return GNUNET_YES; | ||
140 | } | ||
141 | |||
142 | int private_mode; | ||
143 | |||
144 | /** | ||
145 | * Task run in stdio mode, after some data is available at stdin. | ||
146 | * | ||
147 | * @param[in/out] cls Closure | ||
148 | */ | ||
149 | static void | ||
150 | read_stdio (void *cls) | ||
151 | { | ||
152 | read_task = NULL; | ||
153 | |||
154 | char buffer[MAX_BUFFER_SIZE]; | ||
155 | ssize_t length; | ||
156 | |||
157 | length = read (0, buffer, MAX_BUFFER_SIZE); | ||
158 | |||
159 | if ((length <= 0) || (length >= MAX_BUFFER_SIZE)) | ||
160 | { | ||
161 | GNUNET_SCHEDULER_shutdown (); | ||
162 | return; | ||
163 | } | ||
164 | |||
165 | if (buffer[length - 1] == '\n') | ||
166 | buffer[length - 1] = '\0'; | ||
167 | else | ||
168 | buffer[length] = '\0'; | ||
169 | |||
170 | struct GNUNET_MESSENGER_Room *room = cls; | ||
171 | |||
172 | struct GNUNET_MESSENGER_Message message; | ||
173 | message.header.kind = GNUNET_MESSENGER_KIND_TEXT; | ||
174 | message.body.text.text = buffer; | ||
175 | |||
176 | if (GNUNET_YES == private_mode) | ||
177 | GNUNET_MESSENGER_iterate_members(room, iterate_send_private_message, &message); | ||
178 | else | ||
179 | GNUNET_MESSENGER_send_message (room, &message, NULL); | ||
180 | |||
181 | read_task = GNUNET_SCHEDULER_add_now (listen_stdio, cls); | ||
182 | } | ||
183 | |||
184 | /** | ||
185 | * Wait for input on STDIO and send it out over the #ch. | ||
186 | * | ||
187 | * @param[in/out] cls Closure | ||
188 | */ | ||
189 | static void | ||
190 | listen_stdio (void *cls) | ||
191 | { | ||
192 | read_task = NULL; | ||
193 | |||
194 | struct GNUNET_NETWORK_FDSet *rs = GNUNET_NETWORK_fdset_create (); | ||
195 | |||
196 | GNUNET_NETWORK_fdset_set_native (rs, 0); | ||
197 | |||
198 | read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, | ||
199 | GNUNET_TIME_UNIT_FOREVER_REL, rs, | ||
200 | NULL, &read_stdio, cls); | ||
201 | |||
202 | GNUNET_NETWORK_fdset_destroy (rs); | ||
203 | } | ||
204 | |||
205 | /** | ||
206 | * Initial task to startup application. | ||
207 | * | ||
208 | * @param[in/out] cls Closure | ||
209 | */ | ||
210 | static void | ||
211 | idle (void *cls) | ||
212 | { | ||
213 | struct GNUNET_MESSENGER_Room *room = cls; | ||
214 | |||
215 | printf ("* You joined the room.\n"); | ||
216 | |||
217 | read_task = GNUNET_SCHEDULER_add_now (listen_stdio, room); | ||
218 | } | ||
219 | |||
220 | char *door_id; | ||
221 | char *ego_name; | ||
222 | char *room_key; | ||
223 | |||
224 | struct GNUNET_SCHEDULER_Task *shutdown_task; | ||
225 | |||
226 | /** | ||
227 | * Function called when an identity is retrieved. | ||
228 | * | ||
229 | * @param[in/out] cls Closure | ||
230 | * @param[in/out] handle Handle of messenger service | ||
231 | */ | ||
232 | static void | ||
233 | on_identity (void *cls, | ||
234 | struct GNUNET_MESSENGER_Handle *handle) | ||
235 | { | ||
236 | struct GNUNET_HashCode key; | ||
237 | memset (&key, 0, sizeof(key)); | ||
238 | |||
239 | if (room_key) | ||
240 | GNUNET_CRYPTO_hash (room_key, strlen (room_key), &key); | ||
241 | |||
242 | struct GNUNET_PeerIdentity door_peer; | ||
243 | struct GNUNET_PeerIdentity *door = NULL; | ||
244 | |||
245 | if ((door_id) && | ||
246 | (GNUNET_OK == GNUNET_CRYPTO_eddsa_public_key_from_string (door_id, strlen (door_id), &(door_peer.public_key)))) | ||
247 | door = &door_peer; | ||
248 | |||
249 | const char *name = GNUNET_MESSENGER_get_name (handle); | ||
250 | |||
251 | if (!name) | ||
252 | name = "anonymous"; | ||
253 | |||
254 | printf ("* Welcome to the messenger, '%s'!\n", name); | ||
255 | |||
256 | struct GNUNET_MESSENGER_Room *room; | ||
257 | |||
258 | if (door) | ||
259 | { | ||
260 | printf ("* You try to entry a room...\n"); | ||
261 | |||
262 | room = GNUNET_MESSENGER_enter_room (messenger, door, &key); | ||
263 | } | ||
264 | else | ||
265 | { | ||
266 | printf ("* You try to open a room...\n"); | ||
267 | |||
268 | room = GNUNET_MESSENGER_open_room (messenger, &key); | ||
269 | } | ||
270 | |||
271 | GNUNET_SCHEDULER_cancel (shutdown_task); | ||
272 | |||
273 | shutdown_task = GNUNET_SCHEDULER_add_shutdown (shutdown_hook, room); | ||
274 | |||
275 | if (!room) | ||
276 | GNUNET_SCHEDULER_shutdown (); | ||
277 | else | ||
278 | { | ||
279 | struct GNUNET_MESSENGER_Message message; | ||
280 | message.header.kind = GNUNET_MESSENGER_KIND_NAME; | ||
281 | message.body.name.name = GNUNET_strdup(name); | ||
282 | |||
283 | GNUNET_MESSENGER_send_message (room, &message, NULL); | ||
284 | GNUNET_free(message.body.name.name); | ||
285 | |||
286 | GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_relative_get_zero_ (), GNUNET_SCHEDULER_PRIORITY_IDLE, idle, | ||
287 | room); | ||
288 | } | ||
289 | } | ||
290 | |||
291 | /** | ||
292 | * Main function that will be run by the scheduler. | ||
293 | * | ||
294 | * @param[in/out] cls closure | ||
295 | * @param[in] args remaining command-line arguments | ||
296 | * @param[in] cfgfile name of the configuration file used (for saving, can be NULL!) | ||
297 | * @param[in] cfg configuration | ||
298 | */ | ||
299 | static void | ||
300 | run (void *cls, | ||
301 | char *const*args, | ||
302 | const char *cfgfile, | ||
303 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
304 | { | ||
305 | messenger = GNUNET_MESSENGER_connect (cfg, ego_name, &on_identity, NULL, &on_message, NULL); | ||
306 | |||
307 | shutdown_task = GNUNET_SCHEDULER_add_shutdown (shutdown_hook, NULL); | ||
308 | } | ||
309 | |||
310 | /** | ||
311 | * The main function to obtain messenger information. | ||
312 | * | ||
313 | * @param[in] argc number of arguments from the command line | ||
314 | * @param[in] argv command line arguments | ||
315 | * @return #EXIT_SUCCESS ok, #EXIT_FAILURE on error | ||
316 | */ | ||
317 | int | ||
318 | main (int argc, | ||
319 | char **argv) | ||
320 | { | ||
321 | const char *description = "Open and connect to rooms using the MESSENGER to chat."; | ||
322 | |||
323 | struct GNUNET_GETOPT_CommandLineOption options[] = | ||
324 | { | ||
325 | GNUNET_GETOPT_option_string ('d', "door", "PEERIDENTITY", "peer identity to entry into the room", &door_id), | ||
326 | GNUNET_GETOPT_option_string ('e', "ego", "IDENTITY", "identity to use for messaging", &ego_name), | ||
327 | GNUNET_GETOPT_option_string ('r', "room", "ROOMKEY", "key of the room to connect to", &room_key), | ||
328 | GNUNET_GETOPT_option_flag ('p', "private", "flag to enable private mode", &private_mode), | ||
329 | GNUNET_GETOPT_OPTION_END | ||
330 | }; | ||
331 | |||
332 | return (GNUNET_OK == GNUNET_PROGRAM_run (argc, argv, "gnunet-messenger\0", gettext_noop(description), options, &run, | ||
333 | NULL) ? EXIT_SUCCESS : EXIT_FAILURE); | ||
334 | } | ||
diff --git a/src/messenger/gnunet-service-messenger.c b/src/messenger/gnunet-service-messenger.c deleted file mode 100644 index 546f4c0d2..000000000 --- a/src/messenger/gnunet-service-messenger.c +++ /dev/null | |||
@@ -1,420 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger.h" | ||
27 | |||
28 | #include "gnunet-service-messenger_handle.h" | ||
29 | #include "gnunet-service-messenger_message_kind.h" | ||
30 | #include "gnunet-service-messenger_service.h" | ||
31 | #include "messenger_api_message.h" | ||
32 | |||
33 | struct GNUNET_MESSENGER_Client | ||
34 | { | ||
35 | struct GNUNET_SERVICE_Client *client; | ||
36 | struct GNUNET_MESSENGER_SrvHandle *handle; | ||
37 | }; | ||
38 | |||
39 | struct GNUNET_MESSENGER_Service *messenger; | ||
40 | |||
41 | static int | ||
42 | check_create (void *cls, | ||
43 | const struct GNUNET_MESSENGER_CreateMessage *msg) | ||
44 | { | ||
45 | GNUNET_MQ_check_zero_termination(msg); | ||
46 | return GNUNET_OK; | ||
47 | } | ||
48 | |||
49 | static void | ||
50 | handle_create (void *cls, | ||
51 | const struct GNUNET_MESSENGER_CreateMessage *msg) | ||
52 | { | ||
53 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
54 | |||
55 | const char *name = ((const char*) msg) + sizeof(*msg); | ||
56 | |||
57 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Handle created with name: %s\n", name); | ||
58 | |||
59 | setup_handle_name (msg_client->handle, strlen (name) > 0 ? name : NULL); | ||
60 | |||
61 | GNUNET_SERVICE_client_continue (msg_client->client); | ||
62 | } | ||
63 | |||
64 | static void | ||
65 | handle_update (void *cls, | ||
66 | const struct GNUNET_MESSENGER_UpdateMessage *msg) | ||
67 | { | ||
68 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
69 | |||
70 | update_handle (msg_client->handle); | ||
71 | |||
72 | GNUNET_SERVICE_client_continue (msg_client->client); | ||
73 | } | ||
74 | |||
75 | static void | ||
76 | handle_destroy (void *cls, | ||
77 | const struct GNUNET_MESSENGER_DestroyMessage *msg) | ||
78 | { | ||
79 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
80 | |||
81 | GNUNET_SERVICE_client_drop (msg_client->client); | ||
82 | } | ||
83 | |||
84 | static int | ||
85 | check_set_name (void *cls, | ||
86 | const struct GNUNET_MESSENGER_NameMessage *msg) | ||
87 | { | ||
88 | GNUNET_MQ_check_zero_termination(msg); | ||
89 | return GNUNET_OK; | ||
90 | } | ||
91 | |||
92 | static void | ||
93 | handle_set_name (void *cls, | ||
94 | const struct GNUNET_MESSENGER_NameMessage *msg) | ||
95 | { | ||
96 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
97 | |||
98 | const char *name = ((const char*) msg) + sizeof(*msg); | ||
99 | |||
100 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Handles name is now: %s\n", name); | ||
101 | |||
102 | set_handle_name (msg_client->handle, name); | ||
103 | |||
104 | GNUNET_SERVICE_client_continue (msg_client->client); | ||
105 | } | ||
106 | |||
107 | static void | ||
108 | handle_room_open (void *cls, | ||
109 | const struct GNUNET_MESSENGER_RoomMessage *msg) | ||
110 | { | ||
111 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
112 | |||
113 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Opening room: %s\n", GNUNET_h2s (&(msg->key))); | ||
114 | |||
115 | if (GNUNET_YES == open_handle_room (msg_client->handle, &(msg->key))) | ||
116 | { | ||
117 | const struct GNUNET_ShortHashCode *member_id = get_handle_member_id (msg_client->handle, &(msg->key)); | ||
118 | |||
119 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Opening room with member id: %s\n", GNUNET_sh2s (member_id)); | ||
120 | |||
121 | struct GNUNET_MESSENGER_RoomMessage *response; | ||
122 | struct GNUNET_MQ_Envelope *env; | ||
123 | |||
124 | env = GNUNET_MQ_msg(response, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN); | ||
125 | GNUNET_memcpy(&(response->key), &(msg->key), sizeof(msg->key)); | ||
126 | GNUNET_MQ_send (msg_client->handle->mq, env); | ||
127 | } | ||
128 | else | ||
129 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Opening room failed: %s\n", GNUNET_h2s (&(msg->key))); | ||
130 | |||
131 | GNUNET_SERVICE_client_continue (msg_client->client); | ||
132 | } | ||
133 | |||
134 | static void | ||
135 | handle_room_entry (void *cls, | ||
136 | const struct GNUNET_MESSENGER_RoomMessage *msg) | ||
137 | { | ||
138 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
139 | |||
140 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Entering room: %s, %s\n", GNUNET_h2s (&(msg->key)), GNUNET_i2s (&(msg->door))); | ||
141 | |||
142 | if (GNUNET_YES == entry_handle_room (msg_client->handle, &(msg->door), &(msg->key))) | ||
143 | { | ||
144 | const struct GNUNET_ShortHashCode *member_id = get_handle_member_id (msg_client->handle, &(msg->key)); | ||
145 | |||
146 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Entering room with member id: %s\n", GNUNET_sh2s (member_id)); | ||
147 | |||
148 | struct GNUNET_MESSENGER_RoomMessage *response; | ||
149 | struct GNUNET_MQ_Envelope *env; | ||
150 | |||
151 | env = GNUNET_MQ_msg(response, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY); | ||
152 | GNUNET_memcpy(&(response->door), &(msg->door), sizeof(msg->door)); | ||
153 | GNUNET_memcpy(&(response->key), &(msg->key), sizeof(msg->key)); | ||
154 | GNUNET_MQ_send (msg_client->handle->mq, env); | ||
155 | } | ||
156 | else | ||
157 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Entrance into room failed: %s, %s\n", GNUNET_h2s (&(msg->key)), | ||
158 | GNUNET_i2s (&(msg->door))); | ||
159 | |||
160 | GNUNET_SERVICE_client_continue (msg_client->client); | ||
161 | } | ||
162 | |||
163 | static void | ||
164 | handle_room_close (void *cls, | ||
165 | const struct GNUNET_MESSENGER_RoomMessage *msg) | ||
166 | { | ||
167 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
168 | |||
169 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Closing room: %s\n", GNUNET_h2s (&(msg->key))); | ||
170 | |||
171 | if (GNUNET_YES == close_handle_room (msg_client->handle, &(msg->key))) | ||
172 | { | ||
173 | const struct GNUNET_ShortHashCode *member_id = get_handle_member_id (msg_client->handle, &(msg->key)); | ||
174 | |||
175 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Closing room with member id: %s\n", GNUNET_sh2s (member_id)); | ||
176 | |||
177 | struct GNUNET_MESSENGER_RoomMessage *response; | ||
178 | struct GNUNET_MQ_Envelope *env; | ||
179 | |||
180 | env = GNUNET_MQ_msg(response, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE); | ||
181 | GNUNET_memcpy(&(response->key), &(msg->key), sizeof(msg->key)); | ||
182 | GNUNET_MQ_send (msg_client->handle->mq, env); | ||
183 | } | ||
184 | else | ||
185 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Closing room failed: %s\n", GNUNET_h2s (&(msg->key))); | ||
186 | |||
187 | GNUNET_SERVICE_client_continue (msg_client->client); | ||
188 | } | ||
189 | |||
190 | static int | ||
191 | check_send_message (void *cls, | ||
192 | const struct GNUNET_MESSENGER_SendMessage *msg) | ||
193 | { | ||
194 | const uint16_t full_length = ntohs (msg->header.size); | ||
195 | |||
196 | if (full_length < sizeof(*msg)) | ||
197 | return GNUNET_NO; | ||
198 | |||
199 | const enum GNUNET_MESSENGER_MessageFlags flags = ( | ||
200 | (enum GNUNET_MESSENGER_MessageFlags) (msg->flags) | ||
201 | ); | ||
202 | |||
203 | const uint16_t length = full_length - sizeof(*msg); | ||
204 | const char *buffer = ((const char*) msg) + sizeof(*msg); | ||
205 | |||
206 | ssize_t key_length = 0; | ||
207 | |||
208 | if (!(flags & GNUNET_MESSENGER_FLAG_PRIVATE)) | ||
209 | goto check_for_message; | ||
210 | |||
211 | struct GNUNET_IDENTITY_PublicKey public_key; | ||
212 | |||
213 | key_length = GNUNET_IDENTITY_read_key_from_buffer(&public_key, buffer, length); | ||
214 | |||
215 | check_for_message: | ||
216 | if (key_length < 0) | ||
217 | return GNUNET_NO; | ||
218 | |||
219 | const uint16_t msg_length = length - key_length; | ||
220 | const char* msg_buffer = buffer + key_length; | ||
221 | |||
222 | struct GNUNET_MESSENGER_Message message; | ||
223 | |||
224 | if (length < get_message_kind_size(GNUNET_MESSENGER_KIND_UNKNOWN, GNUNET_NO)) | ||
225 | return GNUNET_NO; | ||
226 | |||
227 | if (GNUNET_YES != decode_message (&message, msg_length, msg_buffer, GNUNET_NO, NULL)) | ||
228 | return GNUNET_NO; | ||
229 | |||
230 | const int allowed = filter_message_sending(&message); | ||
231 | |||
232 | cleanup_message(&message); | ||
233 | return GNUNET_YES == allowed? GNUNET_OK : GNUNET_NO; | ||
234 | } | ||
235 | |||
236 | static void | ||
237 | handle_send_message (void *cls, | ||
238 | const struct GNUNET_MESSENGER_SendMessage *msg) | ||
239 | { | ||
240 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
241 | |||
242 | const enum GNUNET_MESSENGER_MessageFlags flags = ( | ||
243 | (enum GNUNET_MESSENGER_MessageFlags) (msg->flags) | ||
244 | ); | ||
245 | |||
246 | const struct GNUNET_HashCode *key = &(msg->key); | ||
247 | const char *buffer = ((const char*) msg) + sizeof(*msg); | ||
248 | |||
249 | const uint16_t length = ntohs (msg->header.size) - sizeof(*msg); | ||
250 | ssize_t key_length = 0; | ||
251 | |||
252 | struct GNUNET_IDENTITY_PublicKey public_key; | ||
253 | |||
254 | if (flags & GNUNET_MESSENGER_FLAG_PRIVATE) | ||
255 | key_length = GNUNET_IDENTITY_read_key_from_buffer( | ||
256 | &public_key, buffer, length | ||
257 | ); | ||
258 | |||
259 | const uint16_t msg_length = length - key_length; | ||
260 | const char* msg_buffer = buffer + key_length; | ||
261 | |||
262 | struct GNUNET_MESSENGER_Message message; | ||
263 | decode_message (&message, msg_length, msg_buffer, GNUNET_NO, NULL); | ||
264 | |||
265 | if ((flags & GNUNET_MESSENGER_FLAG_PRIVATE) && | ||
266 | (GNUNET_YES != encrypt_message(&message, &public_key))) | ||
267 | { | ||
268 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Encrypting message failed: Message got dropped!\n"); | ||
269 | |||
270 | goto end_handling; | ||
271 | } | ||
272 | |||
273 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending message: %s to %s\n", | ||
274 | GNUNET_MESSENGER_name_of_kind (message.header.kind), GNUNET_h2s (key)); | ||
275 | |||
276 | if (GNUNET_YES != send_handle_message (msg_client->handle, key, &message)) | ||
277 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Sending message failed: %s to %s\n", | ||
278 | GNUNET_MESSENGER_name_of_kind (message.header.kind), GNUNET_h2s (key)); | ||
279 | |||
280 | end_handling: | ||
281 | cleanup_message(&message); | ||
282 | |||
283 | GNUNET_SERVICE_client_continue (msg_client->client); | ||
284 | } | ||
285 | |||
286 | static void | ||
287 | callback_found_message (void *cls, | ||
288 | struct GNUNET_MESSENGER_SrvRoom *room, | ||
289 | const struct GNUNET_MESSENGER_Message *message, | ||
290 | const struct GNUNET_HashCode *hash) | ||
291 | { | ||
292 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
293 | |||
294 | if (!message) | ||
295 | { | ||
296 | send_room_message(room, msg_client->handle, create_message_request(hash)); | ||
297 | return; | ||
298 | } | ||
299 | |||
300 | struct GNUNET_MESSENGER_MemberStore *store = get_room_member_store(room); | ||
301 | |||
302 | struct GNUNET_MESSENGER_Member *member = get_store_member_of(store, message); | ||
303 | |||
304 | if (!member) | ||
305 | { | ||
306 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Sender of message (%s) unknown!\n", GNUNET_h2s (hash)); | ||
307 | return; | ||
308 | } | ||
309 | |||
310 | struct GNUNET_MESSENGER_MemberSession *session = get_member_session_of(member, message, hash); | ||
311 | |||
312 | if (session) | ||
313 | notify_handle_message (msg_client->handle, room, session, message, hash); | ||
314 | } | ||
315 | |||
316 | static void | ||
317 | handle_get_message (void *cls, | ||
318 | const struct GNUNET_MESSENGER_GetMessage *msg) | ||
319 | { | ||
320 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
321 | |||
322 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Requesting message from room: %s\n", GNUNET_h2s (&(msg->key))); | ||
323 | |||
324 | struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (messenger, &(msg->key)); | ||
325 | |||
326 | if (!room) | ||
327 | { | ||
328 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Room not found: %s\n", GNUNET_h2s (&(msg->key))); | ||
329 | goto end_handling; | ||
330 | } | ||
331 | |||
332 | struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room); | ||
333 | |||
334 | struct GNUNET_MESSENGER_Member *member = get_store_member(member_store, get_handle_member_id( | ||
335 | msg_client->handle, &(msg->key) | ||
336 | )); | ||
337 | |||
338 | if (!member) | ||
339 | { | ||
340 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Member not valid to request a message!\n"); | ||
341 | goto end_handling; | ||
342 | } | ||
343 | |||
344 | struct GNUNET_MESSENGER_MemberSession *session = get_member_session(member, &(get_handle_ego(msg_client->handle)->pub)); | ||
345 | |||
346 | if (!session) | ||
347 | { | ||
348 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Session not valid to request a message!\n"); | ||
349 | goto end_handling; | ||
350 | } | ||
351 | |||
352 | request_room_message (room, &(msg->hash), session, callback_found_message, msg_client); | ||
353 | |||
354 | end_handling: | ||
355 | GNUNET_SERVICE_client_continue (msg_client->client); | ||
356 | } | ||
357 | |||
358 | static void* | ||
359 | callback_client_connect (void *cls, | ||
360 | struct GNUNET_SERVICE_Client *client, | ||
361 | struct GNUNET_MQ_Handle *mq) | ||
362 | { | ||
363 | struct GNUNET_MESSENGER_Client *msg_client = GNUNET_new(struct GNUNET_MESSENGER_Client); | ||
364 | |||
365 | msg_client->client = client; | ||
366 | msg_client->handle = add_service_handle (messenger, mq); | ||
367 | |||
368 | return msg_client; | ||
369 | } | ||
370 | |||
371 | static void | ||
372 | callback_client_disconnect (void *cls, | ||
373 | struct GNUNET_SERVICE_Client *client, | ||
374 | void *internal_cls) | ||
375 | { | ||
376 | struct GNUNET_MESSENGER_Client *msg_client = internal_cls; | ||
377 | |||
378 | remove_service_handle (messenger, msg_client->handle); | ||
379 | |||
380 | GNUNET_free(msg_client); | ||
381 | } | ||
382 | |||
383 | /** | ||
384 | * Setup MESSENGER internals. | ||
385 | * | ||
386 | * @param[in/out] cls closure | ||
387 | * @param[in] config configuration to use | ||
388 | * @param[in/out] service the initialized service | ||
389 | */ | ||
390 | static void | ||
391 | run (void *cls, | ||
392 | const struct GNUNET_CONFIGURATION_Handle *config, | ||
393 | struct GNUNET_SERVICE_Handle *service) | ||
394 | { | ||
395 | messenger = create_service (config, service); | ||
396 | |||
397 | if (!messenger) | ||
398 | GNUNET_SCHEDULER_shutdown (); | ||
399 | } | ||
400 | |||
401 | /** | ||
402 | * Define "main" method using service macro. | ||
403 | */ | ||
404 | GNUNET_SERVICE_MAIN( | ||
405 | GNUNET_MESSENGER_SERVICE_NAME, | ||
406 | GNUNET_SERVICE_OPTION_NONE, | ||
407 | &run, | ||
408 | &callback_client_connect, | ||
409 | &callback_client_disconnect, | ||
410 | NULL, | ||
411 | GNUNET_MQ_hd_var_size( create, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_CREATE, struct GNUNET_MESSENGER_CreateMessage, NULL ), | ||
412 | GNUNET_MQ_hd_fixed_size( update, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_UPDATE, struct GNUNET_MESSENGER_UpdateMessage, NULL ), | ||
413 | GNUNET_MQ_hd_fixed_size( destroy, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_DESTROY, struct GNUNET_MESSENGER_DestroyMessage, NULL ), | ||
414 | GNUNET_MQ_hd_var_size( set_name, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_SET_NAME, struct GNUNET_MESSENGER_NameMessage, NULL ), | ||
415 | GNUNET_MQ_hd_fixed_size( room_open, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN, struct GNUNET_MESSENGER_RoomMessage, NULL ), | ||
416 | GNUNET_MQ_hd_fixed_size( room_entry, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY, struct GNUNET_MESSENGER_RoomMessage, NULL ), | ||
417 | GNUNET_MQ_hd_fixed_size( room_close, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE, struct GNUNET_MESSENGER_RoomMessage, NULL ), | ||
418 | GNUNET_MQ_hd_var_size( send_message, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE, struct GNUNET_MESSENGER_SendMessage, NULL ), | ||
419 | GNUNET_MQ_hd_fixed_size( get_message, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE, struct GNUNET_MESSENGER_GetMessage, NULL ), | ||
420 | GNUNET_MQ_handler_end()); | ||
diff --git a/src/messenger/gnunet-service-messenger.h b/src/messenger/gnunet-service-messenger.h deleted file mode 100644 index 253fbaadb..000000000 --- a/src/messenger/gnunet-service-messenger.h +++ /dev/null | |||
@@ -1,137 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_cadet_service.h" | ||
31 | #include "gnunet_container_lib.h" | ||
32 | #include "gnunet_crypto_lib.h" | ||
33 | #include "gnunet_identity_service.h" | ||
34 | #include "gnunet_mq_lib.h" | ||
35 | #include "gnunet_peer_lib.h" | ||
36 | #include "gnunet_protocols.h" | ||
37 | #include "gnunet_util_lib.h" | ||
38 | |||
39 | /** | ||
40 | * Message to create a handle for a client | ||
41 | */ | ||
42 | struct GNUNET_MESSENGER_CreateMessage | ||
43 | { | ||
44 | struct GNUNET_MessageHeader header; | ||
45 | }; | ||
46 | |||
47 | /** | ||
48 | * Message to update the handle (its EGO key) for a client | ||
49 | */ | ||
50 | struct GNUNET_MESSENGER_UpdateMessage | ||
51 | { | ||
52 | struct GNUNET_MessageHeader header; | ||
53 | }; | ||
54 | |||
55 | /** | ||
56 | * Message to destroy the handle for a client | ||
57 | */ | ||
58 | struct GNUNET_MESSENGER_DestroyMessage | ||
59 | { | ||
60 | struct GNUNET_MessageHeader header; | ||
61 | }; | ||
62 | |||
63 | /** | ||
64 | * Message to receive the current name of a handle | ||
65 | */ | ||
66 | struct GNUNET_MESSENGER_NameMessage | ||
67 | { | ||
68 | struct GNUNET_MessageHeader header; | ||
69 | }; | ||
70 | |||
71 | /** | ||
72 | * Message to receive the current public key of a handle | ||
73 | */ | ||
74 | struct GNUNET_MESSENGER_KeyMessage | ||
75 | { | ||
76 | struct GNUNET_MessageHeader header; | ||
77 | }; | ||
78 | |||
79 | /** | ||
80 | * General message to confirm interaction with a room | ||
81 | */ | ||
82 | struct GNUNET_MESSENGER_RoomMessage | ||
83 | { | ||
84 | struct GNUNET_MessageHeader header; | ||
85 | |||
86 | struct GNUNET_PeerIdentity door; | ||
87 | struct GNUNET_HashCode key; | ||
88 | }; | ||
89 | |||
90 | /** | ||
91 | * Message to receive the current member id of a handle in room | ||
92 | */ | ||
93 | struct GNUNET_MESSENGER_MemberMessage | ||
94 | { | ||
95 | struct GNUNET_MessageHeader header; | ||
96 | |||
97 | struct GNUNET_HashCode key; | ||
98 | struct GNUNET_ShortHashCode id; | ||
99 | }; | ||
100 | |||
101 | /** | ||
102 | * Message to send something into a room | ||
103 | */ | ||
104 | struct GNUNET_MESSENGER_SendMessage | ||
105 | { | ||
106 | struct GNUNET_MessageHeader header; | ||
107 | |||
108 | struct GNUNET_HashCode key; | ||
109 | uint32_t flags; | ||
110 | }; | ||
111 | |||
112 | /** | ||
113 | * Message to request something from a room | ||
114 | */ | ||
115 | struct GNUNET_MESSENGER_GetMessage | ||
116 | { | ||
117 | struct GNUNET_MessageHeader header; | ||
118 | |||
119 | struct GNUNET_HashCode key; | ||
120 | struct GNUNET_HashCode hash; | ||
121 | }; | ||
122 | |||
123 | /** | ||
124 | * Message to receive something from a room | ||
125 | */ | ||
126 | struct GNUNET_MESSENGER_RecvMessage | ||
127 | { | ||
128 | struct GNUNET_MessageHeader header; | ||
129 | |||
130 | struct GNUNET_HashCode key; | ||
131 | struct GNUNET_HashCode sender; | ||
132 | struct GNUNET_HashCode context; | ||
133 | struct GNUNET_HashCode hash; | ||
134 | uint32_t flags; | ||
135 | }; | ||
136 | |||
137 | #endif //GNUNET_SERVICE_MESSENGER_H | ||
diff --git a/src/messenger/gnunet-service-messenger_basement.c b/src/messenger/gnunet-service-messenger_basement.c deleted file mode 100644 index 89aa103ee..000000000 --- a/src/messenger/gnunet-service-messenger_basement.c +++ /dev/null | |||
@@ -1,64 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_basement.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_basement.h" | ||
27 | |||
28 | size_t | ||
29 | count_of_tunnels (const struct GNUNET_MESSENGER_ListTunnels *tunnels) | ||
30 | { | ||
31 | GNUNET_assert(tunnels); | ||
32 | |||
33 | const struct GNUNET_MESSENGER_ListTunnel *element; | ||
34 | size_t count = 0; | ||
35 | |||
36 | for (element = tunnels->head; element; element = element->next) | ||
37 | count++; | ||
38 | |||
39 | return count; | ||
40 | } | ||
41 | |||
42 | int | ||
43 | should_connect_tunnel_to (size_t count, | ||
44 | size_t src, | ||
45 | size_t dst) | ||
46 | { | ||
47 | if ((src + 1) % count == dst % count) | ||
48 | return GNUNET_YES; | ||
49 | |||
50 | return GNUNET_NO; | ||
51 | } | ||
52 | |||
53 | int | ||
54 | required_connection_between (size_t count, | ||
55 | size_t src, | ||
56 | size_t dst) | ||
57 | { | ||
58 | if (GNUNET_YES == should_connect_tunnel_to (count, src, dst)) | ||
59 | return GNUNET_YES; | ||
60 | if (GNUNET_YES == should_connect_tunnel_to (count, dst, src)) | ||
61 | return GNUNET_YES; | ||
62 | |||
63 | return GNUNET_NO; | ||
64 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_basement.h b/src/messenger/gnunet-service-messenger_basement.h deleted file mode 100644 index a097b482f..000000000 --- a/src/messenger/gnunet-service-messenger_basement.h +++ /dev/null | |||
@@ -1,70 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_basement.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_BASEMENT_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_BASEMENT_H | ||
28 | |||
29 | #include "messenger_api_list_tunnels.h" | ||
30 | |||
31 | /** | ||
32 | * Returns the count of peers in a list (typically from the basement of a room). | ||
33 | * | ||
34 | * @param[in] tunnels List of peer identities | ||
35 | * @return Count of the entries in the list | ||
36 | */ | ||
37 | size_t | ||
38 | count_of_tunnels (const struct GNUNET_MESSENGER_ListTunnels *tunnels); | ||
39 | |||
40 | /** | ||
41 | * Returns #GNUNET_YES or #GNUNET_NO to determine if the peer at index <i>src</i> should | ||
42 | * or should not connect outgoing to the peer at index <i>dst</i> to construct a complete | ||
43 | * basement with a given <i>count</i> of peers. | ||
44 | * | ||
45 | * @param[in] count Count of peers | ||
46 | * @param[in] src Source index | ||
47 | * @param[in] dst Destination index | ||
48 | * @return #GNUNET_YES or #GNUNET_NO based on topologic requirement | ||
49 | */ | ||
50 | int | ||
51 | should_connect_tunnel_to (size_t count, | ||
52 | size_t src, | ||
53 | size_t dst); | ||
54 | |||
55 | /** | ||
56 | * Returns #GNUNET_YES or #GNUNET_NO to determine if the peers of index <i>src</i> and | ||
57 | * index <i>dst</i> should be connected in any direction to construct a complete | ||
58 | * basement with a given <i>count</i> of peers. | ||
59 | * | ||
60 | * @param[in] count Count of peers | ||
61 | * @param[in] src Source index | ||
62 | * @param[in] dst Destination index | ||
63 | * @return #GNUNET_YES or #GNUNET_NO based on topologic requirement | ||
64 | */ | ||
65 | int | ||
66 | required_connection_between (size_t count, | ||
67 | size_t src, | ||
68 | size_t dst); | ||
69 | |||
70 | #endif //GNUNET_SERVICE_MESSENGER_BASEMENT_H | ||
diff --git a/src/messenger/gnunet-service-messenger_ego_store.c b/src/messenger/gnunet-service-messenger_ego_store.c deleted file mode 100644 index c460ac1c7..000000000 --- a/src/messenger/gnunet-service-messenger_ego_store.c +++ /dev/null | |||
@@ -1,310 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_ego_store.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_ego_store.h" | ||
27 | |||
28 | #include "gnunet-service-messenger_handle.h" | ||
29 | |||
30 | static void | ||
31 | callback_update_ego (void *cls, | ||
32 | struct GNUNET_IDENTITY_Ego *ego, | ||
33 | void **ctx, | ||
34 | const char *identifier) | ||
35 | { | ||
36 | if ((!ego) || (!identifier)) | ||
37 | return; | ||
38 | |||
39 | struct GNUNET_MESSENGER_EgoStore *store = cls; | ||
40 | |||
41 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "New ego in use: '%s'\n", identifier); | ||
42 | |||
43 | update_store_ego (store, identifier, GNUNET_IDENTITY_ego_get_private_key (ego)); | ||
44 | } | ||
45 | |||
46 | void | ||
47 | init_ego_store(struct GNUNET_MESSENGER_EgoStore *store, | ||
48 | const struct GNUNET_CONFIGURATION_Handle *config) | ||
49 | { | ||
50 | GNUNET_assert ((store) && (config)); | ||
51 | |||
52 | store->cfg = config; | ||
53 | store->identity = GNUNET_IDENTITY_connect (config, &callback_update_ego, store); | ||
54 | store->egos = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); | ||
55 | |||
56 | store->lu_start = NULL; | ||
57 | store->lu_end = NULL; | ||
58 | |||
59 | store->op_start = NULL; | ||
60 | store->op_end = NULL; | ||
61 | } | ||
62 | |||
63 | |||
64 | static int | ||
65 | iterate_destroy_egos (void *cls, | ||
66 | const struct GNUNET_HashCode *key, | ||
67 | void *value) | ||
68 | { | ||
69 | struct GNUNET_MESSENGER_Ego *ego = value; | ||
70 | GNUNET_free(ego); | ||
71 | return GNUNET_YES; | ||
72 | } | ||
73 | |||
74 | void | ||
75 | clear_ego_store(struct GNUNET_MESSENGER_EgoStore *store) | ||
76 | { | ||
77 | GNUNET_assert (store); | ||
78 | |||
79 | struct GNUNET_MESSENGER_EgoOperation *op; | ||
80 | |||
81 | while (store->op_start) | ||
82 | { | ||
83 | op = store->op_start; | ||
84 | |||
85 | GNUNET_IDENTITY_cancel (op->operation); | ||
86 | GNUNET_CONTAINER_DLL_remove (store->op_start, store->op_end, op); | ||
87 | |||
88 | if (op->identifier) | ||
89 | GNUNET_free (op->identifier); | ||
90 | |||
91 | GNUNET_free (op); | ||
92 | } | ||
93 | |||
94 | struct GNUNET_MESSENGER_EgoLookup *lu; | ||
95 | |||
96 | while (store->lu_start) | ||
97 | { | ||
98 | lu = store->lu_start; | ||
99 | |||
100 | GNUNET_IDENTITY_ego_lookup_cancel(lu->lookup); | ||
101 | GNUNET_CONTAINER_DLL_remove (store->lu_start, store->lu_end, lu); | ||
102 | |||
103 | if (lu->identifier) | ||
104 | GNUNET_free(lu->identifier); | ||
105 | |||
106 | GNUNET_free (lu); | ||
107 | } | ||
108 | |||
109 | GNUNET_CONTAINER_multihashmap_iterate (store->egos, iterate_destroy_egos, NULL); | ||
110 | GNUNET_CONTAINER_multihashmap_destroy (store->egos); | ||
111 | |||
112 | if (store->identity) | ||
113 | { | ||
114 | GNUNET_IDENTITY_disconnect (store->identity); | ||
115 | |||
116 | store->identity = NULL; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | static void | ||
121 | callback_ego_create (void *cls, | ||
122 | const struct GNUNET_IDENTITY_PrivateKey *key, | ||
123 | const char *emsg) | ||
124 | { | ||
125 | struct GNUNET_MESSENGER_EgoOperation *element = cls; | ||
126 | struct GNUNET_MESSENGER_EgoStore *store = element->store; | ||
127 | |||
128 | GNUNET_assert(element->identifier); | ||
129 | |||
130 | if (emsg) | ||
131 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s\n", emsg); | ||
132 | |||
133 | if (key) | ||
134 | { | ||
135 | struct GNUNET_MESSENGER_SrvHandle *handle = element->handle; | ||
136 | |||
137 | struct GNUNET_MESSENGER_Ego *msg_ego = update_store_ego (store, element->identifier, key); | ||
138 | |||
139 | set_handle_ego (handle, msg_ego); | ||
140 | } | ||
141 | else | ||
142 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Creating ego failed!\n"); | ||
143 | |||
144 | GNUNET_CONTAINER_DLL_remove (store->op_start, store->op_end, element); | ||
145 | GNUNET_free (element->identifier); | ||
146 | GNUNET_free (element); | ||
147 | } | ||
148 | |||
149 | void | ||
150 | create_store_ego (struct GNUNET_MESSENGER_EgoStore *store, | ||
151 | const char *identifier, | ||
152 | void *handle) | ||
153 | { | ||
154 | GNUNET_assert ((store) && (identifier)); | ||
155 | |||
156 | struct GNUNET_MESSENGER_EgoOperation *element = GNUNET_new (struct GNUNET_MESSENGER_EgoOperation); | ||
157 | |||
158 | element->store = store; | ||
159 | element->handle = handle; | ||
160 | |||
161 | element->identifier = GNUNET_strdup (identifier); | ||
162 | |||
163 | element->operation = GNUNET_IDENTITY_create (store->identity, identifier, NULL, | ||
164 | GNUNET_IDENTITY_TYPE_ECDSA, callback_ego_create, element); | ||
165 | |||
166 | GNUNET_CONTAINER_DLL_insert (store->op_start, store->op_end, element); | ||
167 | } | ||
168 | |||
169 | static void | ||
170 | callback_ego_lookup (void *cls, | ||
171 | struct GNUNET_IDENTITY_Ego *ego) | ||
172 | { | ||
173 | struct GNUNET_MESSENGER_EgoLookup *element = cls; | ||
174 | struct GNUNET_MESSENGER_EgoStore *store = element->store; | ||
175 | |||
176 | GNUNET_assert(element->identifier); | ||
177 | |||
178 | struct GNUNET_MESSENGER_Ego *msg_ego; | ||
179 | |||
180 | if (ego) | ||
181 | msg_ego = update_store_ego ( | ||
182 | store, element->identifier, GNUNET_IDENTITY_ego_get_private_key(ego) | ||
183 | ); | ||
184 | else | ||
185 | msg_ego = NULL; | ||
186 | |||
187 | if (element->cb) | ||
188 | element->cb(element->cls, element->identifier, msg_ego); | ||
189 | |||
190 | GNUNET_CONTAINER_DLL_remove (store->lu_start, store->lu_end, element); | ||
191 | GNUNET_free (element->identifier); | ||
192 | GNUNET_free (element); | ||
193 | } | ||
194 | |||
195 | void | ||
196 | lookup_store_ego(struct GNUNET_MESSENGER_EgoStore *store, | ||
197 | const char *identifier, | ||
198 | GNUNET_MESSENGER_EgoLookupCallback lookup, | ||
199 | void *cls) | ||
200 | { | ||
201 | GNUNET_assert (store); | ||
202 | |||
203 | if (!identifier) | ||
204 | { | ||
205 | lookup(cls, identifier, NULL); | ||
206 | return; | ||
207 | } | ||
208 | |||
209 | struct GNUNET_HashCode hash; | ||
210 | GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash); | ||
211 | |||
212 | struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get (store->egos, &hash); | ||
213 | |||
214 | if (ego) | ||
215 | lookup(cls, identifier, ego); | ||
216 | else | ||
217 | { | ||
218 | struct GNUNET_MESSENGER_EgoLookup *element = GNUNET_new (struct GNUNET_MESSENGER_EgoLookup); | ||
219 | |||
220 | element->store = store; | ||
221 | |||
222 | element->cb = lookup; | ||
223 | element->cls = cls; | ||
224 | |||
225 | element->identifier = GNUNET_strdup (identifier); | ||
226 | |||
227 | element->lookup = GNUNET_IDENTITY_ego_lookup(store->cfg, identifier, callback_ego_lookup, element); | ||
228 | |||
229 | GNUNET_CONTAINER_DLL_insert (store->lu_start, store->lu_end, element); | ||
230 | } | ||
231 | } | ||
232 | |||
233 | struct GNUNET_MESSENGER_Ego* | ||
234 | update_store_ego(struct GNUNET_MESSENGER_EgoStore *store, | ||
235 | const char *identifier, | ||
236 | const struct GNUNET_IDENTITY_PrivateKey *key) | ||
237 | { | ||
238 | GNUNET_assert ((store) && (identifier) && (key)); | ||
239 | |||
240 | struct GNUNET_HashCode hash; | ||
241 | GNUNET_CRYPTO_hash (identifier, strlen (identifier), &hash); | ||
242 | |||
243 | struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get (store->egos, &hash); | ||
244 | |||
245 | if (!ego) | ||
246 | { | ||
247 | ego = GNUNET_new(struct GNUNET_MESSENGER_Ego); | ||
248 | GNUNET_CONTAINER_multihashmap_put (store->egos, &hash, ego, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
249 | } | ||
250 | |||
251 | GNUNET_memcpy(&(ego->priv), key, sizeof(*key)); | ||
252 | |||
253 | if (GNUNET_OK != GNUNET_IDENTITY_key_get_public (key, &(ego->pub))) | ||
254 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Updating invalid ego key failed!\n"); | ||
255 | |||
256 | return ego; | ||
257 | } | ||
258 | |||
259 | static void | ||
260 | callback_ego_rename (void *cls, | ||
261 | const char *emsg) | ||
262 | { | ||
263 | struct GNUNET_MESSENGER_EgoOperation *element = cls; | ||
264 | struct GNUNET_MESSENGER_EgoStore *store = element->store; | ||
265 | |||
266 | GNUNET_assert(element->identifier); | ||
267 | |||
268 | if (emsg) | ||
269 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s\n", emsg); | ||
270 | |||
271 | struct GNUNET_HashCode hash; | ||
272 | GNUNET_CRYPTO_hash (element->identifier, strlen (element->identifier), &hash); | ||
273 | |||
274 | struct GNUNET_MESSENGER_Ego *ego = GNUNET_CONTAINER_multihashmap_get (store->egos, &hash); | ||
275 | |||
276 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (store->egos, &hash, ego)) | ||
277 | { | ||
278 | GNUNET_CRYPTO_hash ((char*) element->handle, strlen ((char*) element->handle), &hash); | ||
279 | |||
280 | GNUNET_CONTAINER_multihashmap_put (store->egos, &hash, ego, | ||
281 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
282 | } | ||
283 | else | ||
284 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Renaming ego failed!\n"); | ||
285 | |||
286 | GNUNET_free (element->handle); | ||
287 | |||
288 | GNUNET_CONTAINER_DLL_remove (store->op_start, store->op_end, element); | ||
289 | GNUNET_free (element->identifier); | ||
290 | GNUNET_free (element); | ||
291 | } | ||
292 | |||
293 | void | ||
294 | rename_store_ego (struct GNUNET_MESSENGER_EgoStore *store, | ||
295 | const char *old_identifier, | ||
296 | const char *new_identifier) | ||
297 | { | ||
298 | GNUNET_assert ((store) && (old_identifier) && (new_identifier)); | ||
299 | |||
300 | struct GNUNET_MESSENGER_EgoOperation *element = GNUNET_new (struct GNUNET_MESSENGER_EgoOperation); | ||
301 | |||
302 | element->store = store; | ||
303 | element->handle = GNUNET_strdup (new_identifier); | ||
304 | |||
305 | element->identifier = GNUNET_strdup (old_identifier); | ||
306 | |||
307 | element->operation = GNUNET_IDENTITY_rename (store->identity, old_identifier, new_identifier, callback_ego_rename, element); | ||
308 | |||
309 | GNUNET_CONTAINER_DLL_insert (store->op_start, store->op_end, element); | ||
310 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_ego_store.h b/src/messenger/gnunet-service-messenger_ego_store.h deleted file mode 100644 index 4222a4e91..000000000 --- a/src/messenger/gnunet-service-messenger_ego_store.h +++ /dev/null | |||
@@ -1,159 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_ego_store.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_EGO_STORE_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_EGO_STORE_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_container_lib.h" | ||
31 | |||
32 | #include "messenger_api_ego.h" | ||
33 | |||
34 | struct GNUNET_MESSENGER_Ego; | ||
35 | struct GNUNET_MESSENGER_EgoStore; | ||
36 | |||
37 | typedef void | ||
38 | (*GNUNET_MESSENGER_EgoLookupCallback) (void *cls, | ||
39 | const char *identifier, | ||
40 | const struct GNUNET_MESSENGER_Ego *ego); | ||
41 | |||
42 | struct GNUNET_MESSENGER_EgoLookup | ||
43 | { | ||
44 | struct GNUNET_MESSENGER_EgoLookup *prev; | ||
45 | struct GNUNET_MESSENGER_EgoLookup *next; | ||
46 | |||
47 | struct GNUNET_IDENTITY_EgoLookup *lookup; | ||
48 | |||
49 | struct GNUNET_MESSENGER_EgoStore *store; | ||
50 | |||
51 | GNUNET_MESSENGER_EgoLookupCallback cb; | ||
52 | void *cls; | ||
53 | |||
54 | char *identifier; | ||
55 | }; | ||
56 | |||
57 | struct GNUNET_MESSENGER_EgoOperation | ||
58 | { | ||
59 | struct GNUNET_MESSENGER_EgoOperation *prev; | ||
60 | struct GNUNET_MESSENGER_EgoOperation *next; | ||
61 | |||
62 | struct GNUNET_IDENTITY_Operation *operation; | ||
63 | |||
64 | struct GNUNET_MESSENGER_EgoStore *store; | ||
65 | void *handle; | ||
66 | |||
67 | char *identifier; | ||
68 | }; | ||
69 | |||
70 | struct GNUNET_MESSENGER_EgoStore | ||
71 | { | ||
72 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
73 | |||
74 | struct GNUNET_IDENTITY_Handle *identity; | ||
75 | struct GNUNET_CONTAINER_MultiHashMap *egos; | ||
76 | |||
77 | struct GNUNET_MESSENGER_EgoLookup *lu_start; | ||
78 | struct GNUNET_MESSENGER_EgoLookup *lu_end; | ||
79 | |||
80 | struct GNUNET_MESSENGER_EgoOperation *op_start; | ||
81 | struct GNUNET_MESSENGER_EgoOperation *op_end; | ||
82 | }; | ||
83 | |||
84 | /** | ||
85 | * Initializes an EGO-store as fully empty. | ||
86 | * | ||
87 | * @param[out] store EGO-store | ||
88 | * @param[in] config Configuration handle | ||
89 | */ | ||
90 | void | ||
91 | init_ego_store (struct GNUNET_MESSENGER_EgoStore *store, | ||
92 | const struct GNUNET_CONFIGURATION_Handle *config); | ||
93 | |||
94 | /** | ||
95 | * Clears an EGO-store, wipes its content and deallocates its memory. | ||
96 | * | ||
97 | * @param[in/out] store EGO-store | ||
98 | */ | ||
99 | void | ||
100 | clear_ego_store (struct GNUNET_MESSENGER_EgoStore *store); | ||
101 | |||
102 | /** | ||
103 | * Creates a new EGO which will be registered to a <i>store</i> under | ||
104 | * a specific <i>identifier</i>. A given <i>handle</i> will be informed | ||
105 | * about the creation and changes its EGO accordingly. | ||
106 | * | ||
107 | * @param[in/out] store EGO-store | ||
108 | * @param[in] identifier Identifier string | ||
109 | * @param[in/out] handle Handle or NULL | ||
110 | */ | ||
111 | void | ||
112 | create_store_ego (struct GNUNET_MESSENGER_EgoStore *store, | ||
113 | const char *identifier, | ||
114 | void *handle); | ||
115 | |||
116 | /** | ||
117 | * Lookups an EGO which was registered to a <i>store</i> under | ||
118 | * a specific <i>identifier</i>. | ||
119 | * | ||
120 | * @param[in/out] store EGO-store | ||
121 | * @param[in] identifier Identifier string | ||
122 | * @param[in] lookup Lookup callback (non-NULL) | ||
123 | * @param[in] cls Closure | ||
124 | */ | ||
125 | void | ||
126 | lookup_store_ego (struct GNUNET_MESSENGER_EgoStore *store, | ||
127 | const char *identifier, | ||
128 | GNUNET_MESSENGER_EgoLookupCallback lookup, | ||
129 | void *cls); | ||
130 | |||
131 | /** | ||
132 | * Updates the registration of an EGO to a <i>store</i> under | ||
133 | * a specific <i>identifier</i> with a new <i>key</i>. | ||
134 | * | ||
135 | * @param[in/out] store EGO-store | ||
136 | * @param[in] identifier Identifier string | ||
137 | * @param[in] key Private EGO key | ||
138 | * @return Updated EGO | ||
139 | */ | ||
140 | struct GNUNET_MESSENGER_Ego* | ||
141 | update_store_ego (struct GNUNET_MESSENGER_EgoStore *store, | ||
142 | const char *identifier, | ||
143 | const struct GNUNET_IDENTITY_PrivateKey *key); | ||
144 | |||
145 | /** | ||
146 | * Updates the location of a registered EGO in a <i>store</i> to | ||
147 | * a different one under a specific <i>new_identifier<i> replacing | ||
148 | * its old one. | ||
149 | * | ||
150 | * @param[in/out] store EGO-store | ||
151 | * @param[in] old_identifier Old identifier string | ||
152 | * @param[in] new_identifier New identifier string | ||
153 | */ | ||
154 | void | ||
155 | rename_store_ego (struct GNUNET_MESSENGER_EgoStore *store, | ||
156 | const char *old_identifier, | ||
157 | const char *new_identifier); | ||
158 | |||
159 | #endif //GNUNET_SERVICE_MESSENGER_EGO_STORE_H | ||
diff --git a/src/messenger/gnunet-service-messenger_handle.c b/src/messenger/gnunet-service-messenger_handle.c deleted file mode 100644 index 341bb7251..000000000 --- a/src/messenger/gnunet-service-messenger_handle.c +++ /dev/null | |||
@@ -1,711 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_handle.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_handle.h" | ||
27 | |||
28 | #include "gnunet-service-messenger.h" | ||
29 | #include "gnunet-service-messenger_message_kind.h" | ||
30 | |||
31 | #include "messenger_api_util.h" | ||
32 | |||
33 | struct GNUNET_MESSENGER_SrvHandle* | ||
34 | create_handle (struct GNUNET_MESSENGER_Service *service, | ||
35 | struct GNUNET_MQ_Handle *mq) | ||
36 | { | ||
37 | GNUNET_assert((service) && (mq)); | ||
38 | |||
39 | struct GNUNET_MESSENGER_SrvHandle *handle = GNUNET_new(struct GNUNET_MESSENGER_SrvHandle); | ||
40 | |||
41 | handle->service = service; | ||
42 | handle->mq = mq; | ||
43 | |||
44 | handle->name = NULL; | ||
45 | handle->ego = NULL; | ||
46 | |||
47 | handle->member_ids = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); | ||
48 | |||
49 | return handle; | ||
50 | } | ||
51 | |||
52 | int | ||
53 | iterate_free_member_ids (void *cls, | ||
54 | const struct GNUNET_HashCode *key, | ||
55 | void *value) | ||
56 | { | ||
57 | GNUNET_free(value); | ||
58 | |||
59 | return GNUNET_YES; | ||
60 | } | ||
61 | |||
62 | void | ||
63 | destroy_handle (struct GNUNET_MESSENGER_SrvHandle *handle) | ||
64 | { | ||
65 | GNUNET_assert(handle); | ||
66 | |||
67 | if (handle->service->dir) | ||
68 | save_handle_configuration (handle); | ||
69 | |||
70 | if (handle->name) | ||
71 | GNUNET_free(handle->name); | ||
72 | |||
73 | GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_free_member_ids, NULL); | ||
74 | GNUNET_CONTAINER_multihashmap_destroy (handle->member_ids); | ||
75 | |||
76 | GNUNET_free(handle); | ||
77 | } | ||
78 | |||
79 | void | ||
80 | get_handle_data_subdir (const struct GNUNET_MESSENGER_SrvHandle *handle, | ||
81 | const char *name, | ||
82 | char **dir) | ||
83 | { | ||
84 | GNUNET_assert((handle) && (dir)); | ||
85 | |||
86 | if (name) | ||
87 | GNUNET_asprintf (dir, "%s%s%c%s%c", handle->service->dir, "identities", | ||
88 | DIR_SEPARATOR, name, DIR_SEPARATOR); | ||
89 | else | ||
90 | GNUNET_asprintf (dir, "%s%s%c", handle->service->dir, "anonymous", | ||
91 | DIR_SEPARATOR); | ||
92 | } | ||
93 | |||
94 | static int | ||
95 | create_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, | ||
96 | const struct GNUNET_HashCode *key) | ||
97 | { | ||
98 | GNUNET_assert((handle) && (key)); | ||
99 | |||
100 | struct GNUNET_ShortHashCode *random_id = GNUNET_new(struct GNUNET_ShortHashCode); | ||
101 | |||
102 | if (!random_id) | ||
103 | return GNUNET_NO; | ||
104 | |||
105 | generate_free_member_id (random_id, NULL); | ||
106 | |||
107 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, key, random_id, | ||
108 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
109 | { | ||
110 | GNUNET_free(random_id); | ||
111 | return GNUNET_NO; | ||
112 | } | ||
113 | |||
114 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Created a new member id (%s) for room: %s\n", GNUNET_sh2s (random_id), | ||
115 | GNUNET_h2s (key)); | ||
116 | |||
117 | return GNUNET_YES; | ||
118 | } | ||
119 | |||
120 | const struct GNUNET_ShortHashCode* | ||
121 | get_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, | ||
122 | const struct GNUNET_HashCode *key) | ||
123 | { | ||
124 | GNUNET_assert((handle) && (key)); | ||
125 | |||
126 | return GNUNET_CONTAINER_multihashmap_get (handle->member_ids, key); | ||
127 | } | ||
128 | |||
129 | int | ||
130 | change_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
131 | const struct GNUNET_HashCode *key, | ||
132 | const struct GNUNET_ShortHashCode *unique_id) | ||
133 | { | ||
134 | GNUNET_assert((handle) && (key) && (unique_id)); | ||
135 | |||
136 | struct GNUNET_ShortHashCode *member_id = GNUNET_CONTAINER_multihashmap_get (handle->member_ids, key); | ||
137 | |||
138 | if (!member_id) | ||
139 | { | ||
140 | member_id = GNUNET_new(struct GNUNET_ShortHashCode); | ||
141 | GNUNET_memcpy(member_id, unique_id, sizeof(*member_id)); | ||
142 | |||
143 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->member_ids, key, member_id, | ||
144 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
145 | { | ||
146 | GNUNET_free(member_id); | ||
147 | return GNUNET_SYSERR; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | if (0 == GNUNET_memcmp(unique_id, member_id)) | ||
152 | goto send_message_to_client; | ||
153 | |||
154 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Change a member id (%s) for room (%s).\n", GNUNET_sh2s (member_id), | ||
155 | GNUNET_h2s (key)); | ||
156 | |||
157 | GNUNET_memcpy(member_id, unique_id, sizeof(*unique_id)); | ||
158 | |||
159 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Member id changed to (%s).\n", GNUNET_sh2s (unique_id)); | ||
160 | |||
161 | struct GNUNET_MESSENGER_MemberMessage *msg; | ||
162 | struct GNUNET_MQ_Envelope *env; | ||
163 | |||
164 | send_message_to_client: | ||
165 | |||
166 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID); | ||
167 | |||
168 | GNUNET_memcpy(&(msg->key), key, sizeof(*key)); | ||
169 | GNUNET_memcpy(&(msg->id), member_id, sizeof(*member_id)); | ||
170 | |||
171 | GNUNET_MQ_send (handle->mq, env); | ||
172 | return GNUNET_OK; | ||
173 | } | ||
174 | |||
175 | static void | ||
176 | change_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
177 | const char *name) | ||
178 | { | ||
179 | GNUNET_assert(handle); | ||
180 | |||
181 | if (handle->name) | ||
182 | GNUNET_free(handle->name); | ||
183 | |||
184 | handle->name = name ? GNUNET_strdup(name) : NULL; | ||
185 | |||
186 | const uint16_t name_len = handle->name ? strlen (handle->name) : 0; | ||
187 | |||
188 | struct GNUNET_MESSENGER_NameMessage *msg; | ||
189 | struct GNUNET_MQ_Envelope *env; | ||
190 | |||
191 | env = GNUNET_MQ_msg_extra(msg, name_len + 1, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_NAME); | ||
192 | |||
193 | char *extra = ((char*) msg) + sizeof(*msg); | ||
194 | |||
195 | if (name_len) | ||
196 | GNUNET_memcpy(extra, handle->name, name_len); | ||
197 | |||
198 | extra[name_len] = '\0'; | ||
199 | |||
200 | GNUNET_MQ_send (handle->mq, env); | ||
201 | } | ||
202 | |||
203 | static void | ||
204 | change_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
205 | const struct GNUNET_MESSENGER_Ego *ego) | ||
206 | { | ||
207 | GNUNET_assert(handle); | ||
208 | |||
209 | handle->ego = ego; | ||
210 | |||
211 | ego = get_handle_ego (handle); | ||
212 | |||
213 | const uint16_t length = GNUNET_IDENTITY_key_get_length(&(ego->pub)); | ||
214 | |||
215 | struct GNUNET_MESSENGER_KeyMessage *msg; | ||
216 | struct GNUNET_MQ_Envelope *env; | ||
217 | |||
218 | env = GNUNET_MQ_msg_extra(msg, length, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_KEY); | ||
219 | |||
220 | char *extra = ((char*) msg) + sizeof(*msg); | ||
221 | |||
222 | if (GNUNET_IDENTITY_write_key_to_buffer(&(ego->pub), extra, length) < 0) | ||
223 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Could not write key to buffer.\n"); | ||
224 | |||
225 | GNUNET_MQ_send (handle->mq, env); | ||
226 | } | ||
227 | |||
228 | struct GNUNET_MESSENGER_MessageHandle | ||
229 | { | ||
230 | struct GNUNET_MESSENGER_SrvHandle *handle; | ||
231 | struct GNUNET_MESSENGER_Message *message; | ||
232 | }; | ||
233 | |||
234 | static int | ||
235 | iterate_send_message (void *cls, | ||
236 | const struct GNUNET_HashCode *key, | ||
237 | void *value) | ||
238 | { | ||
239 | struct GNUNET_MESSENGER_MessageHandle *msg_handle = cls; | ||
240 | |||
241 | send_handle_message (msg_handle->handle, key, msg_handle->message); | ||
242 | |||
243 | return GNUNET_YES; | ||
244 | } | ||
245 | |||
246 | void | ||
247 | set_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
248 | const struct GNUNET_MESSENGER_Ego *ego) | ||
249 | { | ||
250 | GNUNET_assert((handle) && (ego)); | ||
251 | |||
252 | struct GNUNET_MESSENGER_MessageHandle msg_handle; | ||
253 | |||
254 | msg_handle.handle = handle; | ||
255 | msg_handle.message = create_message_key (&(ego->priv)); | ||
256 | |||
257 | GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_send_message, &msg_handle); | ||
258 | |||
259 | destroy_message (msg_handle.message); | ||
260 | |||
261 | change_handle_ego (handle, ego); | ||
262 | } | ||
263 | |||
264 | const struct GNUNET_MESSENGER_Ego* | ||
265 | get_handle_ego (const struct GNUNET_MESSENGER_SrvHandle *handle) | ||
266 | { | ||
267 | GNUNET_assert(handle); | ||
268 | |||
269 | static struct GNUNET_MESSENGER_Ego anonymous; | ||
270 | static int read_keys = 0; | ||
271 | |||
272 | if (handle->ego) | ||
273 | return handle->ego; | ||
274 | |||
275 | if (!read_keys) | ||
276 | { | ||
277 | struct GNUNET_IDENTITY_Ego *ego = GNUNET_IDENTITY_ego_get_anonymous (); | ||
278 | GNUNET_memcpy(&(anonymous.priv), GNUNET_IDENTITY_ego_get_private_key (ego), sizeof(anonymous.priv)); | ||
279 | GNUNET_IDENTITY_ego_get_public_key (ego, &(anonymous.pub)); | ||
280 | read_keys = 1; | ||
281 | } | ||
282 | |||
283 | return &anonymous; | ||
284 | } | ||
285 | |||
286 | static void | ||
287 | callback_setup_handle_name (void *cls, | ||
288 | const char *name, | ||
289 | const struct GNUNET_MESSENGER_Ego *ego) | ||
290 | { | ||
291 | struct GNUNET_MESSENGER_SrvHandle *handle = cls; | ||
292 | |||
293 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Setting up handle...\n"); | ||
294 | |||
295 | change_handle_name (handle, name); | ||
296 | change_handle_ego (handle, ego); | ||
297 | |||
298 | if (handle->service->dir) | ||
299 | load_handle_configuration (handle); | ||
300 | } | ||
301 | |||
302 | void | ||
303 | setup_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
304 | const char *name) | ||
305 | { | ||
306 | GNUNET_assert(handle); | ||
307 | |||
308 | struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service); | ||
309 | |||
310 | lookup_store_ego (store, name, callback_setup_handle_name, handle); | ||
311 | } | ||
312 | |||
313 | static void | ||
314 | callback_update_handle (void *cls, | ||
315 | const char *name, | ||
316 | const struct GNUNET_MESSENGER_Ego *ego) | ||
317 | { | ||
318 | struct GNUNET_MESSENGER_SrvHandle *handle = cls; | ||
319 | |||
320 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Updating handle...\n"); | ||
321 | |||
322 | struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service); | ||
323 | |||
324 | if (!ego) | ||
325 | create_store_ego(store, handle->name, handle); | ||
326 | else | ||
327 | change_handle_ego (handle, ego); | ||
328 | } | ||
329 | |||
330 | void | ||
331 | update_handle (struct GNUNET_MESSENGER_SrvHandle *handle) | ||
332 | { | ||
333 | GNUNET_assert(handle); | ||
334 | |||
335 | if (!handle->name) | ||
336 | { | ||
337 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Updating handle failed: Name is required!\n"); | ||
338 | return; | ||
339 | } | ||
340 | |||
341 | struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service); | ||
342 | |||
343 | lookup_store_ego (store, handle->name, callback_update_handle, handle); | ||
344 | } | ||
345 | |||
346 | static void | ||
347 | callback_set_handle_name (void *cls, | ||
348 | const char *name, | ||
349 | const struct GNUNET_MESSENGER_Ego *ego) | ||
350 | { | ||
351 | struct GNUNET_MESSENGER_SrvHandle *handle = cls; | ||
352 | |||
353 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Renaming handle...\n"); | ||
354 | |||
355 | if (ego) | ||
356 | { | ||
357 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Renaming handle failed: Name is occupied! (%s)\n", name); | ||
358 | return; | ||
359 | } | ||
360 | |||
361 | struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service); | ||
362 | |||
363 | int rename_ego_in_store = handle->ego? GNUNET_YES : GNUNET_NO; | ||
364 | |||
365 | char *old_dir; | ||
366 | get_handle_data_subdir (handle, handle->name, &old_dir); | ||
367 | |||
368 | char *new_dir; | ||
369 | get_handle_data_subdir (handle, name, &new_dir); | ||
370 | |||
371 | int result = 0; | ||
372 | |||
373 | if (GNUNET_YES == GNUNET_DISK_directory_test (old_dir, GNUNET_YES)) | ||
374 | { | ||
375 | GNUNET_DISK_directory_create_for_file (new_dir); | ||
376 | |||
377 | result = rename (old_dir, new_dir); | ||
378 | } | ||
379 | else if (GNUNET_YES == GNUNET_DISK_directory_test (new_dir, GNUNET_NO)) | ||
380 | result = -1; | ||
381 | |||
382 | if (0 == result) | ||
383 | { | ||
384 | struct GNUNET_MESSENGER_MessageHandle msg_handle; | ||
385 | |||
386 | msg_handle.handle = handle; | ||
387 | msg_handle.message = create_message_name (name); | ||
388 | |||
389 | GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_send_message, &msg_handle); | ||
390 | |||
391 | destroy_message (msg_handle.message); | ||
392 | |||
393 | change_handle_name (handle, name); | ||
394 | } | ||
395 | else | ||
396 | rename_ego_in_store = GNUNET_NO; | ||
397 | |||
398 | GNUNET_free(old_dir); | ||
399 | GNUNET_free(new_dir); | ||
400 | |||
401 | if (GNUNET_YES == rename_ego_in_store) | ||
402 | rename_store_ego(store, handle->name, name); | ||
403 | } | ||
404 | |||
405 | void | ||
406 | set_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
407 | const char *name) | ||
408 | { | ||
409 | GNUNET_assert(handle); | ||
410 | |||
411 | if (!name) | ||
412 | { | ||
413 | if (handle->ego) | ||
414 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Renaming handle failed: Name is required!\n"); | ||
415 | else | ||
416 | change_handle_name (handle, name); | ||
417 | |||
418 | return; | ||
419 | } | ||
420 | |||
421 | struct GNUNET_MESSENGER_EgoStore *store = get_service_ego_store(handle->service); | ||
422 | |||
423 | lookup_store_ego (store, name, callback_set_handle_name, handle); | ||
424 | } | ||
425 | |||
426 | int | ||
427 | open_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
428 | const struct GNUNET_HashCode *key) | ||
429 | { | ||
430 | GNUNET_assert((handle) && (key)); | ||
431 | |||
432 | if ((!get_handle_member_id (handle, key)) && (GNUNET_YES != create_handle_member_id (handle, key))) | ||
433 | return GNUNET_NO; | ||
434 | |||
435 | return open_service_room (handle->service, handle, key); | ||
436 | } | ||
437 | |||
438 | int | ||
439 | entry_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
440 | const struct GNUNET_PeerIdentity *door, | ||
441 | const struct GNUNET_HashCode *key) | ||
442 | { | ||
443 | GNUNET_assert((handle) && (door) && (key)); | ||
444 | |||
445 | if ((!get_handle_member_id (handle, key)) && (GNUNET_YES != create_handle_member_id (handle, key))) | ||
446 | return GNUNET_NO; | ||
447 | |||
448 | return entry_service_room (handle->service, handle, door, key); | ||
449 | } | ||
450 | |||
451 | int | ||
452 | close_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
453 | const struct GNUNET_HashCode *key) | ||
454 | { | ||
455 | GNUNET_assert((handle) && (key)); | ||
456 | |||
457 | if (!get_handle_member_id (handle, key)) | ||
458 | return GNUNET_NO; | ||
459 | |||
460 | return close_service_room (handle->service, handle, key); | ||
461 | } | ||
462 | |||
463 | int | ||
464 | send_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
465 | const struct GNUNET_HashCode *key, | ||
466 | const struct GNUNET_MESSENGER_Message *message) | ||
467 | { | ||
468 | GNUNET_assert((handle) && (key) && (message)); | ||
469 | |||
470 | const struct GNUNET_ShortHashCode *id = get_handle_member_id (handle, key); | ||
471 | |||
472 | if (!id) | ||
473 | { | ||
474 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "It is required to be a member of a room to send messages!\n"); | ||
475 | return GNUNET_NO; | ||
476 | } | ||
477 | |||
478 | struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (handle->service, key); | ||
479 | |||
480 | if (!room) | ||
481 | { | ||
482 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "The room (%s) is unknown!\n", GNUNET_h2s (key)); | ||
483 | return GNUNET_NO; | ||
484 | } | ||
485 | |||
486 | struct GNUNET_MESSENGER_Message *msg = copy_message(message); | ||
487 | |||
488 | GNUNET_memcpy(&(msg->header.sender_id), id, sizeof(*id)); | ||
489 | |||
490 | return send_room_message (room, handle, msg); | ||
491 | } | ||
492 | |||
493 | static const struct GNUNET_HashCode* | ||
494 | get_next_member_session_contect(const struct GNUNET_MESSENGER_MemberSession *session) | ||
495 | { | ||
496 | if (session->next) | ||
497 | return get_next_member_session_contect (session->next); | ||
498 | else | ||
499 | return get_member_session_context(session); | ||
500 | } | ||
501 | |||
502 | static const struct GNUNET_MESSENGER_MemberSession* | ||
503 | get_handle_member_session (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
504 | struct GNUNET_MESSENGER_SrvRoom *room, | ||
505 | const struct GNUNET_HashCode *key) | ||
506 | { | ||
507 | GNUNET_assert((handle) && (room) && (key) && (handle->service)); | ||
508 | |||
509 | const struct GNUNET_ShortHashCode *id = get_handle_member_id(handle, key); | ||
510 | |||
511 | if (!id) | ||
512 | return NULL; | ||
513 | |||
514 | struct GNUNET_MESSENGER_MemberStore *store = get_room_member_store(room); | ||
515 | struct GNUNET_MESSENGER_Member *member = get_store_member(store, id); | ||
516 | |||
517 | const struct GNUNET_MESSENGER_Ego *ego = get_handle_ego(handle); | ||
518 | |||
519 | if (!ego) | ||
520 | return NULL; | ||
521 | |||
522 | return get_member_session(member, &(ego->pub)); | ||
523 | } | ||
524 | |||
525 | void | ||
526 | notify_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
527 | struct GNUNET_MESSENGER_SrvRoom *room, | ||
528 | const struct GNUNET_MESSENGER_MemberSession *session, | ||
529 | const struct GNUNET_MESSENGER_Message *message, | ||
530 | const struct GNUNET_HashCode *hash) | ||
531 | { | ||
532 | GNUNET_assert((handle) && (room) && (session) && (message) && (hash)); | ||
533 | |||
534 | const struct GNUNET_HashCode *key = get_room_key(room); | ||
535 | |||
536 | if ((!handle->mq) || (!get_handle_member_id (handle, key))) | ||
537 | { | ||
538 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Notifying client about message requires membership!\n"); | ||
539 | return; | ||
540 | } | ||
541 | |||
542 | const struct GNUNET_IDENTITY_PublicKey *pubkey = get_contact_key(session->contact); | ||
543 | |||
544 | struct GNUNET_HashCode sender; | ||
545 | GNUNET_CRYPTO_hash(pubkey, sizeof(*pubkey), &sender); | ||
546 | |||
547 | const struct GNUNET_HashCode *context = get_next_member_session_contect (session); | ||
548 | |||
549 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Notifying client about message: %s\n", GNUNET_h2s (hash)); | ||
550 | |||
551 | struct GNUNET_MESSENGER_Message *private_message = NULL; | ||
552 | |||
553 | if (GNUNET_MESSENGER_KIND_PRIVATE == message->header.kind) | ||
554 | { | ||
555 | private_message = copy_message(message); | ||
556 | |||
557 | if (GNUNET_YES != decrypt_message(private_message, &(get_handle_ego(handle)->priv))) | ||
558 | { | ||
559 | destroy_message(private_message); | ||
560 | private_message = NULL; | ||
561 | } | ||
562 | else | ||
563 | message = private_message; | ||
564 | } | ||
565 | |||
566 | struct GNUNET_MESSENGER_RecvMessage *msg; | ||
567 | struct GNUNET_MQ_Envelope *env; | ||
568 | |||
569 | uint16_t length = get_message_size (message, GNUNET_YES); | ||
570 | |||
571 | env = GNUNET_MQ_msg_extra(msg, length, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE); | ||
572 | |||
573 | GNUNET_memcpy(&(msg->key), key, sizeof(msg->key)); | ||
574 | GNUNET_memcpy(&(msg->sender), &sender, sizeof(msg->sender)); | ||
575 | GNUNET_memcpy(&(msg->context), context, sizeof(msg->context)); | ||
576 | GNUNET_memcpy(&(msg->hash), hash, sizeof(msg->hash)); | ||
577 | |||
578 | msg->flags = (uint32_t) GNUNET_MESSENGER_FLAG_NONE; | ||
579 | |||
580 | if (get_handle_member_session(handle, room, key) == session) | ||
581 | msg->flags |= (uint32_t) GNUNET_MESSENGER_FLAG_SENT; | ||
582 | |||
583 | if (private_message) | ||
584 | msg->flags |= (uint32_t) GNUNET_MESSENGER_FLAG_PRIVATE; | ||
585 | |||
586 | char *buffer = ((char*) msg) + sizeof(*msg); | ||
587 | encode_message (message, length, buffer, GNUNET_YES); | ||
588 | |||
589 | if (private_message) | ||
590 | destroy_message(private_message); | ||
591 | |||
592 | GNUNET_MQ_send (handle->mq, env); | ||
593 | } | ||
594 | |||
595 | static int | ||
596 | callback_scan_for_rooms (void *cls, | ||
597 | const char *filename) | ||
598 | { | ||
599 | struct GNUNET_MESSENGER_SrvHandle *handle = cls; | ||
600 | |||
601 | if ((strlen(filename) <= 4) || (0 != strcmp(filename + strlen(filename) - 4, ".cfg"))) | ||
602 | return GNUNET_OK; | ||
603 | |||
604 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Load room configuration of handle: %s\n", filename); | ||
605 | |||
606 | struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create (); | ||
607 | |||
608 | if ((GNUNET_YES == GNUNET_DISK_file_test (filename)) && (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, filename))) | ||
609 | { | ||
610 | struct GNUNET_HashCode key; | ||
611 | struct GNUNET_ShortHashCode member_id; | ||
612 | |||
613 | if ((GNUNET_OK == GNUNET_CONFIGURATION_get_data (cfg, "room", "key", &key, sizeof(key))) && | ||
614 | (GNUNET_OK == GNUNET_CONFIGURATION_get_data (cfg, "room", "member_id", &member_id, sizeof(member_id)))) | ||
615 | change_handle_member_id (handle, &key, &member_id); | ||
616 | } | ||
617 | |||
618 | GNUNET_CONFIGURATION_destroy (cfg); | ||
619 | return GNUNET_OK; | ||
620 | } | ||
621 | |||
622 | void | ||
623 | load_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle) | ||
624 | { | ||
625 | GNUNET_assert(handle); | ||
626 | |||
627 | char *id_dir; | ||
628 | get_handle_data_subdir (handle, handle->name, &id_dir); | ||
629 | |||
630 | if (GNUNET_YES == GNUNET_DISK_directory_test (id_dir, GNUNET_YES)) | ||
631 | { | ||
632 | char *scan_dir; | ||
633 | GNUNET_asprintf (&scan_dir, "%s%s%c", id_dir, "rooms", DIR_SEPARATOR); | ||
634 | |||
635 | if (GNUNET_OK == GNUNET_DISK_directory_test (scan_dir, GNUNET_YES)) | ||
636 | GNUNET_DISK_directory_scan (scan_dir, callback_scan_for_rooms, handle); | ||
637 | |||
638 | GNUNET_free(scan_dir); | ||
639 | } | ||
640 | |||
641 | GNUNET_free(id_dir); | ||
642 | } | ||
643 | |||
644 | static int | ||
645 | iterate_save_rooms (void *cls, | ||
646 | const struct GNUNET_HashCode *key, | ||
647 | void *value) | ||
648 | { | ||
649 | struct GNUNET_MESSENGER_SrvHandle *handle = cls; | ||
650 | struct GNUNET_ShortHashCode *member_id = value; | ||
651 | |||
652 | char *id_dir; | ||
653 | get_handle_data_subdir (handle, handle->name, &id_dir); | ||
654 | |||
655 | char *filename; | ||
656 | GNUNET_asprintf (&filename, "%s%s%c%s.cfg", id_dir, "rooms", DIR_SEPARATOR, GNUNET_h2s (key)); | ||
657 | GNUNET_free(id_dir); | ||
658 | |||
659 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Save room configuration of handle: %s\n", filename); | ||
660 | |||
661 | struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create (); | ||
662 | |||
663 | char *key_data = GNUNET_STRINGS_data_to_string_alloc (key, sizeof(*key)); | ||
664 | |||
665 | if (key_data) | ||
666 | { | ||
667 | GNUNET_CONFIGURATION_set_value_string (cfg, "room", "key", key_data); | ||
668 | |||
669 | GNUNET_free(key_data); | ||
670 | } | ||
671 | |||
672 | char *member_id_data = GNUNET_STRINGS_data_to_string_alloc (member_id, sizeof(*member_id)); | ||
673 | |||
674 | if (member_id_data) | ||
675 | { | ||
676 | GNUNET_CONFIGURATION_set_value_string (cfg, "room", "member_id", member_id_data); | ||
677 | |||
678 | GNUNET_free(member_id_data); | ||
679 | } | ||
680 | |||
681 | GNUNET_CONFIGURATION_write (cfg, filename); | ||
682 | GNUNET_CONFIGURATION_destroy (cfg); | ||
683 | |||
684 | GNUNET_free(filename); | ||
685 | |||
686 | return GNUNET_YES; | ||
687 | } | ||
688 | |||
689 | void | ||
690 | save_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle) | ||
691 | { | ||
692 | GNUNET_assert(handle); | ||
693 | |||
694 | char *id_dir; | ||
695 | get_handle_data_subdir (handle, handle->name, &id_dir); | ||
696 | |||
697 | if ((GNUNET_YES == GNUNET_DISK_directory_test (id_dir, GNUNET_NO)) || (GNUNET_OK | ||
698 | == GNUNET_DISK_directory_create (id_dir))) | ||
699 | { | ||
700 | char *save_dir; | ||
701 | GNUNET_asprintf (&save_dir, "%s%s%c", id_dir, "rooms", DIR_SEPARATOR); | ||
702 | |||
703 | if ((GNUNET_YES == GNUNET_DISK_directory_test (save_dir, GNUNET_NO)) || | ||
704 | (GNUNET_OK == GNUNET_DISK_directory_create (save_dir))) | ||
705 | GNUNET_CONTAINER_multihashmap_iterate (handle->member_ids, iterate_save_rooms, handle); | ||
706 | |||
707 | GNUNET_free(save_dir); | ||
708 | } | ||
709 | |||
710 | GNUNET_free(id_dir); | ||
711 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_handle.h b/src/messenger/gnunet-service-messenger_handle.h deleted file mode 100644 index 4438570b9..000000000 --- a/src/messenger/gnunet-service-messenger_handle.h +++ /dev/null | |||
@@ -1,252 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_handle.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_HANDLE_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_HANDLE_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_cadet_service.h" | ||
31 | #include "gnunet_container_lib.h" | ||
32 | #include "gnunet_crypto_lib.h" | ||
33 | #include "gnunet_identity_service.h" | ||
34 | #include "gnunet_peer_lib.h" | ||
35 | #include "gnunet_mq_lib.h" | ||
36 | |||
37 | #include "gnunet-service-messenger_service.h" | ||
38 | #include "gnunet-service-messenger_member_session.h" | ||
39 | |||
40 | #include "messenger_api_ego.h" | ||
41 | #include "messenger_api_message.h" | ||
42 | |||
43 | struct GNUNET_MESSENGER_SrvHandle | ||
44 | { | ||
45 | struct GNUNET_MESSENGER_Service *service; | ||
46 | struct GNUNET_MQ_Handle *mq; | ||
47 | |||
48 | char *name; | ||
49 | |||
50 | const struct GNUNET_MESSENGER_Ego *ego; | ||
51 | |||
52 | struct GNUNET_CONTAINER_MultiHashMap *member_ids; | ||
53 | }; | ||
54 | |||
55 | /** | ||
56 | * Creates and allocates a new handle related to a <i>service</i> and using a given <i>mq</i> (message queue). | ||
57 | * | ||
58 | * @param[in/out] service MESSENGER Service | ||
59 | * @param[in/out] mq Message queue | ||
60 | * @return New handle | ||
61 | */ | ||
62 | struct GNUNET_MESSENGER_SrvHandle* | ||
63 | create_handle (struct GNUNET_MESSENGER_Service *service, | ||
64 | struct GNUNET_MQ_Handle *mq); | ||
65 | |||
66 | /** | ||
67 | * Destroys a handle and frees its memory fully. | ||
68 | * | ||
69 | * @param[in/out] handle Handle | ||
70 | */ | ||
71 | void | ||
72 | destroy_handle (struct GNUNET_MESSENGER_SrvHandle *handle); | ||
73 | |||
74 | /** | ||
75 | * Writes the path of the directory for a given <i>handle</i> using a specific <i>name</i> to the parameter | ||
76 | * <i>dir</i>. This directory will be used to store data regarding the handle and its messages. | ||
77 | * | ||
78 | * @param[in] handle Handle | ||
79 | * @param[in] name Potential name of the handle | ||
80 | * @param[out] dir Path to store data | ||
81 | */ | ||
82 | void | ||
83 | get_handle_data_subdir (const struct GNUNET_MESSENGER_SrvHandle *handle, | ||
84 | const char *name, | ||
85 | char **dir); | ||
86 | |||
87 | /** | ||
88 | * Returns the member id of a given <i>handle</i> in a specific <i>room</i>. | ||
89 | * | ||
90 | * If the handle is not a member of the specific <i>room</i>, NULL gets returned. | ||
91 | * | ||
92 | * @param[in] handle Handle | ||
93 | * @param[in] key Key of a room | ||
94 | * @return Member id or NULL | ||
95 | */ | ||
96 | const struct GNUNET_ShortHashCode* | ||
97 | get_handle_member_id (const struct GNUNET_MESSENGER_SrvHandle *handle, | ||
98 | const struct GNUNET_HashCode *key); | ||
99 | |||
100 | /** | ||
101 | * Changes the member id of a given <i>handle</i> in a specific <i>room</i> to match a <i>unique_id</i> | ||
102 | * and returns GNUNET_OK on success. | ||
103 | * | ||
104 | * The client connected to the <i>handle</i> will be informed afterwards automatically. | ||
105 | * | ||
106 | * @param[in/out] handle Handle | ||
107 | * @param[in] key Key of a room | ||
108 | * @param[in] unique_id Unique member id | ||
109 | * @return GNUNET_OK on success, otherwise GNUNET_SYSERR | ||
110 | */ | ||
111 | int | ||
112 | change_handle_member_id (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
113 | const struct GNUNET_HashCode *key, | ||
114 | const struct GNUNET_ShortHashCode *unique_id); | ||
115 | |||
116 | /** | ||
117 | * Sets the EGO used by a given <i>handle</i>. | ||
118 | * | ||
119 | * @param[in/out] handle Handle | ||
120 | * @param[in] ego EGO key pair | ||
121 | */ | ||
122 | void | ||
123 | set_handle_ego (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
124 | const struct GNUNET_MESSENGER_Ego *ego); | ||
125 | |||
126 | /** | ||
127 | * Returns the EGO used by a given <i>handle</i>. | ||
128 | * | ||
129 | * @param[in] handle Handle | ||
130 | * @return EGO key pair | ||
131 | */ | ||
132 | const struct GNUNET_MESSENGER_Ego* | ||
133 | get_handle_ego (const struct GNUNET_MESSENGER_SrvHandle *handle); | ||
134 | |||
135 | /** | ||
136 | * Tries to set the name and EGO key of a <i>handle</i> initially by looking up a specific <i>name</i>. | ||
137 | * | ||
138 | * @param[in/out] handle Handle | ||
139 | * @param[in] name Name (optionally: valid EGO name) | ||
140 | */ | ||
141 | void | ||
142 | setup_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
143 | const char *name); | ||
144 | |||
145 | /** | ||
146 | * Tries to change the key pair of an EGO of a <i>handle</i> under the same name and informs all rooms | ||
147 | * about the change automatically. | ||
148 | * | ||
149 | * @param[in/out] handle Handle | ||
150 | */ | ||
151 | void | ||
152 | update_handle (struct GNUNET_MESSENGER_SrvHandle *handle); | ||
153 | |||
154 | /** | ||
155 | * Tries to rename the handle which implies renaming the EGO its using and moving all related data into | ||
156 | * the directory fitting to the changed <i>name</i>. | ||
157 | * | ||
158 | * The client connected to the <i>handle</i> will be informed afterwards automatically. | ||
159 | * | ||
160 | * @param[in/out] handle Handle | ||
161 | * @param[in] name New name | ||
162 | */ | ||
163 | void | ||
164 | set_handle_name (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
165 | const char *name); | ||
166 | |||
167 | /** | ||
168 | * Makes a given <i>handle</i> a member of the room using a specific <i>key</i> and opens the | ||
169 | * room from the handles service. | ||
170 | * | ||
171 | * @param[in/out] handle Handle | ||
172 | * @param[in] key Key of a room | ||
173 | * @return #GNUNET_YES on success, otherwise #GNUNET_NO | ||
174 | */ | ||
175 | int | ||
176 | open_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
177 | const struct GNUNET_HashCode *key); | ||
178 | |||
179 | /** | ||
180 | * Makes a given <i>handle</i> a member of the room using a specific <i>key</i> and enters the room | ||
181 | * through a tunnel to a peer identified by a given <i>door</i> (peer identity). | ||
182 | * | ||
183 | * @param[in/out] handle Handle | ||
184 | * @param[in] door Peer identity | ||
185 | * @param[in] key Key of a room | ||
186 | * @return #GNUNET_YES on success, otherwise #GNUNET_NO | ||
187 | */ | ||
188 | int | ||
189 | entry_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
190 | const struct GNUNET_PeerIdentity *door, | ||
191 | const struct GNUNET_HashCode *key); | ||
192 | |||
193 | /** | ||
194 | * Removes the membership of the room using a specific <i>key</i> and closes it if no other handle | ||
195 | * from this service is still a member of it. | ||
196 | * | ||
197 | * @param[in/out] handle Handle | ||
198 | * @param[in] key Key of a room | ||
199 | * @return #GNUNET_YES on success, otherwise #GNUNET_NO | ||
200 | */ | ||
201 | int | ||
202 | close_handle_room (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
203 | const struct GNUNET_HashCode *key); | ||
204 | |||
205 | /** | ||
206 | * Sends a <i>message</i> from a given <i>handle</i> to the room using a specific <i>key</i>. | ||
207 | * | ||
208 | * @param[in/out] handle Handle | ||
209 | * @param[in] key Key of a room | ||
210 | * @param[in] message Message | ||
211 | * @return #GNUNET_YES on success, #GNUNET_NO or #GNUNET_SYSERR otherwise. | ||
212 | */ | ||
213 | int | ||
214 | send_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
215 | const struct GNUNET_HashCode *key, | ||
216 | const struct GNUNET_MESSENGER_Message *message); | ||
217 | |||
218 | /** | ||
219 | * Notifies the handle that a new message was received or sent. | ||
220 | * | ||
221 | * @param[in/out] handle Handle | ||
222 | * @param[in] room Room of the message | ||
223 | * @param[in] session Member session | ||
224 | * @param[in] message Message | ||
225 | * @param[in] hash Hash of message | ||
226 | */ | ||
227 | void | ||
228 | notify_handle_message (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
229 | struct GNUNET_MESSENGER_SrvRoom *room, | ||
230 | const struct GNUNET_MESSENGER_MemberSession *session, | ||
231 | const struct GNUNET_MESSENGER_Message *message, | ||
232 | const struct GNUNET_HashCode *hash); | ||
233 | |||
234 | /** | ||
235 | * Loads member ids and other potential configuration from a given <i>handle</i> which | ||
236 | * depends on the given name the <i>handle</i> uses. | ||
237 | * | ||
238 | * @param[out] handle Handle | ||
239 | */ | ||
240 | void | ||
241 | load_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle); | ||
242 | |||
243 | /** | ||
244 | * Saves member ids and other potential configuration from a given <i>handle</i> which | ||
245 | * depends on the given name the <i>handle</i> uses. | ||
246 | * | ||
247 | * @param[in] handle Handle | ||
248 | */ | ||
249 | void | ||
250 | save_handle_configuration (struct GNUNET_MESSENGER_SrvHandle *handle); | ||
251 | |||
252 | #endif //GNUNET_SERVICE_MESSENGER_HANDLE_H | ||
diff --git a/src/messenger/gnunet-service-messenger_list_handles.c b/src/messenger/gnunet-service-messenger_list_handles.c deleted file mode 100644 index c0ae18716..000000000 --- a/src/messenger/gnunet-service-messenger_list_handles.c +++ /dev/null | |||
@@ -1,104 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_list_handles.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_list_handles.h" | ||
27 | |||
28 | #include "gnunet-service-messenger_handle.h" | ||
29 | |||
30 | void | ||
31 | init_list_handles (struct GNUNET_MESSENGER_ListHandles *handles) | ||
32 | { | ||
33 | GNUNET_assert(handles); | ||
34 | |||
35 | handles->head = NULL; | ||
36 | handles->tail = NULL; | ||
37 | } | ||
38 | |||
39 | void | ||
40 | clear_list_handles (struct GNUNET_MESSENGER_ListHandles *handles) | ||
41 | { | ||
42 | GNUNET_assert(handles); | ||
43 | |||
44 | while (handles->head) | ||
45 | { | ||
46 | struct GNUNET_MESSENGER_ListHandle *element = handles->head; | ||
47 | |||
48 | GNUNET_CONTAINER_DLL_remove(handles->head, handles->tail, element); | ||
49 | destroy_handle (element->handle); | ||
50 | GNUNET_free(element); | ||
51 | } | ||
52 | |||
53 | handles->head = NULL; | ||
54 | handles->tail = NULL; | ||
55 | } | ||
56 | |||
57 | void | ||
58 | add_list_handle (struct GNUNET_MESSENGER_ListHandles *handles, | ||
59 | struct GNUNET_MESSENGER_SrvHandle *handle) | ||
60 | { | ||
61 | GNUNET_assert((handles) && (handle)); | ||
62 | |||
63 | struct GNUNET_MESSENGER_ListHandle *element = GNUNET_new(struct GNUNET_MESSENGER_ListHandle); | ||
64 | |||
65 | element->handle = handle; | ||
66 | |||
67 | GNUNET_CONTAINER_DLL_insert_tail(handles->head, handles->tail, element); | ||
68 | } | ||
69 | |||
70 | int | ||
71 | remove_list_handle (struct GNUNET_MESSENGER_ListHandles *handles, | ||
72 | struct GNUNET_MESSENGER_SrvHandle *handle) | ||
73 | { | ||
74 | GNUNET_assert((handles) && (handle)); | ||
75 | |||
76 | struct GNUNET_MESSENGER_ListHandle *element; | ||
77 | |||
78 | for (element = handles->head; element; element = element->next) | ||
79 | if (element->handle == handle) | ||
80 | break; | ||
81 | |||
82 | if (!element) | ||
83 | return GNUNET_NO; | ||
84 | |||
85 | GNUNET_CONTAINER_DLL_remove(handles->head, handles->tail, element); | ||
86 | GNUNET_free(element); | ||
87 | |||
88 | return GNUNET_YES; | ||
89 | } | ||
90 | |||
91 | struct GNUNET_MESSENGER_SrvHandle* | ||
92 | find_list_handle_by_member (const struct GNUNET_MESSENGER_ListHandles *handles, | ||
93 | const struct GNUNET_HashCode *key) | ||
94 | { | ||
95 | GNUNET_assert((handles) && (key)); | ||
96 | |||
97 | struct GNUNET_MESSENGER_ListHandle *element; | ||
98 | |||
99 | for (element = handles->head; element; element = element->next) | ||
100 | if (get_handle_member_id ((struct GNUNET_MESSENGER_SrvHandle*) element->handle, key)) | ||
101 | return element->handle; | ||
102 | |||
103 | return NULL; | ||
104 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_list_handles.h b/src/messenger/gnunet-service-messenger_list_handles.h deleted file mode 100644 index f4d7ca5c0..000000000 --- a/src/messenger/gnunet-service-messenger_list_handles.h +++ /dev/null | |||
@@ -1,101 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_list_handles.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_LIST_HANDLES_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_LIST_HANDLES_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_crypto_lib.h" | ||
31 | #include "gnunet_container_lib.h" | ||
32 | |||
33 | struct GNUNET_MESSENGER_SrvHandle; | ||
34 | |||
35 | struct GNUNET_MESSENGER_ListHandle | ||
36 | { | ||
37 | struct GNUNET_MESSENGER_ListHandle *prev; | ||
38 | struct GNUNET_MESSENGER_ListHandle *next; | ||
39 | |||
40 | struct GNUNET_MESSENGER_SrvHandle *handle; | ||
41 | }; | ||
42 | |||
43 | struct GNUNET_MESSENGER_ListHandles | ||
44 | { | ||
45 | struct GNUNET_MESSENGER_ListHandle *head; | ||
46 | struct GNUNET_MESSENGER_ListHandle *tail; | ||
47 | }; | ||
48 | |||
49 | /** | ||
50 | * Initializes list of <i>handles</i> as empty list. | ||
51 | * | ||
52 | * @param[out] handles List of handles | ||
53 | */ | ||
54 | void | ||
55 | init_list_handles (struct GNUNET_MESSENGER_ListHandles *handles); | ||
56 | |||
57 | /** | ||
58 | * Destroys remaining <i>handles</i> and clears the list. | ||
59 | * | ||
60 | * @param[in/out] handles List of handles | ||
61 | */ | ||
62 | void | ||
63 | clear_list_handles (struct GNUNET_MESSENGER_ListHandles *handles); | ||
64 | |||
65 | /** | ||
66 | * Adds a specific <i>handle</i> to the end of the list. | ||
67 | * | ||
68 | * @param[in/out] handles List of handles | ||
69 | * @param[in/out] handle Handle | ||
70 | */ | ||
71 | void | ||
72 | add_list_handle (struct GNUNET_MESSENGER_ListHandles *handles, | ||
73 | struct GNUNET_MESSENGER_SrvHandle *handle); | ||
74 | |||
75 | /** | ||
76 | * Removes the first entry matching with a specific <i>handle</i> from the list of | ||
77 | * <i>handles</i> and returns #GNUNET_YES on success or #GNUNET_NO on failure. | ||
78 | * | ||
79 | * @param[in/out] handles List of handles | ||
80 | * @param[in/out] handle Handle | ||
81 | * @return #GNUNET_YES on success, otherwise #GNUNET_NO | ||
82 | */ | ||
83 | int | ||
84 | remove_list_handle (struct GNUNET_MESSENGER_ListHandles *handles, | ||
85 | struct GNUNET_MESSENGER_SrvHandle *handle); | ||
86 | |||
87 | /** | ||
88 | * Searches linearly through the list of <i>handles</i> for members of a specific room | ||
89 | * which is identified by a given <i>key</i>. | ||
90 | * | ||
91 | * If no handle is found which is a current member, NULL gets returned. | ||
92 | * | ||
93 | * @param[in] handles List of handles | ||
94 | * @param[in] key Common key of a room | ||
95 | * @return First handle which is a current member | ||
96 | */ | ||
97 | struct GNUNET_MESSENGER_SrvHandle* | ||
98 | find_list_handle_by_member (const struct GNUNET_MESSENGER_ListHandles *handles, | ||
99 | const struct GNUNET_HashCode *key); | ||
100 | |||
101 | #endif //GNUNET_SERVICE_MESSENGER_LIST_HANDLES_H | ||
diff --git a/src/messenger/gnunet-service-messenger_list_messages.c b/src/messenger/gnunet-service-messenger_list_messages.c deleted file mode 100644 index 7092dc76f..000000000 --- a/src/messenger/gnunet-service-messenger_list_messages.c +++ /dev/null | |||
@@ -1,155 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_list_messages.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_list_messages.h" | ||
27 | |||
28 | void | ||
29 | init_list_messages (struct GNUNET_MESSENGER_ListMessages *messages) | ||
30 | { | ||
31 | GNUNET_assert(messages); | ||
32 | |||
33 | messages->head = NULL; | ||
34 | messages->tail = NULL; | ||
35 | } | ||
36 | |||
37 | void | ||
38 | clear_list_messages (struct GNUNET_MESSENGER_ListMessages *messages) | ||
39 | { | ||
40 | GNUNET_assert(messages); | ||
41 | |||
42 | while (messages->head) | ||
43 | { | ||
44 | struct GNUNET_MESSENGER_ListMessage *element = messages->head; | ||
45 | |||
46 | GNUNET_CONTAINER_DLL_remove(messages->head, messages->tail, element); | ||
47 | GNUNET_free(element); | ||
48 | } | ||
49 | |||
50 | messages->head = NULL; | ||
51 | messages->tail = NULL; | ||
52 | } | ||
53 | |||
54 | void | ||
55 | add_to_list_messages (struct GNUNET_MESSENGER_ListMessages *messages, | ||
56 | const struct GNUNET_HashCode *hash) | ||
57 | { | ||
58 | GNUNET_assert((messages) && (hash)); | ||
59 | |||
60 | struct GNUNET_MESSENGER_ListMessage *element = GNUNET_new(struct GNUNET_MESSENGER_ListMessage); | ||
61 | |||
62 | GNUNET_memcpy(&(element->hash), hash, sizeof(struct GNUNET_HashCode)); | ||
63 | |||
64 | GNUNET_CONTAINER_DLL_insert_tail(messages->head, messages->tail, element); | ||
65 | } | ||
66 | |||
67 | void | ||
68 | copy_list_messages (struct GNUNET_MESSENGER_ListMessages *messages, | ||
69 | const struct GNUNET_MESSENGER_ListMessages *origin) | ||
70 | { | ||
71 | GNUNET_assert((messages) && (origin)); | ||
72 | |||
73 | struct GNUNET_MESSENGER_ListMessage *element; | ||
74 | |||
75 | for (element = origin->head; element; element = element->next) | ||
76 | add_to_list_messages (messages, &(element->hash)); | ||
77 | } | ||
78 | |||
79 | void | ||
80 | remove_from_list_messages (struct GNUNET_MESSENGER_ListMessages *messages, | ||
81 | const struct GNUNET_HashCode *hash) | ||
82 | { | ||
83 | GNUNET_assert((messages) && (hash)); | ||
84 | |||
85 | struct GNUNET_MESSENGER_ListMessage *element; | ||
86 | |||
87 | for (element = messages->head; element; element = element->next) | ||
88 | if (0 == GNUNET_CRYPTO_hash_cmp (&(element->hash), hash)) | ||
89 | { | ||
90 | GNUNET_CONTAINER_DLL_remove(messages->head, messages->tail, element); | ||
91 | GNUNET_free(element); | ||
92 | break; | ||
93 | } | ||
94 | } | ||
95 | |||
96 | void | ||
97 | load_list_messages (struct GNUNET_MESSENGER_ListMessages *messages, | ||
98 | const char *path) | ||
99 | { | ||
100 | GNUNET_assert((messages) && (path)); | ||
101 | |||
102 | if (GNUNET_YES != GNUNET_DISK_file_test (path)) | ||
103 | return; | ||
104 | |||
105 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); | ||
106 | |||
107 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open( | ||
108 | path, GNUNET_DISK_OPEN_READ, permission | ||
109 | ); | ||
110 | |||
111 | if (!handle) | ||
112 | return; | ||
113 | |||
114 | GNUNET_DISK_file_seek(handle, 0, GNUNET_DISK_SEEK_SET); | ||
115 | |||
116 | struct GNUNET_HashCode hash; | ||
117 | ssize_t len; | ||
118 | |||
119 | do { | ||
120 | len = GNUNET_DISK_file_read(handle, &hash, sizeof(hash)); | ||
121 | |||
122 | if (len != sizeof(hash)) | ||
123 | break; | ||
124 | |||
125 | add_to_list_messages(messages, &hash); | ||
126 | } while (len == sizeof(hash)); | ||
127 | |||
128 | GNUNET_DISK_file_close(handle); | ||
129 | } | ||
130 | |||
131 | void | ||
132 | save_list_messages (const struct GNUNET_MESSENGER_ListMessages *messages, | ||
133 | const char *path) | ||
134 | { | ||
135 | GNUNET_assert((messages) && (path)); | ||
136 | |||
137 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); | ||
138 | |||
139 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open( | ||
140 | path, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, permission | ||
141 | ); | ||
142 | |||
143 | if (!handle) | ||
144 | return; | ||
145 | |||
146 | GNUNET_DISK_file_seek(handle, 0, GNUNET_DISK_SEEK_SET); | ||
147 | |||
148 | struct GNUNET_MESSENGER_ListMessage *element; | ||
149 | |||
150 | for (element = messages->head; element; element = element->next) | ||
151 | GNUNET_DISK_file_write(handle, &(element->hash), sizeof(element->hash)); | ||
152 | |||
153 | GNUNET_DISK_file_sync(handle); | ||
154 | GNUNET_DISK_file_close(handle); | ||
155 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_list_messages.h b/src/messenger/gnunet-service-messenger_list_messages.h deleted file mode 100644 index 7abc8c00f..000000000 --- a/src/messenger/gnunet-service-messenger_list_messages.h +++ /dev/null | |||
@@ -1,114 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_list_messages.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_LIST_MESSAGES_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_LIST_MESSAGES_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_crypto_lib.h" | ||
31 | #include "gnunet_container_lib.h" | ||
32 | #include "gnunet_disk_lib.h" | ||
33 | |||
34 | struct GNUNET_MESSENGER_ListMessage | ||
35 | { | ||
36 | struct GNUNET_MESSENGER_ListMessage *prev; | ||
37 | struct GNUNET_MESSENGER_ListMessage *next; | ||
38 | |||
39 | struct GNUNET_HashCode hash; | ||
40 | }; | ||
41 | |||
42 | struct GNUNET_MESSENGER_ListMessages | ||
43 | { | ||
44 | struct GNUNET_MESSENGER_ListMessage *head; | ||
45 | struct GNUNET_MESSENGER_ListMessage *tail; | ||
46 | }; | ||
47 | |||
48 | /** | ||
49 | * Initializes list of message hashes as empty list. | ||
50 | * | ||
51 | * @param[out] messages List of hashes | ||
52 | */ | ||
53 | void | ||
54 | init_list_messages (struct GNUNET_MESSENGER_ListMessages *messages); | ||
55 | |||
56 | /** | ||
57 | * Clears the list of message hashes. | ||
58 | * | ||
59 | * @param[in/out] messages List of hashes | ||
60 | */ | ||
61 | void | ||
62 | clear_list_messages (struct GNUNET_MESSENGER_ListMessages *messages); | ||
63 | |||
64 | /** | ||
65 | * Adds a specific <i>hash</i> from a message to the end of the list. | ||
66 | * | ||
67 | * @param[in/out] messages List of hashes | ||
68 | * @param[in] hash Hash of message | ||
69 | */ | ||
70 | void | ||
71 | add_to_list_messages (struct GNUNET_MESSENGER_ListMessages *messages, | ||
72 | const struct GNUNET_HashCode *hash); | ||
73 | |||
74 | /** | ||
75 | * Copies all message hashes from an <i>origin</i> to another list. | ||
76 | * | ||
77 | * @param[in/out] messages Destination list of hashes | ||
78 | * @param[in] origin Source list of hashes | ||
79 | */ | ||
80 | void | ||
81 | copy_list_messages (struct GNUNET_MESSENGER_ListMessages *messages, | ||
82 | const struct GNUNET_MESSENGER_ListMessages *origin); | ||
83 | |||
84 | /** | ||
85 | * Removes the first entry with a matching <i>hash</i> from the list. | ||
86 | * | ||
87 | * @param[in/out] messages List of hashes | ||
88 | * @param[in] hash Hash of message | ||
89 | */ | ||
90 | void | ||
91 | remove_from_list_messages (struct GNUNET_MESSENGER_ListMessages *messages, | ||
92 | const struct GNUNET_HashCode *hash); | ||
93 | |||
94 | /** | ||
95 | * Loads the list of message hashes from a file under a given <i>path</i>. | ||
96 | * | ||
97 | * @param[out] messages List of hashes | ||
98 | * @param[in] path Path of file | ||
99 | */ | ||
100 | void | ||
101 | load_list_messages (struct GNUNET_MESSENGER_ListMessages *messages, | ||
102 | const char *path); | ||
103 | |||
104 | /** | ||
105 | * Saves the list of message hashes to a file under a given <i>path</i>. | ||
106 | * | ||
107 | * @param[in] messages List of hashes | ||
108 | * @param[in] path Path of file | ||
109 | */ | ||
110 | void | ||
111 | save_list_messages (const struct GNUNET_MESSENGER_ListMessages *messages, | ||
112 | const char *path); | ||
113 | |||
114 | #endif //GNUNET_SERVICE_MESSENGER_LIST_MESSAGES_H | ||
diff --git a/src/messenger/gnunet-service-messenger_member.c b/src/messenger/gnunet-service-messenger_member.c deleted file mode 100644 index 976b68fe6..000000000 --- a/src/messenger/gnunet-service-messenger_member.c +++ /dev/null | |||
@@ -1,415 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_member.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_member.h" | ||
27 | |||
28 | #include "gnunet-service-messenger_member_session.h" | ||
29 | |||
30 | struct GNUNET_MESSENGER_Member* | ||
31 | create_member (struct GNUNET_MESSENGER_MemberStore *store, | ||
32 | const struct GNUNET_ShortHashCode *id) | ||
33 | { | ||
34 | GNUNET_assert (store); | ||
35 | |||
36 | struct GNUNET_MESSENGER_Member *member = GNUNET_new(struct GNUNET_MESSENGER_Member); | ||
37 | |||
38 | member->store = store; | ||
39 | |||
40 | if (id) | ||
41 | GNUNET_memcpy(&(member->id), id, sizeof(member->id)); | ||
42 | else if (GNUNET_YES != generate_free_member_id(&(member->id), store->members)) | ||
43 | { | ||
44 | GNUNET_free (member); | ||
45 | return NULL; | ||
46 | } | ||
47 | |||
48 | member->sessions = GNUNET_CONTAINER_multihashmap_create(2, GNUNET_NO); | ||
49 | |||
50 | return member; | ||
51 | } | ||
52 | |||
53 | static int | ||
54 | iterate_destroy_session (void *cls, | ||
55 | const struct GNUNET_HashCode *key, | ||
56 | void *value) | ||
57 | { | ||
58 | struct GNUNET_MESSENGER_MemberSession *session = value; | ||
59 | destroy_member_session(session); | ||
60 | return GNUNET_YES; | ||
61 | } | ||
62 | |||
63 | void | ||
64 | destroy_member (struct GNUNET_MESSENGER_Member *member) | ||
65 | { | ||
66 | GNUNET_assert((member) && (member->sessions)); | ||
67 | |||
68 | GNUNET_CONTAINER_multihashmap_iterate (member->sessions, iterate_destroy_session, NULL); | ||
69 | GNUNET_CONTAINER_multihashmap_destroy (member->sessions); | ||
70 | |||
71 | GNUNET_free (member); | ||
72 | } | ||
73 | |||
74 | const struct GNUNET_ShortHashCode* | ||
75 | get_member_id (const struct GNUNET_MESSENGER_Member *member) | ||
76 | { | ||
77 | GNUNET_assert (member); | ||
78 | |||
79 | return &(member->id); | ||
80 | } | ||
81 | |||
82 | static int | ||
83 | callback_scan_for_sessions (void *cls, | ||
84 | const char *filename) | ||
85 | { | ||
86 | struct GNUNET_MESSENGER_Member *member = cls; | ||
87 | |||
88 | if (GNUNET_YES == GNUNET_DISK_directory_test (filename, GNUNET_YES)) | ||
89 | { | ||
90 | char *directory; | ||
91 | |||
92 | GNUNET_asprintf (&directory, "%s%c", filename, DIR_SEPARATOR); | ||
93 | |||
94 | load_member_session(member, directory); | ||
95 | GNUNET_free (directory); | ||
96 | } | ||
97 | |||
98 | return GNUNET_OK; | ||
99 | } | ||
100 | |||
101 | void | ||
102 | load_member (struct GNUNET_MESSENGER_MemberStore *store, | ||
103 | const char *directory) | ||
104 | { | ||
105 | GNUNET_assert ((store) && (directory)); | ||
106 | |||
107 | char *config_file; | ||
108 | GNUNET_asprintf (&config_file, "%s%s", directory, "member.cfg"); | ||
109 | |||
110 | struct GNUNET_MESSENGER_Member *member = NULL; | ||
111 | |||
112 | if (GNUNET_YES != GNUNET_DISK_file_test (config_file)) | ||
113 | goto free_config; | ||
114 | |||
115 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Load member configuration: %s\n", config_file); | ||
116 | |||
117 | struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create (); | ||
118 | |||
119 | if (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, config_file)) | ||
120 | { | ||
121 | struct GNUNET_ShortHashCode id; | ||
122 | |||
123 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_data (cfg, "member", "id", &id, sizeof(id))) | ||
124 | goto destroy_config; | ||
125 | |||
126 | member = add_store_member(store, &id); | ||
127 | } | ||
128 | |||
129 | destroy_config: | ||
130 | |||
131 | GNUNET_CONFIGURATION_destroy (cfg); | ||
132 | |||
133 | free_config: | ||
134 | GNUNET_free(config_file); | ||
135 | |||
136 | if (!member) | ||
137 | return; | ||
138 | |||
139 | char *scan_dir; | ||
140 | GNUNET_asprintf (&scan_dir, "%s%s%c", directory, "sessions", DIR_SEPARATOR); | ||
141 | |||
142 | if (GNUNET_OK == GNUNET_DISK_directory_test (scan_dir, GNUNET_YES)) | ||
143 | GNUNET_DISK_directory_scan (scan_dir, callback_scan_for_sessions, member); | ||
144 | |||
145 | GNUNET_free(scan_dir); | ||
146 | } | ||
147 | |||
148 | static int | ||
149 | iterate_load_next_session (void *cls, | ||
150 | const struct GNUNET_HashCode *key, | ||
151 | void *value) | ||
152 | { | ||
153 | const char* sessions_directory = cls; | ||
154 | |||
155 | char* load_dir; | ||
156 | GNUNET_asprintf (&load_dir, "%s%s%c", sessions_directory, GNUNET_h2s(key), DIR_SEPARATOR); | ||
157 | |||
158 | struct GNUNET_MESSENGER_MemberSession *session = value; | ||
159 | |||
160 | if (GNUNET_YES == GNUNET_DISK_directory_test (load_dir, GNUNET_YES)) | ||
161 | load_member_session_next (session, load_dir); | ||
162 | |||
163 | GNUNET_free (load_dir); | ||
164 | return GNUNET_YES; | ||
165 | } | ||
166 | |||
167 | void | ||
168 | load_member_next_sessions (const struct GNUNET_MESSENGER_Member *member, | ||
169 | const char *directory) | ||
170 | { | ||
171 | GNUNET_assert ((member) && (directory)); | ||
172 | |||
173 | char* load_dir; | ||
174 | GNUNET_asprintf (&load_dir, "%s%s%c", directory, "sessions", DIR_SEPARATOR); | ||
175 | |||
176 | GNUNET_CONTAINER_multihashmap_iterate (member->sessions, iterate_load_next_session, load_dir); | ||
177 | |||
178 | GNUNET_free(load_dir); | ||
179 | } | ||
180 | |||
181 | static int | ||
182 | iterate_save_session (void *cls, | ||
183 | const struct GNUNET_HashCode *key, | ||
184 | void *value) | ||
185 | { | ||
186 | const char* sessions_directory = cls; | ||
187 | |||
188 | char* save_dir; | ||
189 | GNUNET_asprintf (&save_dir, "%s%s%c", sessions_directory, GNUNET_h2s(key), DIR_SEPARATOR); | ||
190 | |||
191 | struct GNUNET_MESSENGER_MemberSession *session = value; | ||
192 | |||
193 | if ((GNUNET_YES == GNUNET_DISK_directory_test (save_dir, GNUNET_NO)) || | ||
194 | (GNUNET_OK == GNUNET_DISK_directory_create (save_dir))) | ||
195 | save_member_session (session, save_dir); | ||
196 | |||
197 | GNUNET_free (save_dir); | ||
198 | return GNUNET_YES; | ||
199 | } | ||
200 | |||
201 | void | ||
202 | save_member (struct GNUNET_MESSENGER_Member *member, | ||
203 | const char *directory) | ||
204 | { | ||
205 | GNUNET_assert ((member) && (directory)); | ||
206 | |||
207 | char *config_file; | ||
208 | GNUNET_asprintf (&config_file, "%s%s", directory, "member.cfg"); | ||
209 | |||
210 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Save member configuration: %s\n", config_file); | ||
211 | |||
212 | struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create (); | ||
213 | |||
214 | char *id_data = GNUNET_STRINGS_data_to_string_alloc (&(member->id), sizeof(member->id)); | ||
215 | |||
216 | if (id_data) | ||
217 | { | ||
218 | GNUNET_CONFIGURATION_set_value_string (cfg, "member", "id", id_data); | ||
219 | |||
220 | GNUNET_free(id_data); | ||
221 | } | ||
222 | |||
223 | GNUNET_CONFIGURATION_write (cfg, config_file); | ||
224 | GNUNET_CONFIGURATION_destroy (cfg); | ||
225 | |||
226 | GNUNET_free(config_file); | ||
227 | |||
228 | char* save_dir; | ||
229 | GNUNET_asprintf (&save_dir, "%s%s%c", directory, "sessions", DIR_SEPARATOR); | ||
230 | |||
231 | if ((GNUNET_YES == GNUNET_DISK_directory_test (save_dir, GNUNET_NO)) || | ||
232 | (GNUNET_OK == GNUNET_DISK_directory_create (save_dir))) | ||
233 | GNUNET_CONTAINER_multihashmap_iterate (member->sessions, iterate_save_session, save_dir); | ||
234 | |||
235 | GNUNET_free(save_dir); | ||
236 | } | ||
237 | |||
238 | static void | ||
239 | sync_session_contact_from_next (struct GNUNET_MESSENGER_MemberSession *session, | ||
240 | struct GNUNET_MESSENGER_MemberSession *next) | ||
241 | { | ||
242 | GNUNET_assert((session) && (next)); | ||
243 | |||
244 | if (session == next) | ||
245 | return; | ||
246 | |||
247 | if (next->next) | ||
248 | sync_session_contact_from_next (session, next->next); | ||
249 | else | ||
250 | session->contact = next->contact; | ||
251 | } | ||
252 | |||
253 | static int | ||
254 | iterate_sync_session_contact (void *cls, | ||
255 | const struct GNUNET_HashCode *key, | ||
256 | void *value) | ||
257 | { | ||
258 | struct GNUNET_MESSENGER_MemberSession *session = value; | ||
259 | |||
260 | if (session->next) | ||
261 | sync_session_contact_from_next (session, session->next); | ||
262 | |||
263 | return GNUNET_YES; | ||
264 | } | ||
265 | |||
266 | void | ||
267 | sync_member_contacts (struct GNUNET_MESSENGER_Member *member) | ||
268 | { | ||
269 | GNUNET_assert ((member) && (member->sessions)); | ||
270 | |||
271 | GNUNET_CONTAINER_multihashmap_iterate (member->sessions, iterate_sync_session_contact, NULL); | ||
272 | } | ||
273 | |||
274 | struct GNUNET_MESSENGER_MemberSession* | ||
275 | get_member_session (const struct GNUNET_MESSENGER_Member *member, | ||
276 | const struct GNUNET_IDENTITY_PublicKey *public_key) | ||
277 | { | ||
278 | GNUNET_assert ((member) && (public_key)); | ||
279 | |||
280 | struct GNUNET_HashCode hash; | ||
281 | GNUNET_CRYPTO_hash(public_key, sizeof(*public_key), &hash); | ||
282 | |||
283 | return GNUNET_CONTAINER_multihashmap_get(member->sessions, &hash); | ||
284 | } | ||
285 | |||
286 | struct GNUNET_MESSENGER_ClosureSearchSession { | ||
287 | const struct GNUNET_MESSENGER_Message *message; | ||
288 | const struct GNUNET_HashCode *hash; | ||
289 | |||
290 | struct GNUNET_MESSENGER_MemberSession *match; | ||
291 | }; | ||
292 | |||
293 | static int | ||
294 | iterate_search_session (void *cls, | ||
295 | const struct GNUNET_HashCode *key, | ||
296 | void *value) | ||
297 | { | ||
298 | struct GNUNET_MESSENGER_ClosureSearchSession* search = cls; | ||
299 | struct GNUNET_MESSENGER_MemberSession *session = value; | ||
300 | |||
301 | if (GNUNET_OK != verify_member_session_as_sender(session, search->message, search->hash)) | ||
302 | return GNUNET_YES; | ||
303 | |||
304 | search->match = session; | ||
305 | return GNUNET_NO; | ||
306 | } | ||
307 | |||
308 | static struct GNUNET_MESSENGER_MemberSession* | ||
309 | try_member_session (struct GNUNET_MESSENGER_Member *member, | ||
310 | const struct GNUNET_IDENTITY_PublicKey *public_key) | ||
311 | { | ||
312 | struct GNUNET_MESSENGER_MemberSession* session = get_member_session(member, public_key); | ||
313 | |||
314 | if (session) | ||
315 | return session; | ||
316 | |||
317 | session = create_member_session(member, public_key); | ||
318 | |||
319 | if (session) | ||
320 | add_member_session(member, session); | ||
321 | |||
322 | return session; | ||
323 | } | ||
324 | |||
325 | struct GNUNET_MESSENGER_MemberSession* | ||
326 | get_member_session_of (struct GNUNET_MESSENGER_Member *member, | ||
327 | const struct GNUNET_MESSENGER_Message *message, | ||
328 | const struct GNUNET_HashCode *hash) | ||
329 | { | ||
330 | GNUNET_assert ((member) && (message) && (hash) && | ||
331 | (0 == GNUNET_memcmp(&(member->id), &(message->header.sender_id)))); | ||
332 | |||
333 | if (GNUNET_MESSENGER_KIND_INFO == message->header.kind) | ||
334 | return try_member_session(member, &(message->body.info.host_key)); | ||
335 | else if (GNUNET_MESSENGER_KIND_JOIN == message->header.kind) | ||
336 | return try_member_session(member, &(message->body.join.key)); | ||
337 | |||
338 | struct GNUNET_MESSENGER_ClosureSearchSession search; | ||
339 | |||
340 | search.message = message; | ||
341 | search.hash = hash; | ||
342 | |||
343 | search.match = NULL; | ||
344 | GNUNET_CONTAINER_multihashmap_iterate(member->sessions, iterate_search_session, &search); | ||
345 | |||
346 | return search.match; | ||
347 | } | ||
348 | |||
349 | void | ||
350 | add_member_session (struct GNUNET_MESSENGER_Member *member, | ||
351 | struct GNUNET_MESSENGER_MemberSession *session) | ||
352 | { | ||
353 | if (!session) | ||
354 | return; | ||
355 | |||
356 | GNUNET_assert((member) && (session->member == member)); | ||
357 | |||
358 | const struct GNUNET_IDENTITY_PublicKey *public_key = get_member_session_public_key(session); | ||
359 | |||
360 | struct GNUNET_HashCode hash; | ||
361 | GNUNET_CRYPTO_hash(public_key, sizeof(*public_key), &hash); | ||
362 | |||
363 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( | ||
364 | member->sessions, &hash, session, | ||
365 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
366 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Adding a member session failed: %s\n", | ||
367 | GNUNET_h2s(&hash)); | ||
368 | } | ||
369 | |||
370 | void | ||
371 | remove_member_session (struct GNUNET_MESSENGER_Member *member, | ||
372 | struct GNUNET_MESSENGER_MemberSession *session) | ||
373 | { | ||
374 | GNUNET_assert ((member) && (session) && (session->member == member)); | ||
375 | |||
376 | const struct GNUNET_IDENTITY_PublicKey *public_key = get_member_session_public_key(session); | ||
377 | |||
378 | struct GNUNET_HashCode hash; | ||
379 | GNUNET_CRYPTO_hash(public_key, sizeof(*public_key), &hash); | ||
380 | |||
381 | if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove(member->sessions, &hash, session)) | ||
382 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Removing a member session failed: %s\n", | ||
383 | GNUNET_h2s(&hash)); | ||
384 | } | ||
385 | |||
386 | struct GNUNET_MESSENGER_ClosureIterateSessions { | ||
387 | GNUNET_MESSENGER_MemberIteratorCallback it; | ||
388 | void *cls; | ||
389 | }; | ||
390 | |||
391 | static int | ||
392 | iterate_member_sessions_it (void *cls, | ||
393 | const struct GNUNET_HashCode *key, | ||
394 | void *value) | ||
395 | { | ||
396 | struct GNUNET_MESSENGER_ClosureIterateSessions *iterate = cls; | ||
397 | struct GNUNET_MESSENGER_MemberSession *session = value; | ||
398 | |||
399 | return iterate->it (iterate->cls, get_member_session_public_key(session), session); | ||
400 | } | ||
401 | |||
402 | int | ||
403 | iterate_member_sessions (struct GNUNET_MESSENGER_Member *member, | ||
404 | GNUNET_MESSENGER_MemberIteratorCallback it, | ||
405 | void *cls) | ||
406 | { | ||
407 | GNUNET_assert ((member) && (member->sessions) && (it)); | ||
408 | |||
409 | struct GNUNET_MESSENGER_ClosureIterateSessions iterate; | ||
410 | |||
411 | iterate.it = it; | ||
412 | iterate.cls = cls; | ||
413 | |||
414 | return GNUNET_CONTAINER_multihashmap_iterate(member->sessions, iterate_member_sessions_it, &iterate); | ||
415 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_member.h b/src/messenger/gnunet-service-messenger_member.h deleted file mode 100644 index 46269315a..000000000 --- a/src/messenger/gnunet-service-messenger_member.h +++ /dev/null | |||
@@ -1,180 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_member.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_MEMBER_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_MEMBER_H | ||
28 | |||
29 | #include "messenger_api_contact.h" | ||
30 | |||
31 | #include "gnunet-service-messenger_list_messages.h" | ||
32 | #include "gnunet-service-messenger_member_store.h" | ||
33 | #include "messenger_api_message.h" | ||
34 | #include "messenger_api_util.h" | ||
35 | |||
36 | struct GNUNET_MESSENGER_Member | ||
37 | { | ||
38 | struct GNUNET_MESSENGER_MemberStore *store; | ||
39 | struct GNUNET_ShortHashCode id; | ||
40 | |||
41 | struct GNUNET_CONTAINER_MultiHashMap *sessions; | ||
42 | }; | ||
43 | |||
44 | /** | ||
45 | * Creates and allocates a new member of a <i>room</i> with an optionally defined or | ||
46 | * random <i>id</i>. | ||
47 | * | ||
48 | * If the creation fails, NULL gets returned. | ||
49 | * | ||
50 | * @param[in/out] store Member store | ||
51 | * @param[in] id Member id or NULL | ||
52 | * @return New member or NULL | ||
53 | */ | ||
54 | struct GNUNET_MESSENGER_Member* | ||
55 | create_member (struct GNUNET_MESSENGER_MemberStore *store, | ||
56 | const struct GNUNET_ShortHashCode *id); | ||
57 | |||
58 | /** | ||
59 | * Destroys a member and frees its memory fully. | ||
60 | * | ||
61 | * @param[in/out] member Member | ||
62 | */ | ||
63 | void | ||
64 | destroy_member (struct GNUNET_MESSENGER_Member *member); | ||
65 | |||
66 | /** | ||
67 | * Returns the current id of a given <i>member</i>. | ||
68 | * | ||
69 | * @param[in] member Member | ||
70 | * @return Member id | ||
71 | */ | ||
72 | const struct GNUNET_ShortHashCode* | ||
73 | get_member_id (const struct GNUNET_MESSENGER_Member *member); | ||
74 | |||
75 | /** | ||
76 | * Loads data from a <i>directory</i> into a new allocated and created member | ||
77 | * of a <i>store</i> if the required information can be read from the content | ||
78 | * of the given directory. | ||
79 | * | ||
80 | * @param[out] store Member store | ||
81 | * @param[in] directory Path to a directory | ||
82 | */ | ||
83 | void | ||
84 | load_member (struct GNUNET_MESSENGER_MemberStore *store, | ||
85 | const char *directory); | ||
86 | |||
87 | /** | ||
88 | * Loads data about next sessions from a <i>directory</i> into an empty loaded | ||
89 | * <i>member</i> which does not contain a fully built session graph yet. | ||
90 | * | ||
91 | * @param[in/out] member Member | ||
92 | * @param[in] directory Path to a directory | ||
93 | */ | ||
94 | void | ||
95 | load_member_next_sessions (const struct GNUNET_MESSENGER_Member *member, | ||
96 | const char *directory); | ||
97 | |||
98 | /** | ||
99 | * Saves data from a <i>member</i> into a directory which | ||
100 | * can be load to restore the member completely. | ||
101 | * | ||
102 | * @param[in] member Member | ||
103 | * @param[in] directory Path to a directory | ||
104 | */ | ||
105 | void | ||
106 | save_member (struct GNUNET_MESSENGER_Member *member, | ||
107 | const char *directory); | ||
108 | |||
109 | /** | ||
110 | * Synchronizes contacts between all sessions from a given <i>member</i> | ||
111 | * and other sessions which are linked to them. | ||
112 | * | ||
113 | * @param[in/out] member Member | ||
114 | */ | ||
115 | void | ||
116 | sync_member_contacts (struct GNUNET_MESSENGER_Member *member); | ||
117 | |||
118 | /** | ||
119 | * Returns the member session of a <i>member</i> identified by a given public key. | ||
120 | * If the member does not provide a session with the given key, NULL gets returned. | ||
121 | * | ||
122 | * @param[in] member Member | ||
123 | * @param[in] public_key Public key of EGO | ||
124 | * @return Member session | ||
125 | */ | ||
126 | struct GNUNET_MESSENGER_MemberSession* | ||
127 | get_member_session (const struct GNUNET_MESSENGER_Member *member, | ||
128 | const struct GNUNET_IDENTITY_PublicKey *public_key); | ||
129 | |||
130 | /** | ||
131 | * Returns the member session of a <i>member</i> using a public key which can verify | ||
132 | * the signature of a given <i>message</i> and its <i>hash</i>. If the member does | ||
133 | * not provide a matching session, NULL gets returned. | ||
134 | * | ||
135 | * @param[in] member Member | ||
136 | * @param[in] message Message | ||
137 | * @param[in] hash Hash of message | ||
138 | * @return Member session | ||
139 | */ | ||
140 | struct GNUNET_MESSENGER_MemberSession* | ||
141 | get_member_session_of (struct GNUNET_MESSENGER_Member *member, | ||
142 | const struct GNUNET_MESSENGER_Message *message, | ||
143 | const struct GNUNET_HashCode *hash); | ||
144 | |||
145 | /** | ||
146 | * Adds a given member <i>session</i> to its <i>member</i>. | ||
147 | * | ||
148 | * @param[in/out] member Member | ||
149 | * @param[in/out] session Member session | ||
150 | */ | ||
151 | void | ||
152 | add_member_session (struct GNUNET_MESSENGER_Member *member, | ||
153 | struct GNUNET_MESSENGER_MemberSession *session); | ||
154 | |||
155 | /** | ||
156 | * Removes a given member <i>session</i> from its <i>member</i>. | ||
157 | * | ||
158 | * @param[in/out] member Member | ||
159 | * @param[in/out] session Member session | ||
160 | */ | ||
161 | void | ||
162 | remove_member_session (struct GNUNET_MESSENGER_Member *member, | ||
163 | struct GNUNET_MESSENGER_MemberSession *session); | ||
164 | |||
165 | /** | ||
166 | * Iterate through all member sessions currently connected to a given <i>member</i> | ||
167 | * and call the provided iterator callback with a selected closure. The function | ||
168 | * will return the amount of member sessions it iterated through. | ||
169 | * | ||
170 | * @param[in/out] member Member | ||
171 | * @param[in] it Iterator callback | ||
172 | * @param[in/out] cls Closure | ||
173 | * @return Amount of sessions iterated through | ||
174 | */ | ||
175 | int | ||
176 | iterate_member_sessions (struct GNUNET_MESSENGER_Member *member, | ||
177 | GNUNET_MESSENGER_MemberIteratorCallback it, | ||
178 | void* cls); | ||
179 | |||
180 | #endif //GNUNET_SERVICE_MESSENGER_MEMBER_H | ||
diff --git a/src/messenger/gnunet-service-messenger_member_session.c b/src/messenger/gnunet-service-messenger_member_session.c deleted file mode 100644 index 846dbbe2b..000000000 --- a/src/messenger/gnunet-service-messenger_member_session.c +++ /dev/null | |||
@@ -1,759 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_member_session.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_member_session.h" | ||
27 | |||
28 | #include "gnunet-service-messenger_room.h" | ||
29 | #include "gnunet-service-messenger_message_store.h" | ||
30 | |||
31 | #include "messenger_api_contact_store.h" | ||
32 | |||
33 | struct GNUNET_MESSENGER_MemberSession* | ||
34 | create_member_session (struct GNUNET_MESSENGER_Member *member, | ||
35 | const struct GNUNET_IDENTITY_PublicKey *pubkey) | ||
36 | { | ||
37 | if ((!member) || (!pubkey) || (!(member->store))) | ||
38 | return NULL; | ||
39 | |||
40 | struct GNUNET_MESSENGER_MemberSession *session = GNUNET_new(struct GNUNET_MESSENGER_MemberSession); | ||
41 | session->member = member; | ||
42 | |||
43 | GNUNET_memcpy(&(session->public_key), pubkey, sizeof(session->public_key)); | ||
44 | |||
45 | get_context_from_member ( | ||
46 | get_member_session_key (session), | ||
47 | get_member_session_id (session), | ||
48 | &(session->context) | ||
49 | ); | ||
50 | |||
51 | struct GNUNET_MESSENGER_ContactStore *store = get_member_contact_store(session->member->store); | ||
52 | |||
53 | session->contact = get_store_contact( | ||
54 | store, | ||
55 | get_member_session_context (session), | ||
56 | get_member_session_public_key (session) | ||
57 | ); | ||
58 | |||
59 | if (!(session->contact)) | ||
60 | { | ||
61 | GNUNET_free(session); | ||
62 | return NULL; | ||
63 | } | ||
64 | |||
65 | increase_contact_rc (session->contact); | ||
66 | |||
67 | session->history = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | ||
68 | |||
69 | init_list_messages(&(session->messages)); | ||
70 | |||
71 | session->prev = NULL; | ||
72 | session->next = NULL; | ||
73 | |||
74 | session->start = GNUNET_TIME_absolute_get(); | ||
75 | |||
76 | session->closed = GNUNET_NO; | ||
77 | session->completed = GNUNET_NO; | ||
78 | |||
79 | return session; | ||
80 | } | ||
81 | |||
82 | static void | ||
83 | check_member_session_completion (struct GNUNET_MESSENGER_MemberSession *session) | ||
84 | { | ||
85 | GNUNET_assert (session); | ||
86 | |||
87 | if (!session->messages.tail) | ||
88 | { | ||
89 | session->completed = GNUNET_YES; | ||
90 | goto completion; | ||
91 | } | ||
92 | |||
93 | const struct GNUNET_HashCode* start = &(session->messages.head->hash); | ||
94 | const struct GNUNET_HashCode* end = &(session->messages.tail->hash); | ||
95 | |||
96 | struct GNUNET_MESSENGER_ListMessages level; | ||
97 | init_list_messages(&level); | ||
98 | |||
99 | add_to_list_messages(&level, end); | ||
100 | |||
101 | struct GNUNET_MESSENGER_MessageStore *store = get_room_message_store(session->member->store->room); | ||
102 | |||
103 | struct GNUNET_MESSENGER_ListMessages list; | ||
104 | init_list_messages(&list); | ||
105 | |||
106 | while (level.head) | ||
107 | { | ||
108 | struct GNUNET_MESSENGER_ListMessage *element; | ||
109 | |||
110 | for (element = level.head; element; element = element->next) | ||
111 | { | ||
112 | const struct GNUNET_MESSENGER_MessageLink *link = get_store_message_link( | ||
113 | store, &(element->hash), GNUNET_NO | ||
114 | ); | ||
115 | |||
116 | if (!link) | ||
117 | continue; | ||
118 | |||
119 | add_to_list_messages(&list, &(link->first)); | ||
120 | |||
121 | if (GNUNET_YES == link->multiple) | ||
122 | add_to_list_messages(&list, &(link->second)); | ||
123 | } | ||
124 | |||
125 | clear_list_messages(&level); | ||
126 | |||
127 | for (element = list.head; element; element = element->next) | ||
128 | if (GNUNET_YES == check_member_session_history(session, &(element->hash), GNUNET_YES)) | ||
129 | break; | ||
130 | |||
131 | if (element) | ||
132 | if (0 != GNUNET_CRYPTO_hash_cmp(&(element->hash), start)) | ||
133 | add_to_list_messages(&level, &(element->hash)); | ||
134 | else | ||
135 | session->completed = GNUNET_YES; | ||
136 | else | ||
137 | copy_list_messages(&level, &list); | ||
138 | |||
139 | clear_list_messages(&list); | ||
140 | } | ||
141 | |||
142 | completion: | ||
143 | if (GNUNET_YES == is_member_session_completed(session)) | ||
144 | { | ||
145 | GNUNET_CONTAINER_multihashmap_destroy (session->history); | ||
146 | |||
147 | struct GNUNET_MESSENGER_ContactStore *store = get_member_contact_store(session->member->store); | ||
148 | |||
149 | if ((session->contact) && (GNUNET_YES == decrease_contact_rc (session->contact))) | ||
150 | remove_store_contact ( | ||
151 | store, | ||
152 | session->contact, | ||
153 | get_member_session_context(session) | ||
154 | ); | ||
155 | |||
156 | session->contact = NULL; | ||
157 | } | ||
158 | } | ||
159 | |||
160 | static int | ||
161 | iterate_copy_history (void *cls, | ||
162 | const struct GNUNET_HashCode *key, | ||
163 | void *value) | ||
164 | { | ||
165 | struct GNUNET_MESSENGER_MemberSession *next = cls; | ||
166 | |||
167 | GNUNET_CONTAINER_multihashmap_put(next->history, key, (value? next : NULL), | ||
168 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
169 | |||
170 | return GNUNET_YES; | ||
171 | } | ||
172 | |||
173 | struct GNUNET_MESSENGER_MemberSession* | ||
174 | switch_member_session (struct GNUNET_MESSENGER_MemberSession *session, | ||
175 | const struct GNUNET_MESSENGER_Message *message, | ||
176 | const struct GNUNET_HashCode *hash) | ||
177 | { | ||
178 | if ((!session) || (!message) || (!hash)) | ||
179 | return NULL; | ||
180 | |||
181 | GNUNET_assert((GNUNET_MESSENGER_KIND_ID == message->header.kind) || | ||
182 | (GNUNET_MESSENGER_KIND_KEY == message->header.kind)); | ||
183 | |||
184 | struct GNUNET_MESSENGER_MemberSession *next = GNUNET_new(struct GNUNET_MESSENGER_MemberSession); | ||
185 | |||
186 | if (GNUNET_MESSENGER_KIND_ID == message->header.kind) | ||
187 | next->member = add_store_member(session->member->store, &(message->body.id.id)); | ||
188 | else | ||
189 | next->member = session->member; | ||
190 | |||
191 | if (GNUNET_MESSENGER_KIND_KEY == message->header.kind) | ||
192 | GNUNET_memcpy(&(next->public_key), &(message->body.key.key), sizeof(next->public_key)); | ||
193 | else | ||
194 | GNUNET_memcpy(&(next->public_key), get_member_session_public_key(session), sizeof(next->public_key)); | ||
195 | |||
196 | get_context_from_member ( | ||
197 | get_member_session_key (next), | ||
198 | get_member_session_id (next), | ||
199 | &(next->context) | ||
200 | ); | ||
201 | |||
202 | update_store_contact( | ||
203 | get_member_contact_store(next->member->store), | ||
204 | get_member_session_contact(session), | ||
205 | get_member_session_context(session), | ||
206 | get_member_session_context(next), | ||
207 | get_member_session_public_key(next) | ||
208 | ); | ||
209 | |||
210 | next->contact = get_member_session_contact(session); | ||
211 | |||
212 | if (!(next->contact)) | ||
213 | { | ||
214 | GNUNET_free(next); | ||
215 | return NULL; | ||
216 | } | ||
217 | |||
218 | increase_contact_rc (next->contact); | ||
219 | |||
220 | next->history = GNUNET_CONTAINER_multihashmap_create( | ||
221 | GNUNET_CONTAINER_multihashmap_size(session->history), GNUNET_NO | ||
222 | ); | ||
223 | |||
224 | GNUNET_CONTAINER_multihashmap_iterate(session->history, iterate_copy_history, next); | ||
225 | |||
226 | init_list_messages(&(next->messages)); | ||
227 | copy_list_messages(&(next->messages), &(session->messages)); | ||
228 | |||
229 | session->next = next; | ||
230 | next->prev = session; | ||
231 | next->next = NULL; | ||
232 | |||
233 | next->start = GNUNET_TIME_absolute_get(); | ||
234 | |||
235 | session->closed = GNUNET_YES; | ||
236 | next->closed = GNUNET_NO; | ||
237 | next->completed = GNUNET_NO; | ||
238 | |||
239 | check_member_session_completion (session); | ||
240 | |||
241 | return next; | ||
242 | } | ||
243 | |||
244 | void | ||
245 | destroy_member_session(struct GNUNET_MESSENGER_MemberSession* session) | ||
246 | { | ||
247 | GNUNET_assert (session); | ||
248 | |||
249 | GNUNET_CONTAINER_multihashmap_destroy (session->history); | ||
250 | |||
251 | clear_list_messages (&(session->messages)); | ||
252 | |||
253 | struct GNUNET_MESSENGER_Contact *contact = get_member_session_contact (session); | ||
254 | |||
255 | if ((contact) && (GNUNET_YES == decrease_contact_rc (contact))) | ||
256 | remove_store_contact ( | ||
257 | get_member_contact_store(session->member->store), | ||
258 | contact, | ||
259 | get_member_session_context(session) | ||
260 | ); | ||
261 | |||
262 | GNUNET_free(session); | ||
263 | } | ||
264 | |||
265 | int | ||
266 | reset_member_session (struct GNUNET_MESSENGER_MemberSession* session, | ||
267 | const struct GNUNET_HashCode *hash) | ||
268 | { | ||
269 | GNUNET_assert ((session) && (hash)); | ||
270 | |||
271 | struct GNUNET_MESSENGER_ContactStore *store = get_member_contact_store(session->member->store); | ||
272 | struct GNUNET_MESSENGER_Contact *contact = get_store_contact( | ||
273 | store, | ||
274 | get_member_session_context (session), | ||
275 | get_member_session_public_key (session) | ||
276 | ); | ||
277 | |||
278 | if (!contact) | ||
279 | return GNUNET_SYSERR; | ||
280 | |||
281 | if (contact == session->contact) | ||
282 | goto clear_messages; | ||
283 | |||
284 | session->contact = contact; | ||
285 | increase_contact_rc (session->contact); | ||
286 | |||
287 | clear_messages: | ||
288 | clear_list_messages(&(session->messages)); | ||
289 | add_to_list_messages(&(session->messages), hash); | ||
290 | |||
291 | session->next = NULL; | ||
292 | session->closed = GNUNET_NO; | ||
293 | session->completed = GNUNET_NO; | ||
294 | |||
295 | return GNUNET_OK; | ||
296 | } | ||
297 | |||
298 | void | ||
299 | close_member_session (struct GNUNET_MESSENGER_MemberSession* session) | ||
300 | { | ||
301 | GNUNET_assert (session); | ||
302 | |||
303 | session->closed = GNUNET_YES; | ||
304 | check_member_session_completion (session); | ||
305 | } | ||
306 | |||
307 | int | ||
308 | is_member_session_closed (const struct GNUNET_MESSENGER_MemberSession* session) | ||
309 | { | ||
310 | GNUNET_assert(session); | ||
311 | |||
312 | return session->closed; | ||
313 | } | ||
314 | |||
315 | int | ||
316 | is_member_session_completed (const struct GNUNET_MESSENGER_MemberSession* session) | ||
317 | { | ||
318 | GNUNET_assert(session); | ||
319 | |||
320 | return session->completed; | ||
321 | } | ||
322 | |||
323 | struct GNUNET_TIME_Absolute | ||
324 | get_member_session_start (const struct GNUNET_MESSENGER_MemberSession* session) | ||
325 | { | ||
326 | GNUNET_assert(session); | ||
327 | |||
328 | if (session->prev) | ||
329 | return get_member_session_start(session->prev); | ||
330 | |||
331 | return session->start; | ||
332 | } | ||
333 | |||
334 | const struct GNUNET_HashCode* | ||
335 | get_member_session_key (const struct GNUNET_MESSENGER_MemberSession* session) | ||
336 | { | ||
337 | GNUNET_assert((session) && (session->member)); | ||
338 | |||
339 | return get_member_store_key(session->member->store); | ||
340 | } | ||
341 | |||
342 | const struct GNUNET_ShortHashCode* | ||
343 | get_member_session_id (const struct GNUNET_MESSENGER_MemberSession* session) | ||
344 | { | ||
345 | GNUNET_assert(session); | ||
346 | |||
347 | return get_member_id(session->member); | ||
348 | } | ||
349 | |||
350 | const struct GNUNET_IDENTITY_PublicKey* | ||
351 | get_member_session_public_key (const struct GNUNET_MESSENGER_MemberSession* session) | ||
352 | { | ||
353 | GNUNET_assert(session); | ||
354 | |||
355 | return &(session->public_key); | ||
356 | } | ||
357 | |||
358 | const struct GNUNET_HashCode* | ||
359 | get_member_session_context (const struct GNUNET_MESSENGER_MemberSession* session) | ||
360 | { | ||
361 | GNUNET_assert(session); | ||
362 | |||
363 | return &(session->context); | ||
364 | } | ||
365 | |||
366 | struct GNUNET_MESSENGER_Contact* | ||
367 | get_member_session_contact (struct GNUNET_MESSENGER_MemberSession* session) | ||
368 | { | ||
369 | GNUNET_assert (session); | ||
370 | |||
371 | return session->contact; | ||
372 | } | ||
373 | |||
374 | int verify_member_session_as_sender (const struct GNUNET_MESSENGER_MemberSession *session, | ||
375 | const struct GNUNET_MESSENGER_Message *message, | ||
376 | const struct GNUNET_HashCode *hash) | ||
377 | { | ||
378 | GNUNET_assert((session) && (message) && (hash)); | ||
379 | |||
380 | if (GNUNET_YES == is_member_session_completed(session)) | ||
381 | return GNUNET_SYSERR; | ||
382 | |||
383 | if (0 != GNUNET_memcmp(get_member_session_id(session), &(message->header.sender_id))) | ||
384 | return GNUNET_SYSERR; | ||
385 | |||
386 | return verify_message(message, hash, get_member_session_public_key(session)); | ||
387 | } | ||
388 | |||
389 | int | ||
390 | check_member_session_history (const struct GNUNET_MESSENGER_MemberSession *session, | ||
391 | const struct GNUNET_HashCode *hash, int ownership) | ||
392 | { | ||
393 | GNUNET_assert((session) && (hash)); | ||
394 | |||
395 | if (GNUNET_YES == ownership) | ||
396 | return (NULL != GNUNET_CONTAINER_multihashmap_get(session->history, hash)? GNUNET_YES : GNUNET_NO); | ||
397 | else | ||
398 | return GNUNET_CONTAINER_multihashmap_contains(session->history, hash); | ||
399 | } | ||
400 | |||
401 | static void | ||
402 | update_member_chain_history (struct GNUNET_MESSENGER_MemberSession *session, | ||
403 | const struct GNUNET_HashCode *hash, int ownership) | ||
404 | { | ||
405 | GNUNET_assert ((session) && (hash)); | ||
406 | |||
407 | if ((GNUNET_OK == GNUNET_CONTAINER_multihashmap_put(session->history, hash, (GNUNET_YES == ownership? session : NULL), | ||
408 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) && (session->next)) | ||
409 | update_member_chain_history (session->next, hash, ownership); | ||
410 | } | ||
411 | |||
412 | void | ||
413 | update_member_session_history (struct GNUNET_MESSENGER_MemberSession *session, | ||
414 | const struct GNUNET_MESSENGER_Message *message, | ||
415 | const struct GNUNET_HashCode *hash) | ||
416 | { | ||
417 | GNUNET_assert((session) && (message) && (hash)); | ||
418 | |||
419 | if (GNUNET_YES == is_member_session_completed(session)) | ||
420 | return; | ||
421 | |||
422 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Updating sessions history (%s) += (%s)\n", | ||
423 | GNUNET_sh2s(get_member_session_id(session)), GNUNET_h2s(hash)); | ||
424 | |||
425 | if (GNUNET_OK == verify_member_session_as_sender (session, message, hash)) | ||
426 | { | ||
427 | if (GNUNET_YES == is_message_session_bound (message)) | ||
428 | add_to_list_messages(&(session->messages), hash); | ||
429 | |||
430 | update_member_chain_history (session, hash, GNUNET_YES); | ||
431 | } | ||
432 | else | ||
433 | update_member_chain_history (session, hash, GNUNET_NO); | ||
434 | |||
435 | if (GNUNET_YES == session->closed) | ||
436 | check_member_session_completion(session); | ||
437 | } | ||
438 | |||
439 | static void | ||
440 | clear_member_chain_history (struct GNUNET_MESSENGER_MemberSession *session, | ||
441 | const struct GNUNET_HashCode *hash) | ||
442 | { | ||
443 | GNUNET_assert ((session) && (hash)); | ||
444 | |||
445 | if ((0 < GNUNET_CONTAINER_multihashmap_remove_all(session->history, hash)) && (session->next)) | ||
446 | clear_member_session_history(session->next, hash); | ||
447 | } | ||
448 | |||
449 | void | ||
450 | clear_member_session_history (struct GNUNET_MESSENGER_MemberSession *session, | ||
451 | const struct GNUNET_HashCode *hash) | ||
452 | { | ||
453 | GNUNET_assert((session) && (hash)); | ||
454 | |||
455 | clear_member_chain_history (session, hash); | ||
456 | } | ||
457 | |||
458 | struct GNUNET_MESSENGER_MemberSessionHistoryEntry | ||
459 | { | ||
460 | struct GNUNET_HashCode hash; | ||
461 | unsigned char ownership; | ||
462 | }; | ||
463 | |||
464 | static void | ||
465 | load_member_session_history (struct GNUNET_MESSENGER_MemberSession *session, | ||
466 | const char *path) | ||
467 | { | ||
468 | GNUNET_assert((session) && (path)); | ||
469 | |||
470 | if (GNUNET_YES != GNUNET_DISK_file_test (path)) | ||
471 | return; | ||
472 | |||
473 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); | ||
474 | |||
475 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open( | ||
476 | path, GNUNET_DISK_OPEN_READ, permission | ||
477 | ); | ||
478 | |||
479 | if (!handle) | ||
480 | return; | ||
481 | |||
482 | GNUNET_DISK_file_seek(handle, 0, GNUNET_DISK_SEEK_SET); | ||
483 | |||
484 | struct GNUNET_MESSENGER_MemberSessionHistoryEntry entry; | ||
485 | ssize_t len; | ||
486 | |||
487 | int status; | ||
488 | |||
489 | do { | ||
490 | len = GNUNET_DISK_file_read(handle, &(entry.hash), sizeof(entry.hash)); | ||
491 | |||
492 | if (len != sizeof(entry.hash)) | ||
493 | break; | ||
494 | |||
495 | len = GNUNET_DISK_file_read(handle, &(entry.ownership), sizeof(entry.ownership)); | ||
496 | |||
497 | if (len != sizeof(entry.ownership)) | ||
498 | break; | ||
499 | |||
500 | status = GNUNET_CONTAINER_multihashmap_put(session->history, &(entry.hash), (entry.ownership? session : NULL), | ||
501 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
502 | } while (status == GNUNET_OK); | ||
503 | |||
504 | GNUNET_DISK_file_close(handle); | ||
505 | } | ||
506 | |||
507 | void | ||
508 | load_member_session (struct GNUNET_MESSENGER_Member *member, | ||
509 | const char *directory) | ||
510 | { | ||
511 | GNUNET_assert ((member) && (directory)); | ||
512 | |||
513 | char *config_file; | ||
514 | GNUNET_asprintf (&config_file, "%s%s", directory, "session.cfg"); | ||
515 | |||
516 | struct GNUNET_MESSENGER_MemberSession *session = NULL; | ||
517 | |||
518 | if (GNUNET_YES != GNUNET_DISK_file_test (config_file)) | ||
519 | goto free_config; | ||
520 | |||
521 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Load session configuration of member: %s\n", config_file); | ||
522 | |||
523 | struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create (); | ||
524 | |||
525 | if (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, config_file)) | ||
526 | { | ||
527 | char *key_data; | ||
528 | |||
529 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "session", "key", &key_data)) | ||
530 | goto destroy_config; | ||
531 | |||
532 | struct GNUNET_IDENTITY_PublicKey key; | ||
533 | |||
534 | enum GNUNET_GenericReturnValue key_return = GNUNET_IDENTITY_public_key_from_string(key_data, &key); | ||
535 | |||
536 | GNUNET_free(key_data); | ||
537 | |||
538 | if (GNUNET_OK != key_return) | ||
539 | goto destroy_config; | ||
540 | |||
541 | session = create_member_session(member, &key); | ||
542 | |||
543 | unsigned long long numeric_value; | ||
544 | |||
545 | if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg, "session", "start", &numeric_value)) | ||
546 | session->start.abs_value_us = numeric_value; | ||
547 | |||
548 | if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg, "session", "closed", &numeric_value)) | ||
549 | session->closed = (GNUNET_YES == numeric_value? GNUNET_YES : GNUNET_NO); | ||
550 | |||
551 | if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg, "session", "completed", &numeric_value)) | ||
552 | session->completed = (GNUNET_YES == numeric_value? GNUNET_YES : GNUNET_NO); | ||
553 | } | ||
554 | |||
555 | destroy_config: | ||
556 | GNUNET_CONFIGURATION_destroy (cfg); | ||
557 | |||
558 | free_config: | ||
559 | GNUNET_free(config_file); | ||
560 | |||
561 | if (!session) | ||
562 | return; | ||
563 | |||
564 | char *history_file; | ||
565 | GNUNET_asprintf (&history_file, "%s%s", directory, "history.map"); | ||
566 | |||
567 | load_member_session_history (session, history_file); | ||
568 | GNUNET_free(history_file); | ||
569 | |||
570 | char *messages_file; | ||
571 | GNUNET_asprintf (&messages_file, "%s%s", directory, "messages.list"); | ||
572 | |||
573 | load_list_messages(&(session->messages), messages_file); | ||
574 | GNUNET_free(messages_file); | ||
575 | |||
576 | add_member_session(member, session); | ||
577 | } | ||
578 | |||
579 | static struct GNUNET_MESSENGER_MemberSession* | ||
580 | get_cycle_safe_next_session (struct GNUNET_MESSENGER_MemberSession *session, | ||
581 | struct GNUNET_MESSENGER_MemberSession *next) | ||
582 | { | ||
583 | if (!next) | ||
584 | return NULL; | ||
585 | |||
586 | struct GNUNET_MESSENGER_MemberSession *check = next; | ||
587 | |||
588 | do { | ||
589 | if (check == session) | ||
590 | return NULL; | ||
591 | |||
592 | check = check->next; | ||
593 | } while (check); | ||
594 | |||
595 | return next; | ||
596 | } | ||
597 | |||
598 | void | ||
599 | load_member_session_next (struct GNUNET_MESSENGER_MemberSession *session, | ||
600 | const char *directory) | ||
601 | { | ||
602 | GNUNET_assert ((session) && (directory)); | ||
603 | |||
604 | char *config_file; | ||
605 | GNUNET_asprintf (&config_file, "%s%s", directory, "session.cfg"); | ||
606 | |||
607 | if (GNUNET_YES != GNUNET_DISK_file_test (config_file)) | ||
608 | goto free_config; | ||
609 | |||
610 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Load next session configuration of member: %s\n", config_file); | ||
611 | |||
612 | struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create (); | ||
613 | |||
614 | if (GNUNET_OK == GNUNET_CONFIGURATION_parse (cfg, config_file)) | ||
615 | { | ||
616 | char *key_data; | ||
617 | |||
618 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "session", "next_key", &key_data)) | ||
619 | goto destroy_config; | ||
620 | |||
621 | struct GNUNET_IDENTITY_PublicKey next_key; | ||
622 | |||
623 | enum GNUNET_GenericReturnValue key_return = GNUNET_IDENTITY_public_key_from_string(key_data, &next_key); | ||
624 | |||
625 | GNUNET_free(key_data); | ||
626 | |||
627 | if (GNUNET_OK != key_return) | ||
628 | goto destroy_config; | ||
629 | |||
630 | struct GNUNET_ShortHashCode next_id; | ||
631 | |||
632 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_data (cfg, "session", "next_id", &next_id, sizeof(next_id))) | ||
633 | goto destroy_config; | ||
634 | |||
635 | struct GNUNET_MESSENGER_Member *member = get_store_member(session->member->store, &next_id); | ||
636 | |||
637 | session->next = get_cycle_safe_next_session( | ||
638 | session, member? get_member_session (member, &next_key) : NULL | ||
639 | ); | ||
640 | |||
641 | if (session->next) | ||
642 | session->next->prev = session; | ||
643 | } | ||
644 | |||
645 | destroy_config: | ||
646 | GNUNET_CONFIGURATION_destroy (cfg); | ||
647 | |||
648 | free_config: | ||
649 | GNUNET_free(config_file); | ||
650 | } | ||
651 | |||
652 | static int | ||
653 | iterate_save_member_session_history_hentries (void *cls, | ||
654 | const struct GNUNET_HashCode *key, | ||
655 | void *value) | ||
656 | { | ||
657 | struct GNUNET_DISK_FileHandle *handle = cls; | ||
658 | unsigned char ownership = value? GNUNET_YES : GNUNET_NO; | ||
659 | |||
660 | GNUNET_DISK_file_write(handle, key, sizeof(*key)); | ||
661 | GNUNET_DISK_file_write(handle, &ownership, sizeof(ownership)); | ||
662 | |||
663 | return GNUNET_YES; | ||
664 | } | ||
665 | |||
666 | static void | ||
667 | save_member_session_history (struct GNUNET_MESSENGER_MemberSession *session, | ||
668 | const char *path) | ||
669 | { | ||
670 | GNUNET_assert((session) && (path)); | ||
671 | |||
672 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); | ||
673 | |||
674 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open( | ||
675 | path, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, permission | ||
676 | ); | ||
677 | |||
678 | if (!handle) | ||
679 | return; | ||
680 | |||
681 | GNUNET_DISK_file_seek(handle, 0, GNUNET_DISK_SEEK_SET); | ||
682 | |||
683 | GNUNET_CONTAINER_multihashmap_iterate( | ||
684 | session->history, | ||
685 | iterate_save_member_session_history_hentries, | ||
686 | handle | ||
687 | ); | ||
688 | |||
689 | GNUNET_DISK_file_sync(handle); | ||
690 | GNUNET_DISK_file_close(handle); | ||
691 | } | ||
692 | |||
693 | void | ||
694 | save_member_session (struct GNUNET_MESSENGER_MemberSession *session, | ||
695 | const char *directory) | ||
696 | { | ||
697 | GNUNET_assert ((session) && (directory)); | ||
698 | |||
699 | char *config_file; | ||
700 | GNUNET_asprintf (&config_file, "%s%s", directory, "session.cfg"); | ||
701 | |||
702 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Save session configuration of member: %s\n", config_file); | ||
703 | |||
704 | struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create (); | ||
705 | |||
706 | char *key_data = GNUNET_IDENTITY_public_key_to_string(get_member_session_public_key(session)); | ||
707 | |||
708 | if (key_data) | ||
709 | { | ||
710 | GNUNET_CONFIGURATION_set_value_string (cfg, "session", "key", key_data); | ||
711 | |||
712 | GNUNET_free(key_data); | ||
713 | } | ||
714 | |||
715 | if (session->next) | ||
716 | { | ||
717 | const struct GNUNET_ShortHashCode *next_id = get_member_session_id(session->next); | ||
718 | |||
719 | char *next_id_data = GNUNET_STRINGS_data_to_string_alloc (next_id, sizeof(*next_id)); | ||
720 | |||
721 | if (next_id_data) | ||
722 | { | ||
723 | GNUNET_CONFIGURATION_set_value_string (cfg, "session", "next_id", next_id_data); | ||
724 | |||
725 | GNUNET_free(next_id_data); | ||
726 | } | ||
727 | |||
728 | key_data = GNUNET_IDENTITY_public_key_to_string(get_member_session_public_key(session->next)); | ||
729 | |||
730 | if (key_data) | ||
731 | { | ||
732 | GNUNET_CONFIGURATION_set_value_string (cfg, "session", "next_key", key_data); | ||
733 | |||
734 | GNUNET_free(key_data); | ||
735 | } | ||
736 | } | ||
737 | |||
738 | GNUNET_CONFIGURATION_set_value_number(cfg, "session", "start", session->start.abs_value_us); | ||
739 | |||
740 | GNUNET_CONFIGURATION_set_value_number (cfg, "session", "closed", session->closed); | ||
741 | GNUNET_CONFIGURATION_set_value_number (cfg, "session", "completed", session->completed); | ||
742 | |||
743 | GNUNET_CONFIGURATION_write (cfg, config_file); | ||
744 | GNUNET_CONFIGURATION_destroy (cfg); | ||
745 | |||
746 | GNUNET_free(config_file); | ||
747 | |||
748 | char *history_file; | ||
749 | GNUNET_asprintf (&history_file, "%s%s", directory, "history.map"); | ||
750 | |||
751 | save_member_session_history (session, history_file); | ||
752 | GNUNET_free(history_file); | ||
753 | |||
754 | char *messages_file; | ||
755 | GNUNET_asprintf (&messages_file, "%s%s", directory, "messages.list"); | ||
756 | |||
757 | save_list_messages(&(session->messages), messages_file); | ||
758 | GNUNET_free(messages_file); | ||
759 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_member_session.h b/src/messenger/gnunet-service-messenger_member_session.h deleted file mode 100644 index 9ba801776..000000000 --- a/src/messenger/gnunet-service-messenger_member_session.h +++ /dev/null | |||
@@ -1,292 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_member_session.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_MEMBER_SESSION_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_MEMBER_SESSION_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_crypto_lib.h" | ||
31 | #include "gnunet_container_lib.h" | ||
32 | #include "gnunet_identity_service.h" | ||
33 | #include "gnunet_time_lib.h" | ||
34 | |||
35 | #include "gnunet-service-messenger_member.h" | ||
36 | |||
37 | #include "messenger_api_contact.h" | ||
38 | |||
39 | struct GNUNET_MESSENGER_MemberSession { | ||
40 | struct GNUNET_MESSENGER_Member *member; | ||
41 | |||
42 | struct GNUNET_IDENTITY_PublicKey public_key; | ||
43 | struct GNUNET_HashCode context; | ||
44 | |||
45 | struct GNUNET_MESSENGER_Contact *contact; | ||
46 | |||
47 | struct GNUNET_CONTAINER_MultiHashMap *history; | ||
48 | struct GNUNET_MESSENGER_ListMessages messages; | ||
49 | |||
50 | struct GNUNET_MESSENGER_MemberSession* prev; | ||
51 | struct GNUNET_MESSENGER_MemberSession* next; | ||
52 | |||
53 | struct GNUNET_TIME_Absolute start; | ||
54 | |||
55 | int closed; | ||
56 | int completed; | ||
57 | }; | ||
58 | |||
59 | /** | ||
60 | * Creates and allocates a new member session of a <i>member</i> with a given | ||
61 | * public key. | ||
62 | * | ||
63 | * If the creation fails, NULL gets returned. | ||
64 | * | ||
65 | * @param[in/out] member Member | ||
66 | * @param[in] pubkey Public key of EGO | ||
67 | * @return New member session | ||
68 | */ | ||
69 | struct GNUNET_MESSENGER_MemberSession* | ||
70 | create_member_session (struct GNUNET_MESSENGER_Member *member, | ||
71 | const struct GNUNET_IDENTITY_PublicKey *pubkey); | ||
72 | |||
73 | /** | ||
74 | * Creates and allocates a new member session closing and replacing a given | ||
75 | * other <i>session</i> of the same member. The new session could have significant | ||
76 | * changes to the members public key or its member id depending on the used | ||
77 | * <i>message</i> to switch session. The new session will be linked to the old | ||
78 | * one. | ||
79 | * | ||
80 | * @param[in/out] session Old member session | ||
81 | * @param[in] message Message | ||
82 | * @param[in] hash Hash of message | ||
83 | * @return New member session | ||
84 | */ | ||
85 | struct GNUNET_MESSENGER_MemberSession* | ||
86 | switch_member_session (struct GNUNET_MESSENGER_MemberSession *session, | ||
87 | const struct GNUNET_MESSENGER_Message *message, | ||
88 | const struct GNUNET_HashCode *hash); | ||
89 | |||
90 | /** | ||
91 | * Destroys a member session and frees its memory fully. | ||
92 | * | ||
93 | * @param[in/out] session Member session | ||
94 | */ | ||
95 | void | ||
96 | destroy_member_session(struct GNUNET_MESSENGER_MemberSession* session); | ||
97 | |||
98 | /** | ||
99 | * Resets a given member <i>session</i> which re-opens a member | ||
100 | * session for new usage. Every connection to other sessions will be | ||
101 | * be dropped. The member sessions messages will be cleared but old | ||
102 | * history from uncompleted sessions however can be reused! | ||
103 | * | ||
104 | * @param[in/out] session Member session | ||
105 | * @param[in] hash Hash of initial message (JOIN message!) | ||
106 | * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise | ||
107 | */ | ||
108 | int | ||
109 | reset_member_session (struct GNUNET_MESSENGER_MemberSession* session, | ||
110 | const struct GNUNET_HashCode *hash); | ||
111 | |||
112 | /** | ||
113 | * Closes a given member <i>session</i> which opens the request | ||
114 | * for completion of the given member session. | ||
115 | * | ||
116 | * Closing a session may complete a session and can't be used without | ||
117 | * a reset! ( @see #reset_member_session() ) | ||
118 | * | ||
119 | * @param[in/out] session Member session | ||
120 | */ | ||
121 | void | ||
122 | close_member_session (struct GNUNET_MESSENGER_MemberSession* session); | ||
123 | |||
124 | /** | ||
125 | * Returns if the given member <i>session</i> has been closed. | ||
126 | * | ||
127 | * @param[in] session Member session | ||
128 | * @return #GNUNET_YES or #GNUNET_NO | ||
129 | */ | ||
130 | int | ||
131 | is_member_session_closed (const struct GNUNET_MESSENGER_MemberSession* session); | ||
132 | |||
133 | /** | ||
134 | * Returns if the given member <i>session</i> has been completed. | ||
135 | * | ||
136 | * A completed member session can't verify any message as its own and | ||
137 | * it won't add any message to its history. | ||
138 | * | ||
139 | * @param[in] session Member session | ||
140 | * @return #GNUNET_YES or #GNUNET_NO | ||
141 | */ | ||
142 | int | ||
143 | is_member_session_completed (const struct GNUNET_MESSENGER_MemberSession* session); | ||
144 | |||
145 | /** | ||
146 | * Returns the timestamp of the member <i>session</i>'s start. | ||
147 | * | ||
148 | * @param[in] session Member session | ||
149 | * @return Absolute timestamp | ||
150 | */ | ||
151 | struct GNUNET_TIME_Absolute | ||
152 | get_member_session_start (const struct GNUNET_MESSENGER_MemberSession* session); | ||
153 | |||
154 | /** | ||
155 | * Returns the key of the room a given member <i>session</i> belongs to. | ||
156 | * | ||
157 | * @param[in] session Member session | ||
158 | * @return Key of room | ||
159 | */ | ||
160 | const struct GNUNET_HashCode* | ||
161 | get_member_session_key (const struct GNUNET_MESSENGER_MemberSession* session); | ||
162 | |||
163 | /** | ||
164 | * Returns the member id of a given member <i>session</i>. | ||
165 | * | ||
166 | * @param[in] session Member session | ||
167 | * @return Member id | ||
168 | */ | ||
169 | const struct GNUNET_ShortHashCode* | ||
170 | get_member_session_id (const struct GNUNET_MESSENGER_MemberSession* session); | ||
171 | |||
172 | /** | ||
173 | * Returns the public key from an EGO of a given member <i>session</i>. | ||
174 | * | ||
175 | * @param[in] session Member session | ||
176 | * @return Public key of EGO | ||
177 | */ | ||
178 | const struct GNUNET_IDENTITY_PublicKey* | ||
179 | get_member_session_public_key (const struct GNUNET_MESSENGER_MemberSession* session); | ||
180 | |||
181 | /** | ||
182 | * Returns the member context of a given member <i>session</i>. | ||
183 | * | ||
184 | * @param[in] session Member session | ||
185 | * @return Member context as hash | ||
186 | */ | ||
187 | const struct GNUNET_HashCode* | ||
188 | get_member_session_context (const struct GNUNET_MESSENGER_MemberSession* session); | ||
189 | |||
190 | /** | ||
191 | * Returns the contact which is connected to a given member <i>session</i>. | ||
192 | * | ||
193 | * @param[in] session Member session | ||
194 | * @return Contact | ||
195 | */ | ||
196 | struct GNUNET_MESSENGER_Contact* | ||
197 | get_member_session_contact (struct GNUNET_MESSENGER_MemberSession* session); | ||
198 | |||
199 | /** | ||
200 | * Verifies a given member <i>session</i> as sender of a selected <i>message</i> and | ||
201 | * its <i>hash</i>. The function returns #GNUNET_OK if the message session is verified | ||
202 | * as sender, otherwise #GNUNET_SYSERR. | ||
203 | * | ||
204 | * @see #is_member_session_completed() for verification. | ||
205 | * | ||
206 | * @param[in] session Member session | ||
207 | * @param[in] message Message | ||
208 | * @param[in] hash Hash of message | ||
209 | * @return #GNUNET_OK on success, otherwise #GNUNET_SYSERR | ||
210 | */ | ||
211 | int | ||
212 | verify_member_session_as_sender (const struct GNUNET_MESSENGER_MemberSession *session, | ||
213 | const struct GNUNET_MESSENGER_Message *message, | ||
214 | const struct GNUNET_HashCode *hash); | ||
215 | |||
216 | /** | ||
217 | * Checks the history of a <i>session</i> for a specific message which is identified | ||
218 | * by its <i>hash</i> and if the <i>ownership</i> flag is set, if the message is | ||
219 | * owned by the sessions contact. | ||
220 | * | ||
221 | * @param[in] session Member session | ||
222 | * @param[in] hash Hash of message | ||
223 | * @param[in] ownership Ownership flag | ||
224 | * @return #GNUNET_YES if found, otherwise #GNUNET_NO | ||
225 | */ | ||
226 | int | ||
227 | check_member_session_history (const struct GNUNET_MESSENGER_MemberSession *session, | ||
228 | const struct GNUNET_HashCode *hash, | ||
229 | int ownership); | ||
230 | |||
231 | /** | ||
232 | * Adds a given <i>message</i> to the history of a <i>session</i> using the messages | ||
233 | * <i>hash</i>. The ownership will be set automatically. | ||
234 | * | ||
235 | * @see #is_member_session_completed() for updating a history. | ||
236 | * | ||
237 | * @param[in/out] session Member session | ||
238 | * @param[in] message Message | ||
239 | * @param[in] hash Hash of message | ||
240 | */ | ||
241 | void | ||
242 | update_member_session_history (struct GNUNET_MESSENGER_MemberSession *session, | ||
243 | const struct GNUNET_MESSENGER_Message *message, | ||
244 | const struct GNUNET_HashCode *hash); | ||
245 | |||
246 | /** | ||
247 | * Removes a message from the history of a <i>session</i> using the messages | ||
248 | * <i>hash</i>. | ||
249 | * | ||
250 | * @param[in/out] session Member session | ||
251 | * @param[in] hash Hash of message | ||
252 | */ | ||
253 | void | ||
254 | clear_member_session_history (struct GNUNET_MESSENGER_MemberSession *session, | ||
255 | const struct GNUNET_HashCode *hash); | ||
256 | |||
257 | /** | ||
258 | * Loads data from a <i>directory</i> into a new allocated and created member | ||
259 | * session of a <i>member</i> if the required information can be read from the | ||
260 | * content of the given directory. | ||
261 | * | ||
262 | * @param[out] member Member | ||
263 | * @param[in] directory Path to a directory | ||
264 | */ | ||
265 | void | ||
266 | load_member_session (struct GNUNET_MESSENGER_Member *member, | ||
267 | const char *directory); | ||
268 | |||
269 | /** | ||
270 | * Loads the connection from one <i>session</i> to another through the | ||
271 | * next attribute. Necessary information will be loaded from a configuration | ||
272 | * file inside of a given <i>directory</i>. | ||
273 | * | ||
274 | * @param[in/out] session Member session | ||
275 | * @param[in] directory Path to a directory | ||
276 | */ | ||
277 | void | ||
278 | load_member_session_next (struct GNUNET_MESSENGER_MemberSession *session, | ||
279 | const char *directory); | ||
280 | |||
281 | /** | ||
282 | * Saves data from a member <i>session</i> into a <i>directory</i> which can be | ||
283 | * load to restore the member session completely. | ||
284 | * | ||
285 | * @param[in] session Member session | ||
286 | * @param[in] directory Path to a directory | ||
287 | */ | ||
288 | void | ||
289 | save_member_session (struct GNUNET_MESSENGER_MemberSession *session, | ||
290 | const char *directory); | ||
291 | |||
292 | #endif //GNUNET_SERVICE_MESSENGER_MEMBER_SESSION_H | ||
diff --git a/src/messenger/gnunet-service-messenger_member_store.c b/src/messenger/gnunet-service-messenger_member_store.c deleted file mode 100644 index e96ee3883..000000000 --- a/src/messenger/gnunet-service-messenger_member_store.c +++ /dev/null | |||
@@ -1,268 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_member_store.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_member_store.h" | ||
27 | |||
28 | #include "gnunet-service-messenger_member.h" | ||
29 | #include "gnunet-service-messenger_service.h" | ||
30 | #include "gnunet-service-messenger_room.h" | ||
31 | |||
32 | void | ||
33 | init_member_store (struct GNUNET_MESSENGER_MemberStore *store, | ||
34 | struct GNUNET_MESSENGER_SrvRoom *room) | ||
35 | { | ||
36 | GNUNET_assert ((store) && (room)); | ||
37 | |||
38 | store->room = room; | ||
39 | store->members = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO); | ||
40 | } | ||
41 | |||
42 | static int | ||
43 | iterate_destroy_members (void *cls, | ||
44 | const struct GNUNET_ShortHashCode *key, | ||
45 | void *value) | ||
46 | { | ||
47 | struct GNUNET_MESSENGER_Member *member = value; | ||
48 | destroy_member(member); | ||
49 | return GNUNET_YES; | ||
50 | } | ||
51 | |||
52 | void | ||
53 | clear_member_store (struct GNUNET_MESSENGER_MemberStore *store) | ||
54 | { | ||
55 | GNUNET_assert ((store) && (store->members)); | ||
56 | |||
57 | GNUNET_CONTAINER_multishortmap_iterate (store->members, iterate_destroy_members, NULL); | ||
58 | GNUNET_CONTAINER_multishortmap_destroy (store->members); | ||
59 | } | ||
60 | |||
61 | |||
62 | struct GNUNET_MESSENGER_ContactStore* | ||
63 | get_member_contact_store (struct GNUNET_MESSENGER_MemberStore *store) | ||
64 | { | ||
65 | GNUNET_assert ((store) && (store->room)); | ||
66 | |||
67 | struct GNUNET_MESSENGER_SrvRoom *room = store->room; | ||
68 | |||
69 | return get_service_contact_store(room->service); | ||
70 | } | ||
71 | |||
72 | const struct GNUNET_HashCode* | ||
73 | get_member_store_key (const struct GNUNET_MESSENGER_MemberStore *store) | ||
74 | { | ||
75 | GNUNET_assert (store); | ||
76 | |||
77 | return get_room_key((const struct GNUNET_MESSENGER_SrvRoom*) store->room); | ||
78 | } | ||
79 | |||
80 | static int | ||
81 | callback_scan_for_members (void *cls, | ||
82 | const char *filename) | ||
83 | { | ||
84 | struct GNUNET_MESSENGER_MemberStore *store = cls; | ||
85 | |||
86 | if (GNUNET_YES == GNUNET_DISK_directory_test (filename, GNUNET_YES)) | ||
87 | { | ||
88 | char *directory; | ||
89 | |||
90 | GNUNET_asprintf (&directory, "%s%c", filename, DIR_SEPARATOR); | ||
91 | |||
92 | load_member(store, directory); | ||
93 | |||
94 | GNUNET_free(directory); | ||
95 | } | ||
96 | |||
97 | return GNUNET_OK; | ||
98 | } | ||
99 | |||
100 | static int | ||
101 | iterate_load_next_member_sessions (void *cls, | ||
102 | const struct GNUNET_ShortHashCode *id, | ||
103 | void *value) | ||
104 | { | ||
105 | const char *sync_dir = cls; | ||
106 | |||
107 | struct GNUNET_MESSENGER_Member *member = value; | ||
108 | |||
109 | if (!member) | ||
110 | return GNUNET_YES; | ||
111 | |||
112 | char *member_dir; | ||
113 | GNUNET_asprintf (&member_dir, "%s%s%c", sync_dir, GNUNET_sh2s(id), DIR_SEPARATOR); | ||
114 | |||
115 | if (GNUNET_YES == GNUNET_DISK_directory_test (member_dir, GNUNET_YES)) | ||
116 | load_member_next_sessions (member, member_dir); | ||
117 | |||
118 | GNUNET_free(member_dir); | ||
119 | return GNUNET_YES; | ||
120 | } | ||
121 | |||
122 | static int | ||
123 | iterate_sync_member_contacts (void *cls, | ||
124 | const struct GNUNET_ShortHashCode *id, | ||
125 | void *value) | ||
126 | { | ||
127 | struct GNUNET_MESSENGER_Member *member = value; | ||
128 | |||
129 | if (!member) | ||
130 | return GNUNET_YES; | ||
131 | |||
132 | sync_member_contacts (member); | ||
133 | return GNUNET_YES; | ||
134 | } | ||
135 | |||
136 | void | ||
137 | load_member_store (struct GNUNET_MESSENGER_MemberStore *store, | ||
138 | const char *directory) | ||
139 | { | ||
140 | GNUNET_assert ((store) && (directory)); | ||
141 | |||
142 | char *scan_dir; | ||
143 | GNUNET_asprintf (&scan_dir, "%s%s%c", directory, "members", DIR_SEPARATOR); | ||
144 | |||
145 | if (GNUNET_OK == GNUNET_DISK_directory_test (scan_dir, GNUNET_YES)) | ||
146 | GNUNET_DISK_directory_scan (scan_dir, callback_scan_for_members, store); | ||
147 | |||
148 | GNUNET_CONTAINER_multishortmap_iterate(store->members, iterate_load_next_member_sessions, scan_dir); | ||
149 | GNUNET_CONTAINER_multishortmap_iterate(store->members, iterate_sync_member_contacts, NULL); | ||
150 | |||
151 | GNUNET_free(scan_dir); | ||
152 | } | ||
153 | |||
154 | static int | ||
155 | iterate_save_members (void *cls, | ||
156 | const struct GNUNET_ShortHashCode *id, | ||
157 | void *value) | ||
158 | { | ||
159 | const char *save_dir = cls; | ||
160 | |||
161 | struct GNUNET_MESSENGER_Member *member = value; | ||
162 | |||
163 | if (!member) | ||
164 | return GNUNET_YES; | ||
165 | |||
166 | char *member_dir; | ||
167 | GNUNET_asprintf (&member_dir, "%s%s%c", save_dir, GNUNET_sh2s(id), DIR_SEPARATOR); | ||
168 | |||
169 | if ((GNUNET_YES == GNUNET_DISK_directory_test (member_dir, GNUNET_NO)) || | ||
170 | (GNUNET_OK == GNUNET_DISK_directory_create (member_dir))) | ||
171 | save_member(member, member_dir); | ||
172 | |||
173 | GNUNET_free(member_dir); | ||
174 | return GNUNET_YES; | ||
175 | } | ||
176 | |||
177 | void | ||
178 | save_member_store (struct GNUNET_MESSENGER_MemberStore *store, | ||
179 | const char *directory) | ||
180 | { | ||
181 | GNUNET_assert ((store) && (directory)); | ||
182 | |||
183 | char* save_dir; | ||
184 | GNUNET_asprintf (&save_dir, "%s%s%c", directory, "members", DIR_SEPARATOR); | ||
185 | |||
186 | if ((GNUNET_YES == GNUNET_DISK_directory_test (save_dir, GNUNET_NO)) || | ||
187 | (GNUNET_OK == GNUNET_DISK_directory_create (save_dir))) | ||
188 | GNUNET_CONTAINER_multishortmap_iterate(store->members, iterate_save_members, save_dir); | ||
189 | |||
190 | GNUNET_free(save_dir); | ||
191 | } | ||
192 | |||
193 | struct GNUNET_MESSENGER_Member* | ||
194 | get_store_member (const struct GNUNET_MESSENGER_MemberStore *store, | ||
195 | const struct GNUNET_ShortHashCode *id) | ||
196 | { | ||
197 | GNUNET_assert ((store) && (store->members) && (id)); | ||
198 | |||
199 | return GNUNET_CONTAINER_multishortmap_get (store->members, id); | ||
200 | } | ||
201 | |||
202 | struct GNUNET_MESSENGER_Member* | ||
203 | get_store_member_of (struct GNUNET_MESSENGER_MemberStore *store, | ||
204 | const struct GNUNET_MESSENGER_Message *message) | ||
205 | { | ||
206 | if ((GNUNET_MESSENGER_KIND_INFO == message->header.kind) || | ||
207 | (GNUNET_MESSENGER_KIND_JOIN == message->header.kind)) | ||
208 | return add_store_member(store, &(message->header.sender_id)); | ||
209 | else | ||
210 | return get_store_member(store, &(message->header.sender_id)); | ||
211 | } | ||
212 | |||
213 | struct GNUNET_MESSENGER_Member* | ||
214 | add_store_member (struct GNUNET_MESSENGER_MemberStore *store, | ||
215 | const struct GNUNET_ShortHashCode *id) | ||
216 | { | ||
217 | GNUNET_assert ((store) && (store->members)); | ||
218 | |||
219 | struct GNUNET_MESSENGER_Member *member = id? get_store_member(store, id) : NULL; | ||
220 | |||
221 | if (member) | ||
222 | return member; | ||
223 | |||
224 | member = create_member(store, id); | ||
225 | |||
226 | if (!member) | ||
227 | return NULL; | ||
228 | |||
229 | if (GNUNET_OK != GNUNET_CONTAINER_multishortmap_put (store->members, get_member_id(member), member, | ||
230 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
231 | { | ||
232 | destroy_member(member); | ||
233 | return NULL; | ||
234 | } | ||
235 | |||
236 | return member; | ||
237 | } | ||
238 | |||
239 | struct GNUNET_MESSENGER_ClosureIterateMembers { | ||
240 | GNUNET_MESSENGER_MemberIteratorCallback it; | ||
241 | void *cls; | ||
242 | }; | ||
243 | |||
244 | static int | ||
245 | iterate_store_members_it (void *cls, | ||
246 | const struct GNUNET_ShortHashCode *key, | ||
247 | void *value) | ||
248 | { | ||
249 | struct GNUNET_MESSENGER_ClosureIterateMembers *iterate = cls; | ||
250 | struct GNUNET_MESSENGER_Member *member = value; | ||
251 | |||
252 | return iterate_member_sessions(member, iterate->it, iterate->cls); | ||
253 | } | ||
254 | |||
255 | int | ||
256 | iterate_store_members (struct GNUNET_MESSENGER_MemberStore *store, | ||
257 | GNUNET_MESSENGER_MemberIteratorCallback it, | ||
258 | void* cls) | ||
259 | { | ||
260 | GNUNET_assert ((store) && (store->members) && (it)); | ||
261 | |||
262 | struct GNUNET_MESSENGER_ClosureIterateMembers iterate; | ||
263 | |||
264 | iterate.it = it; | ||
265 | iterate.cls = cls; | ||
266 | |||
267 | return GNUNET_CONTAINER_multishortmap_iterate(store->members, iterate_store_members_it, &iterate); | ||
268 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_member_store.h b/src/messenger/gnunet-service-messenger_member_store.h deleted file mode 100644 index af50f0d36..000000000 --- a/src/messenger/gnunet-service-messenger_member_store.h +++ /dev/null | |||
@@ -1,158 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_member_store.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_MEMBER_STORE_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_MEMBER_STORE_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_crypto_lib.h" | ||
31 | #include "gnunet_container_lib.h" | ||
32 | #include "gnunet_identity_service.h" | ||
33 | #include "messenger_api_message.h" | ||
34 | |||
35 | struct GNUNET_MESSENGER_SrvRoom; | ||
36 | |||
37 | struct GNUNET_MESSENGER_Member; | ||
38 | struct GNUNET_MESSENGER_MemberSession; | ||
39 | |||
40 | struct GNUNET_MESSENGER_MemberStore | ||
41 | { | ||
42 | struct GNUNET_MESSENGER_SrvRoom *room; | ||
43 | |||
44 | struct GNUNET_CONTAINER_MultiShortmap *members; | ||
45 | }; | ||
46 | |||
47 | typedef int (*GNUNET_MESSENGER_MemberIteratorCallback) ( | ||
48 | void *cls, | ||
49 | const struct GNUNET_IDENTITY_PublicKey *public_key, | ||
50 | struct GNUNET_MESSENGER_MemberSession *session); | ||
51 | |||
52 | /** | ||
53 | * Initializes a member <i>store</i> as fully empty connected to a <i>room</i>. | ||
54 | * | ||
55 | * @param[out] store Member store | ||
56 | * @param room Room | ||
57 | */ | ||
58 | void | ||
59 | init_member_store (struct GNUNET_MESSENGER_MemberStore *store, | ||
60 | struct GNUNET_MESSENGER_SrvRoom *room); | ||
61 | |||
62 | /** | ||
63 | * Clears a member <i>store</i>, wipes its content and deallocates its memory. | ||
64 | * | ||
65 | * @param[in/out] store Member store | ||
66 | */ | ||
67 | void | ||
68 | clear_member_store (struct GNUNET_MESSENGER_MemberStore *store); | ||
69 | |||
70 | /** | ||
71 | * Returns the used contact store of a given member <i>store</i>. | ||
72 | * | ||
73 | * @param[in/out] store Member store | ||
74 | * @return Contact store | ||
75 | */ | ||
76 | struct GNUNET_MESSENGER_ContactStore* | ||
77 | get_member_contact_store (struct GNUNET_MESSENGER_MemberStore *store); | ||
78 | |||
79 | /** | ||
80 | * Returns the shared secret you need to access a room of the <i>store</i>. | ||
81 | * | ||
82 | * @param[in] store Member store | ||
83 | * @return Shared secret | ||
84 | */ | ||
85 | const struct GNUNET_HashCode* | ||
86 | get_member_store_key (const struct GNUNET_MESSENGER_MemberStore *store); | ||
87 | |||
88 | /** | ||
89 | * Loads members from a directory into a member <i>store</i>. | ||
90 | * | ||
91 | * @param[out] store Member store | ||
92 | * @param[in] directory Path to a directory | ||
93 | */ | ||
94 | void | ||
95 | load_member_store (struct GNUNET_MESSENGER_MemberStore *store, | ||
96 | const char *directory); | ||
97 | |||
98 | /** | ||
99 | * Saves members from a member <i>store</i> into a directory. | ||
100 | * | ||
101 | * @param[in] store Member store | ||
102 | * @param[in] directory Path to a directory | ||
103 | */ | ||
104 | void | ||
105 | save_member_store (struct GNUNET_MESSENGER_MemberStore *store, | ||
106 | const char *directory); | ||
107 | |||
108 | /** | ||
109 | * Returns the member in a <i>store</i> identified by a given <i>id</i>. If the <i>store</i> | ||
110 | * does not contain a member with the given <i>id</i>, NULL gets returned. | ||
111 | * | ||
112 | * @param[in] store Member store | ||
113 | * @param[in] id Member id | ||
114 | * @return Member or NULL | ||
115 | */ | ||
116 | struct GNUNET_MESSENGER_Member* | ||
117 | get_store_member (const struct GNUNET_MESSENGER_MemberStore *store, | ||
118 | const struct GNUNET_ShortHashCode *id); | ||
119 | |||
120 | /** | ||
121 | * Returns the member of a <i>store</i> using a sender id of a given <i>message</i>. | ||
122 | * If the member does not provide a matching session, NULL gets returned. | ||
123 | * | ||
124 | * @param[in/out] store Member store | ||
125 | * @param[in] message Message | ||
126 | * @return Member or NULL | ||
127 | */ | ||
128 | struct GNUNET_MESSENGER_Member* | ||
129 | get_store_member_of (struct GNUNET_MESSENGER_MemberStore *store, | ||
130 | const struct GNUNET_MESSENGER_Message *message); | ||
131 | |||
132 | /** | ||
133 | * Adds a member to a <i>store</i> under a specific <i>id</i> and returns it on success. | ||
134 | * | ||
135 | * @param[in/out] store Member store | ||
136 | * @param[in] id Member id | ||
137 | * @return Member or NULL | ||
138 | */ | ||
139 | struct GNUNET_MESSENGER_Member* | ||
140 | add_store_member (struct GNUNET_MESSENGER_MemberStore *store, | ||
141 | const struct GNUNET_ShortHashCode *id); | ||
142 | |||
143 | /** | ||
144 | * Iterate through all member sessions currently connected to the members of the given | ||
145 | * member <i>store</i> and call the provided iterator callback with a selected closure. | ||
146 | * The function will return the amount of members it iterated through. | ||
147 | * | ||
148 | * @param[in/out] store Member store | ||
149 | * @param[in] it Iterator callback | ||
150 | * @param[in/out] cls Closure | ||
151 | * @return Amount of members iterated through | ||
152 | */ | ||
153 | int | ||
154 | iterate_store_members (struct GNUNET_MESSENGER_MemberStore *store, | ||
155 | GNUNET_MESSENGER_MemberIteratorCallback it, | ||
156 | void* cls); | ||
157 | |||
158 | #endif //GNUNET_SERVICE_MESSENGER_MEMBER_STORE_H | ||
diff --git a/src/messenger/gnunet-service-messenger_message_handle.c b/src/messenger/gnunet-service-messenger_message_handle.c deleted file mode 100644 index 701d78c89..000000000 --- a/src/messenger/gnunet-service-messenger_message_handle.c +++ /dev/null | |||
@@ -1,153 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_message_handle.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_message_handle.h" | ||
27 | |||
28 | static void | ||
29 | handle_session_switch (struct GNUNET_MESSENGER_MemberSession *session, | ||
30 | const struct GNUNET_MESSENGER_Message *message, | ||
31 | const struct GNUNET_HashCode *hash) | ||
32 | { | ||
33 | struct GNUNET_MESSENGER_MemberSession *next = switch_member_session(session, message, hash); | ||
34 | |||
35 | if (next != session) | ||
36 | add_member_session(next->member, next); | ||
37 | } | ||
38 | |||
39 | void | ||
40 | handle_message_join (struct GNUNET_MESSENGER_SrvRoom *room, | ||
41 | struct GNUNET_MESSENGER_MemberSession *session, | ||
42 | const struct GNUNET_MESSENGER_Message *message, | ||
43 | const struct GNUNET_HashCode *hash) | ||
44 | { | ||
45 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Member (%s) joins room (%s).\n", | ||
46 | GNUNET_sh2s (&(message->header.sender_id)), GNUNET_h2s(get_room_key(room))); | ||
47 | |||
48 | if (GNUNET_OK != reset_member_session(session, hash)) | ||
49 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Resetting member session failed!\n"); | ||
50 | |||
51 | solve_room_member_collisions ( | ||
52 | room, | ||
53 | &(message->body.join.key), | ||
54 | &(message->header.sender_id), | ||
55 | GNUNET_TIME_absolute_ntoh(message->header.timestamp) | ||
56 | ); | ||
57 | } | ||
58 | |||
59 | void | ||
60 | handle_message_leave (struct GNUNET_MESSENGER_SrvRoom *room, | ||
61 | struct GNUNET_MESSENGER_MemberSession *session, | ||
62 | const struct GNUNET_MESSENGER_Message *message, | ||
63 | const struct GNUNET_HashCode *hash) | ||
64 | { | ||
65 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Member (%s) leaves room (%s).\n", | ||
66 | GNUNET_sh2s (&(message->header.sender_id)), GNUNET_h2s(get_room_key(room))); | ||
67 | |||
68 | close_member_session(session); | ||
69 | } | ||
70 | |||
71 | void | ||
72 | handle_message_name (struct GNUNET_MESSENGER_SrvRoom *room, | ||
73 | struct GNUNET_MESSENGER_MemberSession *session, | ||
74 | const struct GNUNET_MESSENGER_Message *message, | ||
75 | const struct GNUNET_HashCode *hash) | ||
76 | { | ||
77 | struct GNUNET_MESSENGER_Contact *contact = get_member_session_contact(session); | ||
78 | |||
79 | if (!contact) | ||
80 | return; | ||
81 | |||
82 | set_contact_name (contact, message->body.name.name); | ||
83 | } | ||
84 | |||
85 | void | ||
86 | handle_message_key (struct GNUNET_MESSENGER_SrvRoom *room, | ||
87 | struct GNUNET_MESSENGER_MemberSession *session, | ||
88 | const struct GNUNET_MESSENGER_Message *message, | ||
89 | const struct GNUNET_HashCode *hash) | ||
90 | { | ||
91 | handle_session_switch (session, message, hash); | ||
92 | } | ||
93 | |||
94 | void | ||
95 | handle_message_peer (struct GNUNET_MESSENGER_SrvRoom *room, | ||
96 | struct GNUNET_MESSENGER_MemberSession *session, | ||
97 | const struct GNUNET_MESSENGER_Message *message, | ||
98 | const struct GNUNET_HashCode *hash) | ||
99 | { | ||
100 | if (GNUNET_NO == contains_list_tunnels (&(room->basement), &(message->body.peer.peer))) | ||
101 | add_to_list_tunnels (&(room->basement), &(message->body.peer.peer)); | ||
102 | |||
103 | if (room->peer_message) | ||
104 | rebuild_room_basement_structure (room); | ||
105 | } | ||
106 | |||
107 | void | ||
108 | handle_message_id (struct GNUNET_MESSENGER_SrvRoom *room, | ||
109 | struct GNUNET_MESSENGER_MemberSession *session, | ||
110 | const struct GNUNET_MESSENGER_Message *message, | ||
111 | const struct GNUNET_HashCode *hash) | ||
112 | { | ||
113 | handle_session_switch (session, message, hash); | ||
114 | |||
115 | solve_room_member_collisions ( | ||
116 | room, | ||
117 | get_member_session_public_key(session), | ||
118 | &(message->body.id.id), | ||
119 | GNUNET_TIME_absolute_ntoh(message->header.timestamp) | ||
120 | ); | ||
121 | } | ||
122 | |||
123 | void | ||
124 | handle_message_miss (struct GNUNET_MESSENGER_SrvRoom *room, | ||
125 | struct GNUNET_MESSENGER_MemberSession *session, | ||
126 | const struct GNUNET_MESSENGER_Message *message, | ||
127 | const struct GNUNET_HashCode *hash) | ||
128 | { | ||
129 | struct GNUNET_MESSENGER_ListTunnel *element = find_list_tunnels (&(room->basement), &(message->body.peer.peer), NULL); | ||
130 | |||
131 | if (!element) | ||
132 | return; | ||
133 | |||
134 | remove_from_list_tunnels (&(room->basement), element); | ||
135 | |||
136 | if (room->peer_message) | ||
137 | rebuild_room_basement_structure (room); | ||
138 | } | ||
139 | |||
140 | void | ||
141 | handle_message_delete (struct GNUNET_MESSENGER_SrvRoom *room, | ||
142 | struct GNUNET_MESSENGER_MemberSession *session, | ||
143 | const struct GNUNET_MESSENGER_Message *message, | ||
144 | const struct GNUNET_HashCode *hash) | ||
145 | { | ||
146 | struct GNUNET_TIME_Relative delay = GNUNET_TIME_relative_ntoh (message->body.deletion.delay); | ||
147 | struct GNUNET_TIME_Absolute action = GNUNET_TIME_absolute_ntoh (message->header.timestamp); | ||
148 | |||
149 | action = GNUNET_TIME_absolute_add (action, delay); | ||
150 | delay = GNUNET_TIME_absolute_get_difference (GNUNET_TIME_absolute_get (), action); | ||
151 | |||
152 | delete_room_message (room, session, &(message->body.deletion.hash), delay); | ||
153 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_message_handle.h b/src/messenger/gnunet-service-messenger_message_handle.h deleted file mode 100644 index 0e5be3408..000000000 --- a/src/messenger/gnunet-service-messenger_message_handle.h +++ /dev/null | |||
@@ -1,158 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_message_handle.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_MESSAGE_HANDLE_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_MESSAGE_HANDLE_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_crypto_lib.h" | ||
31 | |||
32 | #include "gnunet-service-messenger_message_kind.h" | ||
33 | |||
34 | #include "gnunet-service-messenger_member_session.h" | ||
35 | #include "gnunet-service-messenger_tunnel.h" | ||
36 | #include "messenger_api_message.h" | ||
37 | |||
38 | /** | ||
39 | * Handles a received or sent join message to make changes of current member information. | ||
40 | * (add matching member and clear member info) | ||
41 | * | ||
42 | * @param[in/out] room Room of the message | ||
43 | * @param[in/out] session Member session | ||
44 | * @param[in] message JOIN-Message | ||
45 | * @param[in] hash Hash of the message | ||
46 | */ | ||
47 | void | ||
48 | handle_message_join (struct GNUNET_MESSENGER_SrvRoom *room, | ||
49 | struct GNUNET_MESSENGER_MemberSession *session, | ||
50 | const struct GNUNET_MESSENGER_Message *message, | ||
51 | const struct GNUNET_HashCode *hash); | ||
52 | |||
53 | /** | ||
54 | * Handles a received or sent leave message to make changes of current member information. | ||
55 | * (remove matching member and clear member info) | ||
56 | * | ||
57 | * @param[in/out] room Room of the message | ||
58 | * @param[in/out] session Member session | ||
59 | * @param[in] message LEAVE-Message | ||
60 | * @param[in] hash Hash of the message | ||
61 | */ | ||
62 | void | ||
63 | handle_message_leave (struct GNUNET_MESSENGER_SrvRoom *room, | ||
64 | struct GNUNET_MESSENGER_MemberSession *session, | ||
65 | const struct GNUNET_MESSENGER_Message *message, | ||
66 | const struct GNUNET_HashCode *hash); | ||
67 | |||
68 | /** | ||
69 | * Handles a received or sent name message to rename a current member. | ||
70 | * (change name of matching member) | ||
71 | * | ||
72 | * @param[in/out] room Room of the message | ||
73 | * @param[in/out] session Member session | ||
74 | * @param[in] message NAME-Message | ||
75 | * @param[in] hash Hash of the message | ||
76 | */ | ||
77 | void | ||
78 | handle_message_name (struct GNUNET_MESSENGER_SrvRoom *room, | ||
79 | struct GNUNET_MESSENGER_MemberSession *session, | ||
80 | const struct GNUNET_MESSENGER_Message *message, | ||
81 | const struct GNUNET_HashCode *hash); | ||
82 | |||
83 | /** | ||
84 | * Handles a received or sent key message to change the key of a member and rearrange the contacts accordingly. | ||
85 | * (move the member in the contacts and change its key) | ||
86 | * | ||
87 | * @param[in/out] room Room of the message | ||
88 | * @param[in/out] session Member session | ||
89 | * @param[in] message KEY-Message | ||
90 | * @param[in] hash Hash of the message | ||
91 | */ | ||
92 | void | ||
93 | handle_message_key (struct GNUNET_MESSENGER_SrvRoom *room, | ||
94 | struct GNUNET_MESSENGER_MemberSession *session, | ||
95 | const struct GNUNET_MESSENGER_Message *message, | ||
96 | const struct GNUNET_HashCode *hash); | ||
97 | |||
98 | /** | ||
99 | * Handles a received or sent peer message to make changes of the basement in the room. | ||
100 | * (add a new peer to the basement and restructure connections based on updated list of peers) | ||
101 | * | ||
102 | * @param[in/out] room Room of the message | ||
103 | * @param[in/out] session Member session | ||
104 | * @param[in] message PEER-Message | ||
105 | * @param[in] hash Hash of the message | ||
106 | */ | ||
107 | void | ||
108 | handle_message_peer (struct GNUNET_MESSENGER_SrvRoom *room, | ||
109 | struct GNUNET_MESSENGER_MemberSession *session, | ||
110 | const struct GNUNET_MESSENGER_Message *message, | ||
111 | const struct GNUNET_HashCode *hash); | ||
112 | |||
113 | /** | ||
114 | * Handles a received or sent id message to change a members id. | ||
115 | * (change id of matching member) | ||
116 | * | ||
117 | * @param[in/out] room Room of the message | ||
118 | * @param[in/out] session Member session | ||
119 | * @param[in] message ID-Message | ||
120 | * @param[in] hash Hash of the message | ||
121 | */ | ||
122 | void | ||
123 | handle_message_id (struct GNUNET_MESSENGER_SrvRoom *room, | ||
124 | struct GNUNET_MESSENGER_MemberSession *session, | ||
125 | const struct GNUNET_MESSENGER_Message *message, | ||
126 | const struct GNUNET_HashCode *hash); | ||
127 | |||
128 | /** | ||
129 | * Handles a received or sent miss message to drop a peer from the basement in the room. | ||
130 | * (remove a peer from the basement and restructure connections based on updated list of peers) | ||
131 | * | ||
132 | * @param[in/out] room Room of the message | ||
133 | * @param[in/out] session Member session | ||
134 | * @param[in] message MISS-Message | ||
135 | * @param[in] hash Hash of the message | ||
136 | */ | ||
137 | void | ||
138 | handle_message_miss (struct GNUNET_MESSENGER_SrvRoom *room, | ||
139 | struct GNUNET_MESSENGER_MemberSession *session, | ||
140 | const struct GNUNET_MESSENGER_Message *message, | ||
141 | const struct GNUNET_HashCode *hash); | ||
142 | |||
143 | /** | ||
144 | * Handles a received or sent delete message to delete a specific message from the store. | ||
145 | * (remove a message from the store of a room under a given delay) | ||
146 | * | ||
147 | * @param[in/out] room Room of the message | ||
148 | * @param[in/out] session Member session | ||
149 | * @param[in] message DELETE-Message | ||
150 | * @param[in] hash Hash of the message | ||
151 | */ | ||
152 | void | ||
153 | handle_message_delete (struct GNUNET_MESSENGER_SrvRoom *room, | ||
154 | struct GNUNET_MESSENGER_MemberSession *session, | ||
155 | const struct GNUNET_MESSENGER_Message *message, | ||
156 | const struct GNUNET_HashCode *hash); | ||
157 | |||
158 | #endif //GNUNET_SERVICE_MESSENGER_MESSAGE_HANDLE_H | ||
diff --git a/src/messenger/gnunet-service-messenger_message_kind.c b/src/messenger/gnunet-service-messenger_message_kind.c deleted file mode 100644 index 2449b9230..000000000 --- a/src/messenger/gnunet-service-messenger_message_kind.c +++ /dev/null | |||
@@ -1,241 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_message_kind.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_message_kind.h" | ||
27 | |||
28 | #include "messenger_api_util.h" | ||
29 | |||
30 | struct GNUNET_MESSENGER_Message* | ||
31 | create_message_info (const struct GNUNET_MESSENGER_Ego *ego) | ||
32 | { | ||
33 | if (!ego) | ||
34 | return NULL; | ||
35 | |||
36 | struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_INFO); | ||
37 | |||
38 | if (!message) | ||
39 | return NULL; | ||
40 | |||
41 | GNUNET_memcpy(&(message->body.info.host_key), &(ego->pub), sizeof(ego->pub)); | ||
42 | |||
43 | message->body.info.messenger_version = GNUNET_MESSENGER_VERSION; | ||
44 | |||
45 | return message; | ||
46 | } | ||
47 | |||
48 | struct GNUNET_MESSENGER_Message* | ||
49 | create_message_join (const struct GNUNET_MESSENGER_Ego *ego) | ||
50 | { | ||
51 | if (!ego) | ||
52 | return NULL; | ||
53 | |||
54 | struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_JOIN); | ||
55 | |||
56 | if (!message) | ||
57 | return NULL; | ||
58 | |||
59 | GNUNET_memcpy(&(message->body.join.key), &(ego->pub), sizeof(ego->pub)); | ||
60 | |||
61 | return message; | ||
62 | } | ||
63 | |||
64 | struct GNUNET_MESSENGER_Message* | ||
65 | create_message_leave () | ||
66 | { | ||
67 | return create_message (GNUNET_MESSENGER_KIND_LEAVE); | ||
68 | } | ||
69 | |||
70 | struct GNUNET_MESSENGER_Message* | ||
71 | create_message_name (const char *name) | ||
72 | { | ||
73 | if (!name) | ||
74 | return NULL; | ||
75 | |||
76 | struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_NAME); | ||
77 | |||
78 | if (!message) | ||
79 | return NULL; | ||
80 | |||
81 | message->body.name.name = GNUNET_strdup(name); | ||
82 | return message; | ||
83 | } | ||
84 | |||
85 | struct GNUNET_MESSENGER_Message* | ||
86 | create_message_key (const struct GNUNET_IDENTITY_PrivateKey *key) | ||
87 | { | ||
88 | if (!key) | ||
89 | return NULL; | ||
90 | |||
91 | struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_KEY); | ||
92 | |||
93 | if (!message) | ||
94 | return NULL; | ||
95 | |||
96 | GNUNET_IDENTITY_key_get_public (key, &(message->body.key.key)); | ||
97 | return message; | ||
98 | } | ||
99 | |||
100 | struct GNUNET_MESSENGER_Message* | ||
101 | create_message_peer (const struct GNUNET_MESSENGER_Service *service) | ||
102 | { | ||
103 | if (!service) | ||
104 | return NULL; | ||
105 | |||
106 | struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_PEER); | ||
107 | |||
108 | if (!message) | ||
109 | return NULL; | ||
110 | |||
111 | if (GNUNET_OK == get_service_peer_identity (service, &(message->body.peer.peer))) | ||
112 | return message; | ||
113 | else | ||
114 | { | ||
115 | destroy_message (message); | ||
116 | return NULL; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | struct GNUNET_MESSENGER_Message* | ||
121 | create_message_id (const struct GNUNET_ShortHashCode *unique_id) | ||
122 | { | ||
123 | if (!unique_id) | ||
124 | return NULL; | ||
125 | |||
126 | struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_ID); | ||
127 | |||
128 | if (!message) | ||
129 | return NULL; | ||
130 | |||
131 | GNUNET_memcpy(&(message->body.id.id), unique_id, sizeof(struct GNUNET_ShortHashCode)); | ||
132 | |||
133 | return message; | ||
134 | } | ||
135 | |||
136 | struct GNUNET_MESSENGER_Message* | ||
137 | create_message_miss (const struct GNUNET_PeerIdentity *peer) | ||
138 | { | ||
139 | if (!peer) | ||
140 | return NULL; | ||
141 | |||
142 | struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_MISS); | ||
143 | |||
144 | if (!message) | ||
145 | { | ||
146 | return NULL; | ||
147 | } | ||
148 | |||
149 | GNUNET_memcpy(&(message->body.miss.peer), peer, sizeof(struct GNUNET_PeerIdentity)); | ||
150 | |||
151 | return message; | ||
152 | } | ||
153 | |||
154 | struct GNUNET_MESSENGER_Message* | ||
155 | create_message_merge (const struct GNUNET_HashCode *previous) | ||
156 | { | ||
157 | if (!previous) | ||
158 | return NULL; | ||
159 | |||
160 | struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_MERGE); | ||
161 | |||
162 | if (!message) | ||
163 | return NULL; | ||
164 | |||
165 | GNUNET_memcpy(&(message->body.merge.previous), previous, sizeof(struct GNUNET_HashCode)); | ||
166 | |||
167 | return message; | ||
168 | } | ||
169 | |||
170 | struct GNUNET_MESSENGER_Message* | ||
171 | create_message_request (const struct GNUNET_HashCode *hash) | ||
172 | { | ||
173 | if (!hash) | ||
174 | return NULL; | ||
175 | |||
176 | struct GNUNET_HashCode zero; | ||
177 | memset (&zero, 0, sizeof(zero)); | ||
178 | |||
179 | if (0 == GNUNET_CRYPTO_hash_cmp (hash, &zero)) | ||
180 | return NULL; | ||
181 | |||
182 | struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_REQUEST); | ||
183 | |||
184 | if (!message) | ||
185 | return NULL; | ||
186 | |||
187 | GNUNET_memcpy(&(message->body.request.hash), hash, sizeof(struct GNUNET_HashCode)); | ||
188 | |||
189 | return message; | ||
190 | } | ||
191 | |||
192 | struct GNUNET_MESSENGER_Message* | ||
193 | create_message_invite (const struct GNUNET_PeerIdentity *door, | ||
194 | const struct GNUNET_HashCode *key) | ||
195 | { | ||
196 | if ((!door) || (!key)) | ||
197 | return NULL; | ||
198 | |||
199 | struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_INVITE); | ||
200 | |||
201 | if (!message) | ||
202 | return NULL; | ||
203 | |||
204 | GNUNET_memcpy(&(message->body.invite.door), door, sizeof(struct GNUNET_PeerIdentity)); | ||
205 | GNUNET_memcpy(&(message->body.invite.key), key, sizeof(struct GNUNET_HashCode)); | ||
206 | |||
207 | return message; | ||
208 | } | ||
209 | |||
210 | struct GNUNET_MESSENGER_Message* | ||
211 | create_message_text (const char *text) | ||
212 | { | ||
213 | if (!text) | ||
214 | return NULL; | ||
215 | |||
216 | struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_TEXT); | ||
217 | |||
218 | if (!message) | ||
219 | return NULL; | ||
220 | |||
221 | message->body.text.text = GNUNET_strdup(text); | ||
222 | return message; | ||
223 | } | ||
224 | |||
225 | struct GNUNET_MESSENGER_Message* | ||
226 | create_message_delete (const struct GNUNET_HashCode *hash, | ||
227 | const struct GNUNET_TIME_Relative delay) | ||
228 | { | ||
229 | if (!hash) | ||
230 | return NULL; | ||
231 | |||
232 | struct GNUNET_MESSENGER_Message *message = create_message (GNUNET_MESSENGER_KIND_DELETE); | ||
233 | |||
234 | if (!message) | ||
235 | return NULL; | ||
236 | |||
237 | GNUNET_memcpy(&(message->body.deletion.hash), hash, sizeof(struct GNUNET_HashCode)); | ||
238 | message->body.deletion.delay = GNUNET_TIME_relative_hton (delay); | ||
239 | |||
240 | return message; | ||
241 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_message_kind.h b/src/messenger/gnunet-service-messenger_message_kind.h deleted file mode 100644 index 508f19074..000000000 --- a/src/messenger/gnunet-service-messenger_message_kind.h +++ /dev/null | |||
@@ -1,174 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_message_kind.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_MESSAGE_KIND_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_MESSAGE_KIND_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_container_lib.h" | ||
31 | #include "gnunet_crypto_lib.h" | ||
32 | #include "gnunet_identity_service.h" | ||
33 | #include "gnunet_time_lib.h" | ||
34 | |||
35 | #include "messenger_api_message.h" | ||
36 | #include "gnunet-service-messenger_service.h" | ||
37 | #include "messenger_api_ego.h" | ||
38 | |||
39 | /** | ||
40 | * Creates and allocates a new info message containing the hosts EGO public key and a newly generated unique member id. | ||
41 | * (all values are stored as copy) | ||
42 | * | ||
43 | * @param[in] ego EGO of the host | ||
44 | * @param[in] members Map of all assigned member ids | ||
45 | * @return New message | ||
46 | */ | ||
47 | struct GNUNET_MESSENGER_Message* | ||
48 | create_message_info (const struct GNUNET_MESSENGER_Ego *ego); | ||
49 | |||
50 | /** | ||
51 | * Creates and allocates a new join message containing the clients EGO public key. | ||
52 | * (all values are stored as copy) | ||
53 | * | ||
54 | * @param[in] ego EGO of the client | ||
55 | * @return New message | ||
56 | */ | ||
57 | struct GNUNET_MESSENGER_Message* | ||
58 | create_message_join (const struct GNUNET_MESSENGER_Ego *ego); | ||
59 | |||
60 | /** | ||
61 | * Creates and allocates a new leave message. | ||
62 | * | ||
63 | * @return New message | ||
64 | */ | ||
65 | struct GNUNET_MESSENGER_Message* | ||
66 | create_message_leave (); | ||
67 | |||
68 | /** | ||
69 | * Creates and allocates a new name message containing the <i>name</i> to change to. | ||
70 | * (all values are stored as copy) | ||
71 | * | ||
72 | * @param[in] name New name | ||
73 | * @return New message | ||
74 | */ | ||
75 | struct GNUNET_MESSENGER_Message* | ||
76 | create_message_name (const char *name); | ||
77 | |||
78 | /** | ||
79 | * Creates and allocates a new key message containing the public <i>key</i> to change to derived | ||
80 | * from its private counterpart. (all values are stored as copy) | ||
81 | * | ||
82 | * @param[in] key Private key of EGO | ||
83 | * @return New message | ||
84 | */ | ||
85 | struct GNUNET_MESSENGER_Message* | ||
86 | create_message_key (const struct GNUNET_IDENTITY_PrivateKey *key); | ||
87 | |||
88 | /** | ||
89 | * Creates and allocates a new peer message containing a services peer identity. | ||
90 | * (all values are stored as copy) | ||
91 | * | ||
92 | * @param[in] service Service | ||
93 | * @return New message | ||
94 | */ | ||
95 | struct GNUNET_MESSENGER_Message* | ||
96 | create_message_peer (const struct GNUNET_MESSENGER_Service *service); | ||
97 | |||
98 | /** | ||
99 | * Creates and allocates a new id message containing the unique member id to change to. | ||
100 | * (all values are stored as copy) | ||
101 | * | ||
102 | * @param[in] unique_id Unique member id | ||
103 | * @return New message | ||
104 | */ | ||
105 | struct GNUNET_MESSENGER_Message* | ||
106 | create_message_id (const struct GNUNET_ShortHashCode *unique_id); | ||
107 | |||
108 | /** | ||
109 | * Creates and allocates a new miss message containing the missing <i>peer</i> identity. | ||
110 | * (all values are stored as copy) | ||
111 | * | ||
112 | * @param[in] peer Missing peer identity | ||
113 | * @return New message | ||
114 | */ | ||
115 | struct GNUNET_MESSENGER_Message* | ||
116 | create_message_miss (const struct GNUNET_PeerIdentity *peer); | ||
117 | |||
118 | /** | ||
119 | * Creates and allocates a new merge message containing the hash of a second <i>previous</i> message | ||
120 | * besides the regular previous message mentioned in a messages header. | ||
121 | * (all values are stored as copy) | ||
122 | * | ||
123 | * @param[in] previous Hash of message | ||
124 | * @return New message | ||
125 | */ | ||
126 | struct GNUNET_MESSENGER_Message* | ||
127 | create_message_merge (const struct GNUNET_HashCode *previous); | ||
128 | |||
129 | /** | ||
130 | * Creates and allocates a new request message containing the <i>hash</i> of a missing message. | ||
131 | * (all values are stored as copy) | ||
132 | * | ||
133 | * @param[in] hash Hash of message | ||
134 | * @return New message | ||
135 | */ | ||
136 | struct GNUNET_MESSENGER_Message* | ||
137 | create_message_request (const struct GNUNET_HashCode *hash); | ||
138 | |||
139 | /** | ||
140 | * Creates and allocates a new invite message containing the peer identity of an entrance peer | ||
141 | * to a room using a given <i>key</i> as shared secret for communication. | ||
142 | * (all values are stored as copy) | ||
143 | * | ||
144 | * @param[in] door Peer identity | ||
145 | * @param[in] key Shared secret of a room | ||
146 | * @return New message | ||
147 | */ | ||
148 | struct GNUNET_MESSENGER_Message* | ||
149 | create_message_invite (const struct GNUNET_PeerIdentity *door, | ||
150 | const struct GNUNET_HashCode *key); | ||
151 | |||
152 | /** | ||
153 | * Creates and allocates a new <i>text message containing a string representing text. | ||
154 | * (all values are stored as copy) | ||
155 | * | ||
156 | * @param[in] text Text | ||
157 | * @return New message | ||
158 | */ | ||
159 | struct GNUNET_MESSENGER_Message* | ||
160 | create_message_text (const char *text); | ||
161 | |||
162 | /** | ||
163 | * Creates and allocates a new delete message containing the <i>hash</i> of a message to delete after a specific <i>delay</i>. | ||
164 | * (all values are stored as copy) | ||
165 | * | ||
166 | * @param[in] hash Hash of message | ||
167 | * @param[in] delay Delay of deletion | ||
168 | * @return New message | ||
169 | */ | ||
170 | struct GNUNET_MESSENGER_Message* | ||
171 | create_message_delete (const struct GNUNET_HashCode *hash, | ||
172 | const struct GNUNET_TIME_Relative delay); | ||
173 | |||
174 | #endif //GNUNET_SERVICE_MESSENGER_MESSAGE_KIND_H | ||
diff --git a/src/messenger/gnunet-service-messenger_message_recv.c b/src/messenger/gnunet-service-messenger_message_recv.c deleted file mode 100644 index bb6ee6f17..000000000 --- a/src/messenger/gnunet-service-messenger_message_recv.c +++ /dev/null | |||
@@ -1,185 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_message_recv.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_message_recv.h" | ||
27 | |||
28 | #include "gnunet-service-messenger_operation.h" | ||
29 | |||
30 | static void | ||
31 | forward_about_members (struct GNUNET_MESSENGER_SrvRoom *room, | ||
32 | struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
33 | struct GNUNET_MESSENGER_MemberSession *session, | ||
34 | struct GNUNET_CONTAINER_MultiHashMap *map) | ||
35 | { | ||
36 | if (session->prev) | ||
37 | forward_about_members (room, tunnel, session->prev, map); | ||
38 | |||
39 | struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(room); | ||
40 | struct GNUNET_MESSENGER_ListMessage *element; | ||
41 | |||
42 | for (element = session->messages.head; element; element = element->next) | ||
43 | { | ||
44 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(map, &(element->hash))) | ||
45 | continue; | ||
46 | |||
47 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(map, &(element->hash), NULL, | ||
48 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
49 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Forwarding of session message could be duplicated!\n"); | ||
50 | |||
51 | const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, &(element->hash)); | ||
52 | |||
53 | if (message) | ||
54 | forward_tunnel_message(tunnel, message, &(element->hash)); | ||
55 | } | ||
56 | } | ||
57 | |||
58 | static int | ||
59 | iterate_forward_members (void *cls, | ||
60 | const struct GNUNET_IDENTITY_PublicKey *public_key, | ||
61 | struct GNUNET_MESSENGER_MemberSession *session) | ||
62 | { | ||
63 | struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls; | ||
64 | |||
65 | if (GNUNET_YES == is_member_session_completed(session)) | ||
66 | return GNUNET_YES; | ||
67 | |||
68 | struct GNUNET_CONTAINER_MultiHashMap *map = GNUNET_CONTAINER_multihashmap_create(4, GNUNET_NO); | ||
69 | |||
70 | forward_about_members (tunnel->room, tunnel, session, map); | ||
71 | |||
72 | GNUNET_CONTAINER_multihashmap_destroy(map); | ||
73 | return GNUNET_YES; | ||
74 | } | ||
75 | |||
76 | int | ||
77 | recv_message_info (struct GNUNET_MESSENGER_SrvRoom *room, | ||
78 | struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
79 | const struct GNUNET_MESSENGER_Message *message, | ||
80 | const struct GNUNET_HashCode *hash) | ||
81 | { | ||
82 | const uint32_t version = get_tunnel_messenger_version(tunnel); | ||
83 | |||
84 | if (GNUNET_OK != update_tunnel_messenger_version(tunnel, message->body.info.messenger_version)) | ||
85 | { | ||
86 | disconnect_tunnel(tunnel); | ||
87 | return GNUNET_NO; | ||
88 | } | ||
89 | |||
90 | if (version == get_tunnel_messenger_version(tunnel)) | ||
91 | return GNUNET_NO; | ||
92 | |||
93 | if (room->host) | ||
94 | { | ||
95 | const struct GNUNET_MESSENGER_Ego *ego = get_handle_ego(room->host); | ||
96 | |||
97 | send_tunnel_message (tunnel, room->host, create_message_info(ego)); | ||
98 | } | ||
99 | |||
100 | struct GNUNET_PeerIdentity peer; | ||
101 | get_tunnel_peer_identity(tunnel, &peer); | ||
102 | |||
103 | if (GNUNET_YES != contains_list_tunnels(&(room->basement), &peer)) | ||
104 | { | ||
105 | struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room); | ||
106 | |||
107 | iterate_store_members(member_store, iterate_forward_members, tunnel); | ||
108 | } | ||
109 | |||
110 | check_room_peer_status(room, tunnel); | ||
111 | |||
112 | return GNUNET_NO; | ||
113 | } | ||
114 | |||
115 | int | ||
116 | recv_message_peer (struct GNUNET_MESSENGER_SrvRoom *room, | ||
117 | struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
118 | const struct GNUNET_MESSENGER_Message *message, | ||
119 | const struct GNUNET_HashCode *hash) | ||
120 | { | ||
121 | struct GNUNET_PeerIdentity peer; | ||
122 | GNUNET_PEER_resolve (tunnel->peer, &peer); | ||
123 | |||
124 | if (0 == GNUNET_memcmp(&peer, &(message->body.peer.peer))) | ||
125 | { | ||
126 | if (!tunnel->peer_message) | ||
127 | tunnel->peer_message = GNUNET_new(struct GNUNET_HashCode); | ||
128 | |||
129 | GNUNET_memcpy(tunnel->peer_message, &hash, sizeof(hash)); | ||
130 | } | ||
131 | |||
132 | return GNUNET_YES; | ||
133 | } | ||
134 | |||
135 | static void | ||
136 | callback_found_message (void *cls, | ||
137 | struct GNUNET_MESSENGER_SrvRoom *room, | ||
138 | const struct GNUNET_MESSENGER_Message *message, | ||
139 | const struct GNUNET_HashCode *hash) | ||
140 | { | ||
141 | struct GNUNET_MESSENGER_SrvTunnel *tunnel = tunnel; | ||
142 | |||
143 | if (!message) | ||
144 | { | ||
145 | struct GNUNET_MESSENGER_OperationStore *operation_store = get_room_operation_store(room); | ||
146 | |||
147 | use_store_operation( | ||
148 | operation_store, | ||
149 | hash, | ||
150 | GNUNET_MESSENGER_OP_REQUEST, | ||
151 | GNUNET_MESSENGER_REQUEST_DELAY | ||
152 | ); | ||
153 | } | ||
154 | else | ||
155 | forward_tunnel_message (tunnel, message, hash); | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * Function returns GNUNET_NO to drop forwarding the request. | ||
160 | * It will only be forwarded if it can't be answered! | ||
161 | */ | ||
162 | int | ||
163 | recv_message_request (struct GNUNET_MESSENGER_SrvRoom *room, | ||
164 | struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
165 | const struct GNUNET_MESSENGER_Message *message, | ||
166 | const struct GNUNET_HashCode *hash) | ||
167 | { | ||
168 | struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room); | ||
169 | struct GNUNET_MESSENGER_Member *member = get_store_member_of(member_store, message); | ||
170 | |||
171 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Request for message (%s)\n", GNUNET_h2s (hash)); | ||
172 | |||
173 | if (!member) | ||
174 | return GNUNET_NO; | ||
175 | |||
176 | struct GNUNET_MESSENGER_MemberSession *session = get_member_session_of(member, message, hash); | ||
177 | |||
178 | if ((!session) || (GNUNET_YES != check_member_session_history(session, hash, GNUNET_NO))) | ||
179 | return GNUNET_NO; | ||
180 | |||
181 | if (GNUNET_NO == request_room_message(room, &(message->body.request.hash), session, callback_found_message, tunnel)) | ||
182 | return GNUNET_YES; | ||
183 | |||
184 | return GNUNET_NO; | ||
185 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_message_recv.h b/src/messenger/gnunet-service-messenger_message_recv.h deleted file mode 100644 index 400c10245..000000000 --- a/src/messenger/gnunet-service-messenger_message_recv.h +++ /dev/null | |||
@@ -1,87 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_message_recv.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_MESSAGE_RECV_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_MESSAGE_RECV_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_crypto_lib.h" | ||
31 | |||
32 | #include "gnunet-service-messenger_message_kind.h" | ||
33 | |||
34 | #include "gnunet-service-messenger_member_session.h" | ||
35 | #include "gnunet-service-messenger_tunnel.h" | ||
36 | #include "messenger_api_message.h" | ||
37 | |||
38 | /** | ||
39 | * Handles a received info message to change the current member id to the one generated by | ||
40 | * the host connected to. (all current tunnels will be informed about the id change) | ||
41 | * | ||
42 | * @param[in/out] room Room of the message | ||
43 | * @param[in/out] tunnel Receiving connection | ||
44 | * @param[in] message INFO-Message | ||
45 | * @param[in] hash Hash of the message | ||
46 | * @return #GNUNET_NO to not forward the message | ||
47 | */ | ||
48 | int | ||
49 | recv_message_info (struct GNUNET_MESSENGER_SrvRoom *room, | ||
50 | struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
51 | const struct GNUNET_MESSENGER_Message *message, | ||
52 | const struct GNUNET_HashCode *hash); | ||
53 | |||
54 | /** | ||
55 | * Handles a received peer message to link it to its origin tunnel if the peer identity matches. | ||
56 | * (the peer message and the member id can potentially be linked to the tunnel) | ||
57 | * | ||
58 | * @param[in/out] room Room of the message | ||
59 | * @param[in/out] tunnel Receiving connection | ||
60 | * @param[in] message PEER-Message | ||
61 | * @param[in] hash Hash of the message | ||
62 | * @return #GNUNET_YES to forward the message | ||
63 | */ | ||
64 | int | ||
65 | recv_message_peer (struct GNUNET_MESSENGER_SrvRoom *room, | ||
66 | struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
67 | const struct GNUNET_MESSENGER_Message *message, | ||
68 | const struct GNUNET_HashCode *hash); | ||
69 | |||
70 | /** | ||
71 | * Handles a received request message by checking for the requested message and forwarding it back | ||
72 | * if the message was found. | ||
73 | * (this can also cause this peer to send a new request instead of only forwarding the received one) | ||
74 | * | ||
75 | * @param[in/out] room Room of the message | ||
76 | * @param[in/out] tunnel Receiving connection | ||
77 | * @param[in] message REQUEST-Message | ||
78 | * @param[in] hash Hash of the message | ||
79 | * @return #GNUNET_YES or #GNUNET_NO depending on required forwarding | ||
80 | */ | ||
81 | int | ||
82 | recv_message_request (struct GNUNET_MESSENGER_SrvRoom *room, | ||
83 | struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
84 | const struct GNUNET_MESSENGER_Message *message, | ||
85 | const struct GNUNET_HashCode *hash); | ||
86 | |||
87 | #endif //GNUNET_SERVICE_MESSENGER_MESSAGE_RECV_H | ||
diff --git a/src/messenger/gnunet-service-messenger_message_send.c b/src/messenger/gnunet-service-messenger_message_send.c deleted file mode 100644 index 8cc2466d7..000000000 --- a/src/messenger/gnunet-service-messenger_message_send.c +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_message_send.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_message_send.h" | ||
27 | |||
28 | #include "gnunet-service-messenger_member.h" | ||
29 | #include "gnunet-service-messenger_member_session.h" | ||
30 | #include "gnunet-service-messenger_operation.h" | ||
31 | |||
32 | void | ||
33 | send_message_join (struct GNUNET_MESSENGER_SrvRoom *room, | ||
34 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
35 | const struct GNUNET_MESSENGER_Message *message, | ||
36 | const struct GNUNET_HashCode *hash) | ||
37 | { | ||
38 | check_room_peer_status(room, NULL); | ||
39 | } | ||
40 | |||
41 | void | ||
42 | send_message_peer (struct GNUNET_MESSENGER_SrvRoom *room, | ||
43 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
44 | const struct GNUNET_MESSENGER_Message *message, | ||
45 | const struct GNUNET_HashCode *hash) | ||
46 | { | ||
47 | if (!room->peer_message) | ||
48 | room->peer_message = GNUNET_new(struct GNUNET_HashCode); | ||
49 | |||
50 | GNUNET_memcpy(room->peer_message, hash, sizeof(struct GNUNET_HashCode)); | ||
51 | } | ||
52 | |||
53 | void | ||
54 | send_message_id (struct GNUNET_MESSENGER_SrvRoom *room, | ||
55 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
56 | const struct GNUNET_MESSENGER_Message *message, | ||
57 | const struct GNUNET_HashCode *hash) | ||
58 | { | ||
59 | change_handle_member_id (handle, get_room_key(room), &(message->body.id.id)); | ||
60 | } | ||
61 | |||
62 | void | ||
63 | send_message_request (struct GNUNET_MESSENGER_SrvRoom *room, | ||
64 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
65 | const struct GNUNET_MESSENGER_Message *message, | ||
66 | const struct GNUNET_HashCode *hash) | ||
67 | { | ||
68 | struct GNUNET_MESSENGER_OperationStore *operation_store = get_room_operation_store(room); | ||
69 | |||
70 | use_store_operation( | ||
71 | operation_store, | ||
72 | &(message->body.request.hash), | ||
73 | GNUNET_MESSENGER_OP_REQUEST, | ||
74 | GNUNET_MESSENGER_REQUEST_DELAY | ||
75 | ); | ||
76 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_message_send.h b/src/messenger/gnunet-service-messenger_message_send.h deleted file mode 100644 index 232355c41..000000000 --- a/src/messenger/gnunet-service-messenger_message_send.h +++ /dev/null | |||
@@ -1,97 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_message_send.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_MESSAGE_SEND_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_MESSAGE_SEND_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_crypto_lib.h" | ||
31 | |||
32 | #include "gnunet-service-messenger_message_kind.h" | ||
33 | |||
34 | #include "gnunet-service-messenger_tunnel.h" | ||
35 | #include "messenger_api_message.h" | ||
36 | |||
37 | /** | ||
38 | * Handles a sent join message to ensure growth of the decentralized room structure. | ||
39 | * (if the service provides a peer message for this room currently, it will be forwarded) | ||
40 | * | ||
41 | * @param[in/out] room Room of the message | ||
42 | * @param[in/out] handle Sending handle | ||
43 | * @param[in] message JOIN-Message | ||
44 | * @param[in] hash Hash of the message | ||
45 | */ | ||
46 | void | ||
47 | send_message_join (struct GNUNET_MESSENGER_SrvRoom *room, | ||
48 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
49 | const struct GNUNET_MESSENGER_Message *message, | ||
50 | const struct GNUNET_HashCode *hash); | ||
51 | |||
52 | /** | ||
53 | * Handles a sent peer message to update the rooms peer message of this service. | ||
54 | * (a set peer message indicates this service being a part of the decentralized room structure) | ||
55 | * | ||
56 | * @param[in/out] room Room of the message | ||
57 | * @param[in/out] handle Sending handle | ||
58 | * @param[in] message PEER-Message | ||
59 | * @param[in] hash Hash of the message | ||
60 | */ | ||
61 | void | ||
62 | send_message_peer (struct GNUNET_MESSENGER_SrvRoom *room, | ||
63 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
64 | const struct GNUNET_MESSENGER_Message *message, | ||
65 | const struct GNUNET_HashCode *hash); | ||
66 | |||
67 | /** | ||
68 | * Handles a sent id message to update the handles member id in the room. | ||
69 | * (changing member id is useful to prevent collisions) | ||
70 | * | ||
71 | * @param[in/out] room Room of the message | ||
72 | * @param[in/out] handle Sending handle | ||
73 | * @param[in] message ID-Message | ||
74 | * @param[in] hash Hash of the message | ||
75 | */ | ||
76 | void | ||
77 | send_message_id (struct GNUNET_MESSENGER_SrvRoom *room, | ||
78 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
79 | const struct GNUNET_MESSENGER_Message *message, | ||
80 | const struct GNUNET_HashCode *hash); | ||
81 | |||
82 | /** | ||
83 | * Handles a sent request message to trigger the request operation for this service. | ||
84 | * (the request operation will deactivate the possibility of spamming requests) | ||
85 | * | ||
86 | * @param[in/out] room Room of the message | ||
87 | * @param[in/out] handle Sending handle | ||
88 | * @param[in] message PEER-Message | ||
89 | * @param[in] hash Hash of the message | ||
90 | */ | ||
91 | void | ||
92 | send_message_request (struct GNUNET_MESSENGER_SrvRoom *room, | ||
93 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
94 | const struct GNUNET_MESSENGER_Message *message, | ||
95 | const struct GNUNET_HashCode *hash); | ||
96 | |||
97 | #endif //GNUNET_SERVICE_MESSENGER_MESSAGE_SEND_H | ||
diff --git a/src/messenger/gnunet-service-messenger_message_state.c b/src/messenger/gnunet-service-messenger_message_state.c deleted file mode 100644 index 344962d11..000000000 --- a/src/messenger/gnunet-service-messenger_message_state.c +++ /dev/null | |||
@@ -1,113 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_message_state.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_message_state.h" | ||
27 | |||
28 | void | ||
29 | init_message_state (struct GNUNET_MESSENGER_MessageState *state) | ||
30 | { | ||
31 | GNUNET_assert(state); | ||
32 | |||
33 | init_list_messages (&(state->last_messages)); | ||
34 | } | ||
35 | |||
36 | void | ||
37 | clear_message_state (struct GNUNET_MESSENGER_MessageState *state) | ||
38 | { | ||
39 | GNUNET_assert(state); | ||
40 | |||
41 | clear_list_messages (&(state->last_messages)); | ||
42 | } | ||
43 | |||
44 | void | ||
45 | get_message_state_chain_hash (const struct GNUNET_MESSENGER_MessageState *state, | ||
46 | struct GNUNET_HashCode *hash) | ||
47 | { | ||
48 | GNUNET_assert((state) && (hash)); | ||
49 | |||
50 | if (state->last_messages.head) | ||
51 | GNUNET_memcpy(hash, &(state->last_messages.head->hash), sizeof(*hash)); | ||
52 | else | ||
53 | memset (hash, 0, sizeof(*hash)); | ||
54 | } | ||
55 | |||
56 | const struct GNUNET_HashCode* | ||
57 | get_message_state_merge_hash (const struct GNUNET_MESSENGER_MessageState *state) | ||
58 | { | ||
59 | GNUNET_assert(state); | ||
60 | |||
61 | if (state->last_messages.head == state->last_messages.tail) | ||
62 | return NULL; | ||
63 | |||
64 | return &(state->last_messages.tail->hash); | ||
65 | } | ||
66 | |||
67 | void | ||
68 | update_message_state (struct GNUNET_MESSENGER_MessageState *state, | ||
69 | int requested, | ||
70 | const struct GNUNET_MESSENGER_Message *message, | ||
71 | const struct GNUNET_HashCode *hash) | ||
72 | { | ||
73 | GNUNET_assert((state) && (message) && (hash)); | ||
74 | |||
75 | if ((GNUNET_YES == requested) || | ||
76 | (GNUNET_MESSENGER_KIND_INFO == message->header.kind) || | ||
77 | (GNUNET_MESSENGER_KIND_REQUEST == message->header.kind)) | ||
78 | return; | ||
79 | |||
80 | if (GNUNET_MESSENGER_KIND_MERGE == message->header.kind) | ||
81 | remove_from_list_messages(&(state->last_messages), &(message->body.merge.previous)); | ||
82 | remove_from_list_messages(&(state->last_messages), &(message->header.previous)); | ||
83 | |||
84 | add_to_list_messages (&(state->last_messages), hash); | ||
85 | } | ||
86 | |||
87 | void | ||
88 | load_message_state (struct GNUNET_MESSENGER_MessageState *state, | ||
89 | const char *path) | ||
90 | { | ||
91 | GNUNET_assert((state) && (path)); | ||
92 | |||
93 | char *last_messages_file; | ||
94 | GNUNET_asprintf (&last_messages_file, "%s%s", path, "last_messages.list"); | ||
95 | |||
96 | load_list_messages(&(state->last_messages), last_messages_file); | ||
97 | GNUNET_free(last_messages_file); | ||
98 | } | ||
99 | |||
100 | void | ||
101 | save_message_state (const struct GNUNET_MESSENGER_MessageState *state, | ||
102 | const char *path) | ||
103 | { | ||
104 | GNUNET_assert((state) && (path)); | ||
105 | |||
106 | char *last_messages_file; | ||
107 | GNUNET_asprintf (&last_messages_file, "%s%s", path, "last_messages.list"); | ||
108 | |||
109 | save_list_messages(&(state->last_messages), last_messages_file); | ||
110 | GNUNET_free(last_messages_file); | ||
111 | } | ||
112 | |||
113 | |||
diff --git a/src/messenger/gnunet-service-messenger_message_state.h b/src/messenger/gnunet-service-messenger_message_state.h deleted file mode 100644 index af52b26b6..000000000 --- a/src/messenger/gnunet-service-messenger_message_state.h +++ /dev/null | |||
@@ -1,67 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_message_state.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_MESSAGE_STATE_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_MESSAGE_STATE_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_crypto_lib.h" | ||
31 | |||
32 | #include "messenger_api_message.h" | ||
33 | #include "gnunet-service-messenger_list_messages.h" | ||
34 | |||
35 | struct GNUNET_MESSENGER_MessageState | ||
36 | { | ||
37 | struct GNUNET_MESSENGER_ListMessages last_messages; | ||
38 | }; | ||
39 | |||
40 | void | ||
41 | init_message_state (struct GNUNET_MESSENGER_MessageState *state); | ||
42 | |||
43 | void | ||
44 | clear_message_state (struct GNUNET_MESSENGER_MessageState *state); | ||
45 | |||
46 | void | ||
47 | get_message_state_chain_hash (const struct GNUNET_MESSENGER_MessageState *state, | ||
48 | struct GNUNET_HashCode *hash); | ||
49 | |||
50 | const struct GNUNET_HashCode* | ||
51 | get_message_state_merge_hash (const struct GNUNET_MESSENGER_MessageState *state); | ||
52 | |||
53 | void | ||
54 | update_message_state (struct GNUNET_MESSENGER_MessageState *state, | ||
55 | int requested, | ||
56 | const struct GNUNET_MESSENGER_Message *message, | ||
57 | const struct GNUNET_HashCode *hash); | ||
58 | |||
59 | void | ||
60 | load_message_state (struct GNUNET_MESSENGER_MessageState *state, | ||
61 | const char *path); | ||
62 | |||
63 | void | ||
64 | save_message_state (const struct GNUNET_MESSENGER_MessageState *state, | ||
65 | const char *path); | ||
66 | |||
67 | #endif //GNUNET_SERVICE_MESSENGER_MESSAGE_STATE_H | ||
diff --git a/src/messenger/gnunet-service-messenger_message_store.c b/src/messenger/gnunet-service-messenger_message_store.c deleted file mode 100644 index ddad266ad..000000000 --- a/src/messenger/gnunet-service-messenger_message_store.c +++ /dev/null | |||
@@ -1,582 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_message_store.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_message_store.h" | ||
27 | #include "messenger_api_message.h" | ||
28 | |||
29 | void | ||
30 | init_message_store (struct GNUNET_MESSENGER_MessageStore *store) | ||
31 | { | ||
32 | GNUNET_assert(store); | ||
33 | |||
34 | store->storage_messages = NULL; | ||
35 | |||
36 | store->entries = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); | ||
37 | store->messages = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); | ||
38 | store->links = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); | ||
39 | |||
40 | store->rewrite_entries = GNUNET_NO; | ||
41 | store->write_links = GNUNET_NO; | ||
42 | } | ||
43 | |||
44 | static int | ||
45 | iterate_destroy_entries (void *cls, | ||
46 | const struct GNUNET_HashCode *key, | ||
47 | void *value) | ||
48 | { | ||
49 | struct GNUNET_MESSENGER_MessageEntry *entry = value; | ||
50 | |||
51 | GNUNET_free(entry); | ||
52 | |||
53 | return GNUNET_YES; | ||
54 | } | ||
55 | |||
56 | static int | ||
57 | iterate_destroy_messages (void *cls, | ||
58 | const struct GNUNET_HashCode *key, | ||
59 | void *value) | ||
60 | { | ||
61 | struct GNUNET_MESSENGER_Message *message = value; | ||
62 | |||
63 | destroy_message (message); | ||
64 | |||
65 | return GNUNET_YES; | ||
66 | } | ||
67 | |||
68 | static int | ||
69 | iterate_destroy_links (void *cls, | ||
70 | const struct GNUNET_HashCode *key, | ||
71 | void *value) | ||
72 | { | ||
73 | struct GNUNET_HashCode *previous = value; | ||
74 | |||
75 | GNUNET_free(previous); | ||
76 | |||
77 | return GNUNET_YES; | ||
78 | } | ||
79 | |||
80 | void | ||
81 | clear_message_store (struct GNUNET_MESSENGER_MessageStore *store) | ||
82 | { | ||
83 | GNUNET_assert(store); | ||
84 | |||
85 | if (store->storage_messages) | ||
86 | { | ||
87 | GNUNET_DISK_file_close (store->storage_messages); | ||
88 | |||
89 | store->storage_messages = NULL; | ||
90 | } | ||
91 | |||
92 | GNUNET_CONTAINER_multihashmap_iterate (store->entries, iterate_destroy_entries, NULL); | ||
93 | GNUNET_CONTAINER_multihashmap_iterate (store->messages, iterate_destroy_messages, NULL); | ||
94 | GNUNET_CONTAINER_multihashmap_iterate (store->links, iterate_destroy_links, NULL); | ||
95 | |||
96 | GNUNET_CONTAINER_multihashmap_destroy (store->entries); | ||
97 | GNUNET_CONTAINER_multihashmap_destroy (store->messages); | ||
98 | GNUNET_CONTAINER_multihashmap_destroy (store->links); | ||
99 | } | ||
100 | |||
101 | struct GNUNET_MESSENGER_MessageEntryStorage | ||
102 | { | ||
103 | struct GNUNET_HashCode hash; | ||
104 | struct GNUNET_MESSENGER_MessageEntry entry; | ||
105 | }; | ||
106 | |||
107 | #define load_message_store_attribute_failed(file, attribute) \ | ||
108 | sizeof(attribute) != GNUNET_DISK_file_read(file, &(attribute), sizeof(attribute)) | ||
109 | |||
110 | #define save_message_store_attribute_failed(file, attribute) \ | ||
111 | sizeof(attribute) != GNUNET_DISK_file_write(file, &(attribute), sizeof(attribute)) | ||
112 | |||
113 | static void | ||
114 | load_message_store_entries (struct GNUNET_MESSENGER_MessageStore *store, | ||
115 | const char *filename) | ||
116 | { | ||
117 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ); | ||
118 | |||
119 | struct GNUNET_DISK_FileHandle *entries = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, permission); | ||
120 | |||
121 | if (!entries) | ||
122 | return; | ||
123 | |||
124 | struct GNUNET_MESSENGER_MessageEntryStorage storage; | ||
125 | struct GNUNET_MESSENGER_MessageEntry *entry; | ||
126 | |||
127 | memset(&storage, 0, sizeof(storage)); | ||
128 | |||
129 | do | ||
130 | { | ||
131 | entry = NULL; | ||
132 | |||
133 | if ((load_message_store_attribute_failed(entries, storage.hash)) || | ||
134 | (load_message_store_attribute_failed(entries, storage.entry.offset)) || | ||
135 | (load_message_store_attribute_failed(entries, storage.entry.length))) | ||
136 | break; | ||
137 | |||
138 | entry = GNUNET_new(struct GNUNET_MESSENGER_MessageEntry); | ||
139 | |||
140 | GNUNET_memcpy(entry, &(storage.entry), sizeof(*entry)); | ||
141 | |||
142 | if ((GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->entries, &(storage.hash))) || | ||
143 | (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->entries, &(storage.hash), entry, | ||
144 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) | ||
145 | { | ||
146 | store->rewrite_entries = GNUNET_YES; | ||
147 | break; | ||
148 | } | ||
149 | } | ||
150 | while (entry); | ||
151 | |||
152 | if (entry) | ||
153 | GNUNET_free(entry); | ||
154 | |||
155 | GNUNET_DISK_file_close (entries); | ||
156 | } | ||
157 | |||
158 | struct GNUNET_MESSENGER_MessageLinkStorage | ||
159 | { | ||
160 | struct GNUNET_HashCode hash; | ||
161 | struct GNUNET_MESSENGER_MessageLink link; | ||
162 | }; | ||
163 | |||
164 | static void | ||
165 | load_message_store_links (struct GNUNET_MESSENGER_MessageStore *store, | ||
166 | const char *filename) | ||
167 | { | ||
168 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ); | ||
169 | |||
170 | struct GNUNET_DISK_FileHandle *entries = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READ, permission); | ||
171 | |||
172 | if (!entries) | ||
173 | return; | ||
174 | |||
175 | struct GNUNET_MESSENGER_MessageLinkStorage storage; | ||
176 | struct GNUNET_MESSENGER_MessageLink *link; | ||
177 | |||
178 | memset(&storage, 0, sizeof(storage)); | ||
179 | |||
180 | do | ||
181 | { | ||
182 | link = NULL; | ||
183 | |||
184 | if ((load_message_store_attribute_failed(entries, storage.hash)) || | ||
185 | (load_message_store_attribute_failed(entries, storage.link.multiple)) || | ||
186 | (load_message_store_attribute_failed(entries, storage.link.first)) || | ||
187 | ((GNUNET_YES == storage.link.multiple) && | ||
188 | (load_message_store_attribute_failed(entries, storage.link.second)))) | ||
189 | break; | ||
190 | |||
191 | link = GNUNET_new(struct GNUNET_MESSENGER_MessageLink); | ||
192 | |||
193 | GNUNET_memcpy(link, &(storage.link), sizeof(*link)); | ||
194 | |||
195 | if ((GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->links, &(storage.hash))) || | ||
196 | (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (store->links, &(storage.hash), link, | ||
197 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) | ||
198 | break; | ||
199 | } | ||
200 | while (link); | ||
201 | |||
202 | if (link) | ||
203 | GNUNET_free(link); | ||
204 | |||
205 | GNUNET_DISK_file_close (entries); | ||
206 | } | ||
207 | |||
208 | void | ||
209 | load_message_store (struct GNUNET_MESSENGER_MessageStore *store, | ||
210 | const char *directory) | ||
211 | { | ||
212 | GNUNET_assert((store) && (directory)); | ||
213 | |||
214 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); | ||
215 | |||
216 | if (store->storage_messages) | ||
217 | GNUNET_DISK_file_close (store->storage_messages); | ||
218 | |||
219 | char *filename; | ||
220 | GNUNET_asprintf (&filename, "%s%s", directory, "messages.store"); | ||
221 | |||
222 | if (GNUNET_YES == GNUNET_DISK_file_test (filename)) | ||
223 | store->storage_messages = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READWRITE, permission); | ||
224 | else | ||
225 | store->storage_messages = NULL; | ||
226 | |||
227 | GNUNET_free(filename); | ||
228 | |||
229 | if (!store->storage_messages) | ||
230 | return; | ||
231 | |||
232 | GNUNET_asprintf (&filename, "%s%s", directory, "entries.store"); | ||
233 | |||
234 | if (GNUNET_YES == GNUNET_DISK_file_test (filename)) | ||
235 | load_message_store_entries(store, filename); | ||
236 | |||
237 | GNUNET_free(filename); | ||
238 | |||
239 | GNUNET_asprintf (&filename, "%s%s", directory, "links.store"); | ||
240 | |||
241 | if (GNUNET_YES == GNUNET_DISK_file_test (filename)) | ||
242 | load_message_store_links(store, filename); | ||
243 | |||
244 | GNUNET_free(filename); | ||
245 | } | ||
246 | |||
247 | struct GNUNET_MESSENGER_ClosureMessageSave | ||
248 | { | ||
249 | struct GNUNET_MESSENGER_MessageStore *store; | ||
250 | |||
251 | struct GNUNET_DISK_FileHandle *storage; | ||
252 | }; | ||
253 | |||
254 | static int | ||
255 | iterate_save_entries (void *cls, | ||
256 | const struct GNUNET_HashCode *key, | ||
257 | void *value) | ||
258 | { | ||
259 | struct GNUNET_MESSENGER_ClosureMessageSave *save = cls; | ||
260 | struct GNUNET_MESSENGER_MessageEntry *entry = value; | ||
261 | |||
262 | struct GNUNET_MESSENGER_MessageEntryStorage storage; | ||
263 | |||
264 | GNUNET_DISK_file_write (save->storage, key, sizeof(*key)); | ||
265 | GNUNET_DISK_file_write (save->storage, &(entry->offset), sizeof(entry->offset)); | ||
266 | GNUNET_DISK_file_write (save->storage, &(entry->length), sizeof(entry->length)); | ||
267 | |||
268 | return GNUNET_YES; | ||
269 | } | ||
270 | |||
271 | static int | ||
272 | iterate_save_messages (void *cls, | ||
273 | const struct GNUNET_HashCode *key, | ||
274 | void *value) | ||
275 | { | ||
276 | struct GNUNET_MESSENGER_ClosureMessageSave *save = cls; | ||
277 | |||
278 | if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (save->store->entries, key)) | ||
279 | return GNUNET_YES; | ||
280 | |||
281 | struct GNUNET_MESSENGER_Message *message = value; | ||
282 | struct GNUNET_MESSENGER_MessageEntryStorage storage; | ||
283 | |||
284 | GNUNET_memcpy(&(storage.hash), key, sizeof(storage.hash)); | ||
285 | |||
286 | storage.entry.length = get_message_size (message, GNUNET_YES); | ||
287 | storage.entry.offset = GNUNET_DISK_file_seek (save->store->storage_messages, 0, GNUNET_DISK_SEEK_END); | ||
288 | |||
289 | if ((GNUNET_SYSERR == storage.entry.offset) || | ||
290 | (save_message_store_attribute_failed(save->storage, storage.hash)) || | ||
291 | (save_message_store_attribute_failed(save->storage, storage.entry.offset)) || | ||
292 | (save_message_store_attribute_failed(save->storage, storage.entry.length))) | ||
293 | return GNUNET_YES; | ||
294 | |||
295 | char *buffer = GNUNET_malloc(storage.entry.length); | ||
296 | |||
297 | encode_message (message, storage.entry.length, buffer, GNUNET_YES); | ||
298 | |||
299 | GNUNET_DISK_file_write (save->store->storage_messages, buffer, storage.entry.length); | ||
300 | |||
301 | GNUNET_free(buffer); | ||
302 | return GNUNET_YES; | ||
303 | } | ||
304 | |||
305 | static int | ||
306 | iterate_save_links (void *cls, | ||
307 | const struct GNUNET_HashCode *key, | ||
308 | void *value) | ||
309 | { | ||
310 | struct GNUNET_MESSENGER_ClosureMessageSave *save = cls; | ||
311 | struct GNUNET_MESSENGER_MessageLink *link = value; | ||
312 | |||
313 | GNUNET_DISK_file_write (save->storage, key, sizeof(*key)); | ||
314 | GNUNET_DISK_file_write (save->storage, &(link->multiple), sizeof(link->multiple)); | ||
315 | GNUNET_DISK_file_write (save->storage, &(link->first), sizeof(link->first)); | ||
316 | |||
317 | if (GNUNET_YES == link->multiple) | ||
318 | GNUNET_DISK_file_write (save->storage, &(link->second), sizeof(link->second)); | ||
319 | |||
320 | return GNUNET_YES; | ||
321 | } | ||
322 | |||
323 | void | ||
324 | save_message_store (struct GNUNET_MESSENGER_MessageStore *store, | ||
325 | const char *directory) | ||
326 | { | ||
327 | GNUNET_assert((store) && (directory)); | ||
328 | |||
329 | struct GNUNET_MESSENGER_ClosureMessageSave save; | ||
330 | |||
331 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); | ||
332 | |||
333 | char *filename; | ||
334 | |||
335 | if (GNUNET_YES != store->write_links) | ||
336 | goto save_entries; | ||
337 | |||
338 | GNUNET_asprintf (&filename, "%s%s", directory, "links.store"); | ||
339 | |||
340 | save.store = store; | ||
341 | save.storage = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, permission); | ||
342 | |||
343 | GNUNET_free(filename); | ||
344 | |||
345 | if (!save.storage) | ||
346 | goto save_entries; | ||
347 | |||
348 | if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0, GNUNET_DISK_SEEK_SET)) | ||
349 | goto close_links; | ||
350 | |||
351 | GNUNET_CONTAINER_multihashmap_iterate (store->links, iterate_save_links, &save); | ||
352 | store->write_links = GNUNET_NO; | ||
353 | |||
354 | close_links: | ||
355 | GNUNET_DISK_file_close (save.storage); | ||
356 | |||
357 | save_entries: | ||
358 | GNUNET_asprintf (&filename, "%s%s", directory, "entries.store"); | ||
359 | |||
360 | save.store = store; | ||
361 | save.storage = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, permission); | ||
362 | |||
363 | GNUNET_free(filename); | ||
364 | |||
365 | if (!save.storage) | ||
366 | return; | ||
367 | |||
368 | if (GNUNET_YES == store->rewrite_entries) | ||
369 | { | ||
370 | if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0, GNUNET_DISK_SEEK_SET)) | ||
371 | goto close_entries; | ||
372 | |||
373 | GNUNET_CONTAINER_multihashmap_iterate (store->entries, iterate_save_entries, &save); | ||
374 | store->rewrite_entries = GNUNET_NO; | ||
375 | } | ||
376 | else if (GNUNET_SYSERR == GNUNET_DISK_file_seek (save.storage, 0, GNUNET_DISK_SEEK_END)) | ||
377 | goto close_entries; | ||
378 | |||
379 | if (store->storage_messages) | ||
380 | GNUNET_DISK_file_close (store->storage_messages); | ||
381 | |||
382 | GNUNET_asprintf (&filename, "%s%s", directory, "messages.store"); | ||
383 | |||
384 | store->storage_messages = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_READWRITE | GNUNET_DISK_OPEN_CREATE, | ||
385 | permission); | ||
386 | |||
387 | GNUNET_free(filename); | ||
388 | |||
389 | if (store->storage_messages) | ||
390 | { | ||
391 | GNUNET_CONTAINER_multihashmap_iterate (store->messages, iterate_save_messages, &save); | ||
392 | |||
393 | GNUNET_DISK_file_sync (store->storage_messages); | ||
394 | GNUNET_DISK_file_sync (save.storage); | ||
395 | } | ||
396 | |||
397 | close_entries: | ||
398 | GNUNET_DISK_file_close (save.storage); | ||
399 | } | ||
400 | |||
401 | int | ||
402 | contains_store_message (const struct GNUNET_MESSENGER_MessageStore *store, | ||
403 | const struct GNUNET_HashCode *hash) | ||
404 | { | ||
405 | GNUNET_assert((store) && (hash)); | ||
406 | |||
407 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (store->messages, hash)) | ||
408 | return GNUNET_YES; | ||
409 | |||
410 | return GNUNET_CONTAINER_multihashmap_contains (store->entries, hash); | ||
411 | } | ||
412 | |||
413 | const struct GNUNET_MESSENGER_Message* | ||
414 | get_store_message (struct GNUNET_MESSENGER_MessageStore *store, | ||
415 | const struct GNUNET_HashCode *hash) | ||
416 | { | ||
417 | GNUNET_assert((store) && (hash)); | ||
418 | |||
419 | struct GNUNET_MESSENGER_Message *message = GNUNET_CONTAINER_multihashmap_get (store->messages, hash); | ||
420 | |||
421 | if (message) | ||
422 | return message; | ||
423 | |||
424 | if (!store->storage_messages) | ||
425 | return NULL; | ||
426 | |||
427 | const struct GNUNET_MESSENGER_MessageEntry *entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash); | ||
428 | |||
429 | if (!entry) | ||
430 | return NULL; | ||
431 | |||
432 | if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages, entry->offset, GNUNET_DISK_SEEK_SET)) | ||
433 | return message; | ||
434 | |||
435 | char *buffer = GNUNET_malloc(entry->length); | ||
436 | |||
437 | if (!buffer) | ||
438 | return NULL; | ||
439 | |||
440 | if ((GNUNET_DISK_file_read (store->storage_messages, buffer, entry->length) != entry->length) || | ||
441 | (entry->length < get_message_kind_size(GNUNET_MESSENGER_KIND_UNKNOWN, GNUNET_YES))) | ||
442 | goto free_buffer; | ||
443 | |||
444 | message = create_message (GNUNET_MESSENGER_KIND_UNKNOWN); | ||
445 | |||
446 | const int decoding = decode_message (message, entry->length, buffer, GNUNET_YES, NULL); | ||
447 | |||
448 | struct GNUNET_HashCode check; | ||
449 | hash_message (message, entry->length, buffer, &check); | ||
450 | |||
451 | if ((GNUNET_YES != decoding) || (GNUNET_CRYPTO_hash_cmp (hash, &check) != 0)) | ||
452 | { | ||
453 | if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (store->entries, hash, entry)) | ||
454 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Corrupted entry could not be removed from store: %s\n", | ||
455 | GNUNET_h2s(hash)); | ||
456 | |||
457 | store->rewrite_entries = GNUNET_YES; | ||
458 | |||
459 | goto free_message; | ||
460 | } | ||
461 | |||
462 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (store->messages, hash, message, | ||
463 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
464 | goto free_buffer; | ||
465 | |||
466 | free_message: destroy_message (message); | ||
467 | message = NULL; | ||
468 | |||
469 | free_buffer: | ||
470 | GNUNET_free(buffer); | ||
471 | |||
472 | return message; | ||
473 | } | ||
474 | |||
475 | const struct GNUNET_MESSENGER_MessageLink* | ||
476 | get_store_message_link (struct GNUNET_MESSENGER_MessageStore *store, | ||
477 | const struct GNUNET_HashCode *hash, | ||
478 | int deleted_only) | ||
479 | { | ||
480 | if (deleted_only) | ||
481 | goto get_link; | ||
482 | |||
483 | const struct GNUNET_MESSENGER_Message *message = get_store_message(store, hash); | ||
484 | |||
485 | if (!message) | ||
486 | goto get_link; | ||
487 | |||
488 | static struct GNUNET_MESSENGER_MessageLink link; | ||
489 | |||
490 | GNUNET_memcpy(&(link.first), &(message->header.previous), sizeof(link.first)); | ||
491 | |||
492 | link.multiple = GNUNET_MESSENGER_KIND_MERGE == message->header.kind? GNUNET_YES : GNUNET_NO; | ||
493 | |||
494 | if (GNUNET_YES == link.multiple) | ||
495 | GNUNET_memcpy(&(link.second), &(message->body.merge.previous), sizeof(link.second)); | ||
496 | else | ||
497 | GNUNET_memcpy(&(link.second), &(message->header.previous), sizeof(link.second)); | ||
498 | |||
499 | return &link; | ||
500 | |||
501 | get_link: | ||
502 | return GNUNET_CONTAINER_multihashmap_get (store->links, hash); | ||
503 | } | ||
504 | |||
505 | int | ||
506 | put_store_message (struct GNUNET_MESSENGER_MessageStore *store, | ||
507 | const struct GNUNET_HashCode *hash, | ||
508 | struct GNUNET_MESSENGER_Message *message) | ||
509 | { | ||
510 | GNUNET_assert((store) && (hash) && (message)); | ||
511 | |||
512 | return GNUNET_CONTAINER_multihashmap_put (store->messages, hash, message, | ||
513 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST); | ||
514 | } | ||
515 | |||
516 | static void | ||
517 | add_link (struct GNUNET_MESSENGER_MessageStore *store, | ||
518 | const struct GNUNET_HashCode *hash, | ||
519 | const struct GNUNET_MESSENGER_Message *message) | ||
520 | { | ||
521 | struct GNUNET_MESSENGER_MessageLink *link = GNUNET_new(struct GNUNET_MESSENGER_MessageLink); | ||
522 | |||
523 | GNUNET_memcpy(&(link->first), &(message->header.previous), sizeof(link->first)); | ||
524 | |||
525 | link->multiple = GNUNET_MESSENGER_KIND_MERGE == message->header.kind? GNUNET_YES : GNUNET_NO; | ||
526 | |||
527 | if (GNUNET_YES == link->multiple) | ||
528 | GNUNET_memcpy(&(link->second), &(message->body.merge.previous), sizeof(link->second)); | ||
529 | else | ||
530 | GNUNET_memcpy(&(link->second), &(message->header.previous), sizeof(link->second)); | ||
531 | |||
532 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(store->links, hash, link, | ||
533 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
534 | GNUNET_free(link); | ||
535 | } | ||
536 | |||
537 | int | ||
538 | delete_store_message (struct GNUNET_MESSENGER_MessageStore *store, | ||
539 | const struct GNUNET_HashCode *hash) | ||
540 | { | ||
541 | GNUNET_assert((store) && (hash)); | ||
542 | |||
543 | const struct GNUNET_MESSENGER_MessageEntry *entry = GNUNET_CONTAINER_multihashmap_get (store->entries, hash); | ||
544 | |||
545 | if (!entry) | ||
546 | goto clear_memory; | ||
547 | |||
548 | const struct GNUNET_MESSENGER_Message *message = get_store_message(store, hash); | ||
549 | |||
550 | if (message) | ||
551 | add_link (store, hash, message); | ||
552 | |||
553 | if (!store->storage_messages) | ||
554 | goto clear_entry; | ||
555 | |||
556 | if (entry->offset != GNUNET_DISK_file_seek (store->storage_messages, entry->offset, GNUNET_DISK_SEEK_SET)) | ||
557 | return GNUNET_SYSERR; | ||
558 | |||
559 | char *clear_buffer = GNUNET_malloc(entry->length); | ||
560 | |||
561 | if (!clear_buffer) | ||
562 | return GNUNET_SYSERR; | ||
563 | |||
564 | GNUNET_CRYPTO_zero_keys (clear_buffer, entry->length); | ||
565 | |||
566 | if ((entry->length != GNUNET_DISK_file_write (store->storage_messages, clear_buffer, entry->length)) || (GNUNET_OK | ||
567 | != GNUNET_DISK_file_sync (store->storage_messages))) | ||
568 | { | ||
569 | GNUNET_free(clear_buffer); | ||
570 | return GNUNET_SYSERR; | ||
571 | } | ||
572 | |||
573 | GNUNET_free(clear_buffer); | ||
574 | |||
575 | clear_entry: | ||
576 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (store->entries, hash, entry)) | ||
577 | store->rewrite_entries = GNUNET_YES; | ||
578 | |||
579 | clear_memory: | ||
580 | GNUNET_CONTAINER_multihashmap_remove_all (store->messages, hash); | ||
581 | return GNUNET_OK; | ||
582 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_message_store.h b/src/messenger/gnunet-service-messenger_message_store.h deleted file mode 100644 index 476d98dd5..000000000 --- a/src/messenger/gnunet-service-messenger_message_store.h +++ /dev/null | |||
@@ -1,169 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_message_store.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_MESSAGE_STORE_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_MESSAGE_STORE_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_container_lib.h" | ||
31 | #include "gnunet_disk_lib.h" | ||
32 | |||
33 | struct GNUNET_MESSENGER_MessageEntry | ||
34 | { | ||
35 | off_t offset; | ||
36 | uint16_t length; | ||
37 | }; | ||
38 | |||
39 | struct GNUNET_MESSENGER_Message; | ||
40 | |||
41 | struct GNUNET_MESSENGER_MessageLink | ||
42 | { | ||
43 | uint8_t multiple; | ||
44 | |||
45 | struct GNUNET_HashCode first; | ||
46 | struct GNUNET_HashCode second; | ||
47 | }; | ||
48 | |||
49 | struct GNUNET_MESSENGER_MessageStore | ||
50 | { | ||
51 | struct GNUNET_DISK_FileHandle *storage_messages; | ||
52 | |||
53 | struct GNUNET_CONTAINER_MultiHashMap *entries; | ||
54 | struct GNUNET_CONTAINER_MultiHashMap *messages; | ||
55 | struct GNUNET_CONTAINER_MultiHashMap *links; | ||
56 | |||
57 | int rewrite_entries; | ||
58 | int write_links; | ||
59 | }; | ||
60 | |||
61 | /** | ||
62 | * Initializes a message <i>store</i> as fully empty. | ||
63 | * | ||
64 | * @param[out] store Message store | ||
65 | */ | ||
66 | void | ||
67 | init_message_store (struct GNUNET_MESSENGER_MessageStore *store); | ||
68 | |||
69 | /** | ||
70 | * Clears a message <i>store</i>, wipes its content and deallocates its memory. | ||
71 | * | ||
72 | * @param[in/out] store Message store | ||
73 | */ | ||
74 | void | ||
75 | clear_message_store (struct GNUNET_MESSENGER_MessageStore *store); | ||
76 | |||
77 | /** | ||
78 | * Loads messages from a <i>directory</i> into a message <i>store</i>. | ||
79 | * | ||
80 | * @param[out] store Message store | ||
81 | * @param[in] directory Path to a directory | ||
82 | */ | ||
83 | void | ||
84 | load_message_store (struct GNUNET_MESSENGER_MessageStore *store, | ||
85 | const char *directory); | ||
86 | |||
87 | /** | ||
88 | * Saves messages from a message <i>store</i> into a <i>directory</i>. | ||
89 | * | ||
90 | * @param[in] store Message store | ||
91 | * @param[in] directory Path to a directory | ||
92 | */ | ||
93 | void | ||
94 | save_message_store (struct GNUNET_MESSENGER_MessageStore *store, | ||
95 | const char *directory); | ||
96 | |||
97 | /** | ||
98 | * Checks if a message matching a given <i>hash</i> is stored in a message <i>store</i>. | ||
99 | * The function returns #GNUNET_YES if a match is found, #GNUNET_NO otherwise. | ||
100 | * | ||
101 | * The message has not to be loaded from disk into memory for this check! | ||
102 | * | ||
103 | * @param[in] store Message store | ||
104 | * @param[in] hash Hash of message | ||
105 | * @return #GNUNET_YES on match, otherwise #GNUNET_NO | ||
106 | */ | ||
107 | int | ||
108 | contains_store_message (const struct GNUNET_MESSENGER_MessageStore *store, | ||
109 | const struct GNUNET_HashCode *hash); | ||
110 | |||
111 | /** | ||
112 | * Returns the message from a message <i>store</i> matching a given <i>hash</i>. If no matching | ||
113 | * message is found, NULL gets returned. | ||
114 | * | ||
115 | * This function requires the message to be loaded into memory! | ||
116 | * @see contains_store_message() | ||
117 | * | ||
118 | * @param[in/out] store Message store | ||
119 | * @param[in] hash Hash of message | ||
120 | * @return Message or NULL | ||
121 | */ | ||
122 | const struct GNUNET_MESSENGER_Message* | ||
123 | get_store_message (struct GNUNET_MESSENGER_MessageStore *store, | ||
124 | const struct GNUNET_HashCode *hash); | ||
125 | |||
126 | /** | ||
127 | * Returns the message link from a message <i>store</i> matching a given <i>hash</i>. If the | ||
128 | * flag is set to #GNUNET_YES, only links from deleted messages will be returned or NULL. | ||
129 | * | ||
130 | * Otherwise message links will also returned for messages found in the store under the given | ||
131 | * hash. The link which will be returned copies link information from the message for | ||
132 | * temporary usage. | ||
133 | * | ||
134 | * @param[in/out] store Message store | ||
135 | * @param[in] hash Hash of message | ||
136 | * @param[in] deleted_only Flag | ||
137 | * @return Message link or NULL | ||
138 | */ | ||
139 | const struct GNUNET_MESSENGER_MessageLink* | ||
140 | get_store_message_link (struct GNUNET_MESSENGER_MessageStore *store, | ||
141 | const struct GNUNET_HashCode *hash, | ||
142 | int deleted_only); | ||
143 | |||
144 | /** | ||
145 | * Stores a message into the message store. The result indicates if the operation was successful. | ||
146 | * | ||
147 | * @param[in/out] store Message store | ||
148 | * @param[in] hash Hash of message | ||
149 | * @param[in/out] message Message | ||
150 | * @return #GNUNET_OK on success, otherwise #GNUNET_NO | ||
151 | */ | ||
152 | int | ||
153 | put_store_message (struct GNUNET_MESSENGER_MessageStore *store, | ||
154 | const struct GNUNET_HashCode *hash, | ||
155 | struct GNUNET_MESSENGER_Message *message); | ||
156 | |||
157 | /** | ||
158 | * Deletes a message in the message store. It will be removed from disk space and memory. The result | ||
159 | * indicates if the operation was successful. | ||
160 | * | ||
161 | * @param[in/out] store Message store | ||
162 | * @param[in] hash Hash of message | ||
163 | * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure | ||
164 | */ | ||
165 | int | ||
166 | delete_store_message (struct GNUNET_MESSENGER_MessageStore *store, | ||
167 | const struct GNUNET_HashCode *hash); | ||
168 | |||
169 | #endif //GNUNET_SERVICE_MESSENGER_MESSAGE_STORE_H | ||
diff --git a/src/messenger/gnunet-service-messenger_operation.c b/src/messenger/gnunet-service-messenger_operation.c deleted file mode 100644 index 2b92d0c1d..000000000 --- a/src/messenger/gnunet-service-messenger_operation.c +++ /dev/null | |||
@@ -1,220 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_operation.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_operation.h" | ||
27 | |||
28 | #include "gnunet-service-messenger_operation_store.h" | ||
29 | |||
30 | struct GNUNET_MESSENGER_Operation* | ||
31 | create_operation (const struct GNUNET_HashCode *hash) | ||
32 | { | ||
33 | GNUNET_assert(hash); | ||
34 | |||
35 | struct GNUNET_MESSENGER_Operation *op = GNUNET_new(struct GNUNET_MESSENGER_Operation); | ||
36 | |||
37 | op->type = GNUNET_MESSENGER_OP_UNKNOWN; | ||
38 | GNUNET_memcpy(&(op->hash), hash, sizeof(*hash)); | ||
39 | op->timestamp = GNUNET_TIME_absolute_get_zero_(); | ||
40 | op->store = NULL; | ||
41 | op->task = NULL; | ||
42 | |||
43 | return op; | ||
44 | } | ||
45 | |||
46 | void | ||
47 | destroy_operation (struct GNUNET_MESSENGER_Operation *op) | ||
48 | { | ||
49 | GNUNET_assert(op); | ||
50 | |||
51 | if (op->task) | ||
52 | GNUNET_SCHEDULER_cancel(op->task); | ||
53 | |||
54 | GNUNET_free(op); | ||
55 | } | ||
56 | |||
57 | static void | ||
58 | callback_operation (void *cls); | ||
59 | |||
60 | struct GNUNET_MESSENGER_Operation* | ||
61 | load_operation (struct GNUNET_MESSENGER_OperationStore *store, | ||
62 | const char *path) | ||
63 | { | ||
64 | GNUNET_assert((store) && (path)); | ||
65 | |||
66 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Load operation configuration: %s\n", path); | ||
67 | |||
68 | struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create (); | ||
69 | struct GNUNET_MESSENGER_Operation* op = NULL; | ||
70 | |||
71 | if (GNUNET_OK != GNUNET_CONFIGURATION_parse(cfg, path)) | ||
72 | goto destroy_config; | ||
73 | |||
74 | struct GNUNET_HashCode hash; | ||
75 | |||
76 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_data (cfg, "operation", "hash", &hash, sizeof(hash))) | ||
77 | goto destroy_config; | ||
78 | |||
79 | op = create_operation(&hash); | ||
80 | |||
81 | unsigned long long type_number; | ||
82 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number(cfg, "operation", "type", &type_number)) | ||
83 | switch (type_number) | ||
84 | { | ||
85 | case GNUNET_MESSENGER_OP_REQUEST: | ||
86 | op->type = GNUNET_MESSENGER_OP_REQUEST; | ||
87 | break; | ||
88 | case GNUNET_MESSENGER_OP_DELETE: | ||
89 | op->type = GNUNET_MESSENGER_OP_DELETE; | ||
90 | break; | ||
91 | case GNUNET_MESSENGER_OP_MERGE: | ||
92 | op->type = GNUNET_MESSENGER_OP_MERGE; | ||
93 | break; | ||
94 | default: | ||
95 | break; | ||
96 | } | ||
97 | |||
98 | if ((GNUNET_MESSENGER_OP_UNKNOWN == op->type) || | ||
99 | (GNUNET_OK != GNUNET_CONFIGURATION_get_data (cfg, "operation", "timestamp", &(op->timestamp), sizeof(op->timestamp)))) | ||
100 | { | ||
101 | destroy_operation(op); | ||
102 | op = NULL; | ||
103 | goto destroy_config; | ||
104 | } | ||
105 | |||
106 | const struct GNUNET_TIME_Relative delay = GNUNET_TIME_absolute_get_remaining(op->timestamp); | ||
107 | |||
108 | op->task = GNUNET_SCHEDULER_add_delayed_with_priority( | ||
109 | delay, | ||
110 | GNUNET_SCHEDULER_PRIORITY_BACKGROUND, | ||
111 | callback_operation, | ||
112 | op | ||
113 | ); | ||
114 | |||
115 | op->store = store; | ||
116 | |||
117 | destroy_config: | ||
118 | GNUNET_CONFIGURATION_destroy (cfg); | ||
119 | |||
120 | return op; | ||
121 | } | ||
122 | |||
123 | void | ||
124 | save_operation (const struct GNUNET_MESSENGER_Operation *op, | ||
125 | const char *path) | ||
126 | { | ||
127 | GNUNET_assert((path) && (op)); | ||
128 | |||
129 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Save operation configuration: %s\n", path); | ||
130 | |||
131 | struct GNUNET_CONFIGURATION_Handle *cfg = GNUNET_CONFIGURATION_create (); | ||
132 | |||
133 | char *hash_data; | ||
134 | hash_data = GNUNET_STRINGS_data_to_string_alloc (&(op->hash), sizeof(op->hash)); | ||
135 | |||
136 | if (hash_data) | ||
137 | { | ||
138 | GNUNET_CONFIGURATION_set_value_string (cfg, "operation", "hash", hash_data); | ||
139 | |||
140 | GNUNET_free(hash_data); | ||
141 | } | ||
142 | |||
143 | GNUNET_CONFIGURATION_set_value_number(cfg, "operation", "type", op->type); | ||
144 | |||
145 | char *timestamp_data; | ||
146 | timestamp_data = GNUNET_STRINGS_data_to_string_alloc (&(op->timestamp), sizeof(op->timestamp)); | ||
147 | |||
148 | if (timestamp_data) | ||
149 | { | ||
150 | GNUNET_CONFIGURATION_set_value_string (cfg, "operation", "timestamp", timestamp_data); | ||
151 | |||
152 | GNUNET_free(timestamp_data); | ||
153 | } | ||
154 | |||
155 | GNUNET_CONFIGURATION_write (cfg, path); | ||
156 | GNUNET_CONFIGURATION_destroy (cfg); | ||
157 | } | ||
158 | |||
159 | extern void | ||
160 | callback_store_operation (struct GNUNET_MESSENGER_OperationStore *store, | ||
161 | enum GNUNET_MESSENGER_OperationType type, | ||
162 | const struct GNUNET_HashCode *hash); | ||
163 | |||
164 | static void | ||
165 | callback_operation (void *cls) | ||
166 | { | ||
167 | struct GNUNET_MESSENGER_Operation *op = cls; | ||
168 | |||
169 | op->task = NULL; | ||
170 | |||
171 | callback_store_operation (op->store, op->type, &(op->hash)); | ||
172 | } | ||
173 | |||
174 | int | ||
175 | start_operation (struct GNUNET_MESSENGER_Operation *op, | ||
176 | enum GNUNET_MESSENGER_OperationType type, | ||
177 | struct GNUNET_MESSENGER_OperationStore *store, | ||
178 | struct GNUNET_TIME_Relative delay) | ||
179 | { | ||
180 | GNUNET_assert((op) && (store)); | ||
181 | |||
182 | if (op->task) | ||
183 | return GNUNET_SYSERR; | ||
184 | |||
185 | const struct GNUNET_TIME_Absolute timestamp = GNUNET_TIME_absolute_add( | ||
186 | GNUNET_TIME_absolute_get(), | ||
187 | delay | ||
188 | ); | ||
189 | |||
190 | op->task = GNUNET_SCHEDULER_add_delayed_with_priority( | ||
191 | delay, | ||
192 | GNUNET_SCHEDULER_PRIORITY_BACKGROUND, | ||
193 | callback_operation, | ||
194 | op | ||
195 | ); | ||
196 | |||
197 | op->type = type; | ||
198 | op->timestamp = timestamp; | ||
199 | op->store = store; | ||
200 | |||
201 | return GNUNET_OK; | ||
202 | } | ||
203 | |||
204 | int | ||
205 | stop_operation (struct GNUNET_MESSENGER_Operation *op) | ||
206 | { | ||
207 | GNUNET_assert(op); | ||
208 | |||
209 | if (!op->task) | ||
210 | return GNUNET_SYSERR; | ||
211 | |||
212 | GNUNET_SCHEDULER_cancel(op->task); | ||
213 | op->task = NULL; | ||
214 | |||
215 | op->type = GNUNET_MESSENGER_OP_UNKNOWN; | ||
216 | op->timestamp = GNUNET_TIME_absolute_get_zero_(); | ||
217 | op->store = NULL; | ||
218 | |||
219 | return GNUNET_OK; | ||
220 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_operation.h b/src/messenger/gnunet-service-messenger_operation.h deleted file mode 100644 index 485668548..000000000 --- a/src/messenger/gnunet-service-messenger_operation.h +++ /dev/null | |||
@@ -1,131 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_operation.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_OPERATION_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_OPERATION_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_configuration_lib.h" | ||
31 | #include "gnunet_crypto_lib.h" | ||
32 | #include "gnunet_scheduler_lib.h" | ||
33 | #include "gnunet_strings_lib.h" | ||
34 | #include "gnunet_time_lib.h" | ||
35 | |||
36 | enum GNUNET_MESSENGER_OperationType | ||
37 | { | ||
38 | GNUNET_MESSENGER_OP_REQUEST = 1, | ||
39 | GNUNET_MESSENGER_OP_DELETE = 2, | ||
40 | GNUNET_MESSENGER_OP_MERGE = 3, | ||
41 | |||
42 | GNUNET_MESSENGER_OP_UNKNOWN = 0 | ||
43 | }; | ||
44 | |||
45 | struct GNUNET_MESSENGER_OperationStore; | ||
46 | |||
47 | struct GNUNET_MESSENGER_Operation | ||
48 | { | ||
49 | enum GNUNET_MESSENGER_OperationType type; | ||
50 | |||
51 | struct GNUNET_HashCode hash; | ||
52 | struct GNUNET_TIME_Absolute timestamp; | ||
53 | |||
54 | struct GNUNET_MESSENGER_OperationStore *store; | ||
55 | struct GNUNET_SCHEDULER_Task* task; | ||
56 | }; | ||
57 | |||
58 | /** | ||
59 | * Creates and allocates a new operation under a given <i>hash</i>. | ||
60 | * | ||
61 | * @param[in] hash Hash of message | ||
62 | */ | ||
63 | struct GNUNET_MESSENGER_Operation* | ||
64 | create_operation (const struct GNUNET_HashCode *hash); | ||
65 | |||
66 | /** | ||
67 | * Destroys an operation and frees its memory fully. | ||
68 | * | ||
69 | * @param[in/out] op Operation | ||
70 | */ | ||
71 | void | ||
72 | destroy_operation (struct GNUNET_MESSENGER_Operation *op); | ||
73 | |||
74 | /** | ||
75 | * Loads data from a configuration file at a selected <i>path</i> into | ||
76 | * a new allocated and created operation for a specific operation | ||
77 | * <i>store</i> if the required information could be read successfully. | ||
78 | * | ||
79 | * The method will return the new operation and it will be started | ||
80 | * automatically to match its timestamp of execution. | ||
81 | * | ||
82 | * If the method fails to restore any valid operation from the file, | ||
83 | * NULL gets returned instead. | ||
84 | * | ||
85 | * @param[in/out] store Operation store | ||
86 | * @param[in] path Path of a configuration file | ||
87 | */ | ||
88 | struct GNUNET_MESSENGER_Operation* | ||
89 | load_operation (struct GNUNET_MESSENGER_OperationStore *store, | ||
90 | const char *path); | ||
91 | |||
92 | /** | ||
93 | * Saves data from an <i>operation</i> into a configuration file at a | ||
94 | * selected <i>path</i> which can be load to restore the operation | ||
95 | * completely and continue its process. | ||
96 | * | ||
97 | * @param[in] op Operation | ||
98 | * @param[in] path Path of a configuration file | ||
99 | */ | ||
100 | void | ||
101 | save_operation (const struct GNUNET_MESSENGER_Operation *op, | ||
102 | const char *path); | ||
103 | |||
104 | /** | ||
105 | * Starts an inactive operation with a given <i>delay</i> in a | ||
106 | * specific operation <i>store</i>. The method will replace the | ||
107 | * operations type to process it correctly. An operation can't be | ||
108 | * started twice, it has to be stopped or fully processed first. | ||
109 | * | ||
110 | * @param[in/out] op Operation | ||
111 | * @param[in] type Type of operation | ||
112 | * @param[in/out] store Operation store | ||
113 | * @param[in] delay Delay | ||
114 | * @return #GNUNET_OK on success, otherwise #GNUNET_SYSERR | ||
115 | */ | ||
116 | int | ||
117 | start_operation (struct GNUNET_MESSENGER_Operation *op, | ||
118 | enum GNUNET_MESSENGER_OperationType type, | ||
119 | struct GNUNET_MESSENGER_OperationStore *store, | ||
120 | struct GNUNET_TIME_Relative delay); | ||
121 | |||
122 | /** | ||
123 | * Stops an active operation and resets its type to be | ||
124 | * #GNUNET_MESSENGER_OP_UNKNOWN. | ||
125 | * | ||
126 | * @return #GNUNET_OK on success, otherwise #GNUNET_SYSERR | ||
127 | */ | ||
128 | int | ||
129 | stop_operation (struct GNUNET_MESSENGER_Operation *op); | ||
130 | |||
131 | #endif //GNUNET_SERVICE_MESSENGER_OPERATION_H | ||
diff --git a/src/messenger/gnunet-service-messenger_operation_store.c b/src/messenger/gnunet-service-messenger_operation_store.c deleted file mode 100644 index 276f0b92b..000000000 --- a/src/messenger/gnunet-service-messenger_operation_store.c +++ /dev/null | |||
@@ -1,236 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_operation_store.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_operation_store.h" | ||
27 | |||
28 | #include "gnunet-service-messenger_operation.h" | ||
29 | #include "gnunet-service-messenger_room.h" | ||
30 | |||
31 | void | ||
32 | init_operation_store (struct GNUNET_MESSENGER_OperationStore *store, | ||
33 | struct GNUNET_MESSENGER_SrvRoom *room) | ||
34 | { | ||
35 | GNUNET_assert((store) && (room)); | ||
36 | |||
37 | store->room = room; | ||
38 | store->operations = GNUNET_CONTAINER_multihashmap_create(8, GNUNET_NO); | ||
39 | } | ||
40 | |||
41 | static int | ||
42 | iterate_destroy_operations (void *cls, | ||
43 | const struct GNUNET_HashCode *key, | ||
44 | void *value) | ||
45 | { | ||
46 | struct GNUNET_MESSENGER_Operation *op = value; | ||
47 | |||
48 | destroy_operation(op); | ||
49 | |||
50 | return GNUNET_YES; | ||
51 | } | ||
52 | |||
53 | void | ||
54 | clear_operation_store (struct GNUNET_MESSENGER_OperationStore *store) | ||
55 | { | ||
56 | GNUNET_assert(store); | ||
57 | |||
58 | GNUNET_CONTAINER_multihashmap_iterate (store->operations, iterate_destroy_operations, NULL); | ||
59 | GNUNET_CONTAINER_multihashmap_destroy(store->operations); | ||
60 | } | ||
61 | |||
62 | static int | ||
63 | callback_scan_for_operations (void *cls, | ||
64 | const char *filename) | ||
65 | { | ||
66 | struct GNUNET_MESSENGER_OperationStore *store = cls; | ||
67 | |||
68 | if (GNUNET_YES != GNUNET_DISK_file_test (filename)) | ||
69 | return GNUNET_OK; | ||
70 | |||
71 | if ((strlen(filename) <= 4) || (0 != strcmp(filename + strlen(filename) - 4, ".cfg"))) | ||
72 | return GNUNET_OK; | ||
73 | |||
74 | struct GNUNET_MESSENGER_Operation *op = load_operation(store, filename); | ||
75 | |||
76 | if ((op) && (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put( | ||
77 | store->operations, | ||
78 | &(op->hash), op, | ||
79 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) | ||
80 | { | ||
81 | destroy_operation(op); | ||
82 | } | ||
83 | |||
84 | return GNUNET_OK; | ||
85 | } | ||
86 | |||
87 | void | ||
88 | load_operation_store (struct GNUNET_MESSENGER_OperationStore *store, | ||
89 | const char *directory) | ||
90 | { | ||
91 | GNUNET_assert ((store) && (directory)); | ||
92 | |||
93 | char* load_dir; | ||
94 | GNUNET_asprintf (&load_dir, "%s%s%c", directory, "operations", DIR_SEPARATOR); | ||
95 | |||
96 | if (GNUNET_OK == GNUNET_DISK_directory_test (load_dir, GNUNET_YES)) | ||
97 | GNUNET_DISK_directory_scan (load_dir, callback_scan_for_operations, store); | ||
98 | |||
99 | GNUNET_free(load_dir); | ||
100 | } | ||
101 | |||
102 | static int | ||
103 | iterate_save_operations (void *cls, | ||
104 | const struct GNUNET_HashCode *key, | ||
105 | void *value) | ||
106 | { | ||
107 | const char *save_dir = cls; | ||
108 | |||
109 | struct GNUNET_MESSENGER_Operation *op = value; | ||
110 | |||
111 | if (!op) | ||
112 | return GNUNET_YES; | ||
113 | |||
114 | char *op_dir; | ||
115 | GNUNET_asprintf (&op_dir, "%s%s.cfg", save_dir, GNUNET_h2s(key)); | ||
116 | save_operation(op, op_dir); | ||
117 | |||
118 | GNUNET_free(op_dir); | ||
119 | return GNUNET_YES; | ||
120 | } | ||
121 | |||
122 | void | ||
123 | save_operation_store (const struct GNUNET_MESSENGER_OperationStore *store, | ||
124 | const char *directory) | ||
125 | { | ||
126 | GNUNET_assert ((store) && (directory)); | ||
127 | |||
128 | char* save_dir; | ||
129 | GNUNET_asprintf (&save_dir, "%s%s%c", directory, "operations", DIR_SEPARATOR); | ||
130 | |||
131 | if ((GNUNET_YES == GNUNET_DISK_directory_test (save_dir, GNUNET_NO)) || | ||
132 | (GNUNET_OK == GNUNET_DISK_directory_create (save_dir))) | ||
133 | GNUNET_CONTAINER_multihashmap_iterate (store->operations, iterate_save_operations, save_dir); | ||
134 | |||
135 | GNUNET_free(save_dir); | ||
136 | } | ||
137 | |||
138 | enum GNUNET_MESSENGER_OperationType | ||
139 | get_store_operation_type (const struct GNUNET_MESSENGER_OperationStore *store, | ||
140 | const struct GNUNET_HashCode *hash) | ||
141 | { | ||
142 | GNUNET_assert((store) && (hash)); | ||
143 | |||
144 | struct GNUNET_MESSENGER_Operation *op = GNUNET_CONTAINER_multihashmap_get(store->operations, hash); | ||
145 | |||
146 | if (!op) | ||
147 | return GNUNET_MESSENGER_OP_UNKNOWN; | ||
148 | |||
149 | return op->type; | ||
150 | } | ||
151 | |||
152 | int | ||
153 | use_store_operation (struct GNUNET_MESSENGER_OperationStore *store, | ||
154 | const struct GNUNET_HashCode *hash, | ||
155 | enum GNUNET_MESSENGER_OperationType type, | ||
156 | struct GNUNET_TIME_Relative delay) | ||
157 | { | ||
158 | GNUNET_assert((store) && (hash)); | ||
159 | |||
160 | struct GNUNET_MESSENGER_Operation *op = GNUNET_CONTAINER_multihashmap_get(store->operations, hash); | ||
161 | |||
162 | if (op) | ||
163 | goto use_op; | ||
164 | |||
165 | op = create_operation(hash); | ||
166 | |||
167 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(store->operations, hash, op, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
168 | { | ||
169 | destroy_operation(op); | ||
170 | |||
171 | return GNUNET_SYSERR; | ||
172 | } | ||
173 | |||
174 | use_op: | ||
175 | if ((op->type != GNUNET_MESSENGER_OP_UNKNOWN) && | ||
176 | (type == GNUNET_MESSENGER_OP_DELETE)) | ||
177 | stop_operation (op); | ||
178 | |||
179 | return start_operation(op, type, store, delay); | ||
180 | } | ||
181 | |||
182 | void | ||
183 | cancel_store_operation (struct GNUNET_MESSENGER_OperationStore *store, | ||
184 | const struct GNUNET_HashCode *hash) | ||
185 | { | ||
186 | GNUNET_assert((store) && (hash)); | ||
187 | |||
188 | struct GNUNET_MESSENGER_Operation *op = GNUNET_CONTAINER_multihashmap_get(store->operations, hash); | ||
189 | |||
190 | if (!op) | ||
191 | return; | ||
192 | |||
193 | stop_operation(op); | ||
194 | |||
195 | if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove(store->operations, hash, op)) | ||
196 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Canceled operation could not be removed: %s\n", | ||
197 | GNUNET_h2s(hash)); | ||
198 | |||
199 | destroy_operation(op); | ||
200 | } | ||
201 | |||
202 | extern void | ||
203 | callback_room_deletion (struct GNUNET_MESSENGER_SrvRoom *room, | ||
204 | const struct GNUNET_HashCode *hash); | ||
205 | |||
206 | extern void | ||
207 | callback_room_merge (struct GNUNET_MESSENGER_SrvRoom *room, | ||
208 | const struct GNUNET_HashCode *hash); | ||
209 | |||
210 | void | ||
211 | callback_store_operation (struct GNUNET_MESSENGER_OperationStore *store, | ||
212 | enum GNUNET_MESSENGER_OperationType type, | ||
213 | const struct GNUNET_HashCode *hash) | ||
214 | { | ||
215 | GNUNET_assert((store) && (hash)); | ||
216 | |||
217 | struct GNUNET_HashCode op_hash; | ||
218 | GNUNET_memcpy(&op_hash, hash, sizeof(op_hash)); | ||
219 | cancel_store_operation (store, &op_hash); | ||
220 | |||
221 | struct GNUNET_MESSENGER_SrvRoom *room = store->room; | ||
222 | |||
223 | switch (type) | ||
224 | { | ||
225 | case GNUNET_MESSENGER_OP_REQUEST: | ||
226 | break; | ||
227 | case GNUNET_MESSENGER_OP_DELETE: | ||
228 | callback_room_deletion (room, &op_hash); | ||
229 | break; | ||
230 | case GNUNET_MESSENGER_OP_MERGE: | ||
231 | callback_room_merge (room, &op_hash); | ||
232 | break; | ||
233 | default: | ||
234 | break; | ||
235 | } | ||
236 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_operation_store.h b/src/messenger/gnunet-service-messenger_operation_store.h deleted file mode 100644 index 18eb7f8a1..000000000 --- a/src/messenger/gnunet-service-messenger_operation_store.h +++ /dev/null | |||
@@ -1,132 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_operation_store.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_OPERATION_STORE_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_OPERATION_STORE_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_container_lib.h" | ||
31 | #include "gnunet_crypto_lib.h" | ||
32 | #include "gnunet_scheduler_lib.h" | ||
33 | #include "gnunet_time_lib.h" | ||
34 | |||
35 | struct GNUNET_MESSENGER_SrvRoom; | ||
36 | |||
37 | struct GNUNET_MESSENGER_OperationStore | ||
38 | { | ||
39 | struct GNUNET_MESSENGER_SrvRoom *room; | ||
40 | |||
41 | struct GNUNET_CONTAINER_MultiHashMap *operations; | ||
42 | }; | ||
43 | |||
44 | /** | ||
45 | * Initializes an operation <i>store</i> as fully empty with a given <i>room</i>. | ||
46 | * | ||
47 | * @param[out] store Operation store | ||
48 | * @param[in/out] room Room | ||
49 | */ | ||
50 | void | ||
51 | init_operation_store (struct GNUNET_MESSENGER_OperationStore *store, | ||
52 | struct GNUNET_MESSENGER_SrvRoom *room); | ||
53 | |||
54 | /** | ||
55 | * Clears an operation <i>store</i>, stops all operations and deallocates its memory. | ||
56 | * | ||
57 | * @param[in/out] store Operation store | ||
58 | */ | ||
59 | void | ||
60 | clear_operation_store (struct GNUNET_MESSENGER_OperationStore *store); | ||
61 | |||
62 | /** | ||
63 | * Loads operations from a <i>directory</i> into an operation <i>store</i>. | ||
64 | * | ||
65 | * @param[out] store Operation store | ||
66 | * @param[in] directory Path to a directory | ||
67 | */ | ||
68 | void | ||
69 | load_operation_store (struct GNUNET_MESSENGER_OperationStore *store, | ||
70 | const char *directory); | ||
71 | |||
72 | /** | ||
73 | * Saves operations from an operation <i>store</i> into a <i>directory</i>. | ||
74 | * | ||
75 | * @param[in] store Operation store | ||
76 | * @param[in] directory Path to a directory | ||
77 | */ | ||
78 | void | ||
79 | save_operation_store (const struct GNUNET_MESSENGER_OperationStore *store, | ||
80 | const char *directory); | ||
81 | |||
82 | /** | ||
83 | * Returns the type of the active operation under a given <i>hash</i> in | ||
84 | * a specific operation <i>store</i>. If there is no active operation under | ||
85 | * the given <i>hash</i>, #GNUNET_MESSENGER_OP_UNKNOWN gets returned instead. | ||
86 | * | ||
87 | * @param[in] store Operation store | ||
88 | * @param[in] hash Hash of message | ||
89 | * @return Type of operation or #GNUNET_MESSENGER_OP_UNKNOWN | ||
90 | */ | ||
91 | enum GNUNET_MESSENGER_OperationType | ||
92 | get_store_operation_type (const struct GNUNET_MESSENGER_OperationStore *store, | ||
93 | const struct GNUNET_HashCode *hash); | ||
94 | |||
95 | /** | ||
96 | * Tries to use an operation under a given <i>hash</i> in a specific | ||
97 | * operation <i>store</i>. The operation will use the selected <i>type</i> | ||
98 | * if successful. The operation will be delayed by a given <i>delay</i>. | ||
99 | * | ||
100 | * If the selected type is #GNUNET_MESSENGER_OP_DELETE any active operation | ||
101 | * under the given hash will be stopped and replaced. | ||
102 | * | ||
103 | * If the new operation could be started successfully the method returns | ||
104 | * #GNUNET_OK, otherwise #GNUNET_SYSERR. | ||
105 | * | ||
106 | * @param[in/out] store Operation store | ||
107 | * @param[in] hash Hash of message | ||
108 | * @param[in] type Operation type | ||
109 | * @param[in] delay Delay | ||
110 | * @return #GNUNET_OK on success, otherwise #GNUNET_SYSERR | ||
111 | */ | ||
112 | int | ||
113 | use_store_operation (struct GNUNET_MESSENGER_OperationStore *store, | ||
114 | const struct GNUNET_HashCode *hash, | ||
115 | enum GNUNET_MESSENGER_OperationType type, | ||
116 | struct GNUNET_TIME_Relative delay); | ||
117 | |||
118 | /** | ||
119 | * Stops any active operation under a given <i>hash</i> in a specific | ||
120 | * operation <i>store</i>. | ||
121 | * | ||
122 | * Beware that calling this method will also implicitly free the memory | ||
123 | * of any active operation under the given hash! | ||
124 | * | ||
125 | * @param[in/out] store Operation store | ||
126 | * @param[in] hash Hash of message | ||
127 | */ | ||
128 | void | ||
129 | cancel_store_operation (struct GNUNET_MESSENGER_OperationStore *store, | ||
130 | const struct GNUNET_HashCode *hash); | ||
131 | |||
132 | #endif //GNUNET_SERVICE_MESSENGER_OPERATION_STORE_H | ||
diff --git a/src/messenger/gnunet-service-messenger_room.c b/src/messenger/gnunet-service-messenger_room.c deleted file mode 100644 index 7f2fd0ca6..000000000 --- a/src/messenger/gnunet-service-messenger_room.c +++ /dev/null | |||
@@ -1,1255 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_room.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_room.h" | ||
27 | |||
28 | #include "gnunet-service-messenger_member.h" | ||
29 | #include "gnunet-service-messenger_member_session.h" | ||
30 | |||
31 | #include "gnunet-service-messenger_message_kind.h" | ||
32 | #include "gnunet-service-messenger_message_handle.h" | ||
33 | #include "gnunet-service-messenger_message_send.h" | ||
34 | |||
35 | #include "gnunet-service-messenger_operation.h" | ||
36 | |||
37 | #include "gnunet-service-messenger.h" | ||
38 | #include "gnunet-service-messenger_service.h" | ||
39 | #include "gnunet-service-messenger_tunnel.h" | ||
40 | #include "messenger_api_util.h" | ||
41 | |||
42 | static void | ||
43 | idle_request_room_messages (void *cls); | ||
44 | |||
45 | struct GNUNET_MESSENGER_SrvRoom* | ||
46 | create_room (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
47 | const struct GNUNET_HashCode *key) | ||
48 | { | ||
49 | GNUNET_assert((handle) && (key)); | ||
50 | |||
51 | struct GNUNET_MESSENGER_SrvRoom *room = GNUNET_new(struct GNUNET_MESSENGER_SrvRoom); | ||
52 | |||
53 | room->service = handle->service; | ||
54 | room->host = handle; | ||
55 | room->port = NULL; | ||
56 | |||
57 | GNUNET_memcpy(&(room->key), key, sizeof(struct GNUNET_HashCode)); | ||
58 | |||
59 | room->tunnels = GNUNET_CONTAINER_multipeermap_create (8, GNUNET_NO); | ||
60 | |||
61 | init_member_store(get_room_member_store(room), room); | ||
62 | init_message_store (get_room_message_store(room)); | ||
63 | init_operation_store(get_room_operation_store(room), room); | ||
64 | |||
65 | init_list_tunnels (&(room->basement)); | ||
66 | init_message_state(&(room->state)); | ||
67 | |||
68 | room->peer_message = NULL; | ||
69 | |||
70 | init_list_messages (&(room->handling)); | ||
71 | room->idle = NULL; | ||
72 | |||
73 | if (room->service->dir) | ||
74 | load_room (room); | ||
75 | |||
76 | room->idle = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, idle_request_room_messages, room); | ||
77 | |||
78 | return room; | ||
79 | } | ||
80 | |||
81 | static int | ||
82 | iterate_destroy_tunnels (void *cls, | ||
83 | const struct GNUNET_PeerIdentity *key, | ||
84 | void *value) | ||
85 | { | ||
86 | struct GNUNET_MESSENGER_SrvTunnel *tunnel = value; | ||
87 | destroy_tunnel (tunnel); | ||
88 | return GNUNET_YES; | ||
89 | } | ||
90 | |||
91 | static void | ||
92 | handle_room_messages (struct GNUNET_MESSENGER_SrvRoom *room); | ||
93 | |||
94 | void | ||
95 | destroy_room (struct GNUNET_MESSENGER_SrvRoom *room) | ||
96 | { | ||
97 | GNUNET_assert(room); | ||
98 | |||
99 | if (room->idle) | ||
100 | { | ||
101 | GNUNET_SCHEDULER_cancel (room->idle); | ||
102 | |||
103 | room->idle = NULL; | ||
104 | } | ||
105 | |||
106 | if (room->port) | ||
107 | GNUNET_CADET_close_port (room->port); | ||
108 | |||
109 | GNUNET_CONTAINER_multipeermap_iterate (room->tunnels, iterate_destroy_tunnels, NULL); | ||
110 | |||
111 | handle_room_messages (room); | ||
112 | |||
113 | if (room->service->dir) | ||
114 | save_room (room); | ||
115 | |||
116 | clear_member_store (get_room_member_store(room)); | ||
117 | clear_message_store (get_room_message_store(room)); | ||
118 | clear_operation_store(get_room_operation_store(room)); | ||
119 | |||
120 | GNUNET_CONTAINER_multipeermap_destroy (room->tunnels); | ||
121 | |||
122 | clear_list_tunnels (&(room->basement)); | ||
123 | clear_message_state(&(room->state)); | ||
124 | |||
125 | if (room->peer_message) | ||
126 | GNUNET_free(room->peer_message); | ||
127 | |||
128 | GNUNET_free(room); | ||
129 | } | ||
130 | |||
131 | struct GNUNET_MESSENGER_MemberStore* | ||
132 | get_room_member_store (struct GNUNET_MESSENGER_SrvRoom *room) | ||
133 | { | ||
134 | GNUNET_assert(room); | ||
135 | |||
136 | return &(room->member_store); | ||
137 | } | ||
138 | |||
139 | struct GNUNET_MESSENGER_MessageStore* | ||
140 | get_room_message_store (struct GNUNET_MESSENGER_SrvRoom *room) | ||
141 | { | ||
142 | GNUNET_assert(room); | ||
143 | |||
144 | return &(room->message_store); | ||
145 | } | ||
146 | |||
147 | struct GNUNET_MESSENGER_OperationStore* | ||
148 | get_room_operation_store (struct GNUNET_MESSENGER_SrvRoom *room) | ||
149 | { | ||
150 | GNUNET_assert(room); | ||
151 | |||
152 | return &(room->operation_store); | ||
153 | } | ||
154 | |||
155 | static int | ||
156 | send_room_info (struct GNUNET_MESSENGER_SrvRoom *room, | ||
157 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
158 | struct GNUNET_MESSENGER_SrvTunnel *tunnel) | ||
159 | { | ||
160 | if ((!handle) || (!is_tunnel_connected (tunnel))) | ||
161 | return GNUNET_NO; | ||
162 | |||
163 | return send_tunnel_message (tunnel, handle, create_message_info (get_handle_ego (handle))); | ||
164 | } | ||
165 | |||
166 | static void* | ||
167 | callback_room_connect (void *cls, | ||
168 | struct GNUNET_CADET_Channel *channel, | ||
169 | const struct GNUNET_PeerIdentity *source) | ||
170 | { | ||
171 | struct GNUNET_MESSENGER_SrvRoom *room = cls; | ||
172 | |||
173 | struct GNUNET_MESSENGER_SrvTunnel *tunnel = create_tunnel (room, source); | ||
174 | |||
175 | if ((tunnel) && | ||
176 | (GNUNET_OK != GNUNET_CONTAINER_multipeermap_put (room->tunnels, source, tunnel, | ||
177 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE))) | ||
178 | { | ||
179 | destroy_tunnel (tunnel); | ||
180 | tunnel = NULL; | ||
181 | } | ||
182 | |||
183 | if (!tunnel) | ||
184 | { | ||
185 | delayed_disconnect_channel (channel); | ||
186 | return NULL; | ||
187 | } | ||
188 | |||
189 | bind_tunnel(tunnel, channel); | ||
190 | |||
191 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "New tunnel in room (%s) established to peer: %s\n", | ||
192 | GNUNET_h2s(get_room_key(room)), GNUNET_i2s (source)); | ||
193 | |||
194 | if (GNUNET_YES == send_room_info (room, room->host, tunnel)) | ||
195 | return tunnel; | ||
196 | |||
197 | disconnect_tunnel (tunnel); | ||
198 | |||
199 | if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_remove (room->tunnels, source, tunnel)) | ||
200 | destroy_tunnel (tunnel); | ||
201 | |||
202 | return NULL; | ||
203 | } | ||
204 | |||
205 | static int | ||
206 | join_room (struct GNUNET_MESSENGER_SrvRoom *room, | ||
207 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
208 | struct GNUNET_MESSENGER_Member *member) | ||
209 | { | ||
210 | GNUNET_assert((room) && (handle) && (member)); | ||
211 | |||
212 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Joining room: %s (%s)\n", GNUNET_h2s (get_room_key (room)), | ||
213 | GNUNET_sh2s (get_member_id(member))); | ||
214 | |||
215 | const struct GNUNET_ShortHashCode *member_id = get_member_id(member); | ||
216 | |||
217 | if (GNUNET_OK != change_handle_member_id (handle, get_room_key(room), member_id)) | ||
218 | return GNUNET_NO; | ||
219 | |||
220 | struct GNUNET_MESSENGER_Message *message = create_message_join (get_handle_ego (handle)); | ||
221 | |||
222 | if (!message) | ||
223 | { | ||
224 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Your join message could not be created!\n"); | ||
225 | |||
226 | return GNUNET_NO; | ||
227 | } | ||
228 | |||
229 | GNUNET_memcpy(&(message->header.sender_id), member_id, sizeof(*member_id)); | ||
230 | return send_room_message (room, handle, message); | ||
231 | } | ||
232 | |||
233 | struct GNUNET_MESSENGER_MemberNotify | ||
234 | { | ||
235 | struct GNUNET_MESSENGER_SrvRoom *room; | ||
236 | struct GNUNET_MESSENGER_SrvHandle *handle; | ||
237 | struct GNUNET_MESSENGER_MemberSession *session; | ||
238 | }; | ||
239 | |||
240 | static void | ||
241 | notify_about_members (struct GNUNET_MESSENGER_MemberNotify *notify, | ||
242 | struct GNUNET_MESSENGER_MemberSession *session, | ||
243 | struct GNUNET_CONTAINER_MultiHashMap *map, | ||
244 | int check_permission) | ||
245 | { | ||
246 | if (session->prev) | ||
247 | notify_about_members (notify, session->prev, map, GNUNET_YES); | ||
248 | |||
249 | struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(notify->room); | ||
250 | struct GNUNET_MESSENGER_ListMessage *element; | ||
251 | |||
252 | for (element = session->messages.head; element; element = element->next) | ||
253 | { | ||
254 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(map, &(element->hash))) | ||
255 | continue; | ||
256 | |||
257 | if ((GNUNET_YES == check_permission) && | ||
258 | (GNUNET_YES != check_member_session_history(notify->session, &(element->hash), GNUNET_NO))) | ||
259 | continue; | ||
260 | |||
261 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(map, &(element->hash), NULL, | ||
262 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
263 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Notification of session message could be duplicated!\n"); | ||
264 | |||
265 | const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, &(element->hash)); | ||
266 | |||
267 | if (message) | ||
268 | notify_handle_message (notify->handle, notify->room, session, message, &(element->hash)); | ||
269 | } | ||
270 | } | ||
271 | |||
272 | static int | ||
273 | iterate_notify_about_members (void *cls, | ||
274 | const struct GNUNET_IDENTITY_PublicKey *public_key, | ||
275 | struct GNUNET_MESSENGER_MemberSession *session) | ||
276 | { | ||
277 | struct GNUNET_MESSENGER_MemberNotify *notify = cls; | ||
278 | |||
279 | if ((notify->session == session) || (GNUNET_YES == is_member_session_completed(session))) | ||
280 | return GNUNET_YES; | ||
281 | |||
282 | struct GNUNET_CONTAINER_MultiHashMap *map = GNUNET_CONTAINER_multihashmap_create(4, GNUNET_NO); | ||
283 | |||
284 | notify_about_members (notify, session, map, GNUNET_NO); | ||
285 | |||
286 | GNUNET_CONTAINER_multihashmap_destroy(map); | ||
287 | return GNUNET_YES; | ||
288 | } | ||
289 | |||
290 | static int | ||
291 | join_room_locally (struct GNUNET_MESSENGER_SrvRoom *room, | ||
292 | struct GNUNET_MESSENGER_SrvHandle *handle) | ||
293 | { | ||
294 | const struct GNUNET_ShortHashCode *member_id = get_handle_member_id (handle, get_room_key(room)); | ||
295 | |||
296 | struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room); | ||
297 | struct GNUNET_MESSENGER_Member *member = add_store_member(member_store, member_id); | ||
298 | |||
299 | if (GNUNET_NO == join_room (room, handle, member)) | ||
300 | return GNUNET_NO; | ||
301 | |||
302 | const struct GNUNET_MESSENGER_Ego *ego = get_handle_ego(handle); | ||
303 | struct GNUNET_MESSENGER_MemberSession *session = get_member_session (member, &(ego->pub)); | ||
304 | |||
305 | if (!session) | ||
306 | { | ||
307 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "A valid session is required to join a room!\n"); | ||
308 | return GNUNET_NO; | ||
309 | } | ||
310 | |||
311 | struct GNUNET_MESSENGER_MemberNotify notify; | ||
312 | |||
313 | notify.room = room; | ||
314 | notify.handle = handle; | ||
315 | notify.session = session; | ||
316 | |||
317 | iterate_store_members(get_room_member_store(room), iterate_notify_about_members, ¬ify); | ||
318 | |||
319 | return GNUNET_YES; | ||
320 | } | ||
321 | |||
322 | extern int | ||
323 | check_tunnel_message (void *cls, | ||
324 | const struct GNUNET_MessageHeader *header); | ||
325 | |||
326 | extern void | ||
327 | handle_tunnel_message (void *cls, | ||
328 | const struct GNUNET_MessageHeader *header); | ||
329 | |||
330 | extern void | ||
331 | callback_tunnel_disconnect (void *cls, | ||
332 | const struct GNUNET_CADET_Channel *channel); | ||
333 | |||
334 | int | ||
335 | open_room (struct GNUNET_MESSENGER_SrvRoom *room, | ||
336 | struct GNUNET_MESSENGER_SrvHandle *handle) | ||
337 | { | ||
338 | GNUNET_assert((room) && (handle)); | ||
339 | |||
340 | if (room->port) | ||
341 | return join_room_locally (room, handle); | ||
342 | |||
343 | struct GNUNET_CADET_Handle *cadet = get_room_cadet (room); | ||
344 | const struct GNUNET_HashCode *key = get_room_key (room); | ||
345 | |||
346 | struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size(tunnel_message, GNUNET_MESSAGE_TYPE_CADET_CLI, | ||
347 | struct GNUNET_MessageHeader, NULL), | ||
348 | GNUNET_MQ_handler_end() }; | ||
349 | |||
350 | struct GNUNET_HashCode port; | ||
351 | convert_messenger_key_to_port(key, &port); | ||
352 | room->port = GNUNET_CADET_open_port (cadet, &port, callback_room_connect, room, NULL, callback_tunnel_disconnect, | ||
353 | handlers); | ||
354 | |||
355 | if (room->port) | ||
356 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Port of room (%s) was opened!\n", | ||
357 | GNUNET_h2s(get_room_key(room))); | ||
358 | else | ||
359 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Port of room (%s) could not be opened!\n", | ||
360 | GNUNET_h2s(get_room_key(room))); | ||
361 | |||
362 | const struct GNUNET_ShortHashCode *member_id = get_handle_member_id (handle, get_room_key(room)); | ||
363 | |||
364 | struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room); | ||
365 | struct GNUNET_MESSENGER_Member *member = add_store_member(member_store, member_id); | ||
366 | |||
367 | if ((GNUNET_NO == join_room (room, handle, member)) && (room->port)) | ||
368 | { | ||
369 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "You could not join the room, therefore it keeps closed!\n"); | ||
370 | |||
371 | GNUNET_CADET_close_port (room->port); | ||
372 | room->port = NULL; | ||
373 | |||
374 | return GNUNET_NO; | ||
375 | } | ||
376 | |||
377 | struct GNUNET_MESSENGER_Message *peer_msg = create_message_peer (room->service); | ||
378 | GNUNET_memcpy(&(peer_msg->header.sender_id), member_id, sizeof(*member_id)); | ||
379 | return (room->port ? send_room_message (room, handle, peer_msg) : GNUNET_NO); | ||
380 | } | ||
381 | |||
382 | int | ||
383 | enter_room_at (struct GNUNET_MESSENGER_SrvRoom *room, | ||
384 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
385 | const struct GNUNET_PeerIdentity *door) | ||
386 | { | ||
387 | GNUNET_assert((room) && (handle) && (door)); | ||
388 | |||
389 | struct GNUNET_PeerIdentity peer; | ||
390 | |||
391 | if ((GNUNET_OK == get_service_peer_identity (room->service, &peer)) && | ||
392 | (0 == GNUNET_memcmp(&peer, door))) | ||
393 | return join_room_locally (room, handle); | ||
394 | |||
395 | struct GNUNET_MESSENGER_SrvTunnel *tunnel = GNUNET_CONTAINER_multipeermap_get (room->tunnels, door); | ||
396 | |||
397 | if (!tunnel) | ||
398 | { | ||
399 | tunnel = create_tunnel (room, door); | ||
400 | |||
401 | if (GNUNET_OK != GNUNET_CONTAINER_multipeermap_put (room->tunnels, door, tunnel, | ||
402 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)) | ||
403 | { | ||
404 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "You could not connect to that door!\n"); | ||
405 | destroy_tunnel (tunnel); | ||
406 | return GNUNET_NO; | ||
407 | } | ||
408 | } | ||
409 | |||
410 | if (GNUNET_SYSERR == connect_tunnel (tunnel)) | ||
411 | { | ||
412 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Connection failure during entrance!\n"); | ||
413 | GNUNET_CONTAINER_multipeermap_remove (room->tunnels, door, tunnel); | ||
414 | destroy_tunnel (tunnel); | ||
415 | return GNUNET_NO; | ||
416 | } | ||
417 | |||
418 | return join_room_locally (room, handle); | ||
419 | } | ||
420 | |||
421 | struct GNUNET_MQ_Envelope* | ||
422 | pack_room_message (const struct GNUNET_MESSENGER_SrvRoom *room, | ||
423 | const struct GNUNET_MESSENGER_SrvHandle *handle, | ||
424 | struct GNUNET_MESSENGER_Message *message, | ||
425 | struct GNUNET_HashCode *hash, | ||
426 | int mode) | ||
427 | { | ||
428 | GNUNET_assert((room) && (handle) && (message) && (hash)); | ||
429 | |||
430 | message->header.timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); | ||
431 | |||
432 | const struct GNUNET_ShortHashCode *id = get_handle_member_id (handle, get_room_key(room)); | ||
433 | |||
434 | GNUNET_assert(id); | ||
435 | |||
436 | GNUNET_memcpy(&(message->header.sender_id), id, sizeof(struct GNUNET_ShortHashCode)); | ||
437 | get_message_state_chain_hash (&(room->state), &(message->header.previous)); | ||
438 | |||
439 | return pack_message (message, hash, get_handle_ego (handle), mode); | ||
440 | } | ||
441 | |||
442 | struct GNUNET_MESSENGER_ClosureSendRoom | ||
443 | { | ||
444 | struct GNUNET_MESSENGER_SrvRoom *room; | ||
445 | struct GNUNET_MESSENGER_SrvHandle *handle; | ||
446 | struct GNUNET_MESSENGER_SrvTunnel *exclude; | ||
447 | struct GNUNET_MESSENGER_Message *message; | ||
448 | struct GNUNET_HashCode *hash; | ||
449 | int packed; | ||
450 | }; | ||
451 | |||
452 | static int | ||
453 | iterate_send_room_message (void *cls, | ||
454 | const struct GNUNET_PeerIdentity *key, | ||
455 | void *value) | ||
456 | { | ||
457 | struct GNUNET_MESSENGER_SrvTunnel *tunnel = value; | ||
458 | |||
459 | if ((!is_tunnel_connected (tunnel)) || | ||
460 | (get_tunnel_messenger_version(tunnel) < GNUNET_MESSENGER_VERSION)) | ||
461 | return GNUNET_YES; | ||
462 | |||
463 | struct GNUNET_MESSENGER_ClosureSendRoom *closure = cls; | ||
464 | |||
465 | if (tunnel == closure->exclude) | ||
466 | return GNUNET_YES; | ||
467 | |||
468 | struct GNUNET_MQ_Envelope *env = NULL; | ||
469 | |||
470 | if (closure->packed == GNUNET_NO) | ||
471 | { | ||
472 | env = pack_room_message (closure->room, closure->handle, closure->message, closure->hash, | ||
473 | GNUNET_MESSENGER_PACK_MODE_ENVELOPE); | ||
474 | |||
475 | if (env) | ||
476 | closure->packed = GNUNET_YES; | ||
477 | } | ||
478 | else | ||
479 | env = pack_message (closure->message, NULL, NULL, GNUNET_MESSENGER_PACK_MODE_ENVELOPE); | ||
480 | |||
481 | if (env) | ||
482 | send_tunnel_envelope (tunnel, env, closure->hash); | ||
483 | |||
484 | return GNUNET_YES; | ||
485 | } | ||
486 | |||
487 | int | ||
488 | update_room_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
489 | struct GNUNET_MESSENGER_Message *message, | ||
490 | const struct GNUNET_HashCode *hash); | ||
491 | |||
492 | void | ||
493 | callback_room_handle_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
494 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
495 | const struct GNUNET_MESSENGER_Message *message, | ||
496 | const struct GNUNET_HashCode *hash); | ||
497 | |||
498 | int | ||
499 | send_room_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
500 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
501 | struct GNUNET_MESSENGER_Message *message) | ||
502 | { | ||
503 | GNUNET_assert((room) && (handle)); | ||
504 | |||
505 | if (!message) | ||
506 | return GNUNET_NO; | ||
507 | |||
508 | if (GNUNET_YES == is_message_session_bound(message)) | ||
509 | merge_room_last_messages(room, handle); | ||
510 | |||
511 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Sending message from handle with member id: %s\n", | ||
512 | GNUNET_sh2s(get_handle_member_id(handle, get_room_key(room)))); | ||
513 | |||
514 | struct GNUNET_HashCode hash; | ||
515 | struct GNUNET_MESSENGER_ClosureSendRoom closure; | ||
516 | |||
517 | closure.room = room; | ||
518 | closure.handle = handle; | ||
519 | closure.exclude = NULL; | ||
520 | closure.message = message; | ||
521 | closure.hash = &hash; | ||
522 | closure.packed = GNUNET_NO; | ||
523 | |||
524 | GNUNET_CONTAINER_multipeermap_iterate (room->tunnels, iterate_send_room_message, &closure); | ||
525 | |||
526 | if (GNUNET_NO == closure.packed) | ||
527 | pack_room_message (room, handle, message, &hash, GNUNET_MESSENGER_PACK_MODE_UNKNOWN); | ||
528 | |||
529 | const int new_message = update_room_message (room, message, &hash); | ||
530 | |||
531 | if (GNUNET_YES != new_message) | ||
532 | return GNUNET_SYSERR; | ||
533 | |||
534 | switch (message->header.kind) | ||
535 | { | ||
536 | case GNUNET_MESSENGER_KIND_JOIN: | ||
537 | send_message_join (room, handle, message, &hash); | ||
538 | break; | ||
539 | case GNUNET_MESSENGER_KIND_PEER: | ||
540 | send_message_peer (room, handle, message, &hash); | ||
541 | break; | ||
542 | case GNUNET_MESSENGER_KIND_ID: | ||
543 | send_message_id (room, handle, message, &hash); | ||
544 | break; | ||
545 | case GNUNET_MESSENGER_KIND_REQUEST: | ||
546 | send_message_request (room, handle, message, &hash); | ||
547 | break; | ||
548 | default: | ||
549 | break; | ||
550 | } | ||
551 | |||
552 | callback_room_handle_message (room, handle, message, &hash); | ||
553 | return GNUNET_YES; | ||
554 | } | ||
555 | |||
556 | void | ||
557 | forward_room_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
558 | struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
559 | struct GNUNET_MESSENGER_Message *message, | ||
560 | const struct GNUNET_HashCode *hash) | ||
561 | { | ||
562 | GNUNET_assert((room) && (tunnel)); | ||
563 | |||
564 | if (!message) | ||
565 | return; | ||
566 | |||
567 | struct GNUNET_MESSENGER_ClosureSendRoom closure; | ||
568 | struct GNUNET_HashCode message_hash; | ||
569 | |||
570 | GNUNET_memcpy(&message_hash, hash, sizeof(struct GNUNET_HashCode)); | ||
571 | |||
572 | closure.room = room; | ||
573 | closure.handle = NULL; | ||
574 | closure.exclude = tunnel; | ||
575 | closure.message = message; | ||
576 | closure.hash = &message_hash; | ||
577 | closure.packed = GNUNET_YES; | ||
578 | |||
579 | GNUNET_CONTAINER_multipeermap_iterate (room->tunnels, iterate_send_room_message, &closure); | ||
580 | } | ||
581 | |||
582 | void | ||
583 | check_room_peer_status (struct GNUNET_MESSENGER_SrvRoom *room, | ||
584 | struct GNUNET_MESSENGER_SrvTunnel *tunnel) | ||
585 | { | ||
586 | if (!room->peer_message) | ||
587 | return; | ||
588 | |||
589 | struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(room); | ||
590 | |||
591 | const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, room->peer_message); | ||
592 | |||
593 | if (!message) | ||
594 | { | ||
595 | GNUNET_free(room->peer_message); | ||
596 | room->peer_message = NULL; | ||
597 | return; | ||
598 | } | ||
599 | |||
600 | struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room); | ||
601 | struct GNUNET_MESSENGER_Member *member = get_store_member_of(member_store, message); | ||
602 | |||
603 | if (!member) | ||
604 | goto resend_peer_message; | ||
605 | |||
606 | struct GNUNET_MESSENGER_MemberSession *session = get_member_session_of(member, message, room->peer_message); | ||
607 | |||
608 | if (GNUNET_YES == is_member_session_closed(session)) | ||
609 | goto resend_peer_message; | ||
610 | |||
611 | if (tunnel) | ||
612 | forward_tunnel_message(tunnel, message, room->peer_message); | ||
613 | |||
614 | return; | ||
615 | |||
616 | resend_peer_message: | ||
617 | if (room->host) | ||
618 | send_room_message (room, room->host, create_message_peer (room->service)); | ||
619 | } | ||
620 | |||
621 | void | ||
622 | merge_room_last_messages (struct GNUNET_MESSENGER_SrvRoom *room, | ||
623 | struct GNUNET_MESSENGER_SrvHandle *handle) | ||
624 | { | ||
625 | GNUNET_assert(room); | ||
626 | |||
627 | if (!handle) | ||
628 | return; | ||
629 | |||
630 | const struct GNUNET_HashCode *hash; | ||
631 | |||
632 | merge_next: | ||
633 | hash = get_message_state_merge_hash (&(room->state)); | ||
634 | |||
635 | if (!hash) | ||
636 | return; | ||
637 | |||
638 | send_room_message (room, handle, create_message_merge (hash)); | ||
639 | goto merge_next; | ||
640 | } | ||
641 | |||
642 | void | ||
643 | callback_room_deletion (struct GNUNET_MESSENGER_SrvRoom *room, | ||
644 | const struct GNUNET_HashCode *hash) | ||
645 | { | ||
646 | if (GNUNET_OK != delete_store_message (get_room_message_store(room), hash)) | ||
647 | { | ||
648 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Deletion of message failed! (%s)\n", GNUNET_h2s(hash)); | ||
649 | return; | ||
650 | } | ||
651 | } | ||
652 | |||
653 | void | ||
654 | callback_room_merge (struct GNUNET_MESSENGER_SrvRoom *room, | ||
655 | const struct GNUNET_HashCode *hash) | ||
656 | { | ||
657 | if (!room->host) | ||
658 | return; | ||
659 | |||
660 | send_room_message (room, room->host, create_message_merge (hash)); | ||
661 | } | ||
662 | |||
663 | int | ||
664 | delete_room_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
665 | struct GNUNET_MESSENGER_MemberSession *session, | ||
666 | const struct GNUNET_HashCode *hash, | ||
667 | const struct GNUNET_TIME_Relative delay) | ||
668 | { | ||
669 | GNUNET_assert((room) && (session) && (hash)); | ||
670 | |||
671 | const struct GNUNET_TIME_Relative forever = GNUNET_TIME_relative_get_forever_ (); | ||
672 | |||
673 | if (0 == GNUNET_memcmp(&forever, &delay)) | ||
674 | { | ||
675 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Deletion is delayed forever: operation is impossible!\n"); | ||
676 | return GNUNET_SYSERR; | ||
677 | } | ||
678 | |||
679 | struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(room); | ||
680 | |||
681 | const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, hash); | ||
682 | |||
683 | if (!message) | ||
684 | return GNUNET_YES; | ||
685 | |||
686 | if (GNUNET_YES != check_member_session_history(session, hash, GNUNET_YES)) | ||
687 | { | ||
688 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Unpermitted request for deletion by member (%s) of message (%s)!\n", | ||
689 | GNUNET_sh2s(get_member_session_id(session)), GNUNET_h2s(hash)); | ||
690 | |||
691 | return GNUNET_NO; | ||
692 | } | ||
693 | |||
694 | struct GNUNET_MESSENGER_OperationStore *operation_store = get_room_operation_store(room); | ||
695 | |||
696 | if (GNUNET_OK != use_store_operation(operation_store, hash, GNUNET_MESSENGER_OP_DELETE, delay)) | ||
697 | { | ||
698 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Deletion has failed: operation denied!\n"); | ||
699 | return GNUNET_SYSERR; | ||
700 | } | ||
701 | |||
702 | return GNUNET_YES; | ||
703 | } | ||
704 | |||
705 | struct GNUNET_CADET_Handle* | ||
706 | get_room_cadet (struct GNUNET_MESSENGER_SrvRoom *room) | ||
707 | { | ||
708 | GNUNET_assert(room); | ||
709 | |||
710 | return room->service->cadet; | ||
711 | } | ||
712 | |||
713 | const struct GNUNET_HashCode* | ||
714 | get_room_key (const struct GNUNET_MESSENGER_SrvRoom *room) | ||
715 | { | ||
716 | GNUNET_assert(room); | ||
717 | |||
718 | return &(room->key); | ||
719 | } | ||
720 | |||
721 | const struct GNUNET_MESSENGER_SrvTunnel* | ||
722 | get_room_tunnel (const struct GNUNET_MESSENGER_SrvRoom *room, | ||
723 | const struct GNUNET_PeerIdentity *peer) | ||
724 | { | ||
725 | GNUNET_assert((room) && (peer)); | ||
726 | |||
727 | return GNUNET_CONTAINER_multipeermap_get (room->tunnels, peer); | ||
728 | } | ||
729 | |||
730 | static int | ||
731 | request_room_message_step (struct GNUNET_MESSENGER_SrvRoom *room, | ||
732 | const struct GNUNET_HashCode *hash, | ||
733 | const struct GNUNET_MESSENGER_MemberSession *session, | ||
734 | GNUNET_MESSENGER_MessageRequestCallback callback, | ||
735 | void* cls) | ||
736 | { | ||
737 | struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(room); | ||
738 | |||
739 | const struct GNUNET_MESSENGER_MessageLink *link = get_store_message_link( | ||
740 | message_store, hash, GNUNET_YES | ||
741 | ); | ||
742 | |||
743 | if (!link) | ||
744 | goto forward; | ||
745 | |||
746 | int result = request_room_message_step(room, &(link->first), session, callback, cls); | ||
747 | |||
748 | if ((GNUNET_YES == link->multiple) && | ||
749 | (GNUNET_YES == request_room_message_step(room, &(link->second), session, callback, cls))) | ||
750 | return GNUNET_YES; | ||
751 | else | ||
752 | return result; | ||
753 | |||
754 | forward: | ||
755 | if (GNUNET_YES != check_member_session_history(session, hash, GNUNET_NO)) | ||
756 | return GNUNET_YES; | ||
757 | |||
758 | const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, hash); | ||
759 | |||
760 | if (!message) | ||
761 | return GNUNET_NO; | ||
762 | |||
763 | if (callback) | ||
764 | callback (cls, room, message, hash); | ||
765 | |||
766 | return GNUNET_YES; | ||
767 | } | ||
768 | |||
769 | int | ||
770 | request_room_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
771 | const struct GNUNET_HashCode *hash, | ||
772 | const struct GNUNET_MESSENGER_MemberSession *session, | ||
773 | GNUNET_MESSENGER_MessageRequestCallback callback, | ||
774 | void* cls) | ||
775 | { | ||
776 | GNUNET_assert((room) && (hash)); | ||
777 | |||
778 | int result = request_room_message_step (room, hash, session, callback, cls); | ||
779 | |||
780 | if ((GNUNET_NO == result) && (callback)) | ||
781 | callback (cls, room, NULL, hash); | ||
782 | |||
783 | return result; | ||
784 | } | ||
785 | |||
786 | void | ||
787 | callback_room_disconnect (struct GNUNET_MESSENGER_SrvRoom *room, | ||
788 | void *cls) | ||
789 | { | ||
790 | struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls; | ||
791 | |||
792 | if (!room->host) | ||
793 | return; | ||
794 | |||
795 | struct GNUNET_PeerIdentity identity; | ||
796 | get_tunnel_peer_identity(tunnel, &identity); | ||
797 | |||
798 | if ((GNUNET_YES != GNUNET_CONTAINER_multipeermap_remove (room->tunnels, &identity, tunnel)) || | ||
799 | (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains(room->tunnels, &identity))) | ||
800 | return; | ||
801 | |||
802 | if (GNUNET_YES == contains_list_tunnels (&(room->basement), &identity)) | ||
803 | send_room_message (room, room->host, create_message_miss (&identity)); | ||
804 | } | ||
805 | |||
806 | int | ||
807 | callback_verify_room_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
808 | void *cls, | ||
809 | struct GNUNET_MESSENGER_Message *message, | ||
810 | struct GNUNET_HashCode *hash) | ||
811 | { | ||
812 | if (GNUNET_MESSENGER_KIND_UNKNOWN == message->header.kind) | ||
813 | { | ||
814 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Message error: Kind is unknown! (%d)\n", message->header.kind); | ||
815 | return GNUNET_SYSERR; | ||
816 | } | ||
817 | |||
818 | struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(room); | ||
819 | |||
820 | const struct GNUNET_MESSENGER_Message *previous = get_store_message(message_store, &(message->header.previous)); | ||
821 | |||
822 | if (!previous) | ||
823 | goto skip_time_comparison; | ||
824 | |||
825 | struct GNUNET_TIME_Absolute timestamp = GNUNET_TIME_absolute_ntoh(message->header.timestamp); | ||
826 | struct GNUNET_TIME_Absolute last = GNUNET_TIME_absolute_ntoh(previous->header.timestamp); | ||
827 | |||
828 | if (GNUNET_TIME_relative_get_zero_().rel_value_us != GNUNET_TIME_absolute_get_difference(timestamp, last).rel_value_us) | ||
829 | { | ||
830 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Message error: Timestamp does not check out!\n"); | ||
831 | return GNUNET_SYSERR; | ||
832 | } | ||
833 | |||
834 | skip_time_comparison: | ||
835 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Receiving message of kind: %s!\n", | ||
836 | GNUNET_MESSENGER_name_of_kind(message->header.kind)); | ||
837 | |||
838 | return GNUNET_OK; | ||
839 | } | ||
840 | |||
841 | static void | ||
842 | idle_request_room_messages (void *cls) | ||
843 | { | ||
844 | struct GNUNET_MESSENGER_SrvRoom *room = cls; | ||
845 | |||
846 | room->idle = NULL; | ||
847 | |||
848 | struct GNUNET_MESSENGER_OperationStore *operation_store = get_room_operation_store(room); | ||
849 | const struct GNUNET_HashCode *hash = get_message_state_merge_hash(&(room->state)); | ||
850 | |||
851 | if ((hash) && | ||
852 | (GNUNET_MESSENGER_OP_UNKNOWN == get_store_operation_type(operation_store, hash))) | ||
853 | use_store_operation( | ||
854 | operation_store, | ||
855 | hash, | ||
856 | GNUNET_MESSENGER_OP_MERGE, | ||
857 | GNUNET_MESSENGER_MERGE_DELAY | ||
858 | ); | ||
859 | |||
860 | room->idle = GNUNET_SCHEDULER_add_delayed_with_priority ( | ||
861 | GNUNET_MESSENGER_IDLE_DELAY, | ||
862 | GNUNET_SCHEDULER_PRIORITY_IDLE, | ||
863 | idle_request_room_messages, | ||
864 | cls | ||
865 | ); | ||
866 | } | ||
867 | |||
868 | void | ||
869 | solve_room_member_collisions (struct GNUNET_MESSENGER_SrvRoom *room, | ||
870 | const struct GNUNET_IDENTITY_PublicKey *public_key, | ||
871 | const struct GNUNET_ShortHashCode *member_id, | ||
872 | struct GNUNET_TIME_Absolute timestamp) | ||
873 | { | ||
874 | GNUNET_assert ((room) && (public_key) && (member_id)); | ||
875 | |||
876 | struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room); | ||
877 | struct GNUNET_MESSENGER_Member *member = get_store_member(member_store, member_id); | ||
878 | |||
879 | if ((!member) || (1 >= GNUNET_CONTAINER_multihashmap_size(member->sessions))) | ||
880 | return; | ||
881 | |||
882 | struct GNUNET_MESSENGER_ListHandles *handles = &(room->service->handles); | ||
883 | struct GNUNET_MESSENGER_ListHandle* element; | ||
884 | |||
885 | for (element = handles->head; element; element = element->next) | ||
886 | { | ||
887 | if (0 != GNUNET_memcmp(member_id, get_handle_member_id(element->handle, get_room_key(room)))) | ||
888 | continue; | ||
889 | |||
890 | if (0 == GNUNET_memcmp(public_key, &(get_handle_ego(element->handle)->pub))) | ||
891 | continue; | ||
892 | |||
893 | struct GNUNET_MESSENGER_MemberSession *session = get_member_session(member, &(get_handle_ego(element->handle)->pub)); | ||
894 | |||
895 | if (!session) | ||
896 | continue; | ||
897 | |||
898 | struct GNUNET_TIME_Absolute start = get_member_session_start(session); | ||
899 | |||
900 | if (GNUNET_TIME_relative_get_zero_().rel_value_us != GNUNET_TIME_absolute_get_difference(start, timestamp).rel_value_us) | ||
901 | continue; | ||
902 | |||
903 | struct GNUNET_ShortHashCode random_id; | ||
904 | generate_free_member_id (&random_id, member_store->members); | ||
905 | |||
906 | send_room_message(room, element->handle, create_message_id(&random_id)); | ||
907 | } | ||
908 | } | ||
909 | |||
910 | void | ||
911 | rebuild_room_basement_structure (struct GNUNET_MESSENGER_SrvRoom *room) | ||
912 | { | ||
913 | GNUNET_assert(room); | ||
914 | |||
915 | struct GNUNET_PeerIdentity peer; | ||
916 | size_t src; | ||
917 | |||
918 | if ((GNUNET_OK != get_service_peer_identity (room->service, &peer)) || | ||
919 | (!find_list_tunnels (&(room->basement), &peer, &src))) | ||
920 | return; | ||
921 | |||
922 | size_t count = count_of_tunnels (&(room->basement)); | ||
923 | |||
924 | struct GNUNET_MESSENGER_ListTunnel *element = room->basement.head; | ||
925 | struct GNUNET_MESSENGER_SrvTunnel *tunnel; | ||
926 | |||
927 | size_t dst = 0; | ||
928 | |||
929 | while (element) | ||
930 | { | ||
931 | GNUNET_PEER_resolve (element->peer, &peer); | ||
932 | |||
933 | tunnel = GNUNET_CONTAINER_multipeermap_get (room->tunnels, &peer); | ||
934 | |||
935 | if (!tunnel) | ||
936 | { | ||
937 | element = remove_from_list_tunnels (&(room->basement), element); | ||
938 | continue; | ||
939 | } | ||
940 | |||
941 | if (GNUNET_YES == required_connection_between (count, src, dst)) | ||
942 | { | ||
943 | if (GNUNET_SYSERR == connect_tunnel (tunnel)) | ||
944 | { | ||
945 | element = remove_from_list_tunnels (&(room->basement), element); | ||
946 | continue; | ||
947 | } | ||
948 | } | ||
949 | else | ||
950 | disconnect_tunnel (tunnel); | ||
951 | |||
952 | element = element->next; | ||
953 | dst++; | ||
954 | } | ||
955 | } | ||
956 | |||
957 | static void | ||
958 | handle_room_messages (struct GNUNET_MESSENGER_SrvRoom *room) | ||
959 | { | ||
960 | struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(room); | ||
961 | struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room); | ||
962 | |||
963 | while (room->handling.head) | ||
964 | { | ||
965 | struct GNUNET_MESSENGER_ListMessage *element = room->handling.head; | ||
966 | |||
967 | const struct GNUNET_MESSENGER_Message *message = get_store_message (message_store, &(element->hash)); | ||
968 | |||
969 | if (!message) | ||
970 | goto finish_handling; | ||
971 | |||
972 | struct GNUNET_MESSENGER_Member *member = get_store_member_of(member_store, message); | ||
973 | |||
974 | if (!member) | ||
975 | goto finish_handling; | ||
976 | |||
977 | struct GNUNET_MESSENGER_MemberSession *session = get_member_session_of(member, message, &(element->hash)); | ||
978 | |||
979 | if (session) | ||
980 | handle_service_message (room->service, room, session, message, &(element->hash)); | ||
981 | |||
982 | finish_handling: | ||
983 | GNUNET_CONTAINER_DLL_remove(room->handling.head, room->handling.tail, element); | ||
984 | GNUNET_free(element); | ||
985 | } | ||
986 | } | ||
987 | |||
988 | int | ||
989 | update_room_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
990 | struct GNUNET_MESSENGER_Message *message, | ||
991 | const struct GNUNET_HashCode *hash) | ||
992 | { | ||
993 | GNUNET_assert((room) && (message) && (hash)); | ||
994 | |||
995 | struct GNUNET_MESSENGER_OperationStore *operation_store = get_room_operation_store(room); | ||
996 | |||
997 | const int requested = (GNUNET_MESSENGER_OP_REQUEST == get_store_operation_type(operation_store, hash)? | ||
998 | GNUNET_YES : GNUNET_NO | ||
999 | ); | ||
1000 | |||
1001 | if (GNUNET_YES == requested) | ||
1002 | cancel_store_operation(operation_store, hash); | ||
1003 | |||
1004 | struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(room); | ||
1005 | |||
1006 | const struct GNUNET_MESSENGER_Message *old_message = get_store_message (message_store, hash); | ||
1007 | |||
1008 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Handle a message in room (%s).\n", GNUNET_h2s (get_room_key(room))); | ||
1009 | |||
1010 | if ((old_message) || (GNUNET_OK != put_store_message (message_store, hash, message))) | ||
1011 | { | ||
1012 | if (old_message != message) | ||
1013 | destroy_message(message); | ||
1014 | |||
1015 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Duplicate message got dropped!\n"); | ||
1016 | return GNUNET_NO; | ||
1017 | } | ||
1018 | |||
1019 | update_message_state(&(room->state), requested, message, hash); | ||
1020 | |||
1021 | if ((GNUNET_YES == requested) || | ||
1022 | (GNUNET_MESSENGER_KIND_INFO == message->header.kind) || | ||
1023 | (GNUNET_MESSENGER_KIND_REQUEST == message->header.kind)) | ||
1024 | return GNUNET_YES; | ||
1025 | |||
1026 | if ((GNUNET_MESSENGER_KIND_MERGE == message->header.kind) && | ||
1027 | (GNUNET_MESSENGER_OP_MERGE == get_store_operation_type(operation_store, &(message->body.merge.previous)))) | ||
1028 | cancel_store_operation(operation_store, &(message->body.merge.previous)); | ||
1029 | |||
1030 | if (GNUNET_MESSENGER_OP_MERGE == get_store_operation_type(operation_store, &(message->header.previous))) | ||
1031 | cancel_store_operation(operation_store, &(message->header.previous)); | ||
1032 | |||
1033 | return GNUNET_YES; | ||
1034 | } | ||
1035 | |||
1036 | struct GNUNET_MESSENGER_MemberSessionCompletion | ||
1037 | { | ||
1038 | struct GNUNET_MESSENGER_MemberSessionCompletion *prev; | ||
1039 | struct GNUNET_MESSENGER_MemberSessionCompletion *next; | ||
1040 | |||
1041 | struct GNUNET_MESSENGER_MemberSession *session; | ||
1042 | }; | ||
1043 | |||
1044 | struct GNUNET_MESSENGER_MemberUpdate | ||
1045 | { | ||
1046 | const struct GNUNET_MESSENGER_Message *message; | ||
1047 | const struct GNUNET_HashCode *hash; | ||
1048 | |||
1049 | struct GNUNET_MESSENGER_MemberSessionCompletion *head; | ||
1050 | struct GNUNET_MESSENGER_MemberSessionCompletion *tail; | ||
1051 | }; | ||
1052 | |||
1053 | static int | ||
1054 | iterate_update_member_sessions (void *cls, | ||
1055 | const struct GNUNET_IDENTITY_PublicKey *public_key, | ||
1056 | struct GNUNET_MESSENGER_MemberSession *session) | ||
1057 | { | ||
1058 | struct GNUNET_MESSENGER_MemberUpdate *update = cls; | ||
1059 | |||
1060 | update_member_session_history(session, update->message, update->hash); | ||
1061 | |||
1062 | if (GNUNET_YES == is_member_session_completed(session)) | ||
1063 | { | ||
1064 | struct GNUNET_MESSENGER_MemberSessionCompletion *element = GNUNET_new( | ||
1065 | struct GNUNET_MESSENGER_MemberSessionCompletion | ||
1066 | ); | ||
1067 | |||
1068 | element->session = session; | ||
1069 | |||
1070 | GNUNET_CONTAINER_DLL_insert_tail(update->head, update->tail, element); | ||
1071 | } | ||
1072 | |||
1073 | return GNUNET_YES; | ||
1074 | } | ||
1075 | |||
1076 | static void | ||
1077 | remove_room_member_session (struct GNUNET_MESSENGER_SrvRoom *room, | ||
1078 | struct GNUNET_MESSENGER_MemberSession *session); | ||
1079 | |||
1080 | void | ||
1081 | callback_room_handle_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
1082 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
1083 | const struct GNUNET_MESSENGER_Message *message, | ||
1084 | const struct GNUNET_HashCode *hash) | ||
1085 | { | ||
1086 | struct GNUNET_MESSENGER_MemberStore *member_store = get_room_member_store(room); | ||
1087 | struct GNUNET_MESSENGER_Member *member = get_store_member_of(member_store, message); | ||
1088 | |||
1089 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Callback for message (%s)\n", GNUNET_h2s (hash)); | ||
1090 | |||
1091 | if (!member) | ||
1092 | { | ||
1093 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Message handling dropped: Member is missing!\n"); | ||
1094 | return; | ||
1095 | } | ||
1096 | |||
1097 | struct GNUNET_MESSENGER_MemberSession *session = get_member_session_of(member, message, hash); | ||
1098 | |||
1099 | if (!session) | ||
1100 | { | ||
1101 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Message handling dropped: Session is missing!\n"); | ||
1102 | return; | ||
1103 | } | ||
1104 | |||
1105 | struct GNUNET_MESSENGER_MemberUpdate update; | ||
1106 | update.message = message; | ||
1107 | update.hash = hash; | ||
1108 | |||
1109 | update.head = NULL; | ||
1110 | update.tail = NULL; | ||
1111 | |||
1112 | iterate_store_members(member_store, iterate_update_member_sessions, &update); | ||
1113 | |||
1114 | while (update.head) | ||
1115 | { | ||
1116 | struct GNUNET_MESSENGER_MemberSessionCompletion *element = update.head; | ||
1117 | |||
1118 | remove_room_member_session (room, element->session); | ||
1119 | |||
1120 | GNUNET_CONTAINER_DLL_remove(update.head, update.tail, element); | ||
1121 | GNUNET_free (element); | ||
1122 | } | ||
1123 | |||
1124 | const int start_handle = room->handling.head ? GNUNET_NO : GNUNET_YES; | ||
1125 | |||
1126 | add_to_list_messages (&(room->handling), hash); | ||
1127 | |||
1128 | switch (message->header.kind) | ||
1129 | { | ||
1130 | case GNUNET_MESSENGER_KIND_JOIN: | ||
1131 | handle_message_join (room, session, message, hash); | ||
1132 | break; | ||
1133 | case GNUNET_MESSENGER_KIND_LEAVE: | ||
1134 | handle_message_leave (room, session, message, hash); | ||
1135 | break; | ||
1136 | case GNUNET_MESSENGER_KIND_NAME: | ||
1137 | handle_message_name (room, session, message, hash); | ||
1138 | break; | ||
1139 | case GNUNET_MESSENGER_KIND_KEY: | ||
1140 | handle_message_key (room, session, message, hash); | ||
1141 | break; | ||
1142 | case GNUNET_MESSENGER_KIND_PEER: | ||
1143 | handle_message_peer (room, session, message, hash); | ||
1144 | break; | ||
1145 | case GNUNET_MESSENGER_KIND_ID: | ||
1146 | handle_message_id (room, session, message, hash); | ||
1147 | break; | ||
1148 | case GNUNET_MESSENGER_KIND_MISS: | ||
1149 | handle_message_miss (room, session, message, hash); | ||
1150 | break; | ||
1151 | case GNUNET_MESSENGER_KIND_DELETE: | ||
1152 | handle_message_delete (room, session, message, hash); | ||
1153 | break; | ||
1154 | default: | ||
1155 | break; | ||
1156 | } | ||
1157 | |||
1158 | if (GNUNET_YES == start_handle) | ||
1159 | handle_room_messages (room); | ||
1160 | } | ||
1161 | |||
1162 | static void | ||
1163 | get_room_data_subdir (struct GNUNET_MESSENGER_SrvRoom *room, | ||
1164 | char **dir) | ||
1165 | { | ||
1166 | GNUNET_assert((room) && (dir)); | ||
1167 | |||
1168 | GNUNET_asprintf (dir, "%s%s%c%s%c", room->service->dir, "rooms", DIR_SEPARATOR, GNUNET_h2s (get_room_key(room)), DIR_SEPARATOR); | ||
1169 | } | ||
1170 | |||
1171 | void | ||
1172 | load_room (struct GNUNET_MESSENGER_SrvRoom *room) | ||
1173 | { | ||
1174 | GNUNET_assert(room); | ||
1175 | |||
1176 | char *room_dir; | ||
1177 | get_room_data_subdir (room, &room_dir); | ||
1178 | |||
1179 | if (GNUNET_YES == GNUNET_DISK_directory_test (room_dir, GNUNET_YES)) | ||
1180 | { | ||
1181 | load_member_store (get_room_member_store(room), room_dir); | ||
1182 | load_message_store (get_room_message_store(room), room_dir); | ||
1183 | load_operation_store(get_room_operation_store(room), room_dir); | ||
1184 | |||
1185 | char *basement_file; | ||
1186 | GNUNET_asprintf (&basement_file, "%s%s", room_dir, "basement.list"); | ||
1187 | |||
1188 | load_list_tunnels(&(room->basement), basement_file); | ||
1189 | GNUNET_free(basement_file); | ||
1190 | |||
1191 | load_message_state(&(room->state), room_dir); | ||
1192 | } | ||
1193 | |||
1194 | GNUNET_free(room_dir); | ||
1195 | } | ||
1196 | |||
1197 | void | ||
1198 | save_room (struct GNUNET_MESSENGER_SrvRoom *room) | ||
1199 | { | ||
1200 | GNUNET_assert(room); | ||
1201 | |||
1202 | char *room_dir; | ||
1203 | get_room_data_subdir (room, &room_dir); | ||
1204 | |||
1205 | if ((GNUNET_YES == GNUNET_DISK_directory_test (room_dir, GNUNET_NO)) || | ||
1206 | (GNUNET_OK == GNUNET_DISK_directory_create (room_dir))) | ||
1207 | { | ||
1208 | save_member_store(get_room_member_store(room), room_dir); | ||
1209 | save_message_store (get_room_message_store(room), room_dir); | ||
1210 | save_operation_store(get_room_operation_store(room), room_dir); | ||
1211 | |||
1212 | char *basement_file; | ||
1213 | GNUNET_asprintf (&basement_file, "%s%s", room_dir, "basement.list"); | ||
1214 | |||
1215 | save_list_tunnels(&(room->basement), basement_file); | ||
1216 | GNUNET_free(basement_file); | ||
1217 | |||
1218 | save_message_state(&(room->state), room_dir); | ||
1219 | } | ||
1220 | |||
1221 | GNUNET_free(room_dir); | ||
1222 | } | ||
1223 | |||
1224 | static void | ||
1225 | remove_room_member_session (struct GNUNET_MESSENGER_SrvRoom *room, | ||
1226 | struct GNUNET_MESSENGER_MemberSession *session) | ||
1227 | { | ||
1228 | GNUNET_assert ((room) && (session)); | ||
1229 | |||
1230 | remove_member_session (session->member, session); | ||
1231 | |||
1232 | const struct GNUNET_IDENTITY_PublicKey *public_key = get_member_session_public_key(session); | ||
1233 | |||
1234 | struct GNUNET_HashCode hash; | ||
1235 | GNUNET_CRYPTO_hash(public_key, sizeof(*public_key), &hash); | ||
1236 | |||
1237 | char *room_dir; | ||
1238 | get_room_data_subdir (room, &room_dir); | ||
1239 | |||
1240 | char* session_dir; | ||
1241 | GNUNET_asprintf ( | ||
1242 | &session_dir, "%s%s%c%s%c%s%c%s%c", room_dir, | ||
1243 | "members", DIR_SEPARATOR, | ||
1244 | GNUNET_sh2s(get_member_session_id(session)), DIR_SEPARATOR, | ||
1245 | "sessions", DIR_SEPARATOR, | ||
1246 | GNUNET_h2s(&hash), DIR_SEPARATOR | ||
1247 | ); | ||
1248 | |||
1249 | GNUNET_free (room_dir); | ||
1250 | |||
1251 | GNUNET_DISK_directory_remove(session_dir); | ||
1252 | GNUNET_free (session_dir); | ||
1253 | |||
1254 | destroy_member_session(session); | ||
1255 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_room.h b/src/messenger/gnunet-service-messenger_room.h deleted file mode 100644 index 4b3811104..000000000 --- a/src/messenger/gnunet-service-messenger_room.h +++ /dev/null | |||
@@ -1,367 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_room.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_ROOM_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_ROOM_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_cadet_service.h" | ||
31 | #include "gnunet_container_lib.h" | ||
32 | #include "gnunet_crypto_lib.h" | ||
33 | #include "gnunet_identity_service.h" | ||
34 | #include "gnunet_mq_lib.h" | ||
35 | |||
36 | #include "gnunet_messenger_service.h" | ||
37 | #include "gnunet-service-messenger_basement.h" | ||
38 | #include "gnunet-service-messenger_handle.h" | ||
39 | #include "gnunet-service-messenger_message_state.h" | ||
40 | #include "gnunet-service-messenger_list_messages.h" | ||
41 | |||
42 | #include "messenger_api_list_tunnels.h" | ||
43 | |||
44 | #include "gnunet-service-messenger_member_store.h" | ||
45 | #include "gnunet-service-messenger_message_store.h" | ||
46 | #include "gnunet-service-messenger_operation_store.h" | ||
47 | #include "messenger_api_ego.h" | ||
48 | |||
49 | #define GNUNET_MESSENGER_IDLE_DELAY GNUNET_TIME_relative_multiply \ | ||
50 | (GNUNET_TIME_relative_get_second_ (), 5) | ||
51 | |||
52 | #define GNUNET_MESSENGER_REQUEST_DELAY GNUNET_TIME_relative_multiply \ | ||
53 | (GNUNET_TIME_relative_get_minute_ (), 5) | ||
54 | |||
55 | #define GNUNET_MESSENGER_MERGE_DELAY GNUNET_TIME_relative_multiply \ | ||
56 | (GNUNET_TIME_relative_get_second_ (), 30) | ||
57 | |||
58 | struct GNUNET_MESSENGER_SrvTunnel; | ||
59 | struct GNUNET_MESSENGER_MemberSession; | ||
60 | |||
61 | struct GNUNET_MESSENGER_SrvRoom | ||
62 | { | ||
63 | struct GNUNET_MESSENGER_Service *service; | ||
64 | struct GNUNET_MESSENGER_SrvHandle *host; | ||
65 | struct GNUNET_CADET_Port *port; | ||
66 | |||
67 | struct GNUNET_HashCode key; | ||
68 | |||
69 | struct GNUNET_CONTAINER_MultiPeerMap *tunnels; | ||
70 | |||
71 | struct GNUNET_MESSENGER_MemberStore member_store; | ||
72 | struct GNUNET_MESSENGER_MessageStore message_store; | ||
73 | struct GNUNET_MESSENGER_OperationStore operation_store; | ||
74 | |||
75 | struct GNUNET_MESSENGER_ListTunnels basement; | ||
76 | struct GNUNET_MESSENGER_MessageState state; | ||
77 | |||
78 | struct GNUNET_HashCode *peer_message; | ||
79 | |||
80 | struct GNUNET_MESSENGER_ListMessages handling; | ||
81 | struct GNUNET_SCHEDULER_Task *idle; | ||
82 | }; | ||
83 | |||
84 | /** | ||
85 | * Creates and allocates a new room for a <i>handle</i> with a given <i>key</i>. | ||
86 | * | ||
87 | * @param[in/out] handle Handle | ||
88 | * @param[in] key Key of room | ||
89 | * @return New room | ||
90 | */ | ||
91 | struct GNUNET_MESSENGER_SrvRoom* | ||
92 | create_room (struct GNUNET_MESSENGER_SrvHandle *handle, | ||
93 | const struct GNUNET_HashCode *key); | ||
94 | |||
95 | /** | ||
96 | * Destroys a room and frees its memory fully. | ||
97 | * | ||
98 | * @param[in/out] room Room | ||
99 | */ | ||
100 | void | ||
101 | destroy_room (struct GNUNET_MESSENGER_SrvRoom *room); | ||
102 | |||
103 | /** | ||
104 | * Returns the used member store of a given <i>room</i>. | ||
105 | * | ||
106 | * @param[in/out] room Room | ||
107 | * @return Member store | ||
108 | */ | ||
109 | struct GNUNET_MESSENGER_MemberStore* | ||
110 | get_room_member_store (struct GNUNET_MESSENGER_SrvRoom *room); | ||
111 | |||
112 | /** | ||
113 | * Returns the used message store of a given <i>room</i>. | ||
114 | * | ||
115 | * @param[in/out] room Room | ||
116 | * @return Message store | ||
117 | */ | ||
118 | struct GNUNET_MESSENGER_MessageStore* | ||
119 | get_room_message_store (struct GNUNET_MESSENGER_SrvRoom *room); | ||
120 | |||
121 | /** | ||
122 | * Returns the used operation store of a given <i>room</i>. | ||
123 | * | ||
124 | * @param[in/out] room Room | ||
125 | * @return Operation store | ||
126 | */ | ||
127 | struct GNUNET_MESSENGER_OperationStore* | ||
128 | get_room_operation_store (struct GNUNET_MESSENGER_SrvRoom *room); | ||
129 | |||
130 | /** | ||
131 | * Tries to open a <i>room</i> for a given <i>handle</i>. If the room has already been opened, the handle | ||
132 | * will locally join the room. | ||
133 | * | ||
134 | * Calling this method should result in joining a room and sending a peer message as well for this peer. | ||
135 | * | ||
136 | * If the function returns #GNUNET_YES the port for this room is guaranteed to be open for incoming connections. | ||
137 | * | ||
138 | * @param[in/out] room Room | ||
139 | * @param[in/out] handle Handle | ||
140 | * @return #GNUNET_YES on success, #GNUNET_NO on failure. | ||
141 | */ | ||
142 | int | ||
143 | open_room (struct GNUNET_MESSENGER_SrvRoom *room, | ||
144 | struct GNUNET_MESSENGER_SrvHandle *handle); | ||
145 | |||
146 | /** | ||
147 | * Connects a tunnel to a hosting peer of a <i>room</i> through a so called <i>door</i> which is represented by | ||
148 | * a peer identity of a hosting peer. During the connection the handle will join the room as a member, waiting for | ||
149 | * an info message from the selected host. | ||
150 | * | ||
151 | * @param[in/out] room Room | ||
152 | * @param[in/out] handle Handle | ||
153 | * @param[in] door Peer identity | ||
154 | * @return #GNUNET_YES on success, #GNUNET_NO on failure. | ||
155 | */ | ||
156 | int | ||
157 | enter_room_at (struct GNUNET_MESSENGER_SrvRoom *room, | ||
158 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
159 | const struct GNUNET_PeerIdentity *door); | ||
160 | |||
161 | /** | ||
162 | * Packs a <i>message</i> depending on the selected <i>mode</i> into a newly allocated envelope. It will set the | ||
163 | * timestamp of the message, the sender id and the previous messages hash automatically before packing. The message | ||
164 | * will be signed by the handles EGO. | ||
165 | * | ||
166 | * If the optional <i>hash</i> parameter is a valid pointer, its value will be overridden by the signed messages hash. | ||
167 | * | ||
168 | * If <i>mode</i> is set to #GNUNET_MESSENGER_PACK_MODE_ENVELOPE, the function returns a valid envelope to send | ||
169 | * through a message queue, otherwise NULL. | ||
170 | * | ||
171 | * @param[in] room Room | ||
172 | * @param[in] handle Handle | ||
173 | * @param[in/out] message Message | ||
174 | * @param[out] hash Hash of message | ||
175 | * @param[in] mode Packing mode | ||
176 | * @return New envelope or NULL | ||
177 | */ | ||
178 | struct GNUNET_MQ_Envelope* | ||
179 | pack_room_message (const struct GNUNET_MESSENGER_SrvRoom *room, | ||
180 | const struct GNUNET_MESSENGER_SrvHandle *handle, | ||
181 | struct GNUNET_MESSENGER_Message *message, | ||
182 | struct GNUNET_HashCode *hash, | ||
183 | int mode); | ||
184 | |||
185 | /** | ||
186 | * Sends a <i>message</i> from a given <i>handle</i> into a <i>room</i>. The <i>hash</i> parameter will be | ||
187 | * updated with the hash-value resulting from the sent message. | ||
188 | * | ||
189 | * The function handles packing the message automatically and will call linked message-events locally even if | ||
190 | * the message won't be sent to another peer. | ||
191 | * | ||
192 | * The function returns #GNUNET_YES on success, #GNUNET_NO if message is null and | ||
193 | * #GNUNET_SYSERR if the message was known already. | ||
194 | * | ||
195 | * @param[in/out] room Room | ||
196 | * @param[in/out] handle Handle | ||
197 | * @param[in/out] message Message | ||
198 | * @return #GNUNET_YES on success, #GNUNET_NO or #GNUNET_SYSERR otherwise. | ||
199 | */ | ||
200 | int | ||
201 | send_room_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
202 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
203 | struct GNUNET_MESSENGER_Message *message); | ||
204 | |||
205 | /** | ||
206 | * Forwards a <i>message</i> with a given <i>hash</i> to a specific <i>tunnel</i> inside of a <i>room</i>. | ||
207 | * | ||
208 | * @param[in/out] room Room | ||
209 | * @param[in/out] tunnel Tunnel | ||
210 | * @param[in/out] message Message | ||
211 | * @param[in] hash Hash of message | ||
212 | */ | ||
213 | void | ||
214 | forward_room_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
215 | struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
216 | struct GNUNET_MESSENGER_Message *message, | ||
217 | const struct GNUNET_HashCode *hash); | ||
218 | |||
219 | /** | ||
220 | * Checks the current state of opening a given <i>room</i> from this peer and re-publishes it | ||
221 | * if necessary to a selected <i>tunnel</i> or to all connected tunnels if necessary or if the | ||
222 | * selected tunnel is NULL. | ||
223 | * | ||
224 | * @param[in/out] room Room | ||
225 | * @param[in/out] tunnel Tunnel | ||
226 | */ | ||
227 | void | ||
228 | check_room_peer_status (struct GNUNET_MESSENGER_SrvRoom *room, | ||
229 | struct GNUNET_MESSENGER_SrvTunnel *tunnel); | ||
230 | |||
231 | /** | ||
232 | * Reduces all current forks inside of the message history of a <i>room</i> to one remaining last message | ||
233 | * by merging them down. All merge messages will be sent from a given <i>handle</i>. | ||
234 | * | ||
235 | * @param[in/out] room Room | ||
236 | * @param[in/out] handle Handle | ||
237 | */ | ||
238 | void | ||
239 | merge_room_last_messages (struct GNUNET_MESSENGER_SrvRoom *room, | ||
240 | struct GNUNET_MESSENGER_SrvHandle *handle); | ||
241 | |||
242 | /** | ||
243 | * Deletes a message from the <i>room</i> with a given <i>hash</i> in a specific <i>delay</i> if | ||
244 | * the provided member by its session is permitted to do so. | ||
245 | * | ||
246 | * @param[in/out] room Room | ||
247 | * @param[in/out] session Member session | ||
248 | * @param[in] hash Hash of message | ||
249 | * @param[in] delay Delay of deletion | ||
250 | * @return #GNUNET_YES on success, #GNUNET_NO if permission gets denied, #GNUNET_SYSERR on operation failure | ||
251 | */ | ||
252 | int | ||
253 | delete_room_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
254 | struct GNUNET_MESSENGER_MemberSession *session, | ||
255 | const struct GNUNET_HashCode *hash, | ||
256 | const struct GNUNET_TIME_Relative delay); | ||
257 | |||
258 | /** | ||
259 | * Returns the CADET handle from a rooms service. | ||
260 | * | ||
261 | * @param[in/out] room Room | ||
262 | * @return CADET handle | ||
263 | */ | ||
264 | struct GNUNET_CADET_Handle* | ||
265 | get_room_cadet (struct GNUNET_MESSENGER_SrvRoom *room); | ||
266 | |||
267 | /** | ||
268 | * Returns the shared secret you need to access a <i>room</i>. | ||
269 | * | ||
270 | * @param[in] room Room | ||
271 | * @return Shared secret | ||
272 | */ | ||
273 | const struct GNUNET_HashCode* | ||
274 | get_room_key (const struct GNUNET_MESSENGER_SrvRoom *room); | ||
275 | |||
276 | /** | ||
277 | * Returns a tunnel inside of a <i>room</i> leading towards a given <i>peer</i> if such a tunnel exists, | ||
278 | * otherwise NULL. | ||
279 | * | ||
280 | * @param[in] room Room | ||
281 | * @param[in] peer Peer identity | ||
282 | * @return Tunnel or NULL | ||
283 | */ | ||
284 | const struct GNUNET_MESSENGER_SrvTunnel* | ||
285 | get_room_tunnel (const struct GNUNET_MESSENGER_SrvRoom *room, | ||
286 | const struct GNUNET_PeerIdentity *peer); | ||
287 | |||
288 | /** | ||
289 | * Method called whenever a <i>message</i> is found during a request in a <i>room</i>. | ||
290 | * | ||
291 | * @param[in/out] cls Closure from #request_room_message | ||
292 | * @param[in/out] room Room | ||
293 | * @param[in] message Message or NULL | ||
294 | * @param[in] hash Hash of message | ||
295 | */ | ||
296 | typedef void (GNUNET_MESSENGER_MessageRequestCallback) ( | ||
297 | void *cls, | ||
298 | struct GNUNET_MESSENGER_SrvRoom *room, | ||
299 | const struct GNUNET_MESSENGER_Message *message, | ||
300 | const struct GNUNET_HashCode *hash | ||
301 | ); | ||
302 | |||
303 | /** | ||
304 | * Requests a message from a <i>room</i> identified by a given <i>hash</i>. If the message is found, | ||
305 | * the selected <i>callback</i> will be called with it and the provided closure. If no matching message | ||
306 | * is found but it wasn't deleted the selected callback will be called with #NULL as message instead. | ||
307 | * In case of deletion the next available previous message will be used to call the callback. | ||
308 | * | ||
309 | * It is also possible that the given callback will not be called if the requesting session is not | ||
310 | * permitted! | ||
311 | * | ||
312 | * @param[in/out] room Room | ||
313 | * @param[in] hash Hash of message | ||
314 | * @param[in] callback Callback to process result | ||
315 | * @param[in] cls Closure for the <i>callback</i> | ||
316 | * @return #GNUNET_YES if the request could be processed, otherwise #GNUNET_NO | ||
317 | */ | ||
318 | int | ||
319 | request_room_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
320 | const struct GNUNET_HashCode *hash, | ||
321 | const struct GNUNET_MESSENGER_MemberSession *session, | ||
322 | GNUNET_MESSENGER_MessageRequestCallback callback, | ||
323 | void* cls); | ||
324 | |||
325 | /** | ||
326 | * Checks for potential collisions with member ids and solves them changing active handles ids if they | ||
327 | * use an already used member id (comparing public key and timestamp). | ||
328 | * | ||
329 | * @param[in/out] room Room | ||
330 | * @param[in] public_key Public key of EGO | ||
331 | * @param[in] member_id Member ID | ||
332 | * @param[in] timestamp Timestamp | ||
333 | */ | ||
334 | void | ||
335 | solve_room_member_collisions (struct GNUNET_MESSENGER_SrvRoom *room, | ||
336 | const struct GNUNET_IDENTITY_PublicKey *public_key, | ||
337 | const struct GNUNET_ShortHashCode *member_id, | ||
338 | struct GNUNET_TIME_Absolute timestamp); | ||
339 | |||
340 | /** | ||
341 | * Rebuilds the decentralized structure for a <i>room</i> by ensuring all required connections are made | ||
342 | * depending on the amount of peers and this peers index in the list of them. | ||
343 | * | ||
344 | * @param[in/out] room Room | ||
345 | */ | ||
346 | void | ||
347 | rebuild_room_basement_structure (struct GNUNET_MESSENGER_SrvRoom *room); | ||
348 | |||
349 | /** | ||
350 | * Loads the local configuration for a given <i>room</i> of a service which contains the last messages hash | ||
351 | * and the ruleset for general access of new members. | ||
352 | * | ||
353 | * @param[out] room Room | ||
354 | */ | ||
355 | void | ||
356 | load_room (struct GNUNET_MESSENGER_SrvRoom *room); | ||
357 | |||
358 | /** | ||
359 | * Saves the configuration for a given <i>room</i> of a service which contains the last messages hash | ||
360 | * and the ruleset for general access of new members locally. | ||
361 | * | ||
362 | * @param[in] room Room | ||
363 | */ | ||
364 | void | ||
365 | save_room (struct GNUNET_MESSENGER_SrvRoom *room); | ||
366 | |||
367 | #endif //GNUNET_SERVICE_MESSENGER_ROOM_H | ||
diff --git a/src/messenger/gnunet-service-messenger_service.c b/src/messenger/gnunet-service-messenger_service.c deleted file mode 100644 index b53b72af8..000000000 --- a/src/messenger/gnunet-service-messenger_service.c +++ /dev/null | |||
@@ -1,319 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_service.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_service.h" | ||
27 | #include "gnunet-service-messenger_message_kind.h" | ||
28 | #include "gnunet-service-messenger.h" | ||
29 | |||
30 | static void | ||
31 | callback_shutdown_service (void *cls) | ||
32 | { | ||
33 | struct GNUNET_MESSENGER_Service *service = cls; | ||
34 | |||
35 | if (service) | ||
36 | { | ||
37 | service->shutdown = NULL; | ||
38 | |||
39 | destroy_service (service); | ||
40 | } | ||
41 | } | ||
42 | |||
43 | struct GNUNET_MESSENGER_Service* | ||
44 | create_service (const struct GNUNET_CONFIGURATION_Handle *config, | ||
45 | struct GNUNET_SERVICE_Handle *service_handle) | ||
46 | { | ||
47 | GNUNET_assert((config) && (service_handle)); | ||
48 | |||
49 | struct GNUNET_MESSENGER_Service *service = GNUNET_new(struct GNUNET_MESSENGER_Service); | ||
50 | |||
51 | service->config = config; | ||
52 | service->service = service_handle; | ||
53 | |||
54 | service->shutdown = GNUNET_SCHEDULER_add_shutdown (&callback_shutdown_service, service); | ||
55 | |||
56 | service->dir = NULL; | ||
57 | |||
58 | if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (service->config, | ||
59 | GNUNET_MESSENGER_SERVICE_NAME, | ||
60 | "MESSENGER_DIR", &(service->dir))) | ||
61 | { | ||
62 | if (service->dir) | ||
63 | GNUNET_free(service->dir); | ||
64 | |||
65 | service->dir = NULL; | ||
66 | } | ||
67 | else | ||
68 | { | ||
69 | if ((GNUNET_YES != GNUNET_DISK_directory_test (service->dir, GNUNET_YES)) && (GNUNET_OK | ||
70 | != GNUNET_DISK_directory_create (service->dir))) | ||
71 | { | ||
72 | GNUNET_free(service->dir); | ||
73 | |||
74 | service->dir = NULL; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | service->cadet = GNUNET_CADET_connect (service->config); | ||
79 | |||
80 | init_ego_store(get_service_ego_store(service), service->config); | ||
81 | |||
82 | init_list_handles (&(service->handles)); | ||
83 | |||
84 | service->rooms = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); | ||
85 | |||
86 | init_contact_store(get_service_contact_store(service)); | ||
87 | |||
88 | return service; | ||
89 | } | ||
90 | |||
91 | static int | ||
92 | iterate_destroy_rooms (void *cls, | ||
93 | const struct GNUNET_HashCode *key, | ||
94 | void *value) | ||
95 | { | ||
96 | struct GNUNET_MESSENGER_SrvRoom *room = value; | ||
97 | destroy_room (room); | ||
98 | return GNUNET_YES; | ||
99 | } | ||
100 | |||
101 | void | ||
102 | destroy_service (struct GNUNET_MESSENGER_Service *service) | ||
103 | { | ||
104 | GNUNET_assert(service); | ||
105 | |||
106 | if (service->shutdown) | ||
107 | { | ||
108 | GNUNET_SCHEDULER_cancel (service->shutdown); | ||
109 | |||
110 | service->shutdown = NULL; | ||
111 | } | ||
112 | |||
113 | clear_ego_store(get_service_ego_store(service)); | ||
114 | clear_list_handles (&(service->handles)); | ||
115 | |||
116 | GNUNET_CONTAINER_multihashmap_iterate (service->rooms, iterate_destroy_rooms, NULL); | ||
117 | GNUNET_CONTAINER_multihashmap_destroy (service->rooms); | ||
118 | |||
119 | clear_contact_store(get_service_contact_store(service)); | ||
120 | |||
121 | if (service->cadet) | ||
122 | { | ||
123 | GNUNET_CADET_disconnect (service->cadet); | ||
124 | |||
125 | service->cadet = NULL; | ||
126 | } | ||
127 | |||
128 | if (service->dir) | ||
129 | { | ||
130 | GNUNET_free(service->dir); | ||
131 | |||
132 | service->dir = NULL; | ||
133 | } | ||
134 | |||
135 | GNUNET_SERVICE_shutdown (service->service); | ||
136 | |||
137 | GNUNET_free(service); | ||
138 | } | ||
139 | |||
140 | struct GNUNET_MESSENGER_EgoStore* | ||
141 | get_service_ego_store (struct GNUNET_MESSENGER_Service *service) | ||
142 | { | ||
143 | GNUNET_assert(service); | ||
144 | |||
145 | return &(service->ego_store); | ||
146 | } | ||
147 | |||
148 | struct GNUNET_MESSENGER_ContactStore* | ||
149 | get_service_contact_store (struct GNUNET_MESSENGER_Service *service) | ||
150 | { | ||
151 | GNUNET_assert(service); | ||
152 | |||
153 | return &(service->contact_store); | ||
154 | } | ||
155 | |||
156 | struct GNUNET_MESSENGER_SrvHandle* | ||
157 | add_service_handle (struct GNUNET_MESSENGER_Service *service, | ||
158 | struct GNUNET_MQ_Handle *mq) | ||
159 | { | ||
160 | GNUNET_assert((service) && (mq)); | ||
161 | |||
162 | struct GNUNET_MESSENGER_SrvHandle *handle = create_handle (service, mq); | ||
163 | |||
164 | if (handle) | ||
165 | { | ||
166 | add_list_handle (&(service->handles), handle); | ||
167 | } | ||
168 | |||
169 | return handle; | ||
170 | } | ||
171 | |||
172 | void | ||
173 | remove_service_handle (struct GNUNET_MESSENGER_Service *service, | ||
174 | struct GNUNET_MESSENGER_SrvHandle *handle) | ||
175 | { | ||
176 | GNUNET_assert((service) && (handle)); | ||
177 | |||
178 | if (!handle) | ||
179 | return; | ||
180 | |||
181 | if (GNUNET_YES == remove_list_handle (&(service->handles), handle)) | ||
182 | destroy_handle (handle); | ||
183 | } | ||
184 | |||
185 | int | ||
186 | get_service_peer_identity (const struct GNUNET_MESSENGER_Service *service, | ||
187 | struct GNUNET_PeerIdentity *peer) | ||
188 | { | ||
189 | GNUNET_assert((service) && (peer)); | ||
190 | |||
191 | return GNUNET_CRYPTO_get_peer_identity (service->config, peer); | ||
192 | } | ||
193 | |||
194 | struct GNUNET_MESSENGER_SrvRoom* | ||
195 | get_service_room (const struct GNUNET_MESSENGER_Service *service, | ||
196 | const struct GNUNET_HashCode *key) | ||
197 | { | ||
198 | GNUNET_assert((service) && (key)); | ||
199 | |||
200 | return GNUNET_CONTAINER_multihashmap_get (service->rooms, key); | ||
201 | } | ||
202 | |||
203 | int | ||
204 | open_service_room (struct GNUNET_MESSENGER_Service *service, | ||
205 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
206 | const struct GNUNET_HashCode *key) | ||
207 | { | ||
208 | GNUNET_assert((service) && (handle) && (key)); | ||
209 | |||
210 | struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (service, key); | ||
211 | |||
212 | if (room) | ||
213 | return open_room (room, handle); | ||
214 | |||
215 | room = create_room (handle, key); | ||
216 | |||
217 | if ((GNUNET_YES == open_room (room, handle)) && | ||
218 | (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (service->rooms, | ||
219 | key, room, | ||
220 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) | ||
221 | return GNUNET_YES; | ||
222 | |||
223 | destroy_room (room); | ||
224 | return GNUNET_NO; | ||
225 | } | ||
226 | |||
227 | int | ||
228 | entry_service_room (struct GNUNET_MESSENGER_Service *service, | ||
229 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
230 | const struct GNUNET_PeerIdentity *door, | ||
231 | const struct GNUNET_HashCode *key) | ||
232 | { | ||
233 | GNUNET_assert((service) && (handle) && (door) && (key)); | ||
234 | |||
235 | struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (service, key); | ||
236 | |||
237 | if (room) | ||
238 | { | ||
239 | if (GNUNET_YES == enter_room_at (room, handle, door)) | ||
240 | return GNUNET_YES; | ||
241 | else | ||
242 | return GNUNET_NO; | ||
243 | } | ||
244 | |||
245 | room = create_room (handle, key); | ||
246 | |||
247 | if ((GNUNET_YES == enter_room_at (room, handle, door)) && | ||
248 | (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (service->rooms, | ||
249 | key, room, | ||
250 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))) | ||
251 | { | ||
252 | return GNUNET_YES; | ||
253 | } | ||
254 | else | ||
255 | { | ||
256 | destroy_room (room); | ||
257 | return GNUNET_NO; | ||
258 | } | ||
259 | |||
260 | } | ||
261 | |||
262 | int | ||
263 | close_service_room (struct GNUNET_MESSENGER_Service *service, | ||
264 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
265 | const struct GNUNET_HashCode *key) | ||
266 | { | ||
267 | GNUNET_assert((service) && (handle) && (key)); | ||
268 | |||
269 | struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (service, key); | ||
270 | |||
271 | if (!room) | ||
272 | return GNUNET_NO; | ||
273 | |||
274 | send_room_message (room, handle, create_message_leave ()); | ||
275 | |||
276 | const struct GNUNET_ShortHashCode *id = get_handle_member_id (handle, key); | ||
277 | |||
278 | GNUNET_assert(id); | ||
279 | |||
280 | if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (handle->member_ids, key, id)) | ||
281 | return GNUNET_NO; | ||
282 | |||
283 | struct GNUNET_MESSENGER_SrvHandle *member_handle = (struct GNUNET_MESSENGER_SrvHandle*) find_list_handle_by_member ( | ||
284 | &(service->handles), key); | ||
285 | |||
286 | if (!member_handle) | ||
287 | { | ||
288 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_remove (service->rooms, key, room)) | ||
289 | { | ||
290 | destroy_room (room); | ||
291 | return GNUNET_YES; | ||
292 | } | ||
293 | else | ||
294 | return GNUNET_NO; | ||
295 | } | ||
296 | |||
297 | if (room->host == handle) | ||
298 | room->host = member_handle; | ||
299 | |||
300 | return GNUNET_YES; | ||
301 | } | ||
302 | |||
303 | void | ||
304 | handle_service_message (struct GNUNET_MESSENGER_Service *service, | ||
305 | struct GNUNET_MESSENGER_SrvRoom *room, | ||
306 | const struct GNUNET_MESSENGER_MemberSession *session, | ||
307 | const struct GNUNET_MESSENGER_Message *message, | ||
308 | const struct GNUNET_HashCode *hash) | ||
309 | { | ||
310 | GNUNET_assert((service) && (room) && (session) && (message) && (hash)); | ||
311 | |||
312 | struct GNUNET_MESSENGER_ListHandle *element = service->handles.head; | ||
313 | |||
314 | while (element) | ||
315 | { | ||
316 | notify_handle_message (element->handle, room, session, message, hash); | ||
317 | element = element->next; | ||
318 | } | ||
319 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_service.h b/src/messenger/gnunet-service-messenger_service.h deleted file mode 100644 index d364a93c0..000000000 --- a/src/messenger/gnunet-service-messenger_service.h +++ /dev/null | |||
@@ -1,212 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_service.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_SERVICE_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_SERVICE_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_configuration_lib.h" | ||
31 | #include "gnunet_crypto_lib.h" | ||
32 | #include "gnunet_container_lib.h" | ||
33 | #include "gnunet_disk_lib.h" | ||
34 | #include "gnunet_identity_service.h" | ||
35 | |||
36 | #include "gnunet-service-messenger_ego_store.h" | ||
37 | #include "gnunet-service-messenger_list_handles.h" | ||
38 | |||
39 | #include "messenger_api_contact_store.h" | ||
40 | #include "gnunet-service-messenger_room.h" | ||
41 | |||
42 | #include "gnunet-service-messenger_member_session.h" | ||
43 | |||
44 | struct GNUNET_MESSENGER_Service | ||
45 | { | ||
46 | const struct GNUNET_CONFIGURATION_Handle *config; | ||
47 | struct GNUNET_SERVICE_Handle *service; | ||
48 | |||
49 | struct GNUNET_SCHEDULER_Task *shutdown; | ||
50 | |||
51 | char *dir; | ||
52 | |||
53 | struct GNUNET_CADET_Handle *cadet; | ||
54 | |||
55 | struct GNUNET_MESSENGER_EgoStore ego_store; | ||
56 | struct GNUNET_MESSENGER_ContactStore contact_store; | ||
57 | |||
58 | struct GNUNET_MESSENGER_ListHandles handles; | ||
59 | |||
60 | struct GNUNET_CONTAINER_MultiHashMap *rooms; | ||
61 | }; | ||
62 | |||
63 | /** | ||
64 | * Creates and allocates a new service using a given <i>config</i> and a GNUnet service handle. | ||
65 | * | ||
66 | * @param[in] config Configuration | ||
67 | * @param[in/out] service_handle GNUnet service handle | ||
68 | * @return New service | ||
69 | */ | ||
70 | struct GNUNET_MESSENGER_Service* | ||
71 | create_service (const struct GNUNET_CONFIGURATION_Handle *config, | ||
72 | struct GNUNET_SERVICE_Handle *service_handle); | ||
73 | |||
74 | /** | ||
75 | * Destroys a <i>service</i> and frees its memory fully. | ||
76 | * | ||
77 | * @param[in/out] service Service | ||
78 | */ | ||
79 | void | ||
80 | destroy_service (struct GNUNET_MESSENGER_Service *service); | ||
81 | |||
82 | /** | ||
83 | * Returns the used EGO-store of a given <i>service</i>. | ||
84 | * | ||
85 | * @param[in/out] service Service | ||
86 | * @return EGO-store | ||
87 | */ | ||
88 | struct GNUNET_MESSENGER_EgoStore* | ||
89 | get_service_ego_store (struct GNUNET_MESSENGER_Service *service); | ||
90 | |||
91 | /** | ||
92 | * Returns the used contact store of a given <i>service</i>. | ||
93 | * | ||
94 | * @param[in/out] service Service | ||
95 | * @return Contact store | ||
96 | */ | ||
97 | struct GNUNET_MESSENGER_ContactStore* | ||
98 | get_service_contact_store (struct GNUNET_MESSENGER_Service *service); | ||
99 | |||
100 | /** | ||
101 | * Creates and adds a new handle to a <i>service</i> using a given message queue. | ||
102 | * | ||
103 | * @param[in/out] service Service | ||
104 | * @param[in/out] mq Message queue | ||
105 | * @return New handle | ||
106 | */ | ||
107 | struct GNUNET_MESSENGER_SrvHandle* | ||
108 | add_service_handle (struct GNUNET_MESSENGER_Service *service, | ||
109 | struct GNUNET_MQ_Handle *mq); | ||
110 | |||
111 | /** | ||
112 | * Removes a <i>handle</i> from a <i>service</i> and destroys it. | ||
113 | * | ||
114 | * @param[in/out] service Service | ||
115 | * @param[in/out] handle Handle | ||
116 | */ | ||
117 | void | ||
118 | remove_service_handle (struct GNUNET_MESSENGER_Service *service, | ||
119 | struct GNUNET_MESSENGER_SrvHandle *handle); | ||
120 | |||
121 | /** | ||
122 | * Tries to write the peer identity of the peer running a <i>service</i> on to the <i>peer</i> | ||
123 | * parameter. The functions returns #GNUNET_OK on success, otherwise #GNUNET_SYSERR. | ||
124 | * | ||
125 | * @param[in] service Service | ||
126 | * @param[out] peer Peer identity | ||
127 | * @return #GNUNET_OK on success, otherwise #GNUNET_SYSERR | ||
128 | */ | ||
129 | int | ||
130 | get_service_peer_identity (const struct GNUNET_MESSENGER_Service *service, | ||
131 | struct GNUNET_PeerIdentity *peer); | ||
132 | |||
133 | /** | ||
134 | * Returns the room identified by a given <i>key</i> for a <i>service</i>. If the service doesn't know any room | ||
135 | * using the given key, NULL gets returned. | ||
136 | * | ||
137 | * @param[in] service Service | ||
138 | * @param[in] key Key of room | ||
139 | * @return Room or NULL | ||
140 | */ | ||
141 | struct GNUNET_MESSENGER_SrvRoom* | ||
142 | get_service_room (const struct GNUNET_MESSENGER_Service *service, | ||
143 | const struct GNUNET_HashCode *key); | ||
144 | |||
145 | /** | ||
146 | * Tries to open a room using a given <i>key</i> for a <i>service</i> by a specific <i>handle</i>. The room will be | ||
147 | * created if necessary. If the function is successful, it returns #GNUNET_YES, otherwise #GNUNET_NO. | ||
148 | * | ||
149 | * @param[in/out] service Service | ||
150 | * @param[in/out] handle Handle | ||
151 | * @param[in] key Key of room | ||
152 | * @return #GNUNET_YES on success, otherwise #GNUNET_NO | ||
153 | */ | ||
154 | int | ||
155 | open_service_room (struct GNUNET_MESSENGER_Service *service, | ||
156 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
157 | const struct GNUNET_HashCode *key); | ||
158 | |||
159 | /** | ||
160 | * Tries to enter a room using a given <i>key</i> for a <i>service</i> by a specific <i>handle</i>. The room will | ||
161 | * be created if necessary. If the function is successful, it returns #GNUNET_YES, otherwise #GNUNET_NO. | ||
162 | * | ||
163 | * The room will be entered through the peer identitied by the peer identity provided as <i>door</i> parameter and | ||
164 | * a new connection will be made. | ||
165 | * | ||
166 | * @param[in/out] service Service | ||
167 | * @param[in/out] handle Handle | ||
168 | * @param[in] door Peer identity | ||
169 | * @param[in] key Key of room | ||
170 | * @return #GNUNET_YES on success, otherwise #GNUNET_NO | ||
171 | */ | ||
172 | int | ||
173 | entry_service_room (struct GNUNET_MESSENGER_Service *service, | ||
174 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
175 | const struct GNUNET_PeerIdentity *door, | ||
176 | const struct GNUNET_HashCode *key); | ||
177 | |||
178 | /** | ||
179 | * Tries to close a room using a given <i>key</i> for a <i>service</i> by a specific <i>handle</i>. The room will | ||
180 | * be created if necessary. If the function is successful, it returns #GNUNET_YES, otherwise #GNUNET_NO. | ||
181 | * | ||
182 | * If the specific handle is currently the host of the room for this service, a new handle which is a member will | ||
183 | * take its place. Otherwise the room will be destroyed for this service. | ||
184 | * | ||
185 | * @param[in/out] service Service | ||
186 | * @param[in/out] handle Handle | ||
187 | * @param[in] key Key of room | ||
188 | * @return #GNUNET_YES on success, otherwise #GNUNET_NO | ||
189 | */ | ||
190 | int | ||
191 | close_service_room (struct GNUNET_MESSENGER_Service *service, | ||
192 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
193 | const struct GNUNET_HashCode *key); | ||
194 | |||
195 | /** | ||
196 | * Sends a received or sent <i>message</i> with a given <i>hash</i> to each handle of a <i>service</i> which | ||
197 | * is currently member of a specific <i>room</i> for handling it in the client API. | ||
198 | * | ||
199 | * @param[in/out] service Service | ||
200 | * @param[in/out] room Room | ||
201 | * @param[in] session Member session | ||
202 | * @param[in] message Message | ||
203 | * @param[in] hash Hash of message | ||
204 | */ | ||
205 | void | ||
206 | handle_service_message (struct GNUNET_MESSENGER_Service *service, | ||
207 | struct GNUNET_MESSENGER_SrvRoom *room, | ||
208 | const struct GNUNET_MESSENGER_MemberSession *session, | ||
209 | const struct GNUNET_MESSENGER_Message *message, | ||
210 | const struct GNUNET_HashCode *hash); | ||
211 | |||
212 | #endif //GNUNET_SERVICE_MESSENGER_SERVICE_H | ||
diff --git a/src/messenger/gnunet-service-messenger_tunnel.c b/src/messenger/gnunet-service-messenger_tunnel.c deleted file mode 100644 index 45c10c1af..000000000 --- a/src/messenger/gnunet-service-messenger_tunnel.c +++ /dev/null | |||
@@ -1,402 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_tunnel.c | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet-service-messenger_tunnel.h" | ||
27 | |||
28 | #include "gnunet-service-messenger_handle.h" | ||
29 | #include "gnunet-service-messenger_message_recv.h" | ||
30 | #include "gnunet-service-messenger_message_store.h" | ||
31 | #include "gnunet-service-messenger_operation_store.h" | ||
32 | #include "gnunet-service-messenger_operation.h" | ||
33 | #include "messenger_api_util.h" | ||
34 | |||
35 | struct GNUNET_MESSENGER_SrvTunnel* | ||
36 | create_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, | ||
37 | const struct GNUNET_PeerIdentity *door) | ||
38 | { | ||
39 | GNUNET_assert((room) && (door)); | ||
40 | |||
41 | struct GNUNET_MESSENGER_SrvTunnel *tunnel = GNUNET_new(struct GNUNET_MESSENGER_SrvTunnel); | ||
42 | |||
43 | tunnel->room = room; | ||
44 | tunnel->channel = NULL; | ||
45 | |||
46 | tunnel->peer = GNUNET_PEER_intern (door); | ||
47 | |||
48 | tunnel->messenger_version = 0; | ||
49 | |||
50 | tunnel->peer_message = NULL; | ||
51 | |||
52 | init_message_state(&(tunnel->state)); | ||
53 | |||
54 | return tunnel; | ||
55 | } | ||
56 | |||
57 | void | ||
58 | destroy_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel) | ||
59 | { | ||
60 | GNUNET_assert(tunnel); | ||
61 | |||
62 | if (tunnel->channel) | ||
63 | GNUNET_CADET_channel_destroy (tunnel->channel); | ||
64 | |||
65 | GNUNET_PEER_change_rc (tunnel->peer, -1); | ||
66 | |||
67 | if (tunnel->peer_message) | ||
68 | GNUNET_free(tunnel->peer_message); | ||
69 | |||
70 | clear_message_state(&(tunnel->state)); | ||
71 | |||
72 | GNUNET_free(tunnel); | ||
73 | } | ||
74 | |||
75 | void | ||
76 | bind_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
77 | struct GNUNET_CADET_Channel *channel) | ||
78 | { | ||
79 | GNUNET_assert(tunnel); | ||
80 | |||
81 | if (tunnel->channel) | ||
82 | delayed_disconnect_channel (tunnel->channel); | ||
83 | |||
84 | tunnel->channel = channel; | ||
85 | } | ||
86 | |||
87 | extern void | ||
88 | callback_room_disconnect (struct GNUNET_MESSENGER_SrvRoom *room, | ||
89 | void *cls); | ||
90 | |||
91 | void | ||
92 | callback_tunnel_disconnect (void *cls, | ||
93 | const struct GNUNET_CADET_Channel *channel) | ||
94 | { | ||
95 | struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls; | ||
96 | |||
97 | if (tunnel) | ||
98 | { | ||
99 | tunnel->channel = NULL; | ||
100 | |||
101 | callback_room_disconnect (tunnel->room, cls); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | extern int | ||
106 | callback_verify_room_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
107 | void *cls, | ||
108 | struct GNUNET_MESSENGER_Message *message, | ||
109 | struct GNUNET_HashCode *hash); | ||
110 | |||
111 | int | ||
112 | check_tunnel_message (void *cls, | ||
113 | const struct GNUNET_MessageHeader *header) | ||
114 | { | ||
115 | struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls; | ||
116 | |||
117 | if (!tunnel) | ||
118 | return GNUNET_SYSERR; | ||
119 | |||
120 | const uint16_t length = ntohs (header->size) - sizeof(*header); | ||
121 | const char *buffer = (const char*) &header[1]; | ||
122 | |||
123 | struct GNUNET_MESSENGER_Message message; | ||
124 | |||
125 | if (length < get_message_kind_size(GNUNET_MESSENGER_KIND_UNKNOWN, GNUNET_YES)) | ||
126 | { | ||
127 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Tunnel error: Message too short! (%d)\n", length); | ||
128 | return GNUNET_SYSERR; | ||
129 | } | ||
130 | |||
131 | uint16_t padding = 0; | ||
132 | |||
133 | if (GNUNET_YES != decode_message (&message, length, buffer, GNUNET_YES, &padding)) | ||
134 | { | ||
135 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Tunnel error: Decoding failed!\n"); | ||
136 | return GNUNET_SYSERR; | ||
137 | } | ||
138 | |||
139 | struct GNUNET_HashCode hash; | ||
140 | hash_message (&message, length - padding, buffer, &hash); | ||
141 | |||
142 | return callback_verify_room_message (tunnel->room, cls, &message, &hash); | ||
143 | } | ||
144 | |||
145 | extern int | ||
146 | update_room_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
147 | struct GNUNET_MESSENGER_Message *message, | ||
148 | const struct GNUNET_HashCode *hash); | ||
149 | |||
150 | extern void | ||
151 | callback_room_handle_message (struct GNUNET_MESSENGER_SrvRoom *room, | ||
152 | struct GNUNET_MESSENGER_SrvHandle *handle, | ||
153 | const struct GNUNET_MESSENGER_Message *message, | ||
154 | const struct GNUNET_HashCode *hash); | ||
155 | |||
156 | static void | ||
157 | update_tunnel_last_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
158 | const struct GNUNET_HashCode *hash) | ||
159 | { | ||
160 | struct GNUNET_MESSENGER_OperationStore *operation_store = get_room_operation_store(tunnel->room); | ||
161 | |||
162 | const int requested = (GNUNET_MESSENGER_OP_REQUEST == get_store_operation_type(operation_store, hash)? | ||
163 | GNUNET_YES : GNUNET_NO | ||
164 | ); | ||
165 | |||
166 | struct GNUNET_MESSENGER_MessageStore *message_store = get_room_message_store(tunnel->room); | ||
167 | |||
168 | const struct GNUNET_MESSENGER_Message *message = get_store_message(message_store, hash); | ||
169 | |||
170 | if (message) | ||
171 | update_message_state(&(tunnel->state), requested, message, hash); | ||
172 | } | ||
173 | |||
174 | void | ||
175 | handle_tunnel_message (void *cls, const struct GNUNET_MessageHeader *header) | ||
176 | { | ||
177 | struct GNUNET_MESSENGER_SrvTunnel *tunnel = cls; | ||
178 | |||
179 | if (!tunnel) | ||
180 | return; | ||
181 | |||
182 | const uint16_t length = ntohs (header->size) - sizeof(*header); | ||
183 | const char *buffer = (const char*) &header[1]; | ||
184 | |||
185 | struct GNUNET_MESSENGER_Message message; | ||
186 | struct GNUNET_HashCode hash; | ||
187 | |||
188 | uint16_t padding = 0; | ||
189 | |||
190 | decode_message (&message, length, buffer, GNUNET_YES, &padding); | ||
191 | hash_message (&message, length - padding, buffer, &hash); | ||
192 | |||
193 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Got message of kind: %s!\n", | ||
194 | GNUNET_MESSENGER_name_of_kind(message.header.kind)); | ||
195 | |||
196 | const int new_message = update_room_message ( | ||
197 | tunnel->room, copy_message (&message), &hash | ||
198 | ); | ||
199 | |||
200 | if (GNUNET_YES != new_message) | ||
201 | goto receive_done; | ||
202 | |||
203 | update_tunnel_last_message (tunnel, &hash); | ||
204 | |||
205 | int forward_message = GNUNET_YES; | ||
206 | |||
207 | switch (message.header.kind) | ||
208 | { | ||
209 | case GNUNET_MESSENGER_KIND_INFO: | ||
210 | forward_message = recv_message_info (tunnel->room, tunnel, &message, &hash); | ||
211 | break; | ||
212 | case GNUNET_MESSENGER_KIND_PEER: | ||
213 | forward_message = recv_message_peer (tunnel->room, tunnel, &message, &hash); | ||
214 | break; | ||
215 | case GNUNET_MESSENGER_KIND_REQUEST: | ||
216 | forward_message = recv_message_request (tunnel->room, tunnel, &message, &hash); | ||
217 | break; | ||
218 | default: | ||
219 | break; | ||
220 | } | ||
221 | |||
222 | if (GNUNET_YES == forward_message) | ||
223 | { | ||
224 | forward_room_message (tunnel->room, tunnel, &message, &hash); | ||
225 | callback_room_handle_message (tunnel->room, NULL, &message, &hash); | ||
226 | } | ||
227 | |||
228 | receive_done: | ||
229 | cleanup_message(&message); | ||
230 | |||
231 | GNUNET_CADET_receive_done (tunnel->channel); | ||
232 | } | ||
233 | |||
234 | int | ||
235 | connect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel) | ||
236 | { | ||
237 | GNUNET_assert(tunnel); | ||
238 | |||
239 | if (tunnel->channel) | ||
240 | return GNUNET_NO; | ||
241 | |||
242 | const struct GNUNET_PeerIdentity *door = GNUNET_PEER_resolve2 (tunnel->peer); | ||
243 | |||
244 | struct GNUNET_CADET_Handle *cadet = get_room_cadet (tunnel->room); | ||
245 | const struct GNUNET_HashCode *key = get_room_key (tunnel->room); | ||
246 | |||
247 | struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size(tunnel_message, GNUNET_MESSAGE_TYPE_CADET_CLI, | ||
248 | struct GNUNET_MessageHeader, NULL), | ||
249 | GNUNET_MQ_handler_end() }; | ||
250 | |||
251 | struct GNUNET_HashCode port; | ||
252 | convert_messenger_key_to_port(key, &port); | ||
253 | tunnel->channel = GNUNET_CADET_channel_create (cadet, tunnel, door, &port, NULL, callback_tunnel_disconnect, handlers); | ||
254 | |||
255 | return GNUNET_YES; | ||
256 | } | ||
257 | |||
258 | void | ||
259 | disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel) | ||
260 | { | ||
261 | GNUNET_assert(tunnel); | ||
262 | |||
263 | if (tunnel->channel) | ||
264 | { | ||
265 | delayed_disconnect_channel (tunnel->channel); | ||
266 | |||
267 | tunnel->channel = NULL; | ||
268 | } | ||
269 | } | ||
270 | |||
271 | int | ||
272 | is_tunnel_connected (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) | ||
273 | { | ||
274 | GNUNET_assert(tunnel); | ||
275 | |||
276 | return (tunnel->channel ? GNUNET_YES : GNUNET_NO); | ||
277 | } | ||
278 | |||
279 | struct GNUNET_MESSENGER_MessageSent | ||
280 | { | ||
281 | struct GNUNET_MESSENGER_SrvTunnel *tunnel; | ||
282 | struct GNUNET_HashCode hash; | ||
283 | }; | ||
284 | |||
285 | static void | ||
286 | callback_tunnel_sent (void *cls) | ||
287 | { | ||
288 | struct GNUNET_MESSENGER_MessageSent *sent = cls; | ||
289 | |||
290 | if (sent->tunnel) | ||
291 | update_tunnel_last_message (sent->tunnel, &(sent->hash)); | ||
292 | |||
293 | GNUNET_free(sent); | ||
294 | } | ||
295 | |||
296 | void | ||
297 | send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
298 | struct GNUNET_MQ_Envelope *env, | ||
299 | const struct GNUNET_HashCode *hash) | ||
300 | { | ||
301 | GNUNET_assert((tunnel) && (env) && (hash)); | ||
302 | |||
303 | struct GNUNET_MQ_Handle *mq = GNUNET_CADET_get_mq (tunnel->channel); | ||
304 | |||
305 | struct GNUNET_MESSENGER_MessageSent *sent = GNUNET_new(struct GNUNET_MESSENGER_MessageSent); | ||
306 | |||
307 | GNUNET_memcpy(&(sent->hash), hash, sizeof(struct GNUNET_HashCode)); | ||
308 | |||
309 | sent->tunnel = tunnel; | ||
310 | |||
311 | GNUNET_MQ_notify_sent (env, callback_tunnel_sent, sent); | ||
312 | GNUNET_MQ_send (mq, env); | ||
313 | } | ||
314 | |||
315 | int | ||
316 | send_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
317 | void *handle, | ||
318 | struct GNUNET_MESSENGER_Message *message) | ||
319 | { | ||
320 | GNUNET_assert((tunnel) && (handle)); | ||
321 | |||
322 | if (!message) | ||
323 | return GNUNET_NO; | ||
324 | |||
325 | struct GNUNET_HashCode hash; | ||
326 | struct GNUNET_MQ_Envelope *env = pack_room_message ( | ||
327 | tunnel->room, (struct GNUNET_MESSENGER_SrvHandle*) handle, | ||
328 | message, &hash, GNUNET_MESSENGER_PACK_MODE_ENVELOPE | ||
329 | ); | ||
330 | |||
331 | destroy_message(message); | ||
332 | |||
333 | if (!env) | ||
334 | return GNUNET_NO; | ||
335 | |||
336 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending tunnel message: %s\n", | ||
337 | GNUNET_h2s(&hash)); | ||
338 | |||
339 | send_tunnel_envelope (tunnel, env, &hash); | ||
340 | return GNUNET_YES; | ||
341 | } | ||
342 | |||
343 | void | ||
344 | forward_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
345 | const struct GNUNET_MESSENGER_Message *message, | ||
346 | const struct GNUNET_HashCode *hash) | ||
347 | { | ||
348 | GNUNET_assert((tunnel) && (message) && (hash)); | ||
349 | |||
350 | struct GNUNET_MESSENGER_Message *copy = copy_message(message); | ||
351 | struct GNUNET_MQ_Envelope *env = pack_message (copy, NULL, NULL, GNUNET_MESSENGER_PACK_MODE_ENVELOPE); | ||
352 | |||
353 | destroy_message(copy); | ||
354 | |||
355 | if (!env) | ||
356 | return; | ||
357 | |||
358 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Forwarding tunnel message: %s\n", | ||
359 | GNUNET_h2s(hash)); | ||
360 | |||
361 | send_tunnel_envelope (tunnel, env, hash); | ||
362 | } | ||
363 | |||
364 | const struct GNUNET_HashCode* | ||
365 | get_tunnel_peer_message (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) | ||
366 | { | ||
367 | GNUNET_assert(tunnel); | ||
368 | |||
369 | return tunnel->peer_message; | ||
370 | } | ||
371 | |||
372 | void | ||
373 | get_tunnel_peer_identity (const struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
374 | struct GNUNET_PeerIdentity *peer) | ||
375 | { | ||
376 | GNUNET_assert(tunnel); | ||
377 | |||
378 | GNUNET_PEER_resolve(tunnel->peer, peer); | ||
379 | } | ||
380 | |||
381 | uint32_t | ||
382 | get_tunnel_messenger_version (const struct GNUNET_MESSENGER_SrvTunnel *tunnel) | ||
383 | { | ||
384 | GNUNET_assert(tunnel); | ||
385 | |||
386 | return tunnel->messenger_version; | ||
387 | } | ||
388 | |||
389 | int | ||
390 | update_tunnel_messenger_version (struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
391 | uint32_t version) | ||
392 | { | ||
393 | GNUNET_assert(tunnel); | ||
394 | |||
395 | if (version != GNUNET_MESSENGER_VERSION) | ||
396 | return GNUNET_SYSERR; | ||
397 | |||
398 | if (version > tunnel->messenger_version) | ||
399 | tunnel->messenger_version = version; | ||
400 | |||
401 | return GNUNET_OK; | ||
402 | } | ||
diff --git a/src/messenger/gnunet-service-messenger_tunnel.h b/src/messenger/gnunet-service-messenger_tunnel.h deleted file mode 100644 index 7bd749281..000000000 --- a/src/messenger/gnunet-service-messenger_tunnel.h +++ /dev/null | |||
@@ -1,194 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/gnunet-service-messenger_tunnel.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_TUNNEL_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_TUNNEL_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_cadet_service.h" | ||
31 | #include "gnunet_peer_lib.h" | ||
32 | #include "gnunet_crypto_lib.h" | ||
33 | |||
34 | #include "gnunet-service-messenger_room.h" | ||
35 | #include "gnunet-service-messenger_message_state.h" | ||
36 | |||
37 | struct GNUNET_MESSENGER_SrvTunnel | ||
38 | { | ||
39 | struct GNUNET_MESSENGER_SrvRoom *room; | ||
40 | struct GNUNET_CADET_Channel *channel; | ||
41 | |||
42 | GNUNET_PEER_Id peer; | ||
43 | |||
44 | uint32_t messenger_version; | ||
45 | |||
46 | struct GNUNET_HashCode *peer_message; | ||
47 | struct GNUNET_MESSENGER_MessageState state; | ||
48 | }; | ||
49 | |||
50 | /** | ||
51 | * Creates and allocates a tunnel of a <i>room</i> to a specific peer identity (called <i>door</i>). | ||
52 | * | ||
53 | * @param[in/out] room Room | ||
54 | * @param[in] door Peer identity | ||
55 | * @return New tunnel | ||
56 | */ | ||
57 | struct GNUNET_MESSENGER_SrvTunnel* | ||
58 | create_tunnel (struct GNUNET_MESSENGER_SrvRoom *room, | ||
59 | const struct GNUNET_PeerIdentity *door); | ||
60 | |||
61 | /** | ||
62 | * Destroys a <i>tunnel</i> and frees its memory fully. | ||
63 | * | ||
64 | * @param[in/out] tunnel | ||
65 | */ | ||
66 | void | ||
67 | destroy_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel); | ||
68 | |||
69 | /** | ||
70 | * Binds a CADET <i>channel</i> to a <i>tunnel</i> and replaces its channel | ||
71 | * the tunnel is currently bound to if necessary. | ||
72 | * | ||
73 | * @param[in/out] tunnel Tunnel | ||
74 | * @param[in/out] channel CADET channel | ||
75 | */ | ||
76 | void | ||
77 | bind_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
78 | struct GNUNET_CADET_Channel *channel); | ||
79 | |||
80 | /** | ||
81 | * Tries to connect a <i>tunnel</i> by creating a new CADET channel and binding it. | ||
82 | * The function returns #GNUNET_YES on success, otherwise #GNUNET_NO. | ||
83 | * | ||
84 | * @param[in/out] tunnel Tunnel | ||
85 | * @return #GNUNET_YES on success, otherwise #GNUNET_NO | ||
86 | */ | ||
87 | int | ||
88 | connect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel); | ||
89 | |||
90 | /** | ||
91 | * Disconnects and unbinds a channel from a <i>tunnel</i>. The actual disconnection | ||
92 | * will be asynchronous. | ||
93 | * | ||
94 | * @param[in/out] tunnel Tunnel | ||
95 | */ | ||
96 | void | ||
97 | disconnect_tunnel (struct GNUNET_MESSENGER_SrvTunnel *tunnel); | ||
98 | |||
99 | /** | ||
100 | * Returns the status of a currently bound channel of a <i>tunnel</i>. | ||
101 | * | ||
102 | * @param[in] tunnel Tunnel | ||
103 | * @return #GNUNET_YES or #GNUNET_NO | ||
104 | */ | ||
105 | int | ||
106 | is_tunnel_connected (const struct GNUNET_MESSENGER_SrvTunnel *tunnel); | ||
107 | |||
108 | /** | ||
109 | * Sends an envelope containing a <i>message</i> with a given <i>hash</i> through | ||
110 | * a <i>tunnel</i>. | ||
111 | * | ||
112 | * @param[in/out] tunnel Tunnel | ||
113 | * @param[in/out] env Envelope | ||
114 | * @param[in] hash Hash of message | ||
115 | */ | ||
116 | void | ||
117 | send_tunnel_envelope (struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
118 | struct GNUNET_MQ_Envelope *env, | ||
119 | const struct GNUNET_HashCode *hash); | ||
120 | |||
121 | /** | ||
122 | * Sends a <i>message</i> by packing it automatically into an envelope and passing it | ||
123 | * through the <i>tunnel</i>. The used <i>handle</i> will sign the message and | ||
124 | * the <i>hash</i> will be calculated and stored. | ||
125 | * | ||
126 | * @param[in/out] tunnel Tunnel | ||
127 | * @param[in/out] handle Handle | ||
128 | * @param[in/out] message Message | ||
129 | * @return #GNUNET_YES on success, GNUNET_NO otherwise | ||
130 | */ | ||
131 | int | ||
132 | send_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
133 | void *handle, | ||
134 | struct GNUNET_MESSENGER_Message *message); | ||
135 | |||
136 | /** | ||
137 | * Forwards a given <i>message</i> with a known <i>hash</i> through a <i>tunnel</i>. | ||
138 | * | ||
139 | * @param[in/out] tunnel Tunnel | ||
140 | * @param[in] message Message | ||
141 | * @param[in] hash Hash of message | ||
142 | */ | ||
143 | void | ||
144 | forward_tunnel_message (struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
145 | const struct GNUNET_MESSENGER_Message *message, | ||
146 | const struct GNUNET_HashCode *hash); | ||
147 | |||
148 | /** | ||
149 | * Returns the hash of the latest peer message published through a given <i>tunnel</i> | ||
150 | * and matching the tunnels peer identity. If no peer message has been linked to the tunnel | ||
151 | * yet, NULL gets returned. | ||
152 | * | ||
153 | * @param[in] tunnel Tunnel | ||
154 | * @return Hash of peer message or NULL | ||
155 | */ | ||
156 | const struct GNUNET_HashCode* | ||
157 | get_tunnel_peer_message (const struct GNUNET_MESSENGER_SrvTunnel *tunnel); | ||
158 | |||
159 | /** | ||
160 | * Writes the peer identity of the peer connected via <i>tunnel</i> to this peer into | ||
161 | * the <i>peer</i> parameter. | ||
162 | * | ||
163 | * @param[in] tunnel Tunnel | ||
164 | * @param[out] peer Peer identity | ||
165 | */ | ||
166 | void | ||
167 | get_tunnel_peer_identity (const struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
168 | struct GNUNET_PeerIdentity *peer); | ||
169 | |||
170 | /** | ||
171 | * Returns the current messenger version the peer connected via a given <i>tunnel</i> | ||
172 | * has reported to be using if it was compatible during updating. | ||
173 | * | ||
174 | * @see update_tunnel_messenger_version | ||
175 | * | ||
176 | * @param[in] tunnel Tunnel | ||
177 | * @return Version of messenger | ||
178 | */ | ||
179 | uint32_t | ||
180 | get_tunnel_messenger_version (const struct GNUNET_MESSENGER_SrvTunnel *tunnel); | ||
181 | |||
182 | /** | ||
183 | * Updates the messenger version of the <i>tunnel</i> to a given <i>version</i> if | ||
184 | * it is compatible to the running peer of the service. Depending on success it | ||
185 | * returns #GNUNET_OK or #GNUNET_SYSERR on failure. | ||
186 | * | ||
187 | * @param[in/out] tunnel Tunnel | ||
188 | * @param[in] version Version of messenger | ||
189 | */ | ||
190 | int | ||
191 | update_tunnel_messenger_version (struct GNUNET_MESSENGER_SrvTunnel *tunnel, | ||
192 | uint32_t version); | ||
193 | |||
194 | #endif //GNUNET_SERVICE_MESSENGER_TUNNEL_H | ||
diff --git a/src/messenger/messenger.conf.in b/src/messenger/messenger.conf.in deleted file mode 100644 index 6b54550ea..000000000 --- a/src/messenger/messenger.conf.in +++ /dev/null | |||
@@ -1,14 +0,0 @@ | |||
1 | [messenger] | ||
2 | START_ON_DEMAND = YES | ||
3 | RUN_PER_USER = YES | ||
4 | PORT = 2097 | ||
5 | HOSTNAME = localhost | ||
6 | BINARY = gnunet-service-messenger | ||
7 | ACCEPT_FROM = 127.0.0.1; | ||
8 | ACCEPT_FROM6 = ::1; | ||
9 | UNIXPATH = $GNUNET_RUNTIME_DIR/gnunet-service-messenger.sock | ||
10 | UNIX_MATCH_UID = NO | ||
11 | UNIX_MATCH_GID = YES | ||
12 | |||
13 | # Directory to store messages and contacts | ||
14 | MESSENGER_DIR = $GNUNET_DATA_HOME/messenger/ \ No newline at end of file | ||
diff --git a/src/messenger/messenger_api.c b/src/messenger/messenger_api.c deleted file mode 100644 index a37b1b10b..000000000 --- a/src/messenger/messenger_api.c +++ /dev/null | |||
@@ -1,792 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api.c | ||
23 | * @brief messenger api: client implementation of GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "gnunet_messenger_service.h" | ||
27 | |||
28 | #include "gnunet-service-messenger.h" | ||
29 | |||
30 | #include "messenger_api_handle.h" | ||
31 | #include "messenger_api_message.h" | ||
32 | #include "messenger_api_util.h" | ||
33 | |||
34 | const char* | ||
35 | GNUNET_MESSENGER_name_of_kind (enum GNUNET_MESSENGER_MessageKind kind) | ||
36 | { | ||
37 | switch (kind) | ||
38 | { | ||
39 | case GNUNET_MESSENGER_KIND_INFO: | ||
40 | return "INFO"; | ||
41 | case GNUNET_MESSENGER_KIND_JOIN: | ||
42 | return "JOIN"; | ||
43 | case GNUNET_MESSENGER_KIND_LEAVE: | ||
44 | return "LEAVE"; | ||
45 | case GNUNET_MESSENGER_KIND_NAME: | ||
46 | return "NAME"; | ||
47 | case GNUNET_MESSENGER_KIND_KEY: | ||
48 | return "KEY"; | ||
49 | case GNUNET_MESSENGER_KIND_PEER: | ||
50 | return "PEER"; | ||
51 | case GNUNET_MESSENGER_KIND_ID: | ||
52 | return "ID"; | ||
53 | case GNUNET_MESSENGER_KIND_MISS: | ||
54 | return "MISS"; | ||
55 | case GNUNET_MESSENGER_KIND_MERGE: | ||
56 | return "MERGE"; | ||
57 | case GNUNET_MESSENGER_KIND_REQUEST: | ||
58 | return "REQUEST"; | ||
59 | case GNUNET_MESSENGER_KIND_INVITE: | ||
60 | return "INVITE"; | ||
61 | case GNUNET_MESSENGER_KIND_TEXT: | ||
62 | return "TEXT"; | ||
63 | case GNUNET_MESSENGER_KIND_FILE: | ||
64 | return "FILE"; | ||
65 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
66 | return "PRIVATE"; | ||
67 | default: | ||
68 | return "UNKNOWN"; | ||
69 | } | ||
70 | } | ||
71 | |||
72 | static int | ||
73 | check_get_name (void *cls, | ||
74 | const struct GNUNET_MESSENGER_NameMessage *msg) | ||
75 | { | ||
76 | GNUNET_MQ_check_zero_termination(msg); | ||
77 | return GNUNET_OK; | ||
78 | } | ||
79 | |||
80 | static void | ||
81 | handle_get_name (void *cls, | ||
82 | const struct GNUNET_MESSENGER_NameMessage *msg) | ||
83 | { | ||
84 | struct GNUNET_MESSENGER_Handle *handle = cls; | ||
85 | |||
86 | const char *name = ((const char*) msg) + sizeof(*msg); | ||
87 | |||
88 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set name of handle: %s\n", name); | ||
89 | |||
90 | set_handle_name (handle, strlen (name) > 0 ? name : NULL); | ||
91 | } | ||
92 | |||
93 | static int | ||
94 | check_get_key (void *cls, | ||
95 | const struct GNUNET_MESSENGER_KeyMessage *msg) | ||
96 | { | ||
97 | const uint16_t full_length = ntohs (msg->header.size); | ||
98 | |||
99 | if (full_length < sizeof(*msg)) | ||
100 | return GNUNET_NO; | ||
101 | |||
102 | const uint16_t length = full_length - sizeof(*msg); | ||
103 | const char *buffer = ((const char*) msg) + sizeof(*msg); | ||
104 | |||
105 | struct GNUNET_IDENTITY_PublicKey pubkey; | ||
106 | if (GNUNET_IDENTITY_read_key_from_buffer(&pubkey, buffer, length) < 0) | ||
107 | return GNUNET_NO; | ||
108 | |||
109 | return GNUNET_OK; | ||
110 | } | ||
111 | |||
112 | static void | ||
113 | handle_get_key (void *cls, | ||
114 | const struct GNUNET_MESSENGER_KeyMessage *msg) | ||
115 | { | ||
116 | struct GNUNET_MESSENGER_Handle *handle = cls; | ||
117 | |||
118 | const uint16_t length = ntohs (msg->header.size) - sizeof(*msg); | ||
119 | const char *buffer = ((const char*) msg) + sizeof(*msg); | ||
120 | |||
121 | struct GNUNET_IDENTITY_PublicKey pubkey; | ||
122 | if (GNUNET_IDENTITY_read_key_from_buffer(&pubkey, buffer, length) < 0) | ||
123 | return; | ||
124 | |||
125 | char* str = GNUNET_IDENTITY_public_key_to_string (&pubkey); | ||
126 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set key of handle: %s\n", str); | ||
127 | GNUNET_free(str); | ||
128 | |||
129 | set_handle_key (handle, &pubkey); | ||
130 | |||
131 | if (handle->identity_callback) | ||
132 | handle->identity_callback (handle->identity_cls, handle); | ||
133 | } | ||
134 | |||
135 | static void | ||
136 | handle_member_id (void *cls, | ||
137 | const struct GNUNET_MESSENGER_MemberMessage *msg) | ||
138 | { | ||
139 | struct GNUNET_MESSENGER_Handle *handle = cls; | ||
140 | |||
141 | const struct GNUNET_HashCode *key = &(msg->key); | ||
142 | const struct GNUNET_ShortHashCode *id = &(msg->id); | ||
143 | |||
144 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set id of handle in room: %s\n", GNUNET_h2s (key)); | ||
145 | |||
146 | struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); | ||
147 | |||
148 | if (room) | ||
149 | { | ||
150 | if (!room->contact_id) | ||
151 | room->contact_id = GNUNET_new(struct GNUNET_ShortHashCode); | ||
152 | |||
153 | GNUNET_memcpy(room->contact_id, id, sizeof(*id)); | ||
154 | } | ||
155 | } | ||
156 | |||
157 | static void | ||
158 | handle_room_open (void *cls, | ||
159 | const struct GNUNET_MESSENGER_RoomMessage *msg) | ||
160 | { | ||
161 | struct GNUNET_MESSENGER_Handle *handle = cls; | ||
162 | |||
163 | const struct GNUNET_HashCode *key = &(msg->key); | ||
164 | |||
165 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Opened room: %s\n", GNUNET_h2s (key)); | ||
166 | |||
167 | open_handle_room (handle, key); | ||
168 | } | ||
169 | |||
170 | static void | ||
171 | handle_room_entry (void *cls, | ||
172 | const struct GNUNET_MESSENGER_RoomMessage *msg) | ||
173 | { | ||
174 | struct GNUNET_MESSENGER_Handle *handle = cls; | ||
175 | |||
176 | const struct GNUNET_PeerIdentity *door = &(msg->door); | ||
177 | const struct GNUNET_HashCode *key = &(msg->key); | ||
178 | |||
179 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Entered room: %s\n", GNUNET_h2s (key)); | ||
180 | |||
181 | entry_handle_room_at (handle, door, key); | ||
182 | } | ||
183 | |||
184 | static void | ||
185 | handle_room_close (void *cls, | ||
186 | const struct GNUNET_MESSENGER_RoomMessage *msg) | ||
187 | { | ||
188 | struct GNUNET_MESSENGER_Handle *handle = cls; | ||
189 | |||
190 | const struct GNUNET_HashCode *key = &(msg->key); | ||
191 | |||
192 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Closed room: %s\n", GNUNET_h2s (key)); | ||
193 | |||
194 | close_handle_room (handle, key); | ||
195 | } | ||
196 | |||
197 | static int | ||
198 | check_recv_message (void *cls, | ||
199 | const struct GNUNET_MESSENGER_RecvMessage *msg) | ||
200 | { | ||
201 | const uint16_t full_length = ntohs (msg->header.size); | ||
202 | |||
203 | if (full_length < sizeof(*msg)) | ||
204 | return GNUNET_NO; | ||
205 | |||
206 | const uint16_t length = full_length - sizeof(*msg); | ||
207 | const char *buffer = ((const char*) msg) + sizeof(*msg); | ||
208 | |||
209 | struct GNUNET_MESSENGER_Message message; | ||
210 | |||
211 | if (length < get_message_kind_size(GNUNET_MESSENGER_KIND_UNKNOWN, GNUNET_YES)) | ||
212 | return GNUNET_NO; | ||
213 | |||
214 | if (GNUNET_YES != decode_message (&message, length, buffer, GNUNET_YES, NULL)) | ||
215 | return GNUNET_NO; | ||
216 | |||
217 | cleanup_message(&message); | ||
218 | return GNUNET_OK; | ||
219 | } | ||
220 | |||
221 | static void | ||
222 | handle_recv_message (void *cls, | ||
223 | const struct GNUNET_MESSENGER_RecvMessage *msg) | ||
224 | { | ||
225 | struct GNUNET_MESSENGER_Handle *handle = cls; | ||
226 | |||
227 | const struct GNUNET_HashCode *key = &(msg->key); | ||
228 | const struct GNUNET_HashCode *sender = &(msg->sender); | ||
229 | const struct GNUNET_HashCode *context = &(msg->context); | ||
230 | const struct GNUNET_HashCode *hash = &(msg->hash); | ||
231 | const enum GNUNET_MESSENGER_MessageFlags flags = ( | ||
232 | (enum GNUNET_MESSENGER_MessageFlags) (msg->flags) | ||
233 | ); | ||
234 | |||
235 | const uint16_t length = ntohs (msg->header.size) - sizeof(*msg); | ||
236 | const char *buffer = ((const char*) msg) + sizeof(*msg); | ||
237 | |||
238 | struct GNUNET_MESSENGER_Message message; | ||
239 | decode_message (&message, length, buffer, GNUNET_YES, NULL); | ||
240 | |||
241 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Receiving message: %s\n", GNUNET_MESSENGER_name_of_kind (message.header.kind)); | ||
242 | |||
243 | struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); | ||
244 | |||
245 | if (room) | ||
246 | { | ||
247 | struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store(handle); | ||
248 | |||
249 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Raw contact from sender and context: (%s : %s)\n", | ||
250 | GNUNET_h2s(sender), GNUNET_h2s_full(context)); | ||
251 | |||
252 | struct GNUNET_MESSENGER_Contact *contact = get_store_contact_raw( | ||
253 | store, context, sender | ||
254 | ); | ||
255 | |||
256 | handle_room_message (room, contact, &message, hash); | ||
257 | |||
258 | const struct GNUNET_MESSENGER_Message *stored_message = get_room_message(room, hash); | ||
259 | |||
260 | if (handle->msg_callback) | ||
261 | handle->msg_callback (handle->msg_cls, room, contact, stored_message, hash, flags); | ||
262 | } | ||
263 | else | ||
264 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Unknown room for this client: %s\n", GNUNET_h2s (key)); | ||
265 | |||
266 | cleanup_message(&message); | ||
267 | } | ||
268 | |||
269 | static void | ||
270 | reconnect (struct GNUNET_MESSENGER_Handle *handle); | ||
271 | |||
272 | static void | ||
273 | send_open_room (struct GNUNET_MESSENGER_Handle *handle, | ||
274 | struct GNUNET_MESSENGER_Room *room) | ||
275 | { | ||
276 | struct GNUNET_MESSENGER_RoomMessage *msg; | ||
277 | struct GNUNET_MQ_Envelope *env; | ||
278 | |||
279 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN); | ||
280 | GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key)); | ||
281 | GNUNET_MQ_send (handle->mq, env); | ||
282 | } | ||
283 | |||
284 | static void | ||
285 | send_enter_room (struct GNUNET_MESSENGER_Handle *handle, | ||
286 | struct GNUNET_MESSENGER_Room *room, | ||
287 | const struct GNUNET_PeerIdentity *door) | ||
288 | { | ||
289 | struct GNUNET_MESSENGER_RoomMessage *msg; | ||
290 | struct GNUNET_MQ_Envelope *env; | ||
291 | |||
292 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY); | ||
293 | GNUNET_memcpy(&(msg->door), door, sizeof(*door)); | ||
294 | GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key)); | ||
295 | GNUNET_MQ_send (handle->mq, env); | ||
296 | } | ||
297 | |||
298 | static void | ||
299 | send_close_room (struct GNUNET_MESSENGER_Handle *handle, | ||
300 | struct GNUNET_MESSENGER_Room *room) | ||
301 | { | ||
302 | struct GNUNET_MESSENGER_RoomMessage *msg; | ||
303 | struct GNUNET_MQ_Envelope *env; | ||
304 | |||
305 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE); | ||
306 | GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key)); | ||
307 | GNUNET_MQ_send (handle->mq, env); | ||
308 | } | ||
309 | |||
310 | static int | ||
311 | iterate_reset_room (void *cls, | ||
312 | const struct GNUNET_HashCode *key, | ||
313 | void *value) | ||
314 | { | ||
315 | struct GNUNET_MESSENGER_Handle *handle = cls; | ||
316 | struct GNUNET_MESSENGER_Room *room = value; | ||
317 | |||
318 | if (GNUNET_YES == room->opened) | ||
319 | send_open_room (handle, room); | ||
320 | |||
321 | struct GNUNET_MESSENGER_ListTunnel *entry = room->entries.head; | ||
322 | |||
323 | struct GNUNET_PeerIdentity door; | ||
324 | |||
325 | while (entry) | ||
326 | { | ||
327 | GNUNET_PEER_resolve (entry->peer, &door); | ||
328 | |||
329 | send_enter_room (handle, room, &door); | ||
330 | |||
331 | entry = entry->next; | ||
332 | } | ||
333 | |||
334 | return GNUNET_YES; | ||
335 | } | ||
336 | |||
337 | static void | ||
338 | callback_reconnect (void *cls) | ||
339 | { | ||
340 | struct GNUNET_MESSENGER_Handle *handle = cls; | ||
341 | |||
342 | handle->reconnect_task = NULL; | ||
343 | handle->reconnect_time = GNUNET_TIME_STD_BACKOFF(handle->reconnect_time) | ||
344 | ; | ||
345 | |||
346 | reconnect (handle); | ||
347 | |||
348 | GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, iterate_reset_room, handle); | ||
349 | } | ||
350 | |||
351 | static int | ||
352 | iterate_close_room (void *cls, | ||
353 | const struct GNUNET_HashCode *key, | ||
354 | void *value) | ||
355 | { | ||
356 | struct GNUNET_MESSENGER_Handle *handle = cls; | ||
357 | struct GNUNET_MESSENGER_Room *room = value; | ||
358 | |||
359 | send_close_room (handle, room); | ||
360 | |||
361 | return GNUNET_YES; | ||
362 | } | ||
363 | |||
364 | static void | ||
365 | callback_mq_error (void *cls, | ||
366 | enum GNUNET_MQ_Error error) | ||
367 | { | ||
368 | struct GNUNET_MESSENGER_Handle *handle = cls; | ||
369 | |||
370 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "MQ_Error: %u\n", error); | ||
371 | |||
372 | GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, iterate_close_room, handle); | ||
373 | |||
374 | if (handle->mq) | ||
375 | { | ||
376 | GNUNET_MQ_destroy (handle->mq); | ||
377 | handle->mq = NULL; | ||
378 | } | ||
379 | |||
380 | handle->reconnect_task = GNUNET_SCHEDULER_add_delayed (handle->reconnect_time, &callback_reconnect, handle); | ||
381 | } | ||
382 | |||
383 | static void | ||
384 | reconnect (struct GNUNET_MESSENGER_Handle *handle) | ||
385 | { | ||
386 | const struct GNUNET_MQ_MessageHandler handlers[] = | ||
387 | { | ||
388 | GNUNET_MQ_hd_var_size( | ||
389 | get_name, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_NAME, | ||
390 | struct GNUNET_MESSENGER_NameMessage, handle | ||
391 | ), | ||
392 | GNUNET_MQ_hd_var_size( | ||
393 | get_key, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_KEY, | ||
394 | struct GNUNET_MESSENGER_KeyMessage, handle | ||
395 | ), | ||
396 | GNUNET_MQ_hd_fixed_size( | ||
397 | member_id, | ||
398 | GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID, | ||
399 | struct GNUNET_MESSENGER_MemberMessage, handle | ||
400 | ), | ||
401 | GNUNET_MQ_hd_fixed_size( | ||
402 | room_open, | ||
403 | GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN, | ||
404 | struct GNUNET_MESSENGER_RoomMessage, handle | ||
405 | ), | ||
406 | GNUNET_MQ_hd_fixed_size( | ||
407 | room_entry, | ||
408 | GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY, | ||
409 | struct GNUNET_MESSENGER_RoomMessage, handle | ||
410 | ), | ||
411 | GNUNET_MQ_hd_fixed_size( | ||
412 | room_close, | ||
413 | GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE, | ||
414 | struct GNUNET_MESSENGER_RoomMessage, handle | ||
415 | ), | ||
416 | GNUNET_MQ_hd_var_size( | ||
417 | recv_message, | ||
418 | GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE, | ||
419 | struct GNUNET_MESSENGER_RecvMessage, handle | ||
420 | ), | ||
421 | GNUNET_MQ_handler_end() | ||
422 | }; | ||
423 | |||
424 | handle->mq = GNUNET_CLIENT_connect (handle->cfg, GNUNET_MESSENGER_SERVICE_NAME, handlers, &callback_mq_error, handle); | ||
425 | } | ||
426 | |||
427 | struct GNUNET_MESSENGER_Handle* | ||
428 | GNUNET_MESSENGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
429 | const char *name, | ||
430 | GNUNET_MESSENGER_IdentityCallback identity_callback, | ||
431 | void *identity_cls, | ||
432 | GNUNET_MESSENGER_MessageCallback msg_callback, | ||
433 | void *msg_cls) | ||
434 | { | ||
435 | struct GNUNET_MESSENGER_Handle *handle = create_handle (cfg, identity_callback, identity_cls, msg_callback, msg_cls); | ||
436 | |||
437 | reconnect (handle); | ||
438 | |||
439 | if (handle->mq) | ||
440 | { | ||
441 | const uint16_t name_len = name ? strlen (name) : 0; | ||
442 | |||
443 | struct GNUNET_MESSENGER_CreateMessage *msg; | ||
444 | struct GNUNET_MQ_Envelope *env; | ||
445 | |||
446 | env = GNUNET_MQ_msg_extra(msg, name_len + 1, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_CREATE); | ||
447 | |||
448 | char *extra = ((char*) msg) + sizeof(*msg); | ||
449 | |||
450 | if (name_len) | ||
451 | GNUNET_memcpy(extra, name, name_len); | ||
452 | |||
453 | extra[name_len] = '\0'; | ||
454 | |||
455 | GNUNET_MQ_send (handle->mq, env); | ||
456 | return handle; | ||
457 | } | ||
458 | else | ||
459 | { | ||
460 | destroy_handle (handle); | ||
461 | return NULL; | ||
462 | } | ||
463 | } | ||
464 | |||
465 | int | ||
466 | GNUNET_MESSENGER_update (struct GNUNET_MESSENGER_Handle *handle) | ||
467 | { | ||
468 | if ((!handle) || (!get_handle_name (handle))) | ||
469 | return GNUNET_SYSERR; | ||
470 | |||
471 | struct GNUNET_MESSENGER_UpdateMessage *msg; | ||
472 | struct GNUNET_MQ_Envelope *env; | ||
473 | |||
474 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_UPDATE); | ||
475 | GNUNET_MQ_send (handle->mq, env); | ||
476 | return GNUNET_OK; | ||
477 | } | ||
478 | |||
479 | void | ||
480 | GNUNET_MESSENGER_disconnect (struct GNUNET_MESSENGER_Handle *handle) | ||
481 | { | ||
482 | if (!handle) | ||
483 | return; | ||
484 | |||
485 | struct GNUNET_MESSENGER_DestroyMessage *msg; | ||
486 | struct GNUNET_MQ_Envelope *env; | ||
487 | |||
488 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_DESTROY); | ||
489 | GNUNET_MQ_send (handle->mq, env); | ||
490 | |||
491 | destroy_handle (handle); | ||
492 | } | ||
493 | |||
494 | const char* | ||
495 | GNUNET_MESSENGER_get_name (const struct GNUNET_MESSENGER_Handle *handle) | ||
496 | { | ||
497 | if (!handle) | ||
498 | return NULL; | ||
499 | |||
500 | return get_handle_name (handle); | ||
501 | } | ||
502 | |||
503 | int | ||
504 | GNUNET_MESSENGER_set_name (struct GNUNET_MESSENGER_Handle *handle, | ||
505 | const char *name) | ||
506 | { | ||
507 | if (!handle) | ||
508 | return GNUNET_SYSERR; | ||
509 | |||
510 | const uint16_t name_len = name ? strlen (name) : 0; | ||
511 | |||
512 | struct GNUNET_MESSENGER_NameMessage *msg; | ||
513 | struct GNUNET_MQ_Envelope *env; | ||
514 | |||
515 | env = GNUNET_MQ_msg_extra(msg, name_len + 1, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_SET_NAME); | ||
516 | |||
517 | char *extra = ((char*) msg) + sizeof(*msg); | ||
518 | |||
519 | if (name_len) | ||
520 | GNUNET_memcpy(extra, name, name_len); | ||
521 | |||
522 | extra[name_len] = '\0'; | ||
523 | |||
524 | GNUNET_MQ_send (handle->mq, env); | ||
525 | return GNUNET_YES; | ||
526 | } | ||
527 | |||
528 | static const struct GNUNET_IDENTITY_PublicKey* | ||
529 | get_non_anonymous_key (const struct GNUNET_IDENTITY_PublicKey* public_key) | ||
530 | { | ||
531 | if (0 == GNUNET_memcmp(public_key, get_anonymous_public_key())) | ||
532 | return NULL; | ||
533 | |||
534 | return public_key; | ||
535 | } | ||
536 | |||
537 | const struct GNUNET_IDENTITY_PublicKey* | ||
538 | GNUNET_MESSENGER_get_key (const struct GNUNET_MESSENGER_Handle *handle) | ||
539 | { | ||
540 | if (!handle) | ||
541 | return NULL; | ||
542 | |||
543 | return get_non_anonymous_key (get_handle_key (handle)); | ||
544 | } | ||
545 | |||
546 | struct GNUNET_MESSENGER_Room* | ||
547 | GNUNET_MESSENGER_open_room (struct GNUNET_MESSENGER_Handle *handle, | ||
548 | const struct GNUNET_HashCode *key) | ||
549 | { | ||
550 | if ((!handle) || (!key)) | ||
551 | return NULL; | ||
552 | |||
553 | struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); | ||
554 | |||
555 | if (!room) | ||
556 | { | ||
557 | room = create_room (handle, key); | ||
558 | |||
559 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->rooms, key, room, | ||
560 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
561 | { | ||
562 | destroy_room (room); | ||
563 | return NULL; | ||
564 | } | ||
565 | } | ||
566 | |||
567 | send_open_room (handle, room); | ||
568 | return room; | ||
569 | } | ||
570 | |||
571 | struct GNUNET_MESSENGER_Room* | ||
572 | GNUNET_MESSENGER_enter_room (struct GNUNET_MESSENGER_Handle *handle, | ||
573 | const struct GNUNET_PeerIdentity *door, | ||
574 | const struct GNUNET_HashCode *key) | ||
575 | { | ||
576 | if ((!handle) || (!door) || (!key)) | ||
577 | return NULL; | ||
578 | |||
579 | struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); | ||
580 | |||
581 | if (!room) | ||
582 | { | ||
583 | room = create_room (handle, key); | ||
584 | |||
585 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (handle->rooms, key, room, | ||
586 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
587 | { | ||
588 | destroy_room (room); | ||
589 | return NULL; | ||
590 | } | ||
591 | } | ||
592 | |||
593 | send_enter_room (handle, room, door); | ||
594 | return room; | ||
595 | } | ||
596 | |||
597 | void | ||
598 | GNUNET_MESSENGER_close_room (struct GNUNET_MESSENGER_Room *room) | ||
599 | { | ||
600 | if (!room) | ||
601 | return; | ||
602 | |||
603 | send_close_room (room->handle, room); | ||
604 | } | ||
605 | |||
606 | struct GNUNET_MESSENGER_RoomFind | ||
607 | { | ||
608 | const struct GNUNET_MESSENGER_Contact *contact; | ||
609 | GNUNET_MESSENGER_MemberCallback callback; | ||
610 | size_t counter; | ||
611 | void *cls; | ||
612 | }; | ||
613 | |||
614 | static int | ||
615 | iterate_find_room (void* cls, | ||
616 | const struct GNUNET_HashCode *key, | ||
617 | void *value) | ||
618 | { | ||
619 | struct GNUNET_MESSENGER_RoomFind *find = cls; | ||
620 | struct GNUNET_MESSENGER_Room *room = value; | ||
621 | |||
622 | if ((find->counter > 0) && ((!find->contact) || (GNUNET_YES == find_room_member(room, find->contact)))) | ||
623 | { | ||
624 | find->counter--; | ||
625 | |||
626 | if (!find->callback) | ||
627 | return GNUNET_YES; | ||
628 | |||
629 | return find->callback(find->cls, room, find->contact); | ||
630 | } | ||
631 | else | ||
632 | return GNUNET_NO; | ||
633 | } | ||
634 | |||
635 | int | ||
636 | GNUNET_MESSENGER_find_rooms (const struct GNUNET_MESSENGER_Handle *handle, | ||
637 | const struct GNUNET_MESSENGER_Contact *contact, | ||
638 | GNUNET_MESSENGER_MemberCallback callback, | ||
639 | void *cls) | ||
640 | { | ||
641 | if (!handle) | ||
642 | return GNUNET_SYSERR; | ||
643 | |||
644 | struct GNUNET_MESSENGER_RoomFind find; | ||
645 | |||
646 | find.contact = contact; | ||
647 | find.callback = callback; | ||
648 | find.counter = (contact? contact->rc : SIZE_MAX); | ||
649 | find.cls = cls; | ||
650 | |||
651 | return GNUNET_CONTAINER_multihashmap_iterate(handle->rooms, iterate_find_room, &find); | ||
652 | } | ||
653 | |||
654 | const struct GNUNET_HashCode* | ||
655 | GNUNET_MESSENGER_room_get_key (const struct GNUNET_MESSENGER_Room *room) | ||
656 | { | ||
657 | if (!room) | ||
658 | return NULL; | ||
659 | |||
660 | return &(room->key); | ||
661 | } | ||
662 | |||
663 | const struct GNUNET_MESSENGER_Contact* | ||
664 | GNUNET_MESSENGER_get_sender (const struct GNUNET_MESSENGER_Room *room, | ||
665 | const struct GNUNET_HashCode *hash) | ||
666 | { | ||
667 | if ((!room) || (!hash)) | ||
668 | return NULL; | ||
669 | |||
670 | return get_room_sender(room, hash); | ||
671 | } | ||
672 | |||
673 | const char* | ||
674 | GNUNET_MESSENGER_contact_get_name (const struct GNUNET_MESSENGER_Contact *contact) | ||
675 | { | ||
676 | if (!contact) | ||
677 | return NULL; | ||
678 | |||
679 | return get_contact_name (contact); | ||
680 | } | ||
681 | |||
682 | const struct GNUNET_IDENTITY_PublicKey* | ||
683 | GNUNET_MESSENGER_contact_get_key (const struct GNUNET_MESSENGER_Contact *contact) | ||
684 | { | ||
685 | if (!contact) | ||
686 | return NULL; | ||
687 | |||
688 | return get_non_anonymous_key (get_contact_key (contact)); | ||
689 | } | ||
690 | |||
691 | void | ||
692 | GNUNET_MESSENGER_send_message (struct GNUNET_MESSENGER_Room *room, | ||
693 | const struct GNUNET_MESSENGER_Message *message, | ||
694 | const struct GNUNET_MESSENGER_Contact *contact) | ||
695 | { | ||
696 | if ((!room) || (!message)) | ||
697 | return; | ||
698 | |||
699 | switch (filter_message_sending (message)) | ||
700 | { | ||
701 | case GNUNET_SYSERR: | ||
702 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Sending message aborted: This kind of message is reserved for the service!\n"); | ||
703 | return; | ||
704 | case GNUNET_NO: | ||
705 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Sending message aborted: This kind of message could cause issues!\n"); | ||
706 | return; | ||
707 | default: | ||
708 | break; | ||
709 | } | ||
710 | |||
711 | ssize_t key_length = 0; | ||
712 | |||
713 | if (contact) | ||
714 | { | ||
715 | const struct GNUNET_IDENTITY_PublicKey *public_key = get_non_anonymous_key ( | ||
716 | get_contact_key(contact) | ||
717 | ); | ||
718 | |||
719 | if (public_key) | ||
720 | key_length = GNUNET_IDENTITY_key_get_length(public_key); | ||
721 | else | ||
722 | key_length = -1; | ||
723 | } | ||
724 | |||
725 | if (key_length < 0) | ||
726 | { | ||
727 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Sending message aborted: Invalid key!\n"); | ||
728 | return; | ||
729 | } | ||
730 | |||
731 | const uint16_t msg_length = get_message_size (message, GNUNET_NO); | ||
732 | |||
733 | struct GNUNET_MESSENGER_SendMessage *msg; | ||
734 | struct GNUNET_MQ_Envelope *env; | ||
735 | |||
736 | const uint16_t length = (uint16_t) key_length + msg_length; | ||
737 | |||
738 | env = GNUNET_MQ_msg_extra( | ||
739 | msg, length, | ||
740 | GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE | ||
741 | ); | ||
742 | |||
743 | GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key)); | ||
744 | |||
745 | msg->flags = (uint32_t) ( | ||
746 | contact? GNUNET_MESSENGER_FLAG_PRIVATE : GNUNET_MESSENGER_FLAG_NONE | ||
747 | ); | ||
748 | |||
749 | char *buffer = ((char*) msg) + sizeof(*msg); | ||
750 | char *msg_buffer = buffer + key_length; | ||
751 | |||
752 | if (key_length > 0) | ||
753 | GNUNET_IDENTITY_write_key_to_buffer(get_contact_key(contact), buffer, key_length); | ||
754 | |||
755 | encode_message (message, msg_length, msg_buffer, GNUNET_NO); | ||
756 | |||
757 | GNUNET_MQ_send (room->handle->mq, env); | ||
758 | } | ||
759 | |||
760 | const struct GNUNET_MESSENGER_Message* | ||
761 | GNUNET_MESSENGER_get_message (const struct GNUNET_MESSENGER_Room *room, | ||
762 | const struct GNUNET_HashCode *hash) | ||
763 | { | ||
764 | if ((!room) || (!hash)) | ||
765 | return NULL; | ||
766 | |||
767 | const struct GNUNET_MESSENGER_Message *message = get_room_message (room, hash); | ||
768 | |||
769 | if (!message) | ||
770 | { | ||
771 | struct GNUNET_MESSENGER_GetMessage *msg; | ||
772 | struct GNUNET_MQ_Envelope *env; | ||
773 | |||
774 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE); | ||
775 | GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key)); | ||
776 | GNUNET_memcpy(&(msg->hash), hash, sizeof(*hash)); | ||
777 | GNUNET_MQ_send (room->handle->mq, env); | ||
778 | } | ||
779 | |||
780 | return message; | ||
781 | } | ||
782 | |||
783 | int | ||
784 | GNUNET_MESSENGER_iterate_members (struct GNUNET_MESSENGER_Room *room, | ||
785 | GNUNET_MESSENGER_MemberCallback callback, | ||
786 | void *cls) | ||
787 | { | ||
788 | if (!room) | ||
789 | return GNUNET_SYSERR; | ||
790 | |||
791 | return iterate_room_members(room, callback, cls); | ||
792 | } | ||
diff --git a/src/messenger/messenger_api_contact.c b/src/messenger/messenger_api_contact.c deleted file mode 100644 index cbca17640..000000000 --- a/src/messenger/messenger_api_contact.c +++ /dev/null | |||
@@ -1,110 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api_contact.c | ||
23 | * @brief messenger api: client implementation of GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "messenger_api_contact.h" | ||
27 | |||
28 | struct GNUNET_MESSENGER_Contact* | ||
29 | create_contact (const struct GNUNET_IDENTITY_PublicKey *key) | ||
30 | { | ||
31 | GNUNET_assert(key); | ||
32 | |||
33 | struct GNUNET_MESSENGER_Contact *contact = GNUNET_new(struct GNUNET_MESSENGER_Contact); | ||
34 | |||
35 | contact->name = NULL; | ||
36 | contact->rc = 0; | ||
37 | |||
38 | GNUNET_memcpy(&(contact->public_key), key, sizeof(contact->public_key)); | ||
39 | |||
40 | return contact; | ||
41 | } | ||
42 | |||
43 | void | ||
44 | destroy_contact (struct GNUNET_MESSENGER_Contact *contact) | ||
45 | { | ||
46 | GNUNET_assert(contact); | ||
47 | |||
48 | if (contact->name) | ||
49 | GNUNET_free(contact->name); | ||
50 | |||
51 | GNUNET_free(contact); | ||
52 | } | ||
53 | |||
54 | const char* | ||
55 | get_contact_name (const struct GNUNET_MESSENGER_Contact *contact) | ||
56 | { | ||
57 | GNUNET_assert(contact); | ||
58 | |||
59 | return contact->name; | ||
60 | } | ||
61 | |||
62 | void | ||
63 | set_contact_name (struct GNUNET_MESSENGER_Contact *contact, | ||
64 | const char *name) | ||
65 | { | ||
66 | GNUNET_assert(contact); | ||
67 | |||
68 | if (contact->name) | ||
69 | GNUNET_free(contact->name); | ||
70 | |||
71 | contact->name = name ? GNUNET_strdup(name) : NULL; | ||
72 | } | ||
73 | |||
74 | const struct GNUNET_IDENTITY_PublicKey* | ||
75 | get_contact_key (const struct GNUNET_MESSENGER_Contact *contact) | ||
76 | { | ||
77 | GNUNET_assert(contact); | ||
78 | |||
79 | return &(contact->public_key); | ||
80 | } | ||
81 | |||
82 | void | ||
83 | increase_contact_rc (struct GNUNET_MESSENGER_Contact *contact) | ||
84 | { | ||
85 | GNUNET_assert(contact); | ||
86 | |||
87 | contact->rc++; | ||
88 | } | ||
89 | |||
90 | int | ||
91 | decrease_contact_rc (struct GNUNET_MESSENGER_Contact *contact) | ||
92 | { | ||
93 | GNUNET_assert(contact); | ||
94 | |||
95 | if (contact->rc > 0) | ||
96 | contact->rc--; | ||
97 | |||
98 | return contact->rc ? GNUNET_NO : GNUNET_YES; | ||
99 | } | ||
100 | |||
101 | void | ||
102 | get_context_from_member (const struct GNUNET_HashCode *key, | ||
103 | const struct GNUNET_ShortHashCode *id, | ||
104 | struct GNUNET_HashCode *context) | ||
105 | { | ||
106 | GNUNET_assert((key) && (id) && (context)); | ||
107 | |||
108 | GNUNET_CRYPTO_hash (id, sizeof(*id), context); | ||
109 | GNUNET_CRYPTO_hash_xor (key, context, context); | ||
110 | } | ||
diff --git a/src/messenger/messenger_api_contact.h b/src/messenger/messenger_api_contact.h deleted file mode 100644 index b5410f998..000000000 --- a/src/messenger/messenger_api_contact.h +++ /dev/null | |||
@@ -1,116 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api_contact.h | ||
23 | * @brief messenger api: client implementation of GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_MESSENGER_API_CONTACT_H | ||
27 | #define GNUNET_MESSENGER_API_CONTACT_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_crypto_lib.h" | ||
31 | #include "gnunet_identity_service.h" | ||
32 | |||
33 | struct GNUNET_MESSENGER_Contact | ||
34 | { | ||
35 | char *name; | ||
36 | size_t rc; | ||
37 | |||
38 | struct GNUNET_IDENTITY_PublicKey public_key; | ||
39 | }; | ||
40 | |||
41 | /** | ||
42 | * Creates and allocates a new contact with a given public <i>key</i> from an EGO. | ||
43 | * | ||
44 | * @param[in] key Public key | ||
45 | * @return New contact | ||
46 | */ | ||
47 | struct GNUNET_MESSENGER_Contact* | ||
48 | create_contact (const struct GNUNET_IDENTITY_PublicKey *key); | ||
49 | |||
50 | /** | ||
51 | * Destroys a contact and frees its memory fully. | ||
52 | * | ||
53 | * @param[in/out] contact Contact | ||
54 | */ | ||
55 | void | ||
56 | destroy_contact (struct GNUNET_MESSENGER_Contact *contact); | ||
57 | |||
58 | /** | ||
59 | * Returns the current name of a given <i>contact</i> or NULL if no valid name was assigned yet. | ||
60 | * | ||
61 | * @param[in] contact Contact | ||
62 | * @return Name of the contact or NULL | ||
63 | */ | ||
64 | const char* | ||
65 | get_contact_name (const struct GNUNET_MESSENGER_Contact *contact); | ||
66 | |||
67 | /** | ||
68 | * Changes the current name of a given <i>contact</i> by copying it from the parameter <i>name</i>. | ||
69 | * | ||
70 | * @param[in/out] contact Contact | ||
71 | * @param[in] name Name | ||
72 | */ | ||
73 | void | ||
74 | set_contact_name (struct GNUNET_MESSENGER_Contact *contact, | ||
75 | const char *name); | ||
76 | |||
77 | /** | ||
78 | * Returns the public key of a given <i>contact</i>. | ||
79 | * | ||
80 | * @param[in] contact Contact | ||
81 | * @return Public key of the contact | ||
82 | */ | ||
83 | const struct GNUNET_IDENTITY_PublicKey* | ||
84 | get_contact_key (const struct GNUNET_MESSENGER_Contact *contact); | ||
85 | |||
86 | /** | ||
87 | * Increases the reference counter of a given <i>contact</i> which is zero as default. | ||
88 | * | ||
89 | * @param[in/out] contact Contact | ||
90 | */ | ||
91 | void | ||
92 | increase_contact_rc (struct GNUNET_MESSENGER_Contact *contact); | ||
93 | |||
94 | /** | ||
95 | * Decreases the reference counter if possible (can not underflow!) of a given <i>contact</i> | ||
96 | * and returns #GNUNET_YES if the counter is equal to zero, otherwise #GNUNET_NO. | ||
97 | * | ||
98 | * @param[in/out] contact Contact | ||
99 | * @return #GNUNET_YES or #GNUNET_NO depending on the reference counter | ||
100 | */ | ||
101 | int | ||
102 | decrease_contact_rc (struct GNUNET_MESSENGER_Contact *contact); | ||
103 | |||
104 | /** | ||
105 | * Calculates the context <i>hash</i> of a member in a room and returns it. | ||
106 | * | ||
107 | * @param[in] key Key of room | ||
108 | * @param[in] id Member id | ||
109 | * @param[out] hash Member context | ||
110 | */ | ||
111 | void | ||
112 | get_context_from_member (const struct GNUNET_HashCode *key, | ||
113 | const struct GNUNET_ShortHashCode *id, | ||
114 | struct GNUNET_HashCode *context); | ||
115 | |||
116 | #endif //GNUNET_MESSENGER_API_CONTACT_H | ||
diff --git a/src/messenger/messenger_api_contact_store.c b/src/messenger/messenger_api_contact_store.c deleted file mode 100644 index 1c10a8fbf..000000000 --- a/src/messenger/messenger_api_contact_store.c +++ /dev/null | |||
@@ -1,193 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api_contact_store.c | ||
23 | * @brief messenger api: client implementation of GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "messenger_api_contact_store.h" | ||
27 | |||
28 | #include "messenger_api_contact.h" | ||
29 | #include "messenger_api_util.h" | ||
30 | |||
31 | void | ||
32 | init_contact_store (struct GNUNET_MESSENGER_ContactStore *store) | ||
33 | { | ||
34 | GNUNET_assert (store); | ||
35 | |||
36 | store->anonymous = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); | ||
37 | store->contacts = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); | ||
38 | } | ||
39 | |||
40 | static int | ||
41 | iterate_destroy_contacts (void *cls, | ||
42 | const struct GNUNET_HashCode *key, | ||
43 | void *value) | ||
44 | { | ||
45 | struct GNUNET_MESSENGER_Contact *contact = value; | ||
46 | destroy_contact (contact); | ||
47 | return GNUNET_YES; | ||
48 | } | ||
49 | |||
50 | void | ||
51 | clear_contact_store (struct GNUNET_MESSENGER_ContactStore *store) | ||
52 | { | ||
53 | GNUNET_assert ((store) && (store->contacts)); | ||
54 | |||
55 | GNUNET_CONTAINER_multihashmap_iterate (store->anonymous, iterate_destroy_contacts, NULL); | ||
56 | GNUNET_CONTAINER_multihashmap_iterate (store->contacts, iterate_destroy_contacts, NULL); | ||
57 | |||
58 | GNUNET_CONTAINER_multihashmap_destroy (store->anonymous); | ||
59 | GNUNET_CONTAINER_multihashmap_destroy (store->contacts); | ||
60 | } | ||
61 | |||
62 | static struct GNUNET_CONTAINER_MultiHashMap* | ||
63 | select_store_contact_map (struct GNUNET_MESSENGER_ContactStore *store, | ||
64 | const struct GNUNET_HashCode *context, | ||
65 | struct GNUNET_HashCode *hash) | ||
66 | { | ||
67 | const struct GNUNET_IDENTITY_PublicKey *anonymous = get_anonymous_public_key (); | ||
68 | |||
69 | struct GNUNET_HashCode anonHash; | ||
70 | GNUNET_CRYPTO_hash (anonymous, sizeof(*anonymous), &anonHash); | ||
71 | |||
72 | if ((context) && (0 == GNUNET_CRYPTO_hash_cmp(hash, &anonHash))) | ||
73 | { | ||
74 | GNUNET_memcpy(hash, context, sizeof(*context)); | ||
75 | return store->anonymous; | ||
76 | } | ||
77 | else | ||
78 | return store->contacts; | ||
79 | } | ||
80 | |||
81 | struct GNUNET_MESSENGER_Contact* | ||
82 | get_store_contact_raw (struct GNUNET_MESSENGER_ContactStore *store, | ||
83 | const struct GNUNET_HashCode *context, | ||
84 | const struct GNUNET_HashCode *key_hash) | ||
85 | { | ||
86 | GNUNET_assert ((store) && (store->contacts) && (context) && (key_hash)); | ||
87 | |||
88 | struct GNUNET_HashCode hash; | ||
89 | GNUNET_memcpy(&hash, key_hash, sizeof(*key_hash)); | ||
90 | |||
91 | struct GNUNET_CONTAINER_MultiHashMap *map = select_store_contact_map ( | ||
92 | store, context, &hash | ||
93 | ); | ||
94 | |||
95 | return GNUNET_CONTAINER_multihashmap_get (map, &hash); | ||
96 | } | ||
97 | |||
98 | struct GNUNET_MESSENGER_Contact* | ||
99 | get_store_contact (struct GNUNET_MESSENGER_ContactStore *store, | ||
100 | const struct GNUNET_HashCode *context, | ||
101 | const struct GNUNET_IDENTITY_PublicKey *pubkey) | ||
102 | { | ||
103 | GNUNET_assert ((store) && (store->contacts) && (context) && (pubkey)); | ||
104 | |||
105 | struct GNUNET_HashCode hash; | ||
106 | GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash); | ||
107 | |||
108 | struct GNUNET_CONTAINER_MultiHashMap *map = select_store_contact_map ( | ||
109 | store, context, &hash | ||
110 | ); | ||
111 | |||
112 | struct GNUNET_MESSENGER_Contact *contact = GNUNET_CONTAINER_multihashmap_get (map, &hash); | ||
113 | |||
114 | if (contact) | ||
115 | { | ||
116 | if (0 != GNUNET_memcmp(pubkey, get_contact_key(contact))) | ||
117 | { | ||
118 | char* str = GNUNET_IDENTITY_public_key_to_string (get_contact_key(contact)); | ||
119 | GNUNET_log (GNUNET_ERROR_TYPE_INVALID, "Contact in store uses wrong key: %s\n", str); | ||
120 | GNUNET_free (str); | ||
121 | return NULL; | ||
122 | } | ||
123 | |||
124 | return contact; | ||
125 | } | ||
126 | |||
127 | contact = create_contact (pubkey); | ||
128 | |||
129 | if (GNUNET_OK == GNUNET_CONTAINER_multihashmap_put (map, &hash, contact, | ||
130 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
131 | return contact; | ||
132 | |||
133 | destroy_contact (contact); | ||
134 | return NULL; | ||
135 | } | ||
136 | |||
137 | void | ||
138 | update_store_contact (struct GNUNET_MESSENGER_ContactStore *store, | ||
139 | struct GNUNET_MESSENGER_Contact* contact, | ||
140 | const struct GNUNET_HashCode *context, | ||
141 | const struct GNUNET_HashCode *next_context, | ||
142 | const struct GNUNET_IDENTITY_PublicKey *pubkey) | ||
143 | { | ||
144 | GNUNET_assert ((store) && (store->contacts) && (contact) && (pubkey)); | ||
145 | |||
146 | const struct GNUNET_IDENTITY_PublicKey* oldkey = get_contact_key (contact); | ||
147 | |||
148 | struct GNUNET_HashCode hash; | ||
149 | GNUNET_CRYPTO_hash (oldkey, sizeof(*oldkey), &hash); | ||
150 | |||
151 | struct GNUNET_CONTAINER_MultiHashMap *map = select_store_contact_map ( | ||
152 | store, context, &hash | ||
153 | ); | ||
154 | |||
155 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (map, &hash, contact)) | ||
156 | { | ||
157 | GNUNET_memcpy(&(contact->public_key), pubkey, sizeof(*pubkey)); | ||
158 | |||
159 | GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash); | ||
160 | |||
161 | map = select_store_contact_map ( | ||
162 | store, next_context, &hash | ||
163 | ); | ||
164 | |||
165 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (map, &hash, contact, | ||
166 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
167 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Updating a contact failed: %s\n", | ||
168 | GNUNET_h2s(&hash)); | ||
169 | } | ||
170 | } | ||
171 | |||
172 | void | ||
173 | remove_store_contact (struct GNUNET_MESSENGER_ContactStore *store, | ||
174 | struct GNUNET_MESSENGER_Contact* contact, | ||
175 | const struct GNUNET_HashCode *context) | ||
176 | { | ||
177 | GNUNET_assert ((store) && (store->contacts) && (contact)); | ||
178 | |||
179 | const struct GNUNET_IDENTITY_PublicKey* pubkey = get_contact_key(contact); | ||
180 | |||
181 | struct GNUNET_HashCode hash; | ||
182 | GNUNET_CRYPTO_hash (pubkey, sizeof(*pubkey), &hash); | ||
183 | |||
184 | struct GNUNET_CONTAINER_MultiHashMap *map = select_store_contact_map ( | ||
185 | store, context, &hash | ||
186 | ); | ||
187 | |||
188 | if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (map, &hash, contact)) | ||
189 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Removing a contact failed: %s\n", | ||
190 | GNUNET_h2s(&hash)); | ||
191 | |||
192 | destroy_contact (contact); | ||
193 | } | ||
diff --git a/src/messenger/messenger_api_contact_store.h b/src/messenger/messenger_api_contact_store.h deleted file mode 100644 index bdab2ceeb..000000000 --- a/src/messenger/messenger_api_contact_store.h +++ /dev/null | |||
@@ -1,127 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api_contact_store.h | ||
23 | * @brief messenger api: client implementation of GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_MESSENGER_API_CONTACT_STORE_H | ||
27 | #define GNUNET_MESSENGER_API_CONTACT_STORE_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_container_lib.h" | ||
31 | #include "gnunet_crypto_lib.h" | ||
32 | #include "gnunet_identity_service.h" | ||
33 | |||
34 | struct GNUNET_MESSENGER_Contact; | ||
35 | |||
36 | struct GNUNET_MESSENGER_ContactStore | ||
37 | { | ||
38 | struct GNUNET_CONTAINER_MultiHashMap *anonymous; | ||
39 | struct GNUNET_CONTAINER_MultiHashMap *contacts; | ||
40 | }; | ||
41 | |||
42 | /** | ||
43 | * Initializes a contact store as fully empty. | ||
44 | * | ||
45 | * @param[out] store Contact store | ||
46 | */ | ||
47 | void | ||
48 | init_contact_store (struct GNUNET_MESSENGER_ContactStore *store); | ||
49 | |||
50 | /** | ||
51 | * Clears a contact store, wipes its content and deallocates its memory. | ||
52 | * | ||
53 | * @param[in/out] store Contact store | ||
54 | */ | ||
55 | void | ||
56 | clear_contact_store (struct GNUNET_MESSENGER_ContactStore *store); | ||
57 | |||
58 | /** | ||
59 | * Returns a contact using the hash of a specific public key. In case the anonymous | ||
60 | * key gets used by the requested contact, it will use its provided member | ||
61 | * <i>context</i> to select the matching contact from the <i>store</i>. | ||
62 | * | ||
63 | * In case there is no contact stored which uses the given key or context, | ||
64 | * NULL gets returned. | ||
65 | * | ||
66 | * @param[in/out] store Contact store | ||
67 | * @param[in] context Member context | ||
68 | * @param[in] key_hash Hash of public key | ||
69 | */ | ||
70 | struct GNUNET_MESSENGER_Contact* | ||
71 | get_store_contact_raw (struct GNUNET_MESSENGER_ContactStore *store, | ||
72 | const struct GNUNET_HashCode *context, | ||
73 | const struct GNUNET_HashCode *key_hash); | ||
74 | |||
75 | /** | ||
76 | * Returns a contact using a specific public key. In case the anonymous | ||
77 | * key gets used by the requested contact, it will use its provided member | ||
78 | * <i>context</i> to select the matching contact from the <i>store</i>. | ||
79 | * | ||
80 | * In case there is no contact stored which uses the given key or context, | ||
81 | * a new contact will be created automatically. | ||
82 | * | ||
83 | * The function returns NULL if an error occurs during allocation | ||
84 | * or validation of the contacts key. | ||
85 | * | ||
86 | * @param[in/out] store Contact store | ||
87 | * @param[in] context Member context | ||
88 | * @param[in] pubkey Public key of EGO | ||
89 | */ | ||
90 | struct GNUNET_MESSENGER_Contact* | ||
91 | get_store_contact (struct GNUNET_MESSENGER_ContactStore *store, | ||
92 | const struct GNUNET_HashCode *context, | ||
93 | const struct GNUNET_IDENTITY_PublicKey *pubkey); | ||
94 | |||
95 | /** | ||
96 | * Moves a <i>contact</i> from the <i>store</i> to another location | ||
97 | * matching a given public key and member <i>context</i>. | ||
98 | * | ||
99 | * This function allows changes of keys or changes of member contexts! | ||
100 | * | ||
101 | * @param[in/out] store Contact store | ||
102 | * @param[in/out] contact Contact | ||
103 | * @param[in] context Member context | ||
104 | * @param[in] next_context Member context | ||
105 | * @param[in] pubkey Public key of EGO | ||
106 | */ | ||
107 | void | ||
108 | update_store_contact (struct GNUNET_MESSENGER_ContactStore *store, | ||
109 | struct GNUNET_MESSENGER_Contact* contact, | ||
110 | const struct GNUNET_HashCode *context, | ||
111 | const struct GNUNET_HashCode *next_context, | ||
112 | const struct GNUNET_IDENTITY_PublicKey *pubkey); | ||
113 | |||
114 | /** | ||
115 | * Removes a <i>contact</i> from the <i>store</i> which uses | ||
116 | * a given member <i>context</i>. | ||
117 | * | ||
118 | * @param[in/out] store Contact store | ||
119 | * @param[in/out] contact Contact | ||
120 | * @param[in] context Member context | ||
121 | */ | ||
122 | void | ||
123 | remove_store_contact (struct GNUNET_MESSENGER_ContactStore *store, | ||
124 | struct GNUNET_MESSENGER_Contact* contact, | ||
125 | const struct GNUNET_HashCode *context); | ||
126 | |||
127 | #endif //GNUNET_MESSENGER_API_CONTACT_STORE_H | ||
diff --git a/src/messenger/messenger_api_ego.h b/src/messenger/messenger_api_ego.h deleted file mode 100644 index b52b895f2..000000000 --- a/src/messenger/messenger_api_ego.h +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api_ego.h | ||
23 | * @brief GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_MESSENGER_API_EGO_H | ||
27 | #define GNUNET_MESSENGER_API_EGO_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_identity_service.h" | ||
31 | |||
32 | struct GNUNET_MESSENGER_Ego | ||
33 | { | ||
34 | struct GNUNET_IDENTITY_PrivateKey priv; | ||
35 | struct GNUNET_IDENTITY_PublicKey pub; | ||
36 | }; | ||
37 | |||
38 | #endif //GNUNET_MESSENGER_API_EGO_H | ||
diff --git a/src/messenger/messenger_api_handle.c b/src/messenger/messenger_api_handle.c deleted file mode 100644 index 242389040..000000000 --- a/src/messenger/messenger_api_handle.c +++ /dev/null | |||
@@ -1,207 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api_handle.c | ||
23 | * @brief messenger api: client implementation of GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "messenger_api_handle.h" | ||
27 | |||
28 | #include "messenger_api_util.h" | ||
29 | |||
30 | struct GNUNET_MESSENGER_Handle* | ||
31 | create_handle (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
32 | GNUNET_MESSENGER_IdentityCallback identity_callback, | ||
33 | void *identity_cls, | ||
34 | GNUNET_MESSENGER_MessageCallback msg_callback, | ||
35 | void *msg_cls) | ||
36 | { | ||
37 | GNUNET_assert(cfg); | ||
38 | |||
39 | struct GNUNET_MESSENGER_Handle *handle = GNUNET_new(struct GNUNET_MESSENGER_Handle); | ||
40 | |||
41 | handle->cfg = cfg; | ||
42 | handle->mq = NULL; | ||
43 | |||
44 | handle->identity_callback = identity_callback; | ||
45 | handle->identity_cls = identity_cls; | ||
46 | |||
47 | handle->msg_callback = msg_callback; | ||
48 | handle->msg_cls = msg_cls; | ||
49 | |||
50 | handle->name = NULL; | ||
51 | handle->pubkey = NULL; | ||
52 | |||
53 | handle->reconnect_time = GNUNET_TIME_relative_get_zero_ (); | ||
54 | handle->reconnect_task = NULL; | ||
55 | |||
56 | handle->rooms = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); | ||
57 | |||
58 | init_contact_store(get_handle_contact_store(handle)); | ||
59 | |||
60 | return handle; | ||
61 | } | ||
62 | |||
63 | static int | ||
64 | iterate_destroy_room (void *cls, | ||
65 | const struct GNUNET_HashCode *key, | ||
66 | void *value) | ||
67 | { | ||
68 | struct GNUNET_MESSENGER_Room *room = value; | ||
69 | |||
70 | destroy_room (room); | ||
71 | |||
72 | return GNUNET_YES; | ||
73 | } | ||
74 | |||
75 | void | ||
76 | destroy_handle (struct GNUNET_MESSENGER_Handle *handle) | ||
77 | { | ||
78 | GNUNET_assert(handle); | ||
79 | |||
80 | if (handle->reconnect_task) | ||
81 | GNUNET_SCHEDULER_cancel (handle->reconnect_task); | ||
82 | |||
83 | if (handle->mq) | ||
84 | GNUNET_MQ_destroy (handle->mq); | ||
85 | |||
86 | if (handle->name) | ||
87 | GNUNET_free(handle->name); | ||
88 | |||
89 | if (handle->pubkey) | ||
90 | GNUNET_free(handle->pubkey); | ||
91 | |||
92 | if (handle->rooms) | ||
93 | { | ||
94 | GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, iterate_destroy_room, NULL); | ||
95 | |||
96 | GNUNET_CONTAINER_multihashmap_destroy (handle->rooms); | ||
97 | } | ||
98 | |||
99 | clear_contact_store(get_handle_contact_store(handle)); | ||
100 | |||
101 | GNUNET_free(handle); | ||
102 | } | ||
103 | |||
104 | void | ||
105 | set_handle_name (struct GNUNET_MESSENGER_Handle *handle, | ||
106 | const char *name) | ||
107 | { | ||
108 | GNUNET_assert(handle); | ||
109 | |||
110 | if (handle->name) | ||
111 | GNUNET_free(handle->name); | ||
112 | |||
113 | handle->name = name ? GNUNET_strdup(name) : NULL; | ||
114 | } | ||
115 | |||
116 | const char* | ||
117 | get_handle_name (const struct GNUNET_MESSENGER_Handle *handle) | ||
118 | { | ||
119 | GNUNET_assert(handle); | ||
120 | |||
121 | return handle->name; | ||
122 | } | ||
123 | |||
124 | void | ||
125 | set_handle_key (struct GNUNET_MESSENGER_Handle *handle, | ||
126 | const struct GNUNET_IDENTITY_PublicKey *pubkey) | ||
127 | { | ||
128 | GNUNET_assert(handle); | ||
129 | |||
130 | if (!handle->pubkey) | ||
131 | handle->pubkey = GNUNET_new(struct GNUNET_IDENTITY_PublicKey); | ||
132 | |||
133 | GNUNET_memcpy(handle->pubkey, pubkey, sizeof(*pubkey)); | ||
134 | } | ||
135 | |||
136 | const struct GNUNET_IDENTITY_PublicKey* | ||
137 | get_handle_key (const struct GNUNET_MESSENGER_Handle *handle) | ||
138 | { | ||
139 | GNUNET_assert(handle); | ||
140 | |||
141 | if (handle->pubkey) | ||
142 | return handle->pubkey; | ||
143 | |||
144 | return get_anonymous_public_key (); | ||
145 | } | ||
146 | |||
147 | struct GNUNET_MESSENGER_ContactStore* | ||
148 | get_handle_contact_store (struct GNUNET_MESSENGER_Handle *handle) | ||
149 | { | ||
150 | GNUNET_assert(handle); | ||
151 | |||
152 | return &(handle->contact_store); | ||
153 | } | ||
154 | |||
155 | struct GNUNET_MESSENGER_Contact* | ||
156 | get_handle_contact (struct GNUNET_MESSENGER_Handle *handle, | ||
157 | const struct GNUNET_HashCode *key) | ||
158 | { | ||
159 | GNUNET_assert((handle) && (key)); | ||
160 | |||
161 | struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); | ||
162 | |||
163 | if ((!room) || (!(room->contact_id))) | ||
164 | return NULL; | ||
165 | |||
166 | struct GNUNET_HashCode context; | ||
167 | get_context_from_member (key, room->contact_id, &context); | ||
168 | |||
169 | return get_store_contact(get_handle_contact_store(handle), &context, get_handle_key(handle)); | ||
170 | } | ||
171 | |||
172 | void | ||
173 | open_handle_room (struct GNUNET_MESSENGER_Handle *handle, | ||
174 | const struct GNUNET_HashCode *key) | ||
175 | { | ||
176 | GNUNET_assert((handle) && (key)); | ||
177 | |||
178 | struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); | ||
179 | |||
180 | if (room) | ||
181 | room->opened = GNUNET_YES; | ||
182 | } | ||
183 | |||
184 | void | ||
185 | entry_handle_room_at (struct GNUNET_MESSENGER_Handle *handle, | ||
186 | const struct GNUNET_PeerIdentity *door, | ||
187 | const struct GNUNET_HashCode *key) | ||
188 | { | ||
189 | GNUNET_assert((handle) && (door) && (key)); | ||
190 | |||
191 | struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); | ||
192 | |||
193 | if (room) | ||
194 | add_to_list_tunnels (&(room->entries), door); | ||
195 | } | ||
196 | |||
197 | void | ||
198 | close_handle_room (struct GNUNET_MESSENGER_Handle *handle, | ||
199 | const struct GNUNET_HashCode *key) | ||
200 | { | ||
201 | GNUNET_assert((handle) && (key)); | ||
202 | |||
203 | struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); | ||
204 | |||
205 | if ((room) && (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (handle->rooms, key, room))) | ||
206 | destroy_room (room); | ||
207 | } | ||
diff --git a/src/messenger/messenger_api_handle.h b/src/messenger/messenger_api_handle.h deleted file mode 100644 index 6a43f13a6..000000000 --- a/src/messenger/messenger_api_handle.h +++ /dev/null | |||
@@ -1,180 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api_handle.h | ||
23 | * @brief messenger api: client implementation of GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_MESSENGER_API_HANDLE_H | ||
27 | #define GNUNET_MESSENGER_API_HANDLE_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_cadet_service.h" | ||
31 | #include "gnunet_container_lib.h" | ||
32 | #include "gnunet_crypto_lib.h" | ||
33 | #include "gnunet_identity_service.h" | ||
34 | #include "gnunet_peer_lib.h" | ||
35 | |||
36 | #include "gnunet_messenger_service.h" | ||
37 | |||
38 | #include "messenger_api_contact_store.h" | ||
39 | #include "messenger_api_room.h" | ||
40 | |||
41 | struct GNUNET_MESSENGER_Handle | ||
42 | { | ||
43 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
44 | |||
45 | struct GNUNET_MQ_Handle *mq; | ||
46 | |||
47 | GNUNET_MESSENGER_IdentityCallback identity_callback; | ||
48 | void *identity_cls; | ||
49 | |||
50 | GNUNET_MESSENGER_MessageCallback msg_callback; | ||
51 | void *msg_cls; | ||
52 | |||
53 | char *name; | ||
54 | struct GNUNET_IDENTITY_PublicKey *pubkey; | ||
55 | |||
56 | struct GNUNET_TIME_Relative reconnect_time; | ||
57 | struct GNUNET_SCHEDULER_Task *reconnect_task; | ||
58 | |||
59 | struct GNUNET_MESSENGER_ContactStore contact_store; | ||
60 | |||
61 | struct GNUNET_CONTAINER_MultiHashMap *rooms; | ||
62 | }; | ||
63 | |||
64 | /** | ||
65 | * Creates and allocates a new handle using a given configuration and a custom message callback | ||
66 | * with a given closure for the client API. | ||
67 | * | ||
68 | * @param[in] cfg Configuration | ||
69 | * @param[in] msg_callback Message callback | ||
70 | * @param[in/out] msg_cls Closure | ||
71 | * @return New handle | ||
72 | */ | ||
73 | struct GNUNET_MESSENGER_Handle* | ||
74 | create_handle (const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
75 | GNUNET_MESSENGER_IdentityCallback identity_callback, | ||
76 | void *identity_cls, | ||
77 | GNUNET_MESSENGER_MessageCallback msg_callback, | ||
78 | void *msg_cls); | ||
79 | |||
80 | /** | ||
81 | * Destroys a <i>handle</i> and frees its memory fully from the client API. | ||
82 | * | ||
83 | * @param[in/out] handle Handle | ||
84 | */ | ||
85 | void | ||
86 | destroy_handle (struct GNUNET_MESSENGER_Handle *handle); | ||
87 | |||
88 | /** | ||
89 | * Sets the name of a <i>handle</i> to a specific <i>name</i>. | ||
90 | * | ||
91 | * @param[in/out] handle Handle | ||
92 | * @param[in] name New name | ||
93 | */ | ||
94 | void | ||
95 | set_handle_name (struct GNUNET_MESSENGER_Handle *handle, | ||
96 | const char *name); | ||
97 | |||
98 | /** | ||
99 | * Returns the current name of a given <i>handle</i> or NULL if no valid name was assigned yet. | ||
100 | * | ||
101 | * @param[in] handle Handle | ||
102 | * @return Name of the handle or NULL | ||
103 | */ | ||
104 | const char* | ||
105 | get_handle_name (const struct GNUNET_MESSENGER_Handle *handle); | ||
106 | |||
107 | /** | ||
108 | * Sets the public key of a given <i>handle</i> to a specific public key. | ||
109 | * | ||
110 | * @param[in/out] handle Handle | ||
111 | * @param[in] pubkey Public key | ||
112 | */ | ||
113 | void | ||
114 | set_handle_key (struct GNUNET_MESSENGER_Handle *handle, | ||
115 | const struct GNUNET_IDENTITY_PublicKey *pubkey); | ||
116 | |||
117 | /** | ||
118 | * Returns the public key of a given <i>handle</i>. | ||
119 | * | ||
120 | * @param[in] handle Handle | ||
121 | * @return Public key of the handle | ||
122 | */ | ||
123 | const struct GNUNET_IDENTITY_PublicKey* | ||
124 | get_handle_key (const struct GNUNET_MESSENGER_Handle *handle); | ||
125 | |||
126 | /** | ||
127 | * Returns the used contact store of a given <i>handle</i>. | ||
128 | * | ||
129 | * @param[in/out] handle Handle | ||
130 | * @return Contact store | ||
131 | */ | ||
132 | struct GNUNET_MESSENGER_ContactStore* | ||
133 | get_handle_contact_store (struct GNUNET_MESSENGER_Handle *handle); | ||
134 | |||
135 | /** | ||
136 | * Returns the contact of a given <i>handle</i> in a room identified by a | ||
137 | * given <i>key</i>. | ||
138 | * | ||
139 | * @param[in/out] handle Handle | ||
140 | * @param[in] key Key of room | ||
141 | * @return Contact | ||
142 | */ | ||
143 | struct GNUNET_MESSENGER_Contact* | ||
144 | get_handle_contact (struct GNUNET_MESSENGER_Handle *handle, | ||
145 | const struct GNUNET_HashCode *key); | ||
146 | |||
147 | /** | ||
148 | * Marks a room known to a <i>handle</i> identified by a given <i>key</i> as open. | ||
149 | * | ||
150 | * @param[in/out] handle Handle | ||
151 | * @param[in] key Key of room | ||
152 | */ | ||
153 | void | ||
154 | open_handle_room (struct GNUNET_MESSENGER_Handle *handle, | ||
155 | const struct GNUNET_HashCode *key); | ||
156 | |||
157 | /** | ||
158 | * Adds a tunnel for a room known to a <i>handle</i> identified by a given <i>key</i> to a | ||
159 | * list of opened connections. | ||
160 | * | ||
161 | * @param[in/out] handle Handle | ||
162 | * @param[in] door Peer identity | ||
163 | * @param[in] key Key of room | ||
164 | */ | ||
165 | void | ||
166 | entry_handle_room_at (struct GNUNET_MESSENGER_Handle *handle, | ||
167 | const struct GNUNET_PeerIdentity *door, | ||
168 | const struct GNUNET_HashCode *key); | ||
169 | |||
170 | /** | ||
171 | * Destroys and so implicitly closes a room known to a <i>handle</i> identified by a given <i>key</i>. | ||
172 | * | ||
173 | * @param[in/out] handle Handle | ||
174 | * @param[in] key Key of room | ||
175 | */ | ||
176 | void | ||
177 | close_handle_room (struct GNUNET_MESSENGER_Handle *handle, | ||
178 | const struct GNUNET_HashCode *key); | ||
179 | |||
180 | #endif //GNUNET_MESSENGER_API_HANDLE_H | ||
diff --git a/src/messenger/messenger_api_list_tunnels.c b/src/messenger/messenger_api_list_tunnels.c deleted file mode 100644 index 7e77d8f2f..000000000 --- a/src/messenger/messenger_api_list_tunnels.c +++ /dev/null | |||
@@ -1,192 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api_list_tunnels.c | ||
23 | * @brief messenger api: client and service implementation of GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "messenger_api_list_tunnels.h" | ||
27 | |||
28 | void | ||
29 | init_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels) | ||
30 | { | ||
31 | GNUNET_assert(tunnels); | ||
32 | |||
33 | tunnels->head = NULL; | ||
34 | tunnels->tail = NULL; | ||
35 | } | ||
36 | |||
37 | void | ||
38 | clear_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels) | ||
39 | { | ||
40 | GNUNET_assert(tunnels); | ||
41 | |||
42 | struct GNUNET_MESSENGER_ListTunnel *element; | ||
43 | |||
44 | for (element = tunnels->head; element; element = tunnels->head) | ||
45 | { | ||
46 | GNUNET_CONTAINER_DLL_remove(tunnels->head, tunnels->tail, element); | ||
47 | GNUNET_PEER_change_rc (element->peer, -1); | ||
48 | GNUNET_free(element); | ||
49 | } | ||
50 | |||
51 | tunnels->head = NULL; | ||
52 | tunnels->tail = NULL; | ||
53 | } | ||
54 | |||
55 | static int | ||
56 | compare_list_tunnels (void *cls, | ||
57 | struct GNUNET_MESSENGER_ListTunnel *element0, | ||
58 | struct GNUNET_MESSENGER_ListTunnel *element1) | ||
59 | { | ||
60 | return ((int) element0->peer) - ((int) element1->peer); | ||
61 | } | ||
62 | |||
63 | void | ||
64 | add_to_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, | ||
65 | const struct GNUNET_PeerIdentity *peer) | ||
66 | { | ||
67 | GNUNET_assert((tunnels) && (peer)); | ||
68 | |||
69 | struct GNUNET_MESSENGER_ListTunnel *element = GNUNET_new(struct GNUNET_MESSENGER_ListTunnel); | ||
70 | |||
71 | element->peer = GNUNET_PEER_intern (peer); | ||
72 | |||
73 | GNUNET_CONTAINER_DLL_insert_sorted(struct GNUNET_MESSENGER_ListTunnel, compare_list_tunnels, NULL, tunnels->head, | ||
74 | tunnels->tail, element); | ||
75 | } | ||
76 | |||
77 | struct GNUNET_MESSENGER_ListTunnel* | ||
78 | find_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, | ||
79 | const struct GNUNET_PeerIdentity *peer, | ||
80 | size_t *index) | ||
81 | { | ||
82 | GNUNET_assert((tunnels) && (peer)); | ||
83 | |||
84 | struct GNUNET_MESSENGER_ListTunnel *element; | ||
85 | struct GNUNET_PeerIdentity pid; | ||
86 | |||
87 | if (index) | ||
88 | *index = 0; | ||
89 | |||
90 | for (element = tunnels->head; element; element = element->next) | ||
91 | { | ||
92 | GNUNET_PEER_resolve (element->peer, &pid); | ||
93 | |||
94 | if (0 == GNUNET_memcmp(&pid, peer)) | ||
95 | return element; | ||
96 | |||
97 | if (index) | ||
98 | (*index) = (*index) + 1; | ||
99 | } | ||
100 | |||
101 | return NULL; | ||
102 | } | ||
103 | |||
104 | int | ||
105 | contains_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, | ||
106 | const struct GNUNET_PeerIdentity *peer) | ||
107 | { | ||
108 | GNUNET_assert((tunnels) && (peer)); | ||
109 | |||
110 | return find_list_tunnels (tunnels, peer, NULL) != NULL ? GNUNET_YES : GNUNET_NO; | ||
111 | } | ||
112 | |||
113 | struct GNUNET_MESSENGER_ListTunnel* | ||
114 | remove_from_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, | ||
115 | struct GNUNET_MESSENGER_ListTunnel *element) | ||
116 | { | ||
117 | GNUNET_assert((tunnels) && (element)); | ||
118 | |||
119 | struct GNUNET_MESSENGER_ListTunnel *next = element->next; | ||
120 | |||
121 | GNUNET_CONTAINER_DLL_remove(tunnels->head, tunnels->tail, element); | ||
122 | GNUNET_PEER_change_rc (element->peer, -1); | ||
123 | GNUNET_free(element); | ||
124 | |||
125 | return next; | ||
126 | } | ||
127 | |||
128 | void | ||
129 | load_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, | ||
130 | const char *path) | ||
131 | { | ||
132 | GNUNET_assert((tunnels) && (path)); | ||
133 | |||
134 | if (GNUNET_YES != GNUNET_DISK_file_test (path)) | ||
135 | return; | ||
136 | |||
137 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); | ||
138 | |||
139 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open( | ||
140 | path, GNUNET_DISK_OPEN_READ, permission | ||
141 | ); | ||
142 | |||
143 | if (!handle) | ||
144 | return; | ||
145 | |||
146 | GNUNET_DISK_file_seek(handle, 0, GNUNET_DISK_SEEK_SET); | ||
147 | |||
148 | struct GNUNET_PeerIdentity peer; | ||
149 | ssize_t len; | ||
150 | |||
151 | do { | ||
152 | len = GNUNET_DISK_file_read(handle, &peer, sizeof(peer)); | ||
153 | |||
154 | if (len != sizeof(peer)) | ||
155 | break; | ||
156 | |||
157 | add_to_list_tunnels(tunnels, &peer); | ||
158 | } while (len == sizeof(peer)); | ||
159 | |||
160 | GNUNET_DISK_file_close(handle); | ||
161 | } | ||
162 | |||
163 | void | ||
164 | save_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, | ||
165 | const char *path) | ||
166 | { | ||
167 | GNUNET_assert((tunnels) && (path)); | ||
168 | |||
169 | enum GNUNET_DISK_AccessPermissions permission = (GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); | ||
170 | |||
171 | struct GNUNET_DISK_FileHandle *handle = GNUNET_DISK_file_open( | ||
172 | path, GNUNET_DISK_OPEN_CREATE | GNUNET_DISK_OPEN_WRITE, permission | ||
173 | ); | ||
174 | |||
175 | if (!handle) | ||
176 | return; | ||
177 | |||
178 | GNUNET_DISK_file_seek(handle, 0, GNUNET_DISK_SEEK_SET); | ||
179 | |||
180 | struct GNUNET_MESSENGER_ListTunnel *element; | ||
181 | struct GNUNET_PeerIdentity pid; | ||
182 | |||
183 | for (element = tunnels->head; element; element = element->next) | ||
184 | { | ||
185 | GNUNET_PEER_resolve (element->peer, &pid); | ||
186 | |||
187 | GNUNET_DISK_file_write(handle, &pid, sizeof(pid)); | ||
188 | } | ||
189 | |||
190 | GNUNET_DISK_file_sync(handle); | ||
191 | GNUNET_DISK_file_close(handle); | ||
192 | } | ||
diff --git a/src/messenger/messenger_api_list_tunnels.h b/src/messenger/messenger_api_list_tunnels.h deleted file mode 100644 index 0e086ee5e..000000000 --- a/src/messenger/messenger_api_list_tunnels.h +++ /dev/null | |||
@@ -1,137 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api_list_tunnels.h | ||
23 | * @brief messenger api: client and service implementation of GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_MESSENGER_API_LIST_TUNNELS_H | ||
27 | #define GNUNET_MESSENGER_API_LIST_TUNNELS_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_peer_lib.h" | ||
31 | #include "gnunet_container_lib.h" | ||
32 | |||
33 | struct GNUNET_MESSENGER_ListTunnel | ||
34 | { | ||
35 | struct GNUNET_MESSENGER_ListTunnel *prev; | ||
36 | struct GNUNET_MESSENGER_ListTunnel *next; | ||
37 | |||
38 | GNUNET_PEER_Id peer; | ||
39 | }; | ||
40 | |||
41 | struct GNUNET_MESSENGER_ListTunnels | ||
42 | { | ||
43 | struct GNUNET_MESSENGER_ListTunnel *head; | ||
44 | struct GNUNET_MESSENGER_ListTunnel *tail; | ||
45 | }; | ||
46 | |||
47 | /** | ||
48 | * Initializes list of tunnels peer identities as empty list. | ||
49 | * | ||
50 | * @param[out] tunnels List of peer identities | ||
51 | */ | ||
52 | void | ||
53 | init_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels); | ||
54 | |||
55 | /** | ||
56 | * Clears the list of tunnels peer identities. | ||
57 | * | ||
58 | * @param[in/out] tunnels List of peer identities | ||
59 | */ | ||
60 | void | ||
61 | clear_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels); | ||
62 | |||
63 | /** | ||
64 | * Adds a specific <i>peer</i> from a tunnel to the end of the list. | ||
65 | * | ||
66 | * @param[in/out] tunnels List of peer identities | ||
67 | * @param[in] peer Peer identity of tunnel | ||
68 | */ | ||
69 | void | ||
70 | add_to_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, | ||
71 | const struct GNUNET_PeerIdentity *peer); | ||
72 | |||
73 | /** | ||
74 | * Searches linearly through the list of tunnels peer identities for matching a | ||
75 | * specific <i>peer</i> identity and returns the matching element of the list. | ||
76 | * | ||
77 | * If no matching element is found, NULL gets returned. | ||
78 | * | ||
79 | * If <i>index</i> is not NULL, <i>index</i> will be overridden with the numeric index of | ||
80 | * the found element in the list. If no matching element is found, <i>index</i> will | ||
81 | * contain the total amount of elements in the list. | ||
82 | * | ||
83 | * @param[in/out] tunnels List of peer identities | ||
84 | * @param[in] peer Peer identity of tunnel | ||
85 | * @param[out] index Index of found element (optional) | ||
86 | * @return Element in the list with matching peer identity | ||
87 | */ | ||
88 | struct GNUNET_MESSENGER_ListTunnel* | ||
89 | find_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, | ||
90 | const struct GNUNET_PeerIdentity *peer, | ||
91 | size_t *index); | ||
92 | |||
93 | /** | ||
94 | * Tests linearly if the list of tunnels peer identities contains a specific | ||
95 | * <i>peer</i> identity and returns #GNUNET_YES on success, otherwise #GNUNET_NO. | ||
96 | * | ||
97 | * @param[in/out] tunnels List of peer identities | ||
98 | * @param[in] peer Peer identity of tunnel | ||
99 | * @return #GNUNET_YES on success, otherwise #GNUNET_NO | ||
100 | */ | ||
101 | int | ||
102 | contains_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, | ||
103 | const struct GNUNET_PeerIdentity *peer); | ||
104 | |||
105 | /** | ||
106 | * Removes a specific <i>element</i> from the list of tunnels peer identities and returns | ||
107 | * the next element in the list. | ||
108 | * | ||
109 | * @param[in/out] tunnels List of peer identities | ||
110 | * @param[in/out] element Element of the list | ||
111 | * @return Next element in the list | ||
112 | */ | ||
113 | struct GNUNET_MESSENGER_ListTunnel* | ||
114 | remove_from_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, | ||
115 | struct GNUNET_MESSENGER_ListTunnel *element); | ||
116 | |||
117 | /** | ||
118 | * Loads the list of tunnels peer identities from a file under a given <i>path</i>. | ||
119 | * | ||
120 | * @param[out] messages List of hashes | ||
121 | * @param[in] path Path of file | ||
122 | */ | ||
123 | void | ||
124 | load_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, | ||
125 | const char *path); | ||
126 | |||
127 | /** | ||
128 | * Saves the list of tunnels peer identities to a file under a given <i>path</i>. | ||
129 | * | ||
130 | * @param[in] messages List of hashes | ||
131 | * @param[in] path Path of file | ||
132 | */ | ||
133 | void | ||
134 | save_list_tunnels (struct GNUNET_MESSENGER_ListTunnels *tunnels, | ||
135 | const char *path); | ||
136 | |||
137 | #endif //GNUNET_MESSENGER_API_LIST_TUNNELS_H | ||
diff --git a/src/messenger/messenger_api_message.c b/src/messenger/messenger_api_message.c deleted file mode 100644 index 496c98dbf..000000000 --- a/src/messenger/messenger_api_message.c +++ /dev/null | |||
@@ -1,932 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api_message.c | ||
23 | * @brief messenger api: client and service implementation of GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "messenger_api_message.h" | ||
27 | |||
28 | struct GNUNET_MESSENGER_MessageSignature | ||
29 | { | ||
30 | struct GNUNET_CRYPTO_EccSignaturePurpose purpose; | ||
31 | struct GNUNET_HashCode hash; | ||
32 | }; | ||
33 | |||
34 | struct GNUNET_MESSENGER_ShortMessage | ||
35 | { | ||
36 | enum GNUNET_MESSENGER_MessageKind kind; | ||
37 | struct GNUNET_MESSENGER_MessageBody body; | ||
38 | }; | ||
39 | |||
40 | struct GNUNET_MESSENGER_Message* | ||
41 | create_message (enum GNUNET_MESSENGER_MessageKind kind) | ||
42 | { | ||
43 | struct GNUNET_MESSENGER_Message *message = GNUNET_new(struct GNUNET_MESSENGER_Message); | ||
44 | |||
45 | message->header.kind = kind; | ||
46 | |||
47 | switch (message->header.kind) | ||
48 | { | ||
49 | case GNUNET_MESSENGER_KIND_NAME: | ||
50 | message->body.name.name = NULL; | ||
51 | break; | ||
52 | case GNUNET_MESSENGER_KIND_TEXT: | ||
53 | message->body.text.text = NULL; | ||
54 | break; | ||
55 | case GNUNET_MESSENGER_KIND_FILE: | ||
56 | message->body.file.uri = NULL; | ||
57 | break; | ||
58 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
59 | message->body.privacy.length = 0; | ||
60 | message->body.privacy.data = NULL; | ||
61 | break; | ||
62 | default: | ||
63 | break; | ||
64 | } | ||
65 | |||
66 | return message; | ||
67 | } | ||
68 | |||
69 | struct GNUNET_MESSENGER_Message* | ||
70 | copy_message (const struct GNUNET_MESSENGER_Message *message) | ||
71 | { | ||
72 | GNUNET_assert(message); | ||
73 | |||
74 | struct GNUNET_MESSENGER_Message *copy = GNUNET_new(struct GNUNET_MESSENGER_Message); | ||
75 | |||
76 | GNUNET_memcpy(copy, message, sizeof(struct GNUNET_MESSENGER_Message)); | ||
77 | |||
78 | switch (message->header.kind) | ||
79 | { | ||
80 | case GNUNET_MESSENGER_KIND_NAME: | ||
81 | copy->body.name.name = GNUNET_strdup(message->body.name.name); | ||
82 | break; | ||
83 | case GNUNET_MESSENGER_KIND_TEXT: | ||
84 | copy->body.text.text = GNUNET_strdup(message->body.text.text); | ||
85 | break; | ||
86 | case GNUNET_MESSENGER_KIND_FILE: | ||
87 | copy->body.file.uri = GNUNET_strdup(message->body.file.uri); | ||
88 | break; | ||
89 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
90 | copy->body.privacy.data = copy->body.privacy.length ? GNUNET_malloc(copy->body.privacy.length) : NULL; | ||
91 | |||
92 | if (copy->body.privacy.data) | ||
93 | { | ||
94 | GNUNET_memcpy(copy->body.privacy.data, message->body.privacy.data, copy->body.privacy.length); | ||
95 | } | ||
96 | |||
97 | break; | ||
98 | default: | ||
99 | break; | ||
100 | } | ||
101 | |||
102 | return copy; | ||
103 | } | ||
104 | |||
105 | static void | ||
106 | destroy_message_body (enum GNUNET_MESSENGER_MessageKind kind, | ||
107 | struct GNUNET_MESSENGER_MessageBody *body) | ||
108 | { | ||
109 | switch (kind) | ||
110 | { | ||
111 | case GNUNET_MESSENGER_KIND_NAME: | ||
112 | GNUNET_free(body->name.name); | ||
113 | break; | ||
114 | case GNUNET_MESSENGER_KIND_TEXT: | ||
115 | GNUNET_free(body->text.text); | ||
116 | break; | ||
117 | case GNUNET_MESSENGER_KIND_FILE: | ||
118 | GNUNET_free(body->file.uri); | ||
119 | break; | ||
120 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
121 | GNUNET_free(body->privacy.data); | ||
122 | break; | ||
123 | default: | ||
124 | break; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | void | ||
129 | cleanup_message (struct GNUNET_MESSENGER_Message *message) | ||
130 | { | ||
131 | GNUNET_assert(message); | ||
132 | |||
133 | destroy_message_body (message->header.kind, &(message->body)); | ||
134 | } | ||
135 | |||
136 | void | ||
137 | destroy_message (struct GNUNET_MESSENGER_Message *message) | ||
138 | { | ||
139 | GNUNET_assert(message); | ||
140 | |||
141 | destroy_message_body (message->header.kind, &(message->body)); | ||
142 | |||
143 | GNUNET_free(message); | ||
144 | } | ||
145 | |||
146 | int | ||
147 | is_message_session_bound (const struct GNUNET_MESSENGER_Message *message) | ||
148 | { | ||
149 | GNUNET_assert(message); | ||
150 | |||
151 | if ((GNUNET_MESSENGER_KIND_JOIN == message->header.kind) || | ||
152 | (GNUNET_MESSENGER_KIND_LEAVE == message->header.kind) || | ||
153 | (GNUNET_MESSENGER_KIND_NAME == message->header.kind) || | ||
154 | (GNUNET_MESSENGER_KIND_KEY == message->header.kind) || | ||
155 | (GNUNET_MESSENGER_KIND_ID == message->header.kind)) | ||
156 | return GNUNET_YES; | ||
157 | else | ||
158 | return GNUNET_NO; | ||
159 | } | ||
160 | |||
161 | static void | ||
162 | fold_short_message (const struct GNUNET_MESSENGER_Message *message, | ||
163 | struct GNUNET_MESSENGER_ShortMessage *shortened) | ||
164 | { | ||
165 | shortened->kind = message->header.kind; | ||
166 | |||
167 | GNUNET_memcpy(&(shortened->body), &(message->body), sizeof(struct GNUNET_MESSENGER_MessageBody)); | ||
168 | } | ||
169 | |||
170 | static void | ||
171 | unfold_short_message (struct GNUNET_MESSENGER_ShortMessage *shortened, | ||
172 | struct GNUNET_MESSENGER_Message *message) | ||
173 | { | ||
174 | destroy_message_body (message->header.kind, &(message->body)); | ||
175 | |||
176 | message->header.kind = shortened->kind; | ||
177 | |||
178 | GNUNET_memcpy(&(message->body), &(shortened->body), sizeof(struct GNUNET_MESSENGER_MessageBody)); | ||
179 | } | ||
180 | |||
181 | #define member_size(type, member) sizeof(((type*) NULL)->member) | ||
182 | |||
183 | static uint16_t | ||
184 | get_message_body_kind_size (enum GNUNET_MESSENGER_MessageKind kind) | ||
185 | { | ||
186 | uint16_t length = 0; | ||
187 | |||
188 | switch (kind) | ||
189 | { | ||
190 | case GNUNET_MESSENGER_KIND_INFO: | ||
191 | length += member_size(struct GNUNET_MESSENGER_Message, body.info.messenger_version); | ||
192 | break; | ||
193 | case GNUNET_MESSENGER_KIND_PEER: | ||
194 | length += member_size(struct GNUNET_MESSENGER_Message, body.peer.peer); | ||
195 | break; | ||
196 | case GNUNET_MESSENGER_KIND_ID: | ||
197 | length += member_size(struct GNUNET_MESSENGER_Message, body.id.id); | ||
198 | break; | ||
199 | case GNUNET_MESSENGER_KIND_MISS: | ||
200 | length += member_size(struct GNUNET_MESSENGER_Message, body.miss.peer); | ||
201 | break; | ||
202 | case GNUNET_MESSENGER_KIND_MERGE: | ||
203 | length += member_size(struct GNUNET_MESSENGER_Message, body.merge.previous); | ||
204 | break; | ||
205 | case GNUNET_MESSENGER_KIND_REQUEST: | ||
206 | length += member_size(struct GNUNET_MESSENGER_Message, body.request.hash); | ||
207 | break; | ||
208 | case GNUNET_MESSENGER_KIND_INVITE: | ||
209 | length += member_size(struct GNUNET_MESSENGER_Message, body.invite.door); | ||
210 | length += member_size(struct GNUNET_MESSENGER_Message, body.invite.key); | ||
211 | break; | ||
212 | case GNUNET_MESSENGER_KIND_TEXT: | ||
213 | break; | ||
214 | case GNUNET_MESSENGER_KIND_FILE: | ||
215 | length += member_size(struct GNUNET_MESSENGER_Message, body.file.key); | ||
216 | length += member_size(struct GNUNET_MESSENGER_Message, body.file.hash); | ||
217 | length += member_size(struct GNUNET_MESSENGER_Message, body.file.name); | ||
218 | break; | ||
219 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
220 | length += member_size(struct GNUNET_MESSENGER_Message, body.privacy.key); | ||
221 | break; | ||
222 | default: | ||
223 | break; | ||
224 | } | ||
225 | |||
226 | return length; | ||
227 | } | ||
228 | |||
229 | typedef uint32_t kind_t; | ||
230 | |||
231 | uint16_t | ||
232 | get_message_kind_size (enum GNUNET_MESSENGER_MessageKind kind, | ||
233 | int include_header) | ||
234 | { | ||
235 | uint16_t length = 0; | ||
236 | |||
237 | if (GNUNET_YES == include_header) | ||
238 | { | ||
239 | length += member_size(struct GNUNET_MESSENGER_Message, header.timestamp); | ||
240 | length += member_size(struct GNUNET_MESSENGER_Message, header.sender_id); | ||
241 | length += member_size(struct GNUNET_MESSENGER_Message, header.previous); | ||
242 | } | ||
243 | |||
244 | length += sizeof(kind_t); | ||
245 | |||
246 | return length + get_message_body_kind_size (kind); | ||
247 | } | ||
248 | |||
249 | static uint16_t | ||
250 | get_message_body_size (enum GNUNET_MESSENGER_MessageKind kind, | ||
251 | const struct GNUNET_MESSENGER_MessageBody *body) | ||
252 | { | ||
253 | uint16_t length = 0; | ||
254 | |||
255 | switch (kind) | ||
256 | { | ||
257 | case GNUNET_MESSENGER_KIND_INFO: | ||
258 | length += GNUNET_IDENTITY_key_get_length(&(body->info.host_key)); | ||
259 | break; | ||
260 | case GNUNET_MESSENGER_KIND_JOIN: | ||
261 | length += GNUNET_IDENTITY_key_get_length(&(body->join.key)); | ||
262 | break; | ||
263 | case GNUNET_MESSENGER_KIND_NAME: | ||
264 | length += (body->name.name ? strlen (body->name.name) : 0); | ||
265 | break; | ||
266 | case GNUNET_MESSENGER_KIND_KEY: | ||
267 | length += GNUNET_IDENTITY_key_get_length(&(body->key.key)); | ||
268 | break; | ||
269 | case GNUNET_MESSENGER_KIND_TEXT: | ||
270 | length += strlen (body->text.text); | ||
271 | break; | ||
272 | case GNUNET_MESSENGER_KIND_FILE: | ||
273 | length += strlen (body->file.uri); | ||
274 | break; | ||
275 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
276 | length += body->privacy.length; | ||
277 | break; | ||
278 | default: | ||
279 | break; | ||
280 | } | ||
281 | |||
282 | return length; | ||
283 | } | ||
284 | |||
285 | uint16_t | ||
286 | get_message_size (const struct GNUNET_MESSENGER_Message *message, | ||
287 | int include_header) | ||
288 | { | ||
289 | GNUNET_assert(message); | ||
290 | |||
291 | uint16_t length = 0; | ||
292 | |||
293 | if (GNUNET_YES == include_header) | ||
294 | length += GNUNET_IDENTITY_signature_get_length(&(message->header.signature)); | ||
295 | |||
296 | length += get_message_kind_size (message->header.kind, include_header); | ||
297 | length += get_message_body_size (message->header.kind, &(message->body)); | ||
298 | |||
299 | return length; | ||
300 | } | ||
301 | |||
302 | static uint16_t | ||
303 | get_short_message_size (const struct GNUNET_MESSENGER_ShortMessage *message, | ||
304 | int include_body) | ||
305 | { | ||
306 | const uint16_t minimum_size = sizeof(struct GNUNET_HashCode) + sizeof(kind_t); | ||
307 | |||
308 | if (message) | ||
309 | return minimum_size + get_message_body_kind_size (message->kind) | ||
310 | + (include_body == GNUNET_YES? get_message_body_size (message->kind, &(message->body)) : 0); | ||
311 | else | ||
312 | return minimum_size; | ||
313 | } | ||
314 | |||
315 | static uint16_t | ||
316 | calc_usual_padding () | ||
317 | { | ||
318 | uint16_t padding = 0; | ||
319 | uint16_t kind_size; | ||
320 | |||
321 | for (int i = 0; i <= GNUNET_MESSENGER_KIND_MAX; i++) { | ||
322 | kind_size = get_message_kind_size ((enum GNUNET_MESSENGER_MessageKind) i, GNUNET_YES); | ||
323 | |||
324 | if (kind_size > padding) | ||
325 | padding = kind_size; | ||
326 | } | ||
327 | |||
328 | return padding + GNUNET_MESSENGER_PADDING_MIN; | ||
329 | } | ||
330 | |||
331 | #define max(x, y) (x > y? x : y) | ||
332 | |||
333 | static uint16_t | ||
334 | calc_padded_length (uint16_t length) | ||
335 | { | ||
336 | static uint16_t usual_padding = 0; | ||
337 | |||
338 | if (!usual_padding) | ||
339 | usual_padding = calc_usual_padding(); | ||
340 | |||
341 | const uint16_t padded_length = max( | ||
342 | length + GNUNET_MESSENGER_PADDING_MIN, | ||
343 | usual_padding | ||
344 | ); | ||
345 | |||
346 | if (padded_length <= GNUNET_MESSENGER_PADDING_LEVEL0) | ||
347 | return GNUNET_MESSENGER_PADDING_LEVEL0; | ||
348 | |||
349 | if (padded_length <= GNUNET_MESSENGER_PADDING_LEVEL1) | ||
350 | return GNUNET_MESSENGER_PADDING_LEVEL1; | ||
351 | |||
352 | if (padded_length <= GNUNET_MESSENGER_PADDING_LEVEL2) | ||
353 | return GNUNET_MESSENGER_PADDING_LEVEL2; | ||
354 | |||
355 | return GNUNET_MESSENGER_MAX_MESSAGE_SIZE; | ||
356 | |||
357 | } | ||
358 | |||
359 | #define min(x, y) (x < y? x : y) | ||
360 | |||
361 | #define encode_step_ext(dst, offset, src, size) do { \ | ||
362 | GNUNET_memcpy(dst + offset, src, size); \ | ||
363 | offset += size; \ | ||
364 | } while (0) | ||
365 | |||
366 | #define encode_step(dst, offset, src) do { \ | ||
367 | encode_step_ext(dst, offset, src, sizeof(*src)); \ | ||
368 | } while (0) | ||
369 | |||
370 | #define encode_step_key(dst, offset, src, length) do { \ | ||
371 | ssize_t result = GNUNET_IDENTITY_write_key_to_buffer( \ | ||
372 | src, dst + offset, length - offset \ | ||
373 | ); \ | ||
374 | if (result < 0) \ | ||
375 | GNUNET_break (0); \ | ||
376 | else \ | ||
377 | offset += result; \ | ||
378 | } while (0) | ||
379 | |||
380 | #define encode_step_signature(dst, offset, src, length) do { \ | ||
381 | ssize_t result = GNUNET_IDENTITY_write_signature_to_buffer( \ | ||
382 | src, dst + offset, length - offset \ | ||
383 | ); \ | ||
384 | if (result < 0) \ | ||
385 | GNUNET_break (0); \ | ||
386 | else \ | ||
387 | offset += result; \ | ||
388 | } while (0) | ||
389 | |||
390 | static void | ||
391 | encode_message_body (enum GNUNET_MESSENGER_MessageKind kind, | ||
392 | const struct GNUNET_MESSENGER_MessageBody *body, | ||
393 | uint16_t length, | ||
394 | char *buffer, | ||
395 | uint16_t offset) | ||
396 | { | ||
397 | uint32_t version; | ||
398 | switch (kind) | ||
399 | { | ||
400 | case GNUNET_MESSENGER_KIND_INFO: | ||
401 | version = GNUNET_htobe32(body->info.messenger_version); | ||
402 | |||
403 | encode_step_key(buffer, offset, &(body->info.host_key), length); | ||
404 | encode_step(buffer, offset, &version); | ||
405 | break; | ||
406 | case GNUNET_MESSENGER_KIND_JOIN: | ||
407 | encode_step_key(buffer, offset, &(body->join.key), length); | ||
408 | break; | ||
409 | case GNUNET_MESSENGER_KIND_NAME: | ||
410 | if (body->name.name) | ||
411 | encode_step_ext(buffer, offset, body->name.name, min(length - offset, strlen(body->name.name))); | ||
412 | break; | ||
413 | case GNUNET_MESSENGER_KIND_KEY: | ||
414 | encode_step_key(buffer, offset, &(body->key.key), length); | ||
415 | break; | ||
416 | case GNUNET_MESSENGER_KIND_PEER: | ||
417 | encode_step(buffer, offset, &(body->peer.peer)); | ||
418 | break; | ||
419 | case GNUNET_MESSENGER_KIND_ID: | ||
420 | encode_step(buffer, offset, &(body->id.id)); | ||
421 | break; | ||
422 | case GNUNET_MESSENGER_KIND_MISS: | ||
423 | encode_step(buffer, offset, &(body->miss.peer)); | ||
424 | break; | ||
425 | case GNUNET_MESSENGER_KIND_MERGE: | ||
426 | encode_step(buffer, offset, &(body->merge.previous)); | ||
427 | break; | ||
428 | case GNUNET_MESSENGER_KIND_REQUEST: | ||
429 | encode_step(buffer, offset, &(body->request.hash)); | ||
430 | break; | ||
431 | case GNUNET_MESSENGER_KIND_INVITE: | ||
432 | encode_step(buffer, offset, &(body->invite.door)); | ||
433 | encode_step(buffer, offset, &(body->invite.key)); | ||
434 | break; | ||
435 | case GNUNET_MESSENGER_KIND_TEXT: | ||
436 | encode_step_ext(buffer, offset, body->text.text, min(length - offset, strlen(body->text.text))); | ||
437 | break; | ||
438 | case GNUNET_MESSENGER_KIND_FILE: | ||
439 | encode_step(buffer, offset, &(body->file.key)); | ||
440 | encode_step(buffer, offset, &(body->file.hash)); | ||
441 | encode_step_ext(buffer, offset, body->file.name, sizeof(body->file.name)); | ||
442 | encode_step_ext(buffer, offset, body->file.uri, min(length - offset, strlen(body->file.uri))); | ||
443 | break; | ||
444 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
445 | encode_step(buffer, offset, &(body->privacy.key)); | ||
446 | encode_step_ext(buffer, offset, body->privacy.data, min(length - offset, body->privacy.length)); | ||
447 | break; | ||
448 | default: | ||
449 | break; | ||
450 | } | ||
451 | |||
452 | if (offset >= length) | ||
453 | return; | ||
454 | |||
455 | const uint16_t padding = length - offset; | ||
456 | const uint16_t used_padding = sizeof(padding) + sizeof(char); | ||
457 | |||
458 | GNUNET_assert(padding >= used_padding); | ||
459 | |||
460 | buffer[offset++] = '\0'; | ||
461 | |||
462 | if (padding > used_padding) | ||
463 | GNUNET_CRYPTO_random_block(GNUNET_CRYPTO_QUALITY_WEAK, buffer + offset, padding - used_padding); | ||
464 | |||
465 | GNUNET_memcpy(buffer + length - sizeof(padding), &padding, sizeof(padding)); | ||
466 | } | ||
467 | |||
468 | void | ||
469 | encode_message (const struct GNUNET_MESSENGER_Message *message, | ||
470 | uint16_t length, | ||
471 | char *buffer, | ||
472 | int include_header) | ||
473 | { | ||
474 | GNUNET_assert((message) && (buffer)); | ||
475 | |||
476 | uint16_t offset = 0; | ||
477 | |||
478 | if (GNUNET_YES == include_header) | ||
479 | encode_step_signature(buffer, offset, &(message->header.signature), length); | ||
480 | |||
481 | const kind_t kind = GNUNET_htobe32((kind_t) message->header.kind); | ||
482 | |||
483 | if (GNUNET_YES == include_header) | ||
484 | { | ||
485 | encode_step(buffer, offset, &(message->header.timestamp)); | ||
486 | encode_step(buffer, offset, &(message->header.sender_id)); | ||
487 | encode_step(buffer, offset, &(message->header.previous)); | ||
488 | } | ||
489 | |||
490 | encode_step(buffer, offset, &kind); | ||
491 | |||
492 | encode_message_body (message->header.kind, &(message->body), length, buffer, offset); | ||
493 | } | ||
494 | |||
495 | static void | ||
496 | encode_short_message (const struct GNUNET_MESSENGER_ShortMessage *message, | ||
497 | uint16_t length, | ||
498 | char *buffer) | ||
499 | { | ||
500 | struct GNUNET_HashCode hash; | ||
501 | uint16_t offset = sizeof(hash); | ||
502 | |||
503 | const kind_t kind = GNUNET_htobe32((kind_t) message->kind); | ||
504 | |||
505 | encode_step(buffer, offset, &kind); | ||
506 | |||
507 | encode_message_body (message->kind, &(message->body), length, buffer, offset); | ||
508 | |||
509 | GNUNET_CRYPTO_hash( | ||
510 | buffer + sizeof(hash), | ||
511 | length - sizeof(hash), | ||
512 | &hash | ||
513 | ); | ||
514 | |||
515 | GNUNET_memcpy(buffer, &hash, sizeof(hash)); | ||
516 | } | ||
517 | |||
518 | #define decode_step_ext(src, offset, dst, size) do { \ | ||
519 | GNUNET_memcpy(dst, src + offset, size); \ | ||
520 | offset += size; \ | ||
521 | } while (0) | ||
522 | |||
523 | #define decode_step(src, offset, dst) do { \ | ||
524 | decode_step_ext(src, offset, dst, sizeof(*dst)); \ | ||
525 | } while (0) | ||
526 | |||
527 | #define decode_step_malloc(src, offset, dst, size, zero) do { \ | ||
528 | dst = GNUNET_malloc(size + zero); \ | ||
529 | if (zero) dst[size] = 0; \ | ||
530 | decode_step_ext(src, offset, dst, size); \ | ||
531 | } while (0) | ||
532 | |||
533 | #define decode_step_key(src, offset, dst, length) do { \ | ||
534 | ssize_t result = GNUNET_IDENTITY_read_key_from_buffer( \ | ||
535 | dst, src + offset, length - offset \ | ||
536 | ); \ | ||
537 | if (result < 0) \ | ||
538 | GNUNET_break(0); \ | ||
539 | else \ | ||
540 | offset += result; \ | ||
541 | } while (0) | ||
542 | |||
543 | static uint16_t | ||
544 | decode_message_body (enum GNUNET_MESSENGER_MessageKind *kind, | ||
545 | struct GNUNET_MESSENGER_MessageBody *body, | ||
546 | uint16_t length, | ||
547 | const char *buffer, | ||
548 | uint16_t offset) | ||
549 | { | ||
550 | uint16_t padding = 0; | ||
551 | |||
552 | GNUNET_memcpy(&padding, buffer + length - sizeof(padding), sizeof(padding)); | ||
553 | |||
554 | if (padding > length - offset) | ||
555 | padding = 0; | ||
556 | |||
557 | const uint16_t end_zero = length - padding; | ||
558 | |||
559 | if ((padding) && (buffer[end_zero] != '\0')) | ||
560 | padding = 0; | ||
561 | |||
562 | length -= padding; | ||
563 | |||
564 | uint32_t version; | ||
565 | switch (*kind) | ||
566 | { | ||
567 | case GNUNET_MESSENGER_KIND_INFO: { | ||
568 | decode_step_key(buffer, offset, &(body->info.host_key), length); | ||
569 | decode_step(buffer, offset, &version); | ||
570 | |||
571 | body->info.messenger_version = GNUNET_be32toh(version); | ||
572 | break; | ||
573 | } case GNUNET_MESSENGER_KIND_JOIN: { | ||
574 | decode_step_key(buffer, offset, &(body->join.key), length); | ||
575 | break; | ||
576 | } case GNUNET_MESSENGER_KIND_NAME: | ||
577 | if (length - offset > 0) | ||
578 | decode_step_malloc(buffer, offset, body->name.name, length - offset, 1); | ||
579 | else | ||
580 | body->name.name = NULL; | ||
581 | break; | ||
582 | case GNUNET_MESSENGER_KIND_KEY: | ||
583 | decode_step_key(buffer, offset, &(body->key.key), length); | ||
584 | break; | ||
585 | case GNUNET_MESSENGER_KIND_PEER: | ||
586 | decode_step(buffer, offset, &(body->peer.peer)); | ||
587 | break; | ||
588 | case GNUNET_MESSENGER_KIND_ID: | ||
589 | decode_step(buffer, offset, &(body->id.id)); | ||
590 | break; | ||
591 | case GNUNET_MESSENGER_KIND_MISS: | ||
592 | decode_step(buffer, offset, &(body->miss.peer)); | ||
593 | break; | ||
594 | case GNUNET_MESSENGER_KIND_MERGE: | ||
595 | decode_step(buffer, offset, &(body->merge.previous)); | ||
596 | break; | ||
597 | case GNUNET_MESSENGER_KIND_REQUEST: | ||
598 | decode_step(buffer, offset, &(body->request.hash)); | ||
599 | break; | ||
600 | case GNUNET_MESSENGER_KIND_INVITE: | ||
601 | decode_step(buffer, offset, &(body->invite.door)); | ||
602 | decode_step(buffer, offset, &(body->invite.key)); | ||
603 | break; | ||
604 | case GNUNET_MESSENGER_KIND_TEXT: | ||
605 | decode_step_malloc(buffer, offset, body->text.text, length - offset, 1); | ||
606 | break; | ||
607 | case GNUNET_MESSENGER_KIND_FILE: | ||
608 | decode_step(buffer, offset, &(body->file.key)); | ||
609 | decode_step(buffer, offset, &(body->file.hash)); | ||
610 | decode_step_ext(buffer, offset, body->file.name, sizeof(body->file.name)); | ||
611 | decode_step_malloc(buffer, offset, body->file.uri, length - offset, 1); | ||
612 | break; | ||
613 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
614 | decode_step(buffer, offset, &(body->privacy.key)); | ||
615 | |||
616 | body->privacy.length = (length - offset); | ||
617 | decode_step_malloc(buffer, offset, body->privacy.data, length - offset, 0); | ||
618 | break; | ||
619 | default: | ||
620 | *kind = GNUNET_MESSENGER_KIND_UNKNOWN; | ||
621 | break; | ||
622 | } | ||
623 | |||
624 | return padding; | ||
625 | } | ||
626 | |||
627 | int | ||
628 | decode_message (struct GNUNET_MESSENGER_Message *message, | ||
629 | uint16_t length, | ||
630 | const char *buffer, | ||
631 | int include_header, | ||
632 | uint16_t *padding) | ||
633 | { | ||
634 | GNUNET_assert( | ||
635 | (message) && | ||
636 | (buffer) && | ||
637 | (length >= get_message_kind_size(GNUNET_MESSENGER_KIND_UNKNOWN, include_header)) | ||
638 | ); | ||
639 | |||
640 | uint16_t offset = 0; | ||
641 | |||
642 | if (GNUNET_YES == include_header) | ||
643 | { | ||
644 | ssize_t result = GNUNET_IDENTITY_read_signature_from_buffer( | ||
645 | &(message->header.signature), buffer, length - offset | ||
646 | ); | ||
647 | |||
648 | if (result < 0) | ||
649 | return GNUNET_NO; | ||
650 | else | ||
651 | offset += result; | ||
652 | } | ||
653 | |||
654 | const uint16_t count = length - offset; | ||
655 | |||
656 | if (count < get_message_kind_size (GNUNET_MESSENGER_KIND_UNKNOWN, include_header)) | ||
657 | return GNUNET_NO; | ||
658 | |||
659 | kind_t kind; | ||
660 | |||
661 | if (GNUNET_YES == include_header) | ||
662 | { | ||
663 | decode_step(buffer, offset, &(message->header.timestamp)); | ||
664 | decode_step(buffer, offset, &(message->header.sender_id)); | ||
665 | decode_step(buffer, offset, &(message->header.previous)); | ||
666 | } | ||
667 | |||
668 | decode_step(buffer, offset, &kind); | ||
669 | |||
670 | message->header.kind = (enum GNUNET_MESSENGER_MessageKind) GNUNET_be32toh(kind); | ||
671 | |||
672 | if (count < get_message_kind_size (message->header.kind, include_header)) | ||
673 | return GNUNET_NO; | ||
674 | |||
675 | const uint16_t result = decode_message_body (&(message->header.kind), &(message->body), length, buffer, offset); | ||
676 | |||
677 | if (padding) | ||
678 | *padding = result; | ||
679 | |||
680 | return GNUNET_YES; | ||
681 | } | ||
682 | |||
683 | static int | ||
684 | decode_short_message (struct GNUNET_MESSENGER_ShortMessage *message, | ||
685 | uint16_t length, | ||
686 | const char *buffer) | ||
687 | { | ||
688 | struct GNUNET_HashCode expected, hash; | ||
689 | uint16_t offset = sizeof(hash); | ||
690 | |||
691 | if (length < get_short_message_size (NULL, GNUNET_NO)) | ||
692 | return GNUNET_NO; | ||
693 | |||
694 | GNUNET_memcpy(&hash, buffer, sizeof(hash)); | ||
695 | |||
696 | GNUNET_CRYPTO_hash( | ||
697 | buffer + sizeof(hash), | ||
698 | length - sizeof(hash), | ||
699 | &expected | ||
700 | ); | ||
701 | |||
702 | if (0 != GNUNET_CRYPTO_hash_cmp(&hash, &expected)) | ||
703 | return GNUNET_NO; | ||
704 | |||
705 | kind_t kind; | ||
706 | |||
707 | decode_step(buffer, offset, &kind); | ||
708 | |||
709 | message->kind = (enum GNUNET_MESSENGER_MessageKind) GNUNET_be32toh(kind); | ||
710 | |||
711 | if (length < get_short_message_size (message, GNUNET_NO)) | ||
712 | return GNUNET_NO; | ||
713 | |||
714 | decode_message_body (&(message->kind), &(message->body), length, buffer, offset); | ||
715 | |||
716 | if (GNUNET_MESSENGER_KIND_UNKNOWN == message->kind) | ||
717 | return GNUNET_NO; | ||
718 | |||
719 | return GNUNET_YES; | ||
720 | } | ||
721 | |||
722 | void | ||
723 | hash_message (const struct GNUNET_MESSENGER_Message *message, | ||
724 | uint16_t length, | ||
725 | const char *buffer, | ||
726 | struct GNUNET_HashCode *hash) | ||
727 | { | ||
728 | GNUNET_assert((message) && (buffer) && (hash)); | ||
729 | |||
730 | const ssize_t offset = GNUNET_IDENTITY_signature_get_length( | ||
731 | &(message->header.signature) | ||
732 | ); | ||
733 | |||
734 | GNUNET_CRYPTO_hash (buffer + offset, length - offset, hash); | ||
735 | } | ||
736 | |||
737 | void | ||
738 | sign_message (struct GNUNET_MESSENGER_Message *message, | ||
739 | uint16_t length, | ||
740 | char *buffer, | ||
741 | const struct GNUNET_HashCode *hash, | ||
742 | const struct GNUNET_MESSENGER_Ego *ego) | ||
743 | { | ||
744 | GNUNET_assert((message) && (buffer) && (hash) && (ego)); | ||
745 | |||
746 | struct GNUNET_MESSENGER_MessageSignature signature; | ||
747 | |||
748 | signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); | ||
749 | signature.purpose.size = htonl (sizeof(signature)); | ||
750 | |||
751 | GNUNET_memcpy(&(signature.hash), hash, sizeof(struct GNUNET_HashCode)); | ||
752 | GNUNET_IDENTITY_sign(&(ego->priv), &signature, &(message->header.signature)); | ||
753 | |||
754 | uint16_t offset = 0; | ||
755 | encode_step_signature(buffer, offset, &(message->header.signature), length); | ||
756 | } | ||
757 | |||
758 | int | ||
759 | verify_message (const struct GNUNET_MESSENGER_Message *message, | ||
760 | const struct GNUNET_HashCode *hash, | ||
761 | const struct GNUNET_IDENTITY_PublicKey *key) | ||
762 | { | ||
763 | GNUNET_assert((message) && (hash) && (key)); | ||
764 | |||
765 | if (ntohl (key->type) != ntohl (message->header.signature.type)) | ||
766 | return GNUNET_SYSERR; | ||
767 | |||
768 | struct GNUNET_MESSENGER_MessageSignature signature; | ||
769 | |||
770 | signature.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE); | ||
771 | signature.purpose.size = htonl (sizeof(signature)); | ||
772 | |||
773 | GNUNET_memcpy(&(signature.hash), hash, sizeof(struct GNUNET_HashCode)); | ||
774 | |||
775 | return GNUNET_IDENTITY_signature_verify(GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE, &signature, | ||
776 | &(message->header.signature), key); | ||
777 | } | ||
778 | |||
779 | int | ||
780 | encrypt_message (struct GNUNET_MESSENGER_Message *message, | ||
781 | const struct GNUNET_IDENTITY_PublicKey *key) | ||
782 | { | ||
783 | GNUNET_assert((message) && (key)); | ||
784 | |||
785 | struct GNUNET_MESSENGER_ShortMessage shortened; | ||
786 | |||
787 | fold_short_message (message, &shortened); | ||
788 | |||
789 | const uint16_t length = get_short_message_size (&shortened, GNUNET_YES); | ||
790 | const uint16_t padded_length = calc_padded_length(length); | ||
791 | |||
792 | message->header.kind = GNUNET_MESSENGER_KIND_PRIVATE; | ||
793 | message->body.privacy.data = GNUNET_malloc(padded_length); | ||
794 | message->body.privacy.length = padded_length; | ||
795 | |||
796 | encode_short_message (&shortened, padded_length, message->body.privacy.data); | ||
797 | |||
798 | if (padded_length == GNUNET_IDENTITY_encrypt (message->body.privacy.data, padded_length, key, | ||
799 | &(message->body.privacy.key), | ||
800 | message->body.privacy.data)) | ||
801 | { | ||
802 | destroy_message_body (shortened.kind, &(shortened.body)); | ||
803 | return GNUNET_YES; | ||
804 | } | ||
805 | else | ||
806 | { | ||
807 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Encrypting message failed!\n"); | ||
808 | |||
809 | unfold_short_message (&shortened, message); | ||
810 | return GNUNET_NO; | ||
811 | } | ||
812 | } | ||
813 | |||
814 | int | ||
815 | decrypt_message (struct GNUNET_MESSENGER_Message *message, | ||
816 | const struct GNUNET_IDENTITY_PrivateKey *key) | ||
817 | { | ||
818 | GNUNET_assert((message) && (key)); | ||
819 | |||
820 | if (message->body.privacy.length != GNUNET_IDENTITY_decrypt (message->body.privacy.data, message->body.privacy.length, | ||
821 | key, &(message->body.privacy.key), | ||
822 | message->body.privacy.data)) | ||
823 | { | ||
824 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Decrypting message failed!\n"); | ||
825 | |||
826 | return GNUNET_NO; | ||
827 | } | ||
828 | |||
829 | struct GNUNET_MESSENGER_ShortMessage shortened; | ||
830 | |||
831 | if (GNUNET_YES != decode_short_message (&shortened, message->body.privacy.length, message->body.privacy.data)) | ||
832 | { | ||
833 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Decoding decrypted message failed!\n"); | ||
834 | |||
835 | return GNUNET_NO; | ||
836 | } | ||
837 | |||
838 | unfold_short_message (&shortened, message); | ||
839 | |||
840 | return GNUNET_YES; | ||
841 | } | ||
842 | |||
843 | struct GNUNET_MQ_Envelope* | ||
844 | pack_message (struct GNUNET_MESSENGER_Message *message, | ||
845 | struct GNUNET_HashCode *hash, | ||
846 | const struct GNUNET_MESSENGER_Ego *ego, | ||
847 | int mode) | ||
848 | { | ||
849 | GNUNET_assert(message); | ||
850 | |||
851 | if (ego) | ||
852 | message->header.signature.type = ego->priv.type; | ||
853 | |||
854 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Packing message kind=%u and sender: %s\n", | ||
855 | message->header.kind, GNUNET_sh2s(&(message->header.sender_id))); | ||
856 | |||
857 | struct GNUNET_MessageHeader *header; | ||
858 | |||
859 | const uint16_t length = get_message_size (message, GNUNET_YES); | ||
860 | const uint16_t padded_length = calc_padded_length(length); | ||
861 | |||
862 | struct GNUNET_MQ_Envelope *env; | ||
863 | char *buffer; | ||
864 | |||
865 | if (GNUNET_MESSENGER_PACK_MODE_ENVELOPE == mode) | ||
866 | { | ||
867 | env = GNUNET_MQ_msg_extra(header, padded_length, GNUNET_MESSAGE_TYPE_CADET_CLI); | ||
868 | |||
869 | buffer = (char*) &(header[1]); | ||
870 | } | ||
871 | else | ||
872 | { | ||
873 | env = NULL; | ||
874 | |||
875 | buffer = GNUNET_malloc(padded_length); | ||
876 | } | ||
877 | |||
878 | encode_message (message, padded_length, buffer, GNUNET_YES); | ||
879 | |||
880 | if (hash) | ||
881 | { | ||
882 | hash_message (message, length, buffer, hash); | ||
883 | |||
884 | if (ego) | ||
885 | sign_message (message, length, buffer, hash, ego); | ||
886 | } | ||
887 | |||
888 | if (GNUNET_MESSENGER_PACK_MODE_ENVELOPE != mode) | ||
889 | GNUNET_free(buffer); | ||
890 | |||
891 | return env; | ||
892 | } | ||
893 | |||
894 | int | ||
895 | filter_message_sending (const struct GNUNET_MESSENGER_Message *message) | ||
896 | { | ||
897 | switch (message->header.kind) | ||
898 | { | ||
899 | case GNUNET_MESSENGER_KIND_INFO: | ||
900 | return GNUNET_SYSERR; // Reserved for connection handling only! | ||
901 | case GNUNET_MESSENGER_KIND_JOIN: | ||
902 | return GNUNET_NO; // Use #GNUNET_MESSENGER_enter_room(...) instead! | ||
903 | case GNUNET_MESSENGER_KIND_LEAVE: | ||
904 | return GNUNET_NO; // Use #GNUNET_MESSENGER_close_room(...) instead! | ||
905 | case GNUNET_MESSENGER_KIND_NAME: | ||
906 | return GNUNET_YES; | ||
907 | case GNUNET_MESSENGER_KIND_KEY: | ||
908 | return GNUNET_NO; // Use #GNUNET_MESSENGER_update(...) instead! | ||
909 | case GNUNET_MESSENGER_KIND_PEER: | ||
910 | return GNUNET_NO; // Use #GNUNET_MESSENGER_open_room(...) instead! | ||
911 | case GNUNET_MESSENGER_KIND_ID: | ||
912 | return GNUNET_SYSERR; // Reserved for member id handling only! | ||
913 | case GNUNET_MESSENGER_KIND_MISS: | ||
914 | return GNUNET_SYSERR; // Reserved for connection handling only! | ||
915 | case GNUNET_MESSENGER_KIND_MERGE: | ||
916 | return GNUNET_YES; | ||
917 | case GNUNET_MESSENGER_KIND_REQUEST: | ||
918 | return GNUNET_YES; | ||
919 | case GNUNET_MESSENGER_KIND_INVITE: | ||
920 | return GNUNET_YES; | ||
921 | case GNUNET_MESSENGER_KIND_TEXT: | ||
922 | return GNUNET_YES; | ||
923 | case GNUNET_MESSENGER_KIND_FILE: | ||
924 | return GNUNET_YES; | ||
925 | case GNUNET_MESSENGER_KIND_PRIVATE: | ||
926 | return GNUNET_NO; // Use #GNUNET_MESSENGER_send_message(...) with a contact instead! | ||
927 | case GNUNET_MESSENGER_KIND_DELETE: | ||
928 | return GNUNET_YES; | ||
929 | default: | ||
930 | return GNUNET_SYSERR; | ||
931 | } | ||
932 | } | ||
diff --git a/src/messenger/messenger_api_message.h b/src/messenger/messenger_api_message.h deleted file mode 100644 index 46c5cb024..000000000 --- a/src/messenger/messenger_api_message.h +++ /dev/null | |||
@@ -1,251 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api_message.h | ||
23 | * @brief messenger api: client and service implementation of GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_MESSENGER_API_MESSAGE_H | ||
27 | #define GNUNET_MESSENGER_API_MESSAGE_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_crypto_lib.h" | ||
31 | #include "gnunet_identity_service.h" | ||
32 | #include "gnunet_mq_lib.h" | ||
33 | #include "gnunet_signatures.h" | ||
34 | |||
35 | #include "gnunet_messenger_service.h" | ||
36 | |||
37 | #include "messenger_api_ego.h" | ||
38 | |||
39 | #define GNUNET_MESSENGER_MAX_MESSAGE_SIZE (GNUNET_MAX_MESSAGE_SIZE - GNUNET_MIN_MESSAGE_SIZE) | ||
40 | |||
41 | #define GNUNET_MESSENGER_PADDING_MIN (sizeof(uint16_t) + sizeof(char)) | ||
42 | #define GNUNET_MESSENGER_PADDING_LEVEL0 (512) | ||
43 | #define GNUNET_MESSENGER_PADDING_LEVEL1 (4096) | ||
44 | #define GNUNET_MESSENGER_PADDING_LEVEL2 (32768) | ||
45 | |||
46 | /** | ||
47 | * Creates and allocates a new message with a specific <i>kind</i>. | ||
48 | * | ||
49 | * @param[in] kind Kind of message | ||
50 | * @return New message | ||
51 | */ | ||
52 | struct GNUNET_MESSENGER_Message* | ||
53 | create_message (enum GNUNET_MESSENGER_MessageKind kind); | ||
54 | |||
55 | /** | ||
56 | * Creates and allocates a copy of a given <i>message</i>. | ||
57 | * | ||
58 | * @param[in] message Message | ||
59 | * @return New message | ||
60 | */ | ||
61 | struct GNUNET_MESSENGER_Message* | ||
62 | copy_message (const struct GNUNET_MESSENGER_Message *message); | ||
63 | |||
64 | /** | ||
65 | * Frees the messages body memory. | ||
66 | * | ||
67 | * @param[in/out] message Message | ||
68 | */ | ||
69 | void | ||
70 | cleanup_message (struct GNUNET_MESSENGER_Message *message); | ||
71 | |||
72 | /** | ||
73 | * Destroys a message and frees its memory fully. | ||
74 | * | ||
75 | * @param[in/out] message Message | ||
76 | */ | ||
77 | void | ||
78 | destroy_message (struct GNUNET_MESSENGER_Message *message); | ||
79 | |||
80 | /** | ||
81 | * Returns if the message should be bound to a member session. | ||
82 | * | ||
83 | * @param[in] message Message | ||
84 | * @return #GNUNET_YES or #GNUNET_NO | ||
85 | */ | ||
86 | int | ||
87 | is_message_session_bound (const struct GNUNET_MESSENGER_Message *message); | ||
88 | |||
89 | /** | ||
90 | * Returns the minimal size in bytes to encode a message of a specific <i>kind</i>. | ||
91 | * | ||
92 | * @param[in] kind Kind of message | ||
93 | * @param[in] include_header Flag to include header | ||
94 | * @return Minimal size to encode | ||
95 | */ | ||
96 | uint16_t | ||
97 | get_message_kind_size (enum GNUNET_MESSENGER_MessageKind kind, | ||
98 | int include_header); | ||
99 | |||
100 | /** | ||
101 | * Returns the exact size in bytes to encode a given <i>message</i>. | ||
102 | * | ||
103 | * @param[in] message Message | ||
104 | * @param[in] include_header Flag to include header | ||
105 | * @return Size to encode | ||
106 | */ | ||
107 | uint16_t | ||
108 | get_message_size (const struct GNUNET_MESSENGER_Message *message, | ||
109 | int include_header); | ||
110 | |||
111 | /** | ||
112 | * Encodes a given <i>message</i> into a <i>buffer</i> of a maximal <i>length</i> in bytes. | ||
113 | * | ||
114 | * @param[in] message Message | ||
115 | * @param[in] length Maximal length to encode | ||
116 | * @param[out] buffer Buffer | ||
117 | * @param[in] include_header Flag to include header | ||
118 | */ | ||
119 | void | ||
120 | encode_message (const struct GNUNET_MESSENGER_Message *message, | ||
121 | uint16_t length, | ||
122 | char *buffer, | ||
123 | int include_header); | ||
124 | |||
125 | /** | ||
126 | * Decodes a <i>message</i> from a given <i>buffer</i> of a maximal <i>length</i> in bytes. | ||
127 | * | ||
128 | * If the buffer is too small for a message of its decoded kind the function fails with | ||
129 | * resulting #GNUNET_NO after decoding only the messages header. | ||
130 | * | ||
131 | * On success the function returns #GNUNET_YES. | ||
132 | * | ||
133 | * @param[out] message Message | ||
134 | * @param[in] length Maximal length to decode | ||
135 | * @param[in] buffer Buffer | ||
136 | * @param[in] include_header Flag to include header | ||
137 | * @param[out] padding Padding | ||
138 | * @return #GNUNET_YES on success, otherwise #GNUNET_NO | ||
139 | */ | ||
140 | int | ||
141 | decode_message (struct GNUNET_MESSENGER_Message *message, | ||
142 | uint16_t length, | ||
143 | const char *buffer, | ||
144 | int include_header, | ||
145 | uint16_t *padding); | ||
146 | |||
147 | /** | ||
148 | * Calculates a <i>hash</i> of a given <i>buffer</i> with a <i>length</i> in bytes | ||
149 | * from a <i>message</i>. | ||
150 | * | ||
151 | * @param[in] message Message | ||
152 | * @param[in] length Length of buffer | ||
153 | * @param[in] buffer Buffer | ||
154 | * @param[out] hash Hash | ||
155 | */ | ||
156 | void | ||
157 | hash_message (const struct GNUNET_MESSENGER_Message *message, | ||
158 | uint16_t length, | ||
159 | const char *buffer, | ||
160 | struct GNUNET_HashCode *hash); | ||
161 | |||
162 | /** | ||
163 | * Signs the <i>hash</i> of a <i>message</i> with a given <i>ego</i> and writes the signature | ||
164 | * into the <i>buffer</i> as well. | ||
165 | * | ||
166 | * @param[in/out] message Message | ||
167 | * @param[in] length Length of buffer | ||
168 | * @param[out] buffer Buffer | ||
169 | * @param[in] hash Hash of message | ||
170 | * @param[in] ego EGO | ||
171 | */ | ||
172 | void | ||
173 | sign_message (struct GNUNET_MESSENGER_Message *message, | ||
174 | uint16_t length, | ||
175 | char *buffer, | ||
176 | const struct GNUNET_HashCode *hash, | ||
177 | const struct GNUNET_MESSENGER_Ego *ego); | ||
178 | |||
179 | /** | ||
180 | * Verifies the signature of a given <i>message</i> and its <i>hash</i> with a specific | ||
181 | * public key. The function returns #GNUNET_OK if the signature was valid, otherwise | ||
182 | * #GNUNET_SYSERR. | ||
183 | * | ||
184 | * @param[in] message Message | ||
185 | * @param[in] hash Hash of message | ||
186 | * @param[in] key Public key of EGO | ||
187 | * @return #GNUNET_OK on success, otherwise #GNUNET_SYSERR | ||
188 | */ | ||
189 | int | ||
190 | verify_message (const struct GNUNET_MESSENGER_Message *message, | ||
191 | const struct GNUNET_HashCode *hash, | ||
192 | const struct GNUNET_IDENTITY_PublicKey *key); | ||
193 | |||
194 | /** | ||
195 | * Encrypts a <i>message</i> using a given public <i>key</i> and replaces its body | ||
196 | * and kind with the now private encrypted <i>message</i>. The function returns | ||
197 | * #GNUNET_YES if the operation succeeded, otherwise #GNUNET_NO. | ||
198 | * | ||
199 | * @param[in/out] message Message | ||
200 | * @param[in] key Public key of EGO | ||
201 | * @return #GNUNET_YES on success, otherwise #GNUNET_NO | ||
202 | */ | ||
203 | int | ||
204 | encrypt_message (struct GNUNET_MESSENGER_Message *message, | ||
205 | const struct GNUNET_IDENTITY_PublicKey *key); | ||
206 | |||
207 | /** | ||
208 | * Decrypts a private <i>message</i> using a given private <i>key</i> and replaces its body | ||
209 | * and kind with the inner encrypted message. The function returns #GNUNET_YES if the | ||
210 | * operation succeeded, otherwise #GNUNET_NO. | ||
211 | * | ||
212 | * @param[in/out] message Message | ||
213 | * @param[in] key Private key of EGO | ||
214 | * @return #GNUNET_YES on success, otherwise #GNUNET_NO | ||
215 | */ | ||
216 | int | ||
217 | decrypt_message (struct GNUNET_MESSENGER_Message *message, | ||
218 | const struct GNUNET_IDENTITY_PrivateKey *key); | ||
219 | |||
220 | #define GNUNET_MESSENGER_PACK_MODE_ENVELOPE 0x1 | ||
221 | #define GNUNET_MESSENGER_PACK_MODE_UNKNOWN 0x0 | ||
222 | |||
223 | /** | ||
224 | * Encodes the <i>message</i> to pack it into a newly allocated envelope if <i>mode</i> | ||
225 | * is equal to #GNUNET_MESSENGER_PACK_MODE_ENVELOPE. Independent of the mode the message | ||
226 | * will be hashed if <i>hash</i> is not NULL and it will be signed if the <i>ego</i> is | ||
227 | * not NULL. | ||
228 | * | ||
229 | * @param[out] message Message | ||
230 | * @param[out] hash Hash of message | ||
231 | * @param[in] ego EGO to sign | ||
232 | * @param[in] mode Mode of packing | ||
233 | * @return Envelope or NULL | ||
234 | */ | ||
235 | struct GNUNET_MQ_Envelope* | ||
236 | pack_message (struct GNUNET_MESSENGER_Message *message, | ||
237 | struct GNUNET_HashCode *hash, | ||
238 | const struct GNUNET_MESSENGER_Ego *ego, | ||
239 | int mode); | ||
240 | |||
241 | /** | ||
242 | * Returns if a specific kind of message should be sent by a client. The function returns | ||
243 | * #GNUNET_YES or #GNUNET_NO for recommendations and #GNUNET_SYSERR for specific kinds | ||
244 | * of messages which should not be sent manually at all. | ||
245 | * | ||
246 | * @param[in] message Message | ||
247 | */ | ||
248 | int | ||
249 | filter_message_sending (const struct GNUNET_MESSENGER_Message *message); | ||
250 | |||
251 | #endif //GNUNET_MESSENGER_API_MESSAGE_H | ||
diff --git a/src/messenger/messenger_api_room.c b/src/messenger/messenger_api_room.c deleted file mode 100644 index 6e2d33f48..000000000 --- a/src/messenger/messenger_api_room.c +++ /dev/null | |||
@@ -1,368 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api_room.c | ||
23 | * @brief messenger api: client implementation of GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "messenger_api_room.h" | ||
27 | |||
28 | #include "messenger_api_handle.h" | ||
29 | |||
30 | struct GNUNET_MESSENGER_Room* | ||
31 | create_room (struct GNUNET_MESSENGER_Handle *handle, | ||
32 | const struct GNUNET_HashCode *key) | ||
33 | { | ||
34 | GNUNET_assert((handle) && (key)); | ||
35 | |||
36 | struct GNUNET_MESSENGER_Room *room = GNUNET_new(struct GNUNET_MESSENGER_Room); | ||
37 | |||
38 | room->handle = handle; | ||
39 | GNUNET_memcpy(&(room->key), key, sizeof(*key)); | ||
40 | |||
41 | room->opened = GNUNET_NO; | ||
42 | room->contact_id = NULL; | ||
43 | |||
44 | init_list_tunnels (&(room->entries)); | ||
45 | |||
46 | room->messages = GNUNET_CONTAINER_multihashmap_create (8, GNUNET_NO); | ||
47 | room->members = GNUNET_CONTAINER_multishortmap_create (8, GNUNET_NO); | ||
48 | |||
49 | return room; | ||
50 | } | ||
51 | |||
52 | static int | ||
53 | iterate_destroy_message (void *cls, | ||
54 | const struct GNUNET_HashCode *key, | ||
55 | void *value) | ||
56 | { | ||
57 | struct GNUNET_MESSENGER_RoomMessageEntry *entry = value; | ||
58 | |||
59 | destroy_message (entry->message); | ||
60 | GNUNET_free(entry); | ||
61 | |||
62 | return GNUNET_YES; | ||
63 | } | ||
64 | |||
65 | void | ||
66 | destroy_room (struct GNUNET_MESSENGER_Room *room) | ||
67 | { | ||
68 | GNUNET_assert(room); | ||
69 | |||
70 | clear_list_tunnels (&(room->entries)); | ||
71 | |||
72 | if (room->messages) | ||
73 | { | ||
74 | GNUNET_CONTAINER_multihashmap_iterate (room->messages, iterate_destroy_message, NULL); | ||
75 | |||
76 | GNUNET_CONTAINER_multihashmap_destroy (room->messages); | ||
77 | } | ||
78 | |||
79 | if (room->members) | ||
80 | GNUNET_CONTAINER_multishortmap_destroy (room->members); | ||
81 | |||
82 | if (room->contact_id) | ||
83 | GNUNET_free(room->contact_id); | ||
84 | |||
85 | GNUNET_free(room); | ||
86 | } | ||
87 | |||
88 | const struct GNUNET_MESSENGER_Message* | ||
89 | get_room_message (const struct GNUNET_MESSENGER_Room *room, | ||
90 | const struct GNUNET_HashCode *hash) | ||
91 | { | ||
92 | GNUNET_assert((room) && (hash)); | ||
93 | |||
94 | struct GNUNET_MESSENGER_RoomMessageEntry *entry = GNUNET_CONTAINER_multihashmap_get ( | ||
95 | room->messages, hash | ||
96 | ); | ||
97 | |||
98 | return (entry? entry->message : NULL); | ||
99 | } | ||
100 | |||
101 | struct GNUNET_MESSENGER_Contact* | ||
102 | get_room_sender (const struct GNUNET_MESSENGER_Room *room, | ||
103 | const struct GNUNET_HashCode *hash) | ||
104 | { | ||
105 | GNUNET_assert((room) && (hash)); | ||
106 | |||
107 | struct GNUNET_MESSENGER_RoomMessageEntry *entry = GNUNET_CONTAINER_multihashmap_get ( | ||
108 | room->messages, hash | ||
109 | ); | ||
110 | |||
111 | return (entry? entry->sender : NULL); | ||
112 | } | ||
113 | |||
114 | static struct GNUNET_MESSENGER_Contact* | ||
115 | handle_join_message (struct GNUNET_MESSENGER_Room *room, | ||
116 | struct GNUNET_MESSENGER_Contact *sender, | ||
117 | const struct GNUNET_MESSENGER_Message *message, | ||
118 | const struct GNUNET_HashCode *hash) | ||
119 | { | ||
120 | if (!sender) | ||
121 | { | ||
122 | struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store(room->handle); | ||
123 | struct GNUNET_HashCode context; | ||
124 | |||
125 | get_context_from_member(&(room->key), &(message->header.sender_id), &context); | ||
126 | |||
127 | sender = get_store_contact(store, &context, &(message->body.join.key)); | ||
128 | } | ||
129 | |||
130 | if ((GNUNET_YES != GNUNET_CONTAINER_multishortmap_contains_value(room->members, &(message->header.sender_id), sender)) && | ||
131 | (GNUNET_OK == GNUNET_CONTAINER_multishortmap_put(room->members, &(message->header.sender_id), sender, | ||
132 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE))) | ||
133 | increase_contact_rc(sender); | ||
134 | |||
135 | return sender; | ||
136 | } | ||
137 | |||
138 | static void | ||
139 | handle_leave_message (struct GNUNET_MESSENGER_Room *room, | ||
140 | struct GNUNET_MESSENGER_Contact *sender, | ||
141 | const struct GNUNET_MESSENGER_Message *message, | ||
142 | const struct GNUNET_HashCode *hash) | ||
143 | { | ||
144 | if ((!sender) || | ||
145 | (GNUNET_YES != GNUNET_CONTAINER_multishortmap_remove(room->members, &(message->header.sender_id), sender))) | ||
146 | return; | ||
147 | |||
148 | struct GNUNET_HashCode context; | ||
149 | get_context_from_member(&(room->key), &(message->header.sender_id), &context); | ||
150 | |||
151 | if (GNUNET_YES == decrease_contact_rc(sender)) | ||
152 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "A contact does not share any room with you anymore!\n"); | ||
153 | } | ||
154 | |||
155 | static void | ||
156 | handle_name_message (struct GNUNET_MESSENGER_Room *room, | ||
157 | struct GNUNET_MESSENGER_Contact *sender, | ||
158 | const struct GNUNET_MESSENGER_Message *message, | ||
159 | const struct GNUNET_HashCode *hash) | ||
160 | { | ||
161 | if (!sender) | ||
162 | return; | ||
163 | |||
164 | set_contact_name (sender, message->body.name.name); | ||
165 | } | ||
166 | |||
167 | static void | ||
168 | handle_key_message (struct GNUNET_MESSENGER_Room *room, | ||
169 | struct GNUNET_MESSENGER_Contact *sender, | ||
170 | const struct GNUNET_MESSENGER_Message *message, | ||
171 | const struct GNUNET_HashCode *hash) | ||
172 | { | ||
173 | if (!sender) | ||
174 | return; | ||
175 | |||
176 | struct GNUNET_HashCode context; | ||
177 | get_context_from_member(&(room->key), &(message->header.sender_id), &context); | ||
178 | |||
179 | struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store(room->handle); | ||
180 | |||
181 | update_store_contact(store, sender, &context, &context, &(message->body.key.key)); | ||
182 | } | ||
183 | |||
184 | static void | ||
185 | handle_id_message (struct GNUNET_MESSENGER_Room *room, | ||
186 | struct GNUNET_MESSENGER_Contact *sender, | ||
187 | const struct GNUNET_MESSENGER_Message *message, | ||
188 | const struct GNUNET_HashCode *hash) | ||
189 | { | ||
190 | if ((!sender) || | ||
191 | (GNUNET_YES != GNUNET_CONTAINER_multishortmap_remove(room->members, &(message->header.sender_id), sender)) || | ||
192 | (GNUNET_OK != GNUNET_CONTAINER_multishortmap_put(room->members, &(message->body.id.id), sender, | ||
193 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE))) | ||
194 | return; | ||
195 | |||
196 | struct GNUNET_HashCode context, next_context; | ||
197 | get_context_from_member(&(room->key), &(message->header.sender_id), &context); | ||
198 | get_context_from_member(&(room->key), &(message->body.id.id), &next_context); | ||
199 | |||
200 | struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store(room->handle); | ||
201 | |||
202 | update_store_contact(store, sender, &context, &next_context, get_contact_key(sender)); | ||
203 | } | ||
204 | |||
205 | static void | ||
206 | handle_miss_message (struct GNUNET_MESSENGER_Room *room, | ||
207 | struct GNUNET_MESSENGER_Contact *sender, | ||
208 | const struct GNUNET_MESSENGER_Message *message, | ||
209 | const struct GNUNET_HashCode *hash) | ||
210 | { | ||
211 | if ((room->contact_id) && (0 == GNUNET_memcmp(&(message->header.sender_id), room->contact_id))) | ||
212 | { | ||
213 | struct GNUNET_MESSENGER_ListTunnel *match = find_list_tunnels (&(room->entries), &(message->body.miss.peer), NULL); | ||
214 | |||
215 | if (match) | ||
216 | remove_from_list_tunnels (&(room->entries), match); | ||
217 | } | ||
218 | } | ||
219 | |||
220 | static void | ||
221 | handle_delete_message (struct GNUNET_MESSENGER_Room *room, | ||
222 | struct GNUNET_MESSENGER_Contact *sender, | ||
223 | const struct GNUNET_MESSENGER_Message *message, | ||
224 | const struct GNUNET_HashCode *hash) | ||
225 | { | ||
226 | struct GNUNET_MESSENGER_RoomMessageEntry *entry = GNUNET_CONTAINER_multihashmap_get ( | ||
227 | room->messages, &(message->body.deletion.hash) | ||
228 | ); | ||
229 | |||
230 | if ((entry) && ((entry->sender == sender) || (get_handle_contact (room->handle, &(room->key)) == sender)) && | ||
231 | (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (room->messages, &(message->body.deletion.hash), entry))) | ||
232 | { | ||
233 | destroy_message (entry->message); | ||
234 | GNUNET_free(entry); | ||
235 | } | ||
236 | } | ||
237 | |||
238 | struct GNUNET_MESSENGER_Contact* | ||
239 | handle_room_message (struct GNUNET_MESSENGER_Room *room, | ||
240 | struct GNUNET_MESSENGER_Contact *sender, | ||
241 | const struct GNUNET_MESSENGER_Message *message, | ||
242 | const struct GNUNET_HashCode *hash) | ||
243 | { | ||
244 | if (GNUNET_NO != GNUNET_CONTAINER_multihashmap_contains (room->messages, hash)) | ||
245 | return sender; | ||
246 | |||
247 | switch (message->header.kind) | ||
248 | { | ||
249 | case GNUNET_MESSENGER_KIND_JOIN: | ||
250 | sender = handle_join_message (room, sender, message, hash); | ||
251 | break; | ||
252 | case GNUNET_MESSENGER_KIND_LEAVE: | ||
253 | handle_leave_message (room, sender, message, hash); | ||
254 | break; | ||
255 | case GNUNET_MESSENGER_KIND_NAME: | ||
256 | handle_name_message (room, sender, message, hash); | ||
257 | break; | ||
258 | case GNUNET_MESSENGER_KIND_KEY: | ||
259 | handle_key_message (room, sender, message, hash); | ||
260 | break; | ||
261 | case GNUNET_MESSENGER_KIND_ID: | ||
262 | handle_id_message (room, sender, message, hash); | ||
263 | break; | ||
264 | case GNUNET_MESSENGER_KIND_MISS: | ||
265 | handle_miss_message (room, sender, message, hash); | ||
266 | break; | ||
267 | case GNUNET_MESSENGER_KIND_DELETE: | ||
268 | handle_delete_message (room, sender, message, hash); | ||
269 | break; | ||
270 | default: | ||
271 | break; | ||
272 | } | ||
273 | |||
274 | struct GNUNET_MESSENGER_RoomMessageEntry *entry = GNUNET_new(struct GNUNET_MESSENGER_RoomMessageEntry); | ||
275 | |||
276 | if (!entry) | ||
277 | return sender; | ||
278 | |||
279 | entry->sender = sender; | ||
280 | entry->message = copy_message (message); | ||
281 | |||
282 | if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put (room->messages, hash, entry, | ||
283 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) | ||
284 | { | ||
285 | destroy_message (entry->message); | ||
286 | GNUNET_free(entry); | ||
287 | } | ||
288 | |||
289 | return sender; | ||
290 | } | ||
291 | |||
292 | struct GNUNET_MESSENGER_MemberCall | ||
293 | { | ||
294 | struct GNUNET_MESSENGER_Room *room; | ||
295 | GNUNET_MESSENGER_MemberCallback callback; | ||
296 | void *cls; | ||
297 | }; | ||
298 | |||
299 | static int | ||
300 | iterate_local_members (void* cls, | ||
301 | const struct GNUNET_ShortHashCode *key, | ||
302 | void *value) | ||
303 | { | ||
304 | struct GNUNET_MESSENGER_MemberCall *call = cls; | ||
305 | struct GNUNET_MESSENGER_Contact *contact = value; | ||
306 | |||
307 | return call->callback(call->cls, call->room, contact); | ||
308 | } | ||
309 | |||
310 | int | ||
311 | iterate_room_members (struct GNUNET_MESSENGER_Room *room, | ||
312 | GNUNET_MESSENGER_MemberCallback callback, | ||
313 | void* cls) | ||
314 | { | ||
315 | GNUNET_assert(room); | ||
316 | |||
317 | if (!callback) | ||
318 | return GNUNET_CONTAINER_multishortmap_iterate(room->members, NULL, NULL); | ||
319 | |||
320 | struct GNUNET_MESSENGER_MemberCall call; | ||
321 | |||
322 | call.room = room; | ||
323 | call.callback = callback; | ||
324 | call.cls = cls; | ||
325 | |||
326 | GNUNET_assert(callback); | ||
327 | |||
328 | return GNUNET_CONTAINER_multishortmap_iterate(room->members, iterate_local_members, &call); | ||
329 | } | ||
330 | |||
331 | struct GNUNET_MESSENGER_MemberFind | ||
332 | { | ||
333 | const struct GNUNET_MESSENGER_Contact *contact; | ||
334 | int result; | ||
335 | }; | ||
336 | |||
337 | static int | ||
338 | iterate_find_member (void* cls, | ||
339 | const struct GNUNET_ShortHashCode *key, | ||
340 | void *value) | ||
341 | { | ||
342 | struct GNUNET_MESSENGER_MemberFind *find = cls; | ||
343 | struct GNUNET_MESSENGER_Contact *contact = value; | ||
344 | |||
345 | if (contact == find->contact) | ||
346 | { | ||
347 | find->result = GNUNET_YES; | ||
348 | return GNUNET_NO; | ||
349 | } | ||
350 | |||
351 | return GNUNET_YES; | ||
352 | } | ||
353 | |||
354 | int | ||
355 | find_room_member (const struct GNUNET_MESSENGER_Room *room, | ||
356 | const struct GNUNET_MESSENGER_Contact *contact) | ||
357 | { | ||
358 | GNUNET_assert(room); | ||
359 | |||
360 | struct GNUNET_MESSENGER_MemberFind find; | ||
361 | |||
362 | find.contact = contact; | ||
363 | find.result = GNUNET_NO; | ||
364 | |||
365 | GNUNET_CONTAINER_multishortmap_iterate(room->members, iterate_find_member, &find); | ||
366 | |||
367 | return find.result; | ||
368 | } | ||
diff --git a/src/messenger/messenger_api_room.h b/src/messenger/messenger_api_room.h deleted file mode 100644 index 320312f0c..000000000 --- a/src/messenger/messenger_api_room.h +++ /dev/null | |||
@@ -1,147 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api_room.h | ||
23 | * @brief messenger api: client implementation of GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_MESSENGER_API_ROOM_H | ||
27 | #define GNUNET_MESSENGER_API_ROOM_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_container_lib.h" | ||
31 | #include "gnunet_crypto_lib.h" | ||
32 | |||
33 | #include "gnunet_messenger_service.h" | ||
34 | |||
35 | #include "messenger_api_list_tunnels.h" | ||
36 | #include "messenger_api_contact.h" | ||
37 | #include "messenger_api_message.h" | ||
38 | |||
39 | struct GNUNET_MESSENGER_RoomMessageEntry { | ||
40 | struct GNUNET_MESSENGER_Contact* sender; | ||
41 | struct GNUNET_MESSENGER_Message* message; | ||
42 | }; | ||
43 | |||
44 | struct GNUNET_MESSENGER_Room | ||
45 | { | ||
46 | struct GNUNET_MESSENGER_Handle *handle; | ||
47 | struct GNUNET_HashCode key; | ||
48 | |||
49 | int opened; | ||
50 | |||
51 | struct GNUNET_ShortHashCode *contact_id; | ||
52 | |||
53 | struct GNUNET_MESSENGER_ListTunnels entries; | ||
54 | |||
55 | struct GNUNET_CONTAINER_MultiHashMap *messages; | ||
56 | struct GNUNET_CONTAINER_MultiShortmap *members; | ||
57 | }; | ||
58 | |||
59 | /** | ||
60 | * Creates and allocates a new room for a <i>handle</i> with a given <i>key</i> for the client API. | ||
61 | * | ||
62 | * @param[in/out] handle Handle | ||
63 | * @param[in] key Key of room | ||
64 | * @return New room | ||
65 | */ | ||
66 | struct GNUNET_MESSENGER_Room* | ||
67 | create_room (struct GNUNET_MESSENGER_Handle *handle, | ||
68 | const struct GNUNET_HashCode *key); | ||
69 | |||
70 | /** | ||
71 | * Destroys a room and frees its memory fully from the client API. | ||
72 | * | ||
73 | * @param[in/out] room Room | ||
74 | */ | ||
75 | void | ||
76 | destroy_room (struct GNUNET_MESSENGER_Room *room); | ||
77 | |||
78 | /** | ||
79 | * Returns a message locally stored from a map for a given <i>hash</i> in a <i>room</i>. If no matching | ||
80 | * message is found, NULL gets returned. | ||
81 | * | ||
82 | * @param[in] room Room | ||
83 | * @param[in] hash Hash of message | ||
84 | * @return Message or NULL | ||
85 | */ | ||
86 | const struct GNUNET_MESSENGER_Message* | ||
87 | get_room_message (const struct GNUNET_MESSENGER_Room *room, | ||
88 | const struct GNUNET_HashCode *hash); | ||
89 | |||
90 | /** | ||
91 | * Returns a messages sender locally stored from a map for a given <i>hash</i> in a <i>room</i>. If no | ||
92 | * matching message is found, NULL gets returned. | ||
93 | * | ||
94 | * @param[in] room Room | ||
95 | * @param[in] hash Hash of message | ||
96 | * @return Contact of sender or NULL | ||
97 | */ | ||
98 | struct GNUNET_MESSENGER_Contact* | ||
99 | get_room_sender (const struct GNUNET_MESSENGER_Room *room, | ||
100 | const struct GNUNET_HashCode *hash); | ||
101 | |||
102 | /** | ||
103 | * Handles a <i>message</i> with a given <i>hash</i> in a <i>room</i> for the client API to update | ||
104 | * members and its information. The function also stores the message in map locally for access afterwards. | ||
105 | * | ||
106 | * The contact of the message's sender could be updated or even created. It may not be freed or destroyed though! | ||
107 | * (The contact may still be in use for old messages...) | ||
108 | * | ||
109 | * @param[in/out] room Room | ||
110 | * @param[in/out] sender Contact of sender | ||
111 | * @param[in] message Message | ||
112 | * @param[in] hash Hash of message | ||
113 | * @return Contact of sender | ||
114 | */ | ||
115 | struct GNUNET_MESSENGER_Contact* | ||
116 | handle_room_message (struct GNUNET_MESSENGER_Room *room, | ||
117 | struct GNUNET_MESSENGER_Contact *sender, | ||
118 | const struct GNUNET_MESSENGER_Message *message, | ||
119 | const struct GNUNET_HashCode *hash); | ||
120 | |||
121 | /** | ||
122 | * Iterates through all members of a given <i>room</i> to forward each of them to a selected | ||
123 | * <i>callback</i> with a custom closure. | ||
124 | * | ||
125 | * @param[in/out] room Room | ||
126 | * @param[in] callback Function called for each member | ||
127 | * @param[in/out] cls Closure | ||
128 | * @return Amount of members iterated | ||
129 | */ | ||
130 | int | ||
131 | iterate_room_members (struct GNUNET_MESSENGER_Room *room, | ||
132 | GNUNET_MESSENGER_MemberCallback callback, | ||
133 | void* cls); | ||
134 | |||
135 | /** | ||
136 | * Checks through all members of a given <i>room</i> if a specific <i>contact</i> is found and | ||
137 | * returns a result depending on that. | ||
138 | * | ||
139 | * @param[in] room Room | ||
140 | * @param[in] contact | ||
141 | * @return #GNUNET_YES if found, otherwise #GNUNET_NO | ||
142 | */ | ||
143 | int | ||
144 | find_room_member (const struct GNUNET_MESSENGER_Room *room, | ||
145 | const struct GNUNET_MESSENGER_Contact *contact); | ||
146 | |||
147 | #endif //GNUNET_MESSENGER_API_ROOM_H | ||
diff --git a/src/messenger/messenger_api_util.c b/src/messenger/messenger_api_util.c deleted file mode 100644 index 52b4e934a..000000000 --- a/src/messenger/messenger_api_util.c +++ /dev/null | |||
@@ -1,102 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api_util.c | ||
23 | * @brief messenger api: client implementation of GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #include "messenger_api_util.h" | ||
27 | |||
28 | static void | ||
29 | callback_close_channel (void *cls) | ||
30 | { | ||
31 | struct GNUNET_CADET_Channel *channel = cls; | ||
32 | |||
33 | if (channel) | ||
34 | GNUNET_CADET_channel_destroy (channel); | ||
35 | } | ||
36 | |||
37 | void | ||
38 | delayed_disconnect_channel (struct GNUNET_CADET_Channel *channel) | ||
39 | { | ||
40 | GNUNET_assert(channel); | ||
41 | |||
42 | GNUNET_SCHEDULER_add_delayed_with_priority (GNUNET_TIME_relative_get_zero_ (), | ||
43 | GNUNET_SCHEDULER_PRIORITY_URGENT, | ||
44 | callback_close_channel, channel); | ||
45 | } | ||
46 | |||
47 | int | ||
48 | generate_free_member_id (struct GNUNET_ShortHashCode *id, | ||
49 | const struct GNUNET_CONTAINER_MultiShortmap *members) | ||
50 | { | ||
51 | GNUNET_assert(id); | ||
52 | |||
53 | size_t counter = 1 + (members ? GNUNET_CONTAINER_multishortmap_size (members) : 0); | ||
54 | |||
55 | do | ||
56 | { | ||
57 | GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_STRONG, id, sizeof(struct GNUNET_ShortHashCode)); | ||
58 | |||
59 | if ((members) && (GNUNET_YES == GNUNET_CONTAINER_multishortmap_contains (members, id))) | ||
60 | counter--; | ||
61 | else | ||
62 | break; | ||
63 | } | ||
64 | while (counter > 0); | ||
65 | |||
66 | if (counter) | ||
67 | return GNUNET_YES; | ||
68 | |||
69 | return GNUNET_NO; | ||
70 | } | ||
71 | |||
72 | const struct GNUNET_IDENTITY_PublicKey* | ||
73 | get_anonymous_public_key () | ||
74 | { | ||
75 | static struct GNUNET_IDENTITY_PublicKey public_key; | ||
76 | static struct GNUNET_IDENTITY_Ego* ego = NULL; | ||
77 | |||
78 | if (!ego) | ||
79 | { | ||
80 | ego = GNUNET_IDENTITY_ego_get_anonymous(); | ||
81 | GNUNET_IDENTITY_ego_get_public_key(ego, &public_key); | ||
82 | } | ||
83 | |||
84 | return &public_key; | ||
85 | } | ||
86 | |||
87 | void | ||
88 | convert_messenger_key_to_port(const struct GNUNET_HashCode *key, | ||
89 | struct GNUNET_HashCode *port) | ||
90 | { | ||
91 | static uint32_t version_value = 0; | ||
92 | static struct GNUNET_HashCode version; | ||
93 | |||
94 | if (!version_value) { | ||
95 | version_value = (uint32_t) (GNUNET_MESSENGER_VERSION); | ||
96 | version_value = ((version_value >> 16) & 0xFFFF); | ||
97 | version_value = GNUNET_htole32(version_value); | ||
98 | GNUNET_CRYPTO_hash(&version_value, sizeof(version_value), &version); | ||
99 | } | ||
100 | |||
101 | GNUNET_CRYPTO_hash_sum(key, &version, port); | ||
102 | } | ||
diff --git a/src/messenger/messenger_api_util.h b/src/messenger/messenger_api_util.h deleted file mode 100644 index af64790b6..000000000 --- a/src/messenger/messenger_api_util.h +++ /dev/null | |||
@@ -1,80 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/messenger_api_util.h | ||
23 | * @brief messenger api: client implementation of GNUnet MESSENGER service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_SERVICE_MESSENGER_UTIL_H | ||
27 | #define GNUNET_SERVICE_MESSENGER_UTIL_H | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_cadet_service.h" | ||
31 | #include "gnunet_container_lib.h" | ||
32 | #include "gnunet_crypto_lib.h" | ||
33 | #include "gnunet_disk_lib.h" | ||
34 | #include "gnunet_identity_service.h" | ||
35 | #include "gnunet_messenger_service.h" | ||
36 | |||
37 | /** | ||
38 | * Starts an urgent task to close a CADET channel asynchronously. | ||
39 | * | ||
40 | * @param[in/out] channel Channel | ||
41 | */ | ||
42 | void | ||
43 | delayed_disconnect_channel (struct GNUNET_CADET_Channel *channel); | ||
44 | |||
45 | /** | ||
46 | * Tries to generate an unused member id and store it into the <i>id</i> parameter. | ||
47 | * A map containing all currently used member ids is used to check against. | ||
48 | * | ||
49 | * @param[out] id New member id | ||
50 | * @param[in] members Map of member ids | ||
51 | * @return #GNUNET_YES on success, #GNUNET_NO on failure | ||
52 | */ | ||
53 | int | ||
54 | generate_free_member_id (struct GNUNET_ShortHashCode *id, | ||
55 | const struct GNUNET_CONTAINER_MultiShortmap *members); | ||
56 | |||
57 | /** | ||
58 | * Returns the public identity key of #GNUNET_IDENTITY_ego_get_anonymous() without | ||
59 | * recalculating it every time. | ||
60 | * | ||
61 | * @return anonymous public key | ||
62 | */ | ||
63 | const struct GNUNET_IDENTITY_PublicKey* | ||
64 | get_anonymous_public_key (); | ||
65 | |||
66 | /** | ||
67 | * Converts a Messenger service key of a room to the specific port which | ||
68 | * gets used for the CADET channels. | ||
69 | * | ||
70 | * The port includes upper bits of the #GNUNET_MESSENGER_VERSION to | ||
71 | * reduce the chance of incompatible connections. | ||
72 | * | ||
73 | * @param[in] key Messenger service room key | ||
74 | * @param[out] port CADET service port | ||
75 | */ | ||
76 | void | ||
77 | convert_messenger_key_to_port(const struct GNUNET_HashCode *key, | ||
78 | struct GNUNET_HashCode *port); | ||
79 | |||
80 | #endif //GNUNET_SERVICE_MESSENGER_UTIL_H | ||
diff --git a/src/messenger/plugin_gnsrecord_messenger.c b/src/messenger/plugin_gnsrecord_messenger.c deleted file mode 100644 index 2219f0bde..000000000 --- a/src/messenger/plugin_gnsrecord_messenger.c +++ /dev/null | |||
@@ -1,243 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @author Tobias Frisch | ||
22 | * @file src/messenger/plugin_gnsrecord_messenger.c | ||
23 | * @brief Plugin to provide the API for useful GNS records to improve | ||
24 | * the usability of the messenger service. | ||
25 | */ | ||
26 | |||
27 | #include "platform.h" | ||
28 | #include "gnunet_util_lib.h" | ||
29 | #include "gnunet_gnsrecord_lib.h" | ||
30 | #include "gnunet_messenger_service.h" | ||
31 | #include "gnunet_gnsrecord_plugin.h" | ||
32 | |||
33 | |||
34 | /** | ||
35 | * Convert the 'value' of a record to a string. | ||
36 | * | ||
37 | * @param cls closure, unused | ||
38 | * @param type type of the record | ||
39 | * @param data value in binary encoding | ||
40 | * @param data_size number of bytes in @a data | ||
41 | * @return NULL on error, otherwise human-readable representation of the value | ||
42 | */ | ||
43 | static char * | ||
44 | messenger_value_to_string (void *cls, | ||
45 | uint32_t type, | ||
46 | const void *data, | ||
47 | size_t data_size) | ||
48 | { | ||
49 | (void) cls; | ||
50 | switch (type) | ||
51 | { | ||
52 | case GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_ENTRY: | ||
53 | { | ||
54 | if (data_size != sizeof(struct GNUNET_MESSENGER_RoomEntryRecord)) | ||
55 | { | ||
56 | GNUNET_break_op (0); | ||
57 | return NULL; | ||
58 | } | ||
59 | |||
60 | const struct GNUNET_MESSENGER_RoomEntryRecord *record = data; | ||
61 | |||
62 | char *door = GNUNET_CRYPTO_eddsa_public_key_to_string (&(record->door.public_key)); | ||
63 | char *key = GNUNET_STRINGS_data_to_string_alloc (&(record->key), sizeof(struct GNUNET_HashCode)); | ||
64 | |||
65 | char *ret; | ||
66 | GNUNET_asprintf (&ret, "%s-%s", door, key); | ||
67 | GNUNET_free (key); | ||
68 | GNUNET_free (door); | ||
69 | return ret; | ||
70 | } | ||
71 | |||
72 | default: | ||
73 | return NULL; | ||
74 | } | ||
75 | } | ||
76 | |||
77 | |||
78 | /** | ||
79 | * Convert human-readable version of a 'value' of a record to the binary | ||
80 | * representation. | ||
81 | * | ||
82 | * @param cls closure, unused | ||
83 | * @param type type of the record | ||
84 | * @param s human-readable string | ||
85 | * @param data set to value in binary encoding (will be allocated) | ||
86 | * @param data_size set to number of bytes in @a data | ||
87 | * @return #GNUNET_OK on success | ||
88 | */ | ||
89 | static int | ||
90 | messenger_string_to_value (void *cls, | ||
91 | uint32_t type, | ||
92 | const char *s, | ||
93 | void **data, | ||
94 | size_t *data_size) | ||
95 | { | ||
96 | (void) cls; | ||
97 | if (NULL == s) | ||
98 | { | ||
99 | GNUNET_break (0); | ||
100 | return GNUNET_SYSERR; | ||
101 | } | ||
102 | |||
103 | switch (type) | ||
104 | { | ||
105 | case GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_ENTRY: | ||
106 | { | ||
107 | char key [103]; | ||
108 | const char *dash; | ||
109 | struct GNUNET_PeerIdentity door; | ||
110 | |||
111 | if ((NULL == (dash = strchr (s, '-'))) || | ||
112 | (1 != sscanf (s, "%103s-", key)) || | ||
113 | (GNUNET_OK != GNUNET_CRYPTO_eddsa_public_key_from_string (dash + 1, | ||
114 | strlen (dash + 1), | ||
115 | &(door.public_key)))) | ||
116 | { | ||
117 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
118 | _ ("Unable to parse MESSENGER_ROOM_ENTRY record `%s'\n"), | ||
119 | s); | ||
120 | return GNUNET_SYSERR; | ||
121 | } | ||
122 | |||
123 | struct GNUNET_MESSENGER_RoomEntryRecord *record = GNUNET_new ( | ||
124 | struct GNUNET_MESSENGER_RoomEntryRecord | ||
125 | ); | ||
126 | |||
127 | if (GNUNET_OK != GNUNET_STRINGS_string_to_data (key, | ||
128 | strlen (key), | ||
129 | &(record->key), | ||
130 | sizeof(struct GNUNET_HashCode))) | ||
131 | { | ||
132 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
133 | _ ("Unable to parse MESSENGER_ROOM_ENTRY record `%s'\n"), | ||
134 | s); | ||
135 | GNUNET_free (record); | ||
136 | return GNUNET_SYSERR; | ||
137 | } | ||
138 | |||
139 | record->door = door; | ||
140 | *data = record; | ||
141 | *data_size = sizeof(struct GNUNET_MESSENGER_RoomEntryRecord); | ||
142 | return GNUNET_OK; | ||
143 | } | ||
144 | |||
145 | default: | ||
146 | return GNUNET_SYSERR; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | |||
151 | /** | ||
152 | * Mapping of record type numbers to human-readable | ||
153 | * record type names. | ||
154 | */ | ||
155 | static struct | ||
156 | { | ||
157 | const char *name; | ||
158 | uint32_t number; | ||
159 | } name_map[] = { | ||
160 | { "MESSENGER_ROOM_ENTRY", GNUNET_GNSRECORD_TYPE_MESSENGER_ROOM_ENTRY }, | ||
161 | { NULL, UINT32_MAX } | ||
162 | }; | ||
163 | |||
164 | |||
165 | /** | ||
166 | * Convert a type name (e.g. "AAAA") to the corresponding number. | ||
167 | * | ||
168 | * @param cls closure, unused | ||
169 | * @param gns_typename name to convert | ||
170 | * @return corresponding number, UINT32_MAX on error | ||
171 | */ | ||
172 | static uint32_t | ||
173 | messenger_typename_to_number (void *cls, | ||
174 | const char *gns_typename) | ||
175 | { | ||
176 | unsigned int i; | ||
177 | |||
178 | (void) cls; | ||
179 | i = 0; | ||
180 | while ((name_map[i].name != NULL) && | ||
181 | (0 != strcasecmp (gns_typename, name_map[i].name))) | ||
182 | i++; | ||
183 | return name_map[i].number; | ||
184 | } | ||
185 | |||
186 | |||
187 | /** | ||
188 | * Convert a type number to the corresponding type string (e.g. 1 to "A") | ||
189 | * | ||
190 | * @param cls closure, unused | ||
191 | * @param type number of a type to convert | ||
192 | * @return corresponding typestring, NULL on error | ||
193 | */ | ||
194 | static const char * | ||
195 | messenger_number_to_typename (void *cls, | ||
196 | uint32_t type) | ||
197 | { | ||
198 | unsigned int i; | ||
199 | |||
200 | (void) cls; | ||
201 | i = 0; | ||
202 | while ((name_map[i].name != NULL) && | ||
203 | (type != name_map[i].number)) | ||
204 | i++; | ||
205 | return name_map[i].name; | ||
206 | } | ||
207 | |||
208 | |||
209 | /** | ||
210 | * Entry point for the plugin. | ||
211 | * | ||
212 | * @param cls NULL | ||
213 | * @return the exported block API | ||
214 | */ | ||
215 | void * | ||
216 | libgnunet_plugin_gnsrecord_messenger_init (void *cls) | ||
217 | { | ||
218 | struct GNUNET_GNSRECORD_PluginFunctions *api; | ||
219 | |||
220 | (void) cls; | ||
221 | api = GNUNET_new (struct GNUNET_GNSRECORD_PluginFunctions); | ||
222 | api->value_to_string = &messenger_value_to_string; | ||
223 | api->string_to_value = &messenger_string_to_value; | ||
224 | api->typename_to_number = &messenger_typename_to_number; | ||
225 | api->number_to_typename = &messenger_number_to_typename; | ||
226 | return api; | ||
227 | } | ||
228 | |||
229 | |||
230 | /** | ||
231 | * Exit point from the plugin. | ||
232 | * | ||
233 | * @param cls the return value from #libgnunet_plugin_block_test_init | ||
234 | * @return NULL | ||
235 | */ | ||
236 | void * | ||
237 | libgnunet_plugin_gnsrecord_messenger_done (void *cls) | ||
238 | { | ||
239 | struct GNUNET_GNSRECORD_PluginFunctions *api = cls; | ||
240 | |||
241 | GNUNET_free (api); | ||
242 | return NULL; | ||
243 | } | ||
diff --git a/src/messenger/test_messenger.c b/src/messenger/test_messenger.c deleted file mode 100644 index 5784dfd82..000000000 --- a/src/messenger/test_messenger.c +++ /dev/null | |||
@@ -1,181 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @file messenger/test_messenger.c | ||
22 | * @author Tobias Frisch | ||
23 | * @brief Test for the messenger service using cadet API. | ||
24 | */ | ||
25 | #include <stdio.h> | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_lib.h" | ||
29 | #include "gnunet_messenger_service.h" | ||
30 | |||
31 | /** | ||
32 | * How long until we really give up on a particular testcase portion? | ||
33 | */ | ||
34 | #define TOTAL_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, \ | ||
35 | 60) | ||
36 | |||
37 | /** | ||
38 | * How long until we give up on any particular operation (and retry)? | ||
39 | */ | ||
40 | #define BASE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | ||
41 | |||
42 | #define TESTER_NAME "tester" | ||
43 | |||
44 | static int status = 1; | ||
45 | |||
46 | static struct GNUNET_SCHEDULER_Task *die_task = NULL; | ||
47 | static struct GNUNET_SCHEDULER_Task *op_task = NULL; | ||
48 | |||
49 | struct GNUNET_MESSENGER_Handle *messenger = NULL; | ||
50 | |||
51 | static void | ||
52 | end (void *cls) | ||
53 | { | ||
54 | die_task = NULL; | ||
55 | |||
56 | if (op_task) | ||
57 | { | ||
58 | GNUNET_SCHEDULER_cancel (op_task); | ||
59 | op_task = NULL; | ||
60 | } | ||
61 | |||
62 | if (messenger) | ||
63 | { | ||
64 | GNUNET_MESSENGER_disconnect (messenger); | ||
65 | messenger = NULL; | ||
66 | } | ||
67 | |||
68 | status = 0; | ||
69 | } | ||
70 | |||
71 | static void | ||
72 | end_badly (void *cls) | ||
73 | { | ||
74 | fprintf (stderr, "Testcase failed (timeout).\n"); | ||
75 | |||
76 | end (NULL); | ||
77 | status = 1; | ||
78 | } | ||
79 | |||
80 | static void | ||
81 | end_operation (void *cls) | ||
82 | { | ||
83 | op_task = NULL; | ||
84 | |||
85 | fprintf (stderr, "Testcase failed (operation: '%s').\n", cls ? (const char*) cls : "unknown"); | ||
86 | |||
87 | if (die_task) | ||
88 | GNUNET_SCHEDULER_cancel (die_task); | ||
89 | |||
90 | end (NULL); | ||
91 | status = 1; | ||
92 | } | ||
93 | |||
94 | static int identity_counter = 0; | ||
95 | |||
96 | /** | ||
97 | * Function called when an identity is retrieved. | ||
98 | * | ||
99 | * @param cls Closure | ||
100 | * @param handle Handle of messenger service | ||
101 | */ | ||
102 | static void | ||
103 | on_identity (void *cls, | ||
104 | struct GNUNET_MESSENGER_Handle *handle) | ||
105 | { | ||
106 | if (op_task) | ||
107 | { | ||
108 | GNUNET_SCHEDULER_cancel (op_task); | ||
109 | op_task = NULL; | ||
110 | } | ||
111 | |||
112 | const char *name = GNUNET_MESSENGER_get_name (handle); | ||
113 | |||
114 | if (0 != strcmp (name, TESTER_NAME)) | ||
115 | { | ||
116 | op_task = GNUNET_SCHEDULER_add_now (&end_operation, "name"); | ||
117 | return; | ||
118 | } | ||
119 | |||
120 | const struct GNUNET_IDENTITY_PublicKey *key = GNUNET_MESSENGER_get_key (handle); | ||
121 | |||
122 | if (((!identity_counter) && (key)) || ((identity_counter) && (!key))) | ||
123 | { | ||
124 | op_task = GNUNET_SCHEDULER_add_now (&end_operation, "key"); | ||
125 | return; | ||
126 | } | ||
127 | |||
128 | if (identity_counter) | ||
129 | { | ||
130 | GNUNET_MESSENGER_disconnect (handle); | ||
131 | |||
132 | op_task = NULL; | ||
133 | messenger = NULL; | ||
134 | |||
135 | if (die_task) | ||
136 | GNUNET_SCHEDULER_cancel (die_task); | ||
137 | |||
138 | die_task = GNUNET_SCHEDULER_add_now (&end, NULL); | ||
139 | return; | ||
140 | } | ||
141 | |||
142 | GNUNET_MESSENGER_update (messenger); | ||
143 | identity_counter++; | ||
144 | } | ||
145 | |||
146 | /** | ||
147 | * Main function for testcase. | ||
148 | * | ||
149 | * @param cls Closure | ||
150 | * @param cfg Configuration | ||
151 | * @param peer Peer for testing | ||
152 | */ | ||
153 | static void | ||
154 | run (void *cls, | ||
155 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
156 | struct GNUNET_TESTING_Peer *peer) | ||
157 | { | ||
158 | die_task = GNUNET_SCHEDULER_add_delayed (TOTAL_TIMEOUT, &end_badly, NULL); | ||
159 | |||
160 | identity_counter = 0; | ||
161 | |||
162 | op_task = GNUNET_SCHEDULER_add_delayed (BASE_TIMEOUT, &end_operation, "connect"); | ||
163 | messenger = GNUNET_MESSENGER_connect (cfg, TESTER_NAME, &on_identity, NULL, NULL, NULL); | ||
164 | } | ||
165 | |||
166 | /** | ||
167 | * The main function. | ||
168 | * | ||
169 | * @param argc number of arguments from the command line | ||
170 | * @param argv command line arguments | ||
171 | * @return 0 ok, 1 on error | ||
172 | */ | ||
173 | int | ||
174 | main (int argc, | ||
175 | char **argv) | ||
176 | { | ||
177 | if (0 != GNUNET_TESTING_peer_run ("test-messenger", "test_messenger_api.conf", &run, NULL)) | ||
178 | return 1; | ||
179 | |||
180 | return status; | ||
181 | } | ||
diff --git a/src/messenger/test_messenger_adapt.c b/src/messenger/test_messenger_adapt.c deleted file mode 100644 index 3230af6b7..000000000 --- a/src/messenger/test_messenger_adapt.c +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @file messenger/test_messenger_adapt.c | ||
22 | * @author Tobias Frisch | ||
23 | * @brief Test for the messenger service using cadet API. | ||
24 | */ | ||
25 | |||
26 | #include "testing_messenger_setup.h" | ||
27 | |||
28 | /** | ||
29 | * The main function. | ||
30 | * | ||
31 | * @param argc number of arguments from the command line | ||
32 | * @param argv command line arguments | ||
33 | * @return 0 ok, 1 on error | ||
34 | */ | ||
35 | int | ||
36 | main (int argc, | ||
37 | char **argv) | ||
38 | { | ||
39 | unsigned int doors [] = { 5, 1, 2, 3, 6, 7, 8, 4 }; | ||
40 | unsigned int stages [] = { 0x21, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x21 }; | ||
41 | |||
42 | struct test_configuration cfg; | ||
43 | cfg.count = 8; | ||
44 | cfg.doors = doors; | ||
45 | cfg.stages = stages; | ||
46 | |||
47 | return GNUNET_run_messenger_setup ("test_messenger_adapt", &cfg); | ||
48 | } | ||
diff --git a/src/messenger/test_messenger_anonymous.c b/src/messenger/test_messenger_anonymous.c deleted file mode 100644 index 8cb339f0e..000000000 --- a/src/messenger/test_messenger_anonymous.c +++ /dev/null | |||
@@ -1,173 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @file messenger/test_messenger_anonymous.c | ||
22 | * @author Tobias Frisch | ||
23 | * @brief Test for the messenger service using cadet API. | ||
24 | */ | ||
25 | #include <stdio.h> | ||
26 | #include "platform.h" | ||
27 | #include "gnunet_util_lib.h" | ||
28 | #include "gnunet_testing_lib.h" | ||
29 | #include "gnunet_messenger_service.h" | ||
30 | |||
31 | /** | ||
32 | * How long until we really give up on a particular testcase portion? | ||
33 | */ | ||
34 | #define TOTAL_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, \ | ||
35 | 60) | ||
36 | |||
37 | /** | ||
38 | * How long until we give up on any particular operation (and retry)? | ||
39 | */ | ||
40 | #define BASE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | ||
41 | |||
42 | static int status = 1; | ||
43 | |||
44 | static struct GNUNET_SCHEDULER_Task *die_task = NULL; | ||
45 | static struct GNUNET_SCHEDULER_Task *op_task = NULL; | ||
46 | |||
47 | struct GNUNET_MESSENGER_Handle *messenger = NULL; | ||
48 | |||
49 | static void | ||
50 | end (void *cls) | ||
51 | { | ||
52 | die_task = NULL; | ||
53 | |||
54 | if (op_task) | ||
55 | { | ||
56 | GNUNET_SCHEDULER_cancel (op_task); | ||
57 | op_task = NULL; | ||
58 | } | ||
59 | |||
60 | if (messenger) | ||
61 | { | ||
62 | GNUNET_MESSENGER_disconnect (messenger); | ||
63 | messenger = NULL; | ||
64 | } | ||
65 | |||
66 | status = 0; | ||
67 | } | ||
68 | |||
69 | static void | ||
70 | end_badly (void *cls) | ||
71 | { | ||
72 | fprintf (stderr, "Testcase failed (timeout).\n"); | ||
73 | |||
74 | end (NULL); | ||
75 | status = 1; | ||
76 | } | ||
77 | |||
78 | static void | ||
79 | end_operation (void *cls) | ||
80 | { | ||
81 | op_task = NULL; | ||
82 | |||
83 | fprintf (stderr, "Testcase failed (operation: '%s').\n", cls ? (const char*) cls : "unknown"); | ||
84 | |||
85 | if (die_task) | ||
86 | GNUNET_SCHEDULER_cancel (die_task); | ||
87 | |||
88 | end (NULL); | ||
89 | status = 1; | ||
90 | } | ||
91 | |||
92 | /** | ||
93 | * Function called when an identity is retrieved. | ||
94 | * | ||
95 | * @param cls Closure | ||
96 | * @param handle Handle of messenger service | ||
97 | */ | ||
98 | static void | ||
99 | on_identity (void *cls, | ||
100 | struct GNUNET_MESSENGER_Handle *handle) | ||
101 | { | ||
102 | if (op_task) | ||
103 | { | ||
104 | GNUNET_SCHEDULER_cancel (op_task); | ||
105 | op_task = NULL; | ||
106 | } | ||
107 | |||
108 | const char *name = GNUNET_MESSENGER_get_name (handle); | ||
109 | |||
110 | if (NULL != name) | ||
111 | { | ||
112 | op_task = GNUNET_SCHEDULER_add_now (&end_operation, "name-anonymous"); | ||
113 | return; | ||
114 | } | ||
115 | |||
116 | if (GNUNET_SYSERR != GNUNET_MESSENGER_update (handle)) | ||
117 | { | ||
118 | op_task = GNUNET_SCHEDULER_add_now (&end_operation, "update-fail"); | ||
119 | return; | ||
120 | } | ||
121 | |||
122 | const struct GNUNET_IDENTITY_PublicKey *key = GNUNET_MESSENGER_get_key (handle); | ||
123 | |||
124 | if (key) | ||
125 | { | ||
126 | op_task = GNUNET_SCHEDULER_add_now (&end_operation, "key-anonymous"); | ||
127 | return; | ||
128 | } | ||
129 | |||
130 | GNUNET_MESSENGER_disconnect (handle); | ||
131 | |||
132 | messenger = NULL; | ||
133 | |||
134 | if (die_task) | ||
135 | GNUNET_SCHEDULER_cancel (die_task); | ||
136 | |||
137 | die_task = GNUNET_SCHEDULER_add_now (&end, NULL); | ||
138 | } | ||
139 | |||
140 | /** | ||
141 | * Main function for testcase. | ||
142 | * | ||
143 | * @param cls Closure | ||
144 | * @param cfg Configuration | ||
145 | * @param peer Peer for testing | ||
146 | */ | ||
147 | static void | ||
148 | run (void *cls, | ||
149 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
150 | struct GNUNET_TESTING_Peer *peer) | ||
151 | { | ||
152 | die_task = GNUNET_SCHEDULER_add_delayed (TOTAL_TIMEOUT, &end_badly, NULL); | ||
153 | |||
154 | op_task = GNUNET_SCHEDULER_add_delayed (BASE_TIMEOUT, &end_operation, "connect"); | ||
155 | messenger = GNUNET_MESSENGER_connect (cfg, NULL, &on_identity, NULL, NULL, NULL); | ||
156 | } | ||
157 | |||
158 | /** | ||
159 | * The main function. | ||
160 | * | ||
161 | * @param argc number of arguments from the command line | ||
162 | * @param argv command line arguments | ||
163 | * @return 0 ok, 1 on error | ||
164 | */ | ||
165 | int | ||
166 | main (int argc, | ||
167 | char **argv) | ||
168 | { | ||
169 | if (0 != GNUNET_TESTING_peer_run ("test-messenger", "test_messenger_api.conf", &run, NULL)) | ||
170 | return 1; | ||
171 | |||
172 | return status; | ||
173 | } | ||
diff --git a/src/messenger/test_messenger_api.conf b/src/messenger/test_messenger_api.conf deleted file mode 100644 index 968f56f6d..000000000 --- a/src/messenger/test_messenger_api.conf +++ /dev/null | |||
@@ -1,47 +0,0 @@ | |||
1 | @INLINE@ ../../contrib/conf/gnunet/no_forcestart.conf | ||
2 | @INLINE@ ../../contrib/conf/gnunet/no_autostart_above_core.conf | ||
3 | |||
4 | [testbed] | ||
5 | HOSTNAME = localhost | ||
6 | OVERLAY_TOPOLOGY = CLIQUE | ||
7 | |||
8 | [arm] | ||
9 | GLOBAL_POSTFIX = -l $GNUNET_CACHE_HOME/{}-logs -L verbose | ||
10 | |||
11 | [transport] | ||
12 | IMMEDIATE_START = YES | ||
13 | |||
14 | [core] | ||
15 | START_ON_DEMAND = YES | ||
16 | IMMEDIATE_START = YES | ||
17 | USE_EPHEMERAL_KEYS = NO | ||
18 | |||
19 | [PATHS] | ||
20 | GNUNET_TEST_HOME = $GNUNET_TMP/test-messenger-api/ | ||
21 | |||
22 | [peerinfo] | ||
23 | NO_IO = YES | ||
24 | |||
25 | [cadet] | ||
26 | START_ON_DEMAND = YES | ||
27 | REFRESH_CONNECTION_TIME = 1 s | ||
28 | ID_ANNOUNCE_TIME = 5 s | ||
29 | CONNECT_TIMEOUT = 30 s | ||
30 | DEFAULT_TTL = 16 | ||
31 | DHT_REPLICATION_LEVEL = 10 | ||
32 | MAX_TUNNELS = 10 | ||
33 | MAX_CONNECTIONS = 10 | ||
34 | MAX_MSGS_QUEUE = 20 | ||
35 | DISABLE_TRY_CONNECT = YES | ||
36 | REKEY_PERIOD = 2 s | ||
37 | |||
38 | [identity] | ||
39 | START_ON_DEMAND = YES | ||
40 | |||
41 | [messenger] | ||
42 | START_ON_DEMAND = YES | ||
43 | |||
44 | [nat] | ||
45 | ENABLE_UPNP = NO | ||
46 | RETURN_LOCAL_ADDRESSES = YES | ||
47 | IMMEDIATE_START = NO \ No newline at end of file | ||
diff --git a/src/messenger/test_messenger_async_client.c b/src/messenger/test_messenger_async_client.c deleted file mode 100644 index 8404195dc..000000000 --- a/src/messenger/test_messenger_async_client.c +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @file messenger/test_messenger_async_client.c | ||
22 | * @author Tobias Frisch | ||
23 | * @brief Test for the messenger service using cadet API. | ||
24 | */ | ||
25 | |||
26 | #include "testing_messenger_setup.h" | ||
27 | |||
28 | /** | ||
29 | * The main function. | ||
30 | * | ||
31 | * @param argc number of arguments from the command line | ||
32 | * @param argv command line arguments | ||
33 | * @return 0 ok, 1 on error | ||
34 | */ | ||
35 | int | ||
36 | main (int argc, | ||
37 | char **argv) | ||
38 | { | ||
39 | unsigned int doors [] = { 0, 1 }; | ||
40 | unsigned int stages [] = { 0x10, 0x20 }; | ||
41 | |||
42 | struct test_configuration cfg; | ||
43 | cfg.count = 2; | ||
44 | cfg.doors = doors; | ||
45 | cfg.stages = stages; | ||
46 | |||
47 | return GNUNET_run_messenger_setup ("test_messenger_async_client", &cfg); | ||
48 | } | ||
diff --git a/src/messenger/test_messenger_async_p2p.c b/src/messenger/test_messenger_async_p2p.c deleted file mode 100644 index 25746f7ff..000000000 --- a/src/messenger/test_messenger_async_p2p.c +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @file messenger/test_messenger_async_p2p.c | ||
22 | * @author Tobias Frisch | ||
23 | * @brief Test for the messenger service using cadet API. | ||
24 | */ | ||
25 | |||
26 | #include "testing_messenger_setup.h" | ||
27 | |||
28 | /** | ||
29 | * The main function. | ||
30 | * | ||
31 | * @param argc number of arguments from the command line | ||
32 | * @param argv command line arguments | ||
33 | * @return 0 ok, 1 on error | ||
34 | */ | ||
35 | int | ||
36 | main (int argc, | ||
37 | char **argv) | ||
38 | { | ||
39 | unsigned int doors [] = { 2, 1 }; | ||
40 | unsigned int stages [] = { 0x30, 0x30 }; | ||
41 | |||
42 | struct test_configuration cfg; | ||
43 | cfg.count = 2; | ||
44 | cfg.doors = doors; | ||
45 | cfg.stages = stages; | ||
46 | |||
47 | return GNUNET_run_messenger_setup ("test_messenger_async_p2p", &cfg); | ||
48 | } | ||
diff --git a/src/messenger/test_messenger_growth.c b/src/messenger/test_messenger_growth.c deleted file mode 100644 index c3f243cbf..000000000 --- a/src/messenger/test_messenger_growth.c +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @file messenger/test_messenger_growth.c | ||
22 | * @author Tobias Frisch | ||
23 | * @brief Test for the messenger service using cadet API. | ||
24 | */ | ||
25 | |||
26 | #include "testing_messenger_setup.h" | ||
27 | |||
28 | /** | ||
29 | * The main function. | ||
30 | * | ||
31 | * @param argc number of arguments from the command line | ||
32 | * @param argv command line arguments | ||
33 | * @return 0 ok, 1 on error | ||
34 | */ | ||
35 | int | ||
36 | main (int argc, | ||
37 | char **argv) | ||
38 | { | ||
39 | unsigned int doors [] = { 0, 1, 1, 1, 1, 1, 1, 1 }; | ||
40 | unsigned int stages [] = { 0x01, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21 }; | ||
41 | |||
42 | struct test_configuration cfg; | ||
43 | cfg.count = 8; | ||
44 | cfg.doors = doors; | ||
45 | cfg.stages = stages; | ||
46 | |||
47 | return GNUNET_run_messenger_setup ("test_messenger_growth", &cfg); | ||
48 | } | ||
diff --git a/src/messenger/test_messenger_ring.c b/src/messenger/test_messenger_ring.c deleted file mode 100644 index 777d79eb8..000000000 --- a/src/messenger/test_messenger_ring.c +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @file messenger/test_messenger_ring.c | ||
22 | * @author Tobias Frisch | ||
23 | * @brief Test for the messenger service using cadet API. | ||
24 | */ | ||
25 | |||
26 | #include "testing_messenger_setup.h" | ||
27 | |||
28 | /** | ||
29 | * The main function. | ||
30 | * | ||
31 | * @param argc number of arguments from the command line | ||
32 | * @param argv command line arguments | ||
33 | * @return 0 ok, 1 on error | ||
34 | */ | ||
35 | int | ||
36 | main (int argc, | ||
37 | char **argv) | ||
38 | { | ||
39 | unsigned int doors [] = { 8, 1, 2, 3, 4, 5, 6, 7 }; | ||
40 | unsigned int stages [] = { 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21 }; | ||
41 | |||
42 | struct test_configuration cfg; | ||
43 | cfg.count = 8; | ||
44 | cfg.doors = doors; | ||
45 | cfg.stages = stages; | ||
46 | |||
47 | return GNUNET_run_messenger_setup ("test_messenger_ring", &cfg); | ||
48 | } | ||
diff --git a/src/messenger/test_messenger_server.c b/src/messenger/test_messenger_server.c deleted file mode 100644 index 61e96e879..000000000 --- a/src/messenger/test_messenger_server.c +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @file messenger/test_messenger_server.c | ||
22 | * @author Tobias Frisch | ||
23 | * @brief Test for the messenger service using cadet API. | ||
24 | */ | ||
25 | |||
26 | #include "testing_messenger_setup.h" | ||
27 | |||
28 | /** | ||
29 | * The main function. | ||
30 | * | ||
31 | * @param argc number of arguments from the command line | ||
32 | * @param argv command line arguments | ||
33 | * @return 0 ok, 1 on error | ||
34 | */ | ||
35 | int | ||
36 | main (int argc, | ||
37 | char **argv) | ||
38 | { | ||
39 | unsigned int doors [] = { 0, 1, 1, 1, 1, 1, 1, 1 }; | ||
40 | unsigned int stages [] = { 0x01, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; | ||
41 | |||
42 | struct test_configuration cfg; | ||
43 | cfg.count = 8; | ||
44 | cfg.doors = doors; | ||
45 | cfg.stages = stages; | ||
46 | |||
47 | return GNUNET_run_messenger_setup ("test_messenger_server", &cfg); | ||
48 | } | ||
diff --git a/src/messenger/test_messenger_sync_client.c b/src/messenger/test_messenger_sync_client.c deleted file mode 100644 index 02d90a61d..000000000 --- a/src/messenger/test_messenger_sync_client.c +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @file messenger/test_messenger_sync_client.c | ||
22 | * @author Tobias Frisch | ||
23 | * @brief Test for the messenger service using cadet API. | ||
24 | */ | ||
25 | |||
26 | #include "testing_messenger_setup.h" | ||
27 | |||
28 | /** | ||
29 | * The main function. | ||
30 | * | ||
31 | * @param argc number of arguments from the command line | ||
32 | * @param argv command line arguments | ||
33 | * @return 0 ok, 1 on error | ||
34 | */ | ||
35 | int | ||
36 | main (int argc, | ||
37 | char **argv) | ||
38 | { | ||
39 | unsigned int doors [] = { 0, 1 }; | ||
40 | unsigned int stages [] = { 0x01, 0x20 }; | ||
41 | |||
42 | struct test_configuration cfg; | ||
43 | cfg.count = 2; | ||
44 | cfg.doors = doors; | ||
45 | cfg.stages = stages; | ||
46 | |||
47 | return GNUNET_run_messenger_setup ("test_messenger_sync_client", &cfg); | ||
48 | } | ||
diff --git a/src/messenger/test_messenger_sync_p2p.c b/src/messenger/test_messenger_sync_p2p.c deleted file mode 100644 index 0a900a39e..000000000 --- a/src/messenger/test_messenger_sync_p2p.c +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @file messenger/test_messenger_sync_p2p.c | ||
22 | * @author Tobias Frisch | ||
23 | * @brief Test for the messenger service using cadet API. | ||
24 | */ | ||
25 | |||
26 | #include "testing_messenger_setup.h" | ||
27 | |||
28 | /** | ||
29 | * The main function. | ||
30 | * | ||
31 | * @param argc number of arguments from the command line | ||
32 | * @param argv command line arguments | ||
33 | * @return 0 ok, 1 on error | ||
34 | */ | ||
35 | int | ||
36 | main (int argc, | ||
37 | char **argv) | ||
38 | { | ||
39 | unsigned int doors [] = { 2, 1 }; | ||
40 | unsigned int stages [] = { 0x21, 0x21 }; | ||
41 | |||
42 | struct test_configuration cfg; | ||
43 | cfg.count = 2; | ||
44 | cfg.doors = doors; | ||
45 | cfg.stages = stages; | ||
46 | |||
47 | return GNUNET_run_messenger_setup ("test_messenger_sync_p2p", &cfg); | ||
48 | } | ||
diff --git a/src/messenger/test_messenger_worst_client.c b/src/messenger/test_messenger_worst_client.c deleted file mode 100644 index a3d5aafec..000000000 --- a/src/messenger/test_messenger_worst_client.c +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @file messenger/test_messenger_worst_client.c | ||
22 | * @author Tobias Frisch | ||
23 | * @brief Test for the messenger service using cadet API. | ||
24 | */ | ||
25 | |||
26 | #include "testing_messenger_setup.h" | ||
27 | |||
28 | /** | ||
29 | * The main function. | ||
30 | * | ||
31 | * @param argc number of arguments from the command line | ||
32 | * @param argv command line arguments | ||
33 | * @return 0 ok, 1 on error | ||
34 | */ | ||
35 | int | ||
36 | main (int argc, | ||
37 | char **argv) | ||
38 | { | ||
39 | unsigned int doors [] = { 0, 1 }; | ||
40 | unsigned int stages [] = { 0x10, 0x02 }; | ||
41 | |||
42 | struct test_configuration cfg; | ||
43 | cfg.count = 2; | ||
44 | cfg.doors = doors; | ||
45 | cfg.stages = stages; | ||
46 | |||
47 | return GNUNET_run_messenger_setup ("test_messenger_worst_client", &cfg); | ||
48 | } | ||
diff --git a/src/messenger/test_messenger_worst_p2p.c b/src/messenger/test_messenger_worst_p2p.c deleted file mode 100644 index 89e54cfbd..000000000 --- a/src/messenger/test_messenger_worst_p2p.c +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @file messenger/test_messenger_worst_p2p.c | ||
22 | * @author Tobias Frisch | ||
23 | * @brief Test for the messenger service using cadet API. | ||
24 | */ | ||
25 | |||
26 | #include "testing_messenger_setup.h" | ||
27 | |||
28 | /** | ||
29 | * The main function. | ||
30 | * | ||
31 | * @param argc number of arguments from the command line | ||
32 | * @param argv command line arguments | ||
33 | * @return 0 ok, 1 on error | ||
34 | */ | ||
35 | int | ||
36 | main (int argc, | ||
37 | char **argv) | ||
38 | { | ||
39 | unsigned int doors [] = { 2, 1 }; | ||
40 | unsigned int stages [] = { 0x12, 0x12 }; | ||
41 | |||
42 | struct test_configuration cfg; | ||
43 | cfg.count = 2; | ||
44 | cfg.doors = doors; | ||
45 | cfg.stages = stages; | ||
46 | |||
47 | return GNUNET_run_messenger_setup ("test_messenger_worst_p2p", &cfg); | ||
48 | } | ||
diff --git a/src/messenger/testing_messenger_barrier.c b/src/messenger/testing_messenger_barrier.c deleted file mode 100644 index a95ea9ef1..000000000 --- a/src/messenger/testing_messenger_barrier.c +++ /dev/null | |||
@@ -1,172 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @file messenger/testing_messenger_barrier.c | ||
22 | * @author Tobias Frisch | ||
23 | * @brief Pseudo-barriers for simple event handling | ||
24 | */ | ||
25 | |||
26 | #include "testing_messenger_barrier.h" | ||
27 | |||
28 | struct GNUNET_BarrierHandle | ||
29 | { | ||
30 | unsigned int requirement; | ||
31 | GNUNET_BarrierStatusCallback cb; | ||
32 | void *cls; | ||
33 | |||
34 | struct GNUNET_BarrierWaitHandle *head; | ||
35 | struct GNUNET_BarrierWaitHandle *tail; | ||
36 | |||
37 | struct GNUNET_SCHEDULER_Task* task; | ||
38 | }; | ||
39 | |||
40 | struct GNUNET_BarrierHandle* | ||
41 | GNUNET_init_barrier (unsigned int requirement, | ||
42 | GNUNET_BarrierStatusCallback cb, | ||
43 | void *cb_cls) | ||
44 | { | ||
45 | if (0 == requirement) | ||
46 | return NULL; | ||
47 | |||
48 | struct GNUNET_BarrierHandle *barrier = GNUNET_new(struct GNUNET_BarrierHandle); | ||
49 | |||
50 | if (!barrier) | ||
51 | return NULL; | ||
52 | |||
53 | barrier->requirement = requirement; | ||
54 | barrier->cb = cb; | ||
55 | barrier->cls = cb_cls; | ||
56 | barrier->head = NULL; | ||
57 | barrier->tail = NULL; | ||
58 | barrier->task = NULL; | ||
59 | |||
60 | return barrier; | ||
61 | } | ||
62 | |||
63 | static void | ||
64 | exit_status (struct GNUNET_BarrierHandle *barrier, | ||
65 | int status); | ||
66 | |||
67 | static void | ||
68 | cancel_barrier (void *cls) | ||
69 | { | ||
70 | exit_status ((struct GNUNET_BarrierHandle*) cls, GNUNET_SYSERR); | ||
71 | } | ||
72 | |||
73 | static void | ||
74 | complete_barrier (void *cls) | ||
75 | { | ||
76 | exit_status ((struct GNUNET_BarrierHandle*) cls, GNUNET_OK); | ||
77 | } | ||
78 | |||
79 | void | ||
80 | GNUNET_cancel_barrier (struct GNUNET_BarrierHandle *barrier) | ||
81 | { | ||
82 | if ((!barrier) || (barrier->task)) | ||
83 | return; | ||
84 | |||
85 | barrier->task = GNUNET_SCHEDULER_add_now(cancel_barrier, barrier); | ||
86 | } | ||
87 | |||
88 | struct GNUNET_BarrierWaitHandle | ||
89 | { | ||
90 | GNUNET_BarrierWaitStatusCallback cb; | ||
91 | void *cls; | ||
92 | |||
93 | struct GNUNET_BarrierWaitHandle *prev; | ||
94 | struct GNUNET_BarrierWaitHandle *next; | ||
95 | |||
96 | struct GNUNET_BarrierHandle *barrier; | ||
97 | }; | ||
98 | |||
99 | static void | ||
100 | exit_status (struct GNUNET_BarrierHandle *barrier, | ||
101 | int status) | ||
102 | { | ||
103 | struct GNUNET_BarrierWaitHandle *waiting = barrier->head; | ||
104 | while (waiting) | ||
105 | { | ||
106 | struct GNUNET_BarrierWaitHandle *current = waiting; | ||
107 | |||
108 | if (current->cb) | ||
109 | current->cb(current->cls, current, status); | ||
110 | |||
111 | waiting = waiting->next; | ||
112 | |||
113 | GNUNET_CONTAINER_DLL_remove(barrier->head, barrier->tail, current); | ||
114 | GNUNET_free(current); | ||
115 | } | ||
116 | |||
117 | if (barrier->cb) | ||
118 | barrier->cb(barrier->cls, barrier, status); | ||
119 | |||
120 | GNUNET_free(barrier); | ||
121 | } | ||
122 | |||
123 | struct GNUNET_BarrierWaitHandle* | ||
124 | GNUNET_wait_barrier (struct GNUNET_BarrierHandle *barrier, | ||
125 | GNUNET_BarrierWaitStatusCallback cb, | ||
126 | void *cb_cls) | ||
127 | { | ||
128 | if ((!barrier) || (0 == barrier->requirement)) | ||
129 | return NULL; | ||
130 | |||
131 | struct GNUNET_BarrierWaitHandle *waiting = GNUNET_new(struct GNUNET_BarrierWaitHandle); | ||
132 | |||
133 | if (!waiting) | ||
134 | return NULL; | ||
135 | |||
136 | waiting->cb = cb; | ||
137 | waiting->cls = cb_cls; | ||
138 | waiting->prev = NULL; | ||
139 | waiting->next = NULL; | ||
140 | waiting->barrier = barrier; | ||
141 | |||
142 | GNUNET_CONTAINER_DLL_insert_tail(barrier->head, barrier->tail, waiting); | ||
143 | barrier->requirement--; | ||
144 | |||
145 | if ((barrier->requirement == 0) && (!barrier->task)) | ||
146 | barrier->task = GNUNET_SCHEDULER_add_now(complete_barrier, barrier); | ||
147 | |||
148 | return waiting; | ||
149 | } | ||
150 | |||
151 | void | ||
152 | GNUNET_cancel_wait_barrier (struct GNUNET_BarrierWaitHandle *waiting) | ||
153 | { | ||
154 | if (!waiting) | ||
155 | return; | ||
156 | |||
157 | struct GNUNET_BarrierHandle *barrier = waiting->barrier; | ||
158 | |||
159 | if (!barrier) | ||
160 | return; | ||
161 | |||
162 | if ((barrier->requirement == 0) && (barrier->task)) | ||
163 | { | ||
164 | GNUNET_SCHEDULER_cancel(barrier->task); | ||
165 | barrier->task = NULL; | ||
166 | } | ||
167 | |||
168 | barrier->requirement++; | ||
169 | GNUNET_CONTAINER_DLL_remove(barrier->head, barrier->tail, waiting); | ||
170 | |||
171 | GNUNET_free(waiting); | ||
172 | } | ||
diff --git a/src/messenger/testing_messenger_barrier.h b/src/messenger/testing_messenger_barrier.h deleted file mode 100644 index 3062a393a..000000000 --- a/src/messenger/testing_messenger_barrier.h +++ /dev/null | |||
@@ -1,131 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @file messenger/testing_messenger_barrier.h | ||
22 | * @author Tobias Frisch | ||
23 | * @brief Pseudo-barriers for simple event handling | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_TESTING_MESSENGER_BARRIER_H_ | ||
27 | #define GNUNET_TESTING_MESSENGER_BARRIER_H_ | ||
28 | |||
29 | #include "platform.h" | ||
30 | #include "gnunet_util_lib.h" | ||
31 | |||
32 | /** | ||
33 | * Handle for pseudo-barrier | ||
34 | */ | ||
35 | struct GNUNET_BarrierHandle; | ||
36 | |||
37 | |||
38 | /** | ||
39 | * Functions of this type are to be given as callback argument to | ||
40 | * GNUNET_init_barrier(). The callback will be called when status | ||
41 | * information is available for the pseudo-barrier. | ||
42 | * | ||
43 | * @param cls the closure given to GNUNET_init_barrier() | ||
44 | * @param barrier the pseudo-barrier handle | ||
45 | * @param status status of the pseudo-barrier. The pseudo-barrier is removed | ||
46 | * once it has been crossed or an error occurs while processing it. | ||
47 | * Therefore it is invalid to call GNUNET_cancel_barrier() on a | ||
48 | * crossed or errored pseudo-barrier. | ||
49 | */ | ||
50 | typedef void | ||
51 | (*GNUNET_BarrierStatusCallback) (void *cls, | ||
52 | struct GNUNET_BarrierHandle *barrier, | ||
53 | int status); | ||
54 | |||
55 | |||
56 | /** | ||
57 | * Initialise a pseudo-barrier and call the given callback when the required | ||
58 | * amount of peers (requirement) reach the pseudo-barrier OR upon error. | ||
59 | * | ||
60 | * @param requirement the amount of peers that is required to reach the | ||
61 | * pseudo-barrier. Peers signal reaching a pseudo-barrier by calling | ||
62 | * GNUNET_wait_barrier(). | ||
63 | * @param cb the callback to call when the pseudo-barrier is reached or upon | ||
64 | * error. Can be NULL. | ||
65 | * @param cls closure for the above callback | ||
66 | * @return pseudo-barrier handle; NULL upon error | ||
67 | */ | ||
68 | struct GNUNET_BarrierHandle* | ||
69 | GNUNET_init_barrier (unsigned int requirement, | ||
70 | GNUNET_BarrierStatusCallback cb, | ||
71 | void *cb_cls); | ||
72 | |||
73 | |||
74 | /** | ||
75 | * Cancel a pseudo-barrier. | ||
76 | * | ||
77 | * @param barrier the pseudo-barrier handle | ||
78 | */ | ||
79 | void | ||
80 | GNUNET_cancel_barrier (struct GNUNET_BarrierHandle *barrier); | ||
81 | |||
82 | |||
83 | /** | ||
84 | * Handle for pseudo-barrier wait | ||
85 | */ | ||
86 | struct GNUNET_BarrierWaitHandle; | ||
87 | |||
88 | |||
89 | /** | ||
90 | * Functions of this type are to be given as acallback argument to | ||
91 | * GNUNET_wait_barrier(). The callback will be called when the pseudo-barrier | ||
92 | * corresponding given in GNUNET_wait_barrier() is crossed or cancelled. | ||
93 | * | ||
94 | * @param cls closure pointer given to GNUNET_wait_barrier() | ||
95 | * @param waiting the pseudo-barrier wait handle | ||
96 | * @param status #GNUNET_SYSERR in case of error while waiting for the | ||
97 | * pseudo-barrier; #GNUNET_OK if the pseudo-barrier is crossed | ||
98 | */ | ||
99 | typedef void | ||
100 | (*GNUNET_BarrierWaitStatusCallback) (void *cls, | ||
101 | struct GNUNET_BarrierWaitHandle *waiting, | ||
102 | int status); | ||
103 | |||
104 | |||
105 | /** | ||
106 | * Wait for a pseudo-barrier to be crossed. This function should be called for | ||
107 | * the peers which have been started by the testbed. | ||
108 | * | ||
109 | * @param barrier the pseudo-barrier handle | ||
110 | * @param cb the pseudo-barrier wait callback | ||
111 | * @param cls the closure for the above callback | ||
112 | * @return pseudo-barrier wait handle which can be used to cancel the waiting | ||
113 | * at anytime before the callback is called. NULL upon error. | ||
114 | */ | ||
115 | struct GNUNET_BarrierWaitHandle* | ||
116 | GNUNET_wait_barrier (struct GNUNET_BarrierHandle *barrier, | ||
117 | GNUNET_BarrierWaitStatusCallback cb, | ||
118 | void *cb_cls); | ||
119 | |||
120 | |||
121 | /** | ||
122 | * Cancel a pseudo-barrier wait handle. Should not be called in or after the | ||
123 | * callback given to GNUNET_wait_barrier() has been called. | ||
124 | * | ||
125 | * @param waiting the pseudo-barrier wait handle | ||
126 | */ | ||
127 | void | ||
128 | GNUNET_cancel_wait_barrier (struct GNUNET_BarrierWaitHandle *waiting); | ||
129 | |||
130 | |||
131 | #endif /* GNUNET_TESTING_MESSENGER_BARRIER_H_ */ | ||
diff --git a/src/messenger/testing_messenger_setup.c b/src/messenger/testing_messenger_setup.c deleted file mode 100644 index 3cde8c9bb..000000000 --- a/src/messenger/testing_messenger_setup.c +++ /dev/null | |||
@@ -1,547 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020--2021 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 | * @file messenger/testing_messenger_barrier.c | ||
22 | * @author Tobias Frisch | ||
23 | * @brief A simple test-case setup for the messenger service | ||
24 | */ | ||
25 | |||
26 | #include "testing_messenger_setup.h" | ||
27 | |||
28 | #include <stdio.h> | ||
29 | #include "platform.h" | ||
30 | #include "gnunet_util_lib.h" | ||
31 | #include "gnunet_testbed_logger_service.h" | ||
32 | #include "gnunet_testbed_service.h" | ||
33 | #include "gnunet_testing_lib.h" | ||
34 | #include "gnunet_messenger_service.h" | ||
35 | #include "testing_messenger_barrier.h" | ||
36 | |||
37 | #define TEST_ROOM "test" | ||
38 | #define TEST_NAME "tester" | ||
39 | |||
40 | struct test_properties; | ||
41 | |||
42 | struct test_peer { | ||
43 | struct test_properties *props; | ||
44 | unsigned int num; | ||
45 | |||
46 | struct GNUNET_SCHEDULER_Task *op_task; | ||
47 | struct GNUNET_TESTBED_Operation *op; | ||
48 | |||
49 | struct GNUNET_TESTBED_Peer *peer; | ||
50 | struct GNUNET_PeerIdentity peer_id; | ||
51 | struct GNUNET_BarrierWaitHandle *wait; | ||
52 | |||
53 | struct GNUNET_MESSENGER_Handle *handle; | ||
54 | struct GNUNET_MESSENGER_Room *room; | ||
55 | |||
56 | unsigned int peer_messages; | ||
57 | |||
58 | const char *message; | ||
59 | }; | ||
60 | |||
61 | struct test_properties { | ||
62 | const struct test_configuration *cfg; | ||
63 | |||
64 | unsigned int num_hosts; | ||
65 | |||
66 | struct GNUNET_SCHEDULER_Task *die_task; | ||
67 | struct GNUNET_SCHEDULER_Task *end_task; | ||
68 | |||
69 | struct GNUNET_BarrierHandle *barrier; | ||
70 | |||
71 | struct test_peer *peers; | ||
72 | unsigned int num_peer; | ||
73 | |||
74 | int status; | ||
75 | }; | ||
76 | |||
77 | static void | ||
78 | shutdown_cb (void *cls) | ||
79 | { | ||
80 | struct test_properties *properties = cls; | ||
81 | |||
82 | |||
83 | for (unsigned int i = 0; i < properties->num_peer; i++) | ||
84 | { | ||
85 | struct test_peer *peer = &properties->peers[i]; | ||
86 | |||
87 | GNUNET_assert(peer != NULL); | ||
88 | |||
89 | if (peer->op_task) | ||
90 | GNUNET_SCHEDULER_cancel(peer->op_task); | ||
91 | |||
92 | peer->op_task = NULL; | ||
93 | |||
94 | if (peer->op) | ||
95 | GNUNET_TESTBED_operation_done (peer->op); | ||
96 | |||
97 | peer->op = NULL; | ||
98 | |||
99 | if (peer->wait) | ||
100 | GNUNET_cancel_wait_barrier(peer->wait); | ||
101 | |||
102 | peer->wait = NULL; | ||
103 | |||
104 | if (peer->room) | ||
105 | GNUNET_MESSENGER_close_room (peer->room); | ||
106 | |||
107 | peer->room = NULL; | ||
108 | |||
109 | if (peer->handle) | ||
110 | GNUNET_MESSENGER_disconnect (peer->handle); | ||
111 | |||
112 | peer->handle = NULL; | ||
113 | } | ||
114 | |||
115 | if (properties->die_task) | ||
116 | GNUNET_SCHEDULER_cancel(properties->die_task); | ||
117 | |||
118 | properties->die_task = NULL; | ||
119 | properties->end_task = NULL; | ||
120 | |||
121 | if (properties->barrier) | ||
122 | GNUNET_cancel_barrier(properties->barrier); | ||
123 | |||
124 | properties->barrier = NULL; | ||
125 | } | ||
126 | |||
127 | |||
128 | |||
129 | static void | ||
130 | end_cb (void *cls) | ||
131 | { | ||
132 | struct test_properties *properties = cls; | ||
133 | |||
134 | GNUNET_assert(properties != NULL); | ||
135 | |||
136 | properties->die_task = NULL; | ||
137 | |||
138 | int status = 0; | ||
139 | |||
140 | for (unsigned int i = 0; i < properties->num_peer; i++) | ||
141 | { | ||
142 | struct test_peer *peer = &properties->peers[i]; | ||
143 | |||
144 | GNUNET_assert(peer != NULL); | ||
145 | |||
146 | const int members = GNUNET_MESSENGER_iterate_members(peer->room, NULL, NULL); | ||
147 | |||
148 | GNUNET_assert (members >= 0); | ||
149 | |||
150 | if (peer->props->num_peer != (unsigned int) members) | ||
151 | { | ||
152 | fprintf (stderr, "Testcase failed (members: %d/%u).\n", members, peer->props->num_peer); | ||
153 | status = 1; | ||
154 | break; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | GNUNET_SCHEDULER_shutdown (); | ||
159 | |||
160 | properties->status = status; | ||
161 | } | ||
162 | |||
163 | static void | ||
164 | end_badly_cb (void *cls) | ||
165 | { | ||
166 | struct test_properties *properties = cls; | ||
167 | |||
168 | GNUNET_assert(properties != NULL); | ||
169 | |||
170 | fprintf (stderr, "Testcase failed (timeout).\n"); | ||
171 | |||
172 | end_cb (properties); | ||
173 | |||
174 | properties->status = 1; | ||
175 | } | ||
176 | |||
177 | static void | ||
178 | end_operation_cb (void *cls) | ||
179 | { | ||
180 | struct test_peer *peer = cls; | ||
181 | |||
182 | GNUNET_assert(peer != NULL); | ||
183 | |||
184 | peer->op_task = NULL; | ||
185 | |||
186 | fprintf (stderr, "Testcase failed (operation: '%s').\n", peer->message); | ||
187 | |||
188 | GNUNET_SCHEDULER_shutdown (); | ||
189 | } | ||
190 | |||
191 | static void | ||
192 | end_error_cb (void *cls) | ||
193 | { | ||
194 | struct test_peer *peer = cls; | ||
195 | |||
196 | GNUNET_assert(peer != NULL); | ||
197 | |||
198 | peer->op_task = NULL; | ||
199 | |||
200 | fprintf (stderr, "Testcase failed (error: '%s').\n", peer->message); | ||
201 | GNUNET_free (peer); | ||
202 | |||
203 | GNUNET_SCHEDULER_shutdown (); | ||
204 | } | ||
205 | |||
206 | static void | ||
207 | barrier2_wait_cb (void *cls, | ||
208 | struct GNUNET_BarrierWaitHandle *waiting, | ||
209 | int status) | ||
210 | { | ||
211 | struct test_peer *peer = cls; | ||
212 | |||
213 | GNUNET_assert(peer != NULL); | ||
214 | |||
215 | if (peer->wait == waiting) | ||
216 | peer->wait = NULL; | ||
217 | } | ||
218 | |||
219 | static void | ||
220 | barrier_wait_cb (void *cls, | ||
221 | struct GNUNET_BarrierWaitHandle *waiting, | ||
222 | int status) | ||
223 | { | ||
224 | struct test_peer *peer = cls; | ||
225 | |||
226 | GNUNET_assert(peer != NULL); | ||
227 | |||
228 | if (peer->wait == waiting) | ||
229 | peer->wait = NULL; | ||
230 | |||
231 | if (0 != (peer->props->cfg->stages[peer->num - 1] & 0x02)) | ||
232 | { | ||
233 | unsigned int door = peer->props->cfg->doors[peer->num - 1]; | ||
234 | |||
235 | if (door == 0) | ||
236 | door = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, peer->props->cfg->count); | ||
237 | else | ||
238 | door = door - 1; | ||
239 | |||
240 | struct GNUNET_HashCode hash; | ||
241 | GNUNET_CRYPTO_hash (TEST_ROOM, sizeof(TEST_ROOM), &hash); | ||
242 | |||
243 | struct GNUNET_MESSENGER_Room *room; | ||
244 | room = GNUNET_MESSENGER_enter_room(peer->handle, &(peer->props->peers[door].peer_id), &hash); | ||
245 | |||
246 | if (peer->room) | ||
247 | GNUNET_assert(room == peer->room); | ||
248 | else | ||
249 | GNUNET_assert(room != NULL); | ||
250 | |||
251 | peer->room = room; | ||
252 | } | ||
253 | } | ||
254 | |||
255 | /** | ||
256 | * Function called whenever a message is received or sent. | ||
257 | * | ||
258 | * @param cls Closure | ||
259 | * @param room Room | ||
260 | * @param sender Sender | ||
261 | * @param message Message | ||
262 | * @param hash Hash of message | ||
263 | * @param flags Flags of message | ||
264 | */ | ||
265 | static void | ||
266 | on_message (void *cls, | ||
267 | struct GNUNET_MESSENGER_Room *room, | ||
268 | const struct GNUNET_MESSENGER_Contact *sender, | ||
269 | const struct GNUNET_MESSENGER_Message *message, | ||
270 | const struct GNUNET_HashCode *hash, | ||
271 | enum GNUNET_MESSENGER_MessageFlags flags) | ||
272 | { | ||
273 | struct test_peer *peer = cls; | ||
274 | |||
275 | GNUNET_assert(peer != NULL); | ||
276 | |||
277 | fprintf (stderr, "Peer: %s; [%s] Message: %s (%s)\n", | ||
278 | GNUNET_i2s(&(peer->peer_id)), | ||
279 | GNUNET_sh2s(&(message->header.sender_id)), | ||
280 | GNUNET_MESSENGER_name_of_kind(message->header.kind), | ||
281 | GNUNET_h2s(hash)); | ||
282 | |||
283 | if (GNUNET_MESSENGER_KIND_PEER == message->header.kind) | ||
284 | peer->peer_messages++; | ||
285 | |||
286 | if (peer->props->num_hosts == peer->peer_messages) | ||
287 | peer->wait = GNUNET_wait_barrier (peer->props->barrier, &barrier2_wait_cb, peer); | ||
288 | else if (peer->props->num_hosts < peer->peer_messages) | ||
289 | { | ||
290 | if (peer->wait) | ||
291 | GNUNET_cancel_wait_barrier(peer->wait); | ||
292 | |||
293 | peer->wait = NULL; | ||
294 | |||
295 | if (peer->op_task) | ||
296 | GNUNET_SCHEDULER_cancel(peer->op_task); | ||
297 | |||
298 | peer->message = "peer"; | ||
299 | peer->op_task = GNUNET_SCHEDULER_add_now (&end_operation_cb, peer); | ||
300 | } | ||
301 | } | ||
302 | |||
303 | static void | ||
304 | second_stage (void *cls) | ||
305 | { | ||
306 | struct test_peer *peer = cls; | ||
307 | |||
308 | GNUNET_assert(peer != NULL); | ||
309 | |||
310 | peer->op_task = NULL; | ||
311 | |||
312 | struct GNUNET_HashCode hash; | ||
313 | GNUNET_CRYPTO_hash (TEST_ROOM, sizeof(TEST_ROOM), &hash); | ||
314 | |||
315 | if (0 != (peer->props->cfg->stages[peer->num - 1] & 0x10)) | ||
316 | { | ||
317 | struct GNUNET_MESSENGER_Room *room; | ||
318 | room = GNUNET_MESSENGER_open_room (peer->handle, &hash); | ||
319 | |||
320 | if (peer->room) | ||
321 | GNUNET_assert(room == peer->room); | ||
322 | else | ||
323 | GNUNET_assert(room != NULL); | ||
324 | |||
325 | peer->room = room; | ||
326 | } | ||
327 | |||
328 | if (0 != (peer->props->cfg->stages[peer->num - 1] & 0x20)) | ||
329 | { | ||
330 | unsigned int door = peer->props->cfg->doors[peer->num - 1]; | ||
331 | |||
332 | if (door == 0) | ||
333 | door = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, peer->props->cfg->count); | ||
334 | else | ||
335 | door = door - 1; | ||
336 | |||
337 | struct GNUNET_MESSENGER_Room *room; | ||
338 | room = GNUNET_MESSENGER_enter_room(peer->handle, &(peer->props->peers[door].peer_id), &hash); | ||
339 | |||
340 | if (peer->room) | ||
341 | GNUNET_assert(room == peer->room); | ||
342 | else | ||
343 | GNUNET_assert(room != NULL); | ||
344 | |||
345 | peer->room = room; | ||
346 | } | ||
347 | } | ||
348 | |||
349 | static void | ||
350 | on_peer (void *cb_cls, | ||
351 | struct GNUNET_TESTBED_Operation *op, | ||
352 | const struct GNUNET_TESTBED_PeerInformation *pinfo, | ||
353 | const char *emsg) | ||
354 | { | ||
355 | struct test_peer *peer = cb_cls; | ||
356 | |||
357 | GNUNET_assert(peer != NULL); | ||
358 | |||
359 | if (emsg) | ||
360 | { | ||
361 | peer->message = GNUNET_strdup(emsg); | ||
362 | peer->op_task = GNUNET_SCHEDULER_add_now (&end_error_cb, peer); | ||
363 | return; | ||
364 | } | ||
365 | |||
366 | if (!pinfo) | ||
367 | { | ||
368 | peer->message = "info"; | ||
369 | peer->op_task = GNUNET_SCHEDULER_add_now (&end_operation_cb, peer); | ||
370 | return; | ||
371 | } | ||
372 | |||
373 | if (pinfo->pit != GNUNET_TESTBED_PIT_CONFIGURATION) | ||
374 | { | ||
375 | peer->message = "config"; | ||
376 | peer->op_task = GNUNET_SCHEDULER_add_now (&end_operation_cb, peer); | ||
377 | return; | ||
378 | } | ||
379 | |||
380 | peer->handle = GNUNET_MESSENGER_connect (pinfo->result.cfg, TEST_NAME, NULL, NULL, &on_message, peer); | ||
381 | |||
382 | GNUNET_assert(GNUNET_OK == GNUNET_CRYPTO_get_peer_identity( | ||
383 | pinfo->result.cfg, &(peer->peer_id) | ||
384 | )); | ||
385 | |||
386 | if (0 != (peer->props->cfg->stages[peer->num - 1] & 0x01)) | ||
387 | { | ||
388 | struct GNUNET_HashCode hash; | ||
389 | GNUNET_CRYPTO_hash (TEST_ROOM, sizeof(TEST_ROOM), &hash); | ||
390 | |||
391 | peer->room = GNUNET_MESSENGER_open_room (peer->handle, &hash); | ||
392 | |||
393 | GNUNET_assert(peer->room != NULL); | ||
394 | } | ||
395 | else | ||
396 | peer->room = NULL; | ||
397 | |||
398 | peer->wait = GNUNET_wait_barrier (peer->props->barrier, &barrier_wait_cb, peer); | ||
399 | } | ||
400 | |||
401 | /** | ||
402 | * Main function for a peer of the testcase. | ||
403 | * | ||
404 | * @param cls Closure | ||
405 | * @param event Information about the event | ||
406 | */ | ||
407 | static void | ||
408 | run (void *cls, | ||
409 | const struct GNUNET_TESTBED_EventInformation *event) | ||
410 | { | ||
411 | struct test_properties *properties = cls; | ||
412 | |||
413 | GNUNET_assert(properties != NULL); | ||
414 | |||
415 | if (GNUNET_TESTBED_ET_PEER_START != event->type) | ||
416 | { | ||
417 | fprintf (stderr, "Testcase failed (operation: 'start').\n"); | ||
418 | |||
419 | GNUNET_SCHEDULER_shutdown (); | ||
420 | return; | ||
421 | } | ||
422 | |||
423 | struct test_peer *peer = &(properties->peers[properties->num_peer++]); | ||
424 | |||
425 | peer->props = properties; | ||
426 | peer->num = properties->num_peer; | ||
427 | |||
428 | peer->peer = event->details.peer_start.peer; | ||
429 | peer->op = GNUNET_TESTBED_peer_get_information (peer->peer, GNUNET_TESTBED_PIT_CONFIGURATION, on_peer, peer); | ||
430 | } | ||
431 | |||
432 | static void | ||
433 | barrier2_cb (void *cls, | ||
434 | struct GNUNET_BarrierHandle *barrier, | ||
435 | int status) | ||
436 | { | ||
437 | struct test_properties *properties = cls; | ||
438 | |||
439 | GNUNET_assert(properties != NULL); | ||
440 | |||
441 | if (properties->barrier == barrier) | ||
442 | properties->barrier = NULL; | ||
443 | |||
444 | if (GNUNET_SYSERR == status) | ||
445 | { | ||
446 | fprintf (stderr, "Testcase failed (operation: 'barrier2').\n"); | ||
447 | |||
448 | GNUNET_SCHEDULER_shutdown (); | ||
449 | return; | ||
450 | } | ||
451 | else if (GNUNET_OK == status) | ||
452 | { | ||
453 | if (properties->die_task) | ||
454 | GNUNET_SCHEDULER_cancel(properties->die_task); | ||
455 | |||
456 | properties->die_task = GNUNET_SCHEDULER_add_delayed ( | ||
457 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, properties->cfg->count), | ||
458 | &end_cb, properties | ||
459 | ); | ||
460 | } | ||
461 | } | ||
462 | |||
463 | static void | ||
464 | barrier_cb (void *cls, | ||
465 | struct GNUNET_BarrierHandle *barrier, | ||
466 | int status) | ||
467 | { | ||
468 | struct test_properties *properties = cls; | ||
469 | |||
470 | GNUNET_assert(properties != NULL); | ||
471 | |||
472 | if (properties->barrier == barrier) | ||
473 | properties->barrier = NULL; | ||
474 | else if (!properties->barrier) | ||
475 | return; | ||
476 | |||
477 | if (properties->num_peer != properties->cfg->count) | ||
478 | { | ||
479 | fprintf (stderr, "Testcase failed (operation: 'process').\n"); | ||
480 | |||
481 | GNUNET_SCHEDULER_shutdown (); | ||
482 | return; | ||
483 | } | ||
484 | |||
485 | if (GNUNET_SYSERR == status) | ||
486 | { | ||
487 | fprintf (stderr, "Testcase failed (operation: 'barrier').\n"); | ||
488 | |||
489 | GNUNET_SCHEDULER_shutdown (); | ||
490 | return; | ||
491 | } | ||
492 | else if (GNUNET_OK == status) | ||
493 | { | ||
494 | properties->barrier = GNUNET_init_barrier (properties->num_peer, &barrier2_cb, properties); | ||
495 | |||
496 | for (unsigned int i = 0; i < properties->num_peer; i++) | ||
497 | properties->peers[i].op_task = GNUNET_SCHEDULER_add_now (&second_stage, &(properties->peers[i])); | ||
498 | } | ||
499 | } | ||
500 | |||
501 | static void | ||
502 | init (void *cls, | ||
503 | struct GNUNET_TESTBED_RunHandle *h, | ||
504 | unsigned int num_peers, | ||
505 | struct GNUNET_TESTBED_Peer **peers, | ||
506 | unsigned int links_succeeded, | ||
507 | unsigned int links_failed) | ||
508 | { | ||
509 | struct test_properties *properties = cls; | ||
510 | |||
511 | GNUNET_assert(properties != NULL); | ||
512 | |||
513 | properties->end_task = GNUNET_SCHEDULER_add_shutdown(&shutdown_cb, properties); | ||
514 | properties->die_task = GNUNET_SCHEDULER_add_delayed ( | ||
515 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, properties->cfg->count * 5), | ||
516 | &end_badly_cb, properties | ||
517 | ); | ||
518 | } | ||
519 | |||
520 | int | ||
521 | GNUNET_run_messenger_setup (const char* test_name, | ||
522 | const struct test_configuration *cfg) | ||
523 | { | ||
524 | struct test_properties properties; | ||
525 | memset(&properties, 0, sizeof(properties)); | ||
526 | |||
527 | properties.cfg = cfg; | ||
528 | properties.peers = GNUNET_new_array(cfg->count, struct test_peer); | ||
529 | |||
530 | for (unsigned int i = 0; i < cfg->count; i++) | ||
531 | if (0 != (cfg->stages[i] & 0x11)) | ||
532 | properties.num_hosts++; | ||
533 | |||
534 | properties.status = 1; | ||
535 | properties.barrier = GNUNET_init_barrier (cfg->count, &barrier_cb, &properties); | ||
536 | |||
537 | if (GNUNET_OK != GNUNET_TESTBED_test_run (test_name, "test_messenger_api.conf", | ||
538 | cfg->count, | ||
539 | (1LL << GNUNET_TESTBED_ET_PEER_START), | ||
540 | &run, &properties, | ||
541 | &init, &properties)) | ||
542 | return 1; | ||
543 | |||
544 | GNUNET_free(properties.peers); | ||
545 | |||
546 | return properties.status; | ||
547 | } | ||
diff --git a/src/messenger/testing_messenger_setup.h b/src/messenger/testing_messenger_setup.h deleted file mode 100644 index e5ae0c151..000000000 --- a/src/messenger/testing_messenger_setup.h +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2021 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 | * @file messenger/testing_messenger_setup.h | ||
22 | * @author Tobias Frisch | ||
23 | * @brief A simple test-case setup for the messenger service | ||
24 | */ | ||
25 | |||
26 | #ifndef GNUNET_TESTING_MESSENGER_SETUP_H_ | ||
27 | #define GNUNET_TESTING_MESSENGER_SETUP_H_ | ||
28 | |||
29 | struct test_configuration | ||
30 | { | ||
31 | unsigned int count; | ||
32 | unsigned int *doors; | ||
33 | unsigned int *stages; | ||
34 | }; | ||
35 | |||
36 | int | ||
37 | GNUNET_run_messenger_setup (const char* test_name, | ||
38 | const struct test_configuration *cfg); | ||
39 | |||
40 | #endif /* GNUNET_TESTING_MESSENGER_SETUP_H_ */ | ||