gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r14330 - gnunet/src/transport


From: gnunet
Subject: [GNUnet-SVN] r14330 - gnunet/src/transport
Date: Thu, 3 Feb 2011 17:11:50 +0100

Author: nevans
Date: 2011-02-03 17:11:49 +0100 (Thu, 03 Feb 2011)
New Revision: 14330

Added:
   gnunet/src/transport/plugin_transport_unix.c
   gnunet/src/transport/test_quota_compliance_unix_peer1.conf
   gnunet/src/transport/test_quota_compliance_unix_peer2.conf
   gnunet/src/transport/test_transport_api_unix_peer1.conf
   gnunet/src/transport/test_transport_api_unix_peer2.conf
   gnunet/src/transport/test_transport_api_unreliability.c
Modified:
   gnunet/src/transport/Makefile.am
   gnunet/src/transport/plugin_transport_udp.c
   gnunet/src/transport/test_quota_compliance.c
   gnunet/src/transport/test_transport_api.c
   gnunet/src/transport/test_transport_api_reliability.c
Log:
unix domain socket transport, associated test cases

Modified: gnunet/src/transport/Makefile.am
===================================================================
--- gnunet/src/transport/Makefile.am    2011-02-03 16:09:06 UTC (rev 14329)
+++ gnunet/src/transport/Makefile.am    2011-02-03 16:11:49 UTC (rev 14330)
@@ -43,6 +43,10 @@
 endif
 
 if LINUX
+UNIX_PLUGIN_LA = libgnunet_plugin_transport_unix.la
+UNIX_PLUGIN_TEST = test_transport_api_unix
+UNIX_REL_TEST = test_transport_api_unreliability_unix
+UNIX_QUOTA_TEST = test_quota_compliance_unix
 NATBIN = gnunet-nat-server gnunet-nat-client
 install-exec-hook:
        chown root $(bindir)/gnunet-nat-server $(bindir)/gnunet-nat-client 
$(bindir)/gnunet-wlan || true
@@ -114,6 +118,7 @@
 plugin_LTLIBRARIES = \
   libgnunet_plugin_transport_tcp.la \
   libgnunet_plugin_transport_udp.la \
+  $(UNIX_PLUGIN_LA) \
   $(HTTP_PLUGIN_LA) \
   $(HTTPS_PLUGIN_LA) \
   $(WLAN_PLUGIN_LA) \
@@ -157,17 +162,17 @@
   $(top_builddir)/src/util/libgnunetutil.la 
 libgnunet_plugin_transport_udp_la_LDFLAGS = \
  $(GN_PLUGIN_LDFLAGS)
+ 
+libgnunet_plugin_transport_unix_la_SOURCES = \
+  plugin_transport_unix.c
+libgnunet_plugin_transport_unix_la_LIBADD = \
+  $(top_builddir)/src/hello/libgnunethello.la \
+  $(top_builddir)/src/statistics/libgnunetstatistics.la \
+  $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
+  $(top_builddir)/src/util/libgnunetutil.la 
+libgnunet_plugin_transport_unix_la_LDFLAGS = \
+ $(GN_PLUGIN_LDFLAGS)
 
-#libgnunet_plugin_transport_udp_nat_la_SOURCES = \
-#  plugin_transport_udp_nat.c
-#libgnunet_plugin_transport_udp_nat_la_LIBADD = \
-#  $(top_builddir)/src/hello/libgnunethello.la \
-#  $(top_builddir)/src/statistics/libgnunetstatistics.la \
-#  $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
-#  $(top_builddir)/src/util/libgnunetutil.la 
-#libgnunet_plugin_transport_udp_nat_la_LDFLAGS = \
-# $(GN_PLUGIN_LDFLAGS)
-
 libgnunet_plugin_transport_http_la_SOURCES = \
   plugin_transport_http.c
 libgnunet_plugin_transport_http_la_LIBADD = \
@@ -199,6 +204,7 @@
  test_transport_api_tcp \
  test_transport_api_tcp_nat \
  test_transport_api_udp \
+ $(UNIX_PLUGIN_TEST) \
  test_transport_api_udp_nat \
  $(HTTP_PLUGIN_TEST) \
  $(HTTP_API_TEST) \
@@ -208,13 +214,16 @@
  test_transport_api_multi \
  test_transport_api_reliability_tcp \
  test_transport_api_reliability_tcp_nat \
- test_transport_api_reliability_udp \
+ test_transport_api_unreliability_udp \
+ test_transport_api_unreliability_unix \
+ $(UNIX_REL_TEST) \
  $(HTTP_REL_TEST) \
  $(HTTPS_REL_TEST) \
  test_quota_compliance_tcp \
  test_quota_compliance_tcp_asymmetric_recv_constant \
  test_quota_compliance_udp \
  test_quota_compliance_udp_asymmetric_recv_constant \
+ $(UNIX_QUOTA_TEST) \
  $(HTTP_QUOTA_TEST) \
  $(HTTPS_QUOTA_TEST)
 # TODO: add tests for nat, etc.
@@ -224,6 +233,7 @@
  test_transport_api_tcp \
  test_transport_api_tcp_nat \
  test_transport_api_udp \
+ $(UNIX_PLUGIN_TEST) \
  test_transport_api_udp_nat \
  $(HTTP_PLUGIN_TEST) \
  $(HTTP_API_TEST) \
@@ -233,12 +243,15 @@
  test_transport_api_multi \
  test_transport_api_reliability_tcp \
  test_transport_api_reliability_tcp_nat \
+ test_transport_api_unreliability_udp \
+ test_transport_api_unreliability_unix \
  $(HTTP_REL_TEST) \
  $(HTTPS_REL_TEST) \
  test_quota_compliance_tcp \
  test_quota_compliance_tcp_asymmetric_recv_constant \
  test_quota_compliance_udp \
  test_quota_compliance_udp_asymmetric_recv_constant \
+ $(UNIX_QUOTA_TEST) \
  $(HTTP_QUOTA_TEST) \
  $(HTTPS_QUOTA_TEST)
 endif
@@ -271,19 +284,31 @@
  test_transport_api_reliability.c
 test_transport_api_reliability_udp_LDADD = \
  $(top_builddir)/src/transport/libgnunettransport.la \
- $(top_builddir)/src/util/libgnunetutil.la   
+ $(top_builddir)/src/util/libgnunetutil.la
+ 
+test_transport_api_reliability_unix_SOURCES = \
+ test_transport_api_reliability.c
+test_transport_api_reliability_unix_LDADD = \
+ $(top_builddir)/src/transport/libgnunettransport.la \
+ $(top_builddir)/src/util/libgnunetutil.la  
 
 test_transport_api_udp_SOURCES = \
  test_transport_api.c
 test_transport_api_udp_LDADD = \
  $(top_builddir)/src/transport/libgnunettransport.la \
  $(top_builddir)/src/util/libgnunetutil.la  
-
+ 
 test_transport_api_udp_nat_SOURCES = \
  test_transport_api.c
 test_transport_api_udp_nat_LDADD = \
  $(top_builddir)/src/transport/libgnunettransport.la \
- $(top_builddir)/src/util/libgnunetutil.la  
+ $(top_builddir)/src/util/libgnunetutil.la   
+ 
+test_transport_api_unix_SOURCES = \
+ test_transport_api.c
+test_transport_api_unix_LDADD = \
+ $(top_builddir)/src/transport/libgnunettransport.la \
+ $(top_builddir)/src/util/libgnunetutil.la 
 
 test_plugin_transport_http_SOURCES = \
  test_plugin_transport_http.c
@@ -324,7 +349,19 @@
 test_transport_api_reliability_https_LDADD = \
  $(top_builddir)/src/transport/libgnunettransport.la \
  $(top_builddir)/src/util/libgnunetutil.la
+ 
+test_transport_api_unreliability_unix_SOURCES = \
+ test_transport_api_unreliability.c
+test_transport_api_unreliability_unix_LDADD = \
+ $(top_builddir)/src/transport/libgnunettransport.la \
+ $(top_builddir)/src/util/libgnunetutil.la
 
+test_transport_api_unreliability_udp_SOURCES = \
+ test_transport_api_unreliability.c
+test_transport_api_unreliability_udp_LDADD = \
+ $(top_builddir)/src/transport/libgnunettransport.la \
+ $(top_builddir)/src/util/libgnunetutil.la
+
 if HAVE_PCAP
 if LINUX
 test_transport_api_wlan_SOURCES = \
@@ -407,6 +444,19 @@
 # $(top_builddir)/src/transport/libgnunettransport.la \
 # $(top_builddir)/src/util/libgnunetutil.la 
 
+test_quota_compliance_unix_SOURCES = \
+ test_quota_compliance.c
+test_quota_compliance_unix_LDADD = \
+ $(top_builddir)/src/transport/libgnunettransport.la \
+ $(top_builddir)/src/util/libgnunetutil.la
+
+test_quota_compliance_unix_asymmetric_recv_constant_SOURCES = \
+ test_quota_compliance.c
+test_quota_compliance_unix_asymmetric_recv_constant_LDADD = \
+ $(top_builddir)/src/transport/libgnunettransport.la \
+ $(top_builddir)/src/util/libgnunetutil.la
+
+
 test_transport_api_multi_SOURCES = \
  test_transport_api.c
 test_transport_api_multi_LDADD = \
@@ -419,6 +469,8 @@
   test_transport_api_tcp_peer2.conf \
   test_transport_api_udp_peer1.conf \
   test_transport_api_udp_peer2.conf \
+  test_transport_api_unix_peer1.conf \
+  test_transport_api_unix_peer2.conf \
   test_transport_api_udp_nat_peer1.conf \
   test_transport_api_udp_nat_peer2.conf \
   test_transport_api_tcp_nat_peer1.conf \
@@ -446,4 +498,6 @@
   test_quota_compliance_https_peer1.conf \
   test_quota_compliance_https_peer2.conf \
   test_quota_compliance_udp_peer1.conf \
-  test_quota_compliance_udp_peer2.conf
+  test_quota_compliance_udp_peer2.conf \
+  test_quota_compliance_unix_peer1.conf \
+  test_quota_compliance_unix_peer2.conf

Modified: gnunet/src/transport/plugin_transport_udp.c
===================================================================
--- gnunet/src/transport/plugin_transport_udp.c 2011-02-03 16:09:06 UTC (rev 
14329)
+++ gnunet/src/transport/plugin_transport_udp.c 2011-02-03 16:11:49 UTC (rev 
14330)
@@ -662,6 +662,8 @@
     GNUNET_NETWORK_socket_sendto (send_handle, message, ssize,
                                   sb,
                                   sbs);
+  if (GNUNET_SYSERR == sent)
+    GNUNET_log_strerror(GNUNET_ERROR_TYPE_DEBUG, "sendto");
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
              "UDP transmit %u-byte message to %s (%d: %s)\n",
              (unsigned int) ssize,

