Index: src/arm/gnunet-service-arm_interceptor.c
===================================================================
--- src/arm/gnunet-service-arm_interceptor.c	(revision 13603)
+++ src/arm/gnunet-service-arm_interceptor.c	(working copy)
@@ -187,9 +187,15 @@
    * Have we ever successfully written data to the service?
    */
   int first_write_done;
+
+
+  /**
+   * Service connection attempts
+   */
+  struct ServiceListeningInfo *service_connect_ipv4;
+  struct ServiceListeningInfo *service_connect_ipv6;
 };
 
-
 /**
  * Array with the names of the services started by default.
  */
@@ -694,6 +700,10 @@
 				      &forwardToService, fc);
 }
 
+static void fc_acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc, int is_ipv4, int is_ipv6);
+static void fc_acceptConnection_ipv4 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+static void fc_acceptConnection_ipv6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+static int service_try_to_connect (struct sockaddr *addr, socklen_t addrlen, struct ForwardedConnection *fc);
 
 /**
  *
@@ -704,103 +714,252 @@
 {
   struct ForwardedConnection *fc = cls;
   struct GNUNET_TIME_Relative rem;
+  int fail = 0;
+  int failures = 0;
+  int is_zero = 0, is_ipv6 = 0, is_ipv4 = 0;
+  struct sockaddr_in *target_ipv4;
+  struct sockaddr_in6 *target_ipv6;
 
+  int free_ipv4 = 1, free_ipv6 = 1;
+  char listen_address[128];
+  uint16_t listening_port;
+
   fc->start_task = GNUNET_SCHEDULER_NO_TASK;
   if ( (NULL != tc) &&
        (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) )
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-		  _("Unable to forward to service `%s': shutdown\n"),
-		  fc->listen_info->serviceName);
-      closeClientAndServiceSockets (fc, REASON_ERROR);
-      return;
-    }
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+		_("Unable to forward to service `%s': shutdown\n"),
+		fc->listen_info->serviceName);
+    closeClientAndServiceSockets (fc, REASON_ERROR);
+    return;
+  }
   rem = GNUNET_TIME_absolute_get_remaining (fc->timeout);
   if (rem.rel_value == 0)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+		_("Unable to forward to service `%s': timeout before connect\n"),
+		fc->listen_info->serviceName);
+    closeClientAndServiceSockets (fc, REASON_ERROR);
+    return;
+  }
+  target_ipv4 = GNUNET_malloc (sizeof (struct sockaddr_in));
+  target_ipv6 = GNUNET_malloc (sizeof (struct sockaddr_in6));
+
+  switch (fc->listen_info->service_addr->sa_family)
+  {
+  case AF_INET:
+    inet_ntop (fc->listen_info->service_addr->sa_family, (const void *) &((struct sockaddr_in *) fc->listen_info->service_addr)->sin_addr, listen_address, INET_ADDRSTRLEN);
+    if (strncmp (listen_address, "0.0.0.0:", 8) == 0 || strncmp (listen_address, "0.0.0.0", 7) == 0)
+      is_zero = 1;
+    is_ipv4 = 1;
+    listening_port = ((struct sockaddr_in *)fc->listen_info->service_addr)->sin_port;
+    break;
+  case AF_INET6:
+    inet_ntop (fc->listen_info->service_addr->sa_family, (const void *) &((struct sockaddr_in6 *) fc->listen_info->service_addr)->sin6_addr, listen_address, INET6_ADDRSTRLEN);
+    if (strncmp (listen_address, "[::]:", 5) == 0 || strncmp (listen_address, "::", 2) == 0)
+      is_zero = 1;
+    is_ipv6 = 1;
+    listening_port = ((struct sockaddr_in6 *)fc->listen_info->service_addr)->sin6_port;
+    break;
+  default:
+    break;
+  }
+
+  fc->service_connect_ipv4 = NULL;
+  fc->service_connect_ipv6 = NULL;
+  if (is_zero)
+  {
+    /* connect to [::1] and 127.0.0.1 instead of [::] and 0.0.0.0 */
+    inet_pton (AF_INET, "127.0.0.1", &target_ipv4->sin_addr);
+    target_ipv4->sin_family = AF_INET;
+    target_ipv4->sin_port = listening_port;
+    is_ipv4 = 1;
+    free_ipv4 = 0;
+
+    inet_pton (AF_INET6, "0:0:0:0:0:0:0:1", &target_ipv6->sin6_addr);
+    target_ipv6->sin6_family = AF_INET6;
+    target_ipv6->sin6_port = listening_port;
+    is_ipv6 = 1;
+    free_ipv6 = 0;
+  }
+  else
+  {
+    if (is_ipv4)
+      memcpy (target_ipv4, fc->listen_info->service_addr, sizeof (struct sockaddr_in));
+    else if (is_ipv6)
+      memcpy (target_ipv6, fc->listen_info->service_addr, sizeof (struct sockaddr_in6));
+  }
+
+  if (is_ipv4)
+    failures += free_ipv4 = service_try_to_connect ((struct sockaddr *) target_ipv4, sizeof (struct sockaddr_in), fc);
+  if (is_ipv6)
+    failures += free_ipv6 = service_try_to_connect ((struct sockaddr *) target_ipv6, sizeof (struct sockaddr_in6), fc);
+
+  if (is_ipv4 + is_ipv6 <= failures)
+    fail = 1;
+
+  if (free_ipv4)
+    GNUNET_free (target_ipv4);
+  if (free_ipv6)
+    GNUNET_free (target_ipv6);
+
+  if (fail)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                _ ("Unable to start service `%s': %s\n"),
+		fc->listen_info->serviceName,
+		STRERROR (errno));
+    closeClientAndServiceSockets (fc, REASON_ERROR);
+    return;
+  }
+}
+
+static void
+fc_acceptConnection_ipv4 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  fc_acceptConnection (cls, tc, 1, 0);
+}
+
+static void
+fc_acceptConnection_ipv6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  fc_acceptConnection (cls, tc, 0, 1);
+}
+
+static void
+fc_acceptConnection (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc, int is_ipv4, int is_ipv6)
+{
+  struct ForwardedConnection *fc = cls;
+  struct ServiceListeningInfo *sli;
+
+  if (is_ipv4)
+    sli = fc->service_connect_ipv4;
+  else if (is_ipv6)
+    sli = fc->service_connect_ipv6;
+  else
+    GNUNET_break (0);
+
+  if ((tc->reason & (GNUNET_SCHEDULER_REASON_SHUTDOWN | GNUNET_SCHEDULER_REASON_TIMEOUT | GNUNET_SCHEDULER_REASON_PREREQ_DONE)) || ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) && fc->armServiceSocket))
+  {
+    GNUNET_NETWORK_socket_close (sli->listeningSocket);
+    if (is_ipv4)
+      fc->service_connect_ipv4 = NULL;
+    else if (is_ipv6)
+      fc->service_connect_ipv6 = NULL;
+  }
+  else if (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)
+  {
+#if DEBUG_SERVICE_MANAGER
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+       "Connected to service, now starting forwarding\n");
+#endif
+    fc->armServiceSocket = sli->listeningSocket;
+    if ((is_ipv4 && fc->service_connect_ipv6 != NULL))
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-		  _("Unable to forward to service `%s': timeout before connect\n"),
-		  fc->listen_info->serviceName);
-      closeClientAndServiceSockets (fc, REASON_ERROR);
-      return;
+      GNUNET_SCHEDULER_cancel (fc->service_connect_ipv6->acceptTask);
+      fc->service_connect_ipv6->acceptTask = GNUNET_SCHEDULER_add_now (fc_acceptConnection_ipv6, fc);
     }
