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 /src/chat/gnunet-service-chat.c | |
parent | 7b3d9e8f57db9db2053dd7e25c9dbd92514819e0 (diff) | |
download | gnunet-a0b3e179abb44828f76843739487b2686b14cc8e.tar.gz gnunet-a0b3e179abb44828f76843739487b2686b14cc8e.zip |
more chat code from Mantis #1657
Diffstat (limited to 'src/chat/gnunet-service-chat.c')
-rw-r--r-- | src/chat/gnunet-service-chat.c | 257 |
1 files changed, 217 insertions, 40 deletions
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 | ||