aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_http_server.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2014-07-03 13:08:31 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2014-07-03 13:08:31 +0000
commita52c9a050ee291f77d0ac7a4b5d9e2367d9f1b5c (patch)
treefc01308a34cee8a8ddbb2b3df0f43a32167cd4bf /src/transport/plugin_transport_http_server.c
parentef09d3299be6b1586959a98cfb0313e25d4859ba (diff)
downloadgnunet-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.c123
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 */
777static int
778destroy_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;
785GNUNET_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;