GNU libmicrohttpd 0.9.77
Loading...
Searching...
No Matches
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
37static void
38connection_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
77void
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 */
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 */
void MHD_connection_cleanup_(struct MHD_Daemon *daemon)
functions to cleanup completed connection
void MHD_ip_limit_del(struct MHD_Daemon *daemon, const struct sockaddr *addr, socklen_t addrlen)
counting of connections per IP
@ MHD_CONNECTION_NOTIFY_CLOSED
void MHD_response_queue_for_destroy(struct MHD_Response *response)
Definition response.c:88
@ MHD_EPOLL_STATE_IN_EREADY_EDLL
Definition internal.h:611
@ MHD_EPOLL_STATE_IN_EPOLL_SET
Definition internal.h:616
#define MHD_PANIC(msg)
Definition internal.h:69
#define EDLL_remove(head, tail, element)
Definition internal.h:1847
#define DLL_remove(head, tail, element)
Definition internal.h:1763
void MHD_pool_destroy(struct MemoryPool *pool)
Definition memorypool.c:157
#define MHD_mutex_unlock_chk_(pmutex)
Definition mhd_locks.h:180
#define MHD_mutex_lock_chk_(pmutex)
Definition mhd_locks.h:154
#define MHD_socket_close_chk_(fd)
#define NULL
#define _(String)
Definition mhd_options.h:42
MHD internal shared structures.
#define MHD_INVALID_SOCKET
Definition microhttpd.h:208
MHD_socket socket_fd
Definition internal.h:752
socklen_t addr_len
Definition internal.h:733
struct MHD_Request request
Definition internal.h:717
struct sockaddr_storage addr
Definition internal.h:728
struct MemoryPool * pool
Definition internal.h:685
MHD_thread_handle_ID_ pid
Definition internal.h:723
struct MHD_Daemon * daemon
Definition internal.h:675
bool thread_joined
Definition internal.h:779
bool at_limit
Definition internal.h:1483
MHD_mutex_ cleanup_connection_mutex
Definition internal.h:1265
MHD_NotifyConnectionCallback notify_connection_cb
Definition internal.h:1047
void * notify_connection_cb_cls
Definition internal.h:1052
unsigned int connections
Definition internal.h:1361
enum MHD_EventLoopSyscall event_loop_syscall
Definition internal.h:1436
struct MHD_Connection * cleanup_tail
Definition internal.h:1182
struct MHD_Connection * cleanup_head
Definition internal.h:1177
enum MHD_ThreadingMode threading_mode
Definition internal.h:1417
struct MHD_Response * response
Definition internal.h:383
enum MHD_Bool(* shutdown_connection)(void *cls, struct MHD_TLS_ConnectionState *cs)
void(* teardown_connection)(void *cls, struct MHD_TLS_ConnectionState *cs)