low level network API
authorNils Durner <durner@gnunet.org>
Sun, 23 Aug 2009 22:11:49 +0000 (22:11 +0000)
committerNils Durner <durner@gnunet.org>
Sun, 23 Aug 2009 22:11:49 +0000 (22:11 +0000)
35 files changed:
src/hostlist/hostlist-client.c
src/hostlist/hostlist-server.c
src/include/Makefile.am
src/include/gnunet_client_lib.h
src/include/gnunet_connection_lib.h [new file with mode: 0644]
src/include/gnunet_disk_lib.h
src/include/gnunet_network_lib.h
src/include/gnunet_scheduler_lib.h
src/include/gnunet_server_lib.h
src/include/gnunet_transport_service.h
src/include/gnunet_util_lib.h
src/transport/plugin_transport_http.c
src/transport/plugin_transport_tcp.c
src/transport/plugin_transport_template.c
src/transport/plugin_transport_udp.c
src/upnp/upnp.c
src/upnp/upnp_init.c
src/util/Makefile.am
src/util/disk.c
src/util/disk.h [new file with mode: 0644]
src/util/network.c
src/util/scheduler.c
src/util/server.c
src/util/server_tc.c
src/util/service.c
src/util/sock.c [new file with mode: 0644]
src/util/test_network.c
src/util/test_network_addressing.c
src/util/test_network_receive_cancel.c
src/util/test_network_timeout.c
src/util/test_network_timeout_no_connect.c
src/util/test_network_transmit_cancel.c
src/util/test_scheduler.c
src/util/test_service.c
src/util/win.cc

index 468c6b64cec83453920c750abc389fe9decd3ae3..cc24dc135a2a03a15a1ade98d5ea6db8e7be1035 100644 (file)
@@ -380,11 +380,17 @@ run_multi ()
   fd_set ws;
   fd_set es;
   int max;
+  struct GNUNET_NETWORK_FDSet *grs;
+  struct GNUNET_NETWORK_FDSet *gws;
+  struct GNUNET_NETWORK_FDSet *ges;
   
   max = 0;
   FD_ZERO (&rs);
   FD_ZERO (&ws);
   FD_ZERO (&es);
+  grs = GNUNET_NETWORK_fdset_create ();
+  gws = GNUNET_NETWORK_fdset_create ();
+  ges = GNUNET_NETWORK_fdset_create ();
   mret = curl_multi_fdset (multi, &rs, &ws, &es, &max);
   if (mret != CURLM_OK)
     {
@@ -395,17 +401,22 @@ run_multi ()
       clean_up ();
       return;
     }
+  GNUNET_NETWORK_fdset_copy_native (grs, &rs, max);
+  GNUNET_NETWORK_fdset_copy_native (gws, &ws, max);
+  GNUNET_NETWORK_fdset_copy_native (ges, &es, max);
   current_task 
     = GNUNET_SCHEDULER_add_select (sched,
                                   GNUNET_NO,
                                   GNUNET_SCHEDULER_PRIORITY_DEFAULT,
                                   GNUNET_SCHEDULER_NO_TASK,
                                   GNUNET_TIME_UNIT_MINUTES,
-                                  max,
-                                  &rs,
-                                  &ws,
+                                  grs,
+                                  gws,
                                   &multi_ready,
                                   multi);
+  GNUNET_NETWORK_fdset_destroy (ges);
+  GNUNET_NETWORK_fdset_destroy (gws);
+  GNUNET_NETWORK_fdset_destroy (grs);
 }
 
 
index 5cc26c409519632c4498c4bb658271ae8b7c3b9c..03e3c5d69dd85df8cbb09ebf2de6a9896add1e04 100644 (file)
@@ -221,6 +221,9 @@ prepare_daemon ()
   fd_set rs;
   fd_set ws;
   fd_set es;
+  struct GNUNET_NETWORK_FDSet *wrs;
+  struct GNUNET_NETWORK_FDSet *wws;
+  struct GNUNET_NETWORK_FDSet *wes;
   int max;
   unsigned long long timeout;
   int haveto;
@@ -229,6 +232,9 @@ prepare_daemon ()
   FD_ZERO(&rs);
   FD_ZERO(&ws);
   FD_ZERO(&es);
+  wrs = GNUNET_NETWORK_fdset_create ();
+  wes = GNUNET_NETWORK_fdset_create ();
+  wws = GNUNET_NETWORK_fdset_create ();
   max = -1;
   GNUNET_assert (MHD_YES ==
                 MHD_get_fdset (daemon_handle,
@@ -241,17 +247,22 @@ prepare_daemon ()
     tv.value = (uint64_t) timeout;
   else
     tv = GNUNET_TIME_UNIT_FOREVER_REL;
+  GNUNET_NETWORK_fdset_copy_native (wrs, &rs, max);
+  GNUNET_NETWORK_fdset_copy_native (wws, &ws, max);
+  GNUNET_NETWORK_fdset_copy_native (wes, &es, max);
   hostlist_task 
     = GNUNET_SCHEDULER_add_select (sched,
                                   GNUNET_NO,
                                   GNUNET_SCHEDULER_PRIORITY_HIGH,
                                   GNUNET_SCHEDULER_NO_TASK,
                                   tv,
-                                  max,
-                                  &rs,
-                                  &ws,
+                                  wrs,
+                                  wws,
                                   &run_daemon,
                                   NULL);
+  GNUNET_NETWORK_fdset_destroy (wrs);
+  GNUNET_NETWORK_fdset_destroy (wws);
+  GNUNET_NETWORK_fdset_destroy (wes);
 }
 
 
index 201deeb4fe198802835a55e447beb2b080948d3a..69954fd307dc62489b0954ac45c1dea313e9f007 100644 (file)
@@ -18,6 +18,7 @@ gnunetinclude_HEADERS = \
   gnunet_constants.h \
   gnunet_configuration_lib.h \
   gnunet_container_lib.h \
+  gnunet_connection_lib.h \
   gnunet_core_service.h \
   gnunet_crypto_lib.h \
   gnunet_datacache_lib.h \
index b73691b7908f497dcbb5fde5b70eb64344bd5d21..eb75e8d1ec6e91a7ca96b4678d49c9e541e16644 100644 (file)
@@ -37,7 +37,7 @@ extern "C"
 
 #include "gnunet_common.h"
 #include "gnunet_configuration_lib.h"
-#include "gnunet_network_lib.h"
+#include "gnunet_connection_lib.h"
 #include "gnunet_scheduler_lib.h"
 #include "gnunet_time_lib.h"
 
diff --git a/src/include/gnunet_connection_lib.h b/src/include/gnunet_connection_lib.h
new file mode 100644 (file)
index 0000000..bc4aeea
--- /dev/null
@@ -0,0 +1,330 @@
+/*\r
+     This file is part of GNUnet.\r
+     (C) 2009 Christian Grothoff (and other contributing authors)\r
+\r
+     GNUnet is free software; you can redistribute it and/or modify\r
+     it under the terms of the GNU General Public License as published\r
+     by the Free Software Foundation; either version 2, or (at your\r
+     option) any later version.\r
+\r
+     GNUnet is distributed in the hope that it will be useful, but\r
+     WITHOUT ANY WARRANTY; without even the implied warranty of\r
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+     General Public License for more details.\r
+\r
+     You should have received a copy of the GNU General Public License\r
+     along with GNUnet; see the file COPYING.  If not, write to the\r
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,\r
+     Boston, MA 02111-1307, USA.\r
+*/\r
+\r
+/**\r
+ * @file include/gnunet_connection_lib.h\r
+ * @brief basic, low-level TCP networking interface\r
+ * @author Christian Grothoff\r
+ */\r
+#ifndef GNUNET_NETWORK_LIB_H\r
+#define GNUNET_NETWORK_LIB_H\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#if 0                           /* keep Emacsens' auto-indent happy */\r
+}\r
+#endif\r
+#endif\r
+\r
+#include "gnunet_network_lib.h"\r
+#include "gnunet_scheduler_lib.h"\r
+#include "gnunet_time_lib.h"\r
+\r
+/**\r
+ * Timeout we use on TCP connect before trying another\r
+ * result from the DNS resolver. 5s.\r
+ */\r
+#define GNUNET_NETWORK_CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)\r
+\r
+/**\r
+ * @brief handle for a network connection\r
+ */\r
+struct GNUNET_NETWORK_ConnectionHandle;\r
+\r
+\r
+/**\r
+ * Function to call for access control checks.\r
+ *\r
+ * @param cls closure\r
+ * @param addr address\r
+ * @param addrlen length of address\r
+ * @return GNUNET_YES to allow, GNUNET_NO to deny, GNUNET_SYSERR\r
+ *   for unknown address family (will be denied).\r
+ */\r
+typedef int (*GNUNET_NETWORK_AccessCheck) (void *cls,\r
+                                           const struct sockaddr * addr,\r
+                                           socklen_t addrlen);\r
+\r
+\r
+/**\r
+ * Callback function for data received from the network.  Note that\r
+ * both "available" and "err" would be 0 if the read simply timed out.\r
+ *\r
+ * @param cls closure\r
+ * @param buf pointer to received data\r
+ * @param available number of bytes availabe in "buf",\r
+ *        possibly 0 (on errors)\r
+ * @param addr address of the sender\r
+ * @param addrlen size of addr\r
+ * @param errCode value of errno (on errors receiving)\r
+ */\r
+typedef void (*GNUNET_NETWORK_Receiver) (void *cls,\r
+                                         const void *buf,\r
+                                         size_t available,\r
+                                         const struct sockaddr * addr,\r
+                                         socklen_t addrlen, int errCode);\r
+\r
+\r
+/**\r
+ * Create a socket handle by boxing an existing OS socket.  The OS\r
+ * socket should henceforth be no longer used directly.\r
+ * GNUNET_socket_destroy will close it.\r
+ *\r
+ * @param sched scheduler to use\r
+ * @param osSocket existing socket to box\r
+ * @param maxbuf maximum write buffer size for the socket (use\r
+ *        0 for sockets that need no write buffers, such as listen sockets)\r
+ * @return the boxed socket handle\r
+ */\r
+struct GNUNET_NETWORK_ConnectionHandle\r
+  *GNUNET_NETWORK_connection_create_from_existing (struct\r
+                                                   GNUNET_SCHEDULER_Handle\r
+                                                   *sched,\r
+                                                   struct\r
+                                                   GNUNET_NETWORK_Descriptor\r
+                                                   *osSocket, size_t maxbuf);\r
+\r
+\r
+/**\r
+ * Create a socket handle by accepting on a listen socket.  This\r
+ * function may block if the listen socket has no connection ready.\r
+ *\r
+ * @param sched scheduler to use\r
+ * @param access function to use to check if access is allowed\r
+ * @param access_cls closure for access\r
+ * @param lsock listen socket\r
+ * @param maxbuf maximum write buffer size for the socket (use\r
+ *        0 for sockets that need no write buffers, such as listen sockets)\r
+ * @return the socket handle, NULL on error (for example, access refused)\r
+ */\r
+struct GNUNET_NETWORK_ConnectionHandle\r
+  *GNUNET_NETWORK_connection_create_from_accept (struct\r
+                                                 GNUNET_SCHEDULER_Handle\r
+                                                 *sched,\r
+                                                 GNUNET_NETWORK_AccessCheck\r
+                                                 access, void *access_cls,\r
+                                                 struct\r
+                                                 GNUNET_NETWORK_Descriptor\r
+                                                 *lsock, size_t maxbuf);\r
+\r
+\r
+/**\r
+ * Create a socket handle by (asynchronously) connecting to a host.\r
+ * This function returns immediately, even if the connection has not\r
+ * yet been established.  This function only creates TCP connections.\r
+ *\r
+ * @param sched scheduler to use\r
+ * @param hostname name of the host to connect to\r
+ * @param port port to connect to\r
+ * @param maxbuf maximum write buffer size for the socket (use\r
+ *        0 for sockets that need no write buffers, such as listen sockets)\r
+ * @return the socket handle\r
+ */\r
+struct GNUNET_NETWORK_ConnectionHandle\r
+  *GNUNET_NETWORK_connection_create_from_connect (struct\r
+                                                  GNUNET_SCHEDULER_Handle\r
+                                                  *sched,\r
+                                                  const char *hostname,\r
+                                                  uint16_t port,\r
+                                                  size_t maxbuf);\r
+\r
+\r
+\r
+/**\r
+ * Create a socket handle by (asynchronously) connecting to a host.\r
+ * This function returns immediately, even if the connection has not\r
+ * yet been established.  This function only creates TCP connections.\r
+ *\r
+ * @param sched scheduler to use\r
+ * @param af_family address family to use\r
+ * @param serv_addr server address\r
+ * @param addrlen length of server address\r
+ * @param maxbuf maximum write buffer size for the socket (use\r
+ *        0 for sockets that need no write buffers, such as listen sockets)\r
+ * @return the socket handle\r
+ */\r
+struct GNUNET_NETWORK_ConnectionHandle\r
+  *GNUNET_NETWORK_connection_create_from_sockaddr (struct\r
+                                                   GNUNET_SCHEDULER_Handle\r
+                                                   *sched, int af_family,\r
+                                                   const struct sockaddr\r
+                                                   *serv_addr,\r
+                                                   socklen_t addrlen,\r
+                                                   size_t maxbuf);\r
+\r
+/**\r
+ * Check if socket is valid (no fatal errors have happened so far).\r
+ * Note that a socket that is still trying to connect is considered\r
+ * valid.\r
+ *\r
+ * @param sock socket to check\r
+ * @return GNUNET_YES if valid, GNUNET_NO otherwise\r
+ */\r
+int GNUNET_NETWORK_connection_check (struct GNUNET_NETWORK_ConnectionHandle\r
+                                     *sock);\r
+\r
+\r
+/**\r
+ * Obtain the network address of the other party.\r
+ *\r
+ * @param sock the client to get the address for\r
+ * @param addr where to store the address\r
+ * @param addrlen where to store the length of the address\r
+ * @return GNUNET_OK on success\r
+ */\r
+int GNUNET_NETWORK_connection_get_address (struct\r
+                                           GNUNET_NETWORK_ConnectionHandle\r
+                                           *sock, void **addr,\r
+                                           size_t * addrlen);\r
+\r
+/**\r
+ * Close the socket and free associated resources.  Pending\r
+ * transmissions are simply dropped.  A pending receive call will be\r
+ * called with an error code of "EPIPE".\r
+ *\r
+ * @param sock socket to destroy\r
+ */\r
+void GNUNET_NETWORK_connection_destroy (struct GNUNET_NETWORK_ConnectionHandle\r
+                                        *sock);\r
+\r
+\r
+/**\r
+ * Receive data from the given socket.  Note that this function will\r
+ * call "receiver" asynchronously using the scheduler.  It will\r
+ * "immediately" return.  Note that there MUST only be one active\r
+ * receive call per socket at any given point in time (so do not\r
+ * call receive again until the receiver callback has been invoked).\r
+ *\r
+ * @param sock socket handle\r
+ * @param max maximum number of bytes to read\r
+ * @param timeout maximum amount of time to wait\r
+ * @param receiver function to call with received data\r
+ * @param receiver_cls closure for receiver\r
+ * @return scheduler task ID used for receiving, GNUNET_SCHEDULER_NO_TASK on error\r
+ */\r
+GNUNET_SCHEDULER_TaskIdentifier\r
+GNUNET_NETWORK_connection_receive (struct GNUNET_NETWORK_ConnectionHandle\r
+                                   *sock, size_t max,\r
+                                   struct GNUNET_TIME_Relative timeout,\r
+                                   GNUNET_NETWORK_Receiver receiver,\r
+                                   void *receiver_cls);\r
+\r
+\r
+/**\r
+ * Cancel receive job on the given socket.  Note that the\r
+ * receiver callback must not have been called yet in order\r
+ * for the cancellation to be valid.\r
+ *\r
+ * @param sock socket handle\r
+ * @param task task identifier returned from the receive call\r
+ * @return closure of the original receiver callback\r
+ */\r
+void *GNUNET_NETWORK_connection_receive_cancel (struct\r
+                                                GNUNET_NETWORK_ConnectionHandle\r
+                                                *sock,\r
+                                                GNUNET_SCHEDULER_TaskIdentifier\r
+                                                task);\r
+\r
+\r
+/**\r
+ * Function called to notify a client about the socket\r
+ * begin ready to queue more data.  "buf" will be\r
+ * NULL and "size" zero if the socket was closed for\r
+ * writing in the meantime.\r
+ *\r
+ * @param cls closure\r
+ * @param size number of bytes available in buf\r
+ * @param buf where the callee should write the message\r
+ * @return number of bytes written to buf\r
+ */\r
+typedef size_t (*GNUNET_NETWORK_TransmitReadyNotify) (void *cls,\r
+                                                      size_t size, void *buf);\r
+\r
+\r
+/**\r
+ * Opaque handle that can be used to cancel\r
+ * a transmit-ready notification.\r
+ */\r
+struct GNUNET_NETWORK_TransmitHandle;\r
+\r
+/**\r
+ * Ask the socket to call us once the specified number of bytes\r
+ * are free in the transmission buffer.  May call the notify\r
+ * method immediately if enough space is available.  Note that\r
+ * this function will abort if "size" is greater than\r
+ * "maxbuf" (as specified when the socket handle was created).\r
+ *\r
+ * Note that "notify" will be called either when enough\r
+ * buffer space is available OR when the socket is destroyed.\r
+ * The size parameter given to notify is guaranteed to be\r
+ * larger or equal to size if the buffer is ready, or zero\r
+ * if the socket was destroyed (or at least closed for\r
+ * writing).  Finally, any time before 'notify' is called, a\r
+ * client may call "notify_transmit_ready_cancel" to cancel\r
+ * the transmission request.\r
+ *\r
+ * Only one transmission request can be scheduled at the same\r
+ * time.  Notify will be run with the same scheduler priority\r
+ * as that of the caller.\r
+ *\r
+ * @param sock socket\r
+ * @param size number of bytes to send\r
+ * @param timeout after how long should we give up (and call\r
+ *        notify with buf NULL and size 0)?\r
+ * @param notify function to call when buffer space is available\r
+ * @param notify_cls closure for notify\r
+ * @return non-NULL if the notify callback was queued,\r
+ *         NULL if we are already going to notify someone else (busy)\r
+ */\r
+struct GNUNET_NETWORK_TransmitHandle\r
+  *GNUNET_NETWORK_connection_notify_transmit_ready (struct\r
+                                                    GNUNET_NETWORK_ConnectionHandle\r
+                                                    *sock, size_t size,\r
+                                                    struct\r
+                                                    GNUNET_TIME_Relative\r
+                                                    timeout,\r
+                                                    GNUNET_NETWORK_TransmitReadyNotify\r
+                                                    notify, void *notify_cls);\r
+\r
+\r
+/**\r
+ * Cancel the specified transmission-ready\r
+ * notification.\r
+ *\r
+ * @param h handle for notification to cancel\r
+ */\r
+void\r
+GNUNET_NETWORK_connection_notify_transmit_ready_cancel (struct\r
+                                                        GNUNET_NETWORK_TransmitHandle\r
+                                                        *h);\r
+\r
+\r
+#if 0                           /* keep Emacsens' auto-indent happy */\r
+{\r
+#endif\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+\r
+/* ifndef GNUNET_NETWORK_LIB_H */\r
+#endif\r
+/* end of gnunet_connection_lib.h */\r
index 49f2ece488796f1dc295102c40de01d769c86b8c..a5f279f05c1045e1983a9eb1d8f8c10479b005ba 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2001, 2002, 2003, 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+     (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009 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
@@ -76,6 +76,8 @@ enum GNUNET_DISK_Seek {GNUNET_SEEK_SET, GNUNET_SEEK_CUR, GNUNET_SEEK_END};
 
 struct GNUNET_DISK_FileHandle;
 
+struct GNUNET_DISK_PipeHandle;
+
 /**
  * Get the number of blocks that are left on the partition that
  * contains the given file (for normal users).
@@ -150,6 +152,19 @@ GNUNET_DISK_mktemp (const char *template);
  */
 struct GNUNET_DISK_FileHandle *GNUNET_DISK_file_open (const char *fn, int flags, ...);
 
+/**
+ * Creates an interprocess channel
+ * @param blocking creates an asynchronous pipe if set to GNUNET_NO
+ * @return handle to the new pipe, NULL on error
+ */
+struct GNUNET_DISK_PipeHandle *GNUNET_DISK_pipe (int blocking);
+
+/**
+ * Closes an interprocess channel
+ * @param p pipe
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ */
+int GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p);
 
 /**
  * Close an open file.
@@ -159,6 +174,14 @@ struct GNUNET_DISK_FileHandle *GNUNET_DISK_file_open (const char *fn, int flags,
  */
 int GNUNET_DISK_file_close (struct GNUNET_DISK_FileHandle *h);
 
+/**
+ * Get the handle to a particular pipe end
+ * @param p pipe
+ * @param n number of the end
+ */
+const struct GNUNET_DISK_FileHandle *GNUNET_DISK_pipe_handle (const struct
+                                                              GNUNET_DISK_PipeHandle
+                                                              *p, int n);
 
 /**
  * Read the contents of a binary file into a buffer.
index 68ca346e5b788fc63926fc61211458c3610ecd70..baba3aba88e15607844c2fbc9e39621e921760a9 100644 (file)
 
 /**
  * @file include/gnunet_network_lib.h
- * @brief basic, low-level TCP networking interface
- * @author Christian Grothoff
+ * @brief basic low-level networking interface
+ * @author Nils Durner
  */
-#ifndef GNUNET_NETWORK_LIB_H
-#define GNUNET_NETWORK_LIB_H
+
+#ifndef GNUNET_NETWORK_LIB_H_
+#define GNUNET_NETWORK_LIB_H_
 
 #ifdef __cplusplus
 extern "C"
@@ -34,265 +35,102 @@ extern "C"
 #endif
 #endif
 
-#include "gnunet_scheduler_lib.h"
 #include "gnunet_time_lib.h"
 
-/**
- * Timeout we use on TCP connect before trying another
- * result from the DNS resolver. 5s.
- */
-#define GNUNET_NETWORK_CONNECT_RETRY_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5)
 
 /**
- * @brief handle for a network connection
+ * @brief handle to a socket
  */
-struct GNUNET_NETWORK_ConnectionHandle;
-
+struct GNUNET_NETWORK_Descriptor;
 
 /**
- * Function to call for access control checks.
- *
- * @param cls closure
- * @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).
+ * @brief collection of IO descriptors
  */
-typedef int (*GNUNET_NETWORK_AccessCheck) (void *cls,
-                                           const struct sockaddr * addr,
-                                           socklen_t addrlen);
+struct GNUNET_NETWORK_FDSet;
 
+struct GNUNET_DISK_FileHandle;
 
-/**
- * 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_NETWORK_Receiver) (void *cls,
-                                         const void *buf,
-                                         size_t available,
-                                         const struct sockaddr * addr,
-                                         socklen_t addrlen, int errCode);
+struct GNUNET_NETWORK_Descriptor *GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Descriptor *desc,
+                      struct sockaddr *address,
+                      socklen_t *address_len);
 
+int GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Descriptor *desc,
+                    const struct sockaddr *address, socklen_t address_len);
 
-/**
- * Create a socket handle by boxing an existing OS socket.  The OS
- * socket should henceforth be no longer used directly.
- * GNUNET_socket_destroy will close it.
- *
- * @param sched scheduler to use
- * @param osSocket existing socket to box
- * @param maxbuf maximum write buffer size for the socket (use
- *        0 for sockets that need no write buffers, such as listen sockets)
- * @return the boxed socket handle
- */
-struct GNUNET_NETWORK_ConnectionHandle
-  *GNUNET_NETWORK_connection_create_from_existing (struct GNUNET_SCHEDULER_Handle
-                                               *sched, int osSocket,
-                                               size_t maxbuf);
+int GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Descriptor *desc);
 
