~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/mysql_protocol/mysql_protocol.cc

  • Committer: lbieber
  • Date: 2010-10-01 13:06:31 UTC
  • mfrom: (1802.2.2 drizzle-bug-651948)
  • mto: This revision was merged to the branch mainline in revision 1805.
  • Revision ID: lbieber@orisndriz08-20101001130631-xubscnhmj7r5dn6g
Merge Andrew - Fix bug 651948 - Index lengths not retrieved using drizzledump

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008 Sun Microsystems
5
5
 *
6
6
 * This program is free software; you can redistribute it and/or modify
7
7
 * it under the terms of the GNU General Public License as published by
14
14
 *
15
15
 * You should have received a copy of the GNU General Public License
16
16
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
18
 */
19
19
 
20
20
#include "config.h"
21
21
#include <drizzled/gettext.h>
22
22
#include <drizzled/error.h>
23
23
#include <drizzled/query_id.h>
24
 
#include <drizzled/error/sql_state.h>
 
24
#include <drizzled/sql_state.h>
25
25
#include <drizzled/session.h>
26
26
#include "drizzled/internal/m_string.h"
27
27
#include <algorithm>
28
28
#include <boost/program_options.hpp>
29
29
#include <drizzled/module/option_map.h>
30
 
#include "drizzled/util/tokenize.h"
31
30
#include "errmsg.h"
32
31
#include "mysql_protocol.h"
33
32
#include "mysql_password.h"
34
33
#include "options.h"
35
 
 
36
 
#include "drizzled/identifier.h"
37
 
 
38
 
#define PROTOCOL_VERSION 10
 
34
#include "table_function.h"
39
35
 
40
36
namespace po= boost::program_options;
41
37
using namespace std;
42
38
using namespace drizzled;
43
39
 
44
 
namespace drizzle_plugin
45
 
{
 
40
#define PROTOCOL_VERSION 10
46
41
 
47
 
std::vector<std::string> ClientMySQLProtocol::mysql_admin_ip_addresses;
48
42
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
49
 
 
50
 
static port_constraint port;
51
 
static timeout_constraint connect_timeout;
52
 
static timeout_constraint read_timeout;
53
 
static timeout_constraint write_timeout;
54
 
static retry_constraint retry_count;
55
 
static buffer_constraint buffer_length;
56
 
 
 
43
static uint32_t port;
 
44
static uint32_t connect_timeout;
 
45
static uint32_t read_timeout;
 
46
static uint32_t write_timeout;
 
47
static uint32_t retry_count;
 
48
static uint32_t buffer_length;
 
49
static char* bind_address;
57
50
static uint32_t random_seed1;
58
51
static uint32_t random_seed2;
59
52
static const uint32_t random_max= 0x3FFFFFFF;
60
53
static const double random_max_double= (double)0x3FFFFFFF;
61
54
 
62
 
 
63
 
ProtocolCounters *ListenMySQLProtocol::mysql_counters= new ProtocolCounters();
 
55
static plugin::TableFunction* mysql_status_table_function_ptr= NULL;
64
56
 
65
57
ListenMySQLProtocol::~ListenMySQLProtocol()
66
 
{ }
67
 
 
68
 
void ListenMySQLProtocol::addCountersToTable()
69
58
{
70
 
  counters.push_back(new drizzled::plugin::ListenCounter(new std::string("connection_count"), &getCounters()->connectionCount));
71
 
  counters.push_back(new drizzled::plugin::ListenCounter(new std::string("connected"), &getCounters()->connected));
72
 
  counters.push_back(new drizzled::plugin::ListenCounter(new std::string("failed_connections"), &getCounters()->failedConnections));
 
59
  /* This is strdup'd from the options */
 
60
  free(bind_address);
73
61
}
74
62
 
75
 
const std::string ListenMySQLProtocol::getHost(void) const
 
63
const char* ListenMySQLProtocol::getHost(void) const
76
64
{
77
 
  return _hostname;
 
65
  return bind_address;
78
66
}
79
67
 
80
68
in_port_t ListenMySQLProtocol::getPort(void) const
81
69
{
82
 
  return port.get();
 
70
  return (in_port_t) port;
83
71
}
84
72
 
85
73
plugin::Client *ListenMySQLProtocol::getClient(int fd)
89
77
  if (new_fd == -1)
90
78
    return NULL;
91
79
 
92
 
  return new ClientMySQLProtocol(new_fd, _using_mysql41_protocol, getCounters());
 
80
  return new (nothrow) ClientMySQLProtocol(new_fd, using_mysql41_protocol);
93
81
}
94
82
 
