aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-communicator-unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-communicator-unix.c')
-rw-r--r--src/transport/gnunet-communicator-unix.c494
1 files changed, 211 insertions, 283 deletions
diff --git a/src/transport/gnunet-communicator-unix.c b/src/transport/gnunet-communicator-unix.c
index 9bbc02c65..1772e3647 100644
--- a/src/transport/gnunet-communicator-unix.c
+++ b/src/transport/gnunet-communicator-unix.c
@@ -75,7 +75,6 @@ struct UNIXMessage
75 * What is the identity of the sender (GNUNET_hash of public key) 75 * What is the identity of the sender (GNUNET_hash of public key)
76 */ 76 */
77 struct GNUNET_PeerIdentity sender; 77 struct GNUNET_PeerIdentity sender;
78
79}; 78};
80 79
81GNUNET_NETWORK_STRUCT_END 80GNUNET_NETWORK_STRUCT_END
@@ -142,7 +141,6 @@ struct Queue
142 * Queue timeout task. 141 * Queue timeout task.
143 */ 142 */
144 struct GNUNET_SCHEDULER_Task *timeout_task; 143 struct GNUNET_SCHEDULER_Task *timeout_task;
145
146}; 144};
147 145
148 146
@@ -215,13 +213,11 @@ queue_destroy (struct Queue *queue)
215 struct GNUNET_MQ_Handle *mq; 213 struct GNUNET_MQ_Handle *mq;
216 214
217 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 215 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
218 "Disconnecting queue for peer `%s'\n", 216 "Disconnecting queue for peer `%s'\n",
219 GNUNET_i2s (&queue->target)); 217 GNUNET_i2s (&queue->target));
220 if (0 != queue->bytes_in_queue) 218 if (0 != queue->bytes_in_queue)
221 { 219 {
222 GNUNET_CONTAINER_DLL_remove (queue_head, 220 GNUNET_CONTAINER_DLL_remove (queue_head, queue_tail, queue);
223 queue_tail,
224 queue);
225 queue->bytes_in_queue = 0; 221 queue->bytes_in_queue = 0;
226 } 222 }
227 if (NULL != (mq = queue->mq)) 223 if (NULL != (mq = queue->mq))
@@ -229,14 +225,13 @@ queue_destroy (struct Queue *queue)
229 queue->mq = NULL; 225 queue->mq = NULL;
230 GNUNET_MQ_destroy (mq); 226 GNUNET_MQ_destroy (mq);
231 } 227 }
232 GNUNET_assert (GNUNET_YES == 228 GNUNET_assert (
233 GNUNET_CONTAINER_multipeermap_remove (queue_map, 229 GNUNET_YES ==
234 &queue->target, 230 GNUNET_CONTAINER_multipeermap_remove (queue_map, &queue->target, queue));
235 queue));
236 GNUNET_STATISTICS_set (stats, 231 GNUNET_STATISTICS_set (stats,
237 "# queues active", 232 "# queues active",
238 GNUNET_CONTAINER_multipeermap_size (queue_map), 233 GNUNET_CONTAINER_multipeermap_size (queue_map),
239 GNUNET_NO); 234 GNUNET_NO);
240 if (NULL != queue->timeout_task) 235 if (NULL != queue->timeout_task)
241 { 236 {
242 GNUNET_SCHEDULER_cancel (queue->timeout_task); 237 GNUNET_SCHEDULER_cancel (queue->timeout_task);
@@ -264,17 +259,16 @@ queue_timeout (void *cls)
264 { 259 {
265 /* not actually our turn yet, but let's at least update 260 /* not actually our turn yet, but let's at least update
266 the monitor, it may think we're about to die ... */ 261 the monitor, it may think we're about to die ... */
267 queue->timeout_task 262 queue->timeout_task =
268 = GNUNET_SCHEDULER_add_delayed (left, 263 GNUNET_SCHEDULER_add_delayed (left, &queue_timeout, queue);
269 &queue_timeout,
270 queue);
271 return; 264 return;
272 } 265 }
273 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 266 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
274 "Queue %p was idle for %s, disconnecting\n", 267 "Queue %p was idle for %s, disconnecting\n",
275 queue, 268 queue,
276 GNUNET_STRINGS_relative_time_to_string (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 269 GNUNET_STRINGS_relative_time_to_string (
277 GNUNET_YES)); 270 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
271 GNUNET_YES));
278 queue_destroy (queue); 272 queue_destroy (queue);
279} 273}
280 274
@@ -290,8 +284,8 @@ static void
290reschedule_queue_timeout (struct Queue *queue) 284reschedule_queue_timeout (struct Queue *queue)
291{ 285{
292 GNUNET_assert (NULL != queue->timeout_task); 286 GNUNET_assert (NULL != queue->timeout_task);
293 queue->timeout 287 queue->timeout =
294 = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); 288 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
295} 289}
296 290
297 291
@@ -304,21 +298,18 @@ reschedule_queue_timeout (struct Queue *queue)
304 * @return converted unix path 298 * @return converted unix path
305 */ 299 */
306static struct sockaddr_un * 300static struct sockaddr_un *
307unix_address_to_sockaddr (const char *unixpath, 301unix_address_to_sockaddr (const char *unixpath, socklen_t *sock_len)
308 socklen_t *sock_len)
309{ 302{
310 struct sockaddr_un *un; 303 struct sockaddr_un *un;
311 size_t slen; 304 size_t slen;
312 305
313 GNUNET_assert (0 < strlen (unixpath)); /* sanity check */ 306 GNUNET_assert (0 < strlen (unixpath)); /* sanity check */
314 un = GNUNET_new (struct sockaddr_un); 307 un = GNUNET_new (struct sockaddr_un);
315 un->sun_family = AF_UNIX; 308 un->sun_family = AF_UNIX;
316 slen = strlen (unixpath); 309 slen = strlen (unixpath);
317 if (slen >= sizeof (un->sun_path)) 310 if (slen >= sizeof (un->sun_path))
318 slen = sizeof (un->sun_path) - 1; 311 slen = sizeof (un->sun_path) - 1;
319 GNUNET_memcpy (un->sun_path, 312 GNUNET_memcpy (un->sun_path, unixpath, slen);
320 unixpath,
321 slen);
322 un->sun_path[slen] = '\0'; 313 un->sun_path[slen] = '\0';
323 slen = sizeof (struct sockaddr_un); 314 slen = sizeof (struct sockaddr_un);
324#if HAVE_SOCKADDR_UN_SUN_LEN 315#if HAVE_SOCKADDR_UN_SUN_LEN
@@ -362,17 +353,13 @@ struct LookupCtx
362 * @return #GNUNET_YES if not found (continue looking), #GNUNET_NO on success 353 * @return #GNUNET_YES if not found (continue looking), #GNUNET_NO on success
363 */ 354 */
364static int 355static int
365lookup_queue_it (void *cls, 356lookup_queue_it (void *cls, const struct GNUNET_PeerIdentity *key, void *value)
366 const struct GNUNET_PeerIdentity *key,
367 void *value)
368{ 357{
369 struct LookupCtx *lctx = cls; 358 struct LookupCtx *lctx = cls;
370 struct Queue *queue = value; 359 struct Queue *queue = value;
371 360
372 if ( (queue->address_len = lctx->un_len) && 361 if ((queue->address_len = lctx->un_len) &&
373 (0 == memcmp (lctx->un, 362 (0 == memcmp (lctx->un, queue->address, queue->address_len)))
374 queue->address,
375 queue->address_len)) )
376 { 363 {
377 lctx->res = queue; 364 lctx->res = queue;
378 return GNUNET_NO; 365 return GNUNET_NO;
@@ -390,17 +377,17 @@ lookup_queue_it (void *cls,
390 */ 377 */
391static struct Queue * 378static struct Queue *
392lookup_queue (const struct GNUNET_PeerIdentity *peer, 379lookup_queue (const struct GNUNET_PeerIdentity *peer,
393 const struct sockaddr_un *un, 380 const struct sockaddr_un *un,
394 socklen_t un_len) 381 socklen_t un_len)
395{ 382{
396 struct LookupCtx lctx; 383 struct LookupCtx lctx;
397 384
398 lctx.un = un; 385 lctx.un = un;
399 lctx.un_len = un_len; 386 lctx.un_len = un_len;
400 GNUNET_CONTAINER_multipeermap_get_multiple (queue_map, 387 GNUNET_CONTAINER_multipeermap_get_multiple (queue_map,
401 peer, 388 peer,
402 &lookup_queue_it, 389 &lookup_queue_it,
403 &lctx); 390 &lctx);
404 return lctx.res; 391 return lctx.res;
405} 392}
406 393
@@ -417,26 +404,21 @@ select_write_cb (void *cls)
417 struct Queue *queue = queue_tail; 404 struct Queue *queue = queue_tail;
418 const struct GNUNET_MessageHeader *msg = queue->msg; 405 const struct GNUNET_MessageHeader *msg = queue->msg;
419 size_t msg_size = ntohs (msg->size); 406 size_t msg_size = ntohs (msg->size);
420 const void *msg;
421 ssize_t sent; 407 ssize_t sent;
422 408
423 /* take queue of the ready list */ 409 /* take queue of the ready list */
424 write_task = NULL; 410 write_task = NULL;
425 GNUNET_CONTAINER_DLL_remove (queue_head, 411 GNUNET_CONTAINER_DLL_remove (queue_head, queue_tail, queue);
426 queue_tail,
427 queue);
428 if (NULL != queue_head) 412 if (NULL != queue_head)
429 write_task = 413 write_task = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
430 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 414 unix_sock,
431 unix_sock, 415 &select_write_cb,
432 &select_write_cb, 416 NULL);
433 NULL);
434 417
435 /* send 'msg' */ 418 /* send 'msg' */
436 msg = queue->msg;
437 queue->msg = NULL; 419 queue->msg = NULL;
438 GNUNET_MQ_impl_send_continue (queue->mq); 420 GNUNET_MQ_impl_send_continue (queue->mq);
439 resend: 421resend:
440 /* Send the data */ 422 /* Send the data */
441 sent = GNUNET_NETWORK_socket_sendto (unix_sock, 423 sent = GNUNET_NETWORK_socket_sendto (unix_sock,
442 msg, 424 msg,
@@ -444,79 +426,74 @@ select_write_cb (void *cls)
444 (const struct sockaddr *) queue->address, 426 (const struct sockaddr *) queue->address,
445 queue->address_len); 427 queue->address_len);
446 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 428 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
447 "UNIX transmitted message to %s (%d/%u: %s)\n", 429 "UNIX transmitted message to %s (%d/%u: %s)\n",
448 GNUNET_i2s (&queue->target), 430 GNUNET_i2s (&queue->target),
449 (int) sent, 431 (int) sent,
450 (unsigned int) msg_size, 432 (unsigned int) msg_size,
451 (sent < 0) ? STRERROR (errno) : "ok"); 433 (sent < 0) ? STRERROR (errno) : "ok");
452 if (-1 != sent) 434 if (-1 != sent)
453 { 435 {
454 GNUNET_STATISTICS_update (stats, 436 GNUNET_STATISTICS_update (stats,
455 "# bytes sent", 437 "# bytes sent",
456 (long long) sent, 438 (long long) sent,
457 GNUNET_NO); 439 GNUNET_NO);
458 reschedule_queue_timeout (queue); 440 reschedule_queue_timeout (queue);
459 return; /* all good */ 441 return; /* all good */
460 } 442 }
461 GNUNET_STATISTICS_update (stats, 443 GNUNET_STATISTICS_update (stats,
462 "# network transmission failures", 444 "# network transmission failures",
463 1, 445 1,
464 GNUNET_NO); 446 GNUNET_NO);
465 switch (errno) 447 switch (errno)
466 { 448 {
467 case EAGAIN: 449 case EAGAIN:
468 case ENOBUFS: 450 case ENOBUFS:
469 /* We should retry later... */ 451 /* We should retry later... */
470 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, 452 GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "send");
471 "send");
472 return; 453 return;
473 case EMSGSIZE: 454 case EMSGSIZE: {
455 socklen_t size = 0;
456 socklen_t len = sizeof (size);
457
458 GNUNET_NETWORK_socket_getsockopt (unix_sock,
459 SOL_SOCKET,
460 SO_SNDBUF,
461 &size,
462 &len);
463 if (size > ntohs (msg->size))
474 { 464 {
475 socklen_t size = 0; 465 /* Buffer is bigger than message: error, no retry
476 socklen_t len = sizeof (size);
477
478 GNUNET_NETWORK_socket_getsockopt (unix_sock,
479 SOL_SOCKET,
480 SO_SNDBUF,
481 &size,
482 &len);
483 if (size > ntohs (msg->size))
484 {
485 /* Buffer is bigger than message: error, no retry
486 * This should never happen!*/ 466 * This should never happen!*/
487 GNUNET_break (0); 467 GNUNET_break (0);
488 return;
489 }
490 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
491 "Trying to increase socket buffer size from %u to %u for message size %u\n",
492 (unsigned int) size,
493 (unsigned int) ((msg_size / 1000) + 2) * 1000,
494 (unsigned int) msg_size);
495 size = ((msg_size / 1000) + 2) * 1000;
496 if (GNUNET_OK ==
497 GNUNET_NETWORK_socket_setsockopt (unix_sock,
498 SOL_SOCKET,
499 SO_SNDBUF,
500 &size,
501 sizeof (size)))
502 goto resend; /* Increased buffer size, retry sending */
503 /* Ok, then just try very modest increase */
504 size = msg_size;
505 if (GNUNET_OK ==
506 GNUNET_NETWORK_socket_setsockopt (unix_sock,
507 SOL_SOCKET,
508 SO_SNDBUF,
509 &size,
510 sizeof (size)))
511 goto resend; /* Increased buffer size, retry sending */
512 /* Could not increase buffer size: error, no retry */
513 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
514 "setsockopt");
515 return; 468 return;
516 } 469 }
470 GNUNET_log (
471 GNUNET_ERROR_TYPE_DEBUG,
472 "Trying to increase socket buffer size from %u to %u for message size %u\n",
473 (unsigned int) size,
474 (unsigned int) ((msg_size / 1000) + 2) * 1000,
475 (unsigned int) msg_size);
476 size = ((msg_size / 1000) + 2) * 1000;
477 if (GNUNET_OK == GNUNET_NETWORK_socket_setsockopt (unix_sock,
478 SOL_SOCKET,
479 SO_SNDBUF,
480 &size,
481 sizeof (size)))
482 goto resend; /* Increased buffer size, retry sending */
483 /* Ok, then just try very modest increase */
484 size = msg_size;
485 if (GNUNET_OK == GNUNET_NETWORK_socket_setsockopt (unix_sock,
486 SOL_SOCKET,
487 SO_SNDBUF,
488 &size,
489 sizeof (size)))
490 goto resend; /* Increased buffer size, retry sending */
491 /* Could not increase buffer size: error, no retry */
492 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "setsockopt");
493 return;
494 }
517 default: 495 default:
518 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, 496 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "send");
519 "send");
520 return; 497 return;
521 } 498 }
522} 499}
@@ -532,24 +509,21 @@ select_write_cb (void *cls)
532 */ 509 */
533static void 510static void
534mq_send (struct GNUNET_MQ_Handle *mq, 511mq_send (struct GNUNET_MQ_Handle *mq,
535 const struct GNUNET_MessageHeader *msg, 512 const struct GNUNET_MessageHeader *msg,
536 void *impl_state) 513 void *impl_state)
537{ 514{
538 struct Queue *queue = impl_state; 515 struct Queue *queue = impl_state;
539 516
540 GNUNET_assert (mq == queue->mq); 517 GNUNET_assert (mq == queue->mq);
541 GNUNET_assert (NULL == queue->msg); 518 GNUNET_assert (NULL == queue->msg);
542 queue->msg = msg; 519 queue->msg = msg;
543 GNUNET_CONTAINER_DLL_insert (queue_head, 520 GNUNET_CONTAINER_DLL_insert (queue_head, queue_tail, queue);
544 queue_tail,
545 queue);
546 GNUNET_assert (NULL != unix_sock); 521 GNUNET_assert (NULL != unix_sock);
547 if (NULL == write_task) 522 if (NULL == write_task)
548 write_task = 523 write_task = GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
549 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL, 524 unix_sock,
550 unix_sock, 525 &select_write_cb,
551 &select_write_cb, 526 NULL);
552 NULL);
553} 527}
554 528
555 529
@@ -562,8 +536,7 @@ mq_send (struct GNUNET_MQ_Handle *mq,
562 * @param impl_state our `struct Queue` 536 * @param impl_state our `struct Queue`
563 */ 537 */
564static void 538static void
565mq_destroy (struct GNUNET_MQ_Handle *mq, 539mq_destroy (struct GNUNET_MQ_Handle *mq, void *impl_state)
566 void *impl_state)
567{ 540{
568 struct Queue *queue = impl_state; 541 struct Queue *queue = impl_state;
569 542
@@ -582,16 +555,13 @@ mq_destroy (struct GNUNET_MQ_Handle *mq,
582 * @param impl_state our `struct Queue` 555 * @param impl_state our `struct Queue`
583 */ 556 */
584static void 557static void
585mq_cancel (struct GNUNET_MQ_Handle *mq, 558mq_cancel (struct GNUNET_MQ_Handle *mq, void *impl_state)
586 void *impl_state)
587{ 559{
588 struct Queue *queue = impl_state; 560 struct Queue *queue = impl_state;
589 561
590 GNUNET_assert (NULL != queue->msg); 562 GNUNET_assert (NULL != queue->msg);
591 queue->msg = NULL; 563 queue->msg = NULL;
592 GNUNET_CONTAINER_DLL_remove (queue_head, 564 GNUNET_CONTAINER_DLL_remove (queue_head, queue_tail, queue);
593 queue_tail,
594 queue);
595 GNUNET_assert (NULL != write_task); 565 GNUNET_assert (NULL != write_task);
596 if (NULL == queue_head) 566 if (NULL == queue_head)
597 { 567 {
@@ -611,15 +581,14 @@ mq_cancel (struct GNUNET_MQ_Handle *mq,
611 * @param error error code 581 * @param error error code
612 */ 582 */
613static void 583static void
614mq_error (void *cls, 584mq_error (void *cls, enum GNUNET_MQ_Error error)
615 enum GNUNET_MQ_Error error)
616{ 585{
617 struct Queue *queue = cls; 586 struct Queue *queue = cls;
618 587
619 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 588 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
620 "UNIX MQ error in queue to %s: %d\n", 589 "UNIX MQ error in queue to %s: %d\n",
621 GNUNET_i2s (&queue->target), 590 GNUNET_i2s (&queue->target),
622 (int) error); 591 (int) error);
623 queue_destroy (queue); 592 queue_destroy (queue);
624} 593}
625 594
@@ -644,30 +613,30 @@ setup_queue (const struct GNUNET_PeerIdentity *target,
644 613
645 queue = GNUNET_new (struct Queue); 614 queue = GNUNET_new (struct Queue);
646 queue->target = *target; 615 queue->target = *target;
647 queue->address = GNUNET_memdup (un, 616 queue->address = GNUNET_memdup (un, un_len);
648 un_len);
649 queue->address_len = un_len; 617 queue->address_len = un_len;
650 (void) GNUNET_CONTAINER_multipeermap_put (queue_map, 618 (void) GNUNET_CONTAINER_multipeermap_put (
651 &queue->target, 619 queue_map,
652 queue, 620 &queue->target,
653 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 621 queue,
622 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
654 GNUNET_STATISTICS_set (stats, 623 GNUNET_STATISTICS_set (stats,
655 "# queues active", 624 "# queues active",
656 GNUNET_CONTAINER_multipeermap_size (queue_map), 625 GNUNET_CONTAINER_multipeermap_size (queue_map),
657 GNUNET_NO); 626 GNUNET_NO);
658 queue->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); 627 queue->timeout =
659 queue->timeout_task 628 GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
660 = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 629 queue->timeout_task =
661 &queue_timeout, 630 GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
662 queue); 631 &queue_timeout,
663 queue->mq 632 queue);
664 = GNUNET_MQ_queue_for_callbacks (&mq_send, 633 queue->mq = GNUNET_MQ_queue_for_callbacks (&mq_send,
665 &mq_destroy, 634 &mq_destroy,
666 &mq_cancel, 635 &mq_cancel,
667 queue, 636 queue,
668 NULL, 637 NULL,
669 &mq_error, 638 &mq_error,
670 queue); 639 queue);
671 { 640 {
672 char *foreign_addr; 641 char *foreign_addr;
673 642
@@ -681,14 +650,13 @@ setup_queue (const struct GNUNET_PeerIdentity *target,
681 "%s-%s", 650 "%s-%s",
682 COMMUNICATOR_ADDRESS_PREFIX, 651 COMMUNICATOR_ADDRESS_PREFIX,
683 un->sun_path); 652 un->sun_path);
684 queue->qh 653 queue->qh = GNUNET_TRANSPORT_communicator_mq_add (ch,
685 = GNUNET_TRANSPORT_communicator_mq_add (ch, 654 &queue->target,
686 &queue->target, 655 foreign_addr,
687 foreign_addr, 656 UNIX_MTU,
688 UNIX_MTU, 657 GNUNET_NT_LOOPBACK,
689 GNUNET_NT_LOOPBACK, 658 cs,
690 cs, 659 queue->mq);
691 queue->mq);
692 GNUNET_free (foreign_addr); 660 GNUNET_free (foreign_addr);
693 } 661 }
694 return queue; 662 return queue;
@@ -714,8 +682,7 @@ select_read_cb (void *cls);
714 * @param success #GNUNET_OK on success 682 * @param success #GNUNET_OK on success
715 */ 683 */
716static void 684static void
717receive_complete_cb (void *cls, 685receive_complete_cb (void *cls, int success)
718 int success)
719{ 686{
720 delivering_messages--; 687 delivering_messages--;
721 if (GNUNET_OK != success) 688 if (GNUNET_OK != success)
@@ -724,8 +691,7 @@ receive_complete_cb (void *cls,
724 1, 691 1,
725 GNUNET_NO); 692 GNUNET_NO);
726 GNUNET_assert (NULL != unix_sock); 693 GNUNET_assert (NULL != unix_sock);
727 if ( (NULL == read_task) && 694 if ((NULL == read_task) && (delivering_messages < max_queue_length))
728 (delivering_messages < max_queue_length) )
729 read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 695 read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
730 unix_sock, 696 unix_sock,
731 &select_read_cb, 697 &select_read_cb,
@@ -757,22 +723,17 @@ select_read_cb (void *cls)
757 &select_read_cb, 723 &select_read_cb,
758 NULL); 724 NULL);
759 addrlen = sizeof (un); 725 addrlen = sizeof (un);
760 memset (&un, 726 memset (&un, 0, sizeof (un));
761 0,
762 sizeof (un));
763 ret = GNUNET_NETWORK_socket_recvfrom (unix_sock, 727 ret = GNUNET_NETWORK_socket_recvfrom (unix_sock,
764 buf, 728 buf,
765 sizeof (buf), 729 sizeof (buf),
766 (struct sockaddr *) &un, 730 (struct sockaddr *) &un,
767 &addrlen); 731 &addrlen);
768 if ( (-1 == ret) && 732 if ((-1 == ret) && ((EAGAIN == errno) || (ENOBUFS == errno)))
769 ( (EAGAIN == errno) ||
770 (ENOBUFS == errno) ) )
771 return; 733 return;
772 if (-1 == ret) 734 if (-1 == ret)
773 { 735 {
774 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, 736 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "recvfrom");
775 "recvfrom");
776 return; 737 return;
777 } 738 }
778 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 739 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -782,26 +743,23 @@ select_read_cb (void *cls)
782 GNUNET_assert (AF_UNIX == (un.sun_family)); 743 GNUNET_assert (AF_UNIX == (un.sun_family));
783 msg = (struct UNIXMessage *) buf; 744 msg = (struct UNIXMessage *) buf;
784 msize = ntohs (msg->header.size); 745 msize = ntohs (msg->header.size);
785 if ( (msize < sizeof (struct UNIXMessage)) || 746 if ((msize < sizeof (struct UNIXMessage)) || (msize > ret))
786 (msize > ret) )
787 { 747 {
788 GNUNET_break_op (0); 748 GNUNET_break_op (0);
789 return; 749 return;
790 } 750 }
791 queue = lookup_queue (&msg->sender, 751 queue = lookup_queue (&msg->sender, &un, addrlen);
792 &un,
793 addrlen);
794 if (NULL == queue) 752 if (NULL == queue)
795 queue = setup_queue (&msg->sender, 753 queue =
796 GNUNET_TRANSPORT_CS_INBOUND, 754 setup_queue (&msg->sender, GNUNET_TRANSPORT_CS_INBOUND, &un, addrlen);
797 &un,
798 addrlen);
799 else 755 else
800 reschedule_queue_timeout (queue); 756 reschedule_queue_timeout (queue);
801 if (NULL == queue) 757 if (NULL == queue)
802 { 758 {
803 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 759 GNUNET_log (
804 _("Maximum number of UNIX connections exceeded, dropping incoming message\n")); 760 GNUNET_ERROR_TYPE_ERROR,
761 _ (
762 "Maximum number of UNIX connections exceeded, dropping incoming message\n"));
805 return; 763 return;
806 } 764 }
807 765
@@ -818,12 +776,10 @@ select_read_cb (void *cls)
818 776
819 currhdr = (const struct GNUNET_MessageHeader *) &msgbuf[offset]; 777 currhdr = (const struct GNUNET_MessageHeader *) &msgbuf[offset];
820 /* ensure aligned access */ 778 /* ensure aligned access */
821 memcpy (&al_hdr, 779 memcpy (&al_hdr, currhdr, sizeof (al_hdr));
822 currhdr,
823 sizeof (al_hdr));
824 csize = ntohs (al_hdr.size); 780 csize = ntohs (al_hdr.size);
825 if ( (csize < sizeof (struct GNUNET_MessageHeader)) || 781 if ((csize < sizeof (struct GNUNET_MessageHeader)) ||
826 (csize > tsize - offset)) 782 (csize > tsize - offset))
827 { 783 {
828 GNUNET_break_op (0); 784 GNUNET_break_op (0);
829 break; 785 break;
@@ -835,9 +791,9 @@ select_read_cb (void *cls)
835 &receive_complete_cb, 791 &receive_complete_cb,
836 NULL); 792 NULL);
837 if (GNUNET_SYSERR == ret) 793 if (GNUNET_SYSERR == ret)
838 return; /* transport not up */ 794 return; /* transport not up */
839 if (GNUNET_NO == ret) 795 if (GNUNET_NO == ret)
840 break; 796 break;
841 delivering_messages++; 797 delivering_messages++;
842 offset += csize; 798 offset += csize;
843 } 799 }
@@ -869,9 +825,7 @@ select_read_cb (void *cls)
869 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the provided address is invalid 825 * @return #GNUNET_OK on success, #GNUNET_SYSERR if the provided address is invalid
870 */ 826 */
871static int 827static int
872mq_init (void *cls, 828mq_init (void *cls, const struct GNUNET_PeerIdentity *peer, const char *address)
873 const struct GNUNET_PeerIdentity *peer,
874 const char *address)
875{ 829{
876 struct Queue *queue; 830 struct Queue *queue;
877 const char *path; 831 const char *path;
@@ -879,31 +833,25 @@ mq_init (void *cls,
879 socklen_t un_len; 833 socklen_t un_len;
880 834
881 if (0 != strncmp (address, 835 if (0 != strncmp (address,
882 COMMUNICATOR_ADDRESS_PREFIX "-", 836 COMMUNICATOR_ADDRESS_PREFIX "-",
883 strlen (COMMUNICATOR_ADDRESS_PREFIX "-"))) 837 strlen (COMMUNICATOR_ADDRESS_PREFIX "-")))
884 { 838 {
885 GNUNET_break_op (0); 839 GNUNET_break_op (0);
886 return GNUNET_SYSERR; 840 return GNUNET_SYSERR;
887 } 841 }
888 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")]; 842 path = &address[strlen (COMMUNICATOR_ADDRESS_PREFIX "-")];
889 un = unix_address_to_sockaddr (path, 843 un = unix_address_to_sockaddr (path, &un_len);
890 &un_len); 844 queue = lookup_queue (peer, un, un_len);
891 queue = lookup_queue (peer,
892 un,
893 un_len);
894 if (NULL != queue) 845 if (NULL != queue)
895 { 846 {
896 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 847 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
897 "Address `%s' for %s ignored, queue exists\n", 848 "Address `%s' for %s ignored, queue exists\n",
898 path, 849 path,
899 GNUNET_i2s (peer)); 850 GNUNET_i2s (peer));
900 GNUNET_free (un); 851 GNUNET_free (un);
901 return GNUNET_OK; 852 return GNUNET_OK;
902 } 853 }
903 queue = setup_queue (peer, 854 queue = setup_queue (peer, GNUNET_TRANSPORT_CS_OUTBOUND, un, un_len);
904 GNUNET_TRANSPORT_CS_OUTBOUND,
905 un,
906 un_len);
907 GNUNET_free (un); 855 GNUNET_free (un);
908 if (NULL == queue) 856 if (NULL == queue)
909 { 857 {
@@ -927,8 +875,8 @@ mq_init (void *cls,
927 */ 875 */
928static int 876static int
929get_queue_delete_it (void *cls, 877get_queue_delete_it (void *cls,
930 const struct GNUNET_PeerIdentity *target, 878 const struct GNUNET_PeerIdentity *target,
931 void *value) 879 void *value)
932{ 880{
933 struct Queue *queue = value; 881 struct Queue *queue = value;
934 882
@@ -959,13 +907,10 @@ do_shutdown (void *cls)
959 } 907 }
960 if (NULL != unix_sock) 908 if (NULL != unix_sock)
961 { 909 {
962 GNUNET_break (GNUNET_OK == 910 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (unix_sock));
963 GNUNET_NETWORK_socket_close (unix_sock));
964 unix_sock = NULL; 911 unix_sock = NULL;
965 } 912 }
966 GNUNET_CONTAINER_multipeermap_iterate (queue_map, 913 GNUNET_CONTAINER_multipeermap_iterate (queue_map, &get_queue_delete_it, NULL);
967 &get_queue_delete_it,
968 NULL);
969 GNUNET_CONTAINER_multipeermap_destroy (queue_map); 914 GNUNET_CONTAINER_multipeermap_destroy (queue_map);
970 if (NULL != ai) 915 if (NULL != ai)
971 { 916 {
@@ -979,8 +924,7 @@ do_shutdown (void *cls)
979 } 924 }
980 if (NULL != stats) 925 if (NULL != stats)
981 { 926 {
982 GNUNET_STATISTICS_destroy (stats, 927 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
983 GNUNET_NO);
984 stats = NULL; 928 stats = NULL;
985 } 929 }
986} 930}
@@ -1031,9 +975,9 @@ run (void *cls,
1031 975
1032 if (GNUNET_OK != 976 if (GNUNET_OK !=
1033 GNUNET_CONFIGURATION_get_value_filename (cfg, 977 GNUNET_CONFIGURATION_get_value_filename (cfg,
1034 COMMUNICATOR_CONFIG_SECTION, 978 COMMUNICATOR_CONFIG_SECTION,
1035 "UNIXPATH", 979 "UNIXPATH",
1036 &unix_socket_path)) 980 &unix_socket_path))
1037 { 981 {
1038 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 982 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
1039 COMMUNICATOR_CONFIG_SECTION, 983 COMMUNICATOR_CONFIG_SECTION,
@@ -1042,53 +986,45 @@ run (void *cls,
1042 } 986 }
1043 if (GNUNET_OK != 987 if (GNUNET_OK !=
1044 GNUNET_CONFIGURATION_get_value_number (cfg, 988 GNUNET_CONFIGURATION_get_value_number (cfg,
1045 COMMUNICATOR_CONFIG_SECTION, 989 COMMUNICATOR_CONFIG_SECTION,
1046 "MAX_QUEUE_LENGTH", 990 "MAX_QUEUE_LENGTH",
1047 &max_queue_length)) 991 &max_queue_length))
1048 max_queue_length = DEFAULT_MAX_QUEUE_LENGTH; 992 max_queue_length = DEFAULT_MAX_QUEUE_LENGTH;
1049 993
1050 un = unix_address_to_sockaddr (unix_socket_path, 994 un = unix_address_to_sockaddr (unix_socket_path, &un_len);
1051 &un_len);
1052 if (NULL == un) 995 if (NULL == un)
1053 { 996 {
1054 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 997 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1055 "Failed to setup UNIX domain socket address with path `%s'\n", 998 "Failed to setup UNIX domain socket address with path `%s'\n",
1056 unix_socket_path); 999 unix_socket_path);
1057 GNUNET_free (unix_socket_path); 1000 GNUNET_free (unix_socket_path);
1058 return; 1001 return;
1059 } 1002 }
1060 unix_sock = GNUNET_NETWORK_socket_create (AF_UNIX, 1003 unix_sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0);
1061 SOCK_DGRAM,
1062 0);
1063 if (NULL == unix_sock) 1004 if (NULL == unix_sock)
1064 { 1005 {
1065 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, 1006 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
1066 "socket");
1067 GNUNET_free (un); 1007 GNUNET_free (un);
1068 GNUNET_free (unix_socket_path); 1008 GNUNET_free (unix_socket_path);
1069 return; 1009 return;
1070 } 1010 }
1071 if ( ('\0' != un->sun_path[0]) && 1011 if (('\0' != un->sun_path[0]) &&
1072 (GNUNET_OK != 1012 (GNUNET_OK != GNUNET_DISK_directory_create_for_file (un->sun_path)))
1073 GNUNET_DISK_directory_create_for_file (un->sun_path)) )
1074 { 1013 {
1075 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1014 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1076 _("Cannot create path to `%s'\n"), 1015 _ ("Cannot create path to `%s'\n"),
1077 un->sun_path); 1016 un->sun_path);
1078 GNUNET_NETWORK_socket_close (unix_sock); 1017 GNUNET_NETWORK_socket_close (unix_sock);
1079 unix_sock = NULL; 1018 unix_sock = NULL;
1080 GNUNET_free (un); 1019 GNUNET_free (un);
1081 GNUNET_free (unix_socket_path); 1020 GNUNET_free (unix_socket_path);
1082 return; 1021 return;
1083 } 1022 }
1084 if (GNUNET_OK != 1023 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (unix_sock,
1085 GNUNET_NETWORK_socket_bind (unix_sock, 1024 (const struct sockaddr *) un,
1086 (const struct sockaddr *) un, 1025 un_len))
1087 un_len))
1088 { 1026 {
1089 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, 1027 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "bind", un->sun_path);
1090 "bind",
1091 un->sun_path);
1092 GNUNET_NETWORK_socket_close (unix_sock); 1028 GNUNET_NETWORK_socket_close (unix_sock);
1093 unix_sock = NULL; 1029 unix_sock = NULL;
1094 GNUNET_free (un); 1030 GNUNET_free (un);
@@ -1096,25 +1032,20 @@ run (void *cls,
1096 return; 1032 return;
1097 } 1033 }
1098 GNUNET_free (un); 1034 GNUNET_free (un);
1099 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1035 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Bound to `%s'\n", unix_socket_path);
1100 "Bound to `%s'\n", 1036 stats = GNUNET_STATISTICS_create ("C-UNIX", cfg);
1101 unix_socket_path); 1037 GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
1102 stats = GNUNET_STATISTICS_create ("C-UNIX",
1103 cfg);
1104 GNUNET_SCHEDULER_add_shutdown (&do_shutdown,
1105 NULL);
1106 read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 1038 read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
1107 unix_sock, 1039 unix_sock,
1108 &select_read_cb, 1040 &select_read_cb,
1109 NULL); 1041 NULL);
1110 queue_map = GNUNET_CONTAINER_multipeermap_create (10, 1042 queue_map = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO);
1111 GNUNET_NO);
1112 ch = GNUNET_TRANSPORT_communicator_connect (cfg, 1043 ch = GNUNET_TRANSPORT_communicator_connect (cfg,
1113 COMMUNICATOR_CONFIG_SECTION, 1044 COMMUNICATOR_CONFIG_SECTION,
1114 COMMUNICATOR_ADDRESS_PREFIX, 1045 COMMUNICATOR_ADDRESS_PREFIX,
1115 GNUNET_TRANSPORT_CC_RELIABLE, 1046 GNUNET_TRANSPORT_CC_RELIABLE,
1116 &mq_init, 1047 &mq_init,
1117 NULL, 1048 NULL,
1118 &enc_notify_cb, 1049 &enc_notify_cb,
1119 NULL); 1050 NULL);
1120 if (NULL == ch) 1051 if (NULL == ch)
@@ -1125,14 +1056,14 @@ run (void *cls,
1125 return; 1056 return;
1126 } 1057 }
1127 GNUNET_asprintf (&my_addr, 1058 GNUNET_asprintf (&my_addr,
1128 "%s-%s", 1059 "%s-%s",
1129 COMMUNICATOR_ADDRESS_PREFIX, 1060 COMMUNICATOR_ADDRESS_PREFIX,
1130 unix_socket_path); 1061 unix_socket_path);
1131 GNUNET_free (unix_socket_path); 1062 GNUNET_free (unix_socket_path);
1132 ai = GNUNET_TRANSPORT_communicator_address_add (ch, 1063 ai = GNUNET_TRANSPORT_communicator_address_add (ch,
1133 my_addr, 1064 my_addr,
1134 GNUNET_NT_LOOPBACK, 1065 GNUNET_NT_LOOPBACK,
1135 GNUNET_TIME_UNIT_FOREVER_REL); 1066 GNUNET_TIME_UNIT_FOREVER_REL);
1136 GNUNET_free (my_addr); 1067 GNUNET_free (my_addr);
1137} 1068}
1138 1069
@@ -1145,28 +1076,26 @@ run (void *cls,
1145 * @return 0 ok, 1 on error 1076 * @return 0 ok, 1 on error
1146 */ 1077 */
1147int 1078int
1148main (int argc, 1079main (int argc, char *const *argv)
1149 char *const *argv)
1150{ 1080{
1151 static const struct GNUNET_GETOPT_CommandLineOption options[] = { 1081 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
1152 GNUNET_GETOPT_OPTION_END 1082 GNUNET_GETOPT_OPTION_END};
1153 };
1154 int ret; 1083 int ret;
1155 1084
1156 if (GNUNET_OK != 1085 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
1157 GNUNET_STRINGS_get_utf8_args (argc, argv,
1158 &argc, &argv))
1159 return 2; 1086 return 2;
1160 1087
1161 ret = 1088 ret = (GNUNET_OK ==
1162 (GNUNET_OK == 1089 GNUNET_PROGRAM_run (argc,
1163 GNUNET_PROGRAM_run (argc, argv, 1090 argv,
1164 "gnunet-communicator-unix", 1091 "gnunet-communicator-unix",
1165 _("GNUnet UNIX domain socket communicator"), 1092 _ ("GNUnet UNIX domain socket communicator"),
1166 options, 1093 options,
1167 &run, 1094 &run,
1168 NULL)) ? 0 : 1; 1095 NULL))
1169 GNUNET_free ((void*) argv); 1096 ? 0
1097 : 1;
1098 GNUNET_free ((void *) argv);
1170 return ret; 1099 return ret;
1171} 1100}
1172 1101
@@ -1177,8 +1106,7 @@ main (int argc,
1177/** 1106/**
1178 * MINIMIZE heap size (way below 128k) since this process doesn't need much. 1107 * MINIMIZE heap size (way below 128k) since this process doesn't need much.
1179 */ 1108 */
1180void __attribute__ ((constructor)) 1109void __attribute__ ((constructor)) GNUNET_ARM_memory_init ()
1181GNUNET_ARM_memory_init ()
1182{ 1110{
1183 mallopt (M_TRIM_THRESHOLD, 4 * 1024); 1111 mallopt (M_TRIM_THRESHOLD, 4 * 1024);
1184 mallopt (M_TOP_PAD, 1 * 1024); 1112 mallopt (M_TOP_PAD, 1 * 1024);