~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/mysql_protocol/mysql_protocol.cc

  • Committer: Patrick Crews
  • Date: 2011-01-29 14:17:35 UTC
  • mto: (2126.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 2127.
  • Revision ID: gleebix@gmail.com-20110129141735-3y2658vt5ur0a33o
Fixes to make test-dbqp

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
 
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
17
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
18
 */
19
19
 
20
20
#include "config.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
#include <drizzled/module/option_map.h>
 
30
#include "drizzled/util/tokenize.h"
29
31
#include "errmsg.h"
30
32
#include "mysql_protocol.h"
31
33
#include "mysql_password.h"
32
34
#include "options.h"
33
 
 
 
35
#include "table_function.h"
 
36
 
 
37
#include "drizzled/identifier.h"
 
38
 
 
39
#define PROTOCOL_VERSION 10
 
40
 
 
41
namespace po= boost::program_options;
34
42
using namespace std;
35
43
using namespace drizzled;
36
44
 
37
 
#define PROTOCOL_VERSION 10
38
 
 
39
 
namespace drizzled
 
45
namespace drizzle_plugin
40
46
{
41
 
extern uint32_t global_thread_id;
42
 
}
43
47
 
 
48
std::vector<std::string> ClientMySQLProtocol::mysql_admin_ip_addresses;
44
49
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
45
 
static uint32_t port;
46
 
static uint32_t connect_timeout;
47
 
static uint32_t read_timeout;
48
 
static uint32_t write_timeout;
49
 
static uint32_t retry_count;
50
 
static uint32_t buffer_length;
51
 
static char* bind_address;
 
50
 
 
51
static port_constraint port;
 
52
static timeout_constraint connect_timeout;
 
53
static timeout_constraint read_timeout;
 
54
static timeout_constraint write_timeout;
 
55
static retry_constraint retry_count;
 
56
static buffer_constraint buffer_length;
 
57
 
52
58
static uint32_t random_seed1;
53
59
static uint32_t random_seed2;
54
60
static const uint32_t random_max= 0x3FFFFFFF;
55
61
static const double random_max_double= (double)0x3FFFFFFF;
56
62
 
57
 
const char* ListenMySQLProtocol::getHost(void) const
 
63
 
 
64
ProtocolCounters *ListenMySQLProtocol::mysql_counters= new ProtocolCounters();
 
65
 
 
66
ListenMySQLProtocol::~ListenMySQLProtocol()
 
67
{ }
 
68
 
 
69
const std::string ListenMySQLProtocol::getHost(void) const
58
70
{
59
 
  return bind_address;
 
71
  return _hostname;
60
72
}
61
73
 
62
74
in_port_t ListenMySQLProtocol::getPort(void) const
63
75
{
64
 
  return (in_port_t) port;
 
76
  return port.get();
65
77
}
66
78
 
67
79
plugin::Client *ListenMySQLProtocol::getClient(int fd)
71
83
  if (new_fd == -1)
72
84
    return NULL;
73
85
 
74
 
  return new (nothrow) ClientMySQLProtocol(new_fd, using_mysql41_protocol);
 
86
  return new ClientMySQLProtocol(new_fd, _using_mysql41_protocol, getCounters());
75
87
}
76
88
 
77
 
ClientMySQLProtocol::ClientMySQLProtocol(int fd, bool using_mysql41_protocol_arg):
78
 
  using_mysql41_protocol(using_mysql41_protocol_arg)
 
89
ClientMySQLProtocol::ClientMySQLProtocol(int fd, bool using_mysql41_protocol, ProtocolCounters *set_counters):
 
90
  is_admin_connection(false),
 
91
  _using_mysql41_protocol(using_mysql41_protocol),
 
92
  counters(set_counters)
79
93
{
 
94
  
80
95
  net.vio= 0;
81
96
 
82
97
  if (fd == -1)
83
98
    return;
84
99
 
85
 
  if (drizzleclient_net_init_sock(&net, fd, buffer_length))
 
100
  if (drizzleclient_net_init_sock(&net, fd, buffer_length.get()))
86
101
    throw bad_alloc();
87
102
 
88
 
  drizzleclient_net_set_read_timeout(&net, read_timeout);
89
 
  drizzleclient_net_set_write_timeout(&net, write_timeout);
90
 
  net.retry_count=retry_count;
 
103
  drizzleclient_net_set_read_timeout(&net, read_timeout.get());
 
104
  drizzleclient_net_set_write_timeout(&net, write_timeout.get());
 
105
  net.retry_count=retry_count.get();
91
106
}
92
107
 
