~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/mysql_protocol/mysql_protocol.cc

  • Committer: Andrew Hutchings
  • Date: 2010-12-06 19:36:53 UTC
  • mfrom: (1976 staging)
  • mto: This revision was merged to the branch mainline in revision 1991.
  • Revision ID: andrew@linuxjedi.co.uk-20101206193653-l85vryv18jb0yxx8
Merge with trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include "options.h"
34
34
#include "table_function.h"
35
35
 
 
36
#define PROTOCOL_VERSION 10
 
37
 
36
38
namespace po= boost::program_options;
37
39
using namespace std;
38
40
using namespace drizzled;
39
41
 
40
 
#define PROTOCOL_VERSION 10
 
42
namespace drizzle_plugin
 
43
{
41
44
 
42
45
static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
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;
 
46
 
 
47
static port_constraint port;
 
48
static timeout_constraint connect_timeout;
 
49
static timeout_constraint read_timeout;
 
50
static timeout_constraint write_timeout;
 
51
static retry_constraint retry_count;
 
52
static buffer_constraint buffer_length;
 
53
 
50
54
static uint32_t random_seed1;
51
55
static uint32_t random_seed2;
52
56
static const uint32_t random_max= 0x3FFFFFFF;
53
57
static const double random_max_double= (double)0x3FFFFFFF;
54
58
 
55
 
static plugin::TableFunction* mysql_status_table_function_ptr= NULL;
56
59
 
57
60
ProtocolCounters *ListenMySQLProtocol::mysql_counters= new ProtocolCounters();
58
61
 
59
62
ListenMySQLProtocol::~ListenMySQLProtocol()
60
 
{
61
 
  /* This is strdup'd from the options */
62
 
  free(bind_address);
63
 
}
 
63
{ }
64
64
 
65
 
const char* ListenMySQLProtocol::getHost(void) const
 
65
const std::string ListenMySQLProtocol::getHost(void) const
66
66
{
67
 
  return bind_address;
 
67
  return _hostname;
68
68
}
69
69
 
70
70
in_port_t ListenMySQLProtocol::getPort(void) const
71
71
{
72
 
  return (in_port_t) port;
 
72
  return port.get();
73
73
}
74
74
 
75
75
plugin::Client *ListenMySQLProtocol::getClient(int fd)
79
79
  if (new_fd == -1)
80
80
    return NULL;
81
81
 
82
 
  return new (nothrow) ClientMySQLProtocol(new_fd, using_mysql41_protocol, getCounters());
 
82
  return new ClientMySQLProtocol(new_fd, _using_mysql41_protocol, getCounters());
83
83
}
84
84
 
85
 
ClientMySQLProtocol::ClientMySQLProtocol(int fd, bool using_mysql41_protocol_arg, ProtocolCounters *set_counters):
86
 
  using_mysql41_protocol(using_mysql41_protocol_arg),
 
85
ClientMySQLProtocol::ClientMySQLProtocol(int fd, bool using_mysql41_protocol, ProtocolCounters *set_counters):
 
86
  _using_mysql41_protocol(using_mysql41_protocol),
87
87
  counters(set_counters)
88
88
{
 
89
  
89
90
  net.vio= 0;
90
91
 
91
92
  if (fd == -1)
92
93
    return;
93
94
 
94
 
  if (drizzleclient_net_init_sock(&net, fd, buffer_length))
 
95
  if (drizzleclient_net_init_sock(&net, fd, buffer_length.get()))
95
96
    throw bad_alloc();
96
97
 
97
 
  drizzleclient_net_set_read_timeout(&net, read_timeout);
98
 
  drizzleclient_net_set_write_timeout(&net, write_timeout);
99
 
  net.retry_count=retry_count;
 
98
  drizzleclient_net_set_read_timeout(&net, read_timeout.get());
 
99
  drizzleclient_net_set_write_timeout(&net, write_timeout.get());
 
100
  net.retry_count=retry_count.get();
100
101
}
101
102
 
102
103
ClientMySQLProtocol::~ClientMySQLProtocol()
153
154
  counters->connected.increment();