Added: gnunet/src/transport/plugin_transport_unix.c
===================================================================
--- gnunet/src/transport/plugin_transport_unix.c                                
(rev 0)
+++ gnunet/src/transport/plugin_transport_unix.c        2011-02-03 16:11:49 UTC 
(rev 14330)
@@ -0,0 +1,1155 @@
+/*
+     This file is part of GNUnet
+     (C) 2010 Christian Grothoff (and other contributing authors)
+
+     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., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file transport/plugin_transport_unix.c
+ * @brief Transport plugin using unix domain sockets (!)
+ *        Clearly, can only be used locally on Unix/Linux hosts...
+ *        ONLY INTENDED FOR TESTING!!!
+ * @author Christian Grothoff
+ * @author Nathan Evans
+ */
+
+#include "platform.h"
+#include "gnunet_hello_lib.h"
+#include "gnunet_connection_lib.h"
+#include "gnunet_container_lib.h"
+#include "gnunet_os_lib.h"
+#include "gnunet_peerinfo_service.h"
+#include "gnunet_protocols.h"
+#include "gnunet_resolver_service.h"
+#include "gnunet_server_lib.h"
+#include "gnunet_signatures.h"
+#include "gnunet_statistics_service.h"
+#include "gnunet_transport_service.h"
+#include "gnunet_transport_plugin.h"
+#include "transport.h"
+
+#define DEBUG_UNIX GNUNET_YES
+
+#define MAX_PROBES 20
+
+/*
+ * Transport cost to peer, always 1 for UNIX (direct connection)
+ */
+#define UNIX_DIRECT_DISTANCE 1
+
+#define DEFAULT_NAT_PORT 0
+
+/**
+ * How long until we give up on transmitting the welcome message?
+ */
+#define HOSTNAME_RESOLVE_TIMEOUT GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_SECONDS, 5)
+
+/**
+ * Starting port for listening and sending, eventually a config value
+ */
+#define UNIX_NAT_DEFAULT_PORT 22086
+
+/**
+ * UNIX Message-Packet header.
+ */
+struct UNIXMessage
+{
+  /**
+   * Message header.
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * What is the identity of the sender (GNUNET_hash of public key)
+   */
+  struct GNUNET_PeerIdentity sender;
+
+};
+
+/**
+ * Network format for IPv4 addresses.
+ */
+struct IPv4UdpAddress
+{
+  /**
+   * IPv4 address, in network byte order.
+   */
+  uint32_t ipv4_addr GNUNET_PACKED;
+
+  /**
+   * Port number, in network byte order.
+   */
+  uint16_t u_port GNUNET_PACKED;
+};
+
+
+/**
+ * Network format for IPv6 addresses.
+ */
+struct IPv6UdpAddress
+{
+  /**
+   * IPv6 address.
+   */
+  struct in6_addr ipv6_addr GNUNET_PACKED;
+
+  /**
+   * Port number, in network byte order.
+   */
+  uint16_t u6_port GNUNET_PACKED;
+};
+
+/* Forward definition */
+struct Plugin;
+
+struct PrettyPrinterContext
+{
+  GNUNET_TRANSPORT_AddressStringCallback asc;
+  void *asc_cls;
+  uint16_t port;
+};
+
+struct RetrySendContext
+{
+
+  /**
+   * Main plugin handle.
+   */
+  struct Plugin *plugin;
+
+  /**
+   * Address of recipient.
+   */
+  char *addr;
+
+  /**
+   * Length of address.
+   */
+  ssize_t addrlen;
+
+  /**
+   * Message to send.
+   */
+  char *msg;
+
+  /**
+   * Size of the message.
+   */
+  int msg_size;
+
+  /**
+   * Handle to send message out on.
+   */
+  struct GNUNET_NETWORK_Handle *send_handle;
+
+  /**
+   * Continuation to call on success or
+   * timeout.
+   */
+  GNUNET_TRANSPORT_TransmitContinuation cont;
+
+  /**
+   * Closure for continuation.
+   */
+  void *cont_cls;
+
+  /**
+   * The peer the message is destined for.
+   */
+  struct GNUNET_PeerIdentity target;
+
+  /**
+   * How long before not retrying any longer.
+   */
+  struct GNUNET_TIME_Absolute timeout;
+
+  /**
+   * How long the last message was delayed.
+   */
+  struct GNUNET_TIME_Relative delay;
+
+  /**
+   * The actual retry task.
+   */
+  GNUNET_SCHEDULER_TaskIdentifier retry_task;
+
+  /**
+   * The priority of the message.
+   */
+  unsigned int priority;
+};
+
+/**
+ * Local network addresses (actual unix path follows).
+ */
+struct LocalAddrList
+{
+
+  /**
+   * This is a doubly linked list.
+   */
+  struct LocalAddrList *next;
+
+  /**
+   * This is a doubly linked list.
+   */
+  struct LocalAddrList *prev;
+
+  /**
+   * Number of bytes of the address that follow
+   */
+  size_t size;
+
+};
+
+
+/**
+ * UNIX NAT "Session"
+ */
+struct PeerSession
+{
+
+  /**
+   * Stored in a linked list.
+   */
+  struct PeerSession *next;
+
+  /**
+   * Pointer to the global plugin struct.
+   */
+  struct Plugin *plugin;
+
+  /**
+   * To whom are we talking to (set to our identity
+   * if we are still waiting for the welcome message)
+   */
+  struct GNUNET_PeerIdentity target;
+
+  /**
+   * Address of the other peer (either based on our 'connect'
+   * call or on our 'accept' call).
+   */
+  void *connect_addr;
+
+  /**
+   * Length of connect_addr.
+   */
+  size_t connect_alen;
+
+  /**
+   * Are we still expecting the welcome message? (GNUNET_YES/GNUNET_NO)
+   */
+  int expecting_welcome;
+
+  /**
+   * From which socket do we need to send to this peer?
+   */
+  struct GNUNET_NETWORK_Handle *sock;
+
+  /*
+   * Queue of messages for this peer, in the case that
+   * we have to await a connection...
+   */
+  struct MessageQueue *messages;
+
+};
+
+/**
+ * Information we keep for each of our listen sockets.
+ */
+struct UNIX_Sock_Info
+{
+  /**
+   * The network handle
+   */
+  struct GNUNET_NETWORK_Handle *desc;
+
+  /**
+   * The port we bound to
+   */
+  uint16_t port;
+};
+
+
+/**
+ * Encapsulation of all of the state of the plugin.
+ */
+struct Plugin
+{
+  /**
+   * Our environment.
+   */
+  struct GNUNET_TRANSPORT_PluginEnvironment *env;
+
+  /*
+   * Session of peers with whom we are currently connected
+   */
+  struct PeerSession *sessions;
+
+  /**
+   * ID of task used to update our addresses when one expires.
+   */
+  GNUNET_SCHEDULER_TaskIdentifier address_update_task;
+
+  /**
+   * ID of select task
+   */
+  GNUNET_SCHEDULER_TaskIdentifier select_task;
+
+  /**
+   * Integer to append to unix domain socket.
+   */
+  uint16_t port;
+
+  /**
+   * List of our IP addresses.
+   */
+  struct LocalAddrList *lal_head;
+
+  /**
+   * Tail of our IP address list.
+   */
+  struct LocalAddrList *lal_tail;
+
+  /**
+   * FD Read set
+   */
+  struct GNUNET_NETWORK_FDSet *rs;
+
+  /**
+   * socket that we transmit all data with
+   */
+  struct UNIX_Sock_Info unix_sock;
+
+  /**
+   * Path of our unix domain socket (/tmp/unix-plugin-PORT)
+   */
+  char *unix_socket_path;
+
+};
+
+
+/**
+ * Disconnect from a remote node.  Clean up session if we have one for this 
peer
+ *
+ * @param cls closure for this call (should be handle to Plugin)
+ * @param target the peeridentity of the peer to disconnect
+ * @return GNUNET_OK on success, GNUNET_SYSERR if the operation failed
+ */
+void
+unix_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
+{
+  /** TODO: Implement! */
+  return;
+}
+
+/**
+ * Shutdown the server process (stop receiving inbound traffic). Maybe
+ * restarted later!
+ *
+ * @param cls Handle to the plugin for this transport
+ *
+ * @return returns the number of sockets successfully closed,
+ *         should equal the number of sockets successfully opened
+ */
+static int
+unix_transport_server_stop (void *cls)
+{
+  struct Plugin *plugin = cls;
+
+  if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK)
+    {
+      GNUNET_SCHEDULER_cancel (plugin->select_task);
+      plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
+    }
+
+  GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close 
(plugin->unix_sock.desc));
+  plugin->unix_sock.desc = NULL;
+
+  return GNUNET_OK;
+}
+
+
+struct PeerSession *
+find_session (struct Plugin *plugin,
+             const struct GNUNET_PeerIdentity *peer)
+{
+  struct PeerSession *pos;
+
+  pos = plugin->sessions;
+  while (pos != NULL)
+    {
+      if (memcmp(&pos->target, peer, sizeof(struct GNUNET_PeerIdentity)) == 0)
+        return pos;
+      pos = pos->next;
+    }
+
+  return pos;
+}
+
+/* Forward Declaration */
+static ssize_t
+unix_real_send (void *cls,
+                struct RetrySendContext *incoming_retry_context,
+                struct GNUNET_NETWORK_Handle *send_handle,
+                const struct GNUNET_PeerIdentity *target,
+                const char *msgbuf,
+                size_t msgbuf_size,
+                unsigned int priority,
+                struct GNUNET_TIME_Relative timeout,
+                const void *addr,
+                size_t addrlen,
+                GNUNET_TRANSPORT_TransmitContinuation cont,
+                void *cont_cls);
+
+/**
+ * Retry sending a message.
+ *
+ * @param cls closure a struct RetrySendContext
+ * @param tc context information
+ */
+void retry_send_message (void *cls,
+                         const struct GNUNET_SCHEDULER_TaskContext * tc)
+{
+  struct RetrySendContext *retry_ctx = cls;
+
+  if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
+    return;
+  unix_real_send (retry_ctx->plugin,
+                  retry_ctx,
+                  retry_ctx->send_handle,
+                  &retry_ctx->target,
+                  retry_ctx->msg,
+                  retry_ctx->msg_size,
+                  retry_ctx->priority,
+                  GNUNET_TIME_absolute_get_remaining (retry_ctx->timeout),
+                  retry_ctx->addr,
+                  retry_ctx->addrlen,
+                  retry_ctx->cont,
+                  retry_ctx->cont_cls);
+  return;
+}
+
+/**
+ * Actually send out the message, assume we've got the address and
+ * send_handle squared away!
+ *
+ * @param cls closure
+ * @param incoming_retry_context the retry context to use
+ * @param send_handle which handle to send message on
+ * @param target who should receive this message (ignored by UNIX)
+ * @param msgbuf one or more GNUNET_MessageHeader(s) strung together
+ * @param msgbuf_size the size of the msgbuf to send
+ * @param priority how important is the message (ignored by UNIX)
+ * @param timeout when should we time out (give up) if we can not transmit?
+ * @param addr the addr to send the message to, needs to be a sockaddr for us
+ * @param addrlen the len of addr
+ * @param cont continuation to call once the message has
+ *        been transmitted (or if the transport is ready
+ *        for the next transmission call; or if the
+ *        peer disconnected...)
+ * @param cont_cls closure for cont
+ *
+ * @return the number of bytes written, -1 on errors
+ */
+static ssize_t
+unix_real_send (void *cls,
+                struct RetrySendContext *incoming_retry_context,
+                struct GNUNET_NETWORK_Handle *send_handle,
+               const struct GNUNET_PeerIdentity *target,
+               const char *msgbuf,
+               size_t msgbuf_size,
+               unsigned int priority,
+               struct GNUNET_TIME_Relative timeout,
+               const void *addr,
+               size_t addrlen,
+               GNUNET_TRANSPORT_TransmitContinuation cont,
+               void *cont_cls)
+{
+  struct Plugin *plugin = cls;
+  struct UNIXMessage *message;
+  struct RetrySendContext *retry_ctx;
+  int ssize;
+  ssize_t sent;
+  const void *sb;
+  size_t sbs;
+  struct sockaddr_un *un;
+  size_t slen;
+
+  if (send_handle == NULL)
+    {
+#if DEBUG_UNIX
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                       "unix_real_send with send_handle NULL!\n");
+#endif
+      /* failed to open send socket for AF */
+      if (cont != NULL)
+        cont (cont_cls, target, GNUNET_SYSERR);
+      return 0;
+    }
+  if ((addr == NULL) || (addrlen == 0))
+    {
+#if DEBUG_UNIX
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                      "unix_real_send called without address, returning!\n");
+#endif
+      if (cont != NULL)
+        cont (cont_cls, target, GNUNET_SYSERR);
+      return 0; /* Can never send if we don't have an address!! */
+    }
+
+  /* Build the message to be sent */
+  message = GNUNET_malloc (sizeof (struct UNIXMessage) + msgbuf_size);
+  ssize = sizeof (struct UNIXMessage) + msgbuf_size;
+
+  message->header.size = htons (ssize);
+  message->header.type = htons (0);
+  memcpy (&message->sender, plugin->env->my_identity,
+          sizeof (struct GNUNET_PeerIdentity));
+  memcpy (&message[1], msgbuf, msgbuf_size);
+
+  un = GNUNET_malloc (sizeof (struct sockaddr_un));
+  un->sun_family = AF_UNIX;
+  slen = strlen (addr) + 1;
+  sent = 0;
+  GNUNET_assert(slen < sizeof(un->sun_path));
+  memcpy (un->sun_path, addr, slen);
+  un->sun_path[slen] = '\0';
+#if LINUX
+  un->sun_path[0] = '\0';
+#endif
+  slen += sizeof (sa_family_t);
+  sb = (struct sockaddr*) un;
+  sbs = slen;
+
+  sent = GNUNET_NETWORK_socket_sendto(send_handle, message, ssize, sb, sbs);
+
+  if (GNUNET_SYSERR == sent)
+    {
+      if (incoming_retry_context == NULL)
+        {
+          retry_ctx = GNUNET_malloc(sizeof(struct RetrySendContext));
+          retry_ctx->addr = GNUNET_malloc(addrlen);
+          retry_ctx->msg = GNUNET_malloc(msgbuf_size);
+          retry_ctx->plugin = plugin;
+          memcpy(retry_ctx->addr, addr, addrlen);
+          memcpy(retry_ctx->msg, msgbuf, msgbuf_size);
+          retry_ctx->msg_size = msgbuf_size;
+          retry_ctx->addrlen = addrlen;
+          retry_ctx->send_handle = send_handle;
+          retry_ctx->cont = cont;
+          retry_ctx->cont_cls = cont_cls;
+          retry_ctx->priority = priority;
+          retry_ctx->timeout = GNUNET_TIME_relative_to_absolute(timeout);
+          memcpy(&retry_ctx->target, target, sizeof(struct 
GNUNET_PeerIdentity));
+          retry_ctx->delay = GNUNET_TIME_UNIT_MILLISECONDS;
+        }
+      else
+        {
+          retry_ctx = incoming_retry_context;
+          retry_ctx->delay = GNUNET_TIME_relative_multiply(retry_ctx->delay, 
2);
+        }
+      retry_ctx->retry_task = GNUNET_SCHEDULER_add_delayed(retry_ctx->delay, 
&retry_send_message, retry_ctx);
+#if DETAILS
+      GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Error when trying to send %d byte 
message to %s\n", retry_ctx->msg_size, &un->sun_path[1]);
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "UNIX transmit %u-byte message to %s (%d: %s)\n",
+                  (unsigned int) ssize,
+                  GNUNET_a2s (sb, sbs),
+                  (int) sent,
+                  (sent < 0) ? STRERROR (errno) : "ok");
+#endif
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "send");
+      return ssize;
+    }
+  if (incoming_retry_context != NULL)
+    {
+      GNUNET_free(incoming_retry_context->msg);
+      GNUNET_free(incoming_retry_context->addr);
+      GNUNET_free(incoming_retry_context);
+    }
+#if DEBUG_UNIX
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "UNIX transmit %u-byte message to %s (%d: %s)\n",
+             (unsigned int) ssize,
+             GNUNET_a2s (sb, sbs),
+             (int) sent,
+             (sent < 0) ? STRERROR (errno) : "ok");
+#endif
+  if (cont != NULL)
+    {
+      if (sent == GNUNET_SYSERR)
+        cont (cont_cls, target, GNUNET_SYSERR);
+      else
+        {
+          cont (cont_cls, target, GNUNET_OK);
+        }
+    }
+
+  GNUNET_free (message);
+  return sent;
+}
+
+
+/**
+ * Function that can be used by the transport service to transmit
+ * a message using the plugin.
+ *
+ * @param cls closure
+ * @param target who should receive this message (ignored by UNIX)
+ * @param msgbuf one or more GNUNET_MessageHeader(s) strung together
+ * @param msgbuf_size the size of the msgbuf to send
+ * @param priority how important is the message (ignored by UNIX)
+ * @param timeout when should we time out (give up) if we can not transmit?
+ * @param session identifier used for this session (can be NULL)
+ * @param addr the addr to send the message to, needs to be a sockaddr for us
+ * @param addrlen the len of addr
+ * @param force_address not used, we had better have an address to send to
+ *        because we are stateless!!
+ * @param cont continuation to call once the message has
+ *        been transmitted (or if the transport is ready
+ *        for the next transmission call; or if the
+ *        peer disconnected...)
+ * @param cont_cls closure for cont
+ *
+ * @return the number of bytes written (may return 0 and the message can
+ *         still be transmitted later!)
+ */
+static ssize_t
+unix_plugin_send (void *cls,
+                    const struct GNUNET_PeerIdentity *target,
+                    const char *msgbuf,
+                    size_t msgbuf_size,
+                    unsigned int priority,
+                    struct GNUNET_TIME_Relative timeout,
+                    struct Session *session,
+                    const void *addr,
+                    size_t addrlen,
+                    int force_address,
+                    GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
+{
+  struct Plugin *plugin = cls;
+  ssize_t sent;
+
+  if (force_address == GNUNET_SYSERR)
+    return GNUNET_SYSERR;
+  GNUNET_assert (NULL == session);
+
+#if DEBUG_UNIX
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Asked to send message to `%s'\n", (char 
*)addr);
+#endif
+  sent = unix_real_send(cls,
+                        NULL,
+                        plugin->unix_sock.desc,
+                        target,
+                        msgbuf, msgbuf_size,
+                        priority, timeout, addr, addrlen,
+                        cont, cont_cls);
+#if DEBUG_UNIX
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sent %d bytes to `%s'\n", sent, (char 
*)addr);
+#endif
+  if (sent == GNUNET_SYSERR)
+    return 0;
+  return sent;
+}
+
+
+static void
+add_to_address_list (struct Plugin *plugin,
+                    const void *arg,
+                    size_t arg_size)
+{
+  struct LocalAddrList *lal;
+
+  lal = plugin->lal_head;
+  while (NULL != lal)
+    {
+      if ( (lal->size == arg_size) &&
+          (0 == memcmp (&lal[1], arg, arg_size)) )
+       return;
+      lal = lal->next;
+    }
+  lal = GNUNET_malloc (sizeof (struct LocalAddrList) + arg_size);
+  lal->size = arg_size;
+  memcpy (&lal[1], arg, arg_size);
+  GNUNET_CONTAINER_DLL_insert (plugin->lal_head,
+                              plugin->lal_tail,
+                              lal);
+}
+
+
+/**
+ * Demultiplexer for UNIX messages
+ *
+ * @param plugin the main plugin for this transport
+ * @param sender from which peer the message was received
+ * @param currhdr pointer to the header of the message
+ * @param sender_addr the address from which the message was received
+ * @param fromlen the length of the address
+ */
+static void
+unix_demultiplexer(struct Plugin *plugin,
+                  struct GNUNET_PeerIdentity *sender,
+                   const struct GNUNET_MessageHeader *currhdr,
+                   const struct sockaddr_un *un,
+                   size_t fromlen)
+{
+  struct GNUNET_TRANSPORT_ATS_Information distance[2];
+
+  distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
+  distance[0].value = htonl (UNIX_DIRECT_DISTANCE);
+  distance[1].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
+  distance[1].value = htonl (0);
+
+  GNUNET_assert(fromlen >= sizeof(struct sockaddr_un));
+
+#if DEBUG_UNIX
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received message from %s\n", 
un->sun_path);
+#endif
+  plugin->env->receive (plugin->env->cls, sender, currhdr,
+                       (const struct GNUNET_TRANSPORT_ATS_Information *) 
&distance, 2,
+                              NULL, un->sun_path, strlen(un->sun_path) + 1);
+}
+
+
+/*
+ * @param cls the plugin handle
+ * @param tc the scheduling context (for rescheduling this function again)
+ *
+ * We have been notified that our writeset has something to read.  We don't
+ * know which socket needs to be read, so we have to check each one
+ * Then reschedule this function to be called again once more is available.
+ *
+ */
+static void
+unix_plugin_select (void *cls,
+                   const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct Plugin *plugin = cls;
+  char buf[65536];
+  struct UNIXMessage *msg;
+  struct GNUNET_PeerIdentity sender;
+  //socklen_t fromlen;
+  struct sockaddr_un un;
+  socklen_t addrlen;
+  ssize_t ret;
+  int offset;
+  int tsize;
+  char *msgbuf;
+  const struct GNUNET_MessageHeader *currhdr;
+  uint16_t csize;
+
+  plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
+  if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
+    return;
+
+  addrlen = sizeof(un);
+  memset(&un, 0, sizeof(un));
+  GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, 
plugin->unix_sock.desc));
+  ret =
+    GNUNET_NETWORK_socket_recvfrom (plugin->unix_sock.desc, buf, sizeof (buf),
+                                    (struct sockaddr *)&un, &addrlen);
+
+  if (ret == GNUNET_SYSERR)
+    {
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "recvfrom");
+      plugin->select_task =
+        GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+                                     GNUNET_SCHEDULER_NO_TASK,
+                                     GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
+                                     NULL, &unix_plugin_select, plugin);
+      return;
+    }
+  else
+  {
+#if LINUX
+    un.sun_path[0] = '/';
+#endif
+#if DEBUG_UNIX
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Read %d bytes from socket %s\n", ret, 
&un.sun_path[0]);
+#endif
+  }
+
+  GNUNET_assert (AF_UNIX == (un.sun_family));
+
+  msg = (struct UNIXMessage *) buf;
+  csize = ntohs (msg->header.size);
+  if ( (csize < sizeof (struct UNIXMessage)) ||
+       (csize > ret) )
+    {
+      GNUNET_break_op (0);
+      plugin->select_task =
+       GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+                                    GNUNET_SCHEDULER_NO_TASK,
+                                    GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
+                                    NULL, &unix_plugin_select, plugin);
+      return;
+    }
+  msgbuf = (char *)&msg[1];
+  memcpy (&sender, &msg->sender, sizeof (struct GNUNET_PeerIdentity));
+  offset = 0;
+  tsize = csize - sizeof (struct UNIXMessage);
+  while (offset + sizeof (struct GNUNET_MessageHeader) <= tsize)
+    {
+      currhdr = (struct GNUNET_MessageHeader *)&msgbuf[offset];
+      csize = ntohs (currhdr->size);
+      if ( (csize < sizeof (struct GNUNET_MessageHeader)) ||
+          (csize > tsize - offset) )
+       {
+         GNUNET_break_op (0);
+         break;
+       }
+      unix_demultiplexer(plugin, &sender, currhdr,
+                        &un, sizeof(un));
+      offset += csize;
+    }
+  plugin->select_task =
+    GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+                                 GNUNET_SCHEDULER_NO_TASK,
+                                 GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
+                                 NULL, &unix_plugin_select, plugin);
+}
+
+/**
+ * Create a slew of UNIX sockets.  If possible, use IPv6 and IPv4.
+ *
+ * @param cls closure for server start, should be a struct Plugin *
+ * @return number of sockets created or GNUNET_SYSERR on error
+*/
+static int
+unix_transport_server_start (void *cls)
+{
+  struct Plugin *plugin = cls;
+
+  struct sockaddr *serverAddr;
+  socklen_t addrlen;
+  int sockets_created;
+  struct sockaddr_un *un;
+  size_t slen;
+
+  un = GNUNET_malloc (sizeof (struct sockaddr_un));
+  un->sun_family = AF_UNIX;
+  slen = strlen (plugin->unix_socket_path) + 1;
+
+  GNUNET_assert(slen < sizeof(un->sun_path));
+  memcpy (un->sun_path, plugin->unix_socket_path, slen);
+  un->sun_path[slen] = '\0';
+  slen += sizeof (sa_family_t);
+  serverAddr = (struct sockaddr*) un;
+  addrlen = slen;
+  sockets_created = 0;
+#if LINUX
+  un->sun_path[0] = '\0';
+#endif
+
+  plugin->unix_sock.desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 
0);
+  if (NULL == plugin->unix_sock.desc)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "socket");
+    }
+  else
+    {
+      if (GNUNET_NETWORK_socket_bind (plugin->unix_sock.desc, serverAddr, 
addrlen) !=
+            GNUNET_OK)
+       {
+#if DEBUG_UNIX
+         GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                          "UNIX Binding failed!\n");
+#endif
+       }
+      else
+        GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Bound to `%s'\n", 
&un->sun_path[0]);
+      if (plugin->unix_sock.desc != NULL)
+        sockets_created++;
+    }
+
+  plugin->rs = GNUNET_NETWORK_fdset_create ();
+  GNUNET_NETWORK_fdset_zero (plugin->rs);
+  GNUNET_NETWORK_fdset_set (plugin->rs,
+                            plugin->unix_sock.desc);
+
+  plugin->select_task =
+    GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+                                 GNUNET_SCHEDULER_NO_TASK,
+                                 GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
+                                 NULL, &unix_plugin_select, plugin);
+  return sockets_created;
+}
+
+
+/**
+ * Function that will be called to check if a binary address for this
+ * plugin is well-formed and corresponds to an address for THIS peer
+ * (as per our configuration).  Naturally, if absolutely necessary,
+ * plugins can be a bit conservative in their answer, but in general
+ * plugins should make sure that the address does not redirect
+ * traffic to a 3rd party that might try to man-in-the-middle our
+ * traffic.
+ *
+ * @param cls closure, should be our handle to the Plugin
+ * @param addr pointer to the address
+ * @param addrlen length of addr
+ * @return GNUNET_OK if this is a plausible address for this peer
+ *         and transport, GNUNET_SYSERR if not
+ *
+ */
+static int
+unix_check_address (void *cls,
+                  const void *addr,
+                  size_t addrlen)
+{
+
+#if DEBUG_UNIX
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                   "Informing transport service about my address `%s'\n",
+                   (char *)addr);
+#endif
+  return GNUNET_OK;
+}
+
+
+/**
+ * Append our port and forward the result.
+ */
+static void
+append_port (void *cls, const char *hostname)
+{
+  struct PrettyPrinterContext *ppc = cls;
+  char *ret;
+
+  if (hostname == NULL)
+    {
+      ppc->asc (ppc->asc_cls, NULL);
+      GNUNET_free (ppc);
+      return;
+    }
+  GNUNET_asprintf (&ret, "%s:%d", hostname, ppc->port);
+  ppc->asc (ppc->asc_cls, ret);
+  GNUNET_free (ret);
+}
+
+
+/**
+ * Convert the transports address to a nice, human-readable
+ * format.
+ *
+ * @param cls closure
+ * @param type name of the transport that generated the address
+ * @param addr one of the addresses of the host, NULL for the last address
+ *        the specific address format depends on the transport
+ * @param addrlen length of the address
+ * @param numeric should (IP) addresses be displayed in numeric form?
+ * @param timeout after how long should we give up?
+ * @param asc function to call on each string
+ * @param asc_cls closure for asc
+ */
+static void
+unix_plugin_address_pretty_printer (void *cls,
+                                   const char *type,
+                                   const void *addr,
+                                   size_t addrlen,
+                                   int numeric,
+                                   struct GNUNET_TIME_Relative timeout,
+                                   GNUNET_TRANSPORT_AddressStringCallback asc,
+                                   void *asc_cls)
+{
+  struct Plugin *plugin = cls;
+  struct PrettyPrinterContext *ppc;
+  const void *sb;
+  size_t sbs;
+  struct sockaddr_in a4;
+  struct sockaddr_in6 a6;
+  const struct IPv4UdpAddress *u4;
+  const struct IPv6UdpAddress *u6;
+  uint16_t port;
+
+  if (addrlen == sizeof (struct IPv6UdpAddress))
+    {
+      u6 = addr;
+      memset (&a6, 0, sizeof (a6));
+      a6.sin6_family = AF_INET6;
+      a6.sin6_port = u6->u6_port;
+      memcpy (&a6.sin6_addr,
+              &u6->ipv6_addr,
+              sizeof (struct in6_addr));
+      port = ntohs (u6->u6_port);
+      sb = &a6;
+      sbs = sizeof (a6);
+    }
+  else if (addrlen == sizeof (struct IPv4UdpAddress))
+    {
+      u4 = addr;
+      memset (&a4, 0, sizeof (a4));
+      a4.sin_family = AF_INET;
+      a4.sin_port = u4->u_port;
+      a4.sin_addr.s_addr = u4->ipv4_addr;
+      port = ntohs (u4->u_port);
+      sb = &a4;
+      sbs = sizeof (a4);
+    }
+  else
+    {
+      /* invalid address */
+      GNUNET_break_op (0);
+      asc (asc_cls, NULL);
+      return;
+    }
+  ppc = GNUNET_malloc (sizeof (struct PrettyPrinterContext));
+  ppc->asc = asc;
+  ppc->asc_cls = asc_cls;
+  ppc->port = port;
+  GNUNET_RESOLVER_hostname_get (plugin->env->cfg,
+                                sb,
+                                sbs,
+                                !numeric, timeout, &append_port, ppc);
+}
+
+/**
+ * Function called for a quick conversion of the binary address to
+ * a numeric address.  Note that the caller must not free the
+ * address and that the next call to this function is allowed
+ * to override the address again.
+ *
+ * @param cls closure
+ * @param addr binary address
+ * @param addrlen length of the address
+ * @return string representing the same address
+ */
+static const char*
+unix_address_to_string (void *cls,
+                       const void *addr,
+                       size_t addrlen)
+{
+  static char rbuf[INET6_ADDRSTRLEN + 10];
+  char buf[INET6_ADDRSTRLEN];
+  const void *sb;
+  struct in_addr a4;
+  struct in6_addr a6;
+  const struct IPv4UdpAddress *t4;
+  const struct IPv6UdpAddress *t6;
+  int af;
+  uint16_t port;
+
+  if (addrlen == sizeof (struct IPv6UdpAddress))
+    {
+      t6 = addr;
+      af = AF_INET6;
+      port = ntohs (t6->u6_port);
+      memcpy (&a6, &t6->ipv6_addr, sizeof (a6));
+      sb = &a6;
+    }
+  else if (addrlen == sizeof (struct IPv4UdpAddress))
+    {
+      t4 = addr;
+      af = AF_INET;
+      port = ntohs (t4->u_port);
+      memcpy (&a4, &t4->ipv4_addr, sizeof (a4));
+      sb = &a4;
+    }
+  else
+    return NULL;
+  inet_ntop (af, sb, buf, INET6_ADDRSTRLEN);
+  GNUNET_snprintf (rbuf,
+                   sizeof (rbuf),
+                   "%s:%u",
+                   buf,
+                   port);
+  return rbuf;
+}
+
+/**
+ * The exported method. Makes the core api available via a global and
+ * returns the unix transport API.
+ */
+void *
+libgnunet_plugin_transport_unix_init (void *cls)
+{
+  struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
+  unsigned long long port;
+  struct GNUNET_TRANSPORT_PluginFunctions *api;
+  struct Plugin *plugin;
+  int sockets_created;
+
+  if (GNUNET_OK !=
+      GNUNET_CONFIGURATION_get_value_number (env->cfg,
+                                            "transport-unix",
+                                            "PORT",
+                                            &port))
+    port = UNIX_NAT_DEFAULT_PORT;
+  else if (port > 65535)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  _("Given `%s' option is out of range: %llu > %u\n"),
+                  "PORT",
+                  port,
+                  65535);
+      return NULL;
+    }
+
+
+  plugin = GNUNET_malloc (sizeof (struct Plugin));
+  plugin->port = port;
+  plugin->env = env;
+  GNUNET_asprintf(&plugin->unix_socket_path, "/tmp/unix-plugin-sock.%d", 
plugin->port);
+
+  api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
+  api->cls = plugin;
+
+  api->send = &unix_plugin_send;
+  api->disconnect = &unix_disconnect;
+  api->address_pretty_printer = &unix_plugin_address_pretty_printer;
+  api->address_to_string = &unix_address_to_string;
+  api->check_address = &unix_check_address;
+
+  add_to_address_list (plugin, plugin->unix_socket_path, 
strlen(plugin->unix_socket_path) + 1);
+
+  sockets_created = unix_transport_server_start (plugin);
+  if (sockets_created == 0)
+    GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+               _("Failed to open UNIX sockets\n"));
+
+  plugin->env->notify_address(plugin->env->cls,
+                              "unix",
+                              plugin->unix_socket_path,
+                              strlen(plugin->unix_socket_path) + 1,
+                              GNUNET_TIME_UNIT_FOREVER_REL);
+  return api;
+}
+
+void *
+libgnunet_plugin_transport_unix_done (void *cls)
+{
+  struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
+  struct Plugin *plugin = api->cls;
+  struct LocalAddrList *lal;
+
+  unix_transport_server_stop (plugin);
+
+  GNUNET_NETWORK_fdset_destroy (plugin->rs);
+  while (NULL != (lal = plugin->lal_head))
+    {
+      GNUNET_CONTAINER_DLL_remove (plugin->lal_head,
+                                  plugin->lal_tail,
+                                  lal);
+      GNUNET_free (lal);
+    }
+  GNUNET_free (plugin);
+  GNUNET_free (api);
+  return NULL;
+}
+
+/* end of plugin_transport_unix.c */

