diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-02-06 23:27:01 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-02-06 23:27:01 +0000 |
commit | a0b3e179abb44828f76843739487b2686b14cc8e (patch) | |
tree | 52b2cfb63a66b13ce39bd1bf8bed04ff74ae102a | |
parent | 7b3d9e8f57db9db2053dd7e25c9dbd92514819e0 (diff) | |
download | gnunet-a0b3e179abb44828f76843739487b2686b14cc8e.tar.gz gnunet-a0b3e179abb44828f76843739487b2686b14cc8e.zip |
more chat code from Mantis #1657
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | src/chat/Makefile.am | 82 | ||||
-rw-r--r-- | src/chat/chat.c | 96 | ||||
-rw-r--r-- | src/chat/chat.h | 38 | ||||
-rw-r--r-- | src/chat/gnunet-chat.c | 120 | ||||
-rw-r--r-- | src/chat/gnunet-service-chat.c | 257 | ||||
-rw-r--r-- | src/core/core.h | 2 | ||||
-rw-r--r-- | src/include/gnunet_chat_service.h | 21 |
8 files changed, 503 insertions, 114 deletions
@@ -8,6 +8,7 @@ Nathan Evans <evans@net.in.tum.de> | |||
8 | Nils Durner <durner@gnunet.org> | 8 | Nils Durner <durner@gnunet.org> |
9 | Safey Allah Mohammed <safey.allah@gmail.com> | 9 | Safey Allah Mohammed <safey.allah@gmail.com> |
10 | Philipp Tölke <toelke@in.tum.de> | 10 | Philipp Tölke <toelke@in.tum.de> |
11 | Vitaly Minko <vitaly.minko@gmail.com> | ||
11 | 12 | ||
12 | Code contributions also came from: | 13 | Code contributions also came from: |
13 | Adam Warrington [ UPnP ] | 14 | Adam Warrington [ UPnP ] |
diff --git a/src/chat/Makefile.am b/src/chat/Makefile.am index ad099e6b1..f10796c23 100644 --- a/src/chat/Makefile.am +++ b/src/chat/Makefile.am | |||
@@ -37,3 +37,85 @@ gnunet_chat_LDADD = \ | |||
37 | $(top_builddir)/src/chat/libgnunetchat.la \ | 37 | $(top_builddir)/src/chat/libgnunetchat.la \ |
38 | $(top_builddir)/src/util/libgnunetutil.la \ | 38 | $(top_builddir)/src/util/libgnunetutil.la \ |
39 | $(GN_LIBINTL) | 39 | $(GN_LIBINTL) |
40 | |||
41 | check_PROGRAMS = \ | ||
42 | test_chat \ | ||
43 | test_chat_acknowledgement \ | ||
44 | test_chat_anonymous \ | ||
45 | test_chat_authentication \ | ||
46 | test_chat_p2p \ | ||
47 | test_chat_acknowledgement_p2p \ | ||
48 | test_chat_anonymous_p2p \ | ||
49 | test_chat_authentication_p2p \ | ||
50 | test_chat_private \ | ||
51 | test_chat_private_p2p | ||
52 | |||
53 | if !DISABLE_TEST_RUN | ||
54 | TESTS = $(check_PROGRAMS) | ||
55 | endif | ||
56 | |||
57 | test_chat_SOURCES = \ | ||
58 | test_chat.c | ||
59 | test_chat_LDADD = \ | ||
60 | $(top_builddir)/src/chat/libgnunetchat.la \ | ||
61 | $(top_builddir)/src/util/libgnunetutil.la | ||
62 | |||
63 | test_chat_acknowledgement_SOURCES = \ | ||
64 | test_chat.c | ||
65 | test_chat_acknowledgement_LDADD = \ | ||
66 | $(top_builddir)/src/chat/libgnunetchat.la \ | ||
67 | $(top_builddir)/src/util/libgnunetutil.la | ||
68 | |||
69 | test_chat_anonymous_SOURCES = \ | ||
70 | test_chat.c | ||
71 | test_chat_anonymous_LDADD = \ | ||
72 | $(top_builddir)/src/chat/libgnunetchat.la \ | ||
73 | $(top_builddir)/src/util/libgnunetutil.la | ||
74 | |||
75 | test_chat_authentication_SOURCES = \ | ||
76 | test_chat.c | ||
77 | test_chat_authentication_LDADD = \ | ||
78 | $(top_builddir)/src/chat/libgnunetchat.la \ | ||
79 | $(top_builddir)/src/util/libgnunetutil.la | ||
80 | |||
81 | test_chat_p2p_SOURCES = \ | ||
82 | test_chat.c | ||
83 | test_chat_p2p_LDADD = \ | ||
84 | $(top_builddir)/src/chat/libgnunetchat.la \ | ||
85 | $(top_builddir)/src/util/libgnunetutil.la | ||
86 | |||
87 | test_chat_acknowledgement_p2p_SOURCES = \ | ||
88 | test_chat.c | ||
89 | test_chat_acknowledgement_p2p_LDADD = \ | ||
90 | $(top_builddir)/src/chat/libgnunetchat.la \ | ||
91 | $(top_builddir)/src/util/libgnunetutil.la | ||
92 | |||
93 | test_chat_anonymous_p2p_SOURCES = \ | ||
94 | test_chat.c | ||
95 | test_chat_anonymous_p2p_LDADD = \ | ||
96 | $(top_builddir)/src/chat/libgnunetchat.la \ | ||
97 | $(top_builddir)/src/util/libgnunetutil.la | ||
98 | |||
99 | test_chat_authentication_p2p_SOURCES = \ | ||
100 | test_chat.c | ||
101 | test_chat_authentication_p2p_LDADD = \ | ||
102 | $(top_builddir)/src/chat/libgnunetchat.la \ | ||
103 | $(top_builddir)/src/util/libgnunetutil.la | ||
104 | |||
105 | test_chat_private_SOURCES = \ | ||
106 | test_chat_private.c | ||
107 | test_chat_private_LDADD = \ | ||
108 | $(top_builddir)/src/chat/libgnunetchat.la \ | ||
109 | $(top_builddir)/src/util/libgnunetutil.la | ||
110 | |||
111 | test_chat_private_p2p_SOURCES = \ | ||
112 | test_chat_private.c | ||
113 | test_chat_private_p2p_LDADD = \ | ||
114 | $(top_builddir)/src/chat/libgnunetchat.la \ | ||
115 | $(top_builddir)/src/util/libgnunetutil.la | ||
116 | |||
117 | EXTRA_DIST = \ | ||
118 | test_chat_data.conf \ | ||
119 | test_chat_peer1.conf \ | ||
120 | test_chat_peer2.conf \ | ||
121 | test_chat_peer3.conf | ||
diff --git a/src/chat/chat.c b/src/chat/chat.c index da1237d84..f3e3470a0 100644 --- a/src/chat/chat.c +++ b/src/chat/chat.c | |||
@@ -32,12 +32,12 @@ | |||
32 | #include "gnunet_signatures.h" | 32 | #include "gnunet_signatures.h" |
33 | #include "chat.h" | 33 | #include "chat.h" |
34 | 34 | ||
35 | #define DEBUG_CHAT GNUNET_YES | 35 | #define DEBUG_CHAT GNUNET_NO |
36 | #define NICK_IDENTITY_PREFIX ".chat_identity_" | 36 | #define NICK_IDENTITY_PREFIX ".chat_identity_" |
37 | 37 | ||
38 | 38 | ||
39 | /** | 39 | /** |
40 | * Handle for a (joined) chat room. | 40 | * Handle for a chat room. |
41 | */ | 41 | */ |
42 | struct GNUNET_CHAT_Room | 42 | struct GNUNET_CHAT_Room |
43 | { | 43 | { |
@@ -53,6 +53,12 @@ struct GNUNET_CHAT_Room | |||
53 | 53 | ||
54 | struct MemberList *members; | 54 | struct MemberList *members; |
55 | 55 | ||
56 | int is_joined; | ||
57 | |||
58 | GNUNET_CHAT_JoinCallback join_callback; | ||
59 | |||
60 | void *join_callback_cls; | ||
61 | |||
56 | GNUNET_CHAT_MessageCallback message_callback; | 62 | GNUNET_CHAT_MessageCallback message_callback; |
57 | 63 | ||
58 | void *message_callback_cls; | 64 | void *message_callback_cls; |
@@ -221,7 +227,9 @@ process_result (struct GNUNET_CHAT_Room *room, | |||
221 | struct JoinNotificationMessage *join_msg; | 227 | struct JoinNotificationMessage *join_msg; |
222 | struct ReceiveNotificationMessage *received_msg; | 228 | struct ReceiveNotificationMessage *received_msg; |
223 | struct ConfirmationReceiptMessage *receipt; | 229 | struct ConfirmationReceiptMessage *receipt; |
230 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey; | ||
224 | GNUNET_HashCode id; | 231 | GNUNET_HashCode id; |
232 | const GNUNET_HashCode *sender; | ||
225 | struct GNUNET_CONTAINER_MetaData *meta; | 233 | struct GNUNET_CONTAINER_MetaData *meta; |
226 | struct GNUNET_CHAT_SendReceiptContext *src; | 234 | struct GNUNET_CHAT_SendReceiptContext *src; |
227 | struct MemberList *pos; | 235 | struct MemberList *pos; |
@@ -261,11 +269,30 @@ process_result (struct GNUNET_CHAT_Room *room, | |||
261 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), | 269 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), |
262 | &pos->id); | 270 | &pos->id); |
263 | GNUNET_PSEUDONYM_add (room->cfg, &pos->id, meta); | 271 | GNUNET_PSEUDONYM_add (room->cfg, &pos->id, meta); |
272 | pos->next = room->members; | ||
273 | room->members = pos; | ||
274 | if (GNUNET_NO == room->is_joined) | ||
275 | { | ||
276 | GNUNET_CRYPTO_rsa_key_get_public (room->my_private_key, &pkey); | ||
277 | if (0 == memcmp (&join_msg->public_key, | ||
278 | &pkey, | ||
279 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded))) | ||
280 | { | ||
281 | room->join_callback (room->join_callback_cls); | ||
282 | room->is_joined = GNUNET_YES; | ||
283 | } | ||
284 | else | ||
285 | { | ||
286 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
287 | _("The current user must be the the first one joined\n")); | ||
288 | GNUNET_break (0); | ||
289 | return; | ||
290 | } | ||
291 | } | ||
292 | else | ||
264 | room->member_list_callback (room->member_list_callback_cls, | 293 | room->member_list_callback (room->member_list_callback_cls, |
265 | meta, &join_msg->public_key, | 294 | meta, &join_msg->public_key, |
266 | ntohl (join_msg->msg_options)); | 295 | ntohl (join_msg->msg_options)); |
267 | pos->next = room->members; | ||
268 | room->members = pos; | ||
269 | break; | 296 | break; |
270 | case GNUNET_MESSAGE_TYPE_CHAT_LEAVE_NOTIFICATION: | 297 | case GNUNET_MESSAGE_TYPE_CHAT_LEAVE_NOTIFICATION: |
271 | #if DEBUG_CHAT | 298 | #if DEBUG_CHAT |
@@ -347,6 +374,13 @@ process_result (struct GNUNET_CHAT_Room *room, | |||
347 | memcpy (message_content, &received_msg[1], msg_len); | 374 | memcpy (message_content, &received_msg[1], msg_len); |
348 | } | 375 | } |
349 | message_content[msg_len] = '\0'; | 376 | message_content[msg_len] = '\0'; |
377 | if (0 != (ntohl (received_msg->msg_options) & GNUNET_CHAT_MSG_ANONYMOUS)) | ||
378 | { | ||
379 | sender = NULL; | ||
380 | meta = NULL; | ||
381 | } | ||
382 | else | ||
383 | { | ||
350 | pos = room->members; | 384 | pos = room->members; |
351 | while ((NULL != pos) && | 385 | while ((NULL != pos) && |
352 | (0 != memcmp (&pos->id, | 386 | (0 != memcmp (&pos->id, |
@@ -354,11 +388,15 @@ process_result (struct GNUNET_CHAT_Room *room, | |||
354 | sizeof (GNUNET_HashCode)))) | 388 | sizeof (GNUNET_HashCode)))) |
355 | pos = pos->next; | 389 | pos = pos->next; |
356 | GNUNET_assert (NULL != pos); | 390 | GNUNET_assert (NULL != pos); |
391 | sender = &received_msg->sender; | ||
392 | meta = pos->meta; | ||
393 | } | ||
357 | room->message_callback (room->message_callback_cls, | 394 | room->message_callback (room->message_callback_cls, |
358 | room, | 395 | room, |
359 | &received_msg->sender, | 396 | sender, |
360 | pos->meta, | 397 | meta, |
361 | message_content, | 398 | message_content, |
399 | GNUNET_TIME_absolute_ntoh (received_msg->timestamp), | ||
362 | ntohl (received_msg->msg_options)); | 400 | ntohl (received_msg->msg_options)); |
363 | if (message_content != decrypted_msg) | 401 | if (message_content != decrypted_msg) |
364 | GNUNET_free (message_content); | 402 | GNUNET_free (message_content); |
@@ -378,9 +416,7 @@ process_result (struct GNUNET_CHAT_Room *room, | |||
378 | room, | 416 | room, |
379 | ntohl (receipt->sequence_number), | 417 | ntohl (receipt->sequence_number), |
380 | GNUNET_TIME_absolute_ntoh (receipt->timestamp), | 418 | GNUNET_TIME_absolute_ntoh (receipt->timestamp), |
381 | &receipt->target, | 419 | &receipt->target); |
382 | &receipt->content, | ||
383 | &receipt->signature); | ||
384 | break; | 420 | break; |
385 | default: | 421 | default: |
386 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 422 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
@@ -510,8 +546,9 @@ transmit_join_request (void *cls, | |||
510 | { | 546 | { |
511 | #if DEBUG_CHAT | 547 | #if DEBUG_CHAT |
512 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 548 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
513 | "Could not transmit join request\n"); | 549 | "Could not transmit join request, retrying...\n"); |
514 | #endif | 550 | #endif |
551 | GNUNET_CHAT_rejoin_room (chat_room); | ||
515 | return 0; | 552 | return 0; |
516 | } | 553 | } |
517 | #if DEBUG_CHAT | 554 | #if DEBUG_CHAT |
@@ -542,6 +579,10 @@ transmit_join_request (void *cls, | |||
542 | _("Could not serialize metadata\n")); | 579 | _("Could not serialize metadata\n")); |
543 | return 0; | 580 | return 0; |
544 | } | 581 | } |
582 | GNUNET_CLIENT_receive (chat_room->client, | ||
583 | &receive_results, | ||
584 | chat_room, | ||
585 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
545 | return size_of_join; | 586 | return size_of_join; |
546 | } | 587 | } |
547 | 588 | ||
@@ -623,6 +664,8 @@ GNUNET_CHAT_join_room (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
623 | struct GNUNET_CONTAINER_MetaData *member_info, | 664 | struct GNUNET_CONTAINER_MetaData *member_info, |
624 | const char *room_name, | 665 | const char *room_name, |
625 | enum GNUNET_CHAT_MsgOptions msg_options, | 666 | enum GNUNET_CHAT_MsgOptions msg_options, |
667 | GNUNET_CHAT_JoinCallback joinCallback, | ||
668 | void *join_cls, | ||
626 | GNUNET_CHAT_MessageCallback messageCallback, | 669 | GNUNET_CHAT_MessageCallback messageCallback, |
627 | void *message_cls, | 670 | void *message_cls, |
628 | GNUNET_CHAT_MemberListCallback memberCallback, | 671 | GNUNET_CHAT_MemberListCallback memberCallback, |
@@ -654,11 +697,32 @@ GNUNET_CHAT_join_room (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
654 | _("Failed to connect to the chat service\n")); | 697 | _("Failed to connect to the chat service\n")); |
655 | return NULL; | 698 | return NULL; |
656 | } | 699 | } |
700 | if (NULL == joinCallback) | ||
701 | { | ||
702 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
703 | _("Undefined mandatory parameter: joinCallback\n")); | ||
704 | return NULL; | ||
705 | } | ||
706 | if (NULL == messageCallback) | ||
707 | { | ||
708 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
709 | _("Undefined mandatory parameter: messageCallback\n")); | ||
710 | return NULL; | ||
711 | } | ||
712 | if (NULL == memberCallback) | ||
713 | { | ||
714 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
715 | _("Undefined mandatory parameter: memberCallback\n")); | ||
716 | return NULL; | ||
717 | } | ||
657 | chat_room = GNUNET_malloc (sizeof (struct GNUNET_CHAT_Room)); | 718 | chat_room = GNUNET_malloc (sizeof (struct GNUNET_CHAT_Room)); |
658 | chat_room->msg_options = msg_options; | 719 | chat_room->msg_options = msg_options; |
659 | chat_room->room_name = GNUNET_strdup (room_name); | 720 | chat_room->room_name = GNUNET_strdup (room_name); |
660 | chat_room->member_info = GNUNET_CONTAINER_meta_data_duplicate (member_info); | 721 | chat_room->member_info = GNUNET_CONTAINER_meta_data_duplicate (member_info); |
661 | chat_room->my_private_key = priv_key; | 722 | chat_room->my_private_key = priv_key; |
723 | chat_room->is_joined = GNUNET_NO; | ||
724 | chat_room->join_callback = joinCallback; | ||
725 | chat_room->join_callback_cls = join_cls; | ||
662 | chat_room->message_callback = messageCallback; | 726 | chat_room->message_callback = messageCallback; |
663 | chat_room->message_callback_cls = message_cls; | 727 | chat_room->message_callback_cls = message_cls; |
664 | chat_room->member_list_callback = memberCallback; | 728 | chat_room->member_list_callback = memberCallback; |
@@ -668,10 +732,6 @@ GNUNET_CHAT_join_room (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
668 | chat_room->cfg = cfg; | 732 | chat_room->cfg = cfg; |
669 | chat_room->client = client; | 733 | chat_room->client = client; |
670 | chat_room->members = NULL; | 734 | chat_room->members = NULL; |
671 | GNUNET_CLIENT_receive (client, | ||
672 | &receive_results, | ||
673 | chat_room, | ||
674 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
675 | if (GNUNET_SYSERR == GNUNET_CHAT_rejoin_room (chat_room)) | 735 | if (GNUNET_SYSERR == GNUNET_CHAT_rejoin_room (chat_room)) |
676 | { | 736 | { |
677 | GNUNET_CHAT_leave_room (chat_room); | 737 | GNUNET_CHAT_leave_room (chat_room); |
@@ -717,6 +777,8 @@ transmit_send_request (void *cls, | |||
717 | msg_to_send->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_TRANSMIT_REQUEST); | 777 | msg_to_send->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_TRANSMIT_REQUEST); |
718 | msg_to_send->msg_options = htonl (smc->options); | 778 | msg_to_send->msg_options = htonl (smc->options); |
719 | msg_to_send->sequence_number = htonl (smc->sequence_number); | 779 | msg_to_send->sequence_number = htonl (smc->sequence_number); |
780 | msg_to_send->timestamp = | ||
781 | GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ()); | ||
720 | msg_to_send->reserved = htonl (0); | 782 | msg_to_send->reserved = htonl (0); |
721 | if (NULL == smc->receiver) | 783 | if (NULL == smc->receiver) |
722 | memset (&msg_to_send->target, 0, sizeof (GNUNET_HashCode)); | 784 | memset (&msg_to_send->target, 0, sizeof (GNUNET_HashCode)); |
@@ -770,13 +832,15 @@ GNUNET_CHAT_send_message (struct GNUNET_CHAT_Room *room, | |||
770 | #if DEBUG_CHAT | 832 | #if DEBUG_CHAT |
771 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending a message\n"); | 833 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending a message\n"); |
772 | #endif | 834 | #endif |
773 | *sequence_number = ++room->sequence_number; | 835 | room->sequence_number++; |
836 | if (NULL != sequence_number) | ||
837 | *sequence_number = room->sequence_number; | ||
774 | smc = GNUNET_malloc (sizeof (struct GNUNET_CHAT_SendMessageContext)); | 838 | smc = GNUNET_malloc (sizeof (struct GNUNET_CHAT_SendMessageContext)); |
775 | smc->chat_room = room; | 839 | smc->chat_room = room; |
776 | smc->message = GNUNET_strdup (message); | 840 | smc->message = GNUNET_strdup (message); |
777 | smc->options = options; | 841 | smc->options = options; |
778 | smc->receiver = receiver; | 842 | smc->receiver = receiver; |
779 | smc->sequence_number = *sequence_number; | 843 | smc->sequence_number = room->sequence_number; |
780 | msg_size = strlen (message) + sizeof (struct TransmitRequestMessage); | 844 | msg_size = strlen (message) + sizeof (struct TransmitRequestMessage); |
781 | GNUNET_CLIENT_notify_transmit_ready (room->client, | 845 | GNUNET_CLIENT_notify_transmit_ready (room->client, |
782 | msg_size, | 846 | msg_size, |
diff --git a/src/chat/chat.h b/src/chat/chat.h index a9cf83a8c..9a52a2d75 100644 --- a/src/chat/chat.h +++ b/src/chat/chat.h | |||
@@ -70,8 +70,13 @@ struct ReceiveNotificationMessage | |||
70 | uint32_t reserved GNUNET_PACKED; | 70 | uint32_t reserved GNUNET_PACKED; |
71 | 71 | ||
72 | /** | 72 | /** |
73 | * Timestamp of the message. | ||
74 | */ | ||
75 | struct GNUNET_TIME_AbsoluteNBO timestamp; | ||
76 | |||
77 | /** | ||
73 | * Hash of the public key of the pseudonym of the sender of the message. | 78 | * Hash of the public key of the pseudonym of the sender of the message. |
74 | * TBD: Should be all zeros for anonymous. | 79 | * Should be all zeros for anonymous. |
75 | */ | 80 | */ |
76 | GNUNET_HashCode sender; | 81 | GNUNET_HashCode sender; |
77 | 82 | ||
@@ -122,6 +127,11 @@ struct TransmitRequestMessage | |||
122 | uint32_t sequence_number GNUNET_PACKED; | 127 | uint32_t sequence_number GNUNET_PACKED; |
123 | 128 | ||
124 | /** | 129 | /** |
130 | * Timestamp of the message. | ||
131 | */ | ||
132 | struct GNUNET_TIME_AbsoluteNBO timestamp; | ||
133 | |||
134 | /** | ||
125 | * Who should receive this message? Set to all zeros for "everyone". | 135 | * Who should receive this message? Set to all zeros for "everyone". |
126 | */ | 136 | */ |
127 | GNUNET_HashCode target; | 137 | GNUNET_HashCode target; |
@@ -131,12 +141,15 @@ struct TransmitRequestMessage | |||
131 | 141 | ||
132 | /** | 142 | /** |
133 | * Receipt sent from a message receiver to the service to confirm delivery of | 143 | * Receipt sent from a message receiver to the service to confirm delivery of |
134 | * a chat message. | 144 | * a chat message and from the service to sender of the original message to |
145 | * acknowledge delivery. | ||
135 | */ | 146 | */ |
136 | struct ConfirmationReceiptMessage | 147 | struct ConfirmationReceiptMessage |
137 | { | 148 | { |
138 | /** | 149 | /** |
139 | * Message type will be GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_RECEIPT | 150 | * Message type will be |
151 | * GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_RECEIPT when sending from client, | ||
152 | * GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_NOTIFICATION when sending to client. | ||
140 | */ | 153 | */ |
141 | struct GNUNET_MessageHeader header; | 154 | struct GNUNET_MessageHeader header; |
142 | 155 | ||
@@ -351,8 +364,9 @@ struct P2PLeaveNotificationMessage | |||
351 | 364 | ||
352 | /** | 365 | /** |
353 | * Message send by one peer to another to indicate receiving of a chat message. | 366 | * Message send by one peer to another to indicate receiving of a chat message. |
354 | * After this struct, the remaining bytes are the actual text message. If the | 367 | * This struct is followed by the room name (only if the message is anonymous) |
355 | * mesasge is private, then the text is encrypted, otherwise it's plaintext. | 368 | * and then the remaining bytes are the actual text message. If the mesasge is |
369 | * private, then the text is encrypted, otherwise it's plaintext. | ||
356 | */ | 370 | */ |
357 | struct P2PReceiveNotificationMessage | 371 | struct P2PReceiveNotificationMessage |
358 | { | 372 | { |
@@ -372,13 +386,23 @@ struct P2PReceiveNotificationMessage | |||
372 | uint32_t sequence_number GNUNET_PACKED; | 386 | uint32_t sequence_number GNUNET_PACKED; |
373 | 387 | ||
374 | /** | 388 | /** |
389 | * Length of the room name. This is only used for anonymous messages. | ||
390 | */ | ||
391 | uint16_t room_name_len GNUNET_PACKED; | ||
392 | |||
393 | /** | ||
375 | * Reserved (for alignment). | 394 | * Reserved (for alignment). |
376 | */ | 395 | */ |
377 | uint32_t reserved GNUNET_PACKED; | 396 | uint16_t reserved GNUNET_PACKED; |
397 | |||
398 | /** | ||
399 | * Timestamp of the message. | ||
400 | */ | ||
401 | struct GNUNET_TIME_AbsoluteNBO timestamp; | ||
378 | 402 | ||
379 | /** | 403 | /** |
380 | * Hash of the public key of the pseudonym of the sender of the message | 404 | * Hash of the public key of the pseudonym of the sender of the message |
381 | * TBD: Should be all zeros for anonymous. | 405 | * Should be all zeros for anonymous. |
382 | */ | 406 | */ |
383 | GNUNET_HashCode sender; | 407 | GNUNET_HashCode sender; |
384 | 408 | ||
diff --git a/src/chat/gnunet-chat.c b/src/chat/gnunet-chat.c index 450996382..22bdcc237 100644 --- a/src/chat/gnunet-chat.c +++ b/src/chat/gnunet-chat.c | |||
@@ -78,6 +78,20 @@ static int do_help (const char *args, const void *xtra); | |||
78 | 78 | ||
79 | 79 | ||
80 | /** | 80 | /** |
81 | * Callback used for notification that we have joined the room. | ||
82 | * | ||
83 | * @param cls closure | ||
84 | * @return GNUNET_OK | ||
85 | */ | ||
86 | static int | ||
87 | join_cb (void *cls) | ||
88 | { | ||
89 | fprintf (stdout, _("Joined\n")); | ||
90 | return GNUNET_OK; | ||
91 | } | ||
92 | |||
93 | |||
94 | /** | ||
81 | * Callback used for notification about incoming messages. | 95 | * Callback used for notification about incoming messages. |
82 | * | 96 | * |
83 | * @param cls closure, NULL | 97 | * @param cls closure, NULL |
@@ -93,11 +107,13 @@ static int | |||
93 | receive_cb (void *cls, | 107 | receive_cb (void *cls, |
94 | struct GNUNET_CHAT_Room *room, | 108 | struct GNUNET_CHAT_Room *room, |
95 | const GNUNET_HashCode *sender, | 109 | const GNUNET_HashCode *sender, |
96 | const struct GNUNET_CONTAINER_MetaData *meta, | 110 | const struct GNUNET_CONTAINER_MetaData *member_info, |
97 | const char *message, | 111 | const char *message, |
112 | struct GNUNET_TIME_Absolute timestamp, | ||
98 | enum GNUNET_CHAT_MsgOptions options) | 113 | enum GNUNET_CHAT_MsgOptions options) |
99 | { | 114 | { |
100 | char *nick; | 115 | char *nick; |
116 | char *time; | ||
101 | const char *fmt; | 117 | const char *fmt; |
102 | 118 | ||
103 | if (NULL != sender) | 119 | if (NULL != sender) |
@@ -109,43 +125,43 @@ receive_cb (void *cls, | |||
109 | { | 125 | { |
110 | case GNUNET_CHAT_MSG_OPTION_NONE: | 126 | case GNUNET_CHAT_MSG_OPTION_NONE: |
111 | case GNUNET_CHAT_MSG_ANONYMOUS: | 127 | case GNUNET_CHAT_MSG_ANONYMOUS: |
112 | fmt = _("`%s' said: %s\n"); | 128 | fmt = _("(%s) `%s' said: %s\n"); |
113 | break; | 129 | break; |
114 | case GNUNET_CHAT_MSG_PRIVATE: | 130 | case GNUNET_CHAT_MSG_PRIVATE: |
115 | fmt = _("`%s' said to you: %s\n"); | 131 | fmt = _("(%s) `%s' said to you: %s\n"); |
116 | break; | 132 | break; |
117 | case GNUNET_CHAT_MSG_PRIVATE | GNUNET_CHAT_MSG_ANONYMOUS: | 133 | case GNUNET_CHAT_MSG_PRIVATE | GNUNET_CHAT_MSG_ANONYMOUS: |
118 | fmt = _("`%s' said to you: %s\n"); | 134 | fmt = _("(%s) `%s' said to you: %s\n"); |
119 | break; | 135 | break; |
120 | case GNUNET_CHAT_MSG_AUTHENTICATED: | 136 | case GNUNET_CHAT_MSG_AUTHENTICATED: |
121 | fmt = _("`%s' said for sure: %s\n"); | 137 | fmt = _("(%s) `%s' said for sure: %s\n"); |
122 | break; | 138 | break; |
123 | case GNUNET_CHAT_MSG_PRIVATE | GNUNET_CHAT_MSG_AUTHENTICATED: | 139 | case GNUNET_CHAT_MSG_PRIVATE | GNUNET_CHAT_MSG_AUTHENTICATED: |
124 | fmt = _("`%s' said to you for sure: %s\n"); | 140 | fmt = _("(%s) `%s' said to you for sure: %s\n"); |
125 | break; | 141 | break; |
126 | case GNUNET_CHAT_MSG_ACKNOWLEDGED: | 142 | case GNUNET_CHAT_MSG_ACKNOWLEDGED: |
127 | fmt = _("`%s' was confirmed that you received: %s\n"); | 143 | fmt = _("(%s) `%s' was confirmed that you received: %s\n"); |
128 | break; | 144 | break; |
129 | case GNUNET_CHAT_MSG_PRIVATE | GNUNET_CHAT_MSG_ACKNOWLEDGED: | 145 | case GNUNET_CHAT_MSG_PRIVATE | GNUNET_CHAT_MSG_ACKNOWLEDGED: |
130 | fmt = _("`%s' was confirmed that you and only you received: %s\n"); | 146 | fmt = _("(%s) `%s' was confirmed that you and only you received: %s\n"); |
131 | break; | 147 | break; |
132 | case GNUNET_CHAT_MSG_AUTHENTICATED | GNUNET_CHAT_MSG_ACKNOWLEDGED: | 148 | case GNUNET_CHAT_MSG_AUTHENTICATED | GNUNET_CHAT_MSG_ACKNOWLEDGED: |
133 | fmt = _("`%s' was confirmed that you received from him or her: %s\n"); | 149 | fmt = _("(%s) `%s' was confirmed that you received from him or her: %s\n"); |
134 | break; | 150 | break; |
135 | case GNUNET_CHAT_MSG_AUTHENTICATED | GNUNET_CHAT_MSG_PRIVATE | GNUNET_CHAT_MSG_ACKNOWLEDGED: | 151 | case GNUNET_CHAT_MSG_AUTHENTICATED | GNUNET_CHAT_MSG_PRIVATE | GNUNET_CHAT_MSG_ACKNOWLEDGED: |
136 | fmt = | 152 | fmt = _("(%s) `%s' was confirmed that you and only you received from him or her: %s\n"); |
137 | _ | ||
138 | ("`%s' was confirmed that you and only you received from him or her: %s\n"); | ||
139 | break; | 153 | break; |
140 | case GNUNET_CHAT_MSG_OFF_THE_RECORD: | 154 | case GNUNET_CHAT_MSG_OFF_THE_RECORD: |
141 | fmt = _("`%s' said off the record: %s\n"); | 155 | fmt = _("(%s) `%s' said off the record: %s\n"); |
142 | break; | 156 | break; |
143 | default: | 157 | default: |
144 | fmt = _("<%s> said using an unknown message type: %s\n"); | 158 | fmt = _("(%s) <%s> said using an unknown message type: %s\n"); |
145 | break; | 159 | break; |
146 | } | 160 | } |
147 | fprintf (stdout, fmt, nick, message); | 161 | time = GNUNET_STRINGS_absolute_time_to_string (timestamp); |
162 | fprintf (stdout, fmt, time, nick, message); | ||
148 | GNUNET_free (nick); | 163 | GNUNET_free (nick); |
164 | GNUNET_free (time); | ||
149 | return GNUNET_OK; | 165 | return GNUNET_OK; |
150 | } | 166 | } |
151 | 167 | ||
@@ -168,9 +184,7 @@ confirmation_cb (void *cls, | |||
168 | struct GNUNET_CHAT_Room *room, | 184 | struct GNUNET_CHAT_Room *room, |
169 | uint32_t orig_seq_number, | 185 | uint32_t orig_seq_number, |
170 | struct GNUNET_TIME_Absolute timestamp, | 186 | struct GNUNET_TIME_Absolute timestamp, |
171 | const GNUNET_HashCode *receiver, | 187 | const GNUNET_HashCode *receiver) |
172 | const GNUNET_HashCode *msg_hash, | ||
173 | const struct GNUNET_CRYPTO_RsaSignature *receipt) | ||
174 | { | 188 | { |
175 | char *nick; | 189 | char *nick; |
176 | 190 | ||
@@ -248,18 +262,6 @@ member_list_cb (void *cls, | |||
248 | 262 | ||
249 | 263 | ||
250 | static int | 264 | static int |
251 | do_transmit (const char *msg, const void *xtra) | ||
252 | { | ||
253 | uint32_t seq; | ||
254 | GNUNET_CHAT_send_message (room, | ||
255 | msg, | ||
256 | GNUNET_CHAT_MSG_OPTION_NONE, | ||
257 | NULL, &seq); | ||
258 | return GNUNET_OK; | ||
259 | } | ||
260 | |||
261 | |||
262 | static int | ||
263 | do_join (const char *arg, const void *xtra) | 265 | do_join (const char *arg, const void *xtra) |
264 | { | 266 | { |
265 | char *my_name; | 267 | char *my_name; |
@@ -276,6 +278,7 @@ do_join (const char *arg, const void *xtra) | |||
276 | meta, | 278 | meta, |
277 | room_name, | 279 | room_name, |
278 | -1, | 280 | -1, |
281 | &join_cb, NULL, | ||
279 | &receive_cb, NULL, | 282 | &receive_cb, NULL, |
280 | &member_list_cb, NULL, | 283 | &member_list_cb, NULL, |
281 | &confirmation_cb, NULL, &me); | 284 | &confirmation_cb, NULL, &me); |
@@ -285,7 +288,7 @@ do_join (const char *arg, const void *xtra) | |||
285 | return GNUNET_SYSERR; | 288 | return GNUNET_SYSERR; |
286 | } | 289 | } |
287 | my_name = GNUNET_PSEUDONYM_id_to_name (cfg, &me); | 290 | my_name = GNUNET_PSEUDONYM_id_to_name (cfg, &me); |
288 | fprintf (stdout, _("Joined room `%s' as user `%s'\n"), room_name, my_name); | 291 | fprintf (stdout, _("Joining room `%s' as user `%s'...\n"), room_name, my_name); |
289 | GNUNET_free (my_name); | 292 | GNUNET_free (my_name); |
290 | return GNUNET_OK; | 293 | return GNUNET_OK; |
291 | } | 294 | } |
@@ -315,6 +318,7 @@ do_nick (const char *msg, const void *xtra) | |||
315 | meta, | 318 | meta, |
316 | room_name, | 319 | room_name, |
317 | -1, | 320 | -1, |
321 | &join_cb, NULL, | ||
318 | &receive_cb, NULL, | 322 | &receive_cb, NULL, |
319 | &member_list_cb, NULL, | 323 | &member_list_cb, NULL, |
320 | &confirmation_cb, NULL, &me); | 324 | &confirmation_cb, NULL, &me); |
@@ -355,7 +359,19 @@ do_names (const char *msg, const void *xtra) | |||
355 | 359 | ||
356 | 360 | ||
357 | static int | 361 | static int |
358 | do_pm (const char *msg, const void *xtra) | 362 | do_send (const char *msg, const void *xtra) |
363 | { | ||
364 | uint32_t seq; | ||
365 | GNUNET_CHAT_send_message (room, | ||
366 | msg, | ||
367 | GNUNET_CHAT_MSG_OPTION_NONE, | ||
368 | NULL, &seq); | ||
369 | return GNUNET_OK; | ||
370 | } | ||
371 | |||
372 | |||
373 | static int | ||
374 | do_send_pm (const char *msg, const void *xtra) | ||
359 | { | 375 | { |
360 | char *user; | 376 | char *user; |
361 | GNUNET_HashCode uid; | 377 | GNUNET_HashCode uid; |
@@ -404,7 +420,7 @@ do_pm (const char *msg, const void *xtra) | |||
404 | 420 | ||
405 | 421 | ||
406 | static int | 422 | static int |
407 | do_transmit_sig (const char *msg, const void *xtra) | 423 | do_send_sig (const char *msg, const void *xtra) |
408 | { | 424 | { |
409 | uint32_t seq; | 425 | uint32_t seq; |
410 | GNUNET_CHAT_send_message (room, | 426 | GNUNET_CHAT_send_message (room, |
@@ -416,7 +432,7 @@ do_transmit_sig (const char *msg, const void *xtra) | |||
416 | 432 | ||
417 | 433 | ||
418 | static int | 434 | static int |
419 | do_transmit_ack (const char *msg, const void *xtra) | 435 | do_send_ack (const char *msg, const void *xtra) |
420 | { | 436 | { |
421 | uint32_t seq; | 437 | uint32_t seq; |
422 | GNUNET_CHAT_send_message (room, | 438 | GNUNET_CHAT_send_message (room, |
@@ -428,6 +444,18 @@ do_transmit_ack (const char *msg, const void *xtra) | |||
428 | 444 | ||
429 | 445 | ||
430 | static int | 446 | static int |
447 | do_send_anonymous (const char *msg, const void *xtra) | ||
448 | { | ||
449 | uint32_t seq; | ||
450 | GNUNET_CHAT_send_message (room, | ||
451 | msg, | ||
452 | GNUNET_CHAT_MSG_ANONYMOUS, | ||
453 | NULL, &seq); | ||
454 | return GNUNET_OK; | ||
455 | } | ||
456 | |||
457 | |||
458 | static int | ||
431 | do_quit (const char *args, const void *xtra) | 459 | do_quit (const char *args, const void *xtra) |
432 | { | 460 | { |
433 | return GNUNET_SYSERR; | 461 | return GNUNET_SYSERR; |
@@ -454,19 +482,24 @@ static struct ChatCommand commands[] = { | |||
454 | gettext_noop | 482 | gettext_noop |
455 | ("Use `/nick nickname' to change your nickname. This will cause you to" | 483 | ("Use `/nick nickname' to change your nickname. This will cause you to" |
456 | " leave the current room and immediately rejoin it with the new name.")}, | 484 | " leave the current room and immediately rejoin it with the new name.")}, |
457 | {"/msg ", &do_pm, | 485 | {"/msg ", &do_send_pm, |
458 | gettext_noop | 486 | gettext_noop |
459 | ("Use `/msg nickname message' to send a private message to the specified" | 487 | ("Use `/msg nickname message' to send a private message to the specified" |
460 | " user")}, | 488 | " user")}, |
461 | {"/notice ", &do_pm, | 489 | {"/notice ", &do_send_pm, |
462 | gettext_noop ("The `/notice' command is an alias for `/msg'")}, | 490 | gettext_noop ("The `/notice' command is an alias for `/msg'")}, |
463 | {"/query ", &do_pm, | 491 | {"/query ", &do_send_pm, |
464 | gettext_noop ("The `/query' command is an alias for `/msg'")}, | 492 | gettext_noop ("The `/query' command is an alias for `/msg'")}, |
465 | {"/sig ", &do_transmit_sig, | 493 | {"/sig ", &do_send_sig, |
466 | gettext_noop ("Use `/sig message' to send a signed public message")}, | 494 | gettext_noop ("Use `/sig message' to send a signed public message")}, |
467 | {"/ack ", &do_transmit_ack, | 495 | {"/ack ", &do_send_ack, |
468 | gettext_noop | 496 | gettext_noop |
469 | ("Use `/ack message' to require signed acknowledgment of the message")}, | 497 | ("Use `/ack message' to require signed acknowledgment of the message")}, |
498 | {"/anonymous ", &do_send_anonymous, | ||
499 | gettext_noop | ||
500 | ("Use `/anonymous message' to send a public anonymous message")}, | ||
501 | {"/anon ", &do_send_anonymous, | ||
502 | gettext_noop ("The `/anon' command is an alias for `/anonymous'")}, | ||
470 | {"/quit", &do_quit, | 503 | {"/quit", &do_quit, |
471 | gettext_noop ("Use `/quit' to terminate gnunet-chat")}, | 504 | gettext_noop ("Use `/quit' to terminate gnunet-chat")}, |
472 | {"/leave", &do_quit, | 505 | {"/leave", &do_quit, |
@@ -479,13 +512,9 @@ static struct ChatCommand commands[] = { | |||
479 | /* Add standard commands: | 512 | /* Add standard commands: |
480 | /whois (print metadata), | 513 | /whois (print metadata), |
481 | /ignore (set flag, check on receive!) */ | 514 | /ignore (set flag, check on receive!) */ |
482 | /* Add special commands (currently supported): | ||
483 | + anonymous msgs | ||
484 | + authenticated msgs | ||
485 | */ | ||
486 | /* the following three commands must be last! */ | 515 | /* the following three commands must be last! */ |
487 | {"/", &do_unknown, NULL}, | 516 | {"/", &do_unknown, NULL}, |
488 | {"", &do_transmit, NULL}, | 517 | {"", &do_send, NULL}, |
489 | {NULL, NULL, NULL}, | 518 | {NULL, NULL, NULL}, |
490 | }; | 519 | }; |
491 | 520 | ||
@@ -615,6 +644,7 @@ run (void *cls, | |||
615 | meta, | 644 | meta, |
616 | room_name, | 645 | room_name, |
617 | -1, | 646 | -1, |
647 | &join_cb, NULL, | ||
618 | &receive_cb, NULL, | 648 | &receive_cb, NULL, |
619 | &member_list_cb, NULL, | 649 | &member_list_cb, NULL, |
620 | &confirmation_cb, NULL, &me); | 650 | &confirmation_cb, NULL, &me); |
@@ -628,7 +658,7 @@ run (void *cls, | |||
628 | return; | 658 | return; |
629 | } | 659 | } |
630 | my_name = GNUNET_PSEUDONYM_id_to_name (cfg, &me); | 660 | my_name = GNUNET_PSEUDONYM_id_to_name (cfg, &me); |
631 | fprintf (stdout, _("Joined room `%s' as user `%s'\n"), room_name, my_name); | 661 | fprintf (stdout, _("Joining room `%s' as user `%s'...\n"), room_name, my_name); |
632 | GNUNET_free (my_name); | 662 | GNUNET_free (my_name); |
633 | handle_cmd_task = | 663 | handle_cmd_task = |
634 | GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_UI, | 664 | GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_UI, |
diff --git a/src/chat/gnunet-service-chat.c b/src/chat/gnunet-service-chat.c index e0a46abc4..69318e4e8 100644 --- a/src/chat/gnunet-service-chat.c +++ b/src/chat/gnunet-service-chat.c | |||
@@ -33,9 +33,10 @@ | |||
33 | #include "gnunet_signatures.h" | 33 | #include "gnunet_signatures.h" |
34 | #include "chat.h" | 34 | #include "chat.h" |
35 | 35 | ||
36 | #define DEBUG_CHAT_SERVICE GNUNET_YES | 36 | #define DEBUG_CHAT_SERVICE GNUNET_NO |
37 | #define MAX_TRANSMIT_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) | 37 | #define MAX_TRANSMIT_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 60) |
38 | #define QUEUE_SIZE 16 | 38 | #define QUEUE_SIZE 16 |
39 | #define MAX_ANONYMOUS_MSG_LIST_LENGTH 16 | ||
39 | 40 | ||
40 | 41 | ||
41 | /** | 42 | /** |
@@ -93,6 +94,20 @@ struct ChatClient | |||
93 | 94 | ||
94 | }; | 95 | }; |
95 | 96 | ||
97 | /** | ||
98 | * Linked list of recent anonymous messages. | ||
99 | */ | ||
100 | struct AnonymousMessage | ||
101 | { | ||
102 | struct AnonymousMessage *next; | ||
103 | |||
104 | /** | ||
105 | * Hash of the message. | ||
106 | */ | ||
107 | GNUNET_HashCode hash; | ||
108 | |||
109 | }; | ||
110 | |||
96 | 111 | ||
97 | /** | 112 | /** |
98 | * Handle to the core service (NULL until we've connected to it). | 113 | * Handle to the core service (NULL until we've connected to it). |
@@ -119,6 +134,56 @@ static struct ChatClient *client_list_head = NULL; | |||
119 | */ | 134 | */ |
120 | struct GNUNET_SERVER_NotificationContext *nc = NULL; | 135 | struct GNUNET_SERVER_NotificationContext *nc = NULL; |
121 | 136 | ||
137 | /** | ||
138 | * Head of the list of recent anonymous messages. | ||
139 | */ | ||
140 | static struct AnonymousMessage *anonymous_list_head = NULL; | ||
141 | |||
142 | |||
143 | static void | ||
144 | remember_anonymous_message (const struct P2PReceiveNotificationMessage *p2p_rnmsg) | ||
145 | { | ||
146 | static GNUNET_HashCode hash; | ||
147 | struct AnonymousMessage *anon_msg; | ||
148 | struct AnonymousMessage *prev; | ||
149 | int anon_list_len; | ||
150 | |||
151 | GNUNET_CRYPTO_hash (p2p_rnmsg, ntohs (p2p_rnmsg->header.size), &hash); | ||
152 | anon_msg = GNUNET_malloc (sizeof (struct AnonymousMessage)); | ||
153 | anon_msg->hash = hash; | ||
154 | anon_msg->next = anonymous_list_head; | ||
155 | anonymous_list_head = anon_msg; | ||
156 | anon_list_len = 1; | ||
157 | prev = NULL; | ||
158 | while ((NULL != anon_msg->next)) | ||
159 | { | ||
160 | prev = anon_msg; | ||
161 | anon_msg = anon_msg->next; | ||
162 | anon_list_len++; | ||
163 | } | ||
164 | if (anon_list_len == MAX_ANONYMOUS_MSG_LIST_LENGTH) | ||
165 | { | ||
166 | GNUNET_free (anon_msg); | ||
167 | if (NULL != prev) | ||
168 | prev->next = NULL; | ||
169 | } | ||
170 | } | ||
171 | |||
172 | |||
173 | static int | ||
174 | lookup_anonymous_message (const struct P2PReceiveNotificationMessage *p2p_rnmsg) | ||
175 | { | ||
176 | static GNUNET_HashCode hash; | ||
177 | struct AnonymousMessage *anon_msg; | ||
178 | |||
179 | GNUNET_CRYPTO_hash (p2p_rnmsg, ntohs (p2p_rnmsg->header.size), &hash); | ||
180 | anon_msg = anonymous_list_head; | ||
181 | while ((NULL != anon_msg) && | ||
182 | (0 != memcmp (&anon_msg->hash, &hash, sizeof (GNUNET_HashCode)))) | ||
183 | anon_msg = anon_msg->next; | ||
184 | return (NULL != anon_msg); | ||
185 | } | ||
186 | |||
122 | 187 | ||
123 | /** | 188 | /** |
124 | * Transmit a message notification to the peer. | 189 | * Transmit a message notification to the peer. |
@@ -141,9 +206,17 @@ transmit_message_notification_to_peer (void *cls, | |||
141 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 206 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
142 | "Transmitting P2P message notification\n"); | 207 | "Transmitting P2P message notification\n"); |
143 | #endif | 208 | #endif |
209 | if (buf == NULL) | ||
210 | { | ||
211 | /* client disconnected */ | ||
212 | #if DEBUG_CHAT_SERVICE | ||
213 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
214 | "Buffer is NULL, dropping the message\n"); | ||
215 | #endif | ||
216 | return 0; | ||
217 | } | ||
144 | msg_size = ntohs (my_msg->header.size); | 218 | msg_size = ntohs (my_msg->header.size); |
145 | GNUNET_assert (size >= msg_size); | 219 | GNUNET_assert (size >= msg_size); |
146 | GNUNET_assert (NULL != buf); | ||
147 | memcpy (m, my_msg, msg_size); | 220 | memcpy (m, my_msg, msg_size); |
148 | GNUNET_free (my_msg); | 221 | GNUNET_free (my_msg); |
149 | return msg_size; | 222 | return msg_size; |
@@ -205,8 +278,10 @@ handle_transmit_request (void *cls, | |||
205 | struct GNUNET_CRYPTO_AesSessionKey key; | 278 | struct GNUNET_CRYPTO_AesSessionKey key; |
206 | char encrypted_msg[MAX_MESSAGE_LENGTH]; | 279 | char encrypted_msg[MAX_MESSAGE_LENGTH]; |
207 | const char *room; | 280 | const char *room; |
281 | size_t room_len; | ||
208 | int msg_len; | 282 | int msg_len; |
209 | int priv_msg; | 283 | int is_priv; |
284 | int is_anon; | ||
210 | 285 | ||
211 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Client sent a chat message\n"); | 286 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Client sent a chat message\n"); |
212 | if (ntohs (message->size) <= sizeof (struct TransmitRequestMessage)) | 287 | if (ntohs (message->size) <= sizeof (struct TransmitRequestMessage)) |
@@ -218,8 +293,8 @@ handle_transmit_request (void *cls, | |||
218 | } | 293 | } |
219 | trmsg = (const struct TransmitRequestMessage *) message; | 294 | trmsg = (const struct TransmitRequestMessage *) message; |
220 | msg_len = ntohs (trmsg->header.size) - sizeof (struct TransmitRequestMessage); | 295 | msg_len = ntohs (trmsg->header.size) - sizeof (struct TransmitRequestMessage); |
221 | priv_msg = (ntohl (trmsg->msg_options) & GNUNET_CHAT_MSG_PRIVATE) != 0; | 296 | is_priv = (0 != (ntohl (trmsg->msg_options) & GNUNET_CHAT_MSG_PRIVATE)); |
222 | if (priv_msg) | 297 | if (is_priv) |
223 | { | 298 | { |
224 | #if DEBUG_CHAT_SERVICE | 299 | #if DEBUG_CHAT_SERVICE |
225 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting the message text\n"); | 300 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting the message text\n"); |
@@ -244,7 +319,7 @@ handle_transmit_request (void *cls, | |||
244 | msg_len); | 319 | msg_len); |
245 | rnmsg->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_MESSAGE_NOTIFICATION); | 320 | rnmsg->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_MESSAGE_NOTIFICATION); |
246 | rnmsg->msg_options = trmsg->msg_options; | 321 | rnmsg->msg_options = trmsg->msg_options; |
247 | rnmsg->sequence_number = trmsg->sequence_number; | 322 | rnmsg->timestamp = trmsg->timestamp; |
248 | pos = client_list_head; | 323 | pos = client_list_head; |
249 | while ((NULL != pos) && (pos->client != client)) | 324 | while ((NULL != pos) && (pos->client != client)) |
250 | pos = pos->next; | 325 | pos = pos->next; |
@@ -260,11 +335,18 @@ handle_transmit_request (void *cls, | |||
260 | } | 335 | } |
261 | room = pos->room; | 336 | room = pos->room; |
262 | pos->msg_sequence_number = ntohl (trmsg->sequence_number); | 337 | pos->msg_sequence_number = ntohl (trmsg->sequence_number); |
263 | if (0 == (ntohl (trmsg->msg_options) & GNUNET_CHAT_MSG_ANONYMOUS)) | 338 | is_anon = (0 != (ntohl (trmsg->msg_options) & GNUNET_CHAT_MSG_ANONYMOUS)); |
264 | rnmsg->sender = pos->id; | 339 | if (is_anon) |
265 | else | 340 | { |
266 | memset (&rnmsg->sender, 0, sizeof (GNUNET_HashCode)); | 341 | memset (&rnmsg->sender, 0, sizeof (GNUNET_HashCode)); |
267 | if (priv_msg) | 342 | rnmsg->sequence_number = 0; |
343 | } | ||
344 | else | ||
345 | { | ||
346 | rnmsg->sender = pos->id; | ||
347 | rnmsg->sequence_number = trmsg->sequence_number; | ||
348 | } | ||
349 | if (is_priv) | ||
268 | { | 350 | { |
269 | #if DEBUG_CHAT_SERVICE | 351 | #if DEBUG_CHAT_SERVICE |
270 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 352 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -323,7 +405,7 @@ handle_transmit_request (void *cls, | |||
323 | (NULL != pos->client) && | 405 | (NULL != pos->client) && |
324 | (pos->client != client)) | 406 | (pos->client != client)) |
325 | { | 407 | { |
326 | if (((!priv_msg) || | 408 | if (((!is_priv) || |
327 | (0 == memcmp (&trmsg->target, | 409 | (0 == memcmp (&trmsg->target, |
328 | &pos->id, | 410 | &pos->id, |
329 | sizeof (GNUNET_HashCode)))) && | 411 | sizeof (GNUNET_HashCode)))) && |
@@ -341,16 +423,25 @@ handle_transmit_request (void *cls, | |||
341 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 423 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
342 | "Broadcasting message to neighbour peers\n"); | 424 | "Broadcasting message to neighbour peers\n"); |
343 | #endif | 425 | #endif |
426 | if (is_anon) | ||
427 | { | ||
428 | room_len = strlen (room); | ||
429 | p2p_rnmsg = GNUNET_malloc (sizeof (struct P2PReceiveNotificationMessage) + | ||
430 | msg_len + room_len); | ||
431 | p2p_rnmsg->header.size = | ||
432 | htons (sizeof (struct P2PReceiveNotificationMessage) + msg_len + | ||
433 | room_len); | ||
434 | p2p_rnmsg->room_name_len = htons (room_len); | ||
435 | memcpy ((char *) &p2p_rnmsg[1], room, room_len); | ||
436 | memcpy ((char *) &p2p_rnmsg[1] + room_len, &trmsg[1], msg_len); | ||
437 | } | ||
438 | else | ||
439 | { | ||
344 | p2p_rnmsg = GNUNET_malloc (sizeof (struct P2PReceiveNotificationMessage) + | 440 | p2p_rnmsg = GNUNET_malloc (sizeof (struct P2PReceiveNotificationMessage) + |
345 | msg_len); | 441 | msg_len); |
346 | p2p_rnmsg->header.size = htons (sizeof (struct P2PReceiveNotificationMessage) + | 442 | p2p_rnmsg->header.size = |
347 | msg_len); | 443 | htons (sizeof (struct P2PReceiveNotificationMessage) + msg_len); |
348 | p2p_rnmsg->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_P2P_MESSAGE_NOTIFICATION); | 444 | if (is_priv) |
349 | p2p_rnmsg->msg_options = trmsg->msg_options; | ||
350 | p2p_rnmsg->sequence_number = trmsg->sequence_number; | ||
351 | memcpy (&p2p_rnmsg->sender, &rnmsg->sender, sizeof (GNUNET_HashCode)); | ||
352 | p2p_rnmsg->target = trmsg->target; | ||
353 | if (priv_msg) | ||
354 | { | 445 | { |
355 | memcpy (&p2p_rnmsg[1], encrypted_msg, msg_len); | 446 | memcpy (&p2p_rnmsg[1], encrypted_msg, msg_len); |
356 | memcpy (&p2p_rnmsg->encrypted_key, | 447 | memcpy (&p2p_rnmsg->encrypted_key, |
@@ -358,9 +449,17 @@ handle_transmit_request (void *cls, | |||
358 | sizeof (struct GNUNET_CRYPTO_RsaEncryptedData)); | 449 | sizeof (struct GNUNET_CRYPTO_RsaEncryptedData)); |
359 | } | 450 | } |
360 | else | 451 | else |
361 | { | ||
362 | memcpy (&p2p_rnmsg[1], &trmsg[1], msg_len); | 452 | memcpy (&p2p_rnmsg[1], &trmsg[1], msg_len); |
363 | } | 453 | } |
454 | p2p_rnmsg->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_P2P_MESSAGE_NOTIFICATION); | ||
455 | p2p_rnmsg->msg_options = trmsg->msg_options; | ||
456 | p2p_rnmsg->sequence_number = trmsg->sequence_number; | ||
457 | p2p_rnmsg->timestamp = trmsg->timestamp; | ||
458 | p2p_rnmsg->reserved = 0; | ||
459 | p2p_rnmsg->sender = rnmsg->sender; | ||
460 | p2p_rnmsg->target = trmsg->target; | ||
461 | if (is_anon) | ||
462 | remember_anonymous_message (p2p_rnmsg); | ||
364 | GNUNET_CORE_iterate_peers (cfg, | 463 | GNUNET_CORE_iterate_peers (cfg, |
365 | &send_message_noficiation, | 464 | &send_message_noficiation, |
366 | p2p_rnmsg); | 465 | p2p_rnmsg); |
@@ -591,9 +690,17 @@ transmit_confirmation_receipt_to_peer (void *cls, | |||
591 | "Transmitting P2P confirmation receipt to '%s'\n", | 690 | "Transmitting P2P confirmation receipt to '%s'\n", |
592 | GNUNET_h2s (&receipt->target)); | 691 | GNUNET_h2s (&receipt->target)); |
593 | #endif | 692 | #endif |
693 | if (buf == NULL) | ||
694 | { | ||
695 | /* client disconnected */ | ||
696 | #if DEBUG_CHAT_SERVICE | ||
697 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
698 | "Buffer is NULL, dropping the message\n"); | ||
699 | #endif | ||
700 | return 0; | ||
701 | } | ||
594 | msg_size = sizeof (struct P2PConfirmationReceiptMessage); | 702 | msg_size = sizeof (struct P2PConfirmationReceiptMessage); |
595 | GNUNET_assert (size >= msg_size); | 703 | GNUNET_assert (size >= msg_size); |
596 | GNUNET_assert (NULL != buf); | ||
597 | memcpy (buf, receipt, msg_size); | 704 | memcpy (buf, receipt, msg_size); |
598 | GNUNET_free (receipt); | 705 | GNUNET_free (receipt); |
599 | return msg_size; | 706 | return msg_size; |
@@ -765,9 +872,17 @@ transmit_leave_notification_to_peer (void *cls, | |||
765 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 872 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
766 | "Transmitting P2P leave notification\n"); | 873 | "Transmitting P2P leave notification\n"); |
767 | #endif | 874 | #endif |
875 | if (buf == NULL) | ||
876 | { | ||
877 | /* client disconnected */ | ||
878 | #if DEBUG_CHAT_SERVICE | ||
879 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
880 | "Buffer is NULL, dropping the message\n"); | ||
881 | #endif | ||
882 | return 0; | ||
883 | } | ||
768 | msg_size = sizeof (struct P2PLeaveNotificationMessage); | 884 | msg_size = sizeof (struct P2PLeaveNotificationMessage); |
769 | GNUNET_assert (size >= msg_size); | 885 | GNUNET_assert (size >= msg_size); |
770 | GNUNET_assert (NULL != buf); | ||
771 | m = buf; | 886 | m = buf; |
772 | m->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_P2P_LEAVE_NOTIFICATION); | 887 | m->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_P2P_LEAVE_NOTIFICATION); |
773 | m->header.size = htons (msg_size); | 888 | m->header.size = htons (msg_size); |
@@ -787,7 +902,6 @@ send_leave_noficiation (void *cls, | |||
787 | const struct GNUNET_TRANSPORT_ATS_Information *atsi) | 902 | const struct GNUNET_TRANSPORT_ATS_Information *atsi) |
788 | { | 903 | { |
789 | struct ChatClient *entry = cls; | 904 | struct ChatClient *entry = cls; |
790 | struct GNUNET_CORE_TransmitHandle *th; | ||
791 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key; | 905 | struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key; |
792 | size_t msg_size; | 906 | size_t msg_size; |
793 | 907 | ||
@@ -806,14 +920,15 @@ send_leave_noficiation (void *cls, | |||
806 | msg_size = sizeof (struct P2PLeaveNotificationMessage); | 920 | msg_size = sizeof (struct P2PLeaveNotificationMessage); |
807 | public_key = GNUNET_memdup (&entry->public_key, | 921 | public_key = GNUNET_memdup (&entry->public_key, |
808 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); | 922 | sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); |
809 | th = GNUNET_CORE_notify_transmit_ready (core, | 923 | if (NULL == GNUNET_CORE_notify_transmit_ready (core, |
810 | 1, | 924 | 1, |
811 | MAX_TRANSMIT_DELAY, | 925 | MAX_TRANSMIT_DELAY, |
812 | peer, | 926 | peer, |
813 | msg_size, | 927 | msg_size, |
814 | &transmit_leave_notification_to_peer, | 928 | &transmit_leave_notification_to_peer, |
815 | public_key); | 929 | public_key)) |
816 | GNUNET_assert (NULL != th); | 930 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
931 | _("Failed to queue a leave notification\n")); | ||
817 | } | 932 | } |
818 | } | 933 | } |
819 | 934 | ||
@@ -1108,8 +1223,12 @@ handle_p2p_message_notification (void *cls, | |||
1108 | struct ChatClient *sender; | 1223 | struct ChatClient *sender; |
1109 | struct ChatClient *pos; | 1224 | struct ChatClient *pos; |
1110 | static GNUNET_HashCode all_zeros; | 1225 | static GNUNET_HashCode all_zeros; |
1111 | int priv_msg; | 1226 | int is_priv; |
1227 | int is_anon; | ||
1112 | uint16_t msg_len; | 1228 | uint16_t msg_len; |
1229 | uint16_t room_name_len; | ||
1230 | char *room_name = NULL; | ||
1231 | char *text; | ||
1113 | 1232 | ||
1114 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Got P2P message notification\n"); | 1233 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Got P2P message notification\n"); |
1115 | if (ntohs (message->size) <= sizeof (struct P2PReceiveNotificationMessage)) | 1234 | if (ntohs (message->size) <= sizeof (struct P2PReceiveNotificationMessage)) |
@@ -1119,6 +1238,37 @@ handle_p2p_message_notification (void *cls, | |||
1119 | return GNUNET_SYSERR; | 1238 | return GNUNET_SYSERR; |
1120 | } | 1239 | } |
1121 | p2p_rnmsg = (const struct P2PReceiveNotificationMessage *) message; | 1240 | p2p_rnmsg = (const struct P2PReceiveNotificationMessage *) message; |
1241 | msg_len = ntohs (p2p_rnmsg->header.size) - | ||
1242 | sizeof (struct P2PReceiveNotificationMessage); | ||
1243 | |||
1244 | is_anon = (0 != (ntohl (p2p_rnmsg->msg_options) & GNUNET_CHAT_MSG_ANONYMOUS)); | ||
1245 | if (is_anon) | ||
1246 | { | ||
1247 | room_name_len = ntohs (p2p_rnmsg->room_name_len); | ||
1248 | if (msg_len <= room_name_len) | ||
1249 | { | ||
1250 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1251 | "Malformed message: wrong length of the room name\n"); | ||
1252 | GNUNET_break_op (0); | ||
1253 | return GNUNET_SYSERR; | ||
1254 | } | ||
1255 | msg_len -= room_name_len; | ||
1256 | if (lookup_anonymous_message (p2p_rnmsg)) | ||
1257 | { | ||
1258 | #if DEBUG_CHAT_SERVICE | ||
1259 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1260 | "This anonymous message has already been handled."); | ||
1261 | #endif | ||
1262 | return GNUNET_OK; | ||
1263 | } | ||
1264 | remember_anonymous_message (p2p_rnmsg); | ||
1265 | room_name = GNUNET_malloc (room_name_len + 1); | ||
1266 | memcpy (room_name, (char *) &p2p_rnmsg[1], room_name_len); | ||
1267 | room_name[room_name_len] = '\0'; | ||
1268 | text = (char *) &p2p_rnmsg[1] + room_name_len; | ||
1269 | } | ||
1270 | else | ||
1271 | { | ||
1122 | sender = client_list_head; | 1272 | sender = client_list_head; |
1123 | while ((NULL != sender) && | 1273 | while ((NULL != sender) && |
1124 | (0 != memcmp (&sender->id, | 1274 | (0 != memcmp (&sender->id, |
@@ -1127,10 +1277,13 @@ handle_p2p_message_notification (void *cls, | |||
1127 | sender = sender->next; | 1277 | sender = sender->next; |
1128 | if (NULL == sender) | 1278 | if (NULL == sender) |
1129 | { | 1279 | { |
1130 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1280 | /* not an error since the sender may have left before we got the |
1281 | message */ | ||
1282 | #if DEBUG_CHAT_SERVICE | ||
1283 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1131 | "Unknown source. Rejecting the message\n"); | 1284 | "Unknown source. Rejecting the message\n"); |
1132 | GNUNET_break_op (0); | 1285 | #endif |
1133 | return GNUNET_SYSERR; | 1286 | return GNUNET_OK; |
1134 | } | 1287 | } |
1135 | if (sender->msg_sequence_number >= ntohl (p2p_rnmsg->sequence_number)) | 1288 | if (sender->msg_sequence_number >= ntohl (p2p_rnmsg->sequence_number)) |
1136 | { | 1289 | { |
@@ -1138,15 +1291,19 @@ handle_p2p_message_notification (void *cls, | |||
1138 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1291 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1139 | "This message has already been handled." | 1292 | "This message has already been handled." |
1140 | " Sequence numbers (msg/sender): %u/%u\n", | 1293 | " Sequence numbers (msg/sender): %u/%u\n", |
1141 | ntohl (p2p_rnmsg->sequence_number), sender->msg_sequence_number); | 1294 | ntohl (p2p_rnmsg->sequence_number), |
1295 | sender->msg_sequence_number); | ||
1142 | #endif | 1296 | #endif |
1143 | return GNUNET_OK; | 1297 | return GNUNET_OK; |
1144 | } | 1298 | } |
1145 | sender->msg_sequence_number = ntohl (p2p_rnmsg->sequence_number); | 1299 | sender->msg_sequence_number = ntohl (p2p_rnmsg->sequence_number); |
1146 | msg_len = ntohs (p2p_rnmsg->header.size) - | 1300 | room_name = sender->room; |
1147 | sizeof (struct P2PReceiveNotificationMessage); | 1301 | text = (char *) &p2p_rnmsg[1]; |
1302 | } | ||
1303 | |||
1148 | #if DEBUG_CHAT_SERVICE | 1304 | #if DEBUG_CHAT_SERVICE |
1149 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending message to local room members\n"); | 1305 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1306 | "Sending message to local room members\n"); | ||
1150 | #endif | 1307 | #endif |
1151 | rnmsg = GNUNET_malloc (sizeof (struct ReceiveNotificationMessage) + msg_len); | 1308 | rnmsg = GNUNET_malloc (sizeof (struct ReceiveNotificationMessage) + msg_len); |
1152 | rnmsg->header.size = htons (sizeof (struct ReceiveNotificationMessage) + | 1309 | rnmsg->header.size = htons (sizeof (struct ReceiveNotificationMessage) + |
@@ -1154,21 +1311,22 @@ handle_p2p_message_notification (void *cls, | |||
1154 | rnmsg->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_MESSAGE_NOTIFICATION); | 1311 | rnmsg->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_MESSAGE_NOTIFICATION); |
1155 | rnmsg->msg_options = p2p_rnmsg->msg_options; | 1312 | rnmsg->msg_options = p2p_rnmsg->msg_options; |
1156 | rnmsg->sequence_number = p2p_rnmsg->sequence_number; | 1313 | rnmsg->sequence_number = p2p_rnmsg->sequence_number; |
1157 | priv_msg = (0 != memcmp (&all_zeros, | 1314 | rnmsg->timestamp = p2p_rnmsg->timestamp; |
1315 | is_priv = (0 != memcmp (&all_zeros, | ||
1158 | &p2p_rnmsg->target, sizeof (GNUNET_HashCode))); | 1316 | &p2p_rnmsg->target, sizeof (GNUNET_HashCode))); |
1159 | if (priv_msg) | 1317 | if (is_priv) |
1160 | memcpy (&rnmsg->encrypted_key, | 1318 | memcpy (&rnmsg->encrypted_key, |
1161 | &p2p_rnmsg->encrypted_key, | 1319 | &p2p_rnmsg->encrypted_key, |
1162 | sizeof (struct GNUNET_CRYPTO_RsaEncryptedData)); | 1320 | sizeof (struct GNUNET_CRYPTO_RsaEncryptedData)); |
1163 | memcpy (&rnmsg->sender, &p2p_rnmsg->sender, sizeof (GNUNET_HashCode)); | 1321 | rnmsg->sender = p2p_rnmsg->sender; |
1164 | memcpy (&rnmsg[1], &p2p_rnmsg[1], msg_len); | 1322 | memcpy (&rnmsg[1], text, msg_len); |
1165 | pos = client_list_head; | 1323 | pos = client_list_head; |
1166 | while (NULL != pos) | 1324 | while (NULL != pos) |
1167 | { | 1325 | { |
1168 | if ((0 == strcmp (sender->room, pos->room)) && | 1326 | if ((0 == strcmp (room_name, pos->room)) && |
1169 | (NULL != pos->client)) | 1327 | (NULL != pos->client)) |
1170 | { | 1328 | { |
1171 | if (((!priv_msg) || | 1329 | if (((!is_priv) || |
1172 | (0 == memcmp (&p2p_rnmsg->target, | 1330 | (0 == memcmp (&p2p_rnmsg->target, |
1173 | &pos->id, | 1331 | &pos->id, |
1174 | sizeof (GNUNET_HashCode)))) && | 1332 | sizeof (GNUNET_HashCode)))) && |
@@ -1182,6 +1340,8 @@ handle_p2p_message_notification (void *cls, | |||
1182 | } | 1340 | } |
1183 | pos = pos->next; | 1341 | pos = pos->next; |
1184 | } | 1342 | } |
1343 | if (is_anon) | ||
1344 | GNUNET_free (room_name); | ||
1185 | #if DEBUG_CHAT_SERVICE | 1345 | #if DEBUG_CHAT_SERVICE |
1186 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1346 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1187 | "Broadcasting message notification to neighbour peers\n"); | 1347 | "Broadcasting message notification to neighbour peers\n"); |
@@ -1441,6 +1601,9 @@ static void | |||
1441 | cleanup_task (void *cls, | 1601 | cleanup_task (void *cls, |
1442 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 1602 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
1443 | { | 1603 | { |
1604 | struct AnonymousMessage *next_msg; | ||
1605 | struct ChatClient *next_client; | ||
1606 | |||
1444 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Cleaning up\n"); | 1607 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Cleaning up\n"); |
1445 | if (NULL != core) | 1608 | if (NULL != core) |
1446 | { | 1609 | { |
@@ -1452,6 +1615,20 @@ cleanup_task (void *cls, | |||
1452 | GNUNET_SERVER_notification_context_destroy (nc); | 1615 | GNUNET_SERVER_notification_context_destroy (nc); |
1453 | nc = NULL; | 1616 | nc = NULL; |
1454 | } | 1617 | } |
1618 | while (NULL != client_list_head) | ||
1619 | { | ||
1620 | next_client = client_list_head->next; | ||
1621 | GNUNET_free (client_list_head->room); | ||
1622 | GNUNET_free_non_null (client_list_head->member_info); | ||
1623 | GNUNET_free (client_list_head); | ||
1624 | client_list_head = next_client; | ||
1625 | } | ||
1626 | while (NULL != anonymous_list_head) | ||
1627 | { | ||
1628 | next_msg = anonymous_list_head->next; | ||
1629 | GNUNET_free (anonymous_list_head); | ||
1630 | anonymous_list_head = next_msg; | ||
1631 | } | ||
1455 | } | 1632 | } |
1456 | 1633 | ||
1457 | 1634 | ||
diff --git a/src/core/core.h b/src/core/core.h index acac7c407..7959e565b 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
@@ -30,7 +30,7 @@ | |||
30 | /** | 30 | /** |
31 | * General core debugging. | 31 | * General core debugging. |
32 | */ | 32 | */ |
33 | #define DEBUG_CORE GNUNET_NO | 33 | #define DEBUG_CORE GNUNET_YES |
34 | 34 | ||
35 | /** | 35 | /** |
36 | * Debugging interaction core-clients. | 36 | * Debugging interaction core-clients. |
diff --git a/src/include/gnunet_chat_service.h b/src/include/gnunet_chat_service.h index 059dff254..732d625f2 100644 --- a/src/include/gnunet_chat_service.h +++ b/src/include/gnunet_chat_service.h | |||
@@ -89,6 +89,14 @@ enum GNUNET_CHAT_MsgOptions | |||
89 | struct GNUNET_CHAT_Room; | 89 | struct GNUNET_CHAT_Room; |
90 | 90 | ||
91 | /** | 91 | /** |
92 | * Callback used for notification that we have joined the room. | ||
93 | * | ||
94 | * @param cls closure | ||
95 | * @return GNUNET_OK | ||
96 | */ | ||
97 | typedef int (*GNUNET_CHAT_JoinCallback) (void *cls); | ||
98 | |||
99 | /** | ||
92 | * Callback used for notification about incoming messages. | 100 | * Callback used for notification about incoming messages. |
93 | * | 101 | * |
94 | * @param cls closure | 102 | * @param cls closure |
@@ -96,6 +104,7 @@ struct GNUNET_CHAT_Room; | |||
96 | * @param sender what is the ID of the sender? (maybe NULL) | 104 | * @param sender what is the ID of the sender? (maybe NULL) |
97 | * @param member_info information about the joining member | 105 | * @param member_info information about the joining member |
98 | * @param message the message text | 106 | * @param message the message text |
107 | * @param timestamp when was the message sent? | ||
99 | * @param options options for the message | 108 | * @param options options for the message |
100 | * @return GNUNET_OK to accept the message now, GNUNET_NO to | 109 | * @return GNUNET_OK to accept the message now, GNUNET_NO to |
101 | * accept (but user is away), GNUNET_SYSERR to signal denied delivery | 110 | * accept (but user is away), GNUNET_SYSERR to signal denied delivery |
@@ -105,11 +114,13 @@ typedef int (*GNUNET_CHAT_MessageCallback) (void *cls, | |||
105 | const GNUNET_HashCode *sender, | 114 | const GNUNET_HashCode *sender, |
106 | const struct GNUNET_CONTAINER_MetaData *member_info, | 115 | const struct GNUNET_CONTAINER_MetaData *member_info, |
107 | const char *message, | 116 | const char *message, |
117 | struct GNUNET_TIME_Absolute timestamp, | ||
108 | enum GNUNET_CHAT_MsgOptions options); | 118 | enum GNUNET_CHAT_MsgOptions options); |
109 | 119 | ||
110 | /** | 120 | /** |
111 | * Callback used for notification that another room member has joined or left. | 121 | * Callback used for notification that another room member has joined or left. |
112 | * | 122 | * |
123 | * @param cls closure | ||
113 | * @param member_info will be non-null if the member is joining, NULL if he is | 124 | * @param member_info will be non-null if the member is joining, NULL if he is |
114 | * leaving | 125 | * leaving |
115 | * @param member_id hash of public key of the user (for unique identification) | 126 | * @param member_id hash of public key of the user (for unique identification) |
@@ -129,8 +140,6 @@ typedef int (*GNUNET_CHAT_MemberListCallback) (void *cls, | |||
129 | * @param orig_seq_number sequence number of the original message | 140 | * @param orig_seq_number sequence number of the original message |
130 | * @param timestamp when was the message received? | 141 | * @param timestamp when was the message received? |
131 | * @param receiver who is confirming the receipt? | 142 | * @param receiver who is confirming the receipt? |
132 | * @param msg_hash hash of the original message | ||
133 | * @param receipt signature confirming delivery | ||
134 | * @return GNUNET_OK to continue, GNUNET_SYSERR to refuse processing further | 143 | * @return GNUNET_OK to continue, GNUNET_SYSERR to refuse processing further |
135 | * confirmations from anyone for this message | 144 | * confirmations from anyone for this message |
136 | */ | 145 | */ |
@@ -138,9 +147,7 @@ typedef int (*GNUNET_CHAT_MessageConfirmation) (void *cls, | |||
138 | struct GNUNET_CHAT_Room *room, | 147 | struct GNUNET_CHAT_Room *room, |
139 | uint32_t orig_seq_number, | 148 | uint32_t orig_seq_number, |
140 | struct GNUNET_TIME_Absolute timestamp, | 149 | struct GNUNET_TIME_Absolute timestamp, |
141 | const GNUNET_HashCode *receiver, | 150 | const GNUNET_HashCode *receiver); |
142 | const GNUNET_HashCode *msg_hash, | ||
143 | const struct GNUNET_CRYPTO_RsaSignature *receipt); | ||
144 | 151 | ||
145 | /** | 152 | /** |
146 | * Join a chat room. | 153 | * Join a chat room. |
@@ -153,6 +160,8 @@ typedef int (*GNUNET_CHAT_MessageConfirmation) (void *cls, | |||
153 | * @param member_info information about the joining member | 160 | * @param member_info information about the joining member |
154 | * @param room_name name of the room | 161 | * @param room_name name of the room |
155 | * @param msg_options message options of the joining user | 162 | * @param msg_options message options of the joining user |
163 | * @param joinCallback which function to call when we've joined the room | ||
164 | * @param join_cls argument to callback | ||
156 | * @param messageCallback which function to call if a message has | 165 | * @param messageCallback which function to call if a message has |
157 | * been received? | 166 | * been received? |
158 | * @param message_cls argument to callback | 167 | * @param message_cls argument to callback |
@@ -170,6 +179,8 @@ GNUNET_CHAT_join_room (const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
170 | struct GNUNET_CONTAINER_MetaData *member_info, | 179 | struct GNUNET_CONTAINER_MetaData *member_info, |
171 | const char *room_name, | 180 | const char *room_name, |
172 | enum GNUNET_CHAT_MsgOptions msg_options, | 181 | enum GNUNET_CHAT_MsgOptions msg_options, |
182 | GNUNET_CHAT_JoinCallback joinCallback, | ||
183 | void *join_cls, | ||
173 | GNUNET_CHAT_MessageCallback messageCallback, | 184 | GNUNET_CHAT_MessageCallback messageCallback, |
174 | void *message_cls, | 185 | void *message_cls, |
175 | GNUNET_CHAT_MemberListCallback memberCallback, | 186 | GNUNET_CHAT_MemberListCallback memberCallback, |