+int GNUNET_NETWORK_socket_connect (const struct GNUNET_NETWORK_Descriptor *desc,
+                       const struct sockaddr *address, socklen_t address_len);
 
-/**
- * Create a socket handle by accepting on a listen socket.  This
- * function may block if the listen socket has no connection ready.
- *
- * @param sched scheduler to use
- * @param access function to use to check if access is allowed
- * @param access_cls closure for access
- * @param lsock listen socket
- * @param maxbuf maximum write buffer size for the socket (use
- *        0 for sockets that need no write buffers, such as listen sockets)
- * @return the socket handle, NULL on error (for example, access refused)
- */
-struct GNUNET_NETWORK_ConnectionHandle
-  *GNUNET_NETWORK_connection_create_from_accept (struct GNUNET_SCHEDULER_Handle
-                                             *sched,
-                                             GNUNET_NETWORK_AccessCheck
-                                             access, void *access_cls,
-                                             int lsock, size_t maxbuf);
+int GNUNET_NETWORK_socket_getsockopt(const struct GNUNET_NETWORK_Descriptor *desc, int level, int optname,
+       void *optval, socklen_t *optlen);
 
+int GNUNET_NETWORK_socket_listen (const struct GNUNET_NETWORK_Descriptor *desc, int backlog);
 
-/**
- * Create a socket 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 sched scheduler to use
- * @param hostname name of the host to connect to
- * @param port port to connect to
- * @param maxbuf maximum write buffer size for the socket (use
- *        0 for sockets that need no write buffers, such as listen sockets)
- * @return the socket handle
- */
-struct GNUNET_NETWORK_ConnectionHandle
-  *GNUNET_NETWORK_connection_create_from_connect (struct GNUNET_SCHEDULER_Handle
-                                              *sched, const char *hostname,
-                                              uint16_t port, size_t maxbuf);
+ssize_t GNUNET_NETWORK_socket_read (const struct GNUNET_NETWORK_Descriptor *desc, void *buf,
+                        size_t nbyte);
 
+ssize_t GNUNET_NETWORK_socket_recv (const struct GNUNET_NETWORK_Descriptor *desc, void *buffer,
+                        size_t length, int flags);
 
+int GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
+    struct GNUNET_NETWORK_FDSet *wfds, struct GNUNET_NETWORK_FDSet *efds,
+    struct GNUNET_TIME_Relative timeout);
 
 /**
- * Create a socket 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.
+ * Set if a socket should use blocking or non-blocking IO.
  *
- * @param sched scheduler to use
- * @param af_family address family to use
- * @param serv_addr server address
- * @param addrlen length of server address
- * @param maxbuf maximum write buffer size for the socket (use
- *        0 for sockets that need no write buffers, such as listen sockets)
- * @return the socket handle
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error
  */
-struct GNUNET_NETWORK_ConnectionHandle
-  *GNUNET_NETWORK_connection_create_from_sockaddr (struct GNUNET_SCHEDULER_Handle
-                                               *sched, int af_family,
-                                               const struct sockaddr
-                                               *serv_addr, socklen_t addrlen,
-                                               size_t maxbuf);
+int GNUNET_NETWORK_socket_set_blocking (struct GNUNET_NETWORK_Descriptor *fd, int doBlock);
 
-/**
- * Check if socket is valid (no fatal errors have happened so far).
- * Note that a socket that is still trying to connect is considered
- * valid.
- *
- * @param sock socket to check
- * @return GNUNET_YES if valid, GNUNET_NO otherwise
- */
-int GNUNET_NETWORK_connection_check (struct GNUNET_NETWORK_ConnectionHandle *sock);
+ssize_t GNUNET_NETWORK_socket_send (const struct GNUNET_NETWORK_Descriptor *desc,
+                        const void *buffer, size_t length, int flags);
 
+ssize_t GNUNET_NETWORK_socket_sendto (const struct GNUNET_NETWORK_Descriptor *desc,
+                          const void *message, size_t length, int flags,
+                          const struct sockaddr *dest_addr,
+                          socklen_t dest_len);
 
-/**
- * Obtain the network address of the other party.
- *
- * @param sock 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_NETWORK_connection_get_address (struct GNUNET_NETWORK_ConnectionHandle
-                                       *sock, void **addr, size_t * addrlen);
+int GNUNET_NETWORK_socket_setsockopt(struct GNUNET_NETWORK_Descriptor *fd, int level, int option_name,
+       const void *option_value, socklen_t option_len);
 
-/**
- * Close the socket and free associated resources.  Pending
- * transmissions are simply dropped.  A pending receive call will be
- * called with an error code of "EPIPE".
- *
- * @param sock socket to destroy
- */
-void GNUNET_NETWORK_connection_destroy (struct GNUNET_NETWORK_ConnectionHandle *sock);
+int GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Descriptor *desc, int how);
 
+struct GNUNET_NETWORK_Descriptor *GNUNET_NETWORK_socket_socket (int domain, int type, int protocol);
 
-/**
- * Receive data from the given socket.  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 socket at any given point in time (so do not
- * call receive again until the receiver callback has been invoked).
- *
- * @param sock socket 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
- * @return scheduler task ID used for receiving, GNUNET_SCHEDULER_NO_TASK on error
- */
-GNUNET_SCHEDULER_TaskIdentifier
-GNUNET_NETWORK_connection_receive (struct GNUNET_NETWORK_ConnectionHandle *sock,
-                        size_t max,
-                        struct GNUNET_TIME_Relative timeout,
-                        GNUNET_NETWORK_Receiver receiver, void *receiver_cls);
+ssize_t GNUNET_NETWORK_socket_write (const struct GNUNET_NETWORK_Descriptor *desc,
+                         const void *buf, size_t nbyte);
 
 
-/**
- * Cancel receive job on the given socket.  Note that the
- * receiver callback must not have been called yet in order
- * for the cancellation to be valid.
- *
- * @param sock socket handle
- * @param task task identifier returned from the receive call
- * @return closure of the original receiver callback
- */
-void *GNUNET_NETWORK_connection_receive_cancel (struct GNUNET_NETWORK_ConnectionHandle *sock,
-                                     GNUNET_SCHEDULER_TaskIdentifier task);
+void GNUNET_NETWORK_fdset_zero(struct GNUNET_NETWORK_FDSet *fds);
 
+void GNUNET_NETWORK_fdset_set(struct GNUNET_NETWORK_FDSet *fds,
+    const struct GNUNET_NETWORK_Descriptor *desc);
 
-/**
- * Function called to notify a client about the socket
- * begin ready to queue more data.  "buf" will be
- * NULL and "size" zero if the socket was closed for
- * writing in the meantime.
- *
- * @param cls closure
- * @param size number of bytes available in buf
- * @param buf where the callee should write the message
- * @return number of bytes written to buf
- */
-typedef size_t (*GNUNET_NETWORK_TransmitReadyNotify) (void *cls,
-                                                      size_t size, void *buf);
+int GNUNET_NETWORK_fdset_isset(const struct GNUNET_NETWORK_FDSet *fds,
+    const struct GNUNET_NETWORK_Descriptor *desc);
 
+void GNUNET_NETWORK_fdset_add (struct GNUNET_NETWORK_FDSet *dst,
+    const struct GNUNET_NETWORK_FDSet *src);
 
-/**
- * Opaque handle that can be used to cancel
- * a transmit-ready notification.
- */
-struct GNUNET_NETWORK_TransmitHandle;
+void GNUNET_NETWORK_fdset_copy(struct GNUNET_NETWORK_FDSet *to,
+    const struct GNUNET_NETWORK_FDSet *from);
 
-/**
- * Ask the socket to call us once the specified number of bytes
- * are free in the transmission buffer.  May call the notify
- * method immediately if enough space is available.  Note that
- * this function will abort if "size" is greater than
- * "maxbuf" (as specified when the socket handle was created).
- *
- * Note that "notify" will be called either when enough
- * buffer space is available OR when the socket 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 socket 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 sock socket
- * @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_NETWORK_TransmitHandle
-  *GNUNET_NETWORK_connection_notify_transmit_ready (struct GNUNET_NETWORK_ConnectionHandle
-                                         *sock, size_t size,
-                                         struct GNUNET_TIME_Relative timeout,
-                                         GNUNET_NETWORK_TransmitReadyNotify
-                                         notify, void *notify_cls);
+void GNUNET_NETWORK_fdset_copy_native (struct GNUNET_NETWORK_FDSet *to, const fd_set *from,
+    int nfds);
 
+void GNUNET_NETWORK_fdset_handle_set (struct GNUNET_NETWORK_FDSet *fds,
+    const struct GNUNET_DISK_FileHandle *h);
 
-/**
- * Cancel the specified transmission-ready
- * notification.
- *
- * @param h handle for notification to cancel
- */
-void
-GNUNET_NETWORK_connection_notify_transmit_ready_cancel (struct
-                                             GNUNET_NETWORK_TransmitHandle
-                                             *h);
+int GNUNET_NETWORK_fdset_handle_isset (const struct GNUNET_NETWORK_FDSet *fds,
+    const struct GNUNET_DISK_FileHandle *h);
+
+int GNUNET_NETWORK_fdset_overlap (const struct GNUNET_NETWORK_FDSet *fds1, const struct GNUNET_NETWORK_FDSet *fds2);
 
+struct GNUNET_NETWORK_FDSet *GNUNET_NETWORK_fdset_create ();
+
+void GNUNET_NETWORK_fdset_destroy (struct GNUNET_NETWORK_FDSet *fds);
 
 
 #if 0                           /* keep Emacsens' auto-indent happy */
@@ -302,7 +140,4 @@ GNUNET_NETWORK_connection_notify_transmit_ready_cancel (struct
 }
 #endif
 
-
-/* ifndef GNUNET_NETWORK_LIB_H */
-#endif
-/* end of gnunet_network_lib.h */
+#endif /* GNUNET_NETWORK_LIB_H_ */
index d4013e630b610a543a12ae1c85f0e981c6b7b1f8..86f709ed6f54cd573636573de5996578e05ce55d 100644 (file)
@@ -35,15 +35,15 @@ extern "C"
 #endif
 #endif
 
-#include "gnunet_time_lib.h"
 
+#include "gnunet_time_lib.h"
+#include "gnunet_network_lib.h"
 
 /**
  * Opaque handle for the scheduling service.
  */
 struct GNUNET_SCHEDULER_Handle;
 
-
 /**
  * Opaque reference to a task.
  */
@@ -173,14 +173,14 @@ struct GNUNET_SCHEDULER_TaskContext
    * note that additional bits may be set
    * that were not in the original request
    */
-  const fd_set *read_ready;
+  const struct GNUNET_NETWORK_FDSet *read_ready;
 
   /**
    * Set of file descriptors ready for writing;
    * note that additional bits may be set
    * that were not in the original request.
    */
-  const fd_set *write_ready;
+  const struct GNUNET_NETWORK_FDSet *write_ready;
 
 };
 
