diff options
-rw-r--r-- | src/include/gnunet_protocols.h | 7 | ||||
-rw-r--r-- | src/transport/gnunet-transport-wlan-helper.c | 6 | ||||
-rw-r--r-- | src/transport/plugin_transport_wlan.c | 913 | ||||
-rw-r--r-- | src/transport/plugin_transport_wlan.h | 19 |
4 files changed, 734 insertions, 211 deletions
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index e9eee668a..5f54cddec 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -697,6 +697,13 @@ extern "C" | |||
697 | #define GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT 199 | 697 | #define GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT 199 |
698 | 698 | ||
699 | /** | 699 | /** |
700 | * Fragment ack of a message | ||
701 | */ | ||
702 | |||
703 | #define GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT_ACK 200 | ||
704 | |||
705 | |||
706 | /** | ||
700 | * Type of messages to query the local service-dns | 707 | * Type of messages to query the local service-dns |
701 | */ | 708 | */ |
702 | #define GNUNET_MESSAGE_TYPE_LOCAL_QUERY_DNS 205 | 709 | #define GNUNET_MESSAGE_TYPE_LOCAL_QUERY_DNS 205 |
diff --git a/src/transport/gnunet-transport-wlan-helper.c b/src/transport/gnunet-transport-wlan-helper.c index 341734d6f..7556e6663 100644 --- a/src/transport/gnunet-transport-wlan-helper.c +++ b/src/transport/gnunet-transport-wlan-helper.c | |||
@@ -35,11 +35,9 @@ | |||
35 | 35 | ||
36 | //#include "radiotap.h" | 36 | //#include "radiotap.h" |
37 | 37 | ||
38 | // broadcast mac | ||
39 | static const char macbc[] = "13223344"; | ||
40 | |||
41 | // mac of this node | 38 | // mac of this node |
42 | char mac[] = "13223355"; | 39 | char mac[] = |
40 | { 0x13, 0x22, 0x33, 0x44, 0x55, 0x66 }; | ||
43 | 41 | ||
44 | /* wifi bitrate to use in 500kHz units */ | 42 | /* wifi bitrate to use in 500kHz units */ |
45 | 43 | ||
diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c index 5618ff4c4..ce740e785 100644 --- a/src/transport/plugin_transport_wlan.c +++ b/src/transport/plugin_transport_wlan.c | |||
@@ -96,6 +96,12 @@ struct Plugin | |||
96 | struct Sessionqueue *sessions_tail; | 96 | struct Sessionqueue *sessions_tail; |
97 | 97 | ||
98 | /** | 98 | /** |
99 | * Number of sessions | ||
100 | */ | ||
101 | |||
102 | int session_count; | ||
103 | |||
104 | /** | ||
99 | * encapsulation to the local wlan server prog | 105 | * encapsulation to the local wlan server prog |
100 | */ | 106 | */ |
101 | 107 | ||
@@ -123,17 +129,22 @@ struct Plugin | |||
123 | const struct GNUNET_DISK_FileHandle *server_stdin_handle; | 129 | const struct GNUNET_DISK_FileHandle *server_stdin_handle; |
124 | 130 | ||
125 | /** | 131 | /** |
126 | * ID of select gnunet-nat-server std read task | 132 | * ID of the gnunet-wlan-server std read task |
127 | */ | 133 | */ |
128 | GNUNET_SCHEDULER_TaskIdentifier server_read_task; | 134 | GNUNET_SCHEDULER_TaskIdentifier server_read_task; |
129 | 135 | ||
130 | /** | 136 | /** |
131 | * ID of select gnunet-nat-server std read task | 137 | * ID of the gnunet-wlan-server std read task |
132 | */ | 138 | */ |
133 | GNUNET_SCHEDULER_TaskIdentifier server_write_task; | 139 | GNUNET_SCHEDULER_TaskIdentifier server_write_task; |
134 | 140 | ||
135 | /** | 141 | /** |
136 | * The process id of the server process (if behind NAT) | 142 | * ID of the delay task for writing |
143 | */ | ||
144 | GNUNET_SCHEDULER_TaskIdentifier server_write_delay_task; | ||
145 | |||
146 | /** | ||
147 | * The process id of the wlan process | ||
137 | */ | 148 | */ |
138 | struct GNUNET_OS_Process *server_proc; | 149 | struct GNUNET_OS_Process *server_proc; |
139 | 150 | ||
@@ -182,9 +193,17 @@ struct Plugin | |||
182 | 193 | ||
183 | unsigned int pending_fragment_messages; | 194 | unsigned int pending_fragment_messages; |
184 | 195 | ||
196 | /** | ||
197 | * time of the next "hello-beacon" | ||
198 | */ | ||
199 | |||
200 | struct GNUNET_TIME_Absolute beacon_time; | ||
201 | |||
185 | }; | 202 | }; |
186 | 203 | ||
187 | //TODO doxigen | 204 | /** |
205 | * Queue of sessions, for the general session queue and the pending session queue | ||
206 | */ | ||
188 | 207 | ||
189 | struct Sessionqueue | 208 | struct Sessionqueue |
190 | { | 209 | { |
@@ -193,13 +212,28 @@ struct Sessionqueue | |||
193 | struct Session * content; | 212 | struct Session * content; |
194 | }; | 213 | }; |
195 | 214 | ||
196 | //TODO doxigen | 215 | /** |
216 | * Queue of ack received for messages send | ||
217 | */ | ||
197 | 218 | ||
198 | struct AckQueue | 219 | struct AckQueue |
199 | { | 220 | { |
200 | struct AckQueue * next; | 221 | struct AckQueue * next; |
201 | struct AckQueue * prev; | 222 | struct AckQueue * prev; |
202 | int fragment_num; | 223 | int fragment_num; //TODO change it to offset |
224 | }; | ||
225 | |||
226 | /** | ||
227 | * Queue for the fragments received | ||
228 | */ | ||
229 | |||
230 | struct RecQueue | ||
231 | { | ||
232 | struct RecQueue * next; | ||
233 | struct RecQueue * prev; | ||
234 | uint16_t num; | ||
235 | char * msg; | ||
236 | uint16_t size; | ||
203 | }; | 237 | }; |
204 | 238 | ||
205 | /** | 239 | /** |
@@ -239,6 +273,22 @@ struct PendingMessage | |||
239 | }; | 273 | }; |
240 | 274 | ||
241 | /** | 275 | /** |
276 | * Session infos gathered from a messages | ||
277 | */ | ||
278 | |||
279 | struct Session_light | ||
280 | { | ||
281 | /** | ||
282 | * the session this message belongs to | ||
283 | */ | ||
284 | struct Session * session; | ||
285 | /** | ||
286 | * peer mac address | ||
287 | */ | ||
288 | uint8_t addr[6]; | ||
289 | }; | ||
290 | |||
291 | /** | ||
242 | * Session handle for connections. | 292 | * Session handle for connections. |
243 | */ | 293 | */ |
244 | struct Session | 294 | struct Session |
@@ -267,9 +317,33 @@ struct Session | |||
267 | struct GNUNET_PeerIdentity target; | 317 | struct GNUNET_PeerIdentity target; |
268 | 318 | ||
269 | /** | 319 | /** |
270 | * encapsulation of the data | 320 | * encapsulation of the receive data |
321 | */ | ||
322 | //struct GNUNET_SERVER_MessageStreamTokenizer * receive_token; | ||
323 | |||
324 | /** | ||
325 | * offset of the next fragment for the receive_token, -1 means last message finished | ||
326 | */ | ||
327 | |||
328 | //int rec_offset; | ||
329 | |||
330 | /** | ||
331 | * size of the message received, -1 means that the size is not known, -2 means no message received | ||
271 | */ | 332 | */ |
272 | //struct GNUNET_SERVER_MessageStreamTokenizer * datatoken; | 333 | |
334 | int rec_size; | ||
335 | |||
336 | /** | ||
337 | * Sorted queue with the fragments received; head | ||
338 | */ | ||
339 | |||
340 | struct RecQueue * frag_head; | ||
341 | |||
342 | /** | ||
343 | * Sorted queue with the fragments received; tail | ||
344 | */ | ||
345 | |||
346 | struct RecQueue * frag_tail; | ||
273 | 347 | ||
274 | /** | 348 | /** |
275 | * peer mac address | 349 | * peer mac address |
@@ -440,14 +514,26 @@ struct FragmentationHeader | |||
440 | 514 | ||
441 | //enum { ACK_FRAGMENT = 1, DATA_FRAGMENT = 2, LAST_FRAGMENT = 4, NEW_MESSAGE = 8 }; | 515 | //enum { ACK_FRAGMENT = 1, DATA_FRAGMENT = 2, LAST_FRAGMENT = 4, NEW_MESSAGE = 8 }; |
442 | 516 | ||
443 | int getRadiotapHeader (struct RadiotapHeader * Header); | 517 | int |
444 | int getWlanHeader (struct IeeeHeader * Header); | 518 | getRadiotapHeader(struct RadiotapHeader * Header); |
445 | static int wlan_plugin_address_suggested (void *cls, | 519 | |
446 | const void *addr, | 520 | int |
447 | size_t addrlen); | 521 | getWlanHeader(struct IeeeHeader * Header); |
448 | uint16_t getcrc16 (const char *msgbuf, size_t msgbuf_size); | 522 | |
449 | static void do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | 523 | static int |
450 | static void check_fragment_queue (struct Plugin * plugin); | 524 | wlan_plugin_address_suggested(void *cls, const void *addr, size_t addrlen); |
525 | |||
526 | uint16_t | ||
527 | getcrc16(const char *msgbuf, size_t msgbuf_size); | ||
528 | |||
529 | static void | ||
530 | do_transmit(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
531 | |||
532 | static void | ||
533 | check_fragment_queue(struct Plugin * plugin); | ||
534 | |||
535 | uint32_t | ||
536 | getcrc32(const char *msgbuf, size_t msgbuf_size); | ||
451 | 537 | ||
452 | /** | 538 | /** |
453 | * get the next message number, at the moment just a random one | 539 | * get the next message number, at the moment just a random one |
@@ -457,7 +543,7 @@ static void check_fragment_queue (struct Plugin * plugin); | |||
457 | uint32_t | 543 | uint32_t |
458 | get_next_message_id() | 544 | get_next_message_id() |
459 | { | 545 | { |
460 | return GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); | 546 | return GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, UINT32_MAX); |
461 | } | 547 | } |
462 | 548 | ||
463 | /** | 549 | /** |
@@ -467,68 +553,104 @@ get_next_message_id() | |||
467 | void | 553 | void |
468 | start_next_message_id() | 554 | start_next_message_id() |
469 | { | 555 | { |
470 | //GNUNET_CRYPTO_random_init; | 556 | //GNUNET_CRYPTO_random_init; |
471 | } | 557 | } |
472 | 558 | ||
473 | |||
474 | /** | 559 | /** |
475 | * get Session from address | 560 | * search for a session with the addr |
476 | * | 561 | * |
562 | * @param plugin pointer to the plugin struct | ||
563 | * @param addr pointer to the mac address of the peer | ||
564 | * @return returns the session | ||
477 | */ | 565 | */ |
478 | //TODO doxigen | 566 | |
479 | //TODO add other possibilities to find the right session (are there other?) | ||
480 | static struct Session * | 567 | static struct Session * |
481 | get_Session (struct Plugin *plugin, | 568 | search_session(struct Plugin *plugin, const uint8_t * addr) |
482 | const char * addr) | ||
483 | { | 569 | { |
484 | struct Sessionqueue * queue = plugin->sessions; | 570 | struct Sessionqueue * queue = plugin->sessions; |
485 | struct Sessionqueue * lastitem = NULL; | 571 | struct Sessionqueue * lastitem = NULL; |
486 | 572 | ||
573 | //just look at all the session for the needed one | ||
574 | while (queue != NULL) | ||
575 | { | ||
576 | // content is never NULL | ||
577 | GNUNET_assert (queue->content == NULL); | ||
578 | char * addr2 = queue->content->addr; | ||
579 | if (memcmp(addr, addr2, 6) == 0) | ||
580 | { | ||
581 | //sesion found | ||
582 | return queue->content; | ||
583 | } | ||
584 | // try next | ||
585 | lastitem = queue; | ||
586 | queue = queue->next; | ||
587 | } | ||
588 | return NULL; | ||
589 | } | ||
487 | 590 | ||
488 | //just look at all the session for the needed one | 591 | /** |
489 | while (queue != NULL){ | 592 | * create a new session |
490 | // content is never NULL | 593 | * |
491 | GNUNET_assert (queue->content == NULL); | 594 | * @param plugin pointer to the plugin struct |
492 | char * addr2 = queue->content->addr; | 595 | * @param addr pointer to the mac address of the peer |
493 | if (memcmp(addr, addr2, 6) == 0) | 596 | * @return returns the session |
494 | { | 597 | */ |
495 | //sesion found | ||
496 | return queue->content; | ||
497 | } | ||
498 | // try next | ||
499 | lastitem = queue; | ||
500 | queue = queue->next; | ||
501 | } | ||
502 | // new session | ||
503 | queue = GNUNET_malloc (sizeof (struct Sessionqueue)); | ||
504 | 598 | ||
505 | GNUNET_CONTAINER_DLL_insert(plugin->sessions, plugin->sessions_tail, queue); | 599 | static struct Session * |
506 | 600 | create_session(struct Plugin *plugin,const uint8_t * addr) | |
507 | queue->content = GNUNET_malloc (sizeof (struct Session)); | 601 | { |
508 | queue->content->plugin = plugin; | 602 | struct Sessionqueue * queue = GNUNET_malloc (sizeof (struct Sessionqueue)); |
509 | memcpy(queue->content->addr, addr, 6); | ||
510 | queue->content->message_id_out = get_next_message_id(); | ||
511 | queue->content->has_fragment = 0; | ||
512 | |||
513 | //queue welcome message for new sessions, not realy needed | ||
514 | //struct WelcomeMessage welcome; | ||
515 | struct PendingMessage *pm; | ||
516 | pm = GNUNET_malloc (sizeof (struct PendingMessage)); | ||
517 | pm->msg = GNUNET_malloc(GNUNET_HELLO_size(* (plugin->env->our_hello))); | ||
518 | pm->message_size = GNUNET_HELLO_size(* (plugin->env->our_hello)); | ||
519 | //welcome.header.size = htons (GNUNET_HELLO_size(* (plugin->env->our_hello))); | ||
520 | //welcome.header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT); | ||
521 | //welcome.clientIdentity = *plugin->env->my_identity; | ||
522 | memcpy ( (pm->msg), * plugin->env->our_hello, GNUNET_HELLO_size(* (plugin->env->our_hello))); | ||
523 | pm->timeout = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
524 | queue->content->pending_message = pm; | ||
525 | plugin->pendingsessions ++; | ||
526 | GNUNET_CONTAINER_DLL_insert_tail(plugin->pending_Sessions, plugin->pending_Sessions_tail, queue); | ||
527 | 603 | ||
528 | check_fragment_queue(plugin); | 604 | GNUNET_CONTAINER_DLL_insert_tail(plugin->sessions, plugin->sessions_tail, queue); |
529 | 605 | ||
530 | return queue->content; | 606 | queue->content = GNUNET_malloc (sizeof (struct Session)); |
607 | queue->content->plugin = plugin; | ||
608 | memcpy(queue->content->addr, addr, 6); | ||
609 | queue->content->message_id_out = get_next_message_id(); | ||
610 | queue->content->has_fragment = 0; | ||
611 | queue->content->rec_size = -2; | ||
531 | 612 | ||
613 | plugin->session_count++; | ||
614 | return queue->content; | ||
615 | } | ||
616 | |||
617 | /** | ||
618 | * get Session from address, create if no session exists | ||
619 | * | ||
620 | * @param plugin pointer to the plugin struct | ||
621 | * @param addr pointer to the mac address of the peer | ||
622 | * @return returns the session | ||
623 | */ | ||
624 | //TODO add other possibilities to find the right session (are there other?) | ||
625 | static struct Session * | ||
626 | get_Session(struct Plugin *plugin, const uint8_t * addr) | ||
627 | { | ||
628 | struct Session * session = search_session(plugin, addr); | ||
629 | if (session != NULL) | ||
630 | { | ||
631 | return session; | ||
632 | } | ||
633 | // new session | ||
634 | return create_session(plugin, addr); | ||
635 | |||
636 | /* -- not needed, layer above already has it-- | ||
637 | //queue welcome message for new sessions, not realy needed | ||
638 | //struct WelcomeMessage welcome; | ||
639 | struct PendingMessage *pm; | ||
640 | pm = GNUNET_malloc (sizeof (struct PendingMessage)); | ||
641 | pm->msg = GNUNET_malloc(GNUNET_HELLO_size(* (plugin->env->our_hello))); | ||
642 | pm->message_size = GNUNET_HELLO_size(* (plugin->env->our_hello)); | ||
643 | //welcome.header.size = htons (GNUNET_HELLO_size(* (plugin->env->our_hello))); | ||
644 | //welcome.header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT); | ||
645 | //welcome.clientIdentity = *plugin->env->my_identity; | ||
646 | memcpy ( (pm->msg), * plugin->env->our_hello, GNUNET_HELLO_size(* (plugin->env->our_hello))); | ||
647 | pm->timeout = GNUNET_TIME_UNIT_FOREVER_ABS; | ||
648 | queue->content->pending_message = pm; | ||
649 | plugin->pendingsessions ++; | ||
650 | GNUNET_CONTAINER_DLL_insert_tail(plugin->pending_Sessions, plugin->pending_Sessions_tail, queue); | ||
651 | |||
652 | check_fragment_queue(plugin); | ||
653 | */ | ||
532 | } | 654 | } |
533 | 655 | ||
534 | /** | 656 | /** |
@@ -569,38 +691,72 @@ queue_Session (struct Plugin *plugin, | |||
569 | 691 | ||
570 | //TODO doxigen | 692 | //TODO doxigen |
571 | static void | 693 | static void |
572 | free_acks (struct FragmentMessage * pm){ | 694 | free_acks (struct FragmentMessage * fm){ |
573 | struct AckQueue * fq; | 695 | struct AckQueue * fq; |
574 | while (pm->head != NULL){ | 696 | while (fm->head != NULL){ |
575 | fq = pm->head; | 697 | fq = fm->head; |
576 | GNUNET_CONTAINER_DLL_remove(pm->head, pm->tail, fq); | 698 | GNUNET_CONTAINER_DLL_remove(fm->head, fm->tail, fq); |
577 | GNUNET_free(fq); | 699 | GNUNET_free(fq); |
578 | } | 700 | } |
579 | } | 701 | } |
580 | 702 | ||
581 | //TODO doxigen | 703 | //TODO doxigen |
704 | /** | ||
705 | * Function to schedule the write task, executed after a delay | ||
706 | */ | ||
707 | static void | ||
708 | delay_fragment_task(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
709 | { | ||
710 | struct Plugin * plugin = cls; | ||
711 | plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; | ||
712 | |||
713 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | ||
714 | return; | ||
715 | |||
716 | // GNUNET_TIME_UNIT_FOREVER_REL is needed to clean up old msg | ||
717 | if (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK) | ||
718 | { | ||
719 | plugin->server_write_task = GNUNET_SCHEDULER_add_write_file( | ||
720 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdin_handle, | ||
721 | &do_transmit, plugin); | ||
722 | } | ||
723 | } | ||
724 | |||
725 | //TODO doxigen | ||
726 | /** | ||
727 | * Function to calculate the time of the next periodic "hello-beacon" | ||
728 | */ | ||
582 | static void | 729 | static void |
583 | delay_fragment_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc){ | 730 | set_next_beacon_time(struct Plugin * const plugin) |
584 | struct Plugin * plugin = cls; | 731 | { |
585 | plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; | 732 | //under 10 known peers: once a second |
586 | 733 | if (plugin->session_count < 10) | |
587 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | 734 | { |
588 | return; | 735 | plugin->beacon_time = GNUNET_TIME_absolute_add( |
589 | 736 | GNUNET_TIME_absolute_get(), GNUNET_TIME_UNIT_SECONDS); | |
590 | // GNUNET_TIME_UNIT_FOREVER_REL is needed to clean up old msg | 737 | } |
591 | plugin->server_write_task | 738 | //under 30 known peers: every 10 seconds |
592 | = GNUNET_SCHEDULER_add_write_file(GNUNET_TIME_UNIT_FOREVER_REL, | 739 | else if (plugin->session_count < 30) |
593 | plugin->server_stdin_handle, | 740 | { |
594 | &do_transmit, | 741 | plugin->beacon_time = GNUNET_TIME_absolute_add( |
595 | plugin); | 742 | GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_multiply( |
743 | GNUNET_TIME_UNIT_SECONDS, 10)); | ||
744 | } | ||
745 | //over 30 known peers: once a minute | ||
746 | else | ||
747 | { | ||
748 | plugin->beacon_time = GNUNET_TIME_absolute_add( | ||
749 | GNUNET_TIME_absolute_get(), GNUNET_TIME_UNIT_MINUTES); | ||
750 | } | ||
596 | } | 751 | } |
597 | 752 | ||
598 | 753 | ||
599 | //TODO doxigen | 754 | //TODO doxigen |
600 | struct GNUNET_TIME_Relative | 755 | struct GNUNET_TIME_Relative |
601 | get_next_frag_timeout (struct FragmentMessage * fm) | 756 | get_next_frag_timeout(struct FragmentMessage * fm) |
602 | { | 757 | { |
603 | return GNUNET_TIME_relative_min(GNUNET_TIME_absolute_get_remaining(fm->next_ack), GNUNET_TIME_absolute_get_remaining(fm->timeout)); | 758 | return GNUNET_TIME_relative_min(GNUNET_TIME_absolute_get_remaining( |
759 | fm->next_ack), GNUNET_TIME_absolute_get_remaining(fm->timeout)); | ||
604 | } | 760 | } |
605 | 761 | ||
606 | //TODO doxigen | 762 | //TODO doxigen |
@@ -618,17 +774,34 @@ get_ack_timeout (struct FragmentMessage * fm){ | |||
618 | * Function to set the timer for the next timeout of the fragment queue | 774 | * Function to set the timer for the next timeout of the fragment queue |
619 | */ | 775 | */ |
620 | static void | 776 | static void |
621 | check_next_fragment_timeout (struct Plugin * plugin){ | 777 | check_next_fragment_timeout(struct Plugin * const plugin) |
622 | struct FragmentMessage * fm; | 778 | { |
623 | if (plugin->server_write_task != GNUNET_SCHEDULER_NO_TASK){ | 779 | struct FragmentMessage * fm; |
624 | GNUNET_SCHEDULER_cancel(plugin->server_write_task); | 780 | struct GNUNET_TIME_Relative next_send; |
625 | } | 781 | |
626 | fm = plugin->pending_Fragment_Messages_head; | 782 | next_send = GNUNET_TIME_absolute_get_remaining(plugin->beacon_time); |
627 | if (fm != NULL){ | 783 | |
628 | plugin->server_write_task = GNUNET_SCHEDULER_add_delayed(get_next_frag_timeout(fm), &delay_fragment_task, plugin); | 784 | //cancel old task |
629 | } | 785 | if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK) |
786 | { | ||
787 | GNUNET_SCHEDULER_cancel(plugin->server_write_delay_task); | ||
788 | } | ||
789 | fm = plugin->pending_Fragment_Messages_head; | ||
790 | |||
791 | GNUNET_assert(plugin->server_write_delay_task == GNUNET_SCHEDULER_NO_TASK); | ||
792 | |||
793 | //check if there are some fragments in the queue | ||
794 | if (fm != NULL) | ||
795 | { | ||
796 | next_send | ||
797 | = GNUNET_TIME_relative_min(next_send, get_next_frag_timeout(fm)); | ||
798 | } | ||
799 | plugin->server_write_delay_task = GNUNET_SCHEDULER_add_delayed(next_send, | ||
800 | &delay_fragment_task, plugin); | ||
630 | } | 801 | } |
631 | 802 | ||
803 | |||
804 | |||
632 | //TODO doxigen | 805 | //TODO doxigen |
633 | /** | 806 | /** |
634 | * Function to get the next queued Session, removes the session from the queue | 807 | * Function to get the next queued Session, removes the session from the queue |
@@ -707,6 +880,22 @@ sort_fragment_into_queue (struct Plugin * plugin, struct FragmentMessage * fm){ | |||
707 | } | 880 | } |
708 | 881 | ||
709 | //TODO doxigen | 882 | //TODO doxigen |
883 | static void | ||
884 | free_fragment_message(struct Plugin * plugin,struct FragmentMessage * fm) | ||
885 | { | ||
886 | if (fm != NULL) | ||
887 | { | ||
888 | free_acks(fm); | ||
889 | GNUNET_free_non_null(fm->msg); | ||
890 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Fragment_Messages_head, | ||
891 | plugin->pending_Fragment_Messages_tail, fm); | ||
892 | GNUNET_free(fm); | ||
893 | plugin->pending_fragment_messages --; | ||
894 | check_fragment_queue(plugin); | ||
895 | } | ||
896 | } | ||
897 | |||
898 | //TODO doxigen | ||
710 | /** | 899 | /** |
711 | * Function to check if there is some space in the fragment queue | 900 | * Function to check if there is some space in the fragment queue |
712 | */ | 901 | */ |
@@ -751,6 +940,35 @@ check_fragment_queue (struct Plugin * plugin){ | |||
751 | } | 940 | } |
752 | } | 941 | } |
753 | 942 | ||
943 | static void | ||
944 | check_finished_fragment(struct Plugin * plugin, struct FragmentMessage * fm){ | ||
945 | struct AckQueue * ack; | ||
946 | int counter = 0; | ||
947 | |||
948 | if (fm->message_size >= (WLAN_MTU - sizeof(struct FragmentationHeader)) | ||
949 | * fm->tail->fragment_num) | ||
950 | { | ||
951 | ack = fm->head; | ||
952 | counter = 0; | ||
953 | //check if all acks are present | ||
954 | while (ack != NULL) | ||
955 | { | ||
956 | if (counter == ack->fragment_num) | ||
957 | { | ||
958 | counter ++; | ||
959 | ack = ack->next; | ||
960 | } else { | ||
961 | //ack is missing | ||
962 | return; | ||
963 | } | ||
964 | } | ||
965 | fm->session->has_fragment = 0; | ||
966 | free_fragment_message(plugin, fm); | ||
967 | |||
968 | |||
969 | } | ||
970 | } | ||
971 | |||
754 | /** | 972 | /** |
755 | * Function called to when wlan helper is ready to get some data | 973 | * Function called to when wlan helper is ready to get some data |
756 | * | 974 | * |
@@ -770,18 +988,58 @@ do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
770 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | 988 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) |
771 | return; | 989 | return; |
772 | 990 | ||
773 | struct Session * session; | 991 | struct Session * session = NULL; |
774 | struct FragmentMessage * fm; | 992 | struct FragmentMessage * fm = NULL; |
775 | struct IeeeHeader * wlanheader; | 993 | struct IeeeHeader * ieeewlanheader = NULL; |
776 | struct RadiotapHeader * radioHeader; | 994 | struct RadiotapHeader * radioHeader = NULL; |
777 | struct GNUNET_MessageHeader * msgheader; | 995 | struct GNUNET_MessageHeader * msgheader = NULL; |
996 | struct GNUNET_MessageHeader * msgheader2 = NULL; | ||
778 | struct FragmentationHeader fragheader; | 997 | struct FragmentationHeader fragheader; |
779 | uint16_t size = 0; | 998 | uint16_t size = 0; |
780 | const char * copystart = NULL; | 999 | const char * copystart = NULL; |
781 | uint16_t copysize = 0; | 1000 | uint16_t copysize = 0; |
782 | uint copyoffset = 0; | 1001 | uint copyoffset = 0; |
783 | struct AckQueue * akt = NULL; | 1002 | struct AckQueue * akt = NULL; |
784 | //int exit = 0; | 1003 | |
1004 | //test if a "hello-beacon" has to be send | ||
1005 | if (GNUNET_TIME_absolute_get_remaining(plugin->beacon_time).rel_value == 0) | ||
1006 | { | ||
1007 | //check if the message is not to big | ||
1008 | GNUNET_assert(sizeof(struct WlanHeader) + GNUNET_HELLO_size( | ||
1009 | *(plugin->env->our_hello)) <= WLAN_MTU); | ||
1010 | size = sizeof(struct GNUNET_MessageHeader) | ||
1011 | + sizeof(struct RadiotapHeader) + sizeof(struct IeeeHeader) | ||
1012 | + sizeof(struct GNUNET_MessageHeader) + GNUNET_HELLO_size( | ||
1013 | *(plugin->env->our_hello)); | ||
1014 | |||
1015 | msgheader = GNUNET_malloc(size); | ||
1016 | msgheader->size = htons(size - sizeof(struct GNUNET_MessageHeader)); | ||
1017 | msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); | ||
1018 | |||
1019 | radioHeader = (struct RadiotapHeader *) &msgheader[1]; | ||
1020 | getRadiotapHeader(radioHeader); | ||
1021 | |||
1022 | ieeewlanheader = (struct IeeeHeader *) &radioHeader[1]; | ||
1023 | getWlanHeader(ieeewlanheader); | ||
1024 | |||
1025 | msgheader2 = (struct GNUNET_MessageHeader *) &ieeewlanheader[1]; | ||
1026 | msgheader2->size = htons(GNUNET_HELLO_size(*(plugin->env->our_hello))); | ||
1027 | msgheader2->type = htons(GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT); | ||
1028 | |||
1029 | memcpy(&msgheader2[1], *plugin->env->our_hello, GNUNET_HELLO_size( | ||
1030 | *(plugin->env->our_hello))); | ||
1031 | |||
1032 | |||
1033 | bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader, | ||
1034 | size); | ||
1035 | GNUNET_assert(bytes == size); | ||
1036 | |||
1037 | set_next_beacon_time(plugin); | ||
1038 | check_next_fragment_timeout(plugin); | ||
1039 | return; | ||
1040 | |||
1041 | } | ||
1042 | |||
785 | 1043 | ||
786 | fm = plugin->pending_Fragment_Messages_head; | 1044 | fm = plugin->pending_Fragment_Messages_head; |
787 | GNUNET_assert(fm != NULL); | 1045 | GNUNET_assert(fm != NULL); |
@@ -846,7 +1104,7 @@ do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
846 | copysize = GNUNET_MIN(fm->message_size - copyoffset, | 1104 | copysize = GNUNET_MIN(fm->message_size - copyoffset, |
847 | WLAN_MTU - sizeof(struct FragmentationHeader)); | 1105 | WLAN_MTU - sizeof(struct FragmentationHeader)); |
848 | fragheader.header.size = htons(copysize); | 1106 | fragheader.header.size = htons(copysize); |
849 | fragheader.header.type = GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT; | 1107 | fragheader.header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT); |
850 | 1108 | ||
851 | 1109 | ||
852 | //get the next missing fragment | 1110 | //get the next missing fragment |
@@ -879,23 +1137,23 @@ do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
879 | + sizeof(struct GNUNET_MessageHeader); | 1137 | + sizeof(struct GNUNET_MessageHeader); |
880 | msgheader = GNUNET_malloc(size); | 1138 | msgheader = GNUNET_malloc(size); |
881 | msgheader->size = htons(size - sizeof(struct GNUNET_MessageHeader)); | 1139 | msgheader->size = htons(size - sizeof(struct GNUNET_MessageHeader)); |
882 | msgheader->type = GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA; | 1140 | msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); |
883 | 1141 | ||
884 | radioHeader = (struct RadiotapHeader*) &msgheader[1]; | 1142 | radioHeader = (struct RadiotapHeader*) &msgheader[1]; |
885 | getRadiotapHeader(radioHeader); | 1143 | getRadiotapHeader(radioHeader); |
886 | 1144 | ||
887 | wlanheader = (struct IeeeHeader *) &radioHeader[1]; | 1145 | ieeewlanheader = (struct IeeeHeader *) &radioHeader[1]; |
888 | getWlanHeader(wlanheader); | 1146 | getWlanHeader(ieeewlanheader); |
889 | 1147 | ||
890 | 1148 | ||
891 | //could be faster if content is just send and not copyed before | 1149 | //could be faster if content is just send and not copyed before |
892 | //fragmentheader is needed | 1150 | //fragmentheader is needed |
893 | if (fm->message_size > WLAN_MTU){ | 1151 | if (fm->message_size > WLAN_MTU){ |
894 | fragheader.message_crc = htons(getcrc16(copystart, copysize)); | 1152 | fragheader.message_crc = htons(getcrc16(copystart, copysize)); |
895 | memcpy(&wlanheader[1],&fragheader, sizeof(struct FragmentationHeader)); | 1153 | memcpy(&ieeewlanheader[1],&fragheader, sizeof(struct FragmentationHeader)); |
896 | memcpy(&wlanheader[1] + sizeof(struct FragmentationHeader),copystart,copysize); | 1154 | memcpy(&ieeewlanheader[1] + sizeof(struct FragmentationHeader),copystart,copysize); |
897 | } else { | 1155 | } else { |
898 | memcpy(&wlanheader[1],copystart,copysize); | 1156 | memcpy(&ieeewlanheader[1],copystart,copysize); |
899 | } | 1157 | } |
900 | 1158 | ||
901 | bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader, size); | 1159 | bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader, size); |
@@ -999,16 +1257,19 @@ wlan_plugin_send (void *cls, | |||
999 | GNUNET_assert(msgbuf_size > 0); | 1257 | GNUNET_assert(msgbuf_size > 0); |
1000 | 1258 | ||
1001 | //get session if needed | 1259 | //get session if needed |
1002 | if (session == NULL) { | 1260 | if (session == NULL) |
1003 | if ( wlan_plugin_address_suggested(plugin , addr, addrlen) == GNUNET_OK){ | 1261 | { |
1004 | session = get_Session(plugin, addr); | 1262 | if (wlan_plugin_address_suggested(plugin, addr, addrlen) == GNUNET_OK) |
1005 | } else { | 1263 | { |
1006 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1264 | session = get_Session(plugin, addr); |
1007 | _("Wlan Address len %d is wrong\n"), | 1265 | } |
1008 | addrlen); | 1266 | else |
1009 | return -1; | 1267 | { |
1010 | } | 1268 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, |
1011 | } | 1269 | _("Wlan Address len %d is wrong\n"), addrlen); |
1270 | return -1; | ||
1271 | } | ||
1272 | } | ||
1012 | 1273 | ||
1013 | //TODO target "problem" not solved | 1274 | //TODO target "problem" not solved |
1014 | session->target = *target; | 1275 | session->target = *target; |
@@ -1018,30 +1279,43 @@ wlan_plugin_send (void *cls, | |||
1018 | queue_Session(plugin, session); | 1279 | queue_Session(plugin, session); |
1019 | 1280 | ||
1020 | //queue message in session | 1281 | //queue message in session |
1021 | if (session->pending_message == NULL){ | 1282 | //test if there is no other message in the "queue" |
1022 | newmsg = GNUNET_malloc(sizeof(struct PendingMessage)); | 1283 | GNUNET_assert (session->pending_message == NULL); |
1023 | (newmsg->msg) = GNUNET_malloc(msgbuf_size + sizeof(struct WlanHeader)); | 1284 | |
1024 | wlanheader = (struct WlanHeader *) newmsg->msg; | 1285 | newmsg = GNUNET_malloc(sizeof(struct PendingMessage)); |
1025 | //copy msg to buffer, not fragmented / segmented yet, but with message header | 1286 | (newmsg->msg) = GNUNET_malloc(msgbuf_size + sizeof(struct WlanHeader)); |
1026 | wlanheader->header.size = htons(msgbuf_size); | 1287 | wlanheader = (struct WlanHeader *) newmsg->msg; |
1027 | wlanheader->header.type = GNUNET_MESSAGE_TYPE_WLAN_DATA; | 1288 | //copy msg to buffer, not fragmented / segmented yet, but with message header |
1028 | wlanheader->target = *target; | 1289 | wlanheader->header.size = htons(msgbuf_size); |
1029 | wlanheader->crc = getcrc32(msgbuf, msgbuf_size); | 1290 | wlanheader->header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_DATA); |
1030 | memcpy(&wlanheader[1], msgbuf, msgbuf_size); | 1291 | memcpy(&(wlanheader->target), target, sizeof(struct GNUNET_PeerIdentity)); |
1031 | newmsg->transmit_cont = cont; | 1292 | wlanheader->crc = htonl(getcrc32(msgbuf, msgbuf_size)); |
1032 | newmsg->transmit_cont_cls = cont_cls; | 1293 | memcpy(&wlanheader[1], msgbuf, msgbuf_size); |
1033 | newmsg->timeout = GNUNET_TIME_relative_to_absolute(timeout); | 1294 | newmsg->transmit_cont = cont; |
1034 | newmsg->message_size = msgbuf_size + sizeof(struct WlanHeader); | 1295 | newmsg->transmit_cont_cls = cont_cls; |
1035 | } else { | 1296 | newmsg->timeout = GNUNET_TIME_relative_to_absolute(timeout); |
1036 | //TODO if message is send while hello is still pending, other cases should not occur | 1297 | newmsg->message_size = msgbuf_size + sizeof(struct WlanHeader); |
1037 | } | 1298 | |
1038 | check_fragment_queue(plugin); | 1299 | check_fragment_queue(plugin); |
1039 | //FIXME not the correct size | 1300 | //FIXME not the correct size |
1040 | return msgbuf_size; | 1301 | return msgbuf_size; |
1041 | 1302 | ||
1042 | } | 1303 | } |
1043 | 1304 | ||
1044 | 1305 | static struct FragmentMessage * | |
1306 | get_fragment_message_from_session(struct Session * session) | ||
1307 | { | ||
1308 | struct FragmentMessage * fm = session->plugin->pending_Fragment_Messages_head; | ||
1309 | while (fm != NULL) | ||
1310 | { | ||
1311 | if (fm->session == session) | ||
1312 | { | ||
1313 | return fm; | ||
1314 | } | ||
1315 | fm = fm->next; | ||
1316 | } | ||
1317 | return NULL; | ||
1318 | } | ||
1045 | 1319 | ||
1046 | /** | 1320 | /** |
1047 | * Function that can be used to force the plugin to disconnect | 1321 | * Function that can be used to force the plugin to disconnect |
@@ -1052,36 +1326,57 @@ wlan_plugin_send (void *cls, | |||
1052 | * @param target peer from which to disconnect | 1326 | * @param target peer from which to disconnect |
1053 | */ | 1327 | */ |
1054 | static void | 1328 | static void |
1055 | wlan_plugin_disconnect (void *cls, | 1329 | wlan_plugin_disconnect(void *cls, const struct GNUNET_PeerIdentity *target) |
1056 | const struct GNUNET_PeerIdentity *target) | ||
1057 | { | 1330 | { |
1058 | struct Plugin *plugin = cls; | 1331 | struct Plugin *plugin = cls; |
1059 | struct Sessionqueue * queue = plugin->sessions; | 1332 | struct Sessionqueue * queue = plugin->sessions; |
1060 | struct Sessionqueue * lastitem = NULL; | 1333 | struct Sessionqueue * pendingsession = plugin->pending_Sessions; |
1061 | struct PendingMessage * pm; | 1334 | struct PendingMessage * pm = NULL; |
1062 | 1335 | struct FragmentMessage * fm; | |
1063 | // just look at all the session for the needed one | ||
1064 | while (queue != NULL){ | ||
1065 | // content is never NULL | ||
1066 | GNUNET_assert (queue->content == NULL); | ||
1067 | if (memcmp(target, &(queue->content->target), sizeof(struct GNUNET_PeerIdentity)) == 0) | ||
1068 | { | ||
1069 | // session found | ||
1070 | // remove PendingMessage | ||
1071 | pm = queue->content->pending_message; | ||
1072 | GNUNET_free(pm->msg); | ||
1073 | GNUNET_free(pm); | ||
1074 | |||
1075 | GNUNET_free(queue->content); | ||
1076 | GNUNET_CONTAINER_DLL_remove(plugin->sessions, plugin->sessions_tail, queue); | ||
1077 | GNUNET_free(queue); | ||
1078 | 1336 | ||
1079 | return; | 1337 | // just look at all the session for the needed one |
1080 | } | 1338 | while (queue != NULL) |
1081 | // try next | 1339 | { |
1082 | lastitem = queue; | 1340 | // content is never NULL |
1083 | queue = queue->next; | 1341 | GNUNET_assert (queue->content == NULL); |
1084 | } | 1342 | if (memcmp(target, &(queue->content->target), |
1343 | sizeof(struct GNUNET_PeerIdentity)) == 0) | ||
1344 | { | ||
1345 | //session found | ||
1346 | //is this session pending for send | ||
1347 | while (pendingsession != NULL) | ||
1348 | { | ||
1349 | if (pendingsession->content == queue->content) | ||
1350 | { | ||
1351 | plugin->pendingsessions --; | ||
1352 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions, | ||
1353 | plugin->pending_Sessions_tail, pendingsession); | ||
1354 | GNUNET_free(pendingsession); | ||
1355 | break; | ||
1356 | } | ||
1357 | pendingsession = pendingsession->next; | ||
1358 | } | ||
1359 | |||
1360 | //is something of this session in the fragment queue? | ||
1361 | fm = get_fragment_message_from_session(queue->content); | ||
1362 | free_fragment_message(plugin,fm); | ||
1363 | |||
1364 | |||
1365 | // remove PendingMessage | ||
1366 | pm = queue->content->pending_message; | ||
1367 | GNUNET_free(pm->msg); | ||
1368 | GNUNET_free(pm); | ||
1369 | |||
1370 | GNUNET_free(queue->content); | ||
1371 | GNUNET_CONTAINER_DLL_remove(plugin->sessions, plugin->sessions_tail, queue); | ||
1372 | GNUNET_free(queue); | ||
1373 | plugin->session_count --; | ||
1374 | |||
1375 | return; | ||
1376 | } | ||
1377 | // try next | ||
1378 | queue = queue->next; | ||
1379 | } | ||
1085 | } | 1380 | } |
1086 | 1381 | ||
1087 | 1382 | ||
@@ -1206,6 +1501,7 @@ wlan_plugin_address_to_string (void *cls, | |||
1206 | 1501 | ||
1207 | 1502 | ||
1208 | 1503 | ||
1504 | |||
1209 | /** | 1505 | /** |
1210 | * Function used for to process the data from the suid process | 1506 | * Function used for to process the data from the suid process |
1211 | */ | 1507 | */ |
@@ -1217,28 +1513,224 @@ wlan_process_helper (void *cls, | |||
1217 | const struct GNUNET_MessageHeader *hdr) | 1513 | const struct GNUNET_MessageHeader *hdr) |
1218 | { | 1514 | { |
1219 | struct Plugin *plugin = cls; | 1515 | struct Plugin *plugin = cls; |
1220 | if (hdr->type == GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA){ | 1516 | struct IeeeHeader * wlanIeeeHeader = NULL; |
1221 | //TODO DATA | 1517 | struct Session * session = NULL; |
1222 | } else if (hdr->type == GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT){ | 1518 | struct WlanHeader * wlanheader = NULL; |
1223 | //TODO ADV | 1519 | struct FragmentationHeader * fh = NULL; |
1224 | } else if (hdr->type == GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL){ | 1520 | struct FragmentMessage * fm = NULL; |
1225 | //TODO Control | 1521 | const struct GNUNET_MessageHeader * temp_hdr = NULL; |
1226 | if (hdr->size == 6){ | 1522 | const char * tempmsg = NULL; |
1227 | plugin->mac_address = GNUNET_malloc(6); | 1523 | struct Session_light * session_light; |
1228 | memcpy(plugin->mac_address, &hdr[1],6); | 1524 | struct AckQueue * ack; |
1229 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Notifying transport of address %s\n", wlan_plugin_address_to_string(cls, plugin->mac_address, hdr->size)); | 1525 | struct AckQueue * ack2; |
1230 | plugin->env->notify_address (plugin->env->cls, | 1526 | int pos = 0; |
1231 | "wlan", | 1527 | |
1232 | &plugin->mac_address, sizeof(plugin->mac_address), | 1528 | |
1233 | GNUNET_TIME_UNIT_FOREVER_REL); | 1529 | if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA) |
1234 | } else { | 1530 | { |
1235 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Wrong wlan mac address %s\n", plugin->mac_address); | 1531 | //call wlan_process_helper with the message inside, later with wlan: analyze signal |
1532 | GNUNET_assert(ntohs(hdr->size) >= sizeof(struct IeeeHeader)); | ||
1533 | wlanIeeeHeader = (struct IeeeHeader *) &hdr[1]; | ||
1534 | |||
1535 | session_light = GNUNET_malloc(sizeof(struct Session_light)); | ||
1536 | memcpy(session_light->addr, wlanIeeeHeader->mac3, 6); | ||
1537 | session_light->session = search_session(plugin, session_light->addr); | ||
1538 | |||
1539 | //process only if it is an broadcast or for this computer both with the gnunet bssid | ||
1540 | //check for bssid | ||
1541 | if (memcmp(wlanIeeeHeader->mac2, macbc, sizeof(macbc))) | ||
1542 | { | ||
1543 | //check for broadcast or mac | ||
1544 | if (memcmp(wlanIeeeHeader->mac1, bc_all_mac, sizeof(bc_all_mac)) | ||
1545 | || memcmp(wlanIeeeHeader->mac1, plugin->mac_address, | ||
1546 | sizeof(plugin->mac_address))) | ||
1547 | { | ||
1548 | // process the inner data | ||
1549 | pos = 0; | ||
1550 | temp_hdr = (struct GNUNET_MessageHeader *) &wlanIeeeHeader[1]; | ||
1551 | while (pos < hdr->size) | ||
1552 | { | ||
1553 | wlan_process_helper(plugin, &session_light, | ||
1554 | temp_hdr); | ||
1555 | pos += temp_hdr->size + sizeof(struct GNUNET_MessageHeader); | ||
1556 | } | ||
1557 | } | ||
1558 | } | ||
1559 | |||
1236 | } | 1560 | } |
1237 | 1561 | ||
1238 | 1562 | ||
1239 | } else { | 1563 | else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT) |
1240 | // TODO Wrong data? | 1564 | { |
1241 | } | 1565 | //TODO better DOS protection, error handling |
1566 | GNUNET_assert(client != NULL); | ||
1567 | session_light = (struct Session_light *) client; | ||
1568 | if (session_light->session == NULL){ | ||
1569 | session_light->session = get_Session(plugin, session_light->addr); | ||
1570 | } | ||
1571 | GNUNET_assert(GNUNET_HELLO_get_id( | ||
1572 | (const struct GNUNET_HELLO_Message *) &hdr[1], | ||
1573 | &(session_light->session->target) ) != GNUNET_SYSERR); | ||
1574 | |||
1575 | } | ||
1576 | |||
1577 | |||
1578 | else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_DATA) | ||
1579 | { | ||
1580 | GNUNET_assert(client != NULL); | ||
1581 | session_light = (struct Session_light *) client; | ||
1582 | if (session_light->session == NULL){ | ||
1583 | session_light->session = search_session(plugin, session_light->addr); | ||
1584 | } | ||
1585 | session = session_light->session; | ||
1586 | wlanheader =(struct WlanHeader *) &hdr[1]; | ||
1587 | tempmsg = (char*) &wlanheader[1]; | ||
1588 | temp_hdr = ( const struct GNUNET_MessageHeader *) &wlanheader[1]; | ||
1589 | |||
1590 | if (getcrc32(tempmsg, wlanheader->header.size) != wlanheader->crc){ | ||
1591 | //wrong crc, dispose message | ||
1592 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1593 | "WLAN message crc was wrong\n"); | ||
1594 | return; | ||
1595 | } | ||
1596 | |||
1597 | //if not in session list | ||
1598 | if (session == NULL){ | ||
1599 | |||
1600 | //try if it is a hello message | ||
1601 | if (ntohs(temp_hdr->type) == GNUNET_MESSAGE_TYPE_HELLO){ | ||
1602 | session = create_session(plugin, session_light->addr); | ||
1603 | session_light->session = session; | ||
1604 | GNUNET_assert(GNUNET_HELLO_get_id( | ||
1605 | (const struct GNUNET_HELLO_Message *) temp_hdr, | ||
1606 | &session->target ) != GNUNET_SYSERR); | ||
1607 | |||
1608 | } else { | ||
1609 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
1610 | "WLAN client not in session list and not a hello message\n"); | ||
1611 | return; | ||
1612 | } | ||
1613 | } | ||
1614 | //"receive" the message | ||
1615 | plugin->env->receive(plugin, &session->target, | ||
1616 | temp_hdr, 1, session, session->addr, sizeof(session->addr)); | ||
1617 | } | ||
1618 | |||
1619 | else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT) | ||
1620 | { | ||
1621 | GNUNET_assert(client != NULL); | ||
1622 | session_light = (struct Session_light *) client; | ||
1623 | if (session_light->session == NULL) | ||
1624 | { | ||
1625 | session_light->session = search_session(plugin, session_light->addr); | ||
1626 | } | ||
1627 | session = session_light->session; | ||
1628 | |||
1629 | fh = (struct FragmentationHeader *) &hdr[1]; | ||
1630 | tempmsg = (char*) &fh[1]; | ||
1631 | |||
1632 | //if not in session list | ||
1633 | if (session != NULL) | ||
1634 | { | ||
1635 | if (getcrc16(tempmsg, fh->header.size) != fh->message_crc) | ||
1636 | { | ||
1637 | //wrong crc, dispose message | ||
1638 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
1639 | "WLAN fragment crc was wrong\n"); | ||
1640 | return; | ||
1641 | } | ||
1642 | else | ||
1643 | { | ||
1644 | //todo fragments to message | ||
1645 | } | ||
1646 | } | ||
1647 | else | ||
1648 | { | ||
1649 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | ||
1650 | "WLAN client not in session list and it is a fragment message\n"); | ||
1651 | return; | ||
1652 | } | ||
1653 | |||
1654 | } | ||
1655 | |||
1656 | else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT_ACK) | ||
1657 | { | ||
1658 | GNUNET_assert(client != NULL); | ||
1659 | session_light = (struct Session_light *) client; | ||
1660 | if (session_light->session == NULL) | ||
1661 | { | ||
1662 | session_light->session = search_session(plugin, session_light->addr); | ||
1663 | } | ||
1664 | session = session_light->session; | ||
1665 | fh = (struct FragmentationHeader *) &hdr[1]; | ||
1666 | if (fh->message_id == session->message_id_out) | ||
1667 | { | ||
1668 | fm = get_fragment_message_from_session(session); | ||
1669 | if (fm != NULL) | ||
1670 | { | ||
1671 | ack = GNUNET_malloc(sizeof(struct AckQueue)); | ||
1672 | ack->fragment_num = fh->fragment_off_or_num; | ||
1673 | ack2 = fm->head; | ||
1674 | while (ack2!=NULL){ | ||
1675 | if (ack2->fragment_num != ack->fragment_num) | ||
1676 | { | ||
1677 | if (ack2->fragment_num > ack->fragment_num) | ||
1678 | { | ||
1679 | GNUNET_CONTAINER_DLL_insert_before(fm->head,fm->tail,ack2,ack); | ||
1680 | //check if finished | ||
1681 | check_finished_fragment(plugin, fm); | ||
1682 | } | ||
1683 | } | ||
1684 | else | ||
1685 | { | ||
1686 | //double ack | ||
1687 | return; | ||
1688 | } | ||
1689 | ack2 = ack2->next; | ||
1690 | } | ||
1691 | GNUNET_CONTAINER_DLL_insert_tail(fm->head,fm->tail,ack); | ||
1692 | //should never happen but... | ||
1693 | check_finished_fragment(plugin, fm); | ||
1694 | } | ||
1695 | else | ||
1696 | { | ||
1697 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | ||
1698 | "WLAN fragment not in fragment list but id is right\n"); | ||
1699 | return; | ||
1700 | } | ||
1701 | |||
1702 | } | ||
1703 | |||
1704 | } | ||
1705 | |||
1706 | else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL) | ||
1707 | { | ||
1708 | //TODO Control | ||
1709 | if (ntohs(hdr->size) == 6) | ||
1710 | { | ||
1711 | plugin->mac_address = GNUNET_malloc(6); | ||
1712 | memcpy(plugin->mac_address, &hdr[1], 6); | ||
1713 | GNUNET_log( | ||
1714 | GNUNET_ERROR_TYPE_DEBUG, | ||
1715 | "Notifying transport of address %s\n", | ||
1716 | wlan_plugin_address_to_string(cls, plugin->mac_address, hdr->size)); | ||
1717 | plugin->env->notify_address(plugin->env->cls, "wlan", | ||
1718 | &plugin->mac_address, sizeof(plugin->mac_address), | ||
1719 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
1720 | } | ||
1721 | else | ||
1722 | { | ||
1723 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Wrong wlan mac address %s\n", | ||
1724 | plugin->mac_address); | ||
1725 | } | ||
1726 | |||
1727 | } | ||
1728 | |||
1729 | |||
1730 | else | ||
1731 | { | ||
1732 | // TODO Wrong data? | ||
1733 | } | ||
1242 | } | 1734 | } |
1243 | 1735 | ||
1244 | 1736 | ||
@@ -1247,24 +1739,31 @@ wlan_plugin_helper_read (void *cls, | |||
1247 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 1739 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
1248 | { | 1740 | { |
1249 | struct Plugin *plugin = cls; | 1741 | struct Plugin *plugin = cls; |
1250 | char mybuf[WLAN_MTU]; | 1742 | plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; |
1743 | |||
1744 | char mybuf[WLAN_MTU + sizeof(struct GNUNET_MessageHeader)]; | ||
1251 | ssize_t bytes; | 1745 | ssize_t bytes; |
1252 | 1746 | ||
1253 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | 1747 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) |
1254 | return; | 1748 | return; |
1749 | |||
1255 | bytes = GNUNET_DISK_file_read (plugin->server_stdout_handle, | 1750 | bytes = GNUNET_DISK_file_read (plugin->server_stdout_handle, |
1256 | mybuf, sizeof(mybuf)); | 1751 | mybuf, sizeof(mybuf)); |
1257 | if (bytes <= 0) | 1752 | if (bytes <= 0) |
1258 | { | 1753 | { |
1259 | #if DEBUG_TCP_NAT | 1754 | #if DEBUG_wlan |
1260 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1755 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1261 | _("Finished reading from wlan-helper stdout with code: %d\n"), bytes); | 1756 | _("Finished reading from wlan-helper stdout with code: %d\n"), bytes); |
1262 | #endif | 1757 | #endif |
1263 | return; | 1758 | return; |
1264 | } | 1759 | } |
1265 | GNUNET_SERVER_mst_receive(plugin->consoltoken, NULL, | 1760 | GNUNET_SERVER_mst_receive(plugin->consoltoken, NULL, |
1266 | mybuf, bytes, 0, GNUNET_NO); | 1761 | mybuf, bytes, GNUNET_NO, GNUNET_NO); |
1267 | 1762 | ||
1763 | GNUNET_assert(plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK); | ||
1764 | plugin->server_read_task = | ||
1765 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
1766 | plugin->server_stdout_handle, &wlan_plugin_helper_read, plugin); | ||
1268 | } | 1767 | } |
1269 | 1768 | ||
1270 | 1769 | ||
@@ -1276,28 +1775,30 @@ wlan_plugin_helper_read (void *cls, | |||
1276 | * @return GNUNET_YES if process was started, GNUNET_SYSERR on error | 1775 | * @return GNUNET_YES if process was started, GNUNET_SYSERR on error |
1277 | */ | 1776 | */ |
1278 | static int | 1777 | static int |
1279 | wlan_transport_start_wlan_helper (struct Plugin *plugin) | 1778 | wlan_transport_start_wlan_helper(struct Plugin *plugin) |
1280 | { | 1779 | { |
1281 | 1780 | ||
1282 | plugin->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES); | 1781 | plugin->server_stdout = GNUNET_DISK_pipe(GNUNET_YES, GNUNET_NO, GNUNET_YES); |
1283 | if (plugin->server_stdout == NULL) | 1782 | if (plugin->server_stdout == NULL) |
1284 | return GNUNET_SYSERR; | 1783 | return GNUNET_SYSERR; |
1285 | 1784 | ||
1286 | plugin->server_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO); | 1785 | plugin->server_stdin = GNUNET_DISK_pipe(GNUNET_YES, GNUNET_YES, GNUNET_NO); |
1287 | if (plugin->server_stdin == NULL) | 1786 | if (plugin->server_stdin == NULL) |
1288 | return GNUNET_SYSERR; | 1787 | return GNUNET_SYSERR; |
1289 | 1788 | ||
1290 | #if DEBUG_TCP_NAT | 1789 | #if DEBUG_wlan |
1291 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1790 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1292 | "Starting gnunet-wlan-helper process cmd: %s %s\n", "gnunet-wlan-helper", plugin->interface); | 1791 | "Starting gnunet-wlan-helper process cmd: %s %s\n", "gnunet-wlan-helper", plugin->interface); |
1293 | #endif | 1792 | #endif |
1294 | /* Start the server process */ | 1793 | /* Start the server process */ |
1295 | plugin->server_proc = GNUNET_OS_start_process(plugin->server_stdin, plugin->server_stdout, "gnunet-transport-wlan-helper", "gnunet-transport-wlan-helper", plugin->interface, NULL); | 1794 | plugin->server_proc = GNUNET_OS_start_process(plugin->server_stdin, |
1795 | plugin->server_stdout, "gnunet-transport-wlan-helper", | ||
1796 | "gnunet-transport-wlan-helper", plugin->interface, NULL); | ||
1296 | if (plugin->server_proc == NULL) | 1797 | if (plugin->server_proc == NULL) |
1297 | { | 1798 | { |
1298 | #if DEBUG_TCP_NAT | 1799 | #if DEBUG_wlan |
1299 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1800 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1300 | "Failed to start gnunet-wlan-helper process\n"); | 1801 | "Failed to start gnunet-wlan-helper process\n"); |
1301 | #endif | 1802 | #endif |
1302 | return GNUNET_SYSERR; | 1803 | return GNUNET_SYSERR; |
1303 | } | 1804 | } |
@@ -1307,12 +1808,15 @@ wlan_transport_start_wlan_helper (struct Plugin *plugin) | |||
1307 | /* Close the read end of the write pipe */ | 1808 | /* Close the read end of the write pipe */ |
1308 | GNUNET_DISK_pipe_close_end(plugin->server_stdin, GNUNET_DISK_PIPE_END_READ); | 1809 | GNUNET_DISK_pipe_close_end(plugin->server_stdin, GNUNET_DISK_PIPE_END_READ); |
1309 | 1810 | ||
1310 | plugin->server_stdout_handle = GNUNET_DISK_pipe_handle(plugin->server_stdout, GNUNET_DISK_PIPE_END_READ); | 1811 | plugin->server_stdout_handle = GNUNET_DISK_pipe_handle(plugin->server_stdout, |
1311 | plugin->server_stdin_handle = GNUNET_DISK_pipe_handle(plugin->server_stdin, GNUNET_DISK_PIPE_END_WRITE); | 1812 | GNUNET_DISK_PIPE_END_READ); |
1813 | plugin->server_stdin_handle = GNUNET_DISK_pipe_handle(plugin->server_stdin, | ||
1814 | GNUNET_DISK_PIPE_END_WRITE); | ||
1312 | 1815 | ||
1313 | plugin->server_read_task = | 1816 | GNUNET_assert(plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK); |
1314 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | 1817 | plugin->server_read_task = GNUNET_SCHEDULER_add_read_file( |
1315 | plugin->server_stdout_handle, &wlan_plugin_helper_read, plugin); | 1818 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdout_handle, |
1819 | &wlan_plugin_helper_read, plugin); | ||
1316 | return GNUNET_YES; | 1820 | return GNUNET_YES; |
1317 | } | 1821 | } |
1318 | 1822 | ||
@@ -1345,8 +1849,10 @@ libgnunet_plugin_transport_wlan_init (void *cls) | |||
1345 | plugin = GNUNET_malloc (sizeof (struct Plugin)); | 1849 | plugin = GNUNET_malloc (sizeof (struct Plugin)); |
1346 | plugin->env = env; | 1850 | plugin->env = env; |
1347 | plugin->pendingsessions = 0; | 1851 | plugin->pendingsessions = 0; |
1852 | plugin->session_count = 0; | ||
1348 | plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; | 1853 | plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; |
1349 | plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; | 1854 | plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; |
1855 | plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; | ||
1350 | 1856 | ||
1351 | wlan_transport_start_wlan_helper(plugin); | 1857 | wlan_transport_start_wlan_helper(plugin); |
1352 | plugin->consoltoken = GNUNET_SERVER_mst_create(&wlan_process_helper,plugin); | 1858 | plugin->consoltoken = GNUNET_SERVER_mst_create(&wlan_process_helper,plugin); |
@@ -1373,12 +1879,15 @@ libgnunet_plugin_transport_wlan_init (void *cls) | |||
1373 | * Exit point from the plugin. | 1879 | * Exit point from the plugin. |
1374 | */ | 1880 | */ |
1375 | //TODO doxigen | 1881 | //TODO doxigen |
1882 | //fixme cleanup | ||
1376 | void * | 1883 | void * |
1377 | libgnunet_plugin_transport_wlan_done (void *cls) | 1884 | libgnunet_plugin_transport_wlan_done (void *cls) |
1378 | { | 1885 | { |
1379 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | 1886 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; |
1380 | struct Plugin *plugin = api->cls; | 1887 | struct Plugin *plugin = api->cls; |
1381 | 1888 | ||
1889 | GNUNET_SERVER_mst_destroy(plugin->consoltoken); | ||
1890 | |||
1382 | GNUNET_assert(cls !=NULL); | 1891 | GNUNET_assert(cls !=NULL); |
1383 | 1892 | ||
1384 | GNUNET_free_non_null(plugin->mac_address); | 1893 | GNUNET_free_non_null(plugin->mac_address); |
diff --git a/src/transport/plugin_transport_wlan.h b/src/transport/plugin_transport_wlan.h index 5ea8d3e20..1444af18e 100644 --- a/src/transport/plugin_transport_wlan.h +++ b/src/transport/plugin_transport_wlan.h | |||
@@ -33,15 +33,24 @@ typedef unsigned short uint16_t; | |||
33 | //Informations (in German) http://www.umtslink.at/content/WLAN_macheader-196.html | 33 | //Informations (in German) http://www.umtslink.at/content/WLAN_macheader-196.html |
34 | static const uint8_t u8aIeeeHeader[] = | 34 | static const uint8_t u8aIeeeHeader[] = |
35 | { | 35 | { |
36 | 0x08, 0x01, // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0; b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data | 36 | 0x08, 0x01, // Frame Control 0x08= 00001000 -> | b1,2 = 0 -> Version 0; |
37 | // 0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS; | 37 | // b3,4 = 10 -> Data; b5-8 = 0 -> Normal Data |
38 | // 0x01 = 00000001 -> | b1 = 1 to DS; b2 = 0 not from DS; | ||
38 | 0x00, 0x00, // Duration/ID | 39 | 0x00, 0x00, // Duration/ID |
39 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // mac1 | 40 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // mac1 - in this case receiver |
40 | 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac2 | 41 | 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac2 - in this case bssid |
41 | 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 | 42 | 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, // mac3 - in this case sender |
42 | 0x10, 0x86, //Sequence Control | 43 | 0x10, 0x86, //Sequence Control |
43 | }; | 44 | }; |
44 | 45 | ||
46 | // gnunet bssid | ||
47 | static const char macbc[] = | ||
48 | { 0x13, 0x22, 0x33, 0x44, 0x55, 0x66 }; | ||
49 | |||
50 | // broadcast mac | ||
51 | static const char bc_all_mac[] = | ||
52 | { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | ||
53 | |||
45 | /** | 54 | /** |
46 | * Wlan header | 55 | * Wlan header |
47 | */ | 56 | */ |