aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/libmysql_r/include/mysql/plugin_trace.h
blob: b9fb15ab2bf1e3a2fc5ea5796261616db9794356 (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
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
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
/* Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.

   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 also distributed 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 included with MySQL.

   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 PLUGIN_TRACE_INCLUDED
#define PLUGIN_TRACE_INCLUDED
/**
  @file include/mysql/plugin_trace.h

  Declarations for client-side plugins of type MYSQL_CLIENT_TRACE_PLUGIN.

  See libmysql/mysql_trace.c for a brief description of the client-side
  protocol tracing infrastructure.
*/

#include <mysql/client_plugin.h>

/*
  Lists of protocol stages and trace events
  =========================================

  These lists are defined with PROTOCOL_STAGE_LIST() and TRACE_EVENT_LIST(),
  respectively. Macros accept a disposition name as an argument.

  For example, to process list of protocol stages using disposition "foo",
  define protocol_stage_foo(Stage) macro and then put

    PROTOCOL_STAGE_LIST(foo)

  in your code. This will expand to sequence of protocol_stage_foo(X)
  macros where X ranges over the list of protocol stages, and these macros
  should generate the actual code. See below how this technique is used
  to generate protocol_stage and trace_events enums.
*/

/**
  Protocol stages
  ---------------

  A client following the MySQL protocol goes through several stages of it. Each
  stage determines what packets can be expected from the server or can be send
  by the client.

  Upon receiving each trace event, trace plugin will be notified of the current
  protocol stage so that it can correctly interpret the event.

  These are the possible protocol stages and the transitions between them.

  .. digraph:: protocol_stages

    CONNECTING -> WAIT_FOR_INIT_PACKET;
    CONNECTING -> DISCONNECTED [ label = "failed connection" ];

    WAIT_FOR_INIT_PACKET -> AUTHENTICATE;
    WAIT_FOR_INIT_PACKET -> SSL_NEGOTIATION -> AUTHENTICATE;

    AUTHENTICATE -> READY_FOR_COMMAND [ label = "accepted" ];
    AUTHENTICATE -> DISCONNECTED [ label = "rejected" ];

    READY_FOR_COMMAND -> DISCONNECTED [ label = "COM_QUIT" ];
    READY_FOR_COMMAND -> AUTHENTICATE [ label="after change user" ];
    READY_FOR_COMMAND -> WAIT_FOR_PACKET
         [ label="wait for a single packet after, e.g., COM_STATISTICS" ];
    READY_FOR_COMMAND -> WAIT_FOR_RESULT;
    READY_FOR_COMMAND -> WAIT_FOR_PS_DESCRIPTION
                                      [ label="after prepare command" ];

    WAIT_FOR_PACKET   -> READY_FOR_COMAND;

    WAIT_FOR_RESULT -> READY_FOR_COMMAND [ label="simple reply" ];
    WAIT_FOR_RESULT -> WAIT_FOR_FIELD_DEF;
    WAIT_FOR_RESULT -> FILE_REQUEST;

    WAIT_FOR_FIELD_DEF -> WAIT_FOR_ROW [ label="in a resultset" ];
    WAIT_FOR_FIELD_DEF -> READY_FOR_COMMAND
                          [ label="after describe table or prepare command" ];

    WAIT_FOR_ROW -> READY_FOR_COMMAND;
    WAIT_FOR_ROW -> WAIT_FOR_RESULT [ label="multi-resultset" ];

    WAIT_FOR_PS_DESCRIPTION -> WAIT_FOR_PARAM_DEF;
    WAIT_FOR_PS_DESCRIPTION -> READY_FOR_COMMAND
                                       [ label="no params and result" ];
    WAIT_FOR_PS_DESCRIPTION -> WAIT_FOR_FIELD_DEF [ label="no params" ];

    WAIT_FOR_PARAM_DEF -> WAIT_FOR_FIELD_DEF;
    WAIT_FOR_PARAM_DEF -> READY_FOR_COMMAND [ label="no result" ];

    FILE_REQUEST -> WAIT_FOR_RESULT [label="when whole file sent"];
*/

#define PROTOCOL_STAGE_LIST(X)                                                \
  protocol_stage_##X(CONNECTING) protocol_stage_##X(WAIT_FOR_INIT_PACKET)     \
      protocol_stage_##X(AUTHENTICATE) protocol_stage_##X(SSL_NEGOTIATION)    \
          protocol_stage_##X(READY_FOR_COMMAND)                               \
              protocol_stage_##X(WAIT_FOR_PACKET)                             \
                  protocol_stage_##X(WAIT_FOR_RESULT)                         \
                      protocol_stage_##X(WAIT_FOR_FIELD_DEF)                  \
                          protocol_stage_##X(WAIT_FOR_ROW)                    \
                              protocol_stage_##X(FILE_REQUEST)                \
                                  protocol_stage_##X(WAIT_FOR_PS_DESCRIPTION) \
                                      protocol_stage_##X(WAIT_FOR_PARAM_DEF)  \
                                          protocol_stage_##X(DISCONNECTED)

/**
  Trace events
  ------------

  The following events are generated during the various stages of the
  client-server conversation.

  ---------------------- -----------------------------------------------------
  Connection events
  ---------------------- -----------------------------------------------------
  CONNECTING             Client is connecting to the server.
  CONNECTED              Physical connection has been established.
  DISCONNECTED           Connection with server was broken.
  ---------------------- -----------------------------------------------------
  SSL events
  ---------------------- -----------------------------------------------------
  SEND_SSL_REQUEST       Client is sending SSL connection request.
  SSL_CONNECT            Client is initiating SSL handshake.
  SSL_CONNECTED          SSL connection has been established.
  ---------------------- -----------------------------------------------------
  Authentication events
  ---------------------- -----------------------------------------------------
  CHALLENGE_RECEIVED     Client received authentication challenge.
  AUTH_PLUGIN            Client selects an authentication plugin to be used
                         in the following authentication exchange.
  SEND_AUTH_RESPONSE     Client sends response to the authentication
                         challenge.
  SEND_AUTH_DATA         Client sends extra authentication data packet.
  AUTHENTICATED          Server has accepted connection.
  ---------------------- -----------------------------------------------------
  Command phase events
  ---------------------- -----------------------------------------------------
  SEND_COMMAND           Client is sending a command to the server.
  SEND_FILE              Client is sending local file contents to the server.
  ---------------------- -----------------------------------------------------
  General events
  ---------------------- -----------------------------------------------------
  READ_PACKET            Client starts waiting for a packet from server.
  PACKET_RECEIVED        A packet from server has been received.
  PACKET_SENT            After successful sending of a packet to the server.
  ERROR                  Client detected an error.
  ---------------------- -----------------------------------------------------
*/

#define TRACE_EVENT_LIST(X)                                                    \
  trace_event_##X(ERROR) trace_event_##X(CONNECTING) trace_event_##X(          \
      CONNECTED) trace_event_##X(DISCONNECTED)                                 \
      trace_event_##X(SEND_SSL_REQUEST) trace_event_##X(SSL_CONNECT)           \
          trace_event_##X(SSL_CONNECTED) trace_event_##X(INIT_PACKET_RECEIVED) \
              trace_event_##X(AUTH_PLUGIN) trace_event_##X(SEND_AUTH_RESPONSE) \
                  trace_event_##X(SEND_AUTH_DATA)                              \
                      trace_event_##X(AUTHENTICATED)                           \
                          trace_event_##X(SEND_COMMAND)                        \
                              trace_event_##X(SEND_FILE)                       \
                                  trace_event_##X(READ_PACKET)                 \
                                      trace_event_##X(PACKET_RECEIVED)         \
                                          trace_event_##X(PACKET_SENT)