@@ -345,12 +345,78 @@ GNUNET_SCHEDULER_add_delayed (struct GNUNET_SCHEDULER_Handle *sched,
  *         only valid until "main" is started!
  */
 GNUNET_SCHEDULER_TaskIdentifier
-GNUNET_SCHEDULER_add_read (struct GNUNET_SCHEDULER_Handle *sched,
+GNUNET_SCHEDULER_add_read_net (struct GNUNET_SCHEDULER_Handle *sched,
+                           int run_on_shutdown,
+                           enum GNUNET_SCHEDULER_Priority prio,
+                           GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
+                           struct GNUNET_TIME_Relative delay,
+                           struct GNUNET_NETWORK_Descriptor *rfd, GNUNET_SCHEDULER_Task main, void *cls);
+
+
+/**
+ * Schedule a new task to be run with a specified delay or when the
+ * specified file descriptor is ready for writing.  The delay can be
+ * used as a timeout on the socket being ready.  The task will be
+ * scheduled for execution once either the delay has expired or the
+ * socket operation is ready.
+ *
+ * @param sched scheduler to use
+ * @param run_on_shutdown run on shutdown? Set this
+ *        argument to GNUNET_NO to skip this task if
+ *        the user requested process termination.
+ * @param prio how important is this task?
+ * @param prerequisite_task run this task after the task with the given
+ *        task identifier completes (and any of our other
+ *        conditions, such as delay, read or write-readyness
+ *        are satisfied).  Use  GNUNET_SCHEDULER_NO_TASK to not have any dependency
+ *        on completion of other tasks.
+ * @param delay how long should we wait? Use  GNUNET_TIME_UNIT_FOREVER_REL for "forever"
+ * @param wfd write file-descriptor
+ * @param main main function of the task
+ * @param cls closure of task
+ * @return unique task identifier for the job
+ *         only valid until "main" is started!
+ */
+GNUNET_SCHEDULER_TaskIdentifier
+GNUNET_SCHEDULER_add_write_net (struct GNUNET_SCHEDULER_Handle *sched,
+                            int run_on_shutdown,
+                            enum GNUNET_SCHEDULER_Priority prio,
+                            GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
+                            struct GNUNET_TIME_Relative delay,
+                            struct GNUNET_NETWORK_Descriptor *wfd, GNUNET_SCHEDULER_Task main, void *cls);
+
+
+/**
+ * Schedule a new task to be run with a specified delay or when the
+ * specified file descriptor is ready for reading.  The delay can be
+ * used as a timeout on the socket being ready.  The task will be
+ * scheduled for execution once either the delay has expired or the
+ * socket operation is ready.
+ *
+ * @param sched scheduler to use
+ * @param run_on_shutdown run on shutdown? Set this
+ *        argument to GNUNET_NO to skip this task if
+ *        the user requested process termination.
+ * @param prio how important is this task?
+ * @param prerequisite_task run this task after the task with the given
+ *        task identifier completes (and any of our other
+ *        conditions, such as delay, read or write-readyness
+ *        are satisfied).  Use  GNUNET_SCHEDULER_NO_TASK to not have any dependency
+ *        on completion of other tasks.
+ * @param delay how long should we wait? Use  GNUNET_TIME_UNIT_FOREVER_REL for "forever"
+ * @param rfd read file-descriptor
+ * @param main main function of the task
+ * @param cls closure of task
+ * @return unique task identifier for the job
+ *         only valid until "main" is started!
+ */
+GNUNET_SCHEDULER_TaskIdentifier
+GNUNET_SCHEDULER_add_read_file (struct GNUNET_SCHEDULER_Handle *sched,
                            int run_on_shutdown,
                            enum GNUNET_SCHEDULER_Priority prio,
                            GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
                            struct GNUNET_TIME_Relative delay,
-                           int rfd, GNUNET_SCHEDULER_Task main, void *cls);
+                           struct GNUNET_DISK_FileHandle *rfd, GNUNET_SCHEDULER_Task main, void *cls);
 
 
 /**
@@ -378,12 +444,12 @@ GNUNET_SCHEDULER_add_read (struct GNUNET_SCHEDULER_Handle *sched,
  *         only valid until "main" is started!
  */
 GNUNET_SCHEDULER_TaskIdentifier
-GNUNET_SCHEDULER_add_write (struct GNUNET_SCHEDULER_Handle *sched,
+GNUNET_SCHEDULER_add_write_file (struct GNUNET_SCHEDULER_Handle *sched,
                             int run_on_shutdown,
                             enum GNUNET_SCHEDULER_Priority prio,
                             GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
                             struct GNUNET_TIME_Relative delay,
-                            int wfd, GNUNET_SCHEDULER_Task main, void *cls);
+                            struct GNUNET_DISK_FileHandle *wfd, GNUNET_SCHEDULER_Task main, void *cls);
 
 
 /**
@@ -429,7 +495,7 @@ GNUNET_SCHEDULER_add_select (struct GNUNET_SCHEDULER_Handle *sched,
                              GNUNET_SCHEDULER_TaskIdentifier
                              prerequisite_task,
                              struct GNUNET_TIME_Relative delay,
-                             int nfds, const fd_set * rs, const fd_set * ws,
+                             const struct GNUNET_NETWORK_FDSet * rs, const struct GNUNET_NETWORK_FDSet * ws,
                              GNUNET_SCHEDULER_Task main, void *cls);
 
 #if 0                           /* keep Emacsens' auto-indent happy */
index 82085ad0d73ad3c3997ca41f6ef7c883ea7de0e2..092bab40be9650a29f8778a3d718ead5566f2ef7 100644 (file)
@@ -37,7 +37,7 @@ extern "C"
 #endif
 
 #include "gnunet_common.h"
-#include "gnunet_network_lib.h"
+#include "gnunet_connection_lib.h"
 #include "gnunet_scheduler_lib.h"
 
 
index 037a247a2b44696465533764c9721d82e22be16c..385bf7cfb84b42858e6878907c1b6d6d3cf509ec 100644 (file)
@@ -37,7 +37,7 @@ extern "C"
 
 #include "gnunet_configuration_lib.h"
 #include "gnunet_crypto_lib.h"
-#include "gnunet_network_lib.h"
+#include "gnunet_connection_lib.h"
 #include "gnunet_scheduler_lib.h"
 #include "gnunet_time_lib.h"
 
index 40686b189b76a382fa6d517d7b25114b2c417f1f..fe382be3f6730d0f0310f9daa0da660841280f91 100644 (file)
@@ -39,6 +39,7 @@ extern "C"
 #include "gnunet_common.h"
 #include "gnunet_client_lib.h"
 #include "gnunet_configuration_lib.h"
+#include "gnunet_connection_lib.h"
 #include "gnunet_container_lib.h"
 #include "gnunet_crypto_lib.h"
 #include "gnunet_disk_lib.h"
index f7e06a9cdae59a70940288a113f7e9bf5d705b3d..78691852d646af46cf348724c44f06a77ae69f8e 100644 (file)
@@ -399,7 +399,7 @@ static int stat_connect_calls;
  */
 static unsigned int http_requests_pending;
 
-static int signal_pipe[2];
+static struct GNUNET_DISK_FileHandle signal_pipe[2];
 
 static char *proxy;
 
@@ -453,7 +453,7 @@ static void
 signal_select ()
 {
   static char c;
-  WRITE (signal_pipe[1], &c, sizeof (c));
+  GNUNET_DISK_file_write (signal_pipe[1], &c, sizeof (c));
 }
 
 /**
@@ -1747,8 +1747,10 @@ curl_runner (void *unused)
   fd_set rs;
   fd_set ws;
   fd_set es;
+  struct GNUNET_NETWORK_FDSet *hrs;
+  struct GNUNET_NETWORK_FDSet *hws;
+  struct GNUNET_NETWORK_FDSet *hes;
   int max;
-  struct timeval tv;
   int running;
   unsigned long long timeout;
   long ms;
@@ -1761,6 +1763,11 @@ curl_runner (void *unused)
                  GNUNET_GE_DEBUG | GNUNET_GE_REQUEST | GNUNET_GE_USER,
                  "HTTP transport select thread started\n");
 #endif
+
+  hrs = GNUNET_net_fdset_create ();
+  hws = GNUNET_net_fdset_create ();
+  hes = GNUNET_net_fdset_create ();
+
   while (GNUNET_YES == http_running)
     {
       max = 0;
@@ -1793,16 +1800,20 @@ curl_runner (void *unused)
           have_tv = MHD_YES;
         }
       GNUNET_mutex_unlock (lock);
-      FD_SET (signal_pipe[0], &rs);
-      if (max < signal_pipe[0])
-        max = signal_pipe[0];
-      tv.tv_sec = timeout / 1000;
-      tv.tv_usec = (timeout % 1000) * 1000;
+
+      GNUNET_net_fdset_zero (hws);
+      GNUNET_net_fdset_zero (hrs);
+      GNUNET_net_fdset_zero (hes);
+      GNUNET_net_fdset_copy_native (hws, ws);
+      GNUNET_net_fdset_copy_native (hrs, rs);
+      GNUNET_net_fdset_copy_native (hes, es);
+
+       GNUNET_net_fdset_handle_set (signal_pipe[0], hrs);
       if (stats != NULL)
         stats->change (stat_select_calls, 1);
       ret =
-        SELECT (max + 1, &rs, &ws, &es, (have_tv == MHD_YES) ? &tv : NULL);
-      if (ret == -1)
+        GNUNET_net_select (hrs, hws, hes, (have_tv == MHD_YES) ? timeout : GNUNET_TIME_UNIT_FOREVER_REL);
+      if (ret == GNUNET_SYSERR)
         {
           GNUNET_GE_LOG_STRERROR (coreAPI->ectx,
                                   GNUNET_GE_ERROR | GNUNET_GE_ADMIN |
@@ -1819,8 +1830,8 @@ curl_runner (void *unused)
         }
       while ((mret == CURLM_CALL_MULTI_PERFORM)
              && (http_running == GNUNET_YES));
-      if (FD_ISSET (signal_pipe[0], &rs))
-        read (signal_pipe[0], buf, sizeof (buf));
+      if (GNUNET_net_fdset_handle_isset (signal_pipe[0], hrs))
+        GNUNET_DISK_file_read (signal_pipe[0], buf, sizeof (buf));
       if ((mret != CURLM_OK) && (mret != CURLM_CALL_MULTI_PERFORM))
         GNUNET_GE_LOG (coreAPI->ectx,
                        GNUNET_GE_ERROR | GNUNET_GE_ADMIN | GNUNET_GE_USER |
@@ -1914,7 +1925,7 @@ startTransportServer ()
                                                    GNUNET_YES))
         available_protocols |= VERSION_AVAILABLE_IPV6;
     }
-  if (0 != PIPE (signal_pipe))
+  if (GNUNET_OK != GNUNET_DISK_pipe (signal_pipe, GNUNET_NO))
     {
       MHD_stop_daemon (mhd_daemon);
       curl_multi_cleanup (curl_multi);
@@ -1922,8 +1933,6 @@ startTransportServer ()
       mhd_daemon = NULL;
       return GNUNET_SYSERR;
     }
-  GNUNET_pipe_make_nonblocking (coreAPI->ectx, signal_pipe[0]);
-  GNUNET_pipe_make_nonblocking (coreAPI->ectx, signal_pipe[1]);
   http_running = GNUNET_YES;
   curl_thread = GNUNET_thread_create (&curl_runner, NULL, 32 * 1024);
   if (curl_thread == NULL)
@@ -1950,8 +1959,8 @@ stopTransportServer ()
   signal_select ();
   GNUNET_thread_stop_sleep (curl_thread);
   GNUNET_thread_join (curl_thread, &unused);
-  CLOSE (signal_pipe[0]);
-  CLOSE (signal_pipe[1]);
+  GNUNET_DISK_close (signal_pipe[0]);
+  GNUNET_DISK_close (signal_pipe[1]);
   if (mhd_daemon != NULL)
     {
       MHD_stop_daemon (mhd_daemon);
index 764ef8b2f43df83f52b154150798426645f4ad64..2e174f80acf9259f2110eb07c5275382c3ed4053 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "platform.h"
 #include "gnunet_hello_lib.h"
-#include "gnunet_network_lib.h"
+#include "gnunet_connection_lib.h"
 #include "gnunet_os_lib.h"
 #include "gnunet_peerinfo_service.h"
 #include "gnunet_protocols.h"
index bce4bbc520ac7880f37a5463a5e888e3bcdb9c71..6307092fc7cac218e39508be289517bc66e5a953 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "platform.h"
 #include "gnunet_protocols.h"
-#include "gnunet_network_lib.h"
+#include "gnunet_connection_lib.h"
 #include "gnunet_server_lib.h"
 #include "gnunet_service_lib.h"
 #include "gnunet_statistics_service.h"
index ccaf9fbd12c467ef17047c56546705fc97de4c87..c84b2bae7679b5439cd8fa3f32e1b941ac43972d 100644 (file)
@@ -267,31 +267,23 @@ udp_test_would_try (GNUNET_TSession * tsession, unsigned int size,
  * Create a UDP socket.  If possible, use IPv6, otherwise
  * try IPv4.  Update available_protocols accordingly.
  */
-static int
+static struct GNUNET_NETWORK_Descriptor *
 udp_create_socket ()
 {
-  int s;
+  struct GNUNET_NETWORK_Descriptor *desc;
 
   available_protocols = VERSION_AVAILABLE_NONE;
-  s = -1;
+  desc = NULL;
   if (GNUNET_YES !=
       GNUNET_GC_get_configuration_value_yesno (cfg, "GNUNETD", "DISABLE-IPV6",
                                                GNUNET_YES))
     {
-#ifndef MINGW
-      s = SOCKET (PF_INET6, SOCK_DGRAM, 17);
-#else
-      s = win_ols_socket (PF_INET6, SOCK_DGRAM, 17);
-#endif
+      desc = GNUNET_net_socket (PF_INET6, SOCK_DGRAM, 17);
     }
-  if (s < 0)
+  if (NULL == desc)
     {
-#ifndef MINGW
-      s = SOCKET (PF_INET, SOCK_DGRAM, 17);
-#else
-      s = win_ols_socket (PF_INET, SOCK_DGRAM, 17);
-#endif
-      if (s < 0)
+      desc = GNUNET_net_socket (PF_INET, SOCK_DGRAM, 17);
+      if (NULL == desc)
         {
           GNUNET_GE_LOG_STRERROR (coreAPI->ectx,
                                   GNUNET_GE_ERROR | GNUNET_GE_ADMIN |
@@ -304,7 +296,7 @@ udp_create_socket ()
     {
       available_protocols = VERSION_AVAILABLE_IPV6 | VERSION_AVAILABLE_IPV4;
     }
-  return s;
+  return desc;
 }
 
 /**
@@ -424,7 +416,7 @@ udp_transport_server_start ()
   struct sockaddr_in6 serverAddrv6;
   struct sockaddr *serverAddr;
   socklen_t addrlen;
-  int sock;
+  GNUNET_NETWORK_Descriptor *desc;
   const int on = 1;
   unsigned short port;
 
@@ -433,10 +425,10 @@ udp_transport_server_start ()
   port = get_port ();
   if (port != 0)
     {
-      sock = udp_create_socket ();
-      if (sock < 0)
+      desc = udp_create_socket ();
+      if (NULL == desc)
         return GNUNET_SYSERR;
-      if (SETSOCKOPT (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
+      if (GNUNET_net_setsockopt (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
         {
           GNUNET_GE_DIE_STRERROR (coreAPI->ectx,
                                   GNUNET_GE_FATAL | GNUNET_GE_ADMIN |
@@ -461,7 +453,7 @@ udp_transport_server_start ()
           addrlen = sizeof (serverAddrv6);
           serverAddr = (struct sockaddr *) &serverAddrv6;
         }
-      if (BIND (sock, serverAddr, addrlen) < 0)
+      if (GNUNET_net_bind (desc, serverAddr, addrlen) < 0)
         {
           GNUNET_GE_LOG_STRERROR (coreAPI->ectx,
                                   GNUNET_GE_FATAL | GNUNET_GE_ADMIN |
@@ -471,14 +463,14 @@ udp_transport_server_start ()
                          GNUNET_GE_IMMEDIATE,
                          _("Failed to bind to %s port %d.\n"),
                          MY_TRANSPORT_NAME, port);
-          if (0 != CLOSE (sock))
+          if (0 != GNUNET_net_close (&desc))
             GNUNET_GE_LOG_STRERROR (coreAPI->ectx,
                                     GNUNET_GE_ERROR | GNUNET_GE_USER |
                                     GNUNET_GE_ADMIN | GNUNET_GE_BULK,
                                     "close");
           return GNUNET_SYSERR;
         }
-      selector = GNUNET_select_create ("udp", GNUNET_YES, coreAPI->ectx, load_monitor, sock, addrlen, 0,        /* timeout */
+      selector = GNUNET_select_create ("udp", GNUNET_YES, coreAPI->ectx, load_monitor, desc, addrlen, 0,        /* timeout */
                                        &select_message_handler,
                                        NULL,
                                        &select_accept_handler,
@@ -489,8 +481,8 @@ udp_transport_server_start ()
       if (selector == NULL)
         return GNUNET_SYSERR;
     }
-  sock = udp_create_socket ();
-  if (sock == -1)
+  desc = udp_create_socket ();
+  if (NULL == desc)
     {
       GNUNET_GE_LOG_STRERROR (coreAPI->ectx,
                               GNUNET_GE_ERROR | GNUNET_GE_ADMIN |
@@ -499,7 +491,7 @@ udp_transport_server_start ()
       selector = NULL;
       return GNUNET_SYSERR;
     }
-  udp_sock = GNUNET_socket_create (coreAPI->ectx, load_monitor, sock);
+  udp_sock = GNUNET_socket_create (coreAPI->ectx, load_monitor, desc);
   GNUNET_GE_ASSERT (coreAPI->ectx, udp_sock != NULL);
   return GNUNET_OK;
 }
index 6dc4338a0b60bd86191ac3b06873feb2debdbfb9..afc815b1f11a9c5cb5f312006f051a4e847161e1 100644 (file)
@@ -104,7 +104,7 @@ typedef struct
   char *full_url;
   char *buf;
   unsigned int buf_len;
-  int sock;
+  struct GNUNET_NETWORK_Descriptor *sock;
 } UPnPDiscoveryData;
 
 static GaimUPnPControlInfo control_info = {
@@ -543,7 +543,7 @@ gaim_upnp_parse_description (char *proxy, UPnPDiscoveryData * dd)
 }
 
 int
-gaim_upnp_discover (struct GNUNET_CONFIGURATION_Handle *cfg, int sock)
+gaim_upnp_discover (struct GNUNET_CONFIGURATION_Handle *cfg, struct GNUNET_NETWORK_Descriptor *sock)
 {
   char *proxy;
   socklen_t avail;
@@ -613,7 +613,7 @@ gaim_upnp_discover (struct GNUNET_CONFIGURATION_Handle *cfg, int sock)
   /* try to read response */
   do
     {
-      buf_len = recv (dd.sock, buf, sizeof (buf) - 1, 0);
+      buf_len = GNUNET_IO_recv (dd.sock, buf, sizeof (buf) - 1, 0);
       if (buf_len > 0)
         {
           buf[buf_len] = '\0';
index 3dc0d2b7ca4bfe4f5d1e7551f6ffbd08fd4dbe24..8390494e5adc19d9a992636dc629b92db20385f4 100644 (file)
@@ -50,7 +50,7 @@ static unsigned int maps_size;
 
 static struct GNUNET_ThreadHandle *discovery;
 
-static int discovery_socket;
+static struct GNUNET_NETWORK_Descriptor *discovery_socket;
 
 /**
  * Obtain the public/external IP address.
@@ -84,8 +84,8 @@ kill_discovery ()
 
   if (discovery != NULL)
     {
-      SHUTDOWN (discovery_socket, SHUT_RDWR);
-      CLOSE (discovery_socket);
+      GNUNET_IO_shutdown (discovery_socket, SHUT_RDWR);
+      GNUNET_IO_close (&discovery_socket);
       GNUNET_thread_join (discovery, &unused);
       discovery = NULL;
     }
@@ -105,8 +105,8 @@ static void
 discover (void *unused)
 {
   kill_discovery ();
-  discovery_socket = SOCKET (PF_INET, SOCK_DGRAM, 0);
-  if (discovery_socket == -1)
+  discovery_socket = GNUNET_IO_socket (PF_INET, SOCK_DGRAM, 0);
+  if (NULL == discovery_socket)
     return;
   discovery = GNUNET_thread_create (&discover_thread, NULL, 1024 * 128);
 }
index 089e92018b4e74d435c92721c41b055e1390b12a..46d1c3a7aaa8dec0808114a36e9f646df043f74a 100644 (file)
@@ -32,6 +32,7 @@ libgnunetutil_la_SOURCES = \
   crypto_random.c \
   crypto_rsa.c \
   disk.c \
+  disk.h \
   getopt.c \
   getopt_helpers.c \
   network.c \
@@ -47,6 +48,7 @@ libgnunetutil_la_SOURCES = \
   server_tc.c \
   service.c \
   signal.c \
+  sock.c \
   strings.c \
   time.c \
   $(WINSRC)
index 08f14caf60f77b4357fd264816cbab8513ecb063..b9fad5477a7baf7826603466d91893d0ba472986 100644 (file)
@@ -31,6 +31,7 @@
 #include "gnunet_disk_lib.h"
 #include "gnunet_scheduler_lib.h"
 #include "gnunet_strings_lib.h"
+#include "disk.h"
 
 
 #if LINUX || CYGWIN
@@ -74,13 +75,9 @@ typedef struct
   int include_sym_links;
 } GetFileSizeData;
 
-struct GNUNET_DISK_FileHandle
+struct GNUNET_DISK_PipeHandle
 {
-#if MINGW
-  HANDLE h;
-#else
-  int fd;
-#endif
+  struct GNUNET_DISK_FileHandle fd[2];
 };
 
 static int
@@ -1390,4 +1387,165 @@ GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h)
 #endif
 }
 
+/**
+ * Creates an interprocess channel
+ * @param blocking creates an asynchronous pipe if set to GNUNET_NO
+ * @return handle to the new pipe, NULL on error
+ */
+struct GNUNET_DISK_PipeHandle *
+GNUNET_DISK_pipe (int blocking)
+{
+  struct GNUNET_DISK_PipeHandle *p;
+  int err;
+
+  err = GNUNET_NO;
+  p = GNUNET_malloc (sizeof (struct GNUNET_DISK_PipeHandle));
+
+#ifndef MINGW
+  int fd[2];
+  int ret;
+  int flags;
+
+  ret = pipe (fd);
+  if (ret != -1)
+    {
+      p->fd[0].fd = fd[0];
+      p->fd[1].fd = fd[1];
+
+      if (!blocking)
+        {
+          flags = fcntl (fd[0], F_GETFL);
+          flags |= O_NONBLOCK;
+          ret = fcntl (fd[0], F_SETFL, flags);
+          if (ret != -1)
+            {
+              flags = fcntl (fd[1], F_GETFL);
+              flags |= O_NONBLOCK;
+              ret = fcntl (fd[1], F_SETFL, flags);
+            }
+          if (ret == -1)
+            {
+              GNUNET_log_strerror(GNUNET_ERROR_TYPE_ERROR, "fcntl");
+              close (fd[0]);
+              close (fd[1]);
+              err = GNUNET_YES;
+            }
+        }
+    }
+  else
+    err = GNUNET_YES;
+#else
+  BOOL ret;
+
+  ret = CreatePipe (&p->fd[0].h, &p->fd[1].h, NULL, 0);
+  if (ret)
+    {
+      if (!blocking)
+        {
+          DWORD mode;
+
+          mode = PIPE_NOWAIT;
+          SetNamedPipeHandleState (p->fd[0].h, &mode, NULL, NULL);
+          SetNamedPipeHandleState (p->fd[1].h, &mode, NULL, NULL);
+          /* this always fails on Windows 95, so we don't care about error handling */
+        }
+    }
+  else
+      err = GNUNET_YES;
+#endif
+
+  if (GNUNET_YES == err)
+    {
+      GNUNET_free (p);
+      p = NULL;
+    }
+
+  return p;
+}
+
+/**
+ * Closes an interprocess channel
+ * @param p pipe
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ */
+int
+GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p)
+{
+  int ret;
+
+  ret = GNUNET_OK;
+
+#ifdef MINGW
+  if (!CloseHandle (p->fd[0].h))
+    {
+      SetErrnoFromWinError (GetLastError ());
+      ret = GNUNET_SYSERR;
+    }
+
+  if (!CloseHandle (p->fd[1].h))
+    {
+      SetErrnoFromWinError (GetLastError ());
+      ret = GNUNET_SYSERR;
+    }
+#else
+  {
+    int save;
+
+    if (close (p->fd[0].fd) != -1)
+      {
+        ret = GNUNET_SYSERR;
+        save = errno;
+      }
+    else
+      save = 0;
+
+    if (close (p->fd[1].fd) != -1)
+      {
+        ret = GNUNET_SYSERR;
+      }
+    else
+      errno = save;
+  }
+#endif
+  GNUNET_free (p);
+
+  return ret;
+}
+
+/**
+ * Get the handle to a particular pipe end
+ * @param p pipe
+ * @param n number of the end
+ */
+const struct GNUNET_DISK_FileHandle *
+GNUNET_DISK_pipe_handle (const struct GNUNET_DISK_PipeHandle *p, int n)
+{
+  return &p->fd[n];
+}
+
+/**
+ * Retrieve OS file handle
+ * @internal
+ * @param fh GNUnet file descriptor
+ * @param dst destination buffer
+ * @param dst_len length of dst
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ */
+int
+GNUNET_internal_disk_file_handle (const struct GNUNET_DISK_FileHandle *fh,
+    void *dst, unsigned int dst_len)
+{
+#ifdef MINGW
+  if (dst_len < sizeof (HANDLE))
+    return GNUNET_SYSERR;
+  *((HANDLE *) dst) = fh->h;
+#else
+  if (dst_len < sizeof(int))
+    return GNUNET_SYSERR;
+  *((int *) dst) = fh->fd;
+#endif
+
+  return GNUNET_OK;
+}
+
 /* end of disk.c */
diff --git a/src/util/disk.h b/src/util/disk.h
new file mode 100644 (file)
index 0000000..9857a0f
--- /dev/null
@@ -0,0 +1,53 @@
+/*\r
+     This file is part of GNUnet.\r
+     (C) 2009 Christian Grothoff (and other contributing authors)\r
+\r
+     GNUnet is free software; you can redistribute it and/or modify\r
+     it under the terms of the GNU General Public License as published\r
+     by the Free Software Foundation; either version 2, or (at your\r
+     option) any later version.\r
+\r
+     GNUnet is distributed in the hope that it will be useful, but\r
+     WITHOUT ANY WARRANTY; without even the implied warranty of\r
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+     General Public License for more details.\r
+\r
+     You should have received a copy of the GNU General Public License\r
+     along with GNUnet; see the file COPYING.  If not, write to the\r
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,\r
+     Boston, MA 02111-1307, USA.\r
+*/\r
+\r
+/**\r
+ * @file util/disk.h\r
+ * @brief Internal DISK related helper functions\r
+ * @author Nils Durner\r
+ */\r
+\r
+\r
+#ifndef GNUNET_DISK_H_\r
+#define GNUNET_DISK_H_\r
+\r
+#include "gnunet_disk_lib.h"\r
+\r
+struct GNUNET_DISK_FileHandle\r
+{\r
+#ifdef MINGW\r
+  HANDLE h;\r
+#else\r
+  int fd;\r
+#endif\r
+};\r
+\r
+/**\r
+ * Retrieve OS file handle\r
+ * @internal\r
+ * @param fh GNUnet file descriptor\r
+ * @param dst destination buffer\r
+ * @param dst_len length of dst\r
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise\r
+ */\r
+int GNUNET_internal_disk_file_handle (const struct GNUNET_DISK_FileHandle *fh,\r
+                                      void *dst, unsigned int dst_len);\r
+\r
+#endif /* GNUNET_DISK_H_ */\r
index 3ee19cfb2cc6872659baa56d2e4f16b09651e70d..6d8b9f9382cb34731a01d0b919669b31dd4475dc 100644 (file)
@@ -37,7 +37,7 @@
 
 #include "platform.h"
 #include "gnunet_common.h"
-#include "gnunet_network_lib.h"
+#include "gnunet_connection_lib.h"
 #include "gnunet_scheduler_lib.h"
 
 #define DEBUG_NETWORK GNUNET_NO
@@ -172,9 +172,9 @@ struct GNUNET_NETWORK_ConnectionHandle
   struct GNUNET_NETWORK_TransmitHandle nth;
 
   /**
-   * Underlying OS's socket, set to -1 after fatal errors.
+   * Underlying OS's socket, set to NULL after fatal errors.
    */
-  int sock;
+  struct GNUNET_NETWORK_Descriptor *sock;
 
   /**
    * Port to connect to.
@@ -219,7 +219,7 @@ struct GNUNET_NETWORK_ConnectionHandle
  */
 struct GNUNET_NETWORK_ConnectionHandle *
 GNUNET_NETWORK_connection_create_from_existing (struct GNUNET_SCHEDULER_Handle
-                                            *sched, int osSocket,
+                                            *sched, struct GNUNET_NETWORK_Descriptor *osSocket,
                                             size_t maxbuf)
 {
   struct GNUNET_NETWORK_ConnectionHandle *ret;
@@ -248,13 +248,13 @@ struct GNUNET_NETWORK_ConnectionHandle *
 GNUNET_NETWORK_connection_create_from_accept (struct GNUNET_SCHEDULER_Handle
                                           *sched,
                                           GNUNET_NETWORK_AccessCheck access,
-                                          void *access_cls, int lsock,
+                                          void *access_cls, struct GNUNET_NETWORK_Descriptor *lsock,
                                           size_t maxbuf)
 {
   struct GNUNET_NETWORK_ConnectionHandle *ret;
   char addr[32];
   socklen_t addrlen;
-  int fd;
+  struct GNUNET_NETWORK_Descriptor *sock;
   int aret;
   struct sockaddr_in *v4;
   struct sockaddr_in6 *v6;
@@ -262,22 +262,21 @@ GNUNET_NETWORK_connection_create_from_accept (struct GNUNET_SCHEDULER_Handle
   void *uaddr;
 
   addrlen = sizeof (addr);
-  fd = accept (lsock, (struct sockaddr *) &addr, &addrlen);
-  if (fd == -1)
+  sock = GNUNET_NETWORK_socket_accept (lsock, (struct sockaddr *) &addr, &addrlen);
+  if (NULL == sock)
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept");
       return NULL;
     }
 #ifndef MINGW
-  // FIXME NILS
-  if (0 != fcntl (fd, F_SETFD, fcntl (fd, F_GETFD) | FD_CLOEXEC))
+  if (GNUNET_OK != GNUNET_NETWORK_socket_set_inheritable (sock))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                          "fcntl");
 #endif
   if (addrlen > sizeof (addr))
     {
       GNUNET_break (0);
-      GNUNET_break (0 == CLOSE (fd));
+      GNUNET_break (0 == GNUNET_NETWORK_socket_close (sock));
       return NULL;
     }
 
@@ -310,8 +309,8 @@ GNUNET_NETWORK_connection_create_from_accept (struct GNUNET_SCHEDULER_Handle
        GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                    _("Access denied to `%s'\n"),
                    GNUNET_a2s(uaddr, addrlen));
-      GNUNET_break (0 == SHUTDOWN (fd, SHUT_RDWR));
-      GNUNET_break (0 == CLOSE (fd));
+      GNUNET_break (0 == GNUNET_NETWORK_socket_shutdown (sock, SHUT_RDWR));
+      GNUNET_break (0 == GNUNET_NETWORK_socket_close (sock));
       GNUNET_free (uaddr);
       return NULL;
     }
@@ -325,7 +324,7 @@ GNUNET_NETWORK_connection_create_from_accept (struct GNUNET_SCHEDULER_Handle
   ret->write_buffer_size = maxbuf;
   ret->addr = uaddr;
   ret->addrlen = addrlen;
-  ret->sock = fd;
+  ret->sock = sock;
   ret->sched = sched;
   return ret;
 }
@@ -350,64 +349,6 @@ GNUNET_NETWORK_connection_get_address (struct GNUNET_NETWORK_ConnectionHandle *s
   return GNUNET_OK;
 }
 
-
-/**
- * Set if a socket should use blocking or non-blocking IO.
- *
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
- */
-static int
-socket_set_blocking (int handle, int doBlock)
-{
-#if MINGW
-  u_long mode;
-  mode = !doBlock;
-#if HAVE_PLIBC_FD
-  if (ioctlsocket (plibc_fd_get_handle (handle), FIONBIO, &mode) ==
-      SOCKET_ERROR)
-    {
-      SetErrnoFromWinsockError (WSAGetLastError ());
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "ioctlsocket");
-      return GNUNET_SYSERR;
-    }
-#else
-  if (ioctlsocket (handle, FIONBIO, &mode) == SOCKET_ERROR)
-    {
-      SetErrnoFromWinsockError (WSAGetLastError ());
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "ioctlsocket");
-      return GNUNET_SYSERR;
-    }
-#endif
-  /* store the blocking mode */
-#if HAVE_PLIBC_FD
-  plibc_fd_set_blocking (handle, doBlock);
-#else
-  __win_SetHandleBlockingMode (handle, doBlock);
-#endif
-  return GNUNET_OK;
-
-#else
-  /* not MINGW */
-  int flags = fcntl (handle, F_GETFL);
-  if (flags == -1)
-    {
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "fcntl");
-      return GNUNET_SYSERR;
-    }
-  if (doBlock)
-    flags &= ~O_NONBLOCK;
-  else
-    flags |= O_NONBLOCK;
-  if (0 != fcntl (handle, F_SETFL, flags))
-    {
-      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "fcntl");
-      return GNUNET_SYSERR;
-    }
-  return GNUNET_OK;
-#endif
-}
-
-
 /**
  * Perform a DNS lookup for the hostname associated
  * with the current socket, iterating over the address
@@ -448,7 +389,7 @@ try_lookup (struct GNUNET_NETWORK_ConnectionHandle *sock)
 static int
 try_connect (struct GNUNET_NETWORK_ConnectionHandle *sock)
 {
-  int s;
+  struct GNUNET_NETWORK_Descriptor *s;
 
   if (sock->addr != NULL)
     {
@@ -479,8 +420,8 @@ try_connect (struct GNUNET_NETWORK_ConnectionHandle *sock)
           sock->ai_pos = sock->ai_pos->ai_next;
           continue;
         }
-      s = SOCKET (sock->ai_pos->ai_family, SOCK_STREAM, 0);
-      if (s == -1)
+      s = GNUNET_NETWORK_socket_socket (sock->ai_pos->ai_family, SOCK_STREAM, 0);
+      if (s == NULL)
         {
           /* maybe unsupported address family, try next */
           GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "socket");
