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.
v4 = GNUNET_malloc (sizeof (struct sockaddr_in));
memset (v4, 0, sizeof (struct sockaddr_in));
v4->sin_family = AF_INET;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+ v4->sin_len = (u_char) sizeof (struct sockaddr_in);
+#endif
memcpy (&v4->sin_addr,
&((char *) &v6->sin6_addr)[sizeof (struct in6_addr) -
sizeof (struct in_addr)],
h);
#endif
h->ccs -= COCO_RECEIVE_AGAIN;
- h->read_task = GNUNET_SCHEDULER_add_after (GNUNET_SCHEDULER_NO_TASK,
- &receive_again, h);
+ h->read_task = GNUNET_SCHEDULER_add_now (&receive_again, h);
}
if (0 != (h->ccs & COCO_TRANSMIT_READY))
{
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_after (GNUNET_SCHEDULER_NO_TASK,
- &transmit_ready, h);
+ h->write_task = GNUNET_SCHEDULER_add_now (&transmit_ready, h);
}
if (0 != (h->ccs & COCO_DESTROY_CONTINUATION))
{
h);
#endif
h->ccs -= COCO_RECEIVE_AGAIN;
- h->read_task = GNUNET_SCHEDULER_add_after (GNUNET_SCHEDULER_NO_TASK,
- &receive_again, h);
+ h->read_task = GNUNET_SCHEDULER_add_now (&receive_again, h);
}
if (0 != (h->ccs & COCO_TRANSMIT_READY))
{
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,
ret->write_buffer = GNUNET_malloc(ret->write_buffer_size);
ret->port = port;
ret->hostname = GNUNET_strdup (hostname);
- ret->dns_active = GNUNET_RESOLVER_ip_get (cfg,
- ret->hostname,
+ ret->dns_active = GNUNET_RESOLVER_ip_get (ret->hostname,
AF_UNSPEC,
GNUNET_CONNECTION_CONNECT_RETRY_TIMEOUT,
&try_connect_using_address, ret);
GNUNET_assert (0 < strlen (unixpath)); /* sanity check */
un = GNUNET_malloc (sizeof (struct sockaddr_un));
un->sun_family = AF_UNIX;
- slen = strlen (unixpath) + 1;
+ slen = strlen (unixpath);
if (slen >= sizeof (un->sun_path))
slen = sizeof (un->sun_path) - 1;
memcpy (un->sun_path,
unixpath,
slen);
un->sun_path[slen] = '\0';
- slen += sizeof (sa_family_t);
+ slen = sizeof (struct sockaddr_un);
+#if HAVE_SOCKADDR_IN_SIN_LEN
+ un->sun_len = (u_char) slen;
+#endif
#if LINUX
un->sun_path[0] = '\0';
- slen = sizeof (struct sockaddr_un);
#endif
ret = GNUNET_malloc (sizeof (struct GNUNET_CONNECTION_Handle));
ret->cfg = cfg;
{
/* Just return; we expect everything to work eventually so don't fail HARD */
GNUNET_break (GNUNET_OK == GNUNET_NETWORK_socket_close (ret->sock));
- GNUNET_free (ret->addr);
- GNUNET_free (ret->write_buffer);
- GNUNET_free (ret);
- return NULL;
+ ret->sock = NULL;
+ return ret;
}
connect_success_continuation (ret);
return ret;
{
/* 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;
}
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))
{
struct GNUNET_CONNECTION_Handle *sock = cls;
GNUNET_CONNECTION_TransmitReadyNotify notify;
+#if DEBUG_CONNECTION
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Transmission request of size %u fails (%s/%u), connection failed (%p).\n",
sock->nth.notify_size,
sock->hostname,
sock->port,
sock);
-#if DEBUG_CONNECTION
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Transmission request of size %u fails, connection failed (%p).\n",
- sock->nth.notify_size, sock);
#endif
sock->write_task = GNUNET_SCHEDULER_NO_TASK;
notify = sock->nth.notify_ready;
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))
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;
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);
}
notify, void *notify_cls)
{
if (sock->nth.notify_ready != NULL)
- return NULL;
+ {
+ GNUNET_assert (0);
+ return NULL;
+ }
GNUNET_assert (notify != NULL);
GNUNET_assert (size < GNUNET_SERVER_MAX_MESSAGE_SIZE);
GNUNET_assert (sock->write_buffer_off <= sock->write_buffer_size);
/**
- * 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