-  fc->armServiceSocket =
-    GNUNET_NETWORK_socket_create (fc->listen_info->service_addr->sa_family,
-				  SOCK_STREAM, 0);
-  if (NULL == fc->armServiceSocket)
+    else if (is_ipv6 && fc->service_connect_ipv4 != NULL)
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-		  _ ("Unable to start service `%s': %s\n"),
-		  fc->listen_info->serviceName,
-		  STRERROR (errno));
-      closeClientAndServiceSockets (fc, REASON_ERROR);
-      return;
+      GNUNET_SCHEDULER_cancel (fc->service_connect_ipv4->acceptTask);
+      fc->service_connect_ipv4->acceptTask = GNUNET_SCHEDULER_add_now (fc_acceptConnection_ipv4, fc);
     }
-  if ( (GNUNET_SYSERR ==
-	GNUNET_NETWORK_socket_connect (fc->armServiceSocket,
-				       fc->listen_info->service_addr,
-				       fc->listen_info->service_addr_len)) &&
-       (errno != EINPROGRESS) )
+    GNUNET_free (fc->listen_info->service_addr);
+    fc->listen_info->service_addr = sli->service_addr;
+    fc->listen_info->service_addr_len = sli->service_addr_len;
+    /*fc->listen_info->listeningSocket is it closed already?*/
+    if (fc->client_to_service_task == GNUNET_SCHEDULER_NO_TASK)
     {
-      GNUNET_break (GNUNET_OK ==
-		    GNUNET_NETWORK_socket_close (fc->armServiceSocket));
-      fc->armServiceSocket = NULL;
-      fc->back_off = GNUNET_TIME_relative_multiply (fc->back_off, 2);
-  #if DEBUG_SERVICE_MANAGER
-      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-		  "Failed to connected to service `%s' at `%s', will try again in %llu ms\n",
-		  fc->listen_info->serviceName,
-		  GNUNET_a2s (fc->listen_info->service_addr,
-			      fc->listen_info->service_addr_len),
-		  (unsigned long long) GNUNET_TIME_relative_min (fc->back_off,
-								 rem).rel_value);
-#endif
-      GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == fc->start_task);
-      fc->start_task
-	= GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_min (fc->back_off,
-								  rem),
-					&start_forwarding,
-					fc);
-      return;
-    }
-#if DEBUG_SERVICE_MANAGER
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-	      "Connected to service, now starting forwarding\n");
-#endif
-  if (fc->client_to_service_task == GNUNET_SCHEDULER_NO_TASK)
-    {
       if (fc->client_to_service_bufferDataLength == 0) 
-	fc->client_to_service_task =
-	  GNUNET_SCHEDULER_add_read_net (
+	  fc->client_to_service_task =
+	    GNUNET_SCHEDULER_add_read_net (
 					 GNUNET_TIME_UNIT_FOREVER_REL,
 					 fc->armClientSocket,
 					 &receiveFromClient, fc);
       else
-	fc->client_to_service_task = 
-	  GNUNET_SCHEDULER_add_write_net (
+	  fc->client_to_service_task = 
+	    GNUNET_SCHEDULER_add_write_net (
 					  GNUNET_TIME_UNIT_FOREVER_REL,
 					  fc->armServiceSocket,
 					  &forwardToService, fc);
     }
-  if (fc->service_to_client_task == GNUNET_SCHEDULER_NO_TASK)
+    if (fc->service_to_client_task == GNUNET_SCHEDULER_NO_TASK)
     {
       if (fc->service_to_client_bufferDataLength == 0) 
-	fc->service_to_client_task =
-	  GNUNET_SCHEDULER_add_read_net (
+	  fc->service_to_client_task =
+	    GNUNET_SCHEDULER_add_read_net (
 					 GNUNET_TIME_UNIT_FOREVER_REL,
 					 fc->armServiceSocket,
 					 &receiveFromService, fc);
       else
-	fc->service_to_client_task = 
-	  GNUNET_SCHEDULER_add_write_net (
+	  fc->service_to_client_task = 
+	    GNUNET_SCHEDULER_add_write_net (
 					  GNUNET_TIME_UNIT_FOREVER_REL,
 					  fc->armClientSocket,
 					  &forwardToClient, fc);
     }
+  }
+  else
+  {
+    GNUNET_break (0);
+  }
+  GNUNET_free (sli);
 }
 
+static int
+service_try_to_connect (struct sockaddr *addr, socklen_t addrlen, struct ForwardedConnection *fc)
+{
+  struct GNUNET_NETWORK_Handle *sock;
+  struct ServiceListeningInfo *serviceListeningInfo;
 
+  sock = GNUNET_NETWORK_socket_create (AF_INET, SOCK_STREAM, 0);
+  if (sock == NULL)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to create a socket\n");
+    return 1;
+  }
+  
+  if ( (GNUNET_SYSERR == GNUNET_NETWORK_socket_connect (sock, addr, addrlen)) &&
+       (errno != EINPROGRESS) )
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to connect\n");
+    GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (sock));
+    return 1;
+  }
 