154
155
 
155
156
  /* Use "connect_timeout" value during connection phase */
156
 
  drizzleclient_net_set_read_timeout(&net, connect_timeout);
157
 
  drizzleclient_net_set_write_timeout(&net, connect_timeout);
 
157
  drizzleclient_net_set_read_timeout(&net, connect_timeout.get());
 
158
  drizzleclient_net_set_write_timeout(&net, connect_timeout.get());
158
159
 
159
160
  connection_is_valid= checkConnection();
160
161
 
174
175
  }
175
176
 
176
177
  /* Connect completed, set read/write timeouts back to default */
177
 
  drizzleclient_net_set_read_timeout(&net, read_timeout);
178
 
  drizzleclient_net_set_write_timeout(&net, write_timeout);
 
178
  drizzleclient_net_set_read_timeout(&net, read_timeout.get());
 
179
  drizzleclient_net_set_write_timeout(&net, write_timeout.get());
179
180
  return true;
180
181
}
181
182
 
231
232
    (*l_packet)[0]= (unsigned char) COM_SLEEP;
232
233
    *packet_length= 1;
233
234
  }
234
 
  else if (using_mysql41_protocol)
 
235
  else if (_using_mysql41_protocol)
235
236
  {
236
237
    /* Map from MySQL commands to Drizzle commands. */
237
238
    switch ((int)(*l_packet)[0])
371
372
    drizzleclient_net_flush(&net);
372
373
    session->main_da.can_overwrite_status= false;
373
374
  }
374
 
  packet.shrink(buffer_length);
 
375
  packet.shrink(buffer_length.get());
375
376
}
376
377
 
377
378
 
481
482
    int2store(pos, field.charsetnr);
482
483
    int4store(pos+2, field.length);
483
484
 
484
 
    if (using_mysql41_protocol)
 
485
    if (_using_mysql41_protocol)
485
486
    {
486
487
      /* Switch to MySQL field numbering. */
487
488
      switch (field.type)
665
666
 
666
667
    server_capabilites= CLIENT_BASIC_FLAGS;
667
668
 
668
 
    if (using_mysql41_protocol)
 
669
    if (_using_mysql41_protocol)
669
670
      server_capabilites|= CLIENT_PROTOCOL_MYSQL41;
670
671
 
671
672
#ifdef HAVE_COMPRESS
713
714
      return false;
714
715
    }
715
716
  }
716
 
  if (packet.alloc(buffer_length))
 
717
  if (packet.alloc(buffer_length.get()))
717
718
    return false; /* The error is set by alloc(). */
718
719
 
719
720
  client_capabilities= uint2korr(net.read_pos);
905
906
 
