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.c264
1 files changed, 199 insertions, 65 deletions
diff --git a/src/messenger/messenger_api.c b/src/messenger/messenger_api.c
index 6401b18d7..dc6d11aaf 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 GNUnet e.V. 3 Copyright (C) 2020--2021 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
@@ -29,6 +29,7 @@
29 29
30#include "messenger_api_handle.h" 30#include "messenger_api_handle.h"
31#include "messenger_api_message.h" 31#include "messenger_api_message.h"
32#include "messenger_api_util.h"
32 33
33const char* 34const char*
34GNUNET_MESSENGER_name_of_kind (enum GNUNET_MESSENGER_MessageKind kind) 35GNUNET_MESSENGER_name_of_kind (enum GNUNET_MESSENGER_MessageKind kind)
@@ -61,6 +62,8 @@ GNUNET_MESSENGER_name_of_kind (enum GNUNET_MESSENGER_MessageKind kind)
61 return "TEXT"; 62 return "TEXT";
62 case GNUNET_MESSENGER_KIND_FILE: 63 case GNUNET_MESSENGER_KIND_FILE:
63 return "FILE"; 64 return "FILE";
65 case GNUNET_MESSENGER_KIND_PRIVATE:
66 return "PRIVATE";
64 default: 67 default:
65 return "UNKNOWN"; 68 return "UNKNOWN";
66 } 69 }
@@ -82,7 +85,25 @@ handle_get_name (void *cls, const struct GNUNET_MESSENGER_NameMessage *msg)
82 85
83 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set name of handle: %s\n", name); 86 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set name of handle: %s\n", name);
84 87
85 set_handle_name (handle, strlen(name) > 0? name : NULL); 88 set_handle_name (handle, strlen (name) > 0 ? name : NULL);
89}
90
91static int
92check_get_key (void *cls, const struct GNUNET_MESSENGER_KeyMessage *msg)
93{
94 const uint16_t full_length = ntohs (msg->header.size);
95
96 if (full_length < sizeof(*msg))
97 return GNUNET_NO;
98
99 const uint16_t length = full_length - sizeof(*msg);
100 const char *buffer = ((const char*) msg) + sizeof(*msg);
101
102 struct GNUNET_IDENTITY_PublicKey pubkey;
103 if (GNUNET_IDENTITY_read_key_from_buffer(&pubkey, buffer, length) < 0)
104 return GNUNET_NO;
105
106 return GNUNET_OK;
86} 107}
87 108
88static void 109static void
@@ -90,11 +111,18 @@ handle_get_key (void *cls, const struct GNUNET_MESSENGER_KeyMessage *msg)
90{ 111{
91 struct GNUNET_MESSENGER_Handle *handle = cls; 112 struct GNUNET_MESSENGER_Handle *handle = cls;
92 113
93 const struct GNUNET_IDENTITY_PublicKey *pubkey = &(msg->pubkey); 114 const uint16_t length = ntohs (msg->header.size) - sizeof(*msg);
115 const char *buffer = ((const char*) msg) + sizeof(*msg);
116
117 struct GNUNET_IDENTITY_PublicKey pubkey;
118 if (GNUNET_IDENTITY_read_key_from_buffer(&pubkey, buffer, length) < 0)
119 return;
94 120
95 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set key of handle: %s\n", GNUNET_IDENTITY_public_key_to_string (pubkey)); 121 char* str = GNUNET_IDENTITY_public_key_to_string (&pubkey);
122 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Set key of handle: %s\n", str);
123 GNUNET_free(str);
96 124
97 set_handle_key (handle, pubkey); 125 set_handle_key (handle, &pubkey);
98 126
99 if (handle->identity_callback) 127 if (handle->identity_callback)
100 handle->identity_callback (handle->identity_cls, handle); 128 handle->identity_callback (handle->identity_cls, handle);
@@ -161,12 +189,12 @@ handle_room_close (void *cls, const struct GNUNET_MESSENGER_RoomMessage *msg)
161static int 189static int
162check_recv_message (void *cls, const struct GNUNET_MESSENGER_RecvMessage *msg) 190check_recv_message (void *cls, const struct GNUNET_MESSENGER_RecvMessage *msg)
163{ 191{
164 const uint16_t full_length = ntohs (msg->header.size) - sizeof(msg->header); 192 const uint16_t full_length = ntohs (msg->header.size);
165 193
166 if (full_length < sizeof(msg->hash)) 194 if (full_length < sizeof(*msg))
167 return GNUNET_NO; 195 return GNUNET_NO;
168 196
169 const uint16_t length = full_length - sizeof(msg->hash); 197 const uint16_t length = full_length - sizeof(*msg);
170 const char *buffer = ((const char*) msg) + sizeof(*msg); 198 const char *buffer = ((const char*) msg) + sizeof(*msg);
171 199
172 struct GNUNET_MESSENGER_Message message; 200 struct GNUNET_MESSENGER_Message message;
@@ -174,7 +202,7 @@ check_recv_message (void *cls, const struct GNUNET_MESSENGER_RecvMessage *msg)
174 if (length < sizeof(message.header)) 202 if (length < sizeof(message.header))
175 return GNUNET_NO; 203 return GNUNET_NO;
176 204
177 if (GNUNET_YES != decode_message (&message, length, buffer)) 205 if (GNUNET_YES != decode_message (&message, length, buffer, GNUNET_YES, NULL))
178 return GNUNET_NO; 206 return GNUNET_NO;
179 207
180 return GNUNET_OK; 208 return GNUNET_OK;
@@ -186,14 +214,18 @@ handle_recv_message (void *cls, const struct GNUNET_MESSENGER_RecvMessage *msg)
186 struct GNUNET_MESSENGER_Handle *handle = cls; 214 struct GNUNET_MESSENGER_Handle *handle = cls;
187 215
188 const struct GNUNET_HashCode *key = &(msg->key); 216 const struct GNUNET_HashCode *key = &(msg->key);
217 const struct GNUNET_HashCode *sender = &(msg->sender);
218 const struct GNUNET_HashCode *context = &(msg->context);
189 const struct GNUNET_HashCode *hash = &(msg->hash); 219 const struct GNUNET_HashCode *hash = &(msg->hash);
190 220 const enum GNUNET_MESSENGER_MessageFlags flags = (
191 const char *buffer = ((const char*) msg) + sizeof(*msg); 221 (enum GNUNET_MESSENGER_MessageFlags) (msg->flags)
222 );
192 223
193 const uint16_t length = ntohs (msg->header.size) - sizeof(*msg); 224 const uint16_t length = ntohs (msg->header.size) - sizeof(*msg);
225 const char *buffer = ((const char*) msg) + sizeof(*msg);
194 226
195 struct GNUNET_MESSENGER_Message message; 227 struct GNUNET_MESSENGER_Message message;
196 decode_message (&message, length, buffer); 228 decode_message (&message, length, buffer, GNUNET_YES, NULL);
197 229
198 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Receiving message: %s\n", GNUNET_MESSENGER_name_of_kind (message.header.kind)); 230 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Receiving message: %s\n", GNUNET_MESSENGER_name_of_kind (message.header.kind));
199 231
@@ -201,13 +233,22 @@ handle_recv_message (void *cls, const struct GNUNET_MESSENGER_RecvMessage *msg)
201 233
202 if (room) 234 if (room)
203 { 235 {
204 handle_room_message (room, &message, hash); 236 struct GNUNET_MESSENGER_ContactStore *store = get_handle_contact_store(handle);
237
238 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Raw contact from sender and context: (%s : %s)\n",
239 GNUNET_h2s(sender), GNUNET_h2s_full(context));
240
241 struct GNUNET_MESSENGER_Contact *contact = get_store_contact_raw(
242 store, context, sender
243 );
244
245 handle_room_message (room, contact, &message, hash);
205 246
206 if (handle->msg_callback) 247 if (handle->msg_callback)
207 handle->msg_callback (handle->msg_cls, room, &message, hash); 248 handle->msg_callback (handle->msg_cls, room, contact, &message, hash, flags);
208 } 249 }
209 else 250 else
210 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "MESSENGER ERROR: Room not found\n"); 251 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Room not found\n");
211} 252}
212 253
213static void 254static void
@@ -220,12 +261,12 @@ send_open_room (struct GNUNET_MESSENGER_Handle *handle, struct GNUNET_MESSENGER_
220 struct GNUNET_MQ_Envelope *env; 261 struct GNUNET_MQ_Envelope *env;
221 262
222 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN); 263 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN);
223 GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key)); 264 GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key));
224 GNUNET_MQ_send (handle->mq, env); 265 GNUNET_MQ_send (handle->mq, env);
225} 266}
226 267
227static void 268static void
228send_entry_room (struct GNUNET_MESSENGER_Handle *handle, struct GNUNET_MESSENGER_Room *room, 269send_enter_room (struct GNUNET_MESSENGER_Handle *handle, struct GNUNET_MESSENGER_Room *room,
229 const struct GNUNET_PeerIdentity *door) 270 const struct GNUNET_PeerIdentity *door)
230{ 271{
231 struct GNUNET_MESSENGER_RoomMessage *msg; 272 struct GNUNET_MESSENGER_RoomMessage *msg;
@@ -233,7 +274,7 @@ send_entry_room (struct GNUNET_MESSENGER_Handle *handle, struct GNUNET_MESSENGER
233 274
234 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY); 275 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY);
235 GNUNET_memcpy(&(msg->door), door, sizeof(*door)); 276 GNUNET_memcpy(&(msg->door), door, sizeof(*door));
236 GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key)); 277 GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key));
237 GNUNET_MQ_send (handle->mq, env); 278 GNUNET_MQ_send (handle->mq, env);
238} 279}
239 280
@@ -244,7 +285,7 @@ send_close_room (struct GNUNET_MESSENGER_Handle *handle, struct GNUNET_MESSENGER
244 struct GNUNET_MQ_Envelope *env; 285 struct GNUNET_MQ_Envelope *env;
245 286
246 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE); 287 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE);
247 GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key)); 288 GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key));
248 GNUNET_MQ_send (handle->mq, env); 289 GNUNET_MQ_send (handle->mq, env);
249} 290}
250 291
@@ -265,7 +306,7 @@ iterate_reset_room (void *cls, const struct GNUNET_HashCode *key, void *value)
265 { 306 {
266 GNUNET_PEER_resolve (entry->peer, &door); 307 GNUNET_PEER_resolve (entry->peer, &door);
267 308
268 send_entry_room (handle, room, &door); 309 send_enter_room (handle, room, &door);
269 310
270 entry = entry->next; 311 entry = entry->next;
271 } 312 }
@@ -303,7 +344,7 @@ callback_mq_error (void *cls, enum GNUNET_MQ_Error error)
303{ 344{
304 struct GNUNET_MESSENGER_Handle *handle = cls; 345 struct GNUNET_MESSENGER_Handle *handle = cls;
305 346
306 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "MQ ERROR: %u\n", error); 347 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "MQ_Error: %u\n", error);
307 348
308 GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, iterate_close_room, handle); 349 GNUNET_CONTAINER_multihashmap_iterate (handle->rooms, iterate_close_room, handle);
309 350
@@ -319,36 +360,45 @@ callback_mq_error (void *cls, enum GNUNET_MQ_Error error)
319static void 360static void
320reconnect (struct GNUNET_MESSENGER_Handle *handle) 361reconnect (struct GNUNET_MESSENGER_Handle *handle)
321{ 362{
322 const struct GNUNET_MQ_MessageHandler handlers[] = { GNUNET_MQ_hd_var_size( 363 const struct GNUNET_MQ_MessageHandler handlers[] =
323 get_name, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_NAME, struct GNUNET_MESSENGER_NameMessage, handle), 364 {
324 GNUNET_MQ_hd_fixed_size( 365 GNUNET_MQ_hd_var_size(
325 get_key, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_KEY, 366 get_name, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_NAME,
326 struct GNUNET_MESSENGER_KeyMessage, handle), 367 struct GNUNET_MESSENGER_NameMessage, handle
327 GNUNET_MQ_hd_fixed_size( 368 ),
328 member_id, 369 GNUNET_MQ_hd_var_size(
329 GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID, 370 get_key, GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_GET_KEY,
330 struct GNUNET_MESSENGER_MemberMessage, handle), 371 struct GNUNET_MESSENGER_KeyMessage, handle
331 GNUNET_MQ_hd_fixed_size(room_open, 372 ),
332 GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN, 373 GNUNET_MQ_hd_fixed_size(
333 struct GNUNET_MESSENGER_RoomMessage, 374 member_id,
334 handle), 375 GNUNET_MESSAGE_TYPE_MESSENGER_CONNECTION_MEMBER_ID,
335 GNUNET_MQ_hd_fixed_size(room_entry, 376 struct GNUNET_MESSENGER_MemberMessage, handle
336 GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY, 377 ),
337 struct GNUNET_MESSENGER_RoomMessage, 378 GNUNET_MQ_hd_fixed_size(
338 handle), 379 room_open,
339 GNUNET_MQ_hd_fixed_size(room_close, 380 GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_OPEN,
340 GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE, 381 struct GNUNET_MESSENGER_RoomMessage, handle
341 struct GNUNET_MESSENGER_RoomMessage, 382 ),
342 handle), 383 GNUNET_MQ_hd_fixed_size(
343 GNUNET_MQ_hd_var_size( 384 room_entry,
344 recv_message, 385 GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_ENTRY,
345 GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE, 386 struct GNUNET_MESSENGER_RoomMessage, handle
346 struct GNUNET_MESSENGER_RecvMessage, handle), 387 ),
347 GNUNET_MQ_handler_end() }; 388 GNUNET_MQ_hd_fixed_size(
348 389 room_close,
349 handle->mq = GNUNET_CLIENT_connect (handle->cfg, 390 GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_CLOSE,
350 GNUNET_MESSENGER_SERVICE_NAME, 391 struct GNUNET_MESSENGER_RoomMessage, handle
351 handlers, &callback_mq_error, handle); 392 ),
393 GNUNET_MQ_hd_var_size(
394 recv_message,
395 GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_RECV_MESSAGE,
396 struct GNUNET_MESSENGER_RecvMessage, handle
397 ),
398 GNUNET_MQ_handler_end()
399 };
400
401 handle->mq = GNUNET_CLIENT_connect (handle->cfg, GNUNET_MESSENGER_SERVICE_NAME, handlers, &callback_mq_error, handle);
352} 402}
353 403
354struct GNUNET_MESSENGER_Handle* 404struct GNUNET_MESSENGER_Handle*
@@ -389,7 +439,7 @@ GNUNET_MESSENGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, const c
389int 439int
390GNUNET_MESSENGER_update (struct GNUNET_MESSENGER_Handle *handle) 440GNUNET_MESSENGER_update (struct GNUNET_MESSENGER_Handle *handle)
391{ 441{
392 if ((!handle) || (!get_handle_name(handle))) 442 if ((!handle) || (!get_handle_name (handle)))
393 return GNUNET_SYSERR; 443 return GNUNET_SYSERR;
394 444
395 struct GNUNET_MESSENGER_UpdateMessage *msg; 445 struct GNUNET_MESSENGER_UpdateMessage *msg;
@@ -448,18 +498,30 @@ GNUNET_MESSENGER_set_name (struct GNUNET_MESSENGER_Handle *handle, const char *n
448 return GNUNET_YES; 498 return GNUNET_YES;
449} 499}
450 500
501static const struct GNUNET_IDENTITY_PublicKey*
502get_non_anonymous_key (const struct GNUNET_IDENTITY_PublicKey* public_key)
503{
504 if (0 == GNUNET_memcmp(public_key, get_anonymous_public_key()))
505 return NULL;
506
507 return public_key;
508}
509
451const struct GNUNET_IDENTITY_PublicKey* 510const struct GNUNET_IDENTITY_PublicKey*
452GNUNET_MESSENGER_get_key (const struct GNUNET_MESSENGER_Handle *handle) 511GNUNET_MESSENGER_get_key (const struct GNUNET_MESSENGER_Handle *handle)
453{ 512{
454 if (!handle) 513 if (!handle)
455 return NULL; 514 return NULL;
456 515
457 return get_handle_key (handle); 516 return get_non_anonymous_key (get_handle_key (handle));
458} 517}
459 518
460struct GNUNET_MESSENGER_Room* 519struct GNUNET_MESSENGER_Room*
461GNUNET_MESSENGER_open_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCode *key) 520GNUNET_MESSENGER_open_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_HashCode *key)
462{ 521{
522 if ((!handle) || (!key))
523 return NULL;
524
463 struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); 525 struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key);
464 526
465 if (!room) 527 if (!room)
@@ -479,9 +541,12 @@ GNUNET_MESSENGER_open_room (struct GNUNET_MESSENGER_Handle *handle, const struct
479} 541}
480 542
481struct GNUNET_MESSENGER_Room* 543struct GNUNET_MESSENGER_Room*
482GNUNET_MESSENGER_entry_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_PeerIdentity *door, 544GNUNET_MESSENGER_enter_room (struct GNUNET_MESSENGER_Handle *handle, const struct GNUNET_PeerIdentity *door,
483 const struct GNUNET_HashCode *key) 545 const struct GNUNET_HashCode *key)
484{ 546{
547 if ((!handle) || (!door) || (!key))
548 return NULL;
549
485 struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key); 550 struct GNUNET_MESSENGER_Room *room = GNUNET_CONTAINER_multihashmap_get (handle->rooms, key);
486 551
487 if (!room) 552 if (!room)
@@ -496,20 +561,26 @@ GNUNET_MESSENGER_entry_room (struct GNUNET_MESSENGER_Handle *handle, const struc
496 } 561 }
497 } 562 }
498 563
499 send_entry_room (handle, room, door); 564 send_enter_room (handle, room, door);
500 return room; 565 return room;
501} 566}
502 567
503void 568void
504GNUNET_MESSENGER_close_room (struct GNUNET_MESSENGER_Room *room) 569GNUNET_MESSENGER_close_room (struct GNUNET_MESSENGER_Room *room)
505{ 570{
571 if (!room)
572 return;
573
506 send_close_room (room->handle, room); 574 send_close_room (room->handle, room);
507} 575}
508 576
509struct GNUNET_MESSENGER_Contact* 577struct GNUNET_MESSENGER_Contact*
510GNUNET_MESSENGER_get_member (const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_ShortHashCode *id) 578GNUNET_MESSENGER_get_sender (const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash)
511{ 579{
512 return GNUNET_CONTAINER_multishortmap_get (room->members, id); 580 if ((!room) || (!hash))
581 return NULL;
582
583 return get_room_sender(room, hash);
513} 584}
514 585
515const char* 586const char*
@@ -527,23 +598,73 @@ GNUNET_MESSENGER_contact_get_key (const struct GNUNET_MESSENGER_Contact *contact
527 if (!contact) 598 if (!contact)
528 return NULL; 599 return NULL;
529 600
530 return get_contact_key (contact); 601 return get_non_anonymous_key (get_contact_key (contact));
531} 602}
532 603
533void 604void
534GNUNET_MESSENGER_send_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message) 605GNUNET_MESSENGER_send_message (struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Message *message,
606 const struct GNUNET_MESSENGER_Contact *contact)
535{ 607{
536 const uint16_t length = get_message_size (message); 608 if ((!room) || (!message))
609 return;
610
611 switch (filter_message_sending (message))
612 {
613 case GNUNET_SYSERR:
614 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Sending message aborted: This kind of message is reserved for the service!\n");
615 return;
616 case GNUNET_NO:
617 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Sending message aborted: This kind of message could cause issues!\n");
618 return;
619 default:
620 break;
621 }
622
623 ssize_t key_length = 0;
624
625 if (contact)
626 {
627 const struct GNUNET_IDENTITY_PublicKey *public_key = get_non_anonymous_key (
628 get_contact_key(contact)
629 );
630
631 if (public_key)
632 key_length = GNUNET_IDENTITY_key_get_length(public_key);
633 else
634 key_length = -1;
635 }
636
637 if (key_length < 0)
638 {
639 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Sending message aborted: Invalid key!\n");
640 return;
641 }
642
643 const uint16_t msg_length = get_message_size (message, GNUNET_NO);
537 644
538 struct GNUNET_MESSENGER_SendMessage *msg; 645 struct GNUNET_MESSENGER_SendMessage *msg;
539 struct GNUNET_MQ_Envelope *env; 646 struct GNUNET_MQ_Envelope *env;
540 647
541 env = GNUNET_MQ_msg_extra(msg, length, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE); 648 const uint16_t length = (uint16_t) key_length + msg_length;
649
650 env = GNUNET_MQ_msg_extra(
651 msg, length,
652 GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_SEND_MESSAGE
653 );
542 654
543 GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key)); 655 GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key));
656
657 msg->flags = (uint32_t) (
658 contact? GNUNET_MESSENGER_FLAG_PRIVATE : GNUNET_MESSENGER_FLAG_NONE
659 );
544 660
545 char *buffer = ((char*) msg) + sizeof(*msg); 661 char *buffer = ((char*) msg) + sizeof(*msg);
546 encode_message (message, length, buffer); 662 char *msg_buffer = buffer + key_length;
663
664 if (key_length > 0)
665 GNUNET_IDENTITY_write_key_to_buffer(get_contact_key(contact), buffer, key_length);
666
667 encode_message (message, msg_length, msg_buffer, GNUNET_NO);
547 668
548 GNUNET_MQ_send (room->handle->mq, env); 669 GNUNET_MQ_send (room->handle->mq, env);
549} 670}
@@ -551,18 +672,31 @@ GNUNET_MESSENGER_send_message (struct GNUNET_MESSENGER_Room *room, const struct
551const struct GNUNET_MESSENGER_Message* 672const struct GNUNET_MESSENGER_Message*
552GNUNET_MESSENGER_get_message (const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash) 673GNUNET_MESSENGER_get_message (const struct GNUNET_MESSENGER_Room *room, const struct GNUNET_HashCode *hash)
553{ 674{
675 if ((!room) || (!hash))
676 return NULL;
677
554 const struct GNUNET_MESSENGER_Message *message = get_room_message (room, hash); 678 const struct GNUNET_MESSENGER_Message *message = get_room_message (room, hash);
555 679
556 if (!message) 680 if (!message)
557 { 681 {
558 struct GNUNET_MESSENGER_RecvMessage *msg; 682 struct GNUNET_MESSENGER_GetMessage *msg;
559 struct GNUNET_MQ_Envelope *env; 683 struct GNUNET_MQ_Envelope *env;
560 684
561 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE); 685 env = GNUNET_MQ_msg(msg, GNUNET_MESSAGE_TYPE_MESSENGER_ROOM_GET_MESSAGE);
562 GNUNET_memcpy(&(msg->key), &(room->key), sizeof(room->key)); 686 GNUNET_memcpy(&(msg->key), &(room->key), sizeof(msg->key));
563 GNUNET_memcpy(&(msg->hash), hash, sizeof(*hash)); 687 GNUNET_memcpy(&(msg->hash), hash, sizeof(*hash));
564 GNUNET_MQ_send (room->handle->mq, env); 688 GNUNET_MQ_send (room->handle->mq, env);
565 } 689 }
566 690
567 return message; 691 return message;
568} 692}
693
694int
695GNUNET_MESSENGER_iterate_members (struct GNUNET_MESSENGER_Room *room, GNUNET_MESSENGER_MemberCallback callback,
696 void* cls)
697{
698 if (!room)
699 return GNUNET_SYSERR;
700
701 return iterate_room_members(room, callback, cls);
702}