95
 
ClientMySQLProtocol::ClientMySQLProtocol(int fd, bool using_mysql41_protocol, ProtocolCounters *set_counters):
96
 
  is_admin_connection(false),
97
 
  _using_mysql41_protocol(using_mysql41_protocol),
98
 
  counters(set_counters)
 
83
drizzled::atomic<uint64_t> ClientMySQLProtocol::connectionCount;
 
84
drizzled::atomic<uint64_t> ClientMySQLProtocol::failedConnections;
 
85
drizzled::atomic<uint64_t> ClientMySQLProtocol::connected;
 
86
 
 
87
ClientMySQLProtocol::ClientMySQLProtocol(int fd, bool using_mysql41_protocol_arg):
 
88
  using_mysql41_protocol(using_mysql41_protocol_arg)
99
89
{
100
 
  
101
90
  net.vio= 0;
102
91
 
103
92
  if (fd == -1)
104
93
    return;
105
94
 
106
 
  if (drizzleclient_net_init_sock(&net, fd, buffer_length.get()))
 
95
  if (drizzleclient_net_init_sock(&net, fd, buffer_length))
107
96
    throw bad_alloc();
108
97
 
109
 
  drizzleclient_net_set_read_timeout(&net, read_timeout.get());
110
 
  drizzleclient_net_set_write_timeout(&net, write_timeout.get());
111
 
  net.retry_count=retry_count.get();
 
98
  drizzleclient_net_set_read_timeout(&net, read_timeout);
 
99
  drizzleclient_net_set_write_timeout(&net, write_timeout);
 
100
  net.retry_count=retry_count;
112
101
}
113
102
 
114
103
ClientMySQLProtocol::~ClientMySQLProtocol()
115
104
{
116
105
  if (net.vio)
117
 
    net.vio->close();
 
106
    vio_close(net.vio);
118
107
}
119
108
 
120
109
int ClientMySQLProtocol::getFileDescriptor(void)
153
142
  { 
154
143
    drizzleclient_net_close(&net);
155
144
    drizzleclient_net_end(&net);
156
 
    if (is_admin_connection)
157
 
      counters->adminConnected.decrement();
158
 
    else
159
 
      counters->connected.decrement();
 
145
    connected.decrement();
160
146
  }
161
147
}
162
148
 
163
149
bool ClientMySQLProtocol::authenticate()
164
150
{
165
151
  bool connection_is_valid;
166
 
  if (is_admin_connection)
167
 
  {
168
 
    counters->adminConnectionCount.increment();
169
 
    counters->adminConnected.increment();
170
 
  }
171
 
  else
172
 
  {
173
 
    counters->connectionCount.increment();
174
 
    counters->connected.increment();
175
 
  }
 
152
 
 
153
  connectionCount.increment();
 
154
  connected.increment();
176
155
 
177
156
  /* Use "connect_timeout" value during connection phase */
178
 
  drizzleclient_net_set_read_timeout(&net, connect_timeout.get());
179
 
  drizzleclient_net_set_write_timeout(&net, connect_timeout.get());
 
157
  drizzleclient_net_set_read_timeout(&net, connect_timeout);
 
158
  drizzleclient_net_set_write_timeout(&net, connect_timeout);
180
159
 
181
160
  connection_is_valid= checkConnection();
182
161
 
183
162
  if (connection_is_valid)
184
 
  {
185
 
    if (not is_admin_connection and (counters->connected > counters->max_connections))
186
 
    {
187
 
      std::string errmsg(ER(ER_CON_COUNT_ERROR));
188
 
      sendError(ER_CON_COUNT_ERROR, errmsg.c_str());
189
 
      counters->failedConnections.increment();
190
 
    }
191
 
    else
192
 
    {
193
 
      sendOK();
194
 
    }
195
 
  }
 
163
    sendOK();
196
164
  else
197
165
  {
198
166
    sendError(session->main_da.sql_errno(), session->main_da.message());
199
 
    counters->failedConnections.increment();
 
167
    failedConnections.increment();
200
168
    return false;
201
169
  }
202
 
 
203
170
  /* Connect completed, set read/write timeouts back to default */
204
 
  drizzleclient_net_set_read_timeout(&net, read_timeout.get());
205
 
  drizzleclient_net_set_write_timeout(&net, write_timeout.get());
 
171
  drizzleclient_net_set_read_timeout(&net, read_timeout);
 
172
  drizzleclient_net_set_write_timeout(&net, write_timeout);
206
173
  return true;
207
174
}
208
175
 