93
108
ClientMySQLProtocol::~ClientMySQLProtocol()
94
109
{
95
110
  if (net.vio)
96
 
    vio_close(net.vio);
 
111
    net.vio->close();
97
112
}
98
113
 
99
114
int ClientMySQLProtocol::getFileDescriptor(void)
132
147
  { 
133
148
    drizzleclient_net_close(&net);
134
149
    drizzleclient_net_end(&net);
 
150
    if (is_admin_connection)
 
151
      counters->adminConnected.decrement();
 
152
    else
 
153
      counters->connected.decrement();
135
154
  }
136
155
}
137
156
 
138
157
bool ClientMySQLProtocol::authenticate()
139
158
{
140
159
  bool connection_is_valid;
 
160
  if (is_admin_connection)
 
161
  {
 
162
    counters->adminConnectionCount.increment();
 
163
    counters->adminConnected.increment();
 
164
  }
 
165
  else
 
166
  {
 
167
    counters->connectionCount.increment();
 
168
    counters->connected.increment();
 
169
  }
141
170
 
142
171
  /* Use "connect_timeout" value during connection phase */
143
 
  drizzleclient_net_set_read_timeout(&net, connect_timeout);
144
 
  drizzleclient_net_set_write_timeout(&net, connect_timeout);
 
172
  drizzleclient_net_set_read_timeout(&net, connect_timeout.get());
 
173
  drizzleclient_net_set_write_timeout(&net, connect_timeout.get());
145
174
 
146
175
  connection_is_valid= checkConnection();
147
176
 
148
177
  if (connection_is_valid)
149
 
    sendOK();
 
178
  {
 
179
    if (not is_admin_connection and (counters->connected > counters->max_connections))
 
180
    {
 
181
      std::string errmsg(ER(ER_CON_COUNT_ERROR));
 
182
      sendError(ER_CON_COUNT_ERROR, errmsg.c_str());
 
183
      counters->failedConnections.increment();
 
184
    }
 
185
    else
 
186
    {
 
187
      sendOK();
 
188
    }
 
189
  }
150
190
  else
151
191
  {
152
192
    sendError(session->main_da.sql_errno(), session->main_da.message());
 
193
    counters->failedConnections.increment();
153
194
    return false;
154
195
  }
155
196
 
156
197
  /* Connect completed, set read/write timeouts back to default */
157
 
  drizzleclient_net_set_read_timeout(&net, read_timeout);
158
 
  drizzleclient_net_set_write_timeout(&net, write_timeout);
 
198
  drizzleclient_net_set_read_timeout(&net, read_timeout.get());
 
199
  drizzleclient_net_set_write_timeout(&net, write_timeout.get());
159
200
  return true;
160
201
}
161
202
 
192
233
      return false;                       // We have to close it.
193
234
 
194
235
    net.error= 0;
195
 
    *packet_length= 0;
196
 
    return true;
197
236
  }
198
237
 
199
238
  *l_packet= (char*) net.read_pos;
213
252
    (*l_packet)[0]= (unsigned char) COM_SLEEP;
214
253
    *packet_length= 1;
215
254
  }
216
 
  else if (using_mysql41_protocol)
 
255
  else if (_using_mysql41_protocol)
217
256
  {
218
257
    /* Map from MySQL commands to Drizzle commands. */
219
258
    switch ((int)(*l_packet)[0])
353
392
    drizzleclient_net_flush(&net);
354
393
    session->main_da.can_overwrite_status= false;
355
394
  }
356
 
  packet.shrink(buffer_length);
 
395
  packet.shrink(buffer_length.get());
357
396
}
358
397
 
359
398
 
406
445
 
407
446
  drizzleclient_net_write_command(&net,(unsigned char) 255, (unsigned char*) "", 0, (unsigned char*) err, length);
