X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftransport%2Fplugin_transport_wlan.c;h=cbab8cb0fe42acecb7a2691d22732f0c6f26cc71;hb=83b19539f4d322b43683f5838b72e9ec2c8e6073;hp=160b5924c0e4a84d796a4fc597040ed0fe65ee55;hpb=1207885b627afe3bcdb5fafa17a4edf2730882ef;p=oweals%2Fgnunet.git diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c index 160b5924c..cbab8cb0f 100644 --- a/src/transport/plugin_transport_wlan.c +++ b/src/transport/plugin_transport_wlan.c @@ -1,6 +1,6 @@ /* 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 @@ -67,6 +67,11 @@ */ #define HELLO_BEACON_SCALING_FACTOR 30 +/** + * scaling factor for restarting the helper + */ +#define HELPER_RESTART_SCALING_FACTOR 2 + /** * max size of fragment queue */ @@ -93,8 +98,8 @@ /** * 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 /** @@ -250,6 +255,11 @@ struct Plugin */ 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. */ @@ -311,9 +321,24 @@ struct Plugin */ 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; }; @@ -680,6 +705,9 @@ free_session (struct Plugin *plugin, struct Sessionqueue *queue, 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. * @@ -709,6 +737,7 @@ hexdump (const void *mem, unsigned length) t += sprintf (t, "%02X", src[j] & 0xff); else t += sprintf (t, " "); + t += sprintf (t, j % 2 ? " " : "-"); } @@ -833,7 +862,7 @@ session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 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) { @@ -844,9 +873,10 @@ session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) (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 @@ -871,7 +901,8 @@ create_session (struct Plugin *plugin, struct MacEndpoint *endpoint, { 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)); @@ -954,7 +985,8 @@ queue_session (struct Plugin *plugin, struct Session *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); } } @@ -1103,24 +1135,25 @@ get_next_queue_session (struct Plugin *plugin) 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) @@ -1132,7 +1165,8 @@ get_next_queue_session (struct Plugin *plugin) 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); @@ -1162,7 +1196,8 @@ get_next_queue_session (struct Plugin *plugin) 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); @@ -1188,38 +1223,41 @@ free_fragment_message (struct Plugin *plugin, struct FragmentMessage *fm) 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 - } } /** @@ -1365,7 +1403,7 @@ add_message_for_send (void *cls, const struct GNUNET_MessageHeader *hdr) uint16_t size; #if DEBUG_wlan_retransmission > 1 - GNUNET_loHELLO_BEACON_SCALING_FACTORg_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME, + 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); #endif @@ -1393,155 +1431,520 @@ add_message_for_send (void *cls, const struct GNUNET_MessageHeader *hdr) set_next_send (plugin); } + /** - * function to send a hello 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 hello_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 (); - 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)); + plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; - msgheader2->type = htons (GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT);*/ - memcpy (msgheader2, hello, hello_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 > 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); +#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 + + + /* 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 @@ -1565,6 +1968,8 @@ check_fragment_queue (struct Plugin *plugin) 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); fm = GNUNET_malloc (sizeof (struct FragmentMessage)); fm->session = session; @@ -1618,13 +2023,17 @@ check_fragment_queue (struct Plugin *plugin) /** * 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, @@ -1634,67 +2043,35 @@ send_ack (struct Plugin *plugin, struct AckSendQueue *ack) #endif GNUNET_assert (plugin != NULL); - GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan acks send"), 1, GNUNET_NO); + 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_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); + 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); } } @@ -1709,6 +2086,7 @@ static void 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; @@ -1719,16 +2097,11 @@ do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 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; } @@ -1741,7 +2114,8 @@ do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 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; @@ -1765,35 +2139,36 @@ do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 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)); - //TODO START NEW WLAN HELPER - /* - * alle sessions beenden - * neu starten (alle 5 sec) - * alles bis dahin ablehnen - */ - } - //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 @@ -1838,13 +2213,15 @@ wlan_plugin_address_suggested (void *cls, const void *addr, size_t addrlen) /* 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; } @@ -1885,6 +2262,7 @@ wlan_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target, struct Plugin *plugin = cls; struct PendingMessage *newmsg; struct WlanHeader *wlanheader; + GNUNET_assert (plugin != NULL); //check if msglen > 0 GNUNET_assert (msgbuf_size > 0); @@ -1904,7 +2282,8 @@ wlan_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target, } } - 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: @@ -1989,7 +2368,13 @@ free_macendpoint (struct Plugin *plugin, struct MacEndpoint *endpoint) 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); } @@ -2027,7 +2412,8 @@ free_session (struct Plugin *plugin, struct Sessionqueue *queue, 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); @@ -2064,16 +2450,21 @@ free_session (struct Plugin *plugin, struct Sessionqueue *queue, 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); + 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); + 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); @@ -2145,31 +2536,31 @@ wlan_plugin_address_pretty_printer (void *cls, const char *type, 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); } @@ -2209,7 +2600,9 @@ wlan_data_message_handler (void *cls, const struct GNUNET_MessageHeader *hdr) 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); @@ -2333,7 +2726,7 @@ process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) GNUNET_assert (cls != NULL); struct Session *session = (struct Session *) client; struct Plugin *plugin = (struct Plugin *) cls; - struct GNUNET_TIME_Relative delay; + struct GNUNET_ATS_Information distance; distance.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); @@ -2348,16 +2741,10 @@ process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) htons (hdr->size)); #endif - delay = plugin->env->receive (plugin->env->cls, &(session->target), hdr, - (const struct GNUNET_ATS_Information *) - &distance, 1, session, - (const char *) &session->mac->addr, - sizeof (session->mac->addr)); - if (delay.rel_value == GNUNET_TIME_UNIT_FOREVER_REL.rel_value) - { - // FIXME: terminate session! - } - + plugin->env->receive (plugin->env->cls, &(session->target), hdr, + (const struct GNUNET_ATS_Information *) &distance, 1, + session, (const char *) &session->mac->addr, + sizeof (session->mac->addr)); } /** @@ -2366,7 +2753,7 @@ process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr) * @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, @@ -2378,7 +2765,7 @@ 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) @@ -2404,18 +2791,22 @@ wlan_data_helper (void *cls, struct Session_light *session_light, 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 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)); + { + 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 { @@ -2446,7 +2837,8 @@ wlan_data_helper (void *cls, struct Session_light *session_light, 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); @@ -2498,7 +2890,8 @@ wlan_data_helper (void *cls, struct Session_light *session_light, 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) @@ -2590,8 +2983,9 @@ macendpoint_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) (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 @@ -2613,8 +3007,9 @@ create_macendpoint (struct Plugin *plugin, const struct MacAddress *addr) { 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; @@ -2630,6 +3025,8 @@ create_macendpoint (struct Plugin *plugin, const struct MacAddress *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, @@ -2659,7 +3056,7 @@ wlan_process_helper (void *cls, void *client, int datasize = 0; int pos; - GNUNET_assert(plugin != NULL); + GNUNET_assert (plugin != NULL); switch (ntohs (hdr->type)) { case GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA: @@ -2669,11 +3066,13 @@ wlan_process_helper (void *cls, void *client, 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, @@ -2699,16 +3098,19 @@ wlan_process_helper (void *cls, void *client, { //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 @@ -2720,25 +3122,30 @@ wlan_process_helper (void *cls, void *client, 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); } @@ -2799,186 +3206,6 @@ wlan_process_helper (void *cls, void *client, } } -/** - * 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 @@ -2998,10 +3225,7 @@ libgnunet_plugin_transport_wlan_done (void *cls) "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 @@ -3012,21 +3236,7 @@ libgnunet_plugin_transport_wlan_done (void *cls) 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); @@ -3053,15 +3263,17 @@ libgnunet_plugin_transport_wlan_init (void *cls) 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; @@ -3091,8 +3303,8 @@ libgnunet_plugin_transport_wlan_init (void *cls) { 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")) @@ -3107,9 +3319,9 @@ libgnunet_plugin_transport_wlan_init (void *cls) } //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");