+  serviceListeningInfo = GNUNET_malloc (sizeof (struct ServiceListeningInfo));
+  serviceListeningInfo->serviceName = NULL;
+  serviceListeningInfo->service_addr = addr;
+  serviceListeningInfo->service_addr_len = addrlen;
+  serviceListeningInfo->listeningSocket = sock;
+
+  switch (addrlen)
+  {
+  case sizeof (struct sockaddr_in):
+    fc->service_connect_ipv4 = serviceListeningInfo;
+    serviceListeningInfo->acceptTask =
+        GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
+                                        serviceListeningInfo->listeningSocket,
+				        &fc_acceptConnection_ipv4, fc);
+    break;
+  case sizeof (struct sockaddr_in6):
+    fc->service_connect_ipv6 = serviceListeningInfo;
+    serviceListeningInfo->acceptTask =
+        GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
+                                        serviceListeningInfo->listeningSocket,
+				        &fc_acceptConnection_ipv6, fc);
+    break;
+  default:
+    GNUNET_break (0);
+    return 1;
+    break;
+  }
+  return 0;
+}
+
+
+
 /**
  *
  */
Index: src/include/gnunet_os_lib.h
===================================================================
--- src/include/gnunet_os_lib.h	(revision 13603)
+++ src/include/gnunet_os_lib.h	(working copy)
@@ -273,6 +273,18 @@
  */
 int GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc);
 
+/**
+ * Read env variable and set up the read end of the control
+ * pipe that parent uses to send signals to this process.
+ *
+ * Only does something on Windows
+ *
+ * @param cls user-specified parameter (NULL)
+ * @param tc task context
+ */
+void GNUNET_OS_install_parent_control_handler (void *cls,
+                                               const struct
+                                               GNUNET_SCHEDULER_TaskContext * tc);
 
 #if 0                           /* keep Emacsens' auto-indent happy */
 {
Index: src/transport/plugin_transport_http.c
===================================================================
--- src/transport/plugin_transport_http.c	(revision 13603)
+++ src/transport/plugin_transport_http.c	(working copy)
@@ -1589,7 +1589,7 @@
   if (delay.rel_value > 0)
   {
 #if DEBUG_HTTP
-	GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: Inbound quota management: delay next read for %llu ms \n", ps, delay.abs_value);
+	GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,"Connection %X: Inbound quota management: delay next read for %llu ms \n", ps, delay.rel_value);
 #endif
 	pc->reset_task = GNUNET_SCHEDULER_add_delayed (delay, &reset_inbound_quota_delay, pc);
   }