408
447
 
 
448
  drizzleclient_net_flush(&net);
 
449
 
409
450
  session->main_da.can_overwrite_status= false;
410
451
}
411
452
 
461
502
    int2store(pos, field.charsetnr);
462
503
    int4store(pos+2, field.length);
463
504
 
464
 
    if (using_mysql41_protocol)
 
505
    if (_using_mysql41_protocol)
465
506
    {
466
507
      /* Switch to MySQL field numbering. */
467
508
      switch (field.type)
490
531
        pos[6]= 12;
491
532
        break;
492
533
 
 
534
      case DRIZZLE_TYPE_TIME:
 
535
        pos[6]= 13;
 
536
        break;
 
537
 
493
538
      case DRIZZLE_TYPE_DATE:
494
539
        pos[6]= 14;
495
540
        break;
498
543
        pos[6]= 15;
499
544
        break;
500
545
 
 
546
      case DRIZZLE_TYPE_MICROTIME:
 
547
        pos[6]= 15;
 
548
        break;
 
549
 
 
550
      case DRIZZLE_TYPE_UUID:
 
551
        pos[6]= 15;
 
552
        break;
 
553
 
 
554
      case DRIZZLE_TYPE_BOOLEAN:
 
555
        pos[6]= 15;
 
556
        break;
 
557
 
501
558
      case DRIZZLE_TYPE_DECIMAL:
502
559
        pos[6]= (char)246;
503
560
        break;
549
606
  char buff[MAX_FIELD_WIDTH];
550
607
  String str(buff,sizeof(buff), &my_charset_bin);
551
608
 
552
 
  from->val_str(&str);
 
609
  from->val_str_internal(&str);
553
610
 
554
611
  return netStoreData((const unsigned char *)str.ptr(), str.length());
555
612
}
620
677
  uint32_t pkt_len= 0;
621
678
  char *end;
622
679
  char scramble[SCRAMBLE_LENGTH];
 
680
  identifier::User::shared_ptr user_identifier= identifier::User::make_shared();
623
681
 
624
682
  makeScramble(scramble);
625
683
 
630
688
 
631
689
    if (drizzleclient_net_peer_addr(&net, ip, &peer_port, NI_MAXHOST))
632
690
    {
633
 
      my_error(ER_BAD_HOST_ERROR, MYF(0), session->getSecurityContext().getIp().c_str());
 
691
      my_error(ER_BAD_HOST_ERROR, MYF(0), ip);
634
692
      return false;
635
693
    }
636
694
 
637
 
    session->getSecurityContext().setIp(ip);
 
695
    user_identifier->setAddress(ip);
638
696
  }
639
697
  drizzleclient_net_keepalive(&net, true);
640
698
 
645
703
 
646
704
    server_capabilites= CLIENT_BASIC_FLAGS;
647
705
 
648
 
    if (using_mysql41_protocol)
 
706
    if (_using_mysql41_protocol)
649
707
      server_capabilites|= CLIENT_PROTOCOL_MYSQL41;
650
708
 
651
709
#ifdef HAVE_COMPRESS
652
710
    server_capabilites|= CLIENT_COMPRESS;
653
711
#endif /* HAVE_COMPRESS */
654
712
 
655
 
    end= buff + strlen(VERSION);
 
713
    end= buff + strlen(PANDORA_RELEASE_VERSION);
656
714
    if ((end - buff) >= SERVER_VERSION_LENGTH)
657
715
      end= buff + (SERVER_VERSION_LENGTH - 1);
658
 
    memcpy(buff, VERSION, end - buff);
 
716
    memcpy(buff, PANDORA_RELEASE_VERSION, end - buff);
659
717
    *end= 0;
660
718
    end++;
661
719
 
662
 
    int4store((unsigned char*) end, global_thread_id);
 
720
    int4store((unsigned char*) end, session->variables.pseudo_thread_id);
663
721
    end+= 4;
664
722
 
665
723
    /* We don't use scramble anymore. */
689
747
        ||    (pkt_len= drizzleclient_net_read(&net)) == packet_error 
690
748
        || pkt_len < MIN_HANDSHAKE_SIZE)