239
206
      return false;                       // We have to close it.
240
207
 
241
208
    net.error= 0;
 
209
    *packet_length= 0;
 
210
    return true;
242
211
  }
243
212
 
244
213
  *l_packet= (char*) net.read_pos;
258
227
    (*l_packet)[0]= (unsigned char) COM_SLEEP;
259
228
    *packet_length= 1;
260
229
  }
261
 
  else if (_using_mysql41_protocol)
 
230
  else if (using_mysql41_protocol)
262
231
  {
263
232
    /* Map from MySQL commands to Drizzle commands. */
264
233
    switch ((int)(*l_packet)[0])
398
367
    drizzleclient_net_flush(&net);
399
368
    session->main_da.can_overwrite_status= false;
400
369
  }
401
 
  packet.shrink(buffer_length.get());
 
370
  packet.shrink(buffer_length);
402
371
}
403
372
 
404
373
 
405
 
void ClientMySQLProtocol::sendError(drizzled::error_t sql_errno, const char *err)
 
374
void ClientMySQLProtocol::sendError(uint32_t sql_errno, const char *err)
406
375
{
407
376
  uint32_t length;
408
377
  /*
410
379
  */
411
380
  unsigned char buff[2+1+SQLSTATE_LENGTH+DRIZZLE_ERRMSG_SIZE], *pos;
412
381
 
413
 
  assert(sql_errno != EE_OK);
 
382
  assert(sql_errno);
414
383
  assert(err && err[0]);
415
384
 
416
385
  /*
435
404
    return;
436
405
  }
437
406
 
438
 
  int2store(buff, static_cast<uint16_t>(sql_errno));
 
407
  int2store(buff,sql_errno);
439
408
  pos= buff+2;
440
409
 
441
410
  /* The first # is to make the client backward compatible */
442
411
  buff[2]= '#';
443
 
  pos= (unsigned char*) strcpy((char*) buff+3, error::convert_to_sqlstate(sql_errno));
444
 
  pos+= strlen(error::convert_to_sqlstate(sql_errno));
 
412
  pos= (unsigned char*) strcpy((char*) buff+3, drizzle_errno_to_sqlstate(sql_errno));
 
413
  pos+= strlen(drizzle_errno_to_sqlstate(sql_errno));
445
414
 
446
415
  char *tmp= strncpy((char*)pos, err, DRIZZLE_ERRMSG_SIZE-1);
447
416
  tmp+= strlen((char*)pos);
451
420
 
452
421
  drizzleclient_net_write_command(&net,(unsigned char) 255, (unsigned char*) "", 0, (unsigned char*) err, length);
453
422
 
454
 
  drizzleclient_net_flush(&net);
455
 
 
456
423
  session->main_da.can_overwrite_status= false;
457
424
}
458
425
 
508
475
    int2store(pos, field.charsetnr);
509
476
    int4store(pos+2, field.length);
510
477
 
511
 
    if (_using_mysql41_protocol)
 
478
    if (using_mysql41_protocol)
