diff options
Diffstat (limited to 'src/messenger/messenger_api.c')
-rw-r--r-- | src/messenger/messenger_api.c | 547 |
1 files changed, 368 insertions, 179 deletions
diff --git a/src/messenger/messenger_api.c b/src/messenger/messenger_api.c index 610c979c4..82fc0d1eb 100644 --- a/src/messenger/messenger_api.c +++ b/src/messenger/messenger_api.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | Copyright (C) 2020--2021 GNUnet e.V. | 3 | Copyright (C) 2020--2023 GNUnet e.V. |
4 | 4 | ||
5 | GNUnet is free software: you can redistribute it and/or modify it | 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 | 6 | under the terms of the GNU Affero General Public License as published |
@@ -24,12 +24,15 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include "platform.h" | 26 | #include "platform.h" |
27 | #include "gnunet_identity_service.h" | ||
27 | #include "gnunet_messenger_service.h" | 28 | #include "gnunet_messenger_service.h" |
28 | 29 | ||
29 | #include "gnunet-service-messenger.h" | 30 | #include "gnunet-service-messenger.h" |
30 | 31 | ||
31 | #include "messenger_api_handle.h" | 32 | #include "messenger_api_handle.h" |
32 | #include "messenger_api_message.h" | 33 | #include "messenger_api_message.h" |
34 | #include "messenger_api_message_kind.h" | ||
35 | #include "messenger_api_room.h" | ||
33 | #include "messenger_api_util.h" | 36 | #include "messenger_api_util.h" |
34 | 37 | ||
35 | const char* | 38 | const char* |
@@ -72,135 +75,107 @@ GNUNET_MESSENGER_name_of_kind (enum GNUNET_MESSENGER_MessageKind kind) | |||
72 | } | 75 | } |
73 | } | 76 | } |
74 | 77 | ||
75 | static int | 78 | static enum GNUNET_GenericReturnValue |
76 | check_get_name (void *cls, | 79 | dequeue_messages_from_room (struct GNUNET_MESSENGER_Room *room); |
77 | const struct GNUNET_MESSENGER_NameMessage *msg) | ||
78 | { | ||
79 | GNUNET_MQ_check_zero_termination(msg); | ||
80 | return GNUNET_OK; | ||
81 | } | ||
82 | 80 | ||
83 | static void | 81 | static void |
84 | handle_get_name (void *cls, | 82 | handle_room_open (void *cls, |
85 | const struct GNUNET_MESSENGER_NameMessage *msg) | 83 | const struct GNUNET_MESSENGER_RoomMessage *msg) |
86 | { | 84 | { |
87 | struct GNUNET_MESSENGER_Handle *handle = cls; | 85 | struct GNUNET_MESSENGER_Handle *handle = cls; |
88 | 86 | ||
89 | const char *name = ((const char*) msg) + sizeof(*msg); | 87 | const struct GNUNET_HashCode *key = &(msg->key); |
90 | |||
91 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set name of handle: %s\n", name); | ||
92 | |||
93 | set_handle_name (handle, strlen (name) > 0 ? name : NULL); | ||
94 | } | ||
95 | |||
96 | static int | ||
97 | check_get_key (void *cls, | ||
98 | const struct GNUNET_MESSENGER_KeyMessage *msg) | ||
99 | { | ||
100 | const uint16_t full_length = ntohs (msg->header.size); | ||
101 | 88 | ||
102 | if (full_length < sizeof(*msg)) | 89 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Opened room: %s\n", GNUNET_h2s (key)); |
103 | return GNUNET_NO; | ||
104 | 90 | ||
105 | const uint16_t length = full_length - sizeof(*msg); | 91 | open_handle_room (handle, key); |
106 | const char *buffer = ((const char*) msg) + sizeof(*msg); | ||
107 | 92 | ||
108 | struct GNUNET_IDENTITY_PublicKey pubkey; | 93 | struct GNUNET_MESSENGER_Room *room = get_handle_room (handle, key); |
109 | size_t read; | ||
110 | if (GNUNET_SYSERR == | ||
111 | GNUNET_IDENTITY_read_public_key_from_buffer(buffer, length, | ||
112 | &pubkey, &read)) | ||
113 | return GNUNET_NO; | ||
114 | 94 | ||
115 | return GNUNET_OK; | 95 | if (room) |
96 | dequeue_messages_from_room (room); | ||
116 | } | 97 | } |
117 | 98 | ||
118 | static void | 99 | static void |
119 | handle_get_key (void *cls, | 100 | handle_room_entry (void *cls, |
120 | const struct GNUNET_MESSENGER_KeyMessage *msg) | 101 | const struct GNUNET_MESSENGER_RoomMessage *msg) |
121 | { | 102 | { |
122 | struct GNUNET_MESSENGER_Handle *handle = cls; | 103 | struct GNUNET_MESSENGER_Handle *handle = cls; |
123 | 104 | ||
124 | const uint16_t length = ntohs (msg->header.size) - sizeof(*msg); | 105 | const struct GNUNET_PeerIdentity *door = &(msg->door); |
125 | const char *buffer = ((const char*) msg) + sizeof(*msg); | 106 | const struct GNUNET_HashCode *key = &(msg->key); |
126 | 107 | ||
127 | struct GNUNET_IDENTITY_PublicKey pubkey; | 108 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Entered room: %s\n", GNUNET_h2s (key)); |
128 | size_t read; | ||
129 | if (GNUNET_SYSERR == | ||
130 | GNUNET_IDENTITY_read_public_key_from_buffer(buffer, length, | ||
131 | &pubkey, &read)) | ||
132 | return; | ||
133 | 109 | ||
134 | char* str = GNUNET_IDENTITY_public_key_to_string (&pubkey); | 110 | entry_handle_room_at (handle, door, key); |
135 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set key of handle: %s\n", str); | ||
136 | GNUNET_free(str); | ||
137 | 111 | ||
138 | set_handle_key (handle, &pubkey); | 112 | struct GNUNET_MESSENGER_Room *room = get_handle_room (handle, key); |
139 | 113 | ||
140 | if (handle->identity_callback) | 114 | if (room) |
141 | handle->identity_callback (handle->identity_cls, handle); | 115 | dequeue_messages_from_room (room); |
142 | } | 116 | } |
143 | 117 | ||
144 | static void | 118 | static void |
145 | handle_member_id (void *cls, | 119 | handle_room_close (void *cls, |
146 | const struct GNUNET_MESSENGER_MemberMessage *msg) | 120 | const struct GNUNET_MESSENGER_RoomMessage *msg) |
147 | { | 121 | { |
148 | struct GNUNET_MESSENGER_Handle *handle = cls; | 122 | struct GNUNET_MESSENGER_Handle *handle = cls; |
149 | 123 | ||
150 | const struct GNUNET_HashCode *key = &(msg->key); | 124 | const struct GNUNET_HashCode *key = &(msg->key); |
151 | const struct GNUNET_ShortHashCode *id = &(msg->id); | ||
152 | 125 | ||
153 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set id of handle in room: %s\n", GNUNET_h2s (key)); | 126 | struct GNUNET_MESSENGER_Room *room = get_handle_room (handle, key); |
154 | |||
155 | struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); | ||
156 | 127 | ||
157 | if (room) | 128 | if (room) |
158 | { | 129 | dequeue_messages_from_room (room); |
159 | if (!room->contact_id) | ||
160 | room->contact_id = GNUNET_new(struct GNUNET_ShortHashCode); | ||
161 | 130 | ||
162 | GNUNET_memcpy(room->contact_id, id, sizeof(*id)); | 131 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Closed room: %s\n", GNUNET_h2s (key)); |
163 | } | 132 | |
133 | close_handle_room (handle, key); | ||
164 | } | 134 | } |
165 | 135 | ||
166 | static void | 136 | static void |
167 | handle_room_open (void *cls, | 137 | enqueue_message_to_room (struct GNUNET_MESSENGER_Room *room, |
168 | const struct GNUNET_MESSENGER_RoomMessage *msg) | 138 | struct GNUNET_MESSENGER_Message *message); |
169 | { | ||
170 | struct GNUNET_MESSENGER_Handle *handle = cls; | ||
171 | |||
172 | const struct GNUNET_HashCode *key = &(msg->key); | ||
173 | |||
174 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Opened room: %s\n", GNUNET_h2s (key)); | ||
175 | |||
176 | open_handle_room (handle, key); | ||
177 | } | ||
178 | 139 | ||
179 | static void | 140 | static void |
180 | handle_room_entry (void *cls, | 141 | handle_member_id (void *cls, |
181 | const struct GNUNET_MESSENGER_RoomMessage *msg) | 142 | const struct GNUNET_MESSENGER_MemberMessage *msg) |
182 | { | 143 | { |
183 | struct GNUNET_MESSENGER_Handle *handle = cls; | 144 | struct GNUNET_MESSENGER_Handle *handle = cls; |
184 | 145 | ||
185 | const struct GNUNET_PeerIdentity *door = &(msg->door); | ||
186 | const struct GNUNET_HashCode *key = &(msg->key); | 146 | const struct GNUNET_HashCode *key = &(msg->key); |
147 | const struct GNUNET_ShortHashCode *id = &(msg->id); | ||
148 | const uint32_t reset = msg->reset; | ||
187 | 149 | ||
188 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Entered room: %s\n", GNUNET_h2s (key)); | 150 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Changed member id in room: %s\n", GNUNET_h2s (key)); |
189 | 151 | ||
190 | entry_handle_room_at (handle, door, key); | 152 | struct GNUNET_MESSENGER_Room *room = get_handle_room (handle, key); |
191 | } | ||
192 | 153 | ||
193 | static void | 154 | if (!room) |
194 | handle_room_close (void *cls, | 155 | { |
195 | const struct GNUNET_MESSENGER_RoomMessage *msg) | 156 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Room is unknown to handle: %s\n", GNUNET_h2s (key)); |
196 | { | 157 | return; |
197 | struct GNUNET_MESSENGER_Handle *handle = cls; | 158 | } |
198 | 159 | ||
199 | const struct GNUNET_HashCode *key = &(msg->key); | 160 | struct GNUNET_MESSENGER_Message *message; |
161 | switch (reset) | ||
162 | { | ||
163 | case GNUNET_YES: | ||
164 | set_room_sender_id(room, id); | ||
165 | message = create_message_join (get_handle_key (handle)); | ||
166 | break; | ||
167 | case GNUNET_NO: | ||
168 | message = create_message_id (id); | ||
169 | break; | ||
170 | default: | ||
171 | break; | ||
172 | } | ||
200 | 173 | ||
201 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Closed room: %s\n", GNUNET_h2s (key)); | 174 | if (!message) |
175 | return; | ||
202 | 176 | ||
203 | close_handle_room (handle, key); | 177 | enqueue_message_to_room (room, message); |
178 | destroy_message (message); | ||
204 | } | 179 | } |
205 | 180 | ||
206 | static int | 181 | static int |
@@ -210,7 +185,10 @@ check_recv_message (void *cls, | |||
210 | const uint16_t full_length = ntohs (msg->header.size); | 185 | const uint16_t full_length = ntohs (msg->header.size); |
211 | 186 | ||
212 | if (full_length < sizeof(*msg)) | 187 | if (full_length < sizeof(*msg)) |
188 | { | ||
189 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Receiving failed: Message invalid!\n"); | ||
213 | return GNUNET_NO; | 190 | return GNUNET_NO; |
191 | } | ||
214 | 192 | ||
215 | const uint16_t length = full_length - sizeof(*msg); | 193 | const uint16_t length = full_length - sizeof(*msg); |
216 | const char *buffer = ((const char*) msg) + sizeof(*msg); | 194 | const char *buffer = ((const char*) msg) + sizeof(*msg); |
@@ -218,10 +196,16 @@ check_recv_message (void *cls, | |||
218 | struct GNUNET_MESSENGER_Message message; | 196 | struct GNUNET_MESSENGER_Message message; |
219 | 197 | ||
220 | if (length < get_message_kind_size(GNUNET_MESSENGER_KIND_UNKNOWN, GNUNET_YES)) | 198 | if (length < get_message_kind_size(GNUNET_MESSENGER_KIND_UNKNOWN, GNUNET_YES)) |
199 | { | ||
200 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Receiving failed: Message too short!\n"); | ||
221 | return GNUNET_NO; | 201 | return GNUNET_NO; |
202 | } | ||
222 | 203 | ||
223 | if (GNUNET_YES != decode_message (&message, length, buffer, GNUNET_YES, NULL)) | 204 | if (GNUNET_YES != decode_message (&message, length, buffer, GNUNET_YES, NULL)) |
205 | { | ||
206 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Receiving failed: Message decoding failed!\n"); | ||
224 | return GNUNET_NO; | 207 | return GNUNET_NO; |
208 | } | ||
225 | 209 | ||
226 | cleanup_message(&message); | 210 | cleanup_message(&message); |
227 | return GNUNET_OK; | 211 | return GNUNET_OK; |
@@ -237,7 +221,8 @@ handle_recv_message (void *cls, | |||
237 | const struct GNUNET_HashCode *sender = &(msg->sender); | 221 | const struct GNUNET_HashCode *sender = &(msg->sender); |
238 | const struct GNUNET_HashCode *context = &(msg->context); | 222 | const struct GNUNET_HashCode *context = &(msg->context); |
239 | const struct GNUNET_HashCode *hash = &(msg->hash); | 223 | const struct GNUNET_HashCode *hash = &(msg->hash); |
240 | const enum GNUNET_MESSENGER_MessageFlags flags = ( | 224 | |
225 | enum GNUNET_MESSENGER_MessageFlags flags = ( | ||
241 | (enum GNUNET_MESSENGER_MessageFlags) (msg->flags) | 226 | (enum GNUNET_MESSENGER_MessageFlags) (msg->flags) |
242 | ); | 227 | ); |
243 | 228 | ||
@@ -247,22 +232,38 @@ handle_recv_message (void *cls, | |||
247 | struct GNUNET_MESSENGER_Message message; | 232 | struct GNUNET_MESSENGER_Message message; |
248 | decode_message (&message, length, buffer, GNUNET_YES, NULL); | 233 | decode_message (&message, length, buffer, GNUNET_YES, NULL); |
249 | 234 | ||
250 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Receiving message: %s\n", GNUNET_MESSENGER_name_of_kind (message.header.kind)); | 235 | struct GNUNET_MESSENGER_Message *private_message = NULL; |
236 | if (GNUNET_MESSENGER_KIND_PRIVATE == message.header.kind) | ||
237 | { | ||
238 | private_message = copy_message(&message); | ||
251 | 239 | ||
252 | struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); | 240 | if (GNUNET_YES != decrypt_message(private_message, get_handle_key(handle))) |
241 | { | ||
242 | destroy_message(private_message); | ||
243 | private_message = NULL; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | if (private_message) | ||
248 | flags |= GNUNET_MESSENGER_FLAG_PRIVATE; | ||
249 | |||
250 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receiving message: %s\n", | ||
251 | GNUNET_MESSENGER_name_of_kind (private_message ? private_message->header.kind : message.header.kind)); | ||
252 | |||
253 | struct GNUNET_MESSENGER_Room *room = get_handle_room(handle, key); | ||
253 | 254 | ||
254 | if (room) | 255 | if (room) |
255 | { | 256 | { |
256 | struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store(handle); | 257 | struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store(handle); |
257 | 258 | ||
258 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Raw contact from sender and context: (%s : %s)\n", | 259 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Raw contact from sender and context: (%s : %s)\n", |
259 | GNUNET_h2s(sender), GNUNET_h2s_full(context)); | 260 | GNUNET_h2s(sender), GNUNET_h2s_full(context)); |
260 | 261 | ||
261 | struct GNUNET_MESSENGER_Contact *contact = get_store_contact_raw( | 262 | struct GNUNET_MESSENGER_Contact *contact = get_store_contact_raw( |
262 | store, context, sender | 263 | store, context, sender |
263 | ); | 264 | ); |
264 | 265 | ||
265 | contact = handle_room_message (room, contact, &message, hash); | 266 | contact = handle_room_message (room, contact, private_message ? private_message : &message, hash, flags); |
266 | 267 | ||
267 | const struct GNUNET_MESSENGER_Message *stored_message = get_room_message(room, hash); | 268 | const struct GNUNET_MESSENGER_Message *stored_message = get_room_message(room, hash); |
268 | 269 | ||
@@ -270,9 +271,42 @@ handle_recv_message (void *cls, | |||
270 | handle->msg_callback (handle->msg_cls, room, contact, stored_message, hash, flags); | 271 | handle->msg_callback (handle->msg_cls, room, contact, stored_message, hash, flags); |
271 | } | 272 | } |
272 | else | 273 | else |
273 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Unknown room for this client: %s\n", GNUNET_h2s (key)); | 274 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Unknown room for this client: %s\n", GNUNET_h2s (key)); |
274 | 275 | ||
275 | cleanup_message(&message); | 276 | cleanup_message(&message); |
277 | |||
278 | if (private_message) | ||
279 | destroy_message(private_message); | ||
280 | } | ||
281 | |||
282 | static void | ||
283 | handle_miss_message (void *cls, | ||
284 | const struct GNUNET_MESSENGER_GetMessage *msg) | ||
285 | { | ||
286 | struct GNUNET_MESSENGER_Handle *handle = cls; | ||
287 | |||
288 | const struct GNUNET_HashCode *key = &(msg->key); | ||
289 | const struct GNUNET_HashCode *hash = &(msg->hash); | ||
290 | |||
291 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Missing message in room: %s\n", GNUNET_h2s (hash)); | ||
292 | |||
293 | struct GNUNET_MESSENGER_Room *room = get_handle_room(handle, key); | ||
294 | |||
295 | if (!room) | ||
296 | { | ||
297 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Miss in unknown room for this client: %s\n", GNUNET_h2s (key)); | ||
298 | return; | ||
299 | } | ||
300 | |||
301 | if (!get_room_sender_id(room)) | ||
302 | return; | ||
303 | |||
304 | struct GNUNET_MESSENGER_Message *message = create_message_request (hash); | ||
305 | if (!message) | ||
306 | return; | ||
307 | |||
308 | enqueue_message_to_room (room, message); | ||
309 | destroy_message (message); | ||
276 | } | 310 | } |
277 | 311 | ||
278 | static void | 312 | static void |
@@ -282,11 +316,25 @@ static void | |||
282 | send_open_room (struct GNUNET_MESSENGER_Handle *handle, | 316 | send_open_room (struct GNUNET_MESSENGER_Handle *handle, |
283 | struct GNUNET_MESSENGER_Room *room) | 317 | struct GNUNET_MESSENGER_Room *room) |
284 | { | 318 | { |
319 | const struct GNUNET_IDENTITY_PublicKey *key = get_handle_pubkey(handle); | ||
320 | |||
285 | struct GNUNET_MESSENGER_RoomMessage *msg; | 321 | struct GNUNET_MESSENGER_RoomMessage *msg; |
286 | struct GNUNET_MQ_Envelope *env; | 322 | struct GNUNET_MQ_Envelope *env; |
287 | 323 | ||
288 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN); | 324 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Open room (%s) by member using key: %s\n", |
325 | GNUNET_h2s (&(room->key)), | ||
326 | GNUNET_IDENTITY_public_key_to_string (key)); | ||
327 | |||
328 | const ssize_t len = GNUNET_IDENTITY_public_key_get_length(key); | ||
329 | |||
330 | env = GNUNET_MQ_msg_extra(msg, len > 0 ? len : 0, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN); | ||
289 | GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key)); | 331 | GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key)); |
332 | |||
333 | char *msg_buffer = ((char*) msg) + sizeof(*msg); | ||
334 | |||
335 | if (len > 0) | ||
336 | GNUNET_IDENTITY_write_public_key_to_buffer(key, msg_buffer, len); | ||
337 | |||
290 | GNUNET_MQ_send (handle->mq, env); | 338 | GNUNET_MQ_send (handle->mq, env); |
291 | } | 339 | } |
292 | 340 | ||
@@ -295,12 +343,27 @@ send_enter_room (struct GNUNET_MESSENGER_Handle *handle, | |||
295 | struct GNUNET_MESSENGER_Room *room, | 343 | struct GNUNET_MESSENGER_Room *room, |
296 | const struct GNUNET_PeerIdentity *door) | 344 | const struct GNUNET_PeerIdentity *door) |
297 | { | 345 | { |
346 | const struct GNUNET_IDENTITY_PublicKey *key = get_handle_pubkey(handle); | ||
347 | |||
298 | struct GNUNET_MESSENGER_RoomMessage *msg; | 348 | struct GNUNET_MESSENGER_RoomMessage *msg; |
299 | struct GNUNET_MQ_Envelope *env; | 349 | struct GNUNET_MQ_Envelope *env; |
300 | 350 | ||
301 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY); | 351 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Enter room (%s) via door: %s (%s)\n", |
352 | GNUNET_h2s (&(room->key)), | ||
353 | GNUNET_i2s (door), | ||
354 | GNUNET_IDENTITY_public_key_to_string (key)); | ||
355 | |||
356 | const ssize_t len = GNUNET_IDENTITY_public_key_get_length(key); | ||
357 | |||
358 | env = GNUNET_MQ_msg_extra(msg, len > 0 ? len : 0, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY); | ||
302 | GNUNET_memcpy(&(msg->door), door, sizeof(*door)); | 359 | GNUNET_memcpy(&(msg->door), door, sizeof(*door)); |
303 | GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key)); | 360 | GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key)); |
361 | |||
362 | char *msg_buffer = ((char*) msg) + sizeof(*msg); | ||
363 | |||
364 | if (len > 0) | ||
365 | GNUNET_IDENTITY_write_public_key_to_buffer(key, msg_buffer, len); | ||
366 | |||
304 | GNUNET_MQ_send (handle->mq, env); | 367 | GNUNET_MQ_send (handle->mq, env); |
305 | } | 368 | } |
306 | 369 | ||
@@ -311,6 +374,9 @@ send_close_room (struct GNUNET_MESSENGER_Handle *handle, | |||
311 | struct GNUNET_MESSENGER_RoomMessage *msg; | 374 | struct GNUNET_MESSENGER_RoomMessage *msg; |
312 | struct GNUNET_MQ_Envelope *env; | 375 | struct GNUNET_MQ_Envelope *env; |
313 | 376 | ||
377 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Close room (%s)!\n", | ||
378 | GNUNET_h2s (&(room->key))); | ||
379 | |||
314 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE); | 380 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE); |
315 | GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key)); | 381 | GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key)); |
316 | GNUNET_MQ_send (handle->mq, env); | 382 | GNUNET_MQ_send (handle->mq, env); |
@@ -349,8 +415,9 @@ callback_reconnect (void *cls) | |||
349 | struct GNUNET_MESSENGER_Handle *handle = cls; | 415 | struct GNUNET_MESSENGER_Handle *handle = cls; |
350 | 416 | ||
351 | handle->reconnect_task = NULL; | 417 | handle->reconnect_task = NULL; |
352 | handle->reconnect_time = GNUNET_TIME_STD_BACKOFF(handle->reconnect_time) | 418 | handle->reconnect_time = GNUNET_TIME_STD_BACKOFF(handle->reconnect_time); |
353 | ; | 419 | |
420 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Reconnect messenger!\n"); | ||
354 | 421 | ||
355 | reconnect (handle); | 422 | reconnect (handle); |
356 | 423 | ||
@@ -394,14 +461,6 @@ reconnect (struct GNUNET_MESSENGER_Handle *handle) | |||
394 | { | 461 | { |
395 | const struct GNUNET_MQ_MessageHandler handlers[] = | 462 | const struct GNUNET_MQ_MessageHandler handlers[] = |
396 | { | 463 | { |
397 | GNUNET_MQ_hd_var_size( | ||
398 | get_name, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_NAME, | ||
399 | struct GNUNET_MESSENGER_NameMessage, handle | ||
400 | ), | ||
401 | GNUNET_MQ_hd_var_size( | ||
402 | get_key, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_KEY, | ||
403 | struct GNUNET_MESSENGER_KeyMessage, handle | ||
404 | ), | ||
405 | GNUNET_MQ_hd_fixed_size( | 464 | GNUNET_MQ_hd_fixed_size( |
406 | member_id, | 465 | member_id, |
407 | GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID, | 466 | GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID, |
@@ -427,6 +486,11 @@ reconnect (struct GNUNET_MESSENGER_Handle *handle) | |||
427 | GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE, | 486 | GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE, |
428 | struct GNUNET_MESSENGER_RecvMessage, handle | 487 | struct GNUNET_MESSENGER_RecvMessage, handle |
429 | ), | 488 | ), |
489 | GNUNET_MQ_hd_fixed_size( | ||
490 | miss_message, | ||
491 | GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE, | ||
492 | struct GNUNET_MESSENGER_GetMessage, handle | ||
493 | ), | ||
430 | GNUNET_MQ_handler_end() | 494 | GNUNET_MQ_handler_end() |
431 | }; | 495 | }; |
432 | 496 | ||
@@ -436,31 +500,25 @@ reconnect (struct GNUNET_MESSENGER_Handle *handle) | |||
436 | struct GNUNET_MESSENGER_Handle* | 500 | struct GNUNET_MESSENGER_Handle* |
437 | GNUNET_MESSENGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | 501 | GNUNET_MESSENGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, |
438 | const char *name, | 502 | const char *name, |
439 | GNUNET_MESSENGER_IdentityCallback identity_callback, | 503 | const struct GNUNET_IDENTITY_PrivateKey *key, |
440 | void *identity_cls, | ||
441 | GNUNET_MESSENGER_MessageCallback msg_callback, | 504 | GNUNET_MESSENGER_MessageCallback msg_callback, |
442 | void *msg_cls) | 505 | void *msg_cls) |
443 | { | 506 | { |
444 | struct GNUNET_MESSENGER_Handle *handle = create_handle (cfg, identity_callback, identity_cls, msg_callback, msg_cls); | 507 | struct GNUNET_MESSENGER_Handle *handle = create_handle (cfg, msg_callback, msg_cls); |
445 | 508 | ||
446 | reconnect (handle); | 509 | reconnect (handle); |
447 | 510 | ||
448 | if (handle->mq) | 511 | if (handle->mq) |
449 | { | 512 | { |
450 | const uint16_t name_len = name ? strlen (name) : 0; | 513 | set_handle_name (handle, name); |
514 | |||
515 | if ((!key) || (0 < GNUNET_IDENTITY_private_key_get_length (key))) | ||
516 | set_handle_key (handle, key); | ||
451 | 517 | ||
452 | struct GNUNET_MESSENGER_CreateMessage *msg; | 518 | struct GNUNET_MESSENGER_CreateMessage *msg; |
453 | struct GNUNET_MQ_Envelope *env; | 519 | struct GNUNET_MQ_Envelope *env; |
454 | 520 | ||
455 | env = GNUNET_MQ_msg_extra(msg, name_len + 1, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_CREATE); | 521 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_CREATE); |
456 | |||
457 | char *extra = ((char*) msg) + sizeof(*msg); | ||
458 | |||
459 | if (name_len) | ||
460 | GNUNET_memcpy(extra, name, name_len); | ||
461 | |||
462 | extra[name_len] = '\0'; | ||
463 | |||
464 | GNUNET_MQ_send (handle->mq, env); | 522 | GNUNET_MQ_send (handle->mq, env); |
465 | return handle; | 523 | return handle; |
466 | } | 524 | } |
@@ -471,20 +529,6 @@ GNUNET_MESSENGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
471 | } | 529 | } |
472 | } | 530 | } |
473 | 531 | ||
474 | int | ||
475 | GNUNET_MESSENGER_update (struct GNUNET_MESSENGER_Handle *handle) | ||
476 | { | ||
477 | if ((!handle) || (!get_handle_name (handle))) | ||
478 | return GNUNET_SYSERR; | ||
479 | |||
480 | struct GNUNET_MESSENGER_UpdateMessage *msg; | ||
481 | struct GNUNET_MQ_Envelope *env; | ||
482 | |||
483 | env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_UPDATE); | ||
484 | GNUNET_MQ_send (handle->mq, env); | ||
485 | return GNUNET_OK; | ||
486 | } | ||
487 | |||
488 | void | 532 | void |
489 | GNUNET_MESSENGER_disconnect (struct GNUNET_MESSENGER_Handle *handle) | 533 | GNUNET_MESSENGER_disconnect (struct GNUNET_MESSENGER_Handle *handle) |
490 | { | 534 | { |
@@ -500,6 +544,81 @@ GNUNET_MESSENGER_disconnect (struct GNUNET_MESSENGER_Handle *handle) | |||
500 | destroy_handle (handle); | 544 | destroy_handle (handle); |
501 | } | 545 | } |
502 | 546 | ||
547 | static void | ||
548 | send_message_to_room (struct GNUNET_MESSENGER_Room *room, | ||
549 | struct GNUNET_MESSENGER_Message *message, | ||
550 | const struct GNUNET_IDENTITY_PrivateKey *key) | ||
551 | { | ||
552 | const struct GNUNET_ShortHashCode *sender_id = get_room_sender_id (room); | ||
553 | |||
554 | message->header.timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); | ||
555 | |||
556 | GNUNET_memcpy (&(message->header.sender_id), sender_id, sizeof(message->header.sender_id)); | ||
557 | GNUNET_memcpy (&(message->header.previous), &(room->last_message), sizeof(message->header.previous)); | ||
558 | |||
559 | message->header.signature.type = key->type; | ||
560 | |||
561 | const uint16_t msg_length = get_message_size (message, GNUNET_YES); | ||
562 | |||
563 | struct GNUNET_MESSENGER_SendMessage *msg; | ||
564 | struct GNUNET_MQ_Envelope *env; | ||
565 | |||
566 | env = GNUNET_MQ_msg_extra( | ||
567 | msg, msg_length, | ||
568 | GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE | ||
569 | ); | ||
570 | |||
571 | GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key)); | ||
572 | |||
573 | char *msg_buffer = ((char*) msg) + sizeof(*msg); | ||
574 | encode_message (message, msg_length, msg_buffer, GNUNET_YES); | ||
575 | |||
576 | struct GNUNET_HashCode hash; | ||
577 | hash_message (message, msg_length, msg_buffer, &hash); | ||
578 | sign_message (message, msg_length, msg_buffer, &hash, key); | ||
579 | |||
580 | GNUNET_memcpy (&(room->last_message), &hash, sizeof(room->last_message)); | ||
581 | |||
582 | GNUNET_MQ_send (room->handle->mq, env); | ||
583 | } | ||
584 | |||
585 | static void | ||
586 | enqueue_message_to_room (struct GNUNET_MESSENGER_Room *room, | ||
587 | struct GNUNET_MESSENGER_Message *message) | ||
588 | { | ||
589 | const struct GNUNET_IDENTITY_PrivateKey *key = get_handle_key (room->handle); | ||
590 | |||
591 | if (GNUNET_YES == is_room_available (room)) | ||
592 | { | ||
593 | dequeue_messages_from_room (room); | ||
594 | send_message_to_room (room, message, key); | ||
595 | } | ||
596 | else | ||
597 | enqueue_to_messages(&(room->queue), key, message); | ||
598 | } | ||
599 | |||
600 | static enum GNUNET_GenericReturnValue | ||
601 | dequeue_messages_from_room (struct GNUNET_MESSENGER_Room *room) | ||
602 | { | ||
603 | struct GNUNET_MESSENGER_Message *message = NULL; | ||
604 | struct GNUNET_IDENTITY_PrivateKey key; | ||
605 | |||
606 | if (GNUNET_YES != is_room_available (room)) | ||
607 | return room->queue.head ? GNUNET_NO : GNUNET_YES; | ||
608 | |||
609 | do { | ||
610 | if (message) | ||
611 | destroy_message(message); | ||
612 | |||
613 | message = dequeue_from_messages(&(room->queue), &key); | ||
614 | |||
615 | if (message) | ||
616 | send_message_to_room(room, message, &key); | ||
617 | } while (message); | ||
618 | |||
619 | return GNUNET_YES; | ||
620 | } | ||
621 | |||
503 | const char* | 622 | const char* |
504 | GNUNET_MESSENGER_get_name (const struct GNUNET_MESSENGER_Handle *handle) | 623 | GNUNET_MESSENGER_get_name (const struct GNUNET_MESSENGER_Handle *handle) |
505 | { | 624 | { |
@@ -509,35 +628,47 @@ GNUNET_MESSENGER_get_name (const struct GNUNET_MESSENGER_Handle *handle) | |||
509 | return get_handle_name (handle); | 628 | return get_handle_name (handle); |
510 | } | 629 | } |
511 | 630 | ||
512 | int | 631 | static int |
513 | GNUNET_MESSENGER_set_name (struct GNUNET_MESSENGER_Handle *handle, | 632 | iterate_send_name_to_room (void* cls, |
514 | const char *name) | 633 | struct GNUNET_MESSENGER_Room *room, |
634 | const struct GNUNET_MESSENGER_Contact *contact) | ||
515 | { | 635 | { |
516 | if (!handle) | 636 | const struct GNUNET_MESSENGER_Handle *handle = cls; |
517 | return GNUNET_SYSERR; | ||
518 | 637 | ||
519 | const uint16_t name_len = name ? strlen (name) : 0; | 638 | if (GNUNET_YES != room->use_handle_name) |
639 | return GNUNET_YES; | ||
520 | 640 | ||
521 | struct GNUNET_MESSENGER_NameMessage *msg; | 641 | const char *name = get_handle_name(handle); |
522 | struct GNUNET_MQ_Envelope *env; | ||
523 | 642 | ||
524 | env = GNUNET_MQ_msg_extra(msg, name_len + 1, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_SET_NAME); | 643 | if (!name) |
644 | return GNUNET_YES; | ||
525 | 645 | ||
526 | char *extra = ((char*) msg) + sizeof(*msg); | 646 | struct GNUNET_MESSENGER_Message *message = create_message_name (name); |
527 | 647 | ||
528 | if (name_len) | 648 | if (!message) |
529 | GNUNET_memcpy(extra, name, name_len); | 649 | return GNUNET_NO; |
530 | 650 | ||
531 | extra[name_len] = '\0'; | 651 | enqueue_message_to_room (room, message); |
652 | destroy_message (message); | ||
653 | return GNUNET_YES; | ||
654 | } | ||
532 | 655 | ||
533 | GNUNET_MQ_send (handle->mq, env); | 656 | int |
657 | GNUNET_MESSENGER_set_name (struct GNUNET_MESSENGER_Handle *handle, | ||
658 | const char *name) | ||
659 | { | ||
660 | if (!handle) | ||
661 | return GNUNET_SYSERR; | ||
662 | |||
663 | set_handle_name (handle, strlen (name) > 0 ? name : NULL); | ||
664 | GNUNET_MESSENGER_find_rooms (handle, NULL, iterate_send_name_to_room, handle); | ||
534 | return GNUNET_YES; | 665 | return GNUNET_YES; |
535 | } | 666 | } |
536 | 667 | ||
537 | static const struct GNUNET_IDENTITY_PublicKey* | 668 | static const struct GNUNET_IDENTITY_PublicKey* |
538 | get_non_anonymous_key (const struct GNUNET_IDENTITY_PublicKey* public_key) | 669 | get_non_anonymous_key (const struct GNUNET_IDENTITY_PublicKey* public_key) |
539 | { | 670 | { |
540 | if (0 == GNUNET_memcmp(public_key, get_anonymous_public_key())) | 671 | if (0 == GNUNET_memcmp(public_key, get_anonymous_public_key ())) |
541 | return NULL; | 672 | return NULL; |
542 | 673 | ||
543 | return public_key; | 674 | return public_key; |
@@ -549,7 +680,49 @@ GNUNET_MESSENGER_get_key (const struct GNUNET_MESSENGER_Handle *handle) | |||
549 | if (!handle) | 680 | if (!handle) |
550 | return NULL; | 681 | return NULL; |
551 | 682 | ||
552 | return get_non_anonymous_key (get_handle_key (handle)); | 683 | return get_non_anonymous_key (get_handle_pubkey (handle)); |
684 | } | ||
685 | |||
686 | static int | ||
687 | iterate_send_key_to_room (void* cls, | ||
688 | struct GNUNET_MESSENGER_Room *room, | ||
689 | const struct GNUNET_MESSENGER_Contact *contact) | ||
690 | { | ||
691 | const struct GNUNET_IDENTITY_PrivateKey *key = cls; | ||
692 | |||
693 | struct GNUNET_MESSENGER_Message *message = create_message_key (key); | ||
694 | |||
695 | if (!message) | ||
696 | return GNUNET_NO; | ||
697 | |||
698 | enqueue_message_to_room (room, message); | ||
699 | destroy_message (message); | ||
700 | return GNUNET_YES; | ||
701 | } | ||
702 | |||
703 | int | ||
704 | GNUNET_MESSENGER_set_key (struct GNUNET_MESSENGER_Handle *handle, | ||
705 | const struct GNUNET_IDENTITY_PrivateKey *key) | ||
706 | { | ||
707 | if (!handle) | ||
708 | return GNUNET_SYSERR; | ||
709 | |||
710 | if (!key) | ||
711 | { | ||
712 | GNUNET_MESSENGER_find_rooms (handle, NULL, iterate_send_key_to_room, NULL); | ||
713 | set_handle_key (handle, NULL); | ||
714 | return GNUNET_YES; | ||
715 | } | ||
716 | |||
717 | if (0 >= GNUNET_IDENTITY_private_key_get_length (key)) | ||
718 | return GNUNET_SYSERR; | ||
719 | |||
720 | struct GNUNET_IDENTITY_PrivateKey priv; | ||
721 | GNUNET_memcpy (&priv, key, sizeof (priv)); | ||
722 | |||
723 | GNUNET_MESSENGER_find_rooms (handle, NULL, iterate_send_key_to_room, &priv); | ||
724 | set_handle_key (handle, &priv); | ||
725 | return GNUNET_YES; | ||
553 | } | 726 | } |
554 | 727 | ||
555 | struct GNUNET_MESSENGER_Room* | 728 | struct GNUNET_MESSENGER_Room* |
@@ -609,6 +782,14 @@ GNUNET_MESSENGER_close_room (struct GNUNET_MESSENGER_Room *room) | |||
609 | if (!room) | 782 | if (!room) |
610 | return; | 783 | return; |
611 | 784 | ||
785 | struct GNUNET_MESSENGER_Message *message = create_message_leave(); | ||
786 | |||
787 | if (message) | ||
788 | { | ||
789 | enqueue_message_to_room (room, message); | ||
790 | destroy_message (message); | ||
791 | } | ||
792 | |||
612 | send_close_room (room->handle, room); | 793 | send_close_room (room->handle, room); |
613 | } | 794 | } |
614 | 795 | ||
@@ -699,7 +880,7 @@ GNUNET_MESSENGER_contact_get_key (const struct GNUNET_MESSENGER_Contact *contact | |||
699 | 880 | ||
700 | void | 881 | void |
701 | GNUNET_MESSENGER_send_message (struct GNUNET_MESSENGER_Room *room, | 882 | GNUNET_MESSENGER_send_message (struct GNUNET_MESSENGER_Room *room, |
702 | const struct GNUNET_MESSENGER_Message *message, | 883 | struct GNUNET_MESSENGER_Message *message, |
703 | const struct GNUNET_MESSENGER_Contact *contact) | 884 | const struct GNUNET_MESSENGER_Contact *contact) |
704 | { | 885 | { |
705 | if ((!room) || (!message)) | 886 | if ((!room) || (!message)) |
@@ -717,53 +898,61 @@ GNUNET_MESSENGER_send_message (struct GNUNET_MESSENGER_Room *room, | |||
717 | break; | 898 | break; |
718 | } | 899 | } |
719 | 900 | ||
720 | ssize_t key_length = 0; | 901 | char* original_name; |
902 | char* changed_name = NULL; | ||
721 | 903 | ||
722 | if (contact) | 904 | if (GNUNET_MESSENGER_KIND_NAME != message->header.kind) |
723 | { | 905 | goto skip_naming; |
724 | const struct GNUNET_IDENTITY_PublicKey *public_key = get_non_anonymous_key ( | ||
725 | get_contact_key(contact) | ||
726 | ); | ||
727 | 906 | ||
728 | if (public_key) | 907 | original_name = message->body.name.name; |
729 | key_length = GNUNET_IDENTITY_public_key_get_length(public_key); | 908 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Apply rule for using handle name in room: %s\n", GNUNET_h2s (&(room->key))); |
730 | else | ||
731 | key_length = -1; | ||
732 | } | ||
733 | 909 | ||
734 | if (key_length < 0) | 910 | const char* handle_name = get_handle_name (room->handle); |
911 | |||
912 | if ((handle_name) && (GNUNET_YES == room->use_handle_name) && | ||
913 | ((!original_name) || (0 == strlen (original_name)))) | ||
735 | { | 914 | { |
736 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Sending message aborted: Invalid key!\n"); | 915 | changed_name = GNUNET_strdup (handle_name); |
737 | return; | 916 | message->body.name.name = changed_name; |
738 | } | 917 | } |
739 | 918 | ||
740 | const uint16_t msg_length = get_message_size (message, GNUNET_NO); | 919 | skip_naming: |
920 | if (contact) | ||
921 | { | ||
922 | const struct GNUNET_IDENTITY_PublicKey *public_key = get_non_anonymous_key ( | ||
923 | get_contact_key (contact) | ||
924 | ); | ||
741 | 925 | ||
742 | struct GNUNET_MESSENGER_SendMessage *msg; | 926 | if (!public_key) |
743 | struct GNUNET_MQ_Envelope *env; | 927 | { |
928 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Sending message aborted: Invalid key!\n"); | ||
929 | goto reset_naming; | ||
930 | } | ||
744 | 931 | ||
745 | const uint16_t length = (uint16_t) key_length + msg_length; | 932 | struct GNUNET_MESSENGER_Message *original = message; |
933 | message = copy_message(original); | ||
746 | 934 | ||
747 | env = GNUNET_MQ_msg_extra( | 935 | if (GNUNET_YES != encrypt_message (message, public_key)) |
748 | msg, length, | 936 | { |
749 | GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE | 937 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Sending message aborted: Encryption failed!\n"); |
750 | ); | ||
751 | 938 | ||
752 | GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key)); | 939 | destroy_message(message); |
940 | message = original; | ||
753 | 941 | ||
754 | msg->flags = (uint32_t) ( | 942 | goto reset_naming; |
755 | contact? GNUNET_MESSENGER_FLAG_PRIVATE : GNUNET_MESSENGER_FLAG_NONE | 943 | } |
756 | ); | 944 | } |
757 | 945 | ||
758 | char *buffer = ((char*) msg) + sizeof(*msg); | 946 | enqueue_message_to_room (room, message); |
759 | char *msg_buffer = buffer + key_length; | ||
760 | 947 | ||
761 | if (key_length > 0) | 948 | reset_naming: |
762 | GNUNET_IDENTITY_write_public_key_to_buffer(get_contact_key(contact), buffer, key_length); | 949 | if (changed_name) |
950 | GNUNET_free (changed_name); | ||
763 | 951 | ||
764 | encode_message (message, msg_length, msg_buffer, GNUNET_NO); | 952 | if (GNUNET_MESSENGER_KIND_NAME != message->header.kind) |
953 | return; | ||
765 | 954 | ||
766 | GNUNET_MQ_send (room->handle->mq, env); | 955 | message->body.name.name = original_name; |
767 | } | 956 | } |
768 | 957 | ||
769 | const struct GNUNET_MESSENGER_Message* | 958 | const struct GNUNET_MESSENGER_Message* |