File: socket_connection.h

package info (click to toggle)
mysql-8.0 8.0.44-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,272,892 kB
  • sloc: cpp: 4,685,345; ansic: 412,712; pascal: 108,395; java: 83,641; perl: 30,221; cs: 27,067; sql: 26,594; python: 21,816; sh: 17,285; yacc: 17,169; php: 11,522; xml: 7,388; javascript: 7,083; makefile: 1,793; lex: 1,075; awk: 670; asm: 520; objc: 183; ruby: 97; lisp: 86
file content (240 lines) | stat: -rw-r--r-- 8,629 bytes parent folder | download
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/*
   Copyright (c) 2013, 2025, Oracle and/or its affiliates.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License, version 2.0,
   as published by the Free Software Foundation.

   This program is designed to work with certain software (including
   but not limited to OpenSSL) that is licensed under separate terms,
   as designated in a particular file or component or in included license
   documentation.  The authors of MySQL hereby grant you an additional
   permission to link the program and your derivative works with the
   separately licensed software that they have either included with
   the program or referenced in the documentation.

   This program 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 General Public License, version 2.0, for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
*/

#ifndef SOCKET_CONNECTION_INCLUDED
#define SOCKET_CONNECTION_INCLUDED

#include "my_config.h"

#include <sys/types.h>
#include <list>
#include <map>
#include <string>
#include <vector>

#include "my_psi_config.h"
#include "mysql/components/services/bits/psi_statement_bits.h"
#include "mysql/psi/mysql_socket.h"  // MYSQL_SOCKET
#ifdef HAVE_POLL_H
#include <poll.h>
#endif

class Channel_info;

extern const char *MY_BIND_ALL_ADDRESSES;
extern const char *ipv4_all_addresses;
extern const char *ipv6_all_addresses;

#ifdef HAVE_PSI_STATEMENT_INTERFACE
extern PSI_statement_info stmt_info_new_packet;
#endif

// Enum denoting type of socket whether unix socket or tcp socket.
enum class Socket_type { UNIX_SOCKET, TCP_SOCKET };
// Enum denoting the interface which the socket listens to.
enum class Socket_interface_type { DEFAULT_INTERFACE, ADMIN_INTERFACE };
// Listen socket and it's attributes.
struct Listen_socket {
  Listen_socket(MYSQL_SOCKET socket, Socket_type socket_type)
      : m_socket(socket),
        m_socket_type(socket_type),
        m_network_namespace(nullptr),
        m_socket_interface(Socket_interface_type::DEFAULT_INTERFACE) {}
  Listen_socket(MYSQL_SOCKET socket, Socket_type socket_type,
                const std::string *network_namespace,
                Socket_interface_type socket_interface)
      : m_socket(socket),
        m_socket_type(socket_type),
        m_network_namespace(network_namespace),
        m_socket_interface(socket_interface) {}
  MYSQL_SOCKET m_socket;
  Socket_type m_socket_type;
  const std::string *m_network_namespace;
  Socket_interface_type
      m_socket_interface;  // Interface type which the socket listens for.
};

// typedef for a container holding sockets which the server is listening for
// connections.
typedef std::vector<Listen_socket> socket_vector_t;

/**
  Plain structure to collect together a host name/ip address and
  a corresponding network namespace if set and pass these information
  to different functions as a single unit.
*/
struct Bind_address_info {
  std::string address, network_namespace;
  Bind_address_info() = default;

  explicit Bind_address_info(const std::string &addr) : address(addr) {}

  Bind_address_info(const std::string &addr, const std::string &nspace)
      : address(addr), network_namespace(nspace) {}
};

