/** * This function is called once we either timeout * or have data ready to read. * * @param cls connection to read from * @param tc scheduler context */ static void receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_CONNECTION_Handle *connection = cls; char buffer[connection->max]; ssize_t ret; GNUNET_CONNECTION_Receiver receiver; connection->read_task = GNUNET_SCHEDULER_NO_TASK; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) { /* ignore shutdown request, go again immediately */ connection->read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining (connection->receive_timeout), connection->sock, &receive_ready, connection); return; } if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Receive from `%s' encounters error: timeout (%p)\n", GNUNET_a2s (connection->addr, connection->addrlen), GNUNET_TIME_absolute_get_duration (connection->receive_timeout).rel_value, connection); signal_receive_timeout (connection); return; } if (NULL == connection->sock) { /* connect failed for good */ signal_receive_error (connection, ECONNREFUSED); return; } GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, connection->sock)); RETRY: ret = GNUNET_NETWORK_socket_recv (connection->sock, buffer, connection->max); if (-1 == ret) { if (EINTR == errno) goto RETRY; signal_receive_error (connection, errno); return; } LOG (GNUNET_ERROR_TYPE_DEBUG, "receive_ready read %u/%u bytes from `%s' (%p)!\n", (unsigned int) ret, connection->max, GNUNET_a2s (connection->addr, connection->addrlen), connection); GNUNET_assert (NULL != (receiver = connection->receiver)); connection->receiver = NULL; receiver (connection->receiver_cls, buffer, ret, connection->addr, connection->addrlen, 0); }
/** * We've failed for good to establish a connection (timeout or * no more addresses to try). * * @param connection the connection we tried to establish */ static void connect_fail_continuation (struct GNUNET_CONNECTION_Handle *connection) { LOG (GNUNET_ERROR_TYPE_INFO, _("Failed to establish TCP connection to `%s:%u', no further addresses to try.\n"), connection->hostname, connection->port); GNUNET_break (NULL == connection->ap_head); GNUNET_break (NULL == connection->ap_tail); GNUNET_break (GNUNET_NO == connection->dns_active); GNUNET_break (NULL == connection->sock); GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->write_task); /* signal errors for jobs that used to wait on the connection */ connection->destroy_later = 1; if (NULL != connection->receiver) signal_receive_error (connection, ECONNREFUSED); if (NULL != connection->nth.notify_ready) { GNUNET_assert (connection->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK); GNUNET_SCHEDULER_cancel (connection->nth.timeout_task); connection->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; signal_transmit_error (connection, ECONNREFUSED); } if (-1 == connection->destroy_later) { /* do it now */ connection->destroy_later = 0; GNUNET_CONNECTION_destroy (connection); return; } connection->destroy_later = 0; }