aboutsummaryrefslogtreecommitdiff
path: root/src/messenger/messenger_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/messenger/messenger_api.c')
-rw-r--r--src/messenger/messenger_api.c547
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
35const char* 38const char*
@@ -72,135 +75,107 @@ GNUNET_MESSENGER_name_of_kind (enum GNUNET_MESSENGER_MessageKind kind)
72 } 75 }
73} 76}
74 77
75static int 78static enum GNUNET_GenericReturnValue
76check_get_name (void *cls, 79dequeue_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
83static void 81static void
84handle_get_name (void *cls, 82handle_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
96static int
97check_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
118static void 99static void
119handle_get_key (void *cls, 100handle_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
144static void 118static void
145handle_member_id (void *cls, 119handle_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
166static void 136static void
167handle_room_open (void *cls, 137enqueue_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
179static void 140static void
180handle_room_entry (void *cls, 141handle_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
193static void 154 if (!room)
194handle_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
206static int 181static 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
282static void
283handle_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
278static void 312static void
@@ -282,11 +316,25 @@ static void
282send_open_room (struct GNUNET_MESSENGER_Handle *handle, 316send_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)
436struct GNUNET_MESSENGER_Handle* 500struct GNUNET_MESSENGER_Handle*
437GNUNET_MESSENGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, 501GNUNET_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
474int
475GNUNET_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
488void 532void
489GNUNET_MESSENGER_disconnect (struct GNUNET_MESSENGER_Handle *handle) 533GNUNET_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
547static void
548send_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
585static void
586enqueue_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
600static enum GNUNET_GenericReturnValue
601dequeue_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
503const char* 622const char*
504GNUNET_MESSENGER_get_name (const struct GNUNET_MESSENGER_Handle *handle) 623GNUNET_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
512int 631static int
513GNUNET_MESSENGER_set_name (struct GNUNET_MESSENGER_Handle *handle, 632iterate_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); 656int
657GNUNET_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
537static const struct GNUNET_IDENTITY_PublicKey* 668static const struct GNUNET_IDENTITY_PublicKey*
538get_non_anonymous_key (const struct GNUNET_IDENTITY_PublicKey* public_key) 669get_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
686static int
687iterate_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
703int
704GNUNET_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
555struct GNUNET_MESSENGER_Room* 728struct 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
700void 881void
701GNUNET_MESSENGER_send_message (struct GNUNET_MESSENGER_Room *room, 882GNUNET_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); 919skip_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) 948reset_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
769const struct GNUNET_MESSENGER_Message* 958const struct GNUNET_MESSENGER_Message*