};
+struct RetryList
+{
+ /**
+ * Pointer to next element.
+ */
+ struct RetryList *next;
+
+ /**
+ * Pointer to previous element.
+ */
+ struct RetryList *prev;
+
+ /**
+ * The actual retry context.
+ */
+ struct RetrySendContext *retry_ctx;
+};
+
/**
* Network format for IPv4 addresses.
*/
* The priority of the message.
*/
unsigned int priority;
+
+ /**
+ * Entry in the DLL of retry items.
+ */
+ struct RetryList *retry_list_entry;
};
/**
};
+/**
+ * Head of retry DLL.
+ */
+static struct RetryList *retry_list_head;
+
+/**
+ * Tail of retry DLL.
+ */
+static struct RetryList *retry_list_tail;
+
/**
* Disconnect from a remote node. Clean up session if we have one for this peer
unix_transport_server_stop (void *cls)
{
struct Plugin *plugin = cls;
+ struct RetryList *pos;
+
+ pos = retry_list_head;
+
+ while(NULL != (pos = retry_list_head))
+ {
+ GNUNET_CONTAINER_DLL_remove(retry_list_head, retry_list_tail, pos);
+ if (GNUNET_SCHEDULER_NO_TASK != pos->retry_ctx->retry_task)
+ {
+ GNUNET_SCHEDULER_cancel(pos->retry_ctx->retry_task);
+ }
+ GNUNET_free(pos->retry_ctx->msg);
+ GNUNET_free(pos->retry_ctx->addr);
+ GNUNET_free(pos->retry_ctx);
+ GNUNET_free(pos);
+ }
if (plugin->select_task != GNUNET_SCHEDULER_NO_TASK)
{
{
struct RetrySendContext *retry_ctx = cls;
- if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
- return;
+ if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
+ {
+ GNUNET_free(retry_ctx->msg);
+ GNUNET_free(retry_ctx->addr);
+ GNUNET_free(retry_ctx);
+ return;
+ }
+
unix_real_send (retry_ctx->plugin,
retry_ctx,
retry_ctx->send_handle,
ssize_t sent;
const void *sb;
size_t sbs;
- struct sockaddr_un *un;
+ struct sockaddr_un un;
size_t slen;
+ struct RetryList *retry_list_entry;
if (send_handle == NULL)
{
sizeof (struct GNUNET_PeerIdentity));
memcpy (&message[1], msgbuf, msgbuf_size);
- un = GNUNET_malloc (sizeof (struct sockaddr_un));
- un->sun_family = AF_UNIX;
+ memset(&un, 0, sizeof(un));
+ un.sun_family = AF_UNIX;
slen = strlen (addr) + 1;
sent = 0;
- GNUNET_assert(slen < sizeof(un->sun_path));
- memcpy (un->sun_path, addr, slen);
- un->sun_path[slen] = '\0';
+ GNUNET_assert(slen < sizeof(un.sun_path));
+ memcpy (un.sun_path, addr, slen);
+ un.sun_path[slen] = '\0';
#if LINUX
- un->sun_path[0] = '\0';
+ un.sun_path[0] = '\0';
#endif
slen += sizeof (sa_family_t);
- sb = (struct sockaddr*) un;
+ sb = (struct sockaddr*) &un;
sbs = slen;
sent = GNUNET_NETWORK_socket_sendto(send_handle, message, ssize, sb, sbs);
{
if (incoming_retry_context == NULL)
{
+ retry_list_entry = GNUNET_malloc(sizeof(struct RetryList));
retry_ctx = GNUNET_malloc(sizeof(struct RetrySendContext));
retry_ctx->addr = GNUNET_malloc(addrlen);
retry_ctx->msg = GNUNET_malloc(msgbuf_size);
retry_ctx->timeout = GNUNET_TIME_relative_to_absolute(timeout);
memcpy(&retry_ctx->target, target, sizeof(struct GNUNET_PeerIdentity));
retry_ctx->delay = GNUNET_TIME_UNIT_MILLISECONDS;
+ retry_ctx->retry_list_entry = retry_list_entry;
+ retry_list_entry->retry_ctx = retry_ctx;
+ GNUNET_CONTAINER_DLL_insert(retry_list_head, retry_list_tail, retry_list_entry);
}
else
{
(sent < 0) ? STRERROR (errno) : "ok");
#endif
GNUNET_log_strerror (GNUNET_ERROR_TYPE_DEBUG, "send");
+ GNUNET_free(message);
return ssize;
}
- if (incoming_retry_context != NULL)
- {
- GNUNET_free(incoming_retry_context->msg);
- GNUNET_free(incoming_retry_context->addr);
- GNUNET_free(incoming_retry_context);
- }
#if DEBUG_UNIX
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"UNIX transmit %u-byte message to %s (%d: %s)\n",
}
}
+ if (incoming_retry_context != NULL)
+ {
+ GNUNET_CONTAINER_DLL_remove(retry_list_head, retry_list_tail, incoming_retry_context->retry_list_entry);
+ GNUNET_free(incoming_retry_context->retry_list_entry);
+ GNUNET_free(incoming_retry_context->msg);
+ GNUNET_free(incoming_retry_context->addr);
+ GNUNET_free(incoming_retry_context);
+ }
+
GNUNET_free (message);
return sent;
}
* @param plugin the main plugin for this transport
* @param sender from which peer the message was received
* @param currhdr pointer to the header of the message
- * @param sender_addr the address from which the message was received
+ * @param un the address from which the message was received
* @param fromlen the length of the address
*/
static void
char buf[65536];
struct UNIXMessage *msg;
struct GNUNET_PeerIdentity sender;
- //socklen_t fromlen;
struct sockaddr_un un;
socklen_t addrlen;
ssize_t ret;
uint16_t csize;
plugin->select_task = GNUNET_SCHEDULER_NO_TASK;
- if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
+ if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
return;
addrlen = sizeof(un);
unix_transport_server_start (void *cls)
{
struct Plugin *plugin = cls;
-
struct sockaddr *serverAddr;
socklen_t addrlen;
- int sockets_created;
- struct sockaddr_un *un;
+ struct sockaddr_un un;
size_t slen;
- un = GNUNET_malloc (sizeof (struct sockaddr_un));
- un->sun_family = AF_UNIX;
+ memset(&un, 0, sizeof(un));
+ un.sun_family = AF_UNIX;
slen = strlen (plugin->unix_socket_path) + 1;
- GNUNET_assert(slen < sizeof(un->sun_path));
- memcpy (un->sun_path, plugin->unix_socket_path, slen);
- un->sun_path[slen] = '\0';
+ GNUNET_assert(slen < sizeof(un.sun_path));
+ memcpy (un.sun_path, plugin->unix_socket_path, slen);
+ un.sun_path[slen] = '\0';
slen += sizeof (sa_family_t);
- serverAddr = (struct sockaddr*) un;
+ serverAddr = (struct sockaddr*) &un;
addrlen = slen;
- sockets_created = 0;
#if LINUX
- un->sun_path[0] = '\0';
+ un.sun_path[0] = '\0';
#endif
plugin->unix_sock.desc = GNUNET_NETWORK_socket_create (AF_UNIX, SOCK_DGRAM, 0);
if (NULL == plugin->unix_sock.desc)
{
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "socket");
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
+ return GNUNET_SYSERR;
}
- else
+ if (GNUNET_NETWORK_socket_bind (plugin->unix_sock.desc, serverAddr, addrlen) !=
+ GNUNET_OK)
{
- if (GNUNET_NETWORK_socket_bind (plugin->unix_sock.desc, serverAddr, addrlen) !=
- GNUNET_OK)
- {
+ GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
+ GNUNET_NETWORK_socket_close (plugin->unix_sock.desc);
+ plugin->unix_sock.desc = NULL;
+ return GNUNET_SYSERR;
+ }
#if DEBUG_UNIX
- GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
- "UNIX Binding failed!\n");
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
+ "unix",
+ "Bound to `%s'\n",
+ &un.sun_path[0]);
#endif
- }
- else
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Bound to `%s'\n", &un->sun_path[0]);
- if (plugin->unix_sock.desc != NULL)
- sockets_created++;
- }
-
plugin->rs = GNUNET_NETWORK_fdset_create ();
GNUNET_NETWORK_fdset_zero (plugin->rs);
GNUNET_NETWORK_fdset_set (plugin->rs,
GNUNET_SCHEDULER_NO_TASK,
GNUNET_TIME_UNIT_FOREVER_REL, plugin->rs,
NULL, &unix_plugin_select, plugin);
- return sockets_created;
+ return 1;
}