2 This file is part of GNUnet.
3 Copyright (C) 2009-2013 GNUnet e.V.
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
22 * @file util/connection.c
23 * @brief TCP connection management
24 * @author Christian Grothoff
26 * This code is rather complex. Only modify it if you
27 * 1) Have a NEW testcase showing that the new code
28 * is needed and correct
29 * 2) All EXISTING testcases pass with the new code
30 * These rules should apply in general, but for this
31 * module they are VERY, VERY important.
34 #include "gnunet_util_lib.h"
35 #include "gnunet_resolver_service.h"
39 #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-connection", syscall)
43 * Transmission handle. There can only be one for each connection.
45 struct GNUNET_CONNECTION_TransmitHandle
49 * Function to call if the send buffer has notify_size
52 GNUNET_CONNECTION_TransmitReadyNotify notify_ready;
55 * Closure for notify_ready.
57 void *notify_ready_cls;
60 * Our connection handle.
62 struct GNUNET_CONNECTION_Handle *connection;
65 * Timeout for receiving (in absolute time).
67 struct GNUNET_TIME_Absolute transmit_timeout;
70 * Task called on timeout.
72 struct GNUNET_SCHEDULER_Task * timeout_task;
75 * At what number of bytes available in the
76 * write buffer should the notify method be called?
84 * During connect, we try multiple possible IP addresses
85 * to find out which one might work.
91 * This is a linked list.
93 struct AddressProbe *next;
96 * This is a doubly-linked list.
98 struct AddressProbe *prev;
101 * The address; do not free (allocated at the end of this struct).
103 const struct sockaddr *addr;
106 * Underlying OS's socket.
108 struct GNUNET_NETWORK_Handle *sock;
111 * Connection for which we are probing.
113 struct GNUNET_CONNECTION_Handle *connection;
121 * Task waiting for the connection to finish connecting.
123 struct GNUNET_SCHEDULER_Task * task;
128 * @brief handle for a network connection
130 struct GNUNET_CONNECTION_Handle
134 * Configuration to use.
136 const struct GNUNET_CONFIGURATION_Handle *cfg;
139 * Linked list of sockets we are currently trying out
142 struct AddressProbe *ap_head;
145 * Linked list of sockets we are currently trying out
148 struct AddressProbe *ap_tail;
151 * Network address of the other end-point, may be NULL.
153 struct sockaddr *addr;
156 * Pointer to the hostname if connection was
157 * created using DNS lookup, otherwise NULL.
162 * Underlying OS's socket, set to NULL after fatal errors.
164 struct GNUNET_NETWORK_Handle *sock;
167 * Function to call on data received, NULL if no receive is pending.
169 GNUNET_CONNECTION_Receiver receiver;
172 * Closure for @e receiver.
177 * Pointer to our write buffer.
182 * Current size of our @e write_buffer.
184 size_t write_buffer_size;
187 * Current write-offset in @e write_buffer (where
188 * would we write next).
190 size_t write_buffer_off;
193 * Current read-offset in @e write_buffer (how many
194 * bytes have already been sent).
196 size_t write_buffer_pos;
204 * Read task that we may need to wait for.
206 struct GNUNET_SCHEDULER_Task *read_task;
209 * Write task that we may need to wait for.
211 struct GNUNET_SCHEDULER_Task *write_task;
214 * Handle to a pending DNS lookup request.
216 struct GNUNET_RESOLVER_RequestHandle *dns_active;
219 * The handle we return for #GNUNET_CONNECTION_notify_transmit_ready().
221 struct GNUNET_CONNECTION_TransmitHandle nth;
224 * Timeout for receiving (in absolute time).
226 struct GNUNET_TIME_Absolute receive_timeout;
229 * Maximum number of bytes to read (for receiving).
234 * Port to connect to.
239 * When shutdown, do not ever actually close the socket, but
240 * free resources. Only should ever be set if using program
241 * termination as a signal (because only then will the leaked
247 * Usually 0. Set to 1 if this handle is in use, and should
248 * #GNUNET_CONNECTION_destroy() be called right now, the action needs
249 * to be deferred by setting it to -1.
251 int8_t destroy_later;
254 * Handle to subsequent connection after proxy handshake completes,
256 struct GNUNET_CONNECTION_Handle *proxy_handshake;
262 * Set the persist option on this connection handle. Indicates
263 * that the underlying socket or fd should never really be closed.
264 * Used for indicating process death.
266 * @param connection the connection to set persistent
269 GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *connection)
271 connection->persist = GNUNET_YES;
276 * Disable the "CORK" feature for communication with the given connection,
277 * forcing the OS to immediately flush the buffer on transmission
278 * instead of potentially buffering multiple messages. Essentially
279 * reduces the OS send buffers to zero.
280 * Used to make sure that the last messages sent through the connection
281 * reach the other side before the process is terminated.
283 * @param connection the connection to make flushing and blocking
284 * @return #GNUNET_OK on success
287 GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection)
289 return GNUNET_NETWORK_socket_disable_corking (connection->sock);
294 * Create a connection handle by boxing an existing OS socket. The OS
295 * socket should henceforth be no longer used directly.
296 * #GNUNET_connection_destroy() will close it.
298 * @param osSocket existing socket to box
299 * @return the boxed connection handle
301 struct GNUNET_CONNECTION_Handle *
302 GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket)
304 struct GNUNET_CONNECTION_Handle *connection;
306 connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
307 connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
308 connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
309 connection->sock = osSocket;
315 * Create a connection handle by accepting on a listen socket. This
316 * function may block if the listen socket has no connection ready.
318 * @param access_cb function to use to check if access is allowed
319 * @param access_cb_cls closure for @a access_cb
320 * @param lsock listen socket
321 * @return the connection handle, NULL on error
323 struct GNUNET_CONNECTION_Handle *
324 GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access_cb,
326 struct GNUNET_NETWORK_Handle *lsock)
328 struct GNUNET_CONNECTION_Handle *connection;
331 struct GNUNET_NETWORK_Handle *sock;
333 struct sockaddr_in *v4;
334 struct sockaddr_in6 *v6;
341 struct GNUNET_CONNECTION_Credentials *gcp;
342 #if HAVE_GETPEEREID || defined(SO_PEERCRED) || HAVE_GETPEERUCRED
343 struct GNUNET_CONNECTION_Credentials gc;
349 addrlen = sizeof (addr);
351 GNUNET_NETWORK_socket_accept (lsock,
352 (struct sockaddr *) &addr,
357 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "accept");
360 if ((addrlen > sizeof (addr)) || (addrlen < sizeof (sa_family_t)))
363 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
367 sa = (struct sockaddr *) addr;
368 v6 = (struct sockaddr_in6 *) addr;
369 if ( (AF_INET6 == sa->sa_family) &&
370 (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr)) )
372 /* convert to V4 address */
373 v4 = GNUNET_new (struct sockaddr_in);
374 memset (v4, 0, sizeof (struct sockaddr_in));
375 v4->sin_family = AF_INET;
376 #if HAVE_SOCKADDR_IN_SIN_LEN
377 v4->sin_len = (u_char) sizeof (struct sockaddr_in);
379 GNUNET_memcpy (&v4->sin_addr,
380 &((char *) &v6->sin6_addr)[sizeof (struct in6_addr) -
381 sizeof (struct in_addr)],
382 sizeof (struct in_addr));
383 v4->sin_port = v6->sin6_port;
385 addrlen = sizeof (struct sockaddr_in);
389 uaddr = GNUNET_malloc (addrlen);
390 GNUNET_memcpy (uaddr, addr, addrlen);
393 if (AF_UNIX == sa->sa_family)
397 if (0 == getpeereid (GNUNET_NETWORK_get_fd (sock),
403 /* largely traditional GNU/Linux */
406 getsockopt (GNUNET_NETWORK_get_fd (sock),
411 (olen == sizeof (uc)) )
418 #if HAVE_GETPEERUCRED
419 /* this is for Solaris 10 */
423 if (0 == getpeerucred (GNUNET_NETWORK_get_fd (sock), &uc))
425 gc.uid = ucred_geteuid (uc);
426 gc.gid = ucred_getegid (uc);
435 if ( (NULL != access_cb) &&
436 (GNUNET_YES != (aret = access_cb (access_cb_cls,
441 if (GNUNET_NO == aret)
442 LOG (GNUNET_ERROR_TYPE_INFO,
443 _("Access denied to `%s'\n"),
446 GNUNET_break (GNUNET_OK ==
447 GNUNET_NETWORK_socket_shutdown (sock,
449 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
453 connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
454 connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
455 connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
456 connection->addr = uaddr;
457 connection->addrlen = addrlen;
458 connection->sock = sock;
459 LOG (GNUNET_ERROR_TYPE_INFO,
460 _("Accepting connection from `%s': %p\n"),
469 * Obtain the network address of the other party.
471 * @param connection the client to get the address for
472 * @param addr where to store the address
473 * @param addrlen where to store the length of the @a addr
474 * @return #GNUNET_OK on success
477 GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *connection,
481 if ((NULL == connection->addr) || (0 == connection->addrlen))
483 *addr = GNUNET_malloc (connection->addrlen);
484 GNUNET_memcpy (*addr, connection->addr, connection->addrlen);
485 *addrlen = connection->addrlen;
491 * Tell the receiver callback that we had an IO error.
493 * @param connection connection to signal error
494 * @param errcode error code to send
497 signal_receive_error (struct GNUNET_CONNECTION_Handle *connection,
500 GNUNET_CONNECTION_Receiver receiver;
502 LOG (GNUNET_ERROR_TYPE_DEBUG,
503 "Receive encounters error (%s), connection closed (%p)\n",
506 GNUNET_assert (NULL != (receiver = connection->receiver));
507 connection->receiver = NULL;
508 receiver (connection->receiver_cls,
518 * Tell the receiver callback that a timeout was reached.
520 * @param connection connection to signal for
523 signal_receive_timeout (struct GNUNET_CONNECTION_Handle *connection)
525 GNUNET_CONNECTION_Receiver receiver;
527 LOG (GNUNET_ERROR_TYPE_DEBUG,
528 "Connection signals timeout to receiver (%p)!\n",
530 GNUNET_assert (NULL != (receiver = connection->receiver));
531 connection->receiver = NULL;
532 receiver (connection->receiver_cls, NULL, 0, NULL, 0, 0);
537 * We failed to transmit data to the service, signal the error.
539 * @param connection handle that had trouble
540 * @param ecode error code (errno)
543 signal_transmit_error (struct GNUNET_CONNECTION_Handle *connection,
546 GNUNET_CONNECTION_TransmitReadyNotify notify;
548 LOG (GNUNET_ERROR_TYPE_DEBUG,
549 "Transmission encounterd error (%s), connection closed (%p)\n",
552 if (NULL != connection->sock)
554 (void) GNUNET_NETWORK_socket_shutdown (connection->sock,
556 GNUNET_break (GNUNET_OK ==
557 GNUNET_NETWORK_socket_close (connection->sock));
558 connection->sock = NULL;
559 GNUNET_assert (NULL == connection->write_task);
561 if (NULL != connection->read_task)
563 /* send errors trigger read errors... */
564 GNUNET_SCHEDULER_cancel (connection->read_task);
565 connection->read_task = NULL;
566 signal_receive_timeout (connection);
569 if (NULL == connection->nth.notify_ready)
570 return; /* nobody to tell about it */
571 notify = connection->nth.notify_ready;
572 connection->nth.notify_ready = NULL;
573 notify (connection->nth.notify_ready_cls,
580 * We've failed for good to establish a connection (timeout or
581 * no more addresses to try).
583 * @param connection the connection we tried to establish
586 connect_fail_continuation (struct GNUNET_CONNECTION_Handle *connection)
588 LOG (GNUNET_ERROR_TYPE_INFO,
589 "Failed to establish TCP connection to `%s:%u', no further addresses to try.\n",
590 connection->hostname,
592 GNUNET_break (NULL == connection->ap_head);
593 GNUNET_break (NULL == connection->ap_tail);
594 GNUNET_break (GNUNET_NO == connection->dns_active);
595 GNUNET_break (NULL == connection->sock);
596 GNUNET_assert (NULL == connection->write_task);
597 GNUNET_assert (NULL == connection->proxy_handshake);
599 /* signal errors for jobs that used to wait on the connection */
600 connection->destroy_later = 1;
601 if (NULL != connection->receiver)
602 signal_receive_error (connection,
604 if (NULL != connection->nth.notify_ready)
606 GNUNET_assert (NULL != connection->nth.timeout_task);
607 GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
608 connection->nth.timeout_task = NULL;
609 signal_transmit_error (connection,
612 if (-1 == connection->destroy_later)
615 connection->destroy_later = 0;
616 GNUNET_CONNECTION_destroy (connection);
619 connection->destroy_later = 0;
624 * We are ready to transmit (or got a timeout).
626 * @param cls our connection handle
629 transmit_ready (void *cls);
633 * This function is called once we either timeout or have data ready
636 * @param cls connection to read from
639 receive_ready (void *cls);
643 * We've succeeded in establishing a connection.
645 * @param connection the connection we tried to establish
648 connect_success_continuation (struct GNUNET_CONNECTION_Handle *connection)
650 LOG (GNUNET_ERROR_TYPE_DEBUG,
651 "Connection to `%s' succeeded! (%p)\n",
652 GNUNET_a2s (connection->addr,
653 connection->addrlen),
655 /* trigger jobs that waited for the connection */
656 if (NULL != connection->receiver)
658 LOG (GNUNET_ERROR_TYPE_DEBUG,
659 "Connection succeeded, starting with receiving data (%p)\n",
661 GNUNET_assert (NULL == connection->read_task);
662 connection->read_task =
663 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining
664 (connection->receive_timeout),
666 &receive_ready, connection);
668 if (NULL != connection->nth.notify_ready)
670 LOG (GNUNET_ERROR_TYPE_DEBUG,
671 "Connection succeeded, starting with sending data (%p)\n",
673 GNUNET_assert (connection->nth.timeout_task != NULL);
674 GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
675 connection->nth.timeout_task = NULL;
676 GNUNET_assert (connection->write_task == NULL);
677 connection->write_task =
678 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining
679 (connection->nth.transmit_timeout), connection->sock,
680 &transmit_ready, connection);
686 * Scheduler let us know that we're either ready to write on the
687 * socket OR connect timed out. Do the right thing.
689 * @param cls the `struct AddressProbe *` with the address that we are probing
692 connect_probe_continuation (void *cls)
694 struct AddressProbe *ap = cls;
695 struct GNUNET_CONNECTION_Handle *connection = ap->connection;
696 const struct GNUNET_SCHEDULER_TaskContext *tc;
697 struct AddressProbe *pos;
701 GNUNET_assert (NULL != ap->sock);
702 GNUNET_CONTAINER_DLL_remove (connection->ap_head,
705 len = sizeof (error);
708 tc = GNUNET_SCHEDULER_get_task_context ();
709 if ( (0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ||
711 GNUNET_NETWORK_socket_getsockopt (ap->sock,
718 GNUNET_break (GNUNET_OK ==
719 GNUNET_NETWORK_socket_close (ap->sock));
721 if ( (NULL == connection->ap_head) &&
722 (GNUNET_NO == connection->dns_active) &&
723 (NULL == connection->proxy_handshake) )
724 connect_fail_continuation (connection);
727 GNUNET_assert (NULL == connection->sock);
728 connection->sock = ap->sock;
729 GNUNET_assert (NULL == connection->addr);
730 connection->addr = GNUNET_malloc (ap->addrlen);
731 GNUNET_memcpy (connection->addr, ap->addr, ap->addrlen);
732 connection->addrlen = ap->addrlen;
734 /* cancel all other attempts */
735 while (NULL != (pos = connection->ap_head))
737 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock));
738 GNUNET_SCHEDULER_cancel (pos->task);
739 GNUNET_CONTAINER_DLL_remove (connection->ap_head,
744 connect_success_continuation (connection);
749 * Try to establish a connection given the specified address.
750 * This function is called by the resolver once we have a DNS reply.
752 * @param cls our `struct GNUNET_CONNECTION_Handle *`
753 * @param addr address to try, NULL for "last call"
754 * @param addrlen length of @a addr
757 try_connect_using_address (void *cls,
758 const struct sockaddr *addr,
761 struct GNUNET_CONNECTION_Handle *connection = cls;
762 struct AddressProbe *ap;
763 struct GNUNET_TIME_Relative delay;
767 connection->dns_active = NULL;
768 if ((NULL == connection->ap_head) &&
769 (NULL == connection->sock) &&
770 (NULL == connection->proxy_handshake))
771 connect_fail_continuation (connection);
774 if (NULL != connection->sock)
775 return; /* already connected */
776 GNUNET_assert (NULL == connection->addr);
778 LOG (GNUNET_ERROR_TYPE_DEBUG,
779 "Trying to connect using address `%s:%u/%s:%u'\n",
780 connection->hostname,
782 GNUNET_a2s (addr, addrlen),
784 ap = GNUNET_malloc (sizeof (struct AddressProbe) + addrlen);
785 ap->addr = (const struct sockaddr *) &ap[1];
786 GNUNET_memcpy (&ap[1], addr, addrlen);
787 ap->addrlen = addrlen;
788 ap->connection = connection;
790 switch (ap->addr->sa_family)
793 ((struct sockaddr_in *) ap->addr)->sin_port = htons (connection->port);
796 ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (connection->port);
801 return; /* not supported by us */
803 ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family,
805 if (NULL == ap->sock)
808 return; /* not supported by OS */
810 LOG (GNUNET_ERROR_TYPE_INFO,
811 "Trying to connect to `%s' (%p)\n",
812 GNUNET_a2s (ap->addr, ap->addrlen),
815 GNUNET_NETWORK_socket_connect (ap->sock,
818 (EINPROGRESS != errno))
820 /* maybe refused / unsupported address, try next */
821 LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect");
822 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock));
826 GNUNET_CONTAINER_DLL_insert (connection->ap_head, connection->ap_tail, ap);
827 delay = GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT;
828 if (NULL != connection->nth.notify_ready)
829 delay = GNUNET_TIME_relative_min (delay,
830 GNUNET_TIME_absolute_get_remaining (connection->nth.transmit_timeout));
831 if (NULL != connection->receiver)
832 delay = GNUNET_TIME_relative_min (delay,
833 GNUNET_TIME_absolute_get_remaining (connection->receive_timeout));
834 ap->task = GNUNET_SCHEDULER_add_write_net (delay,
836 &connect_probe_continuation,
842 * Create a connection handle by (asynchronously) connecting to a host.
843 * This function returns immediately, even if the connection has not
844 * yet been established. This function only creates TCP connections.
846 * @param cfg configuration to use
847 * @param hostname name of the host to connect to
848 * @param port port to connect to
849 * @return the connection handle
851 struct GNUNET_CONNECTION_Handle *
852 GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
853 const char *hostname,
856 struct GNUNET_CONNECTION_Handle *connection;
858 GNUNET_assert (0 < strlen (hostname)); /* sanity check */
859 connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
860 connection->cfg = cfg;
861 connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
862 connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
863 connection->port = port;
864 connection->hostname = GNUNET_strdup (hostname);
865 connection->dns_active =
866 GNUNET_RESOLVER_ip_get (connection->hostname,
868 GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT,
869 &try_connect_using_address,
876 * Create a connection handle by connecting to a UNIX domain service.
877 * This function returns immediately, even if the connection has not
878 * yet been established. This function only creates UNIX connections.
880 * @param cfg configuration to use
881 * @param unixpath path to connect to
882 * @return the connection handle, NULL on systems without UNIX support
884 struct GNUNET_CONNECTION_Handle *
885 GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct GNUNET_CONFIGURATION_Handle *cfg,
886 const char *unixpath)
889 struct GNUNET_CONNECTION_Handle *connection;
890 struct sockaddr_un *un;
892 GNUNET_assert (0 < strlen (unixpath)); /* sanity check */
893 un = GNUNET_new (struct sockaddr_un);
894 un->sun_family = AF_UNIX;
895 strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1);
900 abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
902 "USE_ABSTRACT_SOCKETS");
903 if (GNUNET_YES == abstract)
904 un->sun_path[0] = '\0';
907 #if HAVE_SOCKADDR_UN_SUN_LEN
908 un->sun_len = (u_char) sizeof (struct sockaddr_un);
910 connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
911 connection->cfg = cfg;
912 connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
913 connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
914 connection->port = 0;
915 connection->hostname = NULL;
916 connection->addr = (struct sockaddr *) un;
917 connection->addrlen = sizeof (struct sockaddr_un);
918 connection->sock = GNUNET_NETWORK_socket_create (AF_UNIX,
921 if (NULL == connection->sock)
923 GNUNET_free (connection->addr);
924 GNUNET_free (connection->write_buffer);
925 GNUNET_free (connection);
929 GNUNET_NETWORK_socket_connect (connection->sock,
931 connection->addrlen)) &&
932 (EINPROGRESS != errno) )
934 /* Just return; we expect everything to work eventually so don't fail HARD */
935 GNUNET_break (GNUNET_OK ==
936 GNUNET_NETWORK_socket_close (connection->sock));
937 connection->sock = NULL;
940 connect_success_continuation (connection);
949 * Create a connection handle by (asynchronously) connecting to a host.
950 * This function returns immediately, even if the connection has not
951 * yet been established. This function only creates TCP connections.
953 * @param s socket to connect
954 * @param serv_addr server address
955 * @param addrlen length of @a serv_addr
956 * @return the connection handle
958 struct GNUNET_CONNECTION_Handle *
959 GNUNET_CONNECTION_connect_socket (struct GNUNET_NETWORK_Handle *s,
960 const struct sockaddr *serv_addr,
963 struct GNUNET_CONNECTION_Handle *connection;
966 GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) &&
967 (EINPROGRESS != errno) )
969 /* maybe refused / unsupported address, try next */
970 LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG,
972 LOG (GNUNET_ERROR_TYPE_DEBUG,
973 "Attempt to connect to `%s' failed\n",
974 GNUNET_a2s (serv_addr,
976 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s));
979 connection = GNUNET_CONNECTION_create_from_existing (s);
980 connection->addr = GNUNET_malloc (addrlen);
981 GNUNET_memcpy (connection->addr, serv_addr, addrlen);
982 connection->addrlen = addrlen;
983 LOG (GNUNET_ERROR_TYPE_INFO,
984 "Trying to connect to `%s' (%p)\n",
985 GNUNET_a2s (serv_addr, addrlen),
992 * Create a connection handle by creating a socket and
993 * (asynchronously) connecting to a host. This function returns
994 * immediately, even if the connection has not yet been established.
995 * This function only creates TCP connections.
997 * @param af_family address family to use
998 * @param serv_addr server address
999 * @param addrlen length of @a serv_addr
1000 * @return the connection handle
1002 struct GNUNET_CONNECTION_Handle *
1003 GNUNET_CONNECTION_create_from_sockaddr (int af_family,
1004 const struct sockaddr *serv_addr,
1007 struct GNUNET_NETWORK_Handle *s;
1009 s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0);
1012 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
1016 return GNUNET_CONNECTION_connect_socket (s,
1023 * Check if connection is valid (no fatal errors have happened so far).
1024 * Note that a connection that is still trying to connect is considered
1027 * @param connection connection to check
1028 * @return #GNUNET_YES if valid, #GNUNET_NO otherwise
1031 GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *connection)
1033 if ((NULL != connection->ap_head) ||
1034 (NULL != connection->dns_active) ||
1035 (NULL != connection->proxy_handshake))
1036 return GNUNET_YES; /* still trying to connect */
1037 if ( (0 != connection->destroy_later) ||
1038 (NULL == connection->sock) )
1045 * Close the connection and free associated resources. There must
1046 * not be any pending requests for reading or writing to the
1047 * connection at this time.
1049 * @param connection connection to destroy
1052 GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection)
1054 struct AddressProbe *pos;
1056 if (0 != connection->destroy_later)
1058 connection->destroy_later = -1;
1061 LOG (GNUNET_ERROR_TYPE_DEBUG,
1062 "Shutting down connection (%p)\n",
1064 GNUNET_assert (NULL == connection->nth.notify_ready);
1065 GNUNET_assert (NULL == connection->receiver);
1066 if (NULL != connection->write_task)
1068 GNUNET_SCHEDULER_cancel (connection->write_task);
1069 connection->write_task = NULL;
1070 connection->write_buffer_off = 0;
1072 if (NULL != connection->read_task)
1074 GNUNET_SCHEDULER_cancel (connection->read_task);
1075 connection->read_task = NULL;
1077 if (NULL != connection->nth.timeout_task)
1079 GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
1080 connection->nth.timeout_task = NULL;
1082 connection->nth.notify_ready = NULL;
1083 if (NULL != connection->dns_active)
1085 GNUNET_RESOLVER_request_cancel (connection->dns_active);
1086 connection->dns_active = NULL;
1088 if (NULL != connection->proxy_handshake)
1090 /* GNUNET_CONNECTION_destroy (connection->proxy_handshake); */
1091 connection->proxy_handshake->destroy_later = -1;
1092 connection->proxy_handshake = NULL; /* Not leaked ??? */
1094 while (NULL != (pos = connection->ap_head))
1096 GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock));
1097 GNUNET_SCHEDULER_cancel (pos->task);
1098 GNUNET_CONTAINER_DLL_remove (connection->ap_head,
1099 connection->ap_tail,
1103 if ( (NULL != connection->sock) &&
1104 (GNUNET_YES != connection->persist) )
1107 GNUNET_NETWORK_socket_shutdown (connection->sock,
1109 (ENOTCONN != errno) &&
1110 (ECONNRESET != errno) )
1111 LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
1114 if (NULL != connection->sock)
1116 if (GNUNET_YES != connection->persist)
1118 GNUNET_break (GNUNET_OK ==
1119 GNUNET_NETWORK_socket_close (connection->sock));
1123 GNUNET_NETWORK_socket_free_memory_only_ (connection->sock); /* at least no memory leak (we deliberately
1124 * leak the socket in this special case) ... */
1127 GNUNET_free_non_null (connection->addr);
1128 GNUNET_free_non_null (connection->hostname);
1129 GNUNET_free (connection->write_buffer);
1130 GNUNET_free (connection);
1135 * This function is called once we either timeout
1136 * or have data ready to read.
1138 * @param cls connection to read from
1141 receive_ready (void *cls)
1143 struct GNUNET_CONNECTION_Handle *connection = cls;
1144 const struct GNUNET_SCHEDULER_TaskContext *tc;
1145 char buffer[connection->max];
1147 GNUNET_CONNECTION_Receiver receiver;
1149 connection->read_task = NULL;
1150 tc = GNUNET_SCHEDULER_get_task_context ();
1151 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
1153 LOG (GNUNET_ERROR_TYPE_DEBUG,
1154 "Receive from `%s' encounters error: timeout (%s, %p)\n",
1155 GNUNET_a2s (connection->addr,
1156 connection->addrlen),
1157 GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (connection->receive_timeout),
1160 signal_receive_timeout (connection);
1163 if (NULL == connection->sock)
1165 /* connect failed for good */
1166 signal_receive_error (connection, ECONNREFUSED);
1169 GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready,
1172 ret = GNUNET_NETWORK_socket_recv (connection->sock,
1179 signal_receive_error (connection, errno);
1182 LOG (GNUNET_ERROR_TYPE_DEBUG,
1183 "receive_ready read %u/%u bytes from `%s' (%p)!\n",
1186 GNUNET_a2s (connection->addr,
1187 connection->addrlen),
1189 GNUNET_assert (NULL != (receiver = connection->receiver));
1190 connection->receiver = NULL;
1191 receiver (connection->receiver_cls,
1195 connection->addrlen,
1201 * Receive data from the given connection. Note that this function
1202 * will call @a receiver asynchronously using the scheduler. It will
1203 * "immediately" return. Note that there MUST only be one active
1204 * receive call per connection at any given point in time (so do not
1205 * call receive again until the receiver callback has been invoked).
1207 * @param connection connection handle
1208 * @param max maximum number of bytes to read
1209 * @param timeout maximum amount of time to wait
1210 * @param receiver function to call with received data
1211 * @param receiver_cls closure for @a receiver
1214 GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *connection,
1216 struct GNUNET_TIME_Relative timeout,
1217 GNUNET_CONNECTION_Receiver receiver,
1220 GNUNET_assert ((NULL == connection->read_task) &&
1221 (NULL == connection->receiver));
1222 GNUNET_assert (NULL != receiver);
1223 connection->receiver = receiver;
1224 connection->receiver_cls = receiver_cls;
1225 connection->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout);
1226 connection->max = max;
1227 if (NULL != connection->sock)
1229 connection->read_task =
1230 GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining
1231 (connection->receive_timeout),
1237 if ((NULL == connection->dns_active) &&
1238 (NULL == connection->ap_head) &&
1239 (NULL == connection->proxy_handshake))
1241 connection->receiver = NULL;
1242 receiver (receiver_cls,
1252 * Cancel receive job on the given connection. Note that the
1253 * receiver callback must not have been called yet in order
1254 * for the cancellation to be valid.
1256 * @param connection connection handle
1257 * @return closure of the original receiver callback closure
1260 GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *connection)
1262 if (NULL != connection->read_task)
1264 GNUNET_assert (connection ==
1265 GNUNET_SCHEDULER_cancel (connection->read_task));
1266 connection->read_task = NULL;
1268 connection->receiver = NULL;
1269 return connection->receiver_cls;
1274 * Try to call the transmit notify method (check if we do
1275 * have enough space available first)!
1277 * @param connection connection for which we should do this processing
1278 * @return #GNUNET_YES if we were able to call notify
1281 process_notify (struct GNUNET_CONNECTION_Handle *connection)
1286 GNUNET_CONNECTION_TransmitReadyNotify notify;
1288 LOG (GNUNET_ERROR_TYPE_DEBUG,
1289 "process_notify is running\n");
1290 GNUNET_assert (NULL == connection->write_task);
1291 if (NULL == (notify = connection->nth.notify_ready))
1293 LOG (GNUNET_ERROR_TYPE_DEBUG,
1294 "No one to notify\n");
1297 used = connection->write_buffer_off - connection->write_buffer_pos;
1298 avail = connection->write_buffer_size - used;
1299 size = connection->nth.notify_size;
1302 LOG (GNUNET_ERROR_TYPE_DEBUG,
1303 "Not enough buffer\n");
1306 connection->nth.notify_ready = NULL;
1307 if (connection->write_buffer_size - connection->write_buffer_off < size)
1309 /* need to compact */
1310 memmove (connection->write_buffer,
1311 &connection->write_buffer[connection->write_buffer_pos],
1313 connection->write_buffer_off -= connection->write_buffer_pos;
1314 connection->write_buffer_pos = 0;
1316 avail = connection->write_buffer_size - connection->write_buffer_off;
1317 GNUNET_assert (avail >= size);
1319 notify (connection->nth.notify_ready_cls, avail,
1320 &connection->write_buffer[connection->write_buffer_off]);
1321 GNUNET_assert (size <= avail);
1323 connection->write_buffer_off += size;
1329 * Task invoked by the scheduler when a call to transmit
1330 * is timing out (we never got enough buffer space to call
1331 * the callback function before the specified timeout
1334 * This task notifies the client about the timeout.
1336 * @param cls the `struct GNUNET_CONNECTION_Handle`
1339 transmit_timeout (void *cls)
1341 struct GNUNET_CONNECTION_Handle *connection = cls;
1342 GNUNET_CONNECTION_TransmitReadyNotify notify;
1344 connection->nth.timeout_task = NULL;
1345 LOG (GNUNET_ERROR_TYPE_DEBUG,
1346 "Transmit to `%s:%u/%s' fails, time out reached (%p).\n",
1347 connection->hostname,
1349 GNUNET_a2s (connection->addr,
1350 connection->addrlen),
1352 notify = connection->nth.notify_ready;
1353 GNUNET_assert (NULL != notify);
1354 connection->nth.notify_ready = NULL;
1355 notify (connection->nth.notify_ready_cls,
1362 * Task invoked by the scheduler when we failed to connect
1363 * at the time of being asked to transmit.
1365 * This task notifies the client about the error.
1367 * @param cls the `struct GNUNET_CONNECTION_Handle`
1370 connect_error (void *cls)
1372 struct GNUNET_CONNECTION_Handle *connection = cls;
1373 GNUNET_CONNECTION_TransmitReadyNotify notify;
1375 LOG (GNUNET_ERROR_TYPE_DEBUG,
1376 "Transmission request of size %u fails (%s/%u), connection failed (%p).\n",
1377 connection->nth.notify_size,
1378 connection->hostname,
1381 connection->write_task = NULL;
1382 notify = connection->nth.notify_ready;
1383 connection->nth.notify_ready = NULL;
1384 notify (connection->nth.notify_ready_cls,
1391 * We are ready to transmit (or got a timeout).
1393 * @param cls our connection handle
1396 transmit_ready (void *cls)
1398 struct GNUNET_CONNECTION_Handle *connection = cls;
1399 GNUNET_CONNECTION_TransmitReadyNotify notify;
1400 const struct GNUNET_SCHEDULER_TaskContext *tc;
1404 LOG (GNUNET_ERROR_TYPE_DEBUG,
1405 "transmit_ready running (%p).\n",
1407 GNUNET_assert (NULL != connection->write_task);
1408 connection->write_task = NULL;
1409 GNUNET_assert (NULL == connection->nth.timeout_task);
1410 tc = GNUNET_SCHEDULER_get_task_context ();
1411 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
1413 LOG (GNUNET_ERROR_TYPE_DEBUG,
1414 "Transmit to `%s' fails, time out reached (%p).\n",
1415 GNUNET_a2s (connection->addr,
1416 connection->addrlen),
1418 notify = connection->nth.notify_ready;
1419 GNUNET_assert (NULL != notify);
1420 connection->nth.notify_ready = NULL;
1421 notify (connection->nth.notify_ready_cls, 0, NULL);
1424 GNUNET_assert (NULL != connection->sock);
1425 if (NULL == tc->write_ready)
1427 /* special circumstances (in particular, PREREQ_DONE after
1428 * connect): not yet ready to write, but no "fatal" error either.
1430 goto SCHEDULE_WRITE;
1432 if (! GNUNET_NETWORK_fdset_isset (tc->write_ready,
1435 GNUNET_assert (NULL == connection->write_task);
1436 /* special circumstances (in particular, shutdown): not yet ready
1437 * to write, but no "fatal" error either. Hence retry. */
1438 goto SCHEDULE_WRITE;
1440 GNUNET_assert (connection->write_buffer_off >= connection->write_buffer_pos);
1441 if ((NULL != connection->nth.notify_ready) &&
1442 (connection->write_buffer_size < connection->nth.notify_size))
1444 connection->write_buffer =
1445 GNUNET_realloc (connection->write_buffer, connection->nth.notify_size);
1446 connection->write_buffer_size = connection->nth.notify_size;
1448 process_notify (connection);
1449 have = connection->write_buffer_off - connection->write_buffer_pos;
1452 /* no data ready for writing, terminate write loop */
1455 GNUNET_assert (have <= connection->write_buffer_size);
1456 GNUNET_assert (have + connection->write_buffer_pos <= connection->write_buffer_size);
1457 GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size);
1460 GNUNET_NETWORK_socket_send (connection->sock,
1461 &connection->write_buffer[connection->write_buffer_pos],
1467 if (NULL != connection->write_task)
1469 GNUNET_SCHEDULER_cancel (connection->write_task);
1470 connection->write_task = NULL;
1472 signal_transmit_error (connection, errno);
1475 LOG (GNUNET_ERROR_TYPE_DEBUG,
1476 "Connection transmitted %u/%u bytes to `%s' (%p)\n",
1479 GNUNET_a2s (connection->addr,
1480 connection->addrlen),
1482 connection->write_buffer_pos += ret;
1483 if (connection->write_buffer_pos == connection->write_buffer_off)
1485 /* transmitted all pending data */
1486 connection->write_buffer_pos = 0;
1487 connection->write_buffer_off = 0;
1489 if ( (0 == connection->write_buffer_off) &&
1490 (NULL == connection->nth.notify_ready) )
1491 return; /* all data sent! */
1492 /* not done writing, schedule more */
1494 LOG (GNUNET_ERROR_TYPE_DEBUG,
1495 "Re-scheduling transmit_ready (more to do) (%p).\n",
1497 have = connection->write_buffer_off - connection->write_buffer_pos;
1498 GNUNET_assert ( (NULL != connection->nth.notify_ready) ||
1500 if (NULL == connection->write_task)
1501 connection->write_task =
1502 GNUNET_SCHEDULER_add_write_net ((connection->nth.notify_ready ==
1503 NULL) ? GNUNET_TIME_UNIT_FOREVER_REL :
1504 GNUNET_TIME_absolute_get_remaining
1505 (connection->nth.transmit_timeout),
1507 &transmit_ready, connection);
1512 * Ask the connection to call us once the specified number of bytes
1513 * are free in the transmission buffer. Will never call the @a notify
1514 * callback in this task, but always first go into the scheduler.
1516 * @param connection connection
1517 * @param size number of bytes to send
1518 * @param timeout after how long should we give up (and call
1519 * @a notify with buf NULL and size 0)?
1520 * @param notify function to call
1521 * @param notify_cls closure for @a notify
1522 * @return non-NULL if the notify callback was queued,
1523 * NULL if we are already going to notify someone else (busy)
1525 struct GNUNET_CONNECTION_TransmitHandle *
1526 GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connection,
1528 struct GNUNET_TIME_Relative timeout,
1529 GNUNET_CONNECTION_TransmitReadyNotify notify,
1532 if (NULL != connection->nth.notify_ready)
1537 GNUNET_assert (NULL != notify);
1538 GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
1539 GNUNET_assert (connection->write_buffer_off <= connection->write_buffer_size);
1540 GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size);
1541 GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_off);
1542 connection->nth.notify_ready = notify;
1543 connection->nth.notify_ready_cls = notify_cls;
1544 connection->nth.connection = connection;
1545 connection->nth.notify_size = size;
1546 connection->nth.transmit_timeout = GNUNET_TIME_relative_to_absolute (timeout);
1547 GNUNET_assert (NULL == connection->nth.timeout_task);
1548 if ((NULL == connection->sock) &&
1549 (NULL == connection->ap_head) &&
1550 (NULL == connection->dns_active) &&
1551 (NULL == connection->proxy_handshake))
1553 if (NULL != connection->write_task)
1554 GNUNET_SCHEDULER_cancel (connection->write_task);
1555 connection->write_task = GNUNET_SCHEDULER_add_now (&connect_error,
1557 return &connection->nth;
1559 if (NULL != connection->write_task)
1560 return &connection->nth; /* previous transmission still in progress */
1561 if (NULL != connection->sock)
1563 /* connected, try to transmit now */
1564 LOG (GNUNET_ERROR_TYPE_DEBUG,
1565 "Scheduling transmission (%p).\n",
1567 connection->write_task =
1568 GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining
1569 (connection->nth.transmit_timeout),
1571 &transmit_ready, connection);
1572 return &connection->nth;
1574 /* not yet connected, wait for connection */
1575 LOG (GNUNET_ERROR_TYPE_DEBUG,
1576 "Need to wait to schedule transmission for connection, adding timeout task (%p).\n",
1578 connection->nth.timeout_task =
1579 GNUNET_SCHEDULER_add_delayed (timeout,
1582 return &connection->nth;
1587 * Cancel the specified transmission-ready notification.
1589 * @param th notification to cancel
1592 GNUNET_CONNECTION_notify_transmit_ready_cancel (struct GNUNET_CONNECTION_TransmitHandle *th)
1594 GNUNET_assert (NULL != th->notify_ready);
1595 th->notify_ready = NULL;
1596 if (NULL != th->timeout_task)
1598 GNUNET_SCHEDULER_cancel (th->timeout_task);
1599 th->timeout_task = NULL;
1601 if (NULL != th->connection->write_task)
1603 GNUNET_SCHEDULER_cancel (th->connection->write_task);
1604 th->connection->write_task = NULL;
1610 * Create a connection to be proxied using a given connection.
1612 * @param cph connection to proxy server
1613 * @return connection to be proxied
1615 struct GNUNET_CONNECTION_Handle *
1616 GNUNET_CONNECTION_create_proxied_from_handshake (struct GNUNET_CONNECTION_Handle *cph)
1618 struct GNUNET_CONNECTION_Handle *proxied = GNUNET_CONNECTION_create_from_existing (NULL);
1620 proxied->proxy_handshake = cph;
1626 * Activate proxied connection and destroy initial proxy handshake connection.
1627 * There must not be any pending requests for reading or writing to the
1628 * proxy hadshake connection at this time.
1630 * @param proxied connection connection to proxy server
1633 GNUNET_CONNECTION_acivate_proxied (struct GNUNET_CONNECTION_Handle *proxied)
1635 struct GNUNET_CONNECTION_Handle *cph = proxied->proxy_handshake;
1637 GNUNET_assert (NULL != cph);
1638 GNUNET_assert (NULL == proxied->sock);
1639 GNUNET_assert (NULL != cph->sock);
1640 proxied->sock = cph->sock;
1642 GNUNET_CONNECTION_destroy (cph);
1643 connect_success_continuation (proxied);
1647 /* end of connection.c */