512
479
    {
513
480
      /* Switch to MySQL field numbering. */
514
481
      switch (field.type)
537
504
        pos[6]= 12;
538
505
        break;
539
506
 
540
 
      case DRIZZLE_TYPE_TIME:
541
 
        pos[6]= 13;
542
 
        break;
543
 
 
544
507
      case DRIZZLE_TYPE_DATE:
545
508
        pos[6]= 14;
546
509
        break;
549
512
        pos[6]= 15;
550
513
        break;
551
514
 
552
 
      case DRIZZLE_TYPE_MICROTIME:
553
 
        pos[6]= 15;
554
 
        break;
555
 
 
556
 
      case DRIZZLE_TYPE_UUID:
557
 
        pos[6]= 15;
558
 
        break;
559
 
 
560
 
      case DRIZZLE_TYPE_BOOLEAN:
561
 
        pos[6]= 15;
562
 
        break;
563
 
 
564
515
      case DRIZZLE_TYPE_DECIMAL:
565
516
        pos[6]= (char)246;
566
517
        break;
612
563
  char buff[MAX_FIELD_WIDTH];
613
564
  String str(buff,sizeof(buff), &my_charset_bin);
614
565
 
615
 
  from->val_str_internal(&str);
 
566
  from->val_str(&str);
616
567
 
617
568
  return netStoreData((const unsigned char *)str.ptr(), str.length());
618
569
}
683
634
  uint32_t pkt_len= 0;
684
635
  char *end;
685
636
  char scramble[SCRAMBLE_LENGTH];
686
 
  identifier::User::shared_ptr user_identifier= identifier::User::make_shared();
687
637
 
688
638
  makeScramble(scramble);
689
639
 
694
644
 
695
645
    if (drizzleclient_net_peer_addr(&net, ip, &peer_port, NI_MAXHOST))
696
646
    {
697
 
      my_error(ER_BAD_HOST_ERROR, MYF(0), ip);
 
647
      my_error(ER_BAD_HOST_ERROR, MYF(0), session->getSecurityContext().getIp().c_str());
698
648
      return false;
699
649
    }
700
650
 
701
 
    user_identifier->setAddress(ip);
 
651
    session->getSecurityContext().setIp(ip);
702
652
  }
703
653
  drizzleclient_net_keepalive(&net, true);
704
654
 
709
659
 
710
660
    server_capabilites= CLIENT_BASIC_FLAGS;
711
661
 
712
 
    if (_using_mysql41_protocol)
 
662
    if (using_mysql41_protocol)
713
663
      server_capabilites|= CLIENT_PROTOCOL_MYSQL41;
714
664
 
715
665
#ifdef HAVE_COMPRESS
753
703
        ||    (pkt_len= drizzleclient_net_read(&net)) == packet_error 
754
704
        || pkt_len < MIN_HANDSHAKE_SIZE)
755
705
    {
756
 
      my_error(ER_HANDSHAKE_ERROR, MYF(0), user_identifier->address().c_str());
 
706
      my_error(ER_HANDSHAKE_ERROR, MYF(0), session->getSecurityContext().getIp().c_str());
757
707
      return false;
758
708
    }
759
709
  }
760
 
  if (packet.alloc(buffer_length.get()))
 
710
  if (packet.alloc(buffer_length))
761
711
    return false; /* The error is set by alloc(). */
762
712
 
763
713
  client_capabilities= uint2korr(net.read_pos);
764
714
  if (!(client_capabilities & CLIENT_PROTOCOL_MYSQL41))
765
715
  {
766
 
    my_error(ER_HANDSHAKE_ERROR, MYF(0), user_identifier->address().c_str());
 
716
    my_error(ER_HANDSHAKE_ERROR, MYF(0), session->getSecurityContext().getIp().c_str());
767
717
    return false;
768
718
  }
769
719
 
779
729
 
780
730
  if (end >= (char*) net.read_pos + pkt_len + 2)
781
731
  {
782
 
    my_error(ER_HANDSHAKE_ERROR, MYF(0), user_identifier->address().c_str());
 
732
    my_error(ER_HANDSHAKE_ERROR, MYF(0), session->getSecurityContext().getIp().c_str());
783
733
    return false;
784
734
  }
785
735
 
803
753
    passwd_len= (unsigned char)(*passwd++);
804
754
    if (passwd_len > 0)
805
755
    {
806
 
      user_identifier->setPasswordType(identifier::User::MYSQL_HASH);
807
 
      user_identifier->setPasswordContext(scramble, SCRAMBLE_LENGTH);
 
756
      session->getSecurityContext().setPasswordType(SecurityContext::MYSQL_HASH);
 
757
      session->getSecurityContext().setPasswordContext(scramble, SCRAMBLE_LENGTH);
808
758
    }
809
759
  }
810
760
  else
811
 
  {
812
761
    passwd_len= 0;
813
 
  }
