fix
[oweals/gnunet.git] / src / util / client.c
1 /*
2      This file is part of GNUnet.
3      (C) 2001, 2002, 2006, 2008, 2009 Christian Grothoff (and other contributing authors)
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 2, 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., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file util/client.c
23  * @brief code for access to services
24  * @author Christian Grothoff
25  *
26  * Generic TCP code for reliable, record-oriented TCP
27  * connections between clients and service providers.
28  */
29
30 #include "platform.h"
31 #include "gnunet_common.h"
32 #include "gnunet_client_lib.h"
33 #include "gnunet_protocols.h"
34 #include "gnunet_server_lib.h"
35 #include "gnunet_scheduler_lib.h"
36
37 #define DEBUG_CLIENT GNUNET_EXTRA_LOGGING
38
39 /**
40  * How often do we re-try tranmsitting requests before giving up?
41  * Note that if we succeeded transmitting a request but failed to read
42  * a response, we do NOT re-try.
43  */
44 #define MAX_ATTEMPTS 50
45
46 #define LOG(kind,...) GNUNET_log_from (kind, "util",__VA_ARGS__)
47
48 /**
49  * Handle for a transmission request.
50  */
51 struct GNUNET_CLIENT_TransmitHandle
52 {
53   /**
54    * Connection state.
55    */
56   struct GNUNET_CLIENT_Connection *sock;
57
58   /**
59    * Function to call to get the data for transmission.
60    */
61   GNUNET_CONNECTION_TransmitReadyNotify notify;
62
63   /**
64    * Closure for notify.
65    */
66   void *notify_cls;
67
68   /**
69    * Handle to the transmission with the underlying
70    * connection.
71    */
72   struct GNUNET_CONNECTION_TransmitHandle *th;
73
74   /**
75    * If we are re-trying and are delaying to do so,
76    * handle to the scheduled task managing the delay.
77    */
78   GNUNET_SCHEDULER_TaskIdentifier reconnect_task;
79
80   /**
81    * Timeout for the operation overall.
82    */
83   struct GNUNET_TIME_Absolute timeout;
84
85   /**
86    * Number of bytes requested.
87    */
88   size_t size;
89
90   /**
91    * Are we allowed to re-try to connect without telling
92    * the user (of this API) about the connection troubles?
93    */
94   int auto_retry;
95
96   /**
97    * Number of attempts left for transmitting the request.  We may
98    * fail the first time (say because the service is not yet up), in
99    * which case (if auto_retry is set) we wait a bit and re-try
100    * (timeout permitting).
101    */
102   unsigned int attempts_left;
103
104 };
105
106
107 /**
108  * Context for processing
109  * "GNUNET_CLIENT_transmit_and_get_response" requests.
110  */
111 struct TransmitGetResponseContext
112 {
113   /**
114    * Client handle.
115    */
116   struct GNUNET_CLIENT_Connection *sock;
117
118   /**
119    * Message to transmit; do not free, allocated
120    * right after this struct.
121    */
122   const struct GNUNET_MessageHeader *hdr;
123
124   /**
125    * Timeout to use.
126    */
127   struct GNUNET_TIME_Absolute timeout;
128
129   /**
130    * Function to call when done.
131    */
132   GNUNET_CLIENT_MessageHandler rn;
133
134   /**
135    * Closure for "rn".
136    */
137   void *rn_cls;
138 };
139
140 /**
141  * Struct to refer to a GNUnet TCP connection.
142  * This is more than just a socket because if the server
143  * drops the connection, the client automatically tries
144  * to reconnect (and for that needs connection information).
145  */
146 struct GNUNET_CLIENT_Connection
147 {
148
149   /**
150    * the socket handle, NULL if not live
151    */
152   struct GNUNET_CONNECTION_Handle *sock;
153
154   /**
155    * Our configuration.
156    */
157   const struct GNUNET_CONFIGURATION_Handle *cfg;
158
159   /**
160    * Name of the service we interact with.
161    */
162   char *service_name;
163
164   /**
165    * Context of a transmit_and_get_response operation, NULL
166    * if no such operation is pending.
167    */
168   struct TransmitGetResponseContext *tag;
169
170   /**
171    * Handler for current receiver task.
172    */
173   GNUNET_CLIENT_MessageHandler receiver_handler;
174
175   /**
176    * Closure for receiver_handler.
177    */
178   void *receiver_handler_cls;
179
180   /**
181    * Handle for a pending transmission request, NULL if there is
182    * none pending.
183    */
184   struct GNUNET_CLIENT_TransmitHandle *th;
185
186   /**
187    * Handler for service test completion (NULL unless in service_test)
188    */
189   GNUNET_SCHEDULER_Task test_cb;
190
191   /**
192    * Deadline for calling 'test_cb'.
193    */
194   struct GNUNET_TIME_Absolute test_deadline;
195
196   /**
197    * If we are re-trying and are delaying to do so,
198    * handle to the scheduled task managing the delay.
199    */
200   GNUNET_SCHEDULER_TaskIdentifier receive_task;
201
202   /**
203    * Closure for test_cb (NULL unless in service_test)
204    */
205   void *test_cb_cls;
206
207   /**
208    * Buffer for received message.
209    */
210   char *received_buf;
211
212   /**
213    * Timeout for receiving a response (absolute time).
214    */
215   struct GNUNET_TIME_Absolute receive_timeout;
216
217   /**
218    * Current value for our incremental back-off (for
219    * connect re-tries).
220    */
221   struct GNUNET_TIME_Relative back_off;
222
223   /**
224    * Number of bytes in received_buf that are valid.
225    */
226   size_t received_pos;
227
228   /**
229    * Size of received_buf.
230    */
231   unsigned int received_size;
232
233   /**
234    * Do we have a complete response in received_buf?
235    */
236   int msg_complete;
237
238   /**
239    * Are we currently busy doing receive-processing?
240    * GNUNET_YES if so, GNUNET_NO if not.
241    */
242   int in_receive;
243
244   /**
245    * How often have we tried to connect?
246    */
247   unsigned int attempts;
248
249 };
250
251
252 /**
253  * Try to connect to the service.
254  *
255  * @param service_name name of service to connect to
256  * @param cfg configuration to use
257  * @param attempt counter used to alternate between IP and UNIX domain sockets
258  * @return NULL on error
259  */
260 static struct GNUNET_CONNECTION_Handle *
261 do_connect (const char *service_name,
262             const struct GNUNET_CONFIGURATION_Handle *cfg,
263             unsigned int attempt)
264 {
265   struct GNUNET_CONNECTION_Handle *sock;
266   char *hostname;
267   char *unixpath;
268   unsigned long long port;
269
270   sock = NULL;
271 #if AF_UNIX
272   if (0 == (attempt % 2))
273     {
274       /* on even rounds, try UNIX */
275       unixpath = NULL;
276       if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service_name, "UNIXPATH", &unixpath)) && (0 < strlen (unixpath)))   /* We have a non-NULL unixpath, does that mean it's valid? */
277         {
278           sock =
279             GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg, unixpath);
280           if (sock != NULL)
281             {
282 #if DEBUG_CLIENT
283               LOG (GNUNET_ERROR_TYPE_DEBUG, "Connected to unixpath `%s'!\n",
284                    unixpath);
285 #endif
286               GNUNET_free (unixpath);
287               return sock;
288             }
289         }
290       GNUNET_free_non_null (unixpath);
291     }
292 #endif
293
294   if ((GNUNET_OK !=
295        GNUNET_CONFIGURATION_get_value_number (cfg, service_name, "PORT",
296                                               &port)) || (port > 65535)
297       || (GNUNET_OK !=
298           GNUNET_CONFIGURATION_get_value_string (cfg, service_name,
299                                                  "HOSTNAME", &hostname)))
300     {
301       LOG (GNUNET_ERROR_TYPE_WARNING,
302            _
303            ("Could not determine valid hostname and port for service `%s' from configuration.\n"),
304            service_name);
305       return NULL;
306     }
307   if (0 == strlen (hostname))
308     {
309       GNUNET_free (hostname);
310       LOG (GNUNET_ERROR_TYPE_WARNING,
311            _("Need a non-empty hostname for service `%s'.\n"), service_name);
312       return NULL;
313     }
314   if (port == 0)
315     {
316 #if AF_UNIX
317       if (0 != (attempt % 2))
318         {
319           /* try UNIX */
320           unixpath = NULL;
321           if ((GNUNET_OK ==
322                GNUNET_CONFIGURATION_get_value_string (cfg, service_name,
323                                                       "UNIXPATH", &unixpath))
324               && (0 < strlen (unixpath)))
325             {
326               sock =
327                 GNUNET_CONNECTION_create_from_connect_to_unixpath (cfg,
328                                                                    unixpath);
329               if (sock != NULL)
330                 {
331                   GNUNET_free (unixpath);
332                   GNUNET_free (hostname);
333                   return sock;
334                 }
335             }
336           GNUNET_free_non_null (unixpath);
337         }
338 #endif
339 #if DEBUG_CLIENT
340       LOG (GNUNET_ERROR_TYPE_DEBUG,
341            "Port is 0 for service `%s', UNIXPATH did not work, returning NULL!\n",
342            service_name);
343 #endif
344       GNUNET_free (hostname);
345       return NULL;
346     }
347
348   sock = GNUNET_CONNECTION_create_from_connect (cfg, hostname, port);
349   GNUNET_free (hostname);
350   return sock;
351 }
352
353
354 /**
355  * Get a connection with a service.
356  *
357  * @param service_name name of the service
358  * @param cfg configuration to use
359  * @return NULL on error (service unknown to configuration)
360  */
361 struct GNUNET_CLIENT_Connection *
362 GNUNET_CLIENT_connect (const char *service_name,
363                        const struct GNUNET_CONFIGURATION_Handle *cfg)
364 {
365   struct GNUNET_CLIENT_Connection *ret;
366   struct GNUNET_CONNECTION_Handle *sock;
367
368   sock = do_connect (service_name, cfg, 0);
369   ret = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_Connection));
370   ret->attempts = 1;
371   ret->sock = sock;
372   ret->service_name = GNUNET_strdup (service_name);
373   ret->cfg = cfg;
374   ret->back_off = GNUNET_TIME_UNIT_MILLISECONDS;
375   return ret;
376 }
377
378
379 /**
380  * Destroy connection with the service.  This will automatically
381  * cancel any pending "receive" request (however, the handler will
382  * *NOT* be called, not even with a NULL message).  Any pending
383  * transmission request will also be cancelled UNLESS the callback for
384  * the transmission request has already been called, in which case the
385  * transmission 'finish_pending_write' argument determines whether or
386  * not the write is guaranteed to complete before the socket is fully
387  * destroyed (unless, of course, there is an error with the server in
388  * which case the message may still be lost).
389  *
390  * @param finish_pending_write should a transmission already passed to the
391  *          handle be completed?
392  * @param sock handle to the service connection
393  */
394 void
395 GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock,
396                           int finish_pending_write)
397 {
398   if (sock->in_receive == GNUNET_YES)
399     {
400       GNUNET_CONNECTION_receive_cancel (sock->sock);
401       sock->in_receive = GNUNET_NO;
402     }
403   if (sock->th != NULL)
404     {
405       GNUNET_CLIENT_notify_transmit_ready_cancel (sock->th);
406       sock->th = NULL;
407     }
408   if (NULL != sock->sock)
409     {
410       GNUNET_CONNECTION_destroy (sock->sock, finish_pending_write);
411       sock->sock = NULL;
412     }
413   if (sock->receive_task != GNUNET_SCHEDULER_NO_TASK)
414     {
415       GNUNET_SCHEDULER_cancel (sock->receive_task);
416       sock->receive_task = GNUNET_SCHEDULER_NO_TASK;
417     }
418   if (sock->tag != NULL)
419     {
420       GNUNET_free (sock->tag);
421       sock->tag = NULL;
422     }
423   sock->receiver_handler = NULL;
424   GNUNET_array_grow (sock->received_buf, sock->received_size, 0);
425   GNUNET_free (sock->service_name);
426   GNUNET_free (sock);
427 }
428
429
430 /**
431  * Check if message is complete
432  */
433 static void
434 check_complete (struct GNUNET_CLIENT_Connection *conn)
435 {
436   if ((conn->received_pos >= sizeof (struct GNUNET_MessageHeader)) &&
437       (conn->received_pos >=
438        ntohs (((const struct GNUNET_MessageHeader *) conn->received_buf)->
439               size)))
440     conn->msg_complete = GNUNET_YES;
441 }
442
443
444 /**
445  * Callback function for data received from the network.  Note that
446  * both "available" and "errCode" would be 0 if the read simply timed out.
447  *
448  * @param cls closure
449  * @param buf pointer to received data
450  * @param available number of bytes availabe in "buf",
451  *        possibly 0 (on errors)
452  * @param addr address of the sender
453  * @param addrlen size of addr
454  * @param errCode value of errno (on errors receiving)
455  */
456 static void
457 receive_helper (void *cls, const void *buf, size_t available,
458                 const struct sockaddr *addr, socklen_t addrlen, int errCode)
459 {
460   struct GNUNET_CLIENT_Connection *conn = cls;
461   struct GNUNET_TIME_Relative remaining;
462   GNUNET_CLIENT_MessageHandler receive_handler;
463   void *receive_handler_cls;
464
465   GNUNET_assert (conn->msg_complete == GNUNET_NO);
466   conn->in_receive = GNUNET_NO;
467   if ((available == 0) || (conn->sock == NULL) || (errCode != 0))
468     {
469       /* signal timeout! */
470 #if DEBUG_CLIENT
471       LOG (GNUNET_ERROR_TYPE_DEBUG,
472            "Timeout in receive_helper, available %u, conn->sock %s, errCode `%s'\n",
473            (unsigned int) available,
474            conn->sock == NULL ? "NULL" : "non-NULL", STRERROR (errCode));
475 #endif
476       if (NULL != (receive_handler = conn->receiver_handler))
477         {
478           receive_handler_cls = conn->receiver_handler_cls;
479           conn->receiver_handler = NULL;
480           receive_handler (receive_handler_cls, NULL);
481         }
482       return;
483     }
484
485   /* FIXME: optimize for common fast case where buf contains the
486    * entire message and we need no copying... */
487
488
489   /* slow path: append to array */
490   if (conn->received_size < conn->received_pos + available)
491     GNUNET_array_grow (conn->received_buf, conn->received_size,
492                        conn->received_pos + available);
493   memcpy (&conn->received_buf[conn->received_pos], buf, available);
494   conn->received_pos += available;
495   check_complete (conn);
496   /* check for timeout */
497   remaining = GNUNET_TIME_absolute_get_remaining (conn->receive_timeout);
498   if (remaining.rel_value == 0)
499     {
500       /* signal timeout! */
501       if (NULL != conn->receiver_handler)
502         conn->receiver_handler (conn->receiver_handler_cls, NULL);
503       return;
504     }
505   /* back to receive -- either for more data or to call callback! */
506   GNUNET_CLIENT_receive (conn, conn->receiver_handler,
507                          conn->receiver_handler_cls, remaining);
508 }
509
510
511 /**
512  * Continuation to call the receive callback.
513  *
514  * @param cls  our handle to the client connection
515  * @param tc scheduler context
516  */
517 static void
518 receive_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
519 {
520   struct GNUNET_CLIENT_Connection *sock = cls;
521   GNUNET_CLIENT_MessageHandler handler = sock->receiver_handler;
522   const struct GNUNET_MessageHeader *cmsg =
523     (const struct GNUNET_MessageHeader *) sock->received_buf;
524   void *handler_cls = sock->receiver_handler_cls;
525   uint16_t msize = ntohs (cmsg->size);
526   char mbuf[msize];
527   struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) mbuf;
528
529 #if DEBUG_CLIENT
530   LOG (GNUNET_ERROR_TYPE_DEBUG,
531        "Received message of type %u and size %u\n", ntohs (cmsg->type),
532        msize);
533 #endif
534   sock->receive_task = GNUNET_SCHEDULER_NO_TASK;
535   GNUNET_assert (GNUNET_YES == sock->msg_complete);
536   GNUNET_assert (sock->received_pos >= msize);
537   memcpy (msg, cmsg, msize);
538   memmove (sock->received_buf, &sock->received_buf[msize],
539            sock->received_pos - msize);
540   sock->received_pos -= msize;
541   sock->msg_complete = GNUNET_NO;
542   sock->receiver_handler = NULL;
543   check_complete (sock);
544   if (handler != NULL)
545     handler (handler_cls, msg);
546 }
547
548
549 /**
550  * Read from the service.
551  *
552  * @param sock the service
553  * @param handler function to call with the message
554  * @param handler_cls closure for handler
555  * @param timeout how long to wait until timing out
556  */
557 void
558 GNUNET_CLIENT_receive (struct GNUNET_CLIENT_Connection *sock,
559                        GNUNET_CLIENT_MessageHandler handler,
560                        void *handler_cls, struct GNUNET_TIME_Relative timeout)
561 {
562   if (sock->sock == NULL)
563     {
564       /* already disconnected, fail instantly! */
565       GNUNET_break (0);         /* this should not happen in well-written code! */
566       if (NULL != handler)
567         handler (handler_cls, NULL);
568       return;
569     }
570   sock->receiver_handler = handler;
571   sock->receiver_handler_cls = handler_cls;
572   sock->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout);
573   if (GNUNET_YES == sock->msg_complete)
574     {
575       GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == sock->receive_task);
576       sock->receive_task = GNUNET_SCHEDULER_add_now (&receive_task, sock);
577     }
578   else
579     {
580       GNUNET_assert (sock->in_receive == GNUNET_NO);
581       sock->in_receive = GNUNET_YES;
582 #if DEBUG_CLIENT
583       LOG (GNUNET_ERROR_TYPE_DEBUG, "calling GNUNET_CONNECTION_receive\n");
584 #endif
585       GNUNET_CONNECTION_receive (sock->sock,
586                                  GNUNET_SERVER_MAX_MESSAGE_SIZE - 1, timeout,
587                                  &receive_helper, sock);
588     }
589 }
590
591
592 /**
593  * Report service unavailable.
594  */
595 static void
596 service_test_error (GNUNET_SCHEDULER_Task task, void *task_cls)
597 {
598   GNUNET_SCHEDULER_add_continuation (task, task_cls,
599                                      GNUNET_SCHEDULER_REASON_TIMEOUT);
600 }
601
602
603 /**
604  * Receive confirmation from test, service is up.
605  *
606  * @param cls closure
607  * @param msg message received, NULL on timeout or fatal error
608  */
609 static void
610 confirm_handler (void *cls, const struct GNUNET_MessageHeader *msg)
611 {
612   struct GNUNET_CLIENT_Connection *conn = cls;
613
614   /* We may want to consider looking at the reply in more
615    * detail in the future, for example, is this the
616    * correct service? FIXME! */
617   if (msg != NULL)
618     {
619 #if DEBUG_CLIENT
620       LOG (GNUNET_ERROR_TYPE_DEBUG,
621            "Received confirmation that service is running.\n");
622 #endif
623       GNUNET_SCHEDULER_add_continuation (conn->test_cb, conn->test_cb_cls,
624                                          GNUNET_SCHEDULER_REASON_PREREQ_DONE);
625     }
626   else
627     {
628       service_test_error (conn->test_cb, conn->test_cb_cls);
629     }
630   GNUNET_CLIENT_disconnect (conn, GNUNET_NO);
631 }
632
633
634 /**
635  * Send the 'TEST' message to the service.  If successful, prepare to
636  * receive the reply.
637  *
638  * @param cls the 'struct GNUNET_CLIENT_Connection' of the connection to test
639  * @param size number of bytes available in buf
640  * @param buf where to write the message
641  * @return number of bytes written to buf
642  */
643 static size_t
644 write_test (void *cls, size_t size, void *buf)
645 {
646   struct GNUNET_CLIENT_Connection *conn = cls;
647   struct GNUNET_MessageHeader *msg;
648
649   if (size < sizeof (struct GNUNET_MessageHeader))
650     {
651 #if DEBUG_CLIENT
652       LOG (GNUNET_ERROR_TYPE_DEBUG, _("Failure to transmit TEST request.\n"));
653 #endif
654       service_test_error (conn->test_cb, conn->test_cb_cls);
655       GNUNET_CLIENT_disconnect (conn, GNUNET_NO);
656       return 0;                 /* client disconnected */
657     }
658 #if DEBUG_CLIENT
659   LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmitting `%s' request.\n", "TEST");
660 #endif
661   msg = (struct GNUNET_MessageHeader *) buf;
662   msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
663   msg->size = htons (sizeof (struct GNUNET_MessageHeader));
664   GNUNET_CLIENT_receive (conn, &confirm_handler, conn,
665                          GNUNET_TIME_absolute_get_remaining
666                          (conn->test_deadline));
667   return sizeof (struct GNUNET_MessageHeader);
668 }
669
670
671 /**
672  * Test if the service is running.  If we are given a UNIXPATH or a local address,
673  * we do this NOT by trying to connect to the service, but by trying to BIND to
674  * the same port.  If the BIND fails, we know the service is running.
675  *
676  * @param service name of the service to wait for
677  * @param cfg configuration to use
678  * @param timeout how long to wait at most
679  * @param task task to run if service is running
680  *        (reason will be "PREREQ_DONE" (service running)
681  *         or "TIMEOUT" (service not known to be running))
682  * @param task_cls closure for task
683  */
684 void
685 GNUNET_CLIENT_service_test (const char *service,
686                             const struct GNUNET_CONFIGURATION_Handle *cfg,
687                             struct GNUNET_TIME_Relative timeout,
688                             GNUNET_SCHEDULER_Task task, void *task_cls)
689 {
690   char *hostname;
691   unsigned long long port;
692   struct GNUNET_NETWORK_Handle *sock;
693   struct GNUNET_CLIENT_Connection *conn;
694
695 #if DEBUG_CLIENT
696   LOG (GNUNET_ERROR_TYPE_DEBUG, "Testing if service `%s' is running.\n",
697        service);
698 #endif
699 #ifdef AF_UNIX
700   {
701     /* probe UNIX support */
702     struct sockaddr_un s_un;
703     size_t slen;
704     char *unixpath;
705
706     unixpath = NULL;
707     if ((GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, service, "UNIXPATH", &unixpath)) && (0 < strlen (unixpath)))  /* We have a non-NULL unixpath, does that mean it's valid? */
708       {
709         if (strlen (unixpath) >= sizeof (s_un.sun_path))
710           {
711             LOG (GNUNET_ERROR_TYPE_WARNING,
712                  _("UNIXPATH `%s' too long, maximum length is %llu\n"),
713                  unixpath, sizeof (s_un.sun_path));
714           }
715         else
716           {
717             sock = GNUNET_NETWORK_socket_create (PF_UNIX, SOCK_STREAM, 0);
718             if (sock != NULL)
719               {
720                 memset (&s_un, 0, sizeof (s_un));
721                 s_un.sun_family = AF_UNIX;
722                 slen = strlen (unixpath) + 1;
723                 if (slen >= sizeof (s_un.sun_path))
724                   slen = sizeof (s_un.sun_path) - 1;
725                 memcpy (s_un.sun_path, unixpath, slen);
726                 s_un.sun_path[slen] = '\0';
727                 slen = sizeof (struct sockaddr_un);
728 #if LINUX
729                 s_un.sun_path[0] = '\0';
730 #endif
731 #if HAVE_SOCKADDR_IN_SIN_LEN
732                 s_un.sun_len = (u_char) slen;
733 #endif
734                 if (GNUNET_OK !=
735                     GNUNET_NETWORK_socket_bind (sock,
736                                                 (const struct sockaddr *)
737                                                 &s_un, slen))
738                   {
739                     /* failed to bind => service must be running */
740                     GNUNET_free (unixpath);
741                     (void) GNUNET_NETWORK_socket_close (sock);
742                     GNUNET_SCHEDULER_add_continuation (task, task_cls,
743                                                        GNUNET_SCHEDULER_REASON_PREREQ_DONE);
744                     return;
745                   }
746                 (void) GNUNET_NETWORK_socket_close (sock);
747               }
748             /* let's try IP */
749           }
750       }
751     GNUNET_free_non_null (unixpath);
752   }
753 #endif
754
755   hostname = NULL;
756   if ((GNUNET_OK !=
757        GNUNET_CONFIGURATION_get_value_number (cfg, service, "PORT", &port)) ||
758       (port > 65535) ||
759       (GNUNET_OK !=
760        GNUNET_CONFIGURATION_get_value_string (cfg, service, "HOSTNAME",
761                                               &hostname)))
762     {
763       /* UNIXPATH failed (if possible) AND IP failed => error */
764       service_test_error (task, task_cls);
765       return;
766     }
767
768   if (0 == strcmp ("localhost", hostname)
769 #if !LINUX
770       && 0
771 #endif
772     )
773     {
774       /* can test using 'bind' */
775       struct sockaddr_in s_in;
776
777       memset (&s_in, 0, sizeof (s_in));
778 #if HAVE_SOCKADDR_IN_SIN_LEN
779       s_in.sin_len = sizeof (struct sockaddr_in);
780 #endif
781       s_in.sin_family = AF_INET;
782       s_in.sin_port = htons (port);
783
784       sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
785       if (sock != NULL)
786         {
787           if (GNUNET_OK !=
788               GNUNET_NETWORK_socket_bind (sock,
789                                           (const struct sockaddr *) &s_in,
790                                           sizeof (s_in)))
791             {
792               /* failed to bind => service must be running */
793               GNUNET_free (hostname);
794               (void) GNUNET_NETWORK_socket_close (sock);
795               GNUNET_SCHEDULER_add_continuation (task, task_cls,
796                                                  GNUNET_SCHEDULER_REASON_PREREQ_DONE);
797               return;
798             }
799           (void) GNUNET_NETWORK_socket_close (sock);
800         }
801     }
802
803   if (0 == strcmp ("ip6-localhost", hostname)
804 #if !LINUX
805       && 0
806 #endif
807     )
808     {
809       /* can test using 'bind' */
810       struct sockaddr_in6 s_in6;
811
812       memset (&s_in6, 0, sizeof (s_in6));
813 #if HAVE_SOCKADDR_IN_SIN_LEN
814       s_in6.sin6_len = sizeof (struct sockaddr_in6);
815 #endif
816       s_in6.sin6_family = AF_INET6;
817       s_in6.sin6_port = htons (port);
818
819       sock = GNUNET_NETWORK_socket_create (AF_INET6, SOCK_STREAM, 0);
820       if (sock != NULL)
821         {
822           if (GNUNET_OK !=
823               GNUNET_NETWORK_socket_bind (sock,
824                                           (const struct sockaddr *) &s_in6,
825                                           sizeof (s_in6)))
826             {
827               /* failed to bind => service must be running */
828               GNUNET_free (hostname);
829               (void) GNUNET_NETWORK_socket_close (sock);
830               GNUNET_SCHEDULER_add_continuation (task, task_cls,
831                                                  GNUNET_SCHEDULER_REASON_PREREQ_DONE);
832               return;
833             }
834           (void) GNUNET_NETWORK_socket_close (sock);
835         }
836     }
837
838   if (((0 == strcmp ("localhost", hostname)) ||
839        (0 == strcmp ("ip6-localhost", hostname)))
840 #if !LINUX
841       && 0
842 #endif
843     )
844     {
845       /* all binds succeeded => claim service not running right now */
846       GNUNET_free_non_null (hostname);
847       service_test_error (task, task_cls);
848       return;
849     }
850   GNUNET_free_non_null (hostname);
851
852   /* non-localhost, try 'connect' method */
853   conn = GNUNET_CLIENT_connect (service, cfg);
854   if (conn == NULL)
855     {
856       LOG (GNUNET_ERROR_TYPE_INFO,
857            _("Could not connect to service `%s', must not be running.\n"),
858            service);
859       service_test_error (task, task_cls);
860       return;
861     }
862   conn->test_cb = task;
863   conn->test_cb_cls = task_cls;
864   conn->test_deadline = GNUNET_TIME_relative_to_absolute (timeout);
865
866   if (NULL ==
867       GNUNET_CLIENT_notify_transmit_ready (conn,
868                                            sizeof (struct
869                                                    GNUNET_MessageHeader),
870                                            timeout, GNUNET_YES, &write_test,
871                                            conn))
872     {
873       LOG (GNUNET_ERROR_TYPE_WARNING,
874            _("Failure to transmit request to service `%s'\n"), service);
875       service_test_error (task, task_cls);
876       GNUNET_CLIENT_disconnect (conn, GNUNET_NO);
877       return;
878     }
879 }
880
881
882 /**
883  * Connection notifies us about failure or success of
884  * a transmission request.  Either pass it on to our
885  * user or, if possible, retry.
886  *
887  * @param cls our "struct GNUNET_CLIENT_TransmissionHandle"
888  * @param size number of bytes available for transmission
889  * @param buf where to write them
890  * @return number of bytes written to buf
891  */
892 static size_t client_notify (void *cls, size_t size, void *buf);
893
894
895 /**
896  * This task is run if we should re-try connection to the
897  * service after a while.
898  *
899  * @param cls our "struct GNUNET_CLIENT_TransmitHandle" of the request
900  * @param tc unused
901  */
902 static void
903 client_delayed_retry (void *cls,
904                       const struct GNUNET_SCHEDULER_TaskContext *tc)
905 {
906   struct GNUNET_CLIENT_TransmitHandle *th = cls;
907   struct GNUNET_TIME_Relative delay;
908
909   th->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
910   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
911     {
912 #if DEBUG_CLIENT
913       LOG (GNUNET_ERROR_TYPE_DEBUG, "Transmission failed due to shutdown.\n");
914 #endif
915       th->sock->th = NULL;
916       th->notify (th->notify_cls, 0, NULL);
917       GNUNET_free (th);
918       return;
919     }
920   th->sock->sock =
921     do_connect (th->sock->service_name, th->sock->cfg, th->sock->attempts++);
922   if (NULL == th->sock->sock)
923     {
924       /* could happen if we're out of sockets */
925       delay =
926         GNUNET_TIME_relative_min (GNUNET_TIME_absolute_get_remaining
927                                   (th->timeout), th->sock->back_off);
928       th->sock->back_off =
929         GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply
930                                   (th->sock->back_off, 2),
931                                   GNUNET_TIME_UNIT_SECONDS);
932 #if DEBUG_CLIENT
933       LOG (GNUNET_ERROR_TYPE_DEBUG,
934            "Transmission failed %u times, trying again in %llums.\n",
935            MAX_ATTEMPTS - th->attempts_left,
936            (unsigned long long) delay.rel_value);
937 #endif
938       th->reconnect_task =
939         GNUNET_SCHEDULER_add_delayed (delay, &client_delayed_retry, th);
940       return;
941     }
942   th->th =
943     GNUNET_CONNECTION_notify_transmit_ready (th->sock->sock, th->size,
944                                              GNUNET_TIME_absolute_get_remaining
945                                              (th->timeout), &client_notify,
946                                              th);
947   if (th->th == NULL)
948     {
949       GNUNET_break (0);
950       th->sock->th = NULL;
951       th->notify (th->notify_cls, 0, NULL);
952       GNUNET_free (th);
953       return;
954     }
955 }
956
957
958 /**
959  * Connection notifies us about failure or success of a transmission
960  * request.  Either pass it on to our user or, if possible, retry.
961  *
962  * @param cls our "struct GNUNET_CLIENT_TransmissionHandle"
963  * @param size number of bytes available for transmission
964  * @param buf where to write them
965  * @return number of bytes written to buf
966  */
967 static size_t
968 client_notify (void *cls, size_t size, void *buf)
969 {
970   struct GNUNET_CLIENT_TransmitHandle *th = cls;
971   size_t ret;
972   struct GNUNET_TIME_Relative delay;
973
974   th->th = NULL;
975   th->sock->th = NULL;
976   if (buf == NULL)
977     {
978       delay = GNUNET_TIME_absolute_get_remaining (th->timeout);
979       delay.rel_value /= 2;
980       if ((0 !=
981            (GNUNET_SCHEDULER_REASON_SHUTDOWN &
982             GNUNET_SCHEDULER_get_reason ())) || (GNUNET_YES != th->auto_retry)
983           || (0 == --th->attempts_left) || (delay.rel_value < 1))
984         {
985 #if DEBUG_CLIENT
986           LOG (GNUNET_ERROR_TYPE_DEBUG,
987                "Transmission failed %u times, giving up.\n",
988                MAX_ATTEMPTS - th->attempts_left);
989 #endif
990           GNUNET_break (0 == th->notify (th->notify_cls, 0, NULL));
991           GNUNET_free (th);
992           return 0;
993         }
994       /* auto-retry */
995 #if DEBUG_CLIENT
996       LOG (GNUNET_ERROR_TYPE_DEBUG,
997            "Failed to connect to `%s', automatically trying again.\n",
998            th->sock->service_name);
999 #endif
1000       GNUNET_CONNECTION_destroy (th->sock->sock, GNUNET_NO);
1001       th->sock->sock = NULL;
1002       delay = GNUNET_TIME_relative_min (delay, th->sock->back_off);
1003       th->sock->back_off =
1004         GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply
1005                                   (th->sock->back_off, 2),
1006                                   GNUNET_TIME_UNIT_SECONDS);
1007 #if DEBUG_CLIENT
1008       LOG (GNUNET_ERROR_TYPE_DEBUG,
1009            "Transmission failed %u times, trying again in %llums.\n",
1010            MAX_ATTEMPTS - th->attempts_left,
1011            (unsigned long long) delay.rel_value);
1012 #endif
1013       th->sock->th = th;
1014       th->reconnect_task =
1015         GNUNET_SCHEDULER_add_delayed (delay, &client_delayed_retry, th);
1016       return 0;
1017     }
1018   GNUNET_assert (size >= th->size);
1019   ret = th->notify (th->notify_cls, size, buf);
1020   GNUNET_free (th);
1021   return ret;
1022 }
1023
1024
1025 /**
1026  * Ask the client to call us once the specified number of bytes
1027  * are free in the transmission buffer.  May call the notify
1028  * method immediately if enough space is available.
1029  *
1030  * @param sock connection to the service
1031  * @param size number of bytes to send
1032  * @param timeout after how long should we give up (and call
1033  *        notify with buf NULL and size 0)?
1034  * @param auto_retry if the connection to the service dies, should we
1035  *        automatically re-connect and retry (within the timeout period)
1036  *        or should we immediately fail in this case?  Pass GNUNET_YES
1037  *        if the caller does not care about temporary connection errors,
1038  *        for example because the protocol is stateless
1039  * @param notify function to call
1040  * @param notify_cls closure for notify
1041  * @return NULL if our buffer will never hold size bytes,
1042  *         a handle if the notify callback was queued (can be used to cancel)
1043  */
1044 struct GNUNET_CLIENT_TransmitHandle *
1045 GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock,
1046                                      size_t size,
1047                                      struct GNUNET_TIME_Relative timeout,
1048                                      int auto_retry,
1049                                      GNUNET_CONNECTION_TransmitReadyNotify
1050                                      notify, void *notify_cls)
1051 {
1052   struct GNUNET_CLIENT_TransmitHandle *th;
1053
1054   if (NULL != sock->th)
1055     {
1056       /* If this breaks, you most likley called this function twice without waiting
1057        * for completion or canceling the request */
1058       GNUNET_break (0);
1059       return NULL;
1060     }
1061   th = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_TransmitHandle));
1062   th->sock = sock;
1063   th->size = size;
1064   th->timeout = GNUNET_TIME_relative_to_absolute (timeout);
1065   th->auto_retry = auto_retry;
1066   th->notify = notify;
1067   th->notify_cls = notify_cls;
1068   th->attempts_left = MAX_ATTEMPTS;
1069   sock->th = th;
1070   if (sock->sock == NULL)
1071     {
1072       th->reconnect_task =
1073         GNUNET_SCHEDULER_add_delayed (sock->back_off, &client_delayed_retry,
1074                                       th);
1075
1076     }
1077   else
1078     {
1079       th->th =
1080         GNUNET_CONNECTION_notify_transmit_ready (sock->sock, size, timeout,
1081                                                  &client_notify, th);
1082       if (NULL == th->th)
1083         {
1084           GNUNET_break (0);
1085           GNUNET_free (th);
1086           sock->th = NULL;
1087           return NULL;
1088         }
1089     }
1090   return th;
1091 }
1092
1093
1094 /**
1095  * Cancel a request for notification.
1096  *
1097  * @param th handle from the original request.
1098  */
1099 void
1100 GNUNET_CLIENT_notify_transmit_ready_cancel (struct
1101                                             GNUNET_CLIENT_TransmitHandle *th)
1102 {
1103   if (th->reconnect_task != GNUNET_SCHEDULER_NO_TASK)
1104     {
1105       GNUNET_assert (NULL == th->th);
1106       GNUNET_SCHEDULER_cancel (th->reconnect_task);
1107       th->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
1108     }
1109   else
1110     {
1111       GNUNET_assert (NULL != th->th);
1112       GNUNET_CONNECTION_notify_transmit_ready_cancel (th->th);
1113     }
1114   th->sock->th = NULL;
1115   GNUNET_free (th);
1116 }
1117
1118
1119 /**
1120  * Function called to notify a client about the socket
1121  * begin ready to queue the message.  "buf" will be
1122  * NULL and "size" zero if the socket was closed for
1123  * writing in the meantime.
1124  *
1125  * @param cls closure of type "struct TransmitGetResponseContext*"
1126  * @param size number of bytes available in buf
1127  * @param buf where the callee should write the message
1128  * @return number of bytes written to buf
1129  */
1130 static size_t
1131 transmit_for_response (void *cls, size_t size, void *buf)
1132 {
1133   struct TransmitGetResponseContext *tc = cls;
1134   uint16_t msize;
1135
1136   tc->sock->tag = NULL;
1137   msize = ntohs (tc->hdr->size);
1138   if (NULL == buf)
1139     {
1140 #if DEBUG_CLIENT
1141       LOG (GNUNET_ERROR_TYPE_DEBUG,
1142            _
1143            ("Could not submit request, not expecting to receive a response.\n"));
1144 #endif
1145       if (NULL != tc->rn)
1146         tc->rn (tc->rn_cls, NULL);
1147       GNUNET_free (tc);
1148       return 0;
1149     }
1150   GNUNET_assert (size >= msize);
1151   memcpy (buf, tc->hdr, msize);
1152   GNUNET_CLIENT_receive (tc->sock, tc->rn, tc->rn_cls,
1153                          GNUNET_TIME_absolute_get_remaining (tc->timeout));
1154   GNUNET_free (tc);
1155   return msize;
1156 }
1157
1158
1159 /**
1160  * Convenience API that combines sending a request
1161  * to the service and waiting for a response.
1162  * If either operation times out, the callback
1163  * will be called with a "NULL" response (in which
1164  * case the connection should probably be destroyed).
1165  *
1166  * @param sock connection to use
1167  * @param hdr message to transmit
1168  * @param timeout when to give up (for both transmission
1169  *         and for waiting for a response)
1170  * @param auto_retry if the connection to the service dies, should we
1171  *        automatically re-connect and retry (within the timeout period)
1172  *        or should we immediately fail in this case?  Pass GNUNET_YES
1173  *        if the caller does not care about temporary connection errors,
1174  *        for example because the protocol is stateless
1175  * @param rn function to call with the response
1176  * @param rn_cls closure for rn
1177  * @return GNUNET_OK on success, GNUNET_SYSERR if a request
1178  *         is already pending
1179  */
1180 int
1181 GNUNET_CLIENT_transmit_and_get_response (struct GNUNET_CLIENT_Connection
1182                                          *sock,
1183                                          const struct GNUNET_MessageHeader
1184                                          *hdr,
1185                                          struct GNUNET_TIME_Relative timeout,
1186                                          int auto_retry,
1187                                          GNUNET_CLIENT_MessageHandler rn,
1188                                          void *rn_cls)
1189 {
1190   struct TransmitGetResponseContext *tc;
1191   uint16_t msize;
1192
1193   if (NULL != sock->th)
1194     return GNUNET_SYSERR;
1195   GNUNET_assert (sock->tag == NULL);
1196   msize = ntohs (hdr->size);
1197   tc = GNUNET_malloc (sizeof (struct TransmitGetResponseContext) + msize);
1198   tc->sock = sock;
1199   tc->hdr = (const struct GNUNET_MessageHeader *) &tc[1];
1200   memcpy (&tc[1], hdr, msize);
1201   tc->timeout = GNUNET_TIME_relative_to_absolute (timeout);
1202   tc->rn = rn;
1203   tc->rn_cls = rn_cls;
1204   if (NULL ==
1205       GNUNET_CLIENT_notify_transmit_ready (sock, msize, timeout, auto_retry,
1206                                            &transmit_for_response, tc))
1207     {
1208       GNUNET_break (0);
1209       GNUNET_free (tc);
1210       return GNUNET_SYSERR;
1211     }
1212   sock->tag = tc;
1213   return GNUNET_OK;
1214 }
1215
1216
1217
1218 /*  end of client.c */