Index: src/fragmentation/test_frag_ji.c
===================================================================
--- src/fragmentation/test_frag_ji.c	(revision 13603)
+++ src/fragmentation/test_frag_ji.c	(working copy)
@@ -1,60 +1,60 @@
-#include "platform.h"
-#include "gnunet_protocols.h"
-#include "gnunet_fragmentation_lib.h"
-
-struct combine{
-	struct GNUNET_FRAGMENT_Context* ctx;
-	struct GNUNET_PeerIdentity* sender;
-};
-
-void message_proc1(void *cls, const struct GNUNET_MessageHeader * msg){
-	fprintf(stderr, "enter into message_proc1\n");
-
-	struct GNUNET_MessageHeader * originalMsg = (struct GNUNET_MessageHeader *)cls;
-
-	if(ntohs(originalMsg->size) != ntohs(msg->size)){
-			fprintf(stderr, "the received message has the different size with the sent one!\n");
-		}
-	if(ntohs(originalMsg->type) != ntohs(msg->type)){
-			fprintf(stderr, "the received message has the different type with the sent one!\n");
-		}
-	if(memcmp(msg, originalMsg, originalMsg->size)){
-			fprintf(stderr, "the received message is not the sent one!\n");
-	}
-	else{
-		fprintf(stdout, "You got the right message!\n");
-	}
-
-}
-
-void message_proc2(void *cls, const struct GNUNET_MessageHeader * msg){
-	printf("enter into message_proc2\n");
-	struct combine * com2 = (struct combine* )cls;
-	GNUNET_FRAGMENT_process(com2->ctx, com2->sender, msg);
-
-}
-
-int
-main(int argc, char * argv[]){
+#include "platform.h"
+#include "gnunet_protocols.h"
+#include "gnunet_fragmentation_lib.h"
+
+struct combine{
+	struct GNUNET_FRAGMENT_Context* ctx;
+	struct GNUNET_PeerIdentity* sender;
+};
+
+void message_proc1(void *cls, const struct GNUNET_MessageHeader * msg){
+	fprintf(stderr, "enter into message_proc1\n");
+
+	struct GNUNET_MessageHeader * originalMsg = (struct GNUNET_MessageHeader *)cls;
+
+	if(ntohs(originalMsg->size) != ntohs(msg->size)){
+			fprintf(stderr, "the received message has the different size with the sent one!\n");
+		}
+	if(ntohs(originalMsg->type) != ntohs(msg->type)){
+			fprintf(stderr, "the received message has the different type with the sent one!\n");
+		}
+	if(memcmp(msg, originalMsg, originalMsg->size)){
+			fprintf(stderr, "the received message is not the sent one!\n");
+	}
+	else{
+		fprintf(stdout, "You got the right message!\n");
+	}
+
+}
+
+void message_proc2(void *cls, const struct GNUNET_MessageHeader * msg){
+	printf("enter into message_proc2\n");
+	struct combine * com2 = (struct combine* )cls;
+	GNUNET_FRAGMENT_process(com2->ctx, com2->sender, msg);
+
+}
+
+int
+main(int argc, char * argv[]){
 	
-	uint32_t mtu = 512;
-	struct GNUNET_FRAGMENT_Context * ctx;
-	struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)GNUNET_malloc(sizeof(struct GNUNET_MessageHeader)+2*mtu);
-	ctx = GNUNET_FRAGMENT_context_create(NULL, message_proc1, msg);
-	msg->size = htons(sizeof(struct GNUNET_MessageHeader)+4*mtu);
-	msg->type = htons(GNUNET_MESSAGE_TYPE_HELLO);
-	struct GNUNET_PeerIdentity *sender;
-	sender = (struct GNUNET_PeerIdentity *)GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity));
-
-	memset(sender, 9, sizeof(struct GNUNET_PeerIdentity));
-
-	memset(&msg[1], 5, 2*mtu);
-
-	struct combine *com;
-	com = (struct combine *)GNUNET_malloc(sizeof(struct combine));
-	com->ctx = ctx;
-	com->sender = sender;
-	GNUNET_FRAGMENT_fragment(msg, mtu, message_proc2, com);
-	GNUNET_free(msg);
-	return 0;
-}
+	uint32_t mtu = 512;
+	struct GNUNET_FRAGMENT_Context * ctx;
+	struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)GNUNET_malloc(sizeof(struct GNUNET_MessageHeader)+2*mtu);
+	ctx = GNUNET_FRAGMENT_context_create(NULL, message_proc1, msg);
+	msg->size = htons(sizeof(struct GNUNET_MessageHeader)+4*mtu);
+	msg->type = htons(GNUNET_MESSAGE_TYPE_HELLO);
+	struct GNUNET_PeerIdentity *sender;
+	sender = (struct GNUNET_PeerIdentity *)GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity));
+
+	memset(sender, 9, sizeof(struct GNUNET_PeerIdentity));
+
+	memset(&msg[1], 5, 2*mtu);
+
+	struct combine *com;
+	com = (struct combine *)GNUNET_malloc(sizeof(struct combine));
+	com->ctx = ctx;
+	com->sender = sender;
+	GNUNET_FRAGMENT_fragment(msg, mtu, message_proc2, com);
+	GNUNET_free(msg);
+	return 0;
+}
Index: src/fragmentation/test_fragmentation_enhanced.c
===================================================================
--- src/fragmentation/test_fragmentation_enhanced.c	(revision 13603)
+++ src/fragmentation/test_fragmentation_enhanced.c	(working copy)
@@ -1,89 +1,89 @@
-/*
-     This file is part of GNUnet.
-     (C) 2009 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 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/
-
-/**
- * @file fragmentation/test_fragmentation_enhanced.c
- * @brief testcase for the fragmentation.c
- * @author Ji Lu
- */
-
-#include "platform.h"
-#include "gnunet_protocols.h"
-#include "gnunet_fragmentation_lib.h"
-
-struct combine{
-	struct GNUNET_FRAGMENT_Context* ctx;
-	struct GNUNET_PeerIdentity* sender;
-};
-
-void message_proc1(void *cls, const struct GNUNET_MessageHeader * msg){
-
-	fprintf(stderr, "enter into message_proc1\n");
-
-	struct GNUNET_MessageHeader * originalMsg = (struct GNUNET_MessageHeader *)cls;
-
-	if(ntohs(originalMsg->size) != ntohs(msg->size)){
-			fprintf(stderr, "the received message has the different size with the sent one!\n");
-		}
-	if(ntohs(originalMsg->type) != ntohs(msg->type)){
-			fprintf(stderr, "the received message has the different type with the sent one!\n");
-		}
-	if(memcmp(msg, originalMsg, originalMsg->size)){
-			fprintf(stderr, "the received message is not the sent one!\n");
-	}
-	else{
-			fprintf(stdout, "You got the right message!\n");
-	}
-
-}
-
-void message_proc2(void *cls, const struct GNUNET_MessageHeader * msg){
-
-	printf("enter into message_proc2\n");
-
-	struct combine * com2 = (struct combine* )cls;
-	GNUNET_FRAGMENT_process(com2->ctx, com2->sender, msg);
-
-}
-
-int
-main(int argc, char * argv[]){
+/*
+     This file is part of GNUnet.
+     (C) 2009 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 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file fragmentation/test_fragmentation_enhanced.c
+ * @brief testcase for the fragmentation.c
+ * @author Ji Lu
+ */
+
+#include "platform.h"
+#include "gnunet_protocols.h"
+#include "gnunet_fragmentation_lib.h"
+
+struct combine{
+	struct GNUNET_FRAGMENT_Context* ctx;
+	struct GNUNET_PeerIdentity* sender;
+};
+
+void message_proc1(void *cls, const struct GNUNET_MessageHeader * msg){
+
+	fprintf(stderr, "enter into message_proc1\n");
+
+	struct GNUNET_MessageHeader * originalMsg = (struct GNUNET_MessageHeader *)cls;
+
+	if(ntohs(originalMsg->size) != ntohs(msg->size)){
+			fprintf(stderr, "the received message has the different size with the sent one!\n");
+		}
+	if(ntohs(originalMsg->type) != ntohs(msg->type)){
+			fprintf(stderr, "the received message has the different type with the sent one!\n");
+		}
+	if(memcmp(msg, originalMsg, originalMsg->size)){
+			fprintf(stderr, "the received message is not the sent one!\n");
+	}
+	else{
+			fprintf(stdout, "You got the right message!\n");
+	}
+
+}
+
+void message_proc2(void *cls, const struct GNUNET_MessageHeader * msg){
+
+	printf("enter into message_proc2\n");
+
+	struct combine * com2 = (struct combine* )cls;
+	GNUNET_FRAGMENT_process(com2->ctx, com2->sender, msg);
+
+}
+
+int
+main(int argc, char * argv[]){
 	
-	uint32_t mtu = 512;
-	struct GNUNET_FRAGMENT_Context * ctx;
-	struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)GNUNET_malloc(sizeof(struct GNUNET_MessageHeader)+2*mtu);
-	ctx = GNUNET_FRAGMENT_context_create(NULL, message_proc1, msg);
-	msg->size = htons(sizeof(struct GNUNET_MessageHeader)+4*mtu);
-	msg->type = htons(GNUNET_MESSAGE_TYPE_HELLO);
-	struct GNUNET_PeerIdentity *sender;
-	sender = (struct GNUNET_PeerIdentity *)GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity));
-
-	memset(sender, 9, sizeof(struct GNUNET_PeerIdentity));
-
-	memset(&msg[1], 5, 2*mtu);
-
-	struct combine *com;
-	com = (struct combine *)GNUNET_malloc(sizeof(struct combine));
-	com->ctx = ctx;
-	com->sender = sender;
-	GNUNET_FRAGMENT_fragment(msg, mtu, message_proc2, com);
-	GNUNET_free(msg);
-	return 0;
-}
+	uint32_t mtu = 512;
+	struct GNUNET_FRAGMENT_Context * ctx;
+	struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *)GNUNET_malloc(sizeof(struct GNUNET_MessageHeader)+2*mtu);
+	ctx = GNUNET_FRAGMENT_context_create(NULL, message_proc1, msg);
+	msg->size = htons(sizeof(struct GNUNET_MessageHeader)+4*mtu);
+	msg->type = htons(GNUNET_MESSAGE_TYPE_HELLO);
+	struct GNUNET_PeerIdentity *sender;
+	sender = (struct GNUNET_PeerIdentity *)GNUNET_malloc(sizeof(struct GNUNET_PeerIdentity));
+
+	memset(sender, 9, sizeof(struct GNUNET_PeerIdentity));
+
+	memset(&msg[1], 5, 2*mtu);
+
+	struct combine *com;
+	com = (struct combine *)GNUNET_malloc(sizeof(struct combine));
+	com->ctx = ctx;
+	com->sender = sender;
+	GNUNET_FRAGMENT_fragment(msg, mtu, message_proc2, com);
+	GNUNET_free(msg);
+	return 0;
+}
Index: src/hostlist/hostlist-client.c
===================================================================
--- src/hostlist/hostlist-client.c	(revision 13603)
+++ src/hostlist/hostlist-client.c	(working copy)
@@ -1421,6 +1421,7 @@
                   "HOSTLISTFILE", "HOSTLIST");
       return;
     }
