diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2014-07-03 13:08:31 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2014-07-03 13:08:31 +0000 |
commit | a52c9a050ee291f77d0ac7a4b5d9e2367d9f1b5c (patch) | |
tree | fc01308a34cee8a8ddbb2b3df0f43a32167cd4bf /src/transport/plugin_transport_http_server.c | |
parent | ef09d3299be6b1586959a98cfb0313e25d4859ba (diff) | |
download | gnunet-a52c9a050ee291f77d0ac7a4b5d9e2367d9f1b5c.tar.gz gnunet-a52c9a050ee291f77d0ac7a4b5d9e2367d9f1b5c.zip |
fixing memory leak and session disconnect
Diffstat (limited to 'src/transport/plugin_transport_http_server.c')
-rw-r--r-- | src/transport/plugin_transport_http_server.c | 123 |
1 files changed, 77 insertions, 46 deletions
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c index f6c64e602..0db26641b 100644 --- a/src/transport/plugin_transport_http_server.c +++ b/src/transport/plugin_transport_http_server.c | |||
@@ -532,8 +532,6 @@ server_delete_session (struct Session *s) | |||
532 | { | 532 | { |
533 | struct HTTP_Server_Plugin *plugin = s->plugin; | 533 | struct HTTP_Server_Plugin *plugin = s->plugin; |
534 | struct HTTP_Message *msg; | 534 | struct HTTP_Message *msg; |
535 | struct ServerConnection *send; | ||
536 | struct ServerConnection *recv; | ||
537 | 535 | ||
538 | if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task) | 536 | if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task) |
539 | { | 537 | { |
@@ -569,36 +567,33 @@ server_delete_session (struct Session *s) | |||
569 | s->bytes_in_queue -= msg->size; | 567 | s->bytes_in_queue -= msg->size; |
570 | GNUNET_free (msg); | 568 | GNUNET_free (msg); |
571 | } | 569 | } |
570 | |||
572 | GNUNET_assert (0 == s->msgs_in_queue); | 571 | GNUNET_assert (0 == s->msgs_in_queue); |
573 | GNUNET_assert (0 == s->bytes_in_queue); | 572 | GNUNET_assert (0 == s->bytes_in_queue); |
574 | send = s->server_send; | 573 | |
575 | if (NULL != send) | 574 | if (NULL != s->server_send) |
576 | { | 575 | { |
577 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 576 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
578 | "Server: %p / %p Terminating inbound PUT session to peer `%s'\n", | 577 | "Server: %p / %p Terminating inbound PUT session to peer `%s'\n", |
579 | s, send, | 578 | s, s->server_send, |
580 | GNUNET_i2s (&s->target)); | 579 | GNUNET_i2s (&s->target)); |
581 | send->session = NULL; | 580 | s->server_send->session = NULL; |
582 | MHD_set_connection_option (send->mhd_conn, | 581 | MHD_set_connection_option (s->server_send->mhd_conn, |
583 | MHD_CONNECTION_OPTION_TIMEOUT, | 582 | MHD_CONNECTION_OPTION_TIMEOUT, |
584 | 1 /* 0 = no timeout, so this is MIN */); | 583 | 1 /* 0 = no timeout, so this is MIN */); |
585 | server_reschedule (plugin, | 584 | server_reschedule (plugin, s->server_send->mhd_daemon, GNUNET_YES); |
586 | send->mhd_daemon, | ||
587 | GNUNET_YES); | ||
588 | } | 585 | } |
589 | recv = s->server_recv; | 586 | |
590 | if (NULL != recv) | 587 | if (NULL != s->server_recv) |
591 | { | 588 | { |
592 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 589 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
593 | "Server: %p / %p Terminating inbound GET session to peer `%s'\n", | 590 | "Server: %p / %p Terminating inbound GET session to peer `%s'\n", |
594 | s, recv, GNUNET_i2s (&s->target)); | 591 | s, s->server_recv, GNUNET_i2s (&s->target)); |
595 | recv->session = NULL; | 592 | s->server_recv->session = NULL; |
596 | MHD_set_connection_option (recv->mhd_conn, | 593 | MHD_set_connection_option (s->server_recv->mhd_conn, |
597 | MHD_CONNECTION_OPTION_TIMEOUT, | 594 | MHD_CONNECTION_OPTION_TIMEOUT, |
598 | 1 /* 0 = no timeout, so this is MIN */); | 595 | 1 /* 0 = no timeout, so this is MIN */); |
599 | server_reschedule (plugin, | 596 | server_reschedule (plugin, s->server_recv->mhd_daemon, GNUNET_YES); |
600 | recv->mhd_daemon, | ||
601 | GNUNET_YES); | ||
602 | } | 597 | } |
603 | notify_session_monitor (plugin, | 598 | notify_session_monitor (plugin, |
604 | s, | 599 | s, |
@@ -616,6 +611,7 @@ server_delete_session (struct Session *s) | |||
616 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 611 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
617 | "Session %p destroyed\n", | 612 | "Session %p destroyed\n", |
618 | s); | 613 | s); |
614 | |||
619 | GNUNET_free (s); | 615 | GNUNET_free (s); |
620 | } | 616 | } |
621 | 617 | ||
@@ -771,6 +767,33 @@ http_server_plugin_send (void *cls, | |||
771 | 767 | ||
772 | 768 | ||
773 | /** | 769 | /** |
770 | * Terminate session during shutdown. | ||
771 | * | ||
772 | * @param cls the `struct HTTP_Server_Plugin *` | ||
773 | * @param peer for which this is a session | ||
774 | * @param value the `struct Session` to clean up | ||
775 | * @return #GNUNET_OK (continue to iterate) | ||
776 | */ | ||
777 | static int | ||
778 | destroy_session_shutdown_cb (void *cls, | ||
779 | const struct GNUNET_PeerIdentity *peer, | ||
780 | void *value) | ||
781 | { | ||
782 | struct Session *s = value; | ||
783 | struct ServerConnection *sc_send; | ||
784 | struct ServerConnection *sc_recv; | ||
785 | GNUNET_break (0); | ||
786 | sc_send = s->server_send; | ||
787 | sc_recv = s->server_recv; | ||
788 | server_delete_session (s); | ||
789 | |||
790 | GNUNET_free (sc_send); | ||
791 | GNUNET_free (sc_recv); | ||
792 | |||
793 | return GNUNET_OK; | ||
794 | } | ||
795 | |||
796 | /** | ||
774 | * Terminate session. | 797 | * Terminate session. |
775 | * | 798 | * |
776 | * @param cls the `struct HTTP_Server_Plugin *` | 799 | * @param cls the `struct HTTP_Server_Plugin *` |
@@ -789,7 +812,6 @@ destroy_session_cb (void *cls, | |||
789 | return GNUNET_OK; | 812 | return GNUNET_OK; |
790 | } | 813 | } |
791 | 814 | ||
792 | |||
793 | /** | 815 | /** |
794 | * Function that can be used to force the plugin to disconnect | 816 | * Function that can be used to force the plugin to disconnect |
795 | * from the given peer and cancel all previous transmissions | 817 | * from the given peer and cancel all previous transmissions |
@@ -1475,9 +1497,13 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin, | |||
1475 | sc->session = s; | 1497 | sc->session = s; |
1476 | sc->options = options; | 1498 | sc->options = options; |
1477 | if (direction == _SEND) | 1499 | if (direction == _SEND) |
1500 | { | ||
1478 | s->server_send = sc; | 1501 | s->server_send = sc; |
1502 | } | ||
1479 | if (direction == _RECEIVE) | 1503 | if (direction == _RECEIVE) |
1504 | { | ||
1480 | s->server_recv = sc; | 1505 | s->server_recv = sc; |
1506 | } | ||
1481 | 1507 | ||
1482 | if ((GNUNET_NO == s->known_to_service) && | 1508 | if ((GNUNET_NO == s->known_to_service) && |
1483 | (NULL != s->server_send) && | 1509 | (NULL != s->server_send) && |
@@ -1886,40 +1912,45 @@ server_disconnect_cb (void *cls, | |||
1886 | { | 1912 | { |
1887 | struct HTTP_Server_Plugin *plugin = cls; | 1913 | struct HTTP_Server_Plugin *plugin = cls; |
1888 | struct ServerConnection *sc = *httpSessionCache; | 1914 | struct ServerConnection *sc = *httpSessionCache; |
1889 | struct Session *s; | ||
1890 | 1915 | ||
1891 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1916 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1892 | "Disconnect for connection %p\n", | 1917 | "Disconnect for connection %p\n", |
1893 | sc); | 1918 | sc); |
1894 | if (NULL == sc) | 1919 | if (NULL == sc) |
1895 | return; /* never really got setup */ | ||
1896 | if (NULL == (s = sc->session)) | ||
1897 | return; /* session already dead */ | ||
1898 | if (sc->direction == _SEND) | ||
1899 | { | 1920 | { |
1900 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1921 | GNUNET_break (0); |
1901 | "Peer `%s' connection %p, GET on address `%s' disconnected\n", | 1922 | return; /* never really got setup */ |
1902 | GNUNET_i2s (&s->target), | ||
1903 | s->server_send, | ||
1904 | http_common_plugin_address_to_string (plugin->protocol, | ||
1905 | s->address->address, | ||
1906 | s->address->address_length)); | ||
1907 | s->server_send = NULL; | ||
1908 | } | 1923 | } |
1909 | else if (sc->direction == _RECEIVE) | 1924 | |
1925 | if (NULL != sc->session) | ||
1910 | { | 1926 | { |
1911 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1927 | if (sc->direction == _SEND) |
1912 | "Peer `%s' connection %p PUT on address `%s' disconnected\n", | 1928 | { |
1913 | GNUNET_i2s (&s->target), | 1929 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1914 | s->server_recv, | 1930 | "Peer `%s' connection %p, GET on address `%s' disconnected\n", |
1915 | http_common_plugin_address_to_string (plugin->protocol, | 1931 | GNUNET_i2s (&sc->session->target), |
1916 | s->address->address, | 1932 | sc->session->server_send, |
1917 | s->address->address_length)); | 1933 | http_common_plugin_address_to_string (plugin->protocol, |
1918 | s->server_recv = NULL; | 1934 | sc->session->address->address, |
1919 | if (NULL != s->msg_tk) | 1935 | sc->session->address->address_length)); |
1936 | |||
1937 | sc->session->server_send = NULL; | ||
1938 | } | ||
1939 | else if (sc->direction == _RECEIVE) | ||
1920 | { | 1940 | { |
1921 | GNUNET_SERVER_mst_destroy (s->msg_tk); | 1941 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1922 | s->msg_tk = NULL; | 1942 | "Peer `%s' connection %p PUT on address `%s' disconnected\n", |
1943 | GNUNET_i2s (&sc->session->target), | ||
1944 | sc->session->server_recv, | ||
1945 | http_common_plugin_address_to_string (plugin->protocol, | ||
1946 | sc->session->address->address, | ||
1947 | sc->session->address->address_length)); | ||
1948 | sc->session->server_recv = NULL; | ||
1949 | if (NULL != sc->session->msg_tk) | ||
1950 | { | ||
1951 | GNUNET_SERVER_mst_destroy (sc->session->msg_tk); | ||
1952 | sc->session->msg_tk = NULL; | ||
1953 | } | ||
1923 | } | 1954 | } |
1924 | } | 1955 | } |
1925 | GNUNET_free (sc); | 1956 | GNUNET_free (sc); |
@@ -3095,7 +3126,7 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) | |||
3095 | return NULL; | 3126 | return NULL; |
3096 | } | 3127 | } |
3097 | plugin->in_shutdown = GNUNET_YES; | 3128 | plugin->in_shutdown = GNUNET_YES; |
3098 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 3129 | LOG (GNUNET_ERROR_TYPE_INFO, |
3099 | _("Shutting down plugin `%s'\n"), | 3130 | _("Shutting down plugin `%s'\n"), |
3100 | plugin->name); | 3131 | plugin->name); |
3101 | 3132 | ||
@@ -3154,7 +3185,7 @@ LIBGNUNET_PLUGIN_TRANSPORT_DONE (void *cls) | |||
3154 | GNUNET_free_non_null (plugin->key); | 3185 | GNUNET_free_non_null (plugin->key); |
3155 | #endif | 3186 | #endif |
3156 | GNUNET_CONTAINER_multipeermap_iterate (plugin->sessions, | 3187 | GNUNET_CONTAINER_multipeermap_iterate (plugin->sessions, |
3157 | &destroy_session_cb, | 3188 | &destroy_session_shutdown_cb, |
3158 | plugin); | 3189 | plugin); |
3159 | GNUNET_CONTAINER_multipeermap_destroy (plugin->sessions); | 3190 | GNUNET_CONTAINER_multipeermap_destroy (plugin->sessions); |
3160 | plugin->sessions = NULL; | 3191 | plugin->sessions = NULL; |