mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-25 04:09:31 +03:00
implement connection_cleanup.c
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
struct MHD_TLS_ConnectionState;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Callback functions to use for TLS operations.
|
||||
*/
|
||||
|
||||
@@ -59,6 +59,7 @@ libmicrohttpd_la_SOURCES = \
|
||||
action_process_upload.c \
|
||||
action_suspend.c \
|
||||
connection_add.c connection_add.h \
|
||||
connection_cleanup.c connection_cleanup.h \
|
||||
connection_close.c connection_close.h \
|
||||
connection_finish_forward.c connection_finish_forward.h \
|
||||
connection_info.c \
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
/**
|
||||
* @file lib/connection_cleanup.c
|
||||
* @brief function to clean up completed connections
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
#include "connection_cleanup.h"
|
||||
#include "daemon_ip_limit.h"
|
||||
|
||||
|
||||
#ifdef UPGRADE_SUPPORT
|
||||
/**
|
||||
* Finally cleanup upgrade-related resources. It should
|
||||
* be called when TLS buffers have been drained and
|
||||
* application signaled MHD by #MHD_UPGRADE_ACTION_CLOSE.
|
||||
*
|
||||
* @param connection handle to the upgraded connection to clean
|
||||
*/
|
||||
static void
|
||||
cleanup_upgraded_connection (struct MHD_Connection *connection)
|
||||
{
|
||||
struct MHD_UpgradeResponseHandle *urh = connection->request.urh;
|
||||
|
||||
if (NULL == urh)
|
||||
return;
|
||||
#ifdef HTTPS_SUPPORT
|
||||
/* Signal remote client the end of TLS connection by
|
||||
* gracefully closing TLS session. */
|
||||
{
|
||||
struct MHD_TLS_Plugin *tls;
|
||||
|
||||
if (NULL != (tls = connection->daemon->tls_api))
|
||||
(void) tls->shutdown_connection (tls->cls,
|
||||
connection->tls_cs);
|
||||
}
|
||||
if (MHD_INVALID_SOCKET != urh->mhd.socket)
|
||||
MHD_socket_close_chk_ (urh->mhd.socket);
|
||||
if (MHD_INVALID_SOCKET != urh->app.socket)
|
||||
MHD_socket_close_chk_ (urh->app.socket);
|
||||
#endif /* HTTPS_SUPPORT */
|
||||
connection->request.urh = NULL;
|
||||
free (urh);
|
||||
}
|
||||
#endif /* UPGRADE_SUPPORT */
|
||||
|
||||
|
||||
/**
|
||||
* Free resources associated with all closed connections. (destroy
|
||||
* responses, free buffers, etc.). All closed connections are kept in
|
||||
* the "cleanup" doubly-linked list.
|
||||
*
|
||||
* @remark To be called only from thread that process daemon's
|
||||
* select()/poll()/etc.
|
||||
*
|
||||
* @param daemon daemon to clean up
|
||||
*/
|
||||
void
|
||||
MHD_connection_cleanup_ (struct MHD_Daemon *daemon)
|
||||
{
|
||||
struct MHD_Connection *pos;
|
||||
|
||||
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
|
||||
while (NULL != (pos = daemon->cleanup_tail))
|
||||
{
|
||||
DLL_remove (daemon->cleanup_head,
|
||||
daemon->cleanup_tail,
|
||||
pos);
|
||||
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
|
||||
|
||||
if ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_model) &&
|
||||
(! pos->thread_joined) &&
|
||||
(! MHD_join_thread_ (pos->pid.handle)) )
|
||||
MHD_PANIC (_("Failed to join a thread\n"));
|
||||
#ifdef UPGRADE_SUPPORT
|
||||
cleanup_upgraded_connection (pos);
|
||||
#endif /* UPGRADE_SUPPORT */
|
||||
MHD_pool_destroy (pos->request.pool);
|
||||
#ifdef HTTPS_SUPPORT
|
||||
{
|
||||
struct MHD_TLS_Plugin *tls;
|
||||
|
||||
if (NULL != (tls = daemon->tls_api))
|
||||
tls->teardown_connection (tls->cls,
|
||||
pos->tls_cs);
|
||||
}
|
||||
#endif /* HTTPS_SUPPORT */
|
||||
|
||||
/* clean up the connection */
|
||||
if (NULL != daemon->notify_connection_cb)
|
||||
daemon->notify_connection_cb (daemon->notify_connection_cb_cls,
|
||||
pos,
|
||||
MHD_CONNECTION_NOTIFY_CLOSED);
|
||||
MHD_ip_limit_del (daemon,
|
||||
(const struct sockaddr *) &pos->addr,
|
||||
pos->addr_len);
|
||||
#ifdef EPOLL_SUPPORT
|
||||
if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
|
||||
{
|
||||
if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
|
||||
{
|
||||
EDLL_remove (daemon->eready_head,
|
||||
daemon->eready_tail,
|
||||
pos);
|
||||
pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
|
||||
}
|
||||
if ( (-1 != daemon->epoll_fd) &&
|
||||
(0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
|
||||
{
|
||||
/* epoll documentation suggests that closing a FD
|
||||
automatically removes it from the epoll set; however,
|
||||
this is not true as if we fail to do manually remove it,
|
||||
we are still seeing an event for this fd in epoll,
|
||||
causing grief (use-after-free...) --- at least on my
|
||||
system. */
|
||||
if (0 != epoll_ctl (daemon->epoll_fd,
|
||||
EPOLL_CTL_DEL,
|
||||
pos->socket_fd,
|
||||
NULL))
|
||||
MHD_PANIC (_("Failed to remove FD from epoll set\n"));
|
||||
pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (NULL != pos->request.response)
|
||||
{
|
||||
MHD_response_queue_for_destroy (pos->request.response);
|
||||
pos->request.response = NULL;
|
||||
}
|
||||
if (MHD_INVALID_SOCKET != pos->socket_fd)
|
||||
MHD_socket_close_chk_ (pos->socket_fd);
|
||||
free (pos);
|
||||
|
||||
MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
|
||||
daemon->connections--;
|
||||
daemon->at_limit = false;
|
||||
}
|
||||
MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
|
||||
}
|
||||
|
||||
/* end of connection_cleanup.c */
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
/**
|
||||
* @file lib/connection_cleanup.h
|
||||
* @brief functions to cleanup completed connection
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#ifndef CONNECTION_CLEANUP_H
|
||||
#define CONNECTION_CLEANUP_H
|
||||
|
||||
|
||||
/**
|
||||
* Free resources associated with all closed connections. (destroy
|
||||
* responses, free buffers, etc.). All closed connections are kept in
|
||||
* the "cleanup" doubly-linked list.
|
||||
*
|
||||
* @remark To be called only from thread that process daemon's
|
||||
* select()/poll()/etc.
|
||||
*
|
||||
* @param daemon daemon to clean up
|
||||
*/
|
||||
void
|
||||
MHD_connection_cleanup_ (struct MHD_Daemon *daemon)
|
||||
MHD_NONNULL (1);
|
||||
|
||||
#endif
|
||||
@@ -23,9 +23,11 @@
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
#include "connection_cleanup.h"
|
||||
#include "connection_close.h"
|
||||
#include "connection_finish_forward.h"
|
||||
#include "daemon_close_all_connections.h"
|
||||
#include "request_resume.h"
|
||||
#include "upgrade_process.h"
|
||||
|
||||
|
||||
@@ -120,7 +122,7 @@ MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon)
|
||||
if (! daemon->disallow_suspend_resume)
|
||||
{
|
||||
daemon->resuming = true; /* Force check for pending resume. */
|
||||
resume_suspended_connections (daemon);
|
||||
MHD_resume_suspended_connections_ (daemon);
|
||||
}
|
||||
/* first, make sure all threads are aware of shutdown; need to
|
||||
traverse DLLs in peace... */
|
||||
@@ -211,7 +213,7 @@ MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon)
|
||||
if (upg_allowed)
|
||||
{
|
||||
daemon->resuming = true; /* Force check for pending resume. */
|
||||
resume_suspended_connections (daemon);
|
||||
MHD_resume_suspended_connections_ (daemon);
|
||||
}
|
||||
#endif /* UPGRADE_SUPPORT */
|
||||
|
||||
@@ -223,7 +225,7 @@ MHD_daemon_close_all_connections_ (struct MHD_Daemon *daemon)
|
||||
MHD_PANIC (_("Failed to join a thread\n"));
|
||||
close_connection (pos);
|
||||
}
|
||||
MHD_cleanup_connections (daemon);
|
||||
MHD_connection_cleanup_ (daemon);
|
||||
}
|
||||
|
||||
/* end of daemon_close_all_connections.c */
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
*/
|
||||
#include "internal.h"
|
||||
#include "request_resume.h"
|
||||
#include "daemon_close_all_connections.h"
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -388,7 +388,7 @@ MHD_daemon_epoll_ (struct MHD_Daemon *daemon,
|
||||
* Do not accept more then 10 connections at once. The rest will
|
||||
* be accepted on next turn (level trigger is used for listen
|
||||
* socket). */
|
||||
while ( (MHD_YES ==
|
||||
while ( (MHD_SC_OK ==
|
||||
MHD_accept_connection_ (daemon)) &&
|
||||
(series_length < 10) &&
|
||||
(daemon->connections < daemon->global_connection_limit) &&
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
#include "connection_cleanup.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -69,7 +70,7 @@ MHD_daemon_get_information_sz (struct MHD_Daemon *daemon,
|
||||
{
|
||||
/* Assumes that MHD_run() in not called in other thread
|
||||
(of the application) at the same time. */
|
||||
MHD_cleanup_connections (daemon);
|
||||
MHD_connection_cleanup_ (daemon);
|
||||
return_value->num_connections
|
||||
= daemon->connections;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
#include "connection_cleanup.h"
|
||||
#include "daemon_epoll.h"
|
||||
#include "daemon_poll.h"
|
||||
#include "daemon_select.h"
|
||||
@@ -60,19 +61,19 @@ MHD_daemon_run (struct MHD_Daemon *daemon)
|
||||
case MHD_ELS_POLL:
|
||||
sc = MHD_daemon_poll_ (daemon,
|
||||
MHD_NO);
|
||||
MHD_cleanup_connections (daemon);
|
||||
MHD_connection_cleanup_ (daemon);
|
||||
return sc;
|
||||
#ifdef EPOLL_SUPPORT
|
||||
case MHD_ELS_EPOLL:
|
||||
sc = MHD_daemon_epoll_ (daemon,
|
||||
MHD_NO);
|
||||
MHD_cleanup_connections (daemon);
|
||||
MHD_connection_cleanup_ (daemon);
|
||||
return sc;
|
||||
#endif
|
||||
case MHD_ELS_SELECT:
|
||||
return MHD_daemon_select_ (daemon,
|
||||
MHD_NO);
|
||||
/* MHD_select does MHD_cleanup_connections already */
|
||||
/* MHD_select does MHD_connection_cleanup_ already */
|
||||
default:
|
||||
return MHD_SC_CONFIGURATION_UNEXPECTED_ELS;
|
||||
}
|
||||
|
||||
@@ -23,10 +23,13 @@
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
#include "connection_add.h"
|
||||
#include "connection_cleanup.h"
|
||||
#include "connection_finish_forward.h"
|
||||
#include "daemon_select.h"
|
||||
#include "daemon_epoll.h"
|
||||
#include "request_resume.h"
|
||||
#include "upgrade_process.h"
|
||||
#include "connection_finish_forward.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -476,7 +479,7 @@ internal_run_from_select (struct MHD_Daemon *daemon,
|
||||
}
|
||||
}
|
||||
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
|
||||
MHD_cleanup_connections (daemon);
|
||||
MHD_connection_cleanup_ (daemon);
|
||||
return MHD_SC_OK;
|
||||
}
|
||||
|
||||
@@ -492,7 +495,6 @@ void
|
||||
MHD_daemon_upgrade_connection_with_select_ (struct MHD_Connection *con)
|
||||
{
|
||||
struct MHD_UpgradeResponseHandle *urh = con->request.urh;
|
||||
struct MHD_Daemon *daemon = con->daemon;
|
||||
|
||||
while ( (0 != urh->in_buffer_size) ||
|
||||
(0 != urh->out_buffer_size) ||
|
||||
@@ -613,7 +615,7 @@ MHD_daemon_run_from_select (struct MHD_Daemon *daemon,
|
||||
|
||||
sc = MHD_daemon_epoll_ (daemon,
|
||||
MHD_NO);
|
||||
MHD_cleanup_connections (daemon);
|
||||
MHD_connection_cleanup_ (daemon);
|
||||
return sc;
|
||||
#else /* ! EPOLL_SUPPORT */
|
||||
return MHD_NO;
|
||||
@@ -651,7 +653,6 @@ MHD_daemon_select_ (struct MHD_Daemon *daemon,
|
||||
struct timeval timeout;
|
||||
struct timeval *tv;
|
||||
MHD_UNSIGNED_LONG_LONG ltimeout;
|
||||
int err_state;
|
||||
MHD_socket ls;
|
||||
enum MHD_StatusCode sc;
|
||||
enum MHD_StatusCode sc2;
|
||||
|
||||
@@ -23,8 +23,11 @@
|
||||
* @author Christian Grothoff
|
||||
*/
|
||||
#include "internal.h"
|
||||
#include "connection_cleanup.h"
|
||||
#include "daemon_close_all_connections.h"
|
||||
#include "daemon_select.h"
|
||||
#include "daemon_poll.h"
|
||||
#include "daemon_epoll.h"
|
||||
|
||||
|
||||
/**
|
||||
@@ -635,7 +638,7 @@ MHD_polling_thread (void *cls)
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
MHD_cleanup_connections (daemon);
|
||||
MHD_connection_cleanup_ (daemon);
|
||||
}
|
||||
/* Resume any pending for resume connections, join
|
||||
* all connection's threads (if any) and finally cleanup
|
||||
|
||||
@@ -207,7 +207,7 @@ MHD_tls_connection_shutdown (struct MHD_Connection *connection)
|
||||
if (MHD_TLS_CONN_WR_CLOSED > connection->tls_state)
|
||||
{
|
||||
const int res =
|
||||
gnutls_bye(connection->tls_session, GNUTLS_SHUT_WR);
|
||||
gnutls_bye (connection->tls_session, GNUTLS_SHUT_WR);
|
||||
if (GNUTLS_E_SUCCESS == res)
|
||||
{
|
||||
connection->tls_state = MHD_TLS_CONN_WR_CLOSED;
|
||||
|
||||
Reference in New Issue
Block a user