/*
  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
connection_cleanup_upgraded (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_mode) &&
         (! pos->thread_joined) &&
         (! MHD_join_thread_ (pos->pid.handle)) )
      MHD_PANIC (_ ("Failed to join a thread.\n"));
#ifdef UPGRADE_SUPPORT
    connection_cleanup_upgraded (pos);
#endif /* UPGRADE_SUPPORT */
    MHD_pool_destroy (pos->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 */
