fix
[oweals/gnunet.git] / src / util / network.c
index 2d59b46dd2b331862e4efea39500f201734e5df5..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;
 
@@ -204,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
@@ -260,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)
@@ -320,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
 }
@@ -602,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)
     {
@@ -816,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));
@@ -835,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
@@ -988,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,