814
762
 
815
763
  if (client_capabilities & CLIENT_CONNECT_WITH_DB &&
816
764
      passwd < (char *) net.read_pos + pkt_len)
818
766
    l_db= l_db + passwd_len + 1;
819
767
  }
820
768
  else
821
 
  {
822
769
    l_db= NULL;
823
 
  }
824
770
 
825
771
  /* strlen() can't be easily deleted without changing client */
826
772
  uint32_t db_len= l_db ? strlen(l_db) : 0;
827
773
 
828
774
  if (passwd + passwd_len + db_len > (char *) net.read_pos + pkt_len)
829
775
  {
830
 
    my_error(ER_HANDSHAKE_ERROR, MYF(0), user_identifier->address().c_str());
 
776
    my_error(ER_HANDSHAKE_ERROR, MYF(0), session->getSecurityContext().getIp().c_str());
831
777
    return false;
832
778
  }
833
779
 
839
785
    user_len-= 2;
840
786
  }
841
787
 
842
 
  if (client_capabilities & CLIENT_ADMIN)
843
 
  {
844
 
    if ((strncmp(user, "root", 4) == 0) and isAdminAllowed())
845
 
    {
846
 
      is_admin_connection= true;
847
 
    }
848
 
    else
849
 
    {
850
 
      my_error(ER_ADMIN_ACCESS, MYF(0));
851
 
      return false;
852
 
    }
853
 
  }
854
 
 
855
 
  user_identifier->setUser(user);
856
 
  session->setUser(user_identifier);
857
 
 
858
 
  return session->checkUser(string(passwd, passwd_len),
859
 
                            string(l_db ? l_db : ""));
860
 
 
861
 
}
862
 
 
863
 
bool ClientMySQLProtocol::isAdminAllowed(void)
864
 
{
865
 
  if (std::find(mysql_admin_ip_addresses.begin(), mysql_admin_ip_addresses.end(), session->user()->address()) != mysql_admin_ip_addresses.end())
866
 
    return true;
867
 
 
868
 
  return false;
 
788
  session->getSecurityContext().setUser(user);
 
789
 
 
790
  return session->checkUser(passwd, passwd_len, l_db);
869
791
}
870
792
 
871
793
bool ClientMySQLProtocol::netStoreData(const unsigned char *from, size_t length)
960
882
  uint32_t pointer_seed;
961
883
  memcpy(&pointer_seed, &pointer, 4);
962
884
  uint32_t random1= (seed + pointer_seed) % random_max;
963
 
  uint32_t random2= (seed + session->variables.pseudo_thread_id + net.vio->get_fd()) % random_max;
 
885
  uint32_t random2= (seed + session->variables.pseudo_thread_id + net.vio->sd) % random_max;
964
886
 
965
887
  for (char *end= scramble + SCRAMBLE_LENGTH; scramble != end; scramble++)
966
888
  {
970
892
  }
971
893
}
972
894
 
973
 
void ClientMySQLProtocol::mysql_compose_ip_addresses(vector<string> options)
974
 
{
975
 
  for (vector<string>::iterator it= options.begin();
976
 
       it != options.end();
977
 
       ++it)
978
 
  {
979
 
    tokenize(*it, mysql_admin_ip_addresses, ",", true);
980
 
  }
981
 
}
982
 
 
983
895
static ListenMySQLProtocol *listen_obj= NULL;
984
896
plugin::Create_function<MySQLPassword> *mysql_password= NULL;
985
897
 