+  GNUNET_DISK_directory_create_for_file (filename);
   wh = GNUNET_BIO_write_open (filename);
   if ( NULL == wh)
     {
Index: src/util/scheduler.c
===================================================================
--- src/util/scheduler.c	(revision 13603)
+++ src/util/scheduler.c	(working copy)
@@ -744,6 +744,7 @@
   shc_hup = GNUNET_SIGNAL_handler_install (SIGHUP, &sighandler_shutdown);
 #endif
   current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT;
+  GNUNET_SCHEDULER_add_continuation (GNUNET_OS_install_parent_control_handler, NULL, GNUNET_SCHEDULER_REASON_STARTUP);
   GNUNET_SCHEDULER_add_continuation (task,
                                      task_cls,
                                      GNUNET_SCHEDULER_REASON_STARTUP);
@@ -1351,8 +1352,7 @@
   GNUNET_assert (rfd != NULL);
   rs = GNUNET_NETWORK_fdset_create ();
   GNUNET_NETWORK_fdset_handle_set (rs, rfd);
-  ret = GNUNET_SCHEDULER_add_select (sched,
-                                     GNUNET_SCHEDULER_PRIORITY_KEEP,
+  ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_KEEP,
                                      GNUNET_SCHEDULER_NO_TASK, delay,
                                      rs, NULL, task, task_cls);
   GNUNET_NETWORK_fdset_destroy (rs);
@@ -1400,8 +1400,7 @@
   GNUNET_assert (wfd != NULL);
   ws = GNUNET_NETWORK_fdset_create ();
   GNUNET_NETWORK_fdset_handle_set (ws, wfd);
-  ret = GNUNET_SCHEDULER_add_select (sched,
-                                     GNUNET_SCHEDULER_PRIORITY_KEEP,
+  ret = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_KEEP,
                                      GNUNET_SCHEDULER_NO_TASK,
                                      delay, NULL, ws, task, task_cls);
   GNUNET_NETWORK_fdset_destroy (ws);
Index: src/util/os_priority.c
===================================================================
--- src/util/os_priority.c	(revision 13557)
+++ src/util/os_priority.c	(working copy)
@@ -29,28 +29,95 @@
 #include "gnunet_os_lib.h"
 #include "disk.h"
 
+#define GNUNET_OS_NT_CONTROL_PIPE "GNUNET_OS_NT_CONTROL_PIPE"
+
 struct GNUNET_OS_Process
 {
   pid_t pid;
 #if WINDOWS
   HANDLE handle;
+  struct GNUNET_DISK_PipeHandle *control_pipe;
 #endif
 };
 
 static struct GNUNET_OS_Process current_process;
 
-
 #if WINDOWS
-void
-GNUNET_OS_process_set_handle(struct GNUNET_OS_Process *proc, HANDLE handle)
+void GNUNET_OS_parent_control_handler (void *cls,
+                                       const struct
+                                       GNUNET_SCHEDULER_TaskContext * tc)
 {
-  if (proc->handle != NULL)
-    CloseHandle (proc->handle);
-  proc->handle = handle;
+  struct GNUNET_DISK_PipeHandle *control_pipe = (struct GNUNET_DISK_PipeHandle *) cls;
+  unsigned char code;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_OS_parent_control_handler is invoked because of %d\n", tc->reason);
+
+  if (tc->reason & (GNUNET_SCHEDULER_REASON_SHUTDOWN | GNUNET_SCHEDULER_REASON_TIMEOUT | GNUNET_SCHEDULER_REASON_PREREQ_DONE))
+  {
+      GNUNET_DISK_pipe_close (control_pipe);
+  }
+  else
+  {
+    if (GNUNET_DISK_file_read (GNUNET_DISK_pipe_handle (control_pipe, GNUNET_DISK_PIPE_END_READ), &code, sizeof (char)) != sizeof (char))
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "GNUNET_DISK_file_read have failed, errno = %d. Closing the control pipe.\n", errno);
+      GNUNET_DISK_pipe_close (control_pipe);
+    }
+    else
+    {
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got control code %d\n", code);
+      switch (code)
+      {
+        case 0:
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Raising SIGTERM\n");
+          raise (SIGTERM);
+          break;
+        case 1:
+          GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Raising SIGKILL\n");
+          raise (SIGKILL);
+          break;
+        case 255:
+          /* read more bytes - a possibility for extended signals
+           * in case 254 different valies is not enough
+           */
+          break;
+        default:
+          break;
+      }
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Re-adding parent control handler pipe to the scheduler\n");
+      GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_DISK_pipe_handle (control_pipe, GNUNET_DISK_PIPE_END_READ), GNUNET_OS_parent_control_handler, control_pipe);
+    }
+  }
 }
 #endif
 
