X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Futil%2Fconnection.c;h=5aa277546a3eadf0230e4680fc1293d2cb77c4c0;hb=265d10682af1afce58988be998d62e1849a3e545;hp=f6182ebbd9433fc096e6796a57b65a40f9c1f3cc;hpb=8ddd3c314faec2c7f0fe9c0fe7816ca5be54011d;p=oweals%2Fgnunet.git diff --git a/src/util/connection.c b/src/util/connection.c index f6182ebbd..5aa277546 100644 --- a/src/util/connection.c +++ b/src/util/connection.c @@ -1,10 +1,10 @@ /* This file is part of GNUnet. - (C) 2009, 2012 Christian Grothoff (and other contributing authors) + 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 2, or (at your + 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 @@ -14,8 +14,8 @@ 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., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /** @@ -30,14 +30,9 @@ * These rules should apply in general, but for this * module they are VERY, VERY important. */ - #include "platform.h" -#include "gnunet_common.h" -#include "gnunet_connection_lib.h" -#include "gnunet_container_lib.h" +#include "gnunet_util_lib.h" #include "gnunet_resolver_service.h" -#include "gnunet_scheduler_lib.h" -#include "gnunet_server_lib.h" #define LOG(kind,...) GNUNET_log_from (kind, "util", __VA_ARGS__) @@ -75,7 +70,7 @@ struct GNUNET_CONNECTION_TransmitHandle /** * Task called on timeout. */ - GNUNET_SCHEDULER_TaskIdentifier timeout_task; + struct GNUNET_SCHEDULER_Task * timeout_task; /** * At what number of bytes available in the @@ -126,7 +121,7 @@ struct AddressProbe /** * Task waiting for the connection to finish connecting. */ - GNUNET_SCHEDULER_TaskIdentifier task; + struct GNUNET_SCHEDULER_Task * task; }; @@ -175,7 +170,7 @@ struct GNUNET_CONNECTION_Handle GNUNET_CONNECTION_Receiver receiver; /** - * Closure for receiver. + * Closure for @e receiver. */ void *receiver_cls; @@ -185,36 +180,36 @@ struct GNUNET_CONNECTION_Handle char *write_buffer; /** - * Current size of our write buffer. + * Current size of our @e write_buffer. */ size_t write_buffer_size; /** - * Current write-offset in write buffer (where + * Current write-offset in @e write_buffer (where * would we write next). */ size_t write_buffer_off; /** - * Current read-offset in write buffer (how many + * Current read-offset in @e write_buffer (how many * bytes have already been sent). */ size_t write_buffer_pos; /** - * Length of addr. + * Length of @e addr. */ socklen_t addrlen; /** * Read task that we may need to wait for. */ - GNUNET_SCHEDULER_TaskIdentifier read_task; + struct GNUNET_SCHEDULER_Task *read_task; /** * Write task that we may need to wait for. */ - GNUNET_SCHEDULER_TaskIdentifier write_task; + struct GNUNET_SCHEDULER_Task *write_task; /** * Handle to a pending DNS lookup request. @@ -247,7 +242,19 @@ struct GNUNET_CONNECTION_Handle * termination as a signal (because only then will the leaked * socket be freed!) */ - int16_t persist; + 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; }; @@ -275,7 +282,7 @@ GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *connection) * reach the other side before the process is terminated. * * @param connection the connection to make flushing and blocking - * @return GNUNET_OK on success + * @return #GNUNET_OK on success */ int GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection) @@ -287,7 +294,7 @@ GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection) /** * 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. + * #GNUNET_connection_destroy() will close it. * * @param osSocket existing socket to box * @return the boxed connection handle @@ -297,7 +304,7 @@ GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket) { struct GNUNET_CONNECTION_Handle *connection; - connection = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); + 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; @@ -309,14 +316,14 @@ GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket) * Create a connection handle by accepting on a listen socket. This * function may block if the listen socket has no connection ready. * - * @param access function to use to check if access is allowed - * @param access_cls closure for access + * @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, - void *access_cls, +GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access_cb, + void *access_cb_cls, struct GNUNET_NETWORK_Handle *lsock) { struct GNUNET_CONNECTION_Handle *connection; @@ -340,7 +347,8 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, GNUNET_NETWORK_socket_accept (lsock, (struct sockaddr *) &addr, &addrlen); if (NULL == sock) { - LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "accept"); + if (EAGAIN != errno) + LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "accept"); return NULL; } if ((addrlen > sizeof (addr)) || (addrlen < sizeof (sa_family_t))) @@ -355,7 +363,7 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, if ((AF_INET6 == sa->sa_family) && (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr))) { /* convert to V4 address */ - v4 = GNUNET_malloc (sizeof (struct sockaddr_in)); + v4 = GNUNET_new (struct sockaddr_in); memset (v4, 0, sizeof (struct sockaddr_in)); v4->sin_family = AF_INET; #if HAVE_SOCKADDR_IN_SIN_LEN @@ -413,25 +421,28 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, #endif } - if ((NULL != access) && - (GNUNET_YES != (aret = access (access_cls, gcp, uaddr, addrlen)))) + 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)); + 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_NETWORK_socket_shutdown (sock, + SHUT_RDWR)); GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock)); GNUNET_free (uaddr); return NULL; } - connection = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); + 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, + LOG (GNUNET_ERROR_TYPE_INFO, _("Accepting connection from `%s': %p\n"), GNUNET_a2s (uaddr, addrlen), connection); return connection; @@ -443,12 +454,13 @@ GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access, * * @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 address - * @return GNUNET_OK on success + * @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) + void **addr, + size_t *addrlen) { if ((NULL == connection->addr) || (0 == connection->addrlen)) return GNUNET_NO; @@ -466,17 +478,23 @@ GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *connection, * @param errcode error code to send */ static void -signal_receive_error (struct GNUNET_CONNECTION_Handle *connection, int errcode) +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", + "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); + receiver (connection->receiver_cls, + NULL, + 0, + connection->addr, + connection->addrlen, + errcode); } @@ -490,7 +508,8 @@ signal_receive_timeout (struct GNUNET_CONNECTION_Handle *connection) { GNUNET_CONNECTION_Receiver receiver; - LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection signals timeout to receiver (%p)!\n", + LOG (GNUNET_ERROR_TYPE_DEBUG, + "Connection signals timeout to receiver (%p)!\n", connection); GNUNET_assert (NULL != (receiver = connection->receiver)); connection->receiver = NULL; @@ -516,16 +535,18 @@ signal_transmit_error (struct GNUNET_CONNECTION_Handle *connection, connection); if (NULL != connection->sock) { - GNUNET_NETWORK_socket_shutdown (connection->sock, SHUT_RDWR); - GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (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 (GNUNET_SCHEDULER_NO_TASK == connection->write_task); + GNUNET_assert (NULL == connection->write_task); } - if (GNUNET_SCHEDULER_NO_TASK != connection->read_task) + if (NULL != connection->read_task) { /* send errors trigger read errors... */ GNUNET_SCHEDULER_cancel (connection->read_task); - connection->read_task = GNUNET_SCHEDULER_NO_TASK; + connection->read_task = NULL; signal_receive_timeout (connection); return; } @@ -547,24 +568,37 @@ 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); + "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); + 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); + signal_receive_error (connection, + ECONNREFUSED); if (NULL != connection->nth.notify_ready) { - GNUNET_assert (connection->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK); + GNUNET_assert (NULL != connection->nth.timeout_task); GNUNET_SCHEDULER_cancel (connection->nth.timeout_task); - connection->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; - signal_transmit_error (connection, ECONNREFUSED); + 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; } @@ -597,15 +631,17 @@ receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); static void connect_success_continuation (struct GNUNET_CONNECTION_Handle *connection) { - LOG (GNUNET_ERROR_TYPE_DEBUG, + LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection to `%s' succeeded! (%p)\n", - GNUNET_a2s (connection->addr, connection->addrlen), connection); + 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 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, @@ -616,10 +652,10 @@ connect_success_continuation (struct GNUNET_CONNECTION_Handle *connection) LOG (GNUNET_ERROR_TYPE_DEBUG, "Connection succeeded, starting with sending data (%p)\n", connection); - GNUNET_assert (connection->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK); + GNUNET_assert (connection->nth.timeout_task != NULL); GNUNET_SCHEDULER_cancel (connection->nth.timeout_task); - connection->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_assert (connection->write_task == GNUNET_SCHEDULER_NO_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, @@ -657,7 +693,9 @@ connect_probe_continuation (void *cls, { GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock)); GNUNET_free (ap); - if ((NULL == connection->ap_head) && (GNUNET_NO == connection->dns_active)) + if ((NULL == connection->ap_head) && + (GNUNET_NO == connection->dns_active) && + (NULL == connection->proxy_handshake)) connect_fail_continuation (connection); return; } @@ -684,12 +722,13 @@ connect_probe_continuation (void *cls, * 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 cls our `struct GNUNET_CONNECTION_Handle *` * @param addr address to try, NULL for "last call" - * @param addrlen length of addr + * @param addrlen length of @a addr */ static void -try_connect_using_address (void *cls, const struct sockaddr *addr, +try_connect_using_address (void *cls, + const struct sockaddr *addr, socklen_t addrlen) { struct GNUNET_CONNECTION_Handle *connection = cls; @@ -699,7 +738,9 @@ try_connect_using_address (void *cls, const struct sockaddr *addr, if (NULL == addr) { connection->dns_active = NULL; - if ((NULL == connection->ap_head) && (NULL == connection->sock)) + if ((NULL == connection->ap_head) && + (NULL == connection->sock) && + (NULL == connection->proxy_handshake)) connect_fail_continuation (connection); return; } @@ -708,8 +749,11 @@ try_connect_using_address (void *cls, const struct sockaddr *addr, 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); + "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]; memcpy (&ap[1], addr, addrlen); @@ -735,18 +779,16 @@ try_connect_using_address (void *cls, const struct sockaddr *addr, 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); + 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"); -#if 0 - LOG (GNUNET_ERROR_TYPE_INFO, _("Failed to connect to `%s' (%p)\n"), - GNUNET_a2s (ap->addr, ap->addrlen), connection); -#endif GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock)); GNUNET_free (ap); return; @@ -756,8 +798,7 @@ try_connect_using_address (void *cls, const struct sockaddr *addr, if (NULL != connection->nth.notify_ready) delay = GNUNET_TIME_relative_min (delay, - GNUNET_TIME_absolute_get_remaining (connection-> - nth.transmit_timeout)); + GNUNET_TIME_absolute_get_remaining (connection->nth.transmit_timeout)); if (NULL != connection->receiver) delay = GNUNET_TIME_relative_min (delay, @@ -780,14 +821,14 @@ try_connect_using_address (void *cls, const struct sockaddr *addr, * @return the connection handle */ struct GNUNET_CONNECTION_Handle * -GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle - *cfg, const char *hostname, +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_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); + 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); @@ -811,38 +852,38 @@ GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle * @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) +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; - size_t slen; GNUNET_assert (0 < strlen (unixpath)); /* sanity check */ - un = GNUNET_malloc (sizeof (struct sockaddr_un)); + un = GNUNET_new (struct sockaddr_un); un->sun_family = AF_UNIX; - slen = strlen (unixpath); - if (slen >= sizeof (un->sun_path)) - slen = sizeof (un->sun_path) - 1; - memcpy (un->sun_path, unixpath, slen); - un->sun_path[slen] = '\0'; - slen = sizeof (struct sockaddr_un); -#if HAVE_SOCKADDR_IN_SIN_LEN - un->sun_len = (u_char) slen; + 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 LINUX - un->sun_path[0] = '\0'; +#if HAVE_SOCKADDR_IN_SIN_LEN + un->sun_len = (u_char) sizeof (struct sockaddr_un); #endif - connection = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle)); + 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 = slen; + connection->addrlen = sizeof (struct sockaddr_un); connection->sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0); if (NULL == connection->sock) { @@ -851,8 +892,9 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct GNUNET_free (connection); return NULL; } - if (GNUNET_OK != - GNUNET_NETWORK_socket_connect (connection->sock, connection->addr, connection->addrlen)) + 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)); @@ -872,32 +914,29 @@ GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct * 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 s socket to connect * @param serv_addr server address - * @param addrlen length of 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) +GNUNET_CONNECTION_connect_socket (struct GNUNET_NETWORK_Handle *s, + const struct sockaddr *serv_addr, + socklen_t addrlen) { - struct GNUNET_NETWORK_Handle *s; struct GNUNET_CONNECTION_Handle *connection; - 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; - } - if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) && - (EINPROGRESS != errno)) + if ( (GNUNET_OK != + GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) && + (EINPROGRESS != errno) ) { /* maybe refused / unsupported address, try next */ - LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect"); - LOG (GNUNET_ERROR_TYPE_INFO, _("Attempt to connect to `%s' failed\n"), - GNUNET_a2s (serv_addr, addrlen)); + 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; } @@ -905,26 +944,61 @@ GNUNET_CONNECTION_create_from_sockaddr (int af_family, connection->addr = GNUNET_malloc (addrlen); 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); + 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 + * @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)) + if ((NULL != connection->ap_head) || + (NULL != connection->dns_active) || + (NULL != connection->proxy_handshake)) return GNUNET_YES; /* still trying to connect */ - return (NULL == connection->sock) ? GNUNET_NO : GNUNET_YES; + if ( (0 != connection->destroy_later) || + (NULL == connection->sock) ) + return GNUNET_NO; + return GNUNET_YES; } @@ -940,24 +1014,31 @@ GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection) { struct AddressProbe *pos; - LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down connection (%p)\n", connection); + 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 (GNUNET_SCHEDULER_NO_TASK != connection->write_task) + if (NULL != connection->write_task) { GNUNET_SCHEDULER_cancel (connection->write_task); - connection->write_task = GNUNET_SCHEDULER_NO_TASK; + connection->write_task = NULL; connection->write_buffer_off = 0; } - if (GNUNET_SCHEDULER_NO_TASK != connection->read_task) + if (NULL != connection->read_task) { GNUNET_SCHEDULER_cancel (connection->read_task); - connection->read_task = GNUNET_SCHEDULER_NO_TASK; + connection->read_task = NULL; } - if (GNUNET_SCHEDULER_NO_TASK != connection->nth.timeout_task) + if (NULL != connection->nth.timeout_task) { GNUNET_SCHEDULER_cancel (connection->nth.timeout_task); - connection->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; + connection->nth.timeout_task = NULL; } connection->nth.notify_ready = NULL; if (NULL != connection->dns_active) @@ -965,6 +1046,12 @@ GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection) 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)); @@ -975,18 +1062,26 @@ GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection) if ( (NULL != connection->sock) && (GNUNET_YES != connection->persist) ) { - if ((GNUNET_YES != GNUNET_NETWORK_socket_shutdown (connection->sock, SHUT_RDWR)) && - (ENOTCONN != errno) && + if ((GNUNET_OK != + GNUNET_NETWORK_socket_shutdown (connection->sock, + SHUT_RDWR)) && + (ENOTCONN != errno) && (ECONNRESET != errno) ) - LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "shutdown"); + 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)); + { + GNUNET_break (GNUNET_OK == + GNUNET_NETWORK_socket_close (connection->sock)); + } else - GNUNET_free (connection->sock); /* at least no memory leak (we deliberately - * leak the socket in this special case) ... */ + { + 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); @@ -1003,14 +1098,15 @@ GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection) * @param tc scheduler context */ static void -receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +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; + connection->read_task = NULL; if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) { /* ignore shutdown request, go again immediately */ @@ -1023,9 +1119,9 @@ receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) { LOG (GNUNET_ERROR_TYPE_DEBUG, - "Receive from `%s' encounters error: timeout (%p)\n", + "Receive from `%s' encounters error: timeout (%s, %p)\n", GNUNET_a2s (connection->addr, connection->addrlen), - GNUNET_TIME_absolute_get_duration (connection->receive_timeout).rel_value, + GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (connection->receive_timeout), GNUNET_YES), connection); signal_receive_timeout (connection); return; @@ -1038,7 +1134,9 @@ receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, connection->sock)); RETRY: - ret = GNUNET_NETWORK_socket_recv (connection->sock, buffer, connection->max); + ret = GNUNET_NETWORK_socket_recv (connection->sock, + buffer, + connection->max); if (-1 == ret) { if (EINTR == errno) @@ -1047,17 +1145,26 @@ RETRY: 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); + "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); + receiver (connection->receiver_cls, + buffer, + ret, + connection->addr, + connection->addrlen, + 0); } /** * Receive data from the given connection. Note that this function will - * call "receiver" asynchronously using the scheduler. It 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). @@ -1066,15 +1173,16 @@ RETRY: * @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 receiver + * @param receiver_cls closure for @a receiver */ void -GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *connection, size_t max, +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 ((GNUNET_SCHEDULER_NO_TASK == connection->read_task) && + GNUNET_assert ((NULL == connection->read_task) && (NULL == connection->receiver)); GNUNET_assert (NULL != receiver); connection->receiver = receiver; @@ -1085,12 +1193,17 @@ GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *connection, size_t m { connection->read_task = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining - (connection->receive_timeout), connection->sock, - &receive_ready, connection); + (connection->receive_timeout), + connection->sock, + &receive_ready, + connection); return; } - if ((NULL == connection->dns_active) && (NULL == connection->ap_head)) + 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; } @@ -1108,10 +1221,11 @@ GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *connection, size_t m void * GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *connection) { - if (GNUNET_SCHEDULER_NO_TASK == connection->read_task) + if (NULL != connection->read_task) { - GNUNET_assert (connection == GNUNET_SCHEDULER_cancel (connection->read_task)); - connection->read_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_assert (connection == + GNUNET_SCHEDULER_cancel (connection->read_task)); + connection->read_task = NULL; } connection->receiver = NULL; return connection->receiver_cls; @@ -1123,7 +1237,7 @@ GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *connection) * 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 + * @return #GNUNET_YES if we were able to call notify */ static int process_notify (struct GNUNET_CONNECTION_Handle *connection) @@ -1133,19 +1247,30 @@ process_notify (struct GNUNET_CONNECTION_Handle *connection) size_t size; GNUNET_CONNECTION_TransmitReadyNotify notify; - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->write_task); + 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], + 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; @@ -1170,20 +1295,24 @@ process_notify (struct GNUNET_CONNECTION_Handle *connection) * * This task notifies the client about the timeout. * - * @param cls the 'struct GNUNET_CONNECTION_Handle' + * @param cls the `struct GNUNET_CONNECTION_Handle` * @param tc scheduler context */ static void -transmit_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +transmit_timeout (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_CONNECTION_Handle *connection = cls; GNUNET_CONNECTION_TransmitReadyNotify notify; - connection->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK; + 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); + connection->port, + GNUNET_a2s (connection->addr, + connection->addrlen), + connection); notify = connection->nth.notify_ready; GNUNET_assert (NULL != notify); connection->nth.notify_ready = NULL; @@ -1197,19 +1326,23 @@ transmit_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * * This task notifies the client about the error. * - * @param cls the 'struct GNUNET_CONNECTION_Handle' + * @param cls the `struct GNUNET_CONNECTION_Handle` * @param tc scheduler context */ static void -connect_error (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +connect_error (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { 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 = GNUNET_SCHEDULER_NO_TASK; + 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); @@ -1223,17 +1356,20 @@ connect_error (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * @param tc task context describing why we are here */ static void -transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +transmit_ready (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_CONNECTION_Handle *connection = cls; GNUNET_CONNECTION_TransmitReadyNotify notify; ssize_t ret; size_t have; - LOG (GNUNET_ERROR_TYPE_DEBUG, "transmit_ready running (%p).\n", connection); - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != connection->write_task); - connection->write_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->nth.timeout_task); + 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); if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) { if (NULL != connection->sock) @@ -1253,7 +1389,9 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmit to `%s' fails, time out reached (%p).\n", - GNUNET_a2s (connection->addr, connection->addrlen), connection); + GNUNET_a2s (connection->addr, + connection->addrlen), + connection); notify = connection->nth.notify_ready; GNUNET_assert (NULL != notify); connection->nth.notify_ready = NULL; @@ -1261,7 +1399,7 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) return; } GNUNET_assert (NULL != connection->sock); - if (NULL == tc->write_ready) + if (NULL == tc->write_ready) { /* special circumstances (in particular, PREREQ_DONE after * connect): not yet ready to write, but no "fatal" error either. @@ -1270,7 +1408,7 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } if (!GNUNET_NETWORK_fdset_isset (tc->write_ready, connection->sock)) { - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->write_task); + 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; @@ -1302,10 +1440,10 @@ RETRY: { if (EINTR == errno) goto RETRY; - if (GNUNET_SCHEDULER_NO_TASK != connection->write_task) + if (NULL != connection->write_task) { GNUNET_SCHEDULER_cancel (connection->write_task); - connection->write_task = GNUNET_SCHEDULER_NO_TASK; + connection->write_task = NULL; } signal_transmit_error (connection, errno); return; @@ -1328,7 +1466,7 @@ SCHEDULE_WRITE: "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 (GNUNET_SCHEDULER_NO_TASK == connection->write_task) + if (NULL == connection->write_task) connection->write_task = GNUNET_SCHEDULER_add_write_net ((connection->nth.notify_ready == NULL) ? GNUNET_TIME_UNIT_FOREVER_REL : @@ -1340,15 +1478,15 @@ SCHEDULE_WRITE: /** * Ask the connection to call us once the specified number of bytes - * are free in the transmission buffer. May call the notify - * method immediately if enough space is available. + * 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 - * notify with buf NULL and size 0)? + * @a notify with buf NULL and size 0)? * @param notify function to call - * @param notify_cls closure for notify + * @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) */ @@ -1374,22 +1512,26 @@ GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connec connection->nth.connection = connection; connection->nth.notify_size = size; connection->nth.transmit_timeout = GNUNET_TIME_relative_to_absolute (timeout); - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->nth.timeout_task); - if ((NULL == connection->sock) && + GNUNET_assert (NULL == connection->nth.timeout_task); + if ((NULL == connection->sock) && (NULL == connection->ap_head) && - (NULL == connection->dns_active)) + (NULL == connection->dns_active) && + (NULL == connection->proxy_handshake)) { - if (GNUNET_SCHEDULER_NO_TASK != connection->write_task) + if (NULL != connection->write_task) GNUNET_SCHEDULER_cancel (connection->write_task); - connection->write_task = GNUNET_SCHEDULER_add_now (&connect_error, connection); + connection->write_task = GNUNET_SCHEDULER_add_now (&connect_error, + connection); return &connection->nth; } - if (GNUNET_SCHEDULER_NO_TASK != connection->write_task) + 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); + 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), @@ -1398,9 +1540,11 @@ GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connec } /* 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); + "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); + GNUNET_SCHEDULER_add_delayed (timeout, + &transmit_timeout, connection); return &connection->nth; } @@ -1411,22 +1555,57 @@ GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connec * @param th notification to cancel */ void -GNUNET_CONNECTION_notify_transmit_ready_cancel (struct - GNUNET_CONNECTION_TransmitHandle - *th) +GNUNET_CONNECTION_notify_transmit_ready_cancel (struct GNUNET_CONNECTION_TransmitHandle *th) { GNUNET_assert (NULL != th->notify_ready); th->notify_ready = NULL; - if (GNUNET_SCHEDULER_NO_TASK != th->timeout_task) + if (NULL != th->timeout_task) { GNUNET_SCHEDULER_cancel (th->timeout_task); - th->timeout_task = GNUNET_SCHEDULER_NO_TASK; + th->timeout_task = NULL; } - if (GNUNET_SCHEDULER_NO_TASK != th->connection->write_task) + if (NULL != th->connection->write_task) { GNUNET_SCHEDULER_cancel (th->connection->write_task); - th->connection->write_task = GNUNET_SCHEDULER_NO_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 */