Modified: gnunet/src/transport/test_quota_compliance.c
===================================================================
--- gnunet/src/transport/test_quota_compliance.c        2011-02-03 16:09:06 UTC 
(rev 14329)
+++ gnunet/src/transport/test_quota_compliance.c        2011-02-03 16:11:49 UTC 
(rev 14330)
@@ -139,6 +139,7 @@
 static int is_http;
 static int is_https;
 static int is_udp;
+static int is_unix;
 static int is_asymmetric_send_constant;
 static int is_asymmetric_recv_constant;
 
@@ -731,6 +732,17 @@
       setup_peer (&p1, "test_quota_compliance_udp_peer1.conf");
       setup_peer (&p2, "test_quota_compliance_udp_peer2.conf");
     }
+  else if (is_unix)
+    {
+          if (is_asymmetric_recv_constant == GNUNET_YES)
+                  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric 
quota compliance (receiver quota constant) for UNIX transport plugin\n");
+          else if (is_asymmetric_send_constant == GNUNET_YES)
+                  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing asymmetric 
quota compliance (sender quota constant) for UNIX transport plugin\n");
+          else
+                  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Testing symmetric 
quota compliance for UNIX transport plugin\n");
+      setup_peer (&p1, "test_quota_compliance_unix_peer1.conf");
+      setup_peer (&p2, "test_quota_compliance_unix_peer2.conf");
+    }
   else if (is_tcp_nat)
     {
          if (is_asymmetric_recv_constant == GNUNET_YES)
@@ -777,6 +789,10 @@
     {
       is_udp = GNUNET_YES;
     }
+  else if (strstr(argv[0], "unix") != NULL)
+    {
+      is_unix = GNUNET_YES;
+    }
 
   if (strstr(argv[0], "asymmetric_recv") != NULL)
   {
@@ -810,6 +826,15 @@
          else
                  GNUNET_asprintf(&logger, 
"test-quota-compliance-%s-%s","udp","symmetric");
   }
+  else if (is_unix == GNUNET_YES)
+  {
+          if (is_asymmetric_recv_constant == GNUNET_YES)
+                  GNUNET_asprintf(&logger, 
"test-quota-compliance-%s-%s","unix","asymmetric_recv_constant");
+          else if (is_asymmetric_send_constant == GNUNET_YES)
+                  GNUNET_asprintf(&logger, 
"test-quota-compliance-%s-%s","unix","asymmetric_send_constant");
+          else
+                  GNUNET_asprintf(&logger, 
"test-quota-compliance-%s-%s","unix","symmetric");
+  }
   else if (is_http == GNUNET_YES)
   {
          if (is_asymmetric_recv_constant == GNUNET_YES)

Added: gnunet/src/transport/test_quota_compliance_unix_peer1.conf
===================================================================
--- gnunet/src/transport/test_quota_compliance_unix_peer1.conf                  
        (rev 0)
+++ gnunet/src/transport/test_quota_compliance_unix_peer1.conf  2011-02-03 
16:11:49 UTC (rev 14330)
@@ -0,0 +1,104 @@
+[PATHS]
+SERVICEHOME = /tmp/test_quota_compliance_peer1/
+DEFAULTCONFIG = test_quota_compliance_unix_peer1.conf
+
+[fs]
+AUTOSTART = NO
+
+[datastore]
+AUTOSTART = NO
+
+[hostlist]
+HTTP-PROXY = 
+SERVERS = http://gnunet.org:8080/
+OPTIONS = -b
+BINARY = gnunet-daemon-hostlist
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+HTTPPORT = 8080
+
+[topology]
+BINARY = gnunet-daemon-topology
+CONFIG = $DEFAULTCONFIG
+FRIENDS = $SERVICEHOME/friends
+TARGET-CONNECTION-COUNT = 16
+AUTOCONNECT = YES
+FRIENDS-ONLY = NO
+MINIMUM-FRIENDS = 0
+
+[core]
+AUTOSTART = NO
+
+[transport-unix]
+PORT = 4368
+
+
+[transport]
+plugins = unix
+#DEBUG = YES
+PREFIX = 
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+NEIGHBOUR_LIMIT = 50
+BINARY = gnunet-service-transport
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 4091
+UNIXPATH = /tmp/test_quota_compliance_unix_transport_peer1.sock
+
+[peerinfo]
+TRUST = $SERVICEHOME/data/credit/
+HOSTS = $SERVICEHOME/data/hosts/
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-peerinfo
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 4090
+UNIXPATH = /tmp/test_quota_compliance_unix_peerinfo_peer1.sock
+
+[resolver]
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-resolver
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 4089
+UNIXPATH = /tmp/test_quota_compliance_unix_resolver_peer1.sock
+
+[statistics]
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-statistics
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 4088
+UNIXPATH = /tmp/test_quota_compliance_unix_statistics_peer1.sock
+
+[arm]
+DEFAULTSERVICES = 
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-arm
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 4087
+UNIXPATH = /tmp/test_quota_compliance_unix_arm_peer1.sock
+
+[TESTING]
+WEAKRANDOM = YES
+
+[gnunetd]
+HOSTKEY = $SERVICEHOME/.hostkey
+
+
+[dht]
+AUTOSTART = NO
+
+

Added: gnunet/src/transport/test_quota_compliance_unix_peer2.conf
===================================================================
--- gnunet/src/transport/test_quota_compliance_unix_peer2.conf                  
        (rev 0)
+++ gnunet/src/transport/test_quota_compliance_unix_peer2.conf  2011-02-03 
16:11:49 UTC (rev 14330)
@@ -0,0 +1,102 @@
+[PATHS]
+SERVICEHOME = /tmp/test_quota_compliance_peer2
+DEFAULTCONFIG = test_quota_compliance_unix_peer2.conf
+
+[transport-unix]
+PORT = 3368
+[fs]
+AUTOSTART = NO
+
+[datastore]
+AUTOSTART = NO
+
+[hostlist]
+HTTP-PROXY = 
+SERVERS = http://gnunet.org:8080/
+OPTIONS = -b
+BINARY = gnunet-daemon-hostlist
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+HTTPPORT = 8080
+
+[topology]
+BINARY = gnunet-daemon-topology
+CONFIG = $DEFAULTCONFIG
+FRIENDS = $SERVICEHOME/friends
+TARGET-CONNECTION-COUNT = 16
+AUTOCONNECT = YES
+FRIENDS-ONLY = NO
+MINIMUM-FRIENDS = 0
+
+[core]
+AUTOSTART = NO
+
+[transport]
+plugins = unix
+#DEBUG = YES
+PREFIX = 
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+NEIGHBOUR_LIMIT = 50
+BINARY = gnunet-service-transport
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 3091
+UNIXPATH = /tmp/test_quota_compliance_unix_transport_peer2.sock
+
+[peerinfo]
+TRUST = $SERVICEHOME/data/credit/
+HOSTS = $SERVICEHOME/data/hosts/
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-peerinfo
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 3090
+UNIXPATH = /tmp/test_quota_compliance_unix_peerinfo_peer2.sock
+
+[resolver]
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-resolver
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 3089
+UNIXPATH = /tmp/test_quota_compliance_unix_resolver_peer2.sock
+
+[statistics]
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-statistics
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 3088
+UNIXPATH = /tmp/test_quota_compliance_unix_statistics_peer2.sock
+
+[arm]
+DEFAULTSERVICES = 
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-arm
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 3087
+UNIXPATH = /tmp/test_quota_compliance_unix_arm_peer2.sock
+
+[TESTING]
+WEAKRANDOM = YES
+
+[gnunetd]
+HOSTKEY = $SERVICEHOME/.hostkey
+
+
+[dht]
+AUTOSTART = NO
+
+

Modified: gnunet/src/transport/test_transport_api.c
===================================================================
--- gnunet/src/transport/test_transport_api.c   2011-02-03 16:09:06 UTC (rev 
14329)
+++ gnunet/src/transport/test_transport_api.c   2011-02-03 16:11:49 UTC (rev 
14330)
@@ -76,6 +76,8 @@
 
 static int is_udp;
 
+static int is_unix;
+
 static int is_udp_nat;
 
 static int is_http;
@@ -369,6 +371,12 @@
       setup_peer (&p1, "test_transport_api_udp_peer1.conf");
       setup_peer (&p2, "test_transport_api_udp_peer2.conf");
     }
+  if (is_unix)
+    {
+      GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Using unix domain socket 
transport\n");
+      setup_peer (&p1, "test_transport_api_unix_peer1.conf");
+      setup_peer (&p2, "test_transport_api_unix_peer2.conf");
+    }
   if (is_multi_protocol)
     {
       setup_peer (&p1, "test_transport_api_multi_peer1.conf");
@@ -634,6 +642,10 @@
     {
       is_udp = GNUNET_YES;
     }
+  else if (strstr(argv[0], "unix") != NULL)
+    {
+      is_unix = GNUNET_YES;
+    }
   else if (strstr(argv[0], "https") != NULL)
     {
       is_https = GNUNET_YES;

Modified: gnunet/src/transport/test_transport_api_reliability.c
===================================================================
--- gnunet/src/transport/test_transport_api_reliability.c       2011-02-03 
16:09:06 UTC (rev 14329)
+++ gnunet/src/transport/test_transport_api_reliability.c       2011-02-03 
16:11:49 UTC (rev 14330)
@@ -34,6 +34,7 @@
 #include "gnunet_scheduler_lib.h"
 #include "gnunet_server_lib.h"
 #include "gnunet_transport_service.h"
+#include "gauger.h"
 #include "transport.h"
 
 #define VERBOSE GNUNET_NO
@@ -82,6 +83,8 @@
 
 static int is_udp;
 
+static int is_unix;
+
 static int connected;
 
 static unsigned long long total_bytes;
@@ -95,7 +98,7 @@
 
 static char * key_file_p2;
 static char * cert_file_p2;
-
+static char *test_name;
 static int msg_scheduled;
 static int msg_sent;
 static int msg_recv_expected;
@@ -113,6 +116,7 @@
 end ()
 {
   unsigned long long delta;
+  char *value_name;
 
   GNUNET_SCHEDULER_cancel (die_task);
   die_task = GNUNET_SCHEDULER_NO_TASK;
@@ -129,6 +133,9 @@
   fprintf (stderr,
           "\nThroughput was %llu kb/s\n",
           total_bytes * 1000 / 1024 / delta);
+  GNUNET_asprintf(&value_name, "reliable_kbs_%s", test_name);
+  GAUGER (value_name, (int)(total_bytes * 1000 / 1024 /delta));
+  GNUNET_free(value_name);
   ok = 0;
 
 }
@@ -665,6 +672,11 @@
       setup_peer (&p1, "test_transport_api_udp_peer1.conf");
       setup_peer (&p2, "test_transport_api_udp_peer2.conf");
     }
+  else if (is_unix)
+    {
+      setup_peer (&p1, "test_transport_api_unix_peer1.conf");
+      setup_peer (&p2, "test_transport_api_unix_peer2.conf");
+    }
   else if (is_tcp_nat)
     {
       setup_peer (&p1, "test_transport_api_tcp_nat_peer1.conf");
@@ -768,23 +780,33 @@
   if (strstr(argv[0], "tcp_nat") != NULL)
     {
       is_tcp_nat = GNUNET_YES;
+      GNUNET_asprintf(&test_name, "tcp_nat");
     }
   else if (strstr(argv[0], "tcp") != NULL)
     {
       is_tcp = GNUNET_YES;
+      GNUNET_asprintf(&test_name, "tcp");
     }
   else if (strstr(argv[0], "https") != NULL)
     {
       is_https = GNUNET_YES;
+      GNUNET_asprintf(&test_name, "https");
     }
   else if (strstr(argv[0], "http") != NULL)
     {
       is_http = GNUNET_YES;
+      GNUNET_asprintf(&test_name, "http");
     }
   else if (strstr(argv[0], "udp") != NULL)
     {
       is_udp = GNUNET_YES;
+      GNUNET_asprintf(&test_name, "udp");
     }
+  else if (strstr(argv[0], "unix") != NULL)
+    {
+      is_unix = GNUNET_YES;
+      GNUNET_asprintf(&test_name, "unix");
+    }
   GNUNET_log_setup ("test-transport-api-reliability",
 #if VERBOSE
                     "DEBUG",

Added: gnunet/src/transport/test_transport_api_unix_peer1.conf
===================================================================
--- gnunet/src/transport/test_transport_api_unix_peer1.conf                     
        (rev 0)
+++ gnunet/src/transport/test_transport_api_unix_peer1.conf     2011-02-03 
16:11:49 UTC (rev 14330)
@@ -0,0 +1,110 @@
+[transport-unix]
+PORT = 12368
+
+[fs]
+AUTOSTART = NO
+
+[datastore]
+AUTOSTART = NO
+
+[core]
+AUTOSTART = NO
+
+[hostlist]
+HTTP-PROXY = 
+SERVERS = http://gnunet.org:8080/
+OPTIONS = -b
+BINARY = gnunet-daemon-hostlist
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+HTTPPORT = 8080
+
+[topology]
+BINARY = gnunet-daemon-topology
+CONFIG = $DEFAULTCONFIG
+FRIENDS = $SERVICEHOME/friends
+TARGET-CONNECTION-COUNT = 16
+AUTOCONNECT = YES
+FRIENDS-ONLY = NO
+MINIMUM-FRIENDS = 0
+
+[core]
+AUTOSTART = NO
+
+[transport]
+PLUGINS = unix
+#DEBUG = YES
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+NEIGHBOUR_LIMIT = 50
+BINARY = gnunet-service-transport
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 12365
+UNIXPATH = /tmp/gnunet-p1-service-transport.sock
+
+
+[peerinfo]
+TRUST = $SERVICEHOME/data/credit/
+HOSTS = $SERVICEHOME/data/hosts/
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-peerinfo
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 12369
+UNIXPATH = /tmp/gnunet-p1-service-peerinfo.sock
+
+[resolver]
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-resolver
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 12364
+UNIXPATH = /tmp/gnunet-p1-service-resolver.sock
+
+[statistics]
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-statistics
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 12367
+UNIXPATH = /tmp/gnunet-p1-service-statistics.sock
+
+[arm]
+DEFAULTSERVICES = 
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-arm
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 12366
+UNIXPATH = /tmp/gnunet-p1-service-arm.sock
+
+[transport-tcp]
+TIMEOUT = 300000
+PORT = 12368
+
+[TESTING]
+WEAKRANDOM = YES
+
+[gnunetd]
+HOSTKEY = $SERVICEHOME/.hostkey
+
+[PATHS]
+DEFAULTCONFIG = test_transport_api_unix_peer1.conf
+SERVICEHOME = /tmp/test-gnunetd-transport-peer-1/
+
+
+[dht]
+AUTOSTART = NO
+
+

Added: gnunet/src/transport/test_transport_api_unix_peer2.conf
===================================================================
--- gnunet/src/transport/test_transport_api_unix_peer2.conf                     
        (rev 0)
+++ gnunet/src/transport/test_transport_api_unix_peer2.conf     2011-02-03 
16:11:49 UTC (rev 14330)
@@ -0,0 +1,108 @@
+[transport-unix]
+PORT = 22368
+
+[fs]
+AUTOSTART = NO
+
+[datastore]
+AUTOSTART = NO
+
+[core]
+AUTOSTART = NO
+
+[hostlist]
+HTTP-PROXY = 
+SERVERS = http://gnunet.org:8080/
+OPTIONS = -b
+BINARY = gnunet-daemon-hostlist
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+HTTPPORT = 8080
+
+[topology]
+BINARY = gnunet-daemon-topology
+CONFIG = $DEFAULTCONFIG
+FRIENDS = $SERVICEHOME/friends
+TARGET-CONNECTION-COUNT = 16
+AUTOCONNECT = YES
+FRIENDS-ONLY = NO
+MINIMUM-FRIENDS = 0
+
+[transport]
+PLUGINS = unix
+#DEBUG = YES
+PREFIX = 
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+NEIGHBOUR_LIMIT = 50
+BINARY = gnunet-service-transport
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 22365
+UNIXPATH = /tmp/gnunet-p2-service-transport.sock
+#PREFIX = valgrind --track-origins=yes --leak-check=full 
--log-file=valgrind_udp_peer2.log
+
+[peerinfo]
+TRUST = $SERVICEHOME/data/credit/
+HOSTS = $SERVICEHOME/data/hosts/
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-peerinfo
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 22369
+UNIXPATH = /tmp/gnunet-p2-service-peerinfo.sock
+
+[resolver]
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-resolver
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 22364
+UNIXPATH = /tmp/gnunet-p2-service-resolver.sock
+
+[statistics]
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-statistics
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 22367
+UNIXPATH = /tmp/gnunet-p2-service-statistics.sock
+
+[arm]
+DEFAULTSERVICES = 
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+BINARY = gnunet-service-arm
+CONFIG = $DEFAULTCONFIG
+HOME = $SERVICEHOME
+HOSTNAME = localhost
+PORT = 22366
+UNIXPATH = /tmp/gnunet-p2-service-arm.sock
+
+[transport-tcp]
+TIMEOUT = 300000
+PORT = 22368
+
+[TESTING]
+WEAKRANDOM = YES
+
+[gnunetd]
+HOSTKEY = $SERVICEHOME/.hostkey
+
+[PATHS]
+DEFAULTCONFIG = test_transport_api_unix_peer2.conf
+SERVICEHOME = /tmp/test-gnunetd-transport-peer-2/
+
+
+[dht]
+AUTOSTART = NO
+
+

Added: gnunet/src/transport/test_transport_api_unreliability.c
===================================================================
--- gnunet/src/transport/test_transport_api_unreliability.c                     
        (rev 0)
+++ gnunet/src/transport/test_transport_api_unreliability.c     2011-02-03 
16:11:49 UTC (rev 14330)
@@ -0,0 +1,922 @@
+/*
+     This file is part of GNUnet.
+     (C) 2009, 2010 Christian Grothoff (and other contributing authors)
+
+     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., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+/**
+ * @file transport/test_transport_api_unreliability.c
+ * @brief test case for transports; ensures messages get
+ *        through, regardless of order
+ *
+ * This test case serves as a base for unreliable
+ * transport test cases to check that the transports
+ * achieve reliable message delivery.
+ */
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_hello_lib.h"
+#include "gnunet_getopt_lib.h"
+#include "gnunet_os_lib.h"
+#include "gnunet_program_lib.h"
+#include "gnunet_scheduler_lib.h"
+#include "gnunet_server_lib.h"
+#include "gnunet_transport_service.h"
+#include "gauger.h"
+#include "transport.h"
+
+#define VERBOSE GNUNET_NO
+
+#define VERBOSE_ARM GNUNET_NO
+
+#define START_ARM GNUNET_YES
+
+/**
+ * Note that this value must not significantly exceed
+ * 'MAX_PENDING' in 'gnunet-service-transport.c', otherwise
+ * messages may be dropped even for a reliable transport.
+ */
+#define TOTAL_MSGS (80000 * 3) /* Total messages should be divisible by 8, so 
we can make a nice bitmap */
+
+/**
+ * How long until we give up on transmitting the message?
+ */
+#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1500)
+
+#define UNRELIABLE_TIMEOUT GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_SECONDS, 1)
+
+#define MTYPE 12345
+
+struct PeerContext
+{
+  struct GNUNET_CONFIGURATION_Handle *cfg;
+  struct GNUNET_TRANSPORT_Handle *th;
+  struct GNUNET_PeerIdentity id;
+#if START_ARM
+  struct GNUNET_OS_Process *arm_proc;
+#endif
+};
+
+static struct PeerContext p1;
+
+static struct PeerContext p2;
+
+static int ok;
+
+static int is_tcp;
+
+static int is_tcp_nat;
+
+static int is_http;
+
+static int is_https;
+
+static int is_udp;
+
+static int is_unix;
+
+static int connected;
+
+static unsigned long long total_bytes;
+
+static struct GNUNET_TIME_Absolute start_time;
+
+static GNUNET_SCHEDULER_TaskIdentifier die_task;
+
+static char *key_file_p1;
+static char *cert_file_p1;
+
+static char *key_file_p2;
+static char *cert_file_p2;
+
+static char *test_name;
+
+static char bitmap[TOTAL_MSGS / 8];
+
+static int msg_scheduled;
+static int msg_sent;
+static int msg_recv_expected;
+static int msg_recv;
+static struct GNUNET_TRANSPORT_TransmitHandle * transmit_handle;
+
+#if VERBOSE
+#define OKPP do { ok++; fprintf (stderr, "Now at stage %u at %s:%u\n", ok, 
__FILE__, __LINE__); } while (0)
+#else
+#define OKPP do { ok++; } while (0)
+#endif
+
+/**
+ * Sets a bit active in the bitmap.
+ *
+ * @param bitIdx which bit to set
+ */
+static void
+set_bit (unsigned int bitIdx)
+{
+  size_t arraySlot;
+  unsigned int targetBit;
+  if (bitIdx > sizeof(bitmap) * 8)
+    {
+      GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "setting bit %d of %d(!)\n", bitIdx, 
sizeof(bitmap) * 8);
+      return;
+    }
+  GNUNET_assert(bitIdx < sizeof(bitmap) * 8);
+  arraySlot = bitIdx / 8;
+  targetBit = (1L << (bitIdx % 8));
+  bitmap[arraySlot] |= targetBit;
+}
+
+/**
+ * Obtain a bit from bitmap.
+ * @param map the bitmap
+ * @param bit index from bitmap
+ *
+ * @return Bit \a bit from hashcode \a code
+ */
+int
+get_bit (const char *map, unsigned int bit)
+{
+  if (bit >= TOTAL_MSGS)
+    {
+      GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "get bit %d of %d(!?!?)\n", bit, 
sizeof(bitmap) * 8);
+      return 0;
+    }
+  return ((map)[bit >> 3] & (1 << (bit & 7))) > 0;
+}
+
+static void
+end ()
+{
+  unsigned long long delta;
+  int i;
+  int result;
+  char *value_name;
+
+  result = 0;
+  for (i = 0; i < TOTAL_MSGS; i++)
+    {
+      if (get_bit(bitmap, i) == 0)
+        {
+          GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Did not receive message 
%d\n", i);
+          result = -1;
+        }
+    }
+
+  GNUNET_SCHEDULER_cancel (die_task);
+  die_task = GNUNET_SCHEDULER_NO_TASK;
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transports!\n");
+#endif
+  GNUNET_TRANSPORT_disconnect (p1.th);
+  GNUNET_TRANSPORT_disconnect (p2.th);
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+             "Transports disconnected, returning success!\n");
+#endif
+  delta = GNUNET_TIME_absolute_get_duration (start_time).rel_value;
+  GNUNET_asprintf(&value_name, "unreliable_kbs_%s", test_name);
+  GAUGER (value_name, (int)(total_bytes * 1000 / 1024 /delta));
+  GNUNET_free(value_name);
+  fprintf (stderr,
+          "\nThroughput was %llu kb/s\n",
+          total_bytes * 1000 / 1024 / delta);
+  ok = result;
+
+}
+
+static void
+end_unreliably ()
+{
+  unsigned long long delta;
+  int i;
+  int num_failed;
+  char *value_name;
+  num_failed = 0;
+  for (i = 0; i < TOTAL_MSGS; i++)
+    {
+      if (get_bit(bitmap, i) == 0)
+        {
+          GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Did not receive message %d\n", 
i);
+          num_failed++;
+        }
+    }
+
+  die_task = GNUNET_SCHEDULER_NO_TASK;
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from transports!\n");
+#endif
+  GNUNET_TRANSPORT_disconnect (p1.th);
+  GNUNET_TRANSPORT_disconnect (p2.th);
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Transports disconnected, returning success!\n");
+#endif
+  delta = GNUNET_TIME_absolute_get_duration (start_time).rel_value;
+  fprintf (stderr,
+           "\nThroughput was %llu kb/s\n",
+           total_bytes * 1000 / 1024 / delta);
+  GNUNET_asprintf(&value_name, "unreliable_kbs_%s", test_name);
+  GAUGER (value_name, (int)(total_bytes * 1000 / 1024 /delta));
+  GNUNET_free(value_name);
+  GNUNET_asprintf(&value_name, "unreliable_failed_%s", test_name);
+  GAUGER (value_name, (int)num_failed);
+  GNUNET_free(value_name);
+  GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Had %d failed messages!\n", 
num_failed);
+  ok = 0;
+
+}
+
+
+
+static void
+stop_arm (struct PeerContext *p)
+{
+#if START_ARM
+  if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
+    GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
+  GNUNET_OS_process_wait (p->arm_proc);
+  GNUNET_OS_process_close (p->arm_proc);
+  p->arm_proc = NULL;
+#endif
+  GNUNET_CONFIGURATION_destroy (p->cfg);
+}
+
+
+static void
+end_badly (void *cls,
+          const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                 "Reliability failed: \nLast message sent %u \nNext message 
scheduled %u\nLast message received %u\nMessage expected %u \n ", msg_sent, 
msg_scheduled, msg_recv, msg_recv_expected);
+  GNUNET_break (0);
+  GNUNET_TRANSPORT_disconnect (p1.th);
+  GNUNET_TRANSPORT_disconnect (p2.th);
+  ok = 1;
+}
+
+
+struct TestMessage
+{
+  struct GNUNET_MessageHeader header;
+  uint32_t num;
+};
+
+
+static unsigned int
+get_size (unsigned int iter)
+{
+  unsigned int ret;
+
+  if (iter < 60000)
+    return iter + sizeof (struct TestMessage);
+  ret = (iter * iter * iter);
+  return sizeof (struct TestMessage) + (ret % 60000);
+}
+
+
+static void
+notify_receive (void *cls,
+                const struct GNUNET_PeerIdentity *peer,
+                const struct GNUNET_MessageHeader *message,
+                const struct GNUNET_TRANSPORT_ATS_Information *ats,
+                uint32_t ats_count)
+{
+  static int n;
+  unsigned int s;
+  char cbuf[GNUNET_SERVER_MAX_MESSAGE_SIZE - 1];
+  const struct TestMessage *hdr;
+
+  hdr = (const struct TestMessage*) message;
+
+  if (MTYPE != ntohs (message->type))
+    return;
+  msg_recv_expected = n;
+  msg_recv = ntohl(hdr->num);
+  s = get_size (ntohl(hdr->num));
+
+  if (ntohs (message->size) != s)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                 "Expected message %u of size %u, got %u bytes of message 
%u\n",
+                 ntohl(hdr->num), s,
+                 ntohs (message->size),
+                 ntohl (hdr->num));
+      GNUNET_SCHEDULER_cancel (die_task);
+      die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
+      return;
+    }
+
+  memset (cbuf, ntohl(hdr->num), s - sizeof (struct TestMessage));
+  if (0 != memcmp (cbuf,
+                  &hdr[1],
+                  s - sizeof (struct TestMessage)))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                 "Expected message %u with bits %u, but body did not match\n",
+                 ntohl(hdr->num), (unsigned char) n);
+      GNUNET_SCHEDULER_cancel (die_task);
+      die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
+      return;
+    }
+#if VERBOSE
+  if (ntohl(hdr->num) % 5 == 0)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Got message %u of size %u\n",
+                  ntohl (hdr->num),
+                  ntohs (message->size));
+    }
+#endif
+  n++;
+  set_bit(ntohl(hdr->num));
+  if (0 == (n % (5000)))
+    {
+      fprintf (stderr, ".");
+      GNUNET_SCHEDULER_cancel (die_task);
+      die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
+                                              &end_badly,
+                                              NULL);
+    }
+  if (n == TOTAL_MSGS)
+    end ();
+}
+
+
+static size_t
+notify_ready (void *cls, size_t size, void *buf)
+{
+  static int n;
+  char *cbuf = buf;
+  struct TestMessage hdr;
+  unsigned int s;
+  unsigned int ret;
+
+  if (buf == NULL)
+    {
+      GNUNET_break (0);
+      ok = 42;
+      return 0;
+    }
+  ret = 0;
+  s = get_size (n);
+  GNUNET_assert (size >= s);
+  GNUNET_assert (buf != NULL);
+  cbuf = buf;
+  do
+    {
+      hdr.header.size = htons (s);
+      hdr.header.type = htons (MTYPE);
+      hdr.num = htonl (n);
+      msg_sent = n;
+      memcpy (&cbuf[ret], &hdr, sizeof (struct TestMessage));
+      ret += sizeof (struct TestMessage);
+      memset (&cbuf[ret], n, s - sizeof (struct TestMessage));
+      ret += s - sizeof (struct TestMessage);
+#if VERBOSE
+      if (n % 5000 == 0)
+        {
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                      "Sending message %u of size %u\n",
+                      n,
+                      s);
+        }
+#endif
+      n++;
+      s = get_size (n);
+      if (0 == GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 16))
+       break; /* sometimes pack buffer full, sometimes not */
+    }
+  while (size - ret >= s);
+  if (n < TOTAL_MSGS)
+  {
+    GNUNET_TRANSPORT_notify_transmit_ready (p2.th,
+                                           &p1.id,
+                                           s, 0, TIMEOUT,
+                                           &notify_ready,
+                                           NULL);
+    msg_scheduled = n;
+  }
+  else
+    {
+      GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "All messages scheduled to be 
sent!!\n");
+      GNUNET_SCHEDULER_cancel(die_task);
+      die_task = GNUNET_SCHEDULER_add_delayed (UNRELIABLE_TIMEOUT, 
&end_unreliably, NULL);
+    }
+  if (n % 5000 == 0)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+                  "Returning total message block of size %u\n",
+                  ret);
+    }
+  total_bytes += ret;
+  return ret;
+}
+
+
+static void
+notify_connect (void *cls,
+                const struct GNUNET_PeerIdentity *peer,
+                const struct GNUNET_TRANSPORT_ATS_Information *ats,
+                uint32_t ats_count)
+{
+  if (cls == &p1)
+    {
+      GNUNET_TRANSPORT_set_quota (p1.th,
+                                 &p2.id,
+                                 GNUNET_BANDWIDTH_value_init (1024 * 1024 * 
1024),
+                                 GNUNET_BANDWIDTH_value_init (1024 * 1024 * 
1024),
+                                 GNUNET_TIME_UNIT_FOREVER_REL,
+                                 NULL, NULL);
+      start_time = GNUNET_TIME_absolute_get ();
+      connected++;
+    }
+  else
+    {
+      GNUNET_TRANSPORT_set_quota (p2.th,
+                                 &p1.id,
+                                 GNUNET_BANDWIDTH_value_init (1024 * 1024 * 
1024),
+                                 GNUNET_BANDWIDTH_value_init (1024 * 1024 * 
1024),
+                                 GNUNET_TIME_UNIT_FOREVER_REL,
+                                 NULL, NULL);
+      connected++;
+    }
+
+  if (connected == 2)
+    {
+
+         if ((transmit_handle!=NULL) && (cls == NULL))
+                GNUNET_TRANSPORT_notify_transmit_ready_cancel(transmit_handle);
+         if ((transmit_handle!=NULL) && (cls == &transmit_handle))
+                transmit_handle=NULL;
+      GNUNET_TRANSPORT_notify_transmit_ready (p2.th,
+                                              &p1.id,
+                                              get_size (0), 0, TIMEOUT,
+                                              &notify_ready,
+                                              NULL);
+    }
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Peer `%4s' connected to us (%p)!\n", GNUNET_i2s (peer), cls);
+#endif
+}
+
+
+static void
+notify_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
+{
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Peer `%4s' disconnected (%p)!\n",
+             GNUNET_i2s (peer), cls);
+#endif
+}
+
+
+static void
+setup_peer (struct PeerContext *p, const char *cfgname)
+{
+  p->cfg = GNUNET_CONFIGURATION_create ();
+#if START_ARM
+  p->arm_proc = GNUNET_OS_start_process (NULL, NULL,
+                                       "gnunet-service-arm",
+                                        "gnunet-service-arm",
+#if VERBOSE_ARM
+                                        "-L", "DEBUG",
+#endif
+                                        "-c", cfgname, NULL);
+#endif
+  GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
+
+  if (is_https)
+  {
+         struct stat sbuf;
+         if (p==&p1)
+         {
+                 if (GNUNET_CONFIGURATION_have_value (p->cfg,
+                                                                               
           "transport-https", "KEY_FILE"))
+                               GNUNET_CONFIGURATION_get_value_string (p->cfg, 
"transport-https", "KEY_FILE", &key_file_p1);
+                 if (key_file_p1 == NULL)
+                         GNUNET_asprintf(&key_file_p1,"https_p1.key");
+                 if (0 == stat (key_file_p1, &sbuf ))
+                 {
+                         if (0 == remove(key_file_p1))
+                             GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
"Successfully removed existing private key file `%s'\n",key_file_p1);
+                         else
+                                 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed 
to remove private key file `%s'\n",key_file_p1);
+                 }
+                 if (GNUNET_CONFIGURATION_have_value 
(p->cfg,"transport-https", "CERT_FILE"))
+                         GNUNET_CONFIGURATION_get_value_string (p->cfg, 
"transport-https", "CERT_FILE", &cert_file_p1);
+                 if (cert_file_p1 == NULL)
+                         GNUNET_asprintf(&cert_file_p1,"https_p1.cert");
+                 if (0 == stat (cert_file_p1, &sbuf ))
+                 {
+                         if (0 == remove(cert_file_p1))
+                             GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
"Successfully removed existing certificate file `%s'\n",cert_file_p1);
+                         else
+                                 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed 
to remove existing certificate file `%s'\n",cert_file_p1);
+                 }
+         }
+         else if (p==&p2)
+         {
+                 if (GNUNET_CONFIGURATION_have_value (p->cfg,
+                                                                               
           "transport-https", "KEY_FILE"))
+                               GNUNET_CONFIGURATION_get_value_string (p->cfg, 
"transport-https", "KEY_FILE", &key_file_p2);
+                 if (key_file_p2 == NULL)
+                         GNUNET_asprintf(&key_file_p2,"https_p2.key");
+                 if (0 == stat (key_file_p2, &sbuf ))
+                 {
+                         if (0 == remove(key_file_p2))
+                             GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
"Successfully removed existing private key file `%s'\n",key_file_p2);
+                         else
+                                 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed 
to remove private key file `%s'\n",key_file_p2);
+                 }
+                 if (GNUNET_CONFIGURATION_have_value 
(p->cfg,"transport-https", "CERT_FILE"))
+                         GNUNET_CONFIGURATION_get_value_string (p->cfg, 
"transport-https", "CERT_FILE", &cert_file_p2);
+                 if (cert_file_p2 == NULL)
+                         GNUNET_asprintf(&cert_file_p2,"https_p2.cert");
+                 if (0 == stat (cert_file_p2, &sbuf ))
+                 {
+                         if (0 == remove(cert_file_p2))
+                             GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 
"Successfully removed existing certificate file `%s'\n",cert_file_p2);
+                         else
+                                 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed 
to remove existing certificate file `%s'\n",cert_file_p2);
+                 }
+         }
+  }
+
+  p->th = GNUNET_TRANSPORT_connect (p->cfg, NULL,
+                                    p,
+                                    &notify_receive,
+                                    &notify_connect,
+                                   &notify_disconnect);
+  GNUNET_assert (p->th != NULL);
+}
+
+static size_t
+notify_ready_connect (void *cls, size_t size, void *buf)
+{
+  return 0;
+}
+
+static void
+exchange_hello_last (void *cls,
+                     const struct GNUNET_MessageHeader *message)
+{
+  struct PeerContext *me = cls;
+  transmit_handle = NULL;
+  GNUNET_TRANSPORT_get_hello_cancel (p2.th, &exchange_hello_last, me);
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Exchanging HELLO with peer (%p)!\n", cls);
+#endif
+  GNUNET_assert (ok >= 3);
+  OKPP;
+  GNUNET_assert (message != NULL);
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
+                                      message, &me->id));
+
+  GNUNET_assert(NULL != (transmit_handle = 
GNUNET_TRANSPORT_notify_transmit_ready (p2.th,
+                                          &p1.id,
+                                          sizeof (struct 
GNUNET_MessageHeader), 0,
+                                          TIMEOUT,
+                                          &notify_ready_connect,
+                                          &transmit_handle)));
+
+  /* both HELLOs exchanged, get ready to test transmission! */
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Finished exchanging HELLOs, now waiting for transmission!\n");
+}
+
+
+static void
+exchange_hello (void *cls,
+                const struct GNUNET_MessageHeader *message)
+{
+  struct PeerContext *me = cls;
+
+  GNUNET_TRANSPORT_get_hello_cancel (p1.th, &exchange_hello, me);
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Exchanging HELLO with peer (%p)!\n", cls);
+#endif
+  GNUNET_assert (ok >= 2);
+  OKPP;
+  GNUNET_assert (message != NULL);
+  GNUNET_assert (GNUNET_OK ==
+                 GNUNET_HELLO_get_id ((const struct GNUNET_HELLO_Message *)
+                                      message, &me->id));
+
+#if VERBOSE
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+              "Received HELLO size %d\n",
+             GNUNET_HELLO_size((const struct GNUNET_HELLO_Message *)message));
+#endif
+  GNUNET_TRANSPORT_offer_hello (p2.th, message);
+  GNUNET_TRANSPORT_get_hello (p2.th, &exchange_hello_last, &p2);
+}
+
+/**
+ * Return the actual path to a file found in the current
+ * PATH environment variable.
+ *
+ * @param binary the name of the file to find
+ */
+static char *
+get_path_from_PATH (char *binary)
+{
+  char *path;
+  char *pos;
+  char *end;
+  char *buf;
+  const char *p;
+
+  p = getenv ("PATH");
+  if (p == NULL)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  _("PATH environment variable is unset.\n"));
+      return NULL;
+    }
+  path = GNUNET_strdup (p);     /* because we write on it */
+  buf = GNUNET_malloc (strlen (path) + 20);
+  pos = path;
+
+  while (NULL != (end = strchr (pos, PATH_SEPARATOR)))
+    {
+      *end = '\0';
+      sprintf (buf, "%s/%s", pos, binary);
+      if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
+        {
+          GNUNET_free (path);
+          return buf;
+        }
+      pos = end + 1;
+    }
+  sprintf (buf, "%s/%s", pos, binary);
+  if (GNUNET_DISK_file_test (buf) == GNUNET_YES)
+    {
+      GNUNET_free (path);
+      return buf;
+    }
+  GNUNET_free (buf);
+  GNUNET_free (path);
+  return NULL;
+}
+
+/**
+ * Check whether the suid bit is set on a file.
+ * Attempts to find the file using the current
+ * PATH environment variable as a search path.
+ *
+ * @param binary the name of the file to check
+ *
+ * @return GNUNET_YES if the binary is found and
+ *         can be run properly, GNUNET_NO otherwise
+ */
+static int
+check_gnunet_nat_binary(char *binary)
+{
+  struct stat statbuf;
+  char *p;
+#ifdef MINGW
+  SOCKET rawsock;
+#endif
+
+#ifdef MINGW
+  char *binaryexe;
+  GNUNET_asprintf (&binaryexe, "%s.exe", binary);
+  p = get_path_from_PATH (binaryexe);
+  free (binaryexe);
+#else
+  p = get_path_from_PATH (binary);
+#endif
+  if (p == NULL)
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                  _("Could not find binary `%s' in PATH!\n"),
+                  binary);
+      return GNUNET_NO;
+    }
+  if (0 != STAT (p, &statbuf))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  _("stat (%s) failed: %s\n"),
+                  p,
+                  STRERROR (errno));
+      GNUNET_free (p);
+      return GNUNET_SYSERR;
+    }
+  GNUNET_free (p);
+#ifndef MINGW
+  if ( (0 != (statbuf.st_mode & S_ISUID)) &&
+       (statbuf.st_uid == 0) )
+    return GNUNET_YES;
+  return GNUNET_NO;
+#else
+  rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
+  if (INVALID_SOCKET == rawsock)
+    {
+      DWORD err = GetLastError ();
+      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) have failed! GLE = 
%d\n", err);
+      return GNUNET_NO; /* not running as administrator */
+    }
+  closesocket (rawsock);
+  return GNUNET_YES;
+#endif
+}
+
+static void
+run (void *cls,
+     char *const *args,
+     const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+  GNUNET_assert (ok == 1);
+  OKPP;
+  die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
+                                          &end_badly,
+                                          NULL);
+  if (is_tcp)
+    {
+      setup_peer (&p1, "test_transport_api_tcp_peer1.conf");
+      setup_peer (&p2, "test_transport_api_tcp_peer2.conf");
+    }
+  else if (is_http)
+    {
+      setup_peer (&p1, "test_transport_api_rel_http_peer1.conf");
+      setup_peer (&p2, "test_transport_api_rel_http_peer2.conf");
+    }
+  else if (is_https)
+    {
+      setup_peer (&p1, "test_transport_api_rel_https_peer1.conf");
+      setup_peer (&p2, "test_transport_api_rel_https_peer2.conf");
+    }
+  else if (is_udp)
+    {
+      setup_peer (&p1, "test_transport_api_udp_peer1.conf");
+      setup_peer (&p2, "test_transport_api_udp_peer2.conf");
+    }
+  else if (is_unix)
+    {
+      setup_peer (&p1, "test_transport_api_unix_peer1.conf");
+      setup_peer (&p2, "test_transport_api_unix_peer2.conf");
+    }
+  else if (is_tcp_nat)
+    {
+      setup_peer (&p1, "test_transport_api_tcp_nat_peer1.conf");
+      setup_peer (&p2, "test_transport_api_tcp_nat_peer2.conf");
+    }
+  else
+    GNUNET_assert (0);
+  GNUNET_assert(p1.th != NULL);
+  GNUNET_assert(p2.th != NULL);
+  GNUNET_TRANSPORT_get_hello (p1.th, &exchange_hello, &p1);
+}
+
+
+static int
+check ()
+{
+  char *const argv[] = { "test-transport-api-reliability",
+    "-c",
+    "test_transport_api_data.conf",
+#if VERBOSE
+    "-L", "DEBUG",
+#endif
+    NULL
+  };
+  struct GNUNET_GETOPT_CommandLineOption options[] = {
+    GNUNET_GETOPT_OPTION_END
+  };
+
+#if WRITECONFIG
+  setTransportOptions("test_transport_api_data.conf");
+#endif
+  ok = 1;
+
+  if ((GNUNET_YES == is_tcp_nat) && 
(check_gnunet_nat_binary("gnunet-nat-server") != GNUNET_YES))
+    {
+      GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Not running NAT test case, 
binaries not properly installed.\n");
+      return 0;
+    }
+
+  GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
+                      argv, "test-transport-api-reliability", "nohelp",
+                      options, &run, &ok);
+  stop_arm (&p1);
+  stop_arm (&p2);
+
+  if (is_https)
+  {
+    struct stat sbuf;
+    if (0 == stat (cert_file_p1, &sbuf ))
+    {
+      if (0 == remove(cert_file_p1))
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully removed existing 
certificate file `%s'\n",cert_file_p1);
+      else
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to remove certfile 
`%s'\n",cert_file_p1);
+    }
+
+    if (0 == stat (key_file_p1, &sbuf ))
+    {
+      if (0 == remove(key_file_p1))
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully removed private key 
file `%s'\n",key_file_p1);
+      else
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to private key file 
`%s'\n",key_file_p1);
+    }
+
+    if (0 == stat (cert_file_p2, &sbuf ))
+    {
+      if (0 == remove(cert_file_p2))
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully removed existing 
certificate file `%s'\n",cert_file_p2);
+      else
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to remove certfile 
`%s'\n",cert_file_p2);
+    }
+
+    if (0 == stat (key_file_p2, &sbuf ))
+    {
+      if (0 == remove(key_file_p2))
+        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Successfully removed private key 
file `%s'\n",key_file_p2);
+      else
+        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to private key file 
`%s'\n",key_file_p2);
+    }
+    GNUNET_free(key_file_p1);
+    GNUNET_free(key_file_p2);
+    GNUNET_free(cert_file_p1);
+    GNUNET_free(cert_file_p2);
+  }
+
+  return ok;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  int ret;
+#ifdef MINGW
+  return GNUNET_SYSERR;
+#endif
+
+  GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-1");
+  GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-2");
+
+  if (strstr(argv[0], "tcp_nat") != NULL)
+    {
+      is_tcp_nat = GNUNET_YES;
+      GNUNET_asprintf(&test_name, "tcp_nat");
+    }
+  else if (strstr(argv[0], "tcp") != NULL)
+    {
+      is_tcp = GNUNET_YES;
+      GNUNET_asprintf(&test_name, "tcp");
+    }
+  else if (strstr(argv[0], "https") != NULL)
+    {
+      is_https = GNUNET_YES;
+      GNUNET_asprintf(&test_name, "https");
+    }
+  else if (strstr(argv[0], "http") != NULL)
+    {
+      is_http = GNUNET_YES;
+      GNUNET_asprintf(&test_name, "http");
+    }
+  else if (strstr(argv[0], "udp") != NULL)
+    {
+      is_udp = GNUNET_YES;
+      GNUNET_asprintf(&test_name, "udp");
+    }
+  else if (strstr(argv[0], "unix") != NULL)
+    {
+      is_unix = GNUNET_YES;
+      GNUNET_asprintf(&test_name, "unix");
+    }
+  GNUNET_log_setup ("test-transport-api-reliability",
+#if VERBOSE
+                    "DEBUG",
+#else
+                    "WARNING",
+#endif
+                    NULL);
+  ret = check ();
+  GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-1");
+  GNUNET_DISK_directory_remove ("/tmp/test-gnunetd-transport-peer-2");
+  GNUNET_free_non_null(test_name);
+  return ret;
+}
+
+/* end of test_transport_api_reliability.c */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]