+void
+GNUNET_OS_install_parent_control_handler (void *cls,
+                                          const struct
+                                          GNUNET_SCHEDULER_TaskContext * tc)
+{
+#ifdef WINDOWS
+  char *env_buf;
+  char *endptr;
+  HANDLE control_pipe_end[2];
+  struct GNUNET_DISK_PipeHandle *control_pipe = NULL;
 
+  env_buf = getenv (GNUNET_OS_NT_CONTROL_PIPE);
+  if (env_buf == NULL || strlen (env_buf) <= 0 || env_buf[0] < '0' || env_buf[0] > '9')
+    return;
+
+  control_pipe_end[0] = (HANDLE) strtol (env_buf, &endptr, 10);
+  control_pipe_end[1] = INVALID_HANDLE_VALUE;
+ 
+  control_pipe = GNUNET_DISK_pipe_from_internal_handles_ (GNUNET_NO, &control_pipe_end[0], &control_pipe_end[1], sizeof (HANDLE));
+  if (control_pipe == NULL)
+    return;
+
+  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding parent control handler pipe to the scheduler\n");
+  GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_DISK_pipe_handle (control_pipe, GNUNET_DISK_PIPE_END_READ), GNUNET_OS_parent_control_handler, control_pipe);
+#endif
+}
+
 /**
  * Get process structure for current process
  *
@@ -66,7 +133,7 @@
   current_process.pid = GetCurrentProcessId ();
   current_process.handle = GetCurrentProcess ();
 #else
-  current_process.pid = 0;
+  current_process.pid = getpid ();
 #endif
   return &current_process;
 }
@@ -75,27 +142,49 @@
 GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig)
 {
 #if WINDOWS
-  if (sig == SIGKILL || sig == SIGTERM)
+  unsigned char c;
+  DWORD dwresult, error_code = NO_ERROR;
+  BOOL bresult = 1;
+
+  switch (sig)
   {
-    HANDLE h = proc->handle;
-    if (NULL == h)
-    {
-      GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
-		  _("Invalid process information {%d, %08X}\n"),
-		  proc->pid,
-		  h);
+    case SIGKILL:
+      c = 1;
+      break;
+    case SIGTERM:
+      c = 0;
+      break;
+    default:
+      errno = EINVAL;
       return -1;
-    }
-    if (!TerminateProcess (h, 0))
+  }
+
+  if (GNUNET_DISK_file_write (GNUNET_DISK_pipe_handle (proc->control_pipe, GNUNET_DISK_PIPE_END_WRITE), &c, sizeof (c)) != sizeof (c))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to write into control pipe, errno is %d\n", errno);
+    bresult = 0;
+  }
+  else
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Wrote control code into control pipe, now waiting\n");
+    SetLastError (0);
+    dwresult = WaitForSingleObject (proc->handle, 4*1000);
+    error_code = GetLastError ();
+    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Woke up, returned %d, GLE is %d\n", dwresult, error_code);
+    if (WAIT_OBJECT_0 != dwresult || error_code != NO_ERROR)
     {
-      SetErrnoFromWinError (GetLastError ());
-      return -1;
+      SetLastError (0);
+      bresult = TerminateProcess (proc->handle, 0);
+      error_code = GetLastError ();
+      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "TerminateProcess for the child returned %d, GLE is %d\n", bresult, error_code);
     }
-    else
-      return 0;
   }
-  errno = EINVAL;
-  return -1;
+  if (error_code != NO_ERROR || !bresult)
+  {
+    return -1;
+  }
+  else
+    return 0;
 #else
   return kill (proc->pid, sig);
 #endif
@@ -363,19 +452,32 @@
   STARTUPINFO start;
   PROCESS_INFORMATION proc;
   struct GNUNET_OS_Process *gnunet_proc = NULL;
+  struct GNUNET_DISK_PipeHandle *control_pipe = NULL;
+  char *env_buf;
 
   HANDLE stdin_handle;
   HANDLE stdout_handle;
+  HANDLE control_pipe_read_end, control_pipe_write_end;
 
   char path[MAX_PATH + 1];
 
-  cmdlen = 0;
+  if ((HINSTANCE) 32 >= FindExecutableA (filename, NULL, path)) 
+    {
+      SetErrnoFromWinError (GetLastError ());
+      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "FindExecutable", filename);
+      return NULL;
+    }
+
+  cmdlen = strlen (path) + 3;
   va_start (ap, filename);
   while (NULL != (arg = va_arg (ap, char *)))
+  {
       cmdlen = cmdlen + strlen (arg) + 3;
+  }
   va_end (ap);
 
   cmd = idx = GNUNET_malloc (sizeof (char) * (cmdlen + 1));
+  idx += sprintf (idx, "\"%s\" ", path);
   va_start (ap, filename);
   while (NULL != (arg = va_arg (ap, char *)))
       idx += sprintf (idx, "\"%s\" ", arg);
@@ -399,30 +501,42 @@
       start.hStdOutput = stdout_handle;
     }
 
-  if (32 >= FindExecutableA (filename, NULL, path)) 
-    {
-      SetErrnoFromWinError (GetLastError ());
-      GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "FindExecutable", filename);
-      return NULL;
-    }
+  control_pipe = GNUNET_DISK_pipe (GNUNET_NO, 1, 0);
+  GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle (control_pipe, GNUNET_DISK_PIPE_END_READ), &control_pipe_read_end, sizeof (HANDLE));
+  GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle (control_pipe, GNUNET_DISK_PIPE_END_WRITE), &control_pipe_write_end, sizeof (HANDLE));
 
+  GNUNET_asprintf (&env_buf, "%s=%d", GNUNET_OS_NT_CONTROL_PIPE, control_pipe_read_end);
+  putenv (env_buf);
+  GNUNET_free (env_buf);
+
   if (!CreateProcessA
       (path, cmd, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &start,
        &proc))
     {
       SetErrnoFromWinError (GetLastError ());
       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "CreateProcess", path);
-      return NULL;
+      goto end;
     }
 
   gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process));
   gnunet_proc->pid = proc.dwProcessId;
   gnunet_proc->handle = proc.hProcess;
+  gnunet_proc->control_pipe = control_pipe;
 
   CreateThread (NULL, 64000, ChildWaitThread, (void *) gnunet_proc, 0, NULL);
 
   CloseHandle (proc.hThread);
+end:
 
+  GNUNET_asprintf (&env_buf, "%s=", GNUNET_OS_NT_CONTROL_PIPE);
+  putenv (env_buf);
+  GNUNET_free (env_buf);
+
+  if (gnunet_proc == NULL)
+    GNUNET_DISK_pipe_close (control_pipe);
+  else
+    GNUNET_DISK_pipe_close_end (control_pipe, GNUNET_DISK_PIPE_END_READ);
+
   GNUNET_free (cmd);
 
   return gnunet_proc;
@@ -551,12 +665,14 @@
   PROCESS_INFORMATION proc;
   int argcount = 0;
   char non_const_filename[MAX_PATH +1];
-  int filenamelen = 0;
   struct GNUNET_OS_Process *gnunet_proc = NULL;
+  struct GNUNET_DISK_PipeHandle *control_pipe = NULL;
+  char *env_buf;
+  HANDLE control_pipe_read_end, control_pipe_write_end;
 
   GNUNET_assert (lsocks == NULL);
 
-  if (32 >= FindExecutableA (filename, NULL, non_const_filename)) 
+  if ((HINSTANCE) 32 >= FindExecutableA (filename, NULL, non_const_filename)) 
     {
       SetErrnoFromWinError (GetLastError ());
       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, "FindExecutable", filename);
@@ -579,7 +695,12 @@
   arg = (char **) argv;
   while (*arg)
     {
-      non_const_argv[argcount] = GNUNET_strdup (*arg);
+      if (argcount == 0)
+        /* Otherwise we'll get the argv[0] without .exe extension,
+           that will break libtool wrapper */
+        non_const_argv[argcount] = GNUNET_strdup (non_const_filename);
+      else
+        non_const_argv[argcount] = GNUNET_strdup (*arg);
       arg++;
       argcount++;
     }