986
898
static int init(drizzled::module::Context &context)
987
899
{  
 
900
  mysql_status_table_function_ptr= new MysqlProtocolStatus;
 
901
 
 
902
  context.add(mysql_status_table_function_ptr);
988
903
  /* Initialize random seeds for the MySQL algorithm with minimal changes. */
989
904
  time_t seed_time= time(NULL);
990
905
  random_seed1= seed_time % random_max;
991
906
  random_seed2= (seed_time / 2) % random_max;
992
907
 
993
908
  const module::option_map &vm= context.getOptions();
 
909
  if (vm.count("port"))
 
910
  { 
 
911
    if (port > 65535)
 
912
    {
 
913
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value of port\n"));
 
914
      exit(-1);
 
915
    }
 
916
  }
 
917
 
 
918
  if (vm.count("connect-timeout"))
 
919
  {
 
920
    if (connect_timeout < 1 || connect_timeout > 300)
 
921
    {
 
922
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for connect_timeout\n"));
 
923
      exit(-1);
 
924
    }
 
925
  }
 
926
 
 
927
  if (vm.count("read-timeout"))
 
928
  {
 
929
    if (read_timeout < 1 || read_timeout > 300)
 
930
    {
 
931
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read_timeout\n"));
 
932
      exit(-1);
 
933
    }
 
934
  }
 
935
 
 
936
  if (vm.count("write-timeout"))
 
937
  {
 
938
    if (write_timeout < 1 || write_timeout > 300)
 
939
    {
 
940
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for write_timeout\n"));
 
941
      exit(-1);
 
942
    }
 
943
  }
 
944
 
 
945
  if (vm.count("retry-count"))
 
946
  {
 
947
    if (retry_count < 1 || retry_count > 100)
 
948
    {
 
949
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for retry_count"));
 
950
      exit(-1);
 
951
    }
 
952
  }
 
953
 
 
954
  if (vm.count("buffer-length"))
 
955
  {
 
956
    if (buffer_length < 1024 || buffer_length > 1024*1024)
 
957
    {
 
958
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for buffer_length\n"));
 
959
      exit(-1);
 
960
    }
 
961
  }
 
962
 
 
963
  if (vm.count("bind-address"))
 
964
  {
 
965
    bind_address= strdup(vm["bind-address"].as<string>().c_str());
 
966
  }
 
967
 
 
968
  else
 
969
  {
 
970
    bind_address= NULL;
 
971
  }
994
972
 
995
973
  mysql_password= new plugin::Create_function<MySQLPassword>(MySQLPasswordName);
996
974
  context.add(mysql_password);
997
975
 
998
 
  listen_obj= new ListenMySQLProtocol("mysql_protocol", vm["bind-address"].as<std::string>(), true);
999
 
  listen_obj->addCountersToTable();
 
976
  listen_obj= new ListenMySQLProtocol("mysql_protocol", true);
1000
977
  context.add(listen_obj); 
1001
 
  context.registerVariable(new sys_var_constrained_value_readonly<in_port_t>("port", port));
1002
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("connect_timeout", connect_timeout));
1003
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("read_timeout", read_timeout));
1004
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("write_timeout", write_timeout));
1005
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("retry_count", retry_count));
1006
 
  context.registerVariable(new sys_var_constrained_value<uint32_t>("buffer_length", buffer_length));
1007
 
  context.registerVariable(new sys_var_const_string_val("bind_address",
1008
 
                                                        vm["bind-address"].as<std::string>()));
1009
 
 
1010
 
  context.registerVariable(new sys_var_uint32_t_ptr("max-connections", &ListenMySQLProtocol::mysql_counters->max_connections));
1011
978
 
1012
979
  return 0;
1013
980
}
1014
981
 
 
982
static DRIZZLE_SYSVAR_UINT(port, port, PLUGIN_VAR_RQCMDARG,
 
983
                           N_("Port number to use for connection or 0 for default to with MySQL "
 
984
                              "protocol."),
 
985
                           NULL, NULL, 3306, 0, 65535, 0);
 
986
static DRIZZLE_SYSVAR_UINT(connect_timeout, connect_timeout,
 
987
                           PLUGIN_VAR_RQCMDARG, N_("Connect Timeout."),
 
988
                           NULL, NULL, 10, 1, 300, 0);
 
989
static DRIZZLE_SYSVAR_UINT(read_timeout, read_timeout, PLUGIN_VAR_RQCMDARG,
 
990
                           N_("Read Timeout."), NULL, NULL, 30, 1, 300, 0);
 
991
static DRIZZLE_SYSVAR_UINT(write_timeout, write_timeout, PLUGIN_VAR_RQCMDARG,
 
992
                           N_("Write Timeout."), NULL, NULL, 60, 1, 300, 0);
 
993
static DRIZZLE_SYSVAR_UINT(retry_count, retry_count, PLUGIN_VAR_RQCMDARG,
 
994
                           N_("Retry Count."), NULL, NULL, 10, 1, 100, 0);
 
