diff options
Diffstat (limited to 'src/messenger/gnunet-service-messenger.c')
-rw-r--r-- | src/messenger/gnunet-service-messenger.c | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/src/messenger/gnunet-service-messenger.c b/src/messenger/gnunet-service-messenger.c new file mode 100644 index 000000000..2c92305c4 --- /dev/null +++ b/src/messenger/gnunet-service-messenger.c | |||
@@ -0,0 +1,306 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | Copyright (C) 2020 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_service.h" | ||
29 | #include "messenger_api_message.h" | ||
30 | |||
31 | struct GNUNET_MESSENGER_Client | ||
32 | { | ||
33 | struct GNUNET_SERVICE_Client *client; | ||
34 | struct GNUNET_MESSENGER_SrvHandle *handle; | ||
35 | }; | ||
36 | |||
37 | struct GNUNET_MESSENGER_Service *messenger; | ||
38 | |||
39 | static int | ||
40 | check_create (void *cls, const struct GNUNET_MESSENGER_CreateMessage *msg) | ||
41 | { | ||
42 | GNUNET_MQ_check_zero_termination(msg); | ||
43 | return GNUNET_OK; | ||
44 | } | ||
45 | |||
46 | static void | ||
47 | handle_create (void *cls, const struct GNUNET_MESSENGER_CreateMessage *msg) | ||
48 | { | ||
49 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
50 | |||
51 | const char *name = ((const char*) msg) + sizeof(*msg); | ||
52 | |||
53 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Handle created with name: %s\n", name); | ||
54 | |||
55 | setup_handle_name (msg_client->handle, strlen (name) > 0? name : NULL); | ||
56 | |||
57 | GNUNET_SERVICE_client_continue (msg_client->client); | ||
58 | } | ||
59 | |||
60 | static void | ||
61 | handle_update (void *cls, const struct GNUNET_MESSENGER_UpdateMessage *msg) | ||
62 | { | ||
63 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
64 | |||
65 | if (GNUNET_OK != update_handle (msg_client->handle)) | ||
66 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Name is required to update key!\n"); | ||
67 | |||
68 | GNUNET_SERVICE_client_continue (msg_client->client); | ||
69 | } | ||
70 | |||
71 | static void | ||
72 | handle_destroy (void *cls, const struct GNUNET_MESSENGER_DestroyMessage *msg) | ||
73 | { | ||
74 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
75 | |||
76 | GNUNET_SERVICE_client_drop (msg_client->client); | ||
77 | } | ||
78 | |||
79 | static int | ||
80 | check_set_name (void *cls, const struct GNUNET_MESSENGER_NameMessage *msg) | ||
81 | { | ||
82 | GNUNET_MQ_check_zero_termination(msg); | ||
83 | return GNUNET_OK; | ||
84 | } | ||
85 | |||
86 | static void | ||
87 | handle_set_name (void *cls, const struct GNUNET_MESSENGER_NameMessage *msg) | ||
88 | { | ||
89 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
90 | |||
91 | const char *name = ((const char*) msg) + sizeof(*msg); | ||
92 | |||
93 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Handles name is now: %s\n", name); | ||
94 | |||
95 | if (GNUNET_YES != set_handle_name (msg_client->handle, name)) | ||
96 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "No valid name: %s\n", name); | ||
97 | |||
98 | GNUNET_SERVICE_client_continue (msg_client->client); | ||
99 | } | ||
100 | |||
101 | static void | ||
102 | handle_room_open (void *cls, const struct GNUNET_MESSENGER_RoomMessage *msg) | ||
103 | { | ||
104 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
105 | |||
106 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Opening room: %s\n", | ||
107 | GNUNET_h2s (&(msg->key))); | ||
108 | |||
109 | if (GNUNET_YES == open_handle_room (msg_client->handle, &(msg->key))) | ||
110 | { | ||
111 | const struct GNUNET_ShortHashCode* member_id = get_handle_member_id(msg_client->handle, &(msg->key)); | ||
112 | |||
113 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Opening room with member id: %s\n", | ||
114 | GNUNET_sh2s (member_id)); | ||
115 | |||
116 | struct GNUNET_MESSENGER_RoomMessage *response; | ||
117 | struct GNUNET_MQ_Envelope *env; | ||
118 | |||
119 | env = GNUNET_MQ_msg(response, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN); | ||
120 | GNUNET_memcpy(&(response->key), &(msg->key), sizeof(msg->key)); | ||
121 | GNUNET_MQ_send (msg_client->handle->mq, env); | ||
122 | } | ||
123 | else | ||
124 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Opening room failed: %s\n", | ||
125 | GNUNET_h2s (&(msg->key))); | ||
126 | |||
127 | GNUNET_SERVICE_client_continue (msg_client->client); | ||
128 | } | ||
129 | |||
130 | static void | ||
131 | handle_room_entry (void *cls, const struct GNUNET_MESSENGER_RoomMessage *msg) | ||
132 | { | ||
133 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
134 | |||
135 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Entering room: %s, %s\n", | ||
136 | GNUNET_h2s (&(msg->key)), GNUNET_i2s (&(msg->door))); | ||
137 | |||
138 | if (GNUNET_YES == entry_handle_room (msg_client->handle, &(msg->door), &(msg->key))) | ||
139 | { | ||
140 | const struct GNUNET_ShortHashCode* member_id = get_handle_member_id(msg_client->handle, &(msg->key)); | ||
141 | |||
142 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Entering room with member id: %s\n", | ||
143 | GNUNET_sh2s (member_id)); | ||
144 | |||
145 | struct GNUNET_MESSENGER_RoomMessage *response; | ||
146 | struct GNUNET_MQ_Envelope *env; | ||
147 | |||
148 | env = GNUNET_MQ_msg(response, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY); | ||
149 | GNUNET_memcpy(&(response->door), &(msg->door), sizeof(msg->door)); | ||
150 | GNUNET_memcpy(&(response->key), &(msg->key), sizeof(msg->key)); | ||
151 | GNUNET_MQ_send (msg_client->handle->mq, env); | ||
152 | } | ||
153 | else | ||
154 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Entrance into room failed: %s, %s\n", | ||
155 | GNUNET_h2s (&(msg->key)), GNUNET_i2s (&(msg->door))); | ||
156 | |||
157 | GNUNET_SERVICE_client_continue (msg_client->client); | ||
158 | } | ||
159 | |||
160 | static void | ||
161 | handle_room_close (void *cls, const struct GNUNET_MESSENGER_RoomMessage *msg) | ||
162 | { | ||
163 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
164 | |||
165 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Closing room: %s\n", GNUNET_h2s (&(msg->key))); | ||
166 | |||
167 | if (GNUNET_YES == close_handle_room (msg_client->handle, &(msg->key))) | ||
168 | { | ||
169 | const struct GNUNET_ShortHashCode* member_id = get_handle_member_id(msg_client->handle, &(msg->key)); | ||
170 | |||
171 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Closing room with member id: %s\n", | ||
172 | GNUNET_sh2s (member_id)); | ||
173 | |||
174 | struct GNUNET_MESSENGER_RoomMessage *response; | ||
175 | struct GNUNET_MQ_Envelope *env; | ||
176 | |||
177 | env = GNUNET_MQ_msg(response, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE); | ||
178 | GNUNET_memcpy(&(response->key), &(msg->key), sizeof(msg->key)); | ||
179 | GNUNET_MQ_send (msg_client->handle->mq, env); | ||
180 | } | ||
181 | else | ||
182 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Closing room failed: %s\n", GNUNET_h2s (&(msg->key))); | ||
183 | |||
184 | GNUNET_SERVICE_client_continue (msg_client->client); | ||
185 | } | ||
186 | |||
187 | static int | ||
188 | check_send_message (void *cls, const struct GNUNET_MESSENGER_SendMessage *msg) | ||
189 | { | ||
190 | const uint16_t full_length = ntohs (msg->header.size) - sizeof(msg->header); | ||
191 | |||
192 | if (full_length < sizeof(msg->key)) | ||
193 | return GNUNET_NO; | ||
194 | |||
195 | const uint16_t length = full_length - sizeof(msg->key); | ||
196 | const char *buffer = ((const char*) msg) + sizeof(*msg); | ||
197 | |||
198 | struct GNUNET_MESSENGER_Message message; | ||
199 | |||
200 | if (GNUNET_YES != decode_message (&message, length, buffer)) | ||
201 | return GNUNET_NO; | ||
202 | |||
203 | return GNUNET_OK; | ||
204 | } | ||
205 | |||
206 | static void | ||
207 | handle_send_message (void *cls, const struct GNUNET_MESSENGER_SendMessage *msg) | ||
208 | { | ||
209 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
210 | |||
211 | const struct GNUNET_HashCode *key = &(msg->key); | ||
212 | const char *buffer = ((const char*) msg) + sizeof(*msg); | ||
213 | |||
214 | const uint16_t length = ntohs (msg->header.size) - sizeof(*msg); | ||
215 | |||
216 | struct GNUNET_MESSENGER_Message message; | ||
217 | decode_message (&message, length, buffer); | ||
218 | |||
219 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending message: %s to %s\n", | ||
220 | GNUNET_MESSENGER_name_of_kind (message.header.kind), | ||
221 | GNUNET_h2s (key)); | ||
222 | |||
223 | if (GNUNET_YES != send_handle_message (msg_client->handle, key, &message)) | ||
224 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Sending message failed: %s to %s\n", | ||
225 | GNUNET_MESSENGER_name_of_kind (message.header.kind), | ||
226 | GNUNET_h2s (key)); | ||
227 | |||
228 | GNUNET_SERVICE_client_continue (msg_client->client); | ||
229 | } | ||
230 | |||
231 | static void | ||
232 | handle_get_message (void *cls, const struct GNUNET_MESSENGER_RecvMessage *msg) | ||
233 | { | ||
234 | struct GNUNET_MESSENGER_Client *msg_client = cls; | ||
235 | |||
236 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Requesting message from room: %s\n", | ||
237 | GNUNET_h2s (&(msg->key))); | ||
238 | |||
239 | struct GNUNET_MESSENGER_SrvRoom *room = get_service_room (messenger, &(msg->key)); | ||
240 | |||
241 | if (room) | ||
242 | get_room_message (room, msg_client->handle, &(msg->hash), GNUNET_YES); | ||
243 | else | ||
244 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Room not found: %s\n", | ||
245 | GNUNET_h2s (&(msg->key))); | ||
246 | |||
247 | GNUNET_SERVICE_client_continue (msg_client->client); | ||
248 | } | ||
249 | |||
250 | static void* | ||
251 | callback_client_connect (void *cls, struct GNUNET_SERVICE_Client *client, struct GNUNET_MQ_Handle *mq) | ||
252 | { | ||
253 | struct GNUNET_MESSENGER_Client *msg_client = GNUNET_new(struct GNUNET_MESSENGER_Client); | ||
254 | |||
255 | msg_client->client = client; | ||
256 | msg_client->handle = add_service_handle (messenger, mq); | ||
257 | |||
258 | return msg_client; | ||
259 | } | ||
260 | |||
261 | static void | ||
262 | callback_client_disconnect (void *cls, struct GNUNET_SERVICE_Client *client, void *internal_cls) | ||
263 | { | ||
264 | struct GNUNET_MESSENGER_Client *msg_client = internal_cls; | ||
265 | |||
266 | remove_service_handle (messenger, msg_client->handle); | ||
267 | |||
268 | GNUNET_free(msg_client); | ||
269 | } | ||
270 | |||
271 | /** | ||
272 | * Setup MESSENGER internals. | ||
273 | * | ||
274 | * @param cls closure | ||
275 | * @param config configuration to use | ||
276 | * @param service the initialized service | ||
277 | */ | ||
278 | static void | ||
279 | run (void *cls, const struct GNUNET_CONFIGURATION_Handle *config, struct GNUNET_SERVICE_Handle *service) | ||
280 | { | ||
281 | messenger = create_service (config, service); | ||
282 | |||
283 | if ((!messenger) || (!messenger->cadet) || (!messenger->identity)) | ||
284 | GNUNET_SCHEDULER_shutdown (); | ||
285 | } | ||
286 | |||
287 | /** | ||
288 | * Define "main" method using service macro. | ||
289 | */ | ||
290 | GNUNET_SERVICE_MAIN( | ||
291 | GNUNET_MESSENGER_SERVICE_NAME, | ||
292 | GNUNET_SERVICE_OPTION_NONE, | ||
293 | &run, | ||
294 | &callback_client_connect, | ||
295 | &callback_client_disconnect, | ||
296 | NULL, | ||
297 | GNUNET_MQ_hd_var_size( create, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_CREATE, struct GNUNET_MESSENGER_CreateMessage, NULL ), | ||
298 | GNUNET_MQ_hd_fixed_size( update, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_UPDATE, struct GNUNET_MESSENGER_UpdateMessage, NULL ), | ||
299 | GNUNET_MQ_hd_fixed_size( destroy, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_DESTROY, struct GNUNET_MESSENGER_DestroyMessage, NULL ), | ||
300 | GNUNET_MQ_hd_var_size( set_name, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_SET_NAME, struct GNUNET_MESSENGER_NameMessage, NULL ), | ||
301 | GNUNET_MQ_hd_fixed_size( room_open, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN, struct GNUNET_MESSENGER_RoomMessage, NULL ), | ||
302 | GNUNET_MQ_hd_fixed_size( room_entry, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY, struct GNUNET_MESSENGER_RoomMessage, NULL ), | ||
303 | GNUNET_MQ_hd_fixed_size( room_close, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE, struct GNUNET_MESSENGER_RoomMessage, NULL ), | ||
304 | GNUNET_MQ_hd_var_size( send_message, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE, struct GNUNET_MESSENGER_SendMessage, NULL ), | ||
305 | GNUNET_MQ_hd_fixed_size( get_message, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE, struct GNUNET_MESSENGER_RecvMessage, NULL ), | ||
306 | GNUNET_MQ_handler_end()); | ||