906
907
static int init(drizzled::module::Context &context)
907
908
{  
908
 
  mysql_status_table_function_ptr= new MysqlProtocolStatus;
 
909
  context.add(new MysqlProtocolStatus);
909
910
 
910
 
  context.add(mysql_status_table_function_ptr);
911
911
  /* Initialize random seeds for the MySQL algorithm with minimal changes. */
912
912
  time_t seed_time= time(NULL);
913
913
  random_seed1= seed_time % random_max;
914
914
  random_seed2= (seed_time / 2) % random_max;
915
915
 
916
916
  const module::option_map &vm= context.getOptions();
917
 
  if (vm.count("port"))
918
 
  { 
919
 
    if (port > 65535)
920
 
    {
921
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value of port\n"));
922
 
      exit(-1);
923
 
    }
924
 
  }
925
 
 
926
 
  if (vm.count("connect-timeout"))
927
 
  {
928
 
    if (connect_timeout < 1 || connect_timeout > 300)
929
 
    {
930
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for connect_timeout\n"));
931
 
      exit(-1);
932
 
    }
933
 
  }
934
 
 
935
 
  if (vm.count("read-timeout"))
936
 
  {
937
 
    if (read_timeout < 1 || read_timeout > 300)
938
 
    {
939
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for read_timeout\n"));
940
 
      exit(-1);
941
 
    }
942
 
  }
943
 
 
944
 
  if (vm.count("write-timeout"))
945
 
  {
946
 
    if (write_timeout < 1 || write_timeout > 300)
947
 
    {
948
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for write_timeout\n"));
949
 
      exit(-1);
950
 
    }
951
 
  }
952
 
 
953
 
  if (vm.count("retry-count"))
954
 
  {
955
 
    if (retry_count < 1 || retry_count > 100)
956
 
    {
957
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for retry_count"));
958
 
      exit(-1);
959
 
    }
960
 
  }
961
 
 
962
 
  if (vm.count("buffer-length"))
963
 
  {
964
 
    if (buffer_length < 1024 || buffer_length > 1024*1024)
965
 
    {
966
 
      errmsg_printf(ERRMSG_LVL_ERROR, _("Invalid value for buffer_length\n"));
967
 
      exit(-1);
968
 
    }
969
 
  }
970
 
 
971
 
  if (vm.count("bind-address"))
972
 
  {
973
 
    bind_address= strdup(vm["bind-address"].as<string>().c_str());
974
 
  }
975
 
 
976
 
  else
977
 
  {
978
 
    bind_address= NULL;
979
 
  }
980
917
 
981
918
  mysql_password= new plugin::Create_function<MySQLPassword>(MySQLPasswordName);
982
919
  context.add(mysql_password);
983
920
 
984
 
  listen_obj= new ListenMySQLProtocol("mysql_protocol", true);
 
921
  listen_obj= new ListenMySQLProtocol("mysql_protocol", vm["bind-address"].as<std::string>(), true);
985
922
  context.add(listen_obj); 
 
923
  context.registerVariable(new sys_var_constrained_value_readonly<in_port_t>("port", port));
 
924
  context.registerVariable(new sys_var_constrained_value<uint32_t>("connect_timeout", connect_timeout));
 
925
  context.registerVariable(new sys_var_constrained_value<uint32_t>("read_timeout", read_timeout));
 
926
  context.registerVariable(new sys_var_constrained_value<uint32_t>("write_timeout", write_timeout));
 
927
  context.registerVariable(new sys_var_constrained_value<uint32_t>("retry_count", retry_count));
 
928
  context.registerVariable(new sys_var_constrained_value<uint32_t>("buffer_length", buffer_length));
 
929
  context.registerVariable(new sys_var_const_string_val("bind_address",
 
930
                                                        vm["bind-address"].as<std::string>()));
986
931
 
987
932
  context.registerVariable(new sys_var_uint32_t_ptr("max-connections", &ListenMySQLProtocol::mysql_counters->max_connections));
988
933
 
989
934
  return 0;
990
935
}
991
936
 
992
 
static DRIZZLE_SYSVAR_UINT(port, port, PLUGIN_VAR_RQCMDARG,
993
 
                           N_("Port number to use for connection or 0 for default to with MySQL "
994
 
                              "protocol."),
995
 
                           NULL, NULL, 3306, 0, 65535, 0);
996
 
static DRIZZLE_SYSVAR_UINT(connect_timeout, connect_timeout,
997
 
                           PLUGIN_VAR_RQCMDARG, N_("Connect Timeout."),
998
 
                           NULL, NULL, 10, 1, 300, 0);
999
 
static DRIZZLE_SYSVAR_UINT(read_timeout, read_timeout, PLUGIN_VAR_RQCMDARG,
1000
 
                           N_("Read Timeout."), NULL, NULL, 30, 1, 300, 0);
1001
 
static DRIZZLE_SYSVAR_UINT(write_timeout, write_timeout, PLUGIN_VAR_RQCMDARG,
1002
 
                           N_("Write Timeout."), NULL, NULL, 60, 1, 300, 0);
1003
 
static DRIZZLE_SYSVAR_UINT(retry_count, retry_count, PLUGIN_VAR_RQCMDARG,
1004
 
                           N_("Retry Count."), NULL, NULL, 10, 1, 100, 0);
1005
 