@@ -606,22 +727,43 @@
   memset (&start, 0, sizeof (start));
   start.cb = sizeof (start);
 
-  if (!CreateProcess
-      (non_const_filename, cmd, NULL, NULL, FALSE, DETACHED_PROCESS, NULL, NULL, &start,
+  control_pipe = GNUNET_DISK_pipe (GNUNET_NO, 1, 0);
+  GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle (control_pipe, GNUNET_DISK_PIPE_END_READ), &control_pipe_read_end, sizeof (HANDLE));
+  GNUNET_DISK_internal_file_handle_ (GNUNET_DISK_pipe_handle (control_pipe, GNUNET_DISK_PIPE_END_WRITE), &control_pipe_write_end, sizeof (HANDLE));
+
+
+  GNUNET_asprintf (&env_buf, "%s=%d", GNUNET_OS_NT_CONTROL_PIPE, control_pipe_read_end);
+  putenv (env_buf);
+  GNUNET_free (env_buf);
+
+  if (!CreateProcessA
+      (non_const_filename, cmd, NULL, NULL, TRUE,
+       DETACHED_PROCESS, NULL, NULL, &start,
        &proc))
     {
       SetErrnoFromWinError (GetLastError ());
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "CreateProcess");
-      return NULL;
+      goto end;
     }
 
   gnunet_proc = GNUNET_malloc (sizeof (struct GNUNET_OS_Process));
   gnunet_proc->pid = proc.dwProcessId;
   gnunet_proc->handle = proc.hProcess;
+  gnunet_proc->control_pipe = control_pipe;
 
   CreateThread (NULL, 64000, ChildWaitThread, (void *) gnunet_proc, 0, NULL);
 
   CloseHandle (proc.hThread);
+end:
+  GNUNET_asprintf (&env_buf, "%s=", GNUNET_OS_NT_CONTROL_PIPE);
+  putenv (env_buf);
+  GNUNET_free (env_buf);
+
+  if (gnunet_proc == NULL)
+    GNUNET_DISK_pipe_close (control_pipe);
+  else
+    GNUNET_DISK_pipe_close_end (control_pipe, GNUNET_DISK_PIPE_END_READ);
+
   GNUNET_free (cmd);
 
   while (argcount > 0)
Index: src/util/network.c
===================================================================
--- src/util/network.c	(revision 13603)
+++ src/util/network.c	(working copy)
@@ -470,8 +470,8 @@
 
 #ifdef MSG_DONTWAIT
   flags |= MSG_DONTWAIT;
+#endif
 
-#endif
   ret = recvfrom (desc->fd, buffer, length, flags, src_addr, addrlen);
 #ifdef MINGW
   if (SOCKET_ERROR == ret)
