/* 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 */