rename configs to match
[oweals/gnunet.git] / src / transport / tcp_connection_legacy.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009-2013 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
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      Affero General Public License for more details.
14
15      You should have received a copy of the GNU Affero General Public License
16      along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18      SPDX-License-Identifier: AGPL3.0-or-later
19  */
20
21 /**
22  * @file util/connection.c
23  * @brief  TCP connection management
24  * @author Christian Grothoff
25  *
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.
32  */
33 #include "platform.h"
34 #include "gnunet_util_lib.h"
35 #include "gnunet_resolver_service.h"
36
37
38 /**
39  * Timeout we use on TCP connect before trying another
40  * result from the DNS resolver.  Actual value used
41  * is this value divided by the number of address families.
42  * Default is 5s.
43  */
44 #define CONNECT_RETRY_TIMEOUT \
45   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
46
47
48 #define LOG_STRERROR(kind, syscall) \
49   GNUNET_log_from_strerror (kind, "util-connection", syscall)
50
51
52 /**
53  * Transmission handle.  There can only be one for each connection.
54  */
55 struct GNUNET_CONNECTION_TransmitHandle
56 {
57   /**
58    * Function to call if the send buffer has notify_size
59    * bytes available.
60    */
61   GNUNET_CONNECTION_TransmitReadyNotify notify_ready;
62
63   /**
64    * Closure for notify_ready.
65    */
66   void *notify_ready_cls;
67
68   /**
69    * Our connection handle.
70    */
71   struct GNUNET_CONNECTION_Handle *connection;
72
73   /**
74    * Timeout for receiving (in absolute time).
75    */
76   struct GNUNET_TIME_Absolute transmit_timeout;
77
78   /**
79    * Task called on timeout.
80    */
81   struct GNUNET_SCHEDULER_Task *timeout_task;
82
83   /**
84    * At what number of bytes available in the
85    * write buffer should the notify method be called?
86    */
87   size_t notify_size;
88 };
89
90
91 /**
92  * During connect, we try multiple possible IP addresses
93  * to find out which one might work.
94  */
95 struct AddressProbe
96 {
97   /**
98    * This is a linked list.
99    */
100   struct AddressProbe *next;
101
102   /**
103    * This is a doubly-linked list.
104    */
105   struct AddressProbe *prev;
106
107   /**
108    * The address; do not free (allocated at the end of this struct).
109    */
110   const struct sockaddr *addr;
111
112   /**
113    * Underlying OS's socket.
114    */
115   struct GNUNET_NETWORK_Handle *sock;
116
117   /**
118    * Connection for which we are probing.
119    */
120   struct GNUNET_CONNECTION_Handle *connection;
121
122   /**
123    * Lenth of addr.
124    */
125   socklen_t addrlen;
126
127   /**
128    * Task waiting for the connection to finish connecting.
129    */
130   struct GNUNET_SCHEDULER_Task *task;
131 };
132
133
134 /**
135  * @brief handle for a network connection
136  */
137 struct GNUNET_CONNECTION_Handle
138 {
139   /**
140    * Configuration to use.
141    */
142   const struct GNUNET_CONFIGURATION_Handle *cfg;
143
144   /**
145    * Linked list of sockets we are currently trying out
146    * (during connect).
147    */
148   struct AddressProbe *ap_head;
149
150   /**
151    * Linked list of sockets we are currently trying out
152    * (during connect).
153    */
154   struct AddressProbe *ap_tail;
155
156   /**
157    * Network address of the other end-point, may be NULL.
158    */
159   struct sockaddr *addr;
160
161   /**
162    * Pointer to the hostname if connection was
163    * created using DNS lookup, otherwise NULL.
164    */
165   char *hostname;
166
167   /**
168    * Underlying OS's socket, set to NULL after fatal errors.
169    */
170   struct GNUNET_NETWORK_Handle *sock;
171
172   /**
173    * Function to call on data received, NULL if no receive is pending.
174    */
175   GNUNET_CONNECTION_Receiver receiver;
176
177   /**
178    * Closure for @e receiver.
179    */
180   void *receiver_cls;
181
182   /**
183    * Pointer to our write buffer.
184    */
185   char *write_buffer;
186
187   /**
188    * Current size of our @e write_buffer.
189    */
190   size_t write_buffer_size;
191
192   /**
193    * Current write-offset in @e write_buffer (where
194    * would we write next).
195    */
196   size_t write_buffer_off;
197
198   /**
199    * Current read-offset in @e write_buffer (how many
200    * bytes have already been sent).
201    */
202   size_t write_buffer_pos;
203
204   /**
205    * Length of @e addr.
206    */
207   socklen_t addrlen;
208
209   /**
210    * Read task that we may need to wait for.
211    */
212   struct GNUNET_SCHEDULER_Task *read_task;
213
214   /**
215    * Write task that we may need to wait for.
216    */
217   struct GNUNET_SCHEDULER_Task *write_task;
218
219   /**
220    * Handle to a pending DNS lookup request.
221    */
222   struct GNUNET_RESOLVER_RequestHandle *dns_active;
223
224   /**
225    * The handle we return for #GNUNET_CONNECTION_notify_transmit_ready().
226    */
227   struct GNUNET_CONNECTION_TransmitHandle nth;
228
229   /**
230    * Timeout for receiving (in absolute time).
231    */
232   struct GNUNET_TIME_Absolute receive_timeout;
233
234   /**
235    * Maximum number of bytes to read (for receiving).
236    */
237   size_t max;
238
239   /**
240    * Port to connect to.
241    */
242   uint16_t port;
243
244   /**
245    * When shutdown, do not ever actually close the socket, but
246    * free resources.  Only should ever be set if using program
247    * termination as a signal (because only then will the leaked
248    * socket be freed!)
249    */
250   int8_t persist;
251
252   /**
253    * Usually 0.  Set to 1 if this handle is in use, and should
254    * #GNUNET_CONNECTION_destroy() be called right now, the action needs
255    * to be deferred by setting it to -1.
256    */
257   int8_t destroy_later;
258
259   /**
260    * Handle to subsequent connection after proxy handshake completes,
261    */
262   struct GNUNET_CONNECTION_Handle *proxy_handshake;
263 };
264
265
266 /**
267  * Set the persist option on this connection handle.  Indicates
268  * that the underlying socket or fd should never really be closed.
269  * Used for indicating process death.
270  *
271  * @param connection the connection to set persistent
272  */
273 void
274 GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *connection)
275 {
276   connection->persist = GNUNET_YES;
277 }
278
279
280 /**
281  * Disable the "CORK" feature for communication with the given connection,
282  * forcing the OS to immediately flush the buffer on transmission
283  * instead of potentially buffering multiple messages.  Essentially
284  * reduces the OS send buffers to zero.
285  * Used to make sure that the last messages sent through the connection
286  * reach the other side before the process is terminated.
287  *
288  * @param connection the connection to make flushing and blocking
289  * @return #GNUNET_OK on success
290  */
291 int
292 GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection)
293 {
294   return GNUNET_NETWORK_socket_disable_corking (connection->sock);
295 }
296
297
298 /**
299  * Create a connection handle by boxing an existing OS socket.  The OS
300  * socket should henceforth be no longer used directly.
301  * #GNUNET_connection_destroy() will close it.
302  *
303  * @param osSocket existing socket to box
304  * @return the boxed connection handle
305  */
306 struct GNUNET_CONNECTION_Handle *
307 GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket)
308 {
309   struct GNUNET_CONNECTION_Handle *connection;
310
311   connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
312   connection->write_buffer_size = GNUNET_MIN_MESSAGE_SIZE;
313   connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
314   connection->sock = osSocket;
315   return connection;
316 }
317
318
319 /**
320  * Create a connection handle by accepting on a listen socket.  This
321  * function may block if the listen socket has no connection ready.
322  *
323  * @param access_cb function to use to check if access is allowed
324  * @param access_cb_cls closure for @a access_cb
325  * @param lsock listen socket
326  * @return the connection handle, NULL on error
327  */
328 struct GNUNET_CONNECTION_Handle *
329 GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access_cb,
330                                       void *access_cb_cls,
331                                       struct GNUNET_NETWORK_Handle *lsock)
332 {
333   struct GNUNET_CONNECTION_Handle *connection;
334   char addr[128];
335   socklen_t addrlen;
336   struct GNUNET_NETWORK_Handle *sock;
337   int aret;
338   struct sockaddr_in *v4;
339   struct sockaddr_in6 *v6;
340   struct sockaddr *sa;
341   void *uaddr;
342
343 #ifdef SO_PEERCRED
344   struct ucred uc;
345   socklen_t olen;
346 #endif
347   struct GNUNET_CONNECTION_Credentials *gcp;
348 #if HAVE_GETPEEREID || defined(SO_PEERCRED) || HAVE_GETPEERUCRED
349   struct GNUNET_CONNECTION_Credentials gc;
350
351   gc.uid = 0;
352   gc.gid = 0;
353 #endif
354
355   addrlen = sizeof(addr);
356   sock =
357     GNUNET_NETWORK_socket_accept (lsock, (struct sockaddr *) &addr, &addrlen);
358   if (NULL == sock)
359   {
360     if (EAGAIN != errno)
361       LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "accept");
362     return NULL;
363   }
364   if ((addrlen > sizeof(addr)) || (addrlen < sizeof(sa_family_t)))
365   {
366     GNUNET_break (0);
367     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
368     return NULL;
369   }
370
371   sa = (struct sockaddr *) addr;
372   v6 = (struct sockaddr_in6 *) addr;
373   if ((AF_INET6 == sa->sa_family) && (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr)))
374   {
375     /* convert to V4 address */
376     v4 = GNUNET_new (struct sockaddr_in);
377     memset (v4, 0, sizeof(struct sockaddr_in));
378     v4->sin_family = AF_INET;
379 #if HAVE_SOCKADDR_IN_SIN_LEN
380     v4->sin_len = (u_char) sizeof(struct sockaddr_in);
381 #endif
382     GNUNET_memcpy (&v4->sin_addr,
383                    &((char *) &v6->sin6_addr)[sizeof(struct in6_addr)
384                                               - sizeof(struct in_addr)],
385                    sizeof(struct in_addr));
386     v4->sin_port = v6->sin6_port;
387     uaddr = v4;
388     addrlen = sizeof(struct sockaddr_in);
389   }
390   else
391   {
392     uaddr = GNUNET_malloc (addrlen);
393     GNUNET_memcpy (uaddr, addr, addrlen);
394   }
395   gcp = NULL;
396   if (AF_UNIX == sa->sa_family)
397   {
398 #if HAVE_GETPEEREID
399     /* most BSDs */
400     if (0 == getpeereid (GNUNET_NETWORK_get_fd (sock), &gc.uid, &gc.gid))
401       gcp = &gc;
402 #else
403 #ifdef SO_PEERCRED
404     /* largely traditional GNU/Linux */
405     olen = sizeof(uc);
406     if ((0 == getsockopt (GNUNET_NETWORK_get_fd (sock),
407                           SOL_SOCKET,
408                           SO_PEERCRED,
409                           &uc,
410                           &olen)) &&
411         (olen == sizeof(uc)))
412     {
413       gc.uid = uc.uid;
414       gc.gid = uc.gid;
415       gcp = &gc;
416     }
417 #else
418 #if HAVE_GETPEERUCRED
419     /* this is for Solaris 10 */
420     ucred_t *uc;
421
422     uc = NULL;
423     if (0 == getpeerucred (GNUNET_NETWORK_get_fd (sock), &uc))
424     {
425       gc.uid = ucred_geteuid (uc);
426       gc.gid = ucred_getegid (uc);
427       gcp = &gc;
428     }
429     ucred_free (uc);
430 #endif
431 #endif
432 #endif
433   }
434
435   if ((NULL != access_cb) &&
436       (GNUNET_YES != (aret = access_cb (access_cb_cls, gcp, uaddr, addrlen))))
437   {
438     if (GNUNET_NO == aret)
439       LOG (GNUNET_ERROR_TYPE_INFO,
440            _ ("Access denied to `%s'\n"),
441            GNUNET_a2s (uaddr, addrlen));
442     GNUNET_break (GNUNET_OK ==
443                   GNUNET_NETWORK_socket_shutdown (sock, SHUT_RDWR));
444     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
445     GNUNET_free (uaddr);
446     return NULL;
447   }
448   connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
449   connection->write_buffer_size = GNUNET_MIN_MESSAGE_SIZE;
450   connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
451   connection->addr = uaddr;
452   connection->addrlen = addrlen;
453   connection->sock = sock;
454   LOG (GNUNET_ERROR_TYPE_INFO,
455        _ ("Accepting connection from `%s': %p\n"),
456        GNUNET_a2s (uaddr, addrlen),
457        connection);
458   return connection;
459 }
460
461
462 /**
463  * Obtain the network address of the other party.
464  *
465  * @param connection the client to get the address for
466  * @param addr where to store the address
467  * @param addrlen where to store the length of the @a addr
468  * @return #GNUNET_OK on success
469  */
470 int
471 GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *connection,
472                                void **addr,
473                                size_t *addrlen)
474 {
475   if ((NULL == connection->addr) || (0 == connection->addrlen))
476     return GNUNET_NO;
477   *addr = GNUNET_malloc (connection->addrlen);
478   GNUNET_memcpy (*addr, connection->addr, connection->addrlen);
479   *addrlen = connection->addrlen;
480   return GNUNET_OK;
481 }
482
483
484 /**
485  * Tell the receiver callback that we had an IO error.
486  *
487  * @param connection connection to signal error
488  * @param errcode error code to send
489  */
490 static void
491 signal_receive_error (struct GNUNET_CONNECTION_Handle *connection, int errcode)
492 {
493   GNUNET_CONNECTION_Receiver receiver;
494
495   LOG (GNUNET_ERROR_TYPE_DEBUG,
496        "Receive encounters error (%s), connection closed (%p)\n",
497        strerror (errcode),
498        connection);
499   GNUNET_assert (NULL != (receiver = connection->receiver));
500   connection->receiver = NULL;
501   receiver (connection->receiver_cls,
502             NULL,
503             0,
504             connection->addr,
505             connection->addrlen,
506             errcode);
507 }
508
509
510 /**
511  * Tell the receiver callback that a timeout was reached.
512  *
513  * @param connection connection to signal for
514  */
515 static void
516 signal_receive_timeout (struct GNUNET_CONNECTION_Handle *connection)
517 {
518   GNUNET_CONNECTION_Receiver receiver;
519
520   LOG (GNUNET_ERROR_TYPE_DEBUG,
521        "Connection signals timeout to receiver (%p)!\n",
522        connection);
523   GNUNET_assert (NULL != (receiver = connection->receiver));
524   connection->receiver = NULL;
525   receiver (connection->receiver_cls, NULL, 0, NULL, 0, 0);
526 }
527
528
529 /**
530  * We failed to transmit data to the service, signal the error.
531  *
532  * @param connection handle that had trouble
533  * @param ecode error code (errno)
534  */
535 static void
536 signal_transmit_error (struct GNUNET_CONNECTION_Handle *connection, int ecode)
537 {
538   GNUNET_CONNECTION_TransmitReadyNotify notify;
539
540   LOG (GNUNET_ERROR_TYPE_DEBUG,
541        "Transmission encounterd error (%s), connection closed (%p)\n",
542        strerror (ecode),
543        connection);
544   if (NULL != connection->sock)
545   {
546     (void) GNUNET_NETWORK_socket_shutdown (connection->sock, SHUT_RDWR);
547     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (connection->sock));
548     connection->sock = NULL;
549     GNUNET_assert (NULL == connection->write_task);
550   }
551   if (NULL != connection->read_task)
552   {
553     /* send errors trigger read errors... */
554     GNUNET_SCHEDULER_cancel (connection->read_task);
555     connection->read_task = NULL;
556     signal_receive_timeout (connection);
557     return;
558   }
559   if (NULL == connection->nth.notify_ready)
560     return; /* nobody to tell about it */
561   notify = connection->nth.notify_ready;
562   connection->nth.notify_ready = NULL;
563   notify (connection->nth.notify_ready_cls, 0, NULL);
564 }
565
566
567 /**
568  * We've failed for good to establish a connection (timeout or
569  * no more addresses to try).
570  *
571  * @param connection the connection we tried to establish
572  */
573 static void
574 connect_fail_continuation (struct GNUNET_CONNECTION_Handle *connection)
575 {
576   LOG (GNUNET_ERROR_TYPE_INFO,
577        "Failed to establish TCP connection to `%s:%u', no further addresses to try.\n",
578        connection->hostname,
579        connection->port);
580   GNUNET_break (NULL == connection->ap_head);
581   GNUNET_break (NULL == connection->ap_tail);
582   GNUNET_break (GNUNET_NO == connection->dns_active);
583   GNUNET_break (NULL == connection->sock);
584   GNUNET_assert (NULL == connection->write_task);
585   GNUNET_assert (NULL == connection->proxy_handshake);
586
587   /* signal errors for jobs that used to wait on the connection */
588   connection->destroy_later = 1;
589   if (NULL != connection->receiver)
590     signal_receive_error (connection, ECONNREFUSED);
591   if (NULL != connection->nth.notify_ready)
592   {
593     GNUNET_assert (NULL != connection->nth.timeout_task);
594     GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
595     connection->nth.timeout_task = NULL;
596     signal_transmit_error (connection, ECONNREFUSED);
597   }
598   if (-1 == connection->destroy_later)
599   {
600     /* do it now */
601     connection->destroy_later = 0;
602     GNUNET_CONNECTION_destroy (connection);
603     return;
604   }
605   connection->destroy_later = 0;
606 }
607
608
609 /**
610  * We are ready to transmit (or got a timeout).
611  *
612  * @param cls our connection handle
613  */
614 static void
615 transmit_ready (void *cls);
616
617
618 /**
619  * This function is called once we either timeout or have data ready
620  * to read.
621  *
622  * @param cls connection to read from
623  */
624 static void
625 receive_ready (void *cls);
626
627
628 /**
629  * We've succeeded in establishing a connection.
630  *
631  * @param connection the connection we tried to establish
632  */
633 static void
634 connect_success_continuation (struct GNUNET_CONNECTION_Handle *connection)
635 {
636   LOG (GNUNET_ERROR_TYPE_DEBUG,
637        "Connection to `%s' succeeded! (%p)\n",
638        GNUNET_a2s (connection->addr, connection->addrlen),
639        connection);
640   /* trigger jobs that waited for the connection */
641   if (NULL != connection->receiver)
642   {
643     LOG (GNUNET_ERROR_TYPE_DEBUG,
644          "Connection succeeded, starting with receiving data (%p)\n",
645          connection);
646     GNUNET_assert (NULL == connection->read_task);
647     connection->read_task =
648       GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining (
649                                        connection->receive_timeout),
650                                      connection->sock,
651                                      &receive_ready,
652                                      connection);
653   }
654   if (NULL != connection->nth.notify_ready)
655   {
656     LOG (GNUNET_ERROR_TYPE_DEBUG,
657          "Connection succeeded, starting with sending data (%p)\n",
658          connection);
659     GNUNET_assert (connection->nth.timeout_task != NULL);
660     GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
661     connection->nth.timeout_task = NULL;
662     GNUNET_assert (connection->write_task == NULL);
663     connection->write_task =
664       GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining (
665                                         connection->nth.transmit_timeout),
666                                       connection->sock,
667                                       &transmit_ready,
668                                       connection);
669   }
670 }
671
672
673 /**
674  * Scheduler let us know that we're either ready to write on the
675  * socket OR connect timed out.  Do the right thing.
676  *
677  * @param cls the `struct AddressProbe *` with the address that we are probing
678  */
679 static void
680 connect_probe_continuation (void *cls)
681 {
682   struct AddressProbe *ap = cls;
683   struct GNUNET_CONNECTION_Handle *connection = ap->connection;
684   const struct GNUNET_SCHEDULER_TaskContext *tc;
685   struct AddressProbe *pos;
686   int error;
687   socklen_t len;
688
689   GNUNET_assert (NULL != ap->sock);
690   GNUNET_CONTAINER_DLL_remove (connection->ap_head, connection->ap_tail, ap);
691   len = sizeof(error);
692   errno = 0;
693   error = 0;
694   tc = GNUNET_SCHEDULER_get_task_context ();
695   if ((0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ||
696       (GNUNET_OK != GNUNET_NETWORK_socket_getsockopt (ap->sock,
697                                                       SOL_SOCKET,
698                                                       SO_ERROR,
699                                                       &error,
700                                                       &len)) ||
701       (0 != error))
702   {
703     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock));
704     GNUNET_free (ap);
705     if ((NULL == connection->ap_head) &&
706         (GNUNET_NO == connection->dns_active) &&
707         (NULL == connection->proxy_handshake))
708       connect_fail_continuation (connection);
709     return;
710   }
711   GNUNET_assert (NULL == connection->sock);
712   connection->sock = ap->sock;
713   GNUNET_assert (NULL == connection->addr);
714   connection->addr = GNUNET_malloc (ap->addrlen);
715   GNUNET_memcpy (connection->addr, ap->addr, ap->addrlen);
716   connection->addrlen = ap->addrlen;
717   GNUNET_free (ap);
718   /* cancel all other attempts */
719   while (NULL != (pos = connection->ap_head))
720   {
721     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock));
722     GNUNET_SCHEDULER_cancel (pos->task);
723     GNUNET_CONTAINER_DLL_remove (connection->ap_head, connection->ap_tail, pos);
724     GNUNET_free (pos);
725   }
726   connect_success_continuation (connection);
727 }
728
729
730 /**
731  * Try to establish a connection given the specified address.
732  * This function is called by the resolver once we have a DNS reply.
733  *
734  * @param cls our `struct GNUNET_CONNECTION_Handle *`
735  * @param addr address to try, NULL for "last call"
736  * @param addrlen length of @a addr
737  */
738 static void
739 try_connect_using_address (void *cls,
740                            const struct sockaddr *addr,
741                            socklen_t addrlen)
742 {
743   struct GNUNET_CONNECTION_Handle *connection = cls;
744   struct AddressProbe *ap;
745   struct GNUNET_TIME_Relative delay;
746
747   if (NULL == addr)
748   {
749     connection->dns_active = NULL;
750     if ((NULL == connection->ap_head) && (NULL == connection->sock) &&
751         (NULL == connection->proxy_handshake))
752       connect_fail_continuation (connection);
753     return;
754   }
755   if (NULL != connection->sock)
756     return; /* already connected */
757   GNUNET_assert (NULL == connection->addr);
758   /* try to connect */
759   LOG (GNUNET_ERROR_TYPE_DEBUG,
760        "Trying to connect using address `%s:%u/%s:%u'\n",
761        connection->hostname,
762        connection->port,
763        GNUNET_a2s (addr, addrlen),
764        connection->port);
765   ap = GNUNET_malloc (sizeof(struct AddressProbe) + addrlen);
766   ap->addr = (const struct sockaddr *) &ap[1];
767   GNUNET_memcpy (&ap[1], addr, addrlen);
768   ap->addrlen = addrlen;
769   ap->connection = connection;
770
771   switch (ap->addr->sa_family)
772   {
773   case AF_INET:
774     ((struct sockaddr_in *) ap->addr)->sin_port = htons (connection->port);
775     break;
776
777   case AF_INET6:
778     ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (connection->port);
779     break;
780
781   default:
782     GNUNET_break (0);
783     GNUNET_free (ap);
784     return;   /* not supported by us */
785   }
786   ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family, SOCK_STREAM, 0);
787   if (NULL == ap->sock)
788   {
789     GNUNET_free (ap);
790     return;   /* not supported by OS */
791   }
792   LOG (GNUNET_ERROR_TYPE_INFO,
793        "Trying to connect to `%s' (%p)\n",
794        GNUNET_a2s (ap->addr, ap->addrlen),
795        connection);
796   if ((GNUNET_OK !=
797        GNUNET_NETWORK_socket_connect (ap->sock, ap->addr, ap->addrlen)) &&
798       (EINPROGRESS != errno))
799   {
800     /* maybe refused / unsupported address, try next */
801     LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect");
802     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock));
803     GNUNET_free (ap);
804     return;
805   }
806   GNUNET_CONTAINER_DLL_insert (connection->ap_head, connection->ap_tail, ap);
807   delay = CONNECT_RETRY_TIMEOUT;
808   if (NULL != connection->nth.notify_ready)
809     delay = GNUNET_TIME_relative_min (delay,
810                                       GNUNET_TIME_absolute_get_remaining (
811                                         connection->nth.transmit_timeout));
812   if (NULL != connection->receiver)
813     delay = GNUNET_TIME_relative_min (delay,
814                                       GNUNET_TIME_absolute_get_remaining (
815                                         connection->receive_timeout));
816   ap->task = GNUNET_SCHEDULER_add_write_net (delay,
817                                              ap->sock,
818                                              &connect_probe_continuation,
819                                              ap);
820 }
821
822
823 /**
824  * Create a connection handle by (asynchronously) connecting to a host.
825  * This function returns immediately, even if the connection has not
826  * yet been established.  This function only creates TCP connections.
827  *
828  * @param cfg configuration to use
829  * @param hostname name of the host to connect to
830  * @param port port to connect to
831  * @return the connection handle
832  */
833 struct GNUNET_CONNECTION_Handle *
834 GNUNET_CONNECTION_create_from_connect (
835   const struct GNUNET_CONFIGURATION_Handle *cfg,
836   const char *hostname,
837   uint16_t port)
838 {
839   struct GNUNET_CONNECTION_Handle *connection;
840
841   GNUNET_assert (0 < strlen (hostname));   /* sanity check */
842   connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
843   connection->cfg = cfg;
844   connection->write_buffer_size = GNUNET_MIN_MESSAGE_SIZE;
845   connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
846   connection->port = port;
847   connection->hostname = GNUNET_strdup (hostname);
848   connection->dns_active = GNUNET_RESOLVER_ip_get (connection->hostname,
849                                                    AF_UNSPEC,
850                                                    CONNECT_RETRY_TIMEOUT,
851                                                    &try_connect_using_address,
852                                                    connection);
853   return connection;
854 }
855
856
857 /**
858  * Create a connection handle by connecting to a UNIX domain service.
859  * This function returns immediately, even if the connection has not
860  * yet been established.  This function only creates UNIX connections.
861  *
862  * @param cfg configuration to use
863  * @param unixpath path to connect to
864  * @return the connection handle, NULL on systems without UNIX support
865  */
866 struct GNUNET_CONNECTION_Handle *
867 GNUNET_CONNECTION_create_from_connect_to_unixpath (
868   const struct GNUNET_CONFIGURATION_Handle *cfg,
869   const char *unixpath)
870 {
871 #ifdef AF_UNIX
872   struct GNUNET_CONNECTION_Handle *connection;
873   struct sockaddr_un *un;
874
875   GNUNET_assert (0 < strlen (unixpath));   /* sanity check */
876   un = GNUNET_new (struct sockaddr_un);
877   un->sun_family = AF_UNIX;
878   GNUNET_strlcpy (un->sun_path, unixpath, sizeof(un->sun_path));
879 #ifdef __linux__
880   {
881     int abstract;
882
883     abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
884                                                      "TESTING",
885                                                      "USE_ABSTRACT_SOCKETS");
886     if (GNUNET_YES == abstract)
887       un->sun_path[0] = '\0';
888   }
889 #endif
890 #if HAVE_SOCKADDR_UN_SUN_LEN
891   un->sun_len = (u_char) sizeof(struct sockaddr_un);
892 #endif
893   connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
894   connection->cfg = cfg;
895   connection->write_buffer_size = GNUNET_MIN_MESSAGE_SIZE;
896   connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
897   connection->port = 0;
898   connection->hostname = NULL;
899   connection->addr = (struct sockaddr *) un;
900   connection->addrlen = sizeof(struct sockaddr_un);
901   connection->sock = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
902   if (NULL == connection->sock)
903   {
904     GNUNET_free (connection->addr);
905     GNUNET_free (connection->write_buffer);
906     GNUNET_free (connection);
907     return NULL;
908   }
909   if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (connection->sock,
910                                                    connection->addr,
911                                                    connection->addrlen)) &&
912       (EINPROGRESS != errno))
913   {
914     /* Just return; we expect everything to work eventually so don't fail HARD */
915     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (connection->sock));
916     connection->sock = NULL;
917     return connection;
918   }
919   connect_success_continuation (connection);
920   return connection;
921 #else
922   return NULL;
923 #endif
924 }
925
926
927 /**
928  * Create a connection handle by (asynchronously) connecting to a host.
929  * This function returns immediately, even if the connection has not
930  * yet been established.  This function only creates TCP connections.
931  *
932  * @param s socket to connect
933  * @param serv_addr server address
934  * @param addrlen length of @a serv_addr
935  * @return the connection handle
936  */
937 struct GNUNET_CONNECTION_Handle *
938 GNUNET_CONNECTION_connect_socket (struct GNUNET_NETWORK_Handle *s,
939                                   const struct sockaddr *serv_addr,
940                                   socklen_t addrlen)
941 {
942   struct GNUNET_CONNECTION_Handle *connection;
943
944   if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) &&
945       (EINPROGRESS != errno))
946   {
947     /* maybe refused / unsupported address, try next */
948     LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "connect");
949     LOG (GNUNET_ERROR_TYPE_DEBUG,
950          "Attempt to connect to `%s' failed\n",
951          GNUNET_a2s (serv_addr, addrlen));
952     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s));
953     return NULL;
954   }
955   connection = GNUNET_CONNECTION_create_from_existing (s);
956   connection->addr = GNUNET_malloc (addrlen);
957   GNUNET_memcpy (connection->addr, serv_addr, addrlen);
958   connection->addrlen = addrlen;
959   LOG (GNUNET_ERROR_TYPE_INFO,
960        "Trying to connect to `%s' (%p)\n",
961        GNUNET_a2s (serv_addr, addrlen),
962        connection);
963   return connection;
964 }
965
966
967 /**
968  * Create a connection handle by creating a socket and
969  * (asynchronously) connecting to a host.  This function returns
970  * immediately, even if the connection has not yet been established.
971  * This function only creates TCP connections.
972  *
973  * @param af_family address family to use
974  * @param serv_addr server address
975  * @param addrlen length of @a serv_addr
976  * @return the connection handle
977  */
978 struct GNUNET_CONNECTION_Handle *
979 GNUNET_CONNECTION_create_from_sockaddr (int af_family,
980                                         const struct sockaddr *serv_addr,
981                                         socklen_t addrlen)
982 {
983   struct GNUNET_NETWORK_Handle *s;
984
985   s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0);
986   if (NULL == s)
987   {
988     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK, "socket");
989     return NULL;
990   }
991   return GNUNET_CONNECTION_connect_socket (s, serv_addr, addrlen);
992 }
993
994
995 /**
996  * Check if connection is valid (no fatal errors have happened so far).
997  * Note that a connection that is still trying to connect is considered
998  * valid.
999  *
1000  * @param connection connection to check
1001  * @return #GNUNET_YES if valid, #GNUNET_NO otherwise
1002  */
1003 int
1004 GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *connection)
1005 {
1006   if ((NULL != connection->ap_head) || (NULL != connection->dns_active) ||
1007       (NULL != connection->proxy_handshake))
1008     return GNUNET_YES; /* still trying to connect */
1009   if ((0 != connection->destroy_later) || (NULL == connection->sock))
1010     return GNUNET_NO;
1011   return GNUNET_YES;
1012 }
1013
1014
1015 /**
1016  * Close the connection and free associated resources.  There must
1017  * not be any pending requests for reading or writing to the
1018  * connection at this time.
1019  *
1020  * @param connection connection to destroy
1021  */
1022 void
1023 GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection)
1024 {
1025   struct AddressProbe *pos;
1026
1027   if (0 != connection->destroy_later)
1028   {
1029     connection->destroy_later = -1;
1030     return;
1031   }
1032   LOG (GNUNET_ERROR_TYPE_DEBUG, "Shutting down connection (%p)\n", connection);
1033   GNUNET_assert (NULL == connection->nth.notify_ready);
1034   GNUNET_assert (NULL == connection->receiver);
1035   if (NULL != connection->write_task)
1036   {
1037     GNUNET_SCHEDULER_cancel (connection->write_task);
1038     connection->write_task = NULL;
1039     connection->write_buffer_off = 0;
1040   }
1041   if (NULL != connection->read_task)
1042   {
1043     GNUNET_SCHEDULER_cancel (connection->read_task);
1044     connection->read_task = NULL;
1045   }
1046   if (NULL != connection->nth.timeout_task)
1047   {
1048     GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
1049     connection->nth.timeout_task = NULL;
1050   }
1051   connection->nth.notify_ready = NULL;
1052   if (NULL != connection->dns_active)
1053   {
1054     GNUNET_RESOLVER_request_cancel (connection->dns_active);
1055     connection->dns_active = NULL;
1056   }
1057   if (NULL != connection->proxy_handshake)
1058   {
1059     /* GNUNET_CONNECTION_destroy (connection->proxy_handshake); */
1060     connection->proxy_handshake->destroy_later = -1;
1061     connection->proxy_handshake = NULL;   /* Not leaked ??? */
1062   }
1063   while (NULL != (pos = connection->ap_head))
1064   {
1065     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock));
1066     GNUNET_SCHEDULER_cancel (pos->task);
1067     GNUNET_CONTAINER_DLL_remove (connection->ap_head, connection->ap_tail, pos);
1068     GNUNET_free (pos);
1069   }
1070   if ((NULL != connection->sock) && (GNUNET_YES != connection->persist))
1071   {
1072     if ((GNUNET_OK !=
1073          GNUNET_NETWORK_socket_shutdown (connection->sock, SHUT_RDWR)) &&
1074         (ENOTCONN != errno) && (ECONNRESET != errno))
1075       LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "shutdown");
1076   }
1077   if (NULL != connection->sock)
1078   {
1079     if (GNUNET_YES != connection->persist)
1080     {
1081       GNUNET_break (GNUNET_OK ==
1082                     GNUNET_NETWORK_socket_close (connection->sock));
1083     }
1084     else
1085     {
1086       GNUNET_NETWORK_socket_free_memory_only_ (
1087         connection->sock);     /* at least no memory leak (we deliberately
1088                                 * leak the socket in this special case) ... */
1089     }
1090   }
1091   GNUNET_free_non_null (connection->addr);
1092   GNUNET_free_non_null (connection->hostname);
1093   GNUNET_free (connection->write_buffer);
1094   GNUNET_free (connection);
1095 }
1096
1097
1098 /**
1099  * This function is called once we either timeout
1100  * or have data ready to read.
1101  *
1102  * @param cls connection to read from
1103  */
1104 static void
1105 receive_ready (void *cls)
1106 {
1107   struct GNUNET_CONNECTION_Handle *connection = cls;
1108   const struct GNUNET_SCHEDULER_TaskContext *tc;
1109   char buffer[connection->max];
1110   ssize_t ret;
1111   GNUNET_CONNECTION_Receiver receiver;
1112
1113   connection->read_task = NULL;
1114   tc = GNUNET_SCHEDULER_get_task_context ();
1115   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
1116   {
1117     LOG (GNUNET_ERROR_TYPE_DEBUG,
1118          "Receive from `%s' encounters error: timeout (%s, %p)\n",
1119          GNUNET_a2s (connection->addr, connection->addrlen),
1120          GNUNET_STRINGS_relative_time_to_string (
1121            GNUNET_TIME_absolute_get_duration (
1122              connection->receive_timeout),
1123            GNUNET_YES),
1124          connection);
1125     signal_receive_timeout (connection);
1126     return;
1127   }
1128   if (NULL == connection->sock)
1129   {
1130     /* connect failed for good */
1131     signal_receive_error (connection, ECONNREFUSED);
1132     return;
1133   }
1134   GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, connection->sock));
1135 RETRY:
1136   ret = GNUNET_NETWORK_socket_recv (connection->sock, buffer, connection->max);
1137   if (-1 == ret)
1138   {
1139     if (EINTR == errno)
1140       goto RETRY;
1141     signal_receive_error (connection, errno);
1142     return;
1143   }
1144   LOG (GNUNET_ERROR_TYPE_DEBUG,
1145        "receive_ready read %u/%u bytes from `%s' (%p)!\n",
1146        (unsigned int) ret,
1147        connection->max,
1148        GNUNET_a2s (connection->addr, connection->addrlen),
1149        connection);
1150   GNUNET_assert (NULL != (receiver = connection->receiver));
1151   connection->receiver = NULL;
1152   receiver (connection->receiver_cls,
1153             buffer,
1154             ret,
1155             connection->addr,
1156             connection->addrlen,
1157             0);
1158 }
1159
1160
1161 /**
1162  * Receive data from the given connection.  Note that this function
1163  * will call @a receiver asynchronously using the scheduler.  It will
1164  * "immediately" return.  Note that there MUST only be one active
1165  * receive call per connection at any given point in time (so do not
1166  * call receive again until the receiver callback has been invoked).
1167  *
1168  * @param connection connection handle
1169  * @param max maximum number of bytes to read
1170  * @param timeout maximum amount of time to wait
1171  * @param receiver function to call with received data
1172  * @param receiver_cls closure for @a receiver
1173  * @return #GNUNET_SYSERR if @a connection died (receiver was
1174  *          called with error)
1175  */
1176 int
1177 GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *connection,
1178                            size_t max,
1179                            struct GNUNET_TIME_Relative timeout,
1180                            GNUNET_CONNECTION_Receiver receiver,
1181                            void *receiver_cls)
1182 {
1183   GNUNET_assert ((NULL == connection->read_task) &&
1184                  (NULL == connection->receiver));
1185   GNUNET_assert (NULL != receiver);
1186   connection->receiver = receiver;
1187   connection->receiver_cls = receiver_cls;
1188   connection->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout);
1189   connection->max = max;
1190   if (NULL != connection->sock)
1191   {
1192     connection->read_task =
1193       GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining (
1194                                        connection->receive_timeout),
1195                                      connection->sock,
1196                                      &receive_ready,
1197                                      connection);
1198     return GNUNET_OK;
1199   }
1200   if ((NULL == connection->dns_active) && (NULL == connection->ap_head) &&
1201       (NULL == connection->proxy_handshake))
1202   {
1203     connection->receiver = NULL;
1204     receiver (receiver_cls, NULL, 0, NULL, 0, ETIMEDOUT);
1205     return GNUNET_SYSERR;
1206   }
1207   return GNUNET_OK;
1208 }
1209
1210
1211 /**
1212  * Cancel receive job on the given connection.  Note that the
1213  * receiver callback must not have been called yet in order
1214  * for the cancellation to be valid.
1215  *
1216  * @param connection connection handle
1217  * @return closure of the original receiver callback closure
1218  */
1219 void *
1220 GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *connection)
1221 {
1222   if (NULL != connection->read_task)
1223   {
1224     GNUNET_assert (connection ==
1225                    GNUNET_SCHEDULER_cancel (connection->read_task));
1226     connection->read_task = NULL;
1227   }
1228   connection->receiver = NULL;
1229   return connection->receiver_cls;
1230 }
1231
1232
1233 /**
1234  * Try to call the transmit notify method (check if we do
1235  * have enough space available first)!
1236  *
1237  * @param connection connection for which we should do this processing
1238  * @return #GNUNET_YES if we were able to call notify
1239  */
1240 static int
1241 process_notify (struct GNUNET_CONNECTION_Handle *connection)
1242 {
1243   size_t used;
1244   size_t avail;
1245   size_t size;
1246   GNUNET_CONNECTION_TransmitReadyNotify notify;
1247
1248   LOG (GNUNET_ERROR_TYPE_DEBUG, "process_notify is running\n");
1249   GNUNET_assert (NULL == connection->write_task);
1250   if (NULL == (notify = connection->nth.notify_ready))
1251   {
1252     LOG (GNUNET_ERROR_TYPE_DEBUG, "No one to notify\n");
1253     return GNUNET_NO;
1254   }
1255   used = connection->write_buffer_off - connection->write_buffer_pos;
1256   avail = connection->write_buffer_size - used;
1257   size = connection->nth.notify_size;
1258   if (size > avail)
1259   {
1260     LOG (GNUNET_ERROR_TYPE_DEBUG, "Not enough buffer\n");
1261     return GNUNET_NO;
1262   }
1263   connection->nth.notify_ready = NULL;
1264   if (connection->write_buffer_size - connection->write_buffer_off < size)
1265   {
1266     /* need to compact */
1267     memmove (connection->write_buffer,
1268              &connection->write_buffer[connection->write_buffer_pos],
1269              used);
1270     connection->write_buffer_off -= connection->write_buffer_pos;
1271     connection->write_buffer_pos = 0;
1272   }
1273   avail = connection->write_buffer_size - connection->write_buffer_off;
1274   GNUNET_assert (avail >= size);
1275   size = notify (connection->nth.notify_ready_cls,
1276                  avail,
1277                  &connection->write_buffer[connection->write_buffer_off]);
1278   GNUNET_assert (size <= avail);
1279   if (0 != size)
1280     connection->write_buffer_off += size;
1281   return GNUNET_YES;
1282 }
1283
1284
1285 /**
1286  * Task invoked by the scheduler when a call to transmit
1287  * is timing out (we never got enough buffer space to call
1288  * the callback function before the specified timeout
1289  * expired).
1290  *
1291  * This task notifies the client about the timeout.
1292  *
1293  * @param cls the `struct GNUNET_CONNECTION_Handle`
1294  */
1295 static void
1296 transmit_timeout (void *cls)
1297 {
1298   struct GNUNET_CONNECTION_Handle *connection = cls;
1299   GNUNET_CONNECTION_TransmitReadyNotify notify;
1300
1301   connection->nth.timeout_task = NULL;
1302   LOG (GNUNET_ERROR_TYPE_DEBUG,
1303        "Transmit to `%s:%u/%s' fails, time out reached (%p).\n",
1304        connection->hostname,
1305        connection->port,
1306        GNUNET_a2s (connection->addr, connection->addrlen),
1307        connection);
1308   notify = connection->nth.notify_ready;
1309   GNUNET_assert (NULL != notify);
1310   connection->nth.notify_ready = NULL;
1311   notify (connection->nth.notify_ready_cls, 0, NULL);
1312 }
1313
1314
1315 /**
1316  * Task invoked by the scheduler when we failed to connect
1317  * at the time of being asked to transmit.
1318  *
1319  * This task notifies the client about the error.
1320  *
1321  * @param cls the `struct GNUNET_CONNECTION_Handle`
1322  */
1323 static void
1324 connect_error (void *cls)
1325 {
1326   struct GNUNET_CONNECTION_Handle *connection = cls;
1327   GNUNET_CONNECTION_TransmitReadyNotify notify;
1328
1329   LOG (GNUNET_ERROR_TYPE_DEBUG,
1330        "Transmission request of size %u fails (%s/%u), connection failed (%p).\n",
1331        connection->nth.notify_size,
1332        connection->hostname,
1333        connection->port,
1334        connection);
1335   connection->write_task = NULL;
1336   notify = connection->nth.notify_ready;
1337   connection->nth.notify_ready = NULL;
1338   notify (connection->nth.notify_ready_cls, 0, NULL);
1339 }
1340
1341
1342 /**
1343  * We are ready to transmit (or got a timeout).
1344  *
1345  * @param cls our connection handle
1346  */
1347 static void
1348 transmit_ready (void *cls)
1349 {
1350   struct GNUNET_CONNECTION_Handle *connection = cls;
1351   GNUNET_CONNECTION_TransmitReadyNotify notify;
1352   const struct GNUNET_SCHEDULER_TaskContext *tc;
1353   ssize_t ret;
1354   size_t have;
1355
1356   LOG (GNUNET_ERROR_TYPE_DEBUG, "transmit_ready running (%p).\n", connection);
1357   GNUNET_assert (NULL != connection->write_task);
1358   connection->write_task = NULL;
1359   GNUNET_assert (NULL == connection->nth.timeout_task);
1360   tc = GNUNET_SCHEDULER_get_task_context ();
1361   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
1362   {
1363     LOG (GNUNET_ERROR_TYPE_DEBUG,
1364          "Transmit to `%s' fails, time out reached (%p).\n",
1365          GNUNET_a2s (connection->addr, connection->addrlen),
1366          connection);
1367     notify = connection->nth.notify_ready;
1368     GNUNET_assert (NULL != notify);
1369     connection->nth.notify_ready = NULL;
1370     notify (connection->nth.notify_ready_cls, 0, NULL);
1371     return;
1372   }
1373   GNUNET_assert (NULL != connection->sock);
1374   if (NULL == tc->write_ready)
1375   {
1376     /* special circumstances (in particular, PREREQ_DONE after
1377      * connect): not yet ready to write, but no "fatal" error either.
1378      * Hence retry.  */
1379     goto SCHEDULE_WRITE;
1380   }
1381   if (! GNUNET_NETWORK_fdset_isset (tc->write_ready, connection->sock))
1382   {
1383     GNUNET_assert (NULL == connection->write_task);
1384     /* special circumstances (in particular, shutdown): not yet ready
1385      * to write, but no "fatal" error either.  Hence retry.  */
1386     goto SCHEDULE_WRITE;
1387   }
1388   GNUNET_assert (connection->write_buffer_off >= connection->write_buffer_pos);
1389   if ((NULL != connection->nth.notify_ready) &&
1390       (connection->write_buffer_size < connection->nth.notify_size))
1391   {
1392     connection->write_buffer =
1393       GNUNET_realloc (connection->write_buffer, connection->nth.notify_size);
1394     connection->write_buffer_size = connection->nth.notify_size;
1395   }
1396   process_notify (connection);
1397   have = connection->write_buffer_off - connection->write_buffer_pos;
1398   if (0 == have)
1399   {
1400     /* no data ready for writing, terminate write loop */
1401     return;
1402   }
1403   GNUNET_assert (have <= connection->write_buffer_size);
1404   GNUNET_assert (have + connection->write_buffer_pos <=
1405                  connection->write_buffer_size);
1406   GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size);
1407 RETRY:
1408   ret =
1409     GNUNET_NETWORK_socket_send (connection->sock,
1410                                 &connection
1411                                 ->write_buffer[connection->write_buffer_pos],
1412                                 have);
1413   if (-1 == ret)
1414   {
1415     if (EINTR == errno)
1416       goto RETRY;
1417     if (NULL != connection->write_task)
1418     {
1419       GNUNET_SCHEDULER_cancel (connection->write_task);
1420       connection->write_task = NULL;
1421     }
1422     signal_transmit_error (connection, errno);
1423     return;
1424   }
1425   LOG (GNUNET_ERROR_TYPE_DEBUG,
1426        "Connection transmitted %u/%u bytes to `%s' (%p)\n",
1427        (unsigned int) ret,
1428        have,
1429        GNUNET_a2s (connection->addr, connection->addrlen),
1430        connection);
1431   connection->write_buffer_pos += ret;
1432   if (connection->write_buffer_pos == connection->write_buffer_off)
1433   {
1434     /* transmitted all pending data */
1435     connection->write_buffer_pos = 0;
1436     connection->write_buffer_off = 0;
1437   }
1438   if ((0 == connection->write_buffer_off) &&
1439       (NULL == connection->nth.notify_ready))
1440     return; /* all data sent! */
1441   /* not done writing, schedule more */
1442 SCHEDULE_WRITE:
1443   LOG (GNUNET_ERROR_TYPE_DEBUG,
1444        "Re-scheduling transmit_ready (more to do) (%p).\n",
1445        connection);
1446   have = connection->write_buffer_off - connection->write_buffer_pos;
1447   GNUNET_assert ((NULL != connection->nth.notify_ready) || (have > 0));
1448   if (NULL == connection->write_task)
1449     connection->write_task =
1450       GNUNET_SCHEDULER_add_write_net ((connection->nth.notify_ready == NULL)
1451                                       ? GNUNET_TIME_UNIT_FOREVER_REL
1452                                       : GNUNET_TIME_absolute_get_remaining (
1453                                         connection->nth.transmit_timeout),
1454                                       connection->sock,
1455                                       &transmit_ready,
1456                                       connection);
1457 }
1458
1459
1460 /**
1461  * Ask the connection to call us once the specified number of bytes
1462  * are free in the transmission buffer.  Will never call the @a notify
1463  * callback in this task, but always first go into the scheduler.
1464  *
1465  * @param connection connection
1466  * @param size number of bytes to send
1467  * @param timeout after how long should we give up (and call
1468  *        @a notify with buf NULL and size 0)?
1469  * @param notify function to call
1470  * @param notify_cls closure for @a notify
1471  * @return non-NULL if the notify callback was queued,
1472  *         NULL if we are already going to notify someone else (busy)
1473  */
1474 struct GNUNET_CONNECTION_TransmitHandle *
1475 GNUNET_CONNECTION_notify_transmit_ready (
1476   struct GNUNET_CONNECTION_Handle *connection,
1477   size_t size,
1478   struct GNUNET_TIME_Relative timeout,
1479   GNUNET_CONNECTION_TransmitReadyNotify notify,
1480   void *notify_cls)
1481 {
1482   if (NULL != connection->nth.notify_ready)
1483   {
1484     GNUNET_assert (0);
1485     return NULL;
1486   }
1487   GNUNET_assert (NULL != notify);
1488   GNUNET_assert (size < GNUNET_MAX_MESSAGE_SIZE);
1489   GNUNET_assert (connection->write_buffer_off <= connection->write_buffer_size);
1490   GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size);
1491   GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_off);
1492   connection->nth.notify_ready = notify;
1493   connection->nth.notify_ready_cls = notify_cls;
1494   connection->nth.connection = connection;
1495   connection->nth.notify_size = size;
1496   connection->nth.transmit_timeout = GNUNET_TIME_relative_to_absolute (timeout);
1497   GNUNET_assert (NULL == connection->nth.timeout_task);
1498   if ((NULL == connection->sock) && (NULL == connection->ap_head) &&
1499       (NULL == connection->dns_active) && (NULL == connection->proxy_handshake))
1500   {
1501     if (NULL != connection->write_task)
1502       GNUNET_SCHEDULER_cancel (connection->write_task);
1503     connection->write_task =
1504       GNUNET_SCHEDULER_add_now (&connect_error, connection);
1505     return &connection->nth;
1506   }
1507   if (NULL != connection->write_task)
1508     return &connection->nth; /* previous transmission still in progress */
1509   if (NULL != connection->sock)
1510   {
1511     /* connected, try to transmit now */
1512     LOG (GNUNET_ERROR_TYPE_DEBUG,
1513          "Scheduling transmission (%p).\n",
1514          connection);
1515     connection->write_task =
1516       GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining (
1517                                         connection->nth.transmit_timeout),
1518                                       connection->sock,
1519                                       &transmit_ready,
1520                                       connection);
1521     return &connection->nth;
1522   }
1523   /* not yet connected, wait for connection */
1524   LOG (GNUNET_ERROR_TYPE_DEBUG,
1525        "Need to wait to schedule transmission for connection, adding timeout task (%p).\n",
1526        connection);
1527   connection->nth.timeout_task =
1528     GNUNET_SCHEDULER_add_delayed (timeout, &transmit_timeout, connection);
1529   return &connection->nth;
1530 }
1531
1532
1533 /**
1534  * Cancel the specified transmission-ready notification.
1535  *
1536  * @param th notification to cancel
1537  */
1538 void
1539 GNUNET_CONNECTION_notify_transmit_ready_cancel (
1540   struct GNUNET_CONNECTION_TransmitHandle *th)
1541 {
1542   GNUNET_assert (NULL != th->notify_ready);
1543   th->notify_ready = NULL;
1544   if (NULL != th->timeout_task)
1545   {
1546     GNUNET_SCHEDULER_cancel (th->timeout_task);
1547     th->timeout_task = NULL;
1548   }
1549   if (NULL != th->connection->write_task)
1550   {
1551     GNUNET_SCHEDULER_cancel (th->connection->write_task);
1552     th->connection->write_task = NULL;
1553   }
1554 }
1555
1556
1557 /**
1558  * Create a connection to be proxied using a given connection.
1559  *
1560  * @param cph connection to proxy server
1561  * @return connection to be proxied
1562  */
1563 struct GNUNET_CONNECTION_Handle *
1564 GNUNET_CONNECTION_create_proxied_from_handshake (
1565   struct GNUNET_CONNECTION_Handle *cph)
1566 {
1567   struct GNUNET_CONNECTION_Handle *proxied =
1568     GNUNET_CONNECTION_create_from_existing (NULL);
1569
1570   proxied->proxy_handshake = cph;
1571   return proxied;
1572 }
1573
1574
1575 /**
1576  * Activate proxied connection and destroy initial proxy handshake connection.
1577  * There must not be any pending requests for reading or writing to the
1578  * proxy hadshake connection at this time.
1579  *
1580  * @param proxied connection connection to proxy server
1581  */
1582 void
1583 GNUNET_CONNECTION_acivate_proxied (struct GNUNET_CONNECTION_Handle *proxied)
1584 {
1585   struct GNUNET_CONNECTION_Handle *cph = proxied->proxy_handshake;
1586
1587   GNUNET_assert (NULL != cph);
1588   GNUNET_assert (NULL == proxied->sock);
1589   GNUNET_assert (NULL != cph->sock);
1590   proxied->sock = cph->sock;
1591   cph->sock = NULL;
1592   GNUNET_CONNECTION_destroy (cph);
1593   connect_success_continuation (proxied);
1594 }
1595
1596
1597 /* end of connection.c */