1 /* 2 +----------------------------------------------------------------------+ 3 | PHP Version 5 | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 2006-2014 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: Andrey Hristov <andrey@mysql.com> | 16 | Ulf Wendel <uwendel@mysql.com> | 17 | Georg Richter <georg@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_DATA * conn TSRMLS_DC); 55 size_t (*write_to_net)(void * packet, MYSQLND_CONN_DATA * 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 intern_auth_plugin_data[SCRAMBLE_LENGTH]; 74 zend_uchar * auth_plugin_data; 75 size_t auth_plugin_data_len; 76 /* 1 byte pad */ 77 uint32_t server_capabilities; 78 uint8_t charset_no; 79 uint16_t server_status; 80 /* 13 byte pad, in 5.5 first 2 bytes are more capabilities followed by 1 byte scramble_length */ 81 zend_bool pre41; 82 /* If error packet, we use these */ 83 char error[MYSQLND_ERRMSG_SIZE+1]; 84 char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1]; 85 unsigned int error_no; 86 char *auth_protocol; 87 } MYSQLND_PACKET_GREET; 88 89 90 /* Client authenticates */ 91 typedef struct st_mysqlnd_packet_auth { 92 MYSQLND_PACKET_HEADER header; 93 uint32_t client_flags; 94 uint32_t max_packet_size; 95 uint8_t charset_no; 96 const char *user; 97 const zend_uchar *auth_data; 98 size_t auth_data_len; 99 const char *db; 100 const char *auth_plugin_name; 101 /* Here the packet ends. This is user supplied data */ 102 size_t db_len; 103 zend_bool send_auth_data; 104 zend_bool is_change_user_packet; 105 zend_bool silent; 106 107 } MYSQLND_PACKET_AUTH; 108 109 /* Auth response packet */ 110 typedef struct st_mysqlnd_packet_auth_response { 111 MYSQLND_PACKET_HEADER header; 112 uint8_t response_code; 113 uint64_t affected_rows; 114 uint64_t last_insert_id; 115 uint16_t server_status; 116 uint16_t warning_count; 117 char *message; 118 size_t message_len; 119 /* If error packet, we use these */ 120 char error[MYSQLND_ERRMSG_SIZE+1]; 121 char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1]; 122 unsigned int error_no; 123 124 char *new_auth_protocol; 125 size_t new_auth_protocol_len; 126 zend_uchar *new_auth_protocol_data; 127 size_t new_auth_protocol_data_len; 128 } MYSQLND_PACKET_AUTH_RESPONSE; 129 130 131 /* Auth response packet */ 132 typedef struct st_mysqlnd_packet_change_auth_response { 133 MYSQLND_PACKET_HEADER header; 134 const zend_uchar *auth_data; 135 size_t auth_data_len; 136 } MYSQLND_PACKET_CHANGE_AUTH_RESPONSE; 137 138 139 /* OK packet */ 140 typedef struct st_mysqlnd_packet_ok { 141 MYSQLND_PACKET_HEADER header; 142 uint8_t field_count; /* always 0x0 */ 143 uint64_t affected_rows; 144 uint64_t last_insert_id; 145 uint16_t server_status; 146 uint16_t warning_count; 147 char *message; 148 size_t message_len; 149 /* If error packet, we use these */ 150 char error[MYSQLND_ERRMSG_SIZE+1]; 151 char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1]; 152 unsigned int error_no; 153 } MYSQLND_PACKET_OK; 154 155 156 /* Command packet */ 157 typedef struct st_mysqlnd_packet_command { 158 MYSQLND_PACKET_HEADER header; 159 enum php_mysqlnd_server_command command; 160 const zend_uchar *argument; 161 size_t arg_len; 162 } MYSQLND_PACKET_COMMAND; 163 164 165 /* EOF packet */ 166 typedef struct st_mysqlnd_packet_eof { 167 MYSQLND_PACKET_HEADER header; 168 uint8_t field_count; /* 0xFE */ 169 uint16_t warning_count; 170 uint16_t server_status; 171 /* If error packet, we use these */ 172 char error[MYSQLND_ERRMSG_SIZE+1]; 173 char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1]; 174 unsigned int error_no; 175 } MYSQLND_PACKET_EOF; 176 /* EOF packet */ 177 178 179 /* Result Set header*/ 180 typedef struct st_mysqlnd_packet_rset_header { 181 MYSQLND_PACKET_HEADER header; 182 /* 183 0x00 => ok 184 ~0 => LOAD DATA LOCAL 185 error_no != 0 => error 186 others => result set -> Read res_field packets up to field_count 187 */ 188 unsigned long field_count; 189 /* 190 These are filled if no SELECT query. For SELECT warning_count 191 and server status are in the last row packet, the EOF packet. 192 */ 193 uint16_t warning_count; 194 uint16_t server_status; 195 uint64_t affected_rows; 196 uint64_t last_insert_id; 197 /* This is for both LOAD DATA or info, when no result set */ 198 char *info_or_local_file; 199 size_t info_or_local_file_len; 200 /* If error packet, we use these */ 201 MYSQLND_ERROR_INFO error_info; 202 } MYSQLND_PACKET_RSET_HEADER; 203 204 205 /* Result set field packet */ 206 typedef struct st_mysqlnd_packet_res_field { 207 MYSQLND_PACKET_HEADER header; 208 MYSQLND_FIELD *metadata; 209 /* For table definitions, empty for result sets */ 210 zend_bool skip_parsing; 211 zend_bool stupid_list_fields_eof; 212 zend_bool persistent_alloc; 213 214 MYSQLND_ERROR_INFO error_info; 215 } MYSQLND_PACKET_RES_FIELD; 216 217 218 /* Row packet */ 219 typedef struct st_mysqlnd_packet_row { 220 MYSQLND_PACKET_HEADER header; 221 zval **fields; 222 uint32_t field_count; 223 zend_bool eof; 224 /* 225 These are, of course, only for SELECT in the EOF packet, 226 which is detected by this packet 227 */ 228 uint16_t warning_count; 229 uint16_t server_status; 230 231 struct st_mysqlnd_memory_pool_chunk *row_buffer; 232 MYSQLND_MEMORY_POOL * result_set_memory_pool; 233 234 zend_bool skip_extraction; 235 zend_bool binary_protocol; 236 zend_bool persistent_alloc; 237 MYSQLND_FIELD *fields_metadata; 238 /* We need this to alloc bigger bufs in non-PS mode */ 239 unsigned int bit_fields_count; 240 size_t bit_fields_total_len; /* trailing \0 not counted */ 241 242 /* If error packet, we use these */ 243 MYSQLND_ERROR_INFO error_info; 244 } MYSQLND_PACKET_ROW; 245 246 247 /* Statistics packet */ 248 typedef struct st_mysqlnd_packet_stats { 249 MYSQLND_PACKET_HEADER header; 250 char *message; 251 /* message_len is not part of the packet*/ 252 size_t message_len; 253 } MYSQLND_PACKET_STATS; 254 255 256 /* COM_PREPARE response packet */ 257 typedef struct st_mysqlnd_packet_prepare_response { 258 MYSQLND_PACKET_HEADER header; 259 /* also known as field_count 0x00=OK , 0xFF=error */ 260 unsigned char error_code; 261 unsigned long stmt_id; 262 unsigned int field_count; 263 unsigned int param_count; 264 unsigned int warning_count; 265 266 /* present in case of error */ 267 MYSQLND_ERROR_INFO error_info; 268 } MYSQLND_PACKET_PREPARE_RESPONSE; 269 270 271 /* Statistics packet */ 272 typedef struct st_mysqlnd_packet_chg_user_resp { 273 MYSQLND_PACKET_HEADER header; 274 uint32_t response_code; 275 276 /* message_len is not part of the packet*/ 277 uint16_t server_capabilities; 278 /* If error packet, we use these */ 279 MYSQLND_ERROR_INFO error_info; 280 zend_bool server_asked_323_auth; 281 282 char *new_auth_protocol; 283 size_t new_auth_protocol_len; 284 zend_uchar *new_auth_protocol_data; 285 size_t new_auth_protocol_data_len; 286 } MYSQLND_PACKET_CHG_USER_RESPONSE; 287 288 289 PHPAPI void php_mysqlnd_scramble(zend_uchar * const buffer, const zend_uchar * const scramble, const zend_uchar * const pass, size_t pass_len); 290 291 unsigned long php_mysqlnd_net_field_length(zend_uchar **packet); 292 zend_uchar * php_mysqlnd_net_store_length(zend_uchar *packet, uint64_t length); 293 294 PHPAPI const extern char * const mysqlnd_empty_string; 295 296 297 enum_func_status php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, 298 unsigned int field_count, MYSQLND_FIELD *fields_metadata, 299 zend_bool as_unicode, zend_bool as_int_or_float, 300 MYSQLND_STATS * stats TSRMLS_DC); 301 302 303 enum_func_status php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields, 304 unsigned int field_count, MYSQLND_FIELD *fields_metadata, 305 zend_bool as_unicode, zend_bool as_int_or_float, 306 MYSQLND_STATS * stats TSRMLS_DC); 307 308 309 PHPAPI MYSQLND_PROTOCOL * mysqlnd_protocol_init(zend_bool persistent TSRMLS_DC); 310 PHPAPI void mysqlnd_protocol_free(MYSQLND_PROTOCOL * const protocol TSRMLS_DC); 311 312 #endif /* MYSQLND_WIREPROTOCOL_H */ 313 314 /* 315 * Local variables: 316 * tab-width: 4 317 * c-basic-offset: 4 318 * End: 319 * vim600: noet sw=4 ts=4 fdm=marker 320 * vim<600: noet sw=4 ts=4 321 */ 322