@@ -1138,9 +1138,19 @@
 
             {
               HANDLE h;
-              DWORD dwBytes;
+              DWORD dwBytes = 0, error_code;
+              BOOL bresult;
               h = *(HANDLE *) GNUNET_CONTAINER_slist_get (i, NULL);
-              if (!PeekNamedPipe (h, NULL, 0, NULL, &dwBytes, NULL))
+              bresult = PeekNamedPipe (h, NULL, 0, NULL, &dwBytes, NULL);
+              error_code = GetLastError ();
+              /* FIXME: This should fail when the pipe is _really_ invalid,
+               * should skip the pipe if the error means that it's
+               * temporarily unavailable, and should succeed if the pipe
+               * is broken (or that the otherwise valid pipe is in a condition
+               * that prevents further reading). 
+               * For now it succeeds only when the pipe is broken or readable.
+               */
+              if (!bresult && error_code != ERROR_BROKEN_PIPE)
                 {
                   retcode = -1;
                   SetErrnoFromWinError (GetLastError ());
@@ -1152,7 +1162,7 @@
 #endif
                   goto select_loop_end;
                 }
-              else if (dwBytes)
+              else if (dwBytes || error_code == ERROR_BROKEN_PIPE)
 
                 {
                   GNUNET_CONTAINER_slist_add (handles_read,
Index: src/util/disk.c
===================================================================
--- src/util/disk.c	(revision 13603)
+++ src/util/disk.c	(working copy)
@@ -1910,4 +1910,95 @@
   return GNUNET_OK;
 }
 
+struct GNUNET_DISK_FileHandle
+GNUNET_DISK_file_from_internal_handle_ (void *src, size_t src_len)
+{
+  struct GNUNET_DISK_FileHandle ret;
+#ifdef MINGW
+  if (src_len == sizeof (HANDLE))
+    ret.h = *(HANDLE *) src;
+  else
+    ret.h = INVALID_HANDLE_VALUE;
+#else
+  if (src_len == sizeof (int))
+    ret.fd = *(int *) src;
+  else
+    ret.fd = -1;
+#endif
+  return ret;
+}
+
+struct GNUNET_DISK_PipeHandle *
+GNUNET_DISK_pipe_from_internal_handles_ (int blocking, void *src0, void *src1, size_t src_len)
+{
+  struct GNUNET_DISK_PipeHandle *p;
+  struct GNUNET_DISK_FileHandle *fds;
+
+  p =
+    GNUNET_malloc (sizeof (struct GNUNET_DISK_PipeHandle) +
+                   2 * sizeof (struct GNUNET_DISK_FileHandle));
+  fds = (struct GNUNET_DISK_FileHandle *) &p[1];
+  p->fd[0] = &fds[0];
+  p->fd[1] = &fds[1];
+  fds[0] = GNUNET_DISK_file_from_internal_handle_ (src0, src_len);
+  fds[1] = GNUNET_DISK_file_from_internal_handle_ (src1, src_len);
+#ifndef MINGW
+  int fd[2];
+  int ret;
+  int flags;
+  int eno;
+
+  fd[0] = fds[0].fd;
+  fd[1] = fds[1].fd;
+  ret = 0;
+  if (fd[0] >= 0)
+  {
+    flags = fcntl (fd[0], F_GETFL);
+    if (!blocking)
+      flags |= O_NONBLOCK;
+    if (0 > fcntl (fd[0], F_SETFL, flags))
+      ret = -1;
+    flags = fcntl (fd[0], F_GETFD);
+    flags |= FD_CLOEXEC;
+    if (0 > fcntl (fd[0], F_SETFD, flags))
+      ret = -1;
+  }
+  if (fd[1] >= 0)
+  {
+    flags = fcntl (fd[1], F_GETFL);
+    if (!blocking)
+      flags |= O_NONBLOCK;
+    if (0 > fcntl (fd[1], F_SETFL, flags))
+      ret = -1;
+    flags = fcntl (fd[1], F_GETFD);
+    flags |= FD_CLOEXEC;
+    if (0 > fcntl (fd[1], F_SETFD, flags))
+      ret = -1;
+  }
+  if (ret == -1)
+    {
+      eno = errno;
+      GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "fcntl");
+      GNUNET_free (p);
+      errno = eno;
+      return NULL;    
+    }
+#else
+  /* Empirical fact: DuplicateHandle() on a handle inherited from the parent
+   * dies with ERROR_INVALID_HANDLE, so we won't try to duplicate these to
+   * make them inheritable/uninheritable.
+   */
+  if (!blocking)
+  {
+    DWORD mode;
+
+    mode = PIPE_NOWAIT;
+    SetNamedPipeHandleState (p->fd[0]->h, &mode, NULL, NULL);
+    SetNamedPipeHandleState (p->fd[1]->h, &mode, NULL, NULL);
+    /* this always fails on Windows 95, so we don't care about error handling */
+  }
+#endif
+  return p;
+}
+
 /* end of disk.c */
Index: src/util/connection.c
===================================================================
--- src/util/connection.c	(revision 13603)
+++ src/util/connection.c	(working copy)
@@ -461,7 +461,7 @@
   struct GNUNET_CONNECTION_Handle *sock = cls;
   GNUNET_CONNECTION_TransmitReadyNotify notify;
   struct AddressProbe *pos;
-  
+
   sock->destroy_task = GNUNET_SCHEDULER_NO_TASK;
   GNUNET_assert (sock->dns_active == NULL);
   if (0 != (sock->ccs & COCO_TRANSMIT_READY))
@@ -497,7 +497,11 @@
                   "Shutting down socket (%p)\n", sock);
 #endif
       if (sock->persist != GNUNET_YES)
-        GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR);
+      {
+        if (GNUNET_YES != GNUNET_NETWORK_socket_shutdown (sock->sock, SHUT_RDWR))
+          GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+                  "Socket shutdown didn't go well, errno is %d\n", errno);
+      }
     }
   if (sock->read_task != GNUNET_SCHEDULER_NO_TASK)
     {
@@ -945,6 +949,7 @@
   struct GNUNET_NETWORK_Handle *s;
   struct GNUNET_CONNECTION_Handle *ret;
 
+
   s = GNUNET_NETWORK_socket_create (af_family, SOCK_STREAM, 0);
   if (s == NULL)
     {
Index: src/util/disk.h
===================================================================
--- src/util/disk.h	(revision 13603)
+++ src/util/disk.h	(working copy)
@@ -1,75 +1,71 @@
-/*
-     This file is part of GNUnet.
-     (C) 2009 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
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
-*/  
-  
-/**
- * @file util/disk.h
- * @brief Internal DISK related helper functions
- * @author Nils Durner
- */ 
-  -
-#ifndef GNUNET_DISK_H_
-#define GNUNET_DISK_H_
-  
-#include "gnunet_disk_lib.h"
-  -
-/**
- * Handle used to access files (and pipes).  
- */ 
-struct GNUNET_DISK_FileHandle 
+/*
+     This file is part of GNUnet.
+     (C) 2009 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
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/  
+  
+/**
+ * @file util/disk.h
+ * @brief Internal DISK related helper functions
+ * @author Nils Durner
+ */ 
+  
+#ifndef GNUNET_DISK_H_
+#define GNUNET_DISK_H_
+  
+#include "gnunet_disk_lib.h"
+  
+/**
+ * Handle used to access files (and pipes).  
+ */ 
+struct GNUNET_DISK_FileHandle 
 {
-  
-#ifdef MINGW
-  /**
-   * File handle under W32.
-   */ 
+  
+#ifdef MINGW
+  /**
+   * File handle under W32.
+   */ 
   HANDLE h;
-  
+  
 #else                           /*   */
-  /**
-   * File handle on other OSes.
-   */ 
+  /**
+   * File handle on other OSes.
+   */ 
   int fd;
-   
+   
 #endif                          /*   */
 };
----
-/**
- * Retrieve OS file handle
- *
- * @internal
- * @param fh GNUnet file descriptor
- * @param dst destination buffer
- * @param dst_len length of dst
- * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
- */ 
+
+/**
+ * Retrieve OS file handle
+ *
+ * @internal
+ * @param fh GNUnet file descriptor
+ * @param dst destination buffer
+ * @param dst_len length of dst
+ * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
+ */ 
 int GNUNET_DISK_internal_file_handle_ (const struct GNUNET_DISK_FileHandle
                                        *fh,  void *dst,  size_t dst_len);
--
-#endif  /* GNUNET_DISK_H_ */
+
+struct GNUNET_DISK_PipeHandle *GNUNET_DISK_pipe_from_internal_handles_ (int blocking, void *src0, void *src1, size_t src_len);
+
+#endif  /* GNUNET_DISK_H_ */
