diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2013-07-15 09:22:28 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2013-07-15 09:22:28 +0000 |
commit | a85848d1c6686713c0c977868eba2d5fe4fa322f (patch) | |
tree | 9d3b14d3dc43e669492eff0e842708d182c15cf6 /src | |
parent | 3b1199eb8f4a3319a13d34878a956f16c66a5b19 (diff) | |
download | gnunet-a85848d1c6686713c0c977868eba2d5fe4fa322f.tar.gz gnunet-a85848d1c6686713c0c977868eba2d5fe4fa322f.zip |
while running transport: valgrind showed memory leak due to not removed resolution processes
storing pretty printer requests and removing them after timeout
Diffstat (limited to 'src')
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 84 | ||||
-rw-r--r-- | src/transport/plugin_transport_udp.c | 85 |
2 files changed, 166 insertions, 3 deletions
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index b124fc618..be1076ea1 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -1564,10 +1564,40 @@ tcp_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) | |||
1564 | 1564 | ||
1565 | 1565 | ||
1566 | /** | 1566 | /** |
1567 | * Running pretty printers: head | ||
1568 | */ | ||
1569 | static struct PrettyPrinterContext *ppc_dll_head; | ||
1570 | |||
1571 | /** | ||
1572 | * Running pretty printers: tail | ||
1573 | */ | ||
1574 | static struct PrettyPrinterContext *ppc_dll_tail; | ||
1575 | |||
1576 | /** | ||
1567 | * Context for address to string conversion. | 1577 | * Context for address to string conversion. |
1568 | */ | 1578 | */ |
1569 | struct PrettyPrinterContext | 1579 | struct PrettyPrinterContext |
1570 | { | 1580 | { |
1581 | /** | ||
1582 | * DLL | ||
1583 | */ | ||
1584 | struct PrettyPrinterContext *next; | ||
1585 | |||
1586 | /** | ||
1587 | * DLL | ||
1588 | */ | ||
1589 | struct PrettyPrinterContext *prev; | ||
1590 | |||
1591 | /** | ||
1592 | * Timeout task | ||
1593 | */ | ||
1594 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; | ||
1595 | |||
1596 | /** | ||
1597 | * Resolver handle | ||
1598 | */ | ||
1599 | struct GNUNET_RESOLVER_RequestHandle *resolver_handle; | ||
1600 | |||
1571 | /** | 1601 | /** |
1572 | * Function to call with the result. | 1602 | * Function to call with the result. |
1573 | */ | 1603 | */ |
@@ -1595,6 +1625,23 @@ struct PrettyPrinterContext | |||
1595 | }; | 1625 | }; |
1596 | 1626 | ||
1597 | 1627 | ||
1628 | void | ||
1629 | ppc_cancel_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1630 | { | ||
1631 | struct PrettyPrinterContext *ppc = cls; | ||
1632 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "PPC %p was not removed!\n", ppc); | ||
1633 | ppc->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
1634 | if (NULL != ppc->resolver_handle) | ||
1635 | { | ||
1636 | GNUNET_RESOLVER_request_cancel (ppc->resolver_handle); | ||
1637 | ppc->resolver_handle = NULL; | ||
1638 | } | ||
1639 | |||
1640 | GNUNET_CONTAINER_DLL_remove (ppc_dll_head, ppc_dll_tail, ppc); | ||
1641 | GNUNET_free (ppc); | ||
1642 | } | ||
1643 | |||
1644 | |||
1598 | /** | 1645 | /** |
1599 | * Append our port and forward the result. | 1646 | * Append our port and forward the result. |
1600 | * | 1647 | * |
@@ -1605,14 +1652,31 @@ static void | |||
1605 | append_port (void *cls, const char *hostname) | 1652 | append_port (void *cls, const char *hostname) |
1606 | { | 1653 | { |
1607 | struct PrettyPrinterContext *ppc = cls; | 1654 | struct PrettyPrinterContext *ppc = cls; |
1655 | struct PrettyPrinterContext *cur; | ||
1608 | char *ret; | 1656 | char *ret; |
1609 | 1657 | ||
1610 | if (hostname == NULL) | 1658 | if (hostname == NULL) |
1611 | { | 1659 | { |
1612 | ppc->asc (ppc->asc_cls, NULL); | 1660 | ppc->asc (ppc->asc_cls, NULL); |
1661 | GNUNET_CONTAINER_DLL_remove (ppc_dll_head, ppc_dll_tail, ppc); | ||
1662 | GNUNET_SCHEDULER_cancel (ppc->timeout_task); | ||
1663 | ppc->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
1664 | ppc->resolver_handle = NULL; | ||
1665 | /* GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "PPC %p was removed!\n", ppc); */ | ||
1613 | GNUNET_free (ppc); | 1666 | GNUNET_free (ppc); |
1614 | return; | 1667 | return; |
1615 | } | 1668 | } |
1669 | for (cur = ppc_dll_head; (NULL != cur); cur = cur->next) | ||
1670 | { | ||
1671 | if (cur == ppc) | ||
1672 | break; | ||
1673 | } | ||
1674 | if (NULL == cur) | ||
1675 | { | ||
1676 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid callback for PPC %p \n", ppc); | ||
1677 | return; | ||
1678 | } | ||
1679 | |||
1616 | if (GNUNET_YES == ppc->ipv6) | 1680 | if (GNUNET_YES == ppc->ipv6) |
1617 | GNUNET_asprintf (&ret, "%s.%u.[%s]:%d", PLUGIN_NAME, ppc->options, hostname, ppc->port); | 1681 | GNUNET_asprintf (&ret, "%s.%u.[%s]:%d", PLUGIN_NAME, ppc->options, hostname, ppc->port); |
1618 | else | 1682 | else |
@@ -1702,7 +1766,12 @@ tcp_plugin_address_pretty_printer (void *cls, const char *type, | |||
1702 | ppc->asc_cls = asc_cls; | 1766 | ppc->asc_cls = asc_cls; |
1703 | ppc->port = port; | 1767 | ppc->port = port; |
1704 | ppc->options = options; | 1768 | ppc->options = options; |
1705 | GNUNET_RESOLVER_hostname_get (sb, sbs, !numeric, timeout, &append_port, ppc); | 1769 | ppc->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(timeout, 2), |
1770 | &ppc_cancel_task, ppc); | ||
1771 | GNUNET_CONTAINER_DLL_insert (ppc_dll_head, ppc_dll_tail, ppc); | ||
1772 | /* GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "PPC %p was created!\n", ppc); */ | ||
1773 | ppc->resolver_handle = GNUNET_RESOLVER_hostname_get (sb, sbs, !numeric, | ||
1774 | timeout, &append_port, ppc); | ||
1706 | } | 1775 | } |
1707 | 1776 | ||
1708 | 1777 | ||
@@ -2599,6 +2668,8 @@ libgnunet_plugin_transport_tcp_done (void *cls) | |||
2599 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | 2668 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; |
2600 | struct Plugin *plugin = api->cls; | 2669 | struct Plugin *plugin = api->cls; |
2601 | struct TCPProbeContext *tcp_probe; | 2670 | struct TCPProbeContext *tcp_probe; |
2671 | struct PrettyPrinterContext *cur; | ||
2672 | struct PrettyPrinterContext *next; | ||
2602 | 2673 | ||
2603 | if (NULL == plugin) | 2674 | if (NULL == plugin) |
2604 | { | 2675 | { |
@@ -2612,6 +2683,17 @@ libgnunet_plugin_transport_tcp_done (void *cls) | |||
2612 | /* Removing leftover NAT sessions */ | 2683 | /* Removing leftover NAT sessions */ |
2613 | GNUNET_CONTAINER_multihashmap_iterate(plugin->nat_wait_conns, &session_disconnect_it, NULL); | 2684 | GNUNET_CONTAINER_multihashmap_iterate(plugin->nat_wait_conns, &session_disconnect_it, NULL); |
2614 | 2685 | ||
2686 | next = ppc_dll_head; | ||
2687 | for (cur = next; NULL != cur; cur = next) | ||
2688 | { | ||
2689 | next = cur->next; | ||
2690 | GNUNET_CONTAINER_DLL_remove (ppc_dll_head, ppc_dll_tail, cur); | ||
2691 | GNUNET_RESOLVER_request_cancel (cur->resolver_handle); | ||
2692 | GNUNET_SCHEDULER_cancel (cur->timeout_task); | ||
2693 | GNUNET_free (cur); | ||
2694 | GNUNET_break (0); | ||
2695 | } | ||
2696 | |||
2615 | if (plugin->service != NULL) | 2697 | if (plugin->service != NULL) |
2616 | GNUNET_SERVICE_stop (plugin->service); | 2698 | GNUNET_SERVICE_stop (plugin->service); |
2617 | else | 2699 | else |
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index 4d74e272e..46ea48d82 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c | |||
@@ -64,10 +64,40 @@ | |||
64 | #define UDP_MAX_SENDER_ADDRESSES_WITH_DEFRAG 128 | 64 | #define UDP_MAX_SENDER_ADDRESSES_WITH_DEFRAG 128 |
65 | 65 | ||
66 | /** | 66 | /** |
67 | * Running pretty printers: head | ||
68 | */ | ||
69 | static struct PrettyPrinterContext *ppc_dll_head; | ||
70 | |||
71 | /** | ||
72 | * Running pretty printers: tail | ||
73 | */ | ||
74 | static struct PrettyPrinterContext *ppc_dll_tail; | ||
75 | |||
76 | /** | ||
67 | * Closure for 'append_port'. | 77 | * Closure for 'append_port'. |
68 | */ | 78 | */ |
69 | struct PrettyPrinterContext | 79 | struct PrettyPrinterContext |
70 | { | 80 | { |
81 | /** | ||
82 | * DLL | ||
83 | */ | ||
84 | struct PrettyPrinterContext *next; | ||
85 | |||
86 | /** | ||
87 | * DLL | ||
88 | */ | ||
89 | struct PrettyPrinterContext *prev; | ||
90 | |||
91 | /** | ||
92 | * Timeout task | ||
93 | */ | ||
94 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; | ||
95 | |||
96 | /** | ||
97 | * Resolver handle | ||
98 | */ | ||
99 | struct GNUNET_RESOLVER_RequestHandle *resolver_handle; | ||
100 | |||
71 | /** | 101 | /** |
72 | * Function to call with the result. | 102 | * Function to call with the result. |
73 | */ | 103 | */ |
@@ -672,6 +702,23 @@ udp_string_to_address (void *cls, const char *addr, uint16_t addrlen, | |||
672 | } | 702 | } |
673 | 703 | ||
674 | 704 | ||
705 | void | ||
706 | ppc_cancel_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
707 | { | ||
708 | struct PrettyPrinterContext *ppc = cls; | ||
709 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PPC %p was not removed!\n", ppc); | ||
710 | ppc->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
711 | if (NULL != ppc->resolver_handle) | ||
712 | { | ||
713 | GNUNET_RESOLVER_request_cancel (ppc->resolver_handle); | ||
714 | ppc->resolver_handle = NULL; | ||
715 | } | ||
716 | |||
717 | GNUNET_CONTAINER_DLL_remove (ppc_dll_head, ppc_dll_tail, ppc); | ||
718 | GNUNET_free (ppc); | ||
719 | } | ||
720 | |||
721 | |||
675 | /** | 722 | /** |
676 | * Append our port and forward the result. | 723 | * Append our port and forward the result. |
677 | * | 724 | * |
@@ -682,14 +729,31 @@ static void | |||
682 | append_port (void *cls, const char *hostname) | 729 | append_port (void *cls, const char *hostname) |
683 | { | 730 | { |
684 | struct PrettyPrinterContext *ppc = cls; | 731 | struct PrettyPrinterContext *ppc = cls; |
732 | struct PrettyPrinterContext *cur; | ||
685 | char *ret; | 733 | char *ret; |
686 | 734 | ||
687 | if (hostname == NULL) | 735 | if (hostname == NULL) |
688 | { | 736 | { |
689 | ppc->asc (ppc->asc_cls, NULL); | 737 | ppc->asc (ppc->asc_cls, NULL); |
738 | GNUNET_CONTAINER_DLL_remove (ppc_dll_head, ppc_dll_tail, ppc); | ||
739 | GNUNET_SCHEDULER_cancel (ppc->timeout_task); | ||
740 | ppc->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
741 | ppc->resolver_handle = NULL; | ||
742 | /* GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "PPC %p was removed!\n", ppc); */ | ||
690 | GNUNET_free (ppc); | 743 | GNUNET_free (ppc); |
691 | return; | 744 | return; |
692 | } | 745 | } |
746 | for (cur = ppc_dll_head; (NULL != cur); cur = cur->next) | ||
747 | { | ||
748 | if (cur == ppc) | ||
749 | break; | ||
750 | } | ||
751 | if (NULL == cur) | ||
752 | { | ||
753 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Invalid callback for PPC %p \n", ppc); | ||
754 | return; | ||
755 | } | ||
756 | |||
693 | if (GNUNET_YES == ppc->ipv6) | 757 | if (GNUNET_YES == ppc->ipv6) |
694 | GNUNET_asprintf (&ret, "%s.%u.[%s]:%d", PLUGIN_NAME, ppc->options, hostname, ppc->port); | 758 | GNUNET_asprintf (&ret, "%s.%u.[%s]:%d", PLUGIN_NAME, ppc->options, hostname, ppc->port); |
695 | else | 759 | else |
@@ -698,7 +762,6 @@ append_port (void *cls, const char *hostname) | |||
698 | GNUNET_free (ret); | 762 | GNUNET_free (ret); |
699 | } | 763 | } |
700 | 764 | ||
701 | |||
702 | /** | 765 | /** |
703 | * Convert the transports address to a nice, human-readable | 766 | * Convert the transports address to a nice, human-readable |
704 | * format. | 767 | * format. |
@@ -784,7 +847,12 @@ udp_plugin_address_pretty_printer (void *cls, const char *type, | |||
784 | ppc->ipv6 = GNUNET_YES; | 847 | ppc->ipv6 = GNUNET_YES; |
785 | else | 848 | else |
786 | ppc->ipv6 = GNUNET_NO; | 849 | ppc->ipv6 = GNUNET_NO; |
787 | GNUNET_RESOLVER_hostname_get (sb, sbs, !numeric, timeout, &append_port, ppc); | 850 | ppc->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(timeout, 2), |
851 | &ppc_cancel_task, ppc); | ||
852 | GNUNET_CONTAINER_DLL_insert (ppc_dll_head, ppc_dll_tail, ppc); | ||
853 | /* GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "PPC %p was created!\n", ppc); */ | ||
854 | ppc->resolver_handle = GNUNET_RESOLVER_hostname_get (sb, sbs, !numeric, timeout, &append_port, ppc); | ||
855 | |||
788 | } | 856 | } |
789 | 857 | ||
790 | 858 | ||
@@ -3083,6 +3151,8 @@ libgnunet_plugin_transport_udp_done (void *cls) | |||
3083 | { | 3151 | { |
3084 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | 3152 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; |
3085 | struct Plugin *plugin = api->cls; | 3153 | struct Plugin *plugin = api->cls; |
3154 | struct PrettyPrinterContext *cur; | ||
3155 | struct PrettyPrinterContext *next; | ||
3086 | 3156 | ||
3087 | if (NULL == plugin) | 3157 | if (NULL == plugin) |
3088 | { | 3158 | { |
@@ -3169,6 +3239,17 @@ libgnunet_plugin_transport_udp_done (void *cls) | |||
3169 | GNUNET_CONTAINER_multihashmap_iterate (plugin->sessions, &disconnect_and_free_it, plugin); | 3239 | GNUNET_CONTAINER_multihashmap_iterate (plugin->sessions, &disconnect_and_free_it, plugin); |
3170 | GNUNET_CONTAINER_multihashmap_destroy (plugin->sessions); | 3240 | GNUNET_CONTAINER_multihashmap_destroy (plugin->sessions); |
3171 | 3241 | ||
3242 | next = ppc_dll_head; | ||
3243 | for (cur = next; NULL != cur; cur = next) | ||
3244 | { | ||
3245 | next = cur->next; | ||
3246 | GNUNET_CONTAINER_DLL_remove (ppc_dll_head, ppc_dll_tail, cur); | ||
3247 | GNUNET_RESOLVER_request_cancel (cur->resolver_handle); | ||
3248 | GNUNET_SCHEDULER_cancel (cur->timeout_task); | ||
3249 | GNUNET_free (cur); | ||
3250 | GNUNET_break (0); | ||
3251 | } | ||
3252 | |||
3172 | plugin->nat = NULL; | 3253 | plugin->nat = NULL; |
3173 | GNUNET_free (plugin); | 3254 | GNUNET_free (plugin); |
3174 | GNUNET_free (api); | 3255 | GNUNET_free (api); |