/**
  This class represents the Mysqld_socket_listener which prepares the
  listener sockets to receive connection events from the client. The
  Mysqld_socket_listener may be composed of either or both a tcp socket
  which listens on a default mysqld tcp port or a user specified  port
  via mysqld command-line and a unix socket which is bound to a mysqld
  default pathname.
*/
class Mysqld_socket_listener {
  /*
    Addresses to listen to and network namespace for
    every address if set.
  */
  std::list<Bind_address_info> m_bind_addresses;
  /*
    Address to listen to an admin connection request
    and network namespace if set.
  */
  Bind_address_info m_admin_bind_address;
  uint m_tcp_port;        // TCP port to bind to
  uint m_admin_tcp_port;  // TCP port to bind to for support admin connection
  bool m_use_separate_thread_for_admin;  // use a separate thread for listening
                                         // to admin interface
  uint m_backlog;       // backlog specifying length of pending connection queue
  uint m_port_timeout;  // port timeout value
  std::string m_unix_sockname;  // unix socket pathname to bind to
  bool m_unlink_sockname;       // Unlink socket & lock file if true.
  // Container storing listen socket and their attributes.
  socket_vector_t m_socket_vector;
  MYSQL_SOCKET m_admin_interface_listen_socket;

#ifdef HAVE_POLL
  struct poll_info_t {
    std::vector<struct pollfd> m_fds;
    std::vector<MYSQL_SOCKET> m_pfs_fds;
  };
  // poll related info. used in poll for listening to connection events.
  poll_info_t m_poll_info;
#else
  struct select_info_t {
    fd_set m_read_fds, m_client_fds;
    my_socket m_max_used_connection;
    select_info_t() : m_max_used_connection(0) { FD_ZERO(&m_client_fds); }
  };
  // select info for used in select for listening to connection events.
  select_info_t m_select_info;
#endif  // HAVE_POLL

 public:
  /**
    Constructor to setup a listener for listen to connect events from
    clients.

    @param   bind_addresses  list of addresses to listen to
    @param   tcp_port        TCP port to bind to
    @param   admin_bind_addr address to listen admin connection
    @param   admin_tcp_port  TCP port for admin connection to bind
    @param   use_separate_thread_for_admin  Listen to connection requests
                             on admin interface in a separate thread
    @param   backlog         backlog specifying length of pending
                             connection queue used in listen.
    @param   port_timeout    portname.
    @param   unix_sockname   pathname for unix socket to bind to
  */
  Mysqld_socket_listener(const std::list<Bind_address_info> &bind_addresses,
                         uint tcp_port,
                         const Bind_address_info &admin_bind_addr,
                         uint admin_tcp_port,
                         bool use_separate_thread_for_admin, uint backlog,
                         uint port_timeout, std::string unix_sockname);

  /**
    Set up a listener - set of sockets to listen for connection events
    from clients.

    In case a server is started with the option
    use_separate_thread_for_admin=true invocation of this method also spawns a
    thread to handle incoming connection requests on admin interface.

    @retval false  listener sockets setup to be used to listen for connect
    events true   failure in setting up the listener.
  */
  bool setup_listener();

  /**
    The body of the event loop that listen for connection events from clients.

    @retval Channel_info   Channel_info object abstracting the connected client
                           details for processing this connection.
  */
  Channel_info *listen_for_connection_event();

  /**
    Close the listener.

    In case a server is started with the option
    use_separate_thread_for_admin=true this method also shutdowns a thread for
    handling of incoming connection requests on admin interface and joins it.
  */
  void close_listener();

  ~Mysqld_socket_listener() {
    if (!m_socket_vector.empty()) close_listener();
  }

  /**
    Spawn admin connection handler thread if separate thread is required to
    accept admin connections.

    @return true unable to spawn admin connect handler thread else false
  */
  bool check_and_spawn_admin_connection_handler_thread() const;

 private:
  /**
    Add a socket to a set of sockets being waiting for a new
    connection request.

    @param listen_socket  Socket to listen for.
  */
  void add_socket_to_listener(MYSQL_SOCKET listen_socket);

  /**
    Get a socket ready to accept incoming connection.
    @return A socket ready to accept a new incoming connection.
  */
  const Listen_socket *get_listen_socket() const;

  /**
    Set up connection events for poll or select.

    @param socket_vector  sockets to listen for connection requests.
  */
  void setup_connection_events(const socket_vector_t &socket_vector);
};

ulong get_connection_errors_query_block();

ulong get_connection_errors_accept();

ulong get_connection_errors_tcpwrap();

#endif  // SOCKET_CONNECTION_INCLUDED.