@@ -488,15 +429,14 @@ try_connect (struct GNUNET_NETWORK_ConnectionHandle *sock)
           continue;
         }
 #ifndef MINGW
-      // FIXME NILS
-      if (0 != fcntl (s, F_SETFD, fcntl (s, F_GETFD) | FD_CLOEXEC))
+      if (GNUNET_OK != GNUNET_NETWORK_socket_set_inheritable (s))
         GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
-                             "fcntl");
+                             "GNUNET_NETWORK_socket_set_inheritable");
 #endif
-      if (GNUNET_SYSERR == socket_set_blocking (s, GNUNET_NO))
+      if (GNUNET_SYSERR == GNUNET_NETWORK_socket_set_blocking (s, GNUNET_NO))
         {
           /* we'll treat this one as fatal */
-          GNUNET_break (0 == CLOSE (s));
+          GNUNET_break (0 == GNUNET_NETWORK_socket_close (s));
           return GNUNET_SYSERR;
         }
 #if DEBUG_NETWORK
@@ -505,13 +445,13 @@ try_connect (struct GNUNET_NETWORK_ConnectionHandle *sock)
                  GNUNET_a2s(sock->ai_pos->ai_addr,
                             sock->ai_pos->ai_addrlen));
 #endif
-      if ((0 != CONNECT (s,
+      if ((0 != GNUNET_NETWORK_socket_connect (s,
                          sock->ai_pos->ai_addr,
                          sock->ai_pos->ai_addrlen)) && (errno != EINPROGRESS))
         {
           /* maybe refused / unsupported address, try next */
           GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "connect");
-          GNUNET_break (0 == CLOSE (s));
+          GNUNET_break (0 == GNUNET_NETWORK_socket_close (s));
           sock->ai_pos = sock->ai_pos->ai_next;
           continue;
         }
@@ -548,7 +488,7 @@ connect_continuation (void *cls,
   errno = 0;
   error = 0;
   if ((0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) ||
-      (0 != getsockopt (sock->sock, SOL_SOCKET, SO_ERROR, &error, &len)) ||
+      (0 != GNUNET_NETWORK_socket_getsockopt (sock->sock, SOL_SOCKET, SO_ERROR, &error, &len)) ||
       (error != 0) || (errno != 0))
     {
 #if DEBUG_NETWORK
@@ -557,8 +497,8 @@ connect_continuation (void *cls,
                  GNUNET_a2s(sock->addr, sock->addrlen));
 #endif
       /* connect failed / timed out */
-      GNUNET_break (0 == CLOSE (sock->sock));
-      sock->sock = -1;
+      GNUNET_break (0 == GNUNET_NETWORK_socket_close (sock->sock));
+      sock->sock = NULL;
       if (GNUNET_SYSERR == try_connect (sock))
         {
           /* failed for good */
@@ -572,7 +512,7 @@ connect_continuation (void *cls,
           sock->ai = NULL;
           return;
         }
-      sock->connect_task = GNUNET_SCHEDULER_add_write (tc->sched, GNUNET_NO,    /* abort on shutdown */
+      sock->connect_task = GNUNET_SCHEDULER_add_write_net (tc->sched, GNUNET_NO,    /* abort on shutdown */
                                                        GNUNET_SCHEDULER_PRIORITY_KEEP,
                                                        GNUNET_SCHEDULER_NO_TASK,
                                                        GNUNET_NETWORK_CONNECT_RETRY_TIMEOUT,
@@ -613,7 +553,7 @@ GNUNET_NETWORK_connection_create_from_connect (struct GNUNET_SCHEDULER_Handle
   struct GNUNET_NETWORK_ConnectionHandle *ret;
 
   ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_ConnectionHandle) + maxbuf);
-  ret->sock = -1;
+  ret->sock = NULL;
   ret->sched = sched;
   ret->write_buffer = (char *) &ret[1];
   ret->write_buffer_size = maxbuf;
@@ -628,7 +568,7 @@ GNUNET_NETWORK_connection_create_from_connect (struct GNUNET_SCHEDULER_Handle
       GNUNET_free (ret);
       return NULL;
     }
-  ret->connect_task = GNUNET_SCHEDULER_add_write (sched, GNUNET_NO,     /* abort on shutdown */
+  ret->connect_task = GNUNET_SCHEDULER_add_write_net (sched, GNUNET_NO,     /* abort on shutdown */
                                                   GNUNET_SCHEDULER_PRIORITY_KEEP,
                                                   GNUNET_SCHEDULER_NO_TASK,
                                                   GNUNET_NETWORK_CONNECT_RETRY_TIMEOUT,
@@ -658,25 +598,28 @@ GNUNET_NETWORK_connection_create_from_sockaddr (struct GNUNET_SCHEDULER_Handle
                                             const struct sockaddr *serv_addr,
                                             socklen_t addrlen, size_t maxbuf)
 {
-  int s;
+  struct GNUNET_NETWORK_Descriptor *s;
   struct GNUNET_NETWORK_ConnectionHandle *ret;
 
-  s = SOCKET (af_family, SOCK_STREAM, 0);
-  if (s == -1)
+  s = GNUNET_NETWORK_socket_socket (af_family, SOCK_STREAM, 0);
+  if (s == NULL)
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING |
                            GNUNET_ERROR_TYPE_BULK, "socket");
       return NULL;
     }
 #ifndef MINGW
+#if 0
+  // FIXME NILS
   if (0 != fcntl (s, F_SETFD, fcntl (s, F_GETFD) | FD_CLOEXEC))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                          "fcntl");
 #endif
-  if (GNUNET_SYSERR == socket_set_blocking (s, GNUNET_NO))
+#endif
+  if (GNUNET_SYSERR == GNUNET_NETWORK_socket_set_blocking (s, GNUNET_NO))
     {
       /* we'll treat this one as fatal */
-      GNUNET_break (0 == CLOSE (s));
+      GNUNET_break (0 == GNUNET_NETWORK_socket_close (s));
       return NULL;
     }
 #if DEBUG_NETWORK
@@ -684,11 +627,11 @@ GNUNET_NETWORK_connection_create_from_sockaddr (struct GNUNET_SCHEDULER_Handle
              _("Trying to connect to `%s'\n"),
              GNUNET_a2s(serv_addr, addrlen));
 #endif
-  if ((0 != CONNECT (s, serv_addr, addrlen)) && (errno != EINPROGRESS))
+  if ((0 != GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) && (errno != EINPROGRESS))
     {
       /* maybe refused / unsupported address, try next */
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "connect");
-      GNUNET_break (0 == CLOSE (s));
+      GNUNET_break (0 == GNUNET_NETWORK_socket_close (s));
       return NULL;
     }
   ret = GNUNET_NETWORK_connection_create_from_existing (sched, s, maxbuf);
@@ -712,7 +655,7 @@ GNUNET_NETWORK_connection_check (struct GNUNET_NETWORK_ConnectionHandle *sock)
 {
   if (sock->ai != NULL)
     return GNUNET_YES;          /* still trying to connect */
-  return (sock->sock == -1) ? GNUNET_NO : GNUNET_YES;
+  return (sock->sock == NULL) ? GNUNET_NO : GNUNET_YES;
 }
 
 
@@ -736,12 +679,12 @@ destroy_continuation (void *cls,
                                   &destroy_continuation, sock);
       return;
     }
-  if (sock->sock != -1)
+  if (sock->sock != NULL)
     {
 #if DEBUG_NETWORK
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down socket.\n");
 #endif
-      SHUTDOWN (sock->sock, SHUT_RDWR);
+      GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR);
     }
   if (sock->read_task != GNUNET_SCHEDULER_NO_TASK)
     {
@@ -762,8 +705,8 @@ destroy_continuation (void *cls,
           sock->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK;
         }
     }
-  if (sock->sock != -1)
-    GNUNET_break (0 == CLOSE (sock->sock));
+  if (sock->sock != NULL)
+    GNUNET_break (0 == GNUNET_NETWORK_socket_close (sock->sock));
   GNUNET_free_non_null (sock->addr);
   if (sock->ai != NULL)
     freeaddrinfo (sock->ai);      
@@ -850,7 +793,7 @@ receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
       signal_timeout (sh);
       return;
     }
-  if (sh->sock == -1)
+  if (sh->sock == NULL)
     {
       /* connect failed for good */
 #if DEBUG_NETWORK
@@ -860,9 +803,9 @@ receive_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
       signal_error (sh, ECONNREFUSED);
       return;
     }
-  GNUNET_assert (FD_ISSET (sh->sock, tc->read_ready));
+  GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, sh->sock));
 RETRY:
