From d23a815951413af100c74b38cdd09a01ca1c280a Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 16 Mar 2017 05:33:01 +0100 Subject: removing dead/legacy server/connection logic, except for in tcp/wlan/bt plugins (which will be updated 'later') --- src/util/connection.c | 1648 ------------------------------------------------- 1 file changed, 1648 deletions(-) delete mode 100644 src/util/connection.c (limited to 'src/util/connection.c') diff --git a/src/util/connection.c b/src/util/connection.c deleted file mode 100644 index e822b264f..000000000 --- a/src/util/connection.c +++ /dev/null @@ -1,1648 +0,0 @@ -/* - This file is part of GNUnet. - Copyright (C) 2009-2013 GNUnet e.V. - - GNUnet is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3, or (at your - option) any later version. - - GNUnet is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNUnet; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -/** - * @file util/connection.c - * @brief TCP connection management - * @author Christian Grothoff - * - * This code is rather complex. Only modify it if you - * 1) Have a NEW testcase showing that the new code - * is needed and correct - * 2) All EXISTING testcases pass with the new code - * These rules should apply in general, but for this - * module they are VERY, VERY important. - */ -#include "platform.h" -#include "gnunet_util_lib.h" -#include "gnunet_resolver_service.h" - - -#define LOG(kind,...) GNUNET_log_from (kind, "util-connection", __VA_ARGS__) - -#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-connection", syscall) - - -/** - * Transmission handle. There can only be one for each connection. - */ -struct GNUNET_CONNECTION_TransmitHandle -{ - - /** - * Function to call if the send buffer has notify_size - * bytes available. - */ - GNUNET_CONNECTION_TransmitReadyNotify notify_ready; - - /** - * Closure for notify_ready. - */ - void *notify_ready_cls; - - /** - * Our connection handle. - */ - struct GNUNET_CONNECTION_Handle *connection; - - /** - * Timeout for receiving (in absolute time). - */ - struct GNUNET_TIME_Absolute transmit_timeout; - - /** - * Task called on timeout. - */ - struct GNUNET_SCHEDULER_Task * timeout_task; - - /** - * At what number of bytes available in the - * write buffer should the notify method be called? - */ - size_t notify_size; - -}; - - -/** - * During connect, we try multiple possible IP addresses - * to find out which one might work. - */ -struct AddressProbe -{ - - /** - * This is a linked list. - */ - struct AddressProbe *next; - - /** - * This is a doubly-linked list. - */ - struct AddressProbe *prev; - - /** - * The address; do not free (allocated at the end of this struct). - */ - const struct sockaddr *addr; - - /** - * Underlying OS's socket. - */ - struct GNUNET_NETWORK_Handle *sock; - - /** - * Connection for which we are probing. - */ - struct GNUNET_CONNECTION_Handle *connection; - - /** - * Lenth of addr. - */ - socklen_t addrlen; - - /** - * Task waiting for the connection to finish connecting. - */ - struct GNUNET_SCHEDULER_Task * task; -}; - - -/** - * @brief handle for a network connection - */ -struct GNUNET_CONNECTION_Handle -{ - - /** - * Configuration to use. - */ - const struct GNUNET_CONFIGURATION_Handle *cfg; - - /** - * Linked list of sockets we are currently trying out - * (during connect). - */ - struct AddressProbe *ap_head; - - /** - * Linked list of sockets we are currently trying out - * (during connect). - */ - struct AddressProbe *ap_tail; - - /** - * Network address of the other end-point, may be NULL. - */ - struct sockaddr *addr; - - /** - * Pointer to the hostname if connection was - * created using DNS lookup, otherwise NULL. - */ - char *hostname; - - /** - * Underlying OS's socket, set to NULL after fatal errors. - */ - struct GNUNET_NETWORK_Handle *sock; - - /** - * Function to call on data received, NULL if no receive is pending. - */ - GNUNET_CONNECTION_Receiver receiver; - - /** - * Closure for @e receiver. - */ - void *receiver_cls; - - /** - * Pointer to our write buffer. - */ - char *write_buffer; - - /** - * Current size of our @e write_buffer. - */ - size_t write_buffer_size; - - /** - * Current write-offset in @e write_buffer (where - * would we write next). - */ - size_t write_buffer_off; - - /** - * Current read-offset in @e write_buffer (how many - * bytes have already been sent). - */ - size_t write_buffer_pos; - - /** - * Length of @e addr. - */ - socklen_t addrlen; - - /** - * Read task that we may need to wait for. - */ - struct GNUNET_SCHEDULER_Task *read_task; - - /** - * Write task that we may need to wait for. - */ - struct GNUNET_SCHEDULER_Task *write_task; - - /** - * Handle to a pending DNS lookup request. - */ - struct GNUNET_RESOLVER_RequestHandle *dns_active; - - /** - * The handle we return for #GNUNET_CONNECTION_notify_transmit_ready(). - */ - struct GNUNET_CONNECTION_TransmitHandle nth; - - /** - * Timeout for receiving (in absolute time). - */ - struct GNUNET_TIME_Absolute receive_timeout; - - /** - * Maximum number of bytes to read (for receiving). - */ - size_t max; - - /** - * Port to connect to. - */ - uint16_t port; - - /** - * When shutdown, do not ever actually close the socket, but - * free resources. Only should ever be set if using program - * termination as a signal (because only then will the leaked - * socket be freed!) - */ - int8_t persist; - - /** - * Usually 0. Set to 1 if this handle is in use, and should - * #GNUNET_CONNECTION_destroy() be called right now, the action needs - * to be deferred by setting it to -1. - */ - int8_t destroy_later; - - /** - * Handle to subsequent connection after proxy handshake completes, - */ - struct GNUNET_CONNECTION_Handle *proxy_handshake; - -}; - - -/** - * Set the persist option on this connection handle. Indicates - * that the underlying socket or fd should never really be closed. - * Used for indicating process death. - * - * @param connection the connection to set persistent - */ -void -GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *connection) -{ - connection->persist = GNUNET_YES; -} - - -/** - * Disable the "CORK" feature for communication with the given connection, - * forcing the OS to immediately flush the buffer on transmission - * instead of potentially buffering multiple messages. Essentially - * reduces the OS send buffers to zero. - * Used to make sure that the last messages sent through the connection - * reach the other side before the process is terminated. - * - * @param connection the connection to make flushing and blocking - * @return #GNUNET_OK on success - */ -int -GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection) -{ - return GNUNET_NETWORK_socket_disable_corking (connection->sock); -} - - -/** - * Create a connection handle by boxing an existing OS socket. The OS - * socket should henceforth be no longer used directly. - * #GNUNET_connection_destroy() will close it. - * - * @param osSocket existing socket to box - * @return the boxed connection handle - */ -struct GNUNET_CONNECTION_Handle * -GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket) -{ - struct GNUNET_CONNECTION_Handle *connection; - - connection = GNUNET_new (struct GNUNET_CONNECTION_Handle); - connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; - connection->write_buffer = GNUNET_malloc (connection->write_buffer_size); - connection->sock = osSocket; - return connection; -} - - -/** - * Create a connection handle by accepting on a listen socket. This - * function may block if the listen socket has no connection ready. - * - * @param access_cb function to use to check if access is allowed - * @param access_cb_cls closure for @a access_cb - * @param lsock listen socket - * @return the connection handle, NULL on error - */ -struct GNUNET_CONNECTION_Handle * -GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access_cb, - void *access_cb_cls, - struct GNUNET_NETWORK_Handle *lsock) -{ - struct GNUNET_CONNECTION_Handle *connection; - char addr[128]; - socklen_t addrlen; - struct GNUNET_NETWORK_Handle *sock; - int aret; - struct sockaddr_in *v4; - struct sockaddr_in6 *v6; - struct sockaddr *sa; - void *uaddr; -#ifdef SO_PEERCRED - struct ucred uc; - socklen_t olen; -#endif - struct GNUNET_CONNECTION_Credentials *gcp; -#if HAVE_GETPEEREID || defined(SO_PEERCRED) || HAVE_GETPEERUCRED - struct GNUNET_CONNECTION_Credentials gc; - - gc.uid = 0; - gc.gid = 0; -#endif - - addrlen = sizeof (addr); - sock = - GNUNET_NETWORK_socket_accept (lsock, - (struct sockaddr *) &addr, - &addrlen); - if (NULL == sock) - { - if (EAGAIN != errno) - LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "accept"); - return NULL; - } - if ((addrlen > sizeof (addr)) || (addrlen < sizeof (sa_family_t))) - { - GNUNET_break (0); - GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); - return NULL; - } - - sa = (struct sockaddr *) addr; - v6 = (struct sockaddr_in6 *) addr; - if ( (AF_INET6 == sa->sa_family) && - (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr)) ) - { - /* convert to V4 address */ - v4 = GNUNET_new (struct sockaddr_in); - memset (v4, 0, sizeof (struct sockaddr_in)); - v4->sin_family = AF_INET; -#if HAVE_SOCKADDR_IN_SIN_LEN - v4->sin_len = (u_char) sizeof (struct sockaddr_in); -#endif - GNUNET_memcpy (&v4->sin_addr, - &((char *) &v6->sin6_addr)[sizeof (struct in6_addr) - - sizeof (struct in_addr)], - sizeof (struct in_addr)); - v4->sin_port = v6->sin6_port; - uaddr = v4; - addrlen = sizeof (struct sockaddr_in); - } - else - { - uaddr = GNUNET_malloc (addrlen); - GNUNET_memcpy (uaddr, addr, addrlen); - } - gcp = NULL; - if (AF_UNIX == sa->sa_family) - { -#if HAVE_GETPEEREID - /* most BSDs */ - if (0 == getpeereid (GNUNET_NETWORK_get_fd (sock), - &gc.uid, - &gc.gid)) - gcp = &gc; -#else -#ifdef SO_PEERCRED - /* largely traditional GNU/Linux */ - olen = sizeof (uc); - if ( (0 == - getsockopt (GNUNET_NETWORK_get_fd (sock), - SOL_SOCKET, - SO_PEERCRED, - &uc, - &olen)) && - (olen == sizeof (uc)) ) - { - gc.uid = uc.uid; - gc.gid = uc.gid; - gcp = &gc; - } -#else -#if HAVE_GETPEERUCRED - /* this is for Solaris 10 */ - ucred_t *uc; - - uc = NULL; - if (0 == getpeerucred (GNUNET_NETWORK_get_fd (sock), &uc)) - { - gc.uid = ucred_geteuid (uc); - gc.gid = ucred_getegid (uc); - gcp = &gc; - } - ucred_free (uc); -#endif -#endif -#endif - } - - if ( (NULL != access_cb) && - (GNUNET_YES != (aret = access_cb (access_cb_cls, - gcp, - uaddr, - addrlen))) ) - { - if (GNUNET_NO == aret) - LOG (GNUNET_ERROR_TYPE_INFO, - _("Access denied to `%s'\n"), - GNUNET_a2s (uaddr, - addrlen)); - GNUNET_break (GNUNET_OK == - GNUNET_NETWORK_socket_shutdown (sock, - SHUT_RDWR)); - GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); - GNUNET_free (uaddr); - return NULL; - } - connection = GNUNET_new (struct GNUNET_CONNECTION_Handle); - connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; - connection->write_buffer = GNUNET_malloc (connection->write_buffer_size); - connection->addr = uaddr; - connection->addrlen = addrlen; - connection->sock = sock; - LOG (GNUNET_ERROR_TYPE_INFO, - _("Accepting connection from `%s': %p\n"), - GNUNET_a2s (uaddr, - addrlen), - connection); - return connection; -} - - -/** - * Obtain the network address of the other party. - * - * @param connection the client to get the address for - * @param addr where to store the address - * @param addrlen where to store the length of the @a addr - * @return #GNUNET_OK on success - */ -int -GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *connection, - void **addr, - size_t *addrlen) -{ - if ((NULL == connection->addr) || (0 == connection->addrlen)) - return GNUNET_NO; - *addr = GNUNET_malloc (connection->addrlen); - GNUNET_memcpy (*addr, connection->addr, connection->addrlen); - *addrlen = connection->addrlen; - return GNUNET_OK; -} - - -/** - * Tell the receiver callback that we had an IO error. - * - * @param connection connection to signal error - * @param errcode error code to send - */ -static void -signal_receive_error (struct GNUNET_CONNECTION_Handle *connection, - int errcode) -{ - GNUNET_CONNECTION_Receiver receiver; - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Receive encounters error (%s), connection closed (%p)\n", - STRERROR (errcode), - connection); - GNUNET_assert (NULL != (receiver = connection->receiver)); - connection->receiver = NULL; - receiver (connection->receiver_cls, - NULL, - 0, - connection->addr, - connection->addrlen, - errcode); -} - - -/** - * Tell the receiver callback that a timeout was reached. - * - * @param connection connection to signal for - */ -static void -signal_receive_timeout (struct GNUNET_CONNECTION_Handle *connection) -{ - GNUNET_CONNECTION_Receiver receiver; - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Connection signals timeout to receiver (%p)!\n", - connection); - GNUNET_assert (NULL != (receiver = connection->receiver)); - connection->receiver = NULL; - receiver (connection->receiver_cls, NULL, 0, NULL, 0, 0); -} - - -/** - * We failed to transmit data to the service, signal the error. - * - * @param connection handle that had trouble - * @param ecode error code (errno) - */ -static void -signal_transmit_error (struct GNUNET_CONNECTION_Handle *connection, - int ecode) -{ - GNUNET_CONNECTION_TransmitReadyNotify notify; - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Transmission encounterd error (%s), connection closed (%p)\n", - STRERROR (ecode), - connection); - if (NULL != connection->sock) - { - (void) GNUNET_NETWORK_socket_shutdown (connection->sock, - SHUT_RDWR); - GNUNET_break (GNUNET_OK == - GNUNET_NETWORK_socket_close (connection->sock)); - connection->sock = NULL; - GNUNET_assert (NULL == connection->write_task); - } - if (NULL != connection->read_task) - { - /* send errors trigger read errors... */ - GNUNET_SCHEDULER_cancel (connection->read_task); - connection->read_task = NULL; - signal_receive_timeout (connection); - return; - } - if (NULL == connection->nth.notify_ready) - return; /* nobody to tell about it */ - notify = connection->nth.notify_ready; - connection->nth.notify_ready = NULL; - notify (connection->nth.notify_ready_cls, - 0, - NULL); -} - - -/** - * 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 (NULL == connection->write_task); - GNUNET_assert (NULL == connection->proxy_handshake); - - /* 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 (NULL != connection->nth.timeout_task); - GNUNET_SCHEDULER_cancel (connection->nth.timeout_task); - connection->nth.timeout_task = NULL; - 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; -} - - -/** - * We are ready to transmit (or got a timeout). - * - * @param cls our connection handle - */ -static void -transmit_ready (void *cls); - - -/** - * This function is called once we either timeout or have data ready - * to read. - * - * @param cls connection to read from - */ -static void -receive_ready (void *cls); - - -/** - * We've succeeded in establishing a connection. - * - * @param connection the connection we tried to establish - */ -static void -connect_success_continuation (struct GNUNET_CONNECTION_Handle *connection) -{ - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Connection to `%s' succeeded! (%p)\n", - GNUNET_a2s (connection->addr, - connection->addrlen), - connection); - /* trigger jobs that waited for the connection */ - if (NULL != connection->receiver) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Connection succeeded, starting with receiving data (%p)\n", - connection); - GNUNET_assert (NULL == connection->read_task); - connection->read_task = - GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining - (connection->receive_timeout), - connection->sock, - &receive_ready, connection); - } - if (NULL != connection->nth.notify_ready) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Connection succeeded, starting with sending data (%p)\n", - connection); - GNUNET_assert (connection->nth.timeout_task != NULL); - GNUNET_SCHEDULER_cancel (connection->nth.timeout_task); - connection->nth.timeout_task = NULL; - GNUNET_assert (connection->write_task == NULL); - connection->write_task = - GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining - (connection->nth.transmit_timeout), connection->sock, - &transmit_ready, connection); - } -} - - -/** - * Scheduler let us know that we're either ready to write on the - * socket OR connect timed out. Do the right thing. - * - * @param cls the `struct AddressProbe *` with the address that we are probing - */ -static void -connect_probe_continuation (void *cls) -{ - struct AddressProbe *ap = cls; - struct GNUNET_CONNECTION_Handle *connection = ap->connection; - const struct GNUNET_SCHEDULER_TaskContext *tc; - struct AddressProbe *pos; - int error; - socklen_t len; - - GNUNET_assert (NULL != ap->sock); - GNUNET_CONTAINER_DLL_remove (connection->ap_head, - connection->ap_tail, - ap); - len = sizeof (error); - errno = 0; - error = 0; - tc = GNUNET_SCHEDULER_get_task_context (); - if ( (0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) || - (GNUNET_OK != - GNUNET_NETWORK_socket_getsockopt (ap->sock, - SOL_SOCKET, - SO_ERROR, - &error, - &len)) || - (0 != error) ) - { - GNUNET_break (GNUNET_OK == - GNUNET_NETWORK_socket_close (ap->sock)); - GNUNET_free (ap); - if ( (NULL == connection->ap_head) && - (GNUNET_NO == connection->dns_active) && - (NULL == connection->proxy_handshake) ) - connect_fail_continuation (connection); - return; - } - GNUNET_assert (NULL == connection->sock); - connection->sock = ap->sock; - GNUNET_assert (NULL == connection->addr); - connection->addr = GNUNET_malloc (ap->addrlen); - GNUNET_memcpy (connection->addr, ap->addr, ap->addrlen); - connection->addrlen = ap->addrlen; - GNUNET_free (ap); - /* cancel all other attempts */ - while (NULL != (pos = connection->ap_head)) - { - GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock)); - GNUNET_SCHEDULER_cancel (pos->task); - GNUNET_CONTAINER_DLL_remove (connection->ap_head, - connection->ap_tail, - pos); - GNUNET_free (pos); - } - connect_success_continuation (connection); -} - - -/** - * Try to establish a connection given the specified address. - * This function is called by the resolver once we have a DNS reply. - * - * @param cls our `struct GNUNET_CONNECTION_Handle *` - * @param addr address to try, NULL for "last call" - * @param addrlen length of @a addr - */ -static void -try_connect_using_address (void *cls, - const struct sockaddr *addr, - socklen_t addrlen) -{ - struct GNUNET_CONNECTION_Handle *connection = cls; - struct AddressProbe *ap; - struct GNUNET_TIME_Relative delay; - - if (NULL == addr) - { - connection->dns_active = NULL; - if ((NULL == connection->ap_head) && - (NULL == connection->sock) && - (NULL == connection->proxy_handshake)) - connect_fail_continuation (connection); - return; - } - if (NULL != connection->sock) - return; /* already connected */ - GNUNET_assert (NULL == connection->addr); - /* try to connect */ - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Trying to connect using address `%s:%u/%s:%u'\n", - connection->hostname, - connection->port, - GNUNET_a2s (addr, addrlen), - connection->port); - ap = GNUNET_malloc (sizeof (struct AddressProbe) + addrlen); - ap->addr = (const struct sockaddr *) &ap[1]; - GNUNET_memcpy (&ap[1], addr, addrlen); - ap->addrlen = addrlen; - ap->connection = connection; - - switch (ap->addr->sa_family) - { - case AF_INET: - ((struct sockaddr_in *) ap->addr)->sin_port = htons (connection->port); - break; - case AF_INET6: - ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (connection->port); - break; - default: - GNUNET_break (0); - GNUNET_free (ap); - return; /* not supported by us */ - } - ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family, - SOCK_STREAM, 0); - if (NULL == ap->sock) - { - GNUNET_free (ap); - return; /* not supported by OS */ - } - LOG (GNUNET_ERROR_TYPE_INFO, - "Trying to connect to `%s' (%p)\n", - GNUNET_a2s (ap->addr, ap->addrlen), - connection); - if ((GNUNET_OK != - GNUNET_NETWORK_socket_connect (ap->sock, - ap->addr, - ap->addrlen)) && - (EINPROGRESS != errno)) - { - /* maybe refused / unsupported address, try next */ - LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect"); - GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock)); - GNUNET_free (ap); - return; - } - GNUNET_CONTAINER_DLL_insert (connection->ap_head, connection->ap_tail, ap); - delay = GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT; - if (NULL != connection->nth.notify_ready) - delay = GNUNET_TIME_relative_min (delay, - GNUNET_TIME_absolute_get_remaining (connection->nth.transmit_timeout)); - if (NULL != connection->receiver) - delay = GNUNET_TIME_relative_min (delay, - GNUNET_TIME_absolute_get_remaining (connection->receive_timeout)); - ap->task = GNUNET_SCHEDULER_add_write_net (delay, - ap->sock, - &connect_probe_continuation, - ap); -} - - -/** - * Create a connection handle by (asynchronously) connecting to a host. - * This function returns immediately, even if the connection has not - * yet been established. This function only creates TCP connections. - * - * @param cfg configuration to use - * @param hostname name of the host to connect to - * @param port port to connect to - * @return the connection handle - */ -struct GNUNET_CONNECTION_Handle * -GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *hostname, - uint16_t port) -{ - struct GNUNET_CONNECTION_Handle *connection; - - GNUNET_assert (0 < strlen (hostname)); /* sanity check */ - connection = GNUNET_new (struct GNUNET_CONNECTION_Handle); - connection->cfg = cfg; - connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; - connection->write_buffer = GNUNET_malloc (connection->write_buffer_size); - connection->port = port; - connection->hostname = GNUNET_strdup (hostname); - connection->dns_active = - GNUNET_RESOLVER_ip_get (connection->hostname, - AF_UNSPEC, - GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT, - &try_connect_using_address, - connection); - return connection; -} - - -/** - * Create a connection handle by connecting to a UNIX domain service. - * This function returns immediately, even if the connection has not - * yet been established. This function only creates UNIX connections. - * - * @param cfg configuration to use - * @param unixpath path to connect to - * @return the connection handle, NULL on systems without UNIX support - */ -struct GNUNET_CONNECTION_Handle * -GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct GNUNET_CONFIGURATION_Handle *cfg, - const char *unixpath) -{ -#ifdef AF_UNIX - struct GNUNET_CONNECTION_Handle *connection; - struct sockaddr_un *un; - - GNUNET_assert (0 < strlen (unixpath)); /* sanity check */ - un = GNUNET_new (struct sockaddr_un); - un->sun_family = AF_UNIX; - strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1); -#ifdef LINUX - { - int abstract; - - abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg, - "TESTING", - "USE_ABSTRACT_SOCKETS"); - if (GNUNET_YES == abstract) - un->sun_path[0] = '\0'; - } -#endif -#if HAVE_SOCKADDR_UN_SUN_LEN - un->sun_len = (u_char) sizeof (struct sockaddr_un); -#endif - connection = GNUNET_new (struct GNUNET_CONNECTION_Handle); - connection->cfg = cfg; - connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE; - connection->write_buffer = GNUNET_malloc (connection->write_buffer_size); - connection->port = 0; - connection->hostname = NULL; - connection->addr = (struct sockaddr *) un; - connection->addrlen = sizeof (struct sockaddr_un); - connection->sock = GNUNET_NETWORK_socket_create (AF_UNIX, - SOCK_STREAM, - 0); - if (NULL == connection->sock) - { - GNUNET_free (connection->addr); - GNUNET_free (connection->write_buffer); - GNUNET_free (connection); - return NULL; - } - if ( (GNUNET_OK != - GNUNET_NETWORK_socket_connect (connection->sock, - connection->addr, - connection->addrlen)) && - (EINPROGRESS != errno) ) - { - /* Just return; we expect everything to work eventually so don't fail HARD */ - GNUNET_break (GNUNET_OK == - GNUNET_NETWORK_socket_close (connection->sock)); - connection->sock = NULL; - return connection; - } - connect_success_continuation (connection); - return connection; -#else - return NULL; -#endif -} - - -/** - * Create a connection handle by (asynchronously) connecting to a host. - * This function returns immediately, even if the connection has not - * yet been established. This function only creates TCP connections. - * - * @param s socket to connect - * @param serv_addr server address - * @param addrlen length of @a serv_addr - * @return the connection handle - */ -struct GNUNET_CONNECTION_Handle * -GNUNET_CONNECTION_connect_socket (struct GNUNET_NETWORK_Handle *s, - const struct sockaddr *serv_addr, - socklen_t addrlen) -{ - struct GNUNET_CONNECTION_Handle *connection; - - if ( (GNUNET_OK != - GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) && - (EINPROGRESS != errno) ) - { - /* maybe refused / unsupported address, try next */ - LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, - "connect"); - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Attempt to connect to `%s' failed\n", - GNUNET_a2s (serv_addr, - addrlen)); - GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s)); - return NULL; - } - connection = GNUNET_CONNECTION_create_from_existing (s); - connection->addr = GNUNET_malloc (addrlen); - GNUNET_memcpy (connection->addr, serv_addr, addrlen); - connection->addrlen = addrlen; - LOG (GNUNET_ERROR_TYPE_INFO, - "Trying to connect to `%s' (%p)\n", - GNUNET_a2s (serv_addr, addrlen), - connection); - return connection; -} - - -/** - * Create a connection handle by creating a socket and - * (asynchronously) connecting to a host. This function returns - * immediately, even if the connection has not yet been established. - * This function only creates TCP connections. - * - * @param af_family address family to use - * @param serv_addr server address - * @param addrlen length of @a serv_addr - * @return the connection handle - */ -struct GNUNET_CONNECTION_Handle * -GNUNET_CONNECTION_create_from_sockaddr (int af_family, - const struct sockaddr *serv_addr, - socklen_t addrlen) -{ - struct GNUNET_NETWORK_Handle *s; - - s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0); - if (NULL == s) - { - LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, - "socket"); - return NULL; - } - return GNUNET_CONNECTION_connect_socket (s, - serv_addr, - addrlen); -} - - -/** - * Check if connection is valid (no fatal errors have happened so far). - * Note that a connection that is still trying to connect is considered - * valid. - * - * @param connection connection to check - * @return #GNUNET_YES if valid, #GNUNET_NO otherwise - */ -int -GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *connection) -{ - if ((NULL != connection->ap_head) || - (NULL != connection->dns_active) || - (NULL != connection->proxy_handshake)) - return GNUNET_YES; /* still trying to connect */ - if ( (0 != connection->destroy_later) || - (NULL == connection->sock) ) - return GNUNET_NO; - return GNUNET_YES; -} - - -/** - * Close the connection and free associated resources. There must - * not be any pending requests for reading or writing to the - * connection at this time. - * - * @param connection connection to destroy - */ -void -GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection) -{ - struct AddressProbe *pos; - - if (0 != connection->destroy_later) - { - connection->destroy_later = -1; - return; - } - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Shutting down connection (%p)\n", - connection); - GNUNET_assert (NULL == connection->nth.notify_ready); - GNUNET_assert (NULL == connection->receiver); - if (NULL != connection->write_task) - { - GNUNET_SCHEDULER_cancel (connection->write_task); - connection->write_task = NULL; - connection->write_buffer_off = 0; - } - if (NULL != connection->read_task) - { - GNUNET_SCHEDULER_cancel (connection->read_task); - connection->read_task = NULL; - } - if (NULL != connection->nth.timeout_task) - { - GNUNET_SCHEDULER_cancel (connection->nth.timeout_task); - connection->nth.timeout_task = NULL; - } - connection->nth.notify_ready = NULL; - if (NULL != connection->dns_active) - { - GNUNET_RESOLVER_request_cancel (connection->dns_active); - connection->dns_active = NULL; - } - if (NULL != connection->proxy_handshake) - { - /* GNUNET_CONNECTION_destroy (connection->proxy_handshake); */ - connection->proxy_handshake->destroy_later = -1; - connection->proxy_handshake = NULL; /* Not leaked ??? */ - } - while (NULL != (pos = connection->ap_head)) - { - GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock)); - GNUNET_SCHEDULER_cancel (pos->task); - GNUNET_CONTAINER_DLL_remove (connection->ap_head, - connection->ap_tail, - pos); - GNUNET_free (pos); - } - if ( (NULL != connection->sock) && - (GNUNET_YES != connection->persist) ) - { - if ((GNUNET_OK != - GNUNET_NETWORK_socket_shutdown (connection->sock, - SHUT_RDWR)) && - (ENOTCONN != errno) && - (ECONNRESET != errno) ) - LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, - "shutdown"); - } - if (NULL != connection->sock) - { - if (GNUNET_YES != connection->persist) - { - GNUNET_break (GNUNET_OK == - GNUNET_NETWORK_socket_close (connection->sock)); - } - else - { - GNUNET_NETWORK_socket_free_memory_only_ (connection->sock); /* at least no memory leak (we deliberately - * leak the socket in this special case) ... */ - } - } - GNUNET_free_non_null (connection->addr); - GNUNET_free_non_null (connection->hostname); - GNUNET_free (connection->write_buffer); - GNUNET_free (connection); -} - - -/** - * This function is called once we either timeout - * or have data ready to read. - * - * @param cls connection to read from - */ -static void -receive_ready (void *cls) -{ - struct GNUNET_CONNECTION_Handle *connection = cls; - const struct GNUNET_SCHEDULER_TaskContext *tc; - char buffer[connection->max]; - ssize_t ret; - GNUNET_CONNECTION_Receiver receiver; - - connection->read_task = NULL; - tc = GNUNET_SCHEDULER_get_task_context (); - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Receive from `%s' encounters error: timeout (%s, %p)\n", - GNUNET_a2s (connection->addr, - connection->addrlen), - GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (connection->receive_timeout), - GNUNET_YES), - 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); -} - - -/** - * Receive data from the given connection. Note that this function - * will call @a receiver asynchronously using the scheduler. It will - * "immediately" return. Note that there MUST only be one active - * receive call per connection at any given point in time (so do not - * call receive again until the receiver callback has been invoked). - * - * @param connection connection handle - * @param max maximum number of bytes to read - * @param timeout maximum amount of time to wait - * @param receiver function to call with received data - * @param receiver_cls closure for @a receiver - */ -void -GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *connection, - size_t max, - struct GNUNET_TIME_Relative timeout, - GNUNET_CONNECTION_Receiver receiver, - void *receiver_cls) -{ - GNUNET_assert ((NULL == connection->read_task) && - (NULL == connection->receiver)); - GNUNET_assert (NULL != receiver); - connection->receiver = receiver; - connection->receiver_cls = receiver_cls; - connection->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout); - connection->max = max; - if (NULL != connection->sock) - { - connection->read_task = - GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining - (connection->receive_timeout), - connection->sock, - &receive_ready, - connection); - return; - } - if ((NULL == connection->dns_active) && - (NULL == connection->ap_head) && - (NULL == connection->proxy_handshake)) - { - connection->receiver = NULL; - receiver (receiver_cls, - NULL, 0, - NULL, 0, - ETIMEDOUT); - return; - } -} - - -/** - * Cancel receive job on the given connection. Note that the - * receiver callback must not have been called yet in order - * for the cancellation to be valid. - * - * @param connection connection handle - * @return closure of the original receiver callback closure - */ -void * -GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *connection) -{ - if (NULL != connection->read_task) - { - GNUNET_assert (connection == - GNUNET_SCHEDULER_cancel (connection->read_task)); - connection->read_task = NULL; - } - connection->receiver = NULL; - return connection->receiver_cls; -} - - -/** - * Try to call the transmit notify method (check if we do - * have enough space available first)! - * - * @param connection connection for which we should do this processing - * @return #GNUNET_YES if we were able to call notify - */ -static int -process_notify (struct GNUNET_CONNECTION_Handle *connection) -{ - size_t used; - size_t avail; - size_t size; - GNUNET_CONNECTION_TransmitReadyNotify notify; - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "process_notify is running\n"); - GNUNET_assert (NULL == connection->write_task); - if (NULL == (notify = connection->nth.notify_ready)) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "No one to notify\n"); - return GNUNET_NO; - } - used = connection->write_buffer_off - connection->write_buffer_pos; - avail = connection->write_buffer_size - used; - size = connection->nth.notify_size; - if (size > avail) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Not enough buffer\n"); - return GNUNET_NO; - } - connection->nth.notify_ready = NULL; - if (connection->write_buffer_size - connection->write_buffer_off < size) - { - /* need to compact */ - memmove (connection->write_buffer, - &connection->write_buffer[connection->write_buffer_pos], - used); - connection->write_buffer_off -= connection->write_buffer_pos; - connection->write_buffer_pos = 0; - } - avail = connection->write_buffer_size - connection->write_buffer_off; - GNUNET_assert (avail >= size); - size = - notify (connection->nth.notify_ready_cls, avail, - &connection->write_buffer[connection->write_buffer_off]); - GNUNET_assert (size <= avail); - if (0 != size) - connection->write_buffer_off += size; - return GNUNET_YES; -} - - -/** - * Task invoked by the scheduler when a call to transmit - * is timing out (we never got enough buffer space to call - * the callback function before the specified timeout - * expired). - * - * This task notifies the client about the timeout. - * - * @param cls the `struct GNUNET_CONNECTION_Handle` - */ -static void -transmit_timeout (void *cls) -{ - struct GNUNET_CONNECTION_Handle *connection = cls; - GNUNET_CONNECTION_TransmitReadyNotify notify; - - connection->nth.timeout_task = NULL; - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Transmit to `%s:%u/%s' fails, time out reached (%p).\n", - connection->hostname, - connection->port, - GNUNET_a2s (connection->addr, - connection->addrlen), - connection); - notify = connection->nth.notify_ready; - GNUNET_assert (NULL != notify); - connection->nth.notify_ready = NULL; - notify (connection->nth.notify_ready_cls, - 0, - NULL); -} - - -/** - * Task invoked by the scheduler when we failed to connect - * at the time of being asked to transmit. - * - * This task notifies the client about the error. - * - * @param cls the `struct GNUNET_CONNECTION_Handle` - */ -static void -connect_error (void *cls) -{ - struct GNUNET_CONNECTION_Handle *connection = cls; - GNUNET_CONNECTION_TransmitReadyNotify notify; - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Transmission request of size %u fails (%s/%u), connection failed (%p).\n", - connection->nth.notify_size, - connection->hostname, - connection->port, - connection); - connection->write_task = NULL; - notify = connection->nth.notify_ready; - connection->nth.notify_ready = NULL; - notify (connection->nth.notify_ready_cls, - 0, - NULL); -} - - -/** - * We are ready to transmit (or got a timeout). - * - * @param cls our connection handle - */ -static void -transmit_ready (void *cls) -{ - struct GNUNET_CONNECTION_Handle *connection = cls; - GNUNET_CONNECTION_TransmitReadyNotify notify; - const struct GNUNET_SCHEDULER_TaskContext *tc; - ssize_t ret; - size_t have; - - LOG (GNUNET_ERROR_TYPE_DEBUG, - "transmit_ready running (%p).\n", - connection); - GNUNET_assert (NULL != connection->write_task); - connection->write_task = NULL; - GNUNET_assert (NULL == connection->nth.timeout_task); - tc = GNUNET_SCHEDULER_get_task_context (); - if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) - { - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Transmit to `%s' fails, time out reached (%p).\n", - GNUNET_a2s (connection->addr, - connection->addrlen), - connection); - notify = connection->nth.notify_ready; - GNUNET_assert (NULL != notify); - connection->nth.notify_ready = NULL; - notify (connection->nth.notify_ready_cls, 0, NULL); - return; - } - GNUNET_assert (NULL != connection->sock); - if (NULL == tc->write_ready) - { - /* special circumstances (in particular, PREREQ_DONE after - * connect): not yet ready to write, but no "fatal" error either. - * Hence retry. */ - goto SCHEDULE_WRITE; - } - if (! GNUNET_NETWORK_fdset_isset (tc->write_ready, - connection->sock)) - { - GNUNET_assert (NULL == connection->write_task); - /* special circumstances (in particular, shutdown): not yet ready - * to write, but no "fatal" error either. Hence retry. */ - goto SCHEDULE_WRITE; - } - GNUNET_assert (connection->write_buffer_off >= connection->write_buffer_pos); - if ((NULL != connection->nth.notify_ready) && - (connection->write_buffer_size < connection->nth.notify_size)) - { - connection->write_buffer = - GNUNET_realloc (connection->write_buffer, connection->nth.notify_size); - connection->write_buffer_size = connection->nth.notify_size; - } - process_notify (connection); - have = connection->write_buffer_off - connection->write_buffer_pos; - if (0 == have) - { - /* no data ready for writing, terminate write loop */ - return; - } - GNUNET_assert (have <= connection->write_buffer_size); - GNUNET_assert (have + connection->write_buffer_pos <= connection->write_buffer_size); - GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size); -RETRY: - ret = - GNUNET_NETWORK_socket_send (connection->sock, - &connection->write_buffer[connection->write_buffer_pos], - have); - if (-1 == ret) - { - if (EINTR == errno) - goto RETRY; - if (NULL != connection->write_task) - { - GNUNET_SCHEDULER_cancel (connection->write_task); - connection->write_task = NULL; - } - signal_transmit_error (connection, errno); - return; - } - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Connection transmitted %u/%u bytes to `%s' (%p)\n", - (unsigned int) ret, - have, - GNUNET_a2s (connection->addr, - connection->addrlen), - connection); - connection->write_buffer_pos += ret; - if (connection->write_buffer_pos == connection->write_buffer_off) - { - /* transmitted all pending data */ - connection->write_buffer_pos = 0; - connection->write_buffer_off = 0; - } - if ( (0 == connection->write_buffer_off) && - (NULL == connection->nth.notify_ready) ) - return; /* all data sent! */ - /* not done writing, schedule more */ -SCHEDULE_WRITE: - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Re-scheduling transmit_ready (more to do) (%p).\n", - connection); - have = connection->write_buffer_off - connection->write_buffer_pos; - GNUNET_assert ( (NULL != connection->nth.notify_ready) || - (have > 0) ); - if (NULL == connection->write_task) - connection->write_task = - GNUNET_SCHEDULER_add_write_net ((connection->nth.notify_ready == - NULL) ? GNUNET_TIME_UNIT_FOREVER_REL : - GNUNET_TIME_absolute_get_remaining - (connection->nth.transmit_timeout), - connection->sock, - &transmit_ready, connection); -} - - -/** - * Ask the connection to call us once the specified number of bytes - * are free in the transmission buffer. Will never call the @a notify - * callback in this task, but always first go into the scheduler. - * - * @param connection connection - * @param size number of bytes to send - * @param timeout after how long should we give up (and call - * @a notify with buf NULL and size 0)? - * @param notify function to call - * @param notify_cls closure for @a notify - * @return non-NULL if the notify callback was queued, - * NULL if we are already going to notify someone else (busy) - */ -struct GNUNET_CONNECTION_TransmitHandle * -GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connection, - size_t size, - struct GNUNET_TIME_Relative timeout, - GNUNET_CONNECTION_TransmitReadyNotify notify, - void *notify_cls) -{ - if (NULL != connection->nth.notify_ready) - { - GNUNET_assert (0); - return NULL; - } - GNUNET_assert (NULL != notify); - GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE); - GNUNET_assert (connection->write_buffer_off <= connection->write_buffer_size); - GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size); - GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_off); - connection->nth.notify_ready = notify; - connection->nth.notify_ready_cls = notify_cls; - connection->nth.connection = connection; - connection->nth.notify_size = size; - connection->nth.transmit_timeout = GNUNET_TIME_relative_to_absolute (timeout); - GNUNET_assert (NULL == connection->nth.timeout_task); - if ((NULL == connection->sock) && - (NULL == connection->ap_head) && - (NULL == connection->dns_active) && - (NULL == connection->proxy_handshake)) - { - if (NULL != connection->write_task) - GNUNET_SCHEDULER_cancel (connection->write_task); - connection->write_task = GNUNET_SCHEDULER_add_now (&connect_error, - connection); - return &connection->nth; - } - if (NULL != connection->write_task) - return &connection->nth; /* previous transmission still in progress */ - if (NULL != connection->sock) - { - /* connected, try to transmit now */ - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Scheduling transmission (%p).\n", - connection); - connection->write_task = - GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining - (connection->nth.transmit_timeout), - connection->sock, - &transmit_ready, connection); - return &connection->nth; - } - /* not yet connected, wait for connection */ - LOG (GNUNET_ERROR_TYPE_DEBUG, - "Need to wait to schedule transmission for connection, adding timeout task (%p).\n", - connection); - connection->nth.timeout_task = - GNUNET_SCHEDULER_add_delayed (timeout, - &transmit_timeout, - connection); - return &connection->nth; -} - - -/** - * Cancel the specified transmission-ready notification. - * - * @param th notification to cancel - */ -void -GNUNET_CONNECTION_notify_transmit_ready_cancel (struct GNUNET_CONNECTION_TransmitHandle *th) -{ - GNUNET_assert (NULL != th->notify_ready); - th->notify_ready = NULL; - if (NULL != th->timeout_task) - { - GNUNET_SCHEDULER_cancel (th->timeout_task); - th->timeout_task = NULL; - } - if (NULL != th->connection->write_task) - { - GNUNET_SCHEDULER_cancel (th->connection->write_task); - th->connection->write_task = NULL; - } -} - - -/** - * Create a connection to be proxied using a given connection. - * - * @param cph connection to proxy server - * @return connection to be proxied - */ -struct GNUNET_CONNECTION_Handle * -GNUNET_CONNECTION_create_proxied_from_handshake (struct GNUNET_CONNECTION_Handle *cph) -{ - struct GNUNET_CONNECTION_Handle *proxied = GNUNET_CONNECTION_create_from_existing (NULL); - - proxied->proxy_handshake = cph; - return proxied; -} - - -/** - * Activate proxied connection and destroy initial proxy handshake connection. - * There must not be any pending requests for reading or writing to the - * proxy hadshake connection at this time. - * - * @param proxied connection connection to proxy server - */ -void -GNUNET_CONNECTION_acivate_proxied (struct GNUNET_CONNECTION_Handle *proxied) -{ - struct GNUNET_CONNECTION_Handle *cph = proxied->proxy_handshake; - - GNUNET_assert (NULL != cph); - GNUNET_assert (NULL == proxied->sock); - GNUNET_assert (NULL != cph->sock); - proxied->sock = cph->sock; - cph->sock = NULL; - GNUNET_CONNECTION_destroy (cph); - connect_success_continuation (proxied); -} - - -/* end of connection.c */ -- cgit v1.2.3