1 /* 2 +----------------------------------------------------------------------+ 3 | Copyright (c) The PHP Group | 4 +----------------------------------------------------------------------+ 5 | This source file is subject to version 3.01 of the PHP license, | 6 | that is bundled with this package in the file LICENSE, and is | 7 | available through the world-wide-web at the following url: | 8 | http://www.php.net/license/3_01.txt | 9 | If you did not receive a copy of the PHP license and are unable to | 10 | obtain it through the world-wide-web, please send a note to | 11 | license@php.net so we can mail you a copy immediately. | 12 +----------------------------------------------------------------------+ 13 | Authors: Andrey Hristov <andrey@php.net> | 14 | Ulf Wendel <uw@php.net> | 15 +----------------------------------------------------------------------+ 16 */ 17 18 #ifndef MYSQLND_WIREPROTOCOL_H 19 #define MYSQLND_WIREPROTOCOL_H 20 21 #define MYSQLND_HEADER_SIZE 4 22 #define COMPRESSED_HEADER_SIZE 3 23 24 #define MYSQLND_NULL_LENGTH (zend_ulong) ~0 25 26 /* Used in mysqlnd_debug.c */ 27 PHPAPI extern const char mysqlnd_read_header_name[]; 28 PHPAPI extern const char mysqlnd_read_body_name[]; 29 30 31 /* Packet handling */ 32 #define PACKET_WRITE(conn, packet) ((packet)->header.m->write_to_net((conn), (packet))) 33 #define PACKET_READ(conn, packet) ((packet)->header.m->read_from_net((conn), (packet))) 34 #define PACKET_FREE(packet) \ 35 do { \ 36 DBG_INF_FMT("PACKET_FREE(%p)", packet); \ 37 if ((packet)->header.m->free_mem) { \ 38 ((packet)->header.m->free_mem((packet))); \ 39 } \ 40 } while (0); 41 42 PHPAPI extern const char * const mysqlnd_command_to_text[COM_END]; 43 44 /* Low-level extraction functionality */ 45 typedef struct st_mysqlnd_packet_methods { 46 enum_func_status (*read_from_net)(MYSQLND_CONN_DATA * conn, void * packet); 47 size_t (*write_to_net)(MYSQLND_CONN_DATA * conn, void * packet); 48 void (*free_mem)(void *packet); 49 } mysqlnd_packet_methods; 50 51 52 typedef struct st_mysqlnd_packet_header { 53 size_t size; 54 zend_uchar packet_no; 55 56 mysqlnd_packet_methods *m; 57 } MYSQLND_PACKET_HEADER; 58 59 /* Server greets the client */ 60 typedef struct st_mysqlnd_packet_greet { 61 MYSQLND_PACKET_HEADER header; 62 uint8_t protocol_version; 63 char *server_version; 64 uint32_t thread_id; 65 char intern_auth_plugin_data[SCRAMBLE_LENGTH]; 66 MYSQLND_STRING authentication_plugin_data; 67 /* 1 byte pad */ 68 uint32_t server_capabilities; 69 uint8_t charset_no; 70 uint16_t server_status; 71 /* 13 byte pad, in 5.5 first 2 bytes are more capabilities followed by 1 byte scramble_length */ 72 zend_bool pre41; 73 /* If error packet, we use these */ 74 char error[MYSQLND_ERRMSG_SIZE+1]; 75 char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1]; 76 unsigned int error_no; 77 char *auth_protocol; 78 } MYSQLND_PACKET_GREET; 79 80 81 /* Client authenticates */ 82 typedef struct st_mysqlnd_packet_auth { 83 MYSQLND_PACKET_HEADER header; 84 const char *user; 85 const zend_uchar *auth_data; 86 size_t auth_data_len; 87 const char *db; 88 const char *auth_plugin_name; 89 uint32_t client_flags; 90 uint32_t max_packet_size; 91 uint8_t charset_no; 92 /* Here the packet ends. This is user supplied data */ 93 zend_bool send_auth_data; 94 zend_bool is_change_user_packet; 95 zend_bool silent; 96 HashTable *connect_attr; 97 size_t db_len; 98 } MYSQLND_PACKET_AUTH; 99 100 /* Auth response packet */ 101 typedef struct st_mysqlnd_packet_auth_response { 102 MYSQLND_PACKET_HEADER header; 103 uint8_t response_code; 104 uint64_t affected_rows; 105 uint64_t last_insert_id; 106 uint16_t server_status; 107 uint16_t warning_count; 108 char *message; 109 size_t message_len; 110 /* If error packet, we use these */ 111 char error[MYSQLND_ERRMSG_SIZE+1]; 112 char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1]; 113 unsigned int error_no; 114 115 char *new_auth_protocol; 116 size_t new_auth_protocol_len; 117 zend_uchar *new_auth_protocol_data; 118 size_t new_auth_protocol_data_len; 119 } MYSQLND_PACKET_AUTH_RESPONSE; 120 121 122 /* Auth response packet */ 123 typedef struct st_mysqlnd_packet_change_auth_response { 124 MYSQLND_PACKET_HEADER header; 125 const zend_uchar *auth_data; 126 size_t auth_data_len; 127 } MYSQLND_PACKET_CHANGE_AUTH_RESPONSE; 128 129 130 /* OK packet */ 131 typedef struct st_mysqlnd_packet_ok { 132 MYSQLND_PACKET_HEADER header; 133 uint8_t field_count; /* always 0x0 */ 134 uint64_t affected_rows; 135 uint64_t last_insert_id; 136 uint16_t server_status; 137 uint16_t warning_count; 138 char *message; 139 size_t message_len; 140 /* If error packet, we use these */ 141 char error[MYSQLND_ERRMSG_SIZE+1]; 142 char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1]; 143 unsigned int error_no; 144 } MYSQLND_PACKET_OK; 145 146 147 /* Command packet */ 148 typedef struct st_mysqlnd_packet_command { 149 MYSQLND_PACKET_HEADER header; 150 enum php_mysqlnd_server_command command; 151 MYSQLND_CSTRING argument; 152 } MYSQLND_PACKET_COMMAND; 153 154 155 /* EOF packet */ 156 typedef struct st_mysqlnd_packet_eof { 157 MYSQLND_PACKET_HEADER header; 158 uint8_t field_count; /* 0xFE */ 159 uint16_t warning_count; 160 uint16_t server_status; 161 /* If error packet, we use these */ 162 char error[MYSQLND_ERRMSG_SIZE+1]; 163 char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1]; 164 unsigned int error_no; 165 } MYSQLND_PACKET_EOF; 166 /* EOF packet */ 167 168 169 /* Result Set header*/ 170 typedef struct st_mysqlnd_packet_rset_header { 171 MYSQLND_PACKET_HEADER header; 172 /* 173 0x00 => ok 174 ~0 => LOAD DATA LOCAL 175 error_no != 0 => error 176 others => result set -> Read res_field packets up to field_count 177 */ 178 zend_ulong field_count; 179 /* 180 These are filled if no SELECT query. For SELECT warning_count 181 and server status are in the last row packet, the EOF packet. 182 */ 183 uint16_t warning_count; 184 uint16_t server_status; 185 uint64_t affected_rows; 186 uint64_t last_insert_id; 187 /* This is for both LOAD DATA or info, when no result set */ 188 MYSQLND_STRING info_or_local_file; 189 /* If error packet, we use these */ 190 MYSQLND_ERROR_INFO error_info; 191 } MYSQLND_PACKET_RSET_HEADER; 192 193 194 /* Result set field packet */ 195 typedef struct st_mysqlnd_packet_res_field { 196 MYSQLND_PACKET_HEADER header; 197 MYSQLND_MEMORY_POOL *memory_pool; 198 MYSQLND_FIELD *metadata; 199 /* For table definitions, empty for result sets */ 200 zend_bool skip_parsing; 201 202 MYSQLND_ERROR_INFO error_info; 203 } MYSQLND_PACKET_RES_FIELD; 204 205 206 /* Row packet */ 207 typedef struct st_mysqlnd_packet_row { 208 MYSQLND_PACKET_HEADER header; 209 zval *fields; 210 uint32_t field_count; 211 zend_bool eof; 212 /* 213 These are, of course, only for SELECT in the EOF packet, 214 which is detected by this packet 215 */ 216 uint16_t warning_count; 217 uint16_t server_status; 218 219 MYSQLND_ROW_BUFFER row_buffer; 220 MYSQLND_MEMORY_POOL * result_set_memory_pool; 221 222 zend_bool skip_extraction; 223 zend_bool binary_protocol; 224 MYSQLND_FIELD *fields_metadata; 225 226 /* If error packet, we use these */ 227 MYSQLND_ERROR_INFO error_info; 228 } MYSQLND_PACKET_ROW; 229 230 231 /* Statistics packet */ 232 typedef struct st_mysqlnd_packet_stats { 233 MYSQLND_PACKET_HEADER header; 234 MYSQLND_STRING message; 235 } MYSQLND_PACKET_STATS; 236 237 238 /* COM_PREPARE response packet */ 239 typedef struct st_mysqlnd_packet_prepare_response { 240 MYSQLND_PACKET_HEADER header; 241 /* also known as field_count 0x00=OK , 0xFF=error */ 242 unsigned char error_code; 243 zend_ulong stmt_id; 244 unsigned int field_count; 245 unsigned int param_count; 246 unsigned int warning_count; 247 248 /* present in case of error */ 249 MYSQLND_ERROR_INFO error_info; 250 } MYSQLND_PACKET_PREPARE_RESPONSE; 251 252 253 /* Statistics packet */ 254 typedef struct st_mysqlnd_packet_chg_user_resp { 255 MYSQLND_PACKET_HEADER header; 256 uint32_t response_code; 257 258 /* message_len is not part of the packet*/ 259 uint16_t server_capabilities; 260 /* If error packet, we use these */ 261 MYSQLND_ERROR_INFO error_info; 262 zend_bool server_asked_323_auth; 263 264 char *new_auth_protocol; 265 size_t new_auth_protocol_len; 266 zend_uchar *new_auth_protocol_data; 267 size_t new_auth_protocol_data_len; 268 } MYSQLND_PACKET_CHG_USER_RESPONSE; 269 270 271 /* Command packet */ 272 typedef struct st_mysqlnd_packet_sha256_pk_request { 273 MYSQLND_PACKET_HEADER header; 274 } MYSQLND_PACKET_SHA256_PK_REQUEST; 275 276 typedef struct st_mysqlnd_packet_sha256_pk_request_response { 277 MYSQLND_PACKET_HEADER header; 278 zend_uchar *public_key; 279 size_t public_key_len; 280 } MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE; 281 282 typedef struct st_mysqlnd_packet_cached_sha2_result { 283 MYSQLND_PACKET_HEADER header; 284 uint8_t response_code; 285 uint8_t result; 286 uint8_t request; 287 zend_uchar * password; 288 size_t password_len; 289 /* Used for auth switch request */ 290 char *new_auth_protocol; 291 size_t new_auth_protocol_len; 292 zend_uchar *new_auth_protocol_data; 293 size_t new_auth_protocol_data_len; 294 /* Used for error result */ 295 char error[MYSQLND_ERRMSG_SIZE+1]; 296 char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1]; 297 unsigned int error_no; 298 } MYSQLND_PACKET_CACHED_SHA2_RESULT; 299 300 301 302 zend_ulong php_mysqlnd_net_field_length(const zend_uchar **packet); 303 zend_uchar * php_mysqlnd_net_store_length(zend_uchar *packet, const uint64_t length); 304 size_t php_mysqlnd_net_store_length_size(uint64_t length); 305 306 PHPAPI extern const char * const mysqlnd_empty_string; 307 308 enum_func_status php_mysqlnd_rowp_read_binary_protocol(MYSQLND_ROW_BUFFER * row_buffer, zval * fields, 309 unsigned int field_count, const MYSQLND_FIELD * fields_metadata, 310 zend_bool as_int_or_float, MYSQLND_STATS * stats); 311 312 313 enum_func_status php_mysqlnd_rowp_read_text_protocol_zval(MYSQLND_ROW_BUFFER * row_buffer, zval * fields, 314 unsigned int field_count, const MYSQLND_FIELD * fields_metadata, 315 zend_bool as_int_or_float, MYSQLND_STATS * stats); 316 317 enum_func_status php_mysqlnd_rowp_read_text_protocol_c(MYSQLND_ROW_BUFFER * row_buffer, zval * fields, 318 unsigned int field_count, const MYSQLND_FIELD * fields_metadata, 319 zend_bool as_int_or_float, MYSQLND_STATS * stats); 320 321 322 PHPAPI MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * mysqlnd_protocol_payload_decoder_factory_init(MYSQLND_CONN_DATA * conn, const zend_bool persistent); 323 PHPAPI void mysqlnd_protocol_payload_decoder_factory_free(MYSQLND_PROTOCOL_PAYLOAD_DECODER_FACTORY * const payload_decoder_factory); 324 325 #endif /* MYSQLND_WIREPROTOCOL_H */ 326