fix
[oweals/gnunet.git] / src / util / network.c
index 101e794d07c892827182455620e7d30dec5f2b88..cf74d43add439142e5ec259e10918aef285a786c 100644 (file)
@@ -45,6 +45,10 @@ struct GNUNET_NETWORK_Handle
   SOCKET fd;
 #endif
 
+  /**
+   * Address family / domain.
+   */
+  int af;
 };
 
 
@@ -52,7 +56,7 @@ struct GNUNET_NETWORK_FDSet
 {
 
   /**
-   * Maximum number of any socket socket descriptor in the set
+   * Maximum number of any socket socket descriptor in the set (plus one)
    */
   int nsds;
 
@@ -175,10 +179,15 @@ socket_set_nosigpipe (const struct GNUNET_NETWORK_Handle *h)
 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 
 }
 
 
@@ -199,6 +208,7 @@ GNUNET_NETWORK_socket_accept (const struct GNUNET_NETWORK_Handle *desc,
 
   ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle));
   ret->fd = accept (desc->fd, address, address_len);
+  ret->af = address->sa_family;
   if (ret->fd == INVALID_SOCKET)
     {
 #ifdef MINGW
@@ -255,7 +265,18 @@ GNUNET_NETWORK_socket_bind (struct GNUNET_NETWORK_Handle *desc,
                             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)
@@ -315,6 +336,7 @@ GNUNET_NETWORK_socket_box_native (int fd)
     return NULL; /* invalid FD */
   ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle)); 
   ret->fd = fd;
+  ret->af = AF_UNSPEC;
   return ret;
 #endif
 }
@@ -411,13 +433,14 @@ GNUNET_NETWORK_socket_recvfrom_amount (const struct GNUNET_NETWORK_Handle
                                        *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
@@ -596,6 +619,7 @@ GNUNET_NETWORK_socket_create (int domain, int type, int protocol)
 {
   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)
     {
@@ -810,7 +834,6 @@ void
 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));
@@ -829,6 +852,23 @@ GNUNET_NETWORK_fdset_handle_set (struct GNUNET_NETWORK_FDSet *fds,
 }
 
 
+#if MINGW
+/**
+ * Add a W32 file handle to the fd set
+ * @param fds fd set
+ * @param h the file handle to add
+ */
+void
+GNUNET_NETWORK_fdset_handle_set_native_w32_handle (struct GNUNET_NETWORK_FDSet *fds,
+                                                  HANDLE h)
+{
+  GNUNET_CONTAINER_slist_add (fds->handles,
+                              GNUNET_CONTAINER_SLIST_DISPOSITION_TRANSIENT,
+                              &h, sizeof (HANDLE));
+}
+#endif
+
+
 /**
  * Check if a file handle is part of an fd set
  * @param fds fd set
@@ -876,7 +916,7 @@ GNUNET_NETWORK_fdset_overlap (const struct GNUNET_NETWORK_FDSet *fds1,
       {
         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)))
           {
@@ -982,7 +1022,7 @@ GNUNET_NETWORK_socket_select (struct GNUNET_NETWORK_FDSet *rfds,
       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,