1 /*
2   +----------------------------------------------------------------------+
3   | PHP Version 5                                                        |
4   +----------------------------------------------------------------------+
5   | Copyright (c) 2006-2013 The PHP Group                                |
6   +----------------------------------------------------------------------+
7   | This source file is subject to version 3.01 of the PHP license,      |
8   | that is bundled with this package in the file LICENSE, and is        |
9   | available through the world-wide-web at the following url:           |
10   | http://www.php.net/license/3_01.txt                                  |
11   | If you did not receive a copy of the PHP license and are unable to   |
12   | obtain it through the world-wide-web, please send a note to          |
13   | license@php.net so we can mail you a copy immediately.               |
14   +----------------------------------------------------------------------+
15   | Authors: Georg Richter <georg@mysql.com>                             |
16   |          Andrey Hristov <andrey@mysql.com>                           |
17   |          Ulf Wendel <uwendel@mysql.com>                              |
18   +----------------------------------------------------------------------+
19 */
20 
21 /* $Id$ */
22 
23 #ifndef MYSQLND_WIREPROTOCOL_H
24 #define MYSQLND_WIREPROTOCOL_H
25 
26 #include "mysqlnd_net.h"
27 
28 #define MYSQLND_HEADER_SIZE 4
29 #define COMPRESSED_HEADER_SIZE 3
30 
31 #define MYSQLND_NULL_LENGTH	(unsigned long) ~0
32 
33 /* Used in mysqlnd_debug.c */
34 PHPAPI extern const char mysqlnd_read_header_name[];
35 PHPAPI extern const char mysqlnd_read_body_name[];
36 
37 
38 /* Packet handling */
39 #define PACKET_WRITE(packet, conn)	((packet)->header.m->write_to_net((packet), (conn) TSRMLS_CC))
40 #define PACKET_READ(packet, conn)	((packet)->header.m->read_from_net((packet), (conn) TSRMLS_CC))
41 #define PACKET_FREE(packet) \
42 	do { \
43 		DBG_INF_FMT("PACKET_FREE(%p)", packet); \
44 		if ((packet)) { \
45 			((packet)->header.m->free_mem((packet), FALSE TSRMLS_CC)); \
46 		} \
47 	} while (0);
48 
49 PHPAPI extern const char * const mysqlnd_command_to_text[COM_END];
50 
51 /* Low-level extraction functionality */
52 typedef struct st_mysqlnd_packet_methods {
53 	size_t				struct_size;
54 	enum_func_status	(*read_from_net)(void *packet, MYSQLND *conn TSRMLS_DC);
55 	size_t				(*write_to_net)(void *packet, MYSQLND *conn TSRMLS_DC);
56 	void				(*free_mem)(void *packet, zend_bool stack_allocation TSRMLS_DC);
57 } mysqlnd_packet_methods;
58 
59 
60 typedef struct st_mysqlnd_packet_header {
61 	size_t		size;
62 	mysqlnd_packet_methods *m;
63 	zend_uchar	packet_no;
64 	zend_bool	persistent;
65 } MYSQLND_PACKET_HEADER;
66 
67 /* Server greets the client */
68 typedef struct st_mysqlnd_packet_greet {
69 	MYSQLND_PACKET_HEADER		header;
70 	uint8_t		protocol_version;
71 	char		*server_version;
72 	uint32_t	thread_id;
73 	zend_uchar	scramble_buf[SCRAMBLE_LENGTH];
74 	/* 1 byte pad */
75 	uint16_t	server_capabilities;
76 	uint8_t		charset_no;
77 	uint16_t	server_status;
78 	/* 13 byte pad*/
79 	zend_bool	pre41;
80 	/* If error packet, we use these */
81 	char 		error[MYSQLND_ERRMSG_SIZE+1];
82 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
83 	unsigned int 	error_no;
84 } MYSQLND_PACKET_GREET;
85 
86 
87 /* Client authenticates */
88 typedef struct st_mysqlnd_packet_auth {
89 	MYSQLND_PACKET_HEADER		header;
90 	uint32_t	client_flags;
91 	uint32_t	max_packet_size;
92 	uint8_t	charset_no;
93 	/* 23 byte pad */
94 	const char	*user;
95 	/* 8 byte scramble */
96 	const char	*db;
97 	/* 12 byte scramble */
98 
99 	/* Here the packet ends. This is user supplied data */
100 	const char	*password;
101 	/* +1 for \0 because of scramble() */
102 	unsigned char	*server_scramble_buf;
103 	size_t			db_len;
104 	zend_bool		send_half_packet;
105 } MYSQLND_PACKET_AUTH;
106 
107 /* OK packet */
108 typedef struct st_mysqlnd_packet_ok {
109 	MYSQLND_PACKET_HEADER		header;
110 	uint8_t		field_count; /* always 0x0 */
111 	uint64_t	affected_rows;
112 	uint64_t	last_insert_id;
113 	uint16_t	server_status;
114 	uint16_t	warning_count;
115 	char		*message;
116 	size_t		message_len;
117 	/* If error packet, we use these */
118 	char 		error[MYSQLND_ERRMSG_SIZE+1];
119 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
120 	unsigned int 	error_no;
121 } MYSQLND_PACKET_OK;
122 
123 
124 /* Command packet */
125 typedef struct st_mysqlnd_packet_command {
126 	MYSQLND_PACKET_HEADER			header;
127 	enum php_mysqlnd_server_command	command;
128 	const char						*argument;
129 	size_t							arg_len;
130 } MYSQLND_PACKET_COMMAND;
131 
132 
133 /* EOF packet */
134 typedef struct st_mysqlnd_packet_eof {
135 	MYSQLND_PACKET_HEADER		header;
136 	uint8_t		field_count; /* 0xFE */
137 	uint16_t	warning_count;
138 	uint16_t	server_status;
139 	/* If error packet, we use these */
140 	char 		error[MYSQLND_ERRMSG_SIZE+1];
141 	char 		sqlstate[MYSQLND_SQLSTATE_LENGTH + 1];
142 	unsigned int 	error_no;
143 } MYSQLND_PACKET_EOF;
144 /* EOF packet */
145 
146 
147 /* Result Set header*/
148 typedef struct st_mysqlnd_packet_rset_header {
149 	MYSQLND_PACKET_HEADER		header;
150 	/*
151 	  0x00 => ok
152 	  ~0   => LOAD DATA LOCAL
153 	  error_no != 0 => error
154 	  others => result set -> Read res_field packets up to field_count
155 	*/
156 	unsigned long		field_count;
157 	/*
158 	  These are filled if no SELECT query. For SELECT warning_count
159 	  and server status are in the last row packet, the EOF packet.
160 	*/
161 	uint16_t	warning_count;
162 	uint16_t	server_status;
163 	uint64_t	affected_rows;
164 	uint64_t	last_insert_id;
165 	/* This is for both LOAD DATA or info, when no result set */
166 	char		*info_or_local_file;
167 	size_t		info_or_local_file_len;
168 	/* If error packet, we use these */
169 	MYSQLND_ERROR_INFO	error_info;
170 } MYSQLND_PACKET_RSET_HEADER;
171 
172 
173 /* Result set field packet */
174 typedef struct st_mysqlnd_packet_res_field {
175 	MYSQLND_PACKET_HEADER	header;
176 	MYSQLND_FIELD			*metadata;
177 	/* For table definitions, empty for result sets */
178 	zend_bool				skip_parsing;
179 	zend_bool				stupid_list_fields_eof;
180 	zend_bool				persistent_alloc;
181 
182 	MYSQLND_ERROR_INFO		error_info;
183 } MYSQLND_PACKET_RES_FIELD;
184 
185 
186 /* Row packet */
187 typedef struct st_mysqlnd_packet_row {
188 	MYSQLND_PACKET_HEADER	header;
189 	zval		**fields;
190 	uint32_t	field_count;
191 	zend_bool	eof;
192 	/*
193 	  These are, of course, only for SELECT in the EOF packet,
194 	  which is detected by this packet
195 	*/
196 	uint16_t	warning_count;
197 	uint16_t	server_status;
198 
199 	struct st_mysqlnd_memory_pool_chunk	*row_buffer;
200 	MYSQLND_MEMORY_POOL * result_set_memory_pool;
201 
202 	zend_bool		skip_extraction;
203 	zend_bool		binary_protocol;
204 	zend_bool		persistent_alloc;
205 	MYSQLND_FIELD	*fields_metadata;
206 	/* We need this to alloc bigger bufs in non-PS mode */
207 	unsigned int	bit_fields_count;
208 	size_t			bit_fields_total_len; /* trailing \0 not counted */
209 
210 	/* If error packet, we use these */
211 	MYSQLND_ERROR_INFO	error_info;
212 } MYSQLND_PACKET_ROW;
213 
214 
215 /* Statistics packet */
216 typedef struct st_mysqlnd_packet_stats {
217 	MYSQLND_PACKET_HEADER	header;
218 	char *message;
219 	/* message_len is not part of the packet*/
220 	size_t message_len;
221 } MYSQLND_PACKET_STATS;
222 
223 
224 /* COM_PREPARE response packet */
225 typedef struct st_mysqlnd_packet_prepare_response {
226 	MYSQLND_PACKET_HEADER	header;
227 	/* also known as field_count 0x00=OK , 0xFF=error */
228 	unsigned char	error_code;
229 	unsigned long	stmt_id;
230 	unsigned int	field_count;
231 	unsigned int	param_count;
232 	unsigned int	warning_count;
233 
234 	/* present in case of error */
235 	MYSQLND_ERROR_INFO	error_info;
236 } MYSQLND_PACKET_PREPARE_RESPONSE;
237 
238 
239 /* Statistics packet */
240 typedef struct st_mysqlnd_packet_chg_user_resp {
241 	MYSQLND_PACKET_HEADER	header;
242 	uint32_t			field_count;
243 
244 	/* message_len is not part of the packet*/
245 	uint16_t			server_capabilities;
246 	/* If error packet, we use these */
247 	MYSQLND_ERROR_INFO	error_info;
248 	zend_bool			server_asked_323_auth;
249 } MYSQLND_PACKET_CHG_USER_RESPONSE;
250 
251 
252 PHPAPI void php_mysqlnd_scramble(zend_uchar * const buffer, const zend_uchar * const scramble, const zend_uchar * const pass);
253 
254 unsigned long	php_mysqlnd_net_field_length(zend_uchar **packet);
255 zend_uchar *	php_mysqlnd_net_store_length(zend_uchar *packet, uint64_t length);
256 
257 PHPAPI const extern char * const mysqlnd_empty_string;
258 
259 
260 enum_func_status php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
261 										 unsigned int field_count, MYSQLND_FIELD *fields_metadata,
262 										 zend_bool persistent,
263 										 zend_bool as_unicode, zend_bool as_int_or_float,
264 										 MYSQLND_STATS * stats TSRMLS_DC);
265 
266 
267 enum_func_status php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
268 										 unsigned int field_count, MYSQLND_FIELD *fields_metadata,
269 										 zend_bool persistent,
270 										 zend_bool as_unicode, zend_bool as_int_or_float,
271 										 MYSQLND_STATS * stats TSRMLS_DC);
272 
273 
274 PHPAPI MYSQLND_PROTOCOL * mysqlnd_protocol_init(zend_bool persistent TSRMLS_DC);
275 PHPAPI void mysqlnd_protocol_free(MYSQLND_PROTOCOL * const protocol TSRMLS_DC);
276 PHPAPI struct st_mysqlnd_protocol_methods * mysqlnd_protocol_get_methods();
277 
278 #endif /* MYSQLND_WIREPROTOCOL_H */
279 
280 /*
281  * Local variables:
282  * tab-width: 4
283  * c-basic-offset: 4
284  * End:
285  * vim600: noet sw=4 ts=4 fdm=marker
286  * vim<600: noet sw=4 ts=4
287  */
288