23
23
#include <drizzled/error.h>
24
24
#include <drizzled/sql_state.h>
25
25
#include <libdrizzleclient/pack.h>
26
#include <libdrizzleclient/errmsg.h>
26
27
#include <drizzled/protocol.h>
27
28
#include <drizzled/session.h>
29
#include <drizzled/data_home.h>
32
Function called by drizzleclient_net_init() to set some check variables
36
void drizzleclient_net_local_init(NET *net)
38
net->max_packet= (uint32_t) global_system_variables.net_buffer_length;
40
drizzleclient_net_set_read_timeout(net,
41
(uint32_t)global_system_variables.net_read_timeout);
42
drizzleclient_net_set_write_timeout(net,
43
(uint32_t)global_system_variables.net_write_timeout);
45
net->retry_count= (uint32_t) global_system_variables.net_retry_count;
46
net->max_packet_size= cmax(global_system_variables.net_buffer_length,
47
global_system_variables.max_allowed_packet);
29
51
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
30
/* Declared non-static only because of the embedded library. */
31
static void net_send_error_packet(Session *session, uint32_t sql_errno, const char *err);
32
53
static void write_eof_packet(Session *session, NET *net,
33
54
uint32_t server_status, uint32_t total_warn_count);
56
bool Protocol::io_ok()
61
void Protocol::set_read_timeout(uint32_t timeout)
63
drizzleclient_net_set_read_timeout(&net, timeout);
66
void Protocol::set_write_timeout(uint32_t timeout)
68
drizzleclient_net_set_write_timeout(&net, timeout);
71
void Protocol::set_retry_count(uint32_t count)
73
net.retry_count=count;
76
void Protocol::set_error(char error)
81
bool Protocol::have_error(void)
83
return net.error || net.vio == 0;
86
bool Protocol::was_aborted(void)
88
return net.error && net.vio != 0;
91
bool Protocol::have_more_data(void)
93
return drizzleclient_net_more_data(&net);
96
bool Protocol::have_compression(void)
101
void Protocol::enable_compression(void)
106
bool Protocol::is_reading(void)
108
return net.reading_or_writing == 1;
111
bool Protocol::is_writing(void)
113
return net.reading_or_writing == 2;
117
* To disable results we set net.vio to 0.
120
void Protocol::disable_results(void)
126
void Protocol::enable_results(void)
35
132
bool Protocol::net_store_data(const unsigned char *from, size_t length)
37
134
size_t packet_length= packet->length();
110
Send a error string to client.
113
net_printf_error and net_send_error are low-level functions
114
that shall be used only when a new connection is being
115
established or at server startup.
117
For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
118
critical that every error that can be intercepted is issued in one
119
place only, my_message_sql.
121
void net_send_error(Session *session, uint32_t sql_errno, const char *err)
124
assert(err && err[0]);
127
It's one case when we can push an error even though there
128
is an OK or EOF already.
130
session->main_da.can_overwrite_status= true;
132
/* Abort multi-result sets */
133
session->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
135
net_send_error_packet(session, sql_errno, err);
137
session->main_da.can_overwrite_status= false;
141
207
Return ok to the client.
143
209
The ok packet has the following structure:
283
351
length= (uint32_t)(tmp-(char*)buff);
284
352
err= (char*) buff;
286
drizzleclient_net_write_command(net,(unsigned char) 255, (unsigned char*) "", 0, (unsigned char*) err, length);
354
drizzleclient_net_write_command(&net,(unsigned char) 255, (unsigned char*) "", 0, (unsigned char*) err, length);
292
Faster drizzleclient_net_store_length when we know that length is less than 65536.
293
We keep a separate version for that range because it's widely used in
296
uint32_t is used as agrument type because of MySQL type conventions:
297
- uint32_t for 0..65536
298
- ulong for 0..4294967296
299
- uint64_t for bigger numbers.
359
Send a error string to client.
362
net_printf_error and net_send_error are low-level functions
363
that shall be used only when a new connection is being
364
established or at server startup.
366
For SIGNAL/RESIGNAL and GET DIAGNOSTICS functionality it's
367
critical that every error that can be intercepted is issued in one
368
place only, my_message_sql.
302
static unsigned char *drizzleclient_net_store_length_fast(unsigned char *packet, uint32_t length)
370
void Protocol_text::send_error(uint32_t sql_errno, const char *err)
306
*packet=(unsigned char) length;
310
int2store(packet,(uint32_t) length);
373
assert(err && err[0]);
376
It's one case when we can push an error even though there
377
is an OK or EOF already.
379
session->main_da.can_overwrite_status= true;
381
/* Abort multi-result sets */
382
session->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
384
send_error_packet(sql_errno, err);
386
session->main_da.can_overwrite_status= false;
316
391
Send the status of the current statement execution over network.
373
448
switch (session->main_da.status()) {
374
449
case Diagnostics_area::DA_ERROR:
375
450
/* The query failed, send error to log and abort bootstrap. */
376
net_send_error(session,
377
session->main_da.sql_errno(),
378
session->main_da.message());
451
send_error(session->main_da.sql_errno(),
452
session->main_da.message());
380
454
case Diagnostics_area::DA_EOF:
381
net_send_eof(session,
455
net_send_eof(session, &net,
382
456
session->main_da.server_status(),
383
457
session->main_da.total_warn_count());
385
459
case Diagnostics_area::DA_OK:
460
net_send_ok(session, &net,
387
461
session->main_da.server_status(),
388
462
session->main_da.total_warn_count(),
389
463
session->main_da.affected_rows(),
407
/****************************************************************************
408
Functions used by the protocol functions (like net_send_ok) to store
409
strings and numbers in the header result packet.
410
****************************************************************************/
412
/* The following will only be used for short strings < 65K */
414
unsigned char *net_store_data(unsigned char *to, const unsigned char *from, size_t length)
416
to=drizzleclient_net_store_length_fast(to,length);
417
memcpy(to,from,length);
421
unsigned char *net_store_data(unsigned char *to,int32_t from)
424
uint32_t length=(uint32_t) (int10_to_str(from,buff,10)-buff);
425
to=drizzleclient_net_store_length_fast(to,length);
426
memcpy(to,buff,length);
430
unsigned char *net_store_data(unsigned char *to,int64_t from)
433
uint32_t length=(uint32_t) (int64_t10_to_str(from,buff,10)-buff);
434
to=drizzleclient_net_store_length_fast(to,length);
435
memcpy(to,buff,length);
440
481
/*****************************************************************************
441
482
Default Protocol functions
442
483
*****************************************************************************/
496
537
Send_field field;
497
538
item->make_field(&field);
499
prot.prepare_for_resend();
502
if (prot.store(STRING_WITH_LEN("def"), cs, session_charset) ||
503
prot.store(field.db_name, (uint32_t) strlen(field.db_name),
504
cs, session_charset) ||
505
prot.store(field.table_name, (uint32_t) strlen(field.table_name),
506
cs, session_charset) ||
507
prot.store(field.org_table_name, (uint32_t) strlen(field.org_table_name),
508
cs, session_charset) ||
509
prot.store(field.col_name, (uint32_t) strlen(field.col_name),
510
cs, session_charset) ||
511
prot.store(field.org_col_name, (uint32_t) strlen(field.org_col_name),
540
prepare_for_resend();
543
if (store(STRING_WITH_LEN("def"), cs, session_charset) ||
544
store(field.db_name, (uint32_t) strlen(field.db_name),
545
cs, session_charset) ||
546
store(field.table_name, (uint32_t) strlen(field.table_name),
547
cs, session_charset) ||
548
store(field.org_table_name, (uint32_t) strlen(field.org_table_name),
549
cs, session_charset) ||
550
store(field.col_name, (uint32_t) strlen(field.col_name),
551
cs, session_charset) ||
552
store(field.org_col_name, (uint32_t) strlen(field.org_col_name),
512
553
cs, session_charset) ||
513
554
local_packet->realloc(local_packet->length()+12))
645
686
All data are sent as 'packed-string-length' followed by 'string-data'
646
687
****************************************************************************/
689
void Protocol_text::init_random(uint64_t seed1, uint64_t seed2)
691
drizzleclient_randominit(&_rand, seed1, seed2);
694
bool Protocol_text::init_file_descriptor(int fd)
696
if (drizzleclient_net_init_sock(&net, fd, 0))
701
int Protocol_text::file_descriptor(void)
703
return drizzleclient_net_get_sd(&net);
706
bool Protocol_text::authenticate()
708
bool connection_is_valid;
710
/* Use "connect_timeout" value during connection phase */
711
drizzleclient_net_set_read_timeout(&net, connect_timeout);
712
drizzleclient_net_set_write_timeout(&net, connect_timeout);
714
connection_is_valid= _check_connection();
717
if (!connection_is_valid)
720
/* Connect completed, set read/write timeouts back to default */
721
drizzleclient_net_set_read_timeout(&net,
722
session->variables.net_read_timeout);
723
drizzleclient_net_set_write_timeout(&net,
724
session->variables.net_write_timeout);
728
bool Protocol_text::read_command(char **l_packet, uint32_t *packet_length)
731
This thread will do a blocking read from the client which
732
will be interrupted when the next command is received from
733
the client, the connection is closed or "net_wait_timeout"
734
number of seconds has passed
736
drizzleclient_net_set_read_timeout(&net,
737
session->variables.net_wait_timeout);
740
XXX: this code is here only to clear possible errors of init_connect.
741
Consider moving to init_connect() instead.
743
session->clear_error(); // Clear error message
744
session->main_da.reset_diagnostics_area();
748
*packet_length= drizzleclient_net_read(&net);
749
if (*packet_length == packet_error)
751
/* Check if we can continue without closing the connection */
753
if(net.last_errno== CR_NET_PACKET_TOO_LARGE)
754
my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
755
/* Assert is invalid for dirty connection shutdown
756
* assert(session->is_error());
761
return false; // We have to close it.
768
*l_packet= (char*) net.read_pos;
771
'packet_length' contains length of data, as it was stored in packet
772
header. In case of malformed header, drizzleclient_net_read returns zero.
773
If packet_length is not zero, drizzleclient_net_read ensures that the returned
774
number of bytes was actually read from network.
775
There is also an extra safety measure in drizzleclient_net_read:
776
it sets packet[packet_length]= 0, but only for non-zero packets.
779
if (*packet_length == 0) /* safety */
781
/* Initialize with COM_SLEEP packet */
782
(*l_packet)[0]= (unsigned char) COM_SLEEP;
785
/* Do not rely on drizzleclient_net_read, extra safety against programming errors. */
786
(*l_packet)[*packet_length]= '\0'; /* safety */
788
/* Restore read timeout value */
789
drizzleclient_net_set_read_timeout(&net,
790
session->variables.net_read_timeout);
795
void Protocol_text::close(void)
799
drizzleclient_net_close(&net);
800
drizzleclient_net_end(&net);
648
804
void Protocol_text::prepare_for_resend()
650
806
packet->length(0);
822
978
return net_store_data((unsigned char*) buff, length);
981
bool Protocol_text::_check_connection(void)
990
if (drizzleclient_net_peer_addr(&net, ip, &session->peer_port, NI_MAXHOST))
992
my_error(ER_BAD_HOST_ERROR, MYF(0), session->security_ctx.ip.c_str());
996
session->security_ctx.ip.assign(ip);
998
drizzleclient_net_keepalive(&net, true);
1000
uint32_t server_capabilites;
1002
/* buff[] needs to big enough to hold the server_version variable */
1003
char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH + 64];
1005
server_capabilites= CLIENT_BASIC_FLAGS;
1007
#ifdef HAVE_COMPRESS
1008
server_capabilites|= CLIENT_COMPRESS;
1009
#endif /* HAVE_COMPRESS */
1011
end= buff + strlen(server_version);
1012
if ((end - buff) >= SERVER_VERSION_LENGTH)
1013
end= buff + (SERVER_VERSION_LENGTH - 1);
1014
memcpy(buff, server_version, end - buff);
1018
int4store((unsigned char*) end, thread_id);
1021
So as _checkConnection is the only entry point to authorization
1022
procedure, scramble is set here. This gives us new scramble for
1025
drizzleclient_create_random_string(_scramble, SCRAMBLE_LENGTH, &_rand);
1027
Old clients does not understand long scrambles, but can ignore packet
1028
tail: that's why first part of the scramble is placed here, and second
1029
part at the end of packet.
1031
end= strncpy(end, _scramble, SCRAMBLE_LENGTH_323);
1032
end+= SCRAMBLE_LENGTH_323;
1034
*end++= 0; /* an empty byte for some reason */
1036
int2store(end, server_capabilites);
1037
/* write server characteristics: up to 16 bytes allowed */
1038
end[2]=(char) default_charset_info->number;
1039
int2store(end+3, session->server_status);
1040
memset(end+5, 0, 13);
1042
/* write scramble tail */
1043
size_t scramble_len= SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323;
1044
end= strncpy(end, _scramble + SCRAMBLE_LENGTH_323, scramble_len);
1047
*end++= 0; /* an empty byte for some reason */
1049
/* At this point we write connection message and read reply */
1050
if (drizzleclient_net_write_command(&net
1051
, (unsigned char) protocol_version
1052
, (unsigned char*) ""
1054
, (unsigned char*) buff
1055
, (size_t) (end-buff))
1056
|| (pkt_len= drizzleclient_net_read(&net)) == packet_error
1057
|| pkt_len < MIN_HANDSHAKE_SIZE)
1059
my_error(ER_HANDSHAKE_ERROR, MYF(0), session->security_ctx.ip.c_str());
1063
if (session->packet.alloc(session->variables.net_buffer_length))
1064
return false; /* The error is set by alloc(). */
1066
session->client_capabilities= uint2korr(net.read_pos);
1069
session->client_capabilities|= ((uint32_t) uint2korr(net.read_pos + 2)) << 16;
1070
session->max_client_packet_length= uint4korr(net.read_pos + 4);
1071
session->update_charset();
1072
end= (char*) net.read_pos + 32;
1075
Disable those bits which are not supported by the server.
1076
This is a precautionary measure, if the client lies. See Bug#27944.
1078
session->client_capabilities&= server_capabilites;
1080
if (end >= (char*) net.read_pos + pkt_len + 2)
1082
my_error(ER_HANDSHAKE_ERROR, MYF(0), session->security_ctx.ip.c_str());
1086
net.return_status= &session->server_status;
1089
char *passwd= strchr(user, '\0')+1;
1090
uint32_t user_len= passwd - user - 1;
1092
char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
1093
char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
1094
uint32_t dummy_errors;
1097
Old clients send null-terminated string as password; new clients send
1098
the size (1 byte) + string (not null-terminated). Hence in case of empty
1099
password both send '\0'.
1101
This strlen() can't be easily deleted without changing protocol.
1103
Cast *passwd to an unsigned char, so that it doesn't extend the sign for
1104
*passwd > 127 and become 2**32-127+ after casting to uint.
1106
uint32_t passwd_len= session->client_capabilities & CLIENT_SECURE_CONNECTION ?
1107
(unsigned char)(*passwd++) : strlen(passwd);
1108
l_db= session->client_capabilities & CLIENT_CONNECT_WITH_DB ? l_db + passwd_len + 1 : 0;
1110
/* strlen() can't be easily deleted without changing protocol */
1111
uint32_t db_len= l_db ? strlen(l_db) : 0;
1113
if (passwd + passwd_len + db_len > (char *) net.read_pos + pkt_len)
1115
my_error(ER_HANDSHAKE_ERROR, MYF(0), session->security_ctx.ip.c_str());
1119
/* Since 4.1 all database names are stored in utf8 */
1122
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
1123
system_charset_info,
1125
session->charset(), &dummy_errors)]= 0;
1129
user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
1130
system_charset_info, user, user_len,
1131
session->charset(), &dummy_errors)]= '\0';
1134
/* If username starts and ends in "'", chop them off */
1135
if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
1137
user[user_len-1]= 0;
1142
session->security_ctx.user.assign(user);
1144
return session->checkUser(passwd, passwd_len, l_db);