static DRIZZLE_SYSVAR_UINT(buffer_length, buffer_length, PLUGIN_VAR_RQCMDARG,
1006
 
                           N_("Buffer length."), NULL, NULL, 16384, 1024,
1007
 
                           1024*1024, 0);
1008
 
static DRIZZLE_SYSVAR_STR(bind_address, bind_address, PLUGIN_VAR_READONLY,
1009
 
                          N_("Address to bind to."), NULL, NULL, NULL);
1010
 
 
1011
937
static void init_options(drizzled::module::option_context &context)
1012
938
{
1013
939
  context("port",
1014
 
          po::value<uint32_t>(&port)->default_value(3306),
 
940
          po::value<port_constraint>(&port)->default_value(3306),
1015
941
          N_("Port number to use for connection or 0 for default to with MySQL "
1016
942
                              "protocol."));
1017
943
  context("connect-timeout",
1018
 
          po::value<uint32_t>(&connect_timeout)->default_value(10),
 
944
          po::value<timeout_constraint>(&connect_timeout)->default_value(10),
1019
945
          N_("Connect Timeout."));
1020
946
  context("read-timeout",
1021
 
          po::value<uint32_t>(&read_timeout)->default_value(30),
 
947
          po::value<timeout_constraint>(&read_timeout)->default_value(30),
1022
948
          N_("Read Timeout."));
1023
949
  context("write-timeout",
1024
 
          po::value<uint32_t>(&write_timeout)->default_value(60),
 
950
          po::value<timeout_constraint>(&write_timeout)->default_value(60),
1025
951
          N_("Write Timeout."));
1026
952
  context("retry-count",
1027
 
          po::value<uint32_t>(&retry_count)->default_value(10),
 
953
          po::value<retry_constraint>(&retry_count)->default_value(10),
1028
954
          N_("Retry Count."));
1029
955
  context("buffer-length",
1030
 
          po::value<uint32_t>(&buffer_length)->default_value(16384),
 
956
          po::value<buffer_constraint>(&buffer_length)->default_value(16384),
1031
957
          N_("Buffer length."));
1032
958
  context("bind-address",
1033
 
          po::value<string>(),
 
959
          po::value<string>()->default_value(""),
1034
960
          N_("Address to bind to."));
1035
961
  context("max-connections",
1036
962
          po::value<uint32_t>(&ListenMySQLProtocol::mysql_counters->max_connections)->default_value(1000),
1037
963
          N_("Maximum simultaneous connections."));
1038
964
}
1039
965
 
1040
 
static drizzle_sys_var* sys_variables[]= {
1041
 
  DRIZZLE_SYSVAR(port),
1042
 
  DRIZZLE_SYSVAR(connect_timeout),
1043
 
  DRIZZLE_SYSVAR(read_timeout),
1044
 
  DRIZZLE_SYSVAR(write_timeout),
1045
 
  DRIZZLE_SYSVAR(retry_count),
1046
 
  DRIZZLE_SYSVAR(buffer_length),
1047
 
  DRIZZLE_SYSVAR(bind_address),
1048
 
  NULL
1049
 
};
1050
 
 
1051
966
static int mysql_protocol_connection_count_func(drizzle_show_var *var, char *buff)
1052
967
{
1053
968
  var->type= SHOW_LONGLONG;
1145
1060
  return false;
1146
1061
}
1147
1062
 
 
1063
} /* namespace drizzle_plugin */
 
1064
 
1148
1065
DRIZZLE_DECLARE_PLUGIN
1149
1066
{
1150
1067
  DRIZZLE_VERSION_ID,
1153
1070
  "Eric Day",
1154
1071
  "MySQL Protocol Module",
1155
1072
  PLUGIN_LICENSE_GPL,
1156
 
  init,             /* Plugin Init */
1157
 
  sys_variables, /* system variables */
1158
 
  init_options    /* config options */
 
1073
  drizzle_plugin::init,             /* Plugin Init */
 
1074
  NULL, /* system variables */
 
1075
  drizzle_plugin::init_options    /* config options */
1159
1076
}
1160
1077
DRIZZLE_DECLARE_PLUGIN_END;