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:29:17 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2014-07-03 13:29:17 +0000
commita10ad4558026e13b5bce8d7650351f904d110b97 (patch)
tree69d124bbe98a9f43f757d3170029b24300434c7d /src/transport/plugin_transport_http_server.c
parent827d87000e5b839f2f199011c8ecd38aa62db3d0 (diff)
downloadgnunet-a10ad4558026e13b5bce8d7650351f904d110b97.tar.gz
gnunet-a10ad4558026e13b5bce8d7650351f904d110b97.zip
- fixing use after free
- renaming connections to requests
Diffstat (limited to 'src/transport/plugin_transport_http_server.c')
-rw-r--r--src/transport/plugin_transport_http_server.c117
1 files changed, 59 insertions, 58 deletions
diff --git a/src/transport/plugin_transport_http_server.c b/src/transport/plugin_transport_http_server.c
index 0db26641b..4a64559dd 100644
--- a/src/transport/plugin_transport_http_server.c
+++ b/src/transport/plugin_transport_http_server.c
@@ -57,10 +57,11 @@
57/** 57/**
58 * Information we keep with MHD for an HTTP request. 58 * Information we keep with MHD for an HTTP request.
59 */ 59 */
60struct ServerConnection 60struct ServerRequest
61{ 61{
62 /** 62 /**
63 * The session this server connection belongs to 63 * The session this server request belongs to
64 * Can be NULL, when session was disconnected and freed
64 */ 65 */
65 struct Session *session; 66 struct Session *session;
66 67
@@ -86,8 +87,8 @@ struct ServerConnection
86 int direction; 87 int direction;
87 88
88 /** 89 /**
89 * For PUT connections: Is this the first or last callback with size 0 90 * For PUT requests: Is this the first or last callback with size 0
90 * For GET connections: Have we sent a message 91 * For GET requests: Have we sent a message
91 */ 92 */
92 int connected; 93 int connected;
93 94
@@ -205,12 +206,12 @@ struct Session
205 /** 206 /**
206 * Client recv handle 207 * Client recv handle
207 */ 208 */
208 struct ServerConnection *server_recv; 209 struct ServerRequest *server_recv;
209 210
210 /** 211 /**
211 * Client send handle 212 * Client send handle
212 */ 213 */
213 struct ServerConnection *server_send; 214 struct ServerRequest *server_send;
214 215
215 /** 216 /**
216 * Address 217 * Address
@@ -407,15 +408,15 @@ struct HTTP_Server_Plugin
407 408
408 /** 409 /**
409 * Maximum number of sockets the plugin can use 410 * Maximum number of sockets the plugin can use
410 * Each http inbound /outbound connections are two connections 411 * Each http request /request connections are two connections
411 */ 412 */
412 unsigned int max_connections; 413 unsigned int max_request;
413 414
414 /** 415 /**
415 * Current number of sockets the plugin can use 416 * Current number of sockets the plugin can use
416 * Each http inbound /outbound connections are two connections 417 * Each http connection are two requests
417 */ 418 */
418 unsigned int cur_connections; 419 unsigned int cur_request;
419 420
420 /** 421 /**
421 * Did we immediately end the session in disconnect_cb 422 * Did we immediately end the session in disconnect_cb
@@ -725,7 +726,7 @@ http_server_plugin_send (void *cls,
725 char *stat_txt; 726 char *stat_txt;
726 727
727 LOG (GNUNET_ERROR_TYPE_DEBUG, 728 LOG (GNUNET_ERROR_TYPE_DEBUG,
728 "Session %p/connection %p: Sending message with %u to peer `%s'\n", 729 "Session %p/request %p: Sending message with %u to peer `%s'\n",
729 session, 730 session,
730 session->server_send, 731 session->server_send,
731 msgbuf_size, 732 msgbuf_size,
@@ -780,9 +781,9 @@ destroy_session_shutdown_cb (void *cls,
780 void *value) 781 void *value)
781{ 782{
782 struct Session *s = value; 783 struct Session *s = value;
783 struct ServerConnection *sc_send; 784 struct ServerRequest *sc_send;
784 struct ServerConnection *sc_recv; 785 struct ServerRequest *sc_recv;
785GNUNET_break (0); 786
786 sc_send = s->server_send; 787 sc_send = s->server_send;
787 sc_recv = s->server_recv; 788 sc_recv = s->server_recv;
788 server_delete_session (s); 789 server_delete_session (s);
@@ -1348,14 +1349,14 @@ session_tag_it (void *cls,
1348 * @param method PUT or GET 1349 * @param method PUT or GET
1349 * @return the server connecetion 1350 * @return the server connecetion
1350 */ 1351 */
1351static struct ServerConnection * 1352static struct ServerRequest *
1352server_lookup_connection (struct HTTP_Server_Plugin *plugin, 1353server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1353 struct MHD_Connection *mhd_connection, 1354 struct MHD_Connection *mhd_connection,
1354 const char *url, 1355 const char *url,
1355 const char *method) 1356 const char *method)
1356{ 1357{
1357 struct Session *s = NULL; 1358 struct Session *s = NULL;
1358 struct ServerConnection *sc = NULL; 1359 struct ServerRequest *sc = NULL;
1359 const union MHD_ConnectionInfo *conn_info; 1360 const union MHD_ConnectionInfo *conn_info;
1360 struct HttpAddress *addr; 1361 struct HttpAddress *addr;
1361 struct GNUNET_ATS_Information ats; 1362 struct GNUNET_ATS_Information ats;
@@ -1372,7 +1373,7 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1372 (conn_info->client_addr->sa_family != AF_INET6)) 1373 (conn_info->client_addr->sa_family != AF_INET6))
1373 return NULL; 1374 return NULL;
1374 LOG (GNUNET_ERROR_TYPE_DEBUG, 1375 LOG (GNUNET_ERROR_TYPE_DEBUG,
1375 "New %s connection from %s\n", 1376 "New %s request from %s\n",
1376 method, 1377 method,
1377 url); 1378 url);
1378 stc.tag = 0; 1379 stc.tag = 0;
@@ -1390,18 +1391,18 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1390 else 1391 else
1391 { 1392 {
1392 LOG (GNUNET_ERROR_TYPE_DEBUG, 1393 LOG (GNUNET_ERROR_TYPE_DEBUG,
1393 "Invalid method %s connection from %s\n", 1394 "Invalid method %s for request from %s\n",
1394 method, url); 1395 method, url);
1395 return NULL; 1396 return NULL;
1396 } 1397 }
1397 1398
1398 plugin->cur_connections++; 1399 plugin->cur_request++;
1399 LOG (GNUNET_ERROR_TYPE_DEBUG, 1400 LOG (GNUNET_ERROR_TYPE_DEBUG,
1400 "New %s connection from %s with tag %u (%u of %u)\n", 1401 "New %s request from %s with tag %u (%u of %u)\n",
1401 method, 1402 method,
1402 GNUNET_i2s (&target), 1403 GNUNET_i2s (&target),
1403 stc.tag, 1404 stc.tag,
1404 plugin->cur_connections, plugin->max_connections); 1405 plugin->cur_request, plugin->max_request);
1405 /* find existing session */ 1406 /* find existing session */
1406 stc.res = NULL; 1407 stc.res = NULL;
1407 GNUNET_CONTAINER_multipeermap_get_multiple (plugin->sessions, 1408 GNUNET_CONTAINER_multipeermap_get_multiple (plugin->sessions,
@@ -1473,7 +1474,7 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1473 (NULL != s->server_recv) ) 1474 (NULL != s->server_recv) )
1474 { 1475 {
1475 LOG (GNUNET_ERROR_TYPE_DEBUG, 1476 LOG (GNUNET_ERROR_TYPE_DEBUG,
1476 "Duplicate PUT connection from `%s' tag %u, dismissing new connection\n", 1477 "Duplicate PUT request from `%s' tag %u, dismissing new request\n",
1477 GNUNET_i2s (&target), 1478 GNUNET_i2s (&target),
1478 stc.tag); 1479 stc.tag);
1479 return NULL; 1480 return NULL;
@@ -1481,12 +1482,12 @@ server_lookup_connection (struct HTTP_Server_Plugin *plugin,
1481 if ((_SEND == direction) && (NULL != s->server_send)) 1482 if ((_SEND == direction) && (NULL != s->server_send))
1482 { 1483 {
1483 LOG (GNUNET_ERROR_TYPE_DEBUG, 1484 LOG (GNUNET_ERROR_TYPE_DEBUG,
1484 "Duplicate GET connection from `%s' tag %u, dismissing new connection\n", 1485 "Duplicate GET request from `%s' tag %u, dismissing new request\n",
1485 GNUNET_i2s (&target), 1486 GNUNET_i2s (&target),
1486 stc.tag); 1487 stc.tag);
1487 return NULL; 1488 return NULL;
1488 } 1489 }
1489 sc = GNUNET_new (struct ServerConnection); 1490 sc = GNUNET_new (struct ServerRequest);
1490 if (conn_info->client_addr->sa_family == AF_INET) 1491 if (conn_info->client_addr->sa_family == AF_INET)
1491 sc->mhd_daemon = plugin->server_v4; 1492 sc->mhd_daemon = plugin->server_v4;
1492 if (conn_info->client_addr->sa_family == AF_INET6) 1493 if (conn_info->client_addr->sa_family == AF_INET6)
@@ -1550,12 +1551,18 @@ server_send_callback (void *cls,
1550 char *buf, 1551 char *buf,
1551 size_t max) 1552 size_t max)
1552{ 1553{
1553 struct Session *s = cls; 1554 struct ServerRequest *sc = cls;
1554 struct ServerConnection *sc; 1555 struct Session *s = sc->session;
1555 ssize_t bytes_read = 0; 1556 ssize_t bytes_read = 0;
1556 struct HTTP_Message *msg; 1557 struct HTTP_Message *msg;
1557 char *stat_txt; 1558 char *stat_txt;
1558 1559
1560 if (NULL == s)
1561 {
1562 /* session is disconnecting */
1563 return 0;
1564 }
1565
1559 sc = s->server_send; 1566 sc = s->server_send;
1560 if (NULL == sc) 1567 if (NULL == sc)
1561 return 0; 1568 return 0;
@@ -1733,7 +1740,7 @@ server_access_cb (void *cls,
1733 void **httpSessionCache) 1740 void **httpSessionCache)
1734{ 1741{
1735 struct HTTP_Server_Plugin *plugin = cls; 1742 struct HTTP_Server_Plugin *plugin = cls;
1736 struct ServerConnection *sc = *httpSessionCache; 1743 struct ServerRequest *sc = *httpSessionCache;
1737 struct Session *s; 1744 struct Session *s;
1738 struct MHD_Response *response; 1745 struct MHD_Response *response;
1739 int res = MHD_YES; 1746 int res = MHD_YES;
@@ -1741,8 +1748,8 @@ server_access_cb (void *cls,
1741 LOG (GNUNET_ERROR_TYPE_DEBUG, 1748 LOG (GNUNET_ERROR_TYPE_DEBUG,
1742 _("Access from connection %p (%u of %u) for `%s' `%s' url `%s' with upload data size %u\n"), 1749 _("Access from connection %p (%u of %u) for `%s' `%s' url `%s' with upload data size %u\n"),
1743 sc, 1750 sc,
1744 plugin->cur_connections, 1751 plugin->cur_request,
1745 plugin->max_connections, 1752 plugin->max_request,
1746 method, 1753 method,
1747 version, 1754 version,
1748 url, 1755 url,
@@ -1753,7 +1760,7 @@ server_access_cb (void *cls,
1753 if (0 == strcmp (MHD_HTTP_METHOD_OPTIONS, method)) 1760 if (0 == strcmp (MHD_HTTP_METHOD_OPTIONS, method))
1754 { 1761 {
1755 response = MHD_create_response_from_buffer (0, NULL, 1762 response = MHD_create_response_from_buffer (0, NULL,
1756 MHD_RESPMEM_PERSISTENT); 1763 MHD_RESPMEM_PERSISTENT);
1757 add_cors_headers(response); 1764 add_cors_headers(response);
1758 res = MHD_queue_response (mhd_connection, MHD_HTTP_OK, response); 1765 res = MHD_queue_response (mhd_connection, MHD_HTTP_OK, response);
1759 MHD_destroy_response (response); 1766 MHD_destroy_response (response);
@@ -1788,8 +1795,7 @@ server_access_cb (void *cls,
1788 /* Session was already disconnected; 1795 /* Session was already disconnected;
1789 sent HTTP/1.1: 200 OK as response */ 1796 sent HTTP/1.1: 200 OK as response */
1790 response = MHD_create_response_from_data (strlen ("Thank you!"), 1797 response = MHD_create_response_from_data (strlen ("Thank you!"),
1791 "Thank you!", 1798 "Thank you!", MHD_NO, MHD_NO);
1792 MHD_NO, MHD_NO);
1793 add_cors_headers(response); 1799 add_cors_headers(response);
1794 MHD_queue_response (mhd_connection, MHD_HTTP_OK, response); 1800 MHD_queue_response (mhd_connection, MHD_HTTP_OK, response);
1795 MHD_destroy_response (response); 1801 MHD_destroy_response (response);
@@ -1798,10 +1804,8 @@ server_access_cb (void *cls,
1798 1804
1799 if (sc->direction == _SEND) 1805 if (sc->direction == _SEND)
1800 { 1806 {
1801 response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, 1807 response = MHD_create_response_from_callback (MHD_SIZE_UNKNOWN, 32 * 1024,
1802 32 * 1024, 1808 &server_send_callback, sc, NULL);
1803 &server_send_callback, s,
1804 NULL);
1805 add_cors_headers(response); 1809 add_cors_headers(response);
1806 MHD_queue_response (mhd_connection, MHD_HTTP_OK, response); 1810 MHD_queue_response (mhd_connection, MHD_HTTP_OK, response);
1807 MHD_destroy_response (response); 1811 MHD_destroy_response (response);
@@ -1835,8 +1839,7 @@ server_access_cb (void *cls,
1835 sc->connected = GNUNET_NO; 1839 sc->connected = GNUNET_NO;
1836 /* Sent HTTP/1.1: 200 OK as PUT Response\ */ 1840 /* Sent HTTP/1.1: 200 OK as PUT Response\ */
1837 response = MHD_create_response_from_data (strlen ("Thank you!"), 1841 response = MHD_create_response_from_data (strlen ("Thank you!"),
1838 "Thank you!", 1842 "Thank you!", MHD_NO, MHD_NO);
1839 MHD_NO, MHD_NO);
1840 add_cors_headers(response); 1843 add_cors_headers(response);
1841 MHD_queue_response (mhd_connection, MHD_HTTP_OK, response); 1844 MHD_queue_response (mhd_connection, MHD_HTTP_OK, response);
1842 MHD_destroy_response (response); 1845 MHD_destroy_response (response);
@@ -1865,26 +1868,24 @@ server_access_cb (void *cls,
1865 { 1868 {
1866 s->msg_tk = GNUNET_SERVER_mst_create (&server_receive_mst_cb, s); 1869 s->msg_tk = GNUNET_SERVER_mst_create (&server_receive_mst_cb, s);
1867 } 1870 }
1868 GNUNET_SERVER_mst_receive (s->msg_tk, s, upload_data, 1871 GNUNET_SERVER_mst_receive (s->msg_tk, s, upload_data, *upload_data_size,
1869 *upload_data_size, GNUNET_NO, GNUNET_NO); 1872 GNUNET_NO, GNUNET_NO);
1870 server_mhd_connection_timeout (plugin, s, 1873 server_mhd_connection_timeout (plugin, s,
1871 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value_us / 1000LL / 1000LL); 1874 GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value_us / 1000LL
1875 / 1000LL);
1872 (*upload_data_size) = 0; 1876 (*upload_data_size) = 0;
1873 } 1877 }
1874 else 1878 else
1875 { 1879 {
1876 /* delay processing */ 1880 /* delay processing */
1877 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1881 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1878 "Session %p / Connection %p: no inbound bandwidth available! Next read was delayed by %s\n", 1882 "Session %p / Connection %p: no inbound bandwidth available! Next read was delayed by %s\n",
1879 s, sc, 1883 s, sc, GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES));
1880 GNUNET_STRINGS_relative_time_to_string (delay, 1884 GNUNET_assert(s->server_recv->mhd_conn == mhd_connection);
1881 GNUNET_YES));
1882 GNUNET_assert (s->server_recv->mhd_conn == mhd_connection);
1883 MHD_suspend_connection (s->server_recv->mhd_conn); 1885 MHD_suspend_connection (s->server_recv->mhd_conn);
1884 if (GNUNET_SCHEDULER_NO_TASK == s->recv_wakeup_task) 1886 if (GNUNET_SCHEDULER_NO_TASK == s->recv_wakeup_task)
1885 s->recv_wakeup_task = GNUNET_SCHEDULER_add_delayed (delay, 1887 s->recv_wakeup_task = GNUNET_SCHEDULER_add_delayed (delay,
1886 &server_wake_up, 1888 &server_wake_up, s);
1887 s);
1888 } 1889 }
1889 return MHD_YES; 1890 return MHD_YES;
1890 } 1891 }
@@ -1911,7 +1912,7 @@ server_disconnect_cb (void *cls,
1911 void **httpSessionCache) 1912 void **httpSessionCache)
1912{ 1913{
1913 struct HTTP_Server_Plugin *plugin = cls; 1914 struct HTTP_Server_Plugin *plugin = cls;
1914 struct ServerConnection *sc = *httpSessionCache; 1915 struct ServerRequest *sc = *httpSessionCache;
1915 1916
1916 LOG (GNUNET_ERROR_TYPE_DEBUG, 1917 LOG (GNUNET_ERROR_TYPE_DEBUG,
1917 "Disconnect for connection %p\n", 1918 "Disconnect for connection %p\n",
@@ -1954,7 +1955,7 @@ server_disconnect_cb (void *cls,
1954 } 1955 }
1955 } 1956 }
1956 GNUNET_free (sc); 1957 GNUNET_free (sc);
1957 plugin->cur_connections--; 1958 plugin->cur_request--;
1958} 1959}
1959 1960
1960 1961
@@ -1973,11 +1974,11 @@ server_accept_cb (void *cls,
1973{ 1974{
1974 struct HTTP_Server_Plugin *plugin = cls; 1975 struct HTTP_Server_Plugin *plugin = cls;
1975 1976
1976 if (plugin->cur_connections <= plugin->max_connections) 1977 if (plugin->cur_request <= plugin->max_request)
1977 { 1978 {
1978 LOG (GNUNET_ERROR_TYPE_DEBUG, 1979 LOG (GNUNET_ERROR_TYPE_DEBUG,
1979 _("Accepting connection (%u of %u) from `%s'\n"), 1980 _("Accepting connection (%u of %u) from `%s'\n"),
1980 plugin->cur_connections, plugin->max_connections, 1981 plugin->cur_request, plugin->max_request,
1981 GNUNET_a2s (addr, addr_len)); 1982 GNUNET_a2s (addr, addr_len));
1982 return MHD_YES; 1983 return MHD_YES;
1983 } 1984 }
@@ -1985,7 +1986,7 @@ server_accept_cb (void *cls,
1985 { 1986 {
1986 LOG (GNUNET_ERROR_TYPE_WARNING, 1987 LOG (GNUNET_ERROR_TYPE_WARNING,
1987 _("Server reached maximum number connections (%u), rejecting new connection\n"), 1988 _("Server reached maximum number connections (%u), rejecting new connection\n"),
1988 plugin->max_connections); 1989 plugin->max_request);
1989 return MHD_NO; 1990 return MHD_NO;
1990 } 1991 }
1991} 1992}
@@ -2230,7 +2231,7 @@ server_start (struct HTTP_Server_Plugin *plugin)
2230 plugin->server_addr_v4, 2231 plugin->server_addr_v4,
2231 MHD_OPTION_CONNECTION_LIMIT, 2232 MHD_OPTION_CONNECTION_LIMIT,
2232 (unsigned int) 2233 (unsigned int)
2233 plugin->max_connections, 2234 plugin->max_request,
2234#if BUILD_HTTPS 2235#if BUILD_HTTPS
2235 MHD_OPTION_HTTPS_PRIORITIES, 2236 MHD_OPTION_HTTPS_PRIORITIES,
2236 plugin->crypto_init, 2237 plugin->crypto_init,
@@ -2279,7 +2280,7 @@ server_start (struct HTTP_Server_Plugin *plugin)
2279 plugin->server_addr_v6, 2280 plugin->server_addr_v6,
2280 MHD_OPTION_CONNECTION_LIMIT, 2281 MHD_OPTION_CONNECTION_LIMIT,
2281 (unsigned int) 2282 (unsigned int)
2282 plugin->max_connections, 2283 plugin->max_request,
2283#if BUILD_HTTPS 2284#if BUILD_HTTPS
2284 MHD_OPTION_HTTPS_PRIORITIES, 2285 MHD_OPTION_HTTPS_PRIORITIES,
2285 plugin->crypto_init, 2286 plugin->crypto_init,
@@ -3095,11 +3096,11 @@ server_configure_plugin (struct HTTP_Server_Plugin *plugin)
3095 "MAX_CONNECTIONS", 3096 "MAX_CONNECTIONS",
3096 &max_connections)) 3097 &max_connections))
3097 max_connections = 128; 3098 max_connections = 128;
3098 plugin->max_connections = max_connections; 3099 plugin->max_request = max_connections;
3099 3100
3100 LOG (GNUNET_ERROR_TYPE_DEBUG, 3101 LOG (GNUNET_ERROR_TYPE_DEBUG,
3101 _("Maximum number of connections is %u\n"), 3102 _("Maximum number of connections is %u\n"),
3102 plugin->max_connections); 3103 plugin->max_request);
3103 3104
3104 plugin->peer_id_length = strlen (GNUNET_i2s_full (plugin->env->my_identity)); 3105 plugin->peer_id_length = strlen (GNUNET_i2s_full (plugin->env->my_identity));
3105 3106