#include "gnunet_disk_lib.h"
#include "gnunet_time_lib.h"
+
/**
- * accept a new connection on a socket
+ * Accept a new connection on a socket. Configure it for non-blocking
+ * IO and mark it as non-inheritable to child processes (set the
+ * close-on-exec flag).
*
* @param desc bound socket
* @param address address of the connecting peer, may be NULL
struct sockaddr *address,
socklen_t *address_len);
-/**
- * Make a non-inheritable to child processes (sets the
- * close-on-exec flag).
- *
- * @param h the socket to make non-inheritable
- * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
- * @warning Not implemented on Windows
- */
-int
-GNUNET_NETWORK_socket_set_inheritable (const struct GNUNET_NETWORK_Handle
- *h);
/**
* Bind to a connected socket
const struct sockaddr *address, socklen_t address_len);
/**
- * Close a socket
+ * Close a socket.
*
* @param desc socket to close
* @return GNUNET_OK on success, GNUNET_SYSERR otherwise
int GNUNET_NETWORK_socket_listen (const struct GNUNET_NETWORK_Handle *desc, int backlog);
/**
- * Read data from a connected socket
+ * Read data from a connected socket (always non-blocking).
*
* @param desc socket
* @param buffer buffer
* @param length length of buffer
- * @param flags type of message reception
* @return number of bytes read
*/
ssize_t GNUNET_NETWORK_socket_recv (const struct GNUNET_NETWORK_Handle *desc, void *buffer,
- size_t length, int flags);
+ size_t length);
/**
* Check if sockets meet certain conditions
struct GNUNET_NETWORK_FDSet *wfds, struct GNUNET_NETWORK_FDSet *efds,
struct GNUNET_TIME_Relative timeout);
-/**
- * Set if a socket should use blocking or non-blocking IO.
- * @param fd socket
- * @param doBlock blocking mode
- * @return GNUNET_OK on success, GNUNET_SYSERR on error
- */
-int GNUNET_NETWORK_socket_set_blocking (struct GNUNET_NETWORK_Handle *fd,
- int doBlock);
+
/**
- * Send data
+ * Send data (always non-blocking).
+ *
* @param desc socket
* @param buffer data to send
* @param length size of the buffer
- * @param flags type of message transmission
* @return number of bytes sent, GNUNET_SYSERR on error
*/
ssize_t GNUNET_NETWORK_socket_send (const struct GNUNET_NETWORK_Handle *desc,
- const void *buffer, size_t length, int flags);
+ const void *buffer, size_t length);
/**
- * Send data
+ * Send data to a particular destination (always non-blocking).
+ * This function only works for UDP sockets.
+ *
* @param desc socket
* @param message data to send
* @param length size of the data
- * @param flags type of message transmission
* @param dest_addr destination address
* @param dest_len length of address
* @return number of bytes sent, GNUNET_SYSERR on error
*/
ssize_t GNUNET_NETWORK_socket_sendto (const struct GNUNET_NETWORK_Handle *desc,
- const void *message, size_t length, int flags,
+ const void *message, size_t length,
const struct sockaddr *dest_addr,
socklen_t dest_len);
*/
int GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Handle *desc, int how);
+
/**
- * Create a new socket
+ * Create a new socket. Configure it for non-blocking IO and
+ * mark it as non-inheritable to child processes (set the
+ * close-on-exec flag).
+ *
* @param domain domain of the socket
* @param type socket type
* @param protocol network protocol
* @return new socket, NULL on error
*/
-struct GNUNET_NETWORK_Handle *GNUNET_NETWORK_socket_socket (int domain, int type, int protocol);
+struct GNUNET_NETWORK_Handle *GNUNET_NETWORK_socket_create (int domain, int type, int protocol);
/**
* Reset FD set (clears all file descriptors).
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "accept");
return NULL;
}
-#ifndef MINGW
- 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_free (ap);
return; /* not supported by us */
}
- ap->sock = GNUNET_NETWORK_socket_socket (ap->addr->sa_family, SOCK_STREAM, 0);
+ ap->sock = GNUNET_NETWORK_socket_create (ap->addr->sa_family, SOCK_STREAM, 0);
if (ap->sock == NULL)
{
GNUNET_free (ap);
return; /* not supported by OS */
}
-#ifndef MINGW
- if (GNUNET_OK != GNUNET_NETWORK_socket_set_inheritable (ap->sock))
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
- "GNUNET_NETWORK_socket_set_inheritable");
-#endif
- if (GNUNET_SYSERR == GNUNET_NETWORK_socket_set_blocking (ap->sock, GNUNET_NO))
- {
- /* we might want to treat this one as fatal... */
- GNUNET_break (0);
- GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ap->sock));
- GNUNET_free (ap);
- return;
- }
#if DEBUG_CONNECTION
GNUNET_log (GNUNET_ERROR_TYPE_INFO,
_("Trying to connect to `%s' (%p)\n"),
struct GNUNET_NETWORK_Handle *s;
struct GNUNET_CONNECTION_Handle *ret;
- s = GNUNET_NETWORK_socket_socket (af_family, SOCK_STREAM, 0);
+ s = GNUNET_NETWORK_socket_create (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
-#endif
- if (GNUNET_SYSERR == GNUNET_NETWORK_socket_set_blocking (s, GNUNET_NO))
- {
- /* we'll treat this one as fatal */
- GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s));
- return NULL;
- }
if ((GNUNET_OK != GNUNET_NETWORK_socket_connect (s, serv_addr, addrlen)) && (errno != EINPROGRESS))
{
/* maybe refused / unsupported address, try next */
}
GNUNET_assert (GNUNET_NETWORK_fdset_isset (tc->read_ready, sh->sock));
RETRY:
- ret = GNUNET_NETWORK_socket_recv (sh->sock, buffer, sh->max,
-#ifndef MINGW
- // FIXME MINGW
- MSG_DONTWAIT
-#else
- 0
-#endif
- );
+ ret = GNUNET_NETWORK_socket_recv (sh->sock, buffer, sh->max);
if (ret == -1)
{
if (errno == EINTR)
RETRY:
ret = GNUNET_NETWORK_socket_send (sock->sock,
&sock->write_buffer[sock->write_buffer_pos],
- have,
-#ifndef MINGW
- // FIXME NILS
- MSG_DONTWAIT | MSG_NOSIGNAL
-#else
- 0
-#endif
- );
+ have);
if (ret == -1)
{
if (errno == EINTR)
#define FD_COPY(s, d) (memcpy ((d), (s), sizeof (fd_set)))\r
#endif\r
\r
+\r
+\r
+/**\r
+ * Set if a socket should use blocking or non-blocking IO.\r
+ * @param fd socket\r
+ * @param doBlock blocking mode\r
+ * @return GNUNET_OK on success, GNUNET_SYSERR on error\r
+ */\r
+static int\r
+socket_set_blocking (struct GNUNET_NETWORK_Handle *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
+\r
+#ifndef MINGW\r
+/**\r
+ * Make a non-inheritable to child processes\r
+ *\r
+ * @param h the socket to make non-inheritable\r
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise\r
+ * @warning Not implemented on Windows\r
+ */\r
+static int\r
+socket_set_inheritable (const struct GNUNET_NETWORK_Handle\r
+ *h)\r
+{\r
+ int i;\r
+\r
+ i = fcntl (h->fd, F_GETFD);\r
+ if (i == (i | FD_CLOEXEC))\r
+ return GNUNET_OK;\r
+ return (fcntl (h->fd, F_SETFD, i | FD_CLOEXEC) == 0)\r
+ ? GNUNET_OK : GNUNET_SYSERR;\r
+}\r
+#endif\r
+\r
+\r
+\r
/**\r
* accept a new connection on a socket\r
*\r
errno = EMFILE;\r
return NULL;\r
}\r
+#endif\r
+ if (GNUNET_SYSERR == socket_set_blocking (ret, GNUNET_NO))\r
+ {\r
+ /* we might want to treat this one as fatal... */\r
+ GNUNET_break (0);\r
+ GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret));\r
+ return NULL; \r
+ }\r
+#ifndef MINGW\r
+ if (GNUNET_OK != socket_set_inheritable (ret))\r
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,\r
+ "socket_set_inheritable");\r
#endif\r
return ret;\r
}\r
return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;\r
}\r
\r
-/**\r
- * Set if a socket should use blocking or non-blocking IO.\r
- * @param fd socket\r
- * @param doBlock blocking mode\r
- * @return GNUNET_OK on success, GNUNET_SYSERR on error\r
- */\r
-int\r
-GNUNET_NETWORK_socket_set_blocking (struct GNUNET_NETWORK_Handle *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
/**\r
* Close a socket\r
\r
/**\r
* Get socket options\r
+ *\r
* @param desc socket\r
* @param level protocol level of the option\r
* @param optname identifier of the option\r
}\r
\r
/**\r
- * Read data from a connected socket\r
+ * Read data from a connected socket (always non-blocking).\r
* @param desc socket\r
* @param buffer buffer\r
* @param length length of buffer\r
- * @param flags type of message reception\r
*/\r
ssize_t\r
GNUNET_NETWORK_socket_recv (const struct GNUNET_NETWORK_Handle * desc,\r
- void *buffer, size_t length, int flags)\r
+ void *buffer, size_t length)\r
{\r
int ret;\r
+ int flags;\r
\r
+ flags = 0;\r
+#ifdef MSG_DONTWAIT\r
+ flags |= MSG_DONTWAIT;\r
+#endif\r
ret = recv (desc->fd, buffer, length, flags);\r
#ifdef MINGW\r
if (SOCKET_ERROR == ret)\r
}\r
\r
/**\r
- * Send data\r
+ * Send data (always non-blocking).\r
+ *\r
* @param desc socket\r
* @param buffer data to send\r
* @param length size of the buffer\r
- * @param flags type of message transmission\r
* @return number of bytes sent, GNUNET_SYSERR on error\r
*/\r
ssize_t\r
GNUNET_NETWORK_socket_send (const struct GNUNET_NETWORK_Handle * desc,\r
- const void *buffer, size_t length, int flags)\r
+ const void *buffer, size_t length)\r
{\r
int ret;\r
+ int flags;\r
\r
+ flags = 0;\r
+#ifdef MSG_DONTWAIT\r
+ flags |= MSG_DONTWAIT;\r
+#endif\r
+#ifdef MSG_NOSIGNAL\r
+ flags |= MSG_NOSIGNAL;\r
+#endif\r
ret = send (desc->fd, buffer, length, flags);\r
#ifdef MINGW\r
if (SOCKET_ERROR == ret)\r
return ret;\r
}\r
\r
+\r
/**\r
- * Send data\r
+ * Send data to a particular destination (always non-blocking).\r
+ * This function only works for UDP sockets.\r
+ *\r
* @param desc socket\r
* @param message data to send\r
* @param length size of the data\r
- * @param flags type of message transmission\r
* @param dest_addr destination address\r
* @param dest_len length of address\r
* @return number of bytes sent, GNUNET_SYSERR on error\r
*/\r
ssize_t\r
GNUNET_NETWORK_socket_sendto (const struct GNUNET_NETWORK_Handle * desc,\r
- const void *message, size_t length, int flags,\r
+ const void *message, size_t length,\r
const struct sockaddr * dest_addr,\r
socklen_t dest_len)\r
{\r
int ret;\r
+ int flags;\r
\r
+ flags = 0;\r
+#ifdef MSG_DONTWAIT\r
+ flags |= MSG_DONTWAIT;\r
+#endif\r
+#ifdef MSG_NOSIGNAL\r
+ flags |= MSG_NOSIGNAL;\r
+#endif\r
ret = sendto (desc->fd, message, length, flags, dest_addr, dest_len);\r
#ifdef MINGW\r
if (SOCKET_ERROR == ret)\r
return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;\r
}\r
\r
+\r
+\r
/**\r
- * Create a new socket\r
+ * Create a new socket. Configure it for non-blocking IO and\r
+ * mark it as non-inheritable to child processes (set the\r
+ * close-on-exec flag).\r
+ *\r
* @param domain domain of the socket\r
* @param type socket type\r
* @param protocol network protocol\r
* @return new socket, NULL on error\r
*/\r
struct GNUNET_NETWORK_Handle *\r
-GNUNET_NETWORK_socket_socket (int domain, int type, int protocol)\r
+GNUNET_NETWORK_socket_create (int domain, int type, int protocol)\r
{\r
struct GNUNET_NETWORK_Handle *ret;\r
\r
return NULL;\r
}\r
#endif\r
+\r
+ if (GNUNET_SYSERR == socket_set_blocking (ret, GNUNET_NO))\r
+ {\r
+ /* we might want to treat this one as fatal... */\r
+ GNUNET_break (0);\r
+ GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret));\r
+ return NULL; \r
+ }\r
+#ifndef MINGW\r
+ if (GNUNET_OK != socket_set_inheritable (ret))\r
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,\r
+ "socket_set_inheritable");\r
+#endif\r
+\r
return ret;\r
}\r
\r
return ret == 0 ? GNUNET_OK : GNUNET_SYSERR;\r
}\r
\r
-/**\r
- * Make a non-inheritable to child processes\r
- *\r
- * @param h the socket to make non-inheritable\r
- * @return GNUNET_OK on success, GNUNET_SYSERR otherwise\r
- * @warning Not implemented on Windows\r
- */\r
-int\r
-GNUNET_NETWORK_socket_set_inheritable (const struct GNUNET_NETWORK_Handle\r
- *h)\r
-{\r
-#ifdef MINGW\r
- errno = ENOSYS;\r
- return GNUNET_SYSERR;\r
-#else\r
- int i;\r
-\r
- i = fcntl (h->fd, F_GETFD);\r
- if (i == (i | FD_CLOEXEC))\r
- return GNUNET_OK;\r
- return (fcntl (h->fd, F_SETFD, i | FD_CLOEXEC) == 0)\r
- ? GNUNET_OK : GNUNET_SYSERR;\r
-#endif\r
-}\r
-\r
\r
/**\r
* Reset FD set\r
GNUNET_break (0);
return NULL;
}
- sock = GNUNET_NETWORK_socket_socket (serverAddr->sa_family, SOCK_STREAM, 0);
+ sock = GNUNET_NETWORK_socket_create (serverAddr->sa_family, SOCK_STREAM, 0);
if (NULL == sock)
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
return NULL;
}
-#ifndef MINGW
- if (GNUNET_OK != GNUNET_NETWORK_socket_set_inheritable (sock))
- GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
- "fcntl");
-#endif
if (GNUNET_NETWORK_socket_setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
"setsockopt");
if (!disablev6)
{
/* probe IPv6 support */
- desc = GNUNET_NETWORK_socket_socket (PF_INET6, SOCK_STREAM, 0);
+ desc = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
if (NULL == desc)
{
if ((errno == ENOBUFS) ||
#endif
sa.sin_port = htons (PORT);
sa.sin_family = AF_INET;
- desc = GNUNET_NETWORK_socket_socket (AF_INET, SOCK_STREAM, 0);
+ desc = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
GNUNET_assert (desc != NULL);
if (GNUNET_NETWORK_socket_setsockopt (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
sa.sin_len = sizeof (sa);
#endif
sa.sin_port = htons (PORT);
- desc = GNUNET_NETWORK_socket_socket (AF_INET, SOCK_STREAM, 0);
+ desc = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
GNUNET_assert (desc != 0);
if (GNUNET_NETWORK_socket_setsockopt (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
sa.sin_len = sizeof (sa);
#endif
sa.sin_port = htons (PORT);
- desc = GNUNET_NETWORK_socket_socket (AF_INET, SOCK_STREAM, 0);
+ desc = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
GNUNET_assert (desc != NULL);
if (GNUNET_NETWORK_socket_setsockopt (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
sa.sin_len = sizeof (sa);
#endif
sa.sin_port = htons (PORT);
- desc = GNUNET_NETWORK_socket_socket (AF_INET, SOCK_STREAM, 0);
+ desc = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
GNUNET_assert (desc != NULL);
if (GNUNET_NETWORK_socket_setsockopt (desc, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) != GNUNET_OK)
GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
NULL);
ret += check ();
ret += check ();
- s = GNUNET_NETWORK_socket_socket (PF_INET6, SOCK_STREAM, 0);
+ s = GNUNET_NETWORK_socket_create (PF_INET6, SOCK_STREAM, 0);
if (NULL == s)
{
if ((errno == ENOBUFS) ||