removing dead/legacy server/connection logic, except for in tcp/wlan/bt plugins ...
authorChristian Grothoff <christian@grothoff.org>
Thu, 16 Mar 2017 04:33:01 +0000 (05:33 +0100)
committerChristian Grothoff <christian@grothoff.org>
Thu, 16 Mar 2017 04:33:01 +0000 (05:33 +0100)
50 files changed:
po/POTFILES.in
src/consensus/consensus_protocol.h
src/conversation/gnunet-helper-audio-playback.c
src/conversation/microphone.c
src/core/gnunet-service-core_kx.c
src/dns/gnunet-service-dns.c
src/exit/gnunet-daemon-exit.c
src/fs/fs_dirmetascan.c
src/include/Makefile.am
src/include/gnunet_connection_lib.h [deleted file]
src/include/gnunet_helper_lib.h
src/include/gnunet_mq_lib.h
src/include/gnunet_server_lib.h [deleted file]
src/include/gnunet_service_lib.h
src/include/gnunet_util_lib.h
src/nat-auto/Makefile.am
src/nat-auto/gnunet-nat-server.c
src/testbed/testbed_api_hosts.c
src/transport/Makefile.am
src/transport/gnunet-helper-transport-wlan-dummy.c
src/transport/plugin_transport_http_client.c
src/transport/plugin_transport_http_server.c
src/transport/plugin_transport_tcp.c
src/transport/plugin_transport_udp.c
src/transport/plugin_transport_udp.h
src/transport/plugin_transport_udp_broadcasting.c
src/transport/plugin_transport_wlan.c
src/transport/tcp_connection_legacy.c [new file with mode: 0644]
src/transport/tcp_server_legacy.c [new file with mode: 0644]
src/transport/tcp_server_mst_legacy.c [new file with mode: 0644]
src/transport/tcp_service_legacy.c [new file with mode: 0644]
src/transport/test_plugin_transport.c
src/util/Makefile.am
src/util/connection.c [deleted file]
src/util/helper.c
src/util/mq.c
src/util/server.c [deleted file]
src/util/service.c [deleted file]
src/util/test_connection.c [deleted file]
src/util/test_connection_addressing.c [deleted file]
src/util/test_connection_receive_cancel.c [deleted file]
src/util/test_connection_timeout.c [deleted file]
src/util/test_connection_timeout_no_connect.c [deleted file]
src/util/test_connection_transmit_cancel.c [deleted file]
src/util/test_server.c [deleted file]
src/util/test_server_disconnect.c [deleted file]
src/util/test_server_mst_interrupt.c [deleted file]
src/util/test_server_with_client.c [deleted file]
src/util/test_server_with_client_unix.c [deleted file]
src/vpn/gnunet-service-vpn.c

index aea7d5ef76c0fc2246bfc69143823ed951591f1e..df5a298ac4631f07d3b75f451dcfd8d67098c641 100644 (file)
@@ -37,31 +37,19 @@ src/block/block.c
 src/block/plugin_block_template.c
 src/block/plugin_block_test.c
 src/cadet/cadet_api.c
-src/cadet/cadet_api_new.c
-src/cadet/cadet_common.c
-src/cadet/cadet_path.c
 src/cadet/cadet_test_lib.c
-src/cadet/cadet_test_lib_new.c
 src/cadet/desirability_table.c
 src/cadet/gnunet-cadet.c
 src/cadet/gnunet-cadet-profiler.c
 src/cadet/gnunet-service-cadet.c
 src/cadet/gnunet-service-cadet_channel.c
 src/cadet/gnunet-service-cadet_connection.c
+src/cadet/gnunet-service-cadet_core.c
 src/cadet/gnunet-service-cadet_dht.c
 src/cadet/gnunet-service-cadet_hello.c
-src/cadet/gnunet-service-cadet_local.c
-src/cadet/gnunet-service-cadet-new.c
-src/cadet/gnunet-service-cadet-new_channel.c
-src/cadet/gnunet-service-cadet-new_connection.c
-src/cadet/gnunet-service-cadet-new_core.c
-src/cadet/gnunet-service-cadet-new_dht.c
-src/cadet/gnunet-service-cadet-new_hello.c
-src/cadet/gnunet-service-cadet-new_paths.c
-src/cadet/gnunet-service-cadet-new_peer.c
-src/cadet/gnunet-service-cadet-new_tunnels.c
+src/cadet/gnunet-service-cadet_paths.c
 src/cadet/gnunet-service-cadet_peer.c
-src/cadet/gnunet-service-cadet_tunnel.c
+src/cadet/gnunet-service-cadet_tunnels.c
 src/consensus/consensus_api.c
 src/consensus/gnunet-consensus-profiler.c
 src/consensus/gnunet-service-consensus.c
@@ -165,7 +153,6 @@ src/fs/gnunet-service-fs_cadet_client.c
 src/fs/gnunet-service-fs_cadet_server.c
 src/fs/gnunet-service-fs_cp.c
 src/fs/gnunet-service-fs_indexing.c
-src/fs/gnunet-service-fs_lc.c
 src/fs/gnunet-service-fs_pe.c
 src/fs/gnunet-service-fs_pr.c
 src/fs/gnunet-service-fs_push.c
@@ -415,6 +402,9 @@ src/transport/plugin_transport_udp_broadcasting.c
 src/transport/plugin_transport_udp.c
 src/transport/plugin_transport_unix.c
 src/transport/plugin_transport_wlan.c
+src/transport/tcp_connection_legacy.c
+src/transport/tcp_server_legacy.c
+src/transport/tcp_service_legacy.c
 src/transport/transport_api_address_to_string.c
 src/transport/transport_api_blacklist.c
 src/transport/transport_api_core.c
@@ -438,7 +428,6 @@ src/util/common_endian.c
 src/util/common_logging.c
 src/util/configuration.c
 src/util/configuration_loader.c
-src/util/connection.c
 src/util/container_bloomfilter.c
 src/util/container_heap.c
 src/util/container_meta_data.c
@@ -485,11 +474,9 @@ src/util/plugin.c
 src/util/program.c
 src/util/resolver_api.c
 src/util/scheduler.c
-src/util/server.c
 src/util/server_mst.c
 src/util/server_nc.c
 src/util/server_tc.c
-src/util/service.c
 src/util/service_new.c
 src/util/signal.c
 src/util/socks.c
index 320d460c701d6e4c903babaa216539281ad1648b..f2933ed6f8cb32c1c6e211436e2a6373791774f3 100644 (file)
@@ -109,7 +109,7 @@ struct ConsensusElement
   /**
    * Is this a marker element?
    */
-  uint8_t marker GNUNET_PACKED;
+  uint8_t marker;
 
   /* rest: element data */
 };
@@ -117,7 +117,7 @@ struct ConsensusElement
 
 struct ConsensusSizeElement
 {
-  struct ConsensusElement ce GNUNET_PACKED;
+  struct ConsensusElement ce;
 
   uint64_t size GNUNET_PACKED;
   uint8_t sender_index;
@@ -125,7 +125,7 @@ struct ConsensusSizeElement
 
 struct ConsensusStuffedElement
 {
-  struct ConsensusElement ce GNUNET_PACKED;
+  struct ConsensusElement ce;
   struct GNUNET_HashCode rand GNUNET_PACKED;
 };
 
index e965cb2aaa0c259a05a93b9b8e729f5ceb8c5f2b..4344e1d418808f512a0bf5ce1fc87c773121084b 100644 (file)
@@ -549,7 +549,6 @@ ogg_demux_and_decode ()
  */
 static int
 stdin_receiver (void *cls,
-               void *client,
                const struct GNUNET_MessageHeader *msg)
 {
   struct AudioMessage *audio;
@@ -727,12 +726,14 @@ ogg_init ()
   ogg_sync_init (&oy);
 }
 
+
 static void
 drain_callback (pa_stream*s, int success, void *userdata)
 {
   pa_threaded_mainloop_signal (m, 0);
 }
 
+
 /**
  * The main function for the playback helper.
  *
@@ -746,7 +747,7 @@ main (int argc, char *argv[])
   static unsigned long long toff;
 
   char readbuf[MAXLINE];
-  struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst;
+  struct GNUNET_MessageStreamTokenizer *stdin_mst;
   char c;
   ssize_t ret;
 #ifdef DEBUG_READ_PURE_OGG
@@ -762,7 +763,7 @@ main (int argc, char *argv[])
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "pipe");
     return 1;
   }
-  stdin_mst = GNUNET_SERVER_mst_create (&stdin_receiver, NULL);
+  stdin_mst = GNUNET_MST_create (&stdin_receiver, NULL);
   ogg_init ();
   pa_init ();
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -802,11 +803,11 @@ main (int argc, char *argv[])
     }
     else
 #endif
-    GNUNET_SERVER_mst_receive (stdin_mst, NULL,
-                              readbuf, ret,
-                              GNUNET_NO, GNUNET_NO);
+    GNUNET_MST_from_buffer (stdin_mst,
+                            readbuf, ret,
+                            GNUNET_NO, GNUNET_NO);
   }
-  GNUNET_SERVER_mst_destroy (stdin_mst);
+  GNUNET_MST_destroy (stdin_mst);
   if (stream_out)
   {
     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
index 94f52f8dc22b4ff24aae03e8ec2cf06a56967796..7871433a33888cfe27f2247ca34f1bb9f0ab94fb 100644 (file)
@@ -64,13 +64,11 @@ struct Microphone
  * Function to process the audio from the record helper
  *
  * @param cls clsoure with our `struct Microphone`
- * @param client NULL
  * @param msg the message from the helper
  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
  */
 static int
 process_record_messages (void *cls,
-                        void *client,
                         const struct GNUNET_MessageHeader *msg)
 {
   struct Microphone *mic = cls;
index 9068985123fd1723489f5b102400e5177ac82ee0..8a7cada5c5a1a1b76191e7859bb54ee703c6d760 100644 (file)
@@ -262,6 +262,11 @@ struct GSC_KeyExchangeInfo
    */
   struct GNUNET_MQ_Handle *mq;
 
+  /**
+   * Our message stream tokenizer (for encrypted payload).
+   */
+  struct GNUNET_MessageStreamTokenizer *mst;
+
   /**
    * PING message we transmit to the other peer.
    */
@@ -369,11 +374,6 @@ static struct GNUNET_CRYPTO_EcdhePrivateKey *my_ephemeral_key;
  */
 static struct EphemeralKeyMessage current_ekm;
 
-/**
- * Our message stream tokenizer (for encrypted payload).
- */
-static struct GNUNET_SERVER_MessageStreamTokenizer *mst;
-
 /**
  * DLL head.
  */
@@ -701,6 +701,55 @@ setup_fresh_ping (struct GSC_KeyExchangeInfo *kx)
 }
 
 
+/**
+ * Deliver P2P message to interested clients.  Invokes send twice,
+ * once for clients that want the full message, and once for clients
+ * that only want the header
+ *
+ * @param cls the `struct GSC_KeyExchangeInfo`
+ * @param m the message
+ */
+static int
+deliver_message (void *cls,
+                 const struct GNUNET_MessageHeader *m)
+{
+  struct GSC_KeyExchangeInfo *kx = cls;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Decrypted message of type %d from %s\n",
+              ntohs (m->type),
+              GNUNET_i2s (kx->peer));
+  if (GNUNET_CORE_KX_STATE_UP != kx->status)
+  {
+    GNUNET_STATISTICS_update (GSC_stats,
+                              gettext_noop ("# PAYLOAD dropped (out of order)"),
+                              1,
+                              GNUNET_NO);
+    return GNUNET_OK;
+  }
+  switch (ntohs (m->type))
+  {
+  case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
+  case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
+    GSC_SESSIONS_set_typemap (kx->peer, m);
+    return GNUNET_OK;
+  case GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP:
+    GSC_SESSIONS_confirm_typemap (kx->peer, m);
+    return GNUNET_OK;
+  default:
+    GSC_CLIENTS_deliver_message (kx->peer,
+                                 m,
+                                 ntohs (m->size),
+                                 GNUNET_CORE_OPTION_SEND_FULL_INBOUND);
+    GSC_CLIENTS_deliver_message (kx->peer,
+                                 m,
+                                 sizeof (struct GNUNET_MessageHeader),
+                                 GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
+  }
+  return GNUNET_OK;
+}
+
+
 /**
  * Function called by transport to notify us that
  * a peer connected to us (on the network level).
@@ -727,6 +776,8 @@ handle_transport_notify_connect (void *cls,
                             1,
                             GNUNET_NO);
   kx = GNUNET_new (struct GSC_KeyExchangeInfo);
+  kx->mst = GNUNET_MST_create (&deliver_message,
+                               kx);
   kx->mq = mq;
   kx->peer = pid;
   kx->set_key_retry_frequency = INITIAL_SET_KEY_RETRY_FREQUENCY;
@@ -801,6 +852,7 @@ handle_transport_notify_disconnect (void *cls,
   GNUNET_CONTAINER_DLL_remove (kx_head,
                               kx_tail,
                               kx);
+  GNUNET_MST_destroy (kx->mst);
   GNUNET_free (kx);
 }
 
@@ -1416,24 +1468,6 @@ GSC_KX_encrypt_and_transmit (struct GSC_KeyExchangeInfo *kx,
 }
 
 
-/**
- * Closure for #deliver_message()
- */
-struct DeliverMessageContext
-{
-
-  /**
-   * Key exchange context.
-   */
-  struct GSC_KeyExchangeInfo *kx;
-
-  /**
-   * Sender of the message.
-   */
-  const struct GNUNET_PeerIdentity *peer;
-};
-
-
 /**
  * We received an encrypted message.  Check that it is
  * well-formed (size-wise).
@@ -1475,7 +1509,6 @@ handle_encrypted (void *cls,
   struct GNUNET_TIME_Absolute t;
   struct GNUNET_CRYPTO_SymmetricInitializationVector iv;
   struct GNUNET_CRYPTO_AuthKey auth_key;
-  struct DeliverMessageContext dmc;
   uint16_t size = ntohs (m->header.size);
   char buf[size] GNUNET_ALIGN;
 
@@ -1620,15 +1653,12 @@ handle_encrypted (void *cls,
                             gettext_noop ("# bytes of payload decrypted"),
                             size - sizeof (struct EncryptedMessage),
                             GNUNET_NO);
-  dmc.kx = kx;
-  dmc.peer = kx->peer;
   if (GNUNET_OK !=
-      GNUNET_SERVER_mst_receive (mst,
-                                &dmc,
-                                 &buf[sizeof (struct EncryptedMessage)],
-                                 size - sizeof (struct EncryptedMessage),
-                                 GNUNET_YES,
-                                 GNUNET_NO))
+      GNUNET_MST_from_buffer (kx->mst,
+                              &buf[sizeof (struct EncryptedMessage)],
+                              size - sizeof (struct EncryptedMessage),
+                              GNUNET_YES,
+                              GNUNET_NO))
     GNUNET_break_op (0);
 }
 
@@ -1655,57 +1685,6 @@ handle_transport_notify_excess_bw (void *cls,
 }
 
 
-/**
- * Deliver P2P message to interested clients.  Invokes send twice,
- * once for clients that want the full message, and once for clients
- * that only want the header
- *
- * @param cls always NULL
- * @param client who sent us the message (struct GSC_KeyExchangeInfo)
- * @param m the message
- */
-static int
-deliver_message (void *cls,
-                 void *client,
-                 const struct GNUNET_MessageHeader *m)
-{
-  struct DeliverMessageContext *dmc = client;
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Decrypted message of type %d from %s\n",
-              ntohs (m->type),
-              GNUNET_i2s (dmc->peer));
-  if (GNUNET_CORE_KX_STATE_UP != dmc->kx->status)
-  {
-    GNUNET_STATISTICS_update (GSC_stats,
-                              gettext_noop ("# PAYLOAD dropped (out of order)"),
-                              1,
-                              GNUNET_NO);
-    return GNUNET_OK;
-  }
-  switch (ntohs (m->type))
-  {
-  case GNUNET_MESSAGE_TYPE_CORE_BINARY_TYPE_MAP:
-  case GNUNET_MESSAGE_TYPE_CORE_COMPRESSED_TYPE_MAP:
-    GSC_SESSIONS_set_typemap (dmc->peer, m);
-    return GNUNET_OK;
-  case GNUNET_MESSAGE_TYPE_CORE_CONFIRM_TYPE_MAP:
-    GSC_SESSIONS_confirm_typemap (dmc->peer, m);
-    return GNUNET_OK;
-  default:
-    GSC_CLIENTS_deliver_message (dmc->peer,
-                                 m,
-                                 ntohs (m->size),
-                                 GNUNET_CORE_OPTION_SEND_FULL_INBOUND);
-    GSC_CLIENTS_deliver_message (dmc->peer,
-                                 m,
-                                 sizeof (struct GNUNET_MessageHeader),
-                                 GNUNET_CORE_OPTION_SEND_HDR_INBOUND);
-  }
-  return GNUNET_OK;
-}
-
-
 /**
  * Setup the message that links the ephemeral key to our persistent
  * public key and generate the appropriate signature.
@@ -1829,8 +1808,6 @@ GSC_KX_init (struct GNUNET_CRYPTO_EddsaPrivateKey *pk)
   rekey_task = GNUNET_SCHEDULER_add_delayed (REKEY_FREQUENCY,
                                              &do_rekey,
                                              NULL);
-  mst = GNUNET_SERVER_mst_create (&deliver_message,
-                                 NULL);
   transport
     = GNUNET_TRANSPORT_core_connect (GSC_cfg,
                                     &GSC_my_identity,
@@ -1874,11 +1851,6 @@ GSC_KX_done ()
     GNUNET_free (my_private_key);
     my_private_key = NULL;
   }
-  if (NULL != mst)
-  {
-    GNUNET_SERVER_mst_destroy (mst);
-    mst = NULL;
-  }
   if (NULL != nc)
   {
     GNUNET_notification_context_destroy (nc);
index 74f595c5ed9c2ca4ec3be60592af2c5e7b736168..079f74ce4dce88df661fc4e07b894376b6f67433 100644 (file)
@@ -882,11 +882,10 @@ handle_client_response (void *cls,
  * message is received by the tokenizer from the DNS hijack process.
  *
  * @param cls closure
- * @param client identification of the client
  * @param message the actual message, a DNS request we should handle
  */
 static int
-process_helper_messages (void *cls GNUNET_UNUSED, void *client,
+process_helper_messages (void *cls,
                         const struct GNUNET_MessageHeader *message)
 {
   uint16_t msize;
index a32cb3086bd0b4d2c13864c47e661c9c98be130c..15a462ada4526f4c83153508cbad0caf2dcce6d7 100644 (file)
@@ -2905,12 +2905,10 @@ tcp_from_helper (const struct GNUNET_TUN_TcpHeader *tcp,
  * Receive packets from the helper-process
  *
  * @param cls unused
- * @param client unsued
  * @param message message received from helper
  */
 static int
 message_token (void *cls GNUNET_UNUSED,
-               void *client GNUNET_UNUSED,
                const struct GNUNET_MessageHeader *message)
 {
   const struct GNUNET_TUN_Layer2PacketHeader *pkt_tun;
index 2f79c7c05b87077502e2be0b4f2484454ff17606..7b9f178fdcf511a17f0fb9a373aeb0a9b2e53fd6 100644 (file)
@@ -245,12 +245,10 @@ finish_scan (void *cls)
  * Calls the scanner progress handler.
  *
  * @param cls the closure (directory scanner object)
- * @param client always NULL
  * @param msg message from the helper process
  */
 static int
 process_helper_msgs (void *cls,
-                    void *client,
                     const struct GNUNET_MessageHeader *msg)
 {
   struct GNUNET_FS_DirScanner *ds = cls;
index 4fb2577fdffe025cf8e6479142448fa5ba42f596..b745da125ff7ac99b0171cd35bcc2d11f246c844 100644 (file)
@@ -38,7 +38,6 @@ gnunetinclude_HEADERS = \
   gnunet_common.h \
   gnunet_constants.h \
   gnunet_configuration_lib.h \
-  gnunet_connection_lib.h \
   gnunet_consensus_service.h \
   gnunet_container_lib.h \
   gnunet_conversation_service.h \
@@ -107,7 +106,6 @@ gnunetinclude_HEADERS = \
   gnunet_scalarproduct_service.h \
   gnunet_scheduler_lib.h \
   gnunet_secretsharing_service.h \
-  gnunet_server_lib.h \
   gnunet_service_lib.h \
   gnunet_set_service.h \
   gnunet_signal_lib.h \
diff --git a/src/include/gnunet_connection_lib.h b/src/include/gnunet_connection_lib.h
deleted file mode 100644 (file)
index e9dd95d..0000000
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C) 2009 GNUnet e.V.
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-
-/**
- * @author Christian Grothoff
- *
- * @file include/gnunet_connection_lib.h
- * Basic, low-level TCP networking interface
- *
- * @defgroup connection  Connection library
- * Basic, low-level TCP networking interface
- * @{
- */
-#ifndef GNUNET_CONNECTION_LIB_H
-#define GNUNET_CONNECTION_LIB_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0                           /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-#include "gnunet_network_lib.h"
-#include "gnunet_scheduler_lib.h"
-#include "gnunet_time_lib.h"
-
-/**
- * Timeout we use on TCP connect before trying another
- * result from the DNS resolver.  Actual value used
- * is this value divided by the number of address families.
- * Default is 5s.
- */
-#define GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
-
-/**
- * @brief handle for a network connection
- */
-struct GNUNET_CONNECTION_Handle;
-
-
-/**
- * Credentials for UNIX domain sockets.
- */
-struct GNUNET_CONNECTION_Credentials
-{
-  /**
-   * UID of the other end of the connection.
-   */
-  uid_t uid;
-
-  /**
-   * GID of the other end of the connection.
-   */
-  gid_t gid;
-};
-
-
-/**
- * Function to call for access control checks.
- *
- * @param cls closure
- * @param ucred credentials, if available, otherwise NULL
- * @param addr address
- * @param addrlen length of address
- * @return GNUNET_YES to allow, GNUNET_NO to deny, GNUNET_SYSERR
- *   for unknown address family (will be denied).
- */
-typedef int (*GNUNET_CONNECTION_AccessCheck) (void *cls,
-                                              const struct
-                                              GNUNET_CONNECTION_Credentials *
-                                              ucred,
-                                              const struct sockaddr * addr,
-                                              socklen_t addrlen);
-
-
-/**
- * Callback function for data received from the network.  Note that
- * both "available" and "err" would be 0 if the read simply timed out.
- *
- * @param cls closure
- * @param buf pointer to received data
- * @param available number of bytes availabe in "buf",
- *        possibly 0 (on errors)
- * @param addr address of the sender
- * @param addrlen size of addr
- * @param errCode value of errno (on errors receiving)
- */
-typedef void (*GNUNET_CONNECTION_Receiver) (void *cls, const void *buf,
-                                            size_t available,
-                                            const struct sockaddr * addr,
-                                            socklen_t addrlen, int errCode);
-
-/**
- * Set the persist option on this connection handle.  Indicates
- * that the underlying socket or fd should never really be closed.
- * Used for indicating process death.
- *
- * @param connection the connection to set persistent
- */
-void
-GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *connection);
-
-/**
- * Disable the "CORK" feature for communication with the given socket,
- * forcing the OS to immediately flush the buffer on transmission
- * instead of potentially buffering multiple messages.  Essentially
- * reduces the OS send buffers to zero.
- * Used to make sure that the last messages sent through the connection
- * reach the other side before the process is terminated.
- *
- * @param connection the connection to make flushing and blocking
- * @return #GNUNET_OK on success
- */
-int
-GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection);
-
-
-/**
- * Create a connection handle by (asynchronously) connecting to a host.
- * This function returns immediately, even if the connection has not
- * yet been established.  This function only creates TCP connections.
- *
- * @param s socket to connect
- * @param serv_addr server address
- * @param addrlen length of server address
- * @return the connection handle
- */
-struct GNUNET_CONNECTION_Handle *
-GNUNET_CONNECTION_connect_socket (struct GNUNET_NETWORK_Handle *s,
-                                  const struct sockaddr *serv_addr,
-                                  socklen_t addrlen);
-
-
-/**
- * Create a connection handle by boxing an existing OS socket.  The OS
- * socket should henceforth be no longer used directly.
- * #GNUNET_CONNECTION_destroy() will close it.
- *
- * @param osSocket existing socket to box
- * @return the boxed socket handle
- */
-struct GNUNET_CONNECTION_Handle *
-GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket);
-
-
-/**
- * Create a connection handle by accepting on a listen socket.  This
- * function may block if the listen socket has no connection ready.
- *
- * @param access_cb function to use to check if access is allowed
- * @param access_cb_cls closure for @a access_cb
- * @param lsock listen socket
- * @return the connection handle, NULL on error (for example, access refused)
- */
-struct GNUNET_CONNECTION_Handle *
-GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access_cb,
-                                      void *access_cb_cls,
-                                      struct GNUNET_NETWORK_Handle *lsock);
-
-
-/**
- * Create a connection handle by (asynchronously) connecting to a host.
- * This function returns immediately, even if the connection has not
- * yet been established.  This function only creates TCP connections.
- *
- * @param cfg configuration to use
- * @param hostname name of the host to connect to
- * @param port port to connect to
- * @return the connection handle
- */
-struct GNUNET_CONNECTION_Handle *
-GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle
-                                       *cfg, const char *hostname,
-                                       uint16_t port);
-
-
-/**
- * Create a connection handle by connecting to a UNIX domain service.
- * This function returns immediately, even if the connection has not
- * yet been established.  This function only creates UNIX connections.
- *
- * @param cfg configuration to use
- * @param unixpath path to connect to)
- * @return the connection handle, NULL on systems without UNIX support
- */
-struct GNUNET_CONNECTION_Handle *
-GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct
-                                                   GNUNET_CONFIGURATION_Handle
-                                                   *cfg, const char *unixpath);
-
-
-
-
-/**
- * Create a connection handle by (asynchronously) connecting to a host.
- * This function returns immediately, even if the connection has not
- * yet been established.  This function only creates TCP connections.
- *
- * @param af_family address family to use
- * @param serv_addr server address
- * @param addrlen length of server address
- * @return the connection handle
- */
-struct GNUNET_CONNECTION_Handle *
-GNUNET_CONNECTION_create_from_sockaddr (int af_family,
-                                        const struct sockaddr *serv_addr,
-                                        socklen_t addrlen);
-
-/**
- * Check if connection is valid (no fatal errors have happened so far).
- * Note that a connection that is still trying to connect is considered
- * valid.
- *
- * @param connection handle to check
- * @return GNUNET_YES if valid, GNUNET_NO otherwise
- */
-int
-GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *connection);
-
-
-/**
- * Obtain the network address of the other party.
- *
- * @param connection the client to get the address for
- * @param addr where to store the address
- * @param addrlen where to store the length of the address
- * @return GNUNET_OK on success
- */
-int
-GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *connection,
-                               void **addr, size_t * addrlen);
-
-
-/**
- * Close the connection and free associated resources.  There must
- * not be any pending requests for reading or writing to the
- * connection at this time.
- *
- * @param connection connection to destroy
- */
-void
-GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection);
-
-
-/**
- * Receive data from the given connection.  Note that this function will
- * call "receiver" asynchronously using the scheduler.  It will
- * "immediately" return.  Note that there MUST only be one active
- * receive call per connection at any given point in time (so do not
- * call receive again until the receiver callback has been invoked).
- *
- * @param connection connection handle
- * @param max maximum number of bytes to read
- * @param timeout maximum amount of time to wait
- * @param receiver function to call with received data
- * @param receiver_cls closure for receiver
- */
-void
-GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *connection, size_t max,
-                           struct GNUNET_TIME_Relative timeout,
-                           GNUNET_CONNECTION_Receiver receiver,
-                           void *receiver_cls);
-
-
-/**
- * Cancel receive job on the given connection.  Note that the
- * receiver callback must not have been called yet in order
- * for the cancellation to be valid.
- *
- * @param connection connection handle
- * @return closure of the original receiver callback closure
- */
-void *
-GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *connection);
-
-
-/**
- * Function called to notify a client about the connection begin ready
- * to queue more data.  @a buf will be NULL and @a size zero if the
- * connection was closed for writing in the meantime.
- *
- * @param cls closure
- * @param size number of bytes available in @a buf
- * @param buf where the callee should write the message
- * @return number of bytes written to @a buf
- */
-typedef size_t
-(*GNUNET_CONNECTION_TransmitReadyNotify) (void *cls,
-                                          size_t size,
-                                          void *buf);
-
-
-/**
- * Opaque handle that can be used to cancel
- * a transmit-ready notification.
- */
-struct GNUNET_CONNECTION_TransmitHandle;
-
-/**
- * Ask the connection to call us once the specified number of bytes
- * are free in the transmission buffer.  Will never call the @a notify
- * callback in this task, but always first go into the scheduler.  Note that
- * this function will abort if "size" is greater than
- * #GNUNET_SERVER_MAX_MESSAGE_SIZE.
- *
- * Note that "notify" will be called either when enough
- * buffer space is available OR when the connection is destroyed.
- * The size parameter given to notify is guaranteed to be
- * larger or equal to size if the buffer is ready, or zero
- * if the connection was destroyed (or at least closed for
- * writing).  Finally, any time before 'notify' is called, a
- * client may call "notify_transmit_ready_cancel" to cancel
- * the transmission request.
- *
- * Only one transmission request can be scheduled at the same
- * time.  Notify will be run with the same scheduler priority
- * as that of the caller.
- *
- * @param connection connection
- * @param size number of bytes to send
- * @param timeout after how long should we give up (and call
- *        notify with buf NULL and size 0)?
- * @param notify function to call when buffer space is available
- * @param notify_cls closure for notify
- * @return non-NULL if the notify callback was queued,
- *         NULL if we are already going to notify someone else (busy)
- */
-struct GNUNET_CONNECTION_TransmitHandle *
-GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connection,
-                                         size_t size,
-                                         struct GNUNET_TIME_Relative timeout,
-                                         GNUNET_CONNECTION_TransmitReadyNotify
-                                         notify, void *notify_cls);
-
-
-/**
- * Cancel the specified transmission-ready
- * notification.
- *
- * @param th handle for notification to cancel
- */
-void
-GNUNET_CONNECTION_notify_transmit_ready_cancel (struct
-                                                GNUNET_CONNECTION_TransmitHandle
-                                                *th);
-
-
-/**
- * Create a connection to be proxied using a given connection.
- *
- * @param cph connection to proxy server
- * @return connection to be proxied
- */
-struct GNUNET_CONNECTION_Handle *
-GNUNET_CONNECTION_create_proxied_from_handshake (struct GNUNET_CONNECTION_Handle *cph);
-
-
-/**
- * Activate proxied connection and destroy initial proxy handshake connection.
- * There must not be any pending requests for reading or writing to the
- * proxy hadshake connection at this time.
- *
- * @param proxied connection connection to proxy server
- */
-void
-GNUNET_CONNECTION_acivate_proxied (struct GNUNET_CONNECTION_Handle *proxied);
-
-
-#if 0                           /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-/* ifndef GNUNET_CONNECTION_LIB_H */
-#endif
-
-/** @} */  /* end of group */
-
-/* end of gnunet_connection_lib.h */
index db0ca98aafc17655bd26528e113d3b25c943a753..60b3ff6816f7c355f8e7cbe36f181c9b302355a7 100644 (file)
@@ -38,7 +38,8 @@
 #define GNUNET_HELPER_LIB_H
 
 #include "gnunet_scheduler_lib.h"
-#include "gnunet_server_lib.h"
+#include "gnunet_mst_lib.h"
+
 
 /**
  * The handle to a helper process.
@@ -52,7 +53,8 @@ struct GNUNET_HELPER_Handle;
  *
  * @param cls the closure from GNUNET_HELPER_start()
  */
-typedef void (*GNUNET_HELPER_ExceptionCallback) (void *cls);
+typedef void
+(*GNUNET_HELPER_ExceptionCallback) (void *cls);
 
 
 /**
@@ -75,7 +77,7 @@ struct GNUNET_HELPER_Handle *
 GNUNET_HELPER_start (int with_control_pipe,
                     const char *binary_name,
                     char *const binary_argv[],
-                    GNUNET_SERVER_MessageTokenizerCallback cb,
+                    GNUNET_MessageTokenizerCallback cb,
                     GNUNET_HELPER_ExceptionCallback exp_cb,
                     void *cb_cls);
 
index b05128ccc3bd8314abe892c91ee495145175ffd3..ecee1b223bd2ac690aebd956d9048ef8336fe4e3 100644 (file)
@@ -35,6 +35,7 @@
 #ifndef GNUNET_MQ_LIB_H
 #define GNUNET_MQ_LIB_H
 
+#include "gnunet_scheduler_lib.h"
 
 /**
  * Allocate an envelope, with extra space allocated after the space needed
diff --git a/src/include/gnunet_server_lib.h b/src/include/gnunet_server_lib.h
deleted file mode 100644 (file)
index 5da31bc..0000000
+++ /dev/null
@@ -1,887 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C) 2009-2013 GNUnet e.V.
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-
-/**
- * @author Christian Grothoff
- *
- * @file
- * Library for building GNUnet network servers
-
- * @defgroup server  Server library
- * Library for building GNUnet network servers
- *
- * Provides functions for a server that communicates with clients.
- *
- * @see [Documentation](https://gnunet.org/ipc)
- *
- * @{
- */
-
-#ifndef GNUNET_SERVER_LIB_H
-#define GNUNET_SERVER_LIB_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#if 0                           /* keep Emacsens' auto-indent happy */
-}
-#endif
-#endif
-
-#include "gnunet_common.h"
-#include "gnunet_connection_lib.h"
-
-
-/**
- * Largest supported message (to be precise, one byte more
- * than the largest possible message, so tests involving
- * this value should check for messages being smaller than
- * this value).
- */
-#define GNUNET_SERVER_MAX_MESSAGE_SIZE 65536
-
-/**
- * Smallest supported message.
- */
-#define GNUNET_SERVER_MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
-
-/**
- * @brief handle for a server
- */
-struct GNUNET_SERVER_Handle;
-
-/**
- * @brief opaque handle for a client of the server
- */
-struct GNUNET_SERVER_Client;
-
-/**
- * @brief opaque handle server returns for aborting transmission to a client.
- */
-struct GNUNET_SERVER_TransmitHandle;
-
-
-/**
- * Functions with this signature are called whenever a message is
- * received.
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message
- */
-typedef void
-(*GNUNET_SERVER_MessageCallback) (void *cls,
-                                  struct GNUNET_SERVER_Client *client,
-                                  const struct GNUNET_MessageHeader *message);
-
-
-/**
- * Message handler.  Each struct specifies how to handle on particular
- * type of message received.
- */
-struct GNUNET_SERVER_MessageHandler
-{
-  /**
-   * Function to call for messages of "type".
-   */
-  GNUNET_SERVER_MessageCallback callback;
-
-  /**
-   * Closure argument for @e callback.
-   */
-  void *callback_cls;
-
-  /**
-   * Type of the message this handler covers.
-   */
-  uint16_t type;
-
-  /**
-   * Expected size of messages of this type.  Use 0 for
-   * variable-size.  If non-zero, messages of the given
-   * type will be discarded (and the connection closed)
-   * if they do not have the right size.
-   */
-  uint16_t expected_size;
-
-};
-
-
-/**
- * Create a new server.
- *
- * @param access_cb function for access control
- * @param access_cb_cls closure for @a access_cb
- * @param lsocks NULL-terminated array of listen sockets
- * @param idle_timeout after how long should we timeout idle connections?
- * @param require_found if #GNUNET_YES, connections sending messages of unknown type
- *        will be closed
- * @return handle for the new server, NULL on error
- *         (typically, "port" already in use)
- */
-struct GNUNET_SERVER_Handle *
-GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access_cb,
-                                   void *access_cb_cls,
-                                   struct GNUNET_NETWORK_Handle **lsocks,
-                                   struct GNUNET_TIME_Relative idle_timeout,
-                                   int require_found);
-
-/**
- * Create a new server.
- *
- * @param access_cb function for access control
- * @param access_cb_cls closure for @a access_cb
- * @param server_addr address toes listen on (including port), NULL terminated array
- * @param socklen lengths of respective @a server_addr
- * @param idle_timeout after how long should we timeout idle connections?
- * @param require_found if #GNUNET_YES, connections sending messages of unknown type
- *        will be closed
- * @return handle for the new server, NULL on error
- *         (typically, "port" already in use)
- */
-struct GNUNET_SERVER_Handle *
-GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access_cb,
-                     void *access_cb_cls,
-                      struct sockaddr *const *server_addr,
-                      const socklen_t *socklen,
-                      struct GNUNET_TIME_Relative idle_timeout,
-                      int require_found);
-
-
-/**
- * Suspend accepting connections from the listen socket temporarily.
- * Resume activity using #GNUNET_SERVER_resume.
- *
- * @param server server to stop accepting connections.
- */
-void
-GNUNET_SERVER_suspend (struct GNUNET_SERVER_Handle *server);
-
-
-/**
- * Resume accepting connections from the listen socket.
- *
- * @param server server to resume accepting connections.
- */
-void
-GNUNET_SERVER_resume (struct GNUNET_SERVER_Handle *server);
-
-
-/**
- * Stop the listen socket and get ready to shutdown the server once
- * only clients marked using #GNUNET_SERVER_client_mark_monitor are
- * left.
- *
- * @param server server to stop listening on
- */
-void
-GNUNET_SERVER_stop_listening (struct GNUNET_SERVER_Handle *server);
-
-
-/**
- * Free resources held by this server.
- *
- * @param server server to destroy
- */
-void
-GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *server);
-
-
-/**
- * Add additional handlers to an existing server.
- *
- * @param server the server to add handlers to
- * @param handlers array of message handlers for
- *        incoming messages; the last entry must
- *        have "NULL" for the "callback"; multiple
- *        entries for the same type are allowed,
- *        they will be called in order of occurence.
- *        These handlers can be removed later;
- *        the handlers array must exist until removed
- *        (or server is destroyed).
- */
-void
-GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
-                            const struct GNUNET_SERVER_MessageHandler *handlers);
-
-
-/**
- * Notify us when the server has enough space to transmit
- * a message of the given size to the given client.
- *
- * @param client client to transmit message to
- * @param size requested amount of buffer space
- * @param timeout after how long should we give up (and call
- *        notify with buf NULL and size 0)?
- * @param callback function to call when space is available
- * @param callback_cls closure for @a callback
- * @return non-NULL if the notify callback was queued; can be used
- *           to cancel the request using
- *           #GNUNET_SERVER_notify_transmit_ready_cancel.
- *         NULL if we are already going to notify someone else (busy)
- */
-struct GNUNET_SERVER_TransmitHandle *
-GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
-                                     size_t size,
-                                     struct GNUNET_TIME_Relative timeout,
-                                     GNUNET_CONNECTION_TransmitReadyNotify callback,
-                                     void *callback_cls);
-
-
-/**
- * Abort transmission request.
- *
- * @param th request to abort
- */
-void
-GNUNET_SERVER_notify_transmit_ready_cancel (struct GNUNET_SERVER_TransmitHandle *th);
-
-
-/**
- * Set the 'monitor' flag on this client.  Clients which have been
- * marked as 'monitors' won't prevent the server from shutting down
- * once #GNUNET_SERVER_stop_listening has been invoked.  The idea is
- * that for "normal" clients we likely want to allow them to process
- * their requests; however, monitor-clients are likely to 'never'
- * disconnect during shutdown and thus will not be considered when
- * determining if the server should continue to exist after
- * #GNUNET_SERVER_destroy has been called.
- *
- * @param client the client to set the 'monitor' flag on
- */
-void
-GNUNET_SERVER_client_mark_monitor (struct GNUNET_SERVER_Client *client);
-
-
-/**
- * Set the persistent flag on this client, used to setup client
- * connection to only be killed when the process of the service it's
- * connected to is actually dead.  This API is used during shutdown
- * signalling within ARM, and it is not expected that typical users
- * of the API would need this function.
- *
- * @param client the client to set the persistent flag on
- */
-void
-GNUNET_SERVER_client_persist_ (struct GNUNET_SERVER_Client *client);
-
-
-/**
- * Resume receiving from this client, we are done processing the
- * current request.  This function must be called from within each
- * #GNUNET_SERVER_MessageCallback (or its respective continuations).
- *
- * @param client client we were processing a message of
- * @param success #GNUNET_OK to keep the connection open and
- *                          continue to receive
- *                #GNUNET_NO to close the connection (normal behavior)
- *                #GNUNET_SYSERR to close the connection (signal
- *                          serious error)
- */
-void
-GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client,
-                           int success);
-
-
-/**
- * Change the timeout for a particular client.  Decreasing the timeout
- * may not go into effect immediately (only after the previous timeout
- * times out or activity happens on the socket).
- *
- * @param client the client to update
- * @param timeout new timeout for activities on the socket
- */
-void
-GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client,
-                                  struct GNUNET_TIME_Relative timeout);
-
-
-/**
- * Return user context associated with the given client.
- * Note: you should probably use the macro (call without the underscore).
- *
- * @param client client to query
- * @param size number of bytes in user context struct (for verification only)
- * @return pointer to user context
- */
-void *
-GNUNET_SERVER_client_get_user_context_ (struct GNUNET_SERVER_Client *client,
-                                       size_t size);
-
-
-/**
- * Set user context to be associated with the given client.
- * Note: you should probably use the macro (call without the underscore).
- *
- * @param client client to query
- * @param ptr pointer to user context
- * @param size number of bytes in user context struct (for verification only)
- */
-void
-GNUNET_SERVER_client_set_user_context_ (struct GNUNET_SERVER_Client *client,
-                                       void *ptr,
-                                       size_t size);
-
-
-/**
- * Return user context associated with the given client.
- *
- * @param client client to query
- * @param type expected return type (i.e. 'struct Foo')
- * @return pointer to user context of type 'type *'.
- */
-#define GNUNET_SERVER_client_get_user_context(client,type)              \
-  (type *) GNUNET_SERVER_client_get_user_context_ (client, sizeof (type))
-
-/**
- * Set user context to be associated with the given client.
- *
- * @param client client to query
- * @param value pointer to user context
- */
-#define GNUNET_SERVER_client_set_user_context(client,value)             \
-  GNUNET_SERVER_client_set_user_context_ (client, value, sizeof (*value))
-
-
-/**
- * Disable the warning the server issues if a message is not acknowledged
- * in a timely fashion.  Use this call if a client is intentionally delayed
- * for a while.  Only applies to the current message.
- *
- * @param client client for which to disable the warning
- */
-void
-GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client
-                                            *client);
-
-
-/**
- * Inject a message into the server, pretend it came
- * from the specified client.  Delivery of the message
- * will happen instantly (if a handler is installed;
- * otherwise the call does nothing).
- *
- * @param server the server receiving the message
- * @param sender the "pretended" sender of the message
- *        can be NULL!
- * @param message message to transmit
- * @return #GNUNET_OK if the message was OK and the
- *                   connection can stay open
- *         #GNUNET_SYSERR if the connection to the
- *         client should be shut down
- */
-int
-GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
-                      struct GNUNET_SERVER_Client *sender,
-                      const struct GNUNET_MessageHeader *message);
-
-
-/**
- * Add a TCP socket-based connection to the set of handles managed by
- * this server.  Use this function for outgoing (P2P) connections that
- * we initiated (and where this server should process incoming
- * messages).
- *
- * @param server the server to use
- * @param connection the connection to manage (client must
- *        stop using this connection from now on)
- * @return the client handle
- */
-struct GNUNET_SERVER_Client *
-GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server,
-                              struct GNUNET_CONNECTION_Handle *connection);
-
-
-/**
- * Notify the server that the given client handle should
- * be kept (keeps the connection up if possible, increments
- * the internal reference counter).
- *
- * @param client the client to keep
- */
-void
-GNUNET_SERVER_client_keep (struct GNUNET_SERVER_Client *client);
-
-
-/**
- * Notify the server that the given client handle is no
- * longer required.  Decrements the reference counter.  If
- * that counter reaches zero an inactive connection maybe
- * closed.
- *
- * @param client the client to drop
- */
-void
-GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client);
-
-
-/**
- * Obtain the network address of the other party.
- *
- * @param client the client to get the address for
- * @param addr where to store the address
- * @param addrlen where to store the length of @a addr
- * @return #GNUNET_OK on success
- */
-int
-GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client,
-                                  void **addr, size_t *addrlen);
-
-
-/**
- * Functions with this signature are called whenever a client
- * is disconnected on the network level.
- *
- * @param cls closure
- * @param client identification of the client; NULL
- *        for the last call when the server is destroyed
- */
-typedef void
-(*GNUNET_SERVER_DisconnectCallback) (void *cls,
-                                     struct GNUNET_SERVER_Client *client);
-
-
-/**
- * Functions with this signature are called whenever a client
- * is connected on the network level.
- *
- * @param cls closure
- * @param client identification of the client
- */
-typedef void
-(*GNUNET_SERVER_ConnectCallback) (void *cls,
-                                  struct GNUNET_SERVER_Client *client);
-
-
-/**
- * Ask the server to notify us whenever a client disconnects.
- * This function is called whenever the actual network connection
- * is closed; the reference count may be zero or larger than zero
- * at this point.  If the server is destroyed before this
- * notification is explicitly cancelled, the 'callback' will
- * once be called with a 'client' argument of NULL to indicate
- * that the server itself is now gone (and that the callback
- * won't be called anymore and also can no longer be cancelled).
- *
- * @param server the server manageing the clients
- * @param callback function to call on disconnect
- * @param callback_cls closure for @a callback
- */
-void
-GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server,
-                                 GNUNET_SERVER_DisconnectCallback callback,
-                                 void *callback_cls);
-
-
-/**
- * Ask the server to notify us whenever a client connects.
- * This function is called whenever the actual network connection
- * is opened. If the server is destroyed before this
- * notification is explicitly cancelled, the @a callback will
- * once be called with a 'client' argument of NULL to indicate
- * that the server itself is now gone (and that the callback
- * won't be called anymore and also can no longer be cancelled).
- *
- * @param server the server manageing the clients
- * @param callback function to call on sconnect
- * @param callback_cls closure for @a callback
- */
-void
-GNUNET_SERVER_connect_notify (struct GNUNET_SERVER_Handle *server,
-                             GNUNET_SERVER_ConnectCallback callback,
-                             void *callback_cls);
-
-
-/**
- * Ask the server to stop notifying us whenever a client disconnects.
- * Arguments must match exactly those given to
- * #GNUNET_SERVER_disconnect_notify.  It is not necessary to call this
- * function during shutdown of the server; in fact, most applications
- * will never use this function.
- *
- * @param server the server manageing the clients
- * @param callback function to call on disconnect
- * @param callback_cls closure for @a callback
- */
-void
-GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server,
-                                        GNUNET_SERVER_DisconnectCallback callback,
-                                        void *callback_cls);
-
-
-/**
- * Ask the server to stop notifying us whenever a client connects.
- * Arguments must match exactly those given to
- * #GNUNET_SERVER_connect_notify.  It is not necessary to call this
- * function during shutdown of the server; in fact, most applications
- * will never use this function.
- *
- * @param server the server manageing the clients
- * @param callback function to call on connect
- * @param callback_cls closure for @a callback
- */
-void
-GNUNET_SERVER_connect_notify_cancel (struct GNUNET_SERVER_Handle *server,
-                                    GNUNET_SERVER_ConnectCallback callback,
-                                    void *callback_cls);
-
-
-/**
- * Ask the server to disconnect from the given client.  This is the
- * same as passing #GNUNET_SYSERR to #GNUNET_SERVER_receive_done,
- * except that it allows dropping of a client even when not handling a
- * message from that client.
- *
- * @param client the client to disconnect from
- */
-void
-GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client);
-
-
-/**
- * Disable the "CORK" feature for communication with the given client,
- * forcing the OS to immediately flush the buffer on transmission
- * instead of potentially buffering multiple messages.
- *
- * @param client handle to the client
- * @return #GNUNET_OK on success
- */
-int
-GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client);
-
-
-/**
- * The tansmit context is the key datastructure for a conveniance API
- * used for transmission of complex results to the client followed
- * ONLY by signaling receive_done with success or error
- */
-struct GNUNET_SERVER_TransmitContext;
-
-
-/**
- * Create a new transmission context for the given client.
- *
- * @param client client to create the context for.
- * @return NULL on error
- */
-struct GNUNET_SERVER_TransmitContext *
-GNUNET_SERVER_transmit_context_create (struct GNUNET_SERVER_Client *client);
-
-
-/**
- * Append a message to the transmission context.
- * All messages in the context will be sent by
- * the #GNUNET_SERVER_transmit_context_run method.
- *
- * @param tc context to use
- * @param data what to append to the result message
- * @param length length of @a data
- * @param type type of the message
- */
-void
-GNUNET_SERVER_transmit_context_append_data (struct GNUNET_SERVER_TransmitContext *tc,
-                                            const void *data,
-                                            size_t length, uint16_t type);
-
-
-/**
- * Append a message to the transmission context.
- * All messages in the context will be sent by
- * the transmit_context_run method.
- *
- * @param tc context to use
- * @param msg message to append
- */
-void
-GNUNET_SERVER_transmit_context_append_message (struct GNUNET_SERVER_TransmitContext *tc,
-                                               const struct GNUNET_MessageHeader *msg);
-
-
-/**
- * Execute a transmission context.  If there is an error in the
- * transmission, the receive_done method will be called with an error
- * code (#GNUNET_SYSERR), otherwise with #GNUNET_OK.
- *
- * @param tc transmission context to use
- * @param timeout when to time out and abort the transmission
- */
-void
-GNUNET_SERVER_transmit_context_run (struct GNUNET_SERVER_TransmitContext *tc,
-                                    struct GNUNET_TIME_Relative timeout);
-
-
-/**
- * Destroy a transmission context.  This function must not be called
- * after #GNUNET_SERVER_transmit_context_run.
- *
- * @param tc transmission context to destroy
- * @param success code to give to #GNUNET_SERVER_receive_done  for
- *        the client: #GNUNET_OK to keep the connection open and
- *                          continue to receive
- *                #GNUNET_NO to close the connection (normal behavior)
- *                #GNUNET_SYSERR to close the connection (signal
- *                          serious error)
- */
-void
-GNUNET_SERVER_transmit_context_destroy (struct GNUNET_SERVER_TransmitContext *tc,
-                                        int success);
-
-
-/**
- * The notification context is the key datastructure for a conveniance
- * API used for transmission of notifications to the client until the
- * client disconnects or is disconnected (or the notification context
- * is destroyed, in which case we disconnect these clients).
- * Essentially, all (notification) messages are queued up until the
- * client is able to read them.
- */
-struct GNUNET_SERVER_NotificationContext;
-
-
-/**
- * Create a new notification context.
- *
- * @param server server for which this function creates the context
- * @param queue_length maximum number of messages to keep in
- *        the notification queue; optional messages are dropped
- *        if the queue gets longer than this number of messages
- * @return handle to the notification context
- */
-struct GNUNET_SERVER_NotificationContext *
-GNUNET_SERVER_notification_context_create (struct GNUNET_SERVER_Handle *server,
-                                           unsigned int queue_length);
-
-
-/**
- * Destroy the context, force disconnect for all clients.
- *
- * @param nc context to destroy.
- */
-void
-GNUNET_SERVER_notification_context_destroy (struct GNUNET_SERVER_NotificationContext *nc);
-
-
-/**
- * Add a client to the notification context.
- *
- * @param nc context to modify
- * @param client client to add
- */
-void
-GNUNET_SERVER_notification_context_add (struct GNUNET_SERVER_NotificationContext *nc,
-                                        struct GNUNET_SERVER_Client *client);
-
-
-/**
- * Send a message to a particular client; must have
- * already been added to the notification context.
- *
- * @param nc context to modify
- * @param client client to transmit to
- * @param msg message to send
- * @param can_drop can this message be dropped due to queue length limitations
- */
-void
-GNUNET_SERVER_notification_context_unicast (struct GNUNET_SERVER_NotificationContext *nc,
-                                            struct GNUNET_SERVER_Client *client,
-                                            const struct GNUNET_MessageHeader *msg,
-                                            int can_drop);
-
-
-/**
- * Send a message to all clients of this context.
- *
- * @param nc context to modify
- * @param msg message to send
- * @param can_drop can this message be dropped due to queue length limitations
- */
-void
-GNUNET_SERVER_notification_context_broadcast (struct GNUNET_SERVER_NotificationContext *nc,
-                                              const struct GNUNET_MessageHeader *msg,
-                                              int can_drop);
-
-
-/**
- * Return active number of subscribers in this context.
- *
- * @param nc context to query
- * @return number of current subscribers
- */
-unsigned int
-GNUNET_SERVER_notification_context_get_size (struct GNUNET_SERVER_NotificationContext *nc);
-
-
-/**
- * Create a message queue for a server's client.
- *
- * @param client the client
- * @return the message queue
- */
-struct GNUNET_MQ_Handle *
-GNUNET_MQ_queue_for_server_client (struct GNUNET_SERVER_Client *client);
-
-
-/**
- * Handle to a message stream tokenizer.
- */
-struct GNUNET_SERVER_MessageStreamTokenizer;
-
-
-/**
- * Functions with this signature are called whenever a
- * complete message is received by the tokenizer.
- *
- * Do not call #GNUNET_SERVER_mst_destroy from within
- * the scope of this callback.
- *
- * @param cls closure
- * @param client identification of the client
- * @param message the actual message
- * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
- */
-typedef int
-(*GNUNET_SERVER_MessageTokenizerCallback) (void *cls,
-                                           void *client,
-                                           const struct GNUNET_MessageHeader *message);
-
-
-/**
- * Create a message stream tokenizer.
- *
- * @param cb function to call on completed messages
- * @param cb_cls closure for @a cb
- * @return handle to tokenizer
- */
-struct GNUNET_SERVER_MessageStreamTokenizer *
-GNUNET_SERVER_mst_create (GNUNET_SERVER_MessageTokenizerCallback cb,
-                          void *cb_cls);
-
-
-/**
- * Add incoming data to the receive buffer and call the
- * callback for all complete messages.
- *
- * @param mst tokenizer to use
- * @param client_identity ID of client for which this is a buffer,
- *        can be NULL (will be passed back to 'cb')
- * @param buf input data to add
- * @param size number of bytes in @a buf
- * @param purge should any excess bytes in the buffer be discarded
- *       (i.e. for packet-based services like UDP)
- * @param one_shot only call callback once, keep rest of message in buffer
- * @return #GNUNET_OK if we are done processing (need more data)
- *         #GNUNET_NO if one_shot was set and we have another message ready
- *         #GNUNET_SYSERR if the data stream is corrupt
- */
-int
-GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
-                           void *client_identity,
-                           const char *buf, size_t size,
-                           int purge, int one_shot);
-
-
-/**
- * Destroys a tokenizer.
- *
- * @param mst tokenizer to destroy
- */
-void
-GNUNET_SERVER_mst_destroy (struct GNUNET_SERVER_MessageStreamTokenizer *mst);
-
-
-/**
- * Signature of a function to create a custom tokenizer.
- *
- * @param cls closure from #GNUNET_SERVER_set_callbacks
- * @param client handle to client the tokenzier will be used for
- * @return handle to custom tokenizer ('mst')
- */
-typedef void*
-(*GNUNET_SERVER_MstCreateCallback) (void *cls,
-                                    struct GNUNET_SERVER_Client *client);
-
-
-/**
- * Signature of a function to destroy a custom tokenizer.
- *
- * @param cls closure from #GNUNET_SERVER_set_callbacks
- * @param mst custom tokenizer handle
- */
-typedef void
-(*GNUNET_SERVER_MstDestroyCallback) (void *cls,
-                                     void *mst);
-
-
-/**
- * Signature of a function to receive data for a custom tokenizer.
- *
- * @param cls closure from #GNUNET_SERVER_set_callbacks
- * @param mst custom tokenizer handle
- * @param client_identity ID of client for which this is a buffer,
- *        can be NULL (will be passed back to 'cb')
- * @param buf input data to add
- * @param size number of bytes in @a buf
- * @param purge should any excess bytes in the buffer be discarded
- *       (i.e. for packet-based services like UDP)
- * @param one_shot only call callback once, keep rest of message in buffer
- * @return #GNUNET_OK if we are done processing (need more data)
- *         #GNUNET_NO if one_shot was set and we have another message ready
- *         #GNUNET_SYSERR if the data stream is corrupt
- */
-typedef int
-(*GNUNET_SERVER_MstReceiveCallback) (void *cls, void *mst,
-                                     struct GNUNET_SERVER_Client *client,
-                                     const char *buf,
-                                     size_t size,
-                                     int purge,
-                                     int one_shot);
-
-
-/**
- * Change functions used by the server to tokenize the message stream.
- * (very rarely used).
- *
- * @param server server to modify
- * @param create new tokenizer initialization function
- * @param destroy new tokenizer destruction function
- * @param receive new tokenizer receive function
- * @param cls closure for @a create, @a receive and @a destroy
- */
-void
-GNUNET_SERVER_set_callbacks (struct GNUNET_SERVER_Handle *server,
-                             GNUNET_SERVER_MstCreateCallback create,
-                             GNUNET_SERVER_MstDestroyCallback destroy,
-                             GNUNET_SERVER_MstReceiveCallback receive,
-                             void *cls);
-
-
-#if 0                           /* keep Emacsens' auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-/* ifndef GNUNET_SERVER_LIB_H */
-#endif
-
-/** @} */  /* end of group server */
-
-/* end of gnunet_server_lib.h */
index 75b8805304abafe6ff96b13f8f8243016693dd86..c506fc6fa232e235654c2d7518a2d21aad4bb091 100644 (file)
@@ -44,22 +44,28 @@ extern "C"
 #endif
 
 #include "gnunet_configuration_lib.h"
-#include "gnunet_server_lib.h"
 #include "gnunet_mq_lib.h"
 
+/**
+ * Largest supported message (to be precise, one byte more
+ * than the largest possible message, so tests involving
+ * this value should check for messages being smaller than
+ * this value). NOTE: legacy name.
+ */
+#define GNUNET_SERVER_MAX_MESSAGE_SIZE 65536
 
 /**
- * Function called by the service's run
- * method to run service-specific setup code.
- *
- * @param cls closure
- * @param server the initialized server
- * @param cfg configuration to use
+ * Smallest supported message. NOTE: legacy name.
  */
-typedef void
-(*GNUNET_SERVICE_Main) (void *cls,
-                        struct GNUNET_SERVER_Handle *server,
-                        const struct GNUNET_CONFIGURATION_Handle *cfg);
+#define GNUNET_SERVER_MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
+
+/**
+ * Timeout we use on TCP connect before trying another
+ * result from the DNS resolver.  Actual value used
+ * is this value divided by the number of address families.
+ * Default is 5s.  NOTE: legacy name.
+ */
+#define GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
 
 
 /**
@@ -88,27 +94,6 @@ enum GNUNET_SERVICE_Options
 };
 
 
-/**
- * Run a standard GNUnet service startup sequence (initialize loggers
- * and configuration, parse options).
- *
- * @param argc number of command line arguments in @a argv
- * @param argv command line arguments
- * @param service_name our service name
- * @param options service options
- * @param task main task of the service
- * @param task_cls closure for @a task
- * @return #GNUNET_SYSERR on error, #GNUNET_OK
- *         if we shutdown nicely
- * @deprecated
- */
-int
-GNUNET_SERVICE_run (int argc,
-                    char *const *argv,
-                   const char *service_name,
-                    enum GNUNET_SERVICE_Options options,
-                   GNUNET_SERVICE_Main task,
-                   void *task_cls);
 
 
 /**
@@ -133,18 +118,6 @@ GNUNET_SERVICE_start (const char *service_name,
                      enum GNUNET_SERVICE_Options options);
 
 
-/**
- * Obtain the server used by a service.  Note that the server must NOT
- * be destroyed by the caller.
- *
- * @param ctx the service context returned from the start function
- * @return handle to the server for this service, NULL if there is none
- * @deprecated
- */
-struct GNUNET_SERVER_Handle *
-GNUNET_SERVICE_get_server (struct GNUNET_SERVICE_Context *ctx);
-
-
 /**
  * Get the NULL-terminated array of listen sockets for this service.
  *
index 52f5d8ab291f14c5c28601a939be5954d4706066..b42751d2ac03065b646c44ab452b50ae7f9d93e3 100644 (file)
@@ -41,7 +41,6 @@ extern "C"
 #include "gnunet_crypto_lib.h"
 #include "gnunet_bandwidth_lib.h"
 #include "gnunet_bio_lib.h"
-#include "gnunet_connection_lib.h"
 #include "gnunet_client_lib.h"
 #include "gnunet_container_lib.h"
 #include "gnunet_getopt_lib.h"
@@ -55,7 +54,6 @@ extern "C"
 #include "gnunet_plugin_lib.h"
 #include "gnunet_program_lib.h"
 #include "gnunet_protocols.h"
-#include "gnunet_server_lib.h"
 #include "gnunet_service_lib.h"
 #include "gnunet_signal_lib.h"
 #include "gnunet_strings_lib.h"
index 19695fabde8bf00540cef9f3d57c23b57088c634..14f3f2330baa163d28645eef869fcae4b5a67ed1 100644 (file)
@@ -37,11 +37,11 @@ lib_LTLIBRARIES = \
 
 libgnunetnatauto_la_SOURCES = \
   nat_auto_api.c \
-  nat_auto_api_test.c 
+  nat_auto_api_test.c
 libgnunetnatauto_la_LIBADD = \
   $(top_builddir)/src/nat/libgnunetnatnew.la \
   $(top_builddir)/src/util/libgnunetutil.la \
-  $(GN_LIBINTL) @EXT_LIBS@ 
+  $(GN_LIBINTL) @EXT_LIBS@
 libgnunetnatauto_la_LDFLAGS = \
   $(GN_LIB_LDFLAGS) $(WINFLAGS) \
   -version-info 0:0:0
@@ -55,4 +55,3 @@ gnunet_service_nat_auto_LDADD = \
   $(LIBGCRYPT_LIBS) \
   -lgcrypt \
   $(GN_LIBINTL)
-
index 371e4b27e4201dfe71fd97b1325350985aeabb85..590fad4d69dd17556ba22958c318f90591c4a68e 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     Copyright (C) 2011 GNUnet e.V.
+     Copyright (C) 2011, 2017 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
 
 
 /**
- * Our server.
+ * Information we track per client.
  */
-static struct GNUNET_SERVER_Handle *server;
+struct ClientData
+{
+  /**
+   * Timeout task.
+   */
+  struct GNUNET_SCHEDULER_Task *tt;
+
+  /**
+   * Client handle.
+   */
+  struct GNUNET_SERVICE_Client *client;
+};
+
 
 /**
  * Our configuration.
@@ -248,21 +260,18 @@ try_send_udp (uint32_t dst_ipv4,
  * We've received a request to probe a NAT
  * traversal. Do it.
  *
- * @param cls unused
- * @param client handle to client (we always close)
+ * @param cls handle to client (we always close)
  * @param msg message with details about what to test
  */
 static void
-test (void *cls,
-      struct GNUNET_SERVER_Client *client,
-      const struct GNUNET_MessageHeader *msg)
+handle_test (void *cls,
+             const struct GNUNET_NAT_AUTO_TestMessage *tm)
 {
-  const struct GNUNET_NAT_AUTO_TestMessage *tm;
+  struct ClientData *cd = cls;
   uint16_t dport;
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Received test request\n");
-  tm = (const struct GNUNET_NAT_AUTO_TestMessage *) msg;
   dport = ntohs (tm->dport);
   if (0 == dport)
     try_anat (tm->dst_ipv4,
@@ -276,126 +285,119 @@ test (void *cls,
     try_send_udp (tm->dst_ipv4,
                   dport,
                   tm->data);
-  GNUNET_SERVER_receive_done (client,
-                              GNUNET_NO);
+  GNUNET_SERVICE_client_drop (cd->client);
 }
 
 
 /**
- * Task run during shutdown.
+ * Main function that will be run.
  *
- * @param cls unused
+ * @param cls closure
+ * @param c configuration
+ * @param srv service handle
  */
 static void
-shutdown_task (void *cls)
+run (void *cls,
+     const struct GNUNET_CONFIGURATION_Handle *c,
+     struct GNUNET_SERVICE_Handle *srv)
 {
-  GNUNET_SERVER_destroy (server);
-  server = NULL;
+  cfg = c;
 }
 
 
 /**
- * Main function that will be run.
+ * Forcefully drops client after 1s.
  *
- * @param cls closure
- * @param args remaining command-line arguments
- * @param cfgfile name of the configuration file used (for saving, can be NULL!)
- * @param c configuration
+ * @param cls our `struct ClientData` of a client to drop
  */
 static void
-run (void *cls,
-     char *const *args,
-     const char *cfgfile,
-     const struct GNUNET_CONFIGURATION_Handle *c)
+force_timeout (void *cls)
 {
-  static const struct GNUNET_SERVER_MessageHandler handlers[] = {
-    {&test, NULL, GNUNET_MESSAGE_TYPE_NAT_TEST,
-     sizeof (struct GNUNET_NAT_AUTO_TestMessage)},
-    {NULL, NULL, 0, 0}
-  };
-  unsigned int port;
-  struct sockaddr_in in4;
-  struct sockaddr_in6 in6;
-
-  socklen_t slen[] = {
-    sizeof (in4),
-    sizeof (in6),
-    0
-  };
-  struct sockaddr *sa[] = {
-    (struct sockaddr *) &in4,
-    (struct sockaddr *) &in6,
-    NULL
-  };
+  struct ClientData *cd = cls;
 
-  cfg = c;
-  if ( (NULL == args[0]) ||
-       (1 != SSCANF (args[0], "%u", &port)) ||
-       (0 == port) ||
-       (65536 <= port) )
-  {
-    FPRINTF (stderr,
-             _("Please pass valid port number as the first argument! (got `%s')\n"),
-             args[0]);
-    return;
-  }
-  memset (&in4, 0, sizeof (in4));
-  memset (&in6, 0, sizeof (in6));
-  in4.sin_family = AF_INET;
-  in4.sin_port = htons ((uint16_t) port);
-  in6.sin6_family = AF_INET6;
-  in6.sin6_port = htons ((uint16_t) port);
-#if HAVE_SOCKADDR_IN_SIN_LEN
-  in4.sin_len = sizeof (in4);
-  in6.sin6_len = sizeof (in6);
-#endif
-  server = GNUNET_SERVER_create (NULL,
-                                NULL,
-                                (struct sockaddr * const *) sa,
-                                slen,
-                                GNUNET_TIME_UNIT_SECONDS,
-                                GNUNET_YES);
-  GNUNET_SERVER_add_handlers (server,
-                             handlers);
-  GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
-                                NULL);
+  cd->tt = NULL;
+  GNUNET_SERVICE_client_drop (cd->client);
 }
 
 
+
 /**
- * Main function of gnunet-nat-server.
+ * Callback called when a client connects to the service.
  *
- * @param argc number of command-line arguments
- * @param argv command line
- * @return 0 on success, -1 on error
+ * @param cls closure for the service
+ * @param c the new client that connected to the service
+ * @param mq the message queue used to send messages to the client
+ * @return our `struct ClientData`
  */
-int
-main (int argc, char *const argv[])
+static void *
+client_connect_cb (void *cls,
+                  struct GNUNET_SERVICE_Client *c,
+                  struct GNUNET_MQ_Handle *mq)
 {
-  static const struct GNUNET_GETOPT_CommandLineOption options[] = {
-    GNUNET_GETOPT_OPTION_END
-  };
-
-  if (GNUNET_OK !=
-      GNUNET_STRINGS_get_utf8_args (argc, argv,
-                                   &argc, &argv))
-    return 2;
-
-  if (GNUNET_OK !=
-      GNUNET_PROGRAM_run (argc,
-                         argv,
-                         "gnunet-nat-server [options] PORT",
-                          _("GNUnet NAT traversal test helper daemon"),
-                         options,
-                          &run,
-                         NULL))
-  {
-    GNUNET_free ((void*) argv);
-    return 1;
-  }
-  GNUNET_free ((void*) argv);
-  return 0;
+  struct ClientData *cd;
+
+  cd = GNUNET_new (struct ClientData);
+  cd->client = c;
+  cd->tt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
+                                         &force_timeout,
+                                         cd);
+  return cd;
+}
+
+
+/**
+ * Callback called when a client disconnected from the service
+ *
+ * @param cls closure for the service
+ * @param c the client that disconnected
+ * @param internal_cls our `struct ClientData`
+ */
+static void
+client_disconnect_cb (void *cls,
+                     struct GNUNET_SERVICE_Client *c,
+                     void *internal_cls)
+{
+  struct ClientData *cd = internal_cls;
+
+  if (NULL != cd->tt)
+    GNUNET_SCHEDULER_cancel (cd->tt);
+  GNUNET_free (cd);
 }
 
 
+/**
+ * Define "main" method using service macro.
+ */
+GNUNET_SERVICE_MAIN
+("nat-server",
+ GNUNET_SERVICE_OPTION_NONE,
+ &run,
+ &client_connect_cb,
+ &client_disconnect_cb,
+ NULL,
+ GNUNET_MQ_hd_fixed_size (test,
+                         GNUNET_MESSAGE_TYPE_NAT_TEST,
+                         struct GNUNET_NAT_AUTO_TestMessage,
+                         NULL),
+ GNUNET_MQ_handler_end ());
+
+
+#if defined(LINUX) && defined(__GLIBC__)
+#include <malloc.h>
+
+/**
+ * MINIMIZE heap size (way below 128k) since this process doesn't need much.
+ */
+void __attribute__ ((constructor))
+GNUNET_ARM_memory_init ()
+{
+  mallopt (M_TRIM_THRESHOLD, 4 * 1024);
+  mallopt (M_TOP_PAD, 1 * 1024);
+  malloc_trim (0);
+}
+#endif
+
+
+
+
 /* end of gnunet-nat-server.c */
index 731944bc4818f6da21c5c17682175422123572e5..5d2c1cc3773c3ef80daeed2bda7e049791a2c81d 100644 (file)
@@ -952,10 +952,11 @@ gen_rsh_suffix_args (const char * const *append_args)
  * @param client identification of the client
  * @param message the actual message
  *
- * @return GNUNET_OK on success, GNUNET_SYSERR to stop further processing
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
  */
 static int
-helper_mst (void *cls, void *client, const struct GNUNET_MessageHeader *message)
+helper_mst (void *cls,
+            const struct GNUNET_MessageHeader *message)
 {
   struct GNUNET_TESTBED_ControllerProc *cp = cls;
   const struct GNUNET_TESTBED_HelperReply *msg;
index acc2557c605b40d8b3554e8d798dc387a9820b29..7687f2348703ed8babe5783d1593eaefb0d4a2ca 100644 (file)
@@ -191,6 +191,8 @@ libexec_PROGRAMS = \
  $(BT_BIN) \
  gnunet-service-transport
 
+
+
 bin_PROGRAMS = \
  gnunet-transport \
  gnunet-transport-certificate-creation
@@ -561,7 +563,7 @@ TESTS = \
  $(HTTP_API_TIMEOUT_TEST) \
  $(HTTPS_API_TIMEOUT_TEST) \
  $(WLAN_TIMEOUT_TEST) \
- $(BT_TIMEOUT_TEST) 
+ $(BT_TIMEOUT_TEST)
 if HAVE_GETOPT_BINARY
 TESTS += \
 test_transport_api_slow_ats
index 684546314044514355c8c708af0396f48068c4bd..63ed9c4b796ad3abf68f9f8268c60831e22b23c9 100644 (file)
@@ -120,11 +120,11 @@ send_mac_to_plugin (char *buffer, struct GNUNET_TRANSPORT_WLAN_MacAddress *mac)
  * type to the output forward and copy it to the buffer for stdout.
  *
  * @param cls the 'struct SendBuffer' to copy the converted message to
- * @param client unused
  * @param hdr inbound message from the FIFO
  */
 static int
-stdin_send (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
+stdin_send (void *cls,
+            const struct GNUNET_MessageHeader *hdr)
 {
   struct SendBuffer *write_pout = cls;
   const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *in;
@@ -166,11 +166,11 @@ stdin_send (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
  * We read a full message from stdin.  Copy it to our send buffer.
  *
  * @param cls the 'struct SendBuffer' to copy to
- * @param client unused
  * @param hdr the message we received to copy to the buffer
  */
 static int
-file_in_send (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
+file_in_send (void *cls,
+              const struct GNUNET_MessageHeader *hdr)
 {
   struct SendBuffer *write_std = cls;
   uint16_t sendsize;
@@ -213,8 +213,8 @@ main (int argc, char *argv[])
   fd_set wfds;
   struct timeval tv;
   int retval;
-  struct GNUNET_SERVER_MessageStreamTokenizer *stdin_mst = NULL;
-  struct GNUNET_SERVER_MessageStreamTokenizer *file_in_mst = NULL;
+  struct GNUNET_MessageStreamTokenizer *stdin_mst = NULL;
+  struct GNUNET_MessageStreamTokenizer *file_in_mst = NULL;
   struct GNUNET_TRANSPORT_WLAN_MacAddress macaddr;
   int first;
 
@@ -340,8 +340,8 @@ main (int argc, char *argv[])
   write_std.pos = 0;
   write_pout.size = 0;
   write_pout.pos = 0;
-  stdin_mst = GNUNET_SERVER_mst_create (&stdin_send, &write_pout);
-  file_in_mst = GNUNET_SERVER_mst_create (&file_in_send, &write_std);
+  stdin_mst = GNUNET_MST_create (&stdin_send, &write_pout);
+  file_in_mst = GNUNET_MST_create (&file_in_send, &write_std);
 
   /* Send 'random' mac address */
   macaddr.mac[0] = 0x13;
@@ -453,8 +453,9 @@ main (int argc, char *argv[])
       }
       else if (0 < readsize)
       {
-        GNUNET_SERVER_mst_receive (stdin_mst, NULL, readbuf, readsize,
-                                   GNUNET_NO, GNUNET_NO);
+        GNUNET_MST_from_buffer (stdin_mst,
+                                readbuf, readsize,
+                                GNUNET_NO, GNUNET_NO);
 
       }
       else
@@ -475,8 +476,9 @@ main (int argc, char *argv[])
       }
       else if (0 < readsize)
       {
-        GNUNET_SERVER_mst_receive (file_in_mst, NULL, readbuf, readsize,
-                                   GNUNET_NO, GNUNET_NO);
+        GNUNET_MST_from_buffer (file_in_mst,
+                                readbuf, readsize,
+                                GNUNET_NO, GNUNET_NO);
       }
       else
       {
@@ -489,9 +491,9 @@ main (int argc, char *argv[])
 end:
   /* clean up */
   if (NULL != stdin_mst)
-    GNUNET_SERVER_mst_destroy (stdin_mst);
+    GNUNET_MST_destroy (stdin_mst);
   if (NULL != file_in_mst)
-    GNUNET_SERVER_mst_destroy (file_in_mst);
+    GNUNET_MST_destroy (file_in_mst);
 
   if (NULL != fpout)
     fclose (fpout);
index ceed94af8b2d700e7ddd7bdcde231364bd593e57..e91149289a949a62d5c546b7b027223cd5a1b39f 100644 (file)
@@ -221,7 +221,7 @@ struct GNUNET_ATS_Session
   /**
    * Message stream tokenizer for incoming data
    */
-  struct GNUNET_SERVER_MessageStreamTokenizer *msg_tk;
+  struct GNUNET_MessageStreamTokenizer *msg_tk;
 
   /**
    * Session timeout task
@@ -528,7 +528,7 @@ client_delete_session (struct GNUNET_ATS_Session *s)
                           GNUNET_TRANSPORT_SS_DONE);
   if (NULL != s->msg_tk)
   {
-    GNUNET_SERVER_mst_destroy (s->msg_tk);
+    GNUNET_MST_destroy (s->msg_tk);
     s->msg_tk = NULL;
   }
   GNUNET_HELLO_address_free (s->address);
@@ -1158,13 +1158,11 @@ client_wake_up (void *cls)
  * Callback for message stream tokenizer
  *
  * @param cls the session
- * @param client not used
  * @param message the message received
  * @return always #GNUNET_OK
  */
 static int
 client_receive_mst_cb (void *cls,
-                       void *client,
                        const struct GNUNET_MessageHeader *message)
 {
   struct GNUNET_ATS_Session *s = cls;
@@ -1274,14 +1272,13 @@ client_receive (void *stream,
     return CURL_WRITEFUNC_PAUSE;
   }
   if (NULL == s->msg_tk)
-    s->msg_tk = GNUNET_SERVER_mst_create (&client_receive_mst_cb,
-                                          s);
-  GNUNET_SERVER_mst_receive (s->msg_tk,
-                             s,
-                             stream,
-                             len,
-                             GNUNET_NO,
-                             GNUNET_NO);
+    s->msg_tk = GNUNET_MST_create (&client_receive_mst_cb,
+                                   s);
+  GNUNET_MST_from_buffer (s->msg_tk,
+                          stream,
+                          len,
+                          GNUNET_NO,
+                          GNUNET_NO);
   return len;
 }
 
index 63c67b81c50b673f5041472ac28a7a7e4a09946e..2d6f40d58fb91c2141e8661b941b0412602ae9b2 100644 (file)
@@ -201,7 +201,7 @@ struct GNUNET_ATS_Session
   /**
    * Message stream tokenizer for incoming data
    */
-  struct GNUNET_SERVER_MessageStreamTokenizer *msg_tk;
+  struct GNUNET_MessageStreamTokenizer *msg_tk;
 
   /**
    * Client recv handle
@@ -608,7 +608,7 @@ server_delete_session (struct GNUNET_ATS_Session *s)
   }
   if (NULL != s->msg_tk)
   {
-    GNUNET_SERVER_mst_destroy (s->msg_tk);
+    GNUNET_MST_destroy (s->msg_tk);
     s->msg_tk = NULL;
   }
   GNUNET_HELLO_address_free (s->address);
@@ -1621,13 +1621,11 @@ server_send_callback (void *cls,
  * Callback called by MessageStreamTokenizer when a message has arrived
  *
  * @param cls current session as closure
- * @param client client
  * @param message the message to be forwarded to transport service
  * @return #GNUNET_OK
  */
 static int
 server_receive_mst_cb (void *cls,
-                       void *client,
                        const struct GNUNET_MessageHeader *message)
 {
   struct GNUNET_ATS_Session *s = cls;
@@ -1847,13 +1845,16 @@ server_access_cb (void *cls,
              *upload_data_size);
         if (s->msg_tk == NULL)
         {
-          s->msg_tk = GNUNET_SERVER_mst_create (&server_receive_mst_cb, s);
+          s->msg_tk = GNUNET_MST_create (&server_receive_mst_cb,
+                                         s);
         }
-        GNUNET_SERVER_mst_receive (s->msg_tk, s, upload_data, *upload_data_size,
-            GNUNET_NO, GNUNET_NO);
+        GNUNET_MST_from_buffer (s->msg_tk,
+                                upload_data,
+                                *upload_data_size,
+                                GNUNET_NO, GNUNET_NO);
         server_mhd_connection_timeout (plugin, s,
-            GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value_us / 1000LL
-                / 1000LL);
+                                       GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value_us / 1000LL
+                                       / 1000LL);
         (*upload_data_size) = 0;
       }
       else
@@ -1935,7 +1936,7 @@ server_disconnect_cb (void *cls,
       sc->session->server_recv = NULL;
       if (NULL != sc->session->msg_tk)
       {
-        GNUNET_SERVER_mst_destroy (sc->session->msg_tk);
+        GNUNET_MST_destroy (sc->session->msg_tk);
         sc->session->msg_tk = NULL;
       }
     }
@@ -2757,7 +2758,7 @@ server_start_report_addresses (struct HTTP_Server_Plugin *plugin)
     return;
   }
 
-  plugin->nat 
+  plugin->nat
     = GNUNET_NAT_register (plugin->env->cfg,
                           "transport-http_server",
                           IPPROTO_TCP,
index 34bbd00e09bea1bebb138d93adaa141b6cce7d23..10ea01cec3cd569dbefb2cf01d9aef3e605fa7eb 100644 (file)
  */
 #define NAT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
 
-GNUNET_NETWORK_STRUCT_BEGIN
+/**
+ * Opaque handle that can be used to cancel
+ * a transmit-ready notification.
+ */
+struct GNUNET_CONNECTION_TransmitHandle;
+
+/**
+ * @brief handle for a server
+ */
+struct GNUNET_SERVER_Handle;
+
+/**
+ * @brief opaque handle for a client of the server
+ */
+struct GNUNET_SERVER_Client;
+
+/**
+ * @brief opaque handle server returns for aborting transmission to a client.
+ */
+struct GNUNET_SERVER_TransmitHandle;
+
+/**
+ * @brief handle for a network connection
+ */
+struct GNUNET_CONNECTION_Handle;
+
+
+/**
+ * Function called to notify a client about the connection begin ready
+ * to queue more data.  @a buf will be NULL and @a size zero if the
+ * connection was closed for writing in the meantime.
+ *
+ * @param cls closure
+ * @param size number of bytes available in @a buf
+ * @param buf where the callee should write the message
+ * @return number of bytes written to @a buf
+ */
+typedef size_t
+(*GNUNET_CONNECTION_TransmitReadyNotify) (void *cls,
+                                          size_t size,
+                                          void *buf);
+
+/**
+ * Credentials for UNIX domain sockets.
+ */
+struct GNUNET_CONNECTION_Credentials
+{
+  /**
+   * UID of the other end of the connection.
+   */
+  uid_t uid;
+
+  /**
+   * GID of the other end of the connection.
+   */
+  gid_t gid;
+};
+
+
+/**
+ * Functions with this signature are called whenever a client
+ * is disconnected on the network level.
+ *
+ * @param cls closure
+ * @param client identification of the client; NULL
+ *        for the last call when the server is destroyed
+ */
+typedef void
+(*GNUNET_SERVER_DisconnectCallback) (void *cls,
+                                     struct GNUNET_SERVER_Client *client);
+
+
+/**
+ * Functions with this signature are called whenever a client
+ * is connected on the network level.
+ *
+ * @param cls closure
+ * @param client identification of the client
+ */
+typedef void
+(*GNUNET_SERVER_ConnectCallback) (void *cls,
+                                  struct GNUNET_SERVER_Client *client);
+
+
 
 
+/**
+ * Function to call for access control checks.
+ *
+ * @param cls closure
+ * @param ucred credentials, if available, otherwise NULL
+ * @param addr address
+ * @param addrlen length of address
+ * @return GNUNET_YES to allow, GNUNET_NO to deny, GNUNET_SYSERR
+ *   for unknown address family (will be denied).
+ */
+typedef int
+(*GNUNET_CONNECTION_AccessCheck) (void *cls,
+                                  const struct
+                                  GNUNET_CONNECTION_Credentials *
+                                  ucred,
+                                  const struct sockaddr * addr,
+                                  socklen_t addrlen);
+
+/**
+ * Callback function for data received from the network.  Note that
+ * both "available" and "err" would be 0 if the read simply timed out.
+ *
+ * @param cls closure
+ * @param buf pointer to received data
+ * @param available number of bytes availabe in "buf",
+ *        possibly 0 (on errors)
+ * @param addr address of the sender
+ * @param addrlen size of addr
+ * @param errCode value of errno (on errors receiving)
+ */
+typedef void
+(*GNUNET_CONNECTION_Receiver) (void *cls, const void *buf,
+                               size_t available,
+                               const struct sockaddr * addr,
+                               socklen_t addrlen, int errCode);
+
+
+
+/**
+ * Close the connection and free associated resources.  There must
+ * not be any pending requests for reading or writing to the
+ * connection at this time.
+ *
+ * @param connection connection to destroy
+ */
+void
+GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection);
+
+
+/**
+ * Signature of a function to create a custom tokenizer.
+ *
+ * @param cls closure from #GNUNET_SERVER_set_callbacks
+ * @param client handle to client the tokenzier will be used for
+ * @return handle to custom tokenizer ('mst')
+ */
+typedef void*
+(*GNUNET_SERVER_MstCreateCallback) (void *cls,
+                                    struct GNUNET_SERVER_Client *client);
+
+
+/**
+ * Signature of a function to destroy a custom tokenizer.
+ *
+ * @param cls closure from #GNUNET_SERVER_set_callbacks
+ * @param mst custom tokenizer handle
+ */
+typedef void
+(*GNUNET_SERVER_MstDestroyCallback) (void *cls,
+                                     void *mst);
+
+/**
+ * Signature of a function to receive data for a custom tokenizer.
+ *
+ * @param cls closure from #GNUNET_SERVER_set_callbacks
+ * @param mst custom tokenizer handle
+ * @param client_identity ID of client for which this is a buffer,
+ *        can be NULL (will be passed back to 'cb')
+ * @param buf input data to add
+ * @param size number of bytes in @a buf
+ * @param purge should any excess bytes in the buffer be discarded
+ *       (i.e. for packet-based services like UDP)
+ * @param one_shot only call callback once, keep rest of message in buffer
+ * @return #GNUNET_OK if we are done processing (need more data)
+ *         #GNUNET_NO if one_shot was set and we have another message ready
+ *         #GNUNET_SYSERR if the data stream is corrupt
+ */
+typedef int
+(*GNUNET_SERVER_MstReceiveCallback) (void *cls, void *mst,
+                                     struct GNUNET_SERVER_Client *client,
+                                     const char *buf,
+                                     size_t size,
+                                     int purge,
+                                     int one_shot);
+/**
+ * Functions with this signature are called whenever a message is
+ * received.
+ *
+ * @param cls closure
+ * @param client identification of the client
+ * @param message the actual message
+ */
+typedef void
+(*GNUNET_SERVER_MessageCallback) (void *cls,
+                                  struct GNUNET_SERVER_Client *client,
+                                  const struct GNUNET_MessageHeader *message);
+
+/**
+ * Message handler.  Each struct specifies how to handle on particular
+ * type of message received.
+ */
+struct GNUNET_SERVER_MessageHandler
+{
+  /**
+   * Function to call for messages of "type".
+   */
+  GNUNET_SERVER_MessageCallback callback;
+
+  /**
+   * Closure argument for @e callback.
+   */
+  void *callback_cls;
+
+  /**
+   * Type of the message this handler covers.
+   */
+  uint16_t type;
+
+  /**
+   * Expected size of messages of this type.  Use 0 for
+   * variable-size.  If non-zero, messages of the given
+   * type will be discarded (and the connection closed)
+   * if they do not have the right size.
+   */
+  uint16_t expected_size;
+
+};
+
+/**
+ * Ask the server to disconnect from the given client.  This is the
+ * same as passing #GNUNET_SYSERR to #GNUNET_SERVER_receive_done,
+ * except that it allows dropping of a client even when not handling a
+ * message from that client.
+ *
+ * @param client the client to disconnect from
+ */
+void
+GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client);
+
+/**
+ * Return user context associated with the given client.
+ * Note: you should probably use the macro (call without the underscore).
+ *
+ * @param client client to query
+ * @param size number of bytes in user context struct (for verification only)
+ * @return pointer to user context
+ */
+void *
+GNUNET_SERVER_client_get_user_context_ (struct GNUNET_SERVER_Client *client,
+                                        size_t size);
+
+
+/**
+ * Functions with this signature are called whenever a
+ * complete message is received by the tokenizer.
+ *
+ * Do not call #GNUNET_SERVER_mst_destroy from within
+ * the scope of this callback.
+ *
+ * @param cls closure
+ * @param client identification of the client
+ * @param message the actual message
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
+ */
+typedef int
+(*GNUNET_SERVER_MessageTokenizerCallback) (void *cls,
+                                           void *client,
+                                           const struct GNUNET_MessageHeader *message);
+
+
+/**
+ * Create a message stream tokenizer.
+ *
+ * @param cb function to call on completed messages
+ * @param cb_cls closure for @a cb
+ * @return handle to tokenizer
+ */
+struct GNUNET_SERVER_MessageStreamTokenizer *
+GNUNET_SERVER_mst_create (GNUNET_SERVER_MessageTokenizerCallback cb,
+                          void *cb_cls);
+
+/**
+ * Add incoming data to the receive buffer and call the
+ * callback for all complete messages.
+ *
+ * @param mst tokenizer to use
+ * @param client_identity ID of client for which this is a buffer,
+ *        can be NULL (will be passed back to 'cb')
+ * @param buf input data to add
+ * @param size number of bytes in @a buf
+ * @param purge should any excess bytes in the buffer be discarded
+ *       (i.e. for packet-based services like UDP)
+ * @param one_shot only call callback once, keep rest of message in buffer
+ * @return #GNUNET_OK if we are done processing (need more data)
+ *         #GNUNET_NO if one_shot was set and we have another message ready
+ *         #GNUNET_SYSERR if the data stream is corrupt
+ */
+int
+GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
+                           void *client_identity,
+                           const char *buf, size_t size,
+                           int purge, int one_shot);
+
+
+
+/**
+ * Destroys a tokenizer.
+ *
+ * @param mst tokenizer to destroy
+ */
+void
+GNUNET_SERVER_mst_destroy (struct GNUNET_SERVER_MessageStreamTokenizer *mst);
+
+
+/**
+ * Set user context to be associated with the given client.
+ * Note: you should probably use the macro (call without the underscore).
+ *
+ * @param client client to query
+ * @param ptr pointer to user context
+ * @param size number of bytes in user context struct (for verification only)
+ */
+void
+GNUNET_SERVER_client_set_user_context_ (struct GNUNET_SERVER_Client *client,
+                                        void *ptr,
+                                        size_t size);
+/**
+ * Return user context associated with the given client.
+ *
+ * @param client client to query
+ * @param type expected return type (i.e. 'struct Foo')
+ * @return pointer to user context of type 'type *'.
+ */
+#define GNUNET_SERVER_client_get_user_context(client,type)              \
+  (type *) GNUNET_SERVER_client_get_user_context_ (client, sizeof (type))
+
+/**
+ * Set user context to be associated with the given client.
+ *
+ * @param client client to query
+ * @param value pointer to user context
+ */
+#define GNUNET_SERVER_client_set_user_context(client,value)             \
+  GNUNET_SERVER_client_set_user_context_ (client, value, sizeof (*value))
+
+
+
+/**
+ * Notify us when the server has enough space to transmit
+ * a message of the given size to the given client.
+ *
+ * @param client client to transmit message to
+ * @param size requested amount of buffer space
+ * @param timeout after how long should we give up (and call
+ *        notify with buf NULL and size 0)?
+ * @param callback function to call when space is available
+ * @param callback_cls closure for @a callback
+ * @return non-NULL if the notify callback was queued; can be used
+ *           to cancel the request using
+ *           #GNUNET_SERVER_notify_transmit_ready_cancel.
+ *         NULL if we are already going to notify someone else (busy)
+ */
+struct GNUNET_SERVER_TransmitHandle *
+GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
+                                     size_t size,
+                                     struct GNUNET_TIME_Relative timeout,
+                                     GNUNET_CONNECTION_TransmitReadyNotify callback,
+                                     void *callback_cls);
+
+/**
+ * Abort transmission request.
+ *
+ * @param th request to abort
+ */
+void
+GNUNET_SERVER_notify_transmit_ready_cancel (struct GNUNET_SERVER_TransmitHandle *th);
+
+
+
+
+/**
+ * Notify the server that the given client handle should
+ * be kept (keeps the connection up if possible, increments
+ * the internal reference counter).
+ *
+ * @param client the client to keep
+ */
+void
+GNUNET_SERVER_client_keep (struct GNUNET_SERVER_Client *client);
+
+
+/**
+ * Notify the server that the given client handle is no
+ * longer required.  Decrements the reference counter.  If
+ * that counter reaches zero an inactive connection maybe
+ * closed.
+ *
+ * @param client the client to drop
+ */
+void
+GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client);
+
+
+/**
+ * Function called by the service's run
+ * method to run service-specific setup code.
+ *
+ * @param cls closure
+ * @param server the initialized server
+ * @param cfg configuration to use
+ */
+typedef void
+(*GNUNET_SERVICE_Main) (void *cls,
+                        struct GNUNET_SERVER_Handle *server,
+                        const struct GNUNET_CONFIGURATION_Handle *cfg);
+
+
+
+/**
+ * Suspend accepting connections from the listen socket temporarily.
+ * Resume activity using #GNUNET_SERVER_resume.
+ *
+ * @param server server to stop accepting connections.
+ */
+void
+GNUNET_SERVER_suspend (struct GNUNET_SERVER_Handle *server);
+
+/**
+ * Notify us when the server has enough space to transmit
+ * a message of the given size to the given client.
+ *
+ * @param client client to transmit message to
+ * @param size requested amount of buffer space
+ * @param timeout after how long should we give up (and call
+ *        notify with buf NULL and size 0)?
+ * @param callback function to call when space is available
+ * @param callback_cls closure for @a callback
+ * @return non-NULL if the notify callback was queued; can be used
+ *           to cancel the request using
+ *           #GNUNET_SERVER_notify_transmit_ready_cancel.
+ *         NULL if we are already going to notify someone else (busy)
+ */
+struct GNUNET_SERVER_TransmitHandle *
+GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
+                                     size_t size,
+                                     struct GNUNET_TIME_Relative timeout,
+                                     GNUNET_CONNECTION_TransmitReadyNotify callback,
+                                     void *callback_cls);
+
+
+/**
+ * Add a TCP socket-based connection to the set of handles managed by
+ * this server.  Use this function for outgoing (P2P) connections that
+ * we initiated (and where this server should process incoming
+ * messages).
+ *
+ * @param server the server to use
+ * @param connection the connection to manage (client must
+ *        stop using this connection from now on)
+ * @return the client handle
+ */
+struct GNUNET_SERVER_Client *
+GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server,
+                              struct GNUNET_CONNECTION_Handle *connection);
+
+
+/**
+ * Resume accepting connections from the listen socket.
+ *
+ * @param server server to resume accepting connections.
+ */
+void
+GNUNET_SERVER_resume (struct GNUNET_SERVER_Handle *server);
+
+/**
+ * Free resources held by this server.
+ *
+ * @param server server to destroy
+ */
+void
+GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *server);
+
+
+
+
+#include "tcp_connection_legacy.c"
+#include "tcp_server_mst_legacy.c"
+#include "tcp_server_legacy.c"
+#include "tcp_service_legacy.c"
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
 /**
  * Initial handshake message for a session.
  */
@@ -521,47 +1006,6 @@ struct Plugin
 };
 
 
-/* begin of ancient copy-and-pasted code that should be
-   specialized for TCP ...*/
-/**
- * Add the given UNIX domain path as an address to the
- * list (as the first entry).
- *
- * @param saddrs array to update
- * @param saddrlens where to store the address length
- * @param unixpath path to add
- * @param abstract #GNUNET_YES to add an abstract UNIX domain socket.  This
- *          parameter is ignore on systems other than LINUX
- */
-static void
-add_unixpath (struct sockaddr **saddrs,
-              socklen_t *saddrlens,
-              const char *unixpath,
-              int abstract)
-{
-#ifdef AF_UNIX
-  struct sockaddr_un *un;
-
-  un = GNUNET_new (struct sockaddr_un);
-  un->sun_family = AF_UNIX;
-  strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1);
-#ifdef LINUX
-  if (GNUNET_YES == abstract)
-    un->sun_path[0] = '\0';
-#endif
-#if HAVE_SOCKADDR_UN_SUN_LEN
-  un->sun_len = (u_char) sizeof (struct sockaddr_un);
-#endif
-  *saddrs = (struct sockaddr *) un;
-  *saddrlens = sizeof (struct sockaddr_un);
-#else
-  /* this function should never be called
-   * unless AF_UNIX is defined! */
-  GNUNET_assert (0);
-#endif
-}
-
-
 /**
  * Get the list of addresses that a server for the given service
  * should bind to.
index eb48341b7660daee4b2343953e1f27c1fa3dad51..3a9013a5a2b8f2540c219830603effd89016a682 100644 (file)
@@ -158,6 +158,11 @@ struct GNUNET_ATS_Session
    */
   struct GNUNET_PeerIdentity target;
 
+  /**
+   * Tokenizer for inbound messages.
+   */
+  struct GNUNET_MessageStreamTokenizer *mst;
+
   /**
    * Plugin this session belongs to.
    */
@@ -626,6 +631,11 @@ free_session (struct GNUNET_ATS_Session *s)
     GNUNET_free (s->frag_ctx);
     s->frag_ctx = NULL;
   }
+  if (NULL != s->mst)
+  {
+    GNUNET_MST_destroy (s->mst);
+    s->mst = NULL;
+  }
   GNUNET_free (s);
 }
 
@@ -2499,18 +2509,16 @@ read_process_ack (struct Plugin *plugin,
  * Message tokenizer has broken up an incomming message. Pass it on
  * to the service.
  *
- * @param cls the `struct Plugin *`
- * @param client the `struct GNUNET_ATS_Session *`
+ * @param cls the `struct GNUNET_ATS_Session *`
  * @param hdr the actual message
  * @return #GNUNET_OK (always)
  */
 static int
 process_inbound_tokenized_messages (void *cls,
-                                    void *client,
                                     const struct GNUNET_MessageHeader *hdr)
 {
-  struct Plugin *plugin = cls;
-  struct GNUNET_ATS_Session *session = client;
+  struct GNUNET_ATS_Session *session = cls;
+  struct Plugin *plugin = session->plugin;
 
   if (GNUNET_YES == session->in_destroy)
     return GNUNET_OK;
@@ -2626,6 +2634,8 @@ udp_plugin_create_session (void *cls,
   struct GNUNET_ATS_Session *s;
 
   s = GNUNET_new (struct GNUNET_ATS_Session);
+  s->mst = GNUNET_MST_create (&process_inbound_tokenized_messages,
+                              s);
   s->plugin = plugin;
   s->address = GNUNET_HELLO_address_copy (address);
   s->target = address->peer;
@@ -2792,12 +2802,11 @@ process_udp_message (struct Plugin *plugin,
   GNUNET_free (address);
 
   s->rc++;
-  GNUNET_SERVER_mst_receive (plugin->mst,
-                             s,
-                             (const char *) &msg[1],
-                             ntohs (msg->header.size) - sizeof(struct UDPMessage),
-                             GNUNET_YES,
-                             GNUNET_NO);
+  GNUNET_MST_from_buffer (s->mst,
+                          (const char *) &msg[1],
+                          ntohs (msg->header.size) - sizeof(struct UDPMessage),
+                          GNUNET_YES,
+                          GNUNET_NO);
   s->rc--;
   if ( (0 == s->rc) &&
        (GNUNET_YES == s->in_destroy) )
@@ -3990,8 +3999,6 @@ libgnunet_plugin_transport_udp_init (void *cls)
   p->sessions = GNUNET_CONTAINER_multipeermap_create (16,
                                                       GNUNET_NO);
   p->defrag_ctxs = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
-  p->mst = GNUNET_SERVER_mst_create (&process_inbound_tokenized_messages,
-                                     p);
   GNUNET_BANDWIDTH_tracker_init (&p->tracker,
                                  NULL,
                                  NULL,
@@ -4008,7 +4015,6 @@ libgnunet_plugin_transport_udp_init (void *cls)
         _("Failed to create UDP network sockets\n"));
     GNUNET_CONTAINER_multipeermap_destroy (p->sessions);
     GNUNET_CONTAINER_heap_destroy (p->defrag_ctxs);
-    GNUNET_SERVER_mst_destroy (p->mst);
     if (NULL != p->nat)
       GNUNET_NAT_unregister (p->nat);
     GNUNET_free (p);
@@ -4120,11 +4126,6 @@ libgnunet_plugin_transport_udp_done (void *cls)
     GNUNET_CONTAINER_heap_destroy (plugin->defrag_ctxs);
     plugin->defrag_ctxs = NULL;
   }
-  if (NULL != plugin->mst)
-  {
-    GNUNET_SERVER_mst_destroy (plugin->mst);
-    plugin->mst = NULL;
-  }
   while (NULL != (udpw = plugin->ipv4_queue_head))
   {
     dequeue (plugin,
index 152b16099c22914f05c261ecc2b5703fb2159777..48c7365c714192d351f3a40d9f8476312853619e 100644 (file)
@@ -163,11 +163,6 @@ struct Plugin
    */
   struct GNUNET_SCHEDULER_Task *select_task_v6;
 
-  /**
-   * Tokenizer for inbound messages.
-   */
-  struct GNUNET_SERVER_MessageStreamTokenizer *mst;
-
   /**
    * Bandwidth tracker to limit global UDP traffic.
    */
@@ -192,7 +187,7 @@ struct Plugin
    * Handle to NAT traversal support.
    */
   struct GNUNET_NAT_STUN_Handle *stun;
-  
+
   /**
    * The read socket for IPv4
    */
@@ -203,11 +198,6 @@ struct Plugin
    */
   struct GNUNET_NETWORK_Handle *sockv6;
 
-  /**
-   * Tokenizer for inbound messages.
-   */
-  struct GNUNET_SERVER_MessageStreamTokenizer *broadcast_mst;
-
   /**
    * Head of DLL of broadcast addresses
    */
index a440830fd9450252a2749bad235779b701bc1981..c6ddbce9b5ccec2e245734c5c9e2a875773d555b 100644 (file)
@@ -133,11 +133,10 @@ struct MstContext
  */
 static int
 broadcast_mst_cb (void *cls,
-                  void *client,
                   const struct GNUNET_MessageHeader *message)
 {
-  struct Plugin *plugin = cls;
-  struct MstContext *mc = client;
+  struct MstContext *mc = cls;
+  struct Plugin *plugin = mc->plugin;
   struct GNUNET_HELLO_Address *address;
   const struct GNUNET_MessageHeader *hello;
   const struct UDP_Beacon_Message *msg;
@@ -191,16 +190,20 @@ udp_broadcast_receive (struct Plugin *plugin,
                        size_t udp_addr_len,
                        enum GNUNET_ATS_Network_Type network_type)
 {
+  struct GNUNET_MessageStreamTokenizer *broadcast_mst;
   struct MstContext mc;
 
+  broadcast_mst = GNUNET_MST_create (&broadcast_mst_cb,
+                                     &mc);
+  mc.plugin = plugin;
   mc.udp_addr = udp_addr;
   mc.udp_addr_len = udp_addr_len;
   mc.ats_address_network_type = network_type;
-  GNUNET_SERVER_mst_receive (plugin->broadcast_mst,
-                             &mc,
-                             buf, size,
-                             GNUNET_NO,
-                             GNUNET_NO);
+  GNUNET_MST_from_buffer (broadcast_mst,
+                          buf, size,
+                          GNUNET_NO,
+                          GNUNET_NO);
+  GNUNET_MST_destroy (broadcast_mst);
 }
 
 
@@ -546,10 +549,6 @@ setup_broadcast (struct Plugin *plugin,
     return;
   }
 
-  /* always create tokenizers */
-  plugin->broadcast_mst =
-    GNUNET_SERVER_mst_create (&broadcast_mst_cb, plugin);
-
   if (GNUNET_YES != plugin->enable_broadcasting)
     return; /* We do not send, just receive */
 
@@ -636,13 +635,6 @@ stop_broadcast (struct Plugin *plugin)
       GNUNET_free (p);
     }
   }
-
-  /* Destroy MSTs */
-  if (NULL != plugin->broadcast_mst)
-  {
-    GNUNET_SERVER_mst_destroy (plugin->broadcast_mst);
-    plugin->broadcast_mst = NULL;
-  }
 }
 
 /* end of plugin_transport_udp_broadcasting.c */
index 376065d24cf9c5cb0fde48e8c85e9e73e13212c8..3f5ada10b225030346c7be55e5e074474ce60dae 100644 (file)
@@ -38,6 +38,7 @@
 #include "gnunet_fragmentation_lib.h"
 #include "gnunet_constants.h"
 
+
 #if BUILD_WLAN
 /* begin case wlan */
 #define PLUGIN_NAME "wlan"
@@ -48,6 +49,7 @@
 #define LIBGNUNET_PLUGIN_TRANSPORT_DONE libgnunet_plugin_transport_wlan_done
 #define LOG(kind,...) GNUNET_log_from (kind, "transport-wlan",__VA_ARGS__)
 
+
 /**
  * time out of a mac endpoint
  */
 #error need to build wlan or bluetooth
 #endif
 
+
+
+/**
+ * Functions with this signature are called whenever a
+ * complete message is received by the tokenizer.
+ *
+ * Do not call #GNUNET_SERVER_mst_destroy from within
+ * the scope of this callback.
+ *
+ * @param cls closure
+ * @param client identification of the client
+ * @param message the actual message
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
+ */
+typedef int
+(*GNUNET_SERVER_MessageTokenizerCallback) (void *cls,
+                                           void *client,
+                                           const struct GNUNET_MessageHeader *message);
+
+
+/* Include legacy message stream tokenizer that was removed from util (for now) */
+#include "tcp_server_mst_legacy.c"
+
+
 /**
  * Max size of packet (that we give to the WLAN driver for transmission)
  */
@@ -1728,11 +1754,10 @@ send_hello_beacon (void *cls)
  * Function used for to process the data from the suid process
  *
  * @param cls the plugin handle
- * @param client client that send the data (not used)
  * @param hdr header of the GNUNET_MessageHeader
  */
 static int
-handle_helper_message (void *cls, void *client,
+handle_helper_message (void *cls,
                       const struct GNUNET_MessageHeader *hdr)
 {
   struct Plugin *plugin = cls;
diff --git a/src/transport/tcp_connection_legacy.c b/src/transport/tcp_connection_legacy.c
new file mode 100644 (file)
index 0000000..f525344
--- /dev/null
@@ -0,0 +1,1647 @@
+/*
+     This file is part of GNUnet.
+     Copyright (C) 2009-2013 GNUnet e.V.
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file util/connection.c
+ * @brief  TCP connection management
+ * @author Christian Grothoff
+ *
+ * This code is rather complex.  Only modify it if you
+ * 1) Have a NEW testcase showing that the new code
+ *    is needed and correct
+ * 2) All EXISTING testcases pass with the new code
+ * These rules should apply in general, but for this
+ * module they are VERY, VERY important.
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_resolver_service.h"
+
+
+
+#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-connection", syscall)
+
+
+/**
+ * Transmission handle.  There can only be one for each connection.
+ */
+struct GNUNET_CONNECTION_TransmitHandle
+{
+
+  /**
+   * Function to call if the send buffer has notify_size
+   * bytes available.
+   */
+  GNUNET_CONNECTION_TransmitReadyNotify notify_ready;
+
+  /**
+   * Closure for notify_ready.
+   */
+  void *notify_ready_cls;
+
+  /**
+   * Our connection handle.
+   */
+  struct GNUNET_CONNECTION_Handle *connection;
+
+  /**
+   * Timeout for receiving (in absolute time).
+   */
+  struct GNUNET_TIME_Absolute transmit_timeout;
+
+  /**
+   * Task called on timeout.
+   */
+  struct GNUNET_SCHEDULER_Task * timeout_task;
+
+  /**
+   * At what number of bytes available in the
+   * write buffer should the notify method be called?
+   */
+  size_t notify_size;
+
+};
+
+
+/**
+ * During connect, we try multiple possible IP addresses
+ * to find out which one might work.
+ */
+struct AddressProbe
+{
+
+  /**
+   * This is a linked list.
+   */
+  struct AddressProbe *next;
+
+  /**
+   * This is a doubly-linked list.
+   */
+  struct AddressProbe *prev;
+
+  /**
+   * The address; do not free (allocated at the end of this struct).
+   */
+  const struct sockaddr *addr;
+
+  /**
+   * Underlying OS's socket.
+   */
+  struct GNUNET_NETWORK_Handle *sock;
+
+  /**
+   * Connection for which we are probing.
+   */
+  struct GNUNET_CONNECTION_Handle *connection;
+
+  /**
+   * Lenth of addr.
+   */
+  socklen_t addrlen;
+
+  /**
+   * Task waiting for the connection to finish connecting.
+   */
+  struct GNUNET_SCHEDULER_Task * task;
+};
+
+
+/**
+ * @brief handle for a network connection
+ */
+struct GNUNET_CONNECTION_Handle
+{
+
+  /**
+   * Configuration to use.
+   */
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  /**
+   * Linked list of sockets we are currently trying out
+   * (during connect).
+   */
+  struct AddressProbe *ap_head;
+
+  /**
+   * Linked list of sockets we are currently trying out
+   * (during connect).
+   */
+  struct AddressProbe *ap_tail;
+
+  /**
+   * Network address of the other end-point, may be NULL.
+   */
+  struct sockaddr *addr;
+
+  /**
+   * Pointer to the hostname if connection was
+   * created using DNS lookup, otherwise NULL.
+   */
+  char *hostname;
+
+  /**
+   * Underlying OS's socket, set to NULL after fatal errors.
+   */
+  struct GNUNET_NETWORK_Handle *sock;
+
+  /**
+   * Function to call on data received, NULL if no receive is pending.
+   */
+  GNUNET_CONNECTION_Receiver receiver;
+
+  /**
+   * Closure for @e receiver.
+   */
+  void *receiver_cls;
+
+  /**
+   * Pointer to our write buffer.
+   */
+  char *write_buffer;
+
+  /**
+   * Current size of our @e write_buffer.
+   */
+  size_t write_buffer_size;
+
+  /**
+   * Current write-offset in @e write_buffer (where
+   * would we write next).
+   */
+  size_t write_buffer_off;
+
+  /**
+   * Current read-offset in @e write_buffer (how many
+   * bytes have already been sent).
+   */
+  size_t write_buffer_pos;
+
+  /**
+   * Length of @e addr.
+   */
+  socklen_t addrlen;
+
+  /**
+   * Read task that we may need to wait for.
+   */
+  struct GNUNET_SCHEDULER_Task *read_task;
+
+  /**
+   * Write task that we may need to wait for.
+   */
+  struct GNUNET_SCHEDULER_Task *write_task;
+
+  /**
+   * Handle to a pending DNS lookup request.
+   */
+  struct GNUNET_RESOLVER_RequestHandle *dns_active;
+
+  /**
+   * The handle we return for #GNUNET_CONNECTION_notify_transmit_ready().
+   */
+  struct GNUNET_CONNECTION_TransmitHandle nth;
+
+  /**
+   * Timeout for receiving (in absolute time).
+   */
+  struct GNUNET_TIME_Absolute receive_timeout;
+
+  /**
+   * Maximum number of bytes to read (for receiving).
+   */
+  size_t max;
+
+  /**
+   * Port to connect to.
+   */
+  uint16_t port;
+
+  /**
+   * When shutdown, do not ever actually close the socket, but
+   * free resources.  Only should ever be set if using program
+   * termination as a signal (because only then will the leaked
+   * socket be freed!)
+   */
+  int8_t persist;
+
+  /**
+   * Usually 0.  Set to 1 if this handle is in use, and should
+   * #GNUNET_CONNECTION_destroy() be called right now, the action needs
+   * to be deferred by setting it to -1.
+   */
+  int8_t destroy_later;
+
+  /**
+   * Handle to subsequent connection after proxy handshake completes,
+   */
+  struct GNUNET_CONNECTION_Handle *proxy_handshake;
+
+};
+
+
+/**
+ * Set the persist option on this connection handle.  Indicates
+ * that the underlying socket or fd should never really be closed.
+ * Used for indicating process death.
+ *
+ * @param connection the connection to set persistent
+ */
+void
+GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *connection)
+{
+  connection->persist = GNUNET_YES;
+}
+
+
+/**
+ * Disable the "CORK" feature for communication with the given connection,
+ * forcing the OS to immediately flush the buffer on transmission
+ * instead of potentially buffering multiple messages.  Essentially
+ * reduces the OS send buffers to zero.
+ * Used to make sure that the last messages sent through the connection
+ * reach the other side before the process is terminated.
+ *
+ * @param connection the connection to make flushing and blocking
+ * @return #GNUNET_OK on success
+ */
+int
+GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection)
+{
+  return GNUNET_NETWORK_socket_disable_corking (connection->sock);
+}
+
+
+/**
+ * Create a connection handle by boxing an existing OS socket.  The OS
+ * socket should henceforth be no longer used directly.
+ * #GNUNET_connection_destroy() will close it.
+ *
+ * @param osSocket existing socket to box
+ * @return the boxed connection handle
+ */
+struct GNUNET_CONNECTION_Handle *
+GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket)
+{
+  struct GNUNET_CONNECTION_Handle *connection;
+
+  connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
+  connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
+  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
+  connection->sock = osSocket;
+  return connection;
+}
+
+
+/**
+ * Create a connection handle by accepting on a listen socket.  This
+ * function may block if the listen socket has no connection ready.
+ *
+ * @param access_cb function to use to check if access is allowed
+ * @param access_cb_cls closure for @a access_cb
+ * @param lsock listen socket
+ * @return the connection handle, NULL on error
+ */
+struct GNUNET_CONNECTION_Handle *
+GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access_cb,
+                                      void *access_cb_cls,
+                                      struct GNUNET_NETWORK_Handle *lsock)
+{
+  struct GNUNET_CONNECTION_Handle *connection;
+  char addr[128];
+  socklen_t addrlen;
+  struct GNUNET_NETWORK_Handle *sock;
+  int aret;
+  struct sockaddr_in *v4;
+  struct sockaddr_in6 *v6;
+  struct sockaddr *sa;
+  void *uaddr;
+#ifdef SO_PEERCRED
+  struct ucred uc;
+  socklen_t olen;
+#endif
+  struct GNUNET_CONNECTION_Credentials *gcp;
+#if HAVE_GETPEEREID || defined(SO_PEERCRED) || HAVE_GETPEERUCRED
+  struct GNUNET_CONNECTION_Credentials gc;
+
+  gc.uid = 0;
+  gc.gid = 0;
+#endif
+
+  addrlen = sizeof (addr);
+  sock =
+      GNUNET_NETWORK_socket_accept (lsock,
+                                   (struct sockaddr *) &addr,
+                                   &addrlen);
+  if (NULL == sock)
+  {
+    if (EAGAIN != errno)
+      LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "accept");
+    return NULL;
+  }
+  if ((addrlen > sizeof (addr)) || (addrlen < sizeof (sa_family_t)))
+  {
+    GNUNET_break (0);
+    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
+    return NULL;
+  }
+
+  sa = (struct sockaddr *) addr;
+  v6 = (struct sockaddr_in6 *) addr;
+  if ( (AF_INET6 == sa->sa_family) &&
+       (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr)) )
+  {
+    /* convert to V4 address */
+    v4 = GNUNET_new (struct sockaddr_in);
+    memset (v4, 0, sizeof (struct sockaddr_in));
+    v4->sin_family = AF_INET;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+    v4->sin_len = (u_char) sizeof (struct sockaddr_in);
+#endif
+    GNUNET_memcpy (&v4->sin_addr,
+            &((char *) &v6->sin6_addr)[sizeof (struct in6_addr) -
+                                       sizeof (struct in_addr)],
+            sizeof (struct in_addr));
+    v4->sin_port = v6->sin6_port;
+    uaddr = v4;
+    addrlen = sizeof (struct sockaddr_in);
+  }
+  else
+  {
+    uaddr = GNUNET_malloc (addrlen);
+    GNUNET_memcpy (uaddr, addr, addrlen);
+  }
+  gcp = NULL;
+  if (AF_UNIX == sa->sa_family)
+  {
+#if HAVE_GETPEEREID
+    /* most BSDs */
+    if (0 == getpeereid (GNUNET_NETWORK_get_fd (sock),
+                        &gc.uid,
+                        &gc.gid))
+      gcp = &gc;
+#else
+#ifdef SO_PEERCRED
+    /* largely traditional GNU/Linux */
+    olen = sizeof (uc);
+    if ( (0 ==
+         getsockopt (GNUNET_NETWORK_get_fd (sock),
+                     SOL_SOCKET,
+                     SO_PEERCRED,
+                     &uc,
+                     &olen)) &&
+        (olen == sizeof (uc)) )
+    {
+      gc.uid = uc.uid;
+      gc.gid = uc.gid;
+      gcp = &gc;
+    }
+#else
+#if HAVE_GETPEERUCRED
+    /* this is for Solaris 10 */
+    ucred_t *uc;
+
+    uc = NULL;
+    if (0 == getpeerucred (GNUNET_NETWORK_get_fd (sock), &uc))
+    {
+      gc.uid = ucred_geteuid (uc);
+      gc.gid = ucred_getegid (uc);
+      gcp = &gc;
+    }
+    ucred_free (uc);
+#endif
+#endif
+#endif
+  }
+
+  if ( (NULL != access_cb) &&
+       (GNUNET_YES != (aret = access_cb (access_cb_cls,
+                                        gcp,
+                                        uaddr,
+                                        addrlen))) )
+  {
+    if (GNUNET_NO == aret)
+      LOG (GNUNET_ERROR_TYPE_INFO,
+           _("Access denied to `%s'\n"),
+           GNUNET_a2s (uaddr,
+                       addrlen));
+    GNUNET_break (GNUNET_OK ==
+                  GNUNET_NETWORK_socket_shutdown (sock,
+                                                  SHUT_RDWR));
+    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
+    GNUNET_free (uaddr);
+    return NULL;
+  }
+  connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
+  connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
+  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
+  connection->addr = uaddr;
+  connection->addrlen = addrlen;
+  connection->sock = sock;
+  LOG (GNUNET_ERROR_TYPE_INFO,
+       _("Accepting connection from `%s': %p\n"),
+       GNUNET_a2s (uaddr,
+                  addrlen),
+       connection);
+  return connection;
+}
+
+
+/**
+ * Obtain the network address of the other party.
+ *
+ * @param connection the client to get the address for
+ * @param addr where to store the address
+ * @param addrlen where to store the length of the @a addr
+ * @return #GNUNET_OK on success
+ */
+int
+GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *connection,
+                               void **addr,
+                               size_t *addrlen)
+{
+  if ((NULL == connection->addr) || (0 == connection->addrlen))
+    return GNUNET_NO;
+  *addr = GNUNET_malloc (connection->addrlen);
+  GNUNET_memcpy (*addr, connection->addr, connection->addrlen);
+  *addrlen = connection->addrlen;
+  return GNUNET_OK;
+}
+
+
+/**
+ * Tell the receiver callback that we had an IO error.
+ *
+ * @param connection connection to signal error
+ * @param errcode error code to send
+ */
+static void
+signal_receive_error (struct GNUNET_CONNECTION_Handle *connection,
+                      int errcode)
+{
+  GNUNET_CONNECTION_Receiver receiver;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Receive encounters error (%s), connection closed (%p)\n",
+       STRERROR (errcode),
+       connection);
+  GNUNET_assert (NULL != (receiver = connection->receiver));
+  connection->receiver = NULL;
+  receiver (connection->receiver_cls,
+            NULL,
+            0,
+            connection->addr,
+            connection->addrlen,
+            errcode);
+}
+
+
+/**
+ * Tell the receiver callback that a timeout was reached.
+ *
+ * @param connection connection to signal for
+ */
+static void
+signal_receive_timeout (struct GNUNET_CONNECTION_Handle *connection)
+{
+  GNUNET_CONNECTION_Receiver receiver;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Connection signals timeout to receiver (%p)!\n",
+       connection);
+  GNUNET_assert (NULL != (receiver = connection->receiver));
+  connection->receiver = NULL;
+  receiver (connection->receiver_cls, NULL, 0, NULL, 0, 0);
+}
+
+
+/**
+ * We failed to transmit data to the service, signal the error.
+ *
+ * @param connection handle that had trouble
+ * @param ecode error code (errno)
+ */
+static void
+signal_transmit_error (struct GNUNET_CONNECTION_Handle *connection,
+                      int ecode)
+{
+  GNUNET_CONNECTION_TransmitReadyNotify notify;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Transmission encounterd error (%s), connection closed (%p)\n",
+       STRERROR (ecode),
+       connection);
+  if (NULL != connection->sock)
+  {
+    (void) GNUNET_NETWORK_socket_shutdown (connection->sock,
+                                           SHUT_RDWR);
+    GNUNET_break (GNUNET_OK ==
+                  GNUNET_NETWORK_socket_close (connection->sock));
+    connection->sock = NULL;
+    GNUNET_assert (NULL == connection->write_task);
+  }
+  if (NULL != connection->read_task)
+  {
+    /* send errors trigger read errors... */
+    GNUNET_SCHEDULER_cancel (connection->read_task);
+    connection->read_task = NULL;
+    signal_receive_timeout (connection);
+    return;
+  }
+  if (NULL == connection->nth.notify_ready)
+    return;                     /* nobody to tell about it */
+  notify = connection->nth.notify_ready;
+  connection->nth.notify_ready = NULL;
+  notify (connection->nth.notify_ready_cls,
+         0,
+         NULL);
+}
+
+
+/**
+ * We've failed for good to establish a connection (timeout or
+ * no more addresses to try).
+ *
+ * @param connection the connection we tried to establish
+ */
+static void
+connect_fail_continuation (struct GNUNET_CONNECTION_Handle *connection)
+{
+  LOG (GNUNET_ERROR_TYPE_INFO,
+       "Failed to establish TCP connection to `%s:%u', no further addresses to try.\n",
+       connection->hostname,
+    connection->port);
+  GNUNET_break (NULL == connection->ap_head);
+  GNUNET_break (NULL == connection->ap_tail);
+  GNUNET_break (GNUNET_NO == connection->dns_active);
+  GNUNET_break (NULL == connection->sock);
+  GNUNET_assert (NULL == connection->write_task);
+  GNUNET_assert (NULL == connection->proxy_handshake);
+
+  /* signal errors for jobs that used to wait on the connection */
+  connection->destroy_later = 1;
+  if (NULL != connection->receiver)
+    signal_receive_error (connection,
+                          ECONNREFUSED);
+  if (NULL != connection->nth.notify_ready)
+  {
+    GNUNET_assert (NULL != connection->nth.timeout_task);
+    GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
+    connection->nth.timeout_task = NULL;
+    signal_transmit_error (connection,
+                           ECONNREFUSED);
+  }
+  if (-1 == connection->destroy_later)
+  {
+    /* do it now */
+    connection->destroy_later = 0;
+    GNUNET_CONNECTION_destroy (connection);
+    return;
+  }
+  connection->destroy_later = 0;
+}
+
+
+/**
+ * We are ready to transmit (or got a timeout).
+ *
+ * @param cls our connection handle
+ */
+static void
+transmit_ready (void *cls);
+
+
+/**
+ * This function is called once we either timeout or have data ready
+ * to read.
+ *
+ * @param cls connection to read from
+ */
+static void
+receive_ready (void *cls);
+
+
+/**
+ * We've succeeded in establishing a connection.
+ *
+ * @param connection the connection we tried to establish
+ */
+static void
+connect_success_continuation (struct GNUNET_CONNECTION_Handle *connection)
+{
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Connection to `%s' succeeded! (%p)\n",
+       GNUNET_a2s (connection->addr,
+                  connection->addrlen),
+       connection);
+  /* trigger jobs that waited for the connection */
+  if (NULL != connection->receiver)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Connection succeeded, starting with receiving data (%p)\n",
+        connection);
+    GNUNET_assert (NULL == connection->read_task);
+    connection->read_task =
+      GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining
+                                     (connection->receive_timeout),
+                                    connection->sock,
+                                     &receive_ready, connection);
+  }
+  if (NULL != connection->nth.notify_ready)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Connection succeeded, starting with sending data (%p)\n",
+         connection);
+    GNUNET_assert (connection->nth.timeout_task != NULL);
+    GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
+    connection->nth.timeout_task = NULL;
+    GNUNET_assert (connection->write_task == NULL);
+    connection->write_task =
+        GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining
+                                        (connection->nth.transmit_timeout), connection->sock,
+                                        &transmit_ready, connection);
+  }
+}
+
+
+/**
+ * Scheduler let us know that we're either ready to write on the
+ * socket OR connect timed out.  Do the right thing.
+ *
+ * @param cls the `struct AddressProbe *` with the address that we are probing
+ */
+static void
+connect_probe_continuation (void *cls)
+{
+  struct AddressProbe *ap = cls;
+  struct GNUNET_CONNECTION_Handle *connection = ap->connection;
+  const struct GNUNET_SCHEDULER_TaskContext *tc;
+  struct AddressProbe *pos;
+  int error;
+  socklen_t len;
+
+  GNUNET_assert (NULL != ap->sock);
+  GNUNET_CONTAINER_DLL_remove (connection->ap_head,
+                              connection->ap_tail,
+                              ap);
+  len = sizeof (error);
+  errno = 0;
+  error = 0;
+  tc = GNUNET_SCHEDULER_get_task_context ();
+  if ( (0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ||
+       (GNUNET_OK !=
+       GNUNET_NETWORK_socket_getsockopt (ap->sock,
+                                         SOL_SOCKET,
+                                         SO_ERROR,
+                                         &error,
+                                         &len)) ||
+       (0 != error) )
+  {
+    GNUNET_break (GNUNET_OK ==
+                 GNUNET_NETWORK_socket_close (ap->sock));
+    GNUNET_free (ap);
+    if ( (NULL == connection->ap_head) &&
+        (GNUNET_NO == connection->dns_active) &&
+        (NULL == connection->proxy_handshake) )
+      connect_fail_continuation (connection);
+    return;
+  }
+  GNUNET_assert (NULL == connection->sock);
+  connection->sock = ap->sock;
+  GNUNET_assert (NULL == connection->addr);
+  connection->addr = GNUNET_malloc (ap->addrlen);
+  GNUNET_memcpy (connection->addr, ap->addr, ap->addrlen);
+  connection->addrlen = ap->addrlen;
+  GNUNET_free (ap);
+  /* cancel all other attempts */
+  while (NULL != (pos = connection->ap_head))
+  {
+    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock));
+    GNUNET_SCHEDULER_cancel (pos->task);
+    GNUNET_CONTAINER_DLL_remove (connection->ap_head,
+                                connection->ap_tail,
+                                pos);
+    GNUNET_free (pos);
+  }
+  connect_success_continuation (connection);
+}
+
+
+/**
+ * Try to establish a connection given the specified address.
+ * This function is called by the resolver once we have a DNS reply.
+ *
+ * @param cls our `struct GNUNET_CONNECTION_Handle *`
+ * @param addr address to try, NULL for "last call"
+ * @param addrlen length of @a addr
+ */
+static void
+try_connect_using_address (void *cls,
+                           const struct sockaddr *addr,
+                           socklen_t addrlen)
+{
+  struct GNUNET_CONNECTION_Handle *connection = cls;
+  struct AddressProbe *ap;
+  struct GNUNET_TIME_Relative delay;
+
+  if (NULL == addr)
+  {
+    connection->dns_active = NULL;
+    if ((NULL == connection->ap_head) &&
+        (NULL == connection->sock) &&
+        (NULL == connection->proxy_handshake))
+      connect_fail_continuation (connection);
+    return;
+  }
+  if (NULL != connection->sock)
+    return;                     /* already connected */
+  GNUNET_assert (NULL == connection->addr);
+  /* try to connect */
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Trying to connect using address `%s:%u/%s:%u'\n",
+       connection->hostname,
+       connection->port,
+       GNUNET_a2s (addr, addrlen),
+       connection->port);
+  ap = GNUNET_malloc (sizeof (struct AddressProbe) + addrlen);
+  ap->addr = (const struct sockaddr *) &ap[1];
+  GNUNET_memcpy (&ap[1], addr, addrlen);
+  ap->addrlen = addrlen;
+  ap->connection = connection;
+
+  switch (ap->addr->sa_family)
+  {
+  case AF_INET:
+    ((struct sockaddr_in *) ap->addr)->sin_port = htons (connection->port);
+    break;
+  case AF_INET6:
+    ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (connection->port);
+    break;
+  default:
+    GNUNET_break (0);
+    GNUNET_free (ap);
+    return;                     /* not supported by us */
+  }
+  ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family,
+                                          SOCK_STREAM, 0);
+  if (NULL == ap->sock)
+  {
+    GNUNET_free (ap);
+    return;                     /* not supported by OS */
+  }
+  LOG (GNUNET_ERROR_TYPE_INFO,
+       "Trying to connect to `%s' (%p)\n",
+       GNUNET_a2s (ap->addr, ap->addrlen),
+       connection);
+  if ((GNUNET_OK !=
+       GNUNET_NETWORK_socket_connect (ap->sock,
+                                     ap->addr,
+                                     ap->addrlen)) &&
+      (EINPROGRESS != errno))
+  {
+    /* maybe refused / unsupported address, try next */
+    LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect");
+    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock));
+    GNUNET_free (ap);
+    return;
+  }
+  GNUNET_CONTAINER_DLL_insert (connection->ap_head, connection->ap_tail, ap);
+  delay = GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT;
+  if (NULL != connection->nth.notify_ready)
+    delay = GNUNET_TIME_relative_min (delay,
+                                     GNUNET_TIME_absolute_get_remaining (connection->nth.transmit_timeout));
+  if (NULL != connection->receiver)
+    delay = GNUNET_TIME_relative_min (delay,
+                                     GNUNET_TIME_absolute_get_remaining (connection->receive_timeout));
+  ap->task = GNUNET_SCHEDULER_add_write_net (delay,
+                                            ap->sock,
+                                            &connect_probe_continuation,
+                                            ap);
+}
+
+
+/**
+ * Create a connection handle by (asynchronously) connecting to a host.
+ * This function returns immediately, even if the connection has not
+ * yet been established.  This function only creates TCP connections.
+ *
+ * @param cfg configuration to use
+ * @param hostname name of the host to connect to
+ * @param port port to connect to
+ * @return the connection handle
+ */
+struct GNUNET_CONNECTION_Handle *
+GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
+                                       const char *hostname,
+                                       uint16_t port)
+{
+  struct GNUNET_CONNECTION_Handle *connection;
+
+  GNUNET_assert (0 < strlen (hostname));        /* sanity check */
+  connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
+  connection->cfg = cfg;
+  connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
+  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
+  connection->port = port;
+  connection->hostname = GNUNET_strdup (hostname);
+  connection->dns_active =
+      GNUNET_RESOLVER_ip_get (connection->hostname,
+                             AF_UNSPEC,
+                              GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT,
+                              &try_connect_using_address,
+                             connection);
+  return connection;
+}
+
+
+/**
+ * Create a connection handle by connecting to a UNIX domain service.
+ * This function returns immediately, even if the connection has not
+ * yet been established.  This function only creates UNIX connections.
+ *
+ * @param cfg configuration to use
+ * @param unixpath path to connect to
+ * @return the connection handle, NULL on systems without UNIX support
+ */
+struct GNUNET_CONNECTION_Handle *
+GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct GNUNET_CONFIGURATION_Handle *cfg,
+                                                   const char *unixpath)
+{
+#ifdef AF_UNIX
+  struct GNUNET_CONNECTION_Handle *connection;
+  struct sockaddr_un *un;
+
+  GNUNET_assert (0 < strlen (unixpath));        /* sanity check */
+  un = GNUNET_new (struct sockaddr_un);
+  un->sun_family = AF_UNIX;
+  strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1);
+#ifdef LINUX
+  {
+    int abstract;
+
+    abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
+                                                    "TESTING",
+                                                     "USE_ABSTRACT_SOCKETS");
+    if (GNUNET_YES == abstract)
+      un->sun_path[0] = '\0';
+  }
+#endif
+#if HAVE_SOCKADDR_UN_SUN_LEN
+  un->sun_len = (u_char) sizeof (struct sockaddr_un);
+#endif
+  connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
+  connection->cfg = cfg;
+  connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
+  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
+  connection->port = 0;
+  connection->hostname = NULL;
+  connection->addr = (struct sockaddr *) un;
+  connection->addrlen = sizeof (struct sockaddr_un);
+  connection->sock = GNUNET_NETWORK_socket_create (AF_UNIX,
+                                                  SOCK_STREAM,
+                                                  0);
+  if (NULL == connection->sock)
+  {
+    GNUNET_free (connection->addr);
+    GNUNET_free (connection->write_buffer);
+    GNUNET_free (connection);
+    return NULL;
+  }
+  if ( (GNUNET_OK !=
+       GNUNET_NETWORK_socket_connect (connection->sock,
+                                      connection->addr,
+                                      connection->addrlen)) &&
+       (EINPROGRESS != errno) )
+  {
+    /* Just return; we expect everything to work eventually so don't fail HARD */
+    GNUNET_break (GNUNET_OK ==
+                 GNUNET_NETWORK_socket_close (connection->sock));
+    connection->sock = NULL;
+    return connection;
+  }
+  connect_success_continuation (connection);
+  return connection;
+#else
+  return NULL;
+#endif
+}
+
+
+/**
+ * Create a connection handle by (asynchronously) connecting to a host.
+ * This function returns immediately, even if the connection has not
+ * yet been established.  This function only creates TCP connections.
+ *
+ * @param s socket to connect
+ * @param serv_addr server address
+ * @param addrlen length of @a serv_addr
+ * @return the connection handle
+ */
+struct GNUNET_CONNECTION_Handle *
+GNUNET_CONNECTION_connect_socket (struct GNUNET_NETWORK_Handle *s,
+                                  const struct sockaddr *serv_addr,
+                                  socklen_t addrlen)
+{
+  struct GNUNET_CONNECTION_Handle *connection;
+
+  if ( (GNUNET_OK !=
+        GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) &&
+       (EINPROGRESS != errno) )
+  {
+    /* maybe refused / unsupported address, try next */
+    LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG,
+                  "connect");
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Attempt to connect to `%s' failed\n",
+         GNUNET_a2s (serv_addr,
+                     addrlen));
+    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s));
+    return NULL;
+  }
+  connection = GNUNET_CONNECTION_create_from_existing (s);
+  connection->addr = GNUNET_malloc (addrlen);
+  GNUNET_memcpy (connection->addr, serv_addr, addrlen);
+  connection->addrlen = addrlen;
+  LOG (GNUNET_ERROR_TYPE_INFO,
+       "Trying to connect to `%s' (%p)\n",
+       GNUNET_a2s (serv_addr, addrlen),
+       connection);
+  return connection;
+}
+
+
+/**
+ * Create a connection handle by creating a socket and
+ * (asynchronously) connecting to a host.  This function returns
+ * immediately, even if the connection has not yet been established.
+ * This function only creates TCP connections.
+ *
+ * @param af_family address family to use
+ * @param serv_addr server address
+ * @param addrlen length of @a serv_addr
+ * @return the connection handle
+ */
+struct GNUNET_CONNECTION_Handle *
+GNUNET_CONNECTION_create_from_sockaddr (int af_family,
+                                        const struct sockaddr *serv_addr,
+                                        socklen_t addrlen)
+{
+  struct GNUNET_NETWORK_Handle *s;
+
+  s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0);
+  if (NULL == s)
+  {
+    LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
+                 "socket");
+    return NULL;
+  }
+  return GNUNET_CONNECTION_connect_socket (s,
+                                          serv_addr,
+                                          addrlen);
+}
+
+
+/**
+ * Check if connection is valid (no fatal errors have happened so far).
+ * Note that a connection that is still trying to connect is considered
+ * valid.
+ *
+ * @param connection connection to check
+ * @return #GNUNET_YES if valid, #GNUNET_NO otherwise
+ */
+int
+GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *connection)
+{
+  if ((NULL != connection->ap_head) ||
+      (NULL != connection->dns_active) ||
+      (NULL != connection->proxy_handshake))
+    return GNUNET_YES;          /* still trying to connect */
+  if ( (0 != connection->destroy_later) ||
+       (NULL == connection->sock) )
+    return GNUNET_NO;
+  return GNUNET_YES;
+}
+
+
+/**
+ * Close the connection and free associated resources.  There must
+ * not be any pending requests for reading or writing to the
+ * connection at this time.
+ *
+ * @param connection connection to destroy
+ */
+void
+GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection)
+{
+  struct AddressProbe *pos;
+
+  if (0 != connection->destroy_later)
+  {
+    connection->destroy_later = -1;
+    return;
+  }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Shutting down connection (%p)\n",
+       connection);
+  GNUNET_assert (NULL == connection->nth.notify_ready);
+  GNUNET_assert (NULL == connection->receiver);
+  if (NULL != connection->write_task)
+  {
+    GNUNET_SCHEDULER_cancel (connection->write_task);
+    connection->write_task = NULL;
+    connection->write_buffer_off = 0;
+  }
+  if (NULL != connection->read_task)
+  {
+    GNUNET_SCHEDULER_cancel (connection->read_task);
+    connection->read_task = NULL;
+  }
+  if (NULL != connection->nth.timeout_task)
+  {
+    GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
+    connection->nth.timeout_task = NULL;
+  }
+  connection->nth.notify_ready = NULL;
+  if (NULL != connection->dns_active)
+  {
+    GNUNET_RESOLVER_request_cancel (connection->dns_active);
+    connection->dns_active = NULL;
+  }
+  if (NULL != connection->proxy_handshake)
+  {
+    /* GNUNET_CONNECTION_destroy (connection->proxy_handshake); */
+    connection->proxy_handshake->destroy_later = -1;
+    connection->proxy_handshake = NULL;  /* Not leaked ??? */
+  }
+  while (NULL != (pos = connection->ap_head))
+  {
+    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock));
+    GNUNET_SCHEDULER_cancel (pos->task);
+    GNUNET_CONTAINER_DLL_remove (connection->ap_head,
+                                connection->ap_tail,
+                                pos);
+    GNUNET_free (pos);
+  }
+  if ( (NULL != connection->sock) &&
+       (GNUNET_YES != connection->persist) )
+  {
+    if ((GNUNET_OK !=
+         GNUNET_NETWORK_socket_shutdown (connection->sock,
+                                         SHUT_RDWR)) &&
+       (ENOTCONN != errno) &&
+       (ECONNRESET != errno) )
+      LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
+                    "shutdown");
+  }
+  if (NULL != connection->sock)
+  {
+    if (GNUNET_YES != connection->persist)
+    {
+      GNUNET_break (GNUNET_OK ==
+                    GNUNET_NETWORK_socket_close (connection->sock));
+    }
+    else
+    {
+      GNUNET_NETWORK_socket_free_memory_only_ (connection->sock); /* at least no memory leak (we deliberately
+                                                                  * leak the socket in this special case) ... */
+    }
+  }
+  GNUNET_free_non_null (connection->addr);
+  GNUNET_free_non_null (connection->hostname);
+  GNUNET_free (connection->write_buffer);
+  GNUNET_free (connection);
+}
+
+
+/**
+ * This function is called once we either timeout
+ * or have data ready to read.
+ *
+ * @param cls connection to read from
+ */
+static void
+receive_ready (void *cls)
+{
+  struct GNUNET_CONNECTION_Handle *connection = cls;
+  const struct GNUNET_SCHEDULER_TaskContext *tc;
+  char buffer[connection->max];
+  ssize_t ret;
+  GNUNET_CONNECTION_Receiver receiver;
+
+  connection->read_task = NULL;
+  tc = GNUNET_SCHEDULER_get_task_context ();
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+        "Receive from `%s' encounters error: timeout (%s, %p)\n",
+        GNUNET_a2s (connection->addr,
+                    connection->addrlen),
+        GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (connection->receive_timeout),
+                                                GNUNET_YES),
+        connection);
+    signal_receive_timeout (connection);
+    return;
+  }
+  if (NULL == connection->sock)
+  {
+    /* connect failed for good */
+    signal_receive_error (connection, ECONNREFUSED);
+    return;
+  }
+  GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready,
+                                            connection->sock));
+RETRY:
+  ret = GNUNET_NETWORK_socket_recv (connection->sock,
+                                    buffer,
+                                    connection->max);
+  if (-1 == ret)
+  {
+    if (EINTR == errno)
+      goto RETRY;
+    signal_receive_error (connection, errno);
+    return;
+  }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "receive_ready read %u/%u bytes from `%s' (%p)!\n",
+       (unsigned int) ret,
+       connection->max,
+       GNUNET_a2s (connection->addr,
+                   connection->addrlen),
+       connection);
+  GNUNET_assert (NULL != (receiver = connection->receiver));
+  connection->receiver = NULL;
+  receiver (connection->receiver_cls,
+            buffer,
+            ret,
+            connection->addr,
+            connection->addrlen,
+            0);
+}
+
+
+/**
+ * Receive data from the given connection.  Note that this function
+ * will call @a receiver asynchronously using the scheduler.  It will
+ * "immediately" return.  Note that there MUST only be one active
+ * receive call per connection at any given point in time (so do not
+ * call receive again until the receiver callback has been invoked).
+ *
+ * @param connection connection handle
+ * @param max maximum number of bytes to read
+ * @param timeout maximum amount of time to wait
+ * @param receiver function to call with received data
+ * @param receiver_cls closure for @a receiver
+ */
+void
+GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *connection,
+                           size_t max,
+                           struct GNUNET_TIME_Relative timeout,
+                           GNUNET_CONNECTION_Receiver receiver,
+                           void *receiver_cls)
+{
+  GNUNET_assert ((NULL == connection->read_task) &&
+                 (NULL == connection->receiver));
+  GNUNET_assert (NULL != receiver);
+  connection->receiver = receiver;
+  connection->receiver_cls = receiver_cls;
+  connection->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout);
+  connection->max = max;
+  if (NULL != connection->sock)
+  {
+    connection->read_task =
+      GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining
+                                     (connection->receive_timeout),
+                                     connection->sock,
+                                     &receive_ready,
+                                     connection);
+    return;
+  }
+  if ((NULL == connection->dns_active) &&
+      (NULL == connection->ap_head) &&
+      (NULL == connection->proxy_handshake))
+  {
+    connection->receiver = NULL;
+    receiver (receiver_cls,
+             NULL, 0,
+             NULL, 0,
+             ETIMEDOUT);
+    return;
+  }
+}
+
+
+/**
+ * Cancel receive job on the given connection.  Note that the
+ * receiver callback must not have been called yet in order
+ * for the cancellation to be valid.
+ *
+ * @param connection connection handle
+ * @return closure of the original receiver callback closure
+ */
+void *
+GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *connection)
+{
+  if (NULL != connection->read_task)
+  {
+    GNUNET_assert (connection ==
+                   GNUNET_SCHEDULER_cancel (connection->read_task));
+    connection->read_task = NULL;
+  }
+  connection->receiver = NULL;
+  return connection->receiver_cls;
+}
+
+
+/**
+ * Try to call the transmit notify method (check if we do
+ * have enough space available first)!
+ *
+ * @param connection connection for which we should do this processing
+ * @return #GNUNET_YES if we were able to call notify
+ */
+static int
+process_notify (struct GNUNET_CONNECTION_Handle *connection)
+{
+  size_t used;
+  size_t avail;
+  size_t size;
+  GNUNET_CONNECTION_TransmitReadyNotify notify;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "process_notify is running\n");
+  GNUNET_assert (NULL == connection->write_task);
+  if (NULL == (notify = connection->nth.notify_ready))
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "No one to notify\n");
+    return GNUNET_NO;
+  }
+  used = connection->write_buffer_off - connection->write_buffer_pos;
+  avail = connection->write_buffer_size - used;
+  size = connection->nth.notify_size;
+  if (size > avail)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Not enough buffer\n");
+    return GNUNET_NO;
+  }
+  connection->nth.notify_ready = NULL;
+  if (connection->write_buffer_size - connection->write_buffer_off < size)
+  {
+    /* need to compact */
+    memmove (connection->write_buffer,
+             &connection->write_buffer[connection->write_buffer_pos],
+             used);
+    connection->write_buffer_off -= connection->write_buffer_pos;
+    connection->write_buffer_pos = 0;
+  }
+  avail = connection->write_buffer_size - connection->write_buffer_off;
+  GNUNET_assert (avail >= size);
+  size =
+      notify (connection->nth.notify_ready_cls, avail,
+              &connection->write_buffer[connection->write_buffer_off]);
+  GNUNET_assert (size <= avail);
+  if (0 != size)
+    connection->write_buffer_off += size;
+  return GNUNET_YES;
+}
+
+
+/**
+ * Task invoked by the scheduler when a call to transmit
+ * is timing out (we never got enough buffer space to call
+ * the callback function before the specified timeout
+ * expired).
+ *
+ * This task notifies the client about the timeout.
+ *
+ * @param cls the `struct GNUNET_CONNECTION_Handle`
+ */
+static void
+transmit_timeout (void *cls)
+{
+  struct GNUNET_CONNECTION_Handle *connection = cls;
+  GNUNET_CONNECTION_TransmitReadyNotify notify;
+
+  connection->nth.timeout_task = NULL;
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Transmit to `%s:%u/%s' fails, time out reached (%p).\n",
+       connection->hostname,
+       connection->port,
+       GNUNET_a2s (connection->addr,
+                   connection->addrlen),
+       connection);
+  notify = connection->nth.notify_ready;
+  GNUNET_assert (NULL != notify);
+  connection->nth.notify_ready = NULL;
+  notify (connection->nth.notify_ready_cls,
+         0,
+         NULL);
+}
+
+
+/**
+ * Task invoked by the scheduler when we failed to connect
+ * at the time of being asked to transmit.
+ *
+ * This task notifies the client about the error.
+ *
+ * @param cls the `struct GNUNET_CONNECTION_Handle`
+ */
+static void
+connect_error (void *cls)
+{
+  struct GNUNET_CONNECTION_Handle *connection = cls;
+  GNUNET_CONNECTION_TransmitReadyNotify notify;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Transmission request of size %u fails (%s/%u), connection failed (%p).\n",
+       connection->nth.notify_size,
+       connection->hostname,
+       connection->port,
+       connection);
+  connection->write_task = NULL;
+  notify = connection->nth.notify_ready;
+  connection->nth.notify_ready = NULL;
+  notify (connection->nth.notify_ready_cls,
+         0,
+         NULL);
+}
+
+
+/**
+ * We are ready to transmit (or got a timeout).
+ *
+ * @param cls our connection handle
+ */
+static void
+transmit_ready (void *cls)
+{
+  struct GNUNET_CONNECTION_Handle *connection = cls;
+  GNUNET_CONNECTION_TransmitReadyNotify notify;
+  const struct GNUNET_SCHEDULER_TaskContext *tc;
+  ssize_t ret;
+  size_t have;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "transmit_ready running (%p).\n",
+       connection);
+  GNUNET_assert (NULL != connection->write_task);
+  connection->write_task = NULL;
+  GNUNET_assert (NULL == connection->nth.timeout_task);
+  tc = GNUNET_SCHEDULER_get_task_context ();
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Transmit to `%s' fails, time out reached (%p).\n",
+         GNUNET_a2s (connection->addr,
+                     connection->addrlen),
+         connection);
+    notify = connection->nth.notify_ready;
+    GNUNET_assert (NULL != notify);
+    connection->nth.notify_ready = NULL;
+    notify (connection->nth.notify_ready_cls, 0, NULL);
+    return;
+  }
+  GNUNET_assert (NULL != connection->sock);
+  if (NULL == tc->write_ready)
+  {
+    /* special circumstances (in particular, PREREQ_DONE after
+     * connect): not yet ready to write, but no "fatal" error either.
+     * Hence retry.  */
+    goto SCHEDULE_WRITE;
+  }
+  if (! GNUNET_NETWORK_fdset_isset (tc->write_ready,
+                                   connection->sock))
+  {
+    GNUNET_assert (NULL == connection->write_task);
+    /* special circumstances (in particular, shutdown): not yet ready
+     * to write, but no "fatal" error either.  Hence retry.  */
+    goto SCHEDULE_WRITE;
+  }
+  GNUNET_assert (connection->write_buffer_off >= connection->write_buffer_pos);
+  if ((NULL != connection->nth.notify_ready) &&
+      (connection->write_buffer_size < connection->nth.notify_size))
+  {
+    connection->write_buffer =
+        GNUNET_realloc (connection->write_buffer, connection->nth.notify_size);
+    connection->write_buffer_size = connection->nth.notify_size;
+  }
+  process_notify (connection);
+  have = connection->write_buffer_off - connection->write_buffer_pos;
+  if (0 == have)
+  {
+    /* no data ready for writing, terminate write loop */
+    return;
+  }
+  GNUNET_assert (have <= connection->write_buffer_size);
+  GNUNET_assert (have + connection->write_buffer_pos <= connection->write_buffer_size);
+  GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size);
+RETRY:
+  ret =
+      GNUNET_NETWORK_socket_send (connection->sock,
+                                 &connection->write_buffer[connection->write_buffer_pos],
+                                 have);
+  if (-1 == ret)
+  {
+    if (EINTR == errno)
+      goto RETRY;
+    if (NULL != connection->write_task)
+    {
+      GNUNET_SCHEDULER_cancel (connection->write_task);
+      connection->write_task = NULL;
+    }
+    signal_transmit_error (connection, errno);
+    return;
+  }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Connection transmitted %u/%u bytes to `%s' (%p)\n",
+       (unsigned int) ret,
+       have,
+       GNUNET_a2s (connection->addr,
+                  connection->addrlen),
+       connection);
+  connection->write_buffer_pos += ret;
+  if (connection->write_buffer_pos == connection->write_buffer_off)
+  {
+    /* transmitted all pending data */
+    connection->write_buffer_pos = 0;
+    connection->write_buffer_off = 0;
+  }
+  if ( (0 == connection->write_buffer_off) &&
+       (NULL == connection->nth.notify_ready) )
+    return;                     /* all data sent! */
+  /* not done writing, schedule more */
+SCHEDULE_WRITE:
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Re-scheduling transmit_ready (more to do) (%p).\n",
+       connection);
+  have = connection->write_buffer_off - connection->write_buffer_pos;
+  GNUNET_assert ( (NULL != connection->nth.notify_ready) ||
+                 (have > 0) );
+  if (NULL == connection->write_task)
+    connection->write_task =
+        GNUNET_SCHEDULER_add_write_net ((connection->nth.notify_ready ==
+                                         NULL) ? GNUNET_TIME_UNIT_FOREVER_REL :
+                                        GNUNET_TIME_absolute_get_remaining
+                                        (connection->nth.transmit_timeout),
+                                        connection->sock,
+                                       &transmit_ready, connection);
+}
+
+
+/**
+ * Ask the connection to call us once the specified number of bytes
+ * are free in the transmission buffer.  Will never call the @a notify
+ * callback in this task, but always first go into the scheduler.
+ *
+ * @param connection connection
+ * @param size number of bytes to send
+ * @param timeout after how long should we give up (and call
+ *        @a notify with buf NULL and size 0)?
+ * @param notify function to call
+ * @param notify_cls closure for @a notify
+ * @return non-NULL if the notify callback was queued,
+ *         NULL if we are already going to notify someone else (busy)
+ */
+struct GNUNET_CONNECTION_TransmitHandle *
+GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connection,
+                                         size_t size,
+                                         struct GNUNET_TIME_Relative timeout,
+                                         GNUNET_CONNECTION_TransmitReadyNotify notify,
+                                        void *notify_cls)
+{
+  if (NULL != connection->nth.notify_ready)
+  {
+    GNUNET_assert (0);
+    return NULL;
+  }
+  GNUNET_assert (NULL != notify);
+  GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
+  GNUNET_assert (connection->write_buffer_off <= connection->write_buffer_size);
+  GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size);
+  GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_off);
+  connection->nth.notify_ready = notify;
+  connection->nth.notify_ready_cls = notify_cls;
+  connection->nth.connection = connection;
+  connection->nth.notify_size = size;
+  connection->nth.transmit_timeout = GNUNET_TIME_relative_to_absolute (timeout);
+  GNUNET_assert (NULL == connection->nth.timeout_task);
+  if ((NULL == connection->sock) &&
+      (NULL == connection->ap_head) &&
+      (NULL == connection->dns_active) &&
+      (NULL == connection->proxy_handshake))
+  {
+    if (NULL != connection->write_task)
+      GNUNET_SCHEDULER_cancel (connection->write_task);
+    connection->write_task = GNUNET_SCHEDULER_add_now (&connect_error,
+                                                       connection);
+    return &connection->nth;
+  }
+  if (NULL != connection->write_task)
+    return &connection->nth; /* previous transmission still in progress */
+  if (NULL != connection->sock)
+  {
+    /* connected, try to transmit now */
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Scheduling transmission (%p).\n",
+         connection);
+    connection->write_task =
+        GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining
+                                        (connection->nth.transmit_timeout),
+                                        connection->sock,
+                                       &transmit_ready, connection);
+    return &connection->nth;
+  }
+  /* not yet connected, wait for connection */
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Need to wait to schedule transmission for connection, adding timeout task (%p).\n",
+       connection);
+  connection->nth.timeout_task =
+    GNUNET_SCHEDULER_add_delayed (timeout,
+                                  &transmit_timeout,
+                                 connection);
+  return &connection->nth;
+}
+
+
+/**
+ * Cancel the specified transmission-ready notification.
+ *
+ * @param th notification to cancel
+ */
+void
+GNUNET_CONNECTION_notify_transmit_ready_cancel (struct GNUNET_CONNECTION_TransmitHandle *th)
+{
+  GNUNET_assert (NULL != th->notify_ready);
+  th->notify_ready = NULL;
+  if (NULL != th->timeout_task)
+  {
+    GNUNET_SCHEDULER_cancel (th->timeout_task);
+    th->timeout_task = NULL;
+  }
+  if (NULL != th->connection->write_task)
+  {
+    GNUNET_SCHEDULER_cancel (th->connection->write_task);
+    th->connection->write_task = NULL;
+  }
+}
+
+
+/**
+ * Create a connection to be proxied using a given connection.
+ *
+ * @param cph connection to proxy server
+ * @return connection to be proxied
+ */
+struct GNUNET_CONNECTION_Handle *
+GNUNET_CONNECTION_create_proxied_from_handshake (struct GNUNET_CONNECTION_Handle *cph)
+{
+  struct GNUNET_CONNECTION_Handle *proxied = GNUNET_CONNECTION_create_from_existing (NULL);
+
+  proxied->proxy_handshake = cph;
+  return proxied;
+}
+
+
+/**
+ * Activate proxied connection and destroy initial proxy handshake connection.
+ * There must not be any pending requests for reading or writing to the
+ * proxy hadshake connection at this time.
+ *
+ * @param proxied connection connection to proxy server
+ */
+void
+GNUNET_CONNECTION_acivate_proxied (struct GNUNET_CONNECTION_Handle *proxied)
+{
+  struct GNUNET_CONNECTION_Handle *cph = proxied->proxy_handshake;
+
+  GNUNET_assert (NULL != cph);
+  GNUNET_assert (NULL == proxied->sock);
+  GNUNET_assert (NULL != cph->sock);
+  proxied->sock = cph->sock;
+  cph->sock = NULL;
+  GNUNET_CONNECTION_destroy (cph);
+  connect_success_continuation (proxied);
+}
+
+
+/* end of connection.c */
diff --git a/src/transport/tcp_server_legacy.c b/src/transport/tcp_server_legacy.c
new file mode 100644 (file)
index 0000000..c055285
--- /dev/null
@@ -0,0 +1,1748 @@
+/*
+     This file is part of GNUnet.
+     Copyright (C) 2009-2013 GNUnet e.V.
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file util/server.c
+ * @brief library for building GNUnet network servers
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_protocols.h"
+
+#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-server", syscall, filename)
+
+
+/**
+ * List of arrays of message handlers.
+ */
+struct HandlerList
+{
+  /**
+   * This is a linked list.
+   */
+  struct HandlerList *next;
+
+  /**
+   * NULL-terminated array of handlers.
+   */
+  const struct GNUNET_SERVER_MessageHandler *handlers;
+};
+
+
+/**
+ * List of arrays of message handlers.
+ */
+struct NotifyList
+{
+  /**
+   * This is a doubly linked list.
+   */
+  struct NotifyList *next;
+
+  /**
+   * This is a doubly linked list.
+   */
+  struct NotifyList *prev;
+
+  /**
+   * Function to call.
+   */
+  GNUNET_SERVER_DisconnectCallback callback;
+
+  /**
+   * Closure for callback.
+   */
+  void *callback_cls;
+};
+
+
+/**
+ * @brief handle for a server
+ */
+struct GNUNET_SERVER_Handle
+{
+  /**
+   * List of handlers for incoming messages.
+   */
+  struct HandlerList *handlers;
+
+  /**
+   * Head of list of our current clients.
+   */
+  struct GNUNET_SERVER_Client *clients_head;
+
+  /**
+   * Head of list of our current clients.
+   */
+  struct GNUNET_SERVER_Client *clients_tail;
+
+  /**
+   * Head of linked list of functions to call on disconnects by clients.
+   */
+  struct NotifyList *disconnect_notify_list_head;
+
+  /**
+   * Tail of linked list of functions to call on disconnects by clients.
+   */
+  struct NotifyList *disconnect_notify_list_tail;
+
+  /**
+   * Head of linked list of functions to call on connects by clients.
+   */
+  struct NotifyList *connect_notify_list_head;
+
+  /**
+   * Tail of linked list of functions to call on connects by clients.
+   */
+  struct NotifyList *connect_notify_list_tail;
+
+  /**
+   * Function to call for access control.
+   */
+  GNUNET_CONNECTION_AccessCheck access_cb;
+
+  /**
+   * Closure for @e access_cb.
+   */
+  void *access_cb_cls;
+
+  /**
+   * NULL-terminated array of sockets used to listen for new
+   * connections.
+   */
+  struct GNUNET_NETWORK_Handle **listen_sockets;
+
+  /**
+   * After how long should an idle connection time
+   * out (on write).
+   */
+  struct GNUNET_TIME_Relative idle_timeout;
+
+  /**
+   * Task scheduled to do the listening.
+   */
+  struct GNUNET_SCHEDULER_Task * listen_task;
+
+  /**
+   * Alternative function to create a MST instance.
+   */
+  GNUNET_SERVER_MstCreateCallback mst_create;
+
+  /**
+   * Alternative function to destroy a MST instance.
+   */
+  GNUNET_SERVER_MstDestroyCallback mst_destroy;
+
+  /**
+   * Alternative function to give data to a MST instance.
+   */
+  GNUNET_SERVER_MstReceiveCallback mst_receive;
+
+  /**
+   * Closure for 'mst_'-callbacks.
+   */
+  void *mst_cls;
+
+  /**
+   * Do we ignore messages of types that we do not understand or do we
+   * require that a handler is found (and if not kill the connection)?
+   */
+  int require_found;
+
+  /**
+   * Set to #GNUNET_YES once we are in 'soft' shutdown where we wait for
+   * all non-monitor clients to disconnect before we call
+   * #GNUNET_SERVER_destroy.  See test_monitor_clients().  Set to
+   * #GNUNET_SYSERR once the final destroy task has been scheduled
+   * (we cannot run it in the same task).
+   */
+  int in_soft_shutdown;
+};
+
+
+/**
+ * Handle server returns for aborting transmission to a client.
+ */
+struct GNUNET_SERVER_TransmitHandle
+{
+  /**
+   * Function to call to get the message.
+   */
+  GNUNET_CONNECTION_TransmitReadyNotify callback;
+
+  /**
+   * Closure for @e callback
+   */
+  void *callback_cls;
+
+  /**
+   * Active connection transmission handle.
+   */
+  struct GNUNET_CONNECTION_TransmitHandle *cth;
+
+};
+
+
+/**
+ * @brief handle for a client of the server
+ */
+struct GNUNET_SERVER_Client
+{
+
+  /**
+   * This is a doubly linked list.
+   */
+  struct GNUNET_SERVER_Client *next;
+
+  /**
+   * This is a doubly linked list.
+   */
+  struct GNUNET_SERVER_Client *prev;
+
+  /**
+   * Processing of incoming data.
+   */
+  void *mst;
+
+  /**
+   * Server that this client belongs to.
+   */
+  struct GNUNET_SERVER_Handle *server;
+
+  /**
+   * Client closure for callbacks.
+   */
+  struct GNUNET_CONNECTION_Handle *connection;
+
+  /**
+   * User context value, manipulated using
+   * 'GNUNET_SERVER_client_{get/set}_user_context' functions.
+   */
+  void *user_context;
+
+  /**
+   * ID of task used to restart processing.
+   */
+  struct GNUNET_SCHEDULER_Task * restart_task;
+
+  /**
+   * Task that warns about missing calls to #GNUNET_SERVER_receive_done.
+   */
+  struct GNUNET_SCHEDULER_Task * warn_task;
+
+  /**
+   * Time when the warn task was started.
+   */
+  struct GNUNET_TIME_Absolute warn_start;
+
+  /**
+   * Last activity on this socket (used to time it out
+   * if reference_count == 0).
+   */
+  struct GNUNET_TIME_Absolute last_activity;
+
+  /**
+   * Transmission handle we return for this client from
+   * #GNUNET_SERVER_notify_transmit_ready.
+   */
+  struct GNUNET_SERVER_TransmitHandle th;
+
+  /**
+   * After how long should an idle connection time
+   * out (on write).
+   */
+  struct GNUNET_TIME_Relative idle_timeout;
+
+  /**
+   * Number of external entities with a reference to
+   * this client object.
+   */
+  unsigned int reference_count;
+
+  /**
+   * Was processing if incoming messages suspended while
+   * we were still processing data already received?
+   * This is a counter saying how often processing was
+   * suspended (once per handler invoked).
+   */
+  unsigned int suspended;
+
+  /**
+   * Last size given when user context was initialized; used for
+   * sanity check.
+   */
+  size_t user_context_size;
+
+  /**
+   * Are we currently in the "process_client_buffer" function (and
+   * will hence restart the receive job on exit if suspended == 0 once
+   * we are done?).  If this is set, then "receive_done" will
+   * essentially only decrement suspended; if this is not set, then
+   * "receive_done" may need to restart the receive process (either
+   * from the side-buffer or via select/recv).
+   */
+  int in_process_client_buffer;
+
+  /**
+   * We're about to close down this client.
+   */
+  int shutdown_now;
+
+  /**
+   * Are we currently trying to receive? (#GNUNET_YES if we are,
+   * #GNUNET_NO if we are not, #GNUNET_SYSERR if data is already
+   * available in MST).
+   */
+  int receive_pending;
+
+  /**
+   * Persist the file handle for this client no matter what happens,
+   * force the OS to close once the process actually dies.  Should only
+   * be used in special cases!
+   */
+  int persist;
+
+  /**
+   * Is this client a 'monitor' client that should not be counted
+   * when deciding on destroying the server during soft shutdown?
+   * (see also #GNUNET_SERVICE_start)
+   */
+  int is_monitor;
+
+  /**
+   * Type of last message processed (for warn_no_receive_done).
+   */
+  uint16_t warn_type;
+};
+
+
+
+/**
+ * Return user context associated with the given client.
+ * Note: you should probably use the macro (call without the underscore).
+ *
+ * @param client client to query
+ * @param size number of bytes in user context struct (for verification only)
+ * @return pointer to user context
+ */
+void *
+GNUNET_SERVER_client_get_user_context_ (struct GNUNET_SERVER_Client *client,
+                                       size_t size)
+{
+  if ((0 == client->user_context_size) &&
+      (NULL == client->user_context))
+    return NULL; /* never set */
+  GNUNET_assert (size == client->user_context_size);
+  return client->user_context;
+}
+
+
+/**
+ * Set user context to be associated with the given client.
+ * Note: you should probably use the macro (call without the underscore).
+ *
+ * @param client client to query
+ * @param ptr pointer to user context
+ * @param size number of bytes in user context struct (for verification only)
+ */
+void
+GNUNET_SERVER_client_set_user_context_ (struct GNUNET_SERVER_Client *client,
+                                       void *ptr,
+                                       size_t size)
+{
+  if (NULL == ptr)
+  {
+    client->user_context_size = 0;
+    client->user_context = ptr;
+    return;
+  }
+  client->user_context_size = size;
+  client->user_context = ptr;
+}
+
+
+/**
+ * Scheduler says our listen socket is ready.  Process it!
+ *
+ * @param cls handle to our server for which we are processing the listen
+ *        socket
+ */
+static void
+process_listen_socket (void *cls)
+{
+  struct GNUNET_SERVER_Handle *server = cls;
+  const struct GNUNET_SCHEDULER_TaskContext *tc;
+  struct GNUNET_CONNECTION_Handle *sock;
+  unsigned int i;
+
+  server->listen_task = NULL;
+  tc = GNUNET_SCHEDULER_get_task_context ();
+  for (i = 0; NULL != server->listen_sockets[i]; i++)
+  {
+    if (GNUNET_NETWORK_fdset_isset (tc->read_ready,
+                                    server->listen_sockets[i]))
+    {
+      sock =
+          GNUNET_CONNECTION_create_from_accept (server->access_cb,
+                                                server->access_cb_cls,
+                                                server->listen_sockets[i]);
+      if (NULL != sock)
+      {
+        LOG (GNUNET_ERROR_TYPE_DEBUG,
+             "Server accepted incoming connection.\n");
+        (void) GNUNET_SERVER_connect_socket (server,
+                                             sock);
+      }
+    }
+  }
+  /* listen for more! */
+  GNUNET_SERVER_resume (server);
+}
+
+
+/**
+ * Create and initialize a listen socket for the server.
+ *
+ * @param server_addr address to listen on
+ * @param socklen length of @a server_addr
+ * @return NULL on error, otherwise the listen socket
+ */
+static struct GNUNET_NETWORK_Handle *
+open_listen_socket (const struct sockaddr *server_addr,
+                   socklen_t socklen)
+{
+  struct GNUNET_NETWORK_Handle *sock;
+  uint16_t port;
+  int eno;
+
+  switch (server_addr->sa_family)
+  {
+  case AF_INET:
+    port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port);
+    break;
+  case AF_INET6:
+    port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port);
+    break;
+  case AF_UNIX:
+    port = 0;
+    break;
+  default:
+    GNUNET_break (0);
+    port = 0;
+    break;
+  }
+  sock = GNUNET_NETWORK_socket_create (server_addr->sa_family, SOCK_STREAM, 0);
+  if (NULL == sock)
+  {
+    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
+    errno = 0;
+    return NULL;
+  }
+  /* bind the socket */
+  if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, server_addr, socklen))
+  {
+    eno = errno;
+    if (EADDRINUSE != errno)
+    {
+      /* we don't log 'EADDRINUSE' here since an IPv4 bind may
+       * fail if we already took the port on IPv6; if both IPv4 and
+       * IPv6 binds fail, then our caller will log using the
+       * errno preserved in 'eno' */
+      LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
+                    "bind");
+      if (0 != port)
+        LOG (GNUNET_ERROR_TYPE_ERROR,
+             _("`%s' failed for port %d (%s).\n"),
+             "bind",
+             port,
+             (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
+      eno = 0;
+    }
+    else
+    {
+      if (0 != port)
+        LOG (GNUNET_ERROR_TYPE_WARNING,
+             _("`%s' failed for port %d (%s): address already in use\n"),
+             "bind", port,
+             (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
+      else if (AF_UNIX == server_addr->sa_family)
+      {
+        LOG (GNUNET_ERROR_TYPE_WARNING,
+             _("`%s' failed for `%s': address already in use\n"),
+             "bind",
+             GNUNET_a2s (server_addr, socklen));
+      }
+    }
+    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
+    errno = eno;
+    return NULL;
+  }
+  if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
+  {
+    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
+                  "listen");
+    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
+    errno = 0;
+    return NULL;
+  }
+  if (0 != port)
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Server starts to listen on port %u.\n",
+         port);
+  return sock;
+}
+
+
+/**
+ * Create a new server.
+ *
+ * @param access_cb function for access control
+ * @param access_cb_cls closure for @a access_cb
+ * @param lsocks NULL-terminated array of listen sockets
+ * @param idle_timeout after how long should we timeout idle connections?
+ * @param require_found if #GNUNET_YES, connections sending messages of unknown type
+ *        will be closed
+ * @return handle for the new server, NULL on error
+ *         (typically, "port" already in use)
+ */
+struct GNUNET_SERVER_Handle *
+GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access_cb,
+                                   void *access_cb_cls,
+                                   struct GNUNET_NETWORK_Handle **lsocks,
+                                   struct GNUNET_TIME_Relative idle_timeout,
+                                   int require_found)
+{
+  struct GNUNET_SERVER_Handle *server;
+
+  server = GNUNET_new (struct GNUNET_SERVER_Handle);
+  server->idle_timeout = idle_timeout;
+  server->listen_sockets = lsocks;
+  server->access_cb = access_cb;
+  server->access_cb_cls = access_cb_cls;
+  server->require_found = require_found;
+  if (NULL != lsocks)
+    GNUNET_SERVER_resume (server);
+  return server;
+}
+
+
+/**
+ * Create a new server.
+ *
+ * @param access_cb function for access control
+ * @param access_cb_cls closure for @a access_cb
+ * @param server_addr address to listen on (including port), NULL terminated array
+ * @param socklen length of server_addr
+ * @param idle_timeout after how long should we timeout idle connections?
+ * @param require_found if YES, connections sending messages of unknown type
+ *        will be closed
+ * @return handle for the new server, NULL on error
+ *         (typically, "port" already in use)
+ */
+struct GNUNET_SERVER_Handle *
+GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access_cb,
+                     void *access_cb_cls,
+                      struct sockaddr *const *server_addr,
+                      const socklen_t * socklen,
+                      struct GNUNET_TIME_Relative idle_timeout,
+                      int require_found)
+{
+  struct GNUNET_NETWORK_Handle **lsocks;
+  unsigned int i;
+  unsigned int j;
+  unsigned int k;
+  int seen;
+
+  i = 0;
+  while (NULL != server_addr[i])
+    i++;
+  if (i > 0)
+  {
+    lsocks = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1));
+    i = 0;
+    j = 0;
+    while (NULL != server_addr[i])
+    {
+      seen = 0;
+      for (k=0;k<i;k++)
+       if ( (socklen[k] == socklen[i]) &&
+            (0 == memcmp (server_addr[k], server_addr[i], socklen[i])) )
+       {
+         seen = 1;
+         break;
+       }
+      if (0 != seen)
+      {
+       /* duplicate address, skip */
+       i++;
+       continue;
+      }
+      lsocks[j] = open_listen_socket (server_addr[i], socklen[i]);
+      if (NULL != lsocks[j])
+        j++;
+      i++;
+    }
+    if (0 == j)
+    {
+      if (0 != errno)
+        LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind");
+      GNUNET_free (lsocks);
+      lsocks = NULL;
+    }
+  }
+  else
+  {
+    lsocks = NULL;
+  }
+  return GNUNET_SERVER_create_with_sockets (access_cb,
+                                           access_cb_cls,
+                                           lsocks,
+                                            idle_timeout,
+                                           require_found);
+}
+
+
+/**
+ * Set the 'monitor' flag on this client.  Clients which have been
+ * marked as 'monitors' won't prevent the server from shutting down
+ * once '#GNUNET_SERVER_stop_listening()' has been invoked.  The idea is
+ * that for "normal" clients we likely want to allow them to process
+ * their requests; however, monitor-clients are likely to 'never'
+ * disconnect during shutdown and thus will not be considered when
+ * determining if the server should continue to exist after
+ * #GNUNET_SERVER_destroy() has been called.
+ *
+ * @param client the client to set the 'monitor' flag on
+ */
+void
+GNUNET_SERVER_client_mark_monitor (struct GNUNET_SERVER_Client *client)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Marking client as monitor!\n");
+  client->is_monitor = GNUNET_YES;
+}
+
+
+/**
+ * Helper function for #test_monitor_clients() to trigger
+ * #GNUNET_SERVER_destroy() after the stack has unwound.
+ *
+ * @param cls the `struct GNUNET_SERVER_Handle *` to destroy
+ */
+static void
+do_destroy (void *cls)
+{
+  struct GNUNET_SERVER_Handle *server = cls;
+
+  GNUNET_SERVER_destroy (server);
+}
+
+
+/**
+ * Check if only 'monitor' clients are left.  If so, destroy the
+ * server completely.
+ *
+ * @param server server to test for full shutdown
+ */
+static void
+test_monitor_clients (struct GNUNET_SERVER_Handle *server)
+{
+  struct GNUNET_SERVER_Client *client;
+
+  if (GNUNET_YES != server->in_soft_shutdown)
+    return;
+  for (client = server->clients_head; NULL != client; client = client->next)
+    if (GNUNET_NO == client->is_monitor)
+      return; /* not done yet */
+  server->in_soft_shutdown = GNUNET_SYSERR;
+  (void) GNUNET_SCHEDULER_add_now (&do_destroy, server);
+}
+
+
+/**
+ * Suspend accepting connections from the listen socket temporarily.
+ *
+ * @param server server to stop accepting connections.
+ */
+void
+GNUNET_SERVER_suspend (struct GNUNET_SERVER_Handle *server)
+{
+  if (NULL != server->listen_task)
+  {
+    GNUNET_SCHEDULER_cancel (server->listen_task);
+    server->listen_task = NULL;
+  }
+}
+
+
+/**
+ * Resume accepting connections from the listen socket.
+ *
+ * @param server server to stop accepting connections.
+ */
+void
+GNUNET_SERVER_resume (struct GNUNET_SERVER_Handle *server)
+{
+  struct GNUNET_NETWORK_FDSet *r;
+  unsigned int i;
+
+  if (NULL == server->listen_sockets)
+    return;
+  if (NULL == server->listen_sockets[0])
+    return; /* nothing to do, no listen sockets! */
+  if (NULL == server->listen_sockets[1])
+  {
+    /* simplified method: no fd set needed; this is then much simpler
+       and much more efficient */
+    server->listen_task =
+      GNUNET_SCHEDULER_add_read_net_with_priority (GNUNET_TIME_UNIT_FOREVER_REL,
+                                                  GNUNET_SCHEDULER_PRIORITY_HIGH,
+                                                  server->listen_sockets[0],
+                                                  &process_listen_socket, server);
+    return;
+  }
+  r = GNUNET_NETWORK_fdset_create ();
+  i = 0;
+  while (NULL != server->listen_sockets[i])
+    GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
+  server->listen_task =
+    GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
+                                GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
+                                &process_listen_socket, server);
+  GNUNET_NETWORK_fdset_destroy (r);
+}
+
+
+/**
+ * Stop the listen socket and get ready to shutdown the server
+ * once only 'monitor' clients are left.
+ *
+ * @param server server to stop listening on
+ */
+void
+GNUNET_SERVER_stop_listening (struct GNUNET_SERVER_Handle *server)
+{
+  unsigned int i;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Server in soft shutdown\n");
+  if (NULL != server->listen_task)
+  {
+    GNUNET_SCHEDULER_cancel (server->listen_task);
+    server->listen_task = NULL;
+  }
+  if (NULL != server->listen_sockets)
+  {
+    i = 0;
+    while (NULL != server->listen_sockets[i])
+      GNUNET_break (GNUNET_OK ==
+                    GNUNET_NETWORK_socket_close (server->listen_sockets[i++]));
+    GNUNET_free (server->listen_sockets);
+    server->listen_sockets = NULL;
+  }
+  if (GNUNET_NO == server->in_soft_shutdown)
+    server->in_soft_shutdown = GNUNET_YES;
+  test_monitor_clients (server);
+}
+
+
+/**
+ * Free resources held by this server.
+ *
+ * @param server server to destroy
+ */
+void
+GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *server)
+{
+  struct HandlerList *hpos;
+  struct NotifyList *npos;
+  unsigned int i;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Server shutting down.\n");
+  if (NULL != server->listen_task)
+  {
+    GNUNET_SCHEDULER_cancel (server->listen_task);
+    server->listen_task = NULL;
+  }
+  if (NULL != server->listen_sockets)
+  {
+    i = 0;
+    while (NULL != server->listen_sockets[i])
+      GNUNET_break (GNUNET_OK ==
+                    GNUNET_NETWORK_socket_close (server->listen_sockets[i++]));
+    GNUNET_free (server->listen_sockets);
+    server->listen_sockets = NULL;
+  }
+  while (NULL != server->clients_head)
+    GNUNET_SERVER_client_disconnect (server->clients_head);
+  while (NULL != (hpos = server->handlers))
+  {
+    server->handlers = hpos->next;
+    GNUNET_free (hpos);
+  }
+  while (NULL != (npos = server->disconnect_notify_list_head))
+  {
+    npos->callback (npos->callback_cls,
+                    NULL);
+    GNUNET_CONTAINER_DLL_remove (server->disconnect_notify_list_head,
+                                server->disconnect_notify_list_tail,
+                                npos);
+    GNUNET_free (npos);
+  }
+  while (NULL != (npos = server->connect_notify_list_head))
+  {
+    npos->callback (npos->callback_cls,
+                    NULL);
+    GNUNET_CONTAINER_DLL_remove (server->connect_notify_list_head,
+                                server->connect_notify_list_tail,
+                                npos);
+    GNUNET_free (npos);
+  }
+  GNUNET_free (server);
+}
+
+
+/**
+ * Add additional handlers to an existing server.
+ *
+ * @param server the server to add handlers to
+ * @param handlers array of message handlers for
+ *        incoming messages; the last entry must
+ *        have "NULL" for the "callback"; multiple
+ *        entries for the same type are allowed,
+ *        they will be called in order of occurence.
+ *        These handlers can be removed later;
+ *        the handlers array must exist until removed
+ *        (or server is destroyed).
+ */
+void
+GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
+                            const struct GNUNET_SERVER_MessageHandler *handlers)
+{
+  struct HandlerList *p;
+
+  p = GNUNET_new (struct HandlerList);
+  p->handlers = handlers;
+  p->next = server->handlers;
+  server->handlers = p;
+}
+
+
+/**
+ * Change functions used by the server to tokenize the message stream.
+ * (very rarely used).
+ *
+ * @param server server to modify
+ * @param create new tokenizer initialization function
+ * @param destroy new tokenizer destruction function
+ * @param receive new tokenizer receive function
+ * @param cls closure for @a create, @a receive, @a destroy
+ */
+void
+GNUNET_SERVER_set_callbacks (struct GNUNET_SERVER_Handle *server,
+                             GNUNET_SERVER_MstCreateCallback create,
+                             GNUNET_SERVER_MstDestroyCallback destroy,
+                             GNUNET_SERVER_MstReceiveCallback receive,
+                             void *cls)
+{
+  server->mst_create = create;
+  server->mst_destroy = destroy;
+  server->mst_receive = receive;
+  server->mst_cls = cls;
+}
+
+
+/**
+ * Task run to warn about missing calls to #GNUNET_SERVER_receive_done.
+ *
+ * @param cls our `struct GNUNET_SERVER_Client *` to process more requests from
+ */
+static void
+warn_no_receive_done (void *cls)
+{
+  struct GNUNET_SERVER_Client *client = cls;
+
+  GNUNET_break (0 != client->warn_type); /* type should never be 0 here, as we don't use 0 */
+  client->warn_task =
+      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
+                                    &warn_no_receive_done, client);
+  LOG (GNUNET_ERROR_TYPE_WARNING,
+       _("Processing code for message of type %u did not call `GNUNET_SERVER_receive_done' after %s\n"),
+       (unsigned int) client->warn_type,
+       GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (client->warn_start),
+                                              GNUNET_YES));
+}
+
+
+/**
+ * Disable the warning the server issues if a message is not acknowledged
+ * in a timely fashion.  Use this call if a client is intentionally delayed
+ * for a while.  Only applies to the current message.
+ *
+ * @param client client for which to disable the warning
+ */
+void
+GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client *client)
+{
+  if (NULL != client->warn_task)
+  {
+    GNUNET_SCHEDULER_cancel (client->warn_task);
+    client->warn_task = NULL;
+  }
+}
+
+
+/**
+ * Inject a message into the server, pretend it came
+ * from the specified client.  Delivery of the message
+ * will happen instantly (if a handler is installed;
+ * otherwise the call does nothing).
+ *
+ * @param server the server receiving the message
+ * @param sender the "pretended" sender of the message
+ *        can be NULL!
+ * @param message message to transmit
+ * @return #GNUNET_OK if the message was OK and the
+ *                   connection can stay open
+ *         #GNUNET_SYSERR if the connection to the
+ *         client should be shut down
+ */
+int
+GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
+                      struct GNUNET_SERVER_Client *sender,
+                      const struct GNUNET_MessageHeader *message)
+{
+  struct HandlerList *pos;
+  const struct GNUNET_SERVER_MessageHandler *mh;
+  unsigned int i;
+  uint16_t type;
+  uint16_t size;
+  int found;
+
+  type = ntohs (message->type);
+  size = ntohs (message->size);
+  LOG (GNUNET_ERROR_TYPE_INFO,
+       "Received message of type %u and size %u from client\n",
+       type, size);
+  found = GNUNET_NO;
+  for (pos = server->handlers; NULL != pos; pos = pos->next)
+  {
+    i = 0;
+    while (pos->handlers[i].callback != NULL)
+    {
+      mh = &pos->handlers[i];
+      if ((mh->type == type) || (mh->type == GNUNET_MESSAGE_TYPE_ALL))
+      {
+        if ((0 != mh->expected_size) && (mh->expected_size != size))
+        {
+#if GNUNET8_NETWORK_IS_DEAD
+          LOG (GNUNET_ERROR_TYPE_WARNING,
+               "Expected %u bytes for message of type %u, got %u\n",
+               mh->expected_size, mh->type, size);
+          GNUNET_break_op (0);
+#else
+          LOG (GNUNET_ERROR_TYPE_DEBUG,
+               "Expected %u bytes for message of type %u, got %u\n",
+               mh->expected_size, mh->type, size);
+#endif
+          return GNUNET_SYSERR;
+        }
+        if (NULL != sender)
+        {
+          if ( (0 == sender->suspended) &&
+              (NULL == sender->warn_task) )
+          {
+           GNUNET_break (0 != type); /* type should never be 0 here, as we don't use 0 */
+            sender->warn_start = GNUNET_TIME_absolute_get ();
+            sender->warn_task =
+                GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
+                                              &warn_no_receive_done,
+                                             sender);
+            sender->warn_type = type;
+          }
+          sender->suspended++;
+        }
+        mh->callback (mh->callback_cls, sender, message);
+        found = GNUNET_YES;
+      }
+      i++;
+    }
+  }
+  if (GNUNET_NO == found)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
+         "Received message of unknown type %d\n", type);
+    if (GNUNET_YES == server->require_found)
+      return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * We are receiving an incoming message.  Process it.
+ *
+ * @param cls our closure (handle for the client)
+ * @param buf buffer with data received from network
+ * @param available number of bytes available in buf
+ * @param addr address of the sender
+ * @param addrlen length of @a addr
+ * @param errCode code indicating errors receiving, 0 for success
+ */
+static void
+process_incoming (void *cls,
+                  const void *buf,
+                  size_t available,
+                  const struct sockaddr *addr,
+                  socklen_t addrlen,
+                  int errCode);
+
+
+/**
+ * Process messages from the client's message tokenizer until either
+ * the tokenizer is empty (and then schedule receiving more), or
+ * until some handler is not immediately done (then wait for restart_processing)
+ * or shutdown.
+ *
+ * @param client the client to process, RC must have already been increased
+ *        using #GNUNET_SERVER_client_keep and will be decreased by one in this
+ *        function
+ * @param ret #GNUNET_NO to start processing from the buffer,
+ *            #GNUNET_OK if the mst buffer is drained and we should instantly go back to receiving
+ *            #GNUNET_SYSERR if we should instantly abort due to error in a previous step
+ */
+static void
+process_mst (struct GNUNET_SERVER_Client *client,
+             int ret)
+{
+  while ((GNUNET_SYSERR != ret) && (NULL != client->server) &&
+         (GNUNET_YES != client->shutdown_now) && (0 == client->suspended))
+  {
+    if (GNUNET_OK == ret)
+    {
+      LOG (GNUNET_ERROR_TYPE_DEBUG,
+           "Server re-enters receive loop, timeout: %s.\n",
+           GNUNET_STRINGS_relative_time_to_string (client->idle_timeout, GNUNET_YES));
+      client->receive_pending = GNUNET_YES;
+      GNUNET_CONNECTION_receive (client->connection,
+                                 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
+                                 client->idle_timeout,
+                                 &process_incoming,
+                                 client);
+      break;
+    }
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Server processes additional messages instantly.\n");
+    if (NULL != client->server->mst_receive)
+      ret =
+          client->server->mst_receive (client->server->mst_cls, client->mst,
+                                       client, NULL, 0, GNUNET_NO, GNUNET_YES);
+    else
+      ret =
+          GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO,
+                                     GNUNET_YES);
+  }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n",
+       ret, client->server,
+       client->shutdown_now,
+       client->suspended);
+  if (GNUNET_NO == ret)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Server has more data pending but is suspended.\n");
+    client->receive_pending = GNUNET_SYSERR;    /* data pending */
+  }
+  if ( (GNUNET_SYSERR == ret) ||
+       (GNUNET_YES == client->shutdown_now) )
+    GNUNET_SERVER_client_disconnect (client);
+}
+
+
+/**
+ * We are receiving an incoming message.  Process it.
+ *
+ * @param cls our closure (handle for the client)
+ * @param buf buffer with data received from network
+ * @param available number of bytes available in buf
+ * @param addr address of the sender
+ * @param addrlen length of @a addr
+ * @param errCode code indicating errors receiving, 0 for success
+ */
+static void
+process_incoming (void *cls,
+                  const void *buf,
+                  size_t available,
+                  const struct sockaddr *addr,
+                  socklen_t addrlen,
+                  int errCode)
+{
+  struct GNUNET_SERVER_Client *client = cls;
+  struct GNUNET_SERVER_Handle *server = client->server;
+  struct GNUNET_TIME_Absolute end;
+  struct GNUNET_TIME_Absolute now;
+  int ret;
+
+  GNUNET_assert (GNUNET_YES == client->receive_pending);
+  client->receive_pending = GNUNET_NO;
+  now = GNUNET_TIME_absolute_get ();
+  end = GNUNET_TIME_absolute_add (client->last_activity,
+                                  client->idle_timeout);
+
+  if ( (NULL == buf) &&
+       (0 == available) &&
+       (NULL == addr) &&
+       (0 == errCode) &&
+       (GNUNET_YES != client->shutdown_now) &&
+       (NULL != server) &&
+       (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) &&
+       (end.abs_value_us > now.abs_value_us) )
+  {
+    /* wait longer, timeout changed (i.e. due to us sending) */
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Receive time out, but no disconnect due to sending (%p)\n",
+         client);
+    client->receive_pending = GNUNET_YES;
+    GNUNET_CONNECTION_receive (client->connection,
+                               GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
+                               GNUNET_TIME_absolute_get_remaining (end),
+                               &process_incoming,
+                               client);
+    return;
+  }
+  if ( (NULL == buf) ||
+       (0 == available) ||
+       (0 != errCode) ||
+       (NULL == server) ||
+       (GNUNET_YES == client->shutdown_now) ||
+       (GNUNET_YES != GNUNET_CONNECTION_check (client->connection)) )
+  {
+    /* other side closed connection, error connecting, etc. */
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Failed to connect or other side closed connection (%p)\n",
+         client);
+    GNUNET_SERVER_client_disconnect (client);
+    return;
+  }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Server receives %u bytes from `%s'.\n",
+       (unsigned int) available,
+       GNUNET_a2s (addr, addrlen));
+  GNUNET_SERVER_client_keep (client);
+  client->last_activity = now;
+
+  if (NULL != server->mst_receive)
+  {
+    ret = client->server->mst_receive (client->server->mst_cls,
+                                       client->mst,
+                                       client,
+                                       buf,
+                                       available,
+                                       GNUNET_NO,
+                                       GNUNET_YES);
+  }
+  else if (NULL != client->mst)
+  {
+    ret =
+        GNUNET_SERVER_mst_receive (client->mst,
+                                   client,
+                                   buf,
+                                   available,
+                                   GNUNET_NO,
+                                   GNUNET_YES);
+  }
+  else
+  {
+    GNUNET_break (0);
+    return;
+  }
+  process_mst (client,
+               ret);
+  GNUNET_SERVER_client_drop (client);
+}
+
+
+/**
+ * Task run to start again receiving from the network
+ * and process requests.
+ *
+ * @param cls our `struct GNUNET_SERVER_Client *` to process more requests from
+ */
+static void
+restart_processing (void *cls)
+{
+  struct GNUNET_SERVER_Client *client = cls;
+
+  GNUNET_assert (GNUNET_YES != client->shutdown_now);
+  client->restart_task = NULL;
+  if (GNUNET_NO == client->receive_pending)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "Server begins to read again from client.\n");
+    client->receive_pending = GNUNET_YES;
+    GNUNET_CONNECTION_receive (client->connection,
+                               GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
+                               client->idle_timeout,
+                               &process_incoming,
+                               client);
+    return;
+  }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Server continues processing messages still in the buffer.\n");
+  GNUNET_SERVER_client_keep (client);
+  client->receive_pending = GNUNET_NO;
+  process_mst (client,
+               GNUNET_NO);
+  GNUNET_SERVER_client_drop (client);
+}
+
+
+/**
+ * This function is called whenever our inbound message tokenizer has
+ * received a complete message.
+ *
+ * @param cls closure (struct GNUNET_SERVER_Handle)
+ * @param client identification of the client (`struct GNUNET_SERVER_Client *`)
+ * @param message the actual message
+ *
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
+ */
+static int
+client_message_tokenizer_callback (void *cls,
+                                   void *client,
+                                   const struct GNUNET_MessageHeader *message)
+{
+  struct GNUNET_SERVER_Handle *server = cls;
+  struct GNUNET_SERVER_Client *sender = client;
+  int ret;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Tokenizer gives server message of type %u and size %u from client\n",
+       ntohs (message->type), ntohs (message->size));
+  sender->in_process_client_buffer = GNUNET_YES;
+  ret = GNUNET_SERVER_inject (server, sender, message);
+  sender->in_process_client_buffer = GNUNET_NO;
+  if ( (GNUNET_OK != ret) || (GNUNET_YES == sender->shutdown_now) )
+  {
+    GNUNET_SERVER_client_disconnect (sender);
+    return GNUNET_SYSERR;
+  }
+  return GNUNET_OK;
+}
+
+
+/**
+ * Add a TCP socket-based connection to the set of handles managed by
+ * this server.  Use this function for outgoing (P2P) connections that
+ * we initiated (and where this server should process incoming
+ * messages).
+ *
+ * @param server the server to use
+ * @param connection the connection to manage (client must
+ *        stop using this connection from now on)
+ * @return the client handle
+ */
+struct GNUNET_SERVER_Client *
+GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server,
+                              struct GNUNET_CONNECTION_Handle *connection)
+{
+  struct GNUNET_SERVER_Client *client;
+  struct NotifyList *n;
+
+  client = GNUNET_new (struct GNUNET_SERVER_Client);
+  client->connection = connection;
+  client->server = server;
+  client->last_activity = GNUNET_TIME_absolute_get ();
+  client->idle_timeout = server->idle_timeout;
+  GNUNET_CONTAINER_DLL_insert (server->clients_head,
+                              server->clients_tail,
+                              client);
+  if (NULL != server->mst_create)
+    client->mst =
+        server->mst_create (server->mst_cls, client);
+  else
+    client->mst =
+        GNUNET_SERVER_mst_create (&client_message_tokenizer_callback,
+                                  server);
+  GNUNET_assert (NULL != client->mst);
+  for (n = server->connect_notify_list_head; NULL != n; n = n->next)
+    n->callback (n->callback_cls, client);
+  client->receive_pending = GNUNET_YES;
+  GNUNET_CONNECTION_receive (client->connection,
+                             GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
+                             client->idle_timeout,
+                             &process_incoming,
+                             client);
+  return client;
+}
+
+
+/**
+ * Change the timeout for a particular client.  Decreasing the timeout
+ * may not go into effect immediately (only after the previous timeout
+ * times out or activity happens on the socket).
+ *
+ * @param client the client to update
+ * @param timeout new timeout for activities on the socket
+ */
+void
+GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client,
+                                  struct GNUNET_TIME_Relative timeout)
+{
+  client->idle_timeout = timeout;
+}
+
+
+/**
+ * Notify the server that the given client handle should
+ * be kept (keeps the connection up if possible, increments
+ * the internal reference counter).
+ *
+ * @param client the client to keep
+ */
+void
+GNUNET_SERVER_client_keep (struct GNUNET_SERVER_Client *client)
+{
+  client->reference_count++;
+}
+
+
+/**
+ * Notify the server that the given client handle is no
+ * longer required.  Decrements the reference counter.  If
+ * that counter reaches zero an inactive connection maybe
+ * closed.
+ *
+ * @param client the client to drop
+ */
+void
+GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client)
+{
+  GNUNET_assert (client->reference_count > 0);
+  client->reference_count--;
+  if ((GNUNET_YES == client->shutdown_now) && (0 == client->reference_count))
+    GNUNET_SERVER_client_disconnect (client);
+}
+
+
+/**
+ * Obtain the network address of the other party.
+ *
+ * @param client the client to get the address for
+ * @param addr where to store the address
+ * @param addrlen where to store the length of the @a addr
+ * @return #GNUNET_OK on success
+ */
+int
+GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client,
+                                  void **addr, size_t * addrlen)
+{
+  return GNUNET_CONNECTION_get_address (client->connection, addr, addrlen);
+}
+
+
+/**
+ * Ask the server to notify us whenever a client disconnects.
+ * This function is called whenever the actual network connection
+ * is closed; the reference count may be zero or larger than zero
+ * at this point.
+ *
+ * @param server the server manageing the clients
+ * @param callback function to call on disconnect
+ * @param callback_cls closure for @a callback
+ */
+void
+GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server,
+                                 GNUNET_SERVER_DisconnectCallback callback,
+                                 void *callback_cls)
+{
+  struct NotifyList *n;
+
+  n = GNUNET_new (struct NotifyList);
+  n->callback = callback;
+  n->callback_cls = callback_cls;
+  GNUNET_CONTAINER_DLL_insert (server->disconnect_notify_list_head,
+                              server->disconnect_notify_list_tail,
+                              n);
+}
+
+
+/**
+ * Ask the server to notify us whenever a client connects.
+ * This function is called whenever the actual network connection
+ * is opened. If the server is destroyed before this
+ * notification is explicitly cancelled, the 'callback' will
+ * once be called with a 'client' argument of NULL to indicate
+ * that the server itself is now gone (and that the callback
+ * won't be called anymore and also can no longer be cancelled).
+ *
+ * @param server the server manageing the clients
+ * @param callback function to call on sconnect
+ * @param callback_cls closure for @a callback
+ */
+void
+GNUNET_SERVER_connect_notify (struct GNUNET_SERVER_Handle *server,
+                             GNUNET_SERVER_ConnectCallback callback,
+                             void *callback_cls)
+{
+  struct NotifyList *n;
+  struct GNUNET_SERVER_Client *client;
+
+  n = GNUNET_new (struct NotifyList);
+  n->callback = callback;
+  n->callback_cls = callback_cls;
+  GNUNET_CONTAINER_DLL_insert (server->connect_notify_list_head,
+                              server->connect_notify_list_tail,
+                              n);
+  for (client = server->clients_head; NULL != client; client = client->next)
+    callback (callback_cls, client);
+}
+
+
+/**
+ * Ask the server to stop notifying us whenever a client connects.
+ *
+ * @param server the server manageing the clients
+ * @param callback function to call on connect
+ * @param callback_cls closure for @a callback
+ */
+void
+GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server,
+                                        GNUNET_SERVER_DisconnectCallback callback,
+                                        void *callback_cls)
+{
+  struct NotifyList *pos;
+
+  for (pos = server->disconnect_notify_list_head; NULL != pos; pos = pos->next)
+    if ((pos->callback == callback) && (pos->callback_cls == callback_cls))
+      break;
+  if (NULL == pos)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  GNUNET_CONTAINER_DLL_remove (server->disconnect_notify_list_head,
+                              server->disconnect_notify_list_tail,
+                              pos);
+  GNUNET_free (pos);
+}
+
+
+/**
+ * Ask the server to stop notifying us whenever a client disconnects.
+ *
+ * @param server the server manageing the clients
+ * @param callback function to call on disconnect
+ * @param callback_cls closure for @a callback
+ */
+void
+GNUNET_SERVER_connect_notify_cancel (struct GNUNET_SERVER_Handle *server,
+                                    GNUNET_SERVER_ConnectCallback callback,
+                                    void *callback_cls)
+{
+  struct NotifyList *pos;
+
+  for (pos = server->connect_notify_list_head; NULL != pos; pos = pos->next)
+    if ((pos->callback == callback) && (pos->callback_cls == callback_cls))
+      break;
+  if (NULL == pos)
+  {
+    GNUNET_break (0);
+    return;
+  }
+  GNUNET_CONTAINER_DLL_remove (server->connect_notify_list_head,
+                              server->connect_notify_list_tail,
+                              pos);
+  GNUNET_free (pos);
+}
+
+
+/**
+ * Destroy the connection that is passed in via @a cls.  Used
+ * as calling #GNUNET_CONNECTION_destroy from within a function
+ * that was itself called from within process_notify() of
+ * 'connection.c' is not allowed (see #2329).
+ *
+ * @param cls connection to destroy
+ */
+static void
+destroy_connection (void *cls)
+{
+  struct GNUNET_CONNECTION_Handle *connection = cls;
+
+  GNUNET_CONNECTION_destroy (connection);
+}
+
+
+/**
+ * Ask the server to disconnect from the given client.
+ * This is the same as returning #GNUNET_SYSERR from a message
+ * handler, except that it allows dropping of a client even
+ * when not handling a message from that client.
+ *
+ * @param client the client to disconnect from
+ */
+void
+GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
+{
+  struct GNUNET_SERVER_Handle *server = client->server;
+  struct NotifyList *n;
+
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Client is being disconnected from the server.\n");
+  if (NULL != client->restart_task)
+  {
+    GNUNET_SCHEDULER_cancel (client->restart_task);
+    client->restart_task = NULL;
+  }
+  if (NULL != client->warn_task)
+  {
+    GNUNET_SCHEDULER_cancel (client->warn_task);
+    client->warn_task = NULL;
+  }
+  if (GNUNET_YES == client->receive_pending)
+  {
+    GNUNET_CONNECTION_receive_cancel (client->connection);
+    client->receive_pending = GNUNET_NO;
+  }
+  client->shutdown_now = GNUNET_YES;
+  client->reference_count++; /* make sure nobody else clean up client... */
+  if ( (NULL != client->mst) &&
+       (NULL != server) )
+  {
+    GNUNET_CONTAINER_DLL_remove (server->clients_head,
+                                server->clients_tail,
+                                client);
+    if (NULL != server->mst_destroy)
+      server->mst_destroy (server->mst_cls,
+                           client->mst);
+    else
+      GNUNET_SERVER_mst_destroy (client->mst);
+    client->mst = NULL;
+    for (n = server->disconnect_notify_list_head; NULL != n; n = n->next)
+      n->callback (n->callback_cls,
+                   client);
+  }
+  client->reference_count--;
+  if (client->reference_count > 0)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "RC of %p still positive, not destroying everything.\n",
+         client);
+    client->server = NULL;
+    return;
+  }
+  if (GNUNET_YES == client->in_process_client_buffer)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Still processing inputs of %p, not destroying everything.\n",
+         client);
+    return;
+  }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "RC of %p now zero, destroying everything.\n",
+       client);
+  if (GNUNET_YES == client->persist)
+    GNUNET_CONNECTION_persist_ (client->connection);
+  if (NULL != client->th.cth)
+    GNUNET_SERVER_notify_transmit_ready_cancel (&client->th);
+  (void) GNUNET_SCHEDULER_add_now (&destroy_connection,
+                                  client->connection);
+  /* need to cancel again, as it might have been re-added
+     in the meantime (i.e. during callbacks) */
+  if (NULL != client->warn_task)
+  {
+    GNUNET_SCHEDULER_cancel (client->warn_task);
+    client->warn_task = NULL;
+  }
+  if (GNUNET_YES == client->receive_pending)
+  {
+    GNUNET_CONNECTION_receive_cancel (client->connection);
+    client->receive_pending = GNUNET_NO;
+  }
+  GNUNET_free (client);
+  /* we might be in soft-shutdown, test if we're done */
+  if (NULL != server)
+    test_monitor_clients (server);
+}
+
+
+/**
+ * Disable the "CORK" feature for communication with the given client,
+ * forcing the OS to immediately flush the buffer on transmission
+ * instead of potentially buffering multiple messages.
+ *
+ * @param client handle to the client
+ * @return #GNUNET_OK on success
+ */
+int
+GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client)
+{
+  return GNUNET_CONNECTION_disable_corking (client->connection);
+}
+
+
+/**
+ * Wrapper for transmission notification that calls the original
+ * callback and update the last activity time for our connection.
+ *
+ * @param cls the `struct GNUNET_SERVER_Client *`
+ * @param size number of bytes we can transmit
+ * @param buf where to copy the message
+ * @return number of bytes actually transmitted
+ */
+static size_t
+transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
+{
+  struct GNUNET_SERVER_Client *client = cls;
+  GNUNET_CONNECTION_TransmitReadyNotify callback;
+
+  client->th.cth = NULL;
+  callback = client->th.callback;
+  client->th.callback = NULL;
+  client->last_activity = GNUNET_TIME_absolute_get ();
+  return callback (client->th.callback_cls, size, buf);
+}
+
+
+/**
+ * Notify us when the server has enough space to transmit
+ * a message of the given size to the given client.
+ *
+ * @param client client to transmit message to
+ * @param size requested amount of buffer space
+ * @param timeout after how long should we give up (and call
+ *        notify with buf NULL and size 0)?
+ * @param callback function to call when space is available
+ * @param callback_cls closure for @a callback
+ * @return non-NULL if the notify callback was queued; can be used
+ *         to cancel the request using
+ *         #GNUNET_SERVER_notify_transmit_ready_cancel().
+ *         NULL if we are already going to notify someone else (busy)
+ */
+struct GNUNET_SERVER_TransmitHandle *
+GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
+                                     size_t size,
+                                     struct GNUNET_TIME_Relative timeout,
+                                     GNUNET_CONNECTION_TransmitReadyNotify callback,
+                                     void *callback_cls)
+{
+  if (NULL != client->th.callback)
+    return NULL;
+  client->th.callback_cls = callback_cls;
+  client->th.callback = callback;
+  client->th.cth = GNUNET_CONNECTION_notify_transmit_ready (client->connection, size,
+                                                           timeout,
+                                                           &transmit_ready_callback_wrapper,
+                                                           client);
+  return &client->th;
+}
+
+
+/**
+ * Abort transmission request.
+ *
+ * @param th request to abort
+ */
+void
+GNUNET_SERVER_notify_transmit_ready_cancel (struct GNUNET_SERVER_TransmitHandle *th)
+{
+  GNUNET_CONNECTION_notify_transmit_ready_cancel (th->cth);
+  th->cth = NULL;
+  th->callback = NULL;
+}
+
+
+/**
+ * Set the persistent flag on this client, used to setup client connection
+ * to only be killed when the service it's connected to is actually dead.
+ *
+ * @param client the client to set the persistent flag on
+ */
+void
+GNUNET_SERVER_client_persist_ (struct GNUNET_SERVER_Client *client)
+{
+  client->persist = GNUNET_YES;
+}
+
+
+/**
+ * Resume receiving from this client, we are done processing the
+ * current request.  This function must be called from within each
+ * GNUNET_SERVER_MessageCallback (or its respective continuations).
+ *
+ * @param client client we were processing a message of
+ * @param success #GNUNET_OK to keep the connection open and
+ *                          continue to receive
+ *                #GNUNET_NO to close the connection (normal behavior)
+ *                #GNUNET_SYSERR to close the connection (signal
+ *                          serious error)
+ */
+void
+GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client,
+                           int success)
+{
+  if (NULL == client)
+    return;
+  GNUNET_assert (client->suspended > 0);
+  client->suspended--;
+  if (GNUNET_OK != success)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "GNUNET_SERVER_receive_done called with failure indication\n");
+    if ( (client->reference_count > 0) || (client->suspended > 0) )
+      client->shutdown_now = GNUNET_YES;
+    else
+      GNUNET_SERVER_client_disconnect (client);
+    return;
+  }
+  if (client->suspended > 0)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "GNUNET_SERVER_receive_done called, but more clients pending\n");
+    return;
+  }
+  if (NULL != client->warn_task)
+  {
+    GNUNET_SCHEDULER_cancel (client->warn_task);
+    client->warn_task = NULL;
+  }
+  if (GNUNET_YES == client->in_process_client_buffer)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "GNUNET_SERVER_receive_done called while still in processing loop\n");
+    return;
+  }
+  if ((NULL == client->server) || (GNUNET_YES == client->shutdown_now))
+  {
+    GNUNET_SERVER_client_disconnect (client);
+    return;
+  }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "GNUNET_SERVER_receive_done causes restart in reading from the socket\n");
+  GNUNET_assert (NULL == client->restart_task);
+  client->restart_task = GNUNET_SCHEDULER_add_now (&restart_processing,
+                                                   client);
+}
+
+
+/* end of server.c */
diff --git a/src/transport/tcp_server_mst_legacy.c b/src/transport/tcp_server_mst_legacy.c
new file mode 100644 (file)
index 0000000..ba42b18
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+     This file is part of GNUnet.
+     Copyright (C) 2010 GNUnet e.V.
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file util/server_mst.c
+ * @brief convenience functions for handling inbound message buffers
+ * @author Christian Grothoff
+ */
+
+#include "platform.h"
+#include "gnunet_util_lib.h"
+
+
+#if HAVE_UNALIGNED_64_ACCESS
+#define ALIGN_FACTOR 4
+#else
+#define ALIGN_FACTOR 8
+#endif
+
+
+/**
+ * Handle to a message stream tokenizer.
+ */
+struct GNUNET_SERVER_MessageStreamTokenizer
+{
+
+  /**
+   * Function to call on completed messages.
+   */
+  GNUNET_SERVER_MessageTokenizerCallback cb;
+
+  /**
+   * Closure for @e cb.
+   */
+  void *cb_cls;
+
+  /**
+   * Size of the buffer (starting at @e hdr).
+   */
+  size_t curr_buf;
+
+  /**
+   * How many bytes in buffer have we already processed?
+   */
+  size_t off;
+
+  /**
+   * How many bytes in buffer are valid right now?
+   */
+  size_t pos;
+
+  /**
+   * Beginning of the buffer.  Typed like this to force alignment.
+   */
+  struct GNUNET_MessageHeader *hdr;
+
+};
+
+
+
+/**
+ * Create a message stream tokenizer.
+ *
+ * @param cb function to call on completed messages
+ * @param cb_cls closure for @a cb
+ * @return handle to tokenizer
+ */
+struct GNUNET_SERVER_MessageStreamTokenizer *
+GNUNET_SERVER_mst_create (GNUNET_SERVER_MessageTokenizerCallback cb,
+                          void *cb_cls)
+{
+  struct GNUNET_SERVER_MessageStreamTokenizer *ret;
+
+  ret = GNUNET_new (struct GNUNET_SERVER_MessageStreamTokenizer);
+  ret->hdr = GNUNET_malloc (GNUNET_SERVER_MIN_BUFFER_SIZE);
+  ret->curr_buf = GNUNET_SERVER_MIN_BUFFER_SIZE;
+  ret->cb = cb;
+  ret->cb_cls = cb_cls;
+  return ret;
+}
+
+
+/**
+ * Add incoming data to the receive buffer and call the
+ * callback for all complete messages.
+ *
+ * @param mst tokenizer to use
+ * @param client_identity ID of client for which this is a buffer
+ * @param buf input data to add
+ * @param size number of bytes in @a buf
+ * @param purge should any excess bytes in the buffer be discarded
+ *       (i.e. for packet-based services like UDP)
+ * @param one_shot only call callback once, keep rest of message in buffer
+ * @return #GNUNET_OK if we are done processing (need more data)
+ *         #GNUNET_NO if @a one_shot was set and we have another message ready
+ *         #GNUNET_SYSERR if the data stream is corrupt
+ */
+int
+GNUNET_SERVER_mst_receive (struct GNUNET_SERVER_MessageStreamTokenizer *mst,
+                           void *client_identity,
+                           const char *buf, size_t size,
+                           int purge, int one_shot)
+{
+  const struct GNUNET_MessageHeader *hdr;
+  size_t delta;
+  uint16_t want;
+  char *ibuf;
+  int need_align;
+  unsigned long offset;
+  int ret;
+
+  GNUNET_assert (mst->off <= mst->pos);
+  GNUNET_assert (mst->pos <= mst->curr_buf);
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Server-mst receives %u bytes with %u bytes already in private buffer\n",
+       (unsigned int) size, (unsigned int) (mst->pos - mst->off));
+  ret = GNUNET_OK;
+  ibuf = (char *) mst->hdr;
+  while (mst->pos > 0)
+  {
+do_align:
+    GNUNET_assert (mst->pos >= mst->off);
+    if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
+        (0 != (mst->off % ALIGN_FACTOR)))
+    {
+      /* need to align or need more space */
+      mst->pos -= mst->off;
+      memmove (ibuf, &ibuf[mst->off], mst->pos);
+      mst->off = 0;
+    }
+    if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
+    {
+      delta =
+          GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
+                      (mst->pos - mst->off), size);
+      GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
+      mst->pos += delta;
+      buf += delta;
+      size -= delta;
+    }
+    if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
+    {
+      if (purge)
+      {
+        mst->off = 0;
+        mst->pos = 0;
+      }
+      return GNUNET_OK;
+    }
+    hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
+    want = ntohs (hdr->size);
+    if (want < sizeof (struct GNUNET_MessageHeader))
+    {
+      GNUNET_break_op (0);
+      return GNUNET_SYSERR;
+    }
+    if ( (mst->curr_buf - mst->off < want) &&
+        (mst->off > 0) )
+    {
+      /* can get more space by moving */
+      mst->pos -= mst->off;
+      memmove (ibuf, &ibuf[mst->off], mst->pos);
+      mst->off = 0;
+    }
+    if (mst->curr_buf < want)
+    {
+      /* need to get more space by growing buffer */
+      GNUNET_assert (0 == mst->off);
+      mst->hdr = GNUNET_realloc (mst->hdr, want);
+      ibuf = (char *) mst->hdr;
+      mst->curr_buf = want;
+    }
+    hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
+    if (mst->pos - mst->off < want)
+    {
+      delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
+      GNUNET_assert (mst->pos + delta <= mst->curr_buf);
+      GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
+      mst->pos += delta;
+      buf += delta;
+      size -= delta;
+    }
+    if (mst->pos - mst->off < want)
+    {
+      if (purge)
+      {
+        mst->off = 0;
+        mst->pos = 0;
+      }
+      return GNUNET_OK;
+    }
+    if (one_shot == GNUNET_SYSERR)
+    {
+      /* cannot call callback again, but return value saying that
+       * we have another full message in the buffer */
+      ret = GNUNET_NO;
+      goto copy;
+    }
+    if (one_shot == GNUNET_YES)
+      one_shot = GNUNET_SYSERR;
+    mst->off += want;
+    if (GNUNET_SYSERR == mst->cb (mst->cb_cls, client_identity, hdr))
+      return GNUNET_SYSERR;
+    if (mst->off == mst->pos)
+    {
+      /* reset to beginning of buffer, it's free right now! */
+      mst->off = 0;
+      mst->pos = 0;
+    }
+  }
+  GNUNET_assert (0 == mst->pos);
+  while (size > 0)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Server-mst has %u bytes left in inbound buffer\n",
+         (unsigned int) size);
+    if (size < sizeof (struct GNUNET_MessageHeader))
+      break;
+    offset = (unsigned long) buf;
+    need_align = (0 != (offset % ALIGN_FACTOR)) ? GNUNET_YES : GNUNET_NO;
+    if (GNUNET_NO == need_align)
+    {
+      /* can try to do zero-copy and process directly from original buffer */
+      hdr = (const struct GNUNET_MessageHeader *) buf;
+      want = ntohs (hdr->size);
+      if (want < sizeof (struct GNUNET_MessageHeader))
+      {
+       GNUNET_break_op (0);
+        mst->off = 0;
+        return GNUNET_SYSERR;
+      }
+      if (size < want)
+        break;                  /* or not: buffer incomplete, so copy to private buffer... */
+      if (one_shot == GNUNET_SYSERR)
+      {
+        /* cannot call callback again, but return value saying that
+         * we have another full message in the buffer */
+        ret = GNUNET_NO;
+        goto copy;
+      }
+      if (one_shot == GNUNET_YES)
+        one_shot = GNUNET_SYSERR;
+      if (GNUNET_SYSERR == mst->cb (mst->cb_cls, client_identity, hdr))
+        return GNUNET_SYSERR;
+      buf += want;
+      size -= want;
+    }
+    else
+    {
+      /* need to copy to private buffer to align;
+       * yes, we go a bit more spagetti than usual here */
+      goto do_align;
+    }
+  }
+copy:
+  if ((size > 0) && (!purge))
+  {
+    if (size + mst->pos > mst->curr_buf)
+    {
+      mst->hdr = GNUNET_realloc (mst->hdr, size + mst->pos);
+      ibuf = (char *) mst->hdr;
+      mst->curr_buf = size + mst->pos;
+    }
+    GNUNET_assert (size + mst->pos <= mst->curr_buf);
+    GNUNET_memcpy (&ibuf[mst->pos], buf, size);
+    mst->pos += size;
+  }
+  if (purge)
+  {
+    mst->off = 0;
+    mst->pos = 0;
+  }
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Server-mst leaves %u bytes in private buffer\n",
+       (unsigned int) (mst->pos - mst->off));
+  return ret;
+}
+
+
+/**
+ * Destroys a tokenizer.
+ *
+ * @param mst tokenizer to destroy
+ */
+void
+GNUNET_SERVER_mst_destroy (struct GNUNET_SERVER_MessageStreamTokenizer *mst)
+{
+  GNUNET_free (mst->hdr);
+  GNUNET_free (mst);
+}
+
+
+
+/* end of server_mst.c */
diff --git a/src/transport/tcp_service_legacy.c b/src/transport/tcp_service_legacy.c
new file mode 100644 (file)
index 0000000..c55d586
--- /dev/null
@@ -0,0 +1,1687 @@
+/*
+     This file is part of GNUnet.
+     Copyright (C) 2009, 2012 GNUnet e.V.
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file util/service.c
+ * @brief functions related to starting services
+ * @author Christian Grothoff
+ */
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_protocols.h"
+#include "gnunet_constants.h"
+#include "gnunet_resolver_service.h"
+
+#if HAVE_MALLINFO
+#include <malloc.h>
+#include "gauger.h"
+#endif
+
+
+/* ******************* access control ******************** */
+
+/**
+ * Check if the given IP address is in the list of IP addresses.
+ *
+ * @param list a list of networks
+ * @param add the IP to check (in network byte order)
+ * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
+ */
+static int
+check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list,
+                   const struct in_addr *add)
+{
+  unsigned int i;
+
+  if (NULL == list)
+    return GNUNET_NO;
+  i = 0;
+  while ((list[i].network.s_addr != 0) || (list[i].netmask.s_addr != 0))
+  {
+    if ((add->s_addr & list[i].netmask.s_addr) ==
+        (list[i].network.s_addr & list[i].netmask.s_addr))
+      return GNUNET_YES;
+    i++;
+  }
+  return GNUNET_NO;
+}
+
+
+/**
+ * Check if the given IP address is in the list of IP addresses.
+ *
+ * @param list a list of networks
+ * @param ip the IP to check (in network byte order)
+ * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
+ */
+static int
+check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list,
+                   const struct in6_addr *ip)
+{
+  unsigned int i;
+  unsigned int j;
+  struct in6_addr zero;
+
+  if (NULL == list)
+    return GNUNET_NO;
+  memset (&zero, 0, sizeof (struct in6_addr));
+  i = 0;
+NEXT:
+  while (0 != memcmp (&zero, &list[i].network, sizeof (struct in6_addr)))
+  {
+    for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++)
+      if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
+          (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
+      {
+        i++;
+        goto NEXT;
+      }
+    return GNUNET_YES;
+  }
+  return GNUNET_NO;
+}
+
+
+/* ****************** service struct ****************** */
+
+
+/**
+ * Context for "service_task".
+ */
+struct GNUNET_SERVICE_Context
+{
+  /**
+   * Our configuration.
+   */
+  const struct GNUNET_CONFIGURATION_Handle *cfg;
+
+  /**
+   * Handle for the server.
+   */
+  struct GNUNET_SERVER_Handle *server;
+
+  /**
+   * NULL-terminated array of addresses to bind to, NULL if we got pre-bound
+   * listen sockets.
+   */
+  struct sockaddr **addrs;
+
+  /**
+   * Name of our service.
+   */
+  const char *service_name;
+
+  /**
+   * Main service-specific task to run.
+   */
+  GNUNET_SERVICE_Main task;
+
+  /**
+   * Closure for @e task.
+   */
+  void *task_cls;
+
+  /**
+   * IPv4 addresses that are not allowed to connect.
+   */
+  struct GNUNET_STRINGS_IPv4NetworkPolicy *v4_denied;
+
+  /**
+   * IPv6 addresses that are not allowed to connect.
+   */
+  struct GNUNET_STRINGS_IPv6NetworkPolicy *v6_denied;
+
+  /**
+   * IPv4 addresses that are allowed to connect (if not
+   * set, all are allowed).
+   */
+  struct GNUNET_STRINGS_IPv4NetworkPolicy *v4_allowed;
+
+  /**
+   * IPv6 addresses that are allowed to connect (if not
+   * set, all are allowed).
+   */
+  struct GNUNET_STRINGS_IPv6NetworkPolicy *v6_allowed;
+
+  /**
+   * My (default) message handlers.  Adjusted copy
+   * of "defhandlers".
+   */
+  struct GNUNET_SERVER_MessageHandler *my_handlers;
+
+  /**
+   * Array of the lengths of the entries in addrs.
+   */
+  socklen_t *addrlens;
+
+  /**
+   * NULL-terminated array of listen sockets we should take over.
+   */
+  struct GNUNET_NETWORK_Handle **lsocks;
+
+  /**
+   * Task ID of the shutdown task.
+   */
+  struct GNUNET_SCHEDULER_Task *shutdown_task;
+
+  /**
+   * Idle timeout for server.
+   */
+  struct GNUNET_TIME_Relative timeout;
+
+  /**
+   * Overall success/failure of the service start.
+   */
+  int ret;
+
+  /**
+   * If we are daemonizing, this FD is set to the
+   * pipe to the parent.  Send '.' if we started
+   * ok, '!' if not.  -1 if we are not daemonizing.
+   */
+  int ready_confirm_fd;
+
+  /**
+   * Do we close connections if we receive messages
+   * for which we have no handler?
+   */
+  int require_found;
+
+  /**
+   * Do we require a matching UID for UNIX domain socket connections?
+   * #GNUNET_NO means that the UID does not have to match (however,
+   * @e match_gid may still impose other access control checks).
+   */
+  int match_uid;
+
+  /**
+   * Do we require a matching GID for UNIX domain socket connections?
+   * Ignored if @e match_uid is #GNUNET_YES.  Note that this is about
+   * checking that the client's UID is in our group OR that the
+   * client's GID is our GID.  If both "match_gid" and @e match_uid are
+   * #GNUNET_NO, all users on the local system have access.
+   */
+  int match_gid;
+
+  /**
+   * Our options.
+   */
+  enum GNUNET_SERVICE_Options options;
+
+};
+
+
+/* ****************** message handlers ****************** */
+
+/**
+ * Send a 'TEST' message back to the client.
+ *
+ * @param cls the 'struct GNUNET_SERVER_Client' to send TEST to
+ * @param size number of bytes available in 'buf'
+ * @param buf where to copy the message
+ * @return number of bytes written to 'buf'
+ */
+static size_t
+write_test (void *cls, size_t size, void *buf)
+{
+  struct GNUNET_SERVER_Client *client = cls;
+  struct GNUNET_MessageHeader *msg;
+
+  if (size < sizeof (struct GNUNET_MessageHeader))
+  {
+    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    return 0;                   /* client disconnected */
+  }
+  msg = (struct GNUNET_MessageHeader *) buf;
+  msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
+  msg->size = htons (sizeof (struct GNUNET_MessageHeader));
+  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  return sizeof (struct GNUNET_MessageHeader);
+}
+
+
+/**
+ * Handler for TEST message.
+ *
+ * @param cls closure (refers to service)
+ * @param client identification of the client
+ * @param message the actual message
+ */
+static void
+handle_test (void *cls, struct GNUNET_SERVER_Client *client,
+             const struct GNUNET_MessageHeader *message)
+{
+  /* simply bounce message back to acknowledge */
+  if (NULL ==
+      GNUNET_SERVER_notify_transmit_ready (client,
+                                           sizeof (struct GNUNET_MessageHeader),
+                                           GNUNET_TIME_UNIT_FOREVER_REL,
+                                           &write_test, client))
+    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+}
+
+
+/**
+ * Default handlers for all services.  Will be copied and the
+ * "callback_cls" fields will be replaced with the specific service
+ * struct.
+ */
+static const struct GNUNET_SERVER_MessageHandler defhandlers[] = {
+  {&handle_test, NULL, GNUNET_MESSAGE_TYPE_TEST,
+   sizeof (struct GNUNET_MessageHeader)},
+  {NULL, NULL, 0, 0}
+};
+
+
+/* ****************** service core routines ************** */
+
+
+/**
+ * Check if access to the service is allowed from the given address.
+ *
+ * @param cls closure
+ * @param uc credentials, if available, otherwise NULL
+ * @param addr address
+ * @param addrlen length of address
+ * @return #GNUNET_YES to allow, #GNUNET_NO to deny, #GNUNET_SYSERR
+ *   for unknown address family (will be denied).
+ */
+static int
+check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc,
+              const struct sockaddr *addr, socklen_t addrlen)
+{
+  struct GNUNET_SERVICE_Context *sctx = cls;
+  const struct sockaddr_in *i4;
+  const struct sockaddr_in6 *i6;
+  int ret;
+
+  switch (addr->sa_family)
+  {
+  case AF_INET:
+    GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
+    i4 = (const struct sockaddr_in *) addr;
+    ret = ((NULL == sctx->v4_allowed) ||
+           (check_ipv4_listed (sctx->v4_allowed, &i4->sin_addr))) &&
+        ((NULL == sctx->v4_denied) ||
+         (!check_ipv4_listed (sctx->v4_denied, &i4->sin_addr)));
+    break;
+  case AF_INET6:
+    GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
+    i6 = (const struct sockaddr_in6 *) addr;
+    ret = ((NULL == sctx->v6_allowed) ||
+           (check_ipv6_listed (sctx->v6_allowed, &i6->sin6_addr))) &&
+        ((NULL == sctx->v6_denied) ||
+         (!check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr)));
+    break;
+#ifndef WINDOWS
+  case AF_UNIX:
+    ret = GNUNET_OK;            /* controlled using file-system ACL now */
+    break;
+#endif
+  default:
+    LOG (GNUNET_ERROR_TYPE_WARNING, _("Unknown address family %d\n"),
+         addr->sa_family);
+    return GNUNET_SYSERR;
+  }
+  if (GNUNET_OK != ret)
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         _("Access from `%s' denied to service `%s'\n"),
+        GNUNET_a2s (addr, addrlen),
+         sctx->service_name);
+  }
+  return ret;
+}
+
+
+/**
+ * Get the name of the file where we will
+ * write the PID of the service.
+ *
+ * @param sctx service context
+ * @return name of the file for the process ID
+ */
+static char *
+get_pid_file_name (struct GNUNET_SERVICE_Context *sctx)
+{
+  char *pif;
+
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->service_name,
+                                               "PIDFILE", &pif))
+    return NULL;
+  return pif;
+}
+
+
+/**
+ * Parse an IPv4 access control list.
+ *
+ * @param ret location where to write the ACL (set)
+ * @param sctx service context to use to get the configuration
+ * @param option name of the ACL option to parse
+ * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
+ *         no ACL configured)
+ */
+static int
+process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
+              struct GNUNET_SERVICE_Context *sctx,
+              const char *option)
+{
+  char *opt;
+
+  if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option))
+  {
+    *ret = NULL;
+    return GNUNET_OK;
+  }
+  GNUNET_break (GNUNET_OK ==
+                GNUNET_CONFIGURATION_get_value_string (sctx->cfg,
+                                                       sctx->service_name,
+                                                       option, &opt));
+  if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt)))
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
+         opt, sctx->service_name, option);
+    GNUNET_free (opt);
+    return GNUNET_SYSERR;
+  }
+  GNUNET_free (opt);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Parse an IPv6 access control list.
+ *
+ * @param ret location where to write the ACL (set)
+ * @param sctx service context to use to get the configuration
+ * @param option name of the ACL option to parse
+ * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
+ *         no ACL configured)
+ */
+static int
+process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
+              struct GNUNET_SERVICE_Context *sctx,
+              const char *option)
+{
+  char *opt;
+
+  if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option))
+  {
+    *ret = NULL;
+    return GNUNET_OK;
+  }
+  GNUNET_break (GNUNET_OK ==
+                GNUNET_CONFIGURATION_get_value_string (sctx->cfg,
+                                                       sctx->service_name,
+                                                       option, &opt));
+  if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt)))
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
+         opt, sctx->service_name, option);
+    GNUNET_free (opt);
+    return GNUNET_SYSERR;
+  }
+  GNUNET_free (opt);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Add the given UNIX domain path as an address to the
+ * list (as the first entry).
+ *
+ * @param saddrs array to update
+ * @param saddrlens where to store the address length
+ * @param unixpath path to add
+ * @param abstract #GNUNET_YES to add an abstract UNIX domain socket.  This
+ *          parameter is ignore on systems other than LINUX
+ */
+static void
+add_unixpath (struct sockaddr **saddrs,
+              socklen_t *saddrlens,
+              const char *unixpath,
+              int abstract)
+{
+#ifdef AF_UNIX
+  struct sockaddr_un *un;
+
+  un = GNUNET_new (struct sockaddr_un);
+  un->sun_family = AF_UNIX;
+  strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1);
+#ifdef LINUX
+  if (GNUNET_YES == abstract)
+    un->sun_path[0] = '\0';
+#endif
+#if HAVE_SOCKADDR_UN_SUN_LEN
+  un->sun_len = (u_char) sizeof (struct sockaddr_un);
+#endif
+  *saddrs = (struct sockaddr *) un;
+  *saddrlens = sizeof (struct sockaddr_un);
+#else
+  /* this function should never be called
+   * unless AF_UNIX is defined! */
+  GNUNET_assert (0);
+#endif
+}
+
+
+/**
+ * Get the list of addresses that a server for the given service
+ * should bind to.
+ *
+ * @param service_name name of the service
+ * @param cfg configuration (which specifies the addresses)
+ * @param addrs set (call by reference) to an array of pointers to the
+ *              addresses the server should bind to and listen on; the
+ *              array will be NULL-terminated (on success)
+ * @param addr_lens set (call by reference) to an array of the lengths
+ *              of the respective `struct sockaddr` struct in the @a addrs
+ *              array (on success)
+ * @return number of addresses found on success,
+ *              #GNUNET_SYSERR if the configuration
+ *              did not specify reasonable finding information or
+ *              if it specified a hostname that could not be resolved;
+ *              #GNUNET_NO if the number of addresses configured is
+ *              zero (in this case, `*addrs` and `*addr_lens` will be
+ *              set to NULL).
+ */
+int
+GNUNET_SERVICE_get_server_addresses (const char *service_name,
+                                     const struct GNUNET_CONFIGURATION_Handle *cfg,
+                                     struct sockaddr ***addrs,
+                                     socklen_t ** addr_lens)
+{
+  int disablev6;
+  struct GNUNET_NETWORK_Handle *desc;
+  unsigned long long port;
+  char *unixpath;
+  struct addrinfo hints;
+  struct addrinfo *res;
+  struct addrinfo *pos;
+  struct addrinfo *next;
+  unsigned int i;
+  int resi;
+  int ret;
+  int abstract;
+  struct sockaddr **saddrs;
+  socklen_t *saddrlens;
+  char *hostname;
+
+  *addrs = NULL;
+  *addr_lens = NULL;
+  desc = NULL;
+  if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "DISABLEV6"))
+  {
+    if (GNUNET_SYSERR ==
+        (disablev6 =
+         GNUNET_CONFIGURATION_get_value_yesno (cfg, service_name, "DISABLEV6")))
+      return GNUNET_SYSERR;
+  }
+  else
+    disablev6 = GNUNET_NO;
+
+  if (! disablev6)
+  {
+    /* probe IPv6 support */
+    desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
+    if (NULL == desc)
+    {
+      if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
+          (EACCES == errno))
+      {
+        LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
+        return GNUNET_SYSERR;
+      }
+      LOG (GNUNET_ERROR_TYPE_INFO,
+           _("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
+           service_name, STRERROR (errno));
+      disablev6 = GNUNET_YES;
+    }
+    else
+    {
+      GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
+      desc = NULL;
+    }
+  }
+
+  port = 0;
+  if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT"))
+  {
+    if (GNUNET_OK !=
+       GNUNET_CONFIGURATION_get_value_number (cfg, service_name,
+                                              "PORT", &port))
+    {
+      LOG (GNUNET_ERROR_TYPE_ERROR,
+           _("Require valid port number for service `%s' in configuration!\n"),
+           service_name);
+    }
+    if (port > 65535)
+    {
+      LOG (GNUNET_ERROR_TYPE_ERROR,
+           _("Require valid port number for service `%s' in configuration!\n"),
+           service_name);
+      return GNUNET_SYSERR;
+    }
+  }
+
+  if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO"))
+  {
+    GNUNET_break (GNUNET_OK ==
+                  GNUNET_CONFIGURATION_get_value_string (cfg, service_name,
+                                                         "BINDTO", &hostname));
+  }
+  else
+    hostname = NULL;
+
+  unixpath = NULL;
+  abstract = GNUNET_NO;
+#ifdef AF_UNIX
+  if ((GNUNET_YES ==
+       GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) &&
+      (GNUNET_OK ==
+       GNUNET_CONFIGURATION_get_value_filename (cfg, service_name, "UNIXPATH",
+                                              &unixpath)) &&
+      (0 < strlen (unixpath)))
+  {
+    /* probe UNIX support */
+    struct sockaddr_un s_un;
+
+    if (strlen (unixpath) >= sizeof (s_un.sun_path))
+    {
+      LOG (GNUNET_ERROR_TYPE_WARNING,
+           _("UNIXPATH `%s' too long, maximum length is %llu\n"), unixpath,
+           (unsigned long long) sizeof (s_un.sun_path));
+      unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
+      LOG (GNUNET_ERROR_TYPE_INFO,
+          _("Using `%s' instead\n"),
+           unixpath);
+    }
+#ifdef LINUX
+    abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
+                                                     "TESTING",
+                                                     "USE_ABSTRACT_SOCKETS");
+    if (GNUNET_SYSERR == abstract)
+      abstract = GNUNET_NO;
+#endif
+    if ((GNUNET_YES != abstract)
+        && (GNUNET_OK !=
+            GNUNET_DISK_directory_create_for_file (unixpath)))
+      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
+                               "mkdir",
+                               unixpath);
+  }
+  if (NULL != unixpath)
+  {
+    desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
+    if (NULL == desc)
+    {
+      if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
+          (EACCES == errno))
+      {
+        LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
+        GNUNET_free_non_null (hostname);
+        GNUNET_free (unixpath);
+        return GNUNET_SYSERR;
+      }
+      LOG (GNUNET_ERROR_TYPE_INFO,
+           _("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
+           service_name,
+           STRERROR (errno));
+      GNUNET_free (unixpath);
+      unixpath = NULL;
+    }
+    else
+    {
+      GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
+      desc = NULL;
+    }
+  }
+#endif
+
+  if ((0 == port) && (NULL == unixpath))
+  {
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         _("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
+         service_name);
+    GNUNET_free_non_null (hostname);
+    return GNUNET_SYSERR;
+  }
+  if (0 == port)
+  {
+    saddrs = GNUNET_malloc (2 * sizeof (struct sockaddr *));
+    saddrlens = GNUNET_malloc (2 * sizeof (socklen_t));
+    add_unixpath (saddrs, saddrlens, unixpath, abstract);
+    GNUNET_free_non_null (unixpath);
+    GNUNET_free_non_null (hostname);
+    *addrs = saddrs;
+    *addr_lens = saddrlens;
+    return 1;
+  }
+
+  if (NULL != hostname)
+  {
+    LOG (GNUNET_ERROR_TYPE_DEBUG,
+         "Resolving `%s' since that is where `%s' will bind to.\n",
+         hostname,
+         service_name);
+    memset (&hints, 0, sizeof (struct addrinfo));
+    if (disablev6)
+      hints.ai_family = AF_INET;
+    hints.ai_protocol = IPPROTO_TCP;
+    if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
+        (NULL == res))
+    {
+      LOG (GNUNET_ERROR_TYPE_ERROR,
+           _("Failed to resolve `%s': %s\n"),
+           hostname,
+           gai_strerror (ret));
+      GNUNET_free (hostname);
+      GNUNET_free_non_null (unixpath);
+      return GNUNET_SYSERR;
+    }
+    next = res;
+    i = 0;
+    while (NULL != (pos = next))
+    {
+      next = pos->ai_next;
+      if ((disablev6) && (pos->ai_family == AF_INET6))
+        continue;
+      i++;
+    }
+    if (0 == i)
+    {
+      LOG (GNUNET_ERROR_TYPE_ERROR,
+           _("Failed to find %saddress for `%s'.\n"),
+           disablev6 ? "IPv4 " : "",
+           hostname);
+      freeaddrinfo (res);
+      GNUNET_free (hostname);
+      GNUNET_free_non_null (unixpath);
+      return GNUNET_SYSERR;
+    }
+    resi = i;
+    if (NULL != unixpath)
+      resi++;
+    saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
+    saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
+    i = 0;
+    if (NULL != unixpath)
+    {
+      add_unixpath (saddrs, saddrlens, unixpath, abstract);
+      i++;
+    }
+    next = res;
+    while (NULL != (pos = next))
+    {
+      next = pos->ai_next;
+      if ((disablev6) && (AF_INET6 == pos->ai_family))
+        continue;
+      if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
+        continue;               /* not TCP */
+      if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
+        continue;               /* huh? */
+      LOG (GNUNET_ERROR_TYPE_DEBUG, "Service `%s' will bind to `%s'\n",
+           service_name, GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
+      if (AF_INET == pos->ai_family)
+      {
+        GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen);
+        saddrlens[i] = pos->ai_addrlen;
+        saddrs[i] = GNUNET_malloc (saddrlens[i]);
+        GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
+        ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
+      }
+      else
+      {
+        GNUNET_assert (AF_INET6 == pos->ai_family);
+        GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen);
+        saddrlens[i] = pos->ai_addrlen;
+        saddrs[i] = GNUNET_malloc (saddrlens[i]);
+        GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
+        ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
+      }
+      i++;
+    }
+    GNUNET_free (hostname);
+    freeaddrinfo (res);
+    resi = i;
+  }
+  else
+  {
+    /* will bind against everything, just set port */
+    if (disablev6)
+    {
+      /* V4-only */
+      resi = 1;
+      if (NULL != unixpath)
+        resi++;
+      i = 0;
+      saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
+      saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
+      if (NULL != unixpath)
+      {
+        add_unixpath (saddrs, saddrlens, unixpath, abstract);
+        i++;
+      }
+      saddrlens[i] = sizeof (struct sockaddr_in);
+      saddrs[i] = GNUNET_malloc (saddrlens[i]);
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
+#endif
+      ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
+      ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
+    }
+    else
+    {
+      /* dual stack */
+      resi = 2;
+      if (NULL != unixpath)
+        resi++;
+      saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
+      saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
+      i = 0;
+      if (NULL != unixpath)
+      {
+        add_unixpath (saddrs, saddrlens, unixpath, abstract);
+        i++;
+      }
+      saddrlens[i] = sizeof (struct sockaddr_in6);
+      saddrs[i] = GNUNET_malloc (saddrlens[i]);
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
+#endif
+      ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
+      ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
+      i++;
+      saddrlens[i] = sizeof (struct sockaddr_in);
+      saddrs[i] = GNUNET_malloc (saddrlens[i]);
+#if HAVE_SOCKADDR_IN_SIN_LEN
+      ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
+#endif
+      ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
+      ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
+    }
+  }
+  GNUNET_free_non_null (unixpath);
+  *addrs = saddrs;
+  *addr_lens = saddrlens;
+  return resi;
+}
+
+
+#ifdef MINGW
+/**
+ * Read listen sockets from the parent process (ARM).
+ *
+ * @param sctx service context to initialize
+ * @return #GNUNET_YES if ok, #GNUNET_NO if not ok (must bind yourself),
+ * and #GNUNET_SYSERR on error.
+ */
+static int
+receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx)
+{
+  const char *env_buf;
+  int fail;
+  uint64_t count;
+  uint64_t i;
+  HANDLE lsocks_pipe;
+
+  env_buf = getenv ("GNUNET_OS_READ_LSOCKS");
+  if ((NULL == env_buf) || (strlen (env_buf) <= 0))
+    return GNUNET_NO;
+  /* Using W32 API directly here, because this pipe will
+   * never be used outside of this function, and it's just too much of a bother
+   * to create a GNUnet API that boxes a HANDLE (the way it is done with socks)
+   */
+  lsocks_pipe = (HANDLE) strtoul (env_buf, NULL, 10);
+  if ( (0 == lsocks_pipe) || (INVALID_HANDLE_VALUE == lsocks_pipe))
+    return GNUNET_NO;
+  fail = 1;
+  do
+  {
+    int ret;
+    int fail2;
+    DWORD rd;
+
+    ret = ReadFile (lsocks_pipe, &count, sizeof (count), &rd, NULL);
+    if ((0 == ret) || (sizeof (count) != rd) || (0 == count))
+      break;
+    sctx->lsocks =
+        GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (count + 1));
+
+    fail2 = 1;
+    for (i = 0; i < count; i++)
+    {
+      WSAPROTOCOL_INFOA pi;
+      uint64_t size;
+      SOCKET s;
+
+      ret = ReadFile (lsocks_pipe, &size, sizeof (size), &rd, NULL);
+      if ( (0 == ret) || (sizeof (size) != rd) || (sizeof (pi) != size) )
+        break;
+      ret = ReadFile (lsocks_pipe, &pi, sizeof (pi), &rd, NULL);
+      if ( (0 == ret) || (sizeof (pi) != rd))
+        break;
+      s = WSASocketA (pi.iAddressFamily, pi.iSocketType, pi.iProtocol, &pi, 0, WSA_FLAG_OVERLAPPED);
+      sctx->lsocks[i] = GNUNET_NETWORK_socket_box_native (s);
+      if (NULL == sctx->lsocks[i])
+        break;
+      else if (i == count - 1)
+        fail2 = 0;
+    }
+    if (fail2)
+      break;
+    sctx->lsocks[count] = NULL;
+    fail = 0;
+  }
+  while (fail);
+
+  CloseHandle (lsocks_pipe);
+
+  if (fail)
+  {
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         _("Could not access a pre-bound socket, will try to bind myself\n"));
+    for (i = 0; (i < count) && (NULL != sctx->lsocks[i]); i++)
+      GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[i]));
+    GNUNET_free_non_null (sctx->lsocks);
+    sctx->lsocks = NULL;
+    return GNUNET_NO;
+  }
+  return GNUNET_YES;
+}
+#endif
+
+
+/**
+ * Setup addr, addrlen, idle_timeout
+ * based on configuration!
+ *
+ * Configuration may specify:
+ * - PORT (where to bind to for TCP)
+ * - UNIXPATH (where to bind to for UNIX domain sockets)
+ * - TIMEOUT (after how many ms does an inactive service timeout);
+ * - DISABLEV6 (disable support for IPv6, otherwise we use dual-stack)
+ * - BINDTO (hostname or IP address to bind to, otherwise we take everything)
+ * - ACCEPT_FROM  (only allow connections from specified IPv4 subnets)
+ * - ACCEPT_FROM6 (only allow connections from specified IPv6 subnets)
+ * - REJECT_FROM  (disallow allow connections from specified IPv4 subnets)
+ * - REJECT_FROM6 (disallow allow connections from specified IPv6 subnets)
+ *
+ * @param sctx service context to initialize
+ * @return #GNUNET_OK if configuration succeeded
+ */
+static int
+setup_service (struct GNUNET_SERVICE_Context *sctx)
+{
+  struct GNUNET_TIME_Relative idleout;
+  int tolerant;
+
+#ifndef MINGW
+  const char *nfds;
+  unsigned int cnt;
+  int flags;
+#endif
+
+  if (GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, "TIMEOUT"))
+  {
+    if (GNUNET_OK !=
+        GNUNET_CONFIGURATION_get_value_time (sctx->cfg, sctx->service_name,
+                                             "TIMEOUT", &idleout))
+    {
+      LOG (GNUNET_ERROR_TYPE_ERROR,
+           _("Specified value for `%s' of service `%s' is invalid\n"),
+           "TIMEOUT", sctx->service_name);
+      return GNUNET_SYSERR;
+    }
+    sctx->timeout = idleout;
+  }
+  else
+    sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
+
+  if (GNUNET_CONFIGURATION_have_value
+      (sctx->cfg, sctx->service_name, "TOLERANT"))
+  {
+    if (GNUNET_SYSERR ==
+        (tolerant =
+         GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name,
+                                               "TOLERANT")))
+    {
+      LOG (GNUNET_ERROR_TYPE_ERROR,
+           _("Specified value for `%s' of service `%s' is invalid\n"),
+           "TOLERANT", sctx->service_name);
+      return GNUNET_SYSERR;
+    }
+  }
+  else
+    tolerant = GNUNET_NO;
+
+#ifndef MINGW
+  errno = 0;
+  if ((NULL != (nfds = getenv ("LISTEN_FDS"))) &&
+      (1 == SSCANF (nfds, "%u", &cnt)) && (cnt > 0) && (cnt < FD_SETSIZE) &&
+      (cnt + 4 < FD_SETSIZE))
+  {
+    sctx->lsocks =
+        GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (cnt + 1));
+    while (0 < cnt--)
+    {
+      flags = fcntl (3 + cnt, F_GETFD);
+      if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) ||
+          (NULL ==
+           (sctx->lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
+      {
+        LOG (GNUNET_ERROR_TYPE_ERROR,
+             _
+             ("Could not access pre-bound socket %u, will try to bind myself\n"),
+             (unsigned int) 3 + cnt);
+        cnt++;
+        while (sctx->lsocks[cnt] != NULL)
+          GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[cnt++]));
+        GNUNET_free (sctx->lsocks);
+        sctx->lsocks = NULL;
+        break;
+      }
+    }
+    unsetenv ("LISTEN_FDS");
+  }
+#else
+  if (getenv ("GNUNET_OS_READ_LSOCKS") != NULL)
+  {
+    receive_sockets_from_parent (sctx);
+    putenv ("GNUNET_OS_READ_LSOCKS=");
+  }
+#endif
+
+  if ((NULL == sctx->lsocks) &&
+      (GNUNET_SYSERR ==
+       GNUNET_SERVICE_get_server_addresses (sctx->service_name, sctx->cfg,
+                                            &sctx->addrs, &sctx->addrlens)))
+    return GNUNET_SYSERR;
+  sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
+  sctx->match_uid =
+      GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name,
+                                            "UNIX_MATCH_UID");
+  sctx->match_gid =
+      GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name,
+                                            "UNIX_MATCH_GID");
+  process_acl4 (&sctx->v4_denied, sctx, "REJECT_FROM");
+  process_acl4 (&sctx->v4_allowed, sctx, "ACCEPT_FROM");
+  process_acl6 (&sctx->v6_denied, sctx, "REJECT_FROM6");
+  process_acl6 (&sctx->v6_allowed, sctx, "ACCEPT_FROM6");
+
+  return GNUNET_OK;
+}
+
+
+/**
+ * Get the name of the user that'll be used
+ * to provide the service.
+ *
+ * @param sctx service context
+ * @return value of the 'USERNAME' option
+ */
+static char *
+get_user_name (struct GNUNET_SERVICE_Context *sctx)
+{
+  char *un;
+
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->service_name,
+                                               "USERNAME", &un))
+    return NULL;
+  return un;
+}
+
+
+/**
+ * Write PID file.
+ *
+ * @param sctx service context
+ * @param pid PID to write (should be equal to 'getpid()'
+ * @return  #GNUNET_OK on success (including no work to be done)
+ */
+static int
+write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid)
+{
+  FILE *pidfd;
+  char *pif;
+  char *user;
+  char *rdir;
+  int len;
+
+  if (NULL == (pif = get_pid_file_name (sctx)))
+    return GNUNET_OK;           /* no file desired */
+  user = get_user_name (sctx);
+  rdir = GNUNET_strdup (pif);
+  len = strlen (rdir);
+  while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
+    len--;
+  rdir[len] = '\0';
+  if (0 != ACCESS (rdir, F_OK))
+  {
+    /* we get to create a directory -- and claim it
+     * as ours! */
+    (void) GNUNET_DISK_directory_create (rdir);
+    if ((NULL != user) && (0 < strlen (user)))
+      GNUNET_DISK_file_change_owner (rdir, user);
+  }
+  if (0 != ACCESS (rdir, W_OK | X_OK))
+  {
+    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", rdir);
+    GNUNET_free (rdir);
+    GNUNET_free_non_null (user);
+    GNUNET_free (pif);
+    return GNUNET_SYSERR;
+  }
+  GNUNET_free (rdir);
+  pidfd = FOPEN (pif, "w");
+  if (NULL == pidfd)
+  {
+    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "fopen", pif);
+    GNUNET_free (pif);
+    GNUNET_free_non_null (user);
+    return GNUNET_SYSERR;
+  }
+  if (0 > FPRINTF (pidfd, "%u", pid))
+    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fprintf", pif);
+  GNUNET_break (0 == FCLOSE (pidfd));
+  if ((NULL != user) && (0 < strlen (user)))
+    GNUNET_DISK_file_change_owner (pif, user);
+  GNUNET_free_non_null (user);
+  GNUNET_free (pif);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Task run during shutdown.  Stops the server/service.
+ *
+ * @param cls the `struct GNUNET_SERVICE_Context`
+ */
+static void
+shutdown_task (void *cls)
+{
+  struct GNUNET_SERVICE_Context *service = cls;
+  struct GNUNET_SERVER_Handle *server = service->server;
+
+  service->shutdown_task = NULL;
+  if (0 != (service->options & GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN))
+    GNUNET_SERVER_stop_listening (server);
+  else
+    GNUNET_SERVER_destroy (server);
+}
+
+
+/**
+ * Initial task for the service.
+ *
+ * @param cls service context
+ */
+static void
+service_task (void *cls)
+{
+  struct GNUNET_SERVICE_Context *sctx = cls;
+  unsigned int i;
+
+  GNUNET_RESOLVER_connect (sctx->cfg);
+  if (NULL != sctx->lsocks)
+    sctx->server
+      = GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks,
+                                           sctx->timeout, sctx->require_found);
+  else
+    sctx->server
+      = GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens,
+                              sctx->timeout, sctx->require_found);
+  if (NULL == sctx->server)
+  {
+    if (NULL != sctx->addrs)
+      for (i = 0; NULL != sctx->addrs[i]; i++)
+        LOG (GNUNET_ERROR_TYPE_INFO,
+             _("Failed to start `%s' at `%s'\n"),
+             sctx->service_name, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
+    sctx->ret = GNUNET_SYSERR;
+    return;
+  }
+#ifndef WINDOWS
+  if (NULL != sctx->addrs)
+    for (i = 0; NULL != sctx->addrs[i]; i++)
+      if ((AF_UNIX == sctx->addrs[i]->sa_family)
+          && ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0]))
+        GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path,
+                                     sctx->match_uid,
+                                     sctx->match_gid);
+#endif
+
+
+  if (0 == (sctx->options & GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN))
+  {
+    /* install a task that will kill the server
+     * process if the scheduler ever gets a shutdown signal */
+    sctx->shutdown_task = GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
+                                                        sctx);
+  }
+  sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
+  GNUNET_memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
+  i = 0;
+  while (NULL != sctx->my_handlers[i].callback)
+    sctx->my_handlers[i++].callback_cls = sctx;
+  GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers);
+  if (-1 != sctx->ready_confirm_fd)
+  {
+    GNUNET_break (1 == WRITE (sctx->ready_confirm_fd, ".", 1));
+    GNUNET_break (0 == CLOSE (sctx->ready_confirm_fd));
+    sctx->ready_confirm_fd = -1;
+    write_pid_file (sctx, getpid ());
+  }
+  if (NULL != sctx->addrs)
+  {
+    i = 0;
+    while (NULL != sctx->addrs[i])
+    {
+      LOG (GNUNET_ERROR_TYPE_INFO, _("Service `%s' runs at %s\n"),
+           sctx->service_name, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
+      i++;
+    }
+  }
+  sctx->task (sctx->task_cls, sctx->server, sctx->cfg);
+}
+
+
+/**
+ * Detach from terminal.
+ *
+ * @param sctx service context
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ */
+static int
+detach_terminal (struct GNUNET_SERVICE_Context *sctx)
+{
+#ifndef MINGW
+  pid_t pid;
+  int nullfd;
+  int filedes[2];
+
+  if (0 != PIPE (filedes))
+  {
+    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "pipe");
+    return GNUNET_SYSERR;
+  }
+  pid = fork ();
+  if (pid < 0)
+  {
+    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
+    return GNUNET_SYSERR;
+  }
+  if (0 != pid)
+  {
+    /* Parent */
+    char c;
+
+    GNUNET_break (0 == CLOSE (filedes[1]));
+    c = 'X';
+    if (1 != READ (filedes[0], &c, sizeof (char)))
+      LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "read");
+    fflush (stdout);
+    switch (c)
+    {
+    case '.':
+      exit (0);
+    case 'I':
+      LOG (GNUNET_ERROR_TYPE_INFO, _("Service process failed to initialize\n"));
+      break;
+    case 'S':
+      LOG (GNUNET_ERROR_TYPE_INFO,
+           _("Service process could not initialize server function\n"));
+      break;
+    case 'X':
+      LOG (GNUNET_ERROR_TYPE_INFO,
+           _("Service process failed to report status\n"));
+      break;
+    }
+    exit (1);                   /* child reported error */
+  }
+  GNUNET_break (0 == CLOSE (0));
+  GNUNET_break (0 == CLOSE (1));
+  GNUNET_break (0 == CLOSE (filedes[0]));
+  nullfd = OPEN ("/dev/null", O_RDWR | O_APPEND);
+  if (nullfd < 0)
+    return GNUNET_SYSERR;
+  /* set stdin/stdout to /dev/null */
+  if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0))
+  {
+    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2");
+    (void) CLOSE (nullfd);
+    return GNUNET_SYSERR;
+  }
+  (void) CLOSE (nullfd);
+  /* Detach from controlling terminal */
+  pid = setsid ();
+  if (-1 == pid)
+    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "setsid");
+  sctx->ready_confirm_fd = filedes[1];
+#else
+  /* FIXME: we probably need to do something else
+   * elsewhere in order to fork the process itself... */
+  FreeConsole ();
+#endif
+  return GNUNET_OK;
+}
+
+
+/**
+ * Set user ID.
+ *
+ * @param sctx service context
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ */
+static int
+set_user_id (struct GNUNET_SERVICE_Context *sctx)
+{
+  char *user;
+
+  if (NULL == (user = get_user_name (sctx)))
+    return GNUNET_OK;           /* keep */
+#ifndef MINGW
+  struct passwd *pws;
+
+  errno = 0;
+  pws = getpwnam (user);
+  if (NULL == pws)
+  {
+    LOG (GNUNET_ERROR_TYPE_ERROR,
+         _("Cannot obtain information about user `%s': %s\n"), user,
+         errno == 0 ? _("No such user") : STRERROR (errno));
+    GNUNET_free (user);
+    return GNUNET_SYSERR;
+  }
+  if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) ||
+#if HAVE_INITGROUPS
+      (0 != initgroups (user, pws->pw_gid)) ||
+#endif
+      (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid)))
+  {
+    if ((0 != setregid (pws->pw_gid, pws->pw_gid)) ||
+        (0 != setreuid (pws->pw_uid, pws->pw_uid)))
+    {
+      LOG (GNUNET_ERROR_TYPE_ERROR, _("Cannot change user/group to `%s': %s\n"),
+           user, STRERROR (errno));
+      GNUNET_free (user);
+      return GNUNET_SYSERR;
+    }
+  }
+#endif
+  GNUNET_free (user);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Delete the PID file that was created by our parent.
+ *
+ * @param sctx service context
+ */
+static void
+pid_file_delete (struct GNUNET_SERVICE_Context *sctx)
+{
+  char *pif = get_pid_file_name (sctx);
+
+  if (NULL == pif)
+    return;                     /* no PID file */
+  if (0 != UNLINK (pif))
+    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", pif);
+  GNUNET_free (pif);
+}
+
+
+/**
+ * Run a standard GNUnet service startup sequence (initialize loggers
+ * and configuration, parse options).
+ *
+ * @param argc number of command line arguments
+ * @param argv command line arguments
+ * @param service_name our service name
+ * @param options service options
+ * @param task main task of the service
+ * @param task_cls closure for @a task
+ * @return #GNUNET_SYSERR on error, #GNUNET_OK
+ *         if we shutdown nicely
+ */
+int
+GNUNET_SERVICE_run (int argc, char *const *argv,
+                    const char *service_name,
+                    enum GNUNET_SERVICE_Options options,
+                    GNUNET_SERVICE_Main task,
+                    void *task_cls)
+{
+#define HANDLE_ERROR do { GNUNET_break (0); goto shutdown; } while (0)
+
+  int err;
+  int ret;
+  char *cfg_fn;
+  char *opt_cfg_fn;
+  char *loglev;
+  char *logfile;
+  int do_daemonize;
+  unsigned int i;
+  unsigned long long skew_offset;
+  unsigned long long skew_variance;
+  long long clock_offset;
+  struct GNUNET_SERVICE_Context sctx;
+  struct GNUNET_CONFIGURATION_Handle *cfg;
+  const char *xdg;
+
+  struct GNUNET_GETOPT_CommandLineOption service_options[] = {
+    GNUNET_GETOPT_OPTION_CFG_FILE (&opt_cfg_fn),
+    {'d', "daemonize", NULL,
+     gettext_noop ("do daemonize (detach from terminal)"), 0,
+     GNUNET_GETOPT_set_one, &do_daemonize},
+    GNUNET_GETOPT_OPTION_HELP (NULL),
+    GNUNET_GETOPT_OPTION_LOGLEVEL (&loglev),
+    GNUNET_GETOPT_OPTION_LOGFILE (&logfile),
+    GNUNET_GETOPT_OPTION_VERSION (PACKAGE_VERSION " " VCS_VERSION),
+    GNUNET_GETOPT_OPTION_END
+  };
+  err = 1;
+  do_daemonize = 0;
+  logfile = NULL;
+  loglev = NULL;
+  opt_cfg_fn = NULL;
+  xdg = getenv ("XDG_CONFIG_HOME");
+  if (NULL != xdg)
+    GNUNET_asprintf (&cfg_fn,
+                     "%s%s%s",
+                     xdg,
+                     DIR_SEPARATOR_STR,
+                     GNUNET_OS_project_data_get ()->config_file);
+  else
+    cfg_fn = GNUNET_strdup (GNUNET_OS_project_data_get ()->user_config_file);
+  memset (&sctx, 0, sizeof (sctx));
+  sctx.options = options;
+  sctx.ready_confirm_fd = -1;
+  sctx.ret = GNUNET_OK;
+  sctx.timeout = GNUNET_TIME_UNIT_FOREVER_REL;
+  sctx.task = task;
+  sctx.task_cls = task_cls;
+  sctx.service_name = service_name;
+  sctx.cfg = cfg = GNUNET_CONFIGURATION_create ();
+
+  /* setup subsystems */
+  ret = GNUNET_GETOPT_run (service_name, service_options, argc, argv);
+  if (GNUNET_SYSERR == ret)
+    goto shutdown;
+  if (GNUNET_NO == ret)
+  {
+    err = 0;
+    goto shutdown;
+  }
+  if (GNUNET_OK != GNUNET_log_setup (service_name, loglev, logfile))
+    HANDLE_ERROR;
+  if (NULL == opt_cfg_fn)
+    opt_cfg_fn = GNUNET_strdup (cfg_fn);
+  if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_fn))
+  {
+    if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_fn))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  _("Malformed configuration file `%s', exit ...\n"),
+                  opt_cfg_fn);
+      goto shutdown;
+    }
+  }
+  else
+  {
+    if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  _("Malformed configuration, exit ...\n"));
+      goto shutdown;
+    }
+    if (0 != strcmp (opt_cfg_fn, cfg_fn))
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                 _("Could not access configuration file `%s'\n"),
+                 opt_cfg_fn);
+  }
+  if (GNUNET_OK != setup_service (&sctx))
+    goto shutdown;
+  if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sctx)))
+    HANDLE_ERROR;
+  if (GNUNET_OK != set_user_id (&sctx))
+    goto shutdown;
+  LOG (GNUNET_ERROR_TYPE_DEBUG,
+       "Service `%s' runs with configuration from `%s'\n",
+       service_name,
+       opt_cfg_fn);
+  if ((GNUNET_OK ==
+       GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING",
+                                              "SKEW_OFFSET", &skew_offset)) &&
+      (GNUNET_OK ==
+       GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING",
+                                              "SKEW_VARIANCE", &skew_variance)))
+  {
+    clock_offset = skew_offset - skew_variance;
+    GNUNET_TIME_set_offset (clock_offset);
+    LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset);
+  }
+  /* actually run service */
+  err = 0;
+  GNUNET_SCHEDULER_run (&service_task, &sctx);
+  /* shutdown */
+  if ((1 == do_daemonize) && (NULL != sctx.server))
+    pid_file_delete (&sctx);
+  GNUNET_free_non_null (sctx.my_handlers);
+
+shutdown:
+  if (-1 != sctx.ready_confirm_fd)
+  {
+    if (1 != WRITE (sctx.ready_confirm_fd, err ? "I" : "S", 1))
+      LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write");
+    GNUNET_break (0 == CLOSE (sctx.ready_confirm_fd));
+  }
+#if HAVE_MALLINFO
+  {
+    char *counter;
+
+    if ( (GNUNET_YES ==
+         GNUNET_CONFIGURATION_have_value (sctx.cfg, service_name,
+                                          "GAUGER_HEAP")) &&
+        (GNUNET_OK ==
+         GNUNET_CONFIGURATION_get_value_string (sctx.cfg, service_name,
+                                                "GAUGER_HEAP",
+                                                &counter)) )
+    {
+      struct mallinfo mi;
+
+      mi = mallinfo ();
+      GAUGER (service_name, counter, mi.usmblks, "blocks");
+      GNUNET_free (counter);
+    }
+  }
+#endif
+  GNUNET_CONFIGURATION_destroy (cfg);
+  i = 0;
+  if (NULL != sctx.addrs)
+    while (NULL != sctx.addrs[i])
+      GNUNET_free (sctx.addrs[i++]);
+  GNUNET_free_non_null (sctx.addrs);
+  GNUNET_free_non_null (sctx.addrlens);
+  GNUNET_free_non_null (logfile);
+  GNUNET_free_non_null (loglev);
+  GNUNET_free (cfg_fn);
+  GNUNET_free_non_null (opt_cfg_fn);
+  GNUNET_free_non_null (sctx.v4_denied);
+  GNUNET_free_non_null (sctx.v6_denied);
+  GNUNET_free_non_null (sctx.v4_allowed);
+  GNUNET_free_non_null (sctx.v6_allowed);
+
+  return err ? GNUNET_SYSERR : sctx.ret;
+}
+
+
+/**
+ * Run a service startup sequence within an existing
+ * initialized system.
+ *
+ * @param service_name our service name
+ * @param cfg configuration to use
+ * @param options service options
+ * @return NULL on error, service handle
+ */
+struct GNUNET_SERVICE_Context *
+GNUNET_SERVICE_start (const char *service_name,
+                      const struct GNUNET_CONFIGURATION_Handle *cfg,
+                     enum GNUNET_SERVICE_Options options)
+{
+  int i;
+  struct GNUNET_SERVICE_Context *sctx;
+
+  sctx = GNUNET_new (struct GNUNET_SERVICE_Context);
+  sctx->ready_confirm_fd = -1;  /* no daemonizing */
+  sctx->ret = GNUNET_OK;
+  sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
+  sctx->service_name = service_name;
+  sctx->cfg = cfg;
+  sctx->options = options;
+
+  /* setup subsystems */
+  if (GNUNET_OK != setup_service (sctx))
+  {
+    GNUNET_SERVICE_stop (sctx);
+    return NULL;
+  }
+  if (NULL != sctx->lsocks)
+    sctx->server =
+        GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks,
+                                           sctx->timeout, sctx->require_found);
+  else
+    sctx->server =
+        GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens,
+                              sctx->timeout, sctx->require_found);
+
+  if (NULL == sctx->server)
+  {
+    GNUNET_SERVICE_stop (sctx);
+    return NULL;
+  }
+#ifndef WINDOWS
+  if (NULL != sctx->addrs)
+    for (i = 0; NULL != sctx->addrs[i]; i++)
+      if ((AF_UNIX == sctx->addrs[i]->sa_family)
+          && ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0]))
+        GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path,
+                                     sctx->match_uid,
+                                     sctx->match_gid);
+#endif
+  sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
+  GNUNET_memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
+  i = 0;
+  while ((sctx->my_handlers[i].callback != NULL))
+    sctx->my_handlers[i++].callback_cls = sctx;
+  GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers);
+  return sctx;
+}
+
+
+/**
+ * Obtain the server used by a service.  Note that the server must NOT
+ * be destroyed by the caller.
+ *
+ * @param ctx the service context returned from the start function
+ * @return handle to the server for this service, NULL if there is none
+ */
+struct GNUNET_SERVER_Handle *
+GNUNET_SERVICE_get_server (struct GNUNET_SERVICE_Context *ctx)
+{
+  return ctx->server;
+}
+
+
+/**
+ * Get the NULL-terminated array of listen sockets for this service.
+ *
+ * @param ctx service context to query
+ * @return NULL if there are no listen sockets, otherwise NULL-terminated
+ *              array of listen sockets.
+ */
+struct GNUNET_NETWORK_Handle *const*
+GNUNET_SERVICE_get_listen_sockets (struct GNUNET_SERVICE_Context *ctx)
+{
+  return ctx->lsocks;
+}
+
+
+/**
+ * Stop a service that was started with "GNUNET_SERVICE_start".
+ *
+ * @param sctx the service context returned from the start function
+ */
+void
+GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Context *sctx)
+{
+  unsigned int i;
+
+#if HAVE_MALLINFO
+  {
+    char *counter;
+
+    if ( (GNUNET_YES ==
+         GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name,
+                                          "GAUGER_HEAP")) &&
+        (GNUNET_OK ==
+         GNUNET_CONFIGURATION_get_value_string (sctx->cfg, sctx->service_name,
+                                                "GAUGER_HEAP",
+                                                &counter)) )
+    {
+      struct mallinfo mi;
+
+      mi = mallinfo ();
+      GAUGER (sctx->service_name, counter, mi.usmblks, "blocks");
+      GNUNET_free (counter);
+    }
+  }
+#endif
+  if (NULL != sctx->shutdown_task)
+  {
+    GNUNET_SCHEDULER_cancel (sctx->shutdown_task);
+    sctx->shutdown_task = NULL;
+  }
+  if (NULL != sctx->server)
+    GNUNET_SERVER_destroy (sctx->server);
+  GNUNET_free_non_null (sctx->my_handlers);
+  if (NULL != sctx->addrs)
+  {
+    i = 0;
+    while (NULL != sctx->addrs[i])
+      GNUNET_free (sctx->addrs[i++]);
+    GNUNET_free (sctx->addrs);
+  }
+  GNUNET_free_non_null (sctx->addrlens);
+  GNUNET_free_non_null (sctx->v4_denied);
+  GNUNET_free_non_null (sctx->v6_denied);
+  GNUNET_free_non_null (sctx->v4_allowed);
+  GNUNET_free_non_null (sctx->v6_allowed);
+  GNUNET_free (sctx);
+}
+
+
+/* end of service.c */
index be79d54992fffc5f3ff5714076836e8560e27cc3..1d92588ea2672a56302def669c1758334797e881 100644 (file)
@@ -552,7 +552,7 @@ setup_plugin_environment ()
 
 
 static int
-handle_helper_message (void *cls, void *client,
+handle_helper_message (void *cls,
                        const struct GNUNET_MessageHeader *hdr)
 {
   return GNUNET_OK;
index df319fe7792b247755dd96091b1a9d311e6d6428..4418fcfeea87ee6290fe08d91f24a24507aaea21 100644 (file)
@@ -68,7 +68,6 @@ libgnunetutil_la_SOURCES = \
   common_logging.c \
   configuration.c \
   configuration_loader.c \
-  connection.c \
   container_bloomfilter.c \
   container_heap.c \
   container_meta_data.c \
@@ -108,16 +107,10 @@ libgnunetutil_la_SOURCES = \
   program.c \
   resolver_api.c resolver.h \
   scheduler.c \
-  server.c \
-  server_mst.c \
-  server_nc.c \
-  server_tc.c \
-  service.c \
   service_new.c \
   signal.c \
   strings.c \
   time.c \
-  socks.c \
   speedup.c speedup.h
 
 libgnunetutil_la_LIBADD = \
@@ -263,14 +256,13 @@ if HAVE_BENCHMARKS
 endif
 
 if HAVE_SSH_KEY
- SSH_USING_TESTS = test_socks.nc
+# SSH_USING_TESTS = test_socks.nc
 endif
 
 check_PROGRAMS = \
  test_bio \
  test_client.nc \
  $(TEST_CLIENT_UNIX_NC) \
- $(SSH_USING_TESTS) \
  test_common_allocation \
  test_common_endian \
  test_common_logging \
@@ -298,12 +290,6 @@ check_PROGRAMS = \
  test_crypto_rsa \
  test_disk \
  test_getopt \
- test_connection.nc \
- test_connection_addressing.nc \
- test_connection_receive_cancel.nc \
- test_connection_timeout.nc \
- test_connection_timeout_no_connect.nc \
- test_connection_transmit_cancel.nc \
  test_mq \
  test_os_network \
  test_peer \
@@ -312,11 +298,6 @@ check_PROGRAMS = \
  test_resolver_api.nc \
  test_scheduler \
  test_scheduler_delay \
- test_server.nc \
- test_server_disconnect.nc \
- test_server_with_client.nc \
- test_server_mst_interrupt.nc \
- $(SERVER_CLIENT_UNIX) \
  test_service \
  test_strings \
  test_strings_to_data \
@@ -337,11 +318,6 @@ test_connection_transmit_cancel.log: test_connection_timeout_no_connect.log
 test_connection_receive_cancel.log: test_connection_transmit_cancel.log
 test_connection_timeout.log: test_connection_receive_cancel.log
 test_resolver_api.log: test_connection_timeout.log
-test_server.log: test_resolver_api.log
-test_server_disconnect.log: test_server.log
-test_server_with_client.log: test_server_disconnect.log
-test_server_mst_interrupt.log: test_server_with_client.log
-test_client_unix.log: test_server_mst_interrupt.log
 
 test_bio_SOURCES = \
  test_bio.c
@@ -518,36 +494,6 @@ test_getopt_SOURCES = \
 test_getopt_LDADD = \
  libgnunetutil.la
 
-test_connection_nc_SOURCES = \
- test_connection.c
-test_connection_nc_LDADD = \
- libgnunetutil.la
-
-test_connection_addressing_nc_SOURCES = \
- test_connection_addressing.c
-test_connection_addressing_nc_LDADD = \
- libgnunetutil.la
-
-test_connection_receive_cancel_nc_SOURCES = \
- test_connection_receive_cancel.c
-test_connection_receive_cancel_nc_LDADD = \
- libgnunetutil.la
-
-test_connection_timeout_nc_SOURCES = \
- test_connection_timeout.c
-test_connection_timeout_nc_LDADD = \
- libgnunetutil.la
-
-test_connection_timeout_no_connect_nc_SOURCES = \
- test_connection_timeout_no_connect.c
-test_connection_timeout_no_connect_nc_LDADD = \
- libgnunetutil.la
-
-test_connection_transmit_cancel_nc_SOURCES = \
- test_connection_transmit_cancel.c
-test_connection_transmit_cancel_nc_LDADD = \
- libgnunetutil.la
-
 test_mq_SOURCES = \
  test_mq.c
 test_mq_LDADD = \
@@ -588,32 +534,6 @@ test_scheduler_delay_SOURCES = \
 test_scheduler_delay_LDADD = \
  libgnunetutil.la
 
-test_server_mst_interrupt_nc_SOURCES = \
- test_server_mst_interrupt.c
-test_server_mst_interrupt_nc_LDADD = \
- libgnunetutil.la
-
-test_server_nc_SOURCES = \
- test_server.c
-test_server_nc_LDADD = \
- libgnunetutil.la
-
-test_server_disconnect_nc_SOURCES = \
- test_server_disconnect.c
-test_server_disconnect_nc_LDADD = \
- libgnunetutil.la
-
-test_server_with_client_nc_SOURCES = \
- test_server_with_client.c
-test_server_with_client_nc_LDADD = \
- libgnunetutil.la
-
-test_server_with_client_unix_SOURCES = \
- test_server_with_client_unix.c
-test_server_with_client_unix_LDADD = \
- libgnunetutil.la
-
-
 test_service_SOURCES = \
  test_service.c
 test_service_LDADD = \
@@ -624,7 +544,6 @@ test_strings_SOURCES = \
 test_strings_LDADD = \
  libgnunetutil.la
 
-
 test_strings_to_data_SOURCES = \
  test_strings_to_data.c
 test_strings_to_data_LDADD = \
diff --git a/src/util/connection.c b/src/util/connection.c
deleted file mode 100644 (file)
index e822b26..0000000
+++ /dev/null
@@ -1,1648 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C) 2009-2013 GNUnet e.V.
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-
-/**
- * @file util/connection.c
- * @brief  TCP connection management
- * @author Christian Grothoff
- *
- * This code is rather complex.  Only modify it if you
- * 1) Have a NEW testcase showing that the new code
- *    is needed and correct
- * 2) All EXISTING testcases pass with the new code
- * These rules should apply in general, but for this
- * module they are VERY, VERY important.
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_resolver_service.h"
-
-
-#define LOG(kind,...) GNUNET_log_from (kind, "util-connection", __VA_ARGS__)
-
-#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-connection", syscall)
-
-
-/**
- * Transmission handle.  There can only be one for each connection.
- */
-struct GNUNET_CONNECTION_TransmitHandle
-{
-
-  /**
-   * Function to call if the send buffer has notify_size
-   * bytes available.
-   */
-  GNUNET_CONNECTION_TransmitReadyNotify notify_ready;
-
-  /**
-   * Closure for notify_ready.
-   */
-  void *notify_ready_cls;
-
-  /**
-   * Our connection handle.
-   */
-  struct GNUNET_CONNECTION_Handle *connection;
-
-  /**
-   * Timeout for receiving (in absolute time).
-   */
-  struct GNUNET_TIME_Absolute transmit_timeout;
-
-  /**
-   * Task called on timeout.
-   */
-  struct GNUNET_SCHEDULER_Task * timeout_task;
-
-  /**
-   * At what number of bytes available in the
-   * write buffer should the notify method be called?
-   */
-  size_t notify_size;
-
-};
-
-
-/**
- * During connect, we try multiple possible IP addresses
- * to find out which one might work.
- */
-struct AddressProbe
-{
-
-  /**
-   * This is a linked list.
-   */
-  struct AddressProbe *next;
-
-  /**
-   * This is a doubly-linked list.
-   */
-  struct AddressProbe *prev;
-
-  /**
-   * The address; do not free (allocated at the end of this struct).
-   */
-  const struct sockaddr *addr;
-
-  /**
-   * Underlying OS's socket.
-   */
-  struct GNUNET_NETWORK_Handle *sock;
-
-  /**
-   * Connection for which we are probing.
-   */
-  struct GNUNET_CONNECTION_Handle *connection;
-
-  /**
-   * Lenth of addr.
-   */
-  socklen_t addrlen;
-
-  /**
-   * Task waiting for the connection to finish connecting.
-   */
-  struct GNUNET_SCHEDULER_Task * task;
-};
-
-
-/**
- * @brief handle for a network connection
- */
-struct GNUNET_CONNECTION_Handle
-{
-
-  /**
-   * Configuration to use.
-   */
-  const struct GNUNET_CONFIGURATION_Handle *cfg;
-
-  /**
-   * Linked list of sockets we are currently trying out
-   * (during connect).
-   */
-  struct AddressProbe *ap_head;
-
-  /**
-   * Linked list of sockets we are currently trying out
-   * (during connect).
-   */
-  struct AddressProbe *ap_tail;
-
-  /**
-   * Network address of the other end-point, may be NULL.
-   */
-  struct sockaddr *addr;
-
-  /**
-   * Pointer to the hostname if connection was
-   * created using DNS lookup, otherwise NULL.
-   */
-  char *hostname;
-
-  /**
-   * Underlying OS's socket, set to NULL after fatal errors.
-   */
-  struct GNUNET_NETWORK_Handle *sock;
-
-  /**
-   * Function to call on data received, NULL if no receive is pending.
-   */
-  GNUNET_CONNECTION_Receiver receiver;
-
-  /**
-   * Closure for @e receiver.
-   */
-  void *receiver_cls;
-
-  /**
-   * Pointer to our write buffer.
-   */
-  char *write_buffer;
-
-  /**
-   * Current size of our @e write_buffer.
-   */
-  size_t write_buffer_size;
-
-  /**
-   * Current write-offset in @e write_buffer (where
-   * would we write next).
-   */
-  size_t write_buffer_off;
-
-  /**
-   * Current read-offset in @e write_buffer (how many
-   * bytes have already been sent).
-   */
-  size_t write_buffer_pos;
-
-  /**
-   * Length of @e addr.
-   */
-  socklen_t addrlen;
-
-  /**
-   * Read task that we may need to wait for.
-   */
-  struct GNUNET_SCHEDULER_Task *read_task;
-
-  /**
-   * Write task that we may need to wait for.
-   */
-  struct GNUNET_SCHEDULER_Task *write_task;
-
-  /**
-   * Handle to a pending DNS lookup request.
-   */
-  struct GNUNET_RESOLVER_RequestHandle *dns_active;
-
-  /**
-   * The handle we return for #GNUNET_CONNECTION_notify_transmit_ready().
-   */
-  struct GNUNET_CONNECTION_TransmitHandle nth;
-
-  /**
-   * Timeout for receiving (in absolute time).
-   */
-  struct GNUNET_TIME_Absolute receive_timeout;
-
-  /**
-   * Maximum number of bytes to read (for receiving).
-   */
-  size_t max;
-
-  /**
-   * Port to connect to.
-   */
-  uint16_t port;
-
-  /**
-   * When shutdown, do not ever actually close the socket, but
-   * free resources.  Only should ever be set if using program
-   * termination as a signal (because only then will the leaked
-   * socket be freed!)
-   */
-  int8_t persist;
-
-  /**
-   * Usually 0.  Set to 1 if this handle is in use, and should
-   * #GNUNET_CONNECTION_destroy() be called right now, the action needs
-   * to be deferred by setting it to -1.
-   */
-  int8_t destroy_later;
-
-  /**
-   * Handle to subsequent connection after proxy handshake completes,
-   */
-  struct GNUNET_CONNECTION_Handle *proxy_handshake;
-
-};
-
-
-/**
- * Set the persist option on this connection handle.  Indicates
- * that the underlying socket or fd should never really be closed.
- * Used for indicating process death.
- *
- * @param connection the connection to set persistent
- */
-void
-GNUNET_CONNECTION_persist_ (struct GNUNET_CONNECTION_Handle *connection)
-{
-  connection->persist = GNUNET_YES;
-}
-
-
-/**
- * Disable the "CORK" feature for communication with the given connection,
- * forcing the OS to immediately flush the buffer on transmission
- * instead of potentially buffering multiple messages.  Essentially
- * reduces the OS send buffers to zero.
- * Used to make sure that the last messages sent through the connection
- * reach the other side before the process is terminated.
- *
- * @param connection the connection to make flushing and blocking
- * @return #GNUNET_OK on success
- */
-int
-GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *connection)
-{
-  return GNUNET_NETWORK_socket_disable_corking (connection->sock);
-}
-
-
-/**
- * Create a connection handle by boxing an existing OS socket.  The OS
- * socket should henceforth be no longer used directly.
- * #GNUNET_connection_destroy() will close it.
- *
- * @param osSocket existing socket to box
- * @return the boxed connection handle
- */
-struct GNUNET_CONNECTION_Handle *
-GNUNET_CONNECTION_create_from_existing (struct GNUNET_NETWORK_Handle *osSocket)
-{
-  struct GNUNET_CONNECTION_Handle *connection;
-
-  connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
-  connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
-  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
-  connection->sock = osSocket;
-  return connection;
-}
-
-
-/**
- * Create a connection handle by accepting on a listen socket.  This
- * function may block if the listen socket has no connection ready.
- *
- * @param access_cb function to use to check if access is allowed
- * @param access_cb_cls closure for @a access_cb
- * @param lsock listen socket
- * @return the connection handle, NULL on error
- */
-struct GNUNET_CONNECTION_Handle *
-GNUNET_CONNECTION_create_from_accept (GNUNET_CONNECTION_AccessCheck access_cb,
-                                      void *access_cb_cls,
-                                      struct GNUNET_NETWORK_Handle *lsock)
-{
-  struct GNUNET_CONNECTION_Handle *connection;
-  char addr[128];
-  socklen_t addrlen;
-  struct GNUNET_NETWORK_Handle *sock;
-  int aret;
-  struct sockaddr_in *v4;
-  struct sockaddr_in6 *v6;
-  struct sockaddr *sa;
-  void *uaddr;
-#ifdef SO_PEERCRED
-  struct ucred uc;
-  socklen_t olen;
-#endif
-  struct GNUNET_CONNECTION_Credentials *gcp;
-#if HAVE_GETPEEREID || defined(SO_PEERCRED) || HAVE_GETPEERUCRED
-  struct GNUNET_CONNECTION_Credentials gc;
-
-  gc.uid = 0;
-  gc.gid = 0;
-#endif
-
-  addrlen = sizeof (addr);
-  sock =
-      GNUNET_NETWORK_socket_accept (lsock,
-                                   (struct sockaddr *) &addr,
-                                   &addrlen);
-  if (NULL == sock)
-  {
-    if (EAGAIN != errno)
-      LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "accept");
-    return NULL;
-  }
-  if ((addrlen > sizeof (addr)) || (addrlen < sizeof (sa_family_t)))
-  {
-    GNUNET_break (0);
-    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
-    return NULL;
-  }
-
-  sa = (struct sockaddr *) addr;
-  v6 = (struct sockaddr_in6 *) addr;
-  if ( (AF_INET6 == sa->sa_family) &&
-       (IN6_IS_ADDR_V4MAPPED (&v6->sin6_addr)) )
-  {
-    /* convert to V4 address */
-    v4 = GNUNET_new (struct sockaddr_in);
-    memset (v4, 0, sizeof (struct sockaddr_in));
-    v4->sin_family = AF_INET;
-#if HAVE_SOCKADDR_IN_SIN_LEN
-    v4->sin_len = (u_char) sizeof (struct sockaddr_in);
-#endif
-    GNUNET_memcpy (&v4->sin_addr,
-            &((char *) &v6->sin6_addr)[sizeof (struct in6_addr) -
-                                       sizeof (struct in_addr)],
-            sizeof (struct in_addr));
-    v4->sin_port = v6->sin6_port;
-    uaddr = v4;
-    addrlen = sizeof (struct sockaddr_in);
-  }
-  else
-  {
-    uaddr = GNUNET_malloc (addrlen);
-    GNUNET_memcpy (uaddr, addr, addrlen);
-  }
-  gcp = NULL;
-  if (AF_UNIX == sa->sa_family)
-  {
-#if HAVE_GETPEEREID
-    /* most BSDs */
-    if (0 == getpeereid (GNUNET_NETWORK_get_fd (sock),
-                        &gc.uid,
-                        &gc.gid))
-      gcp = &gc;
-#else
-#ifdef SO_PEERCRED
-    /* largely traditional GNU/Linux */
-    olen = sizeof (uc);
-    if ( (0 ==
-         getsockopt (GNUNET_NETWORK_get_fd (sock),
-                     SOL_SOCKET,
-                     SO_PEERCRED,
-                     &uc,
-                     &olen)) &&
-        (olen == sizeof (uc)) )
-    {
-      gc.uid = uc.uid;
-      gc.gid = uc.gid;
-      gcp = &gc;
-    }
-#else
-#if HAVE_GETPEERUCRED
-    /* this is for Solaris 10 */
-    ucred_t *uc;
-
-    uc = NULL;
-    if (0 == getpeerucred (GNUNET_NETWORK_get_fd (sock), &uc))
-    {
-      gc.uid = ucred_geteuid (uc);
-      gc.gid = ucred_getegid (uc);
-      gcp = &gc;
-    }
-    ucred_free (uc);
-#endif
-#endif
-#endif
-  }
-
-  if ( (NULL != access_cb) &&
-       (GNUNET_YES != (aret = access_cb (access_cb_cls,
-                                        gcp,
-                                        uaddr,
-                                        addrlen))) )
-  {
-    if (GNUNET_NO == aret)
-      LOG (GNUNET_ERROR_TYPE_INFO,
-           _("Access denied to `%s'\n"),
-           GNUNET_a2s (uaddr,
-                       addrlen));
-    GNUNET_break (GNUNET_OK ==
-                  GNUNET_NETWORK_socket_shutdown (sock,
-                                                  SHUT_RDWR));
-    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
-    GNUNET_free (uaddr);
-    return NULL;
-  }
-  connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
-  connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
-  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
-  connection->addr = uaddr;
-  connection->addrlen = addrlen;
-  connection->sock = sock;
-  LOG (GNUNET_ERROR_TYPE_INFO,
-       _("Accepting connection from `%s': %p\n"),
-       GNUNET_a2s (uaddr,
-                  addrlen),
-       connection);
-  return connection;
-}
-
-
-/**
- * Obtain the network address of the other party.
- *
- * @param connection the client to get the address for
- * @param addr where to store the address
- * @param addrlen where to store the length of the @a addr
- * @return #GNUNET_OK on success
- */
-int
-GNUNET_CONNECTION_get_address (struct GNUNET_CONNECTION_Handle *connection,
-                               void **addr,
-                               size_t *addrlen)
-{
-  if ((NULL == connection->addr) || (0 == connection->addrlen))
-    return GNUNET_NO;
-  *addr = GNUNET_malloc (connection->addrlen);
-  GNUNET_memcpy (*addr, connection->addr, connection->addrlen);
-  *addrlen = connection->addrlen;
-  return GNUNET_OK;
-}
-
-
-/**
- * Tell the receiver callback that we had an IO error.
- *
- * @param connection connection to signal error
- * @param errcode error code to send
- */
-static void
-signal_receive_error (struct GNUNET_CONNECTION_Handle *connection,
-                      int errcode)
-{
-  GNUNET_CONNECTION_Receiver receiver;
-
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Receive encounters error (%s), connection closed (%p)\n",
-       STRERROR (errcode),
-       connection);
-  GNUNET_assert (NULL != (receiver = connection->receiver));
-  connection->receiver = NULL;
-  receiver (connection->receiver_cls,
-            NULL,
-            0,
-            connection->addr,
-            connection->addrlen,
-            errcode);
-}
-
-
-/**
- * Tell the receiver callback that a timeout was reached.
- *
- * @param connection connection to signal for
- */
-static void
-signal_receive_timeout (struct GNUNET_CONNECTION_Handle *connection)
-{
-  GNUNET_CONNECTION_Receiver receiver;
-
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Connection signals timeout to receiver (%p)!\n",
-       connection);
-  GNUNET_assert (NULL != (receiver = connection->receiver));
-  connection->receiver = NULL;
-  receiver (connection->receiver_cls, NULL, 0, NULL, 0, 0);
-}
-
-
-/**
- * We failed to transmit data to the service, signal the error.
- *
- * @param connection handle that had trouble
- * @param ecode error code (errno)
- */
-static void
-signal_transmit_error (struct GNUNET_CONNECTION_Handle *connection,
-                      int ecode)
-{
-  GNUNET_CONNECTION_TransmitReadyNotify notify;
-
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Transmission encounterd error (%s), connection closed (%p)\n",
-       STRERROR (ecode),
-       connection);
-  if (NULL != connection->sock)
-  {
-    (void) GNUNET_NETWORK_socket_shutdown (connection->sock,
-                                           SHUT_RDWR);
-    GNUNET_break (GNUNET_OK ==
-                  GNUNET_NETWORK_socket_close (connection->sock));
-    connection->sock = NULL;
-    GNUNET_assert (NULL == connection->write_task);
-  }
-  if (NULL != connection->read_task)
-  {
-    /* send errors trigger read errors... */
-    GNUNET_SCHEDULER_cancel (connection->read_task);
-    connection->read_task = NULL;
-    signal_receive_timeout (connection);
-    return;
-  }
-  if (NULL == connection->nth.notify_ready)
-    return;                     /* nobody to tell about it */
-  notify = connection->nth.notify_ready;
-  connection->nth.notify_ready = NULL;
-  notify (connection->nth.notify_ready_cls,
-         0,
-         NULL);
-}
-
-
-/**
- * We've failed for good to establish a connection (timeout or
- * no more addresses to try).
- *
- * @param connection the connection we tried to establish
- */
-static void
-connect_fail_continuation (struct GNUNET_CONNECTION_Handle *connection)
-{
-  LOG (GNUNET_ERROR_TYPE_INFO,
-       "Failed to establish TCP connection to `%s:%u', no further addresses to try.\n",
-       connection->hostname,
-    connection->port);
-  GNUNET_break (NULL == connection->ap_head);
-  GNUNET_break (NULL == connection->ap_tail);
-  GNUNET_break (GNUNET_NO == connection->dns_active);
-  GNUNET_break (NULL == connection->sock);
-  GNUNET_assert (NULL == connection->write_task);
-  GNUNET_assert (NULL == connection->proxy_handshake);
-
-  /* signal errors for jobs that used to wait on the connection */
-  connection->destroy_later = 1;
-  if (NULL != connection->receiver)
-    signal_receive_error (connection,
-                          ECONNREFUSED);
-  if (NULL != connection->nth.notify_ready)
-  {
-    GNUNET_assert (NULL != connection->nth.timeout_task);
-    GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
-    connection->nth.timeout_task = NULL;
-    signal_transmit_error (connection,
-                           ECONNREFUSED);
-  }
-  if (-1 == connection->destroy_later)
-  {
-    /* do it now */
-    connection->destroy_later = 0;
-    GNUNET_CONNECTION_destroy (connection);
-    return;
-  }
-  connection->destroy_later = 0;
-}
-
-
-/**
- * We are ready to transmit (or got a timeout).
- *
- * @param cls our connection handle
- */
-static void
-transmit_ready (void *cls);
-
-
-/**
- * This function is called once we either timeout or have data ready
- * to read.
- *
- * @param cls connection to read from
- */
-static void
-receive_ready (void *cls);
-
-
-/**
- * We've succeeded in establishing a connection.
- *
- * @param connection the connection we tried to establish
- */
-static void
-connect_success_continuation (struct GNUNET_CONNECTION_Handle *connection)
-{
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Connection to `%s' succeeded! (%p)\n",
-       GNUNET_a2s (connection->addr,
-                  connection->addrlen),
-       connection);
-  /* trigger jobs that waited for the connection */
-  if (NULL != connection->receiver)
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Connection succeeded, starting with receiving data (%p)\n",
-        connection);
-    GNUNET_assert (NULL == connection->read_task);
-    connection->read_task =
-      GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining
-                                     (connection->receive_timeout),
-                                    connection->sock,
-                                     &receive_ready, connection);
-  }
-  if (NULL != connection->nth.notify_ready)
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Connection succeeded, starting with sending data (%p)\n",
-         connection);
-    GNUNET_assert (connection->nth.timeout_task != NULL);
-    GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
-    connection->nth.timeout_task = NULL;
-    GNUNET_assert (connection->write_task == NULL);
-    connection->write_task =
-        GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining
-                                        (connection->nth.transmit_timeout), connection->sock,
-                                        &transmit_ready, connection);
-  }
-}
-
-
-/**
- * Scheduler let us know that we're either ready to write on the
- * socket OR connect timed out.  Do the right thing.
- *
- * @param cls the `struct AddressProbe *` with the address that we are probing
- */
-static void
-connect_probe_continuation (void *cls)
-{
-  struct AddressProbe *ap = cls;
-  struct GNUNET_CONNECTION_Handle *connection = ap->connection;
-  const struct GNUNET_SCHEDULER_TaskContext *tc;
-  struct AddressProbe *pos;
-  int error;
-  socklen_t len;
-
-  GNUNET_assert (NULL != ap->sock);
-  GNUNET_CONTAINER_DLL_remove (connection->ap_head,
-                              connection->ap_tail,
-                              ap);
-  len = sizeof (error);
-  errno = 0;
-  error = 0;
-  tc = GNUNET_SCHEDULER_get_task_context ();
-  if ( (0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ||
-       (GNUNET_OK !=
-       GNUNET_NETWORK_socket_getsockopt (ap->sock,
-                                         SOL_SOCKET,
-                                         SO_ERROR,
-                                         &error,
-                                         &len)) ||
-       (0 != error) )
-  {
-    GNUNET_break (GNUNET_OK ==
-                 GNUNET_NETWORK_socket_close (ap->sock));
-    GNUNET_free (ap);
-    if ( (NULL == connection->ap_head) &&
-        (GNUNET_NO == connection->dns_active) &&
-        (NULL == connection->proxy_handshake) )
-      connect_fail_continuation (connection);
-    return;
-  }
-  GNUNET_assert (NULL == connection->sock);
-  connection->sock = ap->sock;
-  GNUNET_assert (NULL == connection->addr);
-  connection->addr = GNUNET_malloc (ap->addrlen);
-  GNUNET_memcpy (connection->addr, ap->addr, ap->addrlen);
-  connection->addrlen = ap->addrlen;
-  GNUNET_free (ap);
-  /* cancel all other attempts */
-  while (NULL != (pos = connection->ap_head))
-  {
-    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock));
-    GNUNET_SCHEDULER_cancel (pos->task);
-    GNUNET_CONTAINER_DLL_remove (connection->ap_head,
-                                connection->ap_tail,
-                                pos);
-    GNUNET_free (pos);
-  }
-  connect_success_continuation (connection);
-}
-
-
-/**
- * Try to establish a connection given the specified address.
- * This function is called by the resolver once we have a DNS reply.
- *
- * @param cls our `struct GNUNET_CONNECTION_Handle *`
- * @param addr address to try, NULL for "last call"
- * @param addrlen length of @a addr
- */
-static void
-try_connect_using_address (void *cls,
-                           const struct sockaddr *addr,
-                           socklen_t addrlen)
-{
-  struct GNUNET_CONNECTION_Handle *connection = cls;
-  struct AddressProbe *ap;
-  struct GNUNET_TIME_Relative delay;
-
-  if (NULL == addr)
-  {
-    connection->dns_active = NULL;
-    if ((NULL == connection->ap_head) &&
-        (NULL == connection->sock) &&
-        (NULL == connection->proxy_handshake))
-      connect_fail_continuation (connection);
-    return;
-  }
-  if (NULL != connection->sock)
-    return;                     /* already connected */
-  GNUNET_assert (NULL == connection->addr);
-  /* try to connect */
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Trying to connect using address `%s:%u/%s:%u'\n",
-       connection->hostname,
-       connection->port,
-       GNUNET_a2s (addr, addrlen),
-       connection->port);
-  ap = GNUNET_malloc (sizeof (struct AddressProbe) + addrlen);
-  ap->addr = (const struct sockaddr *) &ap[1];
-  GNUNET_memcpy (&ap[1], addr, addrlen);
-  ap->addrlen = addrlen;
-  ap->connection = connection;
-
-  switch (ap->addr->sa_family)
-  {
-  case AF_INET:
-    ((struct sockaddr_in *) ap->addr)->sin_port = htons (connection->port);
-    break;
-  case AF_INET6:
-    ((struct sockaddr_in6 *) ap->addr)->sin6_port = htons (connection->port);
-    break;
-  default:
-    GNUNET_break (0);
-    GNUNET_free (ap);
-    return;                     /* not supported by us */
-  }
-  ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family,
-                                          SOCK_STREAM, 0);
-  if (NULL == ap->sock)
-  {
-    GNUNET_free (ap);
-    return;                     /* not supported by OS */
-  }
-  LOG (GNUNET_ERROR_TYPE_INFO,
-       "Trying to connect to `%s' (%p)\n",
-       GNUNET_a2s (ap->addr, ap->addrlen),
-       connection);
-  if ((GNUNET_OK !=
-       GNUNET_NETWORK_socket_connect (ap->sock,
-                                     ap->addr,
-                                     ap->addrlen)) &&
-      (EINPROGRESS != errno))
-  {
-    /* maybe refused / unsupported address, try next */
-    LOG_STRERROR (GNUNET_ERROR_TYPE_INFO, "connect");
-    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock));
-    GNUNET_free (ap);
-    return;
-  }
-  GNUNET_CONTAINER_DLL_insert (connection->ap_head, connection->ap_tail, ap);
-  delay = GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT;
-  if (NULL != connection->nth.notify_ready)
-    delay = GNUNET_TIME_relative_min (delay,
-                                     GNUNET_TIME_absolute_get_remaining (connection->nth.transmit_timeout));
-  if (NULL != connection->receiver)
-    delay = GNUNET_TIME_relative_min (delay,
-                                     GNUNET_TIME_absolute_get_remaining (connection->receive_timeout));
-  ap->task = GNUNET_SCHEDULER_add_write_net (delay,
-                                            ap->sock,
-                                            &connect_probe_continuation,
-                                            ap);
-}
-
-
-/**
- * Create a connection handle by (asynchronously) connecting to a host.
- * This function returns immediately, even if the connection has not
- * yet been established.  This function only creates TCP connections.
- *
- * @param cfg configuration to use
- * @param hostname name of the host to connect to
- * @param port port to connect to
- * @return the connection handle
- */
-struct GNUNET_CONNECTION_Handle *
-GNUNET_CONNECTION_create_from_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
-                                       const char *hostname,
-                                       uint16_t port)
-{
-  struct GNUNET_CONNECTION_Handle *connection;
-
-  GNUNET_assert (0 < strlen (hostname));        /* sanity check */
-  connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
-  connection->cfg = cfg;
-  connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
-  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
-  connection->port = port;
-  connection->hostname = GNUNET_strdup (hostname);
-  connection->dns_active =
-      GNUNET_RESOLVER_ip_get (connection->hostname,
-                             AF_UNSPEC,
-                              GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT,
-                              &try_connect_using_address,
-                             connection);
-  return connection;
-}
-
-
-/**
- * Create a connection handle by connecting to a UNIX domain service.
- * This function returns immediately, even if the connection has not
- * yet been established.  This function only creates UNIX connections.
- *
- * @param cfg configuration to use
- * @param unixpath path to connect to
- * @return the connection handle, NULL on systems without UNIX support
- */
-struct GNUNET_CONNECTION_Handle *
-GNUNET_CONNECTION_create_from_connect_to_unixpath (const struct GNUNET_CONFIGURATION_Handle *cfg,
-                                                   const char *unixpath)
-{
-#ifdef AF_UNIX
-  struct GNUNET_CONNECTION_Handle *connection;
-  struct sockaddr_un *un;
-
-  GNUNET_assert (0 < strlen (unixpath));        /* sanity check */
-  un = GNUNET_new (struct sockaddr_un);
-  un->sun_family = AF_UNIX;
-  strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1);
-#ifdef LINUX
-  {
-    int abstract;
-
-    abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
-                                                    "TESTING",
-                                                     "USE_ABSTRACT_SOCKETS");
-    if (GNUNET_YES == abstract)
-      un->sun_path[0] = '\0';
-  }
-#endif
-#if HAVE_SOCKADDR_UN_SUN_LEN
-  un->sun_len = (u_char) sizeof (struct sockaddr_un);
-#endif
-  connection = GNUNET_new (struct GNUNET_CONNECTION_Handle);
-  connection->cfg = cfg;
-  connection->write_buffer_size = GNUNET_SERVER_MIN_BUFFER_SIZE;
-  connection->write_buffer = GNUNET_malloc (connection->write_buffer_size);
-  connection->port = 0;
-  connection->hostname = NULL;
-  connection->addr = (struct sockaddr *) un;
-  connection->addrlen = sizeof (struct sockaddr_un);
-  connection->sock = GNUNET_NETWORK_socket_create (AF_UNIX,
-                                                  SOCK_STREAM,
-                                                  0);
-  if (NULL == connection->sock)
-  {
-    GNUNET_free (connection->addr);
-    GNUNET_free (connection->write_buffer);
-    GNUNET_free (connection);
-    return NULL;
-  }
-  if ( (GNUNET_OK !=
-       GNUNET_NETWORK_socket_connect (connection->sock,
-                                      connection->addr,
-                                      connection->addrlen)) &&
-       (EINPROGRESS != errno) )
-  {
-    /* Just return; we expect everything to work eventually so don't fail HARD */
-    GNUNET_break (GNUNET_OK ==
-                 GNUNET_NETWORK_socket_close (connection->sock));
-    connection->sock = NULL;
-    return connection;
-  }
-  connect_success_continuation (connection);
-  return connection;
-#else
-  return NULL;
-#endif
-}
-
-
-/**
- * Create a connection handle by (asynchronously) connecting to a host.
- * This function returns immediately, even if the connection has not
- * yet been established.  This function only creates TCP connections.
- *
- * @param s socket to connect
- * @param serv_addr server address
- * @param addrlen length of @a serv_addr
- * @return the connection handle
- */
-struct GNUNET_CONNECTION_Handle *
-GNUNET_CONNECTION_connect_socket (struct GNUNET_NETWORK_Handle *s,
-                                  const struct sockaddr *serv_addr,
-                                  socklen_t addrlen)
-{
-  struct GNUNET_CONNECTION_Handle *connection;
-
-  if ( (GNUNET_OK !=
-        GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) &&
-       (EINPROGRESS != errno) )
-  {
-    /* maybe refused / unsupported address, try next */
-    LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG,
-                  "connect");
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Attempt to connect to `%s' failed\n",
-         GNUNET_a2s (serv_addr,
-                     addrlen));
-    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s));
-    return NULL;
-  }
-  connection = GNUNET_CONNECTION_create_from_existing (s);
-  connection->addr = GNUNET_malloc (addrlen);
-  GNUNET_memcpy (connection->addr, serv_addr, addrlen);
-  connection->addrlen = addrlen;
-  LOG (GNUNET_ERROR_TYPE_INFO,
-       "Trying to connect to `%s' (%p)\n",
-       GNUNET_a2s (serv_addr, addrlen),
-       connection);
-  return connection;
-}
-
-
-/**
- * Create a connection handle by creating a socket and
- * (asynchronously) connecting to a host.  This function returns
- * immediately, even if the connection has not yet been established.
- * This function only creates TCP connections.
- *
- * @param af_family address family to use
- * @param serv_addr server address
- * @param addrlen length of @a serv_addr
- * @return the connection handle
- */
-struct GNUNET_CONNECTION_Handle *
-GNUNET_CONNECTION_create_from_sockaddr (int af_family,
-                                        const struct sockaddr *serv_addr,
-                                        socklen_t addrlen)
-{
-  struct GNUNET_NETWORK_Handle *s;
-
-  s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0);
-  if (NULL == s)
-  {
-    LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
-                 "socket");
-    return NULL;
-  }
-  return GNUNET_CONNECTION_connect_socket (s,
-                                          serv_addr,
-                                          addrlen);
-}
-
-
-/**
- * Check if connection is valid (no fatal errors have happened so far).
- * Note that a connection that is still trying to connect is considered
- * valid.
- *
- * @param connection connection to check
- * @return #GNUNET_YES if valid, #GNUNET_NO otherwise
- */
-int
-GNUNET_CONNECTION_check (struct GNUNET_CONNECTION_Handle *connection)
-{
-  if ((NULL != connection->ap_head) ||
-      (NULL != connection->dns_active) ||
-      (NULL != connection->proxy_handshake))
-    return GNUNET_YES;          /* still trying to connect */
-  if ( (0 != connection->destroy_later) ||
-       (NULL == connection->sock) )
-    return GNUNET_NO;
-  return GNUNET_YES;
-}
-
-
-/**
- * Close the connection and free associated resources.  There must
- * not be any pending requests for reading or writing to the
- * connection at this time.
- *
- * @param connection connection to destroy
- */
-void
-GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *connection)
-{
-  struct AddressProbe *pos;
-
-  if (0 != connection->destroy_later)
-  {
-    connection->destroy_later = -1;
-    return;
-  }
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Shutting down connection (%p)\n",
-       connection);
-  GNUNET_assert (NULL == connection->nth.notify_ready);
-  GNUNET_assert (NULL == connection->receiver);
-  if (NULL != connection->write_task)
-  {
-    GNUNET_SCHEDULER_cancel (connection->write_task);
-    connection->write_task = NULL;
-    connection->write_buffer_off = 0;
-  }
-  if (NULL != connection->read_task)
-  {
-    GNUNET_SCHEDULER_cancel (connection->read_task);
-    connection->read_task = NULL;
-  }
-  if (NULL != connection->nth.timeout_task)
-  {
-    GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
-    connection->nth.timeout_task = NULL;
-  }
-  connection->nth.notify_ready = NULL;
-  if (NULL != connection->dns_active)
-  {
-    GNUNET_RESOLVER_request_cancel (connection->dns_active);
-    connection->dns_active = NULL;
-  }
-  if (NULL != connection->proxy_handshake)
-  {
-    /* GNUNET_CONNECTION_destroy (connection->proxy_handshake); */
-    connection->proxy_handshake->destroy_later = -1;
-    connection->proxy_handshake = NULL;  /* Not leaked ??? */
-  }
-  while (NULL != (pos = connection->ap_head))
-  {
-    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (pos->sock));
-    GNUNET_SCHEDULER_cancel (pos->task);
-    GNUNET_CONTAINER_DLL_remove (connection->ap_head,
-                                connection->ap_tail,
-                                pos);
-    GNUNET_free (pos);
-  }
-  if ( (NULL != connection->sock) &&
-       (GNUNET_YES != connection->persist) )
-  {
-    if ((GNUNET_OK !=
-         GNUNET_NETWORK_socket_shutdown (connection->sock,
-                                         SHUT_RDWR)) &&
-       (ENOTCONN != errno) &&
-       (ECONNRESET != errno) )
-      LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING,
-                    "shutdown");
-  }
-  if (NULL != connection->sock)
-  {
-    if (GNUNET_YES != connection->persist)
-    {
-      GNUNET_break (GNUNET_OK ==
-                    GNUNET_NETWORK_socket_close (connection->sock));
-    }
-    else
-    {
-      GNUNET_NETWORK_socket_free_memory_only_ (connection->sock); /* at least no memory leak (we deliberately
-                                                                  * leak the socket in this special case) ... */
-    }
-  }
-  GNUNET_free_non_null (connection->addr);
-  GNUNET_free_non_null (connection->hostname);
-  GNUNET_free (connection->write_buffer);
-  GNUNET_free (connection);
-}
-
-
-/**
- * This function is called once we either timeout
- * or have data ready to read.
- *
- * @param cls connection to read from
- */
-static void
-receive_ready (void *cls)
-{
-  struct GNUNET_CONNECTION_Handle *connection = cls;
-  const struct GNUNET_SCHEDULER_TaskContext *tc;
-  char buffer[connection->max];
-  ssize_t ret;
-  GNUNET_CONNECTION_Receiver receiver;
-
-  connection->read_task = NULL;
-  tc = GNUNET_SCHEDULER_get_task_context ();
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-        "Receive from `%s' encounters error: timeout (%s, %p)\n",
-        GNUNET_a2s (connection->addr,
-                    connection->addrlen),
-        GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (connection->receive_timeout),
-                                                GNUNET_YES),
-        connection);
-    signal_receive_timeout (connection);
-    return;
-  }
-  if (NULL == connection->sock)
-  {
-    /* connect failed for good */
-    signal_receive_error (connection, ECONNREFUSED);
-    return;
-  }
-  GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready,
-                                            connection->sock));
-RETRY:
-  ret = GNUNET_NETWORK_socket_recv (connection->sock,
-                                    buffer,
-                                    connection->max);
-  if (-1 == ret)
-  {
-    if (EINTR == errno)
-      goto RETRY;
-    signal_receive_error (connection, errno);
-    return;
-  }
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "receive_ready read %u/%u bytes from `%s' (%p)!\n",
-       (unsigned int) ret,
-       connection->max,
-       GNUNET_a2s (connection->addr,
-                   connection->addrlen),
-       connection);
-  GNUNET_assert (NULL != (receiver = connection->receiver));
-  connection->receiver = NULL;
-  receiver (connection->receiver_cls,
-            buffer,
-            ret,
-            connection->addr,
-            connection->addrlen,
-            0);
-}
-
-
-/**
- * Receive data from the given connection.  Note that this function
- * will call @a receiver asynchronously using the scheduler.  It will
- * "immediately" return.  Note that there MUST only be one active
- * receive call per connection at any given point in time (so do not
- * call receive again until the receiver callback has been invoked).
- *
- * @param connection connection handle
- * @param max maximum number of bytes to read
- * @param timeout maximum amount of time to wait
- * @param receiver function to call with received data
- * @param receiver_cls closure for @a receiver
- */
-void
-GNUNET_CONNECTION_receive (struct GNUNET_CONNECTION_Handle *connection,
-                           size_t max,
-                           struct GNUNET_TIME_Relative timeout,
-                           GNUNET_CONNECTION_Receiver receiver,
-                           void *receiver_cls)
-{
-  GNUNET_assert ((NULL == connection->read_task) &&
-                 (NULL == connection->receiver));
-  GNUNET_assert (NULL != receiver);
-  connection->receiver = receiver;
-  connection->receiver_cls = receiver_cls;
-  connection->receive_timeout = GNUNET_TIME_relative_to_absolute (timeout);
-  connection->max = max;
-  if (NULL != connection->sock)
-  {
-    connection->read_task =
-      GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_absolute_get_remaining
-                                     (connection->receive_timeout),
-                                     connection->sock,
-                                     &receive_ready,
-                                     connection);
-    return;
-  }
-  if ((NULL == connection->dns_active) &&
-      (NULL == connection->ap_head) &&
-      (NULL == connection->proxy_handshake))
-  {
-    connection->receiver = NULL;
-    receiver (receiver_cls,
-             NULL, 0,
-             NULL, 0,
-             ETIMEDOUT);
-    return;
-  }
-}
-
-
-/**
- * Cancel receive job on the given connection.  Note that the
- * receiver callback must not have been called yet in order
- * for the cancellation to be valid.
- *
- * @param connection connection handle
- * @return closure of the original receiver callback closure
- */
-void *
-GNUNET_CONNECTION_receive_cancel (struct GNUNET_CONNECTION_Handle *connection)
-{
-  if (NULL != connection->read_task)
-  {
-    GNUNET_assert (connection ==
-                   GNUNET_SCHEDULER_cancel (connection->read_task));
-    connection->read_task = NULL;
-  }
-  connection->receiver = NULL;
-  return connection->receiver_cls;
-}
-
-
-/**
- * Try to call the transmit notify method (check if we do
- * have enough space available first)!
- *
- * @param connection connection for which we should do this processing
- * @return #GNUNET_YES if we were able to call notify
- */
-static int
-process_notify (struct GNUNET_CONNECTION_Handle *connection)
-{
-  size_t used;
-  size_t avail;
-  size_t size;
-  GNUNET_CONNECTION_TransmitReadyNotify notify;
-
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "process_notify is running\n");
-  GNUNET_assert (NULL == connection->write_task);
-  if (NULL == (notify = connection->nth.notify_ready))
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "No one to notify\n");
-    return GNUNET_NO;
-  }
-  used = connection->write_buffer_off - connection->write_buffer_pos;
-  avail = connection->write_buffer_size - used;
-  size = connection->nth.notify_size;
-  if (size > avail)
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Not enough buffer\n");
-    return GNUNET_NO;
-  }
-  connection->nth.notify_ready = NULL;
-  if (connection->write_buffer_size - connection->write_buffer_off < size)
-  {
-    /* need to compact */
-    memmove (connection->write_buffer,
-             &connection->write_buffer[connection->write_buffer_pos],
-             used);
-    connection->write_buffer_off -= connection->write_buffer_pos;
-    connection->write_buffer_pos = 0;
-  }
-  avail = connection->write_buffer_size - connection->write_buffer_off;
-  GNUNET_assert (avail >= size);
-  size =
-      notify (connection->nth.notify_ready_cls, avail,
-              &connection->write_buffer[connection->write_buffer_off]);
-  GNUNET_assert (size <= avail);
-  if (0 != size)
-    connection->write_buffer_off += size;
-  return GNUNET_YES;
-}
-
-
-/**
- * Task invoked by the scheduler when a call to transmit
- * is timing out (we never got enough buffer space to call
- * the callback function before the specified timeout
- * expired).
- *
- * This task notifies the client about the timeout.
- *
- * @param cls the `struct GNUNET_CONNECTION_Handle`
- */
-static void
-transmit_timeout (void *cls)
-{
-  struct GNUNET_CONNECTION_Handle *connection = cls;
-  GNUNET_CONNECTION_TransmitReadyNotify notify;
-
-  connection->nth.timeout_task = NULL;
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Transmit to `%s:%u/%s' fails, time out reached (%p).\n",
-       connection->hostname,
-       connection->port,
-       GNUNET_a2s (connection->addr,
-                   connection->addrlen),
-       connection);
-  notify = connection->nth.notify_ready;
-  GNUNET_assert (NULL != notify);
-  connection->nth.notify_ready = NULL;
-  notify (connection->nth.notify_ready_cls,
-         0,
-         NULL);
-}
-
-
-/**
- * Task invoked by the scheduler when we failed to connect
- * at the time of being asked to transmit.
- *
- * This task notifies the client about the error.
- *
- * @param cls the `struct GNUNET_CONNECTION_Handle`
- */
-static void
-connect_error (void *cls)
-{
-  struct GNUNET_CONNECTION_Handle *connection = cls;
-  GNUNET_CONNECTION_TransmitReadyNotify notify;
-
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Transmission request of size %u fails (%s/%u), connection failed (%p).\n",
-       connection->nth.notify_size,
-       connection->hostname,
-       connection->port,
-       connection);
-  connection->write_task = NULL;
-  notify = connection->nth.notify_ready;
-  connection->nth.notify_ready = NULL;
-  notify (connection->nth.notify_ready_cls,
-         0,
-         NULL);
-}
-
-
-/**
- * We are ready to transmit (or got a timeout).
- *
- * @param cls our connection handle
- */
-static void
-transmit_ready (void *cls)
-{
-  struct GNUNET_CONNECTION_Handle *connection = cls;
-  GNUNET_CONNECTION_TransmitReadyNotify notify;
-  const struct GNUNET_SCHEDULER_TaskContext *tc;
-  ssize_t ret;
-  size_t have;
-
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "transmit_ready running (%p).\n",
-       connection);
-  GNUNET_assert (NULL != connection->write_task);
-  connection->write_task = NULL;
-  GNUNET_assert (NULL == connection->nth.timeout_task);
-  tc = GNUNET_SCHEDULER_get_task_context ();
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Transmit to `%s' fails, time out reached (%p).\n",
-         GNUNET_a2s (connection->addr,
-                     connection->addrlen),
-         connection);
-    notify = connection->nth.notify_ready;
-    GNUNET_assert (NULL != notify);
-    connection->nth.notify_ready = NULL;
-    notify (connection->nth.notify_ready_cls, 0, NULL);
-    return;
-  }
-  GNUNET_assert (NULL != connection->sock);
-  if (NULL == tc->write_ready)
-  {
-    /* special circumstances (in particular, PREREQ_DONE after
-     * connect): not yet ready to write, but no "fatal" error either.
-     * Hence retry.  */
-    goto SCHEDULE_WRITE;
-  }
-  if (! GNUNET_NETWORK_fdset_isset (tc->write_ready,
-                                   connection->sock))
-  {
-    GNUNET_assert (NULL == connection->write_task);
-    /* special circumstances (in particular, shutdown): not yet ready
-     * to write, but no "fatal" error either.  Hence retry.  */
-    goto SCHEDULE_WRITE;
-  }
-  GNUNET_assert (connection->write_buffer_off >= connection->write_buffer_pos);
-  if ((NULL != connection->nth.notify_ready) &&
-      (connection->write_buffer_size < connection->nth.notify_size))
-  {
-    connection->write_buffer =
-        GNUNET_realloc (connection->write_buffer, connection->nth.notify_size);
-    connection->write_buffer_size = connection->nth.notify_size;
-  }
-  process_notify (connection);
-  have = connection->write_buffer_off - connection->write_buffer_pos;
-  if (0 == have)
-  {
-    /* no data ready for writing, terminate write loop */
-    return;
-  }
-  GNUNET_assert (have <= connection->write_buffer_size);
-  GNUNET_assert (have + connection->write_buffer_pos <= connection->write_buffer_size);
-  GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size);
-RETRY:
-  ret =
-      GNUNET_NETWORK_socket_send (connection->sock,
-                                 &connection->write_buffer[connection->write_buffer_pos],
-                                 have);
-  if (-1 == ret)
-  {
-    if (EINTR == errno)
-      goto RETRY;
-    if (NULL != connection->write_task)
-    {
-      GNUNET_SCHEDULER_cancel (connection->write_task);
-      connection->write_task = NULL;
-    }
-    signal_transmit_error (connection, errno);
-    return;
-  }
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Connection transmitted %u/%u bytes to `%s' (%p)\n",
-       (unsigned int) ret,
-       have,
-       GNUNET_a2s (connection->addr,
-                  connection->addrlen),
-       connection);
-  connection->write_buffer_pos += ret;
-  if (connection->write_buffer_pos == connection->write_buffer_off)
-  {
-    /* transmitted all pending data */
-    connection->write_buffer_pos = 0;
-    connection->write_buffer_off = 0;
-  }
-  if ( (0 == connection->write_buffer_off) &&
-       (NULL == connection->nth.notify_ready) )
-    return;                     /* all data sent! */
-  /* not done writing, schedule more */
-SCHEDULE_WRITE:
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Re-scheduling transmit_ready (more to do) (%p).\n",
-       connection);
-  have = connection->write_buffer_off - connection->write_buffer_pos;
-  GNUNET_assert ( (NULL != connection->nth.notify_ready) ||
-                 (have > 0) );
-  if (NULL == connection->write_task)
-    connection->write_task =
-        GNUNET_SCHEDULER_add_write_net ((connection->nth.notify_ready ==
-                                         NULL) ? GNUNET_TIME_UNIT_FOREVER_REL :
-                                        GNUNET_TIME_absolute_get_remaining
-                                        (connection->nth.transmit_timeout),
-                                        connection->sock,
-                                       &transmit_ready, connection);
-}
-
-
-/**
- * Ask the connection to call us once the specified number of bytes
- * are free in the transmission buffer.  Will never call the @a notify
- * callback in this task, but always first go into the scheduler.
- *
- * @param connection connection
- * @param size number of bytes to send
- * @param timeout after how long should we give up (and call
- *        @a notify with buf NULL and size 0)?
- * @param notify function to call
- * @param notify_cls closure for @a notify
- * @return non-NULL if the notify callback was queued,
- *         NULL if we are already going to notify someone else (busy)
- */
-struct GNUNET_CONNECTION_TransmitHandle *
-GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle *connection,
-                                         size_t size,
-                                         struct GNUNET_TIME_Relative timeout,
-                                         GNUNET_CONNECTION_TransmitReadyNotify notify,
-                                        void *notify_cls)
-{
-  if (NULL != connection->nth.notify_ready)
-  {
-    GNUNET_assert (0);
-    return NULL;
-  }
-  GNUNET_assert (NULL != notify);
-  GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
-  GNUNET_assert (connection->write_buffer_off <= connection->write_buffer_size);
-  GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_size);
-  GNUNET_assert (connection->write_buffer_pos <= connection->write_buffer_off);
-  connection->nth.notify_ready = notify;
-  connection->nth.notify_ready_cls = notify_cls;
-  connection->nth.connection = connection;
-  connection->nth.notify_size = size;
-  connection->nth.transmit_timeout = GNUNET_TIME_relative_to_absolute (timeout);
-  GNUNET_assert (NULL == connection->nth.timeout_task);
-  if ((NULL == connection->sock) &&
-      (NULL == connection->ap_head) &&
-      (NULL == connection->dns_active) &&
-      (NULL == connection->proxy_handshake))
-  {
-    if (NULL != connection->write_task)
-      GNUNET_SCHEDULER_cancel (connection->write_task);
-    connection->write_task = GNUNET_SCHEDULER_add_now (&connect_error,
-                                                       connection);
-    return &connection->nth;
-  }
-  if (NULL != connection->write_task)
-    return &connection->nth; /* previous transmission still in progress */
-  if (NULL != connection->sock)
-  {
-    /* connected, try to transmit now */
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Scheduling transmission (%p).\n",
-         connection);
-    connection->write_task =
-        GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining
-                                        (connection->nth.transmit_timeout),
-                                        connection->sock,
-                                       &transmit_ready, connection);
-    return &connection->nth;
-  }
-  /* not yet connected, wait for connection */
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Need to wait to schedule transmission for connection, adding timeout task (%p).\n",
-       connection);
-  connection->nth.timeout_task =
-    GNUNET_SCHEDULER_add_delayed (timeout,
-                                  &transmit_timeout,
-                                 connection);
-  return &connection->nth;
-}
-
-
-/**
- * Cancel the specified transmission-ready notification.
- *
- * @param th notification to cancel
- */
-void
-GNUNET_CONNECTION_notify_transmit_ready_cancel (struct GNUNET_CONNECTION_TransmitHandle *th)
-{
-  GNUNET_assert (NULL != th->notify_ready);
-  th->notify_ready = NULL;
-  if (NULL != th->timeout_task)
-  {
-    GNUNET_SCHEDULER_cancel (th->timeout_task);
-    th->timeout_task = NULL;
-  }
-  if (NULL != th->connection->write_task)
-  {
-    GNUNET_SCHEDULER_cancel (th->connection->write_task);
-    th->connection->write_task = NULL;
-  }
-}
-
-
-/**
- * Create a connection to be proxied using a given connection.
- *
- * @param cph connection to proxy server
- * @return connection to be proxied
- */
-struct GNUNET_CONNECTION_Handle *
-GNUNET_CONNECTION_create_proxied_from_handshake (struct GNUNET_CONNECTION_Handle *cph)
-{
-  struct GNUNET_CONNECTION_Handle *proxied = GNUNET_CONNECTION_create_from_existing (NULL);
-
-  proxied->proxy_handshake = cph;
-  return proxied;
-}
-
-
-/**
- * Activate proxied connection and destroy initial proxy handshake connection.
- * There must not be any pending requests for reading or writing to the
- * proxy hadshake connection at this time.
- *
- * @param proxied connection connection to proxy server
- */
-void
-GNUNET_CONNECTION_acivate_proxied (struct GNUNET_CONNECTION_Handle *proxied)
-{
-  struct GNUNET_CONNECTION_Handle *cph = proxied->proxy_handshake;
-
-  GNUNET_assert (NULL != cph);
-  GNUNET_assert (NULL == proxied->sock);
-  GNUNET_assert (NULL != cph->sock);
-  proxied->sock = cph->sock;
-  cph->sock = NULL;
-  GNUNET_CONNECTION_destroy (cph);
-  connect_success_continuation (proxied);
-}
-
-
-/* end of connection.c */
index cdb1b01d4fac5f59777d42c8de7a4c12fc741d9e..1a79c477ab093f5cc3eea433d53ab3dbb50f282b 100644 (file)
@@ -27,6 +27,7 @@
  */
 #include "platform.h"
 #include "gnunet_util_lib.h"
+#include "gnunet_mst_lib.h"
 
 
 /**
@@ -107,7 +108,7 @@ struct GNUNET_HELPER_Handle
   /**
    * The Message-Tokenizer that tokenizes the messages comming from the helper
    */
-  struct GNUNET_SERVER_MessageStreamTokenizer *mst;
+  struct GNUNET_MessageStreamTokenizer *mst;
 
   /**
    * The exception callback
@@ -272,7 +273,10 @@ GNUNET_HELPER_wait (struct GNUNET_HELPER_Handle *h)
   }
   /* purge MST buffer */
   if (NULL != h->mst)
-    (void) GNUNET_SERVER_mst_receive (h->mst, NULL, NULL, 0, GNUNET_YES, GNUNET_NO);
+    (void) GNUNET_MST_from_buffer (h->mst,
+                                   NULL, 0,
+                                   GNUNET_YES,
+                                   GNUNET_NO);
   return ret;
 }
 
@@ -373,10 +377,10 @@ helper_read (void *cls)
                                                 h->fh_from_helper,
                                                 &helper_read, h);
   if (GNUNET_SYSERR ==
-      GNUNET_SERVER_mst_receive (h->mst,
-                                NULL,
-                                buf, t,
-                                GNUNET_NO, GNUNET_NO))
+      GNUNET_MST_from_buffer (h->mst,
+                              buf, t,
+                              GNUNET_NO,
+                              GNUNET_NO))
   {
     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
                _("Failed to parse inbound message from helper `%s'\n"),
@@ -487,7 +491,7 @@ struct GNUNET_HELPER_Handle *
 GNUNET_HELPER_start (int with_control_pipe,
                     const char *binary_name,
                     char *const binary_argv[],
-                    GNUNET_SERVER_MessageTokenizerCallback cb,
+                    GNUNET_MessageTokenizerCallback cb,
                     GNUNET_HELPER_ExceptionCallback exp_cb,
                     void *cb_cls)
 {
@@ -508,7 +512,8 @@ GNUNET_HELPER_start (int with_control_pipe,
   h->binary_argv[c] = NULL;
   h->cb_cls = cb_cls;
   if (NULL != cb)
-    h->mst = GNUNET_SERVER_mst_create (cb, h->cb_cls);
+    h->mst = GNUNET_MST_create (cb,
+                                h->cb_cls);
   h->exp_cb = exp_cb;
   h->retry_back_off = 0;
   start_helper (h);
@@ -544,7 +549,7 @@ GNUNET_HELPER_destroy (struct GNUNET_HELPER_Handle *h)
     GNUNET_free (sh);
   }
   if (NULL != h->mst)
-    GNUNET_SERVER_mst_destroy (h->mst);
+    GNUNET_MST_destroy (h->mst);
   GNUNET_free (h->binary_name);
   for (c = 0; h->binary_argv[c] != NULL; c++)
     GNUNET_free (h->binary_argv[c]);
index 25cf24e11d3cb5309e72cd7b56e3489b85c04c73..e644994e8fd246458eea35b44ac8ddd303d6f6ee 100644 (file)
@@ -707,92 +707,6 @@ GNUNET_MQ_msg_nested_mh_ (struct GNUNET_MessageHeader **mhp,
 }
 
 
-/**
- * Transmit a queued message to the session's client.
- *
- * @param cls consensus session
- * @param size number of bytes available in @a buf
- * @param buf where the callee should write the message
- * @return number of bytes written to @a buf
- */
-static size_t
-transmit_queued (void *cls,
-                 size_t size,
-                 void *buf)
-{
-  struct GNUNET_MQ_Handle *mq = cls;
-  struct ServerClientSocketState *state = GNUNET_MQ_impl_state (mq);
-  const struct GNUNET_MessageHeader *msg = GNUNET_MQ_impl_current (mq);
-  size_t msg_size;
-
-  GNUNET_assert (NULL != buf);
-  msg_size = ntohs (msg->size);
-  GNUNET_assert (size >= msg_size);
-  GNUNET_memcpy (buf, msg, msg_size);
-  state->th = NULL;
-
-  GNUNET_MQ_impl_send_continue (mq);
-
-  return msg_size;
-}
-
-
-static void
-server_client_destroy_impl (struct GNUNET_MQ_Handle *mq,
-                            void *impl_state)
-{
-  struct ServerClientSocketState *state = impl_state;
-
-  if (NULL != state->th)
-  {
-    GNUNET_SERVER_notify_transmit_ready_cancel (state->th);
-    state->th = NULL;
-  }
-
-  GNUNET_assert (NULL != mq);
-  GNUNET_assert (NULL != state);
-  GNUNET_SERVER_client_drop (state->client);
-  GNUNET_free (state);
-}
-
-
-static void
-server_client_send_impl (struct GNUNET_MQ_Handle *mq,
-                         const struct GNUNET_MessageHeader *msg,
-                         void *impl_state)
-{
-  GNUNET_assert (NULL != mq);
-
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Sending message of type %u and size %u\n",
-       ntohs (msg->type), ntohs (msg->size));
-
-  struct ServerClientSocketState *state = impl_state;
-  state->th = GNUNET_SERVER_notify_transmit_ready (state->client,
-                                                  ntohs (msg->size),
-                                                  GNUNET_TIME_UNIT_FOREVER_REL,
-                                                  &transmit_queued,
-                                                   mq);
-}
-
-
-struct GNUNET_MQ_Handle *
-GNUNET_MQ_queue_for_server_client (struct GNUNET_SERVER_Client *client)
-{
-  struct GNUNET_MQ_Handle *mq;
-  struct ServerClientSocketState *scss;
-
-  mq = GNUNET_new (struct GNUNET_MQ_Handle);
-  scss = GNUNET_new (struct ServerClientSocketState);
-  mq->impl_state = scss;
-  scss->client = client;
-  GNUNET_SERVER_client_keep (client);
-  mq->send_impl = &server_client_send_impl;
-  mq->destroy_impl = &server_client_destroy_impl;
-  return mq;
-}
-
-
 /**
  * Associate the assoc_data in mq with a unique request id.
  *
diff --git a/src/util/server.c b/src/util/server.c
deleted file mode 100644 (file)
index 83c30e3..0000000
+++ /dev/null
@@ -1,1752 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C) 2009-2013 GNUnet e.V.
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-
-/**
- * @file util/server.c
- * @brief library for building GNUnet network servers
- * @author Christian Grothoff
- */
-
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_protocols.h"
-
-#define LOG(kind,...) GNUNET_log_from (kind, "util-server", __VA_ARGS__)
-
-#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-server", syscall)
-
-#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-server", syscall, filename)
-
-
-/**
- * List of arrays of message handlers.
- */
-struct HandlerList
-{
-  /**
-   * This is a linked list.
-   */
-  struct HandlerList *next;
-
-  /**
-   * NULL-terminated array of handlers.
-   */
-  const struct GNUNET_SERVER_MessageHandler *handlers;
-};
-
-
-/**
- * List of arrays of message handlers.
- */
-struct NotifyList
-{
-  /**
-   * This is a doubly linked list.
-   */
-  struct NotifyList *next;
-
-  /**
-   * This is a doubly linked list.
-   */
-  struct NotifyList *prev;
-
-  /**
-   * Function to call.
-   */
-  GNUNET_SERVER_DisconnectCallback callback;
-
-  /**
-   * Closure for callback.
-   */
-  void *callback_cls;
-};
-
-
-/**
- * @brief handle for a server
- */
-struct GNUNET_SERVER_Handle
-{
-  /**
-   * List of handlers for incoming messages.
-   */
-  struct HandlerList *handlers;
-
-  /**
-   * Head of list of our current clients.
-   */
-  struct GNUNET_SERVER_Client *clients_head;
-
-  /**
-   * Head of list of our current clients.
-   */
-  struct GNUNET_SERVER_Client *clients_tail;
-
-  /**
-   * Head of linked list of functions to call on disconnects by clients.
-   */
-  struct NotifyList *disconnect_notify_list_head;
-
-  /**
-   * Tail of linked list of functions to call on disconnects by clients.
-   */
-  struct NotifyList *disconnect_notify_list_tail;
-
-  /**
-   * Head of linked list of functions to call on connects by clients.
-   */
-  struct NotifyList *connect_notify_list_head;
-
-  /**
-   * Tail of linked list of functions to call on connects by clients.
-   */
-  struct NotifyList *connect_notify_list_tail;
-
-  /**
-   * Function to call for access control.
-   */
-  GNUNET_CONNECTION_AccessCheck access_cb;
-
-  /**
-   * Closure for @e access_cb.
-   */
-  void *access_cb_cls;
-
-  /**
-   * NULL-terminated array of sockets used to listen for new
-   * connections.
-   */
-  struct GNUNET_NETWORK_Handle **listen_sockets;
-
-  /**
-   * After how long should an idle connection time
-   * out (on write).
-   */
-  struct GNUNET_TIME_Relative idle_timeout;
-
-  /**
-   * Task scheduled to do the listening.
-   */
-  struct GNUNET_SCHEDULER_Task * listen_task;
-
-  /**
-   * Alternative function to create a MST instance.
-   */
-  GNUNET_SERVER_MstCreateCallback mst_create;
-
-  /**
-   * Alternative function to destroy a MST instance.
-   */
-  GNUNET_SERVER_MstDestroyCallback mst_destroy;
-
-  /**
-   * Alternative function to give data to a MST instance.
-   */
-  GNUNET_SERVER_MstReceiveCallback mst_receive;
-
-  /**
-   * Closure for 'mst_'-callbacks.
-   */
-  void *mst_cls;
-
-  /**
-   * Do we ignore messages of types that we do not understand or do we
-   * require that a handler is found (and if not kill the connection)?
-   */
-  int require_found;
-
-  /**
-   * Set to #GNUNET_YES once we are in 'soft' shutdown where we wait for
-   * all non-monitor clients to disconnect before we call
-   * #GNUNET_SERVER_destroy.  See test_monitor_clients().  Set to
-   * #GNUNET_SYSERR once the final destroy task has been scheduled
-   * (we cannot run it in the same task).
-   */
-  int in_soft_shutdown;
-};
-
-
-/**
- * Handle server returns for aborting transmission to a client.
- */
-struct GNUNET_SERVER_TransmitHandle
-{
-  /**
-   * Function to call to get the message.
-   */
-  GNUNET_CONNECTION_TransmitReadyNotify callback;
-
-  /**
-   * Closure for @e callback
-   */
-  void *callback_cls;
-
-  /**
-   * Active connection transmission handle.
-   */
-  struct GNUNET_CONNECTION_TransmitHandle *cth;
-
-};
-
-
-/**
- * @brief handle for a client of the server
- */
-struct GNUNET_SERVER_Client
-{
-
-  /**
-   * This is a doubly linked list.
-   */
-  struct GNUNET_SERVER_Client *next;
-
-  /**
-   * This is a doubly linked list.
-   */
-  struct GNUNET_SERVER_Client *prev;
-
-  /**
-   * Processing of incoming data.
-   */
-  void *mst;
-
-  /**
-   * Server that this client belongs to.
-   */
-  struct GNUNET_SERVER_Handle *server;
-
-  /**
-   * Client closure for callbacks.
-   */
-  struct GNUNET_CONNECTION_Handle *connection;
-
-  /**
-   * User context value, manipulated using
-   * 'GNUNET_SERVER_client_{get/set}_user_context' functions.
-   */
-  void *user_context;
-
-  /**
-   * ID of task used to restart processing.
-   */
-  struct GNUNET_SCHEDULER_Task * restart_task;
-
-  /**
-   * Task that warns about missing calls to #GNUNET_SERVER_receive_done.
-   */
-  struct GNUNET_SCHEDULER_Task * warn_task;
-
-  /**
-   * Time when the warn task was started.
-   */
-  struct GNUNET_TIME_Absolute warn_start;
-
-  /**
-   * Last activity on this socket (used to time it out
-   * if reference_count == 0).
-   */
-  struct GNUNET_TIME_Absolute last_activity;
-
-  /**
-   * Transmission handle we return for this client from
-   * #GNUNET_SERVER_notify_transmit_ready.
-   */
-  struct GNUNET_SERVER_TransmitHandle th;
-
-  /**
-   * After how long should an idle connection time
-   * out (on write).
-   */
-  struct GNUNET_TIME_Relative idle_timeout;
-
-  /**
-   * Number of external entities with a reference to
-   * this client object.
-   */
-  unsigned int reference_count;
-
-  /**
-   * Was processing if incoming messages suspended while
-   * we were still processing data already received?
-   * This is a counter saying how often processing was
-   * suspended (once per handler invoked).
-   */
-  unsigned int suspended;
-
-  /**
-   * Last size given when user context was initialized; used for
-   * sanity check.
-   */
-  size_t user_context_size;
-
-  /**
-   * Are we currently in the "process_client_buffer" function (and
-   * will hence restart the receive job on exit if suspended == 0 once
-   * we are done?).  If this is set, then "receive_done" will
-   * essentially only decrement suspended; if this is not set, then
-   * "receive_done" may need to restart the receive process (either
-   * from the side-buffer or via select/recv).
-   */
-  int in_process_client_buffer;
-
-  /**
-   * We're about to close down this client.
-   */
-  int shutdown_now;
-
-  /**
-   * Are we currently trying to receive? (#GNUNET_YES if we are,
-   * #GNUNET_NO if we are not, #GNUNET_SYSERR if data is already
-   * available in MST).
-   */
-  int receive_pending;
-
-  /**
-   * Persist the file handle for this client no matter what happens,
-   * force the OS to close once the process actually dies.  Should only
-   * be used in special cases!
-   */
-  int persist;
-
-  /**
-   * Is this client a 'monitor' client that should not be counted
-   * when deciding on destroying the server during soft shutdown?
-   * (see also #GNUNET_SERVICE_start)
-   */
-  int is_monitor;
-
-  /**
-   * Type of last message processed (for warn_no_receive_done).
-   */
-  uint16_t warn_type;
-};
-
-
-
-/**
- * Return user context associated with the given client.
- * Note: you should probably use the macro (call without the underscore).
- *
- * @param client client to query
- * @param size number of bytes in user context struct (for verification only)
- * @return pointer to user context
- */
-void *
-GNUNET_SERVER_client_get_user_context_ (struct GNUNET_SERVER_Client *client,
-                                       size_t size)
-{
-  if ((0 == client->user_context_size) &&
-      (NULL == client->user_context))
-    return NULL; /* never set */
-  GNUNET_assert (size == client->user_context_size);
-  return client->user_context;
-}
-
-
-/**
- * Set user context to be associated with the given client.
- * Note: you should probably use the macro (call without the underscore).
- *
- * @param client client to query
- * @param ptr pointer to user context
- * @param size number of bytes in user context struct (for verification only)
- */
-void
-GNUNET_SERVER_client_set_user_context_ (struct GNUNET_SERVER_Client *client,
-                                       void *ptr,
-                                       size_t size)
-{
-  if (NULL == ptr)
-  {
-    client->user_context_size = 0;
-    client->user_context = ptr;
-    return;
-  }
-  client->user_context_size = size;
-  client->user_context = ptr;
-}
-
-
-/**
- * Scheduler says our listen socket is ready.  Process it!
- *
- * @param cls handle to our server for which we are processing the listen
- *        socket
- */
-static void
-process_listen_socket (void *cls)
-{
-  struct GNUNET_SERVER_Handle *server = cls;
-  const struct GNUNET_SCHEDULER_TaskContext *tc;
-  struct GNUNET_CONNECTION_Handle *sock;
-  unsigned int i;
-
-  server->listen_task = NULL;
-  tc = GNUNET_SCHEDULER_get_task_context ();
-  for (i = 0; NULL != server->listen_sockets[i]; i++)
-  {
-    if (GNUNET_NETWORK_fdset_isset (tc->read_ready,
-                                    server->listen_sockets[i]))
-    {
-      sock =
-          GNUNET_CONNECTION_create_from_accept (server->access_cb,
-                                                server->access_cb_cls,
-                                                server->listen_sockets[i]);
-      if (NULL != sock)
-      {
-        LOG (GNUNET_ERROR_TYPE_DEBUG,
-             "Server accepted incoming connection.\n");
-        (void) GNUNET_SERVER_connect_socket (server,
-                                             sock);
-      }
-    }
-  }
-  /* listen for more! */
-  GNUNET_SERVER_resume (server);
-}
-
-
-/**
- * Create and initialize a listen socket for the server.
- *
- * @param server_addr address to listen on
- * @param socklen length of @a server_addr
- * @return NULL on error, otherwise the listen socket
- */
-static struct GNUNET_NETWORK_Handle *
-open_listen_socket (const struct sockaddr *server_addr,
-                   socklen_t socklen)
-{
-  struct GNUNET_NETWORK_Handle *sock;
-  uint16_t port;
-  int eno;
-
-  switch (server_addr->sa_family)
-  {
-  case AF_INET:
-    port = ntohs (((const struct sockaddr_in *) server_addr)->sin_port);
-    break;
-  case AF_INET6:
-    port = ntohs (((const struct sockaddr_in6 *) server_addr)->sin6_port);
-    break;
-  case AF_UNIX:
-    port = 0;
-    break;
-  default:
-    GNUNET_break (0);
-    port = 0;
-    break;
-  }
-  sock = GNUNET_NETWORK_socket_create (server_addr->sa_family, SOCK_STREAM, 0);
-  if (NULL == sock)
-  {
-    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
-    errno = 0;
-    return NULL;
-  }
-  /* bind the socket */
-  if (GNUNET_OK != GNUNET_NETWORK_socket_bind (sock, server_addr, socklen))
-  {
-    eno = errno;
-    if (EADDRINUSE != errno)
-    {
-      /* we don't log 'EADDRINUSE' here since an IPv4 bind may
-       * fail if we already took the port on IPv6; if both IPv4 and
-       * IPv6 binds fail, then our caller will log using the
-       * errno preserved in 'eno' */
-      LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
-                    "bind");
-      if (0 != port)
-        LOG (GNUNET_ERROR_TYPE_ERROR,
-             _("`%s' failed for port %d (%s).\n"),
-             "bind",
-             port,
-             (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
-      eno = 0;
-    }
-    else
-    {
-      if (0 != port)
-        LOG (GNUNET_ERROR_TYPE_WARNING,
-             _("`%s' failed for port %d (%s): address already in use\n"),
-             "bind", port,
-             (AF_INET == server_addr->sa_family) ? "IPv4" : "IPv6");
-      else if (AF_UNIX == server_addr->sa_family)
-      {
-        LOG (GNUNET_ERROR_TYPE_WARNING,
-             _("`%s' failed for `%s': address already in use\n"),
-             "bind",
-             GNUNET_a2s (server_addr, socklen));
-      }
-    }
-    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
-    errno = eno;
-    return NULL;
-  }
-  if (GNUNET_OK != GNUNET_NETWORK_socket_listen (sock, 5))
-  {
-    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR,
-                  "listen");
-    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
-    errno = 0;
-    return NULL;
-  }
-  if (0 != port)
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Server starts to listen on port %u.\n",
-         port);
-  return sock;
-}
-
-
-/**
- * Create a new server.
- *
- * @param access_cb function for access control
- * @param access_cb_cls closure for @a access_cb
- * @param lsocks NULL-terminated array of listen sockets
- * @param idle_timeout after how long should we timeout idle connections?
- * @param require_found if #GNUNET_YES, connections sending messages of unknown type
- *        will be closed
- * @return handle for the new server, NULL on error
- *         (typically, "port" already in use)
- */
-struct GNUNET_SERVER_Handle *
-GNUNET_SERVER_create_with_sockets (GNUNET_CONNECTION_AccessCheck access_cb,
-                                   void *access_cb_cls,
-                                   struct GNUNET_NETWORK_Handle **lsocks,
-                                   struct GNUNET_TIME_Relative idle_timeout,
-                                   int require_found)
-{
-  struct GNUNET_SERVER_Handle *server;
-
-  server = GNUNET_new (struct GNUNET_SERVER_Handle);
-  server->idle_timeout = idle_timeout;
-  server->listen_sockets = lsocks;
-  server->access_cb = access_cb;
-  server->access_cb_cls = access_cb_cls;
-  server->require_found = require_found;
-  if (NULL != lsocks)
-    GNUNET_SERVER_resume (server);
-  return server;
-}
-
-
-/**
- * Create a new server.
- *
- * @param access_cb function for access control
- * @param access_cb_cls closure for @a access_cb
- * @param server_addr address to listen on (including port), NULL terminated array
- * @param socklen length of server_addr
- * @param idle_timeout after how long should we timeout idle connections?
- * @param require_found if YES, connections sending messages of unknown type
- *        will be closed
- * @return handle for the new server, NULL on error
- *         (typically, "port" already in use)
- */
-struct GNUNET_SERVER_Handle *
-GNUNET_SERVER_create (GNUNET_CONNECTION_AccessCheck access_cb,
-                     void *access_cb_cls,
-                      struct sockaddr *const *server_addr,
-                      const socklen_t * socklen,
-                      struct GNUNET_TIME_Relative idle_timeout,
-                      int require_found)
-{
-  struct GNUNET_NETWORK_Handle **lsocks;
-  unsigned int i;
-  unsigned int j;
-  unsigned int k;
-  int seen;
-
-  i = 0;
-  while (NULL != server_addr[i])
-    i++;
-  if (i > 0)
-  {
-    lsocks = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (i + 1));
-    i = 0;
-    j = 0;
-    while (NULL != server_addr[i])
-    {
-      seen = 0;
-      for (k=0;k<i;k++)
-       if ( (socklen[k] == socklen[i]) &&
-            (0 == memcmp (server_addr[k], server_addr[i], socklen[i])) )
-       {
-         seen = 1;
-         break;
-       }
-      if (0 != seen)
-      {
-       /* duplicate address, skip */
-       i++;
-       continue;
-      }
-      lsocks[j] = open_listen_socket (server_addr[i], socklen[i]);
-      if (NULL != lsocks[j])
-        j++;
-      i++;
-    }
-    if (0 == j)
-    {
-      if (0 != errno)
-        LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "bind");
-      GNUNET_free (lsocks);
-      lsocks = NULL;
-    }
-  }
-  else
-  {
-    lsocks = NULL;
-  }
-  return GNUNET_SERVER_create_with_sockets (access_cb,
-                                           access_cb_cls,
-                                           lsocks,
-                                            idle_timeout,
-                                           require_found);
-}
-
-
-/**
- * Set the 'monitor' flag on this client.  Clients which have been
- * marked as 'monitors' won't prevent the server from shutting down
- * once '#GNUNET_SERVER_stop_listening()' has been invoked.  The idea is
- * that for "normal" clients we likely want to allow them to process
- * their requests; however, monitor-clients are likely to 'never'
- * disconnect during shutdown and thus will not be considered when
- * determining if the server should continue to exist after
- * #GNUNET_SERVER_destroy() has been called.
- *
- * @param client the client to set the 'monitor' flag on
- */
-void
-GNUNET_SERVER_client_mark_monitor (struct GNUNET_SERVER_Client *client)
-{
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Marking client as monitor!\n");
-  client->is_monitor = GNUNET_YES;
-}
-
-
-/**
- * Helper function for #test_monitor_clients() to trigger
- * #GNUNET_SERVER_destroy() after the stack has unwound.
- *
- * @param cls the `struct GNUNET_SERVER_Handle *` to destroy
- */
-static void
-do_destroy (void *cls)
-{
-  struct GNUNET_SERVER_Handle *server = cls;
-
-  GNUNET_SERVER_destroy (server);
-}
-
-
-/**
- * Check if only 'monitor' clients are left.  If so, destroy the
- * server completely.
- *
- * @param server server to test for full shutdown
- */
-static void
-test_monitor_clients (struct GNUNET_SERVER_Handle *server)
-{
-  struct GNUNET_SERVER_Client *client;
-
-  if (GNUNET_YES != server->in_soft_shutdown)
-    return;
-  for (client = server->clients_head; NULL != client; client = client->next)
-    if (GNUNET_NO == client->is_monitor)
-      return; /* not done yet */
-  server->in_soft_shutdown = GNUNET_SYSERR;
-  (void) GNUNET_SCHEDULER_add_now (&do_destroy, server);
-}
-
-
-/**
- * Suspend accepting connections from the listen socket temporarily.
- *
- * @param server server to stop accepting connections.
- */
-void
-GNUNET_SERVER_suspend (struct GNUNET_SERVER_Handle *server)
-{
-  if (NULL != server->listen_task)
-  {
-    GNUNET_SCHEDULER_cancel (server->listen_task);
-    server->listen_task = NULL;
-  }
-}
-
-
-/**
- * Resume accepting connections from the listen socket.
- *
- * @param server server to stop accepting connections.
- */
-void
-GNUNET_SERVER_resume (struct GNUNET_SERVER_Handle *server)
-{
-  struct GNUNET_NETWORK_FDSet *r;
-  unsigned int i;
-
-  if (NULL == server->listen_sockets)
-    return;
-  if (NULL == server->listen_sockets[0])
-    return; /* nothing to do, no listen sockets! */
-  if (NULL == server->listen_sockets[1])
-  {
-    /* simplified method: no fd set needed; this is then much simpler
-       and much more efficient */
-    server->listen_task =
-      GNUNET_SCHEDULER_add_read_net_with_priority (GNUNET_TIME_UNIT_FOREVER_REL,
-                                                  GNUNET_SCHEDULER_PRIORITY_HIGH,
-                                                  server->listen_sockets[0],
-                                                  &process_listen_socket, server);
-    return;
-  }
-  r = GNUNET_NETWORK_fdset_create ();
-  i = 0;
-  while (NULL != server->listen_sockets[i])
-    GNUNET_NETWORK_fdset_set (r, server->listen_sockets[i++]);
-  server->listen_task =
-    GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
-                                GNUNET_TIME_UNIT_FOREVER_REL, r, NULL,
-                                &process_listen_socket, server);
-  GNUNET_NETWORK_fdset_destroy (r);
-}
-
-
-/**
- * Stop the listen socket and get ready to shutdown the server
- * once only 'monitor' clients are left.
- *
- * @param server server to stop listening on
- */
-void
-GNUNET_SERVER_stop_listening (struct GNUNET_SERVER_Handle *server)
-{
-  unsigned int i;
-
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Server in soft shutdown\n");
-  if (NULL != server->listen_task)
-  {
-    GNUNET_SCHEDULER_cancel (server->listen_task);
-    server->listen_task = NULL;
-  }
-  if (NULL != server->listen_sockets)
-  {
-    i = 0;
-    while (NULL != server->listen_sockets[i])
-      GNUNET_break (GNUNET_OK ==
-                    GNUNET_NETWORK_socket_close (server->listen_sockets[i++]));
-    GNUNET_free (server->listen_sockets);
-    server->listen_sockets = NULL;
-  }
-  if (GNUNET_NO == server->in_soft_shutdown)
-    server->in_soft_shutdown = GNUNET_YES;
-  test_monitor_clients (server);
-}
-
-
-/**
- * Free resources held by this server.
- *
- * @param server server to destroy
- */
-void
-GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *server)
-{
-  struct HandlerList *hpos;
-  struct NotifyList *npos;
-  unsigned int i;
-
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Server shutting down.\n");
-  if (NULL != server->listen_task)
-  {
-    GNUNET_SCHEDULER_cancel (server->listen_task);
-    server->listen_task = NULL;
-  }
-  if (NULL != server->listen_sockets)
-  {
-    i = 0;
-    while (NULL != server->listen_sockets[i])
-      GNUNET_break (GNUNET_OK ==
-                    GNUNET_NETWORK_socket_close (server->listen_sockets[i++]));
-    GNUNET_free (server->listen_sockets);
-    server->listen_sockets = NULL;
-  }
-  while (NULL != server->clients_head)
-    GNUNET_SERVER_client_disconnect (server->clients_head);
-  while (NULL != (hpos = server->handlers))
-  {
-    server->handlers = hpos->next;
-    GNUNET_free (hpos);
-  }
-  while (NULL != (npos = server->disconnect_notify_list_head))
-  {
-    npos->callback (npos->callback_cls,
-                    NULL);
-    GNUNET_CONTAINER_DLL_remove (server->disconnect_notify_list_head,
-                                server->disconnect_notify_list_tail,
-                                npos);
-    GNUNET_free (npos);
-  }
-  while (NULL != (npos = server->connect_notify_list_head))
-  {
-    npos->callback (npos->callback_cls,
-                    NULL);
-    GNUNET_CONTAINER_DLL_remove (server->connect_notify_list_head,
-                                server->connect_notify_list_tail,
-                                npos);
-    GNUNET_free (npos);
-  }
-  GNUNET_free (server);
-}
-
-
-/**
- * Add additional handlers to an existing server.
- *
- * @param server the server to add handlers to
- * @param handlers array of message handlers for
- *        incoming messages; the last entry must
- *        have "NULL" for the "callback"; multiple
- *        entries for the same type are allowed,
- *        they will be called in order of occurence.
- *        These handlers can be removed later;
- *        the handlers array must exist until removed
- *        (or server is destroyed).
- */
-void
-GNUNET_SERVER_add_handlers (struct GNUNET_SERVER_Handle *server,
-                            const struct GNUNET_SERVER_MessageHandler *handlers)
-{
-  struct HandlerList *p;
-
-  p = GNUNET_new (struct HandlerList);
-  p->handlers = handlers;
-  p->next = server->handlers;
-  server->handlers = p;
-}
-
-
-/**
- * Change functions used by the server to tokenize the message stream.
- * (very rarely used).
- *
- * @param server server to modify
- * @param create new tokenizer initialization function
- * @param destroy new tokenizer destruction function
- * @param receive new tokenizer receive function
- * @param cls closure for @a create, @a receive, @a destroy
- */
-void
-GNUNET_SERVER_set_callbacks (struct GNUNET_SERVER_Handle *server,
-                             GNUNET_SERVER_MstCreateCallback create,
-                             GNUNET_SERVER_MstDestroyCallback destroy,
-                             GNUNET_SERVER_MstReceiveCallback receive,
-                             void *cls)
-{
-  server->mst_create = create;
-  server->mst_destroy = destroy;
-  server->mst_receive = receive;
-  server->mst_cls = cls;
-}
-
-
-/**
- * Task run to warn about missing calls to #GNUNET_SERVER_receive_done.
- *
- * @param cls our `struct GNUNET_SERVER_Client *` to process more requests from
- */
-static void
-warn_no_receive_done (void *cls)
-{
-  struct GNUNET_SERVER_Client *client = cls;
-
-  GNUNET_break (0 != client->warn_type); /* type should never be 0 here, as we don't use 0 */
-  client->warn_task =
-      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
-                                    &warn_no_receive_done, client);
-  LOG (GNUNET_ERROR_TYPE_WARNING,
-       _("Processing code for message of type %u did not call `GNUNET_SERVER_receive_done' after %s\n"),
-       (unsigned int) client->warn_type,
-       GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (client->warn_start),
-                                              GNUNET_YES));
-}
-
-
-/**
- * Disable the warning the server issues if a message is not acknowledged
- * in a timely fashion.  Use this call if a client is intentionally delayed
- * for a while.  Only applies to the current message.
- *
- * @param client client for which to disable the warning
- */
-void
-GNUNET_SERVER_disable_receive_done_warning (struct GNUNET_SERVER_Client *client)
-{
-  if (NULL != client->warn_task)
-  {
-    GNUNET_SCHEDULER_cancel (client->warn_task);
-    client->warn_task = NULL;
-  }
-}
-
-
-/**
- * Inject a message into the server, pretend it came
- * from the specified client.  Delivery of the message
- * will happen instantly (if a handler is installed;
- * otherwise the call does nothing).
- *
- * @param server the server receiving the message
- * @param sender the "pretended" sender of the message
- *        can be NULL!
- * @param message message to transmit
- * @return #GNUNET_OK if the message was OK and the
- *                   connection can stay open
- *         #GNUNET_SYSERR if the connection to the
- *         client should be shut down
- */
-int
-GNUNET_SERVER_inject (struct GNUNET_SERVER_Handle *server,
-                      struct GNUNET_SERVER_Client *sender,
-                      const struct GNUNET_MessageHeader *message)
-{
-  struct HandlerList *pos;
-  const struct GNUNET_SERVER_MessageHandler *mh;
-  unsigned int i;
-  uint16_t type;
-  uint16_t size;
-  int found;
-
-  type = ntohs (message->type);
-  size = ntohs (message->size);
-  LOG (GNUNET_ERROR_TYPE_INFO,
-       "Received message of type %u and size %u from client\n",
-       type, size);
-  found = GNUNET_NO;
-  for (pos = server->handlers; NULL != pos; pos = pos->next)
-  {
-    i = 0;
-    while (pos->handlers[i].callback != NULL)
-    {
-      mh = &pos->handlers[i];
-      if ((mh->type == type) || (mh->type == GNUNET_MESSAGE_TYPE_ALL))
-      {
-        if ((0 != mh->expected_size) && (mh->expected_size != size))
-        {
-#if GNUNET8_NETWORK_IS_DEAD
-          LOG (GNUNET_ERROR_TYPE_WARNING,
-               "Expected %u bytes for message of type %u, got %u\n",
-               mh->expected_size, mh->type, size);
-          GNUNET_break_op (0);
-#else
-          LOG (GNUNET_ERROR_TYPE_DEBUG,
-               "Expected %u bytes for message of type %u, got %u\n",
-               mh->expected_size, mh->type, size);
-#endif
-          return GNUNET_SYSERR;
-        }
-        if (NULL != sender)
-        {
-          if ( (0 == sender->suspended) &&
-              (NULL == sender->warn_task) )
-          {
-           GNUNET_break (0 != type); /* type should never be 0 here, as we don't use 0 */
-            sender->warn_start = GNUNET_TIME_absolute_get ();
-            sender->warn_task =
-                GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES,
-                                              &warn_no_receive_done,
-                                             sender);
-            sender->warn_type = type;
-          }
-          sender->suspended++;
-        }
-        mh->callback (mh->callback_cls, sender, message);
-        found = GNUNET_YES;
-      }
-      i++;
-    }
-  }
-  if (GNUNET_NO == found)
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
-         "Received message of unknown type %d\n", type);
-    if (GNUNET_YES == server->require_found)
-      return GNUNET_SYSERR;
-  }
-  return GNUNET_OK;
-}
-
-
-/**
- * We are receiving an incoming message.  Process it.
- *
- * @param cls our closure (handle for the client)
- * @param buf buffer with data received from network
- * @param available number of bytes available in buf
- * @param addr address of the sender
- * @param addrlen length of @a addr
- * @param errCode code indicating errors receiving, 0 for success
- */
-static void
-process_incoming (void *cls,
-                  const void *buf,
-                  size_t available,
-                  const struct sockaddr *addr,
-                  socklen_t addrlen,
-                  int errCode);
-
-
-/**
- * Process messages from the client's message tokenizer until either
- * the tokenizer is empty (and then schedule receiving more), or
- * until some handler is not immediately done (then wait for restart_processing)
- * or shutdown.
- *
- * @param client the client to process, RC must have already been increased
- *        using #GNUNET_SERVER_client_keep and will be decreased by one in this
- *        function
- * @param ret #GNUNET_NO to start processing from the buffer,
- *            #GNUNET_OK if the mst buffer is drained and we should instantly go back to receiving
- *            #GNUNET_SYSERR if we should instantly abort due to error in a previous step
- */
-static void
-process_mst (struct GNUNET_SERVER_Client *client,
-             int ret)
-{
-  while ((GNUNET_SYSERR != ret) && (NULL != client->server) &&
-         (GNUNET_YES != client->shutdown_now) && (0 == client->suspended))
-  {
-    if (GNUNET_OK == ret)
-    {
-      LOG (GNUNET_ERROR_TYPE_DEBUG,
-           "Server re-enters receive loop, timeout: %s.\n",
-           GNUNET_STRINGS_relative_time_to_string (client->idle_timeout, GNUNET_YES));
-      client->receive_pending = GNUNET_YES;
-      GNUNET_CONNECTION_receive (client->connection,
-                                 GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
-                                 client->idle_timeout,
-                                 &process_incoming,
-                                 client);
-      break;
-    }
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Server processes additional messages instantly.\n");
-    if (NULL != client->server->mst_receive)
-      ret =
-          client->server->mst_receive (client->server->mst_cls, client->mst,
-                                       client, NULL, 0, GNUNET_NO, GNUNET_YES);
-    else
-      ret =
-          GNUNET_SERVER_mst_receive (client->mst, client, NULL, 0, GNUNET_NO,
-                                     GNUNET_YES);
-  }
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Server leaves instant processing loop: ret = %d, server = %p, shutdown = %d, suspended = %u\n",
-       ret, client->server,
-       client->shutdown_now,
-       client->suspended);
-  if (GNUNET_NO == ret)
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Server has more data pending but is suspended.\n");
-    client->receive_pending = GNUNET_SYSERR;    /* data pending */
-  }
-  if ( (GNUNET_SYSERR == ret) ||
-       (GNUNET_YES == client->shutdown_now) )
-    GNUNET_SERVER_client_disconnect (client);
-}
-
-
-/**
- * We are receiving an incoming message.  Process it.
- *
- * @param cls our closure (handle for the client)
- * @param buf buffer with data received from network
- * @param available number of bytes available in buf
- * @param addr address of the sender
- * @param addrlen length of @a addr
- * @param errCode code indicating errors receiving, 0 for success
- */
-static void
-process_incoming (void *cls,
-                  const void *buf,
-                  size_t available,
-                  const struct sockaddr *addr,
-                  socklen_t addrlen,
-                  int errCode)
-{
-  struct GNUNET_SERVER_Client *client = cls;
-  struct GNUNET_SERVER_Handle *server = client->server;
-  struct GNUNET_TIME_Absolute end;
-  struct GNUNET_TIME_Absolute now;
-  int ret;
-
-  GNUNET_assert (GNUNET_YES == client->receive_pending);
-  client->receive_pending = GNUNET_NO;
-  now = GNUNET_TIME_absolute_get ();
-  end = GNUNET_TIME_absolute_add (client->last_activity,
-                                  client->idle_timeout);
-
-  if ( (NULL == buf) &&
-       (0 == available) &&
-       (NULL == addr) &&
-       (0 == errCode) &&
-       (GNUNET_YES != client->shutdown_now) &&
-       (NULL != server) &&
-       (GNUNET_YES == GNUNET_CONNECTION_check (client->connection)) &&
-       (end.abs_value_us > now.abs_value_us) )
-  {
-    /* wait longer, timeout changed (i.e. due to us sending) */
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Receive time out, but no disconnect due to sending (%p)\n",
-         client);
-    client->receive_pending = GNUNET_YES;
-    GNUNET_CONNECTION_receive (client->connection,
-                               GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
-                               GNUNET_TIME_absolute_get_remaining (end),
-                               &process_incoming,
-                               client);
-    return;
-  }
-  if ( (NULL == buf) ||
-       (0 == available) ||
-       (0 != errCode) ||
-       (NULL == server) ||
-       (GNUNET_YES == client->shutdown_now) ||
-       (GNUNET_YES != GNUNET_CONNECTION_check (client->connection)) )
-  {
-    /* other side closed connection, error connecting, etc. */
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Failed to connect or other side closed connection (%p)\n",
-         client);
-    GNUNET_SERVER_client_disconnect (client);
-    return;
-  }
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Server receives %u bytes from `%s'.\n",
-       (unsigned int) available,
-       GNUNET_a2s (addr, addrlen));
-  GNUNET_SERVER_client_keep (client);
-  client->last_activity = now;
-
-  if (NULL != server->mst_receive)
-  {
-    ret = client->server->mst_receive (client->server->mst_cls,
-                                       client->mst,
-                                       client,
-                                       buf,
-                                       available,
-                                       GNUNET_NO,
-                                       GNUNET_YES);
-  }
-  else if (NULL != client->mst)
-  {
-    ret =
-        GNUNET_SERVER_mst_receive (client->mst,
-                                   client,
-                                   buf,
-                                   available,
-                                   GNUNET_NO,
-                                   GNUNET_YES);
-  }
-  else
-  {
-    GNUNET_break (0);
-    return;
-  }
-  process_mst (client,
-               ret);
-  GNUNET_SERVER_client_drop (client);
-}
-
-
-/**
- * Task run to start again receiving from the network
- * and process requests.
- *
- * @param cls our `struct GNUNET_SERVER_Client *` to process more requests from
- */
-static void
-restart_processing (void *cls)
-{
-  struct GNUNET_SERVER_Client *client = cls;
-
-  GNUNET_assert (GNUNET_YES != client->shutdown_now);
-  client->restart_task = NULL;
-  if (GNUNET_NO == client->receive_pending)
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "Server begins to read again from client.\n");
-    client->receive_pending = GNUNET_YES;
-    GNUNET_CONNECTION_receive (client->connection,
-                               GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
-                               client->idle_timeout,
-                               &process_incoming,
-                               client);
-    return;
-  }
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Server continues processing messages still in the buffer.\n");
-  GNUNET_SERVER_client_keep (client);
-  client->receive_pending = GNUNET_NO;
-  process_mst (client,
-               GNUNET_NO);
-  GNUNET_SERVER_client_drop (client);
-}
-
-
-/**
- * This function is called whenever our inbound message tokenizer has
- * received a complete message.
- *
- * @param cls closure (struct GNUNET_SERVER_Handle)
- * @param client identification of the client (`struct GNUNET_SERVER_Client *`)
- * @param message the actual message
- *
- * @return #GNUNET_OK on success, #GNUNET_SYSERR to stop further processing
- */
-static int
-client_message_tokenizer_callback (void *cls,
-                                   void *client,
-                                   const struct GNUNET_MessageHeader *message)
-{
-  struct GNUNET_SERVER_Handle *server = cls;
-  struct GNUNET_SERVER_Client *sender = client;
-  int ret;
-
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Tokenizer gives server message of type %u and size %u from client\n",
-       ntohs (message->type), ntohs (message->size));
-  sender->in_process_client_buffer = GNUNET_YES;
-  ret = GNUNET_SERVER_inject (server, sender, message);
-  sender->in_process_client_buffer = GNUNET_NO;
-  if ( (GNUNET_OK != ret) || (GNUNET_YES == sender->shutdown_now) )
-  {
-    GNUNET_SERVER_client_disconnect (sender);
-    return GNUNET_SYSERR;
-  }
-  return GNUNET_OK;
-}
-
-
-/**
- * Add a TCP socket-based connection to the set of handles managed by
- * this server.  Use this function for outgoing (P2P) connections that
- * we initiated (and where this server should process incoming
- * messages).
- *
- * @param server the server to use
- * @param connection the connection to manage (client must
- *        stop using this connection from now on)
- * @return the client handle
- */
-struct GNUNET_SERVER_Client *
-GNUNET_SERVER_connect_socket (struct GNUNET_SERVER_Handle *server,
-                              struct GNUNET_CONNECTION_Handle *connection)
-{
-  struct GNUNET_SERVER_Client *client;
-  struct NotifyList *n;
-
-  client = GNUNET_new (struct GNUNET_SERVER_Client);
-  client->connection = connection;
-  client->server = server;
-  client->last_activity = GNUNET_TIME_absolute_get ();
-  client->idle_timeout = server->idle_timeout;
-  GNUNET_CONTAINER_DLL_insert (server->clients_head,
-                              server->clients_tail,
-                              client);
-  if (NULL != server->mst_create)
-    client->mst =
-        server->mst_create (server->mst_cls, client);
-  else
-    client->mst =
-        GNUNET_SERVER_mst_create (&client_message_tokenizer_callback,
-                                  server);
-  GNUNET_assert (NULL != client->mst);
-  for (n = server->connect_notify_list_head; NULL != n; n = n->next)
-    n->callback (n->callback_cls, client);
-  client->receive_pending = GNUNET_YES;
-  GNUNET_CONNECTION_receive (client->connection,
-                             GNUNET_SERVER_MAX_MESSAGE_SIZE - 1,
-                             client->idle_timeout,
-                             &process_incoming,
-                             client);
-  return client;
-}
-
-
-/**
- * Change the timeout for a particular client.  Decreasing the timeout
- * may not go into effect immediately (only after the previous timeout
- * times out or activity happens on the socket).
- *
- * @param client the client to update
- * @param timeout new timeout for activities on the socket
- */
-void
-GNUNET_SERVER_client_set_timeout (struct GNUNET_SERVER_Client *client,
-                                  struct GNUNET_TIME_Relative timeout)
-{
-  client->idle_timeout = timeout;
-}
-
-
-/**
- * Notify the server that the given client handle should
- * be kept (keeps the connection up if possible, increments
- * the internal reference counter).
- *
- * @param client the client to keep
- */
-void
-GNUNET_SERVER_client_keep (struct GNUNET_SERVER_Client *client)
-{
-  client->reference_count++;
-}
-
-
-/**
- * Notify the server that the given client handle is no
- * longer required.  Decrements the reference counter.  If
- * that counter reaches zero an inactive connection maybe
- * closed.
- *
- * @param client the client to drop
- */
-void
-GNUNET_SERVER_client_drop (struct GNUNET_SERVER_Client *client)
-{
-  GNUNET_assert (client->reference_count > 0);
-  client->reference_count--;
-  if ((GNUNET_YES == client->shutdown_now) && (0 == client->reference_count))
-    GNUNET_SERVER_client_disconnect (client);
-}
-
-
-/**
- * Obtain the network address of the other party.
- *
- * @param client the client to get the address for
- * @param addr where to store the address
- * @param addrlen where to store the length of the @a addr
- * @return #GNUNET_OK on success
- */
-int
-GNUNET_SERVER_client_get_address (struct GNUNET_SERVER_Client *client,
-                                  void **addr, size_t * addrlen)
-{
-  return GNUNET_CONNECTION_get_address (client->connection, addr, addrlen);
-}
-
-
-/**
- * Ask the server to notify us whenever a client disconnects.
- * This function is called whenever the actual network connection
- * is closed; the reference count may be zero or larger than zero
- * at this point.
- *
- * @param server the server manageing the clients
- * @param callback function to call on disconnect
- * @param callback_cls closure for @a callback
- */
-void
-GNUNET_SERVER_disconnect_notify (struct GNUNET_SERVER_Handle *server,
-                                 GNUNET_SERVER_DisconnectCallback callback,
-                                 void *callback_cls)
-{
-  struct NotifyList *n;
-
-  n = GNUNET_new (struct NotifyList);
-  n->callback = callback;
-  n->callback_cls = callback_cls;
-  GNUNET_CONTAINER_DLL_insert (server->disconnect_notify_list_head,
-                              server->disconnect_notify_list_tail,
-                              n);
-}
-
-
-/**
- * Ask the server to notify us whenever a client connects.
- * This function is called whenever the actual network connection
- * is opened. If the server is destroyed before this
- * notification is explicitly cancelled, the 'callback' will
- * once be called with a 'client' argument of NULL to indicate
- * that the server itself is now gone (and that the callback
- * won't be called anymore and also can no longer be cancelled).
- *
- * @param server the server manageing the clients
- * @param callback function to call on sconnect
- * @param callback_cls closure for @a callback
- */
-void
-GNUNET_SERVER_connect_notify (struct GNUNET_SERVER_Handle *server,
-                             GNUNET_SERVER_ConnectCallback callback,
-                             void *callback_cls)
-{
-  struct NotifyList *n;
-  struct GNUNET_SERVER_Client *client;
-
-  n = GNUNET_new (struct NotifyList);
-  n->callback = callback;
-  n->callback_cls = callback_cls;
-  GNUNET_CONTAINER_DLL_insert (server->connect_notify_list_head,
-                              server->connect_notify_list_tail,
-                              n);
-  for (client = server->clients_head; NULL != client; client = client->next)
-    callback (callback_cls, client);
-}
-
-
-/**
- * Ask the server to stop notifying us whenever a client connects.
- *
- * @param server the server manageing the clients
- * @param callback function to call on connect
- * @param callback_cls closure for @a callback
- */
-void
-GNUNET_SERVER_disconnect_notify_cancel (struct GNUNET_SERVER_Handle *server,
-                                        GNUNET_SERVER_DisconnectCallback callback,
-                                        void *callback_cls)
-{
-  struct NotifyList *pos;
-
-  for (pos = server->disconnect_notify_list_head; NULL != pos; pos = pos->next)
-    if ((pos->callback == callback) && (pos->callback_cls == callback_cls))
-      break;
-  if (NULL == pos)
-  {
-    GNUNET_break (0);
-    return;
-  }
-  GNUNET_CONTAINER_DLL_remove (server->disconnect_notify_list_head,
-                              server->disconnect_notify_list_tail,
-                              pos);
-  GNUNET_free (pos);
-}
-
-
-/**
- * Ask the server to stop notifying us whenever a client disconnects.
- *
- * @param server the server manageing the clients
- * @param callback function to call on disconnect
- * @param callback_cls closure for @a callback
- */
-void
-GNUNET_SERVER_connect_notify_cancel (struct GNUNET_SERVER_Handle *server,
-                                    GNUNET_SERVER_ConnectCallback callback,
-                                    void *callback_cls)
-{
-  struct NotifyList *pos;
-
-  for (pos = server->connect_notify_list_head; NULL != pos; pos = pos->next)
-    if ((pos->callback == callback) && (pos->callback_cls == callback_cls))
-      break;
-  if (NULL == pos)
-  {
-    GNUNET_break (0);
-    return;
-  }
-  GNUNET_CONTAINER_DLL_remove (server->connect_notify_list_head,
-                              server->connect_notify_list_tail,
-                              pos);
-  GNUNET_free (pos);
-}
-
-
-/**
- * Destroy the connection that is passed in via @a cls.  Used
- * as calling #GNUNET_CONNECTION_destroy from within a function
- * that was itself called from within process_notify() of
- * 'connection.c' is not allowed (see #2329).
- *
- * @param cls connection to destroy
- */
-static void
-destroy_connection (void *cls)
-{
-  struct GNUNET_CONNECTION_Handle *connection = cls;
-
-  GNUNET_CONNECTION_destroy (connection);
-}
-
-
-/**
- * Ask the server to disconnect from the given client.
- * This is the same as returning #GNUNET_SYSERR from a message
- * handler, except that it allows dropping of a client even
- * when not handling a message from that client.
- *
- * @param client the client to disconnect from
- */
-void
-GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client)
-{
-  struct GNUNET_SERVER_Handle *server = client->server;
-  struct NotifyList *n;
-
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Client is being disconnected from the server.\n");
-  if (NULL != client->restart_task)
-  {
-    GNUNET_SCHEDULER_cancel (client->restart_task);
-    client->restart_task = NULL;
-  }
-  if (NULL != client->warn_task)
-  {
-    GNUNET_SCHEDULER_cancel (client->warn_task);
-    client->warn_task = NULL;
-  }
-  if (GNUNET_YES == client->receive_pending)
-  {
-    GNUNET_CONNECTION_receive_cancel (client->connection);
-    client->receive_pending = GNUNET_NO;
-  }
-  client->shutdown_now = GNUNET_YES;
-  client->reference_count++; /* make sure nobody else clean up client... */
-  if ( (NULL != client->mst) &&
-       (NULL != server) )
-  {
-    GNUNET_CONTAINER_DLL_remove (server->clients_head,
-                                server->clients_tail,
-                                client);
-    if (NULL != server->mst_destroy)
-      server->mst_destroy (server->mst_cls,
-                           client->mst);
-    else
-      GNUNET_SERVER_mst_destroy (client->mst);
-    client->mst = NULL;
-    for (n = server->disconnect_notify_list_head; NULL != n; n = n->next)
-      n->callback (n->callback_cls,
-                   client);
-  }
-  client->reference_count--;
-  if (client->reference_count > 0)
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "RC of %p still positive, not destroying everything.\n",
-         client);
-    client->server = NULL;
-    return;
-  }
-  if (GNUNET_YES == client->in_process_client_buffer)
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Still processing inputs of %p, not destroying everything.\n",
-         client);
-    return;
-  }
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "RC of %p now zero, destroying everything.\n",
-       client);
-  if (GNUNET_YES == client->persist)
-    GNUNET_CONNECTION_persist_ (client->connection);
-  if (NULL != client->th.cth)
-    GNUNET_SERVER_notify_transmit_ready_cancel (&client->th);
-  (void) GNUNET_SCHEDULER_add_now (&destroy_connection,
-                                  client->connection);
-  /* need to cancel again, as it might have been re-added
-     in the meantime (i.e. during callbacks) */
-  if (NULL != client->warn_task)
-  {
-    GNUNET_SCHEDULER_cancel (client->warn_task);
-    client->warn_task = NULL;
-  }
-  if (GNUNET_YES == client->receive_pending)
-  {
-    GNUNET_CONNECTION_receive_cancel (client->connection);
-    client->receive_pending = GNUNET_NO;
-  }
-  GNUNET_free (client);
-  /* we might be in soft-shutdown, test if we're done */
-  if (NULL != server)
-    test_monitor_clients (server);
-}
-
-
-/**
- * Disable the "CORK" feature for communication with the given client,
- * forcing the OS to immediately flush the buffer on transmission
- * instead of potentially buffering multiple messages.
- *
- * @param client handle to the client
- * @return #GNUNET_OK on success
- */
-int
-GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client)
-{
-  return GNUNET_CONNECTION_disable_corking (client->connection);
-}
-
-
-/**
- * Wrapper for transmission notification that calls the original
- * callback and update the last activity time for our connection.
- *
- * @param cls the `struct GNUNET_SERVER_Client *`
- * @param size number of bytes we can transmit
- * @param buf where to copy the message
- * @return number of bytes actually transmitted
- */
-static size_t
-transmit_ready_callback_wrapper (void *cls, size_t size, void *buf)
-{
-  struct GNUNET_SERVER_Client *client = cls;
-  GNUNET_CONNECTION_TransmitReadyNotify callback;
-
-  client->th.cth = NULL;
-  callback = client->th.callback;
-  client->th.callback = NULL;
-  client->last_activity = GNUNET_TIME_absolute_get ();
-  return callback (client->th.callback_cls, size, buf);
-}
-
-
-/**
- * Notify us when the server has enough space to transmit
- * a message of the given size to the given client.
- *
- * @param client client to transmit message to
- * @param size requested amount of buffer space
- * @param timeout after how long should we give up (and call
- *        notify with buf NULL and size 0)?
- * @param callback function to call when space is available
- * @param callback_cls closure for @a callback
- * @return non-NULL if the notify callback was queued; can be used
- *         to cancel the request using
- *         #GNUNET_SERVER_notify_transmit_ready_cancel().
- *         NULL if we are already going to notify someone else (busy)
- */
-struct GNUNET_SERVER_TransmitHandle *
-GNUNET_SERVER_notify_transmit_ready (struct GNUNET_SERVER_Client *client,
-                                     size_t size,
-                                     struct GNUNET_TIME_Relative timeout,
-                                     GNUNET_CONNECTION_TransmitReadyNotify callback,
-                                     void *callback_cls)
-{
-  if (NULL != client->th.callback)
-    return NULL;
-  client->th.callback_cls = callback_cls;
-  client->th.callback = callback;
-  client->th.cth = GNUNET_CONNECTION_notify_transmit_ready (client->connection, size,
-                                                           timeout,
-                                                           &transmit_ready_callback_wrapper,
-                                                           client);
-  return &client->th;
-}
-
-
-/**
- * Abort transmission request.
- *
- * @param th request to abort
- */
-void
-GNUNET_SERVER_notify_transmit_ready_cancel (struct GNUNET_SERVER_TransmitHandle *th)
-{
-  GNUNET_CONNECTION_notify_transmit_ready_cancel (th->cth);
-  th->cth = NULL;
-  th->callback = NULL;
-}
-
-
-/**
- * Set the persistent flag on this client, used to setup client connection
- * to only be killed when the service it's connected to is actually dead.
- *
- * @param client the client to set the persistent flag on
- */
-void
-GNUNET_SERVER_client_persist_ (struct GNUNET_SERVER_Client *client)
-{
-  client->persist = GNUNET_YES;
-}
-
-
-/**
- * Resume receiving from this client, we are done processing the
- * current request.  This function must be called from within each
- * GNUNET_SERVER_MessageCallback (or its respective continuations).
- *
- * @param client client we were processing a message of
- * @param success #GNUNET_OK to keep the connection open and
- *                          continue to receive
- *                #GNUNET_NO to close the connection (normal behavior)
- *                #GNUNET_SYSERR to close the connection (signal
- *                          serious error)
- */
-void
-GNUNET_SERVER_receive_done (struct GNUNET_SERVER_Client *client,
-                           int success)
-{
-  if (NULL == client)
-    return;
-  GNUNET_assert (client->suspended > 0);
-  client->suspended--;
-  if (GNUNET_OK != success)
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "GNUNET_SERVER_receive_done called with failure indication\n");
-    if ( (client->reference_count > 0) || (client->suspended > 0) )
-      client->shutdown_now = GNUNET_YES;
-    else
-      GNUNET_SERVER_client_disconnect (client);
-    return;
-  }
-  if (client->suspended > 0)
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "GNUNET_SERVER_receive_done called, but more clients pending\n");
-    return;
-  }
-  if (NULL != client->warn_task)
-  {
-    GNUNET_SCHEDULER_cancel (client->warn_task);
-    client->warn_task = NULL;
-  }
-  if (GNUNET_YES == client->in_process_client_buffer)
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "GNUNET_SERVER_receive_done called while still in processing loop\n");
-    return;
-  }
-  if ((NULL == client->server) || (GNUNET_YES == client->shutdown_now))
-  {
-    GNUNET_SERVER_client_disconnect (client);
-    return;
-  }
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "GNUNET_SERVER_receive_done causes restart in reading from the socket\n");
-  GNUNET_assert (NULL == client->restart_task);
-  client->restart_task = GNUNET_SCHEDULER_add_now (&restart_processing,
-                                                   client);
-}
-
-
-/* end of server.c */
diff --git a/src/util/service.c b/src/util/service.c
deleted file mode 100644 (file)
index 496904f..0000000
+++ /dev/null
@@ -1,1697 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C) 2009, 2012 GNUnet e.V.
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-
-/**
- * @file util/service.c
- * @brief functions related to starting services
- * @author Christian Grothoff
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-#include "gnunet_protocols.h"
-#include "gnunet_constants.h"
-#include "gnunet_resolver_service.h"
-#include "speedup.h"
-
-#if HAVE_MALLINFO
-#include <malloc.h>
-#include "gauger.h"
-#endif
-
-
-#define LOG(kind,...) GNUNET_log_from (kind, "util-service", __VA_ARGS__)
-
-#define LOG_STRERROR(kind,syscall) GNUNET_log_from_strerror (kind, "util-service", syscall)
-
-#define LOG_STRERROR_FILE(kind,syscall,filename) GNUNET_log_from_strerror_file (kind, "util-service", syscall, filename)
-
-
-/* ******************* access control ******************** */
-
-/**
- * Check if the given IP address is in the list of IP addresses.
- *
- * @param list a list of networks
- * @param add the IP to check (in network byte order)
- * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
- */
-static int
-check_ipv4_listed (const struct GNUNET_STRINGS_IPv4NetworkPolicy *list,
-                   const struct in_addr *add)
-{
-  unsigned int i;
-
-  if (NULL == list)
-    return GNUNET_NO;
-  i = 0;
-  while ((list[i].network.s_addr != 0) || (list[i].netmask.s_addr != 0))
-  {
-    if ((add->s_addr & list[i].netmask.s_addr) ==
-        (list[i].network.s_addr & list[i].netmask.s_addr))
-      return GNUNET_YES;
-    i++;
-  }
-  return GNUNET_NO;
-}
-
-
-/**
- * Check if the given IP address is in the list of IP addresses.
- *
- * @param list a list of networks
- * @param ip the IP to check (in network byte order)
- * @return #GNUNET_NO if the IP is not in the list, #GNUNET_YES if it it is
- */
-static int
-check_ipv6_listed (const struct GNUNET_STRINGS_IPv6NetworkPolicy *list,
-                   const struct in6_addr *ip)
-{
-  unsigned int i;
-  unsigned int j;
-  struct in6_addr zero;
-
-  if (NULL == list)
-    return GNUNET_NO;
-  memset (&zero, 0, sizeof (struct in6_addr));
-  i = 0;
-NEXT:
-  while (0 != memcmp (&zero, &list[i].network, sizeof (struct in6_addr)))
-  {
-    for (j = 0; j < sizeof (struct in6_addr) / sizeof (int); j++)
-      if (((((int *) ip)[j] & ((int *) &list[i].netmask)[j])) !=
-          (((int *) &list[i].network)[j] & ((int *) &list[i].netmask)[j]))
-      {
-        i++;
-        goto NEXT;
-      }
-    return GNUNET_YES;
-  }
-  return GNUNET_NO;
-}
-
-
-/* ****************** service struct ****************** */
-
-
-/**
- * Context for "service_task".
- */
-struct GNUNET_SERVICE_Context
-{
-  /**
-   * Our configuration.
-   */
-  const struct GNUNET_CONFIGURATION_Handle *cfg;
-
-  /**
-   * Handle for the server.
-   */
-  struct GNUNET_SERVER_Handle *server;
-
-  /**
-   * NULL-terminated array of addresses to bind to, NULL if we got pre-bound
-   * listen sockets.
-   */
-  struct sockaddr **addrs;
-
-  /**
-   * Name of our service.
-   */
-  const char *service_name;
-
-  /**
-   * Main service-specific task to run.
-   */
-  GNUNET_SERVICE_Main task;
-
-  /**
-   * Closure for @e task.
-   */
-  void *task_cls;
-
-  /**
-   * IPv4 addresses that are not allowed to connect.
-   */
-  struct GNUNET_STRINGS_IPv4NetworkPolicy *v4_denied;
-
-  /**
-   * IPv6 addresses that are not allowed to connect.
-   */
-  struct GNUNET_STRINGS_IPv6NetworkPolicy *v6_denied;
-
-  /**
-   * IPv4 addresses that are allowed to connect (if not
-   * set, all are allowed).
-   */
-  struct GNUNET_STRINGS_IPv4NetworkPolicy *v4_allowed;
-
-  /**
-   * IPv6 addresses that are allowed to connect (if not
-   * set, all are allowed).
-   */
-  struct GNUNET_STRINGS_IPv6NetworkPolicy *v6_allowed;
-
-  /**
-   * My (default) message handlers.  Adjusted copy
-   * of "defhandlers".
-   */
-  struct GNUNET_SERVER_MessageHandler *my_handlers;
-
-  /**
-   * Array of the lengths of the entries in addrs.
-   */
-  socklen_t *addrlens;
-
-  /**
-   * NULL-terminated array of listen sockets we should take over.
-   */
-  struct GNUNET_NETWORK_Handle **lsocks;
-
-  /**
-   * Task ID of the shutdown task.
-   */
-  struct GNUNET_SCHEDULER_Task *shutdown_task;
-
-  /**
-   * Idle timeout for server.
-   */
-  struct GNUNET_TIME_Relative timeout;
-
-  /**
-   * Overall success/failure of the service start.
-   */
-  int ret;
-
-  /**
-   * If we are daemonizing, this FD is set to the
-   * pipe to the parent.  Send '.' if we started
-   * ok, '!' if not.  -1 if we are not daemonizing.
-   */
-  int ready_confirm_fd;
-
-  /**
-   * Do we close connections if we receive messages
-   * for which we have no handler?
-   */
-  int require_found;
-
-  /**
-   * Do we require a matching UID for UNIX domain socket connections?
-   * #GNUNET_NO means that the UID does not have to match (however,
-   * @e match_gid may still impose other access control checks).
-   */
-  int match_uid;
-
-  /**
-   * Do we require a matching GID for UNIX domain socket connections?
-   * Ignored if @e match_uid is #GNUNET_YES.  Note that this is about
-   * checking that the client's UID is in our group OR that the
-   * client's GID is our GID.  If both "match_gid" and @e match_uid are
-   * #GNUNET_NO, all users on the local system have access.
-   */
-  int match_gid;
-
-  /**
-   * Our options.
-   */
-  enum GNUNET_SERVICE_Options options;
-
-};
-
-
-/* ****************** message handlers ****************** */
-
-/**
- * Send a 'TEST' message back to the client.
- *
- * @param cls the 'struct GNUNET_SERVER_Client' to send TEST to
- * @param size number of bytes available in 'buf'
- * @param buf where to copy the message
- * @return number of bytes written to 'buf'
- */
-static size_t
-write_test (void *cls, size_t size, void *buf)
-{
-  struct GNUNET_SERVER_Client *client = cls;
-  struct GNUNET_MessageHeader *msg;
-
-  if (size < sizeof (struct GNUNET_MessageHeader))
-  {
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-    return 0;                   /* client disconnected */
-  }
-  msg = (struct GNUNET_MessageHeader *) buf;
-  msg->type = htons (GNUNET_MESSAGE_TYPE_TEST);
-  msg->size = htons (sizeof (struct GNUNET_MessageHeader));
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
-  return sizeof (struct GNUNET_MessageHeader);
-}
-
-
-/**
- * Handler for TEST message.
- *
- * @param cls closure (refers to service)
- * @param client identification of the client
- * @param message the actual message
- */
-static void
-handle_test (void *cls, struct GNUNET_SERVER_Client *client,
-             const struct GNUNET_MessageHeader *message)
-{
-  /* simply bounce message back to acknowledge */
-  if (NULL ==
-      GNUNET_SERVER_notify_transmit_ready (client,
-                                           sizeof (struct GNUNET_MessageHeader),
-                                           GNUNET_TIME_UNIT_FOREVER_REL,
-                                           &write_test, client))
-    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
-}
-
-
-/**
- * Default handlers for all services.  Will be copied and the
- * "callback_cls" fields will be replaced with the specific service
- * struct.
- */
-static const struct GNUNET_SERVER_MessageHandler defhandlers[] = {
-  {&handle_test, NULL, GNUNET_MESSAGE_TYPE_TEST,
-   sizeof (struct GNUNET_MessageHeader)},
-  {NULL, NULL, 0, 0}
-};
-
-
-/* ****************** service core routines ************** */
-
-
-/**
- * Check if access to the service is allowed from the given address.
- *
- * @param cls closure
- * @param uc credentials, if available, otherwise NULL
- * @param addr address
- * @param addrlen length of address
- * @return #GNUNET_YES to allow, #GNUNET_NO to deny, #GNUNET_SYSERR
- *   for unknown address family (will be denied).
- */
-static int
-check_access (void *cls, const struct GNUNET_CONNECTION_Credentials *uc,
-              const struct sockaddr *addr, socklen_t addrlen)
-{
-  struct GNUNET_SERVICE_Context *sctx = cls;
-  const struct sockaddr_in *i4;
-  const struct sockaddr_in6 *i6;
-  int ret;
-
-  switch (addr->sa_family)
-  {
-  case AF_INET:
-    GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
-    i4 = (const struct sockaddr_in *) addr;
-    ret = ((NULL == sctx->v4_allowed) ||
-           (check_ipv4_listed (sctx->v4_allowed, &i4->sin_addr))) &&
-        ((NULL == sctx->v4_denied) ||
-         (!check_ipv4_listed (sctx->v4_denied, &i4->sin_addr)));
-    break;
-  case AF_INET6:
-    GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
-    i6 = (const struct sockaddr_in6 *) addr;
-    ret = ((NULL == sctx->v6_allowed) ||
-           (check_ipv6_listed (sctx->v6_allowed, &i6->sin6_addr))) &&
-        ((NULL == sctx->v6_denied) ||
-         (!check_ipv6_listed (sctx->v6_denied, &i6->sin6_addr)));
-    break;
-#ifndef WINDOWS
-  case AF_UNIX:
-    ret = GNUNET_OK;            /* controlled using file-system ACL now */
-    break;
-#endif
-  default:
-    LOG (GNUNET_ERROR_TYPE_WARNING, _("Unknown address family %d\n"),
-         addr->sa_family);
-    return GNUNET_SYSERR;
-  }
-  if (GNUNET_OK != ret)
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-         _("Access from `%s' denied to service `%s'\n"),
-        GNUNET_a2s (addr, addrlen),
-         sctx->service_name);
-  }
-  return ret;
-}
-
-
-/**
- * Get the name of the file where we will
- * write the PID of the service.
- *
- * @param sctx service context
- * @return name of the file for the process ID
- */
-static char *
-get_pid_file_name (struct GNUNET_SERVICE_Context *sctx)
-{
-  char *pif;
-
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->service_name,
-                                               "PIDFILE", &pif))
-    return NULL;
-  return pif;
-}
-
-
-/**
- * Parse an IPv4 access control list.
- *
- * @param ret location where to write the ACL (set)
- * @param sctx service context to use to get the configuration
- * @param option name of the ACL option to parse
- * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
- *         no ACL configured)
- */
-static int
-process_acl4 (struct GNUNET_STRINGS_IPv4NetworkPolicy **ret,
-              struct GNUNET_SERVICE_Context *sctx,
-              const char *option)
-{
-  char *opt;
-
-  if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option))
-  {
-    *ret = NULL;
-    return GNUNET_OK;
-  }
-  GNUNET_break (GNUNET_OK ==
-                GNUNET_CONFIGURATION_get_value_string (sctx->cfg,
-                                                       sctx->service_name,
-                                                       option, &opt));
-  if (NULL == (*ret = GNUNET_STRINGS_parse_ipv4_policy (opt)))
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-         _("Could not parse IPv4 network specification `%s' for `%s:%s'\n"),
-         opt, sctx->service_name, option);
-    GNUNET_free (opt);
-    return GNUNET_SYSERR;
-  }
-  GNUNET_free (opt);
-  return GNUNET_OK;
-}
-
-
-/**
- * Parse an IPv6 access control list.
- *
- * @param ret location where to write the ACL (set)
- * @param sctx service context to use to get the configuration
- * @param option name of the ACL option to parse
- * @return #GNUNET_SYSERR on parse error, #GNUNET_OK on success (including
- *         no ACL configured)
- */
-static int
-process_acl6 (struct GNUNET_STRINGS_IPv6NetworkPolicy **ret,
-              struct GNUNET_SERVICE_Context *sctx,
-              const char *option)
-{
-  char *opt;
-
-  if (!GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, option))
-  {
-    *ret = NULL;
-    return GNUNET_OK;
-  }
-  GNUNET_break (GNUNET_OK ==
-                GNUNET_CONFIGURATION_get_value_string (sctx->cfg,
-                                                       sctx->service_name,
-                                                       option, &opt));
-  if (NULL == (*ret = GNUNET_STRINGS_parse_ipv6_policy (opt)))
-  {
-    LOG (GNUNET_ERROR_TYPE_WARNING,
-         _("Could not parse IPv6 network specification `%s' for `%s:%s'\n"),
-         opt, sctx->service_name, option);
-    GNUNET_free (opt);
-    return GNUNET_SYSERR;
-  }
-  GNUNET_free (opt);
-  return GNUNET_OK;
-}
-
-
-/**
- * Add the given UNIX domain path as an address to the
- * list (as the first entry).
- *
- * @param saddrs array to update
- * @param saddrlens where to store the address length
- * @param unixpath path to add
- * @param abstract #GNUNET_YES to add an abstract UNIX domain socket.  This
- *          parameter is ignore on systems other than LINUX
- */
-static void
-add_unixpath (struct sockaddr **saddrs,
-              socklen_t *saddrlens,
-              const char *unixpath,
-              int abstract)
-{
-#ifdef AF_UNIX
-  struct sockaddr_un *un;
-
-  un = GNUNET_new (struct sockaddr_un);
-  un->sun_family = AF_UNIX;
-  strncpy (un->sun_path, unixpath, sizeof (un->sun_path) - 1);
-#ifdef LINUX
-  if (GNUNET_YES == abstract)
-    un->sun_path[0] = '\0';
-#endif
-#if HAVE_SOCKADDR_UN_SUN_LEN
-  un->sun_len = (u_char) sizeof (struct sockaddr_un);
-#endif
-  *saddrs = (struct sockaddr *) un;
-  *saddrlens = sizeof (struct sockaddr_un);
-#else
-  /* this function should never be called
-   * unless AF_UNIX is defined! */
-  GNUNET_assert (0);
-#endif
-}
-
-
-/**
- * Get the list of addresses that a server for the given service
- * should bind to.
- *
- * @param service_name name of the service
- * @param cfg configuration (which specifies the addresses)
- * @param addrs set (call by reference) to an array of pointers to the
- *              addresses the server should bind to and listen on; the
- *              array will be NULL-terminated (on success)
- * @param addr_lens set (call by reference) to an array of the lengths
- *              of the respective `struct sockaddr` struct in the @a addrs
- *              array (on success)
- * @return number of addresses found on success,
- *              #GNUNET_SYSERR if the configuration
- *              did not specify reasonable finding information or
- *              if it specified a hostname that could not be resolved;
- *              #GNUNET_NO if the number of addresses configured is
- *              zero (in this case, `*addrs` and `*addr_lens` will be
- *              set to NULL).
- */
-int
-GNUNET_SERVICE_get_server_addresses (const char *service_name,
-                                     const struct GNUNET_CONFIGURATION_Handle *cfg,
-                                     struct sockaddr ***addrs,
-                                     socklen_t ** addr_lens)
-{
-  int disablev6;
-  struct GNUNET_NETWORK_Handle *desc;
-  unsigned long long port;
-  char *unixpath;
-  struct addrinfo hints;
-  struct addrinfo *res;
-  struct addrinfo *pos;
-  struct addrinfo *next;
-  unsigned int i;
-  int resi;
-  int ret;
-  int abstract;
-  struct sockaddr **saddrs;
-  socklen_t *saddrlens;
-  char *hostname;
-
-  *addrs = NULL;
-  *addr_lens = NULL;
-  desc = NULL;
-  if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "DISABLEV6"))
-  {
-    if (GNUNET_SYSERR ==
-        (disablev6 =
-         GNUNET_CONFIGURATION_get_value_yesno (cfg, service_name, "DISABLEV6")))
-      return GNUNET_SYSERR;
-  }
-  else
-    disablev6 = GNUNET_NO;
-
-  if (! disablev6)
-  {
-    /* probe IPv6 support */
-    desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
-    if (NULL == desc)
-    {
-      if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
-          (EACCES == errno))
-      {
-        LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
-        return GNUNET_SYSERR;
-      }
-      LOG (GNUNET_ERROR_TYPE_INFO,
-           _("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
-           service_name, STRERROR (errno));
-      disablev6 = GNUNET_YES;
-    }
-    else
-    {
-      GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
-      desc = NULL;
-    }
-  }
-
-  port = 0;
-  if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "PORT"))
-  {
-    if (GNUNET_OK !=
-       GNUNET_CONFIGURATION_get_value_number (cfg, service_name,
-                                              "PORT", &port))
-    {
-      LOG (GNUNET_ERROR_TYPE_ERROR,
-           _("Require valid port number for service `%s' in configuration!\n"),
-           service_name);
-    }
-    if (port > 65535)
-    {
-      LOG (GNUNET_ERROR_TYPE_ERROR,
-           _("Require valid port number for service `%s' in configuration!\n"),
-           service_name);
-      return GNUNET_SYSERR;
-    }
-  }
-
-  if (GNUNET_CONFIGURATION_have_value (cfg, service_name, "BINDTO"))
-  {
-    GNUNET_break (GNUNET_OK ==
-                  GNUNET_CONFIGURATION_get_value_string (cfg, service_name,
-                                                         "BINDTO", &hostname));
-  }
-  else
-    hostname = NULL;
-
-  unixpath = NULL;
-  abstract = GNUNET_NO;
-#ifdef AF_UNIX
-  if ((GNUNET_YES ==
-       GNUNET_CONFIGURATION_have_value (cfg, service_name, "UNIXPATH")) &&
-      (GNUNET_OK ==
-       GNUNET_CONFIGURATION_get_value_filename (cfg, service_name, "UNIXPATH",
-                                              &unixpath)) &&
-      (0 < strlen (unixpath)))
-  {
-    /* probe UNIX support */
-    struct sockaddr_un s_un;
-
-    if (strlen (unixpath) >= sizeof (s_un.sun_path))
-    {
-      LOG (GNUNET_ERROR_TYPE_WARNING,
-           _("UNIXPATH `%s' too long, maximum length is %llu\n"), unixpath,
-           (unsigned long long) sizeof (s_un.sun_path));
-      unixpath = GNUNET_NETWORK_shorten_unixpath (unixpath);
-      LOG (GNUNET_ERROR_TYPE_INFO,
-          _("Using `%s' instead\n"),
-           unixpath);
-    }
-#ifdef LINUX
-    abstract = GNUNET_CONFIGURATION_get_value_yesno (cfg,
-                                                     "TESTING",
-                                                     "USE_ABSTRACT_SOCKETS");
-    if (GNUNET_SYSERR == abstract)
-      abstract = GNUNET_NO;
-#endif
-    if ((GNUNET_YES != abstract)
-        && (GNUNET_OK !=
-            GNUNET_DISK_directory_create_for_file (unixpath)))
-      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
-                               "mkdir",
-                               unixpath);
-  }
-  if (NULL != unixpath)
-  {
-    desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_STREAM, 0);
-    if (NULL == desc)
-    {
-      if ((ENOBUFS == errno) || (ENOMEM == errno) || (ENFILE == errno) ||
-          (EACCES == errno))
-      {
-        LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "socket");
-        GNUNET_free_non_null (hostname);
-        GNUNET_free (unixpath);
-        return GNUNET_SYSERR;
-      }
-      LOG (GNUNET_ERROR_TYPE_INFO,
-           _("Disabling UNIX domain socket support for service `%s', failed to create UNIX domain socket: %s\n"),
-           service_name,
-           STRERROR (errno));
-      GNUNET_free (unixpath);
-      unixpath = NULL;
-    }
-    else
-    {
-      GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (desc));
-      desc = NULL;
-    }
-  }
-#endif
-
-  if ((0 == port) && (NULL == unixpath))
-  {
-    LOG (GNUNET_ERROR_TYPE_ERROR,
-         _("Have neither PORT nor UNIXPATH for service `%s', but one is required\n"),
-         service_name);
-    GNUNET_free_non_null (hostname);
-    return GNUNET_SYSERR;
-  }
-  if (0 == port)
-  {
-    saddrs = GNUNET_malloc (2 * sizeof (struct sockaddr *));
-    saddrlens = GNUNET_malloc (2 * sizeof (socklen_t));
-    add_unixpath (saddrs, saddrlens, unixpath, abstract);
-    GNUNET_free_non_null (unixpath);
-    GNUNET_free_non_null (hostname);
-    *addrs = saddrs;
-    *addr_lens = saddrlens;
-    return 1;
-  }
-
-  if (NULL != hostname)
-  {
-    LOG (GNUNET_ERROR_TYPE_DEBUG,
-         "Resolving `%s' since that is where `%s' will bind to.\n",
-         hostname,
-         service_name);
-    memset (&hints, 0, sizeof (struct addrinfo));
-    if (disablev6)
-      hints.ai_family = AF_INET;
-    hints.ai_protocol = IPPROTO_TCP;
-    if ((0 != (ret = getaddrinfo (hostname, NULL, &hints, &res))) ||
-        (NULL == res))
-    {
-      LOG (GNUNET_ERROR_TYPE_ERROR,
-           _("Failed to resolve `%s': %s\n"),
-           hostname,
-           gai_strerror (ret));
-      GNUNET_free (hostname);
-      GNUNET_free_non_null (unixpath);
-      return GNUNET_SYSERR;
-    }
-    next = res;
-    i = 0;
-    while (NULL != (pos = next))
-    {
-      next = pos->ai_next;
-      if ((disablev6) && (pos->ai_family == AF_INET6))
-        continue;
-      i++;
-    }
-    if (0 == i)
-    {
-      LOG (GNUNET_ERROR_TYPE_ERROR,
-           _("Failed to find %saddress for `%s'.\n"),
-           disablev6 ? "IPv4 " : "",
-           hostname);
-      freeaddrinfo (res);
-      GNUNET_free (hostname);
-      GNUNET_free_non_null (unixpath);
-      return GNUNET_SYSERR;
-    }
-    resi = i;
-    if (NULL != unixpath)
-      resi++;
-    saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
-    saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
-    i = 0;
-    if (NULL != unixpath)
-    {
-      add_unixpath (saddrs, saddrlens, unixpath, abstract);
-      i++;
-    }
-    next = res;
-    while (NULL != (pos = next))
-    {
-      next = pos->ai_next;
-      if ((disablev6) && (AF_INET6 == pos->ai_family))
-        continue;
-      if ((IPPROTO_TCP != pos->ai_protocol) && (0 != pos->ai_protocol))
-        continue;               /* not TCP */
-      if ((SOCK_STREAM != pos->ai_socktype) && (0 != pos->ai_socktype))
-        continue;               /* huh? */
-      LOG (GNUNET_ERROR_TYPE_DEBUG, "Service `%s' will bind to `%s'\n",
-           service_name, GNUNET_a2s (pos->ai_addr, pos->ai_addrlen));
-      if (AF_INET == pos->ai_family)
-      {
-        GNUNET_assert (sizeof (struct sockaddr_in) == pos->ai_addrlen);
-        saddrlens[i] = pos->ai_addrlen;
-        saddrs[i] = GNUNET_malloc (saddrlens[i]);
-        GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
-        ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
-      }
-      else
-      {
-        GNUNET_assert (AF_INET6 == pos->ai_family);
-        GNUNET_assert (sizeof (struct sockaddr_in6) == pos->ai_addrlen);
-        saddrlens[i] = pos->ai_addrlen;
-        saddrs[i] = GNUNET_malloc (saddrlens[i]);
-        GNUNET_memcpy (saddrs[i], pos->ai_addr, saddrlens[i]);
-        ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
-      }
-      i++;
-    }
-    GNUNET_free (hostname);
-    freeaddrinfo (res);
-    resi = i;
-  }
-  else
-  {
-    /* will bind against everything, just set port */
-    if (disablev6)
-    {
-      /* V4-only */
-      resi = 1;
-      if (NULL != unixpath)
-        resi++;
-      i = 0;
-      saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
-      saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
-      if (NULL != unixpath)
-      {
-        add_unixpath (saddrs, saddrlens, unixpath, abstract);
-        i++;
-      }
-      saddrlens[i] = sizeof (struct sockaddr_in);
-      saddrs[i] = GNUNET_malloc (saddrlens[i]);
-#if HAVE_SOCKADDR_IN_SIN_LEN
-      ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[i];
-#endif
-      ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
-      ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
-    }
-    else
-    {
-      /* dual stack */
-      resi = 2;
-      if (NULL != unixpath)
-        resi++;
-      saddrs = GNUNET_malloc ((resi + 1) * sizeof (struct sockaddr *));
-      saddrlens = GNUNET_malloc ((resi + 1) * sizeof (socklen_t));
-      i = 0;
-      if (NULL != unixpath)
-      {
-        add_unixpath (saddrs, saddrlens, unixpath, abstract);
-        i++;
-      }
-      saddrlens[i] = sizeof (struct sockaddr_in6);
-      saddrs[i] = GNUNET_malloc (saddrlens[i]);
-#if HAVE_SOCKADDR_IN_SIN_LEN
-      ((struct sockaddr_in6 *) saddrs[i])->sin6_len = saddrlens[0];
-#endif
-      ((struct sockaddr_in6 *) saddrs[i])->sin6_family = AF_INET6;
-      ((struct sockaddr_in6 *) saddrs[i])->sin6_port = htons (port);
-      i++;
-      saddrlens[i] = sizeof (struct sockaddr_in);
-      saddrs[i] = GNUNET_malloc (saddrlens[i]);
-#if HAVE_SOCKADDR_IN_SIN_LEN
-      ((struct sockaddr_in *) saddrs[i])->sin_len = saddrlens[1];
-#endif
-      ((struct sockaddr_in *) saddrs[i])->sin_family = AF_INET;
-      ((struct sockaddr_in *) saddrs[i])->sin_port = htons (port);
-    }
-  }
-  GNUNET_free_non_null (unixpath);
-  *addrs = saddrs;
-  *addr_lens = saddrlens;
-  return resi;
-}
-
-
-#ifdef MINGW
-/**
- * Read listen sockets from the parent process (ARM).
- *
- * @param sctx service context to initialize
- * @return #GNUNET_YES if ok, #GNUNET_NO if not ok (must bind yourself),
- * and #GNUNET_SYSERR on error.
- */
-static int
-receive_sockets_from_parent (struct GNUNET_SERVICE_Context *sctx)
-{
-  const char *env_buf;
-  int fail;
-  uint64_t count;
-  uint64_t i;
-  HANDLE lsocks_pipe;
-
-  env_buf = getenv ("GNUNET_OS_READ_LSOCKS");
-  if ((NULL == env_buf) || (strlen (env_buf) <= 0))
-    return GNUNET_NO;
-  /* Using W32 API directly here, because this pipe will
-   * never be used outside of this function, and it's just too much of a bother
-   * to create a GNUnet API that boxes a HANDLE (the way it is done with socks)
-   */
-  lsocks_pipe = (HANDLE) strtoul (env_buf, NULL, 10);
-  if ( (0 == lsocks_pipe) || (INVALID_HANDLE_VALUE == lsocks_pipe))
-    return GNUNET_NO;
-  fail = 1;
-  do
-  {
-    int ret;
-    int fail2;
-    DWORD rd;
-
-    ret = ReadFile (lsocks_pipe, &count, sizeof (count), &rd, NULL);
-    if ((0 == ret) || (sizeof (count) != rd) || (0 == count))
-      break;
-    sctx->lsocks =
-        GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (count + 1));
-
-    fail2 = 1;
-    for (i = 0; i < count; i++)
-    {
-      WSAPROTOCOL_INFOA pi;
-      uint64_t size;
-      SOCKET s;
-
-      ret = ReadFile (lsocks_pipe, &size, sizeof (size), &rd, NULL);
-      if ( (0 == ret) || (sizeof (size) != rd) || (sizeof (pi) != size) )
-        break;
-      ret = ReadFile (lsocks_pipe, &pi, sizeof (pi), &rd, NULL);
-      if ( (0 == ret) || (sizeof (pi) != rd))
-        break;
-      s = WSASocketA (pi.iAddressFamily, pi.iSocketType, pi.iProtocol, &pi, 0, WSA_FLAG_OVERLAPPED);
-      sctx->lsocks[i] = GNUNET_NETWORK_socket_box_native (s);
-      if (NULL == sctx->lsocks[i])
-        break;
-      else if (i == count - 1)
-        fail2 = 0;
-    }
-    if (fail2)
-      break;
-    sctx->lsocks[count] = NULL;
-    fail = 0;
-  }
-  while (fail);
-
-  CloseHandle (lsocks_pipe);
-
-  if (fail)
-  {
-    LOG (GNUNET_ERROR_TYPE_ERROR,
-         _("Could not access a pre-bound socket, will try to bind myself\n"));
-    for (i = 0; (i < count) && (NULL != sctx->lsocks[i]); i++)
-      GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[i]));
-    GNUNET_free_non_null (sctx->lsocks);
-    sctx->lsocks = NULL;
-    return GNUNET_NO;
-  }
-  return GNUNET_YES;
-}
-#endif
-
-
-/**
- * Setup addr, addrlen, idle_timeout
- * based on configuration!
- *
- * Configuration may specify:
- * - PORT (where to bind to for TCP)
- * - UNIXPATH (where to bind to for UNIX domain sockets)
- * - TIMEOUT (after how many ms does an inactive service timeout);
- * - DISABLEV6 (disable support for IPv6, otherwise we use dual-stack)
- * - BINDTO (hostname or IP address to bind to, otherwise we take everything)
- * - ACCEPT_FROM  (only allow connections from specified IPv4 subnets)
- * - ACCEPT_FROM6 (only allow connections from specified IPv6 subnets)
- * - REJECT_FROM  (disallow allow connections from specified IPv4 subnets)
- * - REJECT_FROM6 (disallow allow connections from specified IPv6 subnets)
- *
- * @param sctx service context to initialize
- * @return #GNUNET_OK if configuration succeeded
- */
-static int
-setup_service (struct GNUNET_SERVICE_Context *sctx)
-{
-  struct GNUNET_TIME_Relative idleout;
-  int tolerant;
-
-#ifndef MINGW
-  const char *nfds;
-  unsigned int cnt;
-  int flags;
-#endif
-
-  if (GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name, "TIMEOUT"))
-  {
-    if (GNUNET_OK !=
-        GNUNET_CONFIGURATION_get_value_time (sctx->cfg, sctx->service_name,
-                                             "TIMEOUT", &idleout))
-    {
-      LOG (GNUNET_ERROR_TYPE_ERROR,
-           _("Specified value for `%s' of service `%s' is invalid\n"),
-           "TIMEOUT", sctx->service_name);
-      return GNUNET_SYSERR;
-    }
-    sctx->timeout = idleout;
-  }
-  else
-    sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
-
-  if (GNUNET_CONFIGURATION_have_value
-      (sctx->cfg, sctx->service_name, "TOLERANT"))
-  {
-    if (GNUNET_SYSERR ==
-        (tolerant =
-         GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name,
-                                               "TOLERANT")))
-    {
-      LOG (GNUNET_ERROR_TYPE_ERROR,
-           _("Specified value for `%s' of service `%s' is invalid\n"),
-           "TOLERANT", sctx->service_name);
-      return GNUNET_SYSERR;
-    }
-  }
-  else
-    tolerant = GNUNET_NO;
-
-#ifndef MINGW
-  errno = 0;
-  if ((NULL != (nfds = getenv ("LISTEN_FDS"))) &&
-      (1 == SSCANF (nfds, "%u", &cnt)) && (cnt > 0) && (cnt < FD_SETSIZE) &&
-      (cnt + 4 < FD_SETSIZE))
-  {
-    sctx->lsocks =
-        GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle *) * (cnt + 1));
-    while (0 < cnt--)
-    {
-      flags = fcntl (3 + cnt, F_GETFD);
-      if ((flags < 0) || (0 != (flags & FD_CLOEXEC)) ||
-          (NULL ==
-           (sctx->lsocks[cnt] = GNUNET_NETWORK_socket_box_native (3 + cnt))))
-      {
-        LOG (GNUNET_ERROR_TYPE_ERROR,
-             _
-             ("Could not access pre-bound socket %u, will try to bind myself\n"),
-             (unsigned int) 3 + cnt);
-        cnt++;
-        while (sctx->lsocks[cnt] != NULL)
-          GNUNET_break (0 == GNUNET_NETWORK_socket_close (sctx->lsocks[cnt++]));
-        GNUNET_free (sctx->lsocks);
-        sctx->lsocks = NULL;
-        break;
-      }
-    }
-    unsetenv ("LISTEN_FDS");
-  }
-#else
-  if (getenv ("GNUNET_OS_READ_LSOCKS") != NULL)
-  {
-    receive_sockets_from_parent (sctx);
-    putenv ("GNUNET_OS_READ_LSOCKS=");
-  }
-#endif
-
-  if ((NULL == sctx->lsocks) &&
-      (GNUNET_SYSERR ==
-       GNUNET_SERVICE_get_server_addresses (sctx->service_name, sctx->cfg,
-                                            &sctx->addrs, &sctx->addrlens)))
-    return GNUNET_SYSERR;
-  sctx->require_found = tolerant ? GNUNET_NO : GNUNET_YES;
-  sctx->match_uid =
-      GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name,
-                                            "UNIX_MATCH_UID");
-  sctx->match_gid =
-      GNUNET_CONFIGURATION_get_value_yesno (sctx->cfg, sctx->service_name,
-                                            "UNIX_MATCH_GID");
-  process_acl4 (&sctx->v4_denied, sctx, "REJECT_FROM");
-  process_acl4 (&sctx->v4_allowed, sctx, "ACCEPT_FROM");
-  process_acl6 (&sctx->v6_denied, sctx, "REJECT_FROM6");
-  process_acl6 (&sctx->v6_allowed, sctx, "ACCEPT_FROM6");
-
-  return GNUNET_OK;
-}
-
-
-/**
- * Get the name of the user that'll be used
- * to provide the service.
- *
- * @param sctx service context
- * @return value of the 'USERNAME' option
- */
-static char *
-get_user_name (struct GNUNET_SERVICE_Context *sctx)
-{
-  char *un;
-
-  if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (sctx->cfg, sctx->service_name,
-                                               "USERNAME", &un))
-    return NULL;
-  return un;
-}
-
-
-/**
- * Write PID file.
- *
- * @param sctx service context
- * @param pid PID to write (should be equal to 'getpid()'
- * @return  #GNUNET_OK on success (including no work to be done)
- */
-static int
-write_pid_file (struct GNUNET_SERVICE_Context *sctx, pid_t pid)
-{
-  FILE *pidfd;
-  char *pif;
-  char *user;
-  char *rdir;
-  int len;
-
-  if (NULL == (pif = get_pid_file_name (sctx)))
-    return GNUNET_OK;           /* no file desired */
-  user = get_user_name (sctx);
-  rdir = GNUNET_strdup (pif);
-  len = strlen (rdir);
-  while ((len > 0) && (rdir[len] != DIR_SEPARATOR))
-    len--;
-  rdir[len] = '\0';
-  if (0 != ACCESS (rdir, F_OK))
-  {
-    /* we get to create a directory -- and claim it
-     * as ours! */
-    (void) GNUNET_DISK_directory_create (rdir);
-    if ((NULL != user) && (0 < strlen (user)))
-      GNUNET_DISK_file_change_owner (rdir, user);
-  }
-  if (0 != ACCESS (rdir, W_OK | X_OK))
-  {
-    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "access", rdir);
-    GNUNET_free (rdir);
-    GNUNET_free_non_null (user);
-    GNUNET_free (pif);
-    return GNUNET_SYSERR;
-  }
-  GNUNET_free (rdir);
-  pidfd = FOPEN (pif, "w");
-  if (NULL == pidfd)
-  {
-    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_ERROR, "fopen", pif);
-    GNUNET_free (pif);
-    GNUNET_free_non_null (user);
-    return GNUNET_SYSERR;
-  }
-  if (0 > FPRINTF (pidfd, "%u", pid))
-    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "fprintf", pif);
-  GNUNET_break (0 == FCLOSE (pidfd));
-  if ((NULL != user) && (0 < strlen (user)))
-    GNUNET_DISK_file_change_owner (pif, user);
-  GNUNET_free_non_null (user);
-  GNUNET_free (pif);
-  return GNUNET_OK;
-}
-
-
-/**
- * Task run during shutdown.  Stops the server/service.
- *
- * @param cls the `struct GNUNET_SERVICE_Context`
- */
-static void
-shutdown_task (void *cls)
-{
-  struct GNUNET_SERVICE_Context *service = cls;
-  struct GNUNET_SERVER_Handle *server = service->server;
-
-  service->shutdown_task = NULL;
-  if (0 != (service->options & GNUNET_SERVICE_OPTION_SOFT_SHUTDOWN))
-    GNUNET_SERVER_stop_listening (server);
-  else
-    GNUNET_SERVER_destroy (server);
-}
-
-
-/**
- * Initial task for the service.
- *
- * @param cls service context
- */
-static void
-service_task (void *cls)
-{
-  struct GNUNET_SERVICE_Context *sctx = cls;
-  unsigned int i;
-
-  (void) GNUNET_SPEEDUP_start_ (sctx->cfg);
-  GNUNET_RESOLVER_connect (sctx->cfg);
-  if (NULL != sctx->lsocks)
-    sctx->server
-      = GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks,
-                                           sctx->timeout, sctx->require_found);
-  else
-    sctx->server
-      = GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens,
-                              sctx->timeout, sctx->require_found);
-  if (NULL == sctx->server)
-  {
-    if (NULL != sctx->addrs)
-      for (i = 0; NULL != sctx->addrs[i]; i++)
-        LOG (GNUNET_ERROR_TYPE_INFO,
-             _("Failed to start `%s' at `%s'\n"),
-             sctx->service_name, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
-    sctx->ret = GNUNET_SYSERR;
-    return;
-  }
-#ifndef WINDOWS
-  if (NULL != sctx->addrs)
-    for (i = 0; NULL != sctx->addrs[i]; i++)
-      if ((AF_UNIX == sctx->addrs[i]->sa_family)
-          && ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0]))
-        GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path,
-                                     sctx->match_uid,
-                                     sctx->match_gid);
-#endif
-
-
-  if (0 == (sctx->options & GNUNET_SERVICE_OPTION_MANUAL_SHUTDOWN))
-  {
-    /* install a task that will kill the server
-     * process if the scheduler ever gets a shutdown signal */
-    sctx->shutdown_task = GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
-                                                        sctx);
-  }
-  sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
-  GNUNET_memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
-  i = 0;
-  while (NULL != sctx->my_handlers[i].callback)
-    sctx->my_handlers[i++].callback_cls = sctx;
-  GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers);
-  if (-1 != sctx->ready_confirm_fd)
-  {
-    GNUNET_break (1 == WRITE (sctx->ready_confirm_fd, ".", 1));
-    GNUNET_break (0 == CLOSE (sctx->ready_confirm_fd));
-    sctx->ready_confirm_fd = -1;
-    write_pid_file (sctx, getpid ());
-  }
-  if (NULL != sctx->addrs)
-  {
-    i = 0;
-    while (NULL != sctx->addrs[i])
-    {
-      LOG (GNUNET_ERROR_TYPE_INFO, _("Service `%s' runs at %s\n"),
-           sctx->service_name, GNUNET_a2s (sctx->addrs[i], sctx->addrlens[i]));
-      i++;
-    }
-  }
-  sctx->task (sctx->task_cls, sctx->server, sctx->cfg);
-}
-
-
-/**
- * Detach from terminal.
- *
- * @param sctx service context
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
- */
-static int
-detach_terminal (struct GNUNET_SERVICE_Context *sctx)
-{
-#ifndef MINGW
-  pid_t pid;
-  int nullfd;
-  int filedes[2];
-
-  if (0 != PIPE (filedes))
-  {
-    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "pipe");
-    return GNUNET_SYSERR;
-  }
-  pid = fork ();
-  if (pid < 0)
-  {
-    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "fork");
-    return GNUNET_SYSERR;
-  }
-  if (0 != pid)
-  {
-    /* Parent */
-    char c;
-
-    GNUNET_break (0 == CLOSE (filedes[1]));
-    c = 'X';
-    if (1 != READ (filedes[0], &c, sizeof (char)))
-      LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "read");
-    fflush (stdout);
-    switch (c)
-    {
-    case '.':
-      exit (0);
-    case 'I':
-      LOG (GNUNET_ERROR_TYPE_INFO, _("Service process failed to initialize\n"));
-      break;
-    case 'S':
-      LOG (GNUNET_ERROR_TYPE_INFO,
-           _("Service process could not initialize server function\n"));
-      break;
-    case 'X':
-      LOG (GNUNET_ERROR_TYPE_INFO,
-           _("Service process failed to report status\n"));
-      break;
-    }
-    exit (1);                   /* child reported error */
-  }
-  GNUNET_break (0 == CLOSE (0));
-  GNUNET_break (0 == CLOSE (1));
-  GNUNET_break (0 == CLOSE (filedes[0]));
-  nullfd = OPEN ("/dev/null", O_RDWR | O_APPEND);
-  if (nullfd < 0)
-    return GNUNET_SYSERR;
-  /* set stdin/stdout to /dev/null */
-  if ((dup2 (nullfd, 0) < 0) || (dup2 (nullfd, 1) < 0))
-  {
-    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "dup2");
-    (void) CLOSE (nullfd);
-    return GNUNET_SYSERR;
-  }
-  (void) CLOSE (nullfd);
-  /* Detach from controlling terminal */
-  pid = setsid ();
-  if (-1 == pid)
-    LOG_STRERROR (GNUNET_ERROR_TYPE_ERROR, "setsid");
-  sctx->ready_confirm_fd = filedes[1];
-#else
-  /* FIXME: we probably need to do something else
-   * elsewhere in order to fork the process itself... */
-  FreeConsole ();
-#endif
-  return GNUNET_OK;
-}
-
-
-/**
- * Set user ID.
- *
- * @param sctx service context
- * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
- */
-static int
-set_user_id (struct GNUNET_SERVICE_Context *sctx)
-{
-  char *user;
-
-  if (NULL == (user = get_user_name (sctx)))
-    return GNUNET_OK;           /* keep */
-#ifndef MINGW
-  struct passwd *pws;
-
-  errno = 0;
-  pws = getpwnam (user);
-  if (NULL == pws)
-  {
-    LOG (GNUNET_ERROR_TYPE_ERROR,
-         _("Cannot obtain information about user `%s': %s\n"), user,
-         errno == 0 ? _("No such user") : STRERROR (errno));
-    GNUNET_free (user);
-    return GNUNET_SYSERR;
-  }
-  if ((0 != setgid (pws->pw_gid)) || (0 != setegid (pws->pw_gid)) ||
-#if HAVE_INITGROUPS
-      (0 != initgroups (user, pws->pw_gid)) ||
-#endif
-      (0 != setuid (pws->pw_uid)) || (0 != seteuid (pws->pw_uid)))
-  {
-    if ((0 != setregid (pws->pw_gid, pws->pw_gid)) ||
-        (0 != setreuid (pws->pw_uid, pws->pw_uid)))
-    {
-      LOG (GNUNET_ERROR_TYPE_ERROR, _("Cannot change user/group to `%s': %s\n"),
-           user, STRERROR (errno));
-      GNUNET_free (user);
-      return GNUNET_SYSERR;
-    }
-  }
-#endif
-  GNUNET_free (user);
-  return GNUNET_OK;
-}
-
-
-/**
- * Delete the PID file that was created by our parent.
- *
- * @param sctx service context
- */
-static void
-pid_file_delete (struct GNUNET_SERVICE_Context *sctx)
-{
-  char *pif = get_pid_file_name (sctx);
-
-  if (NULL == pif)
-    return;                     /* no PID file */
-  if (0 != UNLINK (pif))
-    LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", pif);
-  GNUNET_free (pif);
-}
-
-
-/**
- * Run a standard GNUnet service startup sequence (initialize loggers
- * and configuration, parse options).
- *
- * @param argc number of command line arguments
- * @param argv command line arguments
- * @param service_name our service name
- * @param options service options
- * @param task main task of the service
- * @param task_cls closure for @a task
- * @return #GNUNET_SYSERR on error, #GNUNET_OK
- *         if we shutdown nicely
- */
-int
-GNUNET_SERVICE_run (int argc, char *const *argv,
-                    const char *service_name,
-                    enum GNUNET_SERVICE_Options options,
-                    GNUNET_SERVICE_Main task,
-                    void *task_cls)
-{
-#define HANDLE_ERROR do { GNUNET_break (0); goto shutdown; } while (0)
-
-  int err;
-  int ret;
-  char *cfg_fn;
-  char *opt_cfg_fn;
-  char *loglev;
-  char *logfile;
-  int do_daemonize;
-  unsigned int i;
-  unsigned long long skew_offset;
-  unsigned long long skew_variance;
-  long long clock_offset;
-  struct GNUNET_SERVICE_Context sctx;
-  struct GNUNET_CONFIGURATION_Handle *cfg;
-  const char *xdg;
-
-  struct GNUNET_GETOPT_CommandLineOption service_options[] = {
-    GNUNET_GETOPT_OPTION_CFG_FILE (&opt_cfg_fn),
-    {'d', "daemonize", NULL,
-     gettext_noop ("do daemonize (detach from terminal)"), 0,
-     GNUNET_GETOPT_set_one, &do_daemonize},
-    GNUNET_GETOPT_OPTION_HELP (NULL),
-    GNUNET_GETOPT_OPTION_LOGLEVEL (&loglev),
-    GNUNET_GETOPT_OPTION_LOGFILE (&logfile),
-    GNUNET_GETOPT_OPTION_VERSION (PACKAGE_VERSION " " VCS_VERSION),
-    GNUNET_GETOPT_OPTION_END
-  };
-  err = 1;
-  do_daemonize = 0;
-  logfile = NULL;
-  loglev = NULL;
-  opt_cfg_fn = NULL;
-  xdg = getenv ("XDG_CONFIG_HOME");
-  if (NULL != xdg)
-    GNUNET_asprintf (&cfg_fn,
-                     "%s%s%s",
-                     xdg,
-                     DIR_SEPARATOR_STR,
-                     GNUNET_OS_project_data_get ()->config_file);
-  else
-    cfg_fn = GNUNET_strdup (GNUNET_OS_project_data_get ()->user_config_file);
-  memset (&sctx, 0, sizeof (sctx));
-  sctx.options = options;
-  sctx.ready_confirm_fd = -1;
-  sctx.ret = GNUNET_OK;
-  sctx.timeout = GNUNET_TIME_UNIT_FOREVER_REL;
-  sctx.task = task;
-  sctx.task_cls = task_cls;
-  sctx.service_name = service_name;
-  sctx.cfg = cfg = GNUNET_CONFIGURATION_create ();
-
-  /* setup subsystems */
-  ret = GNUNET_GETOPT_run (service_name, service_options, argc, argv);
-  if (GNUNET_SYSERR == ret)
-    goto shutdown;
-  if (GNUNET_NO == ret)
-  {
-    err = 0;
-    goto shutdown;
-  }
-  if (GNUNET_OK != GNUNET_log_setup (service_name, loglev, logfile))
-    HANDLE_ERROR;
-  if (NULL == opt_cfg_fn)
-    opt_cfg_fn = GNUNET_strdup (cfg_fn);
-  if (GNUNET_YES == GNUNET_DISK_file_test (opt_cfg_fn))
-  {
-    if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, opt_cfg_fn))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  _("Malformed configuration file `%s', exit ...\n"),
-                  opt_cfg_fn);
-      goto shutdown;
-    }
-  }
-  else
-  {
-    if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, NULL))
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  _("Malformed configuration, exit ...\n"));
-      goto shutdown;
-    }
-    if (0 != strcmp (opt_cfg_fn, cfg_fn))
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                 _("Could not access configuration file `%s'\n"),
-                 opt_cfg_fn);
-  }
-  if (GNUNET_OK != setup_service (&sctx))
-    goto shutdown;
-  if ((1 == do_daemonize) && (GNUNET_OK != detach_terminal (&sctx)))
-    HANDLE_ERROR;
-  if (GNUNET_OK != set_user_id (&sctx))
-    goto shutdown;
-  LOG (GNUNET_ERROR_TYPE_DEBUG,
-       "Service `%s' runs with configuration from `%s'\n",
-       service_name,
-       opt_cfg_fn);
-  if ((GNUNET_OK ==
-       GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING",
-                                              "SKEW_OFFSET", &skew_offset)) &&
-      (GNUNET_OK ==
-       GNUNET_CONFIGURATION_get_value_number (sctx.cfg, "TESTING",
-                                              "SKEW_VARIANCE", &skew_variance)))
-  {
-    clock_offset = skew_offset - skew_variance;
-    GNUNET_TIME_set_offset (clock_offset);
-    LOG (GNUNET_ERROR_TYPE_DEBUG, "Skewing clock by %dll ms\n", clock_offset);
-  }
-  /* actually run service */
-  err = 0;
-  GNUNET_SCHEDULER_run (&service_task, &sctx);
-  /* shutdown */
-  if ((1 == do_daemonize) && (NULL != sctx.server))
-    pid_file_delete (&sctx);
-  GNUNET_free_non_null (sctx.my_handlers);
-
-shutdown:
-  if (-1 != sctx.ready_confirm_fd)
-  {
-    if (1 != WRITE (sctx.ready_confirm_fd, err ? "I" : "S", 1))
-      LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "write");
-    GNUNET_break (0 == CLOSE (sctx.ready_confirm_fd));
-  }
-#if HAVE_MALLINFO
-  {
-    char *counter;
-
-    if ( (GNUNET_YES ==
-         GNUNET_CONFIGURATION_have_value (sctx.cfg, service_name,
-                                          "GAUGER_HEAP")) &&
-        (GNUNET_OK ==
-         GNUNET_CONFIGURATION_get_value_string (sctx.cfg, service_name,
-                                                "GAUGER_HEAP",
-                                                &counter)) )
-    {
-      struct mallinfo mi;
-
-      mi = mallinfo ();
-      GAUGER (service_name, counter, mi.usmblks, "blocks");
-      GNUNET_free (counter);
-    }
-  }
-#endif
-  GNUNET_SPEEDUP_stop_ ();
-  GNUNET_CONFIGURATION_destroy (cfg);
-  i = 0;
-  if (NULL != sctx.addrs)
-    while (NULL != sctx.addrs[i])
-      GNUNET_free (sctx.addrs[i++]);
-  GNUNET_free_non_null (sctx.addrs);
-  GNUNET_free_non_null (sctx.addrlens);
-  GNUNET_free_non_null (logfile);
-  GNUNET_free_non_null (loglev);
-  GNUNET_free (cfg_fn);
-  GNUNET_free_non_null (opt_cfg_fn);
-  GNUNET_free_non_null (sctx.v4_denied);
-  GNUNET_free_non_null (sctx.v6_denied);
-  GNUNET_free_non_null (sctx.v4_allowed);
-  GNUNET_free_non_null (sctx.v6_allowed);
-
-  return err ? GNUNET_SYSERR : sctx.ret;
-}
-
-
-/**
- * Run a service startup sequence within an existing
- * initialized system.
- *
- * @param service_name our service name
- * @param cfg configuration to use
- * @param options service options
- * @return NULL on error, service handle
- */
-struct GNUNET_SERVICE_Context *
-GNUNET_SERVICE_start (const char *service_name,
-                      const struct GNUNET_CONFIGURATION_Handle *cfg,
-                     enum GNUNET_SERVICE_Options options)
-{
-  int i;
-  struct GNUNET_SERVICE_Context *sctx;
-
-  sctx = GNUNET_new (struct GNUNET_SERVICE_Context);
-  sctx->ready_confirm_fd = -1;  /* no daemonizing */
-  sctx->ret = GNUNET_OK;
-  sctx->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
-  sctx->service_name = service_name;
-  sctx->cfg = cfg;
-  sctx->options = options;
-
-  /* setup subsystems */
-  if (GNUNET_OK != setup_service (sctx))
-  {
-    GNUNET_SERVICE_stop (sctx);
-    return NULL;
-  }
-  if (NULL != sctx->lsocks)
-    sctx->server =
-        GNUNET_SERVER_create_with_sockets (&check_access, sctx, sctx->lsocks,
-                                           sctx->timeout, sctx->require_found);
-  else
-    sctx->server =
-        GNUNET_SERVER_create (&check_access, sctx, sctx->addrs, sctx->addrlens,
-                              sctx->timeout, sctx->require_found);
-
-  if (NULL == sctx->server)
-  {
-    GNUNET_SERVICE_stop (sctx);
-    return NULL;
-  }
-#ifndef WINDOWS
-  if (NULL != sctx->addrs)
-    for (i = 0; NULL != sctx->addrs[i]; i++)
-      if ((AF_UNIX == sctx->addrs[i]->sa_family)
-          && ('\0' != ((const struct sockaddr_un *)sctx->addrs[i])->sun_path[0]))
-        GNUNET_DISK_fix_permissions (((const struct sockaddr_un *)sctx->addrs[i])->sun_path,
-                                     sctx->match_uid,
-                                     sctx->match_gid);
-#endif
-  sctx->my_handlers = GNUNET_malloc (sizeof (defhandlers));
-  GNUNET_memcpy (sctx->my_handlers, defhandlers, sizeof (defhandlers));
-  i = 0;
-  while ((sctx->my_handlers[i].callback != NULL))
-    sctx->my_handlers[i++].callback_cls = sctx;
-  GNUNET_SERVER_add_handlers (sctx->server, sctx->my_handlers);
-  return sctx;
-}
-
-
-/**
- * Obtain the server used by a service.  Note that the server must NOT
- * be destroyed by the caller.
- *
- * @param ctx the service context returned from the start function
- * @return handle to the server for this service, NULL if there is none
- */
-struct GNUNET_SERVER_Handle *
-GNUNET_SERVICE_get_server (struct GNUNET_SERVICE_Context *ctx)
-{
-  return ctx->server;
-}
-
-
-/**
- * Get the NULL-terminated array of listen sockets for this service.
- *
- * @param ctx service context to query
- * @return NULL if there are no listen sockets, otherwise NULL-terminated
- *              array of listen sockets.
- */
-struct GNUNET_NETWORK_Handle *const*
-GNUNET_SERVICE_get_listen_sockets (struct GNUNET_SERVICE_Context *ctx)
-{
-  return ctx->lsocks;
-}
-
-
-/**
- * Stop a service that was started with "GNUNET_SERVICE_start".
- *
- * @param sctx the service context returned from the start function
- */
-void
-GNUNET_SERVICE_stop (struct GNUNET_SERVICE_Context *sctx)
-{
-  unsigned int i;
-
-#if HAVE_MALLINFO
-  {
-    char *counter;
-
-    if ( (GNUNET_YES ==
-         GNUNET_CONFIGURATION_have_value (sctx->cfg, sctx->service_name,
-                                          "GAUGER_HEAP")) &&
-        (GNUNET_OK ==
-         GNUNET_CONFIGURATION_get_value_string (sctx->cfg, sctx->service_name,
-                                                "GAUGER_HEAP",
-                                                &counter)) )
-    {
-      struct mallinfo mi;
-
-      mi = mallinfo ();
-      GAUGER (sctx->service_name, counter, mi.usmblks, "blocks");
-      GNUNET_free (counter);
-    }
-  }
-#endif
-  if (NULL != sctx->shutdown_task)
-  {
-    GNUNET_SCHEDULER_cancel (sctx->shutdown_task);
-    sctx->shutdown_task = NULL;
-  }
-  if (NULL != sctx->server)
-    GNUNET_SERVER_destroy (sctx->server);
-  GNUNET_free_non_null (sctx->my_handlers);
-  if (NULL != sctx->addrs)
-  {
-    i = 0;
-    while (NULL != sctx->addrs[i])
-      GNUNET_free (sctx->addrs[i++]);
-    GNUNET_free (sctx->addrs);
-  }
-  GNUNET_free_non_null (sctx->addrlens);
-  GNUNET_free_non_null (sctx->v4_denied);
-  GNUNET_free_non_null (sctx->v6_denied);
-  GNUNET_free_non_null (sctx->v4_allowed);
-  GNUNET_free_non_null (sctx->v6_allowed);
-  GNUNET_free (sctx);
-}
-
-
-/* end of service.c */
diff --git a/src/util/test_connection.c b/src/util/test_connection.c
deleted file mode 100644 (file)
index eaca75c..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C) 2009 GNUnet e.V.
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-/**
- * @file util/test_connection.c
- * @brief tests for connection.c
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-
-#define PORT 12435
-
-
-static struct GNUNET_CONNECTION_Handle *csock;
-
-static struct GNUNET_CONNECTION_Handle *asock;
-
-static struct GNUNET_CONNECTION_Handle *lsock;
-
-static size_t sofar;
-
-static struct GNUNET_NETWORK_Handle *ls;
-
-static struct GNUNET_CONFIGURATION_Handle *cfg;
-
-/**
- * Create and initialize a listen socket for the server.
- *
- * @return -1 on error, otherwise the listen socket
- */
-static struct GNUNET_NETWORK_Handle *
-open_listen_socket ()
-{
-  const static int on = 1;
-  struct sockaddr_in sa;
-  struct GNUNET_NETWORK_Handle *desc;
-
-  memset (&sa, 0, sizeof (sa));
-#if HAVE_SOCKADDR_IN_SIN_LEN
-  sa.sin_len = sizeof (sa);
-#endif
-  sa.sin_port = htons (PORT);
-  sa.sin_family = AF_INET;
-  desc = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
-  GNUNET_assert (desc != NULL);
-  if (GNUNET_NETWORK_socket_setsockopt
-      (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "setsockopt");
-  GNUNET_assert (GNUNET_OK ==
-                GNUNET_NETWORK_socket_bind (desc, (const struct sockaddr *) &sa,
-                                            sizeof (sa)));
-  GNUNET_NETWORK_socket_listen (desc, 5);
-  return desc;
-}
-
-static void
-receive_check (void *cls, const void *buf, size_t available,
-               const struct sockaddr *addr, socklen_t addrlen, int errCode)
-{
-  int *ok = cls;
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receive validates incoming data\n");
-  GNUNET_assert (buf != NULL);  /* no timeout */
-  if (0 == memcmp (&"Hello World"[sofar], buf, available))
-    sofar += available;
-  if (sofar < 12)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receive needs more data\n");
-    GNUNET_CONNECTION_receive (asock, 1024,
-                               GNUNET_TIME_relative_multiply
-                               (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check,
-                               cls);
-  }
-  else
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receive closes accepted socket\n");
-    *ok = 0;
-    GNUNET_CONNECTION_destroy (asock);
-    GNUNET_CONNECTION_destroy (csock);
-  }
-}
-
-
-static void
-run_accept (void *cls)
-{
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test accepts connection\n");
-  asock = GNUNET_CONNECTION_create_from_accept (NULL, NULL, ls);
-  GNUNET_assert (asock != NULL);
-  GNUNET_assert (GNUNET_YES == GNUNET_CONNECTION_check (asock));
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test destroys listen socket\n");
-  GNUNET_CONNECTION_destroy (lsock);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Test asks to receive on accepted socket\n");
-  GNUNET_CONNECTION_receive (asock, 1024,
-                             GNUNET_TIME_relative_multiply
-                             (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check,
-                             cls);
-}
-
-
-static size_t
-make_hello (void *cls, size_t size, void *buf)
-{
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Test prepares to transmit on connect socket\n");
-  GNUNET_assert (size >= 12);
-  strcpy ((char *) buf, "Hello World");
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test destroys client socket\n");
-  return 12;
-}
-
-
-static void
-task (void *cls)
-{
-  ls = open_listen_socket ();
-  lsock = GNUNET_CONNECTION_create_from_existing (ls);
-  GNUNET_assert (lsock != NULL);
-  csock = GNUNET_CONNECTION_create_from_connect (cfg, "localhost", PORT);
-  GNUNET_assert (csock != NULL);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test asks for write notification\n");
-  GNUNET_assert (NULL !=
-                 GNUNET_CONNECTION_notify_transmit_ready (csock, 12,
-                                                          GNUNET_TIME_UNIT_SECONDS,
-                                                          &make_hello, NULL));
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test prepares to accept\n");
-  GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, ls, &run_accept,
-                                 cls);
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  int ok;
-
-  GNUNET_log_setup ("test_connection",
-                    "WARNING",
-                    NULL);
-
-  ok = 1;
-  cfg = GNUNET_CONFIGURATION_create ();
-  GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME",
-                                         "localhost");
-  GNUNET_SCHEDULER_run (&task, &ok);
-  GNUNET_CONFIGURATION_destroy (cfg);
-  return ok;
-}
-
-/* end of test_connection.c */
diff --git a/src/util/test_connection_addressing.c b/src/util/test_connection_addressing.c
deleted file mode 100644 (file)
index a6345b1..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C) 2009 GNUnet e.V.
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-/**
- * @file util/test_connection_addressing.c
- * @brief tests for connection.c
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-
-
-#define PORT 12435
-
-
-static struct GNUNET_CONNECTION_Handle *csock;
-
-static struct GNUNET_CONNECTION_Handle *asock;
-
-static struct GNUNET_CONNECTION_Handle *lsock;
-
-static size_t sofar;
-
-static struct GNUNET_NETWORK_Handle *ls;
-
-
-
-/**
- * Create and initialize a listen socket for the server.
- *
- * @return NULL on error, otherwise the listen socket
- */
-static struct GNUNET_NETWORK_Handle *
-open_listen_socket ()
-{
-  const static int on = 1;
-  struct sockaddr_in sa;
-  struct GNUNET_NETWORK_Handle *desc;
-
-  memset (&sa, 0, sizeof (sa));
-#if HAVE_SOCKADDR_IN_SIN_LEN
-  sa.sin_len = sizeof (sa);
-#endif
-  sa.sin_family = AF_INET;
-  sa.sin_port = htons (PORT);
-  desc = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
-  GNUNET_assert (desc != 0);
-  if (GNUNET_NETWORK_socket_setsockopt
-      (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "setsockopt");
-  if (GNUNET_OK !=
-      GNUNET_NETWORK_socket_bind (desc, (const struct sockaddr *) &sa,
-                                  sizeof (sa)))
-  {
-    GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-                         "bind");
-    GNUNET_assert (0);
-  }
-  GNUNET_NETWORK_socket_listen (desc, 5);
-  return desc;
-}
-
-
-static void
-receive_check (void *cls, const void *buf, size_t available,
-               const struct sockaddr *addr, socklen_t addrlen, int errCode)
-{
-  int *ok = cls;
-
-  GNUNET_assert (buf != NULL);  /* no timeout */
-  if (0 == memcmp (&"Hello World"[sofar], buf, available))
-    sofar += available;
-  if (sofar < 12)
-  {
-    GNUNET_CONNECTION_receive (asock, 1024,
-                               GNUNET_TIME_relative_multiply
-                               (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check,
-                               cls);
-  }
-  else
-  {
-    *ok = 0;
-    GNUNET_CONNECTION_destroy (csock);
-    GNUNET_CONNECTION_destroy (asock);
-  }
-}
-
-
-static void
-run_accept (void *cls)
-{
-  void *addr;
-  size_t alen;
-  struct sockaddr_in *v4;
-  struct sockaddr_in expect;
-
-  asock = GNUNET_CONNECTION_create_from_accept (NULL, NULL, ls);
-  GNUNET_assert (asock != NULL);
-  GNUNET_assert (GNUNET_YES == GNUNET_CONNECTION_check (asock));
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_CONNECTION_get_address (asock, &addr, &alen));
-  GNUNET_assert (alen == sizeof (struct sockaddr_in));
-  v4 = addr;
-  memset (&expect, 0, sizeof (expect));
-#if HAVE_SOCKADDR_IN_SIN_LEN
-  expect.sin_len = sizeof (expect);
-#endif
-  expect.sin_family = AF_INET;
-  expect.sin_port = v4->sin_port;
-  expect.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-  GNUNET_assert (0 == memcmp (&expect, v4, alen));
-  GNUNET_free (addr);
-  GNUNET_CONNECTION_destroy (lsock);
-  GNUNET_CONNECTION_receive (asock, 1024,
-                             GNUNET_TIME_relative_multiply
-                             (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check,
-                             cls);
-}
-
-static size_t
-make_hello (void *cls, size_t size, void *buf)
-{
-  GNUNET_assert (size >= 12);
-  strcpy ((char *) buf, "Hello World");
-  return 12;
-}
-
-
-static void
-task (void *cls)
-{
-  struct sockaddr_in v4;
-
-  ls = open_listen_socket ();
-  lsock = GNUNET_CONNECTION_create_from_existing (ls);
-  GNUNET_assert (lsock != NULL);
-
-#if HAVE_SOCKADDR_IN_SIN_LEN
-  v4.sin_len = sizeof (v4);
-#endif
-  v4.sin_family = AF_INET;
-  v4.sin_port = htons (PORT);
-  v4.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-  csock =
-      GNUNET_CONNECTION_create_from_sockaddr (AF_INET,
-                                              (const struct sockaddr *) &v4,
-                                              sizeof (v4));
-  GNUNET_assert (csock != NULL);
-  GNUNET_assert (NULL !=
-                 GNUNET_CONNECTION_notify_transmit_ready (csock, 12,
-                                                          GNUNET_TIME_UNIT_SECONDS,
-                                                          &make_hello, NULL));
-  GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, ls, &run_accept,
-                                 cls);
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  int ok;
-
-  GNUNET_log_setup ("test_connection_addressing",
-                    "WARNING",
-                    NULL);
-  ok = 1;
-  GNUNET_SCHEDULER_run (&task, &ok);
-  return ok;
-}
-
-/* end of test_connection_addressing.c */
diff --git a/src/util/test_connection_receive_cancel.c b/src/util/test_connection_receive_cancel.c
deleted file mode 100644 (file)
index 9c0ab69..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C) 2009 GNUnet e.V.
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-/**
- * @file util/test_connection_receive_cancel.c
- * @brief tests for connection.c
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-
-#define PORT 12435
-
-
-static struct GNUNET_CONNECTION_Handle *csock;
-
-static struct GNUNET_CONNECTION_Handle *asock;
-
-static struct GNUNET_CONNECTION_Handle *lsock;
-
-static struct GNUNET_NETWORK_Handle *ls;
-
-static struct GNUNET_CONFIGURATION_Handle *cfg;
-
-
-/**
- * Create and initialize a listen socket for the server.
- *
- * @return NULL on error, otherwise the listen socket
- */
-static struct GNUNET_NETWORK_Handle *
-open_listen_socket ()
-{
-  const static int on = 1;
-  struct sockaddr_in sa;
-  struct GNUNET_NETWORK_Handle *desc;
-
-  memset (&sa, 0, sizeof (sa));
-#if HAVE_SOCKADDR_IN_SIN_LEN
-  sa.sin_len = sizeof (sa);
-#endif
-  sa.sin_family = AF_INET;
-  sa.sin_port = htons (PORT);
-  desc = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
-  GNUNET_assert (desc != NULL);
-  if (GNUNET_NETWORK_socket_setsockopt
-      (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-               "setsockopt");
-  GNUNET_assert (GNUNET_OK ==
-                GNUNET_NETWORK_socket_bind (desc, (const struct sockaddr *) &sa,
-                                            sizeof (sa)));
-  GNUNET_NETWORK_socket_listen (desc, 5);
-  return desc;
-}
-
-
-static void
-dead_receive (void *cls,
-             const void *buf,
-             size_t available,
-              const struct sockaddr *addr,
-             socklen_t addrlen,
-             int errCode)
-{
-  GNUNET_assert (0);
-}
-
-
-static void
-run_accept_cancel (void *cls)
-{
-  asock = GNUNET_CONNECTION_create_from_accept (NULL, NULL, ls);
-  GNUNET_assert (asock != NULL);
-  GNUNET_assert (GNUNET_YES == GNUNET_CONNECTION_check (asock));
-  GNUNET_CONNECTION_destroy (lsock);
-  GNUNET_CONNECTION_receive (asock, 1024,
-                             GNUNET_TIME_relative_multiply
-                             (GNUNET_TIME_UNIT_SECONDS, 5),
-                            &dead_receive, cls);
-}
-
-
-static void
-receive_cancel_task (void *cls)
-{
-  int *ok = cls;
-
-  GNUNET_CONNECTION_receive_cancel (asock);
-  GNUNET_CONNECTION_destroy (csock);
-  GNUNET_CONNECTION_destroy (asock);
-  *ok = 0;
-}
-
-
-static void
-task_receive_cancel (void *cls)
-{
-  ls = open_listen_socket ();
-  lsock = GNUNET_CONNECTION_create_from_existing (ls);
-  GNUNET_assert (lsock != NULL);
-  csock = GNUNET_CONNECTION_create_from_connect (cfg, "localhost", PORT);
-  GNUNET_assert (csock != NULL);
-  GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
-                                ls,
-                                 &run_accept_cancel,
-                                cls);
-  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
-                               &receive_cancel_task,
-                                cls);
-}
-
-
-/**
- * Main method, starts scheduler with task_timeout.
- */
-static int
-check_receive_cancel ()
-{
-  int ok;
-
-  ok = 1;
-  cfg = GNUNET_CONFIGURATION_create ();
-  GNUNET_CONFIGURATION_set_value_string (cfg,
-                                        "resolver",
-                                        "HOSTNAME",
-                                         "localhost");
-  GNUNET_SCHEDULER_run (&task_receive_cancel, &ok);
-  GNUNET_CONFIGURATION_destroy (cfg);
-  return ok;
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  int ret = 0;
-
-  GNUNET_log_setup ("test_connection_receive_cancel", "WARNING", NULL);
-  ret += check_receive_cancel ();
-
-  return ret;
-}
-
-/* end of test_connection_receive_cancel.c */
diff --git a/src/util/test_connection_timeout.c b/src/util/test_connection_timeout.c
deleted file mode 100644 (file)
index e78cec6..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C) 2009 GNUnet e.V.
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-/**
- * @file util/test_connection_timeout.c
- * @brief tests for connection.c
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-
-#define PORT 12435
-
-static struct GNUNET_CONNECTION_Handle *csock;
-
-static struct GNUNET_CONNECTION_Handle *lsock;
-
-static struct GNUNET_NETWORK_Handle *ls;
-
-static struct GNUNET_CONFIGURATION_Handle *cfg;
-
-
-/**
- * Create and initialize a listen socket for the server.
- *
- * @return NULL on error, otherwise the listen socket
- */
-static struct GNUNET_NETWORK_Handle *
-open_listen_socket ()
-{
-  const static int on = 1;
-  struct sockaddr_in sa;
-  struct GNUNET_NETWORK_Handle *desc;
-
-  memset (&sa, 0, sizeof (sa));
-#if HAVE_SOCKADDR_IN_SIN_LEN
-  sa.sin_len = sizeof (sa);
-#endif
-  sa.sin_family = AF_INET;
-  sa.sin_port = htons (PORT);
-  desc = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
-  GNUNET_assert (desc != NULL);
-  if (GNUNET_NETWORK_socket_setsockopt
-      (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, "setsockopt");
-  GNUNET_assert (GNUNET_OK ==
-                GNUNET_NETWORK_socket_bind (desc, (const struct sockaddr *) &sa,
-                                            sizeof (sa)));
-  GNUNET_NETWORK_socket_listen (desc, 5);
-  return desc;
-}
-
-
-static size_t
-send_kilo (void *cls, size_t size, void *buf)
-{
-  int *ok = cls;
-
-  if (size == 0)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got the desired timeout!\n");
-    GNUNET_assert (buf == NULL);
-    *ok = 0;
-    GNUNET_CONNECTION_destroy (lsock);
-    GNUNET_CONNECTION_destroy (csock);
-    return 0;
-  }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending kilo to fill buffer.\n");
-  GNUNET_assert (size >= 1024);
-  memset (buf, 42, 1024);
-
-  GNUNET_assert (NULL !=
-                 GNUNET_CONNECTION_notify_transmit_ready (csock, 1024,
-                                                          GNUNET_TIME_UNIT_SECONDS,
-                                                          &send_kilo, cls));
-  return 1024;
-}
-
-
-static void
-task_timeout (void *cls)
-{
-
-  ls = open_listen_socket ();
-  lsock = GNUNET_CONNECTION_create_from_existing (ls);
-  GNUNET_assert (lsock != NULL);
-  csock = GNUNET_CONNECTION_create_from_connect (cfg, "localhost", PORT);
-  GNUNET_assert (csock != NULL);
-  GNUNET_assert (NULL !=
-                 GNUNET_CONNECTION_notify_transmit_ready (csock, 1024,
-                                                          GNUNET_TIME_UNIT_SECONDS,
-                                                          &send_kilo, cls));
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  int ok;
-
-  GNUNET_log_setup ("test_connection_timeout",
-                    "WARNING",
-                    NULL);
-
-  ok = 1;
-  cfg = GNUNET_CONFIGURATION_create ();
-  GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME",
-                                         "localhost");
-  GNUNET_SCHEDULER_run (&task_timeout, &ok);
-  GNUNET_CONFIGURATION_destroy (cfg);
-  return ok;
-}
-
-/* end of test_connection_timeout.c */
diff --git a/src/util/test_connection_timeout_no_connect.c b/src/util/test_connection_timeout_no_connect.c
deleted file mode 100644 (file)
index ebcd4b7..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C) 2009 GNUnet e.V.
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-/**
- * @file util/test_connection_timeout_no_connect.c
- * @brief tests for connection.c, doing timeout which connect failure
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-
-#define PORT 13425
-
-static struct GNUNET_CONNECTION_Handle *csock;
-
-static struct GNUNET_CONFIGURATION_Handle *cfg;
-
-static size_t
-handle_timeout (void *cls, size_t size, void *buf)
-{
-  int *ok = cls;
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received timeout signal.\n");
-  GNUNET_assert (size == 0);
-  GNUNET_assert (buf == NULL);
-  *ok = 0;
-  return 0;
-}
-
-
-static void
-task_timeout (void *cls)
-{
-  csock = GNUNET_CONNECTION_create_from_connect (cfg, "localhost", PORT);
-  GNUNET_assert (csock != NULL);
-  GNUNET_assert (NULL !=
-                 GNUNET_CONNECTION_notify_transmit_ready (csock, 1024,
-                                                          GNUNET_TIME_UNIT_SECONDS,
-                                                          &handle_timeout,
-                                                          cls));
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  int ok;
-
-  GNUNET_log_setup ("test_connection_timeout_no_connect",
-                    "WARNING",
-                    NULL);
-  ok = 1;
-  cfg = GNUNET_CONFIGURATION_create ();
-  GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME",
-                                         "localhost");
-  GNUNET_SCHEDULER_run (&task_timeout, &ok);
-  GNUNET_CONFIGURATION_destroy (cfg);
-  return ok;
-}
-
-/* end of test_connection_timeout_no_connect.c */
diff --git a/src/util/test_connection_transmit_cancel.c b/src/util/test_connection_transmit_cancel.c
deleted file mode 100644 (file)
index 9ef0720..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C) 2009 GNUnet e.V.
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-/**
- * @file util/test_connection_transmit_cancel.c
- * @brief tests for connection.c
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-
-#define PORT 12435
-
-static struct GNUNET_CONFIGURATION_Handle *cfg;
-
-
-static size_t
-not_run (void *cls, size_t size, void *buf)
-{
-  GNUNET_assert (0);
-  return 0;
-}
-
-
-static void
-task_transmit_cancel (void *cls)
-{
-  int *ok = cls;
-  struct GNUNET_CONNECTION_TransmitHandle *th;
-  struct GNUNET_CONNECTION_Handle *csock;
-
-  csock = GNUNET_CONNECTION_create_from_connect (cfg, "localhost", PORT);
-  GNUNET_assert (csock != NULL);
-  th = GNUNET_CONNECTION_notify_transmit_ready (csock, 12,
-                                                GNUNET_TIME_UNIT_MINUTES,
-                                                &not_run, cls);
-  GNUNET_assert (NULL != th);
-  GNUNET_CONNECTION_notify_transmit_ready_cancel (th);
-  GNUNET_CONNECTION_destroy (csock);
-  *ok = 0;
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  int ok;
-
-  GNUNET_log_setup ("test_connection_transmit_cancel",
-                    "WARNING",
-                    NULL);
-  ok = 1;
-  cfg = GNUNET_CONFIGURATION_create ();
-  GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME",
-                                         "localhost");
-  GNUNET_SCHEDULER_run (&task_transmit_cancel, &ok);
-  GNUNET_CONFIGURATION_destroy (cfg);
-  return ok;
-}
-
-/* end of test_connection_transmit_cancel.c */
diff --git a/src/util/test_server.c b/src/util/test_server.c
deleted file mode 100644 (file)
index 8003adb..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C) 2009, 2010, 2014, 2016 GNUnet e.V.
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-/**
- * @file util/test_server.c
- * @brief tests for server.c
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-
-/**
- * TCP port to use for the server.
- */
-#define PORT 12435
-
-/**
- * Timeout to use for operations.
- */
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2)
-
-/**
- * Test message type.
- */
-#define MY_TYPE 128
-
-/**
- * Test message type.
- */
-#define MY_TYPE2 129
-
-/**
- * Handle for the server.
- */
-static struct GNUNET_SERVER_Handle *server;
-
-/**
- * Handle for the client.
- */
-static struct GNUNET_MQ_Handle *mq;
-
-/**
- * Handle of the server for the client.
- */
-static struct GNUNET_SERVER_Client *argclient;
-
-/**
- * Our configuration.
- */
-static struct GNUNET_CONFIGURATION_Handle *cfg;
-
-/**
- * Number indiciating in which phase of the test we are.
- */
-static int ok;
-
-
-/**
- * Final task invoked to clean up.
- *
- * @param cls NULL
- */
-static void
-finish_up (void *cls)
-{
-  GNUNET_assert (7 == ok);
-  ok = 0;
-  GNUNET_SERVER_destroy (server);
-  GNUNET_MQ_destroy (mq);
-  GNUNET_CONFIGURATION_destroy (cfg);
-}
-
-
-/**
- * The server has received the second message, initiate clean up.
- *
- * @param cls NULL
- * @param client client we got the message from
- * @param message the message
- */
-static void
-recv_fin_cb (void *cls,
-             struct GNUNET_SERVER_Client *client,
-             const struct GNUNET_MessageHeader *message)
-{
-  GNUNET_assert (6 == ok);
-  ok = 7;
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
-  GNUNET_SCHEDULER_add_now (&finish_up, NULL);
-}
-
-
-/**
- * We have received the reply from the server, check that we are at
- * the right stage and queue the next message to the server.  Cleans
- * up #argclient.
- *
- * @param cls NULL
- * @param msg message we got from the server
- */
-static void
-handle_reply (void *cls,
-              const struct GNUNET_MessageHeader *msg)
-{
-  struct GNUNET_MQ_Envelope *env;
-  struct GNUNET_MessageHeader *m;
-
-  GNUNET_assert (4 == ok);
-  ok = 6;
-  env = GNUNET_MQ_msg (m,
-                       MY_TYPE2);
-  GNUNET_MQ_send (mq,
-                  env);
-}
-
-
-/**
- * Send a reply of type #MY_TYPE from the server to the client.
- * Checks that we are in the right phase and transmits the
- * reply.  Cleans up #argclient state.
- *
- * @param cls NULL
- * @param size number of bytes we are allowed to send
- * @param buf where to copy the reply
- * @return number of bytes written to @a buf
- */
-static size_t
-reply_msg (void *cls,
-           size_t size,
-           void *buf)
-{
-  struct GNUNET_MessageHeader msg;
-
-  GNUNET_assert (3 == ok);
-  ok = 4;
-  GNUNET_assert (size >= sizeof (struct GNUNET_MessageHeader));
-  msg.type = htons (MY_TYPE);
-  msg.size = htons (sizeof (struct GNUNET_MessageHeader));
-  GNUNET_memcpy (buf, &msg, sizeof (struct GNUNET_MessageHeader));
-  GNUNET_assert (NULL != argclient);
-  GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
-  GNUNET_SERVER_client_drop (argclient);
-  argclient = NULL;
-  return sizeof (struct GNUNET_MessageHeader);
-}
-
-
-/**
- * Function called whenever the server receives a message of
- * type #MY_TYPE.  Checks that we are at the stage where
- * we expect the first message, then sends a reply.  Stores
- * the handle to the client in #argclient.
- *
- * @param cls NULL
- * @param client client that sent the message
- * @param message the message we received
- */
-static void
-recv_cb (void *cls,
-         struct GNUNET_SERVER_Client *client,
-         const struct GNUNET_MessageHeader *message)
-{
-  GNUNET_assert (2 == ok);
-  ok = 3;
-  argclient = client;
-  GNUNET_SERVER_client_keep (argclient);
-  GNUNET_assert (sizeof (struct GNUNET_MessageHeader) == ntohs (message->size));
-  GNUNET_assert (MY_TYPE == ntohs (message->type));
-  GNUNET_assert (NULL !=
-                 GNUNET_SERVER_notify_transmit_ready (client,
-                                                      ntohs (message->size),
-                                                      TIMEOUT,
-                                                      &reply_msg,
-                                                      NULL));
-}
-
-
-/**
- * Message handlers for the server.
- */
-static struct GNUNET_SERVER_MessageHandler handlers[] = {
-  {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)},
-  {&recv_fin_cb, NULL, MY_TYPE2, sizeof (struct GNUNET_MessageHeader)},
-  {NULL, NULL, 0, 0}
-};
-
-
-/**
- * Generic error handler, called with the appropriate error code and
- * the same closure specified at the creation of the message queue.
- * Not every message queue implementation supports an error handler.
- *
- * @param cls closure with the `struct GNUNET_STATISTICS_Handle *`
- * @param error error code
- */
-static void
-mq_error_handler (void *cls,
-                  enum GNUNET_MQ_Error error)
-{
-  GNUNET_assert (0); /* should never happen */
-}
-
-
-/**
- * First task run by the scheduler.  Initializes the server and
- * a client and asks for a transmission from the client to the
- * server.
- *
- * @param cls NULL
- */
-static void
-task (void *cls)
-{
-  struct sockaddr_in sa;
-  struct sockaddr *sap[2];
-  socklen_t slens[2];
-  struct GNUNET_MQ_Envelope *env;
-  struct GNUNET_MessageHeader *msg;
-  struct GNUNET_MQ_MessageHandler chandlers[] = {
-    GNUNET_MQ_hd_fixed_size (reply,
-                             MY_TYPE,
-                             struct GNUNET_MessageHeader,
-                             cls),
-    GNUNET_MQ_handler_end ()
-  };
-
-  sap[0] = (struct sockaddr *) &sa;
-  slens[0] = sizeof (sa);
-  sap[1] = NULL;
-  slens[1] = 0;
-  memset (&sa, 0, sizeof (sa));
-#if HAVE_SOCKADDR_IN_SIN_LEN
-  sa.sin_len = sizeof (sa);
-#endif
-  sa.sin_family = AF_INET;
-  sa.sin_port = htons (PORT);
-  server = GNUNET_SERVER_create (NULL, NULL,
-                                 sap, slens,
-                                 TIMEOUT, GNUNET_NO);
-  GNUNET_assert (server != NULL);
-  GNUNET_SERVER_add_handlers (server, handlers);
-  cfg = GNUNET_CONFIGURATION_create ();
-  GNUNET_CONFIGURATION_set_value_number (cfg,
-                                         "test-server",
-                                         "PORT",
-                                         PORT);
-  GNUNET_CONFIGURATION_set_value_string (cfg,
-                                         "test-server",
-                                         "HOSTNAME",
-                                         "localhost");
-  GNUNET_CONFIGURATION_set_value_string (cfg,
-                                         "resolver",
-                                         "HOSTNAME",
-                                         "localhost");
-  mq = GNUNET_CLIENT_connect (cfg,
-                              "test-server",
-                              chandlers,
-                              &mq_error_handler,
-                              NULL);
-  GNUNET_assert (NULL != mq);
-  ok = 2;
-  env = GNUNET_MQ_msg (msg,
-                       MY_TYPE);
-  GNUNET_MQ_send (mq,
-                  env);
-}
-
-
-/**
- * Runs the test.
- *
- * @param argc length of @a argv
- * @param argv command line arguments (ignored)
- * @return 0 on success, otherwise phase of failure
- */
-int
-main (int argc, char *argv[])
-{
-  GNUNET_log_setup ("test_server",
-                    "WARNING",
-                    NULL);
-  ok = 1;
-  GNUNET_SCHEDULER_run (&task, &ok);
-  return ok;
-}
-
-/* end of test_server.c */
diff --git a/src/util/test_server_disconnect.c b/src/util/test_server_disconnect.c
deleted file mode 100644 (file)
index c3d003e..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C) 2009, 2010, 2016 GNUnet e.V.
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-/**
- * @file util/test_server_disconnect.c
- * @brief tests for server.c,  specifically GNUNET_SERVER_client_disconnect
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-
-
-#define PORT 12435
-
-#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250)
-
-#define MY_TYPE 128
-
-static struct GNUNET_SERVER_Handle *server;
-
-static struct GNUNET_MQ_Handle *mq;
-
-static struct GNUNET_CONFIGURATION_Handle *cfg;
-
-static int ok;
-
-
-static void
-finish_up (void *cls)
-{
-  GNUNET_assert (ok == 5);
-  ok = 0;
-  GNUNET_SERVER_destroy (server);
-  GNUNET_MQ_destroy (mq);
-  GNUNET_CONFIGURATION_destroy (cfg);
-}
-
-
-static void
-notify_disconnect (void *cls,
-                   struct GNUNET_SERVER_Client *clientarg)
-{
-  if (NULL == clientarg)
-    return;
-  GNUNET_assert (ok == 4);
-  ok = 5;
-  GNUNET_SCHEDULER_add_now (&finish_up, NULL);
-}
-
-
-static void
-server_disconnect (void *cls)
-{
-  struct GNUNET_SERVER_Client *argclient = cls;
-
-  GNUNET_assert (ok == 3);
-  ok = 4;
-  GNUNET_SERVER_client_disconnect (argclient);
-  GNUNET_SERVER_client_drop (argclient);
-}
-
-
-static void
-recv_cb (void *cls,
-        struct GNUNET_SERVER_Client *client,
-         const struct GNUNET_MessageHeader *message)
-{
-  GNUNET_assert (ok == 2);
-  ok = 3;
-  GNUNET_SERVER_client_keep (client);
-  GNUNET_SCHEDULER_add_now (&server_disconnect, client);
-  GNUNET_assert (sizeof (struct GNUNET_MessageHeader) == ntohs (message->size));
-  GNUNET_assert (MY_TYPE == ntohs (message->type));
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
-}
-
-
-static struct GNUNET_SERVER_MessageHandler handlers[] = {
-  {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)},
-  {NULL, NULL, 0, 0}
-};
-
-
-static void
-task (void *cls)
-{
-  struct sockaddr_in sa;
-  struct sockaddr *sap[2];
-  socklen_t slens[2];
-  struct GNUNET_MQ_Envelope *env;
-  struct GNUNET_MessageHeader *msg;
-
-  sap[0] = (struct sockaddr *) &sa;
-  slens[0] = sizeof (sa);
-  sap[1] = NULL;
-  slens[1] = 0;
-  memset (&sa, 0, sizeof (sa));
-#if HAVE_SOCKADDR_IN_SIN_LEN
-  sa.sin_len = sizeof (sa);
-#endif
-  sa.sin_family = AF_INET;
-  sa.sin_port = htons (PORT);
-  server = GNUNET_SERVER_create (NULL, NULL, sap, slens, TIMEOUT, GNUNET_NO);
-  GNUNET_assert (server != NULL);
-  GNUNET_SERVER_add_handlers (server, handlers);
-  GNUNET_SERVER_disconnect_notify (server, &notify_disconnect, NULL);
-  cfg = GNUNET_CONFIGURATION_create ();
-  GNUNET_CONFIGURATION_set_value_number (cfg, "test-server", "PORT", PORT);
-  GNUNET_CONFIGURATION_set_value_string (cfg, "test-server", "HOSTNAME",
-                                         "localhost");
-  GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME",
-                                         "localhost");
-  mq = GNUNET_CLIENT_connect (cfg,
-                              "test-server",
-                              NULL,
-                              NULL,
-                              NULL);
-  GNUNET_assert (NULL != mq);
-  ok = 2;
-  env = GNUNET_MQ_msg (msg,
-                       MY_TYPE);
-  GNUNET_MQ_send (mq,
-                  env);
-}
-
-
-/**
- * Main method, starts scheduler with task1,
- * checks that "ok" is correct at the end.
- */
-static int
-check ()
-{
-  ok = 1;
-  GNUNET_SCHEDULER_run (&task, &ok);
-  return ok;
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  int ret = 0;
-
-  GNUNET_log_setup ("test_server_disconnect", "WARNING", NULL);
-  ret += check ();
-
-  return ret;
-}
-
-/* end of test_server_disconnect.c */
diff --git a/src/util/test_server_mst_interrupt.c b/src/util/test_server_mst_interrupt.c
deleted file mode 100644 (file)
index 3141a75..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C) 2009, 2010 GNUnet e.V.
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-/**
- * @file util/test_server_mst_interrupt.c
- * @brief test for interrupt message processing in server_mst.c
- */
-#include "platform.h"
-#include "gnunet_protocols.h"
-#include "gnunet_util_lib.h"
-
-static struct GNUNET_SERVER_MessageStreamTokenizer * mst;
-
-
-/* Callback destroying mst with data in buffer */
-static int
-mst_cb (void *cls, void *client,
-        const struct GNUNET_MessageHeader * message)
-{
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MST gave me message, destroying\n");
-  GNUNET_SERVER_mst_destroy (mst);
-  return GNUNET_SYSERR;
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  struct GNUNET_PeerIdentity id;
-  struct GNUNET_MessageHeader msg[2];
-
-  GNUNET_log_setup ("test_server_mst_interrupt", "WARNING", NULL);
-  memset (&id, 0, sizeof (id));
-  msg[0].size = htons (sizeof (msg));
-  msg[0].type = htons (sizeof (GNUNET_MESSAGE_TYPE_DUMMY));
-  mst = GNUNET_SERVER_mst_create(mst_cb, NULL);
-  GNUNET_SERVER_mst_receive (mst, &id,
-                            (const char *) &msg, 2 * sizeof (msg),
-                            GNUNET_NO, GNUNET_NO);
-  /* If we reach this line, it did not crash */
-  return 0;
-}
-
-/* end of test_server_mst_interrupt.c */
diff --git a/src/util/test_server_with_client.c b/src/util/test_server_with_client.c
deleted file mode 100644 (file)
index 63bfda0..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C) 2009, 2016 GNUnet e.V.
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-/**
- * @file util/test_server_with_client.c
- * @brief tests for server.c and client.c,
- *       specifically disconnect_notify,
- *       client_get_address and receive_done (resume processing)
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-
-#define PORT 22335
-
-#define MY_TYPE 128
-
-
-static struct GNUNET_SERVER_Handle *server;
-
-static struct GNUNET_MQ_Handle *mq;
-
-static struct GNUNET_CONFIGURATION_Handle *cfg;
-
-static int ok;
-
-
-static void
-send_done (void *cls)
-{
-  struct GNUNET_SERVER_Client *argclient = cls;
-
-  GNUNET_assert (ok == 3);
-  ok++;
-  GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
-}
-
-
-static void
-recv_cb (void *cls,
-         struct GNUNET_SERVER_Client *argclient,
-         const struct GNUNET_MessageHeader *message)
-{
-  void *addr;
-  size_t addrlen;
-  struct sockaddr_in sa;
-  struct sockaddr_in *have;
-
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_SERVER_client_get_address (argclient,
-                                                   &addr,
-                                                   &addrlen));
-
-  GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
-  have = addr;
-  memset (&sa, 0, sizeof (sa));
-#if HAVE_SOCKADDR_IN_SIN_LEN
-  sa.sin_len = sizeof (sa);
-#endif
-  sa.sin_family = AF_INET;
-  sa.sin_port = have->sin_port;
-  sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-  GNUNET_assert (0 == memcmp (&sa, addr, addrlen));
-  GNUNET_free (addr);
-  switch (ok)
-  {
-  case 2:
-    ok++;
-    GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
-                                  (GNUNET_TIME_UNIT_MILLISECONDS, 50),
-                                  &send_done,
-                                  argclient);
-    break;
-  case 4:
-    ok++;
-    GNUNET_MQ_destroy (mq);
-    GNUNET_SERVER_receive_done (argclient,
-                                GNUNET_OK);
-    break;
-  default:
-    GNUNET_assert (0);
-  }
-
-}
-
-
-static void
-clean_up (void *cls)
-{
-  GNUNET_SERVER_destroy (server);
-  server = NULL;
-  GNUNET_CONFIGURATION_destroy (cfg);
-  cfg = NULL;
-}
-
-
-/**
- * Functions with this signature are called whenever a client
- * is disconnected on the network level.
- *
- * @param cls closure
- * @param client identification of the client
- */
-static void
-notify_disconnect (void *cls,
-                   struct GNUNET_SERVER_Client *client)
-{
-  if (client == NULL)
-    return;
-  GNUNET_assert (ok == 5);
-  ok = 0;
-  GNUNET_SCHEDULER_add_now (&clean_up, NULL);
-}
-
-
-static struct GNUNET_SERVER_MessageHandler handlers[] = {
-  {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)},
-  {NULL, NULL, 0, 0}
-};
-
-
-static void
-task (void *cls)
-{
-  struct sockaddr_in sa;
-  struct sockaddr *sap[2];
-  socklen_t slens[2];
-  struct GNUNET_MQ_Envelope *env;
-  struct GNUNET_MessageHeader *msg;
-
-  sap[0] = (struct sockaddr *) &sa;
-  slens[0] = sizeof (sa);
-  sap[1] = NULL;
-  slens[1] = 0;
-  memset (&sa, 0, sizeof (sa));
-#if HAVE_SOCKADDR_IN_SIN_LEN
-  sa.sin_len = sizeof (sa);
-#endif
-  sa.sin_family = AF_INET;
-  sa.sin_port = htons (PORT);
-  server =
-      GNUNET_SERVER_create (NULL, NULL, sap, slens,
-                            GNUNET_TIME_relative_multiply
-                            (GNUNET_TIME_UNIT_MILLISECONDS, 250), GNUNET_NO);
-  GNUNET_assert (server != NULL);
-  handlers[0].callback_cls = cls;
-  GNUNET_SERVER_add_handlers (server, handlers);
-  GNUNET_SERVER_disconnect_notify (server, &notify_disconnect, cls);
-  cfg = GNUNET_CONFIGURATION_create ();
-  GNUNET_CONFIGURATION_set_value_number (cfg, "test", "PORT", PORT);
-  GNUNET_CONFIGURATION_set_value_string (cfg, "test", "HOSTNAME", "localhost");
-  GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME",
-                                         "localhost");
-  mq = GNUNET_CLIENT_connect (cfg,
-                              "test",
-                              NULL,
-                              NULL,
-                              NULL);
-  GNUNET_assert (NULL != mq);
-  ok = 2;
-  env = GNUNET_MQ_msg (msg,
-                       MY_TYPE);
-  GNUNET_MQ_send (mq,
-                  env);
-  env = GNUNET_MQ_msg (msg,
-                       MY_TYPE);
-  GNUNET_MQ_send (mq,
-                  env);
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  GNUNET_log_setup ("test_server_with_client",
-                    "WARNING",
-                    NULL);
-  ok = 1;
-  GNUNET_SCHEDULER_run (&task, NULL);
-  return ok;
-}
-
-/* end of test_server_with_client.c */
diff --git a/src/util/test_server_with_client_unix.c b/src/util/test_server_with_client_unix.c
deleted file mode 100644 (file)
index 8fabbe2..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
-     This file is part of GNUnet.
-     Copyright (C) 2009, 2016 GNUnet e.V.
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-     Boston, MA 02110-1301, USA.
-*/
-/**
- * @file util/test_server_with_client_unix.c
- * @brief tests for server.c and client.c,
- *       specifically disconnect_notify,
- *       client_get_address and receive_done (resume processing)
- */
-#include "platform.h"
-#include "gnunet_util_lib.h"
-
-#define MY_TYPE 128
-
-
-static struct GNUNET_SERVER_Handle *server;
-
-static struct GNUNET_MQ_Handle *mq;
-
-static struct GNUNET_CONFIGURATION_Handle *cfg;
-
-static int ok;
-
-
-static void
-send_done (void *cls)
-{
-  struct GNUNET_SERVER_Client *argclient = cls;
-
-  GNUNET_assert (ok == 3);
-  ok++;
-  GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
-}
-
-
-static void
-recv_cb (void *cls,
-        struct GNUNET_SERVER_Client *argclient,
-         const struct GNUNET_MessageHeader *message)
-{
-  switch (ok)
-  {
-  case 2:
-    ok++;
-    (void) GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
-                                        (GNUNET_TIME_UNIT_MILLISECONDS, 50),
-                                        &send_done,
-                                        argclient);
-    break;
-  case 4:
-    ok++;
-    GNUNET_MQ_destroy (mq);
-    GNUNET_SERVER_receive_done (argclient, GNUNET_OK);
-    break;
-  default:
-    GNUNET_assert (0);
-  }
-
-}
-
-
-static void
-clean_up (void *cls)
-{
-  GNUNET_SERVER_destroy (server);
-  server = NULL;
-  GNUNET_CONFIGURATION_destroy (cfg);
-  cfg = NULL;
-}
-
-
-/**
- * Functions with this signature are called whenever a client
- * is disconnected on the network level.
- *
- * @param cls closure
- * @param client identification of the client
- */
-static void
-notify_disconnect (void *cls,
-                  struct GNUNET_SERVER_Client *client)
-{
-  if (client == NULL)
-    return;
-  GNUNET_assert (ok == 5);
-  ok = 0;
-  (void) GNUNET_SCHEDULER_add_now (&clean_up, NULL);
-}
-
-
-static struct GNUNET_SERVER_MessageHandler handlers[] = {
-  {&recv_cb, NULL, MY_TYPE, sizeof (struct GNUNET_MessageHeader)},
-  {NULL, NULL, 0, 0}
-};
-
-
-static void
-task (void *cls)
-{
-  struct sockaddr_un un;
-  const char *unixpath = "/tmp/testsock";
-  struct sockaddr *sap[2];
-  socklen_t slens[2];
-  struct GNUNET_MQ_Envelope *env;
-  struct GNUNET_MessageHeader *msg;
-
-  memset (&un, 0, sizeof (un));
-  un.sun_family = AF_UNIX;
-  strncpy(un.sun_path, unixpath, sizeof (un.sun_path) - 1);
-#if HAVE_SOCKADDR_UN_SUN_LEN
-  un.sun_len = (u_char) sizeof (un);
-#endif
-
-  sap[0] = (struct sockaddr *) &un;
-  slens[0] = sizeof (un);
-  sap[1] = NULL;
-  slens[1] = 0;
-  server =
-      GNUNET_SERVER_create (NULL, NULL, sap, slens,
-                            GNUNET_TIME_relative_multiply
-                            (GNUNET_TIME_UNIT_MILLISECONDS, 250), GNUNET_NO);
-  GNUNET_assert (server != NULL);
-  handlers[0].callback_cls = cls;
-  GNUNET_SERVER_add_handlers (server, handlers);
-  GNUNET_SERVER_disconnect_notify (server, &notify_disconnect, cls);
-  cfg = GNUNET_CONFIGURATION_create ();
-
-  GNUNET_CONFIGURATION_set_value_string (cfg, "test", "UNIXPATH", unixpath);
-  GNUNET_CONFIGURATION_set_value_string (cfg, "resolver", "HOSTNAME",
-                                         "localhost");
-  mq = GNUNET_CLIENT_connect (cfg,
-                              "test",
-                              NULL,
-                              NULL,
-                              NULL);
-  GNUNET_assert (NULL != mq);
-  ok = 2;
-  env = GNUNET_MQ_msg (msg,
-                       MY_TYPE);
-  GNUNET_MQ_send (mq,
-                  env);
-  env = GNUNET_MQ_msg (msg,
-                       MY_TYPE);
-  GNUNET_MQ_send (mq,
-                  env);
-}
-
-
-int
-main (int argc, char *argv[])
-{
-  GNUNET_log_setup ("test_server_with_client_unix",
-                    "WARNING",
-                    NULL);
-  ok = 1;
-  GNUNET_SCHEDULER_run (&task, NULL);
-  return ok;
-}
-
-/* end of test_server_with_client_unix.c */
index ab0b00d763fe9ee862cbb5df4fd82f02e3c13f0b..4759f374661e0ba46c4969ee0383ba5e8eade6a6 100644 (file)
@@ -2217,12 +2217,10 @@ route_packet (struct DestinationEntry *destination,
  * and forward the packet.
  *
  * @param cls closure, NULL
- * @param client NULL
  * @param message message we got from the client (VPN channel interface)
  */
 static int
 message_token (void *cls,
-              void *client,
                const struct GNUNET_MessageHeader *message)
 {
   const struct GNUNET_TUN_Layer2PacketHeader *tun;