GNU libmicrohttpd  0.9.69
connection_cleanup.c
Go to the documentation of this file.
1 /*
2  This file is part of libmicrohttpd
3  Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
24 #include "internal.h"
25 #include "connection_cleanup.h"
26 #include "daemon_ip_limit.h"
27 
28 
29 #ifdef UPGRADE_SUPPORT
30 
37 static void
38 connection_cleanup_upgraded (struct MHD_Connection *connection)
39 {
40  struct MHD_UpgradeResponseHandle *urh = connection->request.urh;
41 
42  if (NULL == urh)
43  return;
44 #ifdef HTTPS_SUPPORT
45  /* Signal remote client the end of TLS connection by
46  * gracefully closing TLS session. */
47  {
48  struct MHD_TLS_Plugin *tls;
49 
50  if (NULL != (tls = connection->daemon->tls_api))
51  (void) tls->shutdown_connection (tls->cls,
52  connection->tls_cs);
53  }
54  if (MHD_INVALID_SOCKET != urh->mhd.socket)
55  MHD_socket_close_chk_ (urh->mhd.socket);
56  if (MHD_INVALID_SOCKET != urh->app.socket)
57  MHD_socket_close_chk_ (urh->app.socket);
58 #endif /* HTTPS_SUPPORT */
59  connection->request.urh = NULL;
60  free (urh);
61 }
62 
63 
64 #endif /* UPGRADE_SUPPORT */
65 
66 
77 void
79 {
80  struct MHD_Connection *pos;
81 
83  while (NULL != (pos = daemon->cleanup_tail))
84  {
87  pos);
89 
90  if ( (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_mode) &&
91  (! pos->thread_joined) &&
92  (! MHD_join_thread_ (pos->pid.handle)) )
93  MHD_PANIC (_ ("Failed to join a thread\n"));
94 #ifdef UPGRADE_SUPPORT
95  connection_cleanup_upgraded (pos);
96 #endif /* UPGRADE_SUPPORT */
97  MHD_pool_destroy (pos->pool);
98 #ifdef HTTPS_SUPPORT
99  {
100  struct MHD_TLS_Plugin *tls;
101 
102  if (NULL != (tls = daemon->tls_api))
103  tls->teardown_connection (tls->cls,
104  pos->tls_cs);
105  }
106 #endif /* HTTPS_SUPPORT */
107 
108  /* clean up the connection */
109  if (NULL != daemon->notify_connection_cb)
111  pos,
113  MHD_ip_limit_del (daemon,
114  (const struct sockaddr *) &pos->addr,
115  pos->addr_len);
116 #ifdef EPOLL_SUPPORT
117  if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
118  {
119  if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
120  {
121  EDLL_remove (daemon->eready_head,
122  daemon->eready_tail,
123  pos);
124  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
125  }
126  if ( (-1 != daemon->epoll_fd) &&
127  (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
128  {
129  /* epoll documentation suggests that closing a FD
130  automatically removes it from the epoll set; however,
131  this is not true as if we fail to do manually remove it,
132  we are still seeing an event for this fd in epoll,
133  causing grief (use-after-free...) --- at least on my
134  system. */if (0 != epoll_ctl (daemon->epoll_fd,
135  EPOLL_CTL_DEL,
136  pos->socket_fd,
137  NULL))
138  MHD_PANIC (_ ("Failed to remove FD from epoll set\n"));
139  pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
140  }
141  }
142 #endif
143  if (NULL != pos->request.response)
144  {
146  pos->request.response = NULL;
147  }
148  if (MHD_INVALID_SOCKET != pos->socket_fd)
150  free (pos);
151 
153  daemon->connections--;
154  daemon->at_limit = false;
155  }
157 }
158 
159 
160 /* end of connection_cleanup.c */
_
#define _(String)
Definition: mhd_options.h:42
MHD_socket_close_chk_
#define MHD_socket_close_chk_(fd)
Definition: mhd_sockets.h:248
MHD_mutex_unlock_chk_
#define MHD_mutex_unlock_chk_(pmutex)
Definition: mhd_locks.h:180
MHD_Daemon::cleanup_tail
struct MHD_Connection * cleanup_tail
Definition: internal.h:1182
MHD_Daemon::connections
unsigned int connections
Definition: internal.h:1361
internal.h
internal shared structures
MHD_INVALID_SOCKET
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:188
MHD_Connection::pool
struct MemoryPool * pool
Definition: internal.h:685
NULL
#define NULL
Definition: reason_phrase.c:30
MHD_Daemon::event_loop_syscall
enum MHD_EventLoopSyscall event_loop_syscall
Definition: internal.h:1436
MHD_Daemon::at_limit
bool at_limit
Definition: internal.h:1483
MHD_EPOLL_STATE_IN_EPOLL_SET
Definition: internal.h:616
MHD_Connection::thread_joined
bool thread_joined
Definition: internal.h:779
EDLL_remove
#define EDLL_remove(head, tail, element)
Definition: internal.h:1847
MHD_TLS_Plugin
Definition: microhttpd_tls.h:52
MHD_Daemon::notify_connection_cb_cls
void * notify_connection_cb_cls
Definition: internal.h:1052
MHD_Connection::request
struct MHD_Request request
Definition: internal.h:717
MHD_Connection::addr
struct sockaddr_storage addr
Definition: internal.h:728
DLL_remove
#define DLL_remove(head, tail, element)
Definition: internal.h:1763
MHD_Daemon::threading_mode
enum MHD_ThreadingMode threading_mode
Definition: internal.h:1417
MHD_pool_destroy
void MHD_pool_destroy(struct MemoryPool *pool)
Definition: memorypool.c:157
MHD_Daemon::cleanup_connection_mutex
MHD_mutex_ cleanup_connection_mutex
Definition: internal.h:1265
connection_cleanup.h
functions to cleanup completed connection
MHD_Connection::addr_len
socklen_t addr_len
Definition: internal.h:733
MHD_Daemon
Definition: internal.h:1000
MHD_connection_cleanup_
void MHD_connection_cleanup_(struct MHD_Daemon *daemon)
Definition: connection_cleanup.c:78
MHD_TLS_Plugin::shutdown_connection
enum MHD_Bool(* shutdown_connection)(void *cls, struct MHD_TLS_ConnectionState *cs)
Definition: microhttpd_tls.h:159
MHD_ip_limit_del
void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
Definition: daemon_ip_limit.c:255
MHD_Daemon::cleanup_head
struct MHD_Connection * cleanup_head
Definition: internal.h:1177
MHD_mutex_lock_chk_
#define MHD_mutex_lock_chk_(pmutex)
Definition: mhd_locks.h:154
MHD_Connection::daemon
struct MHD_Daemon * daemon
Definition: internal.h:675
MHD_TLS_Plugin::cls
void * cls
Definition: microhttpd_tls.h:57
MHD_Connection::pid
MHD_thread_handle_ID_ pid
Definition: internal.h:723
MHD_Connection
Definition: internal.h:633
MHD_Request::response
struct MHD_Response * response
Definition: internal.h:383
MHD_PANIC
#define MHD_PANIC(msg)
Definition: internal.h:69
MHD_Daemon::notify_connection_cb
MHD_NotifyConnectionCallback notify_connection_cb
Definition: internal.h:1047
MHD_response_queue_for_destroy
void MHD_response_queue_for_destroy(struct MHD_Response *response)
Definition: response.c:88
MHD_EPOLL_STATE_IN_EREADY_EDLL
Definition: internal.h:611
daemon_ip_limit.h
counting of connections per IP
MHD_CONNECTION_NOTIFY_CLOSED
Definition: microhttpd.h:1879
MHD_Connection::socket_fd
MHD_socket socket_fd
Definition: internal.h:752
MHD_TLS_Plugin::teardown_connection
void(* teardown_connection)(void *cls, struct MHD_TLS_ConnectionState *cs)
Definition: microhttpd_tls.h:164