-  ret = RECV (sh->sock, buffer, sh->max,
+  ret = GNUNET_NETWORK_socket_recv (sh->sock, buffer, sh->max,
 #ifndef MINGW
       // FIXME MINGW
       MSG_DONTWAIT
@@ -908,7 +851,7 @@ receive_again (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   struct GNUNET_TIME_Absolute now;
 
   sh->read_task = GNUNET_SCHEDULER_NO_TASK;
-  if ((sh->sock == -1) &&
+  if ((sh->sock == NULL) &&
       (sh->connect_task == GNUNET_SCHEDULER_NO_TASK))
     {
       /* not connected and no longer trying */
@@ -941,7 +884,7 @@ receive_again (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
       return;
     }
   /* connect succeeded, wait for data! */
-  sh->read_task = GNUNET_SCHEDULER_add_read (tc->sched,
+  sh->read_task = GNUNET_SCHEDULER_add_read_net (tc->sched,
                                             GNUNET_YES,
                                             GNUNET_SCHEDULER_PRIORITY_KEEP,
                                             sh->connect_task,
@@ -1120,25 +1063,25 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
                                       sock);
       return;
     }
-  if ( (sock->sock == -1) ||
+  if ( (sock->sock == NULL) ||
        ( (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT)) &&
         (0 == (tc->reason & GNUNET_SCHEDULER_REASON_PREREQ_DONE)) &&
-        (!FD_ISSET (sock->sock, tc->write_ready)))  )
+        (!GNUNET_NETWORK_fdset_isset (tc->write_ready, sock->sock)))  )
     {
 #if DEBUG_NETWORK
       GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                   _("Could not satisfy pending transmission request, socket closed or connect failed.\n"));
 #endif
-      if (-1 != sock->sock)
+      if (NULL != sock->sock)
        {
-         SHUTDOWN (sock->sock, SHUT_RDWR);
-         GNUNET_break (0 == CLOSE (sock->sock));
-         sock->sock = -1;
+         GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR);
+         GNUNET_break (0 == GNUNET_NETWORK_socket_close (sock->sock));
+         sock->sock = NULL;
        }
       transmit_error (sock);
       return;                   /* connect failed for good, we're finished */
     }
- if ((tc->write_ready == NULL) || (!FD_ISSET (sock->sock, tc->write_ready)))
+ if ((tc->write_ready == NULL) || (!GNUNET_NETWORK_fdset_isset (tc->write_ready, sock->sock)))
     {
       /* special circumstances (in particular,
         PREREQ_DONE after connect): not yet ready to write,
@@ -1154,7 +1097,7 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
       return;
     }
 RETRY:
-  ret = SEND (sock->sock,
+  ret = GNUNET_NETWORK_socket_send (sock->sock,
               &sock->write_buffer[sock->write_buffer_pos],
               have,
 #ifndef MINGW
@@ -1171,9 +1114,9 @@ RETRY:
 #if DEBUG_NETWORK
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "send");
 #endif
-      SHUTDOWN (sock->sock, SHUT_RDWR);
-      GNUNET_break (0 == CLOSE (sock->sock));
-      sock->sock = -1;
+      GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR);
+      GNUNET_break (0 == GNUNET_NETWORK_socket_close (sock->sock));
+      sock->sock = NULL;
       transmit_error (sock);
       return;
     }
@@ -1197,7 +1140,7 @@ RETRY:
 SCHEDULE_WRITE:
   if (sock->write_task == GNUNET_SCHEDULER_NO_TASK)
     sock->write_task =
-      GNUNET_SCHEDULER_add_write (tc->sched,
+      GNUNET_SCHEDULER_add_write_net (tc->sched,
                                   GNUNET_NO,
                                   GNUNET_SCHEDULER_PRIORITY_KEEP,
                                   GNUNET_SCHEDULER_NO_TASK,
@@ -1232,7 +1175,7 @@ GNUNET_NETWORK_connection_notify_transmit_ready (struct GNUNET_NETWORK_Connectio
   GNUNET_assert (notify != NULL);
   GNUNET_assert (sock->write_buffer_size >= size);
 
-  if ((sock->sock == -1) &&
+  if ((sock->sock == NULL) &&
       (sock->connect_task == GNUNET_SCHEDULER_NO_TASK))
     {
 #if DEBUG_NETWORK
@@ -1261,7 +1204,7 @@ GNUNET_NETWORK_connection_notify_transmit_ready (struct GNUNET_NETWORK_Connectio
   if (sock->write_task == GNUNET_SCHEDULER_NO_TASK)
     {
       if (sock->connect_task == GNUNET_SCHEDULER_NO_TASK)
-       sock->write_task = GNUNET_SCHEDULER_add_write (sock->sched,
+       sock->write_task = GNUNET_SCHEDULER_add_write_net (sock->sched,
                                                       GNUNET_NO,
                                                       GNUNET_SCHEDULER_PRIORITY_KEEP,
                                                       GNUNET_SCHEDULER_NO_TASK,
index 0b53072902234ff1161fa0d3358ff0058dd62018..69a5a83e1d5ef2566eb48310b36efbab8d33411f 100644 (file)
@@ -55,7 +55,7 @@ struct Task
    * to reflect the set of file descriptors ready
    * for operation.
    */
-  fd_set read_set;
+  struct GNUNET_NETWORK_FDSet *read_set;
 
   /**
    * Set of file descriptors this task is waiting
@@ -63,7 +63,7 @@ struct Task
    * to reflect the set of file descriptors ready
    * for operation.
    */
-  fd_set write_set;
+  struct GNUNET_NETWORK_FDSet *write_set;
 
   /**
    * Unique task identifier.
@@ -93,11 +93,6 @@ struct Task
    */
   enum GNUNET_SCHEDULER_Priority priority;
 
-  /**
-   * highest-numbered file descriptor in read_set or write_set plus one
-   */
-  int nfds;
-
   /**
    * Should this task be run on shutdown?
    */
@@ -170,33 +165,6 @@ check_priority (enum GNUNET_SCHEDULER_Priority p)
 }
 
 
-/**
- * Update the timeout value so that it is smaller than min.
- */
-static void
-update_timeout (struct timeval *tv, struct GNUNET_TIME_Relative min)
-{
-  if (((tv->tv_sec * 1000) + (tv->tv_usec / 1000)) > min.value)
-    {
-      tv->tv_sec = min.value / 1000;
-      tv->tv_usec = (min.value - tv->tv_sec * 1000) * 1000;
-    }
-}
-
-
-/**
- * Set the given file descriptor bit in the given set and update max
- * to the maximum of the existing max and fd+1.
- */
-static void
-set_fd (int fd, int *max, fd_set * set)
-{
-  if (*max <= fd)
-    *max = fd + 1;
-  FD_SET (fd, set);
-}
-
-
 /**
  * Is a task with this identifier still pending?  Also updates
  * "lowest_pending_id" as a side-effect (for faster checks in the
@@ -247,14 +215,14 @@ is_pending (struct GNUNET_SCHEDULER_Handle *sched,
  */
 static void
 update_sets (struct GNUNET_SCHEDULER_Handle *sched,
-             int *max, fd_set * rs, fd_set * ws, struct timeval *tv)
+             struct GNUNET_NETWORK_FDSet * rs, struct GNUNET_NETWORK_FDSet * ws, struct GNUNET_TIME_Relative *timeout)
 {
-  int i;
   struct Task *pos;
 
   pos = sched->pending;
   while (pos != NULL)
     {
+
       if ((pos->prereq_id != GNUNET_SCHEDULER_NO_TASK) &&
           (GNUNET_YES == is_pending (sched, pos->prereq_id)))
         {
@@ -263,15 +231,16 @@ update_sets (struct GNUNET_SCHEDULER_Handle *sched,
         }
 
       if (pos->timeout.value != GNUNET_TIME_UNIT_FOREVER_ABS.value)
-        update_timeout (tv,
-                        GNUNET_TIME_absolute_get_remaining (pos->timeout));
-      for (i = 0; i < pos->nfds; i++)
         {
-          if (FD_ISSET (i, &pos->read_set))
-            set_fd (i, max, rs);
-          if (FD_ISSET (i, &pos->write_set))
-            set_fd (i, max, ws);
+          struct GNUNET_TIME_Relative to;
+
+          to = GNUNET_TIME_absolute_get_remaining (pos->timeout);
+          if (timeout->value > to.value)
+              *timeout = to;
         }
+
+      GNUNET_NETWORK_fdset_add (rs, pos->read_set);
+      GNUNET_NETWORK_fdset_add (ws, pos->write_set);
       pos = pos->next;
     }
 }
@@ -286,18 +255,15 @@ update_sets (struct GNUNET_SCHEDULER_Handle *sched,
  * @return GNUNET_YES if there was some overlap
  */
 static int
-set_overlaps (const fd_set * ready, fd_set * want, int maxfd)
+set_overlaps (const struct GNUNET_NETWORK_FDSet * ready, struct GNUNET_NETWORK_FDSet * want)
 {
-  int i;
-
-  for (i = 0; i < maxfd; i++)
-    if (FD_ISSET (i, want) && FD_ISSET (i, ready))
-      {
-        /* copy all over (yes, there maybe unrelated bits,
-           but this should not hurt well-written clients) */
-        memcpy (want, ready, sizeof (fd_set));
-        return GNUNET_YES;
-      }
+  if (GNUNET_NETWORK_fdset_overlap (ready, want))
+    {
+      /* copy all over (yes, there maybe unrelated bits,
+         but this should not hurt well-written clients) */
+      GNUNET_NETWORK_fdset_copy (want, ready);
+      return GNUNET_YES;
+    }
   return GNUNET_NO;
 }
 
@@ -312,7 +278,7 @@ static int
 is_ready (struct GNUNET_SCHEDULER_Handle *sched,
           struct Task *task,
           struct GNUNET_TIME_Absolute now,
-          const fd_set * rs, const fd_set * ws)
+          const struct GNUNET_NETWORK_FDSet * rs, const struct GNUNET_NETWORK_FDSet * ws)
 {
   if ((GNUNET_NO == task->run_on_shutdown) && (GNUNET_YES == sched->shutdown))
     return GNUNET_NO;
@@ -322,10 +288,10 @@ is_ready (struct GNUNET_SCHEDULER_Handle *sched,
   if (now.value >= task->timeout.value)
     task->reason |= GNUNET_SCHEDULER_REASON_TIMEOUT;
   if ((0 == (task->reason & GNUNET_SCHEDULER_REASON_READ_READY)) &&
-      (rs != NULL) && (set_overlaps (rs, &task->read_set, task->nfds)))
+      (rs != NULL) && (set_overlaps (rs, task->read_set)))
     task->reason |= GNUNET_SCHEDULER_REASON_READ_READY;
   if ((0 == (task->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) &&
-      (ws != NULL) && (set_overlaps (ws, &task->write_set, task->nfds)))
+      (ws != NULL) && (set_overlaps (ws, task->write_set)))
     task->reason |= GNUNET_SCHEDULER_REASON_WRITE_READY;
   if (task->reason == 0)
     return GNUNET_NO;           /* not ready */
@@ -357,7 +323,7 @@ queue_ready_task (struct GNUNET_SCHEDULER_Handle *handle, struct Task *task)
  */
 static void
 check_ready (struct GNUNET_SCHEDULER_Handle *handle,
-             const fd_set * rs, const fd_set * ws)
+             const struct GNUNET_NETWORK_FDSet * rs, const struct GNUNET_NETWORK_FDSet * ws)
 {
   struct Task *pos;
   struct Task *prev;
@@ -386,6 +352,19 @@ check_ready (struct GNUNET_SCHEDULER_Handle *handle,
 }
 
 
+/**
+ * Destroy a task
+ */
+static void destroy_task (struct Task *t)
+{
+  if (t->read_set)
+    GNUNET_NETWORK_fdset_destroy (t->read_set);
+  if (t->write_set)
+    GNUNET_NETWORK_fdset_destroy (t->write_set);
+  GNUNET_free (t);
+}
+
+
 /**
  * Run at least one task in the highest-priority queue that is not
  * empty.  Keep running tasks until we are either no longer running
@@ -420,10 +399,10 @@ run_ready (struct GNUNET_SCHEDULER_Handle *sched)
       GNUNET_assert (pos->priority == p);
       tc.sched = sched;
       tc.reason = pos->reason;
-      tc.read_ready = &pos->read_set;
-      tc.write_ready = &pos->write_set;
+      tc.read_ready = pos->read_set;
+      tc.write_ready = pos->write_set;
       pos->callback (pos->callback_cls, &tc);
-      GNUNET_free (pos);
+      destroy_task (pos);
     }
   while ((sched->pending == NULL) || (p == GNUNET_SCHEDULER_PRIORITY_URGENT));
 }
@@ -458,10 +437,9 @@ void
 GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *cls)
 {
   struct GNUNET_SCHEDULER_Handle sched;
-  fd_set rs;
-  fd_set ws;
-  int max;
-  struct timeval tv;
+  struct GNUNET_NETWORK_FDSet *rs;
+  struct GNUNET_NETWORK_FDSet *ws;
+  struct GNUNET_TIME_Relative timeout;
   int ret;
   struct GNUNET_SIGNAL_Context *shc_int;
   struct GNUNET_SIGNAL_Context *shc_term;
@@ -470,6 +448,8 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *cls)
   struct Task *tpos;
 
   sig_shutdown = 0;
+  rs = GNUNET_NETWORK_fdset_create ();
+  ws = GNUNET_NETWORK_fdset_create ();
 #ifndef MINGW
   shc_int = GNUNET_SIGNAL_handler_install (SIGINT, &sighandler_shutdown);
   shc_term = GNUNET_SIGNAL_handler_install (SIGTERM, &sighandler_shutdown);
@@ -486,27 +466,24 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *cls)
          (!sig_shutdown) &&
          ((sched.pending != NULL) || (sched.ready_count > 0)))
     {
-      FD_ZERO (&rs);
-      FD_ZERO (&ws);
-      max = 0;
-      tv.tv_sec = 0x7FFFFFFF;
-      tv.tv_usec = 0;
+      GNUNET_NETWORK_fdset_zero (rs);
+      GNUNET_NETWORK_fdset_zero (ws);
+      timeout = GNUNET_TIME_relative_get_forever();
       if (sched.ready_count > 0)
         {
           /* no blocking, more work already ready! */
-          tv.tv_sec = 0;
-          tv.tv_usec = 0;
+          timeout = GNUNET_TIME_relative_get_zero();
         }
-      update_sets (&sched, &max, &rs, &ws, &tv);
-      ret = SELECT (max, &rs, &ws, NULL, &tv);
-      if (ret == -1)
+      update_sets (&sched, rs, ws, &timeout);
+      ret = GNUNET_NETWORK_socket_select (rs, ws, NULL, GNUNET_TIME_relative_get_zero());
+      if (ret == GNUNET_SYSERR)
         {
           if (errno == EINTR)
             continue;
           GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "select");
           break;
         }
-      check_ready (&sched, &rs, &ws);
+      check_ready (&sched, rs, ws);
       run_ready (&sched);
     }
   if (sig_shutdown)
@@ -526,6 +503,8 @@ GNUNET_SCHEDULER_run (GNUNET_SCHEDULER_Task task, void *cls)
       sched.pending = tpos->next;
       GNUNET_free (tpos);
     }
+  GNUNET_NETWORK_fdset_destroy (rs);
+  GNUNET_NETWORK_fdset_destroy (ws);
 }
 
 
@@ -626,7 +605,7 @@ GNUNET_SCHEDULER_cancel (struct GNUNET_SCHEDULER_Handle *sched,
   else
     prev->next = t->next;
   ret = t->callback_cls;
-  GNUNET_free (t);
+  destroy_task (t);
   return ret;
 }
 
@@ -688,7 +667,7 @@ GNUNET_SCHEDULER_add_after (struct GNUNET_SCHEDULER_Handle *sched,
   return GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio,
                                       prerequisite_task,
                                       GNUNET_TIME_UNIT_ZERO,
-                                      0, NULL, NULL, main, cls);
+                                      NULL, NULL, main, cls);
 }
 
 
@@ -726,7 +705,7 @@ GNUNET_SCHEDULER_add_delayed (struct GNUNET_SCHEDULER_Handle * sched,
 {
   return GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio,
                                       prerequisite_task, delay,
-                                      0, NULL, NULL, main, cls);
+                                      NULL, NULL, main, cls);
 }
 
 
@@ -755,21 +734,24 @@ GNUNET_SCHEDULER_add_delayed (struct GNUNET_SCHEDULER_Handle * sched,
  *         only valid until "main" is started!
  */
 GNUNET_SCHEDULER_TaskIdentifier
-GNUNET_SCHEDULER_add_read (struct GNUNET_SCHEDULER_Handle * sched,
+GNUNET_SCHEDULER_add_read_net (struct GNUNET_SCHEDULER_Handle * sched,
                            int run_on_shutdown,
                            enum GNUNET_SCHEDULER_Priority prio,
                            GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
                            struct GNUNET_TIME_Relative delay,
-                           int rfd, GNUNET_SCHEDULER_Task main, void *cls)
+                           struct GNUNET_NETWORK_Descriptor *rfd, GNUNET_SCHEDULER_Task main, void *cls)
 {
-  fd_set rs;
+  struct GNUNET_NETWORK_FDSet *rs;
+  GNUNET_SCHEDULER_TaskIdentifier ret;
 
-  GNUNET_assert (rfd >= 0);
-  FD_ZERO (&rs);
-  FD_SET (rfd, &rs);
-  return GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio,
+  GNUNET_assert (rfd != NULL);
+  rs = GNUNET_NETWORK_fdset_create ();
+  GNUNET_NETWORK_fdset_set (rs, rfd);
+  ret = GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio,
                                       prerequisite_task, delay,
-                                      rfd + 1, &rs, NULL, main, cls);
+                                      rs, NULL, main, cls);
+  GNUNET_NETWORK_fdset_destroy (rs);
+  return ret;
 }
 
 