691
749
    {
692
 
      my_error(ER_HANDSHAKE_ERROR, MYF(0), session->getSecurityContext().getIp().c_str());
 
750
      my_error(ER_HANDSHAKE_ERROR, MYF(0), user_identifier->address().c_str());
693
751
      return false;
694
752
    }
695
753
  }
696
 
  if (packet.alloc(buffer_length))
 
754
  if (packet.alloc(buffer_length.get()))
697
755
    return false; /* The error is set by alloc(). */
698
756
 
699
757
  client_capabilities= uint2korr(net.read_pos);
700
758
  if (!(client_capabilities & CLIENT_PROTOCOL_MYSQL41))
701
759
  {
702
 
    my_error(ER_HANDSHAKE_ERROR, MYF(0), session->getSecurityContext().getIp().c_str());
 
760
    my_error(ER_HANDSHAKE_ERROR, MYF(0), user_identifier->address().c_str());
703
761
    return false;
704
762
  }
705
763
 
715
773
 
716
774
  if (end >= (char*) net.read_pos + pkt_len + 2)
717
775
  {
718
 
    my_error(ER_HANDSHAKE_ERROR, MYF(0), session->getSecurityContext().getIp().c_str());
 
776
    my_error(ER_HANDSHAKE_ERROR, MYF(0), user_identifier->address().c_str());
719
777
    return false;
720
778
  }
721
779
 
739
797
    passwd_len= (unsigned char)(*passwd++);
740
798
    if (passwd_len > 0)
741
799
    {
742
 
      session->getSecurityContext().setPasswordType(SecurityContext::MYSQL_HASH);
743
 
      session->getSecurityContext().setPasswordContext(scramble, SCRAMBLE_LENGTH);
 
800
      user_identifier->setPasswordType(identifier::User::MYSQL_HASH);
 
801
      user_identifier->setPasswordContext(scramble, SCRAMBLE_LENGTH);
744
802
    }
745
803
  }
746
804
  else
 
805
  {
747
806
    passwd_len= 0;
 
807
  }
748
808
 
749
809
  if (client_capabilities & CLIENT_CONNECT_WITH_DB &&
750
810
      passwd < (char *) net.read_pos + pkt_len)
752
812
    l_db= l_db + passwd_len + 1;
753
813
  }
754
814
  else
 
815
  {
755
816
    l_db= NULL;
 
817
  }
756
818
 
757
819
  /* strlen() can't be easily deleted without changing client */
758
820
  uint32_t db_len= l_db ? strlen(l_db) : 0;
759
821
 
760
822
  if (passwd + passwd_len + db_len > (char *) net.read_pos + pkt_len)
761
823
  {
762
 
    my_error(ER_HANDSHAKE_ERROR, MYF(0), session->getSecurityContext().getIp().c_str());
 
824
    my_error(ER_HANDSHAKE_ERROR, MYF(0), user_identifier->address().c_str());
763
825
    return false;
764
826
  }
765
827
 
771
833
    user_len-= 2;
772
834
  }
773
835
 
774
 
  session->getSecurityContext().setUser(user);
775
 
 
776
 
  return session->checkUser(passwd, passwd_len, l_db);
 
836
  if (client_capabilities & CLIENT_ADMIN)
 
837
  {
 
838
    if ((strncmp(user, "root", 4) == 0) and isAdminAllowed())
 
839
    {
 
840
      is_admin_connection= true;
 
841
    }
 
842
    else
 
843
    {
 
844
      my_error(ER_ADMIN_ACCESS, MYF(0));
 
845
      return false;
 
846
    }
 
847
  }
 
848
 
 
849
  user_identifier->setUser(user);
 
850
  session->setUser(user_identifier);
 
851
 
 
852
  return session->checkUser(string(passwd, passwd_len),
 
853
                            string(l_db ? l_db : ""));
 
854
 
 
855
}
 
856
 
 
857
bool ClientMySQLProtocol::isAdminAllowed(void)
 
858
{
 
859
  if (std::find(mysql_admin_ip_addresses.begin(), mysql_admin_ip_addresses.end(), session->user()->address()) != mysql_admin_ip_addresses.end())
 
860
    return true;
 
861
 
 
862
  return false;
777
863
}
778
864
 
