aboutsummaryrefslogtreecommitdiff
path: root/src/lib/connection_finish_forward.c
blob: aac49f8c1babb3891c7669feb07bd77c24d18f0c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*
  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_model)
    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 */