LRN: Fix automake deps to allow -j* builds again
[oweals/gnunet.git] / src / util / connection.c
index f6f94c397302e38633d5b002783f9f4ffe51e3bf..f26130a0689d4ffdbb161f299952e6da4fc6eb5c 100644 (file)
@@ -301,6 +301,23 @@ void GNUNET_CONNECTION_persist_(struct GNUNET_CONNECTION_Handle *sock)
   sock->persist = GNUNET_YES;
 }
 
+
+/**
+ * Disable the "CORK" feature for communication with the given socket,
+ * forcing the OS to immediately flush the buffer on transmission
+ * instead of potentially buffering multiple messages.  Essentially
+ * reduces the OS send buffers to zero.
+ * Used to make sure that the last messages sent through the connection
+ * reach the other side before the process is terminated.
+ *
+ * @param sock the connection to make flushing and blocking
+ * @return GNUNET_OK on success
+ */
+int GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *sock)
+{
+  return GNUNET_NETWORK_socket_disable_corking (sock->sock);
+}
+
 /**
  * Create a socket handle by boxing an existing OS socket.  The OS
  * socket should henceforth be no longer used directly.
@@ -658,6 +675,7 @@ connect_fail_continuation (struct GNUNET_CONNECTION_Handle *h)
       GNUNET_SCHEDULER_cancel (h->nth.timeout_task);
       h->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK;
       h->ccs -= COCO_TRANSMIT_READY;
+      GNUNET_assert (h->nth.notify_ready != NULL);
       GNUNET_assert (h->write_task == GNUNET_SCHEDULER_NO_TASK);
       h->write_task = GNUNET_SCHEDULER_add_now (&transmit_ready, h);
     }
@@ -713,6 +731,7 @@ connect_success_continuation (struct GNUNET_CONNECTION_Handle *h)
       h->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK;
       h->ccs -= COCO_TRANSMIT_READY;
       GNUNET_assert (h->write_task == GNUNET_SCHEDULER_NO_TASK);
+      GNUNET_assert (h->nth.notify_ready != NULL);
       h->write_task =
         GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining
                                         (h->nth.transmit_timeout), h->sock,
@@ -1009,6 +1028,9 @@ GNUNET_CONNECTION_create_from_sockaddr (int af_family,
     {
       /* maybe refused / unsupported address, try next */
       GNUNET_log_strerror (GNUNET_ERROR_TYPE_INFO, "connect");
+      GNUNET_log (GNUNET_ERROR_TYPE_INFO, 
+                 _("Attempt to connect to `%s' failed\n"),
+                 GNUNET_a2s (serv_addr, addrlen));
       GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (s));
       return NULL;
     }
@@ -1067,6 +1089,7 @@ GNUNET_CONNECTION_destroy (struct GNUNET_CONNECTION_Handle *sock,
          sock->write_task = GNUNET_SCHEDULER_NO_TASK;
          sock->write_buffer_off = 0;
        }
+      sock->nth.notify_ready = NULL;
     }
   if ((sock->write_buffer_off == 0) && (sock->dns_active != NULL))
     {
@@ -1499,8 +1522,11 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
                   GNUNET_a2s (sock->addr, sock->addrlen), sock);
 #endif
       notify = sock->nth.notify_ready;
-      sock->nth.notify_ready = NULL;
-      notify (sock->nth.notify_ready_cls, 0, NULL);
+      if (NULL != notify)
+       {
+         sock->nth.notify_ready = NULL;
+         notify (sock->nth.notify_ready_cls, 0, NULL);
+       }
       return;
     }
   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT))
@@ -1511,6 +1537,7 @@ transmit_ready (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
                   GNUNET_a2s (sock->addr, sock->addrlen), sock);
 #endif
       notify = sock->nth.notify_ready;
+      GNUNET_assert (NULL != notify);
       sock->nth.notify_ready = NULL;
       notify (sock->nth.notify_ready_cls, 0, NULL);
       return;
@@ -1596,11 +1623,15 @@ SCHEDULE_WRITE:
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "Re-scheduling transmit_ready (more to do) (%p).\n", sock);
 #endif
+  have = sock->write_buffer_off - sock->write_buffer_pos;
+  GNUNET_assert ( (sock->nth.notify_ready != NULL) || (have > 0) );
   if (sock->write_task == GNUNET_SCHEDULER_NO_TASK)
     sock->write_task =
-      GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_absolute_get_remaining
-                                      (sock->nth.transmit_timeout),
-                                      sock->sock, &transmit_ready, sock);
+      GNUNET_SCHEDULER_add_write_net ((sock->nth.notify_ready == NULL) 
+                                     ? GNUNET_TIME_UNIT_FOREVER_REL 
+                                     : GNUNET_TIME_absolute_get_remaining (sock->nth.transmit_timeout),
+                                     sock->sock, 
+                                     &transmit_ready, sock);
 }
 
 
@@ -1681,8 +1712,9 @@ GNUNET_CONNECTION_notify_transmit_ready (struct GNUNET_CONNECTION_Handle
 
 
 /**
- * Cancel the specified transmission-ready
- * notification.
+ * Cancel the specified transmission-ready notification.
+ *
+ * @param th notification to cancel
  */
 void
 GNUNET_CONNECTION_notify_transmit_ready_cancel (struct