/*
This file is part of GNUnet.
- (C) 2009, 2012 Christian Grothoff (and other contributing authors)
+ (C) 2009-2013 Christian Grothoff (and other contributing authors)
GNUnet is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 2, or (at your
+ by the Free Software Foundation; either version 3, or (at your
option) any later version.
GNUnet is distributed in the hope that it will be useful, but
#else
BOOL b;
SetLastError (0);
- b = SetHandleInformation (h->fd, HANDLE_FLAG_INHERIT, 0);
+ b = SetHandleInformation ((HANDLE) h->fd, HANDLE_FLAG_INHERIT, 0);
if (!b)
{
SetErrnoFromWinsockError (WSAGetLastError ());
int abs_value = 1;
if (0 !=
- setsockopt (h->fd, SOL_SOCKET, SO_NOSIGPIPE, &abs_value,
+ setsockopt (h->fd, SOL_SOCKET, SO_NOSIGPIPE,
+ (const void *) &abs_value,
sizeof (abs_value)))
LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
}
const char *abs_value = "1";
if (0 !=
- setsockopt (h->fd, IPPROTO_TCP, TCP_NODELAY, abs_value,
+ setsockopt (h->fd, IPPROTO_TCP, TCP_NODELAY,
+ (const void *) abs_value,
sizeof (abs_value)))
LOG_STRERROR (GNUNET_ERROR_TYPE_WARNING, "setsockopt");
#endif
/**
* Bind to a connected socket
- * @param desc socket
+ *
+ * @param desc socket to bind
* @param address address to be bound
* @param address_len length of address
+ * @param flags flags affecting bind behaviour
* @return GNUNET_OK on success, GNUNET_SYSERR otherwise
*/
int
GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
const struct sockaddr *address,
- socklen_t address_len)
+ socklen_t address_len,
+ int flags)
{
int ret;
#ifdef IPV6_V6ONLY
#ifdef IPPROTO_IPV6
- const int on = 1;
+ {
+ const int on = 1;
- if (desc->af == AF_INET6)
- if (0 != setsockopt (desc->fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on)))
- LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "setsockopt");
+ if (desc->af == AF_INET6)
+ if (setsockopt (desc->fd, IPPROTO_IPV6, IPV6_V6ONLY,
+ (const void *) &on,
+ sizeof (on)))
+ LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "setsockopt");
+ }
#endif
#endif
#ifndef WINDOWS
- /* This is required, and required here, but only on UNIX */
- if (0 != setsockopt (desc->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)))
- LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "setsockopt");
+ {
+ const int on = 1;
+
+ /* This is required, and required here, but only on UNIX */
+ if (0 != setsockopt (desc->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)))
+ LOG_STRERROR (GNUNET_ERROR_TYPE_DEBUG, "setsockopt");
+ }
#endif
#ifndef LINUX
#ifndef MINGW
- if (address->sa_family == AF_UNIX)
+ if (address->sa_family == AF_UNIX && (flags & GNUNET_BIND_EXCLUSIVE) == 0)
{
const struct sockaddr_un *un = (const struct sockaddr_un *) address;
_selector (LPVOID p)
{
struct _select_params *sp = p;
- int i;
+
while (1)
{
WaitForSingleObject (sp->standby, INFINITE);
}
if ((nfds == 0) &&
- (timeout.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
+ (timeout.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
#ifdef MINGW
&& handles == 0
#endif
"select");
}
#ifndef MINGW
- tv.tv_sec = timeout.rel_value / GNUNET_TIME_UNIT_SECONDS.rel_value;
+ tv.tv_sec = timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us;
tv.tv_usec =
- 1000 * (timeout.rel_value -
- (tv.tv_sec * GNUNET_TIME_UNIT_SECONDS.rel_value));
- return select (nfds, (rfds != NULL) ? &rfds->sds : NULL,
- (wfds != NULL) ? &wfds->sds : NULL,
- (efds != NULL) ? &efds->sds : NULL,
- (timeout.rel_value ==
- GNUNET_TIME_UNIT_FOREVER_REL.rel_value) ? NULL : &tv);
+ (timeout.rel_value_us -
+ (tv.tv_sec * GNUNET_TIME_UNIT_SECONDS.rel_value_us));
+ return select (nfds,
+ (NULL != rfds) ? &rfds->sds : NULL,
+ (NULL != wfds) ? &wfds->sds : NULL,
+ (NULL != efds) ? &efds->sds : NULL,
+ (timeout.rel_value_us ==
+ GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us) ? NULL : &tv);
#else
#define SAFE_FD_ISSET(fd, set) (set != NULL && FD_ISSET(fd, set))
/* calculate how long we need to wait in milliseconds */
- if (timeout.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
+ if (timeout.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
ms_total = INFINITE;
else
{
- ms_total = timeout.rel_value / GNUNET_TIME_UNIT_MILLISECONDS.rel_value;
- if (timeout.rel_value / GNUNET_TIME_UNIT_MILLISECONDS.rel_value > 0xFFFFFFFFLL - 1)
+ ms_total = timeout.rel_value_us / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us;
+ if (timeout.rel_value_us / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us > 0xFFFFFFFFLL - 1)
{
GNUNET_break (0);
ms_total = 0xFFFFFFFF - 1;
return 0;
}
- if (select_thread == NULL)
+ if (NULL == select_thread)
{
SOCKET select_listening_socket = -1;
struct sockaddr_in s_in;
p = 1;
res = ioctlsocket (select_wakeup_socket, FIONBIO, &p);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: ioctlsocket() returns %d\n", res);
alen = sizeof (s_in);
s_in.sin_family = AF_INET;
s_in.sin_addr.S_un.S_un_b.s_b3 = 0;
s_in.sin_addr.S_un.S_un_b.s_b4 = 1;
res = bind (select_listening_socket, (const struct sockaddr *) &s_in, sizeof (s_in));
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: bind() returns %d\n", res);
res = getsockname (select_listening_socket, (struct sockaddr *) &s_in, &alen);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: getsockname() returns %d\n", res);
res = listen (select_listening_socket, SOMAXCONN);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: listen() returns %d\n", res);
res = connect (select_wakeup_socket, (const struct sockaddr *) &s_in, sizeof (s_in));
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Select thread initialization: connect() returns %d\n", res);
select_send_socket = accept (select_listening_socket, (struct sockaddr *) &s_in, &alen);
if (rfds && read_handles)
{
struct GNUNET_CONTAINER_SList_Iterator i;
+ int c;
- for (i = GNUNET_CONTAINER_slist_begin (rfds->handles);
+ for (c = 0, i = GNUNET_CONTAINER_slist_begin (rfds->handles);
GNUNET_CONTAINER_slist_end (&i) != GNUNET_YES;
- GNUNET_CONTAINER_slist_next (&i))
+ GNUNET_CONTAINER_slist_next (&i), c++)
{
struct GNUNET_DISK_FileHandle *fh;
bret = PeekNamedPipe (fh->h, NULL, 0, NULL, &waitstatus, NULL);
error = GetLastError ();
LOG (GNUNET_ERROR_TYPE_DEBUG, "Peek at read pipe %d (0x%x) returned %d (%d bytes available) GLE %u\n",
- i, fh->h, bret, waitstatus, error);
+ c, fh->h, bret, waitstatus, error);
if (bret == 0)
{
/* TODO: either add more errors to this condition, or eliminate it
if (nfds > 0)
{
LOG (GNUNET_ERROR_TYPE_DEBUG,
- "Adding the socket event to the array as %d\n", nhandles);
+ "Adding the socket event to the array as %d\n",
+ nhandles);
handle_array[nhandles++] = select_finished_event;
- if (timeout.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value)
+ if (timeout.rel_value_us == GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us)
sp.tv = NULL;
else
{
- select_timeout.tv_sec = timeout.rel_value / GNUNET_TIME_UNIT_SECONDS.rel_value;
- select_timeout.tv_usec = 1000 * (timeout.rel_value -
- (select_timeout.tv_sec * GNUNET_TIME_UNIT_SECONDS.rel_value));
+ select_timeout.tv_sec = timeout.rel_value_us / GNUNET_TIME_UNIT_SECONDS.rel_value_us;
+ select_timeout.tv_usec =(timeout.rel_value_us -
+ (select_timeout.tv_sec * GNUNET_TIME_UNIT_SECONDS.rel_value_us));
sp.tv = &select_timeout;
}
FD_SET (select_wakeup_socket, &aread);