1 /*  Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
2 
3     This program is free software; you can redistribute it and/or modify
4     it under the terms of the GNU General Public License, version 2.0,
5     as published by the Free Software Foundation.
6 
7     This program is also distributed with certain software (including
8     but not limited to OpenSSL) that is licensed under separate terms,
9     as designated in a particular file or component or in included license
10     documentation.  The authors of MySQL hereby grant you an additional
11     permission to link the program and your derivative works with the
12     separately licensed software that they have included with MySQL.
13 
14     This program is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU General Public License, version 2.0, for more details.
18 
19     You should have received a copy of the GNU General Public License
20     along with this program; if not, write to the Free Software
21     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 #ifndef SRV_SESSION_H
24 #define SRV_SESSION_H
25 
26 #include <stdint.h>
27 
28 #include "lex_string.h"
29 #include "m_ctype.h"
30 #include "my_command.h"
31 #include "my_psi_config.h"
32 #include "my_thread_local.h"
33 #include "mysql/components/services/psi_statement_bits.h"
34 #include "mysql/service_command.h"
35 #include "mysql/service_srv_session.h"
36 #include "sql/protocol_callback.h"
37 #include "sql/sql_class.h"
38 #include "sql/sql_error.h"
39 #include "violite.h" /* enum_vio_type */
40 
41 struct st_plugin_int;
42 
43 /**
44   @file
45   Header file for the Srv_session class that wraps THD, DA in one bundle
46   for easy use of internal APIs.
47   Srv_session also provides means for physical thread initialization and
48   respective deinitialization.
49 */
50 
51 #ifdef HAVE_PSI_STATEMENT_INTERFACE
52 extern PSI_statement_info stmt_info_new_packet;
53 #endif
54 
55 class Srv_session {
56  public:
57   /**
58     Initializes the module.
59 
60 
61     This method has to be called at server startup.
62 
63     @return
64      false  success
65      true   failure
66   */
67   static bool module_init();
68 
69   /**
70     Deinitializes the module
71 
72 
73     This method has to be called at server shutdown.
74 
75     @return
76       false  success
77       true   failure
78   */
79   static bool module_deinit();
80 
81   /**
82     Initializes the current physical thread for use with this class.
83 
84     @param plugin Pointer to the plugin structure, passed to the plugin over
85                   the plugin init function.
86 
87     @return
88       false  success
89       true   failure
90   */
91   static bool init_thread(const void *plugin);
92 
93   /**
94     Deinitializes the current physical thread for use with session service
95   */
96   static void deinit_thread();
97 
98   /**
99     Checks if a plugin has left threads and sessions
100 
101     @param plugin  The plugin to be checked
102   */
103   static void check_for_stale_threads(const st_plugin_int *plugin);
104 
105   /**
106     Checks if the session is valid.
107 
108     Checked is if session is NULL, or in the list of opened sessions. If the
109     session is not in this list it was either closed or the address is invalid.
110 
111     @return
112       true  valid
113       false not valid
114   */
115   static bool is_valid(const Srv_session *session);
116 
117   /**
118     Returns the number opened sessions in thread initialized by this class.
119   */
120   static unsigned int session_count();
121 
122   /**
123     Returns the number currently running threads initialized by this class.
124   */
125   static unsigned int thread_count(const void *plugin_name);
126 
127   /**
128     Check if current physical thread was created to be used with this class.
129   */
130   static bool is_srv_session_thread();
131 
132   /* Non-static members follow */
133 
134   /**
135     Enum for the state of the session
136   */
137   enum srv_session_state {
138     SRV_SESSION_CREATED,
139     SRV_SESSION_OPENED,
140     SRV_SESSION_ATTACHED,
141     SRV_SESSION_DETACHED,
142     SRV_SESSION_CLOSED
143   };
144 
145   /**
146     Constructs a server session
147 
148     @param err_cb         Default completion callback
149     @param err_cb_ctx     Plugin's context, opaque pointer that would
150                           be provided to callbacks. Might be NULL.
151   */
152   Srv_session(srv_session_error_cb err_cb, void *err_cb_ctx);
153 
154   /**
155     Opens a server session
156 
157     @return
158       session  on success
159       NULL     on failure
160   */
161   bool open();
162 
163   /**
164     Attaches the session to the current physical thread
165 
166     @returns
167       false   success
168       true    failure
169   */
170   bool attach();
171 
172   /**
173     Detaches the session from current physical thread.
174 
175     @returns
176       false success
177       true  failure
178   */
179   bool detach();
180 
181   /**
182     Closes the session
183 
184     @returns
185       false Session successfully closed
186       true  Session wasn't found or key doesn't match
187   */
188   bool close();
189 
190   /**
191     Returns if the session is in attached state
192 
193     @returns
194       false   Not attached
195       true    Attached
196   */
is_attached()197   inline bool is_attached() const { return state == SRV_SESSION_ATTACHED; }
198 
199   /**
200     Executes a server command.
201 
202     @param command  Command to be executed
203     @param data     Command's arguments
204     @param client_cs  The charset for the string data input (COM_QUERY
205                       for example)
206     @param command_callbacks  Callbacks to be used by the server to encode data
207                               and to communicate with the client (plugin) side.
208     @param text_or_binary     See enum cs_text_or_binary
209     @param callbacks_context  Context passed to the callbacks
210 
211     @returns
212       1   error
213       0   success
214   */
215   int execute_command(enum enum_server_command command,
216                       const union COM_DATA *data, const CHARSET_INFO *client_cs,
217                       const struct st_command_service_cbs *command_callbacks,
218                       enum cs_text_or_binary text_or_binary,
219                       void *callbacks_context);
220 
221   /**
222     Returns the internal THD object
223   */
get_thd()224   inline THD *get_thd() { return &thd; }
225 
226   /**
227     Returns the ID of a session.
228 
229     The value returned from THD::thread_id()
230   */
get_session_id()231   my_thread_id get_session_id() const { return thd.thread_id(); }
232 
233   /**
234     Returns the client port.
235 
236     @note The client port in SHOW PROCESSLIST, INFORMATION_SCHEMA.PROCESSLIST.
237     This port is NOT shown in PERFORMANCE_SCHEMA.THREADS.
238   */
get_client_port()239   uint16_t get_client_port() const { return thd.peer_port; }
240 
241   /**
242     Sets the client port.
243 
244     @note The client port in SHOW PROCESSLIST, INFORMATION_SCHEMA.PROCESSLIST.
245     This port is NOT shown in PERFORMANCE_SCHEMA.THREADS.
246 
247     @param port  Port number
248   */
249   void set_client_port(uint16_t port);
250 
251   /**
252     Returns the current database of a session.
253 
254     @note This call is not thread-safe. Don't invoke the method from a thread
255           different than the one in which the invocation happens. This means
256           that the call should NOT happen during run_command(). The value
257           returned is valid until the next run_command() call, which may
258           change it.
259   */
get_current_database()260   LEX_CSTRING get_current_database() const { return thd.db(); }
261 
262   /**
263     Sets the connection type.
264 
265     @see enum_vio_type
266 
267     @note If NO_VIO_TYPE passed as type the call will fail.
268 
269     @return
270       false success
271       true  failure
272   */
273   bool set_connection_type(enum_vio_type type);
274 
275   struct st_err_protocol_ctx {
st_err_protocol_ctxst_err_protocol_ctx276     st_err_protocol_ctx(srv_session_error_cb h, void *h_ctx)
277         : handler(h), handler_context(h_ctx) {}
278 
279     srv_session_error_cb handler;
280     void *handler_context;
281   };
282 
283  private:
284   /**
285     Sets session's state to attached
286 
287     @param stack  New stack address
288   */
289   void set_attached(const char *stack);
290 
291   /**
292     Changes the state of a session to detached
293   */
294   void set_detached();
295 
296   THD thd;
297   Diagnostics_area da;
298   st_err_protocol_ctx err_protocol_ctx;
299   Protocol_callback protocol_error;
300 
301   srv_session_state state;
302   enum_vio_type vio_type;
303 
304   class Session_backup_and_attach {
305    public:
306     /**
307       Constructs a session state object. Saves state then attaches a session.
308       Uses RAII.
309 
310       @param sess Session to backup
311       @param is_in_close_session Wheather session needs to be closed.
312     */
313     Session_backup_and_attach(Srv_session *sess, bool is_in_close_session);
314 
315     /**
316       Destructs the session state object. In other words it restores to
317       previous state.
318     */
319     ~Session_backup_and_attach();
320 
321    private:
322     Srv_session *session;
323     Srv_session *old_session; /* used in srv_session threads */
324     THD *backup_thd;
325     bool in_close_session;
326 
327    public:
328     bool attach_error;
329   };
330 };
331 
332 #endif /* SRV_SESSION_H */
333