aboutsummaryrefslogtreecommitdiff
path: root/src/util/connection.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-02-21 20:21:40 +0000
committerChristian Grothoff <christian@grothoff.org>2015-02-21 20:21:40 +0000
commit9e308ff38737cc6b1d840eb72d016a7d1e109ea4 (patch)
tree07f4ed30972e879eca11c36dc4b2619bb153d35a /src/util/connection.c
parent0359101b306e170ecca31520ca12081e09d1804f (diff)
downloadgnunet-9e308ff38737cc6b1d840eb72d016a7d1e109ea4.tar.gz
gnunet-9e308ff38737cc6b1d840eb72d016a7d1e109ea4.zip
-signal connection failure to receive even if receive is triggered after failure is observed
Diffstat (limited to 'src/util/connection.c')
-rw-r--r--src/util/connection.c73
1 files changed, 53 insertions, 20 deletions
diff --git a/src/util/connection.c b/src/util/connection.c
index 8fe136b02..b600baa12 100644
--- a/src/util/connection.c
+++ b/src/util/connection.c
@@ -469,7 +469,8 @@ GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *connection,
469 * @param errcode error code to send 469 * @param errcode error code to send
470 */ 470 */
471static void 471static void
472signal_receive_error (struct GNUNET_CONNECTION_Handle *connection, int errcode) 472signal_receive_error (struct GNUNET_CONNECTION_Handle *connection,
473 int errcode)
473{ 474{
474 GNUNET_CONNECTION_Receiver receiver; 475 GNUNET_CONNECTION_Receiver receiver;
475 476
@@ -479,7 +480,12 @@ signal_receive_error (struct GNUNET_CONNECTION_Handle *connection, int errcode)
479 connection); 480 connection);
480 GNUNET_assert (NULL != (receiver = connection->receiver)); 481 GNUNET_assert (NULL != (receiver = connection->receiver));
481 connection->receiver = NULL; 482 connection->receiver = NULL;
482 receiver (connection->receiver_cls, NULL, 0, connection->addr, connection->addrlen, errcode); 483 receiver (connection->receiver_cls,
484 NULL,
485 0,
486 connection->addr,
487 connection->addrlen,
488 errcode);
483} 489}
484 490
485 491
@@ -519,8 +525,9 @@ signal_transmit_error (struct GNUNET_CONNECTION_Handle *connection,
519 connection); 525 connection);
520 if (NULL != connection->sock) 526 if (NULL != connection->sock)
521 { 527 {
522 GNUNET_NETWORK_socket_shutdown (connection->sock, SHUT_RDWR); 528 (void) GNUNET_NETWORK_socket_shutdown (connection->sock, SHUT_RDWR);
523 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (connection->sock)); 529 GNUNET_break (GNUNET_OK ==
530 GNUNET_NETWORK_socket_close (connection->sock));
524 connection->sock = NULL; 531 connection->sock = NULL;
525 GNUNET_assert (NULL == connection->write_task); 532 GNUNET_assert (NULL == connection->write_task);
526 } 533 }
@@ -561,13 +568,15 @@ connect_fail_continuation (struct GNUNET_CONNECTION_Handle *connection)
561 /* signal errors for jobs that used to wait on the connection */ 568 /* signal errors for jobs that used to wait on the connection */
562 connection->destroy_later = 1; 569 connection->destroy_later = 1;
563 if (NULL != connection->receiver) 570 if (NULL != connection->receiver)
564 signal_receive_error (connection, ECONNREFUSED); 571 signal_receive_error (connection,
572 ECONNREFUSED);
565 if (NULL != connection->nth.notify_ready) 573 if (NULL != connection->nth.notify_ready)
566 { 574 {
567 GNUNET_assert (connection->nth.timeout_task != NULL); 575 GNUNET_assert (NULL != connection->nth.timeout_task);
568 GNUNET_SCHEDULER_cancel (connection->nth.timeout_task); 576 GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
569 connection->nth.timeout_task = NULL; 577 connection->nth.timeout_task = NULL;
570 signal_transmit_error (connection, ECONNREFUSED); 578 signal_transmit_error (connection,
579 ECONNREFUSED);
571 } 580 }
572 if (-1 == connection->destroy_later) 581 if (-1 == connection->destroy_later)
573 { 582 {
@@ -979,7 +988,9 @@ GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection)
979 connection->destroy_later = -1; 988 connection->destroy_later = -1;
980 return; 989 return;
981 } 990 }
982 LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down connection (%p)\n", connection); 991 LOG (GNUNET_ERROR_TYPE_DEBUG,
992 "Shutting down connection (%p)\n",
993 connection);
983 GNUNET_assert (NULL == connection->nth.notify_ready); 994 GNUNET_assert (NULL == connection->nth.notify_ready);
984 GNUNET_assert (NULL == connection->receiver); 995 GNUNET_assert (NULL == connection->receiver);
985 if (NULL != connection->write_task) 996 if (NULL != connection->write_task)
@@ -1014,15 +1025,21 @@ GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection)
1014 if ( (NULL != connection->sock) && 1025 if ( (NULL != connection->sock) &&
1015 (GNUNET_YES != connection->persist) ) 1026 (GNUNET_YES != connection->persist) )
1016 { 1027 {
1017 if ((GNUNET_YES != GNUNET_NETWORK_socket_shutdown (connection->sock, SHUT_RDWR)) && 1028 if ((GNUNET_OK !=
1029 GNUNET_NETWORK_socket_shutdown (connection->sock,
1030 SHUT_RDWR)) &&
1018 (ENOTCONN != errno) && 1031 (ENOTCONN != errno) &&
1019 (ECONNRESET != errno) ) 1032 (ECONNRESET != errno) )
1020 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "shutdown"); 1033 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
1034 "shutdown");
1021 } 1035 }
1022 if (NULL != connection->sock) 1036 if (NULL != connection->sock)
1023 { 1037 {
1024 if (GNUNET_YES != connection->persist) 1038 if (GNUNET_YES != connection->persist)
1025 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (connection->sock)); 1039 {
1040 GNUNET_break (GNUNET_OK ==
1041 GNUNET_NETWORK_socket_close (connection->sock));
1042 }
1026 else 1043 else
1027 { 1044 {
1028 GNUNET_NETWORK_socket_free_memory_only_ (connection->sock); /* at least no memory leak (we deliberately 1045 GNUNET_NETWORK_socket_free_memory_only_ (connection->sock); /* at least no memory leak (we deliberately
@@ -1079,7 +1096,9 @@ receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1079 } 1096 }
1080 GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, connection->sock)); 1097 GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, connection->sock));
1081RETRY: 1098RETRY:
1082 ret = GNUNET_NETWORK_socket_recv (connection->sock, buffer, connection->max); 1099 ret = GNUNET_NETWORK_socket_recv (connection->sock,
1100 buffer,
1101 connection->max);
1083 if (-1 == ret) 1102 if (-1 == ret)
1084 { 1103 {
1085 if (EINTR == errno) 1104 if (EINTR == errno)
@@ -1088,11 +1107,20 @@ RETRY:
1088 return; 1107 return;
1089 } 1108 }
1090 LOG (GNUNET_ERROR_TYPE_DEBUG, 1109 LOG (GNUNET_ERROR_TYPE_DEBUG,
1091 "receive_ready read %u/%u bytes from `%s' (%p)!\n", (unsigned int) ret, 1110 "receive_ready read %u/%u bytes from `%s' (%p)!\n",
1092 connection->max, GNUNET_a2s (connection->addr, connection->addrlen), connection); 1111 (unsigned int) ret,
1112 connection->max,
1113 GNUNET_a2s (connection->addr,
1114 connection->addrlen),
1115 connection);
1093 GNUNET_assert (NULL != (receiver = connection->receiver)); 1116 GNUNET_assert (NULL != (receiver = connection->receiver));
1094 connection->receiver = NULL; 1117 connection->receiver = NULL;
1095 receiver (connection->receiver_cls, buffer, ret, connection->addr, connection->addrlen, 0); 1118 receiver (connection->receiver_cls,
1119 buffer,
1120 ret,
1121 connection->addr,
1122 connection->addrlen,
1123 0);
1096} 1124}
1097 1125
1098 1126
@@ -1398,7 +1426,7 @@ SCHEDULE_WRITE:
1398 * @param timeout after how long should we give up (and call 1426 * @param timeout after how long should we give up (and call
1399 * notify with buf NULL and size 0)? 1427 * notify with buf NULL and size 0)?
1400 * @param notify function to call 1428 * @param notify function to call
1401 * @param notify_cls closure for notify 1429 * @param notify_cls closure for @a notify
1402 * @return non-NULL if the notify callback was queued, 1430 * @return non-NULL if the notify callback was queued,
1403 * NULL if we are already going to notify someone else (busy) 1431 * NULL if we are already going to notify someone else (busy)
1404 */ 1432 */
@@ -1431,7 +1459,8 @@ GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connec
1431 { 1459 {
1432 if (NULL != connection->write_task) 1460 if (NULL != connection->write_task)
1433 GNUNET_SCHEDULER_cancel (connection->write_task); 1461 GNUNET_SCHEDULER_cancel (connection->write_task);
1434 connection->write_task = GNUNET_SCHEDULER_add_now (&connect_error, connection); 1462 connection->write_task = GNUNET_SCHEDULER_add_now (&connect_error,
1463 connection);
1435 return &connection->nth; 1464 return &connection->nth;
1436 } 1465 }
1437 if (NULL != connection->write_task) 1466 if (NULL != connection->write_task)
@@ -1439,7 +1468,9 @@ GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connec
1439 if (NULL != connection->sock) 1468 if (NULL != connection->sock)
1440 { 1469 {
1441 /* connected, try to transmit now */ 1470 /* connected, try to transmit now */
1442 LOG (GNUNET_ERROR_TYPE_DEBUG, "Scheduling transmission (%p).\n", connection); 1471 LOG (GNUNET_ERROR_TYPE_DEBUG,
1472 "Scheduling transmission (%p).\n",
1473 connection);
1443 connection->write_task = 1474 connection->write_task =
1444 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining 1475 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining
1445 (connection->nth.transmit_timeout), 1476 (connection->nth.transmit_timeout),
@@ -1448,9 +1479,11 @@ GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connec
1448 } 1479 }
1449 /* not yet connected, wait for connection */ 1480 /* not yet connected, wait for connection */
1450 LOG (GNUNET_ERROR_TYPE_DEBUG, 1481 LOG (GNUNET_ERROR_TYPE_DEBUG,
1451 "Need to wait to schedule transmission for connection, adding timeout task (%p).\n", connection); 1482 "Need to wait to schedule transmission for connection, adding timeout task (%p).\n",
1483 connection);
1452 connection->nth.timeout_task = 1484 connection->nth.timeout_task =
1453 GNUNET_SCHEDULER_add_delayed (timeout, &transmit_timeout, connection); 1485 GNUNET_SCHEDULER_add_delayed (timeout,
1486 &transmit_timeout, connection);
1454 return &connection->nth; 1487 return &connection->nth;
1455} 1488}
1456 1489