@@ -798,21 +780,24 @@ GNUNET_SCHEDULER_add_read (struct GNUNET_SCHEDULER_Handle * sched,
  *         only valid until "main" is started!
  */
 GNUNET_SCHEDULER_TaskIdentifier
-GNUNET_SCHEDULER_add_write (struct GNUNET_SCHEDULER_Handle * sched,
+GNUNET_SCHEDULER_add_write_net (struct GNUNET_SCHEDULER_Handle * sched,
                             int run_on_shutdown,
                             enum GNUNET_SCHEDULER_Priority prio,
                             GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
                             struct GNUNET_TIME_Relative delay,
-                            int wfd, GNUNET_SCHEDULER_Task main, void *cls)
+                            struct GNUNET_NETWORK_Descriptor *wfd, GNUNET_SCHEDULER_Task main, void *cls)
 {
-  fd_set ws;
+  struct GNUNET_NETWORK_FDSet *ws;
+  GNUNET_SCHEDULER_TaskIdentifier ret;
 
-  GNUNET_assert (wfd >= 0);
-  FD_ZERO (&ws);
-  FD_SET (wfd, &ws);
-  return GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio,
+  GNUNET_assert (wfd != NULL);
+  ws = GNUNET_NETWORK_fdset_create ();
+  GNUNET_NETWORK_fdset_set (ws, wfd);
+  ret = GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio,
                                       prerequisite_task, delay,
-                                      wfd + 1, NULL, &ws, main, cls);
+                                      NULL, ws, main, cls);
+  GNUNET_NETWORK_fdset_destroy (ws);
+  return ret;
 }
 
 
@@ -844,7 +829,6 @@ GNUNET_SCHEDULER_add_write (struct GNUNET_SCHEDULER_Handle * sched,
  *        are satisfied).  Use GNUNET_SCHEDULER_NO_TASK to not have any dependency
  *        on completion of other tasks.
  * @param delay how long should we wait? Use GNUNET_TIME_UNIT_FOREVER_REL for "forever"
- * @param nfds highest-numbered file descriptor in any of the two sets plus one
  * @param rs set of file descriptors we want to read (can be NULL)
  * @param ws set of file descriptors we want to write (can be NULL)
  * @param main main function of the task
@@ -859,7 +843,7 @@ GNUNET_SCHEDULER_add_select (struct GNUNET_SCHEDULER_Handle * sched,
                              GNUNET_SCHEDULER_TaskIdentifier
                              prerequisite_task,
                              struct GNUNET_TIME_Relative delay,
-                             int nfds, const fd_set * rs, const fd_set * ws,
+                             const struct GNUNET_NETWORK_FDSet * rs, const struct GNUNET_NETWORK_FDSet * ws,
                              GNUNET_SCHEDULER_Task main, void *cls)
 {
   struct Task *task;
@@ -867,10 +851,12 @@ GNUNET_SCHEDULER_add_select (struct GNUNET_SCHEDULER_Handle * sched,
   task = GNUNET_malloc (sizeof (struct Task));
   task->callback = main;
   task->callback_cls = cls;
-  if ((rs != NULL) && (nfds > 0))
-    memcpy (&task->read_set, rs, sizeof (fd_set));
-  if ((ws != NULL) && (nfds > 0))
-    memcpy (&task->write_set, ws, sizeof (fd_set));
+  task->read_set = GNUNET_NETWORK_fdset_create ();
+  if (rs != NULL)
+    GNUNET_NETWORK_fdset_copy (task->read_set, rs);
+  task->write_set = GNUNET_NETWORK_fdset_create ();
+  if (ws != NULL)
+    GNUNET_NETWORK_fdset_copy (task->write_set, ws);
   task->id = ++sched->last_id;
   task->prereq_id = prerequisite_task;
   task->timeout = GNUNET_TIME_relative_to_absolute (delay);
@@ -878,11 +864,102 @@ GNUNET_SCHEDULER_add_select (struct GNUNET_SCHEDULER_Handle * sched,
     check_priority ((prio ==
                      GNUNET_SCHEDULER_PRIORITY_KEEP) ? sched->current_priority
                     : prio);
-  task->nfds = nfds;
   task->run_on_shutdown = run_on_shutdown;
   task->next = sched->pending;
   sched->pending = task;
   return task->id;
 }
 
+/**
+ * Schedule a new task to be run with a specified delay or when the
+ * specified file descriptor is ready for reading.  The delay can be
+ * used as a timeout on the socket being ready.  The task will be
+ * scheduled for execution once either the delay has expired or the
+ * socket operation is ready.
+ *
+ * @param sched scheduler to use
+ * @param run_on_shutdown run on shutdown? Set this
+ *        argument to GNUNET_NO to skip this task if
+ *        the user requested process termination.
+ * @param prio how important is this task?
+ * @param prerequisite_task run this task after the task with the given
+ *        task identifier completes (and any of our other
+ *        conditions, such as delay, read or write-readyness
+ *        are satisfied).  Use  GNUNET_SCHEDULER_NO_TASK to not have any dependency
+ *        on completion of other tasks.
+ * @param delay how long should we wait? Use  GNUNET_TIME_UNIT_FOREVER_REL for "forever"
+ * @param rfd read file-descriptor
+ * @param main main function of the task
+ * @param cls closure of task
+ * @return unique task identifier for the job
+ *         only valid until "main" is started!
+ */
+GNUNET_SCHEDULER_TaskIdentifier
+GNUNET_SCHEDULER_add_read_file (struct GNUNET_SCHEDULER_Handle * sched,
+                           int run_on_shutdown,
+                           enum GNUNET_SCHEDULER_Priority prio,
+                           GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
+                           struct GNUNET_TIME_Relative delay,
+                           struct GNUNET_DISK_FileHandle *rfd, GNUNET_SCHEDULER_Task main, void *cls)
+{
+  struct GNUNET_NETWORK_FDSet *rs;
+  GNUNET_SCHEDULER_TaskIdentifier ret;
+
+  GNUNET_assert (rfd != NULL);
+  rs = GNUNET_NETWORK_fdset_create ();
+  GNUNET_NETWORK_fdset_handle_set (rs, rfd);
+  ret = GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio,
+                                      prerequisite_task, delay,
+                                      rs, NULL, main, cls);
+  GNUNET_NETWORK_fdset_destroy (rs);
+  return ret;
+}
+
+
+/**
+ * Schedule a new task to be run with a specified delay or when the
+ * specified file descriptor is ready for writing.  The delay can be
+ * used as a timeout on the socket being ready.  The task will be
+ * scheduled for execution once either the delay has expired or the
+ * socket operation is ready.
+ *
+ * @param sched scheduler to use
+ * @param run_on_shutdown run on shutdown? Set this
+ *        argument to GNUNET_NO to skip this task if
+ *        the user requested process termination.
+ * @param prio how important is this task?
+ * @param prerequisite_task run this task after the task with the given
+ *        task identifier completes (and any of our other
+ *        conditions, such as delay, read or write-readyness
+ *        are satisfied).  Use  GNUNET_SCHEDULER_NO_TASK to not have any dependency
+ *        on completion of other tasks.
+ * @param delay how long should we wait? Use  GNUNET_TIME_UNIT_FOREVER_REL for "forever"
+ * @param wfd write file-descriptor
+ * @param main main function of the task
+ * @param cls closure of task
+ * @return unique task identifier for the job
+ *         only valid until "main" is started!
+ */
+GNUNET_SCHEDULER_TaskIdentifier
+GNUNET_SCHEDULER_add_write_file (struct GNUNET_SCHEDULER_Handle * sched,
+                            int run_on_shutdown,
+                            enum GNUNET_SCHEDULER_Priority prio,
+                            GNUNET_SCHEDULER_TaskIdentifier prerequisite_task,
+                            struct GNUNET_TIME_Relative delay,
+                            struct GNUNET_DISK_FileHandle *wfd, GNUNET_SCHEDULER_Task main, void *cls)
+{
+  struct GNUNET_NETWORK_FDSet *ws;
+  GNUNET_SCHEDULER_TaskIdentifier ret;
+
+  GNUNET_assert (wfd != NULL);
+  ws = GNUNET_NETWORK_fdset_create ();
+  GNUNET_NETWORK_fdset_handle_set (ws, wfd);
+  ret = GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio,
+                                      prerequisite_task, delay,
+                                      NULL, ws, main, cls);
+  GNUNET_NETWORK_fdset_destroy (ws);
+  return ret;
+}
+
+
 /* end of scheduler.c */
index d518cbeec2e6f60a2c488b58ee654e2b212eefac..ff9ea993de2e6b3309313590ff7aba95581d7bf3 100644 (file)
 
 #include "platform.h"
 #include "gnunet_common.h"
-#include "gnunet_network_lib.h"
+#include "gnunet_connection_lib.h"
 #include "gnunet_scheduler_lib.h"
 #include "gnunet_server_lib.h"
 #include "gnunet_time_lib.h"
+#include "gnunet_disk_lib.h"
 
 #define DEBUG_SERVER GNUNET_NO
 
@@ -124,13 +125,13 @@ struct GNUNET_SERVER_Handle
   /**
    * Pipe used to signal shutdown of the server.
    */
-  int shutpipe[2];
+  struct GNUNET_DISK_PipeHandle *shutpipe;
 
   /**
    * Socket used to listen for new connections.  Set to
    * "-1" by GNUNET_SERVER_destroy to initiate shutdown.
    */
-  int listen_socket;
+  struct GNUNET_NETWORK_Descriptor *listen_socket;
 
   /**
    * Set to GNUNET_YES if we are shutting down.
@@ -280,9 +281,8 @@ destroy_server (struct GNUNET_SERVER_Handle *server)
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Server shutting down.\n");
 #endif
-  GNUNET_assert (server->listen_socket == -1);
-  GNUNET_break (0 == CLOSE (server->shutpipe[0]));
-  GNUNET_break (0 == CLOSE (server->shutpipe[1]));
+  GNUNET_assert (server->listen_socket == NULL);
+  GNUNET_break (GNUNET_YES == GNUNET_DISK_pipe_close (server->shutpipe));
   while (server->clients != NULL)
     {
       pos = server->clients;
@@ -314,21 +314,23 @@ process_listen_socket (void *cls,
   struct GNUNET_SERVER_Handle *server = cls;
   struct GNUNET_NETWORK_ConnectionHandle *sock;
   struct GNUNET_SERVER_Client *client;
-  fd_set r;
+  struct GNUNET_NETWORK_FDSet *r;
+  const struct GNUNET_DISK_FileHandle *shutpipe;
 
   if ((server->do_shutdown) ||
       ((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0))
     {
       /* shutdown was initiated */
-      GNUNET_assert (server->listen_socket != -1);
-      GNUNET_break (0 == CLOSE (server->listen_socket));
-      server->listen_socket = -1;
+      GNUNET_assert (server->listen_socket != NULL);
+      GNUNET_break (0 == GNUNET_NETWORK_socket_close (server->listen_socket));
+      server->listen_socket = NULL;
       if (server->do_shutdown)
         destroy_server (server);
       return;
     }
-  GNUNET_assert (FD_ISSET (server->listen_socket, tc->read_ready));
-  GNUNET_assert (!FD_ISSET (server->shutpipe[0], tc->read_ready));
+  shutpipe = GNUNET_DISK_pipe_handle (server->shutpipe, 0);
+  GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, server->listen_socket));
+  GNUNET_assert (!GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, shutpipe));
   sock = GNUNET_NETWORK_connection_create_from_accept (tc->sched,
                                                    server->access,
                                                    server->access_cls,
@@ -345,30 +347,30 @@ process_listen_socket (void *cls,
       GNUNET_SERVER_client_drop (client);
     }
   /* listen for more! */
-  FD_ZERO (&r);
-  FD_SET (server->listen_socket, &r);
-  FD_SET (server->shutpipe[0], &r);
+  r = GNUNET_NETWORK_fdset_create ();
+  GNUNET_NETWORK_fdset_set (r, server->listen_socket);
+  GNUNET_NETWORK_fdset_handle_set (r, shutpipe);
   GNUNET_SCHEDULER_add_select (server->sched,
                                GNUNET_YES,
                                GNUNET_SCHEDULER_PRIORITY_HIGH,
                                GNUNET_SCHEDULER_NO_TASK,
                                GNUNET_TIME_UNIT_FOREVER_REL,
-                               GNUNET_MAX (server->listen_socket,
-                                           server->shutpipe[0]) + 1, &r, NULL,
+                               r, NULL,
                                &process_listen_socket, server);
+  GNUNET_NETWORK_fdset_destroy (r);
 }
 
 
 /**
  * Create and initialize a listen socket for the server.
  *
- * @return -1 on error, otherwise the listen socket
+ * @return NULL on error, otherwise the listen socket
  */
-static int
+static struct GNUNET_NETWORK_Descriptor *
 open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
 {
   const static int on = 1;
-  int fd;
+  struct GNUNET_NETWORK_Descriptor *sock;
   uint16_t port;
 
   switch (serverAddr->sa_family)
@@ -381,46 +383,45 @@ open_listen_socket (const struct sockaddr *serverAddr, socklen_t socklen)
       break;
     default:
       GNUNET_break (0);
-      return -1;
+      return NULL;
     }
-  fd = SOCKET (serverAddr->sa_family, SOCK_STREAM, 0);
-  if (fd < 0)
+  sock = GNUNET_NETWORK_socket_socket (serverAddr->sa_family, SOCK_STREAM, 0);
+  if (NULL == sock)
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
-      return -1;
+      return NULL;
     }
 #ifndef MINGW
-  // FIXME NILS
-  if (0 != fcntl (fd, F_SETFD, fcntl (fd, F_GETFD) | FD_CLOEXEC))
+  if (GNUNET_OK != GNUNET_NETWORK_socket_set_inheritable (sock))
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                          "fcntl");
 #endif
-  if (SETSOCKOPT (fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
+  if (GNUNET_NETWORK_socket_setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                          "setsockopt");
   /* bind the socket */
-  if (BIND (fd, serverAddr, socklen) < 0)
+  if (GNUNET_NETWORK_socket_bind (sock, serverAddr, socklen) < 0)
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                   _
                   ("`%s' failed for port %d. Is the service already running?\n"),
                   "bind", port);
-      GNUNET_break (0 == CLOSE (fd));
-      return -1;
+      GNUNET_break (0 == GNUNET_NETWORK_socket_close (sock));
+      return NULL;
     }
-  if (0 != LISTEN (fd, 5))
+  if (0 != GNUNET_NETWORK_socket_listen (sock, 5))
     {
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen");
-      GNUNET_break (0 == CLOSE (fd));
-      return -1;
+      GNUNET_break (0 == GNUNET_NETWORK_socket_close (sock));
+      return NULL;
     }
 #if DEBUG_SERVER
       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                  "Server starts to listen on port %u.\n",
                  port);
 #endif
-  return fd;
+  return sock;
 }
 
 
@@ -451,20 +452,22 @@ GNUNET_SERVER_create (struct GNUNET_SCHEDULER_Handle *sched,
                       idle_timeout, int require_found)
 {
   struct GNUNET_SERVER_Handle *ret;
-  int lsock;
-  fd_set r;
+  struct GNUNET_NETWORK_Descriptor *lsock;
+  struct GNUNET_NETWORK_FDSet *r;
 
-  lsock = -2;
+  lsock = NULL; // FIXME NILS: this was -2, does that have a special meaning?
   if (serverAddr != NULL)
     {
       lsock = open_listen_socket (serverAddr, socklen);
-      if (lsock == -1)
+      if (lsock == NULL)
         return NULL;
     }
   ret = GNUNET_malloc (sizeof (struct GNUNET_SERVER_Handle));
-  if (0 != PIPE (ret->shutpipe))
+  ret->shutpipe = GNUNET_malloc (sizeof (struct GNUNET_DISK_FileDescriptor *[2]));
+  if ((ret->shutpipe = GNUNET_DISK_pipe (GNUNET_NO)) == NULL)
     {
-      GNUNET_break (0 == CLOSE (lsock));
+      GNUNET_break (0 == GNUNET_NETWORK_socket_close (lsock));
+      GNUNET_free (ret->shutpipe);
       GNUNET_free (ret);
       return NULL;
     }
@@ -475,19 +478,19 @@ GNUNET_SERVER_create (struct GNUNET_SCHEDULER_Handle *sched,
   ret->access = access;
   ret->access_cls = access_cls;
   ret->require_found = require_found;
-  if (lsock >= 0)
+  if (lsock != NULL)
     {
-      FD_ZERO (&r);
-      FD_SET (ret->listen_socket, &r);
-      FD_SET (ret->shutpipe[0], &r);
+      r = GNUNET_NETWORK_fdset_create ();
+      GNUNET_NETWORK_fdset_set (r, ret->listen_socket);
+      GNUNET_NETWORK_fdset_handle_set (r, GNUNET_DISK_pipe_handle (ret->shutpipe, 0));
       GNUNET_SCHEDULER_add_select (sched,
                                    GNUNET_YES,
                                    GNUNET_SCHEDULER_PRIORITY_HIGH,
                                    GNUNET_SCHEDULER_NO_TASK,
                                    GNUNET_TIME_UNIT_FOREVER_REL,
-                                   GNUNET_MAX (ret->listen_socket,
-                                               ret->shutpipe[0]) + 1, &r,
+                                   r,
                                    NULL, &process_listen_socket, ret);
+      GNUNET_NETWORK_fdset_destroy (r);
     }
   return ret;
 }
@@ -503,10 +506,10 @@ GNUNET_SERVER_destroy (struct GNUNET_SERVER_Handle *s)
 
   GNUNET_assert (s->do_shutdown == GNUNET_NO);
   s->do_shutdown = GNUNET_YES;
-  if (s->listen_socket == -1)
+  if (s->listen_socket == NULL)
     destroy_server (s);
   else
-    GNUNET_break (1 == WRITE (s->shutpipe[1], &c, 1));
+    GNUNET_break (1 == GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (s->shutpipe, 1), &c, 1));
 }
 
 
index dc51e1433d5f59da77651cf0bbd1e5e789d1d627..bffb892b17299afd9a70d888fb426a6d830feaab 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "platform.h"
 #include "gnunet_common.h"
-#include "gnunet_network_lib.h"
+#include "gnunet_connection_lib.h"
 #include "gnunet_scheduler_lib.h"
 #include "gnunet_server_lib.h"
 #include "gnunet_time_lib.h"
index a976fab781ff623cb27fc3d3135e444d0031cee6..782c70fe9ee58c3fa3f7b70896615f1a7d33c0f6 100644 (file)
@@ -813,9 +813,11 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
 
   if (!disablev6)
     {
+      struct GNUNET_NETWORK_Descriptor *desc;
+
       /* probe IPv6 support */
-      ret = SOCKET (PF_INET6, SOCK_STREAM, 0);
-      if (ret == -1)
+      desc = GNUNET_NETWORK_socket_socket (PF_INET6, SOCK_STREAM, 0);
+      if (NULL == desc)
         {
           if ((errno == ENOBUFS) ||
               (errno == ENOMEM) || (errno == ENFILE) || (errno == EACCES))
@@ -823,18 +825,18 @@ setup_service (struct GNUNET_SERVICE_Context *sctx)
               GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
               return GNUNET_SYSERR;
             }
-          ret = SOCKET (PF_INET, SOCK_STREAM, 0);
-          if (ret != -1)
+          desc = GNUNET_NETWORK_socket_socket (PF_INET, SOCK_STREAM, 0);
+          if (NULL == desc)
             {
               GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                           _
                           ("Disabling IPv6 support for service `%s', failed to create IPv6 socket: %s\n"),
-                          sctx->serviceName, strerror (errno));
+                          sctx->serviceName, STRERROR (errno));
               disablev6 = GNUNET_YES;
             }
         }
-      if (ret != -1)
-        GNUNET_break (0 == CLOSE (ret));
+      if (NULL != desc)
+        GNUNET_break (0 == GNUNET_NETWORK_socket_close (desc));
     }
 
 