/**
  Some trace events have additional arguments. These are stored in
  st_trace_event_args structure. Various events store their arguments in the
  structure as follows. Unused members are set to 0/NULL.

   AUTH_PLUGIN
  ------------- ----------------------------------
   plugin_name  the name of the plugin
  ------------- ----------------------------------

   SEND_COMMAND
  ------------- ----------------------------------
   cmd          the command code
   hdr          pointer to command packet header
   hdr_len      length of the header
   pkt          pointer to command arguments
   pkt_len      length of arguments
  ------------- ----------------------------------

   Other SEND_* and *_RECEIVED events
  ------------- ----------------------------------
   pkt          the data sent or received
   pkt_len      length of the data
  ------------- ----------------------------------

   PACKET_SENT
  ------------- ----------------------------------
   pkt_len      number of bytes sent
  ------------- ----------------------------------
*/

struct st_trace_event_args {
  const char *plugin_name;
  int cmd;
  const unsigned char *hdr;
  size_t hdr_len;
  const unsigned char *pkt;
  size_t pkt_len;
};

/* Definitions of protocol_stage and trace_event enums. */

#define protocol_stage_enum(X) PROTOCOL_STAGE_##X,

enum protocol_stage { PROTOCOL_STAGE_LIST(enum) PROTOCOL_STAGE_LAST };

