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)
{
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);
}
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;
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,
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);
}
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 \
#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"
--- /dev/null
+/*\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
/*
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
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).
*/
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.
*/
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.
/**
* @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"
#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 */
}
#endif
-
-/* ifndef GNUNET_NETWORK_LIB_H */
-#endif
-/* end of gnunet_network_lib.h */
+#endif /* GNUNET_NETWORK_LIB_H_ */
#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.
*/
* 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;
};
* 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);
/**
* 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);
/**
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 */
#endif
#include "gnunet_common.h"
-#include "gnunet_network_lib.h"
+#include "gnunet_connection_lib.h"
#include "gnunet_scheduler_lib.h"
#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"
#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"
*/
static unsigned int http_requests_pending;
-static int signal_pipe[2];
+static struct GNUNET_DISK_FileHandle signal_pipe[2];
static char *proxy;
signal_select ()
{
static char c;
- WRITE (signal_pipe[1], &c, sizeof (c));
+ GNUNET_DISK_file_write (signal_pipe[1], &c, sizeof (c));
}
/**
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;
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;
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 |
}
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 |
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);
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)
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);
#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"
#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"
* 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 |
{
available_protocols = VERSION_AVAILABLE_IPV6 | VERSION_AVAILABLE_IPV4;
}
- return s;
+ return desc;
}
/**
struct sockaddr_in6 serverAddrv6;
struct sockaddr *serverAddr;
socklen_t addrlen;
- int sock;
+ GNUNET_NETWORK_Descriptor *desc;
const int on = 1;
unsigned short port;
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 |
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 |
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,
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 |
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;
}
char *full_url;
char *buf;
unsigned int buf_len;
- int sock;
+ struct GNUNET_NETWORK_Descriptor *sock;
} UPnPDiscoveryData;
static GaimUPnPControlInfo control_info = {
}
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;
/* 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';
static struct GNUNET_ThreadHandle *discovery;
-static int discovery_socket;
+static struct GNUNET_NETWORK_Descriptor *discovery_socket;
/**
* Obtain the public/external IP address.
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;
}
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);
}
crypto_random.c \
crypto_rsa.c \
disk.c \
+ disk.h \
getopt.c \
getopt_helpers.c \
network.c \
server_tc.c \
service.c \
signal.c \
+ sock.c \
strings.c \
time.c \
$(WINSRC)
#include "gnunet_disk_lib.h"
#include "gnunet_scheduler_lib.h"
#include "gnunet_strings_lib.h"
+#include "disk.h"
#if LINUX || CYGWIN
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
#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 */
--- /dev/null
+/*\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
#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
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.
*/
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;
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;
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;
}
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;
}
ret->write_buffer_size = maxbuf;
ret->addr = uaddr;
ret->addrlen = addrlen;
- ret->sock = fd;
+ ret->sock = sock;
ret->sched = sched;
return ret;
}
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
static int
try_connect (struct GNUNET_NETWORK_ConnectionHandle *sock)
{
- int s;
+ struct GNUNET_NETWORK_Descriptor *s;
if (sock->addr != NULL)
{
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");
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
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;
}
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
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 */
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,
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;
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,
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
_("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);
{
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;
}
&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)
{
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);
signal_timeout (sh);
return;
}
- if (sh->sock == -1)
+ if (sh->sock == NULL)
{
/* connect failed for good */
#if DEBUG_NETWORK
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
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 */
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,
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,
return;
}
RETRY:
- ret = SEND (sock->sock,
+ ret = GNUNET_NETWORK_socket_send (sock->sock,
&sock->write_buffer[sock->write_buffer_pos],
have,
#ifndef MINGW
#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;
}
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,
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
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,
* 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
* to reflect the set of file descriptors ready
* for operation.
*/
- fd_set write_set;
+ struct GNUNET_NETWORK_FDSet *write_set;
/**
* Unique task identifier.
*/
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?
*/
}
-/**
- * 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
*/
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)))
{
}
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;
}
}
* @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;
}
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;
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 */
*/
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;
}
+/**
+ * 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
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));
}
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;
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);
(!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)
sched.pending = tpos->next;
GNUNET_free (tpos);
}
+ GNUNET_NETWORK_fdset_destroy (rs);
+ GNUNET_NETWORK_fdset_destroy (ws);
}
else
prev->next = t->next;
ret = t->callback_cls;
- GNUNET_free (t);
+ destroy_task (t);
return ret;
}
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);
}
{
return GNUNET_SCHEDULER_add_select (sched, run_on_shutdown, prio,
prerequisite_task, delay,
- 0, NULL, NULL, main, cls);
+ NULL, NULL, main, cls);
}
* 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;
}
* 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;
}
* 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
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;
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);
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 */
#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
/**
* 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.
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;
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,
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)
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;
}
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;
}
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;
}
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));
}
#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"
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))
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));
}
--- /dev/null
+/*\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
*/
#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"
*
* @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
#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,
*/
#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"
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;
}
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,
*/
#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"
static struct GNUNET_NETWORK_ConnectionHandle *lsock;
-static int ls;
+static struct GNUNET_NETWORK_Descriptor *ls;
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;
}
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,
*/
#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"
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;
}
*/
#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"
*/
#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"
#include "gnunet_common.h"
#include "gnunet_scheduler_lib.h"
#include "gnunet_time_lib.h"
+#include "gnunet_disk_lib.h"
#define VERBOSE GNUNET_NO
(*ok) = 5;
}
-static int fds[2];
+struct GNUNET_DISK_PipeHandle *p;
+static struct GNUNET_DISK_FileHandle *fds[2];
static void
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));
}
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,
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,
ret += check ();
ret += checkSignal ();
ret += checkCancel ();
+ GNUNET_DISK_pipe_close (p);
return ret;
}
main (int argc, char *argv[])
{
int ret = 0;
- int s;
+ struct GNUNET_NETWORK_Descriptor *s;
GNUNET_log_setup ("test-service",
#if VERBOSE
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))
}
else
{
- GNUNET_break (0 == CLOSE (s));
+ GNUNET_break (0 == GNUNET_NETWORK_socket_close (s));
ret += check6 ();
ret += check6d (); /* with daemonization */
}
#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