f5253445da20b473df570f627d442e4a929e5d48
[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
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.
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      General Public License for more details.
14
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.
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 #define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-connection", syscall)
40
41
42 /**
43  * Transmission handle.  There can only be one for each connection.
44  */
45 struct GNUNET_CONNECTION_TransmitHandle
46 {
47
48   /**
49    * Function to call if the send buffer has notify_size
50    * bytes available.
51    */
52   GNUNET_CONNECTION_TransmitReadyNotify notify_ready;
53
54   /**
55    * Closure for notify_ready.
56    */
57   void *notify_ready_cls;
58
59   /**
60    * Our connection handle.
61    */
62   struct GNUNET_CONNECTION_Handle *connection;
63
64   /**
65    * Timeout for receiving (in absolute time).
66    */
67   struct GNUNET_TIME_Absolute transmit_timeout;
68
69   /**
70    * Task called on timeout.
71    */
72   struct GNUNET_SCHEDULER_Task * timeout_task;
73
74   /**
75    * At what number of bytes available in the
76    * write buffer should the notify method be called?
77    */
78   size_t notify_size;
79
80 };
81
82
83 /**
84  * During connect, we try multiple possible IP addresses
85  * to find out which one might work.
86  */
87 struct AddressProbe
88 {
89
90   /**
91    * This is a linked list.
92    */
93   struct AddressProbe *next;
94
95   /**
96    * This is a doubly-linked list.
97    */
98   struct AddressProbe *prev;
99
100   /**
101    * The address; do not free (allocated at the end of this struct).
102    */
103   const struct sockaddr *addr;
104
105   /**
106    * Underlying OS's socket.
107    */
108   struct GNUNET_NETWORK_Handle *sock;
109
110   /**
111    * Connection for which we are probing.
112    */
113   struct GNUNET_CONNECTION_Handle *connection;
114
115   /**
116    * Lenth of addr.
117    */
118   socklen_t addrlen;
119
120   /**
121    * Task waiting for the connection to finish connecting.
122    */
123   struct GNUNET_SCHEDULER_Task * task;
124 };
125
126
127 /**
128  * @brief handle for a network connection
129  */
130 struct GNUNET_CONNECTION_Handle
131 {
132
133   /**
134    * Configuration to use.
135    */
136   const struct GNUNET_CONFIGURATION_Handle *cfg;
137
138   /**
139    * Linked list of sockets we are currently trying out
140    * (during connect).
141    */
142   struct AddressProbe *ap_head;
143
144   /**
145    * Linked list of sockets we are currently trying out
146    * (during connect).
147    */
148   struct AddressProbe *ap_tail;
149
150   /**
151    * Network address of the other end-point, may be NULL.
152    */
153   struct sockaddr *addr;
154
155   /**
156    * Pointer to the hostname if connection was
157    * created using DNS lookup, otherwise NULL.
158    */
159   char *hostname;
160
161   /**
162    * Underlying OS's socket, set to NULL after fatal errors.
163    */
164   struct GNUNET_NETWORK_Handle *sock;
165
166   /**
167    * Function to call on data received, NULL if no receive is pending.
168    */
169   GNUNET_CONNECTION_Receiver receiver;
170
171   /**
172    * Closure for @e receiver.
173    */
174   void *receiver_cls;
175
176   /**
177    * Pointer to our write buffer.
178    */
179   char *write_buffer;
180
181   /**
182    * Current size of our @e write_buffer.
183    */
184   size_t write_buffer_size;
185
186   /**
187    * Current write-offset in @e write_buffer (where
188    * would we write next).
189    */
190   size_t write_buffer_off;
191
192   /**
193    * Current read-offset in @e write_buffer (how many
194    * bytes have already been sent).
195    */
196   size_t write_buffer_pos;
197
198   /**
199    * Length of @e addr.
200    */
201   socklen_t addrlen;
202
203   /**
204    * Read task that we may need to wait for.
205    */
206   struct GNUNET_SCHEDULER_Task *read_task;
207
208   /**
209    * Write task that we may need to wait for.
210    */
211   struct GNUNET_SCHEDULER_Task *write_task;
212
213   /**
214    * Handle to a pending DNS lookup request.
215    */
216   struct GNUNET_RESOLVER_RequestHandle *dns_active;
217
218   /**
219    * The handle we return for #GNUNET_CONNECTION_notify_transmit_ready().
220    */
221   struct GNUNET_CONNECTION_TransmitHandle nth;
222
223   /**
224    * Timeout for receiving (in absolute time).
225    */
226   struct GNUNET_TIME_Absolute receive_timeout;
227
228   /**
229    * Maximum number of bytes to read (for receiving).
230    */
231   size_t max;
232
233   /**
234    * Port to connect to.
235    */
236   uint16_t port;
237
238   /**
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
242    * socket be freed!)
243    */
244   int8_t persist;
245
246   /**
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.
250    */
251   int8_t destroy_later;
252
253   /**
254    * Handle to subsequent connection after proxy handshake completes,
255    */
256   struct GNUNET_CONNECTION_Handle *proxy_handshake;
257
258 };
259
260
261 /**
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.
265  *
266  * @param connection the connection to set persistent
267  */
268 void
269 GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *connection)
270 {
271   connection->persist = GNUNET_YES;
272 }
273
274
275 /**
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.
282  *
283  * @param connection the connection to make flushing and blocking
284  * @return #GNUNET_OK on success
285  */
286 int
287 GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection)
288 {
289   return GNUNET_NETWORK_socket_disable_corking (connection->sock);
290 }
291
292
293 /**
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.
297  *
298  * @param osSocket existing socket to box
299  * @return the boxed connection handle
300  */
301 struct GNUNET_CONNECTION_Handle *
302 GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket)
303 {
304   struct GNUNET_CONNECTION_Handle *connection;
305
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;
310   return connection;
311 }
312
313
314 /**
315  * Create a connection handle by accepting on a listen socket.  This
316  * function may block if the listen socket has no connection ready.
317  *
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
322  */
323 struct GNUNET_CONNECTION_Handle *
324 GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access_cb,
325                                       void *access_cb_cls,
326                                       struct GNUNET_NETWORK_Handle *lsock)
327 {
328   struct GNUNET_CONNECTION_Handle *connection;
329   char addr[128];
330   socklen_t addrlen;
331   struct GNUNET_NETWORK_Handle *sock;
332   int aret;
333   struct sockaddr_in *v4;
334   struct sockaddr_in6 *v6;
335   struct sockaddr *sa;
336   void *uaddr;
337 #ifdef SO_PEERCRED
338   struct ucred uc;
339   socklen_t olen;
340 #endif
341   struct GNUNET_CONNECTION_Credentials *gcp;
342 #if HAVE_GETPEEREID || defined(SO_PEERCRED) || HAVE_GETPEERUCRED
343   struct GNUNET_CONNECTION_Credentials gc;
344
345   gc.uid = 0;
346   gc.gid = 0;
347 #endif
348
349   addrlen = sizeof (addr);
350   sock =
351       GNUNET_NETWORK_socket_accept (lsock,
352                                     (struct sockaddr *) &addr,
353                                     &addrlen);
354   if (NULL == sock)
355   {
356     if (EAGAIN != errno)
357       LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "accept");
358     return NULL;
359   }
360   if ((addrlen > sizeof (addr)) || (addrlen < sizeof (sa_family_t)))
361   {
362     GNUNET_break (0);
363     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
364     return NULL;
365   }
366
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)) )
371   {
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);
378 #endif
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;
384     uaddr = v4;
385     addrlen = sizeof (struct sockaddr_in);
386   }
387   else
388   {
389     uaddr = GNUNET_malloc (addrlen);
390     GNUNET_memcpy (uaddr, addr, addrlen);
391   }
392   gcp = NULL;
393   if (AF_UNIX == sa->sa_family)
394   {
395 #if HAVE_GETPEEREID
396     /* most BSDs */
397     if (0 == getpeereid (GNUNET_NETWORK_get_fd (sock),
398                          &gc.uid,
399                          &gc.gid))
400       gcp = &gc;
401 #else
402 #ifdef SO_PEERCRED
403     /* largely traditional GNU/Linux */
404     olen = sizeof (uc);
405     if ( (0 ==
406           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,
437                                          gcp,
438                                          uaddr,
439                                          addrlen))) )
440   {
441     if (GNUNET_NO == aret)
442       LOG (GNUNET_ERROR_TYPE_INFO,
443            _("Access denied to `%s'\n"),
444            GNUNET_a2s (uaddr,
445                        addrlen));
446     GNUNET_break (GNUNET_OK ==
447                   GNUNET_NETWORK_socket_shutdown (sock,
448                                                   SHUT_RDWR));
449     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
450     GNUNET_free (uaddr);
451     return NULL;
452   }
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"),
461        GNUNET_a2s (uaddr,
462                    addrlen),
463        connection);
464   return connection;
465 }
466
467
468 /**
469  * Obtain the network address of the other party.
470  *
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
475  */
476 int
477 GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *connection,
478                                void **addr,
479                                size_t *addrlen)
480 {
481   if ((NULL == connection->addr) || (0 == connection->addrlen))
482     return GNUNET_NO;
483   *addr = GNUNET_malloc (connection->addrlen);
484   GNUNET_memcpy (*addr, connection->addr, connection->addrlen);
485   *addrlen = connection->addrlen;
486   return GNUNET_OK;
487 }
488
489
490 /**
491  * Tell the receiver callback that we had an IO error.
492  *
493  * @param connection connection to signal error
494  * @param errcode error code to send
495  */
496 static void
497 signal_receive_error (struct GNUNET_CONNECTION_Handle *connection,
498                       int errcode)
499 {
500   GNUNET_CONNECTION_Receiver receiver;
501
502   LOG (GNUNET_ERROR_TYPE_DEBUG,
503        "Receive encounters error (%s), connection closed (%p)\n",
504        STRERROR (errcode),
505        connection);
506   GNUNET_assert (NULL != (receiver = connection->receiver));
507   connection->receiver = NULL;
508   receiver (connection->receiver_cls,
509             NULL,
510             0,
511             connection->addr,
512             connection->addrlen,
513             errcode);
514 }
515
516
517 /**
518  * Tell the receiver callback that a timeout was reached.
519  *
520  * @param connection connection to signal for
521  */
522 static void
523 signal_receive_timeout (struct GNUNET_CONNECTION_Handle *connection)
524 {
525   GNUNET_CONNECTION_Receiver receiver;
526
527   LOG (GNUNET_ERROR_TYPE_DEBUG,
528        "Connection signals timeout to receiver (%p)!\n",
529        connection);
530   GNUNET_assert (NULL != (receiver = connection->receiver));
531   connection->receiver = NULL;
532   receiver (connection->receiver_cls, NULL, 0, NULL, 0, 0);
533 }
534
535
536 /**
537  * We failed to transmit data to the service, signal the error.
538  *
539  * @param connection handle that had trouble
540  * @param ecode error code (errno)
541  */
542 static void
543 signal_transmit_error (struct GNUNET_CONNECTION_Handle *connection,
544                        int ecode)
545 {
546   GNUNET_CONNECTION_TransmitReadyNotify notify;
547
548   LOG (GNUNET_ERROR_TYPE_DEBUG,
549        "Transmission encounterd error (%s), connection closed (%p)\n",
550        STRERROR (ecode),
551        connection);
552   if (NULL != connection->sock)
553   {
554     (void) GNUNET_NETWORK_socket_shutdown (connection->sock,
555                                            SHUT_RDWR);
556     GNUNET_break (GNUNET_OK ==
557                   GNUNET_NETWORK_socket_close (connection->sock));
558     connection->sock = NULL;
559     GNUNET_assert (NULL == connection->write_task);
560   }
561   if (NULL != connection->read_task)
562   {
563     /* send errors trigger read errors... */
564     GNUNET_SCHEDULER_cancel (connection->read_task);
565     connection->read_task = NULL;
566     signal_receive_timeout (connection);
567     return;
568   }
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,
574           0,
575           NULL);
576 }
577
578
579 /**
580  * We've failed for good to establish a connection (timeout or
581  * no more addresses to try).
582  *
583  * @param connection the connection we tried to establish
584  */
585 static void
586 connect_fail_continuation (struct GNUNET_CONNECTION_Handle *connection)
587 {
588   LOG (GNUNET_ERROR_TYPE_INFO,
589        "Failed to establish TCP connection to `%s:%u', no further addresses to try.\n",
590        connection->hostname,
591     connection->port);
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);
598
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,
603                           ECONNREFUSED);
604   if (NULL != connection->nth.notify_ready)
605   {
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,
610                            ECONNREFUSED);
611   }
612   if (-1 == connection->destroy_later)
613   {
614     /* do it now */
615     connection->destroy_later = 0;
616     GNUNET_CONNECTION_destroy (connection);
617     return;
618   }
619   connection->destroy_later = 0;
620 }
621
622
623 /**
624  * We are ready to transmit (or got a timeout).
625  *
626  * @param cls our connection handle
627  */
628 static void
629 transmit_ready (void *cls);
630
631
632 /**
633  * This function is called once we either timeout or have data ready
634  * to read.
635  *
636  * @param cls connection to read from
637  */
638 static void
639 receive_ready (void *cls);
640
641
642 /**
643  * We've succeeded in establishing a connection.
644  *
645  * @param connection the connection we tried to establish
646  */
647 static void
648 connect_success_continuation (struct GNUNET_CONNECTION_Handle *connection)
649 {
650   LOG (GNUNET_ERROR_TYPE_DEBUG,
651        "Connection to `%s' succeeded! (%p)\n",
652        GNUNET_a2s (connection->addr,
653                    connection->addrlen),
654        connection);
655   /* trigger jobs that waited for the connection */
656   if (NULL != connection->receiver)
657   {
658     LOG (GNUNET_ERROR_TYPE_DEBUG,
659          "Connection succeeded, starting with receiving data (%p)\n",
660          connection);
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),
665                                      connection->sock,
666                                      &receive_ready, connection);
667   }
668   if (NULL != connection->nth.notify_ready)
669   {
670     LOG (GNUNET_ERROR_TYPE_DEBUG,
671          "Connection succeeded, starting with sending data (%p)\n",
672          connection);
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);
681   }
682 }
683
684
685 /**
686  * Scheduler let us know that we're either ready to write on the
687  * socket OR connect timed out.  Do the right thing.
688  *
689  * @param cls the `struct AddressProbe *` with the address that we are probing
690  */
691 static void
692 connect_probe_continuation (void *cls)
693 {
694   struct AddressProbe *ap = cls;
695   struct GNUNET_CONNECTION_Handle *connection = ap->connection;
696   const struct GNUNET_SCHEDULER_TaskContext *tc;
697   struct AddressProbe *pos;
698   int error;
699   socklen_t len;
700
701   GNUNET_assert (NULL != ap->sock);
702   GNUNET_CONTAINER_DLL_remove (connection->ap_head,
703                                connection->ap_tail,
704                                ap);
705   len = sizeof (error);
706   errno = 0;
707   error = 0;
708   tc = GNUNET_SCHEDULER_get_task_context ();
709   if ( (0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ||
710        (GNUNET_OK !=
711         GNUNET_NETWORK_socket_getsockopt (ap->sock,
712                                           SOL_SOCKET,
713                                           SO_ERROR,
714                                           &error,
715                                           &len)) ||
716        (0 != error) )
717   {
718     GNUNET_break (GNUNET_OK ==
719                   GNUNET_NETWORK_socket_close (ap->sock));
720     GNUNET_free (ap);
721     if ( (NULL == connection->ap_head) &&
722          (GNUNET_NO == connection->dns_active) &&
723          (NULL == connection->proxy_handshake) )
724       connect_fail_continuation (connection);
725     return;
726   }
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;
733   GNUNET_free (ap);
734   /* cancel all other attempts */
735   while (NULL != (pos = connection->ap_head))
736   {
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,
740                                  connection->ap_tail,
741                                  pos);
742     GNUNET_free (pos);
743   }
744   connect_success_continuation (connection);
745 }
746
747
748 /**
749  * Try to establish a connection given the specified address.
750  * This function is called by the resolver once we have a DNS reply.
751  *
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
755  */
756 static void
757 try_connect_using_address (void *cls,
758                            const struct sockaddr *addr,
759                            socklen_t addrlen)
760 {
761   struct GNUNET_CONNECTION_Handle *connection = cls;
762   struct AddressProbe *ap;
763   struct GNUNET_TIME_Relative delay;
764
765   if (NULL == addr)
766   {
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);
772     return;
773   }
774   if (NULL != connection->sock)
775     return;                     /* already connected */
776   GNUNET_assert (NULL == connection->addr);
777   /* try to connect */
778   LOG (GNUNET_ERROR_TYPE_DEBUG,
779        "Trying to connect using address `%s:%u/%s:%u'\n",
780        connection->hostname,
781        connection->port,
782        GNUNET_a2s (addr, addrlen),
783        connection->port);
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;
789
790   switch (ap->addr->sa_family)
791   {
792   case AF_INET:
793     ((struct sockaddr_in *) ap->addr)->sin_port = htons (connection->port);
794     break;
795   case AF_INET6:
796     ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (connection->port);
797     break;
798   default:
799     GNUNET_break (0);
800     GNUNET_free (ap);
801     return;                     /* not supported by us */
802   }
803   ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family,
804                                            SOCK_STREAM, 0);
805   if (NULL == ap->sock)
806   {
807     GNUNET_free (ap);
808     return;                     /* not supported by OS */
809   }
810   LOG (GNUNET_ERROR_TYPE_INFO,
811        "Trying to connect to `%s' (%p)\n",
812        GNUNET_a2s (ap->addr, ap->addrlen),
813        connection);
814   if ((GNUNET_OK !=
815        GNUNET_NETWORK_socket_connect (ap->sock,
816                                       ap->addr,
817                                       ap->addrlen)) &&
818       (EINPROGRESS != errno))
819   {
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));
823     GNUNET_free (ap);
824     return;
825   }
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,
835                                              ap->sock,
836                                              &connect_probe_continuation,
837                                              ap);
838 }
839
840
841 /**
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.
845  *
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
850  */
851 struct GNUNET_CONNECTION_Handle *
852 GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
853                                        const char *hostname,
854                                        uint16_t port)
855 {
856   struct GNUNET_CONNECTION_Handle *connection;
857
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,
867                               AF_UNSPEC,
868                               GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT,
869                               &try_connect_using_address,
870                               connection);
871   return connection;
872 }
873
874
875 /**
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.
879  *
880  * @param cfg configuration to use
881  * @param unixpath path to connect to
882  * @return the connection handle, NULL on systems without UNIX support
883  */
884 struct GNUNET_CONNECTION_Handle *
885 GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct GNUNET_CONFIGURATION_Handle *cfg,
886                                                    const char *unixpath)
887 {
888 #ifdef AF_UNIX
889   struct GNUNET_CONNECTION_Handle *connection;
890   struct sockaddr_un *un;
891
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);
896 #ifdef LINUX
897   {
898     int abstract;
899
900     abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
901                                                      "TESTING",
902                                                      "USE_ABSTRACT_SOCKETS");
903     if (GNUNET_YES == abstract)
904       un->sun_path[0] = '\0';
905   }
906 #endif
907 #if HAVE_SOCKADDR_UN_SUN_LEN
908   un->sun_len = (u_char) sizeof (struct sockaddr_un);
909 #endif
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,
919                                                    SOCK_STREAM,
920                                                    0);
921   if (NULL == connection->sock)
922   {
923     GNUNET_free (connection->addr);
924     GNUNET_free (connection->write_buffer);
925     GNUNET_free (connection);
926     return NULL;
927   }
928   if ( (GNUNET_OK !=
929         GNUNET_NETWORK_socket_connect (connection->sock,
930                                        connection->addr,
931                                        connection->addrlen)) &&
932        (EINPROGRESS != errno) )
933   {
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;
938     return connection;
939   }
940   connect_success_continuation (connection);
941   return connection;
942 #else
943   return NULL;
944 #endif
945 }
946
947
948 /**
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.
952  *
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
957  */
958 struct GNUNET_CONNECTION_Handle *
959 GNUNET_CONNECTION_connect_socket (struct GNUNET_NETWORK_Handle *s,
960                                   const struct sockaddr *serv_addr,
961                                   socklen_t addrlen)
962 {
963   struct GNUNET_CONNECTION_Handle *connection;
964
965   if ( (GNUNET_OK !=
966         GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) &&
967        (EINPROGRESS != errno) )
968   {
969     /* maybe refused / unsupported address, try next */
970     LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG,
971                   "connect");
972     LOG (GNUNET_ERROR_TYPE_DEBUG,
973          "Attempt to connect to `%s' failed\n",
974          GNUNET_a2s (serv_addr,
975                      addrlen));
976     GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s));
977     return NULL;
978   }
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),
986        connection);
987   return connection;
988 }
989
990
991 /**
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.
996  *
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
1001  */
1002 struct GNUNET_CONNECTION_Handle *
1003 GNUNET_CONNECTION_create_from_sockaddr (int af_family,
1004                                         const struct sockaddr *serv_addr,
1005                                         socklen_t addrlen)
1006 {
1007   struct GNUNET_NETWORK_Handle *s;
1008
1009   s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0);
1010   if (NULL == s)
1011   {
1012     LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
1013                   "socket");
1014     return NULL;
1015   }
1016   return GNUNET_CONNECTION_connect_socket (s,
1017                                            serv_addr,
1018                                            addrlen);
1019 }
1020
1021
1022 /**
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
1025  * valid.
1026  *
1027  * @param connection connection to check
1028  * @return #GNUNET_YES if valid, #GNUNET_NO otherwise
1029  */
1030 int
1031 GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *connection)
1032 {
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) )
1039     return GNUNET_NO;
1040   return GNUNET_YES;
1041 }
1042
1043
1044 /**
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.
1048  *
1049  * @param connection connection to destroy
1050  */
1051 void
1052 GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection)
1053 {
1054   struct AddressProbe *pos;
1055
1056   if (0 != connection->destroy_later)
1057   {
1058     connection->destroy_later = -1;
1059     return;
1060   }
1061   LOG (GNUNET_ERROR_TYPE_DEBUG,
1062        "Shutting down connection (%p)\n",
1063        connection);
1064   GNUNET_assert (NULL == connection->nth.notify_ready);
1065   GNUNET_assert (NULL == connection->receiver);
1066   if (NULL != connection->write_task)
1067   {
1068     GNUNET_SCHEDULER_cancel (connection->write_task);
1069     connection->write_task = NULL;
1070     connection->write_buffer_off = 0;
1071   }
1072   if (NULL != connection->read_task)
1073   {
1074     GNUNET_SCHEDULER_cancel (connection->read_task);
1075     connection->read_task = NULL;
1076   }
1077   if (NULL != connection->nth.timeout_task)
1078   {
1079     GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
1080     connection->nth.timeout_task = NULL;
1081   }
1082   connection->nth.notify_ready = NULL;
1083   if (NULL != connection->dns_active)
1084   {
1085     GNUNET_RESOLVER_request_cancel (connection->dns_active);
1086     connection->dns_active = NULL;
1087   }
1088   if (NULL != connection->proxy_handshake)
1089   {
1090     /* GNUNET_CONNECTION_destroy (connection->proxy_handshake); */
1091     connection->proxy_handshake->destroy_later = -1;
1092     connection->proxy_handshake = NULL;  /* Not leaked ??? */
1093   }
1094   while (NULL != (pos = connection->ap_head))
1095   {
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,
1100                                  pos);
1101     GNUNET_free (pos);
1102   }
1103   if ( (NULL != connection->sock) &&
1104        (GNUNET_YES != connection->persist) )
1105   {
1106     if ((GNUNET_OK !=
1107          GNUNET_NETWORK_socket_shutdown (connection->sock,
1108                                          SHUT_RDWR)) &&
1109         (ENOTCONN != errno) &&
1110         (ECONNRESET != errno) )
1111       LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
1112                     "shutdown");
1113   }
1114   if (NULL != connection->sock)
1115   {
1116     if (GNUNET_YES != connection->persist)
1117     {
1118       GNUNET_break (GNUNET_OK ==
1119                     GNUNET_NETWORK_socket_close (connection->sock));
1120     }
1121     else
1122     {
1123       GNUNET_NETWORK_socket_free_memory_only_ (connection->sock); /* at least no memory leak (we deliberately
1124                                                                    * leak the socket in this special case) ... */
1125     }
1126   }
1127   GNUNET_free_non_null (connection->addr);
1128   GNUNET_free_non_null (connection->hostname);
1129   GNUNET_free (connection->write_buffer);
1130   GNUNET_free (connection);
1131 }
1132
1133
1134 /**
1135  * This function is called once we either timeout
1136  * or have data ready to read.
1137  *
1138  * @param cls connection to read from
1139  */
1140 static void
1141 receive_ready (void *cls)
1142 {
1143   struct GNUNET_CONNECTION_Handle *connection = cls;
1144   const struct GNUNET_SCHEDULER_TaskContext *tc;
1145   char buffer[connection->max];
1146   ssize_t ret;
1147   GNUNET_CONNECTION_Receiver receiver;
1148
1149   connection->read_task = NULL;
1150   tc = GNUNET_SCHEDULER_get_task_context ();
1151   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
1152   {
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),
1158                                                  GNUNET_YES),
1159          connection);
1160     signal_receive_timeout (connection);
1161     return;
1162   }
1163   if (NULL == connection->sock)
1164   {
1165     /* connect failed for good */
1166     signal_receive_error (connection, ECONNREFUSED);
1167     return;
1168   }
1169   GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready,
1170                                              connection->sock));
1171 RETRY:
1172   ret = GNUNET_NETWORK_socket_recv (connection->sock,
1173                                     buffer,
1174                                     connection->max);
1175   if (-1 == ret)
1176   {
1177     if (EINTR == errno)
1178       goto RETRY;
1179     signal_receive_error (connection, errno);
1180     return;
1181   }
1182   LOG (GNUNET_ERROR_TYPE_DEBUG,
1183        "receive_ready read %u/%u bytes from `%s' (%p)!\n",
1184        (unsigned int) ret,
1185        connection->max,
1186        GNUNET_a2s (connection->addr,
1187                    connection->addrlen),
1188        connection);
1189   GNUNET_assert (NULL != (receiver = connection->receiver));
1190   connection->receiver = NULL;
1191   receiver (connection->receiver_cls,
1192             buffer,
1193             ret,
1194             connection->addr,
1195             connection->addrlen,
1196             0);
1197 }
1198
1199
1200 /**
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).
1206  *
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
1212  */
1213 void
1214 GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *connection,
1215                            size_t max,
1216                            struct GNUNET_TIME_Relative timeout,
1217                            GNUNET_CONNECTION_Receiver receiver,
1218                            void *receiver_cls)
1219 {
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)
1228   {
1229     connection->read_task =
1230       GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining
1231                                      (connection->receive_timeout),
1232                                      connection->sock,
1233                                      &receive_ready,
1234                                      connection);
1235     return;
1236   }
1237   if ((NULL == connection->dns_active) &&
1238       (NULL == connection->ap_head) &&
1239       (NULL == connection->proxy_handshake))
1240   {
1241     connection->receiver = NULL;
1242     receiver (receiver_cls,
1243               NULL, 0,
1244               NULL, 0,
1245               ETIMEDOUT);
1246     return;
1247   }
1248 }
1249
1250
1251 /**
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.
1255  *
1256  * @param connection connection handle
1257  * @return closure of the original receiver callback closure
1258  */
1259 void *
1260 GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *connection)
1261 {
1262   if (NULL != connection->read_task)
1263   {
1264     GNUNET_assert (connection ==
1265                    GNUNET_SCHEDULER_cancel (connection->read_task));
1266     connection->read_task = NULL;
1267   }
1268   connection->receiver = NULL;
1269   return connection->receiver_cls;
1270 }
1271
1272
1273 /**
1274  * Try to call the transmit notify method (check if we do
1275  * have enough space available first)!
1276  *
1277  * @param connection connection for which we should do this processing
1278  * @return #GNUNET_YES if we were able to call notify
1279  */
1280 static int
1281 process_notify (struct GNUNET_CONNECTION_Handle *connection)
1282 {
1283   size_t used;
1284   size_t avail;
1285   size_t size;
1286   GNUNET_CONNECTION_TransmitReadyNotify notify;
1287
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))
1292   {
1293     LOG (GNUNET_ERROR_TYPE_DEBUG,
1294          "No one to notify\n");
1295     return GNUNET_NO;
1296   }
1297   used = connection->write_buffer_off - connection->write_buffer_pos;
1298   avail = connection->write_buffer_size - used;
1299   size = connection->nth.notify_size;
1300   if (size > avail)
1301   {
1302     LOG (GNUNET_ERROR_TYPE_DEBUG,
1303          "Not enough buffer\n");
1304     return GNUNET_NO;
1305   }
1306   connection->nth.notify_ready = NULL;
1307   if (connection->write_buffer_size - connection->write_buffer_off < size)
1308   {
1309     /* need to compact */
1310     memmove (connection->write_buffer,
1311              &connection->write_buffer[connection->write_buffer_pos],
1312              used);
1313     connection->write_buffer_off -= connection->write_buffer_pos;
1314     connection->write_buffer_pos = 0;
1315   }
1316   avail = connection->write_buffer_size - connection->write_buffer_off;
1317   GNUNET_assert (avail >= size);
1318   size =
1319       notify (connection->nth.notify_ready_cls, avail,
1320               &connection->write_buffer[connection->write_buffer_off]);
1321   GNUNET_assert (size <= avail);
1322   if (0 != size)
1323     connection->write_buffer_off += size;
1324   return GNUNET_YES;
1325 }
1326
1327
1328 /**
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
1332  * expired).
1333  *
1334  * This task notifies the client about the timeout.
1335  *
1336  * @param cls the `struct GNUNET_CONNECTION_Handle`
1337  */
1338 static void
1339 transmit_timeout (void *cls)
1340 {
1341   struct GNUNET_CONNECTION_Handle *connection = cls;
1342   GNUNET_CONNECTION_TransmitReadyNotify notify;
1343
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,
1348        connection->port,
1349        GNUNET_a2s (connection->addr,
1350                    connection->addrlen),
1351        connection);
1352   notify = connection->nth.notify_ready;
1353   GNUNET_assert (NULL != notify);
1354   connection->nth.notify_ready = NULL;
1355   notify (connection->nth.notify_ready_cls,
1356           0,
1357           NULL);
1358 }
1359
1360
1361 /**
1362  * Task invoked by the scheduler when we failed to connect
1363  * at the time of being asked to transmit.
1364  *
1365  * This task notifies the client about the error.
1366  *
1367  * @param cls the `struct GNUNET_CONNECTION_Handle`
1368  */
1369 static void
1370 connect_error (void *cls)
1371 {
1372   struct GNUNET_CONNECTION_Handle *connection = cls;
1373   GNUNET_CONNECTION_TransmitReadyNotify notify;
1374
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,
1379        connection->port,
1380        connection);
1381   connection->write_task = NULL;
1382   notify = connection->nth.notify_ready;
1383   connection->nth.notify_ready = NULL;
1384   notify (connection->nth.notify_ready_cls,
1385           0,
1386           NULL);
1387 }
1388
1389
1390 /**
1391  * We are ready to transmit (or got a timeout).
1392  *
1393  * @param cls our connection handle
1394  */
1395 static void
1396 transmit_ready (void *cls)
1397 {
1398   struct GNUNET_CONNECTION_Handle *connection = cls;
1399   GNUNET_CONNECTION_TransmitReadyNotify notify;
1400   const struct GNUNET_SCHEDULER_TaskContext *tc;
1401   ssize_t ret;
1402   size_t have;
1403
1404   LOG (GNUNET_ERROR_TYPE_DEBUG,
1405        "transmit_ready running (%p).\n",
1406        connection);
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))
1412   {
1413     LOG (GNUNET_ERROR_TYPE_DEBUG,
1414          "Transmit to `%s' fails, time out reached (%p).\n",
1415          GNUNET_a2s (connection->addr,
1416                      connection->addrlen),
1417          connection);
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);
1422     return;
1423   }
1424   GNUNET_assert (NULL != connection->sock);
1425   if (NULL == tc->write_ready)
1426   {
1427     /* special circumstances (in particular, PREREQ_DONE after
1428      * connect): not yet ready to write, but no "fatal" error either.
1429      * Hence retry.  */
1430     goto SCHEDULE_WRITE;
1431   }
1432   if (! GNUNET_NETWORK_fdset_isset (tc->write_ready,
1433                                     connection->sock))
1434   {
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;
1439   }
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))
1443   {
1444     connection->write_buffer =
1445         GNUNET_realloc (connection->write_buffer, connection->nth.notify_size);
1446     connection->write_buffer_size = connection->nth.notify_size;
1447   }
1448   process_notify (connection);
1449   have = connection->write_buffer_off - connection->write_buffer_pos;
1450   if (0 == have)
1451   {
1452     /* no data ready for writing, terminate write loop */
1453     return;
1454   }
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);
1458 RETRY:
1459   ret =
1460       GNUNET_NETWORK_socket_send (connection->sock,
1461                                   &connection->write_buffer[connection->write_buffer_pos],
1462                                   have);
1463   if (-1 == ret)
1464   {
1465     if (EINTR == errno)
1466       goto RETRY;
1467     if (NULL != connection->write_task)
1468     {
1469       GNUNET_SCHEDULER_cancel (connection->write_task);
1470       connection->write_task = NULL;
1471     }
1472     signal_transmit_error (connection, errno);
1473     return;
1474   }
1475   LOG (GNUNET_ERROR_TYPE_DEBUG,
1476        "Connection transmitted %u/%u bytes to `%s' (%p)\n",
1477        (unsigned int) ret,
1478        have,
1479        GNUNET_a2s (connection->addr,
1480                    connection->addrlen),
1481        connection);
1482   connection->write_buffer_pos += ret;
1483   if (connection->write_buffer_pos == connection->write_buffer_off)
1484   {
1485     /* transmitted all pending data */
1486     connection->write_buffer_pos = 0;
1487     connection->write_buffer_off = 0;
1488   }
1489   if ( (0 == connection->write_buffer_off) &&
1490        (NULL == connection->nth.notify_ready) )
1491     return;                     /* all data sent! */
1492   /* not done writing, schedule more */
1493 SCHEDULE_WRITE:
1494   LOG (GNUNET_ERROR_TYPE_DEBUG,
1495        "Re-scheduling transmit_ready (more to do) (%p).\n",
1496        connection);
1497   have = connection->write_buffer_off - connection->write_buffer_pos;
1498   GNUNET_assert ( (NULL != connection->nth.notify_ready) ||
1499                   (have > 0) );
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),
1506                                         connection->sock,
1507                                         &transmit_ready, connection);
1508 }
1509
1510
1511 /**
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.
1515  *
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)
1524  */
1525 struct GNUNET_CONNECTION_TransmitHandle *
1526 GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connection,
1527                                          size_t size,
1528                                          struct GNUNET_TIME_Relative timeout,
1529                                          GNUNET_CONNECTION_TransmitReadyNotify notify,
1530                                          void *notify_cls)
1531 {
1532   if (NULL != connection->nth.notify_ready)
1533   {
1534     GNUNET_assert (0);
1535     return NULL;
1536   }
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))
1552   {
1553     if (NULL != connection->write_task)
1554       GNUNET_SCHEDULER_cancel (connection->write_task);
1555     connection->write_task = GNUNET_SCHEDULER_add_now (&connect_error,
1556                                                        connection);
1557     return &connection->nth;
1558   }
1559   if (NULL != connection->write_task)
1560     return &connection->nth; /* previous transmission still in progress */
1561   if (NULL != connection->sock)
1562   {
1563     /* connected, try to transmit now */
1564     LOG (GNUNET_ERROR_TYPE_DEBUG,
1565          "Scheduling transmission (%p).\n",
1566          connection);
1567     connection->write_task =
1568         GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining
1569                                         (connection->nth.transmit_timeout),
1570                                         connection->sock,
1571                                         &transmit_ready, connection);
1572     return &connection->nth;
1573   }
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",
1577        connection);
1578   connection->nth.timeout_task =
1579     GNUNET_SCHEDULER_add_delayed (timeout,
1580                                   &transmit_timeout,
1581                                   connection);
1582   return &connection->nth;
1583 }
1584
1585
1586 /**
1587  * Cancel the specified transmission-ready notification.
1588  *
1589  * @param th notification to cancel
1590  */
1591 void
1592 GNUNET_CONNECTION_notify_transmit_ready_cancel (struct GNUNET_CONNECTION_TransmitHandle *th)
1593 {
1594   GNUNET_assert (NULL != th->notify_ready);
1595   th->notify_ready = NULL;
1596   if (NULL != th->timeout_task)
1597   {
1598     GNUNET_SCHEDULER_cancel (th->timeout_task);
1599     th->timeout_task = NULL;
1600   }
1601   if (NULL != th->connection->write_task)
1602   {
1603     GNUNET_SCHEDULER_cancel (th->connection->write_task);
1604     th->connection->write_task = NULL;
1605   }
1606 }
1607
1608
1609 /**
1610  * Create a connection to be proxied using a given connection.
1611  *
1612  * @param cph connection to proxy server
1613  * @return connection to be proxied
1614  */
1615 struct GNUNET_CONNECTION_Handle *
1616 GNUNET_CONNECTION_create_proxied_from_handshake (struct GNUNET_CONNECTION_Handle *cph)
1617 {
1618   struct GNUNET_CONNECTION_Handle *proxied = GNUNET_CONNECTION_create_from_existing (NULL);
1619
1620   proxied->proxy_handshake = cph;
1621   return proxied;
1622 }
1623
1624
1625 /**
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.
1629  *
1630  * @param proxied connection connection to proxy server
1631  */
1632 void
1633 GNUNET_CONNECTION_acivate_proxied (struct GNUNET_CONNECTION_Handle *proxied)
1634 {
1635   struct GNUNET_CONNECTION_Handle *cph = proxied->proxy_handshake;
1636
1637   GNUNET_assert (NULL != cph);
1638   GNUNET_assert (NULL == proxied->sock);
1639   GNUNET_assert (NULL != cph->sock);
1640   proxied->sock = cph->sock;
1641   cph->sock = NULL;
1642   GNUNET_CONNECTION_destroy (cph);
1643   connect_success_continuation (proxied);
1644 }
1645
1646
1647 /* end of connection.c */