995
static DRIZZLE_SYSVAR_UINT(buffer_length, buffer_length, PLUGIN_VAR_RQCMDARG,
 
996
                           N_("Buffer length."), NULL, NULL, 16384, 1024,
 
997
                           1024*1024, 0);
 
998
static DRIZZLE_SYSVAR_STR(bind_address, bind_address, PLUGIN_VAR_READONLY,
 
999
                          N_("Address to bind to."), NULL, NULL, NULL);
 
1000
 
1015
1001
static void init_options(drizzled::module::option_context &context)
1016
1002
{
1017
1003
  context("port",
1018
 
          po::value<port_constraint>(&port)->default_value(3306),
1019
 
          _("Port number to use for connection or 0 for default to with MySQL "
 
1004
          po::value<uint32_t>(&port)->default_value(3306),
 
1005
          N_("Port number to use for connection or 0 for default to with MySQL "
1020
1006
                              "protocol."));
1021
1007
  context("connect-timeout",
1022
 
          po::value<timeout_constraint>(&connect_timeout)->default_value(10),
1023
 
          _("Connect Timeout."));
 
1008
          po::value<uint32_t>(&connect_timeout)->default_value(10),
 
1009
          N_("Connect Timeout."));
1024
1010
  context("read-timeout",
1025
 
          po::value<timeout_constraint>(&read_timeout)->default_value(30),
1026
 
          _("Read Timeout."));
 
1011
          po::value<uint32_t>(&read_timeout)->default_value(30),
 
1012
          N_("Read Timeout."));
1027
1013
  context("write-timeout",
1028
 
          po::value<timeout_constraint>(&write_timeout)->default_value(60),
1029
 
          _("Write Timeout."));
 
1014
          po::value<uint32_t>(&write_timeout)->default_value(60),
 
1015
          N_("Write Timeout."));
1030
1016
  context("retry-count",
1031
 
          po::value<retry_constraint>(&retry_count)->default_value(10),
1032
 
          _("Retry Count."));
 
1017
          po::value<uint32_t>(&retry_count)->default_value(10),
 
1018
          N_("Retry Count."));
1033
1019
  context("buffer-length",
1034
 
          po::value<buffer_constraint>(&buffer_length)->default_value(16384),
1035
 
          _("Buffer length."));
 
1020
          po::value<uint32_t>(&buffer_length)->default_value(16384),
 
1021
          N_("Buffer length."));
1036
1022
  context("bind-address",
1037
 
          po::value<string>()->default_value(""),
1038
 
          _("Address to bind to."));
1039
 
  context("max-connections",
1040
 
          po::value<uint32_t>(&ListenMySQLProtocol::mysql_counters->max_connections)->default_value(1000),
1041
 
          _("Maximum simultaneous connections."));
1042
 
  context("admin-ip-addresses",
1043
 
          po::value<vector<string> >()->composing()->notifier(&ClientMySQLProtocol::mysql_compose_ip_addresses),
1044
 
          _("A restrictive IP address list for incoming admin connections."));
1045
 
}
1046
 
 
1047
 
} /* namespace drizzle_plugin */
 
1023
          po::value<string>(),
 
1024
          N_("Address to bind to."));
 
1025
}
 
1026
 
 
1027
static drizzle_sys_var* sys_variables[]= {
 
1028
  DRIZZLE_SYSVAR(port),
 
1029
  DRIZZLE_SYSVAR(connect_timeout),
 
1030
  DRIZZLE_SYSVAR(read_timeout),
 
1031
  DRIZZLE_SYSVAR(write_timeout),
 
1032
  DRIZZLE_SYSVAR(retry_count),
 
1033
  DRIZZLE_SYSVAR(buffer_length),
 
1034
  DRIZZLE_SYSVAR(bind_address),
 
1035
  NULL
 
1036
};
 
1037
 
 
1038
static int mysql_protocol_connection_count_func(drizzle_show_var *var, char *buff)
 
1039
{
 
1040
  var->type= SHOW_LONGLONG;
 
1041
  var->value= buff;
 
1042
  *((uint64_t *)buff)= ClientMySQLProtocol::connectionCount;
 
1043
  return 0;
 
1044
}
 