#define trace_event_enum(X) TRACE_EVENT_##X,

enum trace_event { TRACE_EVENT_LIST(enum) TRACE_EVENT_LAST };

/*
  Trace plugin methods
  ====================
*/

struct st_mysql_client_plugin_TRACE;
struct MYSQL;

/**
  Trace plugin tracing_start() method.

  Called when tracing with this plugin starts on a connection. A trace
  plugin might want to maintain per-connection information. It can
  return a pointer to memory area holding such information. It will be
  stored in a connection handle and passed to other plugin methods.

  @param self   pointer to the plugin instance
  @param connection_handle Session
  @param stage  protocol stage in which tracing has started - currently
                it is always CONNECTING stage.

  @return A pointer to plugin-specific, per-connection data if any.
*/

typedef void *(tracing_start_callback)(
    struct st_mysql_client_plugin_TRACE *self, MYSQL *connection_handle,
    enum protocol_stage stage);

/**
  Trace plugin tracing_stop() method.

  Called when tracing of the connection has ended. If a plugin
  allocated any per-connection resources, it should de-allocate them
  here.

  @param self   pointer to the plugin instance
  @param connection_handle Session
  @param plugin_data pointer to plugin's per-connection data.
*/

typedef void(tracing_stop_callback)(struct st_mysql_client_plugin_TRACE *self,
                                    MYSQL *connection_handle,
                                    void *plugin_data);

/**
  Trace plugin trace_event() method.

  Called when a trace event occurs. Plugin can decide to stop tracing
  this connection by returning non-zero value.

  @param self         pointer to the plugin instance
  @param plugin_data  pointer to plugin's per-connection data
  @param connection_handle Session
  @param stage        current protocol stage
  @param event        the trace event
  @param args         trace event arguments

  @return Non-zero if tracing of the connection should end here.
*/

typedef int(trace_event_handler)(struct st_mysql_client_plugin_TRACE *self,
                                 void *plugin_data, MYSQL *connection_handle,
                                 enum protocol_stage stage,
                                 enum trace_event event,
                                 struct st_trace_event_args args);

struct st_mysql_client_plugin_TRACE {
  MYSQL_CLIENT_PLUGIN_HEADER
  tracing_start_callback *tracing_start;
  tracing_stop_callback *tracing_stop;
  trace_event_handler *trace_event;
};

/**
  The global trace_plugin pointer. If it is not NULL, it points at a
  loaded trace plugin which should be used to trace all connections made
  to the server.
*/
extern struct st_mysql_client_plugin_TRACE *trace_plugin;

#ifndef DBUG_OFF

/*
  Functions for getting names of trace events and protocol
  stages for debugging purposes.
*/
const char *protocol_stage_name(enum protocol_stage stage);
const char *trace_event_name(enum trace_event ev);

#endif

#endif