diff --git a/src/util/sock.c b/src/util/sock.c
new file mode 100644 (file)
index 0000000..33b6df1
--- /dev/null
@@ -0,0 +1,678 @@
+/*\r
+     This file is part of GNUnet.\r
+     (C) 2009 Christian Grothoff (and other contributing authors)\r
+\r
+     GNUnet is free software; you can redistribute it and/or modify\r
+     it under the terms of the GNU General Public License as published\r
+     by the Free Software Foundation; either version 2, or (at your\r
+     option) any later version.\r
+\r
+     GNUnet is distributed in the hope that it will be useful, but\r
+     WITHOUT ANY WARRANTY; without even the implied warranty of\r
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+     General Public License for more details.\r
+\r
+     You should have received a copy of the GNU General Public License\r
+     along with GNUnet; see the file COPYING.  If not, write to the\r
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,\r
+     Boston, MA 02111-1307, USA.\r
+*/\r
+\r
+/**\r
+ * @file util/sock.c\r
+ * @brief basic, low-level networking interface\r
+ * @author Nils Durner\r
+ */\r
+\r
+#include "platform.h"\r
+#include "gnunet_disk_lib.h"\r
+#include "disk.h"\r
+#include "gnunet_container_lib.h"\r
+\r
+#define DEBUG_SOCK GNUNET_NO\r
+\r
+struct GNUNET_NETWORK_Descriptor\r
+{\r
+  int fd;\r
+};\r
+\r
+struct GNUNET_NETWORK_FDSet\r
+{\r
+  /* socket descriptors */\r
+  int nsds;\r
+  fd_set sds;\r
+#ifdef WINDOWS\r
+  /* handles */\r
+  struct GNUNET_CONTAINER_Vector *handles;\r
+#endif\r
+};\r
+\r
+#ifndef FD_COPY\r
+#define FD_COPY(s, d) (memcpy ((d), (s), sizeof (fd_set)))\r
+#endif\r
+\r
+struct GNUNET_NETWORK_Descriptor *\r
+GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Descriptor *desc,\r
+                              struct sockaddr *address,\r
+                              socklen_t * address_len)\r
+{\r
+  struct GNUNET_NETWORK_Descriptor *ret;\r
+\r
+  ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Descriptor));\r
+  ret->fd = accept (desc->fd, address, address_len);\r
+#ifdef MINGW\r
+  if (INVALID_SOCKET == ret->fd)\r
+    SetErrnoFromWinsockError (WSAGetLastError ());\r
+#endif\r
+  return ret;\r
+}\r
+\r
+int\r
+GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Descriptor *desc,\r
+                            const struct sockaddr *address,\r
+                            socklen_t address_len)\r
+{\r
+  int ret;\r
+\r
+  ret = bind (desc->fd, address, address_len);\r
+#ifdef MINGW\r
+  if (SOCKET_ERROR == ret)\r
+    SetErrnoFromWinsockError (WSAGetLastError ());\r
+#endif\r
+  return ret;\r
+}\r
+\r
+/**\r
+ * Set if a socket should use blocking or non-blocking IO.\r
+ *\r
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error\r
+ */\r
+int\r
+GNUNET_NETWORK_socket_set_blocking (struct GNUNET_NETWORK_Descriptor *fd,\r
+                                    int doBlock)\r
+{\r
+#if MINGW\r
+  u_long mode;\r
+  mode = !doBlock;\r
+  if (ioctlsocket (fd->fd, FIONBIO, &mode) == SOCKET_ERROR)\r
+    {\r
+      SetErrnoFromWinsockError (WSAGetLastError ());\r
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "ioctlsocket");\r
+      return GNUNET_SYSERR;\r
+    }\r
+  return GNUNET_OK;\r
+\r
+#else\r
+  /* not MINGW */\r
+  int flags = fcntl (fd->fd, F_GETFL);\r
+  if (flags == -1)\r
+    {\r
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "fcntl");\r
+      return GNUNET_SYSERR;\r
+    }\r
+  if (doBlock)\r
+    flags &= ~O_NONBLOCK;\r
+  else\r
+    flags |= O_NONBLOCK;\r
+  if (0 != fcntl (fd->fd, F_SETFL, flags))\r
+    {\r
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "fcntl");\r
+      return GNUNET_SYSERR;\r
+    }\r
+  return GNUNET_OK;\r
+#endif\r
+}\r
+\r
+int\r
+GNUNET_NETWORK_socket_close (struct GNUNET_NETWORK_Descriptor *desc)\r
+{\r
+  int ret;\r
+#ifdef MINGW\r
+  ret = closesocket (desc->fd);\r
+  if (SOCKET_ERROR != ret)\r
+    GNUNET_free (desc);\r
+  else\r
+    SetErrnoFromWinsockError (WSAGetLastError ());\r
+#else\r
+  ret = close (desc->fd);\r
+  if (-1 == ret)\r
+    {\r
+      GNUNET_free (desc);\r
+    }\r
+#endif\r
+\r
+  return ret;\r
+}\r
+\r
+int\r
+GNUNET_NETWORK_socket_connect (const struct GNUNET_NETWORK_Descriptor *desc,\r
+                               const struct sockaddr *address,\r
+                               socklen_t address_len)\r
+{\r
+  int ret;\r
+\r
+  ret = connect (desc->fd, address, address_len);\r
+#ifdef MINGW\r
+  if (SOCKET_ERROR == ret)\r
+    SetErrnoFromWinsockError (WSAGetLastError ());\r
+#endif\r
+  return ret;\r
+}\r
+\r
+int\r
+GNUNET_NETWORK_socket_getsockopt (const struct GNUNET_NETWORK_Descriptor *desc,\r
+                                  int level, int optname, void *optval,\r
+                                  socklen_t * optlen)\r
+{\r
+  int ret;\r
+\r
+  ret = getsockopt (desc->fd, level, optname, optval, optlen);\r
+#ifdef MINGW\r
+  if (ret == 0 && level == SOL_SOCKET && optname == SO_ERROR)\r
+    *((int *) optval) = GetErrnoFromWinsockError (*((int *) optval));\r
+  else if (SOCKET_ERROR == ret)\r
+    SetErrnoFromWinsockError (WSAGetLastError ());\r
+#endif\r
+  return ret;\r
+}\r
+\r
+int\r
+GNUNET_NETWORK_socket_listen (const struct GNUNET_NETWORK_Descriptor *desc,\r
+                              int backlog)\r
+{\r
+  int ret;\r
+\r
+  ret = listen (desc->fd, backlog);\r
+#ifdef MINGW\r
+  if (SOCKET_ERROR == ret)\r
+    SetErrnoFromWinsockError (WSAGetLastError ());\r
+#endif\r
+\r
+  return ret;\r
+}\r
+\r
+ssize_t\r
+GNUNET_NETWORK_socket_recv (const struct GNUNET_NETWORK_Descriptor * desc,\r
+                            void *buffer, size_t length, int flags)\r
+{\r
+  int ret;\r
+\r
+  ret = recv (desc->fd, buffer, length, flags);\r
+#ifdef MINGW\r
+  if (SOCKET_ERROR == ret)\r
+    SetErrnoFromWinsockError (WSAGetLastError ());\r
+#endif\r
+\r
+  return ret;\r
+}\r
+\r
+ssize_t\r
+GNUNET_NETWORK_socket_send (const struct GNUNET_NETWORK_Descriptor * desc,\r
+                            const void *buffer, size_t length, int flags)\r
+{\r
+  int ret;\r
+\r
+  ret = send (desc->fd, buffer, length, flags);\r
+#ifdef MINGW\r
+  if (SOCKET_ERROR == ret)\r
+    SetErrnoFromWinsockError (WSAGetLastError ());\r
+#endif\r
+\r
+  return ret;\r
+}\r
+\r
+ssize_t\r
+GNUNET_NETWORK_socket_sendto (const struct GNUNET_NETWORK_Descriptor * desc,\r
+                              const void *message, size_t length, int flags,\r
+                              const struct sockaddr * dest_addr,\r
+                              socklen_t dest_len)\r
+{\r
+  int ret;\r
+\r
+  ret = sendto (desc->fd, message, length, flags, dest_addr, dest_len);\r
+#ifdef MINGW\r
+  if (SOCKET_ERROR == ret)\r
+    SetErrnoFromWinsockError (WSAGetLastError ());\r
+#endif\r
+\r
+  return ret;\r
+}\r
+\r
+int\r
+GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Descriptor *fd,\r
+                                  int level, int option_name,\r
+                                  const void *option_value,\r
+                                  socklen_t option_len)\r
+{\r
+  int ret;\r
+\r
+  ret = setsockopt (fd->fd, level, option_name, option_value, option_len);\r
+#ifdef MINGW\r
+  if (SOCKET_ERROR == ret)\r
+    SetErrnoFromWinsockError (WSAGetLastError ());\r
+#endif\r
+\r
+  return ret;\r
+}\r
+\r
+struct GNUNET_NETWORK_Descriptor *\r
+GNUNET_NETWORK_socket_socket (int domain, int type, int protocol)\r
+{\r
+  struct GNUNET_NETWORK_Descriptor *ret;\r
+\r
+  ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Descriptor));\r
+  ret->fd = socket (domain, type, protocol);\r
+#ifdef MINGW\r
+  if (INVALID_SOCKET == ret->fd)\r
+    SetErrnoFromWinsockError (WSAGetLastError ());\r
+#endif\r
+\r
+  if (ret->fd < 0)\r
+    {\r
+      GNUNET_free (ret);\r
+      ret = NULL;\r
+    }\r
+\r
+  return ret;\r
+}\r
+\r
+int\r
+GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Descriptor *desc,\r
+                                int how)\r
+{\r
+  int ret;\r
+\r
+  ret = shutdown (desc->fd, how);\r
+#ifdef MINGW\r
+  if (ret != 0)\r
+    SetErrnoFromWinsockError (WSAGetLastError ());\r
+#endif\r
+\r
+  return ret;\r
+}\r
+\r
+int\r
+GNUNET_NETWORK_socket_set_inheritable (const struct GNUNET_NETWORK_Descriptor\r
+                                       *desc)\r
+{\r
+#ifdef MINGW\r
+  errno = ENOSYS;\r
+  return GNUNET_SYSERR;\r
+#else\r
+  return fcntl (desc->fd, F_SETFD,\r
+                fcntl (desc->fd,\r
+                       F_GETFD) | FD_CLOEXEC) ==\r
+    0 ? GNUNET_OK : GNUNET_SYSERR;\r
+#endif\r
+}\r
+\r
+void\r
+GNUNET_NETWORK_fdset_zero (struct GNUNET_NETWORK_FDSet *fds)\r
+{\r
+  FD_ZERO (&fds->sds);\r
+  fds->nsds = 0;\r
+#ifdef MINGW\r
+  if (fds->handles)\r
+    GNUNET_CONTAINER_vector_destroy (fds->handles);\r
+  fds->handles = GNUNET_CONTAINER_vector_create (2);\r
+#endif\r
+}\r
+\r
+void\r
+GNUNET_NETWORK_fdset_set (struct GNUNET_NETWORK_FDSet *fds,\r
+                          const struct GNUNET_NETWORK_Descriptor *desc)\r
+{\r
+  FD_SET (desc->fd, &fds->sds);\r
+\r
+  if (desc->fd + 1 > fds->nsds)\r
+    fds->nsds = desc->fd + 1;\r
+}\r
+\r
+int\r
+GNUNET_NETWORK_fdset_isset (const struct GNUNET_NETWORK_FDSet *fds,\r
+                            const struct GNUNET_NETWORK_Descriptor *desc)\r
+{\r
+  return FD_ISSET (desc->fd, &fds->sds);\r
+}\r
+\r
+void\r
+GNUNET_NETWORK_fdset_add (struct GNUNET_NETWORK_FDSet *dst,\r
+                          const struct GNUNET_NETWORK_FDSet *src)\r
+{\r
+  int nfds;\r
+\r
+  for (nfds = src->nsds; nfds > 0; nfds--)\r
+    if (FD_ISSET (nfds, &src->sds))\r
+      {\r
+        FD_SET (nfds, &dst->sds);\r
+        if (nfds + 1 > dst->nsds)\r
+          dst->nsds = nfds + 1;\r
+      }\r
+}\r
+\r
+void\r
+GNUNET_NETWORK_fdset_copy (struct GNUNET_NETWORK_FDSet *to,\r
+                           const struct GNUNET_NETWORK_FDSet *from)\r
+{\r
+  FD_COPY (&from->sds, &to->sds);\r
+  to->nsds = from->nsds;\r
+#ifdef MINGW\r
+  void *obj;\r
+\r
+  if (to->handles)\r
+    GNUNET_CONTAINER_vector_destroy (to->handles);\r
+  to->handles = GNUNET_CONTAINER_vector_create (2);\r
+  for (obj = GNUNET_CONTAINER_vector_get_first (from->handles); obj != NULL;\r
+       obj = GNUNET_CONTAINER_vector_get_next (from->handles))\r
+    {\r
+      GNUNET_CONTAINER_vector_insert_last (to->handles, obj);\r
+    }\r
+#endif\r
+}\r
+\r
+void\r
+GNUNET_NETWORK_fdset_copy_native (struct GNUNET_NETWORK_FDSet *to,\r
+                                  const fd_set * from, int nfds)\r
+{\r
+  FD_COPY (from, &to->sds);\r
+  to->nsds = nfds;\r
+}\r
+\r
+void\r
+GNUNET_NETWORK_fdset_handle_set (struct GNUNET_NETWORK_FDSet *fds,\r
+                                 const struct GNUNET_DISK_FileHandle *h)\r
+{\r
+#ifdef MINGW\r
+  HANDLE hw;\r
+\r
+  GNUNET_internal_disk_file_handle (h, &hw, sizeof (HANDLE));\r
+  GNUNET_CONTAINER_vector_insert_last (fds->handles, h);\r
+#else\r
+  int fd;\r
+\r
+  GNUNET_internal_disk_file_handle (h, &fd, sizeof (int));\r
+  FD_SET (fd, &fds->sds);\r
+  if (fd + 1 > fds->nsds)\r
+    fds->nsds = fd + 1;\r
+#endif\r
+}\r
+\r
+int\r
+GNUNET_NETWORK_fdset_handle_isset (const struct GNUNET_NETWORK_FDSet *fds,\r
+                                   const struct GNUNET_DISK_FileHandle *h)\r
+{\r
+#ifdef MINGW\r
+  return GNUNET_CONTAINER_vector_index_of (fds->handles, h->h) !=\r
+    (unsigned int) -1;\r
+#else\r
+  return FD_ISSET (h->fd, &fds->sds);\r
+#endif\r
+}\r
+\r
+int\r
+GNUNET_NETWORK_fdset_overlap (const struct GNUNET_NETWORK_FDSet *fds1,\r
+                              const struct GNUNET_NETWORK_FDSet *fds2)\r
+{\r
+  int nfds;\r
+\r
+  nfds = fds1->nsds;\r
+  if (nfds < fds2->nsds)\r
+    nfds = fds2->nsds;\r
+\r
+  for (; nfds >= 0; nfds--)\r
+    if (FD_ISSET (nfds, &fds1->sds) && FD_ISSET (nfds, &fds2->sds))\r
+      return GNUNET_YES;\r
+\r
+  return GNUNET_NO;\r
+}\r
+\r
+struct GNUNET_NETWORK_FDSet *\r
+GNUNET_NETWORK_fdset_create ()\r
+{\r
+  struct GNUNET_NETWORK_FDSet *fds;\r
+\r
+  fds = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_FDSet));\r
+#ifdef MINGW\r
+  fds->handles = NULL;\r
+#endif\r
+  GNUNET_NETWORK_fdset_zero (fds);\r
+\r
+  return fds;\r
+}\r
+\r
+void\r
+GNUNET_NETWORK_fdset_destroy (struct GNUNET_NETWORK_FDSet *fds)\r
+{\r
+#ifdef MINGW\r
+  GNUNET_CONTAINER_vector_destroy (fds->handles);\r
+#endif\r
+  GNUNET_free (fds);\r
+}\r
+\r
+int\r
+GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,\r
+                              struct GNUNET_NETWORK_FDSet *wfds,\r
+                              struct GNUNET_NETWORK_FDSet *efds,\r
+                              const struct GNUNET_TIME_Relative timeout)\r
+{\r
+  int nfds;\r
+\r
+  nfds = 0;\r
+\r
+  if (rfds)\r
+    nfds = rfds->nsds;\r
+  if (wfds && wfds->nsds > nfds)\r
+    nfds = wfds->nsds;\r
+  if (efds && efds->nsds > nfds)\r
+    nfds = efds->nsds;\r
+\r
+#ifndef MINGW\r
+  struct timeval tv;\r
+\r
+  tv.tv_sec = timeout.value / GNUNET_TIME_UNIT_SECONDS.value;\r
+  tv.tv_usec = (timeout.value - (tv.tv_sec * GNUNET_TIME_UNIT_SECONDS.value))\r
+    / GNUNET_TIME_UNIT_MILLISECONDS.value;\r
+\r
+  return select (nfds + 1, rfds ? &rfds->sds : NULL, wfds ? &wfds->sds : NULL,\r
+      efds ? &efds->sds : NULL, timeout.value\r
+          == GNUNET_TIME_UNIT_FOREVER_REL.value ? NULL : &tv);\r
+#else\r
+  DWORD limit;\r
+  fd_set sock_read, sock_write, sock_except;\r
+  fd_set aread, awrite, aexcept;\r
+  int i;\r
+  struct timeval tvslice;\r
+  int retcode;\r
+  DWORD ms_total;\r
+\r
+#define SAFE_FD_ISSET(fd, set)  (set != NULL && FD_ISSET(fd, set))\r
+\r
+  /* calculate how long we need to wait in milliseconds */\r
+  if (timeout.value == GNUNET_TIME_UNIT_FOREVER_REL.value)\r
+    ms_total = INFINITE;\r
+  else\r
+    ms_total = timeout.value / GNUNET_TIME_UNIT_MILLISECONDS.value;\r
+\r
+  /* select() may be used as a portable way to sleep */\r
+  if (!(rfds || wfds || efds))\r
+    {\r
+      Sleep (ms_total);\r
+\r
+      return 0;\r
+    }\r
+\r
+  if (rfds)\r
+    sock_read = rfds->sds;\r
+  else\r
+    FD_ZERO(&sock_read);\r
+\r
+  if (wfds)\r
+    sock_write = wfds->sds;\r
+  else\r
+    FD_ZERO(&sock_write);\r
+\r
+  if (efds)\r
+    sock_except = efds->sds;\r
+  else\r
+    FD_ZERO(&sock_except);\r
+\r
+  /*\r
+  if (rfds)\r
+    FD_COPY (&rfds->sds, &sock_read);\r
+  else\r
+    FD_ZERO(&sock_read);\r
+\r
+  if (wfds)\r
+    FD_COPY (&wfds->sds, &sock_write);\r
+  else\r
+    FD_ZERO(&sock_write);\r
+\r
+  if (efds)\r
+    FD_COPY (&efds->sds, &sock_except);\r
+  else\r
+    FD_ZERO(&sock_except);\r
+*/\r
+\r
+  /* multiplex between winsock select() and waiting on the handles */\r
+\r
+  FD_ZERO (&aread);\r
+  FD_ZERO (&awrite);\r
+  FD_ZERO (&aexcept);\r
+\r
+  limit = GetTickCount () + ms_total;\r
+  do\r
+    {\r
+      retcode = 0;\r
+\r
+      if (nfds > 0)\r
+        {\r
+          /* overwrite the zero'd sets here; the select call\r
+           * will clear those that are not active */\r
+\r
+          FD_COPY (&sock_read, &aread);\r
+          FD_COPY (&sock_write, &awrite);\r
+          FD_COPY (&sock_except, &aexcept);\r
+\r
+          tvslice.tv_sec = 0;\r
+          tvslice.tv_usec = 100000;\r
+\r
+          if ((retcode =\r
+               select (nfds + 1, &aread, &awrite, &aexcept,\r
+                       &tvslice)) == SOCKET_ERROR)\r
+            {\r
+              SetErrnoFromWinsockError (WSAGetLastError ());\r
+              if (errno == ENOTSOCK)\r
+                errno = EBADF;\r
+\r
+#if DEBUG_SOCK\r
+            GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "select");\r
+#endif\r
+\r
+              goto select_loop_end;\r
+            }\r
+        }\r
+\r
+      /* Poll read pipes */\r
+      if (rfds)\r
+        for (i = GNUNET_CONTAINER_vector_size (rfds->handles) - 1; i >= 0; i--)\r
+          {\r
+            DWORD dwBytes;\r
+\r
+            if (!PeekNamedPipe\r
+                (GNUNET_CONTAINER_vector_get_at (rfds->handles, i), NULL, 0,\r
+                 NULL, &dwBytes, NULL))\r
+              {\r
+                GNUNET_CONTAINER_vector_remove_at (rfds->handles, i);\r
+\r
+                retcode = -1;\r
+                SetErrnoFromWinError (GetLastError ());\r
+#if DEBUG_SOCK\r
+            GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "PeekNamedPipe");\r
+#endif\r
+               goto select_loop_end;\r
+              }\r
+            else if (dwBytes)\r
+              {\r
+                retcode++;\r
+              }\r
+            else\r
+              GNUNET_CONTAINER_vector_remove_at (rfds->handles, i);\r
+          }\r
+\r
+      /* Poll for faulty pipes */\r
+      if (efds)\r
+        for (i = GNUNET_CONTAINER_vector_size (efds->handles); i >= 0; i--)\r
+          {\r
+            DWORD dwBytes;\r
+\r
+            if (PeekNamedPipe\r
+                (GNUNET_CONTAINER_vector_get_at (rfds->handles, i), NULL, 0,\r
+                 NULL, &dwBytes, NULL))\r
+              {\r
+                GNUNET_CONTAINER_vector_remove_at (efds->handles, i);\r
+\r
+                retcode++;\r
+              }\r
+          }\r
+\r
+      /* FIXME */\r
+      if (wfds)\r
+        GNUNET_assert (GNUNET_CONTAINER_vector_size (wfds->handles) == 0);\r
+\r
+      /* Check for closed sockets */\r
+      for (i = 0; i < nfds; i++)\r
+        {\r
+          if (SAFE_FD_ISSET (i, &sock_read))\r
+            {\r
+              struct sockaddr addr;\r
+              int len;\r
+\r
+              if (getpeername (i, &addr, &len) == SOCKET_ERROR)\r
+                {\r
+                  int err, len;\r
+\r
+                  len = sizeof (err);\r
+                  if (getsockopt\r
+                      (i, SOL_SOCKET, SO_ERROR, (char *) &err, &len) == 0\r
+                      && err == WSAENOTCONN)\r
+                    {\r
+                      if (!SAFE_FD_ISSET (i, &aread))\r
+                        {\r
+                          FD_SET (i, &aread);\r
+                          retcode++;\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+\r
+    select_loop_end:;\r
+    }\r
+  while (retcode == 0 && (ms_total == INFINITE || GetTickCount () < limit));\r
+\r
+  if (retcode != -1)\r
+    {\r
+      if (rfds)\r
+        {\r
+          GNUNET_NETWORK_fdset_zero (rfds);\r
+          GNUNET_NETWORK_fdset_copy_native (rfds, &aread, retcode);\r
+        }\r
+\r
+      if (wfds)\r
+        {\r
+          GNUNET_NETWORK_fdset_zero (wfds);\r
+          GNUNET_NETWORK_fdset_copy_native (wfds, &awrite, retcode);\r
+        }\r
+\r
+      if (efds)\r
+        {\r
+          GNUNET_NETWORK_fdset_zero (efds);\r
+          GNUNET_NETWORK_fdset_copy_native (efds, &aexcept, retcode);\r
+        }\r
+    }\r
+\r
+  return retcode;\r
+#endif\r
+}\r
+\r
+/* end of io.c */\r
index cb0656921d43caa65487cb60a2706c2a987161f4..6f09c4fcecea3deaa6d6b1139054fefce801cced 100644 (file)
@@ -23,7 +23,7 @@
  */
 #include "platform.h"
 #include "gnunet_common.h"
-#include "gnunet_network_lib.h"
+#include "gnunet_connection_lib.h"
 #include "gnunet_scheduler_lib.h"
 #include "gnunet_time_lib.h"
 
@@ -49,24 +49,24 @@ static int ls;
  *
  * @return -1 on error, otherwise the listen socket
  */
-static int
+static struct GNUNET_NETWORK_Descriptor *
 open_listen_socket ()
 {
   const static int on = 1;
   struct sockaddr_in sa;
-  int fd;
+  struct GNUNET_NETWORK_Descriptor *desc;
 
   memset (&sa, 0, sizeof (sa));
   sa.sin_port = htons (PORT);
   sa.sin_family = AF_INET;
-  fd = SOCKET (AF_INET, SOCK_STREAM, 0);
-  GNUNET_assert (fd >= 0);
-  if (SETSOCKOPT (fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
+  desc = GNUNET_NETWORK_socket_socket (AF_INET, SOCK_STREAM, 0);
+  GNUNET_assert (desc != NULL);
+  if (GNUNET_NETWORK_socket_setsockopt (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                 "setsockopt");
-  GNUNET_assert (BIND (fd, &sa, sizeof (sa)) >= 0);
-  LISTEN (fd, 5);
-  return fd;
+  GNUNET_assert (GNUNET_NETWORK_socket_bind (desc, &sa, sizeof (sa)) >= 0);
+  GNUNET_NETWORK_socket_listen (desc, 5);
+  return desc;
 }
 
 static void
@@ -166,7 +166,7 @@ task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 #if VERBOSE
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test prepares to accept\n");
 #endif
-  GNUNET_SCHEDULER_add_read (tc->sched,
+  GNUNET_SCHEDULER_add_read_net (tc->sched,
                              GNUNET_NO,
                              GNUNET_SCHEDULER_PRIORITY_HIGH,
                              GNUNET_SCHEDULER_NO_TASK,
index aeb1876343380933d867c4130a2476b47addc0d3..a2682a7333f108fc1208976bc25619515073e942 100644 (file)
@@ -23,7 +23,7 @@
  */
 #include "platform.h"
 #include "gnunet_common.h"
-#include "gnunet_network_lib.h"
+#include "gnunet_connection_lib.h"
 #include "gnunet_scheduler_lib.h"
 #include "gnunet_time_lib.h"
 
@@ -40,32 +40,32 @@ static struct GNUNET_NETWORK_ConnectionHandle *lsock;
 
 static size_t sofar;
 
-static int ls;
+static struct GNUNET_NETWORK_Descriptor *ls;
 
 
 
 /**
  * Create and initialize a listen socket for the server.
  *
- * @return -1 on error, otherwise the listen socket
+ * @return NULL on error, otherwise the listen socket
  */
-static int
+static struct GNUNET_NETWORK_Descriptor *
 open_listen_socket ()
 {
   const static int on = 1;
   struct sockaddr_in sa;
-  int fd;
+  struct GNUNET_NETWORK_Descriptor *desc;
 
   memset (&sa, 0, sizeof (sa));
   sa.sin_port = htons (PORT);
-  fd = SOCKET (AF_INET, SOCK_STREAM, 0);
-  GNUNET_assert (fd >= 0);
-  if (SETSOCKOPT (fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
+  desc = GNUNET_NETWORK_socket_socket (AF_INET, SOCK_STREAM, 0);
+  GNUNET_assert (desc != 0);
+  if (GNUNET_NETWORK_socket_setsockopt (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                 "setsockopt");
-  GNUNET_assert (BIND (fd, &sa, sizeof (sa)) >= 0);
-  LISTEN (fd, 5);
-  return fd;
+  GNUNET_assert (GNUNET_NETWORK_socket_bind (desc, &sa, sizeof (sa)) >= 0);
+  GNUNET_NETWORK_socket_listen (desc, 5);
+  return desc;
 }
 
 
@@ -156,7 +156,7 @@ task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
                                                        GNUNET_TIME_UNIT_SECONDS,
                                                        &make_hello, NULL));
   GNUNET_NETWORK_connection_destroy (csock);
-  GNUNET_SCHEDULER_add_read (tc->sched,
+  GNUNET_SCHEDULER_add_read_net (tc->sched,
                              GNUNET_NO,
                              GNUNET_SCHEDULER_PRIORITY_HIGH,
                              GNUNET_SCHEDULER_NO_TASK,
index 51d8350afba951b5c5cdef59ad9f4d55bf5c022a..1a3cb4866066424c7c73a6b50e615cb70d139a8c 100644 (file)
@@ -23,7 +23,7 @@
  */
 #include "platform.h"
 #include "gnunet_common.h"
-#include "gnunet_network_lib.h"
+#include "gnunet_connection_lib.h"
 #include "gnunet_scheduler_lib.h"
 #include "gnunet_time_lib.h"
 
@@ -38,7 +38,7 @@ static struct GNUNET_NETWORK_ConnectionHandle *asock;
 
 static struct GNUNET_NETWORK_ConnectionHandle *lsock;
 
-static int ls;
+static struct GNUNET_NETWORK_Descriptor *ls;
 
 static GNUNET_SCHEDULER_TaskIdentifier receive_task;
 
@@ -48,25 +48,25 @@ static GNUNET_SCHEDULER_TaskIdentifier receive_task;
 /**
  * Create and initialize a listen socket for the server.
  *
- * @return -1 on error, otherwise the listen socket
+ * @return NULL on error, otherwise the listen socket
  */
-static int
+static struct GNUNET_NETWORK_Descriptor *
 open_listen_socket ()
 {
   const static int on = 1;
   struct sockaddr_in sa;
-  int fd;
+  struct GNUNET_NETWORK_Descriptor *desc;
 
   memset (&sa, 0, sizeof (sa));
   sa.sin_port = htons (PORT);
-  fd = SOCKET (AF_INET, SOCK_STREAM, 0);
-  GNUNET_assert (fd >= 0);
-  if (SETSOCKOPT (fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
+  desc = GNUNET_NETWORK_socket_socket (AF_INET, SOCK_STREAM, 0);
+  GNUNET_assert (desc != NULL);
+  if (GNUNET_NETWORK_socket_setsockopt (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                 "setsockopt");
-  GNUNET_assert (BIND (fd, &sa, sizeof (sa)) >= 0);
-  LISTEN (fd, 5);
-  return fd;
+  GNUNET_assert (GNUNET_NETWORK_socket_bind (desc, &sa, sizeof (sa)) >= 0);
+  GNUNET_NETWORK_socket_listen (desc, 5);
+  return desc;
 }
 
 
@@ -120,7 +120,7 @@ task_receive_cancel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   csock = GNUNET_NETWORK_connection_create_from_connect (tc->sched,
                                                      "localhost", PORT, 1024);
   GNUNET_assert (csock != NULL);
-  GNUNET_SCHEDULER_add_read (tc->sched,
+  GNUNET_SCHEDULER_add_read_net (tc->sched,
                              GNUNET_NO,
                              GNUNET_SCHEDULER_PRIORITY_HIGH,
                              GNUNET_SCHEDULER_NO_TASK,
index 1d89108429329c282feac73cb84ab243673ea32e..442775463c5823e452c7dd3cfc633abe2543d76d 100644 (file)
@@ -23,7 +23,7 @@
  */
 #include "platform.h"
 #include "gnunet_common.h"
-#include "gnunet_network_lib.h"
+#include "gnunet_connection_lib.h"
 #include "gnunet_scheduler_lib.h"
 #include "gnunet_time_lib.h"
 
@@ -35,31 +35,31 @@ static struct GNUNET_NETWORK_ConnectionHandle *csock;
 
 static struct GNUNET_NETWORK_ConnectionHandle *lsock;
 
-static int ls;
+static struct GNUNET_NETWORK_Descriptor *ls;
 
 
 /**
  * Create and initialize a listen socket for the server.
  *
- * @return -1 on error, otherwise the listen socket
+ * @return NULL on error, otherwise the listen socket
  */
-static int
+static struct GNUNET_NETWORK_Descriptor *
 open_listen_socket ()
 {
   const static int on = 1;
   struct sockaddr_in sa;
-  int fd;
+  struct GNUNET_NETWORK_Descriptor *desc;
 
   memset (&sa, 0, sizeof (sa));
   sa.sin_port = htons (PORT);
-  fd = SOCKET (AF_INET, SOCK_STREAM, 0);
-  GNUNET_assert (fd >= 0);
-  if (SETSOCKOPT (fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
+  desc = GNUNET_NETWORK_socket_socket (AF_INET, SOCK_STREAM, 0);
+  GNUNET_assert (desc != NULL);
+  if (GNUNET_NETWORK_socket_setsockopt (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                 "setsockopt");
-  GNUNET_assert (BIND (fd, &sa, sizeof (sa)) >= 0);
-  LISTEN (fd, 5);
-  return fd;
+  GNUNET_assert (GNUNET_NETWORK_socket_bind (desc, &sa, sizeof (sa)) >= 0);
+  GNUNET_NETWORK_socket_listen (desc, 5);
+  return desc;
 }
 
 
index 172a6991df5fa3372dac55991e5991f23ec22923..902edd2fa411fb15f38440718882080dc42adc93 100644 (file)
@@ -23,7 +23,7 @@
  */
 #include "platform.h"
 #include "gnunet_common.h"
-#include "gnunet_network_lib.h"
+#include "gnunet_connection_lib.h"
 #include "gnunet_scheduler_lib.h"
 #include "gnunet_time_lib.h"
 
index 7a67000a852bfd0398a8e895561947cb18687ce5..c46fecd2247157816752e588f8508a36b77d09df 100644 (file)
@@ -23,7 +23,7 @@
  */
 #include "platform.h"
 #include "gnunet_common.h"
-#include "gnunet_network_lib.h"
+#include "gnunet_connection_lib.h"
 #include "gnunet_scheduler_lib.h"
 #include "gnunet_time_lib.h"
 
index d5a93ed7da4f5be4f002bddeedf7d6db51549cc8..34def7b1eeda898d771b6a866bd410fc94eec8c5 100644 (file)
@@ -25,6 +25,7 @@
 #include "gnunet_common.h"
 #include "gnunet_scheduler_lib.h"
 #include "gnunet_time_lib.h"
+#include "gnunet_disk_lib.h"
 
 #define VERBOSE GNUNET_NO
 
@@ -55,7 +56,8 @@ task4 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   (*ok) = 5;
 }
 
-static int fds[2];
+struct GNUNET_DISK_PipeHandle *p;
+static struct GNUNET_DISK_FileHandle *fds[2];
 
 
 static void
@@ -64,10 +66,9 @@ taskWrt (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   static char c;
   int *ok = cls;
   GNUNET_assert (6 == *ok);
-  GNUNET_assert (FD_ISSET (fds[1], tc->write_ready));
+  GNUNET_assert (GNUNET_NETWORK_fdset_handle_isset (tc->write_ready, fds[1]));
   (*ok) = 7;
-  GNUNET_assert (1 == WRITE (fds[1], &c, 1));
-  GNUNET_break (0 == CLOSE (fds[1]));
+  GNUNET_assert (1 == GNUNET_DISK_file_write (fds[1], &c, 1));
 }
 
 
@@ -92,9 +93,8 @@ taskRd (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   static char c;
   int *ok = cls;
   GNUNET_assert (7 == *ok);
-  GNUNET_assert (FD_ISSET (fds[0], tc->read_ready));
-  GNUNET_assert (1 == READ (fds[0], &c, 1));
-  GNUNET_break (0 == CLOSE (fds[0]));
+  GNUNET_assert (GNUNET_NETWORK_fdset_handle_isset (tc->read_ready, fds[0]));
+  GNUNET_assert (1 == GNUNET_DISK_file_read (fds[0], &c, 1));
   (*ok) = 8;
   GNUNET_SCHEDULER_add_after (tc->sched,
                               GNUNET_NO,
@@ -114,14 +114,17 @@ task5 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   int *ok = cls;
   GNUNET_assert (5 == *ok);
   (*ok) = 6;
-  GNUNET_assert (0 == PIPE (fds));
-  GNUNET_SCHEDULER_add_read (tc->sched,
+  p = GNUNET_DISK_pipe (GNUNET_NO);
+  GNUNET_assert (NULL != p);
+  fds[0] = GNUNET_DISK_pipe_handle (p, 0);
+  fds[1] = GNUNET_DISK_pipe_handle (p, 1);
+  GNUNET_SCHEDULER_add_read_file (tc->sched,
                              GNUNET_NO,
                              GNUNET_SCHEDULER_PRIORITY_DEFAULT,
                              GNUNET_SCHEDULER_NO_TASK,
                              GNUNET_TIME_UNIT_FOREVER_REL,
                              fds[0], &taskRd, cls);
-  GNUNET_SCHEDULER_add_write (tc->sched,
+  GNUNET_SCHEDULER_add_write_file (tc->sched,
                               GNUNET_NO,
                               GNUNET_SCHEDULER_PRIORITY_DEFAULT,
                               GNUNET_SCHEDULER_NO_TASK,
@@ -256,6 +259,7 @@ main (int argc, char *argv[])
   ret += check ();
   ret += checkSignal ();
   ret += checkCancel ();
+  GNUNET_DISK_pipe_close (p);
 
   return ret;
 }
index e8e3f8741d64901b427f561243a5c9061a4c7219..8e351deb3c8cfac9ab891adc5e1597f9ae111b29 100644 (file)
@@ -300,7 +300,7 @@ int
 main (int argc, char *argv[])
 {
   int ret = 0;
-  int s;
+  struct GNUNET_NETWORK_Descriptor *s;
 
   GNUNET_log_setup ("test-service",
 #if VERBOSE
@@ -311,8 +311,8 @@ main (int argc, char *argv[])
                     NULL);
   ret += check ();
   ret += check ();
-  s = SOCKET (PF_INET6, SOCK_STREAM, 0);
-  if (s == -1)
+  s = GNUNET_NETWORK_socket_socket (PF_INET6, SOCK_STREAM, 0);
+  if (NULL == s)
     {
       if ((errno == ENOBUFS) ||
           (errno == ENOMEM) || (errno == ENFILE) || (errno == EACCES))
@@ -326,7 +326,7 @@ main (int argc, char *argv[])
     }
   else
     {
-      GNUNET_break (0 == CLOSE (s));
+      GNUNET_break (0 == GNUNET_NETWORK_socket_close (s));
       ret += check6 ();
       ret += check6d ();        /* with daemonization */
     }
index f3e4bd98cbc8f0634aeb19036e3fd86850f52197..8e71744d0492382affe5cb975790d6eefd4ef22d 100644 (file)
@@ -30,7 +30,7 @@
 #include "winproc.h"\r
 #include "platform.h"\r
 #include "gnunet_common.h"\r
-#include "gnunet_network_lib.h"\r
+#include "gnunet_connection_lib.h"\r
 \r
 #include <list>\r
 using namespace std;\r