779
865
bool ClientMySQLProtocol::netStoreData(const unsigned char *from, size_t length)
868
954
  uint32_t pointer_seed;
869
955
  memcpy(&pointer_seed, &pointer, 4);
870
956
  uint32_t random1= (seed + pointer_seed) % random_max;
871
 
  uint32_t random2= (seed + global_thread_id + net.vio->sd) % random_max;
 
957
  uint32_t random2= (seed + session->variables.pseudo_thread_id + net.vio->get_fd()) % random_max;
872
958
 
873
959
  for (char *end= scramble + SCRAMBLE_LENGTH; scramble != end; scramble++)
874
960
  {
878
964
  }
879
965
}
880
966
 
 
967
void ClientMySQLProtocol::mysql_compose_ip_addresses(vector<string> options)
 
968
{
 
969
  for (vector<string>::iterator it= options.begin();
 
970
       it != options.end();
 
971
       ++it)
 
972
  {
 
973
    tokenize(*it, mysql_admin_ip_addresses, ",", true);
 
974
  }
 
975
}
 
976
 
881
977
static ListenMySQLProtocol *listen_obj= NULL;
882
978
plugin::Create_function<MySQLPassword> *mysql_password= NULL;
883
979
 
884
 
static int init(drizzled::plugin::Context &context)
885
 
