diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-02-21 20:21:40 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-02-21 20:21:40 +0000 |
commit | 9e308ff38737cc6b1d840eb72d016a7d1e109ea4 (patch) | |
tree | 07f4ed30972e879eca11c36dc4b2619bb153d35a /src/util/connection.c | |
parent | 0359101b306e170ecca31520ca12081e09d1804f (diff) | |
download | gnunet-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.c | 73 |
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 | */ |
471 | static void | 471 | static void |
472 | signal_receive_error (struct GNUNET_CONNECTION_Handle *connection, int errcode) | 472 | signal_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)); |
1081 | RETRY: | 1098 | RETRY: |
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 | ||