aboutsummaryrefslogtreecommitdiff
path: root/src/chat/gnunet-service-chat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/chat/gnunet-service-chat.c')
-rw-r--r--src/chat/gnunet-service-chat.c1196
1 files changed, 570 insertions, 626 deletions
diff --git a/src/chat/gnunet-service-chat.c b/src/chat/gnunet-service-chat.c
index 470b4ad0b..7afa18d68 100644
--- a/src/chat/gnunet-service-chat.c
+++ b/src/chat/gnunet-service-chat.c
@@ -105,7 +105,7 @@ struct ConnectedPeer
105 /** 105 /**
106 * The peer's identity. 106 * The peer's identity.
107 */ 107 */
108 GNUNET_PEER_Id pid; 108 GNUNET_PEER_Id pid;
109}; 109};
110 110
111/** 111/**
@@ -157,10 +157,11 @@ static struct AnonymousMessage *anonymous_list_head = NULL;
157 * Map of peer identifiers to "struct ConnectedPeer" (for that peer). 157 * Map of peer identifiers to "struct ConnectedPeer" (for that peer).
158 */ 158 */
159static struct GNUNET_CONTAINER_MultiHashMap *connected_peers; 159static struct GNUNET_CONTAINER_MultiHashMap *connected_peers;
160 160
161 161
162static void 162static void
163remember_anonymous_message (const struct P2PReceiveNotificationMessage *p2p_rnmsg) 163remember_anonymous_message (const struct P2PReceiveNotificationMessage
164 *p2p_rnmsg)
164{ 165{
165 static GNUNET_HashCode hash; 166 static GNUNET_HashCode hash;
166 struct AnonymousMessage *anon_msg; 167 struct AnonymousMessage *anon_msg;
@@ -175,17 +176,17 @@ remember_anonymous_message (const struct P2PReceiveNotificationMessage *p2p_rnms
175 anon_list_len = 1; 176 anon_list_len = 1;
176 prev = NULL; 177 prev = NULL;
177 while ((NULL != anon_msg->next)) 178 while ((NULL != anon_msg->next))
178 { 179 {
179 prev = anon_msg; 180 prev = anon_msg;
180 anon_msg = anon_msg->next; 181 anon_msg = anon_msg->next;
181 anon_list_len++; 182 anon_list_len++;
182 } 183 }
183 if (anon_list_len == MAX_ANONYMOUS_MSG_LIST_LENGTH) 184 if (anon_list_len == MAX_ANONYMOUS_MSG_LIST_LENGTH)
184 { 185 {
185 GNUNET_free (anon_msg); 186 GNUNET_free (anon_msg);
186 if (NULL != prev) 187 if (NULL != prev)
187 prev->next = NULL; 188 prev->next = NULL;
188 } 189 }
189} 190}
190 191
191 192
@@ -213,9 +214,7 @@ lookup_anonymous_message (const struct P2PReceiveNotificationMessage *p2p_rnmsg)
213 * @return number of bytes written to buf 214 * @return number of bytes written to buf
214 */ 215 */
215static size_t 216static size_t
216transmit_message_notification_to_peer (void *cls, 217transmit_message_notification_to_peer (void *cls, size_t size, void *buf)
217 size_t size,
218 void *buf)
219{ 218{
220 struct P2PReceiveNotificationMessage *my_msg = cls; 219 struct P2PReceiveNotificationMessage *my_msg = cls;
221 struct P2PReceiveNotificationMessage *m = buf; 220 struct P2PReceiveNotificationMessage *m = buf;
@@ -226,14 +225,14 @@ transmit_message_notification_to_peer (void *cls,
226 "Transmitting P2P message notification\n"); 225 "Transmitting P2P message notification\n");
227#endif 226#endif
228 if (buf == NULL) 227 if (buf == NULL)
229 { 228 {
230 /* client disconnected */ 229 /* client disconnected */
231#if DEBUG_CHAT_SERVICE 230#if DEBUG_CHAT_SERVICE
232 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 231 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
233 "Buffer is NULL, dropping the message\n"); 232 "Buffer is NULL, dropping the message\n");
234#endif 233#endif
235 return 0; 234 return 0;
236 } 235 }
237 msg_size = ntohs (my_msg->header.size); 236 msg_size = ntohs (my_msg->header.size);
238 GNUNET_assert (size >= msg_size); 237 GNUNET_assert (size >= msg_size);
239 memcpy (m, my_msg, msg_size); 238 memcpy (m, my_msg, msg_size);
@@ -246,9 +245,7 @@ transmit_message_notification_to_peer (void *cls,
246 * Ask to send a message notification to the peer. 245 * Ask to send a message notification to the peer.
247 */ 246 */
248static int 247static int
249send_message_noficiation (void *cls, 248send_message_noficiation (void *cls, const GNUNET_HashCode * key, void *value)
250 const GNUNET_HashCode *key,
251 void *value)
252{ 249{
253 struct P2PReceiveNotificationMessage *msg = cls; 250 struct P2PReceiveNotificationMessage *msg = cls;
254 struct ConnectedPeer *cp = value; 251 struct ConnectedPeer *cp = value;
@@ -262,7 +259,7 @@ send_message_noficiation (void *cls,
262#endif 259#endif
263 my_msg = GNUNET_memdup (msg, ntohs (msg->header.size)); 260 my_msg = GNUNET_memdup (msg, ntohs (msg->header.size));
264 if (NULL == GNUNET_CORE_notify_transmit_ready (core, 261 if (NULL == GNUNET_CORE_notify_transmit_ready (core,
265 GNUNET_NO, 262 GNUNET_NO,
266 1, 263 1,
267 MAX_TRANSMIT_DELAY, 264 MAX_TRANSMIT_DELAY,
268 &pid, 265 &pid,
@@ -304,35 +301,36 @@ handle_transmit_request (void *cls,
304 301
305 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Client sent a chat message\n"); 302 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Client sent a chat message\n");
306 if (ntohs (message->size) <= sizeof (struct TransmitRequestMessage)) 303 if (ntohs (message->size) <= sizeof (struct TransmitRequestMessage))
307 { 304 {
308 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed message: wrong size\n"); 305 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed message: wrong size\n");
309 GNUNET_break (0); 306 GNUNET_break (0);
310 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 307 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
311 return; 308 return;
312 } 309 }
313 trmsg = (const struct TransmitRequestMessage *) message; 310 trmsg = (const struct TransmitRequestMessage *) message;
314 msg_len = ntohs (trmsg->header.size) - sizeof (struct TransmitRequestMessage); 311 msg_len = ntohs (trmsg->header.size) - sizeof (struct TransmitRequestMessage);
315 is_priv = (0 != (ntohl (trmsg->msg_options) & GNUNET_CHAT_MSG_PRIVATE)); 312 is_priv = (0 != (ntohl (trmsg->msg_options) & GNUNET_CHAT_MSG_PRIVATE));
316 if (is_priv) 313 if (is_priv)
317 { 314 {
318#if DEBUG_CHAT_SERVICE 315#if DEBUG_CHAT_SERVICE
319 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting the message text\n"); 316 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Encrypting the message text\n");
320#endif 317#endif
321 GNUNET_CRYPTO_aes_create_session_key (&key); 318 GNUNET_CRYPTO_aes_create_session_key (&key);
322 msg_len = GNUNET_CRYPTO_aes_encrypt (&trmsg[1], 319 msg_len = GNUNET_CRYPTO_aes_encrypt (&trmsg[1],
323 msg_len, 320 msg_len,
324 &key, 321 &key,
325 (const struct GNUNET_CRYPTO_AesInitializationVector *) INITVALUE, 322 (const struct
326 encrypted_msg); 323 GNUNET_CRYPTO_AesInitializationVector
327 if (-1 == msg_len) 324 *) INITVALUE, encrypted_msg);
328 { 325 if (-1 == msg_len)
329 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 326 {
330 "Could not encrypt the message text\n"); 327 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
331 GNUNET_break (0); 328 "Could not encrypt the message text\n");
332 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 329 GNUNET_break (0);
333 return; 330 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
334 } 331 return;
335 } 332 }
333 }
336 rnmsg = GNUNET_malloc (sizeof (struct ReceiveNotificationMessage) + msg_len); 334 rnmsg = GNUNET_malloc (sizeof (struct ReceiveNotificationMessage) + msg_len);
337 rnmsg->header.size = htons (sizeof (struct ReceiveNotificationMessage) + 335 rnmsg->header.size = htons (sizeof (struct ReceiveNotificationMessage) +
338 msg_len); 336 msg_len);
@@ -343,134 +341,134 @@ handle_transmit_request (void *cls,
343 while ((NULL != pos) && (pos->client != client)) 341 while ((NULL != pos) && (pos->client != client))
344 pos = pos->next; 342 pos = pos->next;
345 if (NULL == pos) 343 if (NULL == pos)
346 { 344 {
347 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 345 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
348 "The client is not a member of a chat room. Client has to " 346 "The client is not a member of a chat room. Client has to "
349 "join a chat room first\n"); 347 "join a chat room first\n");
350 GNUNET_break (0); 348 GNUNET_break (0);
351 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 349 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
352 GNUNET_free (rnmsg); 350 GNUNET_free (rnmsg);
353 return; 351 return;
354 } 352 }
355 room = pos->room; 353 room = pos->room;
356 pos->msg_sequence_number = ntohl (trmsg->sequence_number); 354 pos->msg_sequence_number = ntohl (trmsg->sequence_number);
357 is_anon = (0 != (ntohl (trmsg->msg_options) & GNUNET_CHAT_MSG_ANONYMOUS)); 355 is_anon = (0 != (ntohl (trmsg->msg_options) & GNUNET_CHAT_MSG_ANONYMOUS));
358 if (is_anon) 356 if (is_anon)
359 { 357 {
360 memset (&rnmsg->sender, 0, sizeof (GNUNET_HashCode)); 358 memset (&rnmsg->sender, 0, sizeof (GNUNET_HashCode));
361 rnmsg->sequence_number = 0; 359 rnmsg->sequence_number = 0;
362 } 360 }
363 else 361 else
364 { 362 {
365 rnmsg->sender = pos->id; 363 rnmsg->sender = pos->id;
366 rnmsg->sequence_number = trmsg->sequence_number; 364 rnmsg->sequence_number = trmsg->sequence_number;
367 } 365 }
368 if (is_priv) 366 if (is_priv)
369 { 367 {
370#if DEBUG_CHAT_SERVICE 368#if DEBUG_CHAT_SERVICE
371 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 369 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
372 "Encrypting the session key using the public key of '%s'\n", 370 "Encrypting the session key using the public key of '%s'\n",
373 GNUNET_h2s (&trmsg->target)); 371 GNUNET_h2s (&trmsg->target));
374#endif 372#endif
375 if (0 == memcmp (&all_zeros, &trmsg->target, sizeof (GNUNET_HashCode))) 373 if (0 == memcmp (&all_zeros, &trmsg->target, sizeof (GNUNET_HashCode)))
376 { 374 {
377 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 375 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
378 "Malformed message: private, but no target\n"); 376 "Malformed message: private, but no target\n");
379 GNUNET_break (0); 377 GNUNET_break (0);
380 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 378 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
381 GNUNET_free (rnmsg); 379 GNUNET_free (rnmsg);
382 return; 380 return;
383 }
384 memcpy (&rnmsg[1], encrypted_msg, msg_len);
385 target = client_list_head;
386 while ((NULL != target) &&
387 (0 != memcmp (&target->id,
388 &trmsg->target,
389 sizeof (GNUNET_HashCode))))
390 target = target->next;
391 if (NULL == target)
392 {
393 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
394 "Unknown target of the private message\n");
395 GNUNET_break (0);
396 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
397 GNUNET_free (rnmsg);
398 return;
399 }
400 if (GNUNET_SYSERR == GNUNET_CRYPTO_rsa_encrypt (&key,
401 sizeof (struct GNUNET_CRYPTO_AesSessionKey),
402 &target->public_key,
403 &rnmsg->encrypted_key))
404 {
405 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
406 "Could not encrypt the session key\n");
407 GNUNET_break (0);
408 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
409 GNUNET_free (rnmsg);
410 return;
411 }
412 } 381 }
413 else 382 memcpy (&rnmsg[1], encrypted_msg, msg_len);
383 target = client_list_head;
384 while ((NULL != target) &&
385 (0 != memcmp (&target->id,
386 &trmsg->target, sizeof (GNUNET_HashCode))))
387 target = target->next;
388 if (NULL == target)
414 { 389 {
415 memcpy (&rnmsg[1], &trmsg[1], msg_len); 390 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
391 "Unknown target of the private message\n");
392 GNUNET_break (0);
393 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
394 GNUNET_free (rnmsg);
395 return;
416 } 396 }
397 if (GNUNET_SYSERR == GNUNET_CRYPTO_rsa_encrypt (&key,
398 sizeof (struct
399 GNUNET_CRYPTO_AesSessionKey),
400 &target->public_key,
401 &rnmsg->encrypted_key))
402 {
403 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
404 "Could not encrypt the session key\n");
405 GNUNET_break (0);
406 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
407 GNUNET_free (rnmsg);
408 return;
409 }
410 }
411 else
412 {
413 memcpy (&rnmsg[1], &trmsg[1], msg_len);
414 }
417 pos = client_list_head; 415 pos = client_list_head;
418#if DEBUG_CHAT_SERVICE 416#if DEBUG_CHAT_SERVICE
419 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending message to local room members\n"); 417 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
418 "Sending message to local room members\n");
420#endif 419#endif
421 while (NULL != pos) 420 while (NULL != pos)
421 {
422 if ((0 == strcmp (room, pos->room)) &&
423 (NULL != pos->client) && (pos->client != client))
422 { 424 {
423 if ((0 == strcmp (room, pos->room)) && 425 if (((!is_priv) ||
424 (NULL != pos->client) && 426 (0 == memcmp (&trmsg->target,
425 (pos->client != client)) 427 &pos->id,
426 { 428 sizeof (GNUNET_HashCode)))) &&
427 if (((!is_priv) || 429 (0 == (ntohl (trmsg->msg_options) & (~pos->msg_options))))
428 (0 == memcmp (&trmsg->target, 430 {
429 &pos->id, 431 GNUNET_SERVER_notification_context_unicast (nc,
430 sizeof (GNUNET_HashCode)))) && 432 pos->client,
431 (0 == (ntohl (trmsg->msg_options) & (~pos->msg_options)))) 433 &rnmsg->header, GNUNET_NO);
432 { 434 }
433 GNUNET_SERVER_notification_context_unicast (nc,
434 pos->client,
435 &rnmsg->header,
436 GNUNET_NO);
437 }
438 }
439 pos = pos->next;
440 } 435 }
436 pos = pos->next;
437 }
441#if DEBUG_CHAT_SERVICE 438#if DEBUG_CHAT_SERVICE
442 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 439 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
443 "Broadcasting message to neighbour peers\n"); 440 "Broadcasting message to neighbour peers\n");
444#endif 441#endif
445 if (is_anon) 442 if (is_anon)
446 { 443 {
447 room_len = strlen (room); 444 room_len = strlen (room);
448 p2p_rnmsg = GNUNET_malloc (sizeof (struct P2PReceiveNotificationMessage) + 445 p2p_rnmsg = GNUNET_malloc (sizeof (struct P2PReceiveNotificationMessage) +
449 msg_len + room_len); 446 msg_len + room_len);
450 p2p_rnmsg->header.size = 447 p2p_rnmsg->header.size =
451 htons (sizeof (struct P2PReceiveNotificationMessage) + msg_len + 448 htons (sizeof (struct P2PReceiveNotificationMessage) + msg_len +
452 room_len); 449 room_len);
453 p2p_rnmsg->room_name_len = htons (room_len); 450 p2p_rnmsg->room_name_len = htons (room_len);
454 memcpy ((char *) &p2p_rnmsg[1], room, room_len); 451 memcpy ((char *) &p2p_rnmsg[1], room, room_len);
455 memcpy ((char *) &p2p_rnmsg[1] + room_len, &trmsg[1], msg_len); 452 memcpy ((char *) &p2p_rnmsg[1] + room_len, &trmsg[1], msg_len);
456 } 453 }
457 else 454 else
458 { 455 {
459 p2p_rnmsg = GNUNET_malloc (sizeof (struct P2PReceiveNotificationMessage) + 456 p2p_rnmsg = GNUNET_malloc (sizeof (struct P2PReceiveNotificationMessage) +
460 msg_len); 457 msg_len);
461 p2p_rnmsg->header.size = 458 p2p_rnmsg->header.size =
462 htons (sizeof (struct P2PReceiveNotificationMessage) + msg_len); 459 htons (sizeof (struct P2PReceiveNotificationMessage) + msg_len);
463 if (is_priv) 460 if (is_priv)
464 { 461 {
465 memcpy (&p2p_rnmsg[1], encrypted_msg, msg_len); 462 memcpy (&p2p_rnmsg[1], encrypted_msg, msg_len);
466 memcpy (&p2p_rnmsg->encrypted_key, 463 memcpy (&p2p_rnmsg->encrypted_key,
467 &rnmsg->encrypted_key, 464 &rnmsg->encrypted_key,
468 sizeof (struct GNUNET_CRYPTO_RsaEncryptedData)); 465 sizeof (struct GNUNET_CRYPTO_RsaEncryptedData));
469 } 466 }
470 else 467 else
471 memcpy (&p2p_rnmsg[1], &trmsg[1], msg_len); 468 memcpy (&p2p_rnmsg[1], &trmsg[1], msg_len);
472 } 469 }
473 p2p_rnmsg->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_P2P_MESSAGE_NOTIFICATION); 470 p2p_rnmsg->header.type =
471 htons (GNUNET_MESSAGE_TYPE_CHAT_P2P_MESSAGE_NOTIFICATION);
474 p2p_rnmsg->msg_options = trmsg->msg_options; 472 p2p_rnmsg->msg_options = trmsg->msg_options;
475 p2p_rnmsg->sequence_number = trmsg->sequence_number; 473 p2p_rnmsg->sequence_number = trmsg->sequence_number;
476 p2p_rnmsg->timestamp = trmsg->timestamp; 474 p2p_rnmsg->timestamp = trmsg->timestamp;
@@ -480,8 +478,7 @@ handle_transmit_request (void *cls,
480 if (is_anon) 478 if (is_anon)
481 remember_anonymous_message (p2p_rnmsg); 479 remember_anonymous_message (p2p_rnmsg);
482 GNUNET_CONTAINER_multihashmap_iterate (connected_peers, 480 GNUNET_CONTAINER_multihashmap_iterate (connected_peers,
483 &send_message_noficiation, 481 &send_message_noficiation, p2p_rnmsg);
484 p2p_rnmsg);
485 GNUNET_free (p2p_rnmsg); 482 GNUNET_free (p2p_rnmsg);
486 GNUNET_SERVER_receive_done (client, GNUNET_OK); 483 GNUNET_SERVER_receive_done (client, GNUNET_OK);
487 GNUNET_free (rnmsg); 484 GNUNET_free (rnmsg);
@@ -497,9 +494,7 @@ handle_transmit_request (void *cls,
497 * @return number of bytes written to buf 494 * @return number of bytes written to buf
498 */ 495 */
499static size_t 496static size_t
500transmit_join_notification_to_peer (void *cls, 497transmit_join_notification_to_peer (void *cls, size_t size, void *buf)
501 size_t size,
502 void *buf)
503{ 498{
504 struct ChatClient *entry = cls; 499 struct ChatClient *entry = cls;
505 struct P2PJoinNotificationMessage *m = buf; 500 struct P2PJoinNotificationMessage *m = buf;
@@ -509,8 +504,7 @@ transmit_join_notification_to_peer (void *cls,
509 char *roomptr; 504 char *roomptr;
510 505
511#if DEBUG_CHAT_SERVICE 506#if DEBUG_CHAT_SERVICE
512 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 507 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting P2P join notification\n");
513 "Transmitting P2P join notification\n");
514#endif 508#endif
515 room_len = strlen (entry->room); 509 room_len = strlen (entry->room);
516 meta_len = entry->meta_len; 510 meta_len = entry->meta_len;
@@ -537,9 +531,7 @@ transmit_join_notification_to_peer (void *cls,
537 * Ask to send a join notification to the peer. 531 * Ask to send a join notification to the peer.
538 */ 532 */
539static int 533static int
540send_join_noficiation (void *cls, 534send_join_noficiation (void *cls, const GNUNET_HashCode * key, void *value)
541 const GNUNET_HashCode *key,
542 void *value)
543{ 535{
544 struct ChatClient *entry = cls; 536 struct ChatClient *entry = cls;
545 struct ConnectedPeer *cp = value; 537 struct ConnectedPeer *cp = value;
@@ -552,10 +544,9 @@ send_join_noficiation (void *cls,
552 "Sending join notification to `%s'\n", GNUNET_i2s (&pid)); 544 "Sending join notification to `%s'\n", GNUNET_i2s (&pid));
553#endif 545#endif
554 msg_size = sizeof (struct P2PJoinNotificationMessage) + 546 msg_size = sizeof (struct P2PJoinNotificationMessage) +
555 strlen (entry->room) + 547 strlen (entry->room) + entry->meta_len;
556 entry->meta_len;
557 if (NULL == GNUNET_CORE_notify_transmit_ready (core, 548 if (NULL == GNUNET_CORE_notify_transmit_ready (core,
558 GNUNET_NO, 549 GNUNET_NO,
559 1, 550 1,
560 MAX_TRANSMIT_DELAY, 551 MAX_TRANSMIT_DELAY,
561 &pid, 552 &pid,
@@ -594,26 +585,24 @@ handle_join_request (void *cls,
594 585
595 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Client sent a join request\n"); 586 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Client sent a join request\n");
596 if (ntohs (message->size) <= sizeof (struct JoinRequestMessage)) 587 if (ntohs (message->size) <= sizeof (struct JoinRequestMessage))
597 { 588 {
598 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed message: wrong size\n"); 589 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed message: wrong size\n");
599 GNUNET_break (0); 590 GNUNET_break (0);
600 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 591 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
601 return; 592 return;
602 } 593 }
603 jrmsg = (const struct JoinRequestMessage *) message; 594 jrmsg = (const struct JoinRequestMessage *) message;
604 header_size = ntohs (jrmsg->header.size); 595 header_size = ntohs (jrmsg->header.size);
605 room_name_len = ntohs (jrmsg->room_name_len); 596 room_name_len = ntohs (jrmsg->room_name_len);
606 if (header_size - sizeof (struct JoinRequestMessage) <= 597 if (header_size - sizeof (struct JoinRequestMessage) <= room_name_len)
607 room_name_len) 598 {
608 { 599 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
609 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 600 "Malformed message: wrong length of the room name\n");
610 "Malformed message: wrong length of the room name\n"); 601 GNUNET_break (0);
611 GNUNET_break (0); 602 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
612 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 603 return;
613 return; 604 }
614 } 605 meta_len = header_size - sizeof (struct JoinRequestMessage) - room_name_len;
615 meta_len =
616 header_size - sizeof (struct JoinRequestMessage) - room_name_len;
617 roomptr = (const char *) &jrmsg[1]; 606 roomptr = (const char *) &jrmsg[1];
618 room_name = GNUNET_malloc (room_name_len + 1); 607 room_name = GNUNET_malloc (room_name_len + 1);
619 memcpy (room_name, roomptr, room_name_len); 608 memcpy (room_name, roomptr, room_name_len);
@@ -625,10 +614,10 @@ handle_join_request (void *cls,
625 new_entry->public_key = jrmsg->public_key; 614 new_entry->public_key = jrmsg->public_key;
626 new_entry->meta_len = meta_len; 615 new_entry->meta_len = meta_len;
627 if (meta_len > 0) 616 if (meta_len > 0)
628 { 617 {
629 new_entry->member_info = GNUNET_malloc (meta_len); 618 new_entry->member_info = GNUNET_malloc (meta_len);
630 memcpy (new_entry->member_info, &roomptr[room_name_len], meta_len); 619 memcpy (new_entry->member_info, &roomptr[room_name_len], meta_len);
631 } 620 }
632 else 621 else
633 new_entry->member_info = NULL; 622 new_entry->member_info = NULL;
634 GNUNET_CRYPTO_hash (&new_entry->public_key, 623 GNUNET_CRYPTO_hash (&new_entry->public_key,
@@ -644,50 +633,47 @@ handle_join_request (void *cls,
644 jnmsg = GNUNET_malloc (sizeof (struct JoinNotificationMessage) + meta_len); 633 jnmsg = GNUNET_malloc (sizeof (struct JoinNotificationMessage) + meta_len);
645 jnmsg->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_JOIN_NOTIFICATION); 634 jnmsg->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_JOIN_NOTIFICATION);
646 jnmsg->header.size = 635 jnmsg->header.size =
647 htons (sizeof (struct JoinNotificationMessage) + meta_len); 636 htons (sizeof (struct JoinNotificationMessage) + meta_len);
648 jnmsg->msg_options = jrmsg->msg_options; 637 jnmsg->msg_options = jrmsg->msg_options;
649 jnmsg->public_key = new_entry->public_key; 638 jnmsg->public_key = new_entry->public_key;
650 memcpy (&jnmsg[1], &roomptr[room_name_len], meta_len); 639 memcpy (&jnmsg[1], &roomptr[room_name_len], meta_len);
651 GNUNET_SERVER_notification_context_add (nc, client); 640 GNUNET_SERVER_notification_context_add (nc, client);
652 entry = client_list_head; 641 entry = client_list_head;
653 while (NULL != entry) 642 while (NULL != entry)
643 {
644 if (0 == strcmp (room_name, entry->room))
654 { 645 {
655 if (0 == strcmp (room_name, entry->room)) 646 if (NULL != entry->client)
656 { 647 GNUNET_SERVER_notification_context_unicast (nc,
657 if (NULL != entry->client) 648 entry->client,
658 GNUNET_SERVER_notification_context_unicast (nc, 649 &jnmsg->header, GNUNET_NO);
659 entry->client, 650 if (entry->client != client)
660 &jnmsg->header, 651 {
661 GNUNET_NO); 652 entry_jnmsg =
662 if (entry->client != client) 653 GNUNET_malloc (sizeof (struct JoinNotificationMessage) +
663 { 654 entry->meta_len);
664 entry_jnmsg = 655 entry_jnmsg->header.type =
665 GNUNET_malloc (sizeof (struct JoinNotificationMessage) + 656 htons (GNUNET_MESSAGE_TYPE_CHAT_JOIN_NOTIFICATION);
666 entry->meta_len); 657 entry_jnmsg->header.size =
667 entry_jnmsg->header.type = 658 htons (sizeof (struct JoinNotificationMessage) + entry->meta_len);
668 htons (GNUNET_MESSAGE_TYPE_CHAT_JOIN_NOTIFICATION); 659 entry_jnmsg->msg_options = entry->msg_options;
669 entry_jnmsg->header.size = 660 entry_jnmsg->public_key = entry->public_key;
670 htons (sizeof (struct JoinNotificationMessage) + 661 memcpy (&entry_jnmsg[1], entry->member_info, entry->meta_len);
671 entry->meta_len); 662 GNUNET_SERVER_notification_context_unicast (nc,
672 entry_jnmsg->msg_options = entry->msg_options; 663 client,
673 entry_jnmsg->public_key = entry->public_key; 664 &entry_jnmsg->header,
674 memcpy (&entry_jnmsg[1], entry->member_info, entry->meta_len); 665 GNUNET_NO);
675 GNUNET_SERVER_notification_context_unicast (nc, 666 GNUNET_free (entry_jnmsg);
676 client, 667 }
677 &entry_jnmsg->header,
678 GNUNET_NO);
679 GNUNET_free (entry_jnmsg);
680 }
681 }
682 entry = entry->next;
683 } 668 }
669 entry = entry->next;
670 }
684#if DEBUG_CHAT_SERVICE 671#if DEBUG_CHAT_SERVICE
685 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 672 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
686 "Broadcasting join notification to neighbour peers\n"); 673 "Broadcasting join notification to neighbour peers\n");
687#endif 674#endif
688 GNUNET_CONTAINER_multihashmap_iterate (connected_peers, 675 GNUNET_CONTAINER_multihashmap_iterate (connected_peers,
689 &send_join_noficiation, 676 &send_join_noficiation, new_entry);
690 new_entry);
691 GNUNET_SERVER_receive_done (client, GNUNET_OK); 677 GNUNET_SERVER_receive_done (client, GNUNET_OK);
692 GNUNET_free (jnmsg); 678 GNUNET_free (jnmsg);
693} 679}
@@ -701,9 +687,7 @@ handle_join_request (void *cls,
701 * @return number of bytes written to buf 687 * @return number of bytes written to buf
702 */ 688 */
703static size_t 689static size_t
704transmit_confirmation_receipt_to_peer (void *cls, 690transmit_confirmation_receipt_to_peer (void *cls, size_t size, void *buf)
705 size_t size,
706 void *buf)
707{ 691{
708 struct P2PConfirmationReceiptMessage *receipt = cls; 692 struct P2PConfirmationReceiptMessage *receipt = cls;
709 size_t msg_size; 693 size_t msg_size;
@@ -714,14 +698,14 @@ transmit_confirmation_receipt_to_peer (void *cls,
714 GNUNET_h2s (&receipt->target)); 698 GNUNET_h2s (&receipt->target));
715#endif 699#endif
716 if (buf == NULL) 700 if (buf == NULL)
717 { 701 {
718 /* client disconnected */ 702 /* client disconnected */
719#if DEBUG_CHAT_SERVICE 703#if DEBUG_CHAT_SERVICE
720 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 704 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
721 "Buffer is NULL, dropping the message\n"); 705 "Buffer is NULL, dropping the message\n");
722#endif 706#endif
723 return 0; 707 return 0;
724 } 708 }
725 msg_size = sizeof (struct P2PConfirmationReceiptMessage); 709 msg_size = sizeof (struct P2PConfirmationReceiptMessage);
726 GNUNET_assert (size >= msg_size); 710 GNUNET_assert (size >= msg_size);
727 memcpy (buf, receipt, msg_size); 711 memcpy (buf, receipt, msg_size);
@@ -734,9 +718,7 @@ transmit_confirmation_receipt_to_peer (void *cls,
734 * Ask to send a confirmation receipt to the peer. 718 * Ask to send a confirmation receipt to the peer.
735 */ 719 */
736static int 720static int
737send_confirmation_receipt (void *cls, 721send_confirmation_receipt (void *cls, const GNUNET_HashCode * key, void *value)
738 const GNUNET_HashCode *key,
739 void *value)
740{ 722{
741 struct P2PConfirmationReceiptMessage *receipt = cls; 723 struct P2PConfirmationReceiptMessage *receipt = cls;
742 struct ConnectedPeer *cp = value; 724 struct ConnectedPeer *cp = value;
@@ -753,7 +735,7 @@ send_confirmation_receipt (void *cls,
753 my_receipt = GNUNET_memdup (receipt, 735 my_receipt = GNUNET_memdup (receipt,
754 sizeof (struct P2PConfirmationReceiptMessage)); 736 sizeof (struct P2PConfirmationReceiptMessage));
755 if (NULL == GNUNET_CORE_notify_transmit_ready (core, 737 if (NULL == GNUNET_CORE_notify_transmit_ready (core,
756 GNUNET_YES, 738 GNUNET_YES,
757 1, 739 1,
758 MAX_TRANSMIT_DELAY, 740 MAX_TRANSMIT_DELAY,
759 &pid, 741 &pid,
@@ -791,86 +773,84 @@ handle_acknowledge_request (void *cls,
791 author = client_list_head; 773 author = client_list_head;
792 while ((NULL != author) && 774 while ((NULL != author) &&
793 (0 != memcmp (&receipt->author, 775 (0 != memcmp (&receipt->author,
794 &author->id, 776 &author->id, sizeof (GNUNET_HashCode))))
795 sizeof (GNUNET_HashCode))))
796 author = author->next; 777 author = author->next;
797 if (NULL == author) 778 if (NULL == author)
798 { 779 {
799 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 780 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
800 "Unknown author of the original message\n"); 781 "Unknown author of the original message\n");
801 GNUNET_break (0); 782 GNUNET_break (0);
802 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 783 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
803 return; 784 return;
804 } 785 }
805 target = client_list_head; 786 target = client_list_head;
806 while ((NULL != target) && 787 while ((NULL != target) &&
807 (0 != memcmp (&receipt->target, 788 (0 != memcmp (&receipt->target,
808 &target->id, 789 &target->id, sizeof (GNUNET_HashCode))))
809 sizeof (GNUNET_HashCode))))
810 target = target->next; 790 target = target->next;
811 if (NULL == target) 791 if (NULL == target)
812 { 792 {
813 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 793 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
814 "Unknown target of the confirmation receipt\n"); 794 "Unknown target of the confirmation receipt\n");
815 GNUNET_break (0); 795 GNUNET_break (0);
816 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 796 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
817 return; 797 return;
818 } 798 }
819 if (NULL == author->client) 799 if (NULL == author->client)
820 { 800 {
821 target->rcpt_sequence_number++; 801 target->rcpt_sequence_number++;
822#if DEBUG_CHAT_SERVICE 802#if DEBUG_CHAT_SERVICE
823 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 803 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
824 "Broadcasting %s's receipt #%u to neighbour peers\n", 804 "Broadcasting %s's receipt #%u to neighbour peers\n",
825 GNUNET_h2s (&target->id), target->rcpt_sequence_number); 805 GNUNET_h2s (&target->id), target->rcpt_sequence_number);
826#endif 806#endif
827 p2p_crmsg = GNUNET_malloc (sizeof (struct P2PConfirmationReceiptMessage)); 807 p2p_crmsg = GNUNET_malloc (sizeof (struct P2PConfirmationReceiptMessage));
828 p2p_crmsg->header.size = htons (sizeof (struct P2PConfirmationReceiptMessage)); 808 p2p_crmsg->header.size =
829 p2p_crmsg->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_P2P_CONFIRMATION_RECEIPT); 809 htons (sizeof (struct P2PConfirmationReceiptMessage));
830 p2p_crmsg->reserved = htonl (0); 810 p2p_crmsg->header.type =
831 p2p_crmsg->signature = receipt->signature; 811 htons (GNUNET_MESSAGE_TYPE_CHAT_P2P_CONFIRMATION_RECEIPT);
832 p2p_crmsg->purpose = receipt->purpose; 812 p2p_crmsg->reserved = htonl (0);
833 p2p_crmsg->msg_sequence_number = receipt->sequence_number; 813 p2p_crmsg->signature = receipt->signature;
834 p2p_crmsg->timestamp = receipt->timestamp; 814 p2p_crmsg->purpose = receipt->purpose;
835 p2p_crmsg->target = receipt->target; 815 p2p_crmsg->msg_sequence_number = receipt->sequence_number;
836 p2p_crmsg->author = receipt->author; 816 p2p_crmsg->timestamp = receipt->timestamp;
837 p2p_crmsg->content = receipt->content; 817 p2p_crmsg->target = receipt->target;
838 p2p_crmsg->sequence_number = htonl (target->rcpt_sequence_number); 818 p2p_crmsg->author = receipt->author;
839 GNUNET_CONTAINER_multihashmap_iterate (connected_peers, 819 p2p_crmsg->content = receipt->content;
840 &send_confirmation_receipt, 820 p2p_crmsg->sequence_number = htonl (target->rcpt_sequence_number);
841 p2p_crmsg); 821 GNUNET_CONTAINER_multihashmap_iterate (connected_peers,
842 GNUNET_free (p2p_crmsg); 822 &send_confirmation_receipt,
843 } 823 p2p_crmsg);
824 GNUNET_free (p2p_crmsg);
825 }
844 else 826 else
845 { 827 {
846#if DEBUG_CHAT_SERVICE 828#if DEBUG_CHAT_SERVICE
847 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 829 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
848 "Verifying signature of the receipt\n"); 830 "Verifying signature of the receipt\n");
849#endif 831#endif
850 if (GNUNET_OK != 832 if (GNUNET_OK !=
851 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_CHAT_RECEIPT, 833 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_CHAT_RECEIPT,
852 &receipt->purpose, 834 &receipt->purpose,
853 &receipt->signature, 835 &receipt->signature, &target->public_key))
854 &target->public_key)) 836 {
855 { 837 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
856 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 838 "Invalid signature of the receipt\n");
857 "Invalid signature of the receipt\n"); 839 GNUNET_break (0);
858 GNUNET_break (0); 840 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
859 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 841 return;
860 return; 842 }
861 }
862#if DEBUG_CHAT_SERVICE 843#if DEBUG_CHAT_SERVICE
863 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 844 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
864 "Sending receipt to the client which sent the original message\n"); 845 "Sending receipt to the client which sent the original message\n");
865#endif 846#endif
866 crmsg = GNUNET_memdup (receipt, sizeof (struct ConfirmationReceiptMessage)); 847 crmsg = GNUNET_memdup (receipt, sizeof (struct ConfirmationReceiptMessage));
867 crmsg->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_NOTIFICATION); 848 crmsg->header.type =
868 GNUNET_SERVER_notification_context_unicast (nc, 849 htons (GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_NOTIFICATION);
869 author->client, 850 GNUNET_SERVER_notification_context_unicast (nc, author->client,
870 &crmsg->header, 851 &crmsg->header, GNUNET_NO);
871 GNUNET_NO); 852 GNUNET_free (crmsg);
872 GNUNET_free (crmsg); 853 }
873 }
874 GNUNET_SERVER_receive_done (client, GNUNET_OK); 854 GNUNET_SERVER_receive_done (client, GNUNET_OK);
875} 855}
876 856
@@ -885,27 +865,24 @@ handle_acknowledge_request (void *cls,
885 * @return number of bytes written to buf 865 * @return number of bytes written to buf
886 */ 866 */
887static size_t 867static size_t
888transmit_leave_notification_to_peer (void *cls, 868transmit_leave_notification_to_peer (void *cls, size_t size, void *buf)
889 size_t size,
890 void *buf)
891{ 869{
892 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key = cls; 870 struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key = cls;
893 struct P2PLeaveNotificationMessage *m = buf; 871 struct P2PLeaveNotificationMessage *m = buf;
894 size_t msg_size; 872 size_t msg_size;
895 873
896#if DEBUG_CHAT_SERVICE 874#if DEBUG_CHAT_SERVICE
897 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 875 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting P2P leave notification\n");
898 "Transmitting P2P leave notification\n");
899#endif 876#endif
900 if (buf == NULL) 877 if (buf == NULL)
901 { 878 {
902 /* client disconnected */ 879 /* client disconnected */
903#if DEBUG_CHAT_SERVICE 880#if DEBUG_CHAT_SERVICE
904 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 881 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
905 "Buffer is NULL, dropping the message\n"); 882 "Buffer is NULL, dropping the message\n");
906#endif 883#endif
907 return 0; 884 return 0;
908 } 885 }
909 msg_size = sizeof (struct P2PLeaveNotificationMessage); 886 msg_size = sizeof (struct P2PLeaveNotificationMessage);
910 GNUNET_assert (size >= msg_size); 887 GNUNET_assert (size >= msg_size);
911 m = buf; 888 m = buf;
@@ -922,9 +899,7 @@ transmit_leave_notification_to_peer (void *cls,
922 * Ask to send a leave notification to the peer. 899 * Ask to send a leave notification to the peer.
923 */ 900 */
924static int 901static int
925send_leave_noficiation (void *cls, 902send_leave_noficiation (void *cls, const GNUNET_HashCode * key, void *value)
926 const GNUNET_HashCode *key,
927 void *value)
928{ 903{
929 struct ChatClient *entry = cls; 904 struct ChatClient *entry = cls;
930 struct ConnectedPeer *cp = value; 905 struct ConnectedPeer *cp = value;
@@ -939,15 +914,13 @@ send_leave_noficiation (void *cls,
939#endif 914#endif
940 msg_size = sizeof (struct P2PLeaveNotificationMessage); 915 msg_size = sizeof (struct P2PLeaveNotificationMessage);
941 public_key = GNUNET_memdup (&entry->public_key, 916 public_key = GNUNET_memdup (&entry->public_key,
942 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); 917 sizeof (struct
943 if (NULL == GNUNET_CORE_notify_transmit_ready (core, 918 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded));
944 GNUNET_YES, 919 if (NULL ==
945 1, 920 GNUNET_CORE_notify_transmit_ready (core, GNUNET_YES, 1,
946 MAX_TRANSMIT_DELAY, 921 MAX_TRANSMIT_DELAY, &pid, msg_size,
947 &pid, 922 &transmit_leave_notification_to_peer,
948 msg_size, 923 public_key))
949 &transmit_leave_notification_to_peer,
950 public_key))
951 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 924 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
952 _("Failed to queue a leave notification\n")); 925 _("Failed to queue a leave notification\n"));
953 return GNUNET_YES; 926 return GNUNET_YES;
@@ -962,8 +935,7 @@ send_leave_noficiation (void *cls,
962 * @param client identification of the client 935 * @param client identification of the client
963 */ 936 */
964static void 937static void
965handle_client_disconnect (void *cls, 938handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
966 struct GNUNET_SERVER_Client *client)
967{ 939{
968 struct ChatClient *entry; 940 struct ChatClient *entry;
969 struct ChatClient *pos; 941 struct ChatClient *pos;
@@ -974,18 +946,18 @@ handle_client_disconnect (void *cls,
974 pos = client_list_head; 946 pos = client_list_head;
975 prev = NULL; 947 prev = NULL;
976 while ((NULL != pos) && (pos->client != client)) 948 while ((NULL != pos) && (pos->client != client))
977 { 949 {
978 prev = pos; 950 prev = pos;
979 pos = pos->next; 951 pos = pos->next;
980 } 952 }
981 if (NULL == pos) 953 if (NULL == pos)
982 { 954 {
983#if DEBUG_CHAT_SERVICE 955#if DEBUG_CHAT_SERVICE
984 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 956 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
985 "No such client. There is nothing to do\n"); 957 "No such client. There is nothing to do\n");
986#endif 958#endif
987 return; 959 return;
988 } 960 }
989 if (NULL == prev) 961 if (NULL == prev)
990 client_list_head = pos->next; 962 client_list_head = pos->next;
991 else 963 else
@@ -1000,24 +972,21 @@ handle_client_disconnect (void *cls,
1000 lnmsg.reserved = htonl (0); 972 lnmsg.reserved = htonl (0);
1001 lnmsg.user = pos->public_key; 973 lnmsg.user = pos->public_key;
1002 while (NULL != entry) 974 while (NULL != entry)
975 {
976 if ((0 == strcmp (pos->room, entry->room)) && (NULL != entry->client))
1003 { 977 {
1004 if ((0 == strcmp (pos->room, entry->room)) && 978 GNUNET_SERVER_notification_context_unicast (nc,
1005 (NULL != entry->client)) 979 entry->client,
1006 { 980 &lnmsg.header, GNUNET_NO);
1007 GNUNET_SERVER_notification_context_unicast (nc,
1008 entry->client,
1009 &lnmsg.header,
1010 GNUNET_NO);
1011 }
1012 entry = entry->next;
1013 } 981 }
982 entry = entry->next;
983 }
1014#if DEBUG_CHAT_SERVICE 984#if DEBUG_CHAT_SERVICE
1015 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 985 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1016 "Broadcasting leave notification to neighbour peers\n"); 986 "Broadcasting leave notification to neighbour peers\n");
1017#endif 987#endif
1018 GNUNET_CONTAINER_multihashmap_iterate (connected_peers, 988 GNUNET_CONTAINER_multihashmap_iterate (connected_peers,
1019 &send_leave_noficiation, 989 &send_leave_noficiation, pos);
1020 pos);
1021 GNUNET_free (pos->room); 990 GNUNET_free (pos->room);
1022 GNUNET_free_non_null (pos->member_info); 991 GNUNET_free_non_null (pos->member_info);
1023 GNUNET_free (pos); 992 GNUNET_free (pos);
@@ -1038,7 +1007,8 @@ static int
1038handle_p2p_join_notification (void *cls, 1007handle_p2p_join_notification (void *cls,
1039 const struct GNUNET_PeerIdentity *other, 1008 const struct GNUNET_PeerIdentity *other,
1040 const struct GNUNET_MessageHeader *message, 1009 const struct GNUNET_MessageHeader *message,
1041 const struct GNUNET_TRANSPORT_ATS_Information *atsi) 1010 const struct GNUNET_TRANSPORT_ATS_Information
1011 *atsi)
1042{ 1012{
1043 const struct P2PJoinNotificationMessage *p2p_jnmsg; 1013 const struct P2PJoinNotificationMessage *p2p_jnmsg;
1044 char *room_name; 1014 char *room_name;
@@ -1053,40 +1023,39 @@ handle_p2p_join_notification (void *cls,
1053 1023
1054 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Got P2P join notification\n"); 1024 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Got P2P join notification\n");
1055 if (ntohs (message->size) <= sizeof (struct P2PJoinNotificationMessage)) 1025 if (ntohs (message->size) <= sizeof (struct P2PJoinNotificationMessage))
1056 { 1026 {
1057 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed message: wrong size\n"); 1027 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed message: wrong size\n");
1058 GNUNET_break_op (0); 1028 GNUNET_break_op (0);
1059 return GNUNET_SYSERR; 1029 return GNUNET_SYSERR;
1060 } 1030 }
1061 p2p_jnmsg = (const struct P2PJoinNotificationMessage *) message; 1031 p2p_jnmsg = (const struct P2PJoinNotificationMessage *) message;
1062 header_size = ntohs (p2p_jnmsg->header.size); 1032 header_size = ntohs (p2p_jnmsg->header.size);
1063 room_name_len = ntohs (p2p_jnmsg->room_name_len); 1033 room_name_len = ntohs (p2p_jnmsg->room_name_len);
1064 if (header_size - sizeof (struct P2PJoinNotificationMessage) <= 1034 if (header_size - sizeof (struct P2PJoinNotificationMessage) <= room_name_len)
1065 room_name_len) 1035 {
1066 { 1036 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1067 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1037 "Malformed message: wrong length of the room name\n");
1068 "Malformed message: wrong length of the room name\n"); 1038 GNUNET_break_op (0);
1069 GNUNET_break_op (0); 1039 return GNUNET_SYSERR;
1070 return GNUNET_SYSERR; 1040 }
1071 }
1072 GNUNET_CRYPTO_hash (&p2p_jnmsg->public_key, 1041 GNUNET_CRYPTO_hash (&p2p_jnmsg->public_key,
1073 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 1042 sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
1074 &id); 1043 &id);
1075 entry = client_list_head; 1044 entry = client_list_head;
1076 while (NULL != entry) 1045 while (NULL != entry)
1046 {
1047 if (0 == memcmp (&entry->id, &id, sizeof (GNUNET_HashCode)))
1077 { 1048 {
1078 if (0 == memcmp (&entry->id, &id, sizeof (GNUNET_HashCode)))
1079 {
1080#if DEBUG_CHAT_SERVICE 1049#if DEBUG_CHAT_SERVICE
1081 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1050 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1082 "The client has already joined. There is nothing to do\n"); 1051 "The client has already joined. There is nothing to do\n");
1083#endif 1052#endif
1084 return GNUNET_OK; 1053 return GNUNET_OK;
1085 }
1086 entry = entry->next;
1087 } 1054 }
1055 entry = entry->next;
1056 }
1088 meta_len = 1057 meta_len =
1089 header_size - sizeof (struct P2PJoinNotificationMessage) - room_name_len; 1058 header_size - sizeof (struct P2PJoinNotificationMessage) - room_name_len;
1090 roomptr = (const char *) &p2p_jnmsg[1]; 1059 roomptr = (const char *) &p2p_jnmsg[1];
1091 room_name = GNUNET_malloc (room_name_len + 1); 1060 room_name = GNUNET_malloc (room_name_len + 1);
1092 memcpy (room_name, roomptr, room_name_len); 1061 memcpy (room_name, roomptr, room_name_len);
@@ -1099,10 +1068,10 @@ handle_p2p_join_notification (void *cls,
1099 new_entry->public_key = p2p_jnmsg->public_key; 1068 new_entry->public_key = p2p_jnmsg->public_key;
1100 new_entry->meta_len = meta_len; 1069 new_entry->meta_len = meta_len;
1101 if (meta_len > 0) 1070 if (meta_len > 0)
1102 { 1071 {
1103 new_entry->member_info = GNUNET_malloc (meta_len); 1072 new_entry->member_info = GNUNET_malloc (meta_len);
1104 memcpy (new_entry->member_info, &roomptr[room_name_len], meta_len); 1073 memcpy (new_entry->member_info, &roomptr[room_name_len], meta_len);
1105 } 1074 }
1106 else 1075 else
1107 new_entry->member_info = NULL; 1076 new_entry->member_info = NULL;
1108 new_entry->msg_options = ntohl (p2p_jnmsg->msg_options); 1077 new_entry->msg_options = ntohl (p2p_jnmsg->msg_options);
@@ -1115,30 +1084,27 @@ handle_p2p_join_notification (void *cls,
1115 jnmsg = GNUNET_malloc (sizeof (struct JoinNotificationMessage) + meta_len); 1084 jnmsg = GNUNET_malloc (sizeof (struct JoinNotificationMessage) + meta_len);
1116 jnmsg->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_JOIN_NOTIFICATION); 1085 jnmsg->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_JOIN_NOTIFICATION);
1117 jnmsg->header.size = 1086 jnmsg->header.size =
1118 htons (sizeof (struct JoinNotificationMessage) + meta_len); 1087 htons (sizeof (struct JoinNotificationMessage) + meta_len);
1119 jnmsg->msg_options = p2p_jnmsg->msg_options; 1088 jnmsg->msg_options = p2p_jnmsg->msg_options;
1120 jnmsg->public_key = new_entry->public_key; 1089 jnmsg->public_key = new_entry->public_key;
1121 memcpy (&jnmsg[1], &roomptr[room_name_len], meta_len); 1090 memcpy (&jnmsg[1], &roomptr[room_name_len], meta_len);
1122 entry = client_list_head; 1091 entry = client_list_head;
1123 while (NULL != entry) 1092 while (NULL != entry)
1093 {
1094 if ((0 == strcmp (room_name, entry->room)) && (NULL != entry->client))
1124 { 1095 {
1125 if ((0 == strcmp (room_name, entry->room)) && 1096 GNUNET_SERVER_notification_context_unicast (nc,
1126 (NULL != entry->client)) 1097 entry->client,
1127 { 1098 &jnmsg->header, GNUNET_NO);
1128 GNUNET_SERVER_notification_context_unicast (nc,
1129 entry->client,
1130 &jnmsg->header,
1131 GNUNET_NO);
1132 }
1133 entry = entry->next;
1134 } 1099 }
1100 entry = entry->next;
1101 }
1135#if DEBUG_CHAT_SERVICE 1102#if DEBUG_CHAT_SERVICE
1136 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1103 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1137 "Broadcasting join notification to neighbour peers\n"); 1104 "Broadcasting join notification to neighbour peers\n");
1138#endif 1105#endif
1139 GNUNET_CONTAINER_multihashmap_iterate (connected_peers, 1106 GNUNET_CONTAINER_multihashmap_iterate (connected_peers,
1140 &send_join_noficiation, 1107 &send_join_noficiation, new_entry);
1141 new_entry);
1142 GNUNET_free (jnmsg); 1108 GNUNET_free (jnmsg);
1143 return GNUNET_OK; 1109 return GNUNET_OK;
1144} 1110}
@@ -1158,7 +1124,8 @@ static int
1158handle_p2p_leave_notification (void *cls, 1124handle_p2p_leave_notification (void *cls,
1159 const struct GNUNET_PeerIdentity *other, 1125 const struct GNUNET_PeerIdentity *other,
1160 const struct GNUNET_MessageHeader *message, 1126 const struct GNUNET_MessageHeader *message,
1161 const struct GNUNET_TRANSPORT_ATS_Information *atsi) 1127 const struct GNUNET_TRANSPORT_ATS_Information
1128 *atsi)
1162{ 1129{
1163 const struct P2PLeaveNotificationMessage *p2p_lnmsg; 1130 const struct P2PLeaveNotificationMessage *p2p_lnmsg;
1164 GNUNET_HashCode id; 1131 GNUNET_HashCode id;
@@ -1175,20 +1142,20 @@ handle_p2p_leave_notification (void *cls,
1175 pos = client_list_head; 1142 pos = client_list_head;
1176 prev = NULL; 1143 prev = NULL;
1177 while (NULL != pos) 1144 while (NULL != pos)
1178 { 1145 {
1179 if (0 == memcmp (&pos->id, &id, sizeof (GNUNET_HashCode))) 1146 if (0 == memcmp (&pos->id, &id, sizeof (GNUNET_HashCode)))
1180 break; 1147 break;
1181 prev = pos; 1148 prev = pos;
1182 pos = pos->next; 1149 pos = pos->next;
1183 } 1150 }
1184 if (NULL == pos) 1151 if (NULL == pos)
1185 { 1152 {
1186#if DEBUG_CHAT_SERVICE 1153#if DEBUG_CHAT_SERVICE
1187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1154 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1188 "No such client. There is nothing to do\n"); 1155 "No such client. There is nothing to do\n");
1189#endif 1156#endif
1190 return GNUNET_OK; 1157 return GNUNET_OK;
1191 } 1158 }
1192 if (NULL == prev) 1159 if (NULL == prev)
1193 client_list_head = pos->next; 1160 client_list_head = pos->next;
1194 else 1161 else
@@ -1203,24 +1170,21 @@ handle_p2p_leave_notification (void *cls,
1203 lnmsg.user = pos->public_key; 1170 lnmsg.user = pos->public_key;
1204 entry = client_list_head; 1171 entry = client_list_head;
1205 while (NULL != entry) 1172 while (NULL != entry)
1173 {
1174 if (0 == strcmp (pos->room, entry->room) && (NULL != entry->client))
1206 { 1175 {
1207 if (0 == strcmp (pos->room, entry->room) && 1176 GNUNET_SERVER_notification_context_unicast (nc,
1208 (NULL != entry->client)) 1177 entry->client,
1209 { 1178 &lnmsg.header, GNUNET_NO);
1210 GNUNET_SERVER_notification_context_unicast (nc,
1211 entry->client,
1212 &lnmsg.header,
1213 GNUNET_NO);
1214 }
1215 entry = entry->next;
1216 } 1179 }
1180 entry = entry->next;
1181 }
1217#if DEBUG_CHAT_SERVICE 1182#if DEBUG_CHAT_SERVICE
1218 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1183 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1219 "Broadcasting leave notification to neighbour peers\n"); 1184 "Broadcasting leave notification to neighbour peers\n");
1220#endif 1185#endif
1221 GNUNET_CONTAINER_multihashmap_iterate (connected_peers, 1186 GNUNET_CONTAINER_multihashmap_iterate (connected_peers,
1222 &send_leave_noficiation, 1187 &send_leave_noficiation, pos);
1223 pos);
1224 GNUNET_free (pos->room); 1188 GNUNET_free (pos->room);
1225 GNUNET_free_non_null (pos->member_info); 1189 GNUNET_free_non_null (pos->member_info);
1226 GNUNET_free (pos); 1190 GNUNET_free (pos);
@@ -1242,7 +1206,8 @@ static int
1242handle_p2p_message_notification (void *cls, 1206handle_p2p_message_notification (void *cls,
1243 const struct GNUNET_PeerIdentity *other, 1207 const struct GNUNET_PeerIdentity *other,
1244 const struct GNUNET_MessageHeader *message, 1208 const struct GNUNET_MessageHeader *message,
1245 const struct GNUNET_TRANSPORT_ATS_Information *atsi) 1209 const struct GNUNET_TRANSPORT_ATS_Information
1210 *atsi)
1246{ 1211{
1247 const struct P2PReceiveNotificationMessage *p2p_rnmsg; 1212 const struct P2PReceiveNotificationMessage *p2p_rnmsg;
1248 struct P2PReceiveNotificationMessage *my_p2p_rnmsg; 1213 struct P2PReceiveNotificationMessage *my_p2p_rnmsg;
@@ -1259,74 +1224,73 @@ handle_p2p_message_notification (void *cls,
1259 1224
1260 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Got P2P message notification\n"); 1225 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Got P2P message notification\n");
1261 if (ntohs (message->size) <= sizeof (struct P2PReceiveNotificationMessage)) 1226 if (ntohs (message->size) <= sizeof (struct P2PReceiveNotificationMessage))
1262 { 1227 {
1263 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed message: wrong size\n"); 1228 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Malformed message: wrong size\n");
1264 GNUNET_break_op (0); 1229 GNUNET_break_op (0);
1265 return GNUNET_SYSERR; 1230 return GNUNET_SYSERR;
1266 } 1231 }
1267 p2p_rnmsg = (const struct P2PReceiveNotificationMessage *) message; 1232 p2p_rnmsg = (const struct P2PReceiveNotificationMessage *) message;
1268 msg_len = ntohs (p2p_rnmsg->header.size) - 1233 msg_len = ntohs (p2p_rnmsg->header.size) -
1269 sizeof (struct P2PReceiveNotificationMessage); 1234 sizeof (struct P2PReceiveNotificationMessage);
1270 1235
1271 is_anon = (0 != (ntohl (p2p_rnmsg->msg_options) & GNUNET_CHAT_MSG_ANONYMOUS)); 1236 is_anon = (0 != (ntohl (p2p_rnmsg->msg_options) & GNUNET_CHAT_MSG_ANONYMOUS));
1272 if (is_anon) 1237 if (is_anon)
1238 {
1239 room_name_len = ntohs (p2p_rnmsg->room_name_len);
1240 if (msg_len <= room_name_len)
1241 {
1242 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1243 "Malformed message: wrong length of the room name\n");
1244 GNUNET_break_op (0);
1245 return GNUNET_SYSERR;
1246 }
1247 msg_len -= room_name_len;
1248 if (lookup_anonymous_message (p2p_rnmsg))
1273 { 1249 {
1274 room_name_len = ntohs (p2p_rnmsg->room_name_len);
1275 if (msg_len <= room_name_len)
1276 {
1277 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1278 "Malformed message: wrong length of the room name\n");
1279 GNUNET_break_op (0);
1280 return GNUNET_SYSERR;
1281 }
1282 msg_len -= room_name_len;
1283 if (lookup_anonymous_message (p2p_rnmsg))
1284 {
1285#if DEBUG_CHAT_SERVICE 1250#if DEBUG_CHAT_SERVICE
1286 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1251 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1287 "This anonymous message has already been handled."); 1252 "This anonymous message has already been handled.");
1288#endif 1253#endif
1289 return GNUNET_OK; 1254 return GNUNET_OK;
1290 }
1291 remember_anonymous_message (p2p_rnmsg);
1292 room_name = GNUNET_malloc (room_name_len + 1);
1293 memcpy (room_name, (char *) &p2p_rnmsg[1], room_name_len);
1294 room_name[room_name_len] = '\0';
1295 text = (char *) &p2p_rnmsg[1] + room_name_len;
1296 } 1255 }
1256 remember_anonymous_message (p2p_rnmsg);
1257 room_name = GNUNET_malloc (room_name_len + 1);
1258 memcpy (room_name, (char *) &p2p_rnmsg[1], room_name_len);
1259 room_name[room_name_len] = '\0';
1260 text = (char *) &p2p_rnmsg[1] + room_name_len;
1261 }
1297 else 1262 else
1263 {
1264 sender = client_list_head;
1265 while ((NULL != sender) &&
1266 (0 != memcmp (&sender->id,
1267 &p2p_rnmsg->sender, sizeof (GNUNET_HashCode))))
1268 sender = sender->next;
1269 if (NULL == sender)
1298 { 1270 {
1299 sender = client_list_head; 1271 /* not an error since the sender may have left before we got the
1300 while ((NULL != sender) && 1272 * message */
1301 (0 != memcmp (&sender->id,
1302 &p2p_rnmsg->sender,
1303 sizeof (GNUNET_HashCode))))
1304 sender = sender->next;
1305 if (NULL == sender)
1306 {
1307 /* not an error since the sender may have left before we got the
1308 message */
1309#if DEBUG_CHAT_SERVICE 1273#if DEBUG_CHAT_SERVICE
1310 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1274 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1311 "Unknown source. Rejecting the message\n"); 1275 "Unknown source. Rejecting the message\n");
1312#endif 1276#endif
1313 return GNUNET_OK; 1277 return GNUNET_OK;
1314 } 1278 }
1315 if (sender->msg_sequence_number >= ntohl (p2p_rnmsg->sequence_number)) 1279 if (sender->msg_sequence_number >= ntohl (p2p_rnmsg->sequence_number))
1316 { 1280 {
1317#if DEBUG_CHAT_SERVICE 1281#if DEBUG_CHAT_SERVICE
1318 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1282 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1319 "This message has already been handled." 1283 "This message has already been handled."
1320 " Sequence numbers (msg/sender): %u/%u\n", 1284 " Sequence numbers (msg/sender): %u/%u\n",
1321 ntohl (p2p_rnmsg->sequence_number), 1285 ntohl (p2p_rnmsg->sequence_number),
1322 sender->msg_sequence_number); 1286 sender->msg_sequence_number);
1323#endif 1287#endif
1324 return GNUNET_OK; 1288 return GNUNET_OK;
1325 } 1289 }
1326 sender->msg_sequence_number = ntohl (p2p_rnmsg->sequence_number); 1290 sender->msg_sequence_number = ntohl (p2p_rnmsg->sequence_number);
1327 room_name = sender->room; 1291 room_name = sender->room;
1328 text = (char *) &p2p_rnmsg[1]; 1292 text = (char *) &p2p_rnmsg[1];
1329 } 1293 }
1330 1294
1331#if DEBUG_CHAT_SERVICE 1295#if DEBUG_CHAT_SERVICE
1332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1296 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1341,7 +1305,7 @@ handle_p2p_message_notification (void *cls,
1341 rnmsg->reserved = htonl (0); 1305 rnmsg->reserved = htonl (0);
1342 rnmsg->timestamp = p2p_rnmsg->timestamp; 1306 rnmsg->timestamp = p2p_rnmsg->timestamp;
1343 is_priv = (0 != memcmp (&all_zeros, 1307 is_priv = (0 != memcmp (&all_zeros,
1344 &p2p_rnmsg->target, sizeof (GNUNET_HashCode))); 1308 &p2p_rnmsg->target, sizeof (GNUNET_HashCode)));
1345 if (is_priv) 1309 if (is_priv)
1346 memcpy (&rnmsg->encrypted_key, 1310 memcpy (&rnmsg->encrypted_key,
1347 &p2p_rnmsg->encrypted_key, 1311 &p2p_rnmsg->encrypted_key,
@@ -1350,24 +1314,22 @@ handle_p2p_message_notification (void *cls,
1350 memcpy (&rnmsg[1], text, msg_len); 1314 memcpy (&rnmsg[1], text, msg_len);
1351 pos = client_list_head; 1315 pos = client_list_head;
1352 while (NULL != pos) 1316 while (NULL != pos)
1317 {
1318 if ((0 == strcmp (room_name, pos->room)) && (NULL != pos->client))
1353 { 1319 {
1354 if ((0 == strcmp (room_name, pos->room)) && 1320 if (((!is_priv) ||
1355 (NULL != pos->client)) 1321 (0 == memcmp (&p2p_rnmsg->target,
1356 { 1322 &pos->id,
1357 if (((!is_priv) || 1323 sizeof (GNUNET_HashCode)))) &&
1358 (0 == memcmp (&p2p_rnmsg->target, 1324 (0 == (ntohl (p2p_rnmsg->msg_options) & (~pos->msg_options))))
1359 &pos->id, 1325 {
1360 sizeof (GNUNET_HashCode)))) && 1326 GNUNET_SERVER_notification_context_unicast (nc,
1361 (0 == (ntohl (p2p_rnmsg->msg_options) & (~pos->msg_options)))) 1327 pos->client,
1362 { 1328 &rnmsg->header, GNUNET_NO);
1363 GNUNET_SERVER_notification_context_unicast (nc, 1329 }
1364 pos->client,
1365 &rnmsg->header,
1366 GNUNET_NO);
1367 }
1368 }
1369 pos = pos->next;
1370 } 1330 }
1331 pos = pos->next;
1332 }
1371 if (is_anon) 1333 if (is_anon)
1372 GNUNET_free (room_name); 1334 GNUNET_free (room_name);
1373#if DEBUG_CHAT_SERVICE 1335#if DEBUG_CHAT_SERVICE
@@ -1410,21 +1372,20 @@ handle_p2p_sync_request (void *cls,
1410#endif 1372#endif
1411 entry = client_list_head; 1373 entry = client_list_head;
1412 while (NULL != entry) 1374 while (NULL != entry)
1413 { 1375 {
1414 msg_size = sizeof (struct P2PJoinNotificationMessage) + 1376 msg_size = sizeof (struct P2PJoinNotificationMessage) +
1415 strlen (entry->room) + 1377 strlen (entry->room) + entry->meta_len;
1416 entry->meta_len; 1378 th = GNUNET_CORE_notify_transmit_ready (core,
1417 th = GNUNET_CORE_notify_transmit_ready (core, 1379 GNUNET_NO,
1418 GNUNET_NO, 1380 1,
1419 1, 1381 MAX_TRANSMIT_DELAY,
1420 MAX_TRANSMIT_DELAY, 1382 other,
1421 other, 1383 msg_size,
1422 msg_size, 1384 &transmit_join_notification_to_peer,
1423 &transmit_join_notification_to_peer, 1385 entry);
1424 entry); 1386 GNUNET_assert (NULL != th);
1425 GNUNET_assert (NULL != th); 1387 entry = entry->next;
1426 entry = entry->next; 1388 }
1427 }
1428 return GNUNET_OK; 1389 return GNUNET_OK;
1429} 1390}
1430 1391
@@ -1443,7 +1404,8 @@ static int
1443handle_p2p_confirmation_receipt (void *cls, 1404handle_p2p_confirmation_receipt (void *cls,
1444 const struct GNUNET_PeerIdentity *other, 1405 const struct GNUNET_PeerIdentity *other,
1445 const struct GNUNET_MessageHeader *message, 1406 const struct GNUNET_MessageHeader *message,
1446 const struct GNUNET_TRANSPORT_ATS_Information *atsi) 1407 const struct GNUNET_TRANSPORT_ATS_Information
1408 *atsi)
1447{ 1409{
1448 const struct P2PConfirmationReceiptMessage *p2p_crmsg; 1410 const struct P2PConfirmationReceiptMessage *p2p_crmsg;
1449 struct P2PConfirmationReceiptMessage *my_p2p_crmsg; 1411 struct P2PConfirmationReceiptMessage *my_p2p_crmsg;
@@ -1456,94 +1418,94 @@ handle_p2p_confirmation_receipt (void *cls,
1456 target = client_list_head; 1418 target = client_list_head;
1457 while ((NULL != target) && 1419 while ((NULL != target) &&
1458 (0 != memcmp (&target->id, 1420 (0 != memcmp (&target->id,
1459 &p2p_crmsg->target, 1421 &p2p_crmsg->target, sizeof (GNUNET_HashCode))))
1460 sizeof (GNUNET_HashCode))))
1461 target = target->next; 1422 target = target->next;
1462 if (NULL == target) 1423 if (NULL == target)
1463 { 1424 {
1464 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1425 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1465 "Unknown source of the receipt. Rejecting the message\n"); 1426 "Unknown source of the receipt. Rejecting the message\n");
1466 GNUNET_break_op (0); 1427 GNUNET_break_op (0);
1467 return GNUNET_SYSERR; 1428 return GNUNET_SYSERR;
1468 } 1429 }
1469 if (target->rcpt_sequence_number >= ntohl (p2p_crmsg->sequence_number)) 1430 if (target->rcpt_sequence_number >= ntohl (p2p_crmsg->sequence_number))
1470 { 1431 {
1471#if DEBUG_CHAT_SERVICE 1432#if DEBUG_CHAT_SERVICE
1472 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1433 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1473 "This receipt has already been handled." 1434 "This receipt has already been handled."
1474 " Sequence numbers (msg/sender): %u/%u\n", 1435 " Sequence numbers (msg/sender): %u/%u\n",
1475 ntohl (p2p_crmsg->sequence_number), target->rcpt_sequence_number); 1436 ntohl (p2p_crmsg->sequence_number),
1437 target->rcpt_sequence_number);
1476#endif 1438#endif
1477 return GNUNET_OK; 1439 return GNUNET_OK;
1478 } 1440 }
1479 target->rcpt_sequence_number = ntohl (p2p_crmsg->sequence_number); 1441 target->rcpt_sequence_number = ntohl (p2p_crmsg->sequence_number);
1480 author = client_list_head; 1442 author = client_list_head;
1481 while ((NULL != author) && 1443 while ((NULL != author) &&
1482 (0 != memcmp (&author->id, 1444 (0 != memcmp (&author->id,
1483 &p2p_crmsg->author, 1445 &p2p_crmsg->author, sizeof (GNUNET_HashCode))))
1484 sizeof (GNUNET_HashCode))))
1485 author = author->next; 1446 author = author->next;
1486 if (NULL == author) 1447 if (NULL == author)
1487 { 1448 {
1488 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1449 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1489 "Unknown addressee. Rejecting the receipt\n"); 1450 "Unknown addressee. Rejecting the receipt\n");
1490 GNUNET_break_op (0); 1451 GNUNET_break_op (0);
1491 return GNUNET_SYSERR; 1452 return GNUNET_SYSERR;
1492 } 1453 }
1493 1454
1494 if (NULL == author->client) 1455 if (NULL == author->client)
1495 { 1456 {
1496#if DEBUG_CHAT_SERVICE 1457#if DEBUG_CHAT_SERVICE
1497 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1458 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1498 "The author of the original message is not a local client." 1459 "The author of the original message is not a local client."
1499 " Broadcasting receipt to neighbour peers\n"); 1460 " Broadcasting receipt to neighbour peers\n");
1500#endif 1461#endif
1501 my_p2p_crmsg = GNUNET_memdup (p2p_crmsg, sizeof (struct P2PConfirmationReceiptMessage)); 1462 my_p2p_crmsg =
1502 GNUNET_CONTAINER_multihashmap_iterate (connected_peers, 1463 GNUNET_memdup (p2p_crmsg,
1503 &send_confirmation_receipt, 1464 sizeof (struct P2PConfirmationReceiptMessage));
1504 my_p2p_crmsg); 1465 GNUNET_CONTAINER_multihashmap_iterate (connected_peers,
1505 GNUNET_free (my_p2p_crmsg); 1466 &send_confirmation_receipt,
1506 } 1467 my_p2p_crmsg);
1468 GNUNET_free (my_p2p_crmsg);
1469 }
1507 else 1470 else
1508 { 1471 {
1509#if DEBUG_CHAT_SERVICE 1472#if DEBUG_CHAT_SERVICE
1510 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1473 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1511 "The author of the original message is a local client." 1474 "The author of the original message is a local client."
1512 " Verifying signature of the receipt\n"); 1475 " Verifying signature of the receipt\n");
1513#endif 1476#endif
1514 crmsg = GNUNET_malloc (sizeof (struct ConfirmationReceiptMessage)); 1477 crmsg = GNUNET_malloc (sizeof (struct ConfirmationReceiptMessage));
1515 crmsg->header.size = htons (sizeof (struct ConfirmationReceiptMessage)); 1478 crmsg->header.size = htons (sizeof (struct ConfirmationReceiptMessage));
1516 crmsg->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_NOTIFICATION); 1479 crmsg->header.type =
1517 crmsg->signature = p2p_crmsg->signature; 1480 htons (GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_NOTIFICATION);
1518 crmsg->purpose = p2p_crmsg->purpose; 1481 crmsg->signature = p2p_crmsg->signature;
1519 crmsg->sequence_number = p2p_crmsg->msg_sequence_number; 1482 crmsg->purpose = p2p_crmsg->purpose;
1520 crmsg->reserved2 = 0; 1483 crmsg->sequence_number = p2p_crmsg->msg_sequence_number;
1521 crmsg->timestamp = p2p_crmsg->timestamp; 1484 crmsg->reserved2 = 0;
1522 crmsg->target = p2p_crmsg->target; 1485 crmsg->timestamp = p2p_crmsg->timestamp;
1523 crmsg->author = p2p_crmsg->author; 1486 crmsg->target = p2p_crmsg->target;
1524 crmsg->content = p2p_crmsg->content; 1487 crmsg->author = p2p_crmsg->author;
1525 if (GNUNET_OK != 1488 crmsg->content = p2p_crmsg->content;
1526 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_CHAT_RECEIPT, 1489 if (GNUNET_OK !=
1527 &crmsg->purpose, 1490 GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_CHAT_RECEIPT,
1528 &crmsg->signature, 1491 &crmsg->purpose,
1529 &target->public_key)) 1492 &crmsg->signature, &target->public_key))
1530 { 1493 {
1531 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1494 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1532 "Invalid signature of the receipt\n"); 1495 "Invalid signature of the receipt\n");
1533 GNUNET_break_op (0); 1496 GNUNET_break_op (0);
1534 return GNUNET_SYSERR; 1497 return GNUNET_SYSERR;
1535 } 1498 }
1536#if DEBUG_CHAT_SERVICE 1499#if DEBUG_CHAT_SERVICE
1537 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1500 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1538 "The author of the original message is a local client." 1501 "The author of the original message is a local client."
1539 " Sending receipt to the client\n"); 1502 " Sending receipt to the client\n");
1540#endif 1503#endif
1541 GNUNET_SERVER_notification_context_unicast (nc, 1504 GNUNET_SERVER_notification_context_unicast (nc,
1542 author->client, 1505 author->client,
1543 &crmsg->header, 1506 &crmsg->header, GNUNET_NO);
1544 GNUNET_NO); 1507 GNUNET_free (crmsg);
1545 GNUNET_free (crmsg); 1508 }
1546 }
1547 return GNUNET_OK; 1509 return GNUNET_OK;
1548} 1510}
1549 1511
@@ -1557,9 +1519,7 @@ handle_p2p_confirmation_receipt (void *cls,
1557 * @return number of bytes written to buf 1519 * @return number of bytes written to buf
1558 */ 1520 */
1559static size_t 1521static size_t
1560transmit_sync_request_to_peer (void *cls, 1522transmit_sync_request_to_peer (void *cls, size_t size, void *buf)
1561 size_t size,
1562 void *buf)
1563{ 1523{
1564 struct GNUNET_MessageHeader *m = buf; 1524 struct GNUNET_MessageHeader *m = buf;
1565 size_t msg_size; 1525 size_t msg_size;
@@ -1584,7 +1544,7 @@ transmit_sync_request_to_peer (void *cls,
1584 * @param peer peer identity this notification is about 1544 * @param peer peer identity this notification is about
1585 * @param atsi performance data 1545 * @param atsi performance data
1586 */ 1546 */
1587static void 1547static void
1588peer_connect_handler (void *cls, 1548peer_connect_handler (void *cls,
1589 const struct GNUNET_PeerIdentity *peer, 1549 const struct GNUNET_PeerIdentity *peer,
1590 const struct GNUNET_TRANSPORT_ATS_Information *atsi) 1550 const struct GNUNET_TRANSPORT_ATS_Information *atsi)
@@ -1597,21 +1557,19 @@ peer_connect_handler (void *cls,
1597 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 1557 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1598 "Peer connected: %s\n", GNUNET_i2s (peer)); 1558 "Peer connected: %s\n", GNUNET_i2s (peer));
1599 th = GNUNET_CORE_notify_transmit_ready (core, 1559 th = GNUNET_CORE_notify_transmit_ready (core,
1600 GNUNET_YES, 1560 GNUNET_YES,
1601 1, 1561 1,
1602 MAX_TRANSMIT_DELAY, 1562 MAX_TRANSMIT_DELAY,
1603 peer, 1563 peer,
1604 sizeof (struct GNUNET_MessageHeader), 1564 sizeof (struct GNUNET_MessageHeader),
1605 &transmit_sync_request_to_peer, 1565 &transmit_sync_request_to_peer, NULL);
1606 NULL);
1607 GNUNET_assert (NULL != th); 1566 GNUNET_assert (NULL != th);
1608 cp = GNUNET_CONTAINER_multihashmap_get (connected_peers, 1567 cp = GNUNET_CONTAINER_multihashmap_get (connected_peers, &peer->hashPubKey);
1609 &peer->hashPubKey);
1610 if (NULL != cp) 1568 if (NULL != cp)
1611 { 1569 {
1612 GNUNET_break (0); 1570 GNUNET_break (0);
1613 return; 1571 return;
1614 } 1572 }
1615 cp = GNUNET_malloc (sizeof (struct ConnectedPeer)); 1573 cp = GNUNET_malloc (sizeof (struct ConnectedPeer));
1616 cp->pid = GNUNET_PEER_intern (peer); 1574 cp->pid = GNUNET_PEER_intern (peer);
1617 GNUNET_break (GNUNET_OK == 1575 GNUNET_break (GNUNET_OK ==
@@ -1630,22 +1588,19 @@ peer_connect_handler (void *cls,
1630 * @param value value in the hash map (peer entry) 1588 * @param value value in the hash map (peer entry)
1631 * @return GNUNET_YES (we should continue to iterate) 1589 * @return GNUNET_YES (we should continue to iterate)
1632 */ 1590 */
1633static int 1591static int
1634clean_peer (void *cls, 1592clean_peer (void *cls, const GNUNET_HashCode * key, void *value)
1635 const GNUNET_HashCode * key,
1636 void *value)
1637{ 1593{
1638 struct ConnectedPeer *cp; 1594 struct ConnectedPeer *cp;
1639 const struct GNUNET_PeerIdentity *peer = (const struct GNUNET_PeerIdentity *) key; 1595 const struct GNUNET_PeerIdentity *peer =
1596 (const struct GNUNET_PeerIdentity *) key;
1640 1597
1641 cp = GNUNET_CONTAINER_multihashmap_get (connected_peers, 1598 cp = GNUNET_CONTAINER_multihashmap_get (connected_peers, &peer->hashPubKey);
1642 &peer->hashPubKey);
1643 if (cp == NULL) 1599 if (cp == NULL)
1644 return GNUNET_YES; 1600 return GNUNET_YES;
1645 GNUNET_break (GNUNET_YES == 1601 GNUNET_break (GNUNET_YES ==
1646 GNUNET_CONTAINER_multihashmap_remove (connected_peers, 1602 GNUNET_CONTAINER_multihashmap_remove (connected_peers,
1647 &peer->hashPubKey, 1603 &peer->hashPubKey, cp));
1648 cp));
1649 GNUNET_PEER_change_rc (cp->pid, -1); 1604 GNUNET_PEER_change_rc (cp->pid, -1);
1650 GNUNET_free (cp); 1605 GNUNET_free (cp);
1651 return GNUNET_YES; 1606 return GNUNET_YES;
@@ -1659,8 +1614,7 @@ clean_peer (void *cls,
1659 * @param peer peer identity this notification is about 1614 * @param peer peer identity this notification is about
1660 */ 1615 */
1661static void 1616static void
1662peer_disconnect_handler (void *cls, 1617peer_disconnect_handler (void *cls, const struct GNUNET_PeerIdentity *peer)
1663 const struct GNUNET_PeerIdentity *peer)
1664{ 1618{
1665 1619
1666 if (0 == memcmp (peer, me, sizeof (struct GNUNET_PeerIdentity))) 1620 if (0 == memcmp (peer, me, sizeof (struct GNUNET_PeerIdentity)))
@@ -1678,40 +1632,37 @@ peer_disconnect_handler (void *cls,
1678 * @param tc unused 1632 * @param tc unused
1679 */ 1633 */
1680static void 1634static void
1681cleanup_task (void *cls, 1635cleanup_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1682 const struct GNUNET_SCHEDULER_TaskContext *tc)
1683{ 1636{
1684 struct AnonymousMessage *next_msg; 1637 struct AnonymousMessage *next_msg;
1685 struct ChatClient *next_client; 1638 struct ChatClient *next_client;
1686 1639
1687 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Cleaning up\n"); 1640 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Cleaning up\n");
1688 if (NULL != core) 1641 if (NULL != core)
1689 { 1642 {
1690 GNUNET_CORE_disconnect (core); 1643 GNUNET_CORE_disconnect (core);
1691 core = NULL; 1644 core = NULL;
1692 } 1645 }
1693 if (NULL != nc) 1646 if (NULL != nc)
1694 { 1647 {
1695 GNUNET_SERVER_notification_context_destroy (nc); 1648 GNUNET_SERVER_notification_context_destroy (nc);
1696 nc = NULL; 1649 nc = NULL;
1697 } 1650 }
1698 while (NULL != client_list_head) 1651 while (NULL != client_list_head)
1699 { 1652 {
1700 next_client = client_list_head->next; 1653 next_client = client_list_head->next;
1701 GNUNET_free (client_list_head->room); 1654 GNUNET_free (client_list_head->room);
1702 GNUNET_free_non_null (client_list_head->member_info); 1655 GNUNET_free_non_null (client_list_head->member_info);
1703 GNUNET_free (client_list_head); 1656 GNUNET_free (client_list_head);
1704 client_list_head = next_client; 1657 client_list_head = next_client;
1705 } 1658 }
1706 while (NULL != anonymous_list_head) 1659 while (NULL != anonymous_list_head)
1707 { 1660 {
1708 next_msg = anonymous_list_head->next; 1661 next_msg = anonymous_list_head->next;
1709 GNUNET_free (anonymous_list_head); 1662 GNUNET_free (anonymous_list_head);
1710 anonymous_list_head = next_msg; 1663 anonymous_list_head = next_msg;
1711 } 1664 }
1712 GNUNET_CONTAINER_multihashmap_iterate (connected_peers, 1665 GNUNET_CONTAINER_multihashmap_iterate (connected_peers, &clean_peer, NULL);
1713 &clean_peer,
1714 NULL);
1715 GNUNET_CONTAINER_multihashmap_destroy (connected_peers); 1666 GNUNET_CONTAINER_multihashmap_destroy (connected_peers);
1716 connected_peers = NULL; 1667 connected_peers = NULL;
1717} 1668}
@@ -1748,34 +1699,32 @@ run (void *cls,
1748 struct GNUNET_SERVER_Handle *server, 1699 struct GNUNET_SERVER_Handle *server,
1749 const struct GNUNET_CONFIGURATION_Handle *c) 1700 const struct GNUNET_CONFIGURATION_Handle *c)
1750{ 1701{
1751 static const struct GNUNET_SERVER_MessageHandler handlers[] = 1702 static const struct GNUNET_SERVER_MessageHandler handlers[] = {
1752 { 1703 {&handle_join_request, NULL,
1753 { &handle_join_request, NULL, 1704 GNUNET_MESSAGE_TYPE_CHAT_JOIN_REQUEST, 0},
1754 GNUNET_MESSAGE_TYPE_CHAT_JOIN_REQUEST, 0 }, 1705 {&handle_transmit_request, NULL,
1755 { &handle_transmit_request, NULL, 1706 GNUNET_MESSAGE_TYPE_CHAT_TRANSMIT_REQUEST, 0},
1756 GNUNET_MESSAGE_TYPE_CHAT_TRANSMIT_REQUEST, 0 }, 1707 {&handle_acknowledge_request, NULL,
1757 { &handle_acknowledge_request, NULL, 1708 GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_RECEIPT,
1758 GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_RECEIPT, 1709 sizeof (struct ConfirmationReceiptMessage)},
1759 sizeof (struct ConfirmationReceiptMessage) }, 1710 {NULL, NULL, 0, 0}
1760 { NULL, NULL, 0, 0 } 1711 };
1761 }; 1712 static const struct GNUNET_CORE_MessageHandler p2p_handlers[] = {
1762 static const struct GNUNET_CORE_MessageHandler p2p_handlers[] = 1713 {&handle_p2p_join_notification,
1763 { 1714 GNUNET_MESSAGE_TYPE_CHAT_P2P_JOIN_NOTIFICATION, 0},
1764 { &handle_p2p_join_notification, 1715 {&handle_p2p_leave_notification,
1765 GNUNET_MESSAGE_TYPE_CHAT_P2P_JOIN_NOTIFICATION, 0 }, 1716 GNUNET_MESSAGE_TYPE_CHAT_P2P_LEAVE_NOTIFICATION,
1766 { &handle_p2p_leave_notification, 1717 sizeof (struct P2PLeaveNotificationMessage)},
1767 GNUNET_MESSAGE_TYPE_CHAT_P2P_LEAVE_NOTIFICATION, 1718 {&handle_p2p_message_notification,
1768 sizeof (struct P2PLeaveNotificationMessage) }, 1719 GNUNET_MESSAGE_TYPE_CHAT_P2P_MESSAGE_NOTIFICATION, 0},
1769 { &handle_p2p_message_notification, 1720 {&handle_p2p_sync_request,
1770 GNUNET_MESSAGE_TYPE_CHAT_P2P_MESSAGE_NOTIFICATION, 0 }, 1721 GNUNET_MESSAGE_TYPE_CHAT_P2P_SYNC_REQUEST,
1771 { &handle_p2p_sync_request, 1722 sizeof (struct GNUNET_MessageHeader)},
1772 GNUNET_MESSAGE_TYPE_CHAT_P2P_SYNC_REQUEST, 1723 {&handle_p2p_confirmation_receipt,
1773 sizeof (struct GNUNET_MessageHeader) }, 1724 GNUNET_MESSAGE_TYPE_CHAT_P2P_CONFIRMATION_RECEIPT,
1774 { &handle_p2p_confirmation_receipt, 1725 sizeof (struct P2PConfirmationReceiptMessage)},
1775 GNUNET_MESSAGE_TYPE_CHAT_P2P_CONFIRMATION_RECEIPT, 1726 {NULL, 0, 0}
1776 sizeof (struct P2PConfirmationReceiptMessage) }, 1727 };
1777 { NULL, 0, 0 }
1778 };
1779 1728
1780 GNUNET_log_setup ("gnunet-service-chat", 1729 GNUNET_log_setup ("gnunet-service-chat",
1781#if DEBUG_CHAT_SERVICE 1730#if DEBUG_CHAT_SERVICE
@@ -1786,7 +1735,8 @@ run (void *cls,
1786 NULL); 1735 NULL);
1787 cfg = c; 1736 cfg = c;
1788 nc = GNUNET_SERVER_notification_context_create (server, 16); 1737 nc = GNUNET_SERVER_notification_context_create (server, 16);
1789 connected_peers = GNUNET_CONTAINER_multihashmap_create (EXPECTED_NEIGHBOUR_COUNT); 1738 connected_peers =
1739 GNUNET_CONTAINER_multihashmap_create (EXPECTED_NEIGHBOUR_COUNT);
1790 GNUNET_SERVER_add_handlers (server, handlers); 1740 GNUNET_SERVER_add_handlers (server, handlers);
1791 core = GNUNET_CORE_connect (cfg, 1741 core = GNUNET_CORE_connect (cfg,
1792 QUEUE_SIZE, 1742 QUEUE_SIZE,
@@ -1795,15 +1745,10 @@ run (void *cls,
1795 &peer_connect_handler, 1745 &peer_connect_handler,
1796 &peer_disconnect_handler, 1746 &peer_disconnect_handler,
1797 NULL, 1747 NULL,
1798 NULL, GNUNET_NO, 1748 NULL, GNUNET_NO, NULL, GNUNET_NO, p2p_handlers);
1799 NULL, GNUNET_NO, 1749 GNUNET_SERVER_disconnect_notify (server, &handle_client_disconnect, NULL);
1800 p2p_handlers);
1801 GNUNET_SERVER_disconnect_notify (server,
1802 &handle_client_disconnect,
1803 NULL);
1804 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, 1750 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
1805 &cleanup_task, 1751 &cleanup_task, NULL);
1806 NULL);
1807} 1752}
1808 1753
1809 1754
@@ -1821,8 +1766,7 @@ main (int argc, char *const *argv)
1821 GNUNET_SERVICE_run (argc, 1766 GNUNET_SERVICE_run (argc,
1822 argv, 1767 argv,
1823 "chat", 1768 "chat",
1824 GNUNET_SERVICE_OPTION_NONE, 1769 GNUNET_SERVICE_OPTION_NONE, &run, NULL)) ? 0 : 1;
1825 &run, NULL)) ? 0 : 1;
1826} 1770}
1827 1771
1828/* end of gnunet-service-chat.c */ 1772/* end of gnunet-service-chat.c */