{
 
980
static int init(drizzled::module::Context &context)
 
981
{  
 
982
  context.add(new MysqlProtocolStatus);
 
983
 
886
984
  /* Initialize random seeds for the MySQL algorithm with minimal changes. */
887
985
  time_t seed_time= time(NULL);
888
986
  random_seed1= seed_time % random_max;
889
987
  random_seed2= (seed_time / 2) % random_max;
890
988
 
 
989
  const module::option_map &vm= context.getOptions();
 
990
 
891
991
  mysql_password= new plugin::Create_function<MySQLPassword>(MySQLPasswordName);
892
992
  context.add(mysql_password);
893
993
 
894
 
  listen_obj= new ListenMySQLProtocol("mysql_protocol", true);
 
994
  listen_obj= new ListenMySQLProtocol("mysql_protocol", vm["bind-address"].as<std::string>(), true);
895
995
  context.add(listen_obj); 
896
 
 
897
 
  return 0;
898
 
}
899
 
 
900
 
static DRIZZLE_SYSVAR_UINT(port, port, PLUGIN_VAR_RQCMDARG,
901
 
                           N_("Port number to use for connection or 0 for default to with MySQL "
902
 
                              "protocol."),
903
 
                           NULL, NULL, 3306, 0, 65535, 0);
904
 
static DRIZZLE_SYSVAR_UINT(connect_timeout, connect_timeout,
905
 
                           PLUGIN_VAR_RQCMDARG, N_("Connect Timeout."),
906
 
                           NULL, NULL, 10, 1, 300, 0);
907
 
static DRIZZLE_SYSVAR_UINT(read_timeout, read_timeout, PLUGIN_VAR_RQCMDARG,
908
 
                           N_("Read Timeout."), NULL, NULL, 30, 1, 300, 0);
909
 
static DRIZZLE_SYSVAR_UINT(write_timeout, write_timeout, PLUGIN_VAR_RQCMDARG,
910
 
                           N_("Write Timeout."), NULL, NULL, 60, 1, 300, 0);
911
 
static DRIZZLE_SYSVAR_UINT(retry_count, retry_count, PLUGIN_VAR_RQCMDARG,
912
 
                           N_("Retry Count."), NULL, NULL, 10, 1, 100, 0);
913
 
static DRIZZLE_SYSVAR_UINT(buffer_length, buffer_length, PLUGIN_VAR_RQCMDARG,
914
 
                           N_("Buffer length."), NULL, NULL, 16384, 1024,
915
 
                           1024*1024, 0);
916
 
static DRIZZLE_SYSVAR_STR(bind_address, bind_address, PLUGIN_VAR_READONLY,
917
 
                          N_("Address to bind to."), NULL, NULL, NULL);
918
 
 
919
 
static drizzle_sys_var* sys_variables[]= {
920
 
  DRIZZLE_SYSVAR(port),
921
 
  DRIZZLE_SYSVAR(connect_timeout),
922
 
  DRIZZLE_SYSVAR(read_timeout),
923
 
  DRIZZLE_SYSVAR(write_timeout),
924
 
  DRIZZLE_SYSVAR(retry_count),
925
 
  DRIZZLE_SYSVAR(buffer_length),
926
 
  DRIZZLE_SYSVAR(bind_address),
927
 
  NULL
 
996
  context.registerVariable(new sys_var_constrained_value_readonly<in_port_t>("port", port));
 
997
  context.registerVariable(new sys_var_constrained_value<uint32_t>("connect_timeout", connect_timeout));
 
998
  context.registerVariable(new sys_var_constrained_value<uint32_t>("read_timeout", read_timeout));
 
999
  context.registerVariable(new sys_var_constrained_value<uint32_t>("write_timeout", write_timeout));
 
1000
  context.registerVariable(new sys_var_constrained_value<uint32_t>("retry_count", retry_count));
 
1001
  context.registerVariable(new sys_var_constrained_value<uint32_t>("buffer_length", buffer_length));
 
1002
  context.registerVariable(new sys_var_const_string_val("bind_address",
 
1003
                                                        vm["bind-address"].as<std::string>()));
 
1004
 
 
1005
  context.registerVariable(new sys_var_uint32_t_ptr("max-connections", &ListenMySQLProtocol::mysql_counters->max_connections));
 
1006
 
 
1007
  return 0;
 
1008
}
 
1009
 
 
1010
static void init_options(drizzled::module::option_context &context)
 
1011
{
 
1012
  context("port",
 
1013
          po::value<port_constraint>(&port)->default_value(3306),
 
1014
          _("Port number to use for connection or 0 for default to with MySQL "
 
1015
                              "protocol."));
 
1016
  context("connect-timeout",
 
1017
          po::value<timeout_constraint>(&connect_timeout)->default_value(10),
 
1018
          _("Connect Timeout."));
 
1019
  context("read-timeout",
 
1020
          po::value<timeout_constraint>(&read_timeout)->default_value(30),
 
1021
          _("Read Timeout."));
 
1022
  context("write-timeout",
 
1023
          po::value<timeout_constraint>(&write_timeout)->default_value(60),
 
1024
          _("Write Timeout."));
 
1025
  context("retry-count",
 
1026
          po::value<retry_constraint>(&retry_count)->default_value(10),
 
1027
          _("Retry Count."));
 
1028
  context("buffer-length",
 
1029
          po::value<buffer_constraint>(&buffer_length)->default_value(16384),
 
1030
          _("Buffer length."));
 
1031
  context("bind-address",
 
1032
          po::value<string>()->default_value(""),
 
1033
          _("Address to bind to."));
 
1034
  context("max-connections",
 
1035
          po::value<uint32_t>(&ListenMySQLProtocol::mysql_counters->max_connections)->default_value(1000),
 
1036
          _("Maximum simultaneous connections."));
 
1037
  context("admin-ip-addresses",
 
1038
          po::value<vector<string> >()->composing()->notifier(&ClientMySQLProtocol::mysql_compose_ip_addresses),
 
1039
          _("A restrictive IP address list for incoming admin connections."));
 
1040
}
 
1041
 
 
1042
static int mysql_protocol_connection_count_func(drizzle_show_var *var, char *buff)
 
1043
{
 
1044
  var->type= SHOW_LONGLONG;
 
1045
  var->value= buff;
 
1046
  *((uint64_t *)buff)= ListenMySQLProtocol::mysql_counters->connectionCount;
 
1047
  return 0;
 
1048
}
 
1049
 
 
1050
static int mysql_protocol_connected_count_func(drizzle_show_var *var, char *buff)
 
1051
{
 
1052
  var->type= SHOW_LONGLONG;
 
1053
  var->value= buff;
 
1054
  *((uint64_t *)buff)= ListenMySQLProtocol::mysql_counters->connected;
 
1055
  return 0;
 
1056
}
 
1057
 
 
1058
static int mysql_protocol_failed_count_func(drizzle_show_var *var, char *buff)
 
1059
{
 
1060
  var->type= SHOW_LONGLONG;
 
1061
  var->value= buff;
 
1062
  *((uint64_t *)buff)= ListenMySQLProtocol::mysql_counters->failedConnections;
 
1063
  return 0;
 
1064
}
 
1065
 
 
1066
static st_show_var_func_container mysql_protocol_connection_count=
 
1067
  { &mysql_protocol_connection_count_func };
 
1068
 
 
1069
static st_show_var_func_container mysql_protocol_connected_count=
 
1070
  { &mysql_protocol_connected_count_func };
 
1071
 
 
1072
static st_show_var_func_container mysql_protocol_failed_count=
 
1073
  { &mysql_protocol_failed_count_func };
 
1074
 
 
1075
static drizzle_show_var mysql_protocol_status_variables[]= {
 
1076
  {"Connections",
 
1077
  (char*) &mysql_protocol_connection_count, SHOW_FUNC},
 
1078
  {"Connected",
 
1079
  (char*) &mysql_protocol_connected_count, SHOW_FUNC},
 
1080
  {"Failed_connections",
 
1081
  (char*) &mysql_protocol_failed_count, SHOW_FUNC},
 
1082
  {NULL, NULL, SHOW_LONGLONG}
928
1083
};
929
1084
 
 
1085
MysqlProtocolStatus::Generator::Generator(drizzled::Field **fields) :
 
1086
  plugin::TableFunction::Generator(fields)
 
1087
{
 
1088
  status_var_ptr= mysql_protocol_status_variables;
 
1089
}
 
1090
 
 
1091
bool MysqlProtocolStatus::Generator::populate()
 
1092
{
 
1093
  MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, int64_t);
 
1094
  char * const buff= (char *) &buff_data;
 
1095
  drizzle_show_var tmp;
 
1096
 
 
1097
  if (status_var_ptr->name)
 
1098
  {
 
1099
    std::ostringstream oss;
 
1100
    string return_value;
 
1101
    const char *value;
 
1102
    int type;
 
1103
 
 
1104
    push(status_var_ptr->name);
 
1105
 
 
1106
    if (status_var_ptr->type == SHOW_FUNC)
 
1107
    {
 
1108
      ((drizzle_show_var_func)((st_show_var_func_container *)status_var_ptr->value)->func)(&tmp, buff);
 
1109
      value= buff;
 
1110
      type= tmp.type;
 
1111
    }
 
1112
    else
 
1113
    {
 
1114
      value= status_var_ptr->value;
 
1115
      type= status_var_ptr->type;
 
1116
    }
 
1117
 
 
1118
    switch(type)
 
1119
    {
 
1120
    case SHOW_LONGLONG:
 
1121
      oss << *(uint64_t*) value;
 
1122
      return_value= oss.str();
 
1123
      break;
 
1124
    default:
 
1125
      assert(0);
 
1126
    }
 
1127
    if (return_value.length())
 
1128
      push(return_value);
 
1129
    else
 
1130
      push(" ");
 
1131
 
 
1132
    status_var_ptr++;
 
1133
 
 
1134
    return true;
 
1135
  }
 
1136
  return false;
 
1137
}
 
1138
 
 
1139
} /* namespace drizzle_plugin */
 
1140
 
930
1141
DRIZZLE_DECLARE_PLUGIN
931
1142
{
932
1143
  DRIZZLE_VERSION_ID,
933
 
  "mysql_protocol",
 
1144
  "mysql-protocol",
934
1145
  "0.1",
935
1146
  "Eric Day",
936
1147
  "MySQL Protocol Module",
937
1148
  PLUGIN_LICENSE_GPL,
938
 
  init,             /* Plugin Init */
939
 
  sys_variables, /* system variables */
940
 
  NULL              /* config options */
 
1149
  drizzle_plugin::init,             /* Plugin Init */
 
1150
  NULL, /* depends */
 
1151
  drizzle_plugin::init_options    /* config options */
941
1152
}
942
1153
DRIZZLE_DECLARE_PLUGIN_END;