1 #ifndef PROTOCOL_CLASSIC_INCLUDED
2 #define PROTOCOL_CLASSIC_INCLUDED
3 
4 /* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License, version 2.0,
8    as published by the Free Software Foundation.
9 
10    This program is also distributed with certain software (including
11    but not limited to OpenSSL) that is licensed under separate terms,
12    as designated in a particular file or component or in included license
13    documentation.  The authors of MySQL hereby grant you an additional
14    permission to link the program and your derivative works with the
15    separately licensed software that they have included with MySQL.
16 
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License, version 2.0, for more details.
21 
22    You should have received a copy of the GNU General Public License
23    along with this program; if not, write to the Free Software
24    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
25 
26 #include <stddef.h>
27 #include <sys/types.h>
28 
29 #include "field_types.h"  // enum_field_types
30 #include "m_ctype.h"
31 #include "my_command.h"
32 #include "my_inttypes.h"
33 #include "my_io.h"
34 #include "mysql_com.h"
35 #include "mysql_time.h"
36 #include "sql/protocol.h"  // Protocol
37 #include "violite.h"
38 
39 class Item_param;
40 class Send_field;
41 class String;
42 class i_string;
43 class my_decimal;
44 template <class T>
45 class I_List;
46 template <class T>
47 class List;
48 union COM_DATA;
49 class THD;
50 
51 class Protocol_classic : public Protocol {
52  private:
53   ulong m_client_capabilities;
54   bool parse_packet(union COM_DATA *data, enum_server_command cmd);
55   bool net_store_data_with_conversion(const uchar *from, size_t length,
56                                       const CHARSET_INFO *fromcs,
57                                       const CHARSET_INFO *tocs);
58 
59  protected:
60   THD *m_thd;
61   String *packet;
62   String convert;
63   uint field_pos;
64   bool send_metadata;
65 #ifndef DBUG_OFF
66   enum enum_field_types *field_types;
67   uint count;
68 #endif
69   uint field_count;
70   uint sending_flags;
71   ulong input_packet_length;
72   uchar *input_raw_packet;
73   const CHARSET_INFO *result_cs;
74 
75   bool send_ok(uint server_status, uint statement_warn_count,
76                ulonglong affected_rows, ulonglong last_insert_id,
77                const char *message) override;
78 
79   bool send_eof(uint server_status, uint statement_warn_count) override;
80 
81   bool send_error(uint sql_errno, const char *err_msg,
82                   const char *sql_state) override;
83   bool store_ps_status(ulong stmt_id, uint column_count, uint param_count,
84                        ulong cond_count) override;
85 
86  public:
87   bool bad_packet;
Protocol_classic()88   Protocol_classic()
89       : send_metadata(false), input_packet_length(0), bad_packet(true) {}
Protocol_classic(THD * thd)90   Protocol_classic(THD *thd)
91       : send_metadata(false),
92         input_packet_length(0),
93         input_raw_packet(nullptr),
94         bad_packet(true) {
95     init(thd);
96   }
97   void init(THD *thd_arg);
98   bool store_field(const Field *field) final override;
99   bool store_string(const char *from, size_t length,
100                     const CHARSET_INFO *cs) final;
101   int read_packet() override;
102   int get_command(COM_DATA *com_data, enum_server_command *cmd) override;
103   /**
104     Parses the passed parameters and creates a command
105 
106     @param com_data  out parameter
107     @param cmd       in  parameter
108     @param pkt       packet to be parsed
109     @param length    size of the packet
110 
111     @retval false   ok
112     @retval true    error
113   */
114   bool create_command(COM_DATA *com_data, enum_server_command cmd, uchar *pkt,
115                       size_t length);
116   bool flush() override;
117   void end_partial_result_set() override;
118 
119   bool end_row() override;
120   uint get_rw_status() override;
121   bool get_compression() override;
122 
123   char *get_compression_algorithm() override;
124   uint get_compression_level() override;
125 
126   bool start_result_metadata(uint num_cols, uint flags,
127                              const CHARSET_INFO *resultcs) override;
128   bool end_result_metadata() override;
129   bool send_field_metadata(Send_field *field,
130                            const CHARSET_INFO *item_charset) override;
abort_row()131   void abort_row() override {}
132 
133   /**
134     Returns the type of the connection
135 
136     @return
137       enum enum_vio_type
138   */
connection_type()139   enum enum_vio_type connection_type() const override {
140     const Vio *v = get_vio();
141     return v ? vio_type(v) : NO_VIO_TYPE;
142   }
143 
144   my_socket get_socket();
145   // NET interaction functions
146   /* Initialize NET */
147   bool init_net(Vio *vio);
148   void claim_memory_ownership();
149   /* Deinitialize NET */
150   void end_net();
151   /* Write data to NET buffer */
152   bool write(const uchar *ptr, size_t len);
153   /* Return last error from NET */
154   uchar get_error();
155   /* Set max allowed packet size */
156   void set_max_packet_size(ulong max_packet_size);
157   /* Deinitialize VIO */
158   int shutdown(bool server_shutdown = false) override;
159   /* Wipe NET with zeros */
160   void wipe_net();
161   /* Check whether VIO is healhty */
162   bool connection_alive() const override;
163   /* Returns the client capabilities */
get_client_capabilities()164   ulong get_client_capabilities() override { return m_client_capabilities; }
165   /* Sets the client capabilities */
set_client_capabilities(ulong client_capabilities)166   void set_client_capabilities(ulong client_capabilities) {
167     this->m_client_capabilities = client_capabilities;
168   }
169   /* Adds  client capability */
add_client_capability(ulong client_capability)170   void add_client_capability(ulong client_capability) {
171     m_client_capabilities |= client_capability;
172   }
173   /* Removes a client capability*/
remove_client_capability(unsigned long capability)174   void remove_client_capability(unsigned long capability) {
175     m_client_capabilities &= ~capability;
176   }
177   /* Returns true if the client has the capability and false otherwise*/
has_client_capability(unsigned long client_capability)178   bool has_client_capability(unsigned long client_capability) override {
179     return (bool)(m_client_capabilities & client_capability);
180   }
181   // TODO: temporary functions. Will be removed.
182   // DON'T USE IN ANY NEW FEATURES.
183   /* Return NET */
184   NET *get_net();
185   /* return VIO */
186   Vio *get_vio();
187   const Vio *get_vio() const;
188   /* Set VIO */
189   void set_vio(Vio *vio);
190   /* Set packet number */
191   void set_output_pkt_nr(uint pkt_nr);
192   /* Return packet number */
193   uint get_output_pkt_nr();
194   /* Return packet string */
195   String *get_output_packet();
196   /* return packet length */
get_packet_length()197   ulong get_packet_length() { return input_packet_length; }
198   /* Return raw packet buffer */
get_raw_packet()199   uchar *get_raw_packet() { return input_raw_packet; }
200   /* Set read timeout */
201   virtual void set_read_timeout(ulong read_timeout);
202   /* Set write timeout */
203   virtual void set_write_timeout(ulong write_timeout);
204 
205   /**
206    * Sets the character set expected by the client. This function is for unit
207    * tests. It should usually be set by calling start_result_metadata().
208    */
set_result_character_set(const CHARSET_INFO * charset)209   void set_result_character_set(const CHARSET_INFO *charset) {
210     result_cs = charset;
211   }
212 };
213 
214 /** Class used for the old (MySQL 4.0 protocol). */
215 
216 class Protocol_text : public Protocol_classic {
217  public:
Protocol_text()218   Protocol_text() {}
Protocol_text(THD * thd_arg)219   Protocol_text(THD *thd_arg) : Protocol_classic(thd_arg) {}
220   bool store_null() override;
221   bool store_tiny(longlong from, uint32 zerofill) override;
222   bool store_short(longlong from, uint32 zerofill) override;
223   bool store_long(longlong from, uint32 zerofill) override;
224   bool store_longlong(longlong from, bool unsigned_flag,
225                       uint32 zerofill) override;
226   bool store_decimal(const my_decimal *, uint, uint) final;
227   bool store_float(float nr, uint32 decimals, uint32 zerofill) override;
228   bool store_double(double from, uint32 decimals, uint32 zerofill) override;
229   bool store_datetime(const MYSQL_TIME &time, uint precision) override;
230   bool store_date(const MYSQL_TIME &time) override;
231   bool store_time(const MYSQL_TIME &time, uint precision) override;
232   void start_row() override;
233   bool send_parameters(List<Item_param> *parameters, bool) override;
234 
type()235   enum enum_protocol_type type() const override { return PROTOCOL_TEXT; }
236 };
237 
238 class Protocol_binary final : public Protocol_text {
239  private:
240   uint bit_fields;
241 
242  public:
Protocol_binary()243   Protocol_binary() {}
Protocol_binary(THD * thd_arg)244   Protocol_binary(THD *thd_arg) : Protocol_text(thd_arg) {}
245   void start_row() override;
246   bool store_null() override;
247   bool store_tiny(longlong from, uint32 zerofill) override;
248   bool store_short(longlong from, uint32 zerofill) override;
249   bool store_long(longlong from, uint32 zerofill) override;
250   bool store_longlong(longlong from, bool unsigned_flag,
251                       uint32 zerofill) override;
252   // Decimals are sent as text, also over the binary protocol.
253   using Protocol_text::store_decimal;
254   bool store_datetime(const MYSQL_TIME &time, uint precision) override;
255   bool store_date(const MYSQL_TIME &time) override;
256   bool store_time(const MYSQL_TIME &time, uint precision) override;
257   bool store_float(float nr, uint32 decimals, uint32 zerofill) override;
258   bool store_double(double from, uint32 decimals, uint32 zerofill) override;
259 
260   bool start_result_metadata(uint num_cols, uint flags,
261                              const CHARSET_INFO *resultcs) override;
262   bool send_parameters(List<Item_param> *parameters,
263                        bool is_sql_prepare) override;
264 
type()265   enum enum_protocol_type type() const override { return PROTOCOL_BINARY; }
266 };
267 
268 bool net_send_error(THD *thd, uint sql_errno, const char *err);
269 bool net_send_error(NET *net, uint sql_errno, const char *err);
270 uchar *net_store_data(uchar *to, const uchar *from, size_t length);
271 bool store(Protocol *prot, I_List<i_string> *str_list);
272 #endif /* PROTOCOL_CLASSIC_INCLUDED */
273