aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Brodski <david@brodski.eu>2010-11-23 22:50:50 +0000
committerDavid Brodski <david@brodski.eu>2010-11-23 22:50:50 +0000
commitcc47103dd756181a23e032a93aa4cec925819747 (patch)
tree04c253e0e5a302fc53bfdcd49e1ba2f8bc15f005
parent2d8268aefde82aa59895dcd55a5eb80bab7ca7a8 (diff)
downloadgnunet-cc47103dd756181a23e032a93aa4cec925819747.tar.gz
gnunet-cc47103dd756181a23e032a93aa4cec925819747.zip
fragments are now put together to form a message
-rw-r--r--src/transport/plugin_transport_wlan.c201
1 files changed, 186 insertions, 15 deletions
diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c
index ce740e785..de868a427 100644
--- a/src/transport/plugin_transport_wlan.c
+++ b/src/transport/plugin_transport_wlan.c
@@ -51,6 +51,10 @@
51 51
52#define DEBUG_wlan GNUNET_NO 52#define DEBUG_wlan GNUNET_NO
53 53
54#define MESSAGE_LENGHT_UNKNOWN -1
55#define NO_MESSAGE_OR_MESSAGE_FINISHED -2
56
57
54/** 58/**
55 * After how long do we expire an address that we 59 * After how long do we expire an address that we
56 * learned from another peer if it is not reconfirmed 60 * learned from another peer if it is not reconfirmed
@@ -220,7 +224,7 @@ struct AckQueue
220{ 224{
221 struct AckQueue * next; 225 struct AckQueue * next;
222 struct AckQueue * prev; 226 struct AckQueue * prev;
223 int fragment_num; //TODO change it to offset 227 int fragment_num; //TODO change it to offset if better
224}; 228};
225 229
226/** 230/**
@@ -232,7 +236,7 @@ struct RecQueue
232 struct RecQueue * next; 236 struct RecQueue * next;
233 struct RecQueue * prev; 237 struct RecQueue * prev;
234 uint16_t num; 238 uint16_t num;
235 char * msg; 239 const char * msg;
236 uint16_t size; 240 uint16_t size;
237}; 241};
238 242
@@ -328,7 +332,9 @@ struct Session
328 //int rec_offset; 332 //int rec_offset;
329 333
330 /** 334 /**
331 * size of the message received, -1 means that the size is not known, -2 means no message received 335 * size of the message received,
336 * MESSAGE_LENGHT_UNKNOWN means that the size is not known,
337 * NO_MESSAGE_OR_MESSAGE_FINISHED means no message received
332 */ 338 */
333 339
334 int rec_size; 340 int rec_size;
@@ -535,6 +541,14 @@ check_fragment_queue(struct Plugin * plugin);
535uint32_t 541uint32_t
536getcrc32(const char *msgbuf, size_t msgbuf_size); 542getcrc32(const char *msgbuf, size_t msgbuf_size);
537 543
544static void
545free_rec_frag_queue(struct Session * session);
546
547static void
548wlan_process_helper (void *cls,
549 void *client,
550 const struct GNUNET_MessageHeader *hdr);
551
538/** 552/**
539 * get the next message number, at the moment just a random one 553 * get the next message number, at the moment just a random one
540 * 554 *
@@ -608,7 +622,7 @@ create_session(struct Plugin *plugin,const uint8_t * addr)
608 memcpy(queue->content->addr, addr, 6); 622 memcpy(queue->content->addr, addr, 6);
609 queue->content->message_id_out = get_next_message_id(); 623 queue->content->message_id_out = get_next_message_id();
610 queue->content->has_fragment = 0; 624 queue->content->has_fragment = 0;
611 queue->content->rec_size = -2; 625 queue->content->rec_size = NO_MESSAGE_OR_MESSAGE_FINISHED;
612 626
613 plugin->session_count++; 627 plugin->session_count++;
614 return queue->content; 628 return queue->content;
@@ -698,6 +712,9 @@ free_acks (struct FragmentMessage * fm){
698 GNUNET_CONTAINER_DLL_remove(fm->head, fm->tail, fq); 712 GNUNET_CONTAINER_DLL_remove(fm->head, fm->tail, fq);
699 GNUNET_free(fq); 713 GNUNET_free(fq);
700 } 714 }
715 //needed?
716 fm->head = NULL;
717 fm->tail = NULL;
701} 718}
702 719
703//TODO doxigen 720//TODO doxigen
@@ -940,6 +957,7 @@ check_fragment_queue (struct Plugin * plugin){
940 } 957 }
941} 958}
942 959
960//TODO doxigen
943static void 961static void
944check_finished_fragment(struct Plugin * plugin, struct FragmentMessage * fm){ 962check_finished_fragment(struct Plugin * plugin, struct FragmentMessage * fm){
945 struct AckQueue * ack; 963 struct AckQueue * ack;
@@ -1013,7 +1031,7 @@ do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1013 *(plugin->env->our_hello)); 1031 *(plugin->env->our_hello));
1014 1032
1015 msgheader = GNUNET_malloc(size); 1033 msgheader = GNUNET_malloc(size);
1016 msgheader->size = htons(size - sizeof(struct GNUNET_MessageHeader)); 1034 msgheader->size = htons(size);
1017 msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); 1035 msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1018 1036
1019 radioHeader = (struct RadiotapHeader *) &msgheader[1]; 1037 radioHeader = (struct RadiotapHeader *) &msgheader[1];
@@ -1023,7 +1041,7 @@ do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1023 getWlanHeader(ieeewlanheader); 1041 getWlanHeader(ieeewlanheader);
1024 1042
1025 msgheader2 = (struct GNUNET_MessageHeader *) &ieeewlanheader[1]; 1043 msgheader2 = (struct GNUNET_MessageHeader *) &ieeewlanheader[1];
1026 msgheader2->size = htons(GNUNET_HELLO_size(*(plugin->env->our_hello))); 1044 msgheader2->size = htons(GNUNET_HELLO_size(*(plugin->env->our_hello)) + sizeof(struct GNUNET_MessageHeader));
1027 msgheader2->type = htons(GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT); 1045 msgheader2->type = htons(GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT);
1028 1046
1029 memcpy(&msgheader2[1], *plugin->env->our_hello, GNUNET_HELLO_size( 1047 memcpy(&msgheader2[1], *plugin->env->our_hello, GNUNET_HELLO_size(
@@ -1103,7 +1121,7 @@ do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1103 //or the missing part of the message in case this is the last fragment 1121 //or the missing part of the message in case this is the last fragment
1104 copysize = GNUNET_MIN(fm->message_size - copyoffset, 1122 copysize = GNUNET_MIN(fm->message_size - copyoffset,
1105 WLAN_MTU - sizeof(struct FragmentationHeader)); 1123 WLAN_MTU - sizeof(struct FragmentationHeader));
1106 fragheader.header.size = htons(copysize); 1124 fragheader.header.size = htons(copysize + sizeof(struct FragmentationHeader));
1107 fragheader.header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT); 1125 fragheader.header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT);
1108 1126
1109 1127
@@ -1136,7 +1154,7 @@ do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1136 size += sizeof(struct RadiotapHeader) + sizeof(struct IeeeHeader) 1154 size += sizeof(struct RadiotapHeader) + sizeof(struct IeeeHeader)
1137 + sizeof(struct GNUNET_MessageHeader); 1155 + sizeof(struct GNUNET_MessageHeader);
1138 msgheader = GNUNET_malloc(size); 1156 msgheader = GNUNET_malloc(size);
1139 msgheader->size = htons(size - sizeof(struct GNUNET_MessageHeader)); 1157 msgheader->size = htons(size);
1140 msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); 1158 msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1141 1159
1142 radioHeader = (struct RadiotapHeader*) &msgheader[1]; 1160 radioHeader = (struct RadiotapHeader*) &msgheader[1];
@@ -1286,7 +1304,7 @@ wlan_plugin_send (void *cls,
1286 (newmsg->msg) = GNUNET_malloc(msgbuf_size + sizeof(struct WlanHeader)); 1304 (newmsg->msg) = GNUNET_malloc(msgbuf_size + sizeof(struct WlanHeader));
1287 wlanheader = (struct WlanHeader *) newmsg->msg; 1305 wlanheader = (struct WlanHeader *) newmsg->msg;
1288 //copy msg to buffer, not fragmented / segmented yet, but with message header 1306 //copy msg to buffer, not fragmented / segmented yet, but with message header
1289 wlanheader->header.size = htons(msgbuf_size); 1307 wlanheader->header.size = htons(msgbuf_size + sizeof(struct WlanHeader));
1290 wlanheader->header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_DATA); 1308 wlanheader->header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_DATA);
1291 memcpy(&(wlanheader->target), target, sizeof(struct GNUNET_PeerIdentity)); 1309 memcpy(&(wlanheader->target), target, sizeof(struct GNUNET_PeerIdentity));
1292 wlanheader->crc = htonl(getcrc32(msgbuf, msgbuf_size)); 1310 wlanheader->crc = htonl(getcrc32(msgbuf, msgbuf_size));
@@ -1302,6 +1320,7 @@ wlan_plugin_send (void *cls,
1302 1320
1303} 1321}
1304 1322
1323//TODO doxigen
1305static struct FragmentMessage * 1324static struct FragmentMessage *
1306get_fragment_message_from_session(struct Session * session) 1325get_fragment_message_from_session(struct Session * session)
1307{ 1326{
@@ -1361,6 +1380,8 @@ wlan_plugin_disconnect(void *cls, const struct GNUNET_PeerIdentity *target)
1361 fm = get_fragment_message_from_session(queue->content); 1380 fm = get_fragment_message_from_session(queue->content);
1362 free_fragment_message(plugin,fm); 1381 free_fragment_message(plugin,fm);
1363 1382
1383 //dispose all received fragments
1384 free_rec_frag_queue(queue->content);
1364 1385
1365 // remove PendingMessage 1386 // remove PendingMessage
1366 pm = queue->content->pending_message; 1387 pm = queue->content->pending_message;
@@ -1499,9 +1520,125 @@ wlan_plugin_address_to_string (void *cls,
1499 return GNUNET_strdup (ret); 1520 return GNUNET_strdup (ret);
1500} 1521}
1501 1522
1523/**
1524 * Function to test if fragment number already exists in the fragments received
1525 */
1526//TODO doxigen
1527static const int
1528is_double_msg(struct Session * session, struct FragmentationHeader * fh)
1529{
1530 struct RecQueue * rec_queue = session->frag_head;
1531 while (rec_queue != NULL)
1532 {
1533 if (rec_queue->num == fh->fragment_off_or_num)
1534 {
1535 return GNUNET_YES;
1536 }
1537 rec_queue = rec_queue->next;
1502 1538
1539 }
1540 return GNUNET_NO;
1541}
1503 1542
1504 1543
1544static void
1545insert_fragment_in_queue(struct Session * session, struct RecQueue * rec_queue)
1546{
1547 struct RecQueue * rec_queue2 = session->frag_head;
1548 struct WlanHeader * wlanheader = NULL;
1549 //first received fragment of message
1550 if (session->rec_size == NO_MESSAGE_OR_MESSAGE_FINISHED)
1551 {
1552 session->rec_size = MESSAGE_LENGHT_UNKNOWN;
1553 }
1554 //this is the first fragment of the message (fragment id 0)
1555 if (rec_queue->num == 0)
1556 {
1557 wlanheader = (struct WlanHeader *) rec_queue->msg;
1558 session->rec_size = wlanheader->header.size;
1559 }
1560
1561 //sort into list
1562 while (rec_queue2 != NULL)
1563 {
1564 if (rec_queue2->num > rec_queue->num)
1565 {
1566 //next element number is grater than the current num
1567 GNUNET_CONTAINER_DLL_insert_before(session->frag_head, session->frag_tail, rec_queue2, rec_queue);
1568 return;
1569 }
1570 rec_queue = rec_queue->next;
1571 }
1572 //no element has a grater number
1573 GNUNET_CONTAINER_DLL_insert_tail(session->frag_head, session->frag_tail, rec_queue);
1574}
1575
1576/**
1577 * Function to dispose the fragments received for a message
1578 */
1579//TODO doxigen
1580static void
1581free_rec_frag_queue(struct Session * session)
1582{
1583 struct RecQueue * rec_queue = session->frag_head;
1584 struct RecQueue * rec_queue2;
1585 while (rec_queue != NULL)
1586 {
1587 rec_queue2 = rec_queue;
1588 rec_queue = rec_queue->next;
1589 GNUNET_free(rec_queue2);
1590 }
1591 session->frag_head = NULL;
1592 session->frag_tail = NULL;
1593 session->rec_size = NO_MESSAGE_OR_MESSAGE_FINISHED;
1594}
1595
1596/**
1597 * Function to check if all fragments of a message have been received
1598 */
1599//TODO doxigen
1600static void
1601check_rec_finished_msg (struct Plugin* plugin, struct Session_light * session_light, struct Session * session){
1602 struct RecQueue * rec_queue = session->frag_head;
1603 int packetsize = session->rec_size;
1604 int sum = 0;
1605 int aktnum = 0;
1606 char * msg;
1607 //some fragment should be received
1608 GNUNET_assert(session->rec_size != NO_MESSAGE_OR_MESSAGE_FINISHED);
1609 //check if first fragment is present
1610 if (session->rec_size == MESSAGE_LENGHT_UNKNOWN){
1611 return;
1612 }
1613 while (rec_queue != NULL){
1614 sum += rec_queue->size;
1615 //check if all fragment numbers are present
1616 if (rec_queue->num != aktnum){
1617 return;
1618 }
1619 aktnum ++;
1620 rec_queue = rec_queue->next;
1621 }
1622 //sum should always be smaller or equal of
1623 GNUNET_assert(sum <= packetsize);
1624 if (sum == packetsize){
1625 //copy fragments together
1626 msg = GNUNET_malloc(packetsize);
1627 rec_queue = session->frag_head;
1628 aktnum = 0;
1629 while (rec_queue != NULL){
1630 memcpy(msg + aktnum, rec_queue->msg, rec_queue->size);
1631 aktnum += rec_queue->size;
1632 rec_queue = rec_queue->next;
1633 }
1634 free_rec_frag_queue(session);
1635 //call wlan_process_helper to process the message
1636 wlan_process_helper (plugin, session_light, (struct GNUNET_MessageHeader*) msg);
1637
1638 GNUNET_free(msg);
1639 }
1640}
1641
1505/** 1642/**
1506 * Function used for to process the data from the suid process 1643 * Function used for to process the data from the suid process
1507 */ 1644 */
@@ -1518,6 +1655,7 @@ wlan_process_helper (void *cls,
1518 struct WlanHeader * wlanheader = NULL; 1655 struct WlanHeader * wlanheader = NULL;
1519 struct FragmentationHeader * fh = NULL; 1656 struct FragmentationHeader * fh = NULL;
1520 struct FragmentMessage * fm = NULL; 1657 struct FragmentMessage * fm = NULL;
1658 struct RecQueue * rec_queue = NULL;
1521 const struct GNUNET_MessageHeader * temp_hdr = NULL; 1659 const struct GNUNET_MessageHeader * temp_hdr = NULL;
1522 const char * tempmsg = NULL; 1660 const char * tempmsg = NULL;
1523 struct Session_light * session_light; 1661 struct Session_light * session_light;
@@ -1626,7 +1764,7 @@ wlan_process_helper (void *cls,
1626 } 1764 }
1627 session = session_light->session; 1765 session = session_light->session;
1628 1766
1629 fh = (struct FragmentationHeader *) &hdr[1]; 1767 fh = (struct FragmentationHeader *) hdr;
1630 tempmsg = (char*) &fh[1]; 1768 tempmsg = (char*) &fh[1];
1631 1769
1632 //if not in session list 1770 //if not in session list
@@ -1641,7 +1779,38 @@ wlan_process_helper (void *cls,
1641 } 1779 }
1642 else 1780 else
1643 { 1781 {
1644 //todo fragments to message 1782 //todo fragments do not timeout
1783 //check if message_id is rigth or it is a new msg
1784 if ((session->message_id_in == ntohs(fh->message_id))
1785 || (session->rec_size == NO_MESSAGE_OR_MESSAGE_FINISHED))
1786 {
1787 session->message_id_in = ntohs(fh->message_id);
1788 if (is_double_msg(session, fh) != GNUNET_YES)
1789 {
1790 rec_queue = GNUNET_malloc(sizeof (struct RecQueue) +
1791 ntohs(fh->header.size) - sizeof(struct FragmentationHeader));
1792 rec_queue->size = ntohs(fh->header.size
1793 - sizeof(struct FragmentationHeader));
1794 rec_queue->num = ntohs(fh->fragment_off_or_num);
1795 rec_queue->msg = (char*) &rec_queue[1];
1796 //copy msg to buffer
1797 memcpy((char*) rec_queue->msg, tempmsg, rec_queue->size);
1798 insert_fragment_in_queue(session, rec_queue);
1799 check_rec_finished_msg(plugin, session_light, session);
1800 }
1801 else
1802 {
1803 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1804 "WLAN fragment is a clone\n");
1805 return;
1806 }
1807 }
1808 else
1809 {
1810 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1811 "WLAN fragment message_id and session message_id are not the same and a message is already (partly) received\n");
1812 return;
1813 }
1645 } 1814 }
1646 } 1815 }
1647 else 1816 else
@@ -1705,7 +1874,7 @@ wlan_process_helper (void *cls,
1705 1874
1706 else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL) 1875 else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL)
1707 { 1876 {
1708 //TODO Control 1877 //TODO more control
1709 if (ntohs(hdr->size) == 6) 1878 if (ntohs(hdr->size) == 6)
1710 { 1879 {
1711 plugin->mac_address = GNUNET_malloc(6); 1880 plugin->mac_address = GNUNET_malloc(6);
@@ -1730,6 +1899,8 @@ wlan_process_helper (void *cls,
1730 else 1899 else
1731 { 1900 {
1732 // TODO Wrong data? 1901 // TODO Wrong data?
1902 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "WLAN packet has not the right type\n");
1903 return;
1733 } 1904 }
1734} 1905}
1735 1906
@@ -1879,17 +2050,17 @@ libgnunet_plugin_transport_wlan_init (void *cls)
1879 * Exit point from the plugin. 2050 * Exit point from the plugin.
1880 */ 2051 */
1881//TODO doxigen 2052//TODO doxigen
1882//fixme cleanup 2053//FIXME cleanup
1883void * 2054void *
1884libgnunet_plugin_transport_wlan_done (void *cls) 2055libgnunet_plugin_transport_wlan_done (void *cls)
1885{ 2056{
1886 struct GNUNET_TRANSPORT_PluginFunctions *api = cls; 2057 struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
1887 struct Plugin *plugin = api->cls; 2058 struct Plugin *plugin = api->cls;
1888 2059
1889 GNUNET_SERVER_mst_destroy(plugin->consoltoken);
1890
1891 GNUNET_assert(cls !=NULL); 2060 GNUNET_assert(cls !=NULL);
1892 2061
2062 GNUNET_SERVER_mst_destroy(plugin->consoltoken);
2063
1893 GNUNET_free_non_null(plugin->mac_address); 2064 GNUNET_free_non_null(plugin->mac_address);
1894 GNUNET_free (plugin); 2065 GNUNET_free (plugin);
1895 GNUNET_free (api); 2066 GNUNET_free (api);