blob: 74b5b48f62fdcda5d3dde13015c3a4cca54ea5d0 [file] [log] [blame]
/*
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_finish_forward.c
* @brief complete upgrade socket forwarding operation in TLS mode
* @author Christian Grothoff
*/
#include "internal.h"
#include "connection_finish_forward.h"
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
/**
* Stop TLS forwarding on upgraded connection and
* reflect remote disconnect state to socketpair.
* @remark In thread-per-connection mode this function
* can be called from any thread, in other modes this
* function must be called only from thread that process
* daemon's select()/poll()/etc.
*
* @param connection the upgraded connection
*/
void
MHD_connection_finish_forward_ (struct MHD_Connection *connection)
{
struct MHD_Daemon *daemon = connection->daemon;
struct MHD_UpgradeResponseHandle *urh = connection->request.urh;
if (NULL == daemon->tls_api)
return; /* Nothing to do with non-TLS connection. */
if (MHD_TM_THREAD_PER_CONNECTION != daemon->threading_mode)
DLL_remove (daemon->urh_head,
daemon->urh_tail,
urh);
#if EPOLL_SUPPORT
if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
(0 != epoll_ctl (daemon->epoll_upgrade_fd,
EPOLL_CTL_DEL,
connection->socket_fd,
NULL)) )
{
MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
}
if (urh->in_eready_list)
{
EDLL_remove (daemon->eready_urh_head,
daemon->eready_urh_tail,
urh);
urh->in_eready_list = false;
}
#endif /* EPOLL_SUPPORT */
if (MHD_INVALID_SOCKET != urh->mhd.socket)
{
#if EPOLL_SUPPORT
if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
(0 != epoll_ctl (daemon->epoll_upgrade_fd,
EPOLL_CTL_DEL,
urh->mhd.socket,
NULL)) )
{
MHD_PANIC (_ ("Failed to remove FD from epoll set.\n"));
}
#endif /* EPOLL_SUPPORT */
/* Reflect remote disconnect to application by breaking
* socketpair connection. */
shutdown (urh->mhd.socket,
SHUT_RDWR);
}
/* Socketpair sockets will remain open as they will be
* used with MHD_UPGRADE_ACTION_CLOSE. They will be
* closed by MHD_cleanup_upgraded_connection_() during
* connection's final cleanup.
*/}
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT*/
/* end of connection_finish_forward.c */