/*
This file is part of GNUnet
- (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors)
+ (C) 2010 2011 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
/**
* scaling factor for hello beacon
*/
-#define HALLO_BEACON_SCALING_FACTOR 1
+#define HELLO_BEACON_SCALING_FACTOR 30
+
+/**
+ * scaling factor for restarting the helper
+ */
+#define HELPER_RESTART_SCALING_FACTOR 2
/**
* max size of fragment queue
/**
* LLC fields for better compatibility
*/
-#define WLAN_LLC_DSAP_FIELD 0xf
-#define WLAN_LLC_SSAP_FIELD 0xf
+#define WLAN_LLC_DSAP_FIELD 0x1f
+#define WLAN_LLC_SSAP_FIELD 0x1f
/**
* DEBUG switch
*/
-#define DEBUG_wlan GNUNET_YES
-#define DEBUG_wlan_retransmission GNUNET_NO
+#define DEBUG_wlan GNUNET_EXTRA_LOGGING
+#define DEBUG_wlan_retransmission GNUNET_EXTRA_LOGGING
#define DEBUG_wlan_ip_udp_packets_on_air GNUNET_NO
-#define DEBUG_wlan_msg_dump GNUNET_NO
+#define DEBUG_wlan_msg_dump GNUNET_EXTRA_LOGGING
#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */
u_int8_t i_addr3[IEEE80211_ADDR_LEN];
u_int8_t i_seq[2];
u_int8_t llc[4];
-#if DEBUG_wlan_ip_udp_packets_on_air
+#if DEBUG_wlan_ip_udp_packets_on_air > 1
struct iph ip;
struct udphdr udp;
#endif
*/
char *interface;
+ /**
+ * Mode of operation for the helper, 0 = normal, 1 = first loopback, 2 = second loopback
+ */
+ long long unsigned int testmode;
+
/**
* The mac_address of the wlan card given to us by the helper.
*/
*/
struct Finish_send
{
+ /**
+ * pointer to the global plugin struct
+ */
struct Plugin *plugin;
- char *msgheader;
+
+ /**
+ * head of the next part to send to the helper
+ */
+ char *head_of_next_write;
+
+ /**
+ * Start of the message to send, needed for free
+ */
struct GNUNET_MessageHeader *msgstart;
+
+ /**
+ * rest size to send
+ */
ssize_t size;
};
static struct MacEndpoint *
create_macendpoint (struct Plugin *plugin, const struct MacAddress *addr);
+static void
+finish_sending (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+
/**
* Generates a nice hexdump of a memory area.
*
t += sprintf (t, "%02X", src[j] & 0xff);
else
t += sprintf (t, " ");
+
t += sprintf (t, j % 2 ? " " : "-");
}
while (queue != NULL)
{
- GNUNET_assert (queue->sessions_head != NULL);
+ //GNUNET_assert (queue->sessions_head != NULL);
if (memcmp (addr, &queue->addr, sizeof (struct MacAddress)) == 0)
return queue; /* session found */
queue = queue->next;
struct Sessionqueue *queue = cls;
GNUNET_assert (queue != NULL);
- GNUNET_assert(queue->content != NULL);
+ GNUNET_assert (queue->content != NULL);
queue->content->timeout_task = GNUNET_SCHEDULER_NO_TASK;
if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
{
(queue->content->last_activity, SESSION_TIMEOUT)).rel_value == 0)
{
- GNUNET_assert(queue->content->mac != NULL);
- GNUNET_assert(queue->content->mac->plugin != NULL);
- GNUNET_STATISTICS_update (queue->content->mac->plugin->env->stats, _("# wlan session timeouts"), 1, GNUNET_NO);
+ GNUNET_assert (queue->content->mac != NULL);
+ GNUNET_assert (queue->content->mac->plugin != NULL);
+ GNUNET_STATISTICS_update (queue->content->mac->plugin->env->stats,
+ _("# wlan session timeouts"), 1, GNUNET_NO);
free_session (queue->content->mac->plugin, queue, GNUNET_YES);
}
else
{
GNUNET_assert (endpoint != NULL);
GNUNET_assert (plugin != NULL);
- GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan session created"), 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan session created"), 1,
+ GNUNET_NO);
struct Sessionqueue *queue =
GNUNET_malloc (sizeof (struct Sessionqueue) + sizeof (struct Session));
GNUNET_CONTAINER_DLL_insert_tail (plugin->pending_Sessions_head,
plugin->pending_Sessions_tail, queue);
plugin->pendingsessions++;
- GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan pending sessions"), plugin->pendingsessions, GNUNET_NO);
+ GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
+ plugin->pendingsessions, GNUNET_NO);
}
}
GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS,
- HALLO_BEACON_SCALING_FACTOR));
+ HELLO_BEACON_SCALING_FACTOR));
}
//under 30 known peers: every 10 seconds
else if (plugin->mac_count < 30)
GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_SECONDS,
- 10 * HALLO_BEACON_SCALING_FACTOR));
+ 10 * HELLO_BEACON_SCALING_FACTOR));
}
//over 30 known peers: once a minute
else
GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
GNUNET_TIME_relative_multiply
(GNUNET_TIME_UNIT_MINUTES,
- HALLO_BEACON_SCALING_FACTOR));
+ HELLO_BEACON_SCALING_FACTOR));
}
}
pm = session->pending_message_head;
if (pm == NULL)
- {
+ {
#if DEBUG_wlan
- GNUNET_log_from(GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
- "pending message is empty, should not happen. session %p\n",
- session);
+ GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+ "pending message is empty, should not happen. session %p\n",
+ session);
#endif
- sessionqueue_alt = sessionqueue;
- sessionqueue = sessionqueue->next;
- plugin->pendingsessions--;
- GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan pending sessions"), plugin->pendingsessions, GNUNET_NO);
- GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
- plugin->pending_Sessions_tail,
- sessionqueue_alt);
+ sessionqueue_alt = sessionqueue;
+ sessionqueue = sessionqueue->next;
+ plugin->pendingsessions--;
+ GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
+ plugin->pendingsessions, GNUNET_NO);
+ GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
+ plugin->pending_Sessions_tail,
+ sessionqueue_alt);
- GNUNET_free (sessionqueue_alt);
- continue;
+ GNUNET_free (sessionqueue_alt);
+ continue;
- }
+ }
//check for message timeout
if (GNUNET_TIME_absolute_get_remaining (pm->timeout).rel_value > 0)
FRAGMENT_QUEUE_MESSAGES_OUT_PER_SESSION))
{
plugin->pendingsessions--;
- GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan pending sessions"), plugin->pendingsessions, GNUNET_NO);
+ GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
+ plugin->pendingsessions, GNUNET_NO);
GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
plugin->pending_Sessions_tail,
sessionqueue);
sessionqueue_alt = sessionqueue;
sessionqueue = sessionqueue->next;
plugin->pendingsessions--;
- GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan pending sessions"), plugin->pendingsessions, GNUNET_NO);
+ GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
+ plugin->pendingsessions, GNUNET_NO);
GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
plugin->pending_Sessions_tail,
sessionqueue_alt);
struct FragmentMessage_queue *fmq;
struct FragmentMessage_queue *fmq_next;
- if (fm != NULL)
+ fmq = plugin->sending_messages_head;
+ while (fmq != NULL)
{
- fmq = plugin->sending_messages_head;
- while (fmq != NULL)
+ fmq_next = fmq->next;
+ if (fmq->content == fm)
{
- fmq_next = fmq->next;
- if (fmq->content == fm)
- {
- GNUNET_CONTAINER_DLL_remove (plugin->sending_messages_head,
- plugin->sending_messages_tail, fmq);
- GNUNET_free (fmq);
- }
- fmq = fmq_next;
+ GNUNET_CONTAINER_DLL_remove (plugin->sending_messages_head,
+ plugin->sending_messages_tail, fmq);
+ GNUNET_free (fmq);
}
+ fmq = fmq_next;
+ }
+
+ (session->mac->fragment_messages_out_count)--;
+ session->fragment_messages_out_count--;
+ plugin->pending_Fragment_Messages--;
+ GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending fragments"),
+ plugin->pending_Fragment_Messages, GNUNET_NO);
+ GNUNET_CONTAINER_DLL_remove (endpoint->sending_messages_head,
+ endpoint->sending_messages_tail, fm);
+ GNUNET_FRAGMENT_context_destroy (fm->fragcontext);
+ if (fm->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (fm->timeout_task);
+ fm->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ GNUNET_free (fm);
- (session->mac->fragment_messages_out_count)--;
- session->fragment_messages_out_count--;
- plugin->pending_Fragment_Messages--;
- GNUNET_CONTAINER_DLL_remove (endpoint->sending_messages_head,
- endpoint->sending_messages_tail, fm);
- GNUNET_FRAGMENT_context_destroy (fm->fragcontext);
- if (fm->timeout_task != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (fm->timeout_task);
- GNUNET_free (fm);
-
- queue_session (plugin, session);
+ queue_session (plugin, session);
#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "Free pending fragment messages %p, session %p\n", fm,
- session);
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+ "Free pending fragment messages %p, session %p\n", fm,
+ session);
#endif
- }
}
/**
Header->llc[0] = WLAN_LLC_DSAP_FIELD;
Header->llc[1] = WLAN_LLC_SSAP_FIELD;
-#if DEBUG_wlan_ip_udp_packets_on_air
+#if DEBUG_wlan_ip_udp_packets_on_air > 1
uint crc = 0;
uint16_t *x;
int count;
struct GNUNET_MessageHeader *msgheader2;
uint16_t size;
-#if DEBUG_wlan_retransmission
+#if DEBUG_wlan_retransmission > 1
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
"Adding fragment of message %p to send, session %p, endpoint %p, type %u\n",
fm, fm->session, endpoint, hdr->type);
set_next_send (plugin);
}
+
/**
- * function to send a hallo beacon
- * @param plugin pointer to the plugin struct
+ * We have been notified that wlan-helper has written something to stdout.
+ * Handle the output, then reschedule this function to be called again once
+ * more is available.
+ *
+ * @param cls the plugin handle
+ * @param tc the scheduling context
*/
static void
-send_hello_beacon (struct Plugin *plugin)
+wlan_plugin_helper_read (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
{
+ struct Plugin *plugin = cls;
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "Sending hello beacon\n");
-#endif
-
- uint16_t size;
- ssize_t bytes;
- uint16_t hallo_size;
- struct GNUNET_MessageHeader *msgheader;
- struct ieee80211_frame *ieeewlanheader;
- struct Radiotap_Send *radioHeader;
- struct GNUNET_MessageHeader *msgheader2;
- const struct GNUNET_MessageHeader *hello;
-
- GNUNET_assert (plugin != NULL);
-
- GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan hello beacons send"), 1, GNUNET_NO);
-
- hello = plugin->env->get_our_hello ();
- hallo_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello);
- GNUNET_assert (sizeof (struct WlanHeader) + hallo_size <= WLAN_MTU);
- size =
- sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
- sizeof (struct ieee80211_frame) + hallo_size;
-
- msgheader = GNUNET_malloc (size);
- msgheader->size = htons (size);
- msgheader->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
-
- radioHeader = (struct Radiotap_Send *) &msgheader[1];
- getRadiotapHeader (plugin, NULL, radioHeader);
- ieeewlanheader = (struct ieee80211_frame *) &radioHeader[1];
- getWlanHeader (ieeewlanheader, &bc_all_mac, plugin, size);
-
- msgheader2 = (struct GNUNET_MessageHeader *) &ieeewlanheader[1];
- /*msgheader2->size =
- htons (GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello) +
- sizeof (struct GNUNET_MessageHeader));
+ plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
- msgheader2->type = htons (GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT);*/
- memcpy (msgheader2, hello, hallo_size);
+ if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+ return;
- bytes = GNUNET_DISK_file_write (plugin->server_stdin_handle, msgheader, size);
+ char mybuf[WLAN_MTU + sizeof (struct GNUNET_MessageHeader)];
+ ssize_t bytes;
- if (bytes == GNUNET_SYSERR)
+ bytes =
+ GNUNET_DISK_file_read (plugin->server_stdout_handle, mybuf,
+ sizeof (mybuf));
+ if (bytes <= 0)
{
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+#if DEBUG_wlan
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
_
- ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
- errno, strerror (errno));
-
+ ("Finished reading from wlan-helper stdout with code: %d\n"),
+ bytes);
+#endif
+ return;
}
- GNUNET_assert (bytes != GNUNET_SYSERR);
- GNUNET_assert (bytes == size);
- GNUNET_free (msgheader);
+ GNUNET_SERVER_mst_receive (plugin->suid_tokenizer, NULL, mybuf, bytes,
+ GNUNET_NO, GNUNET_NO);
- set_next_beacon_time (plugin);
- set_next_send (plugin);
+ GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
+ plugin->server_read_task =
+ GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+ plugin->server_stdout_handle,
+ &wlan_plugin_helper_read, plugin);
}
/**
- * function to add an ack to send it for a received fragment
- * @param cls MacEndpoint this ack belongs to
- * @param msg_id id of the message
- * @param hdr pointer to the hdr where the ack is stored
+ * Start the gnunet-wlan-helper process.
*
+ * @param plugin the transport plugin
+ * @return GNUNET_YES if process was started, GNUNET_SYSERR on error
*/
-
-static void
-add_ack_for_send (void *cls, uint32_t msg_id,
- const struct GNUNET_MessageHeader *hdr)
+static int
+wlan_transport_start_wlan_helper (struct Plugin *plugin)
{
+ const char *filenamehw = "gnunet-transport-wlan-helper";
+ char *filenameloopback = "gnunet-transport-wlan-helper-dummy";
+ char *absolute_filename = NULL;
- struct AckSendQueue *ack;
+ plugin->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES);
+ if (plugin->server_stdout == NULL)
+ return GNUNET_SYSERR;
- GNUNET_assert (cls != NULL);
- struct MacEndpoint *endpoint = cls;
- struct Plugin *plugin = endpoint->plugin;
- struct GNUNET_MessageHeader *msgheader;
- struct GNUNET_MessageHeader *msgheader2;
- uint16_t size;
+ plugin->server_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO);
+ if (plugin->server_stdin == NULL)
+ return GNUNET_SYSERR;
- size =
- sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
- sizeof (struct ieee80211_frame) + ntohs (hdr->size) +
- sizeof (struct AckSendQueue);
+ if ((plugin->testmode == 1) || (plugin->testmode == 2))
+ {
+ if (GNUNET_OS_check_helper_binary (filenameloopback) == GNUNET_YES)
+ {
+ absolute_filename = strdup (filenameloopback);
+ }
+ else
+ {
+ char cwd[FILENAME_MAX];
- ack = GNUNET_malloc (size);
- ack->message_id = msg_id;
- ack->endpoint = endpoint;
+ GNUNET_assert (getcwd (cwd, sizeof (cwd)) != NULL);
- size =
- sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
- sizeof (struct ieee80211_frame) + ntohs (hdr->size);
+ GNUNET_asprintf (&absolute_filename, "%s%s%s", cwd, DIR_SEPARATOR_STR,
+ filenameloopback);
- msgheader = (struct GNUNET_MessageHeader *) &ack[1];
- ack->hdr = (struct GNUNET_MessageHeader *) &ack[1];
- msgheader->size = htons (size);
- msgheader->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
+ if (GNUNET_DISK_file_test (filenameloopback) != GNUNET_YES)
+ {
+ GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+ "Helper `%s' not found! %i\n", absolute_filename);
+ GNUNET_break (0);
+ }
+ }
+ }
- ack->radioHeader = (struct Radiotap_Send *) &msgheader[1];
- ack->ieeewlanheader = (struct ieee80211_frame *) &(ack->radioHeader)[1];
- msgheader2 = (struct GNUNET_MessageHeader *) &(ack->ieeewlanheader)[1];
- memcpy (msgheader2, hdr, ntohs (hdr->size));
+ /* Start the server process */
- GNUNET_CONTAINER_DLL_insert_tail (plugin->ack_send_queue_head,
- plugin->ack_send_queue_tail, ack);
+ if (plugin->testmode == 0)
+ {
-#if DEBUG_wlan_retransmission
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "Adding ack with message id %u to send, AckSendQueue %p, endpoint %p\n",
- msg_id, ack, endpoint);
+#if DEBUG_wlan
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+ "Starting gnunet-wlan-helper process cmd: %s %s %i\n",
+ filenamehw, plugin->interface, plugin->testmode);
#endif
- set_next_send (plugin);
-}
+ if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_YES)
+ {
+ plugin->server_proc =
+ GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
+ filenamehw, filenamehw, plugin->interface,
+ NULL);
+ }
+ else if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_NO)
+ {
+ GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+ "gnunet-transport-wlan-helper is not suid, please change it or look at the doku\n");
+ GNUNET_break (0);
+ }
+ else
+ {
+ GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+ "gnunet-transport-wlan-helper not found, please look if it exists and is the $PATH variable!\n");
+ GNUNET_break (0);
+ }
-/**
- * Function for the scheduler if a FragmentMessage times out
- * @param cls pointer to the FragmentMessage
- * @param tc pointer to the GNUNET_SCHEDULER_TaskContext
- */
-static void
-fragmentmessage_timeout (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct FragmentMessage *fm = cls;
+ }
+ else if (plugin->testmode == 1)
+ {
- GNUNET_assert (fm != NULL);
- fm->timeout_task = GNUNET_SCHEDULER_NO_TASK;
- if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
+#if DEBUG_wlan
+ GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME,
+ "Starting gnunet-wlan-helper loopback 1 process cmd: %s %s %i\n",
+ absolute_filename, plugin->interface, plugin->testmode);
+#endif
+ plugin->server_proc =
+ GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
+ absolute_filename, absolute_filename, "1",
+ NULL);
+ if (plugin->server_proc == NULL)
+ {
+ GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+ "`%s' not found, please look if it exists and is in the $PATH variable!\n",
+ absolute_filename);
+ GNUNET_break (0);
+ }
+ }
+ else if (plugin->testmode == 2)
{
- return;
+#if DEBUG_wlan
+ GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME,
+ "Starting gnunet-wlan-helper loopback 2 process cmd: %s %s %i\n",
+ absolute_filename, plugin->interface, plugin->testmode);
+#endif
+
+ plugin->server_proc =
+ GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
+ absolute_filename, absolute_filename, "2",
+ NULL);
+ if (plugin->server_proc == NULL)
+ {
+ GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+ "`%s' not found, please look if it exists and is in the $PATH variable!\n",
+ absolute_filename);
+ GNUNET_break (0);
+ }
+ }
+ if (absolute_filename != NULL)
+ GNUNET_free (absolute_filename);
+ if (plugin->server_proc == NULL)
+ {
+#if DEBUG_wlan
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+ "Failed to start gnunet-wlan-helper process\n");
+#endif
+ return GNUNET_SYSERR;
}
- free_fragment_message (fm->session->mac->plugin, fm);
-}
-/**
- * Function to check if there is some space in the fragment queue
- * inserts a message if space is available
- * @param plugin the plugin struct
- */
-static void
-check_fragment_queue (struct Plugin *plugin)
-{
- struct Session *session;
- struct FragmentMessage *fm;
- struct GNUNET_PeerIdentity pid;
- struct PendingMessage *pm;
+ /* Close the write end of the read pipe */
+ GNUNET_DISK_pipe_close_end (plugin->server_stdout,
+ GNUNET_DISK_PIPE_END_WRITE);
+
+ /* Close the read end of the write pipe */
+ GNUNET_DISK_pipe_close_end (plugin->server_stdin, GNUNET_DISK_PIPE_END_READ);
+
+ plugin->server_stdout_handle =
+ GNUNET_DISK_pipe_handle (plugin->server_stdout,
+ GNUNET_DISK_PIPE_END_READ);
+ plugin->server_stdin_handle =
+ GNUNET_DISK_pipe_handle (plugin->server_stdin,
+ GNUNET_DISK_PIPE_END_WRITE);
+
+ GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
+
+#if DEBUG_wlan
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+ "Adding server_read_task for the wlan-helper\n");
+#endif
+
+ plugin->server_read_task =
+ GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+ plugin->server_stdout_handle,
+ &wlan_plugin_helper_read, plugin);
+
+ return GNUNET_YES;
+}
+
+/**
+ * Stops the gnunet-wlan-helper process.
+ *
+ * @param plugin the transport plugin
+ * @return GNUNET_YES if process was started, GNUNET_SYSERR on error
+ */
+static int
+wlan_transport_stop_wlan_helper (struct Plugin *plugin)
+{
+#if DEBUG_wlan
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+ "Stoping WLAN helper process\n");
+#endif
+
+ if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (plugin->server_write_delay_task);
+ plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ if (plugin->server_write_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (plugin->server_write_task);
+ plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ if (plugin->server_read_task != GNUNET_SCHEDULER_NO_TASK)
+ {
+ GNUNET_SCHEDULER_cancel (plugin->server_read_task);
+ plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ GNUNET_DISK_pipe_close (plugin->server_stdout);
+ GNUNET_DISK_pipe_close (plugin->server_stdin);
+ GNUNET_OS_process_kill (plugin->server_proc, SIGKILL);
+ GNUNET_OS_process_wait (plugin->server_proc);
+ GNUNET_OS_process_close (plugin->server_proc);
+
+ return GNUNET_YES;
+}
+
+/**
+ * function for delayed restart of the helper process
+ * @param cls Finish_send struct if message should be finished
+ * @param tc TaskContext
+ */
+static void
+delay_restart_helper (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct Finish_send *finish = cls;
+ struct Plugin *plugin;
+
+ plugin = finish->plugin;
+
+ plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
+ if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
+ {
+ GNUNET_free_non_null (finish->msgstart);
+ GNUNET_free (finish);
+ return;
+ }
+
+ wlan_transport_start_wlan_helper (plugin);
+
+ if (finish->size != 0)
+ {
+ plugin->server_write_task =
+ GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
+ plugin->server_stdin_handle,
+ &finish_sending, finish);
+ }
+ else
+ {
+ set_next_send (plugin);
+ GNUNET_free_non_null (finish->msgstart);
+ GNUNET_free (finish);
+ }
+
+}
+
+/**
+ * Function to restart the helper
+ * @param plugin pointer to the global plugin struct
+ * @param finish pointer to the Finish_send struct to finish
+ */
+static void
+restart_helper (struct Plugin *plugin, struct Finish_send *finish)
+{
+ static struct GNUNET_TIME_Relative next_try = { 1000 };
+ GNUNET_assert (finish != NULL);
+
+ wlan_transport_stop_wlan_helper (plugin);
+ plugin->server_write_task =
+ GNUNET_SCHEDULER_add_delayed (next_try, &delay_restart_helper, finish);
+ GNUNET_TIME_relative_multiply (next_try, HELPER_RESTART_SCALING_FACTOR);
+
+}
+
+/**
+ * function to finish a sending if not all could have been writen befor
+ * @param cls pointer to the Finish_send struct
+ * @param tc TaskContext
+ */
+static void
+finish_sending (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct Finish_send *finish = cls;
+ struct Plugin *plugin;
+ ssize_t bytes;
+
+ plugin = finish->plugin;
+ plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
+
+ if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
+ {
+ GNUNET_free (finish->msgstart);
+ GNUNET_free (finish);
+ return;
+ }
+ bytes =
+ GNUNET_DISK_file_write (plugin->server_stdin_handle,
+ finish->head_of_next_write, finish->size);
+
+ if (bytes != finish->size)
+ {
+ if (bytes != GNUNET_SYSERR)
+ {
+ finish->head_of_next_write += bytes;
+ finish->size -= bytes;
+ plugin->server_write_task =
+ GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
+ plugin->server_stdin_handle,
+ &finish_sending, finish);
+ }
+ else
+ {
+ restart_helper (plugin, finish);
+ }
+ }
+ else
+ {
+ GNUNET_free (finish->msgstart);
+ GNUNET_free (finish);
+ set_next_send (plugin);
+ }
+}
+
+/**
+ * function to send a hello beacon
+ * @param plugin pointer to the plugin struct
+ */
+static void
+send_hello_beacon (struct Plugin *plugin)
+{
+
+#if DEBUG_wlan
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+ "Sending hello beacon\n");
+#endif
+
+ uint16_t size;
+ ssize_t bytes;
+ uint16_t hello_size;
+ struct GNUNET_MessageHeader *msgheader;
+ struct ieee80211_frame *ieeewlanheader;
+ struct Radiotap_Send *radioHeader;
+ struct GNUNET_MessageHeader *msgheader2;
+ const struct GNUNET_MessageHeader *hello;
+ struct Finish_send *finish;
+
+ GNUNET_assert (plugin != NULL);
+
+ GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan hello beacons send"),
+ 1, GNUNET_NO);
+
+ hello = plugin->env->get_our_hello ();
+ hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello);
+ GNUNET_assert (sizeof (struct WlanHeader) + hello_size <= WLAN_MTU);
+ size =
+ sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
+ sizeof (struct ieee80211_frame) + hello_size;
+
+ msgheader = GNUNET_malloc (size);
+ msgheader->size = htons (size);
+ msgheader->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
+
+ radioHeader = (struct Radiotap_Send *) &msgheader[1];
+ getRadiotapHeader (plugin, NULL, radioHeader);
+ ieeewlanheader = (struct ieee80211_frame *) &radioHeader[1];
+ getWlanHeader (ieeewlanheader, &bc_all_mac, plugin, size);
+
+ msgheader2 = (struct GNUNET_MessageHeader *) &ieeewlanheader[1];
+ /*msgheader2->size =
+ * htons (GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello) +
+ * sizeof (struct GNUNET_MessageHeader));
+ *
+ * msgheader2->type = htons (GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT); */
+ memcpy (msgheader2, hello, hello_size);
+
+ bytes = GNUNET_DISK_file_write (plugin->server_stdin_handle, msgheader, size);
+
+ if (bytes == GNUNET_SYSERR)
+ {
+ GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+ _
+ ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
+ errno, strerror (errno));
+ finish = GNUNET_malloc (sizeof (struct Finish_send));
+ finish->plugin = plugin;
+ finish->head_of_next_write = NULL;
+ finish->size = 0;
+ finish->msgstart = NULL;
+ restart_helper (plugin, finish);
+
+ set_next_beacon_time (plugin);
+
+ }
+ else
+ {
+ GNUNET_assert (bytes == size);
+ set_next_beacon_time (plugin);
+ set_next_send (plugin);
+ }
+ GNUNET_free (msgheader);
+
+
+}
+
+/**
+ * function to add an ack to send it for a received fragment
+ * @param cls MacEndpoint this ack belongs to
+ * @param msg_id id of the message
+ * @param hdr pointer to the hdr where the ack is stored
+ *
+ */
+
+static void
+add_ack_for_send (void *cls, uint32_t msg_id,
+ const struct GNUNET_MessageHeader *hdr)
+{
+
+ struct AckSendQueue *ack;
+
+ GNUNET_assert (cls != NULL);
+ struct MacEndpoint *endpoint = cls;
+ struct Plugin *plugin = endpoint->plugin;
+ struct GNUNET_MessageHeader *msgheader;
+ struct GNUNET_MessageHeader *msgheader2;
+ uint16_t size;
+
+ size =
+ sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
+ sizeof (struct ieee80211_frame) + ntohs (hdr->size) +
+ sizeof (struct AckSendQueue);
+
+ ack = GNUNET_malloc (size);
+ ack->message_id = msg_id;
+ ack->endpoint = endpoint;
+
+ size =
+ sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
+ sizeof (struct ieee80211_frame) + ntohs (hdr->size);
+
+ msgheader = (struct GNUNET_MessageHeader *) &ack[1];
+ ack->hdr = (struct GNUNET_MessageHeader *) &ack[1];
+ msgheader->size = htons (size);
+ msgheader->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
+
+ ack->radioHeader = (struct Radiotap_Send *) &msgheader[1];
+ ack->ieeewlanheader = (struct ieee80211_frame *) &(ack->radioHeader)[1];
+ msgheader2 = (struct GNUNET_MessageHeader *) &(ack->ieeewlanheader)[1];
+ memcpy (msgheader2, hdr, ntohs (hdr->size));
+
+ GNUNET_CONTAINER_DLL_insert_tail (plugin->ack_send_queue_head,
+ plugin->ack_send_queue_tail, ack);
+
+#if DEBUG_wlan_retransmission > 1
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+ "Adding ack with message id %u to send, AckSendQueue %p, endpoint %p\n",
+ msg_id, ack, endpoint);
+#endif
+
+ set_next_send (plugin);
+}
+
+/**
+ * Function for the scheduler if a FragmentMessage times out
+ * @param cls pointer to the FragmentMessage
+ * @param tc pointer to the GNUNET_SCHEDULER_TaskContext
+ */
+static void
+fragmentmessage_timeout (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct FragmentMessage *fm = cls;
+
+ GNUNET_assert (fm != NULL);
+ fm->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+ if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
+ {
+ return;
+ }
+ free_fragment_message (fm->session->mac->plugin, fm);
+}
+
+/**
+ * Function to check if there is some space in the fragment queue
+ * inserts a message if space is available
+ * @param plugin the plugin struct
+ */
+
+static void
+check_fragment_queue (struct Plugin *plugin)
+{
+ struct Session *session;
+ struct FragmentMessage *fm;
+ struct GNUNET_PeerIdentity pid;
+
+ struct PendingMessage *pm;
if (plugin->pending_Fragment_Messages < FRAGMENT_QUEUE_SIZE)
{
if (session != NULL)
{
pm = session->pending_message_head;
+ GNUNET_assert (pm != NULL);
GNUNET_CONTAINER_DLL_remove (session->pending_message_head,
session->pending_message_tail, pm);
session->mac->fragment_messages_out_count++;
session->fragment_messages_out_count++;
plugin->pending_Fragment_Messages++;
- GNUNET_assert (pm != NULL);
+ GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending fragments"),
+ plugin->pending_Fragment_Messages, GNUNET_NO);
fm = GNUNET_malloc (sizeof (struct FragmentMessage));
fm->session = session;
/**
* Function to send an ack, does not free the ack
* @param plugin pointer to the plugin
- * @param ack pointer to the ack to send
*/
static void
-send_ack (struct Plugin *plugin, struct AckSendQueue *ack)
+send_ack (struct Plugin *plugin)
{
ssize_t bytes;
+ struct AckSendQueue *ack;
+ struct Finish_send *finish;
+
+ ack = plugin->ack_send_queue_head;
+
#if DEBUG_wlan
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
#endif
GNUNET_assert (plugin != NULL);
- GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan acks send"), 1, GNUNET_NO);
-
- getRadiotapHeader (plugin, ack->endpoint, ack->radioHeader);
- getWlanHeader (ack->ieeewlanheader, &ack->endpoint->addr, plugin,
- ntohs (ack->hdr->size));
-
- bytes =
- GNUNET_DISK_file_write (plugin->server_stdin_handle, ack->hdr,
- ntohs (ack->hdr->size));
- if (bytes == GNUNET_SYSERR)
- {
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
- _
- ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
- errno, strerror (errno));
+ GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan acks send"), 1,
+ GNUNET_NO);
- }
- GNUNET_assert (bytes != GNUNET_SYSERR);
- GNUNET_assert (bytes == ntohs (ack->hdr->size));
- set_next_send (plugin);
-}
-
-/**
- * function to finish a sending if not all could have been writen befor
- * @param cls pointer to the Finish_send struct
- * @param tc TaskContext
- */
-static void
-finish_sending (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct Finish_send *finish = cls;
- struct Plugin *plugin;
- ssize_t bytes;
-
- plugin = finish->plugin;
- plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
-
- if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
- {
- GNUNET_free (finish->msgstart);
- GNUNET_free (finish);
- return;
- }
- bytes =
- GNUNET_DISK_file_write (plugin->server_stdin_handle, finish->msgheader,
- finish->size);
- GNUNET_assert (bytes != GNUNET_SYSERR);
+ getRadiotapHeader (plugin, ack->endpoint, ack->radioHeader);
+ getWlanHeader (ack->ieeewlanheader, &ack->endpoint->addr, plugin,
+ ntohs (ack->hdr->size));
- if (bytes != finish->size)
+ bytes =
+ GNUNET_DISK_file_write (plugin->server_stdin_handle, ack->hdr,
+ ntohs (ack->hdr->size));
+ if (bytes == GNUNET_SYSERR)
{
- finish->msgheader = finish->msgheader + bytes;
- finish->size = finish->size - bytes;
- plugin->server_write_task =
- GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
- plugin->server_stdin_handle,
- &finish_sending, finish);
+ GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+ _
+ ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
+ errno, strerror (errno));
+ finish = GNUNET_malloc (sizeof (struct Finish_send));
+ finish->plugin = plugin;
+ finish->head_of_next_write = NULL;
+ finish->size = 0;
+ finish->msgstart = NULL;
+ restart_helper (plugin, finish);
}
else
{
- GNUNET_free (finish->msgstart);
- GNUNET_free (finish);
+ GNUNET_assert (bytes == ntohs (ack->hdr->size));
+ GNUNET_CONTAINER_DLL_remove (plugin->ack_send_queue_head,
+ plugin->ack_send_queue_tail, ack);
+ GNUNET_free (ack);
set_next_send (plugin);
}
}
do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
struct Plugin *plugin = cls;
+
GNUNET_assert (plugin != NULL);
plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
struct FragmentMessage *fm;
struct Finish_send *finish;
struct FragmentMessage_queue *fmq;
- struct AckSendQueue *ack;
ssize_t bytes;
if (plugin->ack_send_queue_head != NULL)
{
- ack = plugin->ack_send_queue_head;
- GNUNET_CONTAINER_DLL_remove (plugin->ack_send_queue_head,
- plugin->ack_send_queue_tail, ack);
- send_ack (plugin, ack);
- GNUNET_free (ack);
+ send_ack (plugin);
return;
}
if (plugin->sending_messages_head != NULL)
{
- GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan fragments send"), 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan fragments send"), 1,
+ GNUNET_NO);
fmq = plugin->sending_messages_head;
fm = fmq->content;
bytes =
GNUNET_DISK_file_write (plugin->server_stdin_handle, fm->frag,
fm->size);
- if (bytes == GNUNET_SYSERR)
- {
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
- _
- ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
- errno, strerror (errno));
- }
- GNUNET_assert (bytes != GNUNET_SYSERR);
if (bytes != fm->size)
{
finish = GNUNET_malloc (sizeof (struct Finish_send));
finish->plugin = plugin;
- finish->msgheader = fm->frag + bytes;
- finish->size = fm->size - bytes;
finish->msgstart = (struct GNUNET_MessageHeader *) fm->frag;
-
GNUNET_assert (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK);
- plugin->server_write_task =
- GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
- plugin->server_stdin_handle,
- &finish_sending, finish);
+ if (bytes == GNUNET_SYSERR)
+ {
+ GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+ _
+ ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
+ errno, strerror (errno));
+
+ finish->head_of_next_write = fm->frag;
+ finish->size = fm->size;
+ restart_helper (plugin, finish);
+ }
+ else
+ {
+ finish->head_of_next_write = fm->frag + bytes;
+ finish->size = fm->size - bytes;
+ plugin->server_write_task =
+ GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
+ plugin->server_stdin_handle,
+ &finish_sending, finish);
+ }
+
fm->frag = NULL;
}
else
/* TODO check for bad addresses like multicast, broadcast, etc */
#if DEBUG_wlan
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "wlan_plugin_address_suggested got good address, size %u!\n", addrlen);
+ "wlan_plugin_address_suggested got good address, size %u!\n",
+ addrlen);
#endif
return GNUNET_OK;
}
#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "wlan_plugin_address_suggested got bad address, size %u!\n", addrlen);
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+ "wlan_plugin_address_suggested got bad address, size %u!\n",
+ addrlen);
#endif
return GNUNET_SYSERR;
}
struct Plugin *plugin = cls;
struct PendingMessage *newmsg;
struct WlanHeader *wlanheader;
+
GNUNET_assert (plugin != NULL);
//check if msglen > 0
GNUNET_assert (msgbuf_size > 0);
}
}
- GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan messages queued"), 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan messages queued"), 1,
+ GNUNET_NO);
//queue message:
if (session->pending_message_head != NULL)
{
newmsg = session->pending_message_head;
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
"wlan_plugin_send: a pending message is already in the queue for this client\n remaining time to send this message is %u, queued fragment messages for this mac connection %u\n",
GNUNET_TIME_absolute_get_remaining (newmsg->
timeout).rel_value,
"New message for %p with size (incl wlan header) %u added\n",
session, newmsg->message_size);
#endif
-#if DEBUG_wlan_msg_dump
+#if DEBUG_wlan_msg_dump > 1
hexdump (msgbuf, GNUNET_MIN (msgbuf_size, 256));
#endif
//queue session
GNUNET_CONTAINER_DLL_remove (plugin->mac_head, plugin->mac_tail, endpoint);
if (endpoint->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+ {
GNUNET_SCHEDULER_cancel (endpoint->timeout_task);
+ endpoint->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ plugin->mac_count--;
+ GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan mac endpoints"),
+ plugin->mac_count, GNUNET_NO);
GNUNET_free (endpoint);
}
if (pendingsession_tmp->content == queue->content)
{
plugin->pendingsessions--;
- GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan pending sessions"), plugin->pendingsessions, GNUNET_NO);
+ GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
+ plugin->pendingsessions, GNUNET_NO);
GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
plugin->pending_Sessions_tail,
pendingsession_tmp);
GNUNET_CONTAINER_DLL_remove (endpoint->sessions_head, endpoint->sessions_tail,
queue);
-
+ //Check that no ohter session on this endpoint for this session exits
+ GNUNET_assert (search_session (plugin, endpoint, &queue->content->target) ==
+ NULL);
if (endpoint->sessions_head == NULL && do_free_macendpoint == GNUNET_YES)
{
free_macendpoint (plugin, endpoint);
+ //check if no endpoint with the same address exists
+ GNUNET_assert (get_macendpoint (plugin, &endpoint->addr, GNUNET_NO) ==
+ NULL);
}
if (queue->content->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+ {
GNUNET_SCHEDULER_cancel (queue->content->timeout_task);
+ queue->content->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+ }
GNUNET_free (queue);
+
check_fragment_queue (plugin);
}
const unsigned char *input;
//GNUNET_assert(cls !=NULL);
- if (addrlen != sizeof(struct MacAddress))
+ if (addrlen != sizeof (struct MacAddress))
{
/* invalid address (MAC addresses have 6 bytes) */
//GNUNET_break (0);
#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "Func wlan_plugin_address_pretty_printer got size: %u, worng size!\n",
- addrlen);
+ GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+ "Func wlan_plugin_address_pretty_printer got size: %u, worng size!\n",
+ addrlen);
#endif
- asc(asc_cls, NULL);
+ asc (asc_cls, NULL);
return;
}
input = (const unsigned char *) addr;
GNUNET_asprintf (&ret,
- "Transport %s: %s Mac-Address %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",type,
- PROTOCOL_PREFIX, input[0], input[1], input[2], input[3],
- input[4], input[5]);
+ "Transport %s: %s Mac-Address %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
+ type, PROTOCOL_PREFIX, input[0], input[1], input[2],
+ input[3], input[4], input[5]);
#if DEBUG_wlan
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
"Func wlan_plugin_address_pretty_printer got size: %u, nummeric %u, type %s; made string: %s\n",
addrlen, numeric, type, ret);
#endif
- asc ( asc_cls, ret);
+ asc (asc_cls, ret);
//only one mac address per plugin
- asc ( asc_cls, NULL);
+ asc (asc_cls, NULL);
}
return;
}
- GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan whole messages received"), 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (plugin->env->stats,
+ _("# wlan whole messages received"), 1,
+ GNUNET_NO);
wlanheader = (struct WlanHeader *) hdr;
session = search_session (plugin, endpoint, &wlanheader->source);
struct Session *session = (struct Session *) client;
struct Plugin *plugin = (struct Plugin *) cls;
- struct GNUNET_TRANSPORT_ATS_Information distance[2];
+ struct GNUNET_ATS_Information distance;
- distance[0].type = htonl (GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
- distance[0].value = htonl (1);
- distance[1].type = htonl (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
- distance[1].value = htonl (0);
+ distance.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+ distance.value = htonl (1);
#if DEBUG_wlan
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
#endif
plugin->env->receive (plugin->env->cls, &(session->target), hdr,
- (const struct GNUNET_TRANSPORT_ATS_Information *)
- &distance, 2, session,
- (const char *) &session->mac->addr,
+ (const struct GNUNET_ATS_Information *) &distance, 1,
+ session, (const char *) &session->mac->addr,
sizeof (session->mac->addr));
}
* @param cls the plugin handle
* @param session_light pointer to the struct holding known informations
* @param hdr hdr of the GNUNET_MessageHeader
- * @param rxinfo pointer to the radiotap informations got with this packet
+ * @param rxinfo pointer to the radiotap informations got with this packet FIXME: give ATS for info
*/
static void
wlan_data_helper (void *cls, struct Session_light *session_light,
struct FragmentMessage *fm2;
struct GNUNET_PeerIdentity tmpsource;
- GNUNET_assert(plugin != NULL);
+ GNUNET_assert (plugin != NULL);
//ADVERTISEMENT
if (ntohs (hdr->type) == GNUNET_MESSAGE_TYPE_HELLO)
if (GNUNET_HELLO_get_id
- ((const struct GNUNET_HELLO_Message *) hdr,
- &tmpsource) == GNUNET_OK)
+ ((const struct GNUNET_HELLO_Message *) hdr, &tmpsource) == GNUNET_OK)
{
- session_light->session = search_session (plugin, session_light->macendpoint, &tmpsource);
+ session_light->session =
+ search_session (plugin, session_light->macendpoint, &tmpsource);
if (session_light->session == NULL)
- {
- session_light->session = create_session (plugin, session_light->macendpoint, &tmpsource);
- }
- GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan hallo messages received"), 1, GNUNET_NO);
- plugin->env->receive(plugin->env->cls,&session_light->session->target,hdr, NULL, 0, session_light->session,
- (const char *) &session_light->session->mac->addr,
- sizeof (session_light->session->mac->addr));
+ {
+ session_light->session =
+ create_session (plugin, session_light->macendpoint, &tmpsource);
+ }
+ GNUNET_STATISTICS_update (plugin->env->stats,
+ _("# wlan hello messages received"), 1,
+ GNUNET_NO);
+ plugin->env->receive (plugin->env->cls, &session_light->session->target,
+ hdr, NULL, 0, session_light->session,
+ (const char *) &session_light->session->mac->addr,
+ sizeof (session_light->session->mac->addr));
}
else
{
6));
#endif
- GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan fragments received"), 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (plugin->env->stats,
+ _("# wlan fragments received"), 1, GNUNET_NO);
int ret =
GNUNET_DEFRAGMENT_process_fragment (session_light->macendpoint->defrag,
hdr);
while (fm != NULL)
{
fm2 = fm->next;
- GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan acks received"), 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan acks received"),
+ 1, GNUNET_NO);
int ret = GNUNET_FRAGMENT_process_ack (fm->fragcontext, hdr);
if (ret == GNUNET_OK)
{
-#if DEBUG_wlan_retransmission
+#if DEBUG_wlan_retransmission > 1
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
"Got last ack, finished fragment message %p\n", fm);
#endif
}
if (ret == GNUNET_NO)
{
-#if DEBUG_wlan_retransmission
+#if DEBUG_wlan_retransmission > 1
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
"Got ack for: %p\n", fm);
#endif
fm = fm2;
}
-#if DEBUG_wlan_retransmission
+#if DEBUG_wlan_retransmission > 1
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
"WLAN fragment not in fragment list\n");
#endif
(GNUNET_TIME_absolute_add
(endpoint->last_activity, MACENDPOINT_TIMEOUT)).rel_value == 0)
{
- GNUNET_assert(endpoint->plugin != NULL);
- GNUNET_STATISTICS_update (endpoint->plugin->env->stats, _("# wlan mac endpoints timeouts"), 1, GNUNET_NO);
+ GNUNET_assert (endpoint->plugin != NULL);
+ GNUNET_STATISTICS_update (endpoint->plugin->env->stats,
+ _("# wlan mac endpoints timeouts"), 1, GNUNET_NO);
free_macendpoint (endpoint->plugin, endpoint);
}
else
{
struct MacEndpoint *newend = GNUNET_malloc (sizeof (struct MacEndpoint));
- GNUNET_assert(plugin != NULL);
- GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan mac endpoints created"), 1, GNUNET_NO);
+ GNUNET_assert (plugin != NULL);
+ GNUNET_STATISTICS_update (plugin->env->stats,
+ _("# wlan mac endpoints created"), 1, GNUNET_NO);
newend->addr = *addr;
newend->plugin = plugin;
newend->addr = *addr;
newend);
plugin->mac_count++;
+ GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan mac endpoints"),
+ plugin->mac_count, GNUNET_NO);
GNUNET_CONTAINER_DLL_insert_tail (plugin->mac_head, plugin->mac_tail, newend);
#if DEBUG_wlan
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
int datasize = 0;
int pos;
- GNUNET_assert(plugin != NULL);
+ GNUNET_assert (plugin != NULL);
switch (ntohs (hdr->type))
{
case GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA:
ntohs (hdr->size));
#endif
- GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan WLAN_HELPER_DATA received"), 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (plugin->env->stats,
+ _("# wlan WLAN_HELPER_DATA received"), 1,
+ GNUNET_NO);
//call wlan_process_helper with the message inside, later with wlan: analyze signal
if (ntohs (hdr->size) <
- sizeof (struct ieee80211_frame) + 2*sizeof (struct GNUNET_MessageHeader) +
- sizeof (struct Radiotap_rx))
+ sizeof (struct ieee80211_frame) +
+ 2 * sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_rx))
{
#if DEBUG_wlan
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
{
//check for broadcast or mac
if ((memcmp
- (&(wlanIeeeHeader->i_addr1), &bc_all_mac,
- sizeof (struct MacAddress)) == 0) ||
- (memcmp (&(wlanIeeeHeader->i_addr1), &(plugin->mac_address),
- sizeof (struct MacAddress)) == 0))
+ (&(wlanIeeeHeader->i_addr1), &bc_all_mac,
+ sizeof (struct MacAddress)) == 0) ||
+ (memcmp
+ (&(wlanIeeeHeader->i_addr1), &(plugin->mac_address),
+ sizeof (struct MacAddress)) == 0))
{
- //if packet is from us return
- if ((memcmp (&(wlanIeeeHeader->i_addr2), &(plugin->mac_address),
- sizeof (struct MacAddress)) == 0)){
- return;
- }
+ //if packet is from us return
+ if ((memcmp
+ (&(wlanIeeeHeader->i_addr2), &(plugin->mac_address),
+ sizeof (struct MacAddress)) == 0))
+ {
+ return;
+ }
// process the inner data
memcpy (&session_light->addr, &(wlanIeeeHeader->i_addr2),
sizeof (struct MacAddress));
//session_light->session = search_session(plugin,session_light->addr);
- GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan messaged for this client received"), 1, GNUNET_NO);
+ GNUNET_STATISTICS_update (plugin->env->stats,
+ _("# wlan messages for this client received"),
+ 1, GNUNET_NO);
pos = 0;
while (pos < datasize)
{
temp_hdr = (struct GNUNET_MessageHeader *) &wlanIeeeHeader[1] + pos;
- if (ntohs(temp_hdr->size) <= datasize + pos)
- {
- GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan messaged inside WLAN_HELPER_DATA received"), 1, GNUNET_NO);
- wlan_data_helper (plugin, session_light, temp_hdr, rxinfo);
- }
+ if (ntohs (temp_hdr->size) <= datasize + pos)
+ {
+ GNUNET_STATISTICS_update (plugin->env->stats,
+ _
+ ("# wlan messages inside WLAN_HELPER_DATA received"),
+ 1, GNUNET_NO);
+ wlan_data_helper (plugin, session_light, temp_hdr, rxinfo);
+ }
else
- {
+ {
#if DEBUG_wlan
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "Size of packet is too small; size: %u > size of packet: %u\n",
- ntohs(temp_hdr->size),datasize + pos);
+ "Size of packet is too small; size: %u > size of packet: %u\n",
+ ntohs (temp_hdr->size), datasize + pos);
#endif
- }
+ }
pos += ntohs (temp_hdr->size);
}
ntohs (hdr->type), ntohs (hdr->size));
#endif
-#if DEBUG_wlan_msg_dump
+#if DEBUG_wlan_msg_dump > 1
hexdump (hdr, GNUNET_MIN (ntohs (hdr->size), 256));
#endif
GNUNET_break (0);
}
}
-/**
- * We have been notified that wlan-helper has written something to stdout.
- * Handle the output, then reschedule this function to be called again once
- * more is available.
- *
- * @param cls the plugin handle
- * @param tc the scheduling context
- */
-static void
-wlan_plugin_helper_read (void *cls,
- const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
- struct Plugin *plugin = cls;
-
- plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
-
- if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
- return;
-
- char mybuf[WLAN_MTU + sizeof (struct GNUNET_MessageHeader)];
- ssize_t bytes;
-
- bytes =
- GNUNET_DISK_file_read (plugin->server_stdout_handle, mybuf,
- sizeof (mybuf));
- if (bytes <= 0)
- {
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- _
- ("Finished reading from wlan-helper stdout with code: %d\n"),
- bytes);
-#endif
- return;
- }
- GNUNET_SERVER_mst_receive (plugin->suid_tokenizer, NULL, mybuf, bytes,
- GNUNET_NO, GNUNET_NO);
-
- GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
- plugin->server_read_task =
- GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
- plugin->server_stdout_handle,
- &wlan_plugin_helper_read, plugin);
-}
-
-/**
- * Start the gnunet-wlan-helper process.
- *
- * @param plugin the transport plugin
- * @param testmode should we use the dummy driver for testing?
- * @return GNUNET_YES if process was started, GNUNET_SYSERR on error
- */
-static int
-wlan_transport_start_wlan_helper (struct Plugin *plugin, int testmode)
-{
- const char *filenamehw = "gnunet-transport-wlan-helper";
- const char *filenameloopback = "gnunet-transport-wlan-helper-dummy";
-
- plugin->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES);
- if (plugin->server_stdout == NULL)
- return GNUNET_SYSERR;
-
- plugin->server_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO);
- if (plugin->server_stdin == NULL)
- return GNUNET_SYSERR;
-
- /* Start the server process */
-
- if (testmode == 0)
- {
-
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "Starting gnunet-wlan-helper process cmd: %s %s %i\n",
- filenamehw, plugin->interface, testmode);
-#endif
-
- if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_YES)
- {
- plugin->server_proc =
- GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
- filenamehw, filenamehw, plugin->interface,
- NULL);
- }
- else if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_NO)
- {
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
- "gnunet-transport-wlan-helper is not suid, please change it or look at the doku\n");
- GNUNET_break (0);
- }
- else
- {
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
- "gnunet-transport-wlan-helper not found, please look if it exists and is the $PATH variable!\n");
- GNUNET_break (0);
- }
-
- }
- else if (testmode == 1)
- {
-
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "Starting gnunet-wlan-helper loopback 1 process cmd: %s %s %i\n",
- filenameloopback, plugin->interface, testmode);
-#endif
-
- if (GNUNET_OS_check_helper_binary (filenameloopback) != GNUNET_SYSERR)
- {
- plugin->server_proc =
- GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
- filenameloopback, filenameloopback, "1",
- NULL);
- }
- else
- {
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
- "gnunet-transport-wlan-helper-dummy not found, please look if it exists and is the $PATH variable!\n");
- GNUNET_break (0);
- }
- }
- else if (testmode == 2)
- {
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "Starting gnunet-wlan-helper loopback 2 process cmd: %s %s %i\n",
- filenameloopback, plugin->interface, testmode);
-#endif
- if (GNUNET_OS_check_helper_binary (filenameloopback) != GNUNET_SYSERR)
- {
- plugin->server_proc =
- GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
- filenameloopback, filenameloopback, "2",
- NULL);
- }
- else
- {
- GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
- "gnunet-transport-wlan-helper-dummy not found, please look if it exists and is in the $PATH variable!\n");
- GNUNET_break (0);
- }
- }
- if (plugin->server_proc == NULL)
- {
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "Failed to start gnunet-wlan-helper process\n");
-#endif
- return GNUNET_SYSERR;
- }
-
- /* Close the write end of the read pipe */
- GNUNET_DISK_pipe_close_end (plugin->server_stdout,
- GNUNET_DISK_PIPE_END_WRITE);
-
- /* Close the read end of the write pipe */
- GNUNET_DISK_pipe_close_end (plugin->server_stdin, GNUNET_DISK_PIPE_END_READ);
-
- plugin->server_stdout_handle =
- GNUNET_DISK_pipe_handle (plugin->server_stdout,
- GNUNET_DISK_PIPE_END_READ);
- plugin->server_stdin_handle =
- GNUNET_DISK_pipe_handle (plugin->server_stdin,
- GNUNET_DISK_PIPE_END_WRITE);
-
- GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
-
-#if DEBUG_wlan
- GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
- "Adding server_read_task for the wlan-helper\n");
-#endif
-
- plugin->server_read_task =
- GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
- plugin->server_stdout_handle,
- &wlan_plugin_helper_read, plugin);
-
- return GNUNET_YES;
-}
-
/**
* Exit point from the plugin.
* @param cls pointer to the api struct
"libgnunet_plugin_transport_wlan_done started\n");
#endif
- GNUNET_DISK_pipe_close (plugin->server_stdout);
- GNUNET_DISK_pipe_close (plugin->server_stdin);
- GNUNET_OS_process_kill (plugin->server_proc, 9);
- GNUNET_OS_process_close (plugin->server_proc);
+ wlan_transport_stop_wlan_helper (plugin);
GNUNET_assert (cls != NULL);
//free sessions
endpoint = endpoint_next;
}
- if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (plugin->server_write_delay_task);
- plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
- }
- if (plugin->server_write_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (plugin->server_write_task);
- plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
- }
- if (plugin->server_read_task != GNUNET_SCHEDULER_NO_TASK)
- {
- GNUNET_SCHEDULER_cancel (plugin->server_read_task);
- plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
- }
+
if (plugin->suid_tokenizer != NULL)
GNUNET_SERVER_mst_destroy (plugin->suid_tokenizer);
struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
struct GNUNET_TRANSPORT_PluginFunctions *api;
struct Plugin *plugin;
- static unsigned long long testmode = 0;
GNUNET_assert (cls != NULL);
plugin = GNUNET_malloc (sizeof (struct Plugin));
plugin->env = env;
plugin->pendingsessions = 0;
- GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan pending sessions"), plugin->pendingsessions, GNUNET_NO);
+ GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
+ plugin->pendingsessions, GNUNET_NO);
plugin->mac_count = 0;
+ GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan mac endpoints"),
+ plugin->mac_count, GNUNET_NO);
plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
{
if (GNUNET_SYSERR ==
GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-wlan",
- "TESTMODE", &testmode))
- testmode = 0; //default value
+ "TESTMODE", &(plugin->testmode)))
+ plugin->testmode = 0; //default value
}
if (GNUNET_CONFIGURATION_have_value (env->cfg, "transport-wlan", "INTERFACE"))
}
//start the plugin
- wlan_transport_start_wlan_helper (plugin, testmode);
+ wlan_transport_start_wlan_helper (plugin);
set_next_beacon_time (plugin);
- set_next_send(plugin);
+ set_next_send (plugin);
#if DEBUG_wlan
GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
"wlan init finished\n");