1045
 
 
1046
static int mysql_protocol_connected_count_func(drizzle_show_var *var, char *buff)
 
1047
{
 
1048
  var->type= SHOW_LONGLONG;
 
1049
  var->value= buff;
 
1050
  *((uint64_t *)buff)= ClientMySQLProtocol::connected;
 
1051
  return 0;
 
1052
}
 
1053
 
 
1054
static int mysql_protocol_failed_count_func(drizzle_show_var *var, char *buff)
 
1055
{
 
1056
  var->type= SHOW_LONGLONG;
 
1057
  var->value= buff;
 
1058
  *((uint64_t *)buff)= ClientMySQLProtocol::failedConnections;
 
1059
  return 0;
 
1060
}
 
1061
 
 
1062
static st_show_var_func_container mysql_protocol_connection_count=
 
1063
  { &mysql_protocol_connection_count_func };
 
1064
 
 
1065
static st_show_var_func_container mysql_protocol_connected_count=
 
1066
  { &mysql_protocol_connected_count_func };
 
1067
 
 
1068
static st_show_var_func_container mysql_protocol_failed_count=
 
1069
  { &mysql_protocol_failed_count_func };
 
1070
 
 
1071
static drizzle_show_var mysql_protocol_status_variables[]= {
 
1072
  {"Connections",
 
1073
  (char*) &mysql_protocol_connection_count, SHOW_FUNC},
 
1074
  {"Connected",
 
1075
  (char*) &mysql_protocol_connected_count, SHOW_FUNC},
 
1076
  {"Failed_connections",
 
1077
  (char*) &mysql_protocol_failed_count, SHOW_FUNC},
 
1078
  {NULL, NULL, SHOW_LONGLONG}
 
1079
};
 
1080
 
 
1081
MysqlProtocolStatus::Generator::Generator(drizzled::Field **fields) :
 
1082
  plugin::TableFunction::Generator(fields)
 
1083
{
 
1084
  status_var_ptr= mysql_protocol_status_variables;
 
1085
}
 
1086
 
 
1087
bool MysqlProtocolStatus::Generator::populate()
 
1088
{
 
1089
  MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, int64_t);
 
1090
  char * const buff= (char *) &buff_data;
 
1091
  drizzle_show_var tmp;
 
1092
 
 
1093
  if (status_var_ptr->name)
 
1094
  {
 
1095
    std::ostringstream oss;
 
1096
    string return_value;
 
1097
    const char *value;
 
1098
    int type;
 
1099
 
 
1100
    push(status_var_ptr->name);
 
1101
 
 
1102
    if (status_var_ptr->type == SHOW_FUNC)
 
1103
    {
 
1104
      ((mysql_show_var_func)((st_show_var_func_container *)status_var_ptr->value)->func)(&tmp, buff);
 
1105
      value= buff;
 
1106
      type= tmp.type;
 
1107
    }
 
1108
    else
 
1109
    {
 
1110
      value= status_var_ptr->value;
 
1111
      type= status_var_ptr->type;
 
1112
    }
 
1113
 
 
1114
    switch(type)
 
1115
    {
 
1116
    case SHOW_LONGLONG:
 
1117
      oss << *(uint64_t*) value;
 
1118
      return_value= oss.str();
 
1119
      break;
 
1120
    default:
 
1121
      assert(0);
 
1122
    }
 
1123
    if (return_value.length())
 
1124
      push(return_value);
 
1125
    else
 
1126
      push(" ");
 
1127
 
 
1128
    status_var_ptr++;
 
1129
 
 
1130
    return true;
 
1131
  }
 
1132
  return false;
 
1133
}
1048
1134
 
1049
1135
DRIZZLE_DECLARE_PLUGIN
1050
1136
{
1054
1140
  "Eric Day",
1055
1141
  "MySQL Protocol Module",
1056
1142
  PLUGIN_LICENSE_GPL,
1057
 
  drizzle_plugin::init,             /* Plugin Init */
1058
 
  NULL, /* depends */
1059
 
  drizzle_plugin::init_options    /* config options */
 
1143
  init,             /* Plugin Init */
 
1144
  sys_variables, /* system variables */
 
1145
  init_options    /* config options */
1060
1146
}
1061
1147
DRIZZLE_DECLARE_PLUGIN_END;