diff options
author | David Brodski <david@brodski.eu> | 2011-07-26 22:54:20 +0000 |
---|---|---|
committer | David Brodski <david@brodski.eu> | 2011-07-26 22:54:20 +0000 |
commit | b28504c9671f8b99b242f6fb2fb46822b8a626b3 (patch) | |
tree | 943b9248bba6cab8282a3e0ce5402373b6cb2f4f /src/transport | |
parent | 4b05e36936d22d82c554519d540d92f4823ca885 (diff) | |
download | gnunet-b28504c9671f8b99b242f6fb2fb46822b8a626b3.tar.gz gnunet-b28504c9671f8b99b242f6fb2fb46822b8a626b3.zip |
Changed wlan plugin, now uses fragmentation lib
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/Makefile.am | 1 | ||||
-rw-r--r-- | src/transport/plugin_transport_wlan.c | 1660 | ||||
-rw-r--r-- | src/transport/plugin_transport_wlan.h | 26 |
3 files changed, 475 insertions, 1212 deletions
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index feddbec78..608c41505 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am | |||
@@ -174,6 +174,7 @@ libgnunet_plugin_transport_wlan_la_LIBADD = \ | |||
174 | $(top_builddir)/src/hello/libgnunethello.la \ | 174 | $(top_builddir)/src/hello/libgnunethello.la \ |
175 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 175 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
176 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ | 176 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ |
177 | $(top_builddir)/src/fragmentation/libgnunetfragmentation.la \ | ||
177 | $(top_builddir)/src/util/libgnunetutil.la | 178 | $(top_builddir)/src/util/libgnunetutil.la |
178 | libgnunet_plugin_transport_wlan_la_LDFLAGS = \ | 179 | libgnunet_plugin_transport_wlan_la_LDFLAGS = \ |
179 | $(GN_PLUGIN_LDFLAGS) | 180 | $(GN_PLUGIN_LDFLAGS) |
diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c index 13c16d9d7..845407a9e 100644 --- a/src/transport/plugin_transport_wlan.c +++ b/src/transport/plugin_transport_wlan.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "plugin_transport_wlan.h" | 34 | #include "plugin_transport_wlan.h" |
35 | #include "gnunet_common.h" | 35 | #include "gnunet_common.h" |
36 | #include "gnunet_crypto_lib.h" | 36 | #include "gnunet_crypto_lib.h" |
37 | #include "gnunet/gnunet_fragmentation_lib.h" | ||
37 | //#include "wlan/ieee80211.h" | 38 | //#include "wlan/ieee80211.h" |
38 | //#include <netinet/ip.h> | 39 | //#include <netinet/ip.h> |
39 | 40 | ||
@@ -61,6 +62,11 @@ | |||
61 | #define FRAGMENT_QUEUE_MESSAGES_OUT_PER_SESSION 1 | 62 | #define FRAGMENT_QUEUE_MESSAGES_OUT_PER_SESSION 1 |
62 | 63 | ||
63 | /** | 64 | /** |
65 | * max messages in fragment queue per MAC | ||
66 | */ | ||
67 | #define FRAGMENT_QUEUE_MESSAGES_OUT_PER_MACENDPOINT 1 | ||
68 | |||
69 | /** | ||
64 | * time until message in in queue | 70 | * time until message in in queue |
65 | */ | 71 | */ |
66 | #define MESSAGE_IN_TIMEOUT GNUNET_TIME_UNIT_SECONDS | 72 | #define MESSAGE_IN_TIMEOUT GNUNET_TIME_UNIT_SECONDS |
@@ -72,7 +78,7 @@ | |||
72 | /** | 78 | /** |
73 | * max messages in in queue per session/client | 79 | * max messages in in queue per session/client |
74 | */ | 80 | */ |
75 | #define MESSAGES_IN_QUEUE_PER_SESSION 1 | 81 | #define MESSAGES_IN_DEFRAG_QUEUE_PER_MAC 1 |
76 | /** | 82 | /** |
77 | * scaling factor for hello beacon | 83 | * scaling factor for hello beacon |
78 | */ | 84 | */ |
@@ -209,10 +215,6 @@ struct Plugin | |||
209 | * encapsulation of packets received from the wlan helper | 215 | * encapsulation of packets received from the wlan helper |
210 | */ | 216 | */ |
211 | struct GNUNET_SERVER_MessageStreamTokenizer * data_tokenizer; | 217 | struct GNUNET_SERVER_MessageStreamTokenizer * data_tokenizer; |
212 | /** | ||
213 | * encapsulation of packets received | ||
214 | */ | ||
215 | struct GNUNET_SERVER_MessageStreamTokenizer * fragment_tokenizer; | ||
216 | 218 | ||
217 | /** | 219 | /** |
218 | * stdout pipe handle for the gnunet-wlan-helper process | 220 | * stdout pipe handle for the gnunet-wlan-helper process |
@@ -266,13 +268,13 @@ struct Plugin | |||
266 | 268 | ||
267 | /** | 269 | /** |
268 | * Sessions currently pending for transmission | 270 | * Sessions currently pending for transmission |
269 | * to this peer, if any. | 271 | * to a peer, if any. |
270 | */ | 272 | */ |
271 | struct Sessionqueue * pending_Sessions_head; | 273 | struct Sessionqueue * pending_Sessions_head; |
272 | 274 | ||
273 | /** | 275 | /** |
274 | * Sessions currently pending for transmission | 276 | * Sessions currently pending for transmission |
275 | * to this peer (tail), if any. | 277 | * to a peer (tail), if any. |
276 | */ | 278 | */ |
277 | struct Sessionqueue * pending_Sessions_tail; | 279 | struct Sessionqueue * pending_Sessions_tail; |
278 | 280 | ||
@@ -282,25 +284,18 @@ struct Plugin | |||
282 | unsigned int pendingsessions; | 284 | unsigned int pendingsessions; |
283 | 285 | ||
284 | /** | 286 | /** |
285 | * Messages in the fragmentation queue, head | 287 | * Messages in the sending queues |
286 | */ | 288 | */ |
287 | struct GNUNET_CONTAINER_Heap * pending_Fragment_Messages; | 289 | int pending_Fragment_Messages; |
288 | 290 | ||
289 | /** | 291 | /** |
290 | * Messages in the in Queue, head | 292 | * messages ready for send, head |
291 | */ | 293 | */ |
292 | struct Receive_Message_Queue * receive_messages_head; | 294 | struct FragmentMessage_queue * sending_messages_head; |
293 | |||
294 | /** | 295 | /** |
295 | * Messages in the in Queue, tail | 296 | * messages ready for send, tail |
296 | */ | 297 | */ |
297 | struct Receive_Message_Queue * receive_messages_teil; | 298 | struct FragmentMessage_queue * sending_messages_tail; |
298 | |||
299 | /** | ||
300 | * number of messages in the in queue | ||
301 | */ | ||
302 | unsigned int pending_receive_messages; | ||
303 | |||
304 | /** | 299 | /** |
305 | * time of the next "hello-beacon" | 300 | * time of the next "hello-beacon" |
306 | */ | 301 | */ |
@@ -315,6 +310,11 @@ struct Plugin | |||
315 | * queue to send acks for received fragments (tail) | 310 | * queue to send acks for received fragments (tail) |
316 | */ | 311 | */ |
317 | struct AckSendQueue * ack_send_queue_tail; | 312 | struct AckSendQueue * ack_send_queue_tail; |
313 | |||
314 | /** | ||
315 | * Tracker for bandwidth limit | ||
316 | */ | ||
317 | struct GNUNET_BANDWIDTH_Tracker tracker; | ||
318 | }; | 318 | }; |
319 | 319 | ||
320 | /** | 320 | /** |
@@ -340,6 +340,17 @@ struct Sessionqueue | |||
340 | }; | 340 | }; |
341 | 341 | ||
342 | /** | 342 | /** |
343 | * Queue of fragmented messages, for the sending queue of the plugin | ||
344 | */ | ||
345 | //TODO DOXIGEN | ||
346 | struct FragmentMessage_queue | ||
347 | { | ||
348 | struct FragmentMessage_queue * next; | ||
349 | struct FragmentMessage_queue * prev; | ||
350 | struct FragmentMessage * content; | ||
351 | }; | ||
352 | |||
353 | /** | ||
343 | * Queue for the fragments received | 354 | * Queue for the fragments received |
344 | */ | 355 | */ |
345 | //TODO DOXIGEN | 356 | //TODO DOXIGEN |
@@ -369,63 +380,6 @@ struct Plugin_Session_pair | |||
369 | }; | 380 | }; |
370 | 381 | ||
371 | /** | 382 | /** |
372 | * Queue for the fragments received | ||
373 | */ | ||
374 | struct Receive_Message_Queue | ||
375 | { | ||
376 | struct Receive_Message_Queue * next; | ||
377 | |||
378 | struct Receive_Message_Queue * prev; | ||
379 | |||
380 | /** | ||
381 | * current number for message incoming, to distinguish between the messages | ||
382 | */ | ||
383 | uint32_t message_id_in; | ||
384 | |||
385 | /** | ||
386 | * size of the message received, | ||
387 | * MESSAGE_LENGHT_UNKNOWN means that the size is not known, | ||
388 | * NO_MESSAGE_OR_MESSAGE_FINISHED means no message received | ||
389 | */ | ||
390 | int rec_size; | ||
391 | |||
392 | /** | ||
393 | * Sorted queue with the fragments received; head | ||
394 | */ | ||
395 | |||
396 | struct Receive_Fragment_Queue * frag_head; | ||
397 | |||
398 | /** | ||
399 | * Sorted queue with the fragments received; tail | ||
400 | */ | ||
401 | |||
402 | struct Receive_Fragment_Queue * frag_tail; | ||
403 | |||
404 | /** | ||
405 | * Session this fragment belongs to | ||
406 | */ | ||
407 | |||
408 | //struct Session * session; | ||
409 | |||
410 | /** | ||
411 | * Mac enddpoint this fragment belongs to | ||
412 | */ | ||
413 | |||
414 | struct MacEndpoint * endpoint; | ||
415 | |||
416 | /** | ||
417 | * Timeout value for the pending message. | ||
418 | */ | ||
419 | struct GNUNET_TIME_Absolute timeout; | ||
420 | |||
421 | /** | ||
422 | * Bitfield of received fragments | ||
423 | */ | ||
424 | |||
425 | uint64_t received_fragments; | ||
426 | }; | ||
427 | |||
428 | /** | ||
429 | * Information kept for each message that is yet to | 383 | * Information kept for each message that is yet to |
430 | * be transmitted. | 384 | * be transmitted. |
431 | */ | 385 | */ |
@@ -443,7 +397,7 @@ struct PendingMessage | |||
443 | /** | 397 | /** |
444 | * The pending message | 398 | * The pending message |
445 | */ | 399 | */ |
446 | char *msg; | 400 | struct WlanHeader *msg; |
447 | 401 | ||
448 | /** | 402 | /** |
449 | * Size of the message | 403 | * Size of the message |
@@ -493,10 +447,17 @@ struct AckSendQueue | |||
493 | uint32_t message_id; | 447 | uint32_t message_id; |
494 | 448 | ||
495 | /** | 449 | /** |
496 | * Bit field for received fragments | 450 | * msg to send |
497 | */ | 451 | */ |
498 | uint64_t fragments_field; | 452 | struct GNUNET_MessageHeader * hdr; |
499 | 453 | /** | |
454 | * pointer to the ieee wlan header | ||
455 | */ | ||
456 | struct ieee80211_frame * ieeewlanheader; | ||
457 | /** | ||
458 | * pointer to the radiotap header | ||
459 | */ | ||
460 | struct Radiotap_Send * radioHeader; | ||
500 | }; | 461 | }; |
501 | 462 | ||
502 | /** | 463 | /** |
@@ -566,6 +527,12 @@ struct Session | |||
566 | */ | 527 | */ |
567 | struct MacEndpoint * mac; | 528 | struct MacEndpoint * mac; |
568 | 529 | ||
530 | /** | ||
531 | * count of messages in the fragment out queue for this session | ||
532 | */ | ||
533 | |||
534 | int fragment_messages_out_count; | ||
535 | |||
569 | }; | 536 | }; |
570 | 537 | ||
571 | /** | 538 | /** |
@@ -586,6 +553,17 @@ struct MacEndpoint | |||
586 | */ | 553 | */ |
587 | struct Sessionqueue * sessions_tail; | 554 | struct Sessionqueue * sessions_tail; |
588 | /** | 555 | /** |
556 | * Messages currently sending | ||
557 | * to a peer, if any. | ||
558 | */ | ||
559 | struct FragmentMessage * sending_messages_head; | ||
560 | |||
561 | /** | ||
562 | * Messages currently sending | ||
563 | * to a peer (tail), if any. | ||
564 | */ | ||
565 | struct FragmentMessage * sending_messages_tail; | ||
566 | /** | ||
589 | * dll next | 567 | * dll next |
590 | */ | 568 | */ |
591 | struct MacEndpoint *next; | 569 | struct MacEndpoint *next; |
@@ -600,16 +578,15 @@ struct MacEndpoint | |||
600 | struct MacAddress addr; | 578 | struct MacAddress addr; |
601 | 579 | ||
602 | /** | 580 | /** |
603 | * count of messages in the fragment out queue for this session | 581 | * Defrag context for this mac endpoint |
604 | */ | 582 | */ |
605 | 583 | struct GNUNET_DEFRAGMENT_Context * defrag; | |
606 | int fragment_messages_out_count; | ||
607 | 584 | ||
608 | /** | 585 | /** |
609 | * count of messages in the fragment in queue for this session | 586 | * count of messages in the fragment out queue for this mac endpoint |
610 | */ | 587 | */ |
611 | 588 | ||
612 | int fragment_messages_in_count; | 589 | int fragment_messages_out_count; |
613 | 590 | ||
614 | //TODO DOXIGEN | 591 | //TODO DOXIGEN |
615 | uint8_t rate; | 592 | uint8_t rate; |
@@ -617,13 +594,19 @@ struct MacEndpoint | |||
617 | uint8_t antenna; | 594 | uint8_t antenna; |
618 | 595 | ||
619 | /** | 596 | /** |
620 | * backlog for incoming message ids | 597 | * Duplicates received |
621 | */ | 598 | */ |
622 | uint32_t message_id_backlog[MESSAGE_ID_BACKLOG_SIZE]; | 599 | int dups; |
600 | |||
601 | /** | ||
602 | * Fragments received | ||
603 | */ | ||
604 | int fragc; | ||
605 | |||
623 | /** | 606 | /** |
624 | * position in the backlog | 607 | * Acks received |
625 | */ | 608 | */ |
626 | int message_id_backlog_pos; | 609 | int acks; |
627 | }; | 610 | }; |
628 | 611 | ||
629 | /** | 612 | /** |
@@ -632,10 +615,6 @@ struct MacEndpoint | |||
632 | 615 | ||
633 | struct FragmentMessage | 616 | struct FragmentMessage |
634 | { | 617 | { |
635 | /** | ||
636 | * heap pointer of this message | ||
637 | */ | ||
638 | struct GNUNET_CONTAINER_HeapNode * node; | ||
639 | 618 | ||
640 | /** | 619 | /** |
641 | * Session this message belongs to | 620 | * Session this message belongs to |
@@ -654,68 +633,33 @@ struct FragmentMessage | |||
654 | struct FragmentMessage *prev; | 633 | struct FragmentMessage *prev; |
655 | 634 | ||
656 | /** | 635 | /** |
657 | * The pending message | ||
658 | */ | ||
659 | char *msg; | ||
660 | |||
661 | /** | ||
662 | * 0 if not in ack queue | ||
663 | * 1 if in ack queue | ||
664 | */ | ||
665 | |||
666 | char in_ack_queue; | ||
667 | |||
668 | /** | ||
669 | * Timeout value for the pending message. | 636 | * Timeout value for the pending message. |
670 | */ | 637 | */ |
671 | struct GNUNET_TIME_Absolute timeout; | 638 | struct GNUNET_TIME_Absolute timeout; |
672 | 639 | ||
673 | /** | 640 | /** |
674 | * Timeout value for the pending fragments. | 641 | * Fragmentation context |
675 | * Stores the time when the next msg fragment ack has to be received | ||
676 | */ | 642 | */ |
677 | struct GNUNET_TIME_Absolute next_ack; | 643 | struct GNUNET_FRAGMENT_Context * fragcontext; |
678 | 644 | ||
679 | /** | 645 | /** |
680 | * bitfield with all acks received for this message | 646 | * Fragment to send |
681 | */ | 647 | */ |
682 | uint64_t ack_bitfield; | 648 | char * frag; |
683 | 649 | ||
684 | /** | 650 | /** |
685 | * Size of the message | 651 | * size of message |
686 | */ | 652 | */ |
687 | size_t message_size; | 653 | size_t size; |
688 | 654 | ||
689 | /** | 655 | /** |
690 | * pos / next fragment number in the message, for fragmentation/segmentation, | 656 | * pointer to the ieee wlan header |
691 | * some acks can be missing but there is still time | ||
692 | */ | 657 | */ |
693 | uint32_t message_pos; | 658 | struct ieee80211_frame * ieeewlanheader; |
694 | |||
695 | /** | ||
696 | * current number for message outgoing, to distinguish between the messages | ||
697 | */ | ||
698 | uint32_t message_id_out; | ||
699 | }; | ||
700 | |||
701 | /** | ||
702 | * Header for messages which need fragmentation | ||
703 | */ | ||
704 | struct FragmentationAckHeader | ||
705 | { | ||
706 | |||
707 | struct GNUNET_MessageHeader header; | ||
708 | |||
709 | /** | ||
710 | * ID of message, to distinguish between the messages, picked randomly. | ||
711 | */ | ||
712 | uint32_t message_id GNUNET_PACKED; | ||
713 | |||
714 | /** | 659 | /** |
715 | * Offset or number of this fragment, for fragmentation/segmentation (design choice, TBD) | 660 | * pointer to the radiotap header |
716 | */ | 661 | */ |
717 | uint64_t fragment_field GNUNET_PACKED; | 662 | struct Radiotap_Send * radioHeader; |
718 | |||
719 | }; | 663 | }; |
720 | 664 | ||
721 | static void | 665 | static void |
@@ -723,6 +667,8 @@ do_transmit(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | |||
723 | static void | 667 | static void |
724 | free_session(struct Plugin * plugin, struct Sessionqueue * queue, | 668 | free_session(struct Plugin * plugin, struct Sessionqueue * queue, |
725 | int do_free_macendpoint); | 669 | int do_free_macendpoint); |
670 | static struct MacEndpoint * | ||
671 | create_macendpoint(struct Plugin *plugin, const struct MacAddress *addr); | ||
726 | 672 | ||
727 | /** | 673 | /** |
728 | * Generates a nice hexdump of a memory area. | 674 | * Generates a nice hexdump of a memory area. |
@@ -779,71 +725,6 @@ hexdump(void *mem, unsigned length) | |||
779 | } | 725 | } |
780 | 726 | ||
781 | /** | 727 | /** |
782 | * Sets a bit active in the bitArray. Increment bit-specific | ||
783 | * usage counter on disk only if below 4bit max (==15). | ||
784 | * | ||
785 | * @param bitArray memory area to set the bit in | ||
786 | * @param bitIdx which bit to set | ||
787 | */ | ||
788 | static void | ||
789 | setBit(char *bitArray, unsigned int bitIdx) | ||
790 | { | ||
791 | size_t arraySlot; | ||
792 | unsigned int targetBit; | ||
793 | |||
794 | arraySlot = bitIdx / 8; | ||
795 | targetBit = (1L << (bitIdx % 8)); | ||
796 | bitArray[arraySlot] |= targetBit; | ||
797 | } | ||
798 | |||
799 | /** | ||
800 | * Checks if a bit is active in the bitArray | ||
801 | * | ||
802 | * @param bitArray memory area to set the bit in | ||
803 | * @param bitIdx which bit to test | ||
804 | * @return GNUNET_YES if the bit is set, GNUNET_NO if not. | ||
805 | */ | ||
806 | static int | ||
807 | testBit(char *bitArray, unsigned int bitIdx) | ||
808 | { | ||
809 | size_t slot; | ||
810 | unsigned int targetBit; | ||
811 | |||
812 | slot = bitIdx / 8; | ||
813 | targetBit = (1L << (bitIdx % 8)); | ||
814 | if (bitArray[slot] & targetBit) | ||
815 | return GNUNET_YES; | ||
816 | return GNUNET_NO; | ||
817 | } | ||
818 | |||
819 | /** | ||
820 | * get the next message number, at the moment just a random one | ||
821 | * @return returns the next valid message-number for sending packets | ||
822 | */ | ||
823 | static uint32_t | ||
824 | get_next_message_id() | ||
825 | { | ||
826 | return GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); | ||
827 | } | ||
828 | |||
829 | static struct MacEndpoint * | ||
830 | create_macendpoint(struct Plugin *plugin, const struct MacAddress *addr) | ||
831 | { | ||
832 | struct MacEndpoint * newend = GNUNET_malloc(sizeof (struct MacEndpoint)); | ||
833 | newend->addr = *addr; | ||
834 | newend->plugin = plugin; | ||
835 | newend->addr = *addr; | ||
836 | newend->fragment_messages_out_count = 0; | ||
837 | newend->fragment_messages_in_count = 0; | ||
838 | newend->message_id_backlog_pos = 0; | ||
839 | |||
840 | plugin->mac_count++; | ||
841 | GNUNET_CONTAINER_DLL_insert_tail(plugin->mac_head, plugin->mac_tail, newend); | ||
842 | |||
843 | return newend; | ||
844 | } | ||
845 | |||
846 | /** | ||
847 | * Function to find a MacEndpoint with a specific mac addr | 728 | * Function to find a MacEndpoint with a specific mac addr |
848 | * @param plugin pointer to the plugin struct | 729 | * @param plugin pointer to the plugin struct |
849 | * @param addr pointer to the mac address | 730 | * @param addr pointer to the mac address |
@@ -882,14 +763,10 @@ get_macendpoint(struct Plugin *plugin, const struct MacAddress *addr, | |||
882 | * @return returns the session | 763 | * @return returns the session |
883 | */ | 764 | */ |
884 | static struct Session * | 765 | static struct Session * |
885 | search_session(struct Plugin *plugin, const struct MacAddress *addr, | 766 | search_session(struct Plugin *plugin, const struct MacEndpoint * endpoint, |
886 | const struct GNUNET_PeerIdentity * peer) | 767 | const struct GNUNET_PeerIdentity * peer) |
887 | { | 768 | { |
888 | struct MacEndpoint * endpoint = get_macendpoint(plugin, addr, GNUNET_NO); | 769 | GNUNET_assert(endpoint != NULL); |
889 | if (endpoint == NULL) | ||
890 | { | ||
891 | return NULL; | ||
892 | } | ||
893 | struct Sessionqueue * queue = endpoint->sessions_head; | 770 | struct Sessionqueue * queue = endpoint->sessions_head; |
894 | 771 | ||
895 | while (queue != NULL) | 772 | while (queue != NULL) |
@@ -954,8 +831,8 @@ create_session(struct Plugin *plugin, struct MacEndpoint * endpoint, | |||
954 | memcpy(&(queue->content->target), peer, sizeof(struct GNUNET_PeerIdentity)); | 831 | memcpy(&(queue->content->target), peer, sizeof(struct GNUNET_PeerIdentity)); |
955 | 832 | ||
956 | #if DEBUG_wlan | 833 | #if DEBUG_wlan |
957 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "New session %p with %s\n", | 834 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "New session %p with endpoint %p: %s\n", |
958 | queue->content, | 835 | queue->content, endpoint, |
959 | wlan_plugin_address_to_string(NULL, endpoint->addr.mac, 6)); | 836 | wlan_plugin_address_to_string(NULL, endpoint->addr.mac, 6)); |
960 | #endif | 837 | #endif |
961 | 838 | ||
@@ -974,11 +851,12 @@ static struct Session * | |||
974 | get_session(struct Plugin *plugin, const struct MacAddress *addr, | 851 | get_session(struct Plugin *plugin, const struct MacAddress *addr, |
975 | const struct GNUNET_PeerIdentity * peer) | 852 | const struct GNUNET_PeerIdentity * peer) |
976 | { | 853 | { |
977 | struct Session * session = search_session(plugin, addr, peer); | ||
978 | struct MacEndpoint * mac; | 854 | struct MacEndpoint * mac; |
855 | mac = get_macendpoint(plugin, addr, GNUNET_YES); | ||
856 | struct Session * session = search_session(plugin, mac, peer); | ||
857 | |||
979 | if (session != NULL) | 858 | if (session != NULL) |
980 | return session; | 859 | return session; |
981 | mac = get_macendpoint(plugin, addr, GNUNET_YES); | ||
982 | return create_session(plugin, mac, peer); | 860 | return create_session(plugin, mac, peer); |
983 | } | 861 | } |
984 | 862 | ||
@@ -1080,17 +958,6 @@ set_next_beacon_time(struct Plugin * const plugin) | |||
1080 | } | 958 | } |
1081 | 959 | ||
1082 | /** | 960 | /** |
1083 | * Function to get the timeout value for acks for this session | ||
1084 | * @param fm pointer to the FragmentMessage to get the next timeout | ||
1085 | * @return time until the next ack should be received, in GNUNET_TIME_Relative | ||
1086 | */ | ||
1087 | static struct GNUNET_TIME_Relative | ||
1088 | get_ack_timeout(struct FragmentMessage * fm) | ||
1089 | { | ||
1090 | return FRAGMENT_TIMEOUT; | ||
1091 | } | ||
1092 | |||
1093 | /** | ||
1094 | * Function to set the timer for the next timeout of the fragment queue | 961 | * Function to set the timer for the next timeout of the fragment queue |
1095 | * @param plugin the handle to the plugin struct | 962 | * @param plugin the handle to the plugin struct |
1096 | */ | 963 | */ |
@@ -1098,9 +965,7 @@ get_ack_timeout(struct FragmentMessage * fm) | |||
1098 | static void | 965 | static void |
1099 | set_next_send(struct Plugin * const plugin) | 966 | set_next_send(struct Plugin * const plugin) |
1100 | { | 967 | { |
1101 | struct FragmentMessage * fm; | ||
1102 | struct GNUNET_TIME_Relative next_send; | 968 | struct GNUNET_TIME_Relative next_send; |
1103 | struct GNUNET_TIME_Absolute next_send_tmp; | ||
1104 | 969 | ||
1105 | //cancel old task | 970 | //cancel old task |
1106 | if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK) | 971 | if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK) |
@@ -1109,8 +974,6 @@ set_next_send(struct Plugin * const plugin) | |||
1109 | plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; | 974 | plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; |
1110 | } | 975 | } |
1111 | 976 | ||
1112 | fm = GNUNET_CONTAINER_heap_peek(plugin->pending_Fragment_Messages); | ||
1113 | |||
1114 | //check if some acks are in the queue | 977 | //check if some acks are in the queue |
1115 | if (plugin->ack_send_queue_head != NULL) | 978 | if (plugin->ack_send_queue_head != NULL) |
1116 | { | 979 | { |
@@ -1118,17 +981,13 @@ set_next_send(struct Plugin * const plugin) | |||
1118 | } | 981 | } |
1119 | 982 | ||
1120 | //check if there are some fragments in the queue | 983 | //check if there are some fragments in the queue |
984 | else if (plugin->sending_messages_head != NULL) | ||
985 | { | ||
986 | next_send = GNUNET_TIME_UNIT_ZERO; | ||
987 | } | ||
1121 | else | 988 | else |
1122 | { | 989 | { |
1123 | next_send = GNUNET_TIME_absolute_get_remaining(plugin->beacon_time); | 990 | next_send = GNUNET_TIME_absolute_get_remaining(plugin->beacon_time); |
1124 | if (fm != NULL) | ||
1125 | { | ||
1126 | next_send_tmp.abs_value = GNUNET_CONTAINER_heap_node_get_cost( | ||
1127 | fm->node); | ||
1128 | next_send = GNUNET_TIME_relative_min(next_send, | ||
1129 | GNUNET_TIME_absolute_get_remaining(next_send_tmp)); | ||
1130 | |||
1131 | } | ||
1132 | } | 991 | } |
1133 | 992 | ||
1134 | #if DEBUG_wlan | 993 | #if DEBUG_wlan |
@@ -1149,8 +1008,11 @@ set_next_send(struct Plugin * const plugin) | |||
1149 | } | 1008 | } |
1150 | else | 1009 | else |
1151 | { | 1010 | { |
1152 | plugin->server_write_delay_task = GNUNET_SCHEDULER_add_delayed(next_send, | 1011 | if (plugin->server_write_delay_task == GNUNET_SCHEDULER_NO_TASK) |
1153 | &delay_fragment_task, plugin); | 1012 | { |
1013 | plugin->server_write_delay_task = GNUNET_SCHEDULER_add_delayed( | ||
1014 | next_send, &delay_fragment_task, plugin); | ||
1015 | } | ||
1154 | } | 1016 | } |
1155 | } | 1017 | } |
1156 | 1018 | ||
@@ -1190,8 +1052,10 @@ get_next_queue_session(struct Plugin * plugin) | |||
1190 | if (GNUNET_TIME_absolute_get_remaining(pm->timeout).rel_value > 0) | 1052 | if (GNUNET_TIME_absolute_get_remaining(pm->timeout).rel_value > 0) |
1191 | { | 1053 | { |
1192 | //check if session has no message in the fragment queue | 1054 | //check if session has no message in the fragment queue |
1193 | if (session->mac->fragment_messages_out_count | 1055 | if ((session->mac->fragment_messages_out_count |
1194 | < FRAGMENT_QUEUE_MESSAGES_OUT_PER_SESSION) | 1056 | < FRAGMENT_QUEUE_MESSAGES_OUT_PER_MACENDPOINT) |
1057 | && (session->fragment_messages_out_count | ||
1058 | < FRAGMENT_QUEUE_MESSAGES_OUT_PER_SESSION)) | ||
1195 | { | 1059 | { |
1196 | plugin->pendingsessions--; | 1060 | plugin->pendingsessions--; |
1197 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head, | 1061 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head, |
@@ -1241,174 +1105,40 @@ static void | |||
1241 | free_fragment_message(struct Plugin * plugin, struct FragmentMessage * fm) | 1105 | free_fragment_message(struct Plugin * plugin, struct FragmentMessage * fm) |
1242 | { | 1106 | { |
1243 | struct Session * session = fm->session; | 1107 | struct Session * session = fm->session; |
1108 | struct MacEndpoint * endpoint = session->mac; | ||
1109 | struct FragmentMessage_queue * fmq; | ||
1110 | struct FragmentMessage_queue * fmq_next; | ||
1244 | 1111 | ||
1245 | if (fm != NULL) | 1112 | if (fm != NULL) |
1246 | { | 1113 | { |
1247 | (session->mac->fragment_messages_out_count)--; | 1114 | fmq = plugin->sending_messages_head; |
1248 | GNUNET_free_non_null(fm->msg); | 1115 | while (fmq != NULL) |
1249 | GNUNET_CONTAINER_heap_remove_node(fm->node); | ||
1250 | GNUNET_free(fm); | ||
1251 | |||
1252 | queue_session(plugin, session); | ||
1253 | #if DEBUG_wlan | ||
1254 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1255 | "free pending fragment messages, pending messages remaining %u\n", | ||
1256 | GNUNET_CONTAINER_heap_get_size(plugin->pending_Fragment_Messages)); | ||
1257 | #endif | ||
1258 | } | ||
1259 | } | ||
1260 | |||
1261 | /** | ||
1262 | * Function to check if there is some space in the fragment queue | ||
1263 | * inserts a message if space is available | ||
1264 | * @param plugin the plugin struct | ||
1265 | */ | ||
1266 | |||
1267 | static void | ||
1268 | check_fragment_queue(struct Plugin * plugin) | ||
1269 | { | ||
1270 | struct Session * session; | ||
1271 | struct FragmentMessage * fm; | ||
1272 | struct GNUNET_PeerIdentity pid; | ||
1273 | |||
1274 | struct PendingMessage * pm; | ||
1275 | |||
1276 | if (GNUNET_CONTAINER_heap_get_size(plugin->pending_Fragment_Messages) | ||
1277 | < FRAGMENT_QUEUE_SIZE) | ||
1278 | { | ||
1279 | session = get_next_queue_session(plugin); | ||
1280 | if (session != NULL) | ||
1281 | { | 1116 | { |
1282 | pm = session->pending_message_head; | 1117 | fmq_next = fmq->next; |
1283 | GNUNET_CONTAINER_DLL_remove(session->pending_message_head, session->pending_message_tail, pm); | 1118 | if (fmq->content == fm) |
1284 | session->mac->fragment_messages_out_count++; | ||
1285 | GNUNET_assert(pm != NULL); | ||
1286 | |||
1287 | fm = GNUNET_malloc(sizeof(struct FragmentMessage)); | ||
1288 | fm->message_size = pm->message_size; | ||
1289 | fm->msg = pm->msg; | ||
1290 | fm->session = session; | ||
1291 | fm->timeout.abs_value = pm->timeout.abs_value; | ||
1292 | fm->message_pos = 0; | ||
1293 | fm->next_ack = GNUNET_TIME_absolute_get(); | ||
1294 | fm->message_id_out = get_next_message_id(); | ||
1295 | fm->ack_bitfield = 0; | ||
1296 | fm->node = GNUNET_CONTAINER_heap_insert( | ||
1297 | plugin->pending_Fragment_Messages, fm, | ||
1298 | GNUNET_TIME_absolute_get().abs_value); | ||
1299 | |||
1300 | GNUNET_assert(session !=NULL); | ||
1301 | |||
1302 | if (pm->transmit_cont != NULL) | ||
1303 | { | 1119 | { |
1304 | pid = session->target; | 1120 | GNUNET_CONTAINER_DLL_remove(plugin->sending_messages_head,plugin->sending_messages_tail, fmq); |
1305 | pm->transmit_cont(pm->transmit_cont_cls, &pid, GNUNET_OK); | 1121 | GNUNET_free(fmq); |
1306 | #if DEBUG_wlan | ||
1307 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1308 | "called pm->transmit_cont for %p\n", session); | ||
1309 | #endif | ||
1310 | } | 1122 | } |
1311 | else | 1123 | fmq = fmq_next; |
1312 | { | ||
1313 | #if DEBUG_wlan | ||
1314 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1315 | "no pm->transmit_cont for %p\n", session); | ||
1316 | #endif | ||
1317 | } | ||
1318 | GNUNET_free(pm); | ||
1319 | |||
1320 | if (session->pending_message_head != NULL) | ||
1321 | { | ||
1322 | //requeue session | ||
1323 | queue_session(plugin, session); | ||
1324 | } | ||
1325 | |||
1326 | } | 1124 | } |
1327 | } | ||
1328 | |||
1329 | //check if timeout changed | ||
1330 | set_next_send(plugin); | ||
1331 | } | ||
1332 | 1125 | ||
1333 | /** | 1126 | (session->mac->fragment_messages_out_count)--; |
1334 | * Funktion to check if all fragments where send and the acks received | 1127 | session->fragment_messages_out_count--; |
1335 | * frees the space if finished | 1128 | plugin->pending_Fragment_Messages--; |
1336 | * @param plugin the plugin struct | 1129 | GNUNET_CONTAINER_DLL_remove(endpoint->sending_messages_head,endpoint->sending_messages_tail, fm); |
1337 | * @param fm the message to check | 1130 | GNUNET_FRAGMENT_context_destroy(fm->fragcontext); |
1338 | */ | 1131 | GNUNET_free(fm); |
1339 | static void | ||
1340 | check_finished_fragment(struct Plugin * plugin, struct FragmentMessage * fm) | ||
1341 | { | ||
1342 | //maxack = size of message / max packet size, eg 12 / 5 = 2 start at 0 so ack numbers are 0,1,2 | ||
1343 | unsigned int maxack = 63 - ((fm->message_size - 1) / (WLAN_MTU | ||
1344 | - sizeof(struct FragmentationHeader))); | ||
1345 | uint64_t tmpfield = UINT64_MAX; | ||
1346 | tmpfield = tmpfield >> maxack; | ||
1347 | 1132 | ||
1133 | queue_session(plugin, session); | ||
1348 | #if DEBUG_wlan | 1134 | #if DEBUG_wlan |
1349 | if (maxack != 63) | ||
1350 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1351 | "Test bitfields %X and %X, maxack is %u, fm size %u\n", | ||
1352 | fm->ack_bitfield, tmpfield, maxack, fm->message_size); | ||
1353 | #endif | ||
1354 | |||
1355 | if (fm->ack_bitfield == tmpfield) | ||
1356 | { | ||
1357 | |||
1358 | #if DEBUG_wlan_retransmission | ||
1359 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 1135 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
1360 | "Finished sending and got all acks; message_id %u\n", | 1136 | "Free pending fragment messages %p, session %p\n", fm, session); |
1361 | fm->message_id_out); | ||
1362 | #endif | 1137 | #endif |
1363 | |||
1364 | free_fragment_message(plugin, fm); | ||
1365 | |||
1366 | check_fragment_queue(plugin); | ||
1367 | |||
1368 | } | 1138 | } |
1369 | } | 1139 | } |
1370 | 1140 | ||
1371 | /** | 1141 | /** |
1372 | * Function to set the next fragment number | ||
1373 | * @param fm use this FragmentMessage | ||
1374 | */ | ||
1375 | |||
1376 | static void | ||
1377 | set_next_message_fragment_pos(struct Plugin * plugin, | ||
1378 | struct FragmentMessage * fm) | ||
1379 | { | ||
1380 | |||
1381 | fm->message_pos++; | ||
1382 | |||
1383 | //check if retransmit is needed | ||
1384 | if (GNUNET_TIME_absolute_get_remaining(fm->next_ack).rel_value == 0) | ||
1385 | { | ||
1386 | |||
1387 | // be positive and try again later :-D | ||
1388 | fm->next_ack = GNUNET_TIME_relative_to_absolute(get_ack_timeout(fm)); | ||
1389 | // find first missing fragment | ||
1390 | |||
1391 | fm->message_pos = 0; | ||
1392 | |||
1393 | GNUNET_CONTAINER_heap_update_cost(plugin->pending_Fragment_Messages, | ||
1394 | fm->node, 0); | ||
1395 | |||
1396 | #if DEBUG_wlan_retransmission | ||
1397 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1398 | "Retransmit; message_id %u; fragment number %i, size: %u\n", | ||
1399 | fm->message_id_out, fm->message_pos, fm->message_size); | ||
1400 | #endif | ||
1401 | } | ||
1402 | |||
1403 | //test if ack 0 (or X) was already received | ||
1404 | while (testBit((char*) &fm->ack_bitfield, fm->message_pos) == GNUNET_YES) | ||
1405 | { | ||
1406 | fm->message_pos++; | ||
1407 | } | ||
1408 | |||
1409 | } | ||
1410 | |||
1411 | /** | ||
1412 | * function to fill the radiotap header | 1142 | * function to fill the radiotap header |
1413 | * @param plugin pointer to the plugin struct | 1143 | * @param plugin pointer to the plugin struct |
1414 | * @param endpoint pointer to the endpoint | 1144 | * @param endpoint pointer to the endpoint |
@@ -1526,7 +1256,59 @@ getcrc16(const char *msgbuf, size_t msgbuf_size) | |||
1526 | return 0; | 1256 | return 0; |
1527 | } | 1257 | } |
1528 | 1258 | ||
1529 | //TODO DOXIGEN | 1259 | /** |
1260 | * function to add a fragment of a message to send | ||
1261 | * @param cls FragmentMessage this message belongs to | ||
1262 | * @param hdr pointer to the start of the message | ||
1263 | */ | ||
1264 | |||
1265 | void | ||
1266 | add_message_for_send(void *cls, const struct GNUNET_MessageHeader *hdr) | ||
1267 | { | ||
1268 | |||
1269 | struct FragmentMessage * fm = cls; | ||
1270 | struct FragmentMessage_queue * fmqueue; | ||
1271 | |||
1272 | GNUNET_assert(cls != NULL); | ||
1273 | GNUNET_assert(fm->frag == NULL); | ||
1274 | struct MacEndpoint * endpoint = fm->session->mac; | ||
1275 | struct Plugin * plugin = endpoint->plugin; | ||
1276 | struct GNUNET_MessageHeader * msgheader; | ||
1277 | struct GNUNET_MessageHeader * msgheader2; | ||
1278 | uint16_t size; | ||
1279 | |||
1280 | #if DEBUG_wlan_retransmission | ||
1281 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1282 | "Adding fragment of message %p to send, session %p, endpoint %p\n", fm, | ||
1283 | fm->session, endpoint); | ||
1284 | #endif | ||
1285 | |||
1286 | size = sizeof(struct GNUNET_MessageHeader) + sizeof(struct Radiotap_Send) | ||
1287 | + sizeof(struct ieee80211_frame) + ntohs(hdr->size); | ||
1288 | fm->frag = GNUNET_malloc(size); | ||
1289 | fm->size = size; | ||
1290 | |||
1291 | msgheader = (struct GNUNET_MessageHeader *) fm->frag; | ||
1292 | msgheader->size = htons(size); | ||
1293 | msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); | ||
1294 | |||
1295 | fm->radioHeader = (struct Radiotap_Send*) &msgheader[1]; | ||
1296 | fm->ieeewlanheader = (struct ieee80211_frame*) &fm->radioHeader[1]; | ||
1297 | msgheader2 = (struct GNUNET_MessageHeader*) &fm->ieeewlanheader[1]; | ||
1298 | memcpy(msgheader2, hdr, ntohs(hdr->size)); | ||
1299 | |||
1300 | fmqueue = GNUNET_malloc(sizeof(struct FragmentMessage_queue)); | ||
1301 | fmqueue->content = fm; | ||
1302 | |||
1303 | GNUNET_CONTAINER_DLL_insert_tail(plugin->sending_messages_head, | ||
1304 | plugin->sending_messages_tail, fmqueue); | ||
1305 | set_next_send(plugin); | ||
1306 | } | ||
1307 | |||
1308 | /** | ||
1309 | * function to send a hallo beacon | ||
1310 | * @param plugin pointer to the plugin struct | ||
1311 | */ | ||
1530 | static void | 1312 | static void |
1531 | send_hello_beacon(struct Plugin * plugin) | 1313 | send_hello_beacon(struct Plugin * plugin) |
1532 | { | 1314 | { |
@@ -1583,46 +1365,153 @@ send_hello_beacon(struct Plugin * plugin) | |||
1583 | set_next_send(plugin); | 1365 | set_next_send(plugin); |
1584 | } | 1366 | } |
1585 | 1367 | ||
1586 | //TODO DOXIGEN | 1368 | /** |
1369 | * function to add an ack to send it for a received fragment | ||
1370 | * @param cls MacEndpoint this ack belongs to | ||
1371 | * @param msg_id id of the message | ||
1372 | * @param hdr pointer to the hdr where the ack is stored | ||
1373 | * | ||
1374 | */ | ||
1375 | |||
1587 | static void | 1376 | static void |
1588 | send_ack(struct Plugin * plugin, struct AckSendQueue * ack) | 1377 | add_ack_for_send(void *cls, uint32_t msg_id, |
1378 | const struct GNUNET_MessageHeader *hdr) | ||
1589 | { | 1379 | { |
1590 | 1380 | ||
1591 | uint16_t size; | 1381 | struct AckSendQueue * ack; |
1592 | ssize_t bytes; | 1382 | |
1383 | GNUNET_assert(cls != NULL); | ||
1384 | struct MacEndpoint * endpoint = cls; | ||
1385 | struct Plugin * plugin = endpoint->plugin; | ||
1593 | struct GNUNET_MessageHeader * msgheader; | 1386 | struct GNUNET_MessageHeader * msgheader; |
1594 | struct ieee80211_frame * ieeewlanheader; | 1387 | struct GNUNET_MessageHeader * msgheader2; |
1595 | struct Radiotap_Send * radioHeader; | 1388 | uint16_t size; |
1596 | struct FragmentationAckHeader * msgheader2; | 1389 | |
1390 | size = sizeof(struct GNUNET_MessageHeader) + sizeof(struct Radiotap_Send) | ||
1391 | + sizeof(struct ieee80211_frame) + ntohs(hdr->size) | ||
1392 | + sizeof(struct AckSendQueue); | ||
1597 | 1393 | ||
1598 | GNUNET_assert(sizeof(struct FragmentationAckHeader) <= WLAN_MTU); | 1394 | ack = GNUNET_malloc(size); |
1395 | ack->message_id = msg_id; | ||
1396 | ack->endpoint = endpoint; | ||
1599 | 1397 | ||
1600 | size = sizeof(struct GNUNET_MessageHeader) + sizeof(struct Radiotap_Send) | 1398 | size = sizeof(struct GNUNET_MessageHeader) + sizeof(struct Radiotap_Send) |
1601 | + sizeof(struct ieee80211_frame) + sizeof(struct FragmentationAckHeader); | 1399 | + sizeof(struct ieee80211_frame) + ntohs(hdr->size); |
1602 | 1400 | ||
1603 | #if DEBUG_wlan | 1401 | msgheader = (struct GNUNET_MessageHeader *) &ack[1]; |
1402 | ack->hdr = (struct GNUNET_MessageHeader *) &ack[1]; | ||
1403 | msgheader->size = htons(size); | ||
1404 | msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); | ||
1405 | |||
1406 | ack->radioHeader = (struct Radiotap_Send*) &msgheader[1]; | ||
1407 | ack->ieeewlanheader = (struct ieee80211_frame*) &(ack->radioHeader)[1]; | ||
1408 | msgheader2 = (struct GNUNET_MessageHeader*) &(ack->ieeewlanheader)[1]; | ||
1409 | memcpy(msgheader2, hdr, ntohs(hdr->size)); | ||
1410 | |||
1411 | GNUNET_CONTAINER_DLL_insert_tail(plugin->ack_send_queue_head, | ||
1412 | plugin->ack_send_queue_tail, ack); | ||
1413 | |||
1414 | #if DEBUG_wlan_retransmission | ||
1604 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 1415 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
1605 | "Sending ack for message_id %u with fragment field %u, size %u\n", | 1416 | "Adding ack with message id %u to send, AckSendQueue %p, endpoint %p\n", |
1606 | ack->message_id, ack->fragments_field, | 1417 | msg_id, ack, endpoint); |
1607 | size - sizeof(struct Radiotap_Send)); | ||
1608 | #endif | 1418 | #endif |
1609 | 1419 | ||
1610 | msgheader = GNUNET_malloc(size); | 1420 | set_next_send(plugin); |
1611 | msgheader->size = htons(size); | 1421 | } |
1612 | msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); | ||
1613 | 1422 | ||
1614 | radioHeader = (struct Radiotap_Send*) &msgheader[1]; | 1423 | /** |
1615 | getRadiotapHeader(plugin, ack->endpoint, radioHeader); | 1424 | * Function to check if there is some space in the fragment queue |
1616 | ieeewlanheader = (struct ieee80211_frame*) &radioHeader[1]; | 1425 | * inserts a message if space is available |
1617 | getWlanHeader(ieeewlanheader, &ack->endpoint->addr, plugin, size); | 1426 | * @param plugin the plugin struct |
1427 | */ | ||
1618 | 1428 | ||
1619 | msgheader2 = (struct FragmentationAckHeader*) &ieeewlanheader[1]; | 1429 | static void |
1620 | msgheader2->header.size = htons(sizeof(struct FragmentationAckHeader)); | 1430 | check_fragment_queue(struct Plugin * plugin) |
1621 | msgheader2->header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT_ACK); | 1431 | { |
1622 | msgheader2->message_id = htonl(ack->message_id); | 1432 | struct Session * session; |
1623 | msgheader2->fragment_field = GNUNET_htonll(ack->fragments_field); | 1433 | struct FragmentMessage * fm; |
1434 | struct GNUNET_PeerIdentity pid; | ||
1624 | 1435 | ||
1625 | bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader, size); | 1436 | struct PendingMessage * pm; |
1437 | |||
1438 | if (plugin->pending_Fragment_Messages < FRAGMENT_QUEUE_SIZE) | ||
1439 | { | ||
1440 | session = get_next_queue_session(plugin); | ||
1441 | if (session != NULL) | ||
1442 | { | ||
1443 | pm = session->pending_message_head; | ||
1444 | GNUNET_CONTAINER_DLL_remove(session->pending_message_head, session->pending_message_tail, pm); | ||
1445 | session->mac->fragment_messages_out_count++; | ||
1446 | session->fragment_messages_out_count++; | ||
1447 | plugin->pending_Fragment_Messages++; | ||
1448 | GNUNET_assert(pm != NULL); | ||
1449 | |||
1450 | fm = GNUNET_malloc(sizeof(struct FragmentMessage)); | ||
1451 | fm->session = session; | ||
1452 | fm->timeout.abs_value = pm->timeout.abs_value; | ||
1453 | fm->frag = NULL; | ||
1454 | fm->fragcontext = GNUNET_FRAGMENT_context_create(plugin->env->stats, | ||
1455 | WLAN_MTU, &plugin->tracker, GNUNET_TIME_UNIT_SECONDS, | ||
1456 | &(pm->msg->header), &add_message_for_send, | ||
1457 | fm); | ||
1458 | GNUNET_CONTAINER_DLL_insert_tail(session->mac->sending_messages_head,session->mac->sending_messages_tail,fm); | ||
1459 | |||
1460 | if (pm->transmit_cont != NULL) | ||
1461 | { | ||
1462 | pid = session->target; | ||
1463 | pm->transmit_cont(pm->transmit_cont_cls, &pid, GNUNET_OK); | ||
1464 | #if DEBUG_wlan | ||
1465 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1466 | "called pm->transmit_cont for %p\n", session); | ||
1467 | #endif | ||
1468 | } | ||
1469 | else | ||
1470 | { | ||
1471 | #if DEBUG_wlan | ||
1472 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1473 | "no pm->transmit_cont for %p\n", session); | ||
1474 | #endif | ||
1475 | } | ||
1476 | GNUNET_free(pm); | ||
1477 | |||
1478 | if (session->pending_message_head != NULL) | ||
1479 | { | ||
1480 | //requeue session | ||
1481 | queue_session(plugin, session); | ||
1482 | } | ||
1483 | |||
1484 | } | ||
1485 | } | ||
1486 | |||
1487 | //check if timeout changed | ||
1488 | set_next_send(plugin); | ||
1489 | } | ||
1490 | |||
1491 | /** | ||
1492 | * Function to send an ack, does not free the ack | ||
1493 | * @param plugin pointer to the plugin | ||
1494 | * @param ack pointer to the ack to send | ||
1495 | */ | ||
1496 | static void | ||
1497 | send_ack(struct Plugin * plugin, struct AckSendQueue * ack) | ||
1498 | { | ||
1499 | |||
1500 | ssize_t bytes; | ||
1501 | |||
1502 | #if DEBUG_wlan | ||
1503 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1504 | "Sending ack for message_id %u for mac endpoint %p, size %u\n", | ||
1505 | ack->message_id, ack->endpoint, | ||
1506 | ntohs(ack->hdr->size) - sizeof(struct Radiotap_Send)); | ||
1507 | #endif | ||
1508 | |||
1509 | getRadiotapHeader(plugin, ack->endpoint, ack->radioHeader); | ||
1510 | getWlanHeader(ack->ieeewlanheader, &ack->endpoint->addr, plugin, | ||
1511 | ntohs(ack->hdr->size)); | ||
1512 | |||
1513 | bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, ack->hdr, | ||
1514 | ntohs(ack->hdr->size)); | ||
1626 | if (bytes == GNUNET_SYSERR) | 1515 | if (bytes == GNUNET_SYSERR) |
1627 | { | 1516 | { |
1628 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | 1517 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, |
@@ -1631,12 +1520,15 @@ send_ack(struct Plugin * plugin, struct AckSendQueue * ack) | |||
1631 | 1520 | ||
1632 | } | 1521 | } |
1633 | GNUNET_assert(bytes != GNUNET_SYSERR); | 1522 | GNUNET_assert(bytes != GNUNET_SYSERR); |
1634 | GNUNET_assert(bytes == size); | 1523 | GNUNET_assert(bytes == ntohs(ack->hdr->size)); |
1635 | GNUNET_free(msgheader); | ||
1636 | set_next_send(plugin); | 1524 | set_next_send(plugin); |
1637 | } | 1525 | } |
1638 | 1526 | ||
1639 | //TODO DOXIGEN | 1527 | /** |
1528 | * function to finish a sending if not all could have been writen befor | ||
1529 | * @param cls pointer to the Finish_send struct | ||
1530 | * @param tc TaskContext | ||
1531 | */ | ||
1640 | static void | 1532 | static void |
1641 | finish_sending(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 1533 | finish_sending(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
1642 | { | 1534 | { |
@@ -1690,18 +1582,10 @@ do_transmit(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1690 | 1582 | ||
1691 | struct Session * session; | 1583 | struct Session * session; |
1692 | struct FragmentMessage * fm; | 1584 | struct FragmentMessage * fm; |
1693 | struct ieee80211_frame * ieeewlanheader; | ||
1694 | struct Radiotap_Send * radioHeader; | ||
1695 | struct GNUNET_MessageHeader * msgheader; | ||
1696 | struct FragmentationHeader fragheader; | ||
1697 | struct FragmentationHeader * fragheaderptr; | ||
1698 | struct Finish_send * finish; | 1585 | struct Finish_send * finish; |
1586 | struct FragmentMessage_queue * fmq; | ||
1699 | struct AckSendQueue * ack; | 1587 | struct AckSendQueue * ack; |
1700 | uint16_t size; | ||
1701 | ssize_t bytes; | 1588 | ssize_t bytes; |
1702 | const char * copystart; | ||
1703 | uint16_t copysize; | ||
1704 | uint copyoffset; | ||
1705 | 1589 | ||
1706 | if (plugin->ack_send_queue_head != NULL) | 1590 | if (plugin->ack_send_queue_head != NULL) |
1707 | { | 1591 | { |
@@ -1720,149 +1604,60 @@ do_transmit(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1720 | return; | 1604 | return; |
1721 | } | 1605 | } |
1722 | 1606 | ||
1723 | fm = GNUNET_CONTAINER_heap_peek(plugin->pending_Fragment_Messages); | 1607 | if (plugin->sending_messages_head != NULL) |
1724 | |||
1725 | if (fm != NULL) | ||
1726 | { | 1608 | { |
1609 | fmq = plugin->sending_messages_head; | ||
1610 | fm = fmq->content; | ||
1611 | GNUNET_CONTAINER_DLL_remove(plugin->sending_messages_head,plugin->sending_messages_tail,fmq); | ||
1612 | GNUNET_free(fmq); | ||
1613 | |||
1727 | session = fm->session; | 1614 | session = fm->session; |
1728 | GNUNET_assert(session != NULL); | 1615 | GNUNET_assert(session != NULL); |
1729 | 1616 | ||
1730 | // test if message timed out | ||
1731 | if (GNUNET_TIME_absolute_get_remaining(fm->timeout).rel_value == 0) | ||
1732 | { | ||
1733 | #if DEBUG_wlan | 1617 | #if DEBUG_wlan |
1734 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "message timeout\n"); | 1618 | GNUNET_log( |
1619 | GNUNET_ERROR_TYPE_DEBUG, | ||
1620 | "Sending GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT for fragment message %p, size: %u\n", | ||
1621 | fm, fm->size); | ||
1735 | #endif | 1622 | #endif |
1736 | 1623 | ||
1737 | free_fragment_message(plugin, fm); | 1624 | getRadiotapHeader(plugin, session->mac, fm->radioHeader); |
1738 | check_fragment_queue(plugin); | 1625 | getWlanHeader(fm->ieeewlanheader, &(fm->session->mac->addr), plugin, |
1626 | fm->size); | ||
1739 | 1627 | ||
1740 | } | 1628 | bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, fm->frag, |
1741 | else | 1629 | fm->size); |
1630 | if (bytes == GNUNET_SYSERR) | ||
1742 | { | 1631 | { |
1632 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1633 | _("Error writing to wlan healper. errno == %d, ERROR: %s\n"), | ||
1634 | errno, strerror(errno)); | ||
1743 | 1635 | ||
1744 | //if (fm->message_size > WLAN_MTU) | 1636 | } |
1745 | // { | 1637 | GNUNET_assert(bytes != GNUNET_SYSERR); |
1746 | size = sizeof(struct FragmentationHeader); | ||
1747 | |||
1748 | set_next_message_fragment_pos(plugin, fm); | ||
1749 | |||
1750 | copyoffset = (WLAN_MTU - sizeof(struct FragmentationHeader)) | ||
1751 | * fm->message_pos; | ||
1752 | |||
1753 | fragheader.fragment_off_or_num = htons(fm->message_pos); | ||
1754 | fragheader.message_id = htonl(fm->message_id_out); | ||
1755 | copystart = fm->msg + copyoffset; | ||
1756 | copysize = GNUNET_MIN(fm->message_size - copyoffset, | ||
1757 | WLAN_MTU - sizeof(struct FragmentationHeader)); | ||
1758 | |||
1759 | #if DEBUG_wlan | ||
1760 | GNUNET_log( | ||
1761 | GNUNET_ERROR_TYPE_DEBUG, | ||
1762 | "Sending GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT with message_id %u with fragment number %i, size: %u, offset %u, time until timeout %u\n", | ||
1763 | fm->message_id_out, fm->message_pos, | ||
1764 | copysize + sizeof(struct FragmentationHeader), copyoffset, | ||
1765 | GNUNET_TIME_absolute_get_remaining(fm->timeout)); | ||
1766 | #endif | ||
1767 | |||
1768 | if (copyoffset >= fm->message_size) | ||
1769 | { | ||
1770 | GNUNET_log( | ||
1771 | GNUNET_ERROR_TYPE_ERROR, | ||
1772 | "offset in message for fragment too large, offset %u, size %u, max size %u, copysize %u, message_pos %u,\n", | ||
1773 | copyoffset, fm->message_size, | ||
1774 | WLAN_MTU - sizeof(struct FragmentationHeader), copysize, | ||
1775 | fm->message_pos); | ||
1776 | } | ||
1777 | GNUNET_assert(copyoffset < fm->message_size); | ||
1778 | |||
1779 | fragheader.header.size = htons( | ||
1780 | copysize + sizeof(struct FragmentationHeader)); | ||
1781 | fragheader.header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT); | ||
1782 | |||
1783 | size += copysize; | ||
1784 | size += sizeof(struct Radiotap_Send) + sizeof(struct ieee80211_frame) | ||
1785 | + sizeof(struct GNUNET_MessageHeader); | ||
1786 | msgheader = GNUNET_malloc(size); | ||
1787 | msgheader->size = htons(size); | ||
1788 | msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); | ||
1789 | |||
1790 | radioHeader = (struct Radiotap_Send*) &msgheader[1]; | ||
1791 | getRadiotapHeader(plugin, session->mac, radioHeader); | ||
1792 | |||
1793 | ieeewlanheader = (struct ieee80211_frame *) &radioHeader[1]; | ||
1794 | getWlanHeader(ieeewlanheader, &(fm->session->mac->addr), plugin, size); | ||
1795 | |||
1796 | //could be faster if content is just send and not copyed before | ||
1797 | //fragmentheader is needed | ||
1798 | fragheader.message_crc = htons(getcrc16(copystart, copysize)); | ||
1799 | memcpy(&ieeewlanheader[1], &fragheader, | ||
1800 | sizeof(struct FragmentationHeader)); | ||
1801 | fragheaderptr = (struct FragmentationHeader *) &ieeewlanheader[1]; | ||
1802 | memcpy(&fragheaderptr[1], copystart, copysize); | ||
1803 | |||
1804 | bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, | ||
1805 | msgheader, size); | ||
1806 | if (bytes == GNUNET_SYSERR) | ||
1807 | { | ||
1808 | GNUNET_log( | ||
1809 | GNUNET_ERROR_TYPE_ERROR, | ||
1810 | _("Error writing to wlan healper. errno == %d, ERROR: %s\n"), | ||
1811 | errno, strerror(errno)); | ||
1812 | |||
1813 | } | ||
1814 | GNUNET_assert(bytes != GNUNET_SYSERR); | ||
1815 | |||
1816 | //check if this was the last fragment of this message, if true then queue at the end of the list | ||
1817 | if (copysize + copyoffset >= fm->message_size) | ||
1818 | { | ||
1819 | GNUNET_assert(copysize + copyoffset == fm->message_size); | ||
1820 | |||
1821 | GNUNET_CONTAINER_heap_update_cost( | ||
1822 | plugin->pending_Fragment_Messages, fm->node, | ||
1823 | MIN(fm->timeout.abs_value, fm->next_ack.abs_value)); | ||
1824 | // if fragments have opimized timeouts | ||
1825 | //sort_fragment_into_queue(plugin,fm); | ||
1826 | |||
1827 | |||
1828 | #if DEBUG_wlan_retransmission | ||
1829 | GNUNET_log( | ||
1830 | GNUNET_ERROR_TYPE_DEBUG, | ||
1831 | "Finished sending all fragments waiting for acks; message_id %u; message_id %u; fragment number %i, size: %u, time until timeout %u\n", | ||
1832 | fm->message_id_out, fm->message_id_out, fm->message_pos, | ||
1833 | fm->message_size, | ||
1834 | GNUNET_TIME_absolute_get_remaining(fm->timeout)); | ||
1835 | #endif | ||
1836 | } | ||
1837 | else | ||
1838 | { | ||
1839 | GNUNET_CONTAINER_heap_update_cost( | ||
1840 | plugin->pending_Fragment_Messages, fm->node, | ||
1841 | GNUNET_TIME_absolute_get().abs_value); | ||
1842 | } | ||
1843 | |||
1844 | if (bytes != size) | ||
1845 | { | ||
1846 | finish = GNUNET_malloc(sizeof( struct Finish_send)); | ||
1847 | finish->plugin = plugin; | ||
1848 | finish->msgheader = (char *) msgheader + bytes; | ||
1849 | finish->size = size - bytes; | ||
1850 | finish->msgstart = msgheader; | ||
1851 | |||
1852 | GNUNET_assert(plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK); | ||
1853 | 1638 | ||
1854 | plugin->server_write_task = GNUNET_SCHEDULER_add_write_file( | 1639 | if (bytes != fm->size) |
1855 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdin_handle, | 1640 | { |
1856 | &finish_sending, finish); | 1641 | finish = GNUNET_malloc(sizeof( struct Finish_send)); |
1642 | finish->plugin = plugin; | ||
1643 | finish->msgheader = fm->frag + bytes; | ||
1644 | finish->size = fm->size - bytes; | ||
1645 | finish->msgstart = (struct GNUNET_MessageHeader *) fm->frag; | ||
1857 | 1646 | ||
1858 | } | 1647 | GNUNET_assert(plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK); |
1859 | else | ||
1860 | { | ||
1861 | GNUNET_free(msgheader); | ||
1862 | set_next_send(plugin); | ||
1863 | } | ||
1864 | 1648 | ||
1649 | plugin->server_write_task = GNUNET_SCHEDULER_add_write_file( | ||
1650 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdin_handle, | ||
1651 | &finish_sending, finish); | ||
1652 | fm->frag = NULL; | ||
1653 | } | ||
1654 | else | ||
1655 | { | ||
1656 | GNUNET_free(fm->frag); | ||
1657 | fm->frag = NULL; | ||
1658 | set_next_send(plugin); | ||
1865 | } | 1659 | } |
1660 | GNUNET_FRAGMENT_context_transmission_done (fm->fragcontext); | ||
1866 | return; | 1661 | return; |
1867 | } | 1662 | } |
1868 | 1663 | ||
@@ -1973,13 +1768,14 @@ wlan_plugin_send(void *cls, const struct GNUNET_PeerIdentity * target, | |||
1973 | } | 1768 | } |
1974 | 1769 | ||
1975 | newmsg = GNUNET_malloc(sizeof(struct PendingMessage)); | 1770 | newmsg = GNUNET_malloc(sizeof(struct PendingMessage)); |
1976 | (newmsg->msg) = GNUNET_malloc(msgbuf_size + sizeof(struct WlanHeader)); | 1771 | newmsg->msg = GNUNET_malloc(msgbuf_size + sizeof(struct WlanHeader)); |
1977 | wlanheader = (struct WlanHeader *) newmsg->msg; | 1772 | wlanheader = newmsg->msg; |
1978 | //copy msg to buffer, not fragmented / segmented yet, but with message header | 1773 | //copy msg to buffer, not fragmented / segmented yet, but with message header |
1979 | wlanheader->header.size = htons(msgbuf_size + sizeof(struct WlanHeader)); | 1774 | wlanheader->header.size = htons(msgbuf_size + sizeof(struct WlanHeader)); |
1980 | wlanheader->header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_DATA); | 1775 | wlanheader->header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_DATA); |
1981 | memcpy(&(wlanheader->target), target, sizeof(struct GNUNET_PeerIdentity)); | 1776 | memcpy(&(wlanheader->target), target, sizeof(struct GNUNET_PeerIdentity)); |
1982 | memcpy(&(wlanheader->source), plugin->env->my_identity , sizeof(struct GNUNET_PeerIdentity)); | 1777 | memcpy(&(wlanheader->source), plugin->env->my_identity, |
1778 | sizeof(struct GNUNET_PeerIdentity)); | ||
1983 | wlanheader->crc = 0; | 1779 | wlanheader->crc = 0; |
1984 | memcpy(&wlanheader[1], msgbuf, msgbuf_size); | 1780 | memcpy(&wlanheader[1], msgbuf, msgbuf_size); |
1985 | wlanheader->crc = htonl( | 1781 | wlanheader->crc = htonl( |
@@ -2013,156 +1809,6 @@ wlan_plugin_send(void *cls, const struct GNUNET_PeerIdentity * target, | |||
2013 | } | 1809 | } |
2014 | 1810 | ||
2015 | /** | 1811 | /** |
2016 | * Iterate over the fragment messages of the given session. | ||
2017 | * | ||
2018 | * @param cls argument to give to iterator | ||
2019 | * @param node node to iterate over | ||
2020 | * @param element value stored at the node | ||
2021 | * @param cost cost associated with the node | ||
2022 | * @return GNUNET_YES if we should continue to iterate, | ||
2023 | * GNUNET_NO if not. | ||
2024 | */ | ||
2025 | static int | ||
2026 | free_fragment_message_from_session(void *cls, | ||
2027 | struct GNUNET_CONTAINER_HeapNode *node, void *element, | ||
2028 | GNUNET_CONTAINER_HeapCostType cost) | ||
2029 | { | ||
2030 | struct Plugin_Session_pair * pair = (struct Plugin_Session_pair *) cls; | ||
2031 | struct FragmentMessage * fm = (struct FragmentMessage*) element; | ||
2032 | |||
2033 | if (fm->session == pair->session) | ||
2034 | { | ||
2035 | |||
2036 | free_fragment_message(pair->plugin, fm); | ||
2037 | } | ||
2038 | return GNUNET_YES; | ||
2039 | |||
2040 | } | ||
2041 | |||
2042 | /** | ||
2043 | * Search for fragment message with given id and session | ||
2044 | * | ||
2045 | * @param cls argument to give to iterator | ||
2046 | * @param node node to iterate over | ||
2047 | * @param element value stored at the node | ||
2048 | * @param cost cost associated with the node | ||
2049 | * @return GNUNET_YES if we should continue to iterate, | ||
2050 | * GNUNET_NO if not. | ||
2051 | */ | ||
2052 | static int | ||
2053 | search_fragment_message_from_endpoint_and_id(void *cls, | ||
2054 | struct GNUNET_CONTAINER_HeapNode *node, void *element, | ||
2055 | GNUNET_CONTAINER_HeapCostType cost) | ||
2056 | { | ||
2057 | struct MacEndpoint_id_fragment_triple * triple = | ||
2058 | (struct MacEndpoint_id_fragment_triple *) cls; | ||
2059 | struct FragmentMessage * fm = (struct FragmentMessage*) element; | ||
2060 | |||
2061 | if ((fm->session->mac == triple->endpoint) && (fm->message_id_out | ||
2062 | == triple->message_id)) | ||
2063 | { | ||
2064 | triple->fm = fm; | ||
2065 | return GNUNET_NO; | ||
2066 | } | ||
2067 | return GNUNET_YES; | ||
2068 | |||
2069 | } | ||
2070 | |||
2071 | /** | ||
2072 | * function to get the message in the fragement queue (out) of a session with a specific id | ||
2073 | * @param session pointer to the session | ||
2074 | * @param message_id id of the message | ||
2075 | * @return pointer to the struct FragmentMessage | ||
2076 | */ | ||
2077 | static struct FragmentMessage * | ||
2078 | get_fragment_message_from_endpoint_and_id(struct Plugin * plugin, | ||
2079 | struct MacEndpoint * endpoint, uint32_t message_id) | ||
2080 | { | ||
2081 | struct MacEndpoint_id_fragment_triple triple; | ||
2082 | triple.endpoint = endpoint; | ||
2083 | triple.message_id = message_id; | ||
2084 | triple.fm = NULL; | ||
2085 | GNUNET_CONTAINER_heap_iterate(plugin->pending_Fragment_Messages, | ||
2086 | &search_fragment_message_from_endpoint_and_id, &triple); | ||
2087 | return triple.fm; | ||
2088 | } | ||
2089 | |||
2090 | /** | ||
2091 | * function to get the receive message of a session | ||
2092 | * @param plugin pointer to the plugin struct | ||
2093 | * @param endpoint MacEndpoint this fragment belongs to | ||
2094 | * @param message_id id of the message | ||
2095 | */ | ||
2096 | static struct Receive_Message_Queue * | ||
2097 | get_receive_message(struct Plugin * plugin, struct MacEndpoint * endpoint, | ||
2098 | uint32_t message_id) | ||
2099 | { | ||
2100 | struct Receive_Message_Queue * rec_message = plugin->receive_messages_head; | ||
2101 | while (rec_message != NULL) | ||
2102 | { | ||
2103 | if (rec_message->endpoint == endpoint && message_id | ||
2104 | == rec_message->message_id_in) | ||
2105 | { | ||
2106 | return rec_message; | ||
2107 | } | ||
2108 | rec_message = rec_message->next; | ||
2109 | } | ||
2110 | return NULL; | ||
2111 | } | ||
2112 | |||
2113 | /** | ||
2114 | * Function to dispose the fragments received for a message and the message | ||
2115 | * @param plugin pointer to the plugin struct | ||
2116 | * @param rec_message pointer to the struct holding the message which should be freed | ||
2117 | */ | ||
2118 | static void | ||
2119 | free_receive_message(struct Plugin* plugin, | ||
2120 | struct Receive_Message_Queue * rx_message) | ||
2121 | { | ||
2122 | GNUNET_assert(rx_message !=NULL); | ||
2123 | struct Receive_Fragment_Queue * rec_queue = rx_message->frag_head; | ||
2124 | struct Receive_Fragment_Queue * rec_queue2; | ||
2125 | |||
2126 | while (rec_queue != NULL) | ||
2127 | { | ||
2128 | rec_queue2 = rec_queue; | ||
2129 | rec_queue = rec_queue->next; | ||
2130 | GNUNET_free(rec_queue2); | ||
2131 | } | ||
2132 | |||
2133 | GNUNET_CONTAINER_DLL_remove(plugin->receive_messages_head,plugin->receive_messages_teil, rx_message); | ||
2134 | |||
2135 | GNUNET_assert(plugin->pending_receive_messages > 0); | ||
2136 | GNUNET_assert(rx_message->endpoint != NULL); | ||
2137 | GNUNET_assert(rx_message->endpoint !=NULL); | ||
2138 | GNUNET_assert(rx_message->endpoint->fragment_messages_in_count > 0); | ||
2139 | |||
2140 | plugin->pending_receive_messages--; | ||
2141 | rx_message->endpoint->fragment_messages_in_count--; | ||
2142 | GNUNET_free(rx_message); | ||
2143 | } | ||
2144 | |||
2145 | /** | ||
2146 | * function to check for timeouts | ||
2147 | * @param plugin pointer to the plugin struct | ||
2148 | */ | ||
2149 | static void | ||
2150 | check_receive_message_timeouts(struct Plugin * plugin) | ||
2151 | { | ||
2152 | struct Receive_Message_Queue * rec_message = plugin->receive_messages_head; | ||
2153 | while (rec_message != NULL) | ||
2154 | { | ||
2155 | if (GNUNET_TIME_absolute_get_remaining(rec_message->timeout).rel_value | ||
2156 | == 0) | ||
2157 | { | ||
2158 | free_receive_message(plugin, rec_message); | ||
2159 | } | ||
2160 | rec_message = rec_message->next; | ||
2161 | } | ||
2162 | |||
2163 | } | ||
2164 | |||
2165 | /** | ||
2166 | * function to free a mac endpoint | 1812 | * function to free a mac endpoint |
2167 | * @param plugin pointer to the plugin struct | 1813 | * @param plugin pointer to the plugin struct |
2168 | * @param endpoin pointer to the MacEndpoint to free | 1814 | * @param endpoin pointer to the MacEndpoint to free |
@@ -2173,6 +1819,7 @@ free_macendpoint(struct Plugin * plugin, struct MacEndpoint * endpoin) | |||
2173 | struct Sessionqueue * sessions; | 1819 | struct Sessionqueue * sessions; |
2174 | struct Sessionqueue * sessions_next; | 1820 | struct Sessionqueue * sessions_next; |
2175 | GNUNET_assert(endpoin != NULL); | 1821 | GNUNET_assert(endpoin != NULL); |
1822 | |||
2176 | sessions = endpoin->sessions_head; | 1823 | sessions = endpoin->sessions_head; |
2177 | while (sessions != NULL) | 1824 | while (sessions != NULL) |
2178 | { | 1825 | { |
@@ -2199,9 +1846,9 @@ free_session(struct Plugin * plugin, struct Sessionqueue * queue, | |||
2199 | struct Sessionqueue * pendingsession; | 1846 | struct Sessionqueue * pendingsession; |
2200 | struct Sessionqueue * pendingsession_tmp; | 1847 | struct Sessionqueue * pendingsession_tmp; |
2201 | struct PendingMessage * pm; | 1848 | struct PendingMessage * pm; |
2202 | //struct Receive_Message_Queue * receive_queue; | ||
2203 | struct Plugin_Session_pair pair; | ||
2204 | struct MacEndpoint * endpoint; | 1849 | struct MacEndpoint * endpoint; |
1850 | struct FragmentMessage * fm; | ||
1851 | struct FragmentMessage * fmnext; | ||
2205 | int check = 0; | 1852 | int check = 0; |
2206 | 1853 | ||
2207 | GNUNET_assert(queue != NULL); | 1854 | GNUNET_assert(queue != NULL); |
@@ -2227,31 +1874,28 @@ free_session(struct Plugin * plugin, struct Sessionqueue * queue, | |||
2227 | pendingsession = pendingsession_tmp; | 1874 | pendingsession = pendingsession_tmp; |
2228 | } | 1875 | } |
2229 | 1876 | ||
2230 | //is something of this session in the fragment queue? | 1877 | endpoint = queue->content->mac; |
2231 | pair.plugin = plugin; | 1878 | fm = endpoint->sending_messages_head; |
2232 | pair.session = queue->content; | 1879 | while (fm != NULL) |
2233 | GNUNET_CONTAINER_heap_iterate(plugin->pending_Fragment_Messages, | 1880 | { |
2234 | &free_fragment_message_from_session, &pair); | 1881 | fmnext = fm->next; |
2235 | 1882 | if (fm->session == queue->content) | |
2236 | //dispose all received fragments | 1883 | { |
2237 | /*receive_queue = get_receive_message_from_session(plugin, queue->content); | 1884 | free_fragment_message(plugin, fm); |
2238 | while (receive_queue != NULL) | 1885 | } |
2239 | { | 1886 | fm = fmnext; |
2240 | free_receive_message(plugin, receive_queue); | 1887 | } |
2241 | receive_queue = get_receive_message_from_session(plugin, queue->content); | ||
2242 | }*/ | ||
2243 | 1888 | ||
2244 | // remove PendingMessage | 1889 | // remove PendingMessage |
2245 | pm = queue->content->pending_message_head; | 1890 | pm = queue->content->pending_message_head; |
2246 | while (pm != NULL) | 1891 | while (pm != NULL) |
2247 | { | 1892 | { |
2248 | GNUNET_CONTAINER_DLL_remove(queue->content->pending_message_head,queue->content->pending_message_tail,pm); | 1893 | GNUNET_CONTAINER_DLL_remove(queue->content->pending_message_head,queue->content->pending_message_tail,pm); |
2249 | GNUNET_free_non_null(pm->msg); | 1894 | GNUNET_free(pm->msg); |
2250 | GNUNET_free(pm); | 1895 | GNUNET_free(pm); |
2251 | pm = queue->content->pending_message_head; | 1896 | pm = queue->content->pending_message_head; |
2252 | } | 1897 | } |
2253 | 1898 | ||
2254 | endpoint = queue->content->mac; | ||
2255 | GNUNET_CONTAINER_DLL_remove(endpoint->sessions_head , | 1899 | GNUNET_CONTAINER_DLL_remove(endpoint->sessions_head , |
2256 | endpoint->sessions_tail, | 1900 | endpoint->sessions_tail, |
2257 | queue); | 1901 | queue); |
@@ -2341,75 +1985,16 @@ wlan_plugin_address_pretty_printer(void *cls, const char *type, | |||
2341 | } | 1985 | } |
2342 | 1986 | ||
2343 | /** | 1987 | /** |
2344 | * Function to test if fragment number already exists in the fragments received | ||
2345 | * | ||
2346 | * @param rec_message message this fragment belongs to | ||
2347 | * @param fh Fragmentheader of the fragment | ||
2348 | * @return GNUNET_YES if fragment exists already, GNUNET_NO if it does not exists in the queue of the session | ||
2349 | */ | ||
2350 | static int | ||
2351 | is_double_msg(struct Receive_Message_Queue * rx_msg, | ||
2352 | struct FragmentationHeader * fh) | ||
2353 | { | ||
2354 | |||
2355 | return testBit((char *) &rx_msg->received_fragments, | ||
2356 | ntohs(fh->fragment_off_or_num)); | ||
2357 | |||
2358 | } | ||
2359 | |||
2360 | /** | ||
2361 | * Function to insert a fragment in a queue of a message | ||
2362 | * @param session session the fragment belongs to | ||
2363 | * @param rec_queue fragment to add | ||
2364 | */ | ||
2365 | static void | ||
2366 | insert_fragment_in_queue(struct Receive_Message_Queue * rx_message, | ||
2367 | struct Receive_Fragment_Queue * rx_frag) | ||
2368 | { | ||
2369 | GNUNET_assert(rx_message != NULL); | ||
2370 | GNUNET_assert(rx_frag != NULL); | ||
2371 | |||
2372 | struct Receive_Fragment_Queue * rx_frag2 = rx_message->frag_head; | ||
2373 | struct WlanHeader * wlanheader; | ||
2374 | |||
2375 | //this is the first fragment of the message (fragment id 0) | ||
2376 | if (rx_frag->num == 0) | ||
2377 | { | ||
2378 | wlanheader = (struct WlanHeader *) rx_frag->msg; | ||
2379 | rx_message->rec_size = ntohs(wlanheader->header.size); | ||
2380 | } | ||
2381 | |||
2382 | //sort into list | ||
2383 | while (rx_frag2 != NULL) | ||
2384 | { | ||
2385 | if (rx_frag2->num > rx_frag->num) | ||
2386 | { | ||
2387 | //next element number is grater than the current num | ||
2388 | GNUNET_CONTAINER_DLL_insert_before(rx_message->frag_head, rx_message->frag_tail, rx_frag2, rx_frag); | ||
2389 | setBit((char *) &rx_message->received_fragments, rx_frag->num); | ||
2390 | return; | ||
2391 | } | ||
2392 | rx_frag2 = rx_frag2->next; | ||
2393 | } | ||
2394 | |||
2395 | //no element has a grater number | ||
2396 | GNUNET_CONTAINER_DLL_insert_tail(rx_message->frag_head, rx_message->frag_tail, rx_frag); | ||
2397 | |||
2398 | setBit((char *) &rx_message->received_fragments, rx_frag->num); | ||
2399 | } | ||
2400 | |||
2401 | /** | ||
2402 | * handels the data after all fragments are put together | 1988 | * handels the data after all fragments are put together |
2403 | * @param plugin | 1989 | * @param plugin |
2404 | * @param session_light | 1990 | * @param session_light |
2405 | * @param hdr pointer to the data | 1991 | * @param hdr pointer to the data |
2406 | */ | 1992 | */ |
2407 | static void | 1993 | static void |
2408 | wlan_data_message_handler(void *cls, void *client, | 1994 | wlan_data_message_handler(void *cls, const struct GNUNET_MessageHeader *hdr) |
2409 | const struct GNUNET_MessageHeader *hdr) | ||
2410 | { | 1995 | { |
2411 | struct Plugin * plugin = (struct Plugin*) cls; | 1996 | struct MacEndpoint * endpoint = (struct MacEndpoint *) cls; |
2412 | struct Session_light * session_light = (struct Session_light *) client; | 1997 | struct Plugin * plugin = endpoint->plugin; |
2413 | struct WlanHeader * wlanheader; | 1998 | struct WlanHeader * wlanheader; |
2414 | struct Session * session; | 1999 | struct Session * session; |
2415 | //const char * tempmsg; | 2000 | //const char * tempmsg; |
@@ -2434,15 +2019,9 @@ wlan_data_message_handler(void *cls, void *client, | |||
2434 | return; | 2019 | return; |
2435 | } | 2020 | } |
2436 | 2021 | ||
2437 | GNUNET_assert(session_light != NULL); | ||
2438 | wlanheader = (struct WlanHeader *) hdr; | 2022 | wlanheader = (struct WlanHeader *) hdr; |
2439 | 2023 | ||
2440 | if (session_light->session == NULL) | 2024 | session = search_session(plugin, endpoint, &wlanheader->source); |
2441 | { | ||
2442 | session_light->session = search_session(plugin, &session_light->addr, | ||
2443 | &wlanheader->source); | ||
2444 | } | ||
2445 | session = session_light->session; | ||
2446 | 2025 | ||
2447 | //tempmsg = (char*) &wlanheader[1]; | 2026 | //tempmsg = (char*) &wlanheader[1]; |
2448 | temp_hdr = (const struct GNUNET_MessageHeader *) &wlanheader[1]; | 2027 | temp_hdr = (const struct GNUNET_MessageHeader *) &wlanheader[1]; |
@@ -2452,7 +2031,7 @@ wlan_data_message_handler(void *cls, void *client, | |||
2452 | { | 2031 | { |
2453 | //wrong crc, dispose message | 2032 | //wrong crc, dispose message |
2454 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 2033 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, |
2455 | "Wlan message Header crc was wrong: %u != %u\n", | 2034 | "Wlan message header crc was wrong: %u != %u\n", |
2456 | getcrc32((char *) wlanheader, ntohs(wlanheader->header.size)), | 2035 | getcrc32((char *) wlanheader, ntohs(wlanheader->header.size)), |
2457 | crc); | 2036 | crc); |
2458 | hexdump((void *) hdr, ntohs(hdr->size)); | 2037 | hexdump((void *) hdr, ntohs(hdr->size)); |
@@ -2479,12 +2058,7 @@ wlan_data_message_handler(void *cls, void *client, | |||
2479 | (const struct GNUNET_HELLO_Message *) temp_hdr, | 2058 | (const struct GNUNET_HELLO_Message *) temp_hdr, |
2480 | &tmpsource) == GNUNET_OK) | 2059 | &tmpsource) == GNUNET_OK) |
2481 | { | 2060 | { |
2482 | session_light->macendpoint = get_macendpoint(plugin, | 2061 | session = create_session(plugin, endpoint, &tmpsource); |
2483 | &session_light->addr, GNUNET_YES); | ||
2484 | session = create_session(plugin, | ||
2485 | session_light->macendpoint, &tmpsource); | ||
2486 | session_light->session = session; | ||
2487 | |||
2488 | } | 2062 | } |
2489 | else | 2063 | else |
2490 | { | 2064 | { |
@@ -2519,7 +2093,8 @@ wlan_data_message_handler(void *cls, void *client, | |||
2519 | { | 2093 | { |
2520 | //wrong peer id | 2094 | //wrong peer id |
2521 | #if DEBUG_wlan | 2095 | #if DEBUG_wlan |
2522 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 2096 | GNUNET_log( |
2097 | GNUNET_ERROR_TYPE_DEBUG, | ||
2523 | "WLAN peer source id doesn't match packet peer source id: session %p\n", | 2098 | "WLAN peer source id doesn't match packet peer source id: session %p\n", |
2524 | session); | 2099 | session); |
2525 | #endif | 2100 | #endif |
@@ -2552,117 +2127,6 @@ wlan_data_message_handler(void *cls, void *client, | |||
2552 | } | 2127 | } |
2553 | } | 2128 | } |
2554 | 2129 | ||
2555 | /** | ||
2556 | * Function to check if all fragments of a message have been received | ||
2557 | * @param plugin the plugin handle | ||
2558 | * @param session_light information of the message sender | ||
2559 | * @param rec_message pointer to the message that should be checked | ||
2560 | */ | ||
2561 | |||
2562 | static void | ||
2563 | check_rx_finished_msg(struct Plugin* plugin, | ||
2564 | struct Session_light * session_light, | ||
2565 | struct Receive_Message_Queue * rx_message) | ||
2566 | { | ||
2567 | GNUNET_assert(rx_message !=NULL); | ||
2568 | |||
2569 | struct Receive_Fragment_Queue * rx_frag = rx_message->frag_head; | ||
2570 | int packetsize = rx_message->rec_size; | ||
2571 | int sum; | ||
2572 | //TODO CLEANUP | ||
2573 | //int aktnum; | ||
2574 | uint64_t bitfield = 0; | ||
2575 | //char * msg; | ||
2576 | |||
2577 | //check if first fragment is present | ||
2578 | if (packetsize == MESSAGE_LENGHT_UNKNOWN) | ||
2579 | { | ||
2580 | return; | ||
2581 | } | ||
2582 | // test if message has at least the size of the WlanHeader and a GNUNET_MessageHeader | ||
2583 | |||
2584 | else if (packetsize < sizeof(struct WlanHeader) | ||
2585 | + sizeof(struct GNUNET_MessageHeader)) | ||
2586 | { | ||
2587 | #if DEBUG_wlan | ||
2588 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Message not big enough\n"); | ||
2589 | #endif | ||
2590 | free_receive_message(plugin, rx_message); | ||
2591 | return; | ||
2592 | } | ||
2593 | |||
2594 | // if (rx_message->frag_tail->num == ffsl(rx_message->received_fragments)) | ||
2595 | // { | ||
2596 | bitfield = ~bitfield; | ||
2597 | bitfield = bitfield >> (63 - rx_message->frag_tail->num); | ||
2598 | if (rx_message->received_fragments == bitfield) | ||
2599 | { | ||
2600 | sum = 0; | ||
2601 | while (rx_frag != NULL) | ||
2602 | { | ||
2603 | sum += rx_frag->size; | ||
2604 | rx_frag = rx_frag->next; | ||
2605 | } | ||
2606 | //sum should always be smaller or equal of | ||
2607 | GNUNET_assert(sum <= packetsize); | ||
2608 | if (sum == packetsize) | ||
2609 | { | ||
2610 | |||
2611 | #if DEBUG_wlan | ||
2612 | GNUNET_log( | ||
2613 | GNUNET_ERROR_TYPE_DEBUG, | ||
2614 | "check_rec_finished_msg: A message for endpoint %p is complete\n", | ||
2615 | rx_message->endpoint); | ||
2616 | #endif | ||
2617 | |||
2618 | //TODO cleanup | ||
2619 | |||
2620 | //copy fragments together | ||
2621 | //msg = GNUNET_malloc(packetsize); | ||
2622 | rx_frag = rx_message->frag_head; | ||
2623 | //aktnum = 0; | ||
2624 | /*while (rx_frag != NULL) | ||
2625 | { | ||
2626 | //TODO SAVE SOME COPY OPS AND CHECK CRC WITHOUT COPY | ||
2627 | memcpy(msg + aktnum, rx_frag->msg, rx_frag->size); | ||
2628 | aktnum += rx_frag->size; | ||
2629 | rx_frag = rx_frag->next; | ||
2630 | }*/ | ||
2631 | |||
2632 | while (rx_frag != NULL) | ||
2633 | { | ||
2634 | if (rx_frag->next != NULL) | ||
2635 | { | ||
2636 | GNUNET_SERVER_mst_receive(plugin->fragment_tokenizer, | ||
2637 | session_light, rx_frag->msg, rx_frag->size, GNUNET_NO, | ||
2638 | GNUNET_NO); | ||
2639 | } | ||
2640 | else | ||
2641 | { | ||
2642 | //if it is the last fragment just kill all leftover | ||
2643 | GNUNET_SERVER_mst_receive(plugin->fragment_tokenizer, | ||
2644 | session_light, rx_frag->msg, rx_frag->size, GNUNET_YES, | ||
2645 | GNUNET_NO); | ||
2646 | } | ||
2647 | rx_frag = rx_frag->next; | ||
2648 | } | ||
2649 | session_light->macendpoint->message_id_backlog[session_light->macendpoint->message_id_backlog_pos] | ||
2650 | = rx_message->message_id_in; | ||
2651 | session_light->macendpoint->message_id_backlog_pos | ||
2652 | = (session_light->macendpoint->message_id_backlog_pos + 1) | ||
2653 | % MESSAGE_ID_BACKLOG_SIZE; | ||
2654 | free_receive_message(plugin, rx_message); | ||
2655 | //call wlan_process_helper to process the message | ||
2656 | //wlan_data_message_handler(plugin, session_light, | ||
2657 | // (struct GNUNET_MessageHeader*) msg); | ||
2658 | //wlan_data_helper (plugin, session_light, (struct GNUNET_MessageHeader*) msg); | ||
2659 | |||
2660 | //GNUNET_free(msg); | ||
2661 | } | ||
2662 | } | ||
2663 | // } | ||
2664 | } | ||
2665 | |||
2666 | //TODO DOXIGEN | 2130 | //TODO DOXIGEN |
2667 | static void | 2131 | static void |
2668 | process_data(void *cls, void *client, const struct GNUNET_MessageHeader *hdr) | 2132 | process_data(void *cls, void *client, const struct GNUNET_MessageHeader *hdr) |
@@ -2692,177 +2156,6 @@ process_data(void *cls, void *client, const struct GNUNET_MessageHeader *hdr) | |||
2692 | } | 2156 | } |
2693 | 2157 | ||
2694 | /** | 2158 | /** |
2695 | * function to add an ack to send it for a received fragment | ||
2696 | * @param plugin pointer to the global plugin structure | ||
2697 | * @param endpoint pointer to the MacEndpoint this ack belongs to | ||
2698 | * @param bitfield bitfield to send | ||
2699 | * @param fh pointer to the fragmentation header which we would like to acknolage | ||
2700 | */ | ||
2701 | |||
2702 | void | ||
2703 | add_ack_for_send(struct Plugin * plugin, struct MacEndpoint * endpoint, | ||
2704 | uint64_t bitfield, struct FragmentationHeader * fh) | ||
2705 | { | ||
2706 | struct AckSendQueue * ack; | ||
2707 | |||
2708 | GNUNET_assert(plugin != NULL); | ||
2709 | GNUNET_assert(endpoint != NULL); | ||
2710 | GNUNET_assert(fh != NULL); | ||
2711 | |||
2712 | ack = GNUNET_malloc(sizeof(struct AckSendQueue)); | ||
2713 | ack->fragments_field = bitfield; | ||
2714 | ack->message_id = ntohl(fh->message_id); | ||
2715 | ack->endpoint = endpoint; | ||
2716 | |||
2717 | GNUNET_CONTAINER_DLL_insert_tail(plugin->ack_send_queue_head, | ||
2718 | plugin->ack_send_queue_tail, ack); | ||
2719 | |||
2720 | } | ||
2721 | |||
2722 | /** | ||
2723 | * function to get the receive message from the message id and the session | ||
2724 | * @param plugin pointer to the plugin struct | ||
2725 | * @param endpoint MacEndpoint this fragment belongs to | ||
2726 | * @param message_id id of the message | ||
2727 | */ | ||
2728 | |||
2729 | /*struct Receive_Message_Queue * | ||
2730 | get_receive_message(struct Plugin * plugin, struct MacEndpoint * endpoint, | ||
2731 | uint32_t message_id) | ||
2732 | { | ||
2733 | struct Receive_Message_Queue * rec_message = plugin->receive_messages_head; | ||
2734 | while (rec_message != NULL) | ||
2735 | { | ||
2736 | if ((rec_message->message_id_in == message_id) && (rec_message->endpoint | ||
2737 | == endpoint)) | ||
2738 | { | ||
2739 | return rec_message; | ||
2740 | } | ||
2741 | rec_message = rec_message->next; | ||
2742 | } | ||
2743 | return NULL; | ||
2744 | }*/ | ||
2745 | |||
2746 | /** | ||
2747 | * function to insert a received fragment into the right fragment queue of the right message | ||
2748 | * @param plugin pointer to the plugin struct | ||
2749 | * @param session_light pointer to the session_light struct of this message | ||
2750 | * @param fh pointer to the header of the fragment | ||
2751 | * @return new fragment bitfield for the message | ||
2752 | */ | ||
2753 | |||
2754 | uint64_t | ||
2755 | insert_fragment_in_in_message_queue(struct Plugin * plugin, | ||
2756 | struct Session_light * session_light, struct FragmentationHeader * fh, | ||
2757 | const struct Radiotap_rx * rxinfo) | ||
2758 | { | ||
2759 | struct Receive_Fragment_Queue * rx_frag = NULL; | ||
2760 | struct Receive_Message_Queue * rx_message; | ||
2761 | struct MacEndpoint * endpoint = session_light->macendpoint; | ||
2762 | const char * tempmsg = (char*) &fh[1]; | ||
2763 | uint64_t retval = 0; | ||
2764 | int i; | ||
2765 | |||
2766 | //TODO fragments do not timeout | ||
2767 | //check if message_id is right or it is a new msg | ||
2768 | GNUNET_assert(fh != NULL); | ||
2769 | |||
2770 | //check for receive of old messages | ||
2771 | for (i = 0; i < MESSAGE_ID_BACKLOG_SIZE; i++) | ||
2772 | { | ||
2773 | if (endpoint->message_id_backlog[i] == ntohl(fh->message_id)) | ||
2774 | { | ||
2775 | setBit((char *) &retval, ntohs(fh->fragment_off_or_num)); | ||
2776 | return retval; | ||
2777 | } | ||
2778 | } | ||
2779 | |||
2780 | rx_message = get_receive_message(plugin, endpoint, ntohl(fh->message_id)); | ||
2781 | |||
2782 | if (rx_message == NULL) | ||
2783 | { | ||
2784 | if (endpoint->fragment_messages_in_count < MESSAGES_IN_QUEUE_PER_SESSION) | ||
2785 | { | ||
2786 | check_receive_message_timeouts(plugin); | ||
2787 | } | ||
2788 | |||
2789 | if (endpoint->fragment_messages_in_count < MESSAGES_IN_QUEUE_PER_SESSION) | ||
2790 | { | ||
2791 | |||
2792 | //new message incoming | ||
2793 | rx_message = GNUNET_malloc(sizeof (struct Receive_Message_Queue)); | ||
2794 | rx_message->message_id_in = ntohl(fh->message_id); | ||
2795 | rx_message->rec_size = MESSAGE_LENGHT_UNKNOWN; | ||
2796 | rx_message->endpoint = endpoint; | ||
2797 | rx_message->received_fragments = 0; | ||
2798 | |||
2799 | GNUNET_CONTAINER_DLL_insert(plugin->receive_messages_head, plugin->receive_messages_teil, rx_message); | ||
2800 | |||
2801 | endpoint->fragment_messages_in_count++; | ||
2802 | plugin->pending_receive_messages++; | ||
2803 | |||
2804 | #if DEBUG_wlan | ||
2805 | GNUNET_log( | ||
2806 | GNUNET_ERROR_TYPE_DEBUG, | ||
2807 | "New fragmented message started: message id %u, messages in for this session %u, messages in %u\n", | ||
2808 | rx_message->message_id_in, | ||
2809 | rx_message->endpoint->fragment_messages_in_count, | ||
2810 | plugin->pending_receive_messages); | ||
2811 | #endif | ||
2812 | } | ||
2813 | else | ||
2814 | { | ||
2815 | |||
2816 | GNUNET_log( | ||
2817 | GNUNET_ERROR_TYPE_INFO, | ||
2818 | "WLAN fragment message_id and session message_id do not exist, max MESSAGES_IN_QUEUE_PER_SESSION reached\n"); | ||
2819 | setBit((char *) &retval, ntohs(fh->fragment_off_or_num)); | ||
2820 | return retval; | ||
2821 | } | ||
2822 | } | ||
2823 | |||
2824 | //reset timeout | ||
2825 | rx_message->timeout = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), | ||
2826 | MESSAGE_IN_TIMEOUT); | ||
2827 | |||
2828 | if (is_double_msg(rx_message, fh) != GNUNET_YES) | ||
2829 | { | ||
2830 | |||
2831 | //report size | ||
2832 | rx_frag = GNUNET_malloc(sizeof (struct Receive_Fragment_Queue) + | ||
2833 | ntohs(fh->header.size) - sizeof(struct FragmentationHeader)); | ||
2834 | rx_frag->size = ntohs(fh->header.size) | ||
2835 | - sizeof(struct FragmentationHeader); | ||
2836 | rx_frag->num = ntohs(fh->fragment_off_or_num); | ||
2837 | rx_frag->msg = (char*) &(rx_frag[1]); | ||
2838 | //copy msg to buffer | ||
2839 | memcpy((char *) rx_frag->msg, tempmsg, rx_frag->size); | ||
2840 | memcpy((char *) &(rx_frag->rxinfo), rxinfo, sizeof(rxinfo)); | ||
2841 | insert_fragment_in_queue(rx_message, rx_frag); | ||
2842 | //save bitfield | ||
2843 | retval = rx_message->received_fragments; | ||
2844 | |||
2845 | #if DEBUG_wlan | ||
2846 | GNUNET_log( | ||
2847 | GNUNET_ERROR_TYPE_DEBUG, | ||
2848 | "New fragment: size %u, fragsize %u, message id %u, bitfield %X, endpoint %p\n", | ||
2849 | rx_message->rec_size, rx_frag->size, rx_message->message_id_in, | ||
2850 | rx_message->received_fragments, rx_message->endpoint); | ||
2851 | #endif | ||
2852 | |||
2853 | check_rx_finished_msg(plugin, session_light, rx_message); | ||
2854 | } | ||
2855 | else | ||
2856 | { | ||
2857 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "WLAN fragment is a clone\n"); | ||
2858 | retval = rx_message->received_fragments; | ||
2859 | |||
2860 | } | ||
2861 | return retval; | ||
2862 | |||
2863 | } | ||
2864 | |||
2865 | /** | ||
2866 | * Function used for to process the data received from the wlan interface | 2159 | * Function used for to process the data received from the wlan interface |
2867 | * | 2160 | * |
2868 | * @param cls the plugin handle | 2161 | * @param cls the plugin handle |
@@ -2874,14 +2167,8 @@ wlan_data_helper(void *cls, struct Session_light * session_light, | |||
2874 | const struct GNUNET_MessageHeader * hdr, const struct Radiotap_rx * rxinfo) | 2167 | const struct GNUNET_MessageHeader * hdr, const struct Radiotap_rx * rxinfo) |
2875 | { | 2168 | { |
2876 | struct Plugin *plugin = cls; | 2169 | struct Plugin *plugin = cls; |
2877 | |||
2878 | struct FragmentationHeader * fh; | ||
2879 | struct FragmentationAckHeader * fah; | ||
2880 | struct FragmentMessage * fm; | 2170 | struct FragmentMessage * fm; |
2881 | 2171 | struct FragmentMessage * fm2; | |
2882 | const char * tempmsg; | ||
2883 | |||
2884 | uint64_t fragment_bitfield = 0; | ||
2885 | 2172 | ||
2886 | //ADVERTISEMENT | 2173 | //ADVERTISEMENT |
2887 | if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT) | 2174 | if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT) |
@@ -2912,81 +2199,42 @@ wlan_data_helper(void *cls, struct Session_light * session_light, | |||
2912 | 2199 | ||
2913 | //FRAGMENT | 2200 | //FRAGMENT |
2914 | 2201 | ||
2915 | else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT) | 2202 | else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_FRAGMENT) |
2916 | { | 2203 | { |
2917 | 2204 | ||
2918 | GNUNET_assert(session_light != NULL); | 2205 | GNUNET_assert(session_light != NULL); |
2919 | if (session_light->macendpoint == NULL) | 2206 | if (session_light->macendpoint == NULL) |
2920 | { | 2207 | { |
2921 | session_light->macendpoint = get_macendpoint(plugin, | 2208 | session_light->macendpoint = get_macendpoint(plugin, |
2922 | &session_light->addr, GNUNET_NO); | 2209 | &session_light->addr, GNUNET_YES); |
2923 | } | 2210 | } |
2924 | 2211 | ||
2925 | fh = (struct FragmentationHeader *) hdr; | ||
2926 | tempmsg = (char*) &fh[1]; | ||
2927 | |||
2928 | #if DEBUG_wlan | 2212 | #if DEBUG_wlan |
2929 | GNUNET_log( | 2213 | GNUNET_log( |
2930 | GNUNET_ERROR_TYPE_DEBUG, | 2214 | GNUNET_ERROR_TYPE_DEBUG, |
2931 | "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT with message_id %u with fragment number %i, size: %u; %s\n", | 2215 | "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_FRAGMENT with size: %u; mac endpoint %p: %s\n", |
2932 | ntohl(fh->message_id), ntohs(fh->fragment_off_or_num), | 2216 | ntohs(hdr->size), session_light->macendpoint, |
2933 | ntohs(hdr->size), | ||
2934 | wlan_plugin_address_to_string(NULL, session_light->addr.mac, 6)); | 2217 | wlan_plugin_address_to_string(NULL, session_light->addr.mac, 6)); |
2935 | #endif | 2218 | #endif |
2936 | 2219 | ||
2937 | if (getcrc16(tempmsg, ntohs(fh->header.size)) != ntohs(fh->message_crc)) | 2220 | int ret = GNUNET_DEFRAGMENT_process_fragment( |
2938 | { | 2221 | session_light->macendpoint->defrag, hdr); |
2939 | //wrong crc, dispose message | 2222 | if (ret == GNUNET_NO) |
2940 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "WLAN fragment crc was wrong\n"); | ||
2941 | return; | ||
2942 | } | ||
2943 | |||
2944 | //if in the session list | ||
2945 | if (session_light->macendpoint != NULL) | ||
2946 | { | 2223 | { |
2947 | fragment_bitfield = insert_fragment_in_in_message_queue(plugin, | 2224 | session_light->macendpoint->dups++; |
2948 | session_light, fh, rxinfo); | ||
2949 | } | 2225 | } |
2950 | else | 2226 | else if (ret == GNUNET_OK) |
2951 | { | 2227 | { |
2952 | // new session | 2228 | session_light->macendpoint->fragc++; |
2953 | GNUNET_log( | ||
2954 | GNUNET_ERROR_TYPE_INFO, | ||
2955 | "WLAN client not in session list, fragment num %u, message id %u\n", | ||
2956 | ntohs(fh->fragment_off_or_num), ntohl(fh->message_id)); | ||
2957 | |||
2958 | GNUNET_SERVER_mst_receive(plugin->fragment_tokenizer, session_light, | ||
2959 | tempmsg, ntohs(hdr->size) - sizeof(struct FragmentationHeader), | ||
2960 | GNUNET_YES, GNUNET_NO); | ||
2961 | //wlan_data_message_handler(plugin, session_light, | ||
2962 | // (struct GNUNET_MessageHeader *) tempmsg); | ||
2963 | //test if a session was created | ||
2964 | if (session_light->session == NULL) | ||
2965 | { | ||
2966 | return; | ||
2967 | } | ||
2968 | setBit((char *) &fragment_bitfield, ntohs(fh->fragment_off_or_num)); | ||
2969 | } | 2229 | } |
2970 | |||
2971 | add_ack_for_send(plugin, session_light->macendpoint, fragment_bitfield, | ||
2972 | fh); | ||
2973 | set_next_send(plugin); | 2230 | set_next_send(plugin); |
2974 | 2231 | ||
2975 | } | 2232 | } |
2976 | 2233 | ||
2977 | //ACK | 2234 | //ACK |
2978 | 2235 | ||
2979 | else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT_ACK) | 2236 | else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_FRAGMENT_ACK) |
2980 | { | 2237 | { |
2981 | |||
2982 | #if DEBUG_wlan | ||
2983 | GNUNET_log( | ||
2984 | GNUNET_ERROR_TYPE_DEBUG, | ||
2985 | "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT_ACK size: %u; %s\n", | ||
2986 | ntohs(hdr->size), | ||
2987 | wlan_plugin_address_to_string(NULL, session_light->addr.mac, 6)); | ||
2988 | #endif | ||
2989 | |||
2990 | GNUNET_assert(session_light != NULL); | 2238 | GNUNET_assert(session_light != NULL); |
2991 | if (session_light->macendpoint == NULL) | 2239 | if (session_light->macendpoint == NULL) |
2992 | { | 2240 | { |
@@ -2994,32 +2242,62 @@ wlan_data_helper(void *cls, struct Session_light * session_light, | |||
2994 | &session_light->addr, GNUNET_NO); | 2242 | &session_light->addr, GNUNET_NO); |
2995 | } | 2243 | } |
2996 | 2244 | ||
2997 | fah = (struct FragmentationAckHeader *) hdr; | 2245 | if (session_light->macendpoint == NULL) |
2998 | fm = get_fragment_message_from_endpoint_and_id(plugin, | ||
2999 | session_light->macendpoint, ntohl(fah->message_id)); | ||
3000 | |||
3001 | if (fm != NULL) | ||
3002 | { | 2246 | { |
2247 | #if DEBUG_wlan | ||
2248 | GNUNET_log( | ||
2249 | GNUNET_ERROR_TYPE_DEBUG, | ||
2250 | "Macendpoint does not exist for this GNUNET_MESSAGE_TYPE_FRAGMENT_ACK size: %u; %s\n", | ||
2251 | ntohs(hdr->size), | ||
2252 | wlan_plugin_address_to_string(NULL, session_light->addr.mac, 6)); | ||
2253 | #endif | ||
2254 | return; | ||
2255 | } | ||
3003 | 2256 | ||
3004 | fm->ack_bitfield = fm->ack_bitfield | GNUNET_ntohll( | 2257 | #if DEBUG_wlan |
3005 | fah->fragment_field); | 2258 | GNUNET_log( |
3006 | fm->next_ack = GNUNET_TIME_relative_to_absolute(get_ack_timeout(fm)); | 2259 | GNUNET_ERROR_TYPE_DEBUG, |
3007 | 2260 | "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_FRAGMENT_ACK size: %u; mac endpoint: %p; %s\n", | |
2261 | ntohs(hdr->size), session_light->macendpoint, | ||
2262 | wlan_plugin_address_to_string(NULL, session_light->addr.mac, 6)); | ||
2263 | #endif | ||
2264 | fm = session_light->macendpoint->sending_messages_head; | ||
2265 | while (fm != NULL) | ||
2266 | { | ||
2267 | fm2 = fm->next; | ||
2268 | int ret = GNUNET_FRAGMENT_process_ack(fm->fragcontext, hdr); | ||
2269 | if (ret == GNUNET_OK) | ||
2270 | { | ||
3008 | #if DEBUG_wlan_retransmission | 2271 | #if DEBUG_wlan_retransmission |
3009 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Got ack for: %u; %u\n", | 2272 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
3010 | fm->message_id_out, fm->ack_bitfield); | 2273 | "Got last ack, finished fragment message %p\n", fm); |
3011 | #endif | 2274 | #endif |
3012 | check_finished_fragment(plugin, fm); | 2275 | session_light->macendpoint->acks++; |
3013 | set_next_send(plugin); | 2276 | free_fragment_message(plugin, fm); |
2277 | check_fragment_queue(plugin); | ||
2278 | return; | ||
2279 | } | ||
2280 | if (ret == GNUNET_NO) | ||
2281 | { | ||
2282 | #if DEBUG_wlan_retransmission | ||
2283 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Got ack for: %p\n", fm); | ||
2284 | #endif | ||
2285 | session_light->macendpoint->acks++; | ||
2286 | return; | ||
2287 | } | ||
2288 | if (ret == GNUNET_SYSERR) | ||
2289 | { | ||
3014 | 2290 | ||
2291 | } | ||
2292 | |||
2293 | fm = fm2; | ||
3015 | } | 2294 | } |
3016 | else | 2295 | |
3017 | { | 2296 | #if DEBUG_wlan_retransmission |
3018 | //GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | 2297 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
3019 | // "WLAN fragment not in fragment list with id %u of ack\n", ntohl( | 2298 | "WLAN fragment not in fragment list\n"); |
3020 | // fah->message_id)); | 2299 | #endif |
3021 | return; | 2300 | return; |
3022 | } | ||
3023 | 2301 | ||
3024 | } | 2302 | } |
3025 | else | 2303 | else |
@@ -3052,6 +2330,33 @@ macprinter(const u_int8_t * mac) | |||
3052 | } | 2330 | } |
3053 | 2331 | ||
3054 | /** | 2332 | /** |
2333 | * function to create an macendpoint | ||
2334 | * @param plugin pointer to the plugin struct | ||
2335 | * @param addr pointer to the macaddress | ||
2336 | * @return returns a macendpoint | ||
2337 | */ | ||
2338 | static struct MacEndpoint * | ||
2339 | create_macendpoint(struct Plugin *plugin, const struct MacAddress *addr) | ||
2340 | { | ||
2341 | struct MacEndpoint * newend = GNUNET_malloc(sizeof (struct MacEndpoint)); | ||
2342 | newend->addr = *addr; | ||
2343 | newend->plugin = plugin; | ||
2344 | newend->addr = *addr; | ||
2345 | newend->fragment_messages_out_count = 0; | ||
2346 | newend->defrag = GNUNET_DEFRAGMENT_context_create(plugin->env->stats, | ||
2347 | WLAN_MTU, MESSAGES_IN_DEFRAG_QUEUE_PER_MAC, newend, | ||
2348 | &wlan_data_message_handler, &add_ack_for_send); | ||
2349 | |||
2350 | plugin->mac_count++; | ||
2351 | GNUNET_CONTAINER_DLL_insert_tail(plugin->mac_head, plugin->mac_tail, newend); | ||
2352 | #if DEBUG_wlan | ||
2353 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "New Mac Endpoint %p: %s\n", newend, | ||
2354 | wlan_plugin_address_to_string(NULL, newend->addr.mac, 6)); | ||
2355 | #endif | ||
2356 | return newend; | ||
2357 | } | ||
2358 | |||
2359 | /** | ||
3055 | * Function used for to process the data from the suid process | 2360 | * Function used for to process the data from the suid process |
3056 | * | 2361 | * |
3057 | * @param cls the plugin handle | 2362 | * @param cls the plugin handle |
@@ -3328,7 +2633,6 @@ libgnunet_plugin_transport_wlan_done(void *cls) | |||
3328 | struct Plugin *plugin = api->cls; | 2633 | struct Plugin *plugin = api->cls; |
3329 | struct MacEndpoint * endpoint = plugin->mac_head; | 2634 | struct MacEndpoint * endpoint = plugin->mac_head; |
3330 | struct MacEndpoint * endpoint_next; | 2635 | struct MacEndpoint * endpoint_next; |
3331 | struct FragmentMessage * fm; | ||
3332 | 2636 | ||
3333 | #if DEBUG_wlan | 2637 | #if DEBUG_wlan |
3334 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 2638 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
@@ -3371,21 +2675,7 @@ libgnunet_plugin_transport_wlan_done(void *cls) | |||
3371 | if (plugin->data_tokenizer != NULL) | 2675 | if (plugin->data_tokenizer != NULL) |
3372 | GNUNET_SERVER_mst_destroy(plugin->data_tokenizer); | 2676 | GNUNET_SERVER_mst_destroy(plugin->data_tokenizer); |
3373 | 2677 | ||
3374 | if (plugin->fragment_tokenizer != NULL) | ||
3375 | GNUNET_SERVER_mst_destroy(plugin->fragment_tokenizer); | ||
3376 | |||
3377 | fm = (struct FragmentMessage *) GNUNET_CONTAINER_heap_peek( | ||
3378 | plugin->pending_Fragment_Messages); | ||
3379 | |||
3380 | while (fm != NULL) | ||
3381 | { | ||
3382 | free_fragment_message(plugin, fm); | ||
3383 | fm = (struct FragmentMessage *) GNUNET_CONTAINER_heap_peek( | ||
3384 | plugin->pending_Fragment_Messages); | ||
3385 | } | ||
3386 | |||
3387 | GNUNET_free_non_null(plugin->interface); | 2678 | GNUNET_free_non_null(plugin->interface); |
3388 | GNUNET_CONTAINER_heap_destroy(plugin->pending_Fragment_Messages); | ||
3389 | GNUNET_free (plugin); | 2679 | GNUNET_free (plugin); |
3390 | GNUNET_free (api); | 2680 | GNUNET_free (api); |
3391 | return NULL; | 2681 | return NULL; |
@@ -3415,15 +2705,13 @@ libgnunet_plugin_transport_wlan_init(void *cls) | |||
3415 | plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; | 2705 | plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; |
3416 | plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; | 2706 | plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; |
3417 | plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; | 2707 | plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; |
3418 | plugin->pending_Fragment_Messages = GNUNET_CONTAINER_heap_create( | 2708 | GNUNET_BANDWIDTH_tracker_init(&plugin->tracker, |
3419 | GNUNET_CONTAINER_HEAP_ORDER_MIN); | 2709 | GNUNET_BANDWIDTH_value_init(100 * 1024 * 1024 / 8), 100); |
3420 | 2710 | ||
3421 | plugin->suid_tokenizer = GNUNET_SERVER_mst_create(&wlan_process_helper, | 2711 | plugin->suid_tokenizer = GNUNET_SERVER_mst_create(&wlan_process_helper, |
3422 | plugin); | 2712 | plugin); |
3423 | 2713 | ||
3424 | plugin->data_tokenizer = GNUNET_SERVER_mst_create(&process_data, plugin); | 2714 | plugin->data_tokenizer = GNUNET_SERVER_mst_create(&process_data, plugin); |
3425 | plugin->fragment_tokenizer = GNUNET_SERVER_mst_create( | ||
3426 | &wlan_data_message_handler, plugin); | ||
3427 | 2715 | ||
3428 | //plugin->sessions = GNUNET_malloc (sizeof (struct Sessionqueue)); | 2716 | //plugin->sessions = GNUNET_malloc (sizeof (struct Sessionqueue)); |
3429 | //plugin->pending_Sessions_head = GNUNET_malloc (sizeof (struct Sessionqueue)); | 2717 | //plugin->pending_Sessions_head = GNUNET_malloc (sizeof (struct Sessionqueue)); |
diff --git a/src/transport/plugin_transport_wlan.h b/src/transport/plugin_transport_wlan.h index 5c86c5bd0..8528d984a 100644 --- a/src/transport/plugin_transport_wlan.h +++ b/src/transport/plugin_transport_wlan.h | |||
@@ -41,32 +41,6 @@ struct Wlan_Helper_Control_Message | |||
41 | struct MacAddress mac; | 41 | struct MacAddress mac; |
42 | }; | 42 | }; |
43 | 43 | ||
44 | /** | ||
45 | * Header for messages which need fragmentation | ||
46 | */ | ||
47 | struct FragmentationHeader | ||
48 | { | ||
49 | |||
50 | struct GNUNET_MessageHeader header; | ||
51 | |||
52 | /** | ||
53 | * ID of message, to distinguish between the messages, picked randomly. | ||
54 | */ | ||
55 | uint32_t message_id GNUNET_PACKED; | ||
56 | |||
57 | /** | ||
58 | * Offset or number of this fragment, for fragmentation/segmentation (design choice, TBD) | ||
59 | */ | ||
60 | uint16_t fragment_off_or_num GNUNET_PACKED; | ||
61 | |||
62 | /** | ||
63 | * CRC of fragment (for error checking) | ||
64 | */ | ||
65 | uint16_t message_crc GNUNET_PACKED; | ||
66 | |||
67 | // followed by payload | ||
68 | |||
69 | }; | ||
70 | 44 | ||
71 | /** | 45 | /** |
72 | * Header for messages which need fragmentation | 46 | * Header for messages which need fragmentation |