#ifndef MINGW
int fd;
-#ifndef LINUX
- /**
- * For UNIX domain listen sockets, underlying filename to be removed
- * on close.
- */
- char *filename;
-#endif
-
#else
SOCKET fd;
#endif
+ /**
+ * Address family / domain.
+ */
+ int af;
};
{
/**
- * Maximum number of any socket socket descriptor in the set
+ * Maximum number of any socket socket descriptor in the set (plus one)
*/
int nsds;
socket_set_inheritable (const struct GNUNET_NETWORK_Handle *h)
{
int i;
- i = fcntl (h->fd, F_GETFD);
+
+ i = fcntl (h->fd, F_GETFD);
+ if (i < 0)
+ return GNUNET_SYSERR;
if (i == (i | FD_CLOEXEC))
return GNUNET_OK;
- return (fcntl (h->fd, F_SETFD, i | FD_CLOEXEC) == 0)
- ? GNUNET_OK : GNUNET_SYSERR;
+ i |= FD_CLOEXEC;
+ if (fcntl (h->fd, F_SETFD, i) < 0)
+ return GNUNET_SYSERR;
+ return GNUNET_OK;
}
#endif
static void
socket_set_nodelay (const struct GNUNET_NETWORK_Handle *h)
{
+#ifndef WINDOWS
int value = 1;
- if (0 !=
- setsockopt (h->fd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof (value)))
+ if (0 != setsockopt (h->fd, IPPROTO_TCP, TCP_NODELAY, &value, sizeof (value)))
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
+#else
+ const char * value = "1";
+ if (0 != setsockopt (h->fd, IPPROTO_TCP, TCP_NODELAY, value, sizeof (value)))
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
+#endif
}
struct GNUNET_NETWORK_Handle *ret;
ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle));
+ ret->af = address->sa_family;
+ /* NOTE: if sa_family does not exist on some platform,
+ using AF_UNSPEC should be safe */
ret->fd = accept (desc->fd, address, address_len);
if (ret->fd == INVALID_SOCKET)
{
socklen_t address_len)
{
int ret;
-
+
+#ifdef IPV6_V6ONLY
+#ifdef IPPROTO_IPV6
+ const int on = 1;
+ if (desc->af == AF_INET6)
+ setsockopt (desc->fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on));
+#if 0
+ /* is this needed or desired? or done elsewhere? */
+ setsockopt (desc->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on));
+#endif
+#endif
+#endif
ret = bind (desc->fd, address, address_len);
#ifdef MINGW
if (SOCKET_ERROR == ret)
if ( (ret == 0) && (address->sa_family == AF_UNIX))
{
const struct sockaddr_un *un = (const struct sockaddr_un*) address;
- desc->filename = GNUNET_strdup (un->sun_path);
+ if (0 != unlink (un->sun_path))
+ GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
+ "unlink",
+ un->sun_path);
}
#endif
#endif
SetErrnoFromWinsockError (WSAGetLastError ());
#else
ret = close (desc->fd);
-#ifndef LINUX
- if (NULL != desc->filename)
- {
- if (0 != unlink (desc->filename))
- GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
- "unlink",
- desc->filename);
- GNUNET_free (desc->filename);
- }
-#endif
#endif
GNUNET_free (desc);
return (ret == 0) ? GNUNET_OK : GNUNET_SYSERR;
return NULL; /* invalid FD */
ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle));
ret->fd = fd;
+ ret->af = AF_UNSPEC;
return ret;
#endif
}
*desc)
{
int error;
- int pending;
/* How much is there to be read? */
#ifndef WINDOWS
+ int pending;
error = ioctl (desc->fd, FIONREAD, &pending);
if (error == 0)
#else
+ u_long pending;
error = ioctlsocket (desc->fd, FIONREAD, &pending);
if (error != SOCKET_ERROR)
#endif
{
struct GNUNET_NETWORK_Handle *ret;
ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle));
+ ret->af = domain;
ret->fd = socket (domain, type, protocol);
if (INVALID_SOCKET == ret->fd)
{
}
+/**
+ * Test native fd in a set
+ *
+ * @param to set to test, NULL for empty set
+ * @param nfd native FD to test, or -1 for none
+ * @return GNUNET_YES if FD is set in the set
+ */
+int
+GNUNET_NETWORK_fdset_test_native (const struct GNUNET_NETWORK_FDSet *to,
+ int nfd)
+{
+ if ( (nfd == -1) || (to == NULL) )
+ return GNUNET_NO;
+ return FD_ISSET (nfd, &to->sds) ? GNUNET_YES : GNUNET_NO;
+}
+
+
/**
* Add a file handle to the fd set
* @param fds fd set
GNUNET_NETWORK_fdset_handle_set (struct GNUNET_NETWORK_FDSet *fds,
const struct GNUNET_DISK_FileHandle *h)
{
-
#ifdef MINGW
HANDLE hw;
GNUNET_DISK_internal_file_handle_ (h, &hw, sizeof (HANDLE));
{
HANDLE *h;
- h = GNUNET_CONTAINER_slist_get (it, NULL);
+ h = (HANDLE *) GNUNET_CONTAINER_slist_get ((const struct GNUNET_CONTAINER_SList_Iterator *)it, NULL);
if (GNUNET_CONTAINER_slist_contains
(fds2->handles, h, sizeof (HANDLE)))
{
GNUNET_break (0);
}
#ifndef MINGW
- return select (nfds + 1,
+ return select (nfds,
(rfds != NULL) ? &rfds->sds : NULL,
(wfds != NULL) ? &wfds->sds : NULL,
(efds != NULL) ? &efds->sds : NULL,
while (retcode == 0 && (ms_total == INFINITE || GetTickCount () < limit));
if (retcode != -1)
-
{
if (rfds)
-
{
GNUNET_NETWORK_fdset_zero (rfds);
GNUNET_NETWORK_fdset_copy_native (rfds, &aread, retcode);
GNUNET_CONTAINER_slist_clear (rfds->handles);
GNUNET_CONTAINER_slist_append (rfds->handles, handles_read);
-
}
if (wfds)
-
{
GNUNET_NETWORK_fdset_zero (wfds);
GNUNET_NETWORK_fdset_copy_native (wfds, &awrite, retcode);
GNUNET_CONTAINER_slist_append (wfds->handles, handles_write);
}
if (efds)
-
{
GNUNET_NETWORK_fdset_zero (efds);
GNUNET_NETWORK_fdset_copy_native (efds, &aexcept, retcode);