~drizzle-trunk/drizzle/development

520.6.3 by Monty Taylor
Moved scheduler.h out of common_includes.
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2008 Sun Microsystems
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; version 2 of the License.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
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
18
 */
1 by brian
clean slate
19
20
21
/*
22
  Functions to autenticate and handle reqests for a connection
23
*/
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
24
#include <drizzled/server_includes.h>
575.4.7 by Monty Taylor
More header cleanup.
25
#include <netdb.h>
26
259 by Brian Aker
First pass on PAM auth
27
#include <drizzled/authentication.h>
575.4.6 by Monty Taylor
Removed my_getwd.
28
#include <drizzled/db.h>
549 by Monty Taylor
Took gettext.h out of header files.
29
#include <drizzled/error.h>
575.4.7 by Monty Taylor
More header cleanup.
30
#include <drizzled/sql_parse.h>
809 by Brian Aker
Refactor of scheduler plugin code to simplify around one structure. Also
31
#include <drizzled/plugin_scheduling.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
32
#include <drizzled/session.h>
798.2.26 by Brian Aker
Remove log_event.h from session.h
33
#include <drizzled/data_home.h>
1 by brian
clean slate
34
809 by Brian Aker
Refactor of scheduler plugin code to simplify around one structure. Also
35
extern scheduling_st thread_scheduler;
520.6.3 by Monty Taylor
Moved scheduler.h out of common_includes.
36
1 by brian
clean slate
37
#define MIN_HANDSHAKE_SIZE      6
38
39
/**
40
  Check if user exist and password supplied is correct.
41
520.1.22 by Brian Aker
Second pass of thd cleanup
42
  @param  session         thread handle, session->security_ctx->{host,user,ip} are used
1 by brian
clean slate
43
  @param  command     originator of the check: now check_user is called
44
                      during connect and change user procedures; used for
45
                      logging.
46
  @param  passwd      scrambled password received from client
47
  @param  passwd_len  length of scrambled password
48
  @param  db          database name to connect to, may be NULL
49
50
  @note Host, user and passwd may point to communication buffer.
51
  Current implementation does not depend on that, but future changes
520.1.22 by Brian Aker
Second pass of thd cleanup
52
  should be done with this in mind; 'session' is INOUT, all other params
1 by brian
clean slate
53
  are 'IN'.
54
265 by brian
First pass through cleaning up security context.
55
  @retval  0  OK
1 by brian
clean slate
56
  @retval  1  error, e.g. access denied or handshake error, not sent to
57
              the client. A message is pushed into the error stack.
58
*/
59
60
int
520.1.22 by Brian Aker
Second pass of thd cleanup
61
check_user(Session *session, const char *passwd,
832.2.9 by Mark Atwood
remove unused parameter to check_user() related to max_connections
62
           uint32_t passwd_len, const char *db)
1 by brian
clean slate
63
{
64
  LEX_STRING db_str= { (char *) db, db ? strlen(db) : 0 };
259 by Brian Aker
First pass on PAM auth
65
  bool is_authenticated;
1 by brian
clean slate
66
67
  /*
520.1.22 by Brian Aker
Second pass of thd cleanup
68
    Clear session->db as it points to something, that will be freed when
1 by brian
clean slate
69
    connection is closed. We don't want to accidentally free a wrong
70
    pointer if connect failed. Also in case of 'CHANGE USER' failure,
71
    current database will be switched to 'no database selected'.
72
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
73
  session->reset_db(NULL, 0);
1 by brian
clean slate
74
259 by Brian Aker
First pass on PAM auth
75
  if (passwd_len != 0 && passwd_len != SCRAMBLE_LENGTH)
1 by brian
clean slate
76
  {
694 by Brian Aker
Refactor out char* strdup for string class in user.
77
    my_error(ER_HANDSHAKE_ERROR, MYF(0), session->security_ctx.ip.c_str());
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
78
    return(1);
1 by brian
clean slate
79
  }
80
520.1.22 by Brian Aker
Second pass of thd cleanup
81
  is_authenticated= authenticate_user(session, passwd);
259 by Brian Aker
First pass on PAM auth
82
83
  if (is_authenticated != true)
84
  {
85
    my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
694 by Brian Aker
Refactor out char* strdup for string class in user.
86
             session->security_ctx.user.c_str(),
87
             session->security_ctx.ip.c_str(),
259 by Brian Aker
First pass on PAM auth
88
             passwd_len ? ER(ER_YES) : ER(ER_NO));
89
90
    return 1;
91
  }
92
93
694 by Brian Aker
Refactor out char* strdup for string class in user.
94
  session->security_ctx.skip_grants();
1 by brian
clean slate
95
96
  /* Change database if necessary */
97
  if (db && db[0])
98
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
99
    if (mysql_change_db(session, &db_str, false))
1 by brian
clean slate
100
    {
101
      /* mysql_change_db() has pushed the error message. */
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
102
      return(1);
1 by brian
clean slate
103
    }
104
  }
836 by Brian Aker
Fixed session call from function to method.
105
  session->my_ok();
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
106
  session->password= test(passwd_len);          // remember for error messages
1 by brian
clean slate
107
  /* Ready to handle queries */
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
108
  return(0);
1 by brian
clean slate
109
}
110
111
112
/*
113
  Check for maximum allowable user connections, if the mysqld server is
114
  started with corresponding variable that is greater then 0.
115
*/
116
481 by Brian Aker
Remove all of uchar.
117
extern "C" unsigned char *get_key_conn(user_conn *buff, size_t *length,
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
118
                               bool )
1 by brian
clean slate
119
{
120
  *length= buff->len;
481 by Brian Aker
Remove all of uchar.
121
  return (unsigned char*) buff->user;
1 by brian
clean slate
122
}
123
124
125
extern "C" void free_user(struct user_conn *uc)
126
{
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
127
  free((char*) uc);
1 by brian
clean slate
128
}
129
130
/*
131
  Initialize connection threads
132
*/
133
134
bool init_new_connection_handler_thread()
135
{
136
  pthread_detach_this_thread();
137
  /* Win32 calls this in pthread_create */
138
  if (my_thread_init())
139
    return 1;
140
  return 0;
141
}
142
143
/*
520.1.22 by Brian Aker
Second pass of thd cleanup
144
  Perform handshake, authorize client and update session ACL variables.
1 by brian
clean slate
145
146
  SYNOPSIS
147
    check_connection()
520.1.22 by Brian Aker
Second pass of thd cleanup
148
    session  thread handle
1 by brian
clean slate
149
150
  RETURN
520.1.22 by Brian Aker
Second pass of thd cleanup
151
     0  success, OK is sent to user, session is updated.
1 by brian
clean slate
152
    -1  error, which is sent to user
153
   > 0  error code (not sent to user)
154
*/
155
520.1.22 by Brian Aker
Second pass of thd cleanup
156
static int check_connection(Session *session)
1 by brian
clean slate
157
{
520.1.22 by Brian Aker
Second pass of thd cleanup
158
  NET *net= &session->net;
307 by Brian Aker
Minor cleanups around ulong in kernel.
159
  uint32_t pkt_len= 0;
1 by brian
clean slate
160
  char *end;
161
265 by brian
First pass through cleaning up security context.
162
  // TCP/IP connection
1 by brian
clean slate
163
  {
164
    char ip[NI_MAXHOST];
165
520.1.22 by Brian Aker
Second pass of thd cleanup
166
    if (net_peer_addr(net, ip, &session->peer_port, NI_MAXHOST))
1 by brian
clean slate
167
    {
694 by Brian Aker
Refactor out char* strdup for string class in user.
168
      my_error(ER_BAD_HOST_ERROR, MYF(0), session->security_ctx.ip.c_str());
1 by brian
clean slate
169
      return 1;
170
    }
694 by Brian Aker
Refactor out char* strdup for string class in user.
171
172
    session->security_ctx.ip.assign(ip);
1 by brian
clean slate
173
  }
383.1.54 by Monty Taylor
More violite refactoring/removal.
174
  net_keepalive(net, true);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
175
307 by Brian Aker
Minor cleanups around ulong in kernel.
176
  uint32_t server_capabilites;
1 by brian
clean slate
177
  {
178
    /* buff[] needs to big enough to hold the server_version variable */
179
    char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH + 64];
180
    server_capabilites= CLIENT_BASIC_FLAGS;
181
182
    if (opt_using_transactions)
183
      server_capabilites|= CLIENT_TRANSACTIONS;
184
#ifdef HAVE_COMPRESS
185
    server_capabilites|= CLIENT_COMPRESS;
186
#endif /* HAVE_COMPRESS */
187
741.1.1 by Eric Day
Reworked server version packing in handshake, was writing max length instead of just string length + NULL.
188
    end= buff + strlen(server_version);
189
    if ((end - buff) >= SERVER_VERSION_LENGTH)
190
      end= buff + (SERVER_VERSION_LENGTH - 1);
191
    memcpy(buff, server_version, end - buff);
192
    *end= 0;
193
    end++;
670.3.1 by Toru Maesaka
Replaced MySQL's my_stpncpy() with libc and c++ calls
194
520.1.22 by Brian Aker
Second pass of thd cleanup
195
    int4store((unsigned char*) end, session->thread_id);
1 by brian
clean slate
196
    end+= 4;
197
    /*
198
      So as check_connection is the only entry point to authorization
199
      procedure, scramble is set here. This gives us new scramble for
200
      each handshake.
201
    */
520.1.22 by Brian Aker
Second pass of thd cleanup
202
    create_random_string(session->scramble, SCRAMBLE_LENGTH, &session->rand);
1 by brian
clean slate
203
    /*
204
      Old clients does not understand long scrambles, but can ignore packet
205
      tail: that's why first part of the scramble is placed here, and second
206
      part at the end of packet.
207
    */
629.5.3 by Toru Maesaka
Third pass of replacing MySQL's strmake() with libc calls
208
    end= strncpy(end, session->scramble, SCRAMBLE_LENGTH_323);
209
    end+= SCRAMBLE_LENGTH_323 + 1;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
210
1 by brian
clean slate
211
    int2store(end, server_capabilites);
212
    /* write server characteristics: up to 16 bytes allowed */
213
    end[2]=(char) default_charset_info->number;
520.1.22 by Brian Aker
Second pass of thd cleanup
214
    int2store(end+3, session->server_status);
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
215
    memset(end+5, 0, 13);
1 by brian
clean slate
216
    end+= 18;
217
    /* write scramble tail */
629.5.3 by Toru Maesaka
Third pass of replacing MySQL's strmake() with libc calls
218
    size_t scramble_len= SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323;
219
    end= strncpy(end, session->scramble + SCRAMBLE_LENGTH_323, scramble_len);
220
    end+= scramble_len + 1;
1 by brian
clean slate
221
222
    /* At this point we write connection message and read reply */
481 by Brian Aker
Remove all of uchar.
223
    if (net_write_command(net, (unsigned char) protocol_version, (unsigned char*) "", 0,
224
                          (unsigned char*) buff, (size_t) (end-buff)) ||
840.1.17 by Monty Taylor
Renamed my_net_* to drizzleclient_net_* to help with namespace issues.
225
	(pkt_len= drizzleclient_net_read(net)) == packet_error ||
1 by brian
clean slate
226
	pkt_len < MIN_HANDSHAKE_SIZE)
227
    {
228
      my_error(ER_HANDSHAKE_ERROR, MYF(0),
694 by Brian Aker
Refactor out char* strdup for string class in user.
229
               session->security_ctx.ip.c_str());
1 by brian
clean slate
230
      return 1;
231
    }
232
  }
520.1.22 by Brian Aker
Second pass of thd cleanup
233
  if (session->packet.alloc(session->variables.net_buffer_length))
1 by brian
clean slate
234
    return 1; /* The error is set by alloc(). */
235
520.1.22 by Brian Aker
Second pass of thd cleanup
236
  session->client_capabilities= uint2korr(net->read_pos);
237
238
239
  session->client_capabilities|= ((uint32_t) uint2korr(net->read_pos+2)) << 16;
240
  session->max_client_packet_length= uint4korr(net->read_pos+4);
241
  session->update_charset();
264.2.4 by Andrey Hristov
Remove support for the old, pre-4.1, protocol
242
  end= (char*) net->read_pos+32;
243
1 by brian
clean slate
244
  /*
245
    Disable those bits which are not supported by the server.
246
    This is a precautionary measure, if the client lies. See Bug#27944.
247
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
248
  session->client_capabilities&= server_capabilites;
1 by brian
clean slate
249
250
  if (end >= (char*) net->read_pos+ pkt_len +2)
251
  {
252
694 by Brian Aker
Refactor out char* strdup for string class in user.
253
    my_error(ER_HANDSHAKE_ERROR, MYF(0), session->security_ctx.ip.c_str());
1 by brian
clean slate
254
    return 1;
255
  }
256
520.1.22 by Brian Aker
Second pass of thd cleanup
257
  if (session->client_capabilities & CLIENT_INTERACTIVE)
258
    session->variables.net_wait_timeout= session->variables.net_interactive_timeout;
259
  if ((session->client_capabilities & CLIENT_TRANSACTIONS) &&
1 by brian
clean slate
260
      opt_using_transactions)
520.1.22 by Brian Aker
Second pass of thd cleanup
261
    net->return_status= &session->server_status;
1 by brian
clean slate
262
263
  char *user= end;
376 by Brian Aker
strend remove
264
  char *passwd= strchr(user, '\0')+1;
482 by Brian Aker
Remove uint.
265
  uint32_t user_len= passwd - user - 1;
1 by brian
clean slate
266
  char *db= passwd;
267
  char db_buff[NAME_LEN + 1];           // buffer to store db in utf8
268
  char user_buff[USERNAME_LENGTH + 1];	// buffer to store user in utf8
482 by Brian Aker
Remove uint.
269
  uint32_t dummy_errors;
1 by brian
clean slate
270
271
  /*
272
    Old clients send null-terminated string as password; new clients send
273
    the size (1 byte) + string (not null-terminated). Hence in case of empty
274
    password both send '\0'.
275
276
    This strlen() can't be easily deleted without changing protocol.
277
278
    Cast *passwd to an unsigned char, so that it doesn't extend the sign for
279
    *passwd > 127 and become 2**32-127+ after casting to uint.
280
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
281
  uint32_t passwd_len= session->client_capabilities & CLIENT_SECURE_CONNECTION ?
481 by Brian Aker
Remove all of uchar.
282
    (unsigned char)(*passwd++) : strlen(passwd);
520.1.22 by Brian Aker
Second pass of thd cleanup
283
  db= session->client_capabilities & CLIENT_CONNECT_WITH_DB ?
1 by brian
clean slate
284
    db + passwd_len + 1 : 0;
285
  /* strlen() can't be easily deleted without changing protocol */
482 by Brian Aker
Remove uint.
286
  uint32_t db_len= db ? strlen(db) : 0;
1 by brian
clean slate
287
288
  if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
289
  {
694 by Brian Aker
Refactor out char* strdup for string class in user.
290
    my_error(ER_HANDSHAKE_ERROR, MYF(0), session->security_ctx.ip.c_str());
1 by brian
clean slate
291
    return 1;
292
  }
293
294
  /* Since 4.1 all database names are stored in utf8 */
295
  if (db)
296
  {
297
    db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
298
                             system_charset_info,
299
                             db, db_len,
520.1.22 by Brian Aker
Second pass of thd cleanup
300
                             session->charset(), &dummy_errors)]= 0;
1 by brian
clean slate
301
    db= db_buff;
302
  }
303
304
  user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
305
                                       system_charset_info, user, user_len,
520.1.22 by Brian Aker
Second pass of thd cleanup
306
                                       session->charset(), &dummy_errors)]= '\0';
1 by brian
clean slate
307
  user= user_buff;
308
309
  /* If username starts and ends in "'", chop them off */
310
  if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
311
  {
312
    user[user_len-1]= 0;
313
    user++;
314
    user_len-= 2;
315
  }
316
694 by Brian Aker
Refactor out char* strdup for string class in user.
317
  session->security_ctx.user.assign(user);
318
832.2.9 by Mark Atwood
remove unused parameter to check_user() related to max_connections
319
  return check_user(session, passwd, passwd_len, db);
1 by brian
clean slate
320
}
321
322
323
/*
324
  Setup thread to be used with the current thread
325
326
  SYNOPSIS
327
    bool setup_connection_thread_globals()
520.1.22 by Brian Aker
Second pass of thd cleanup
328
    session    Thread/connection handler
1 by brian
clean slate
329
330
  RETURN
331
    0   ok
332
    1   Error (out of memory)
333
        In this case we will close the connection and increment status
334
*/
335
520.1.22 by Brian Aker
Second pass of thd cleanup
336
bool setup_connection_thread_globals(Session *session)
1 by brian
clean slate
337
{
520.1.22 by Brian Aker
Second pass of thd cleanup
338
  if (session->store_globals())
1 by brian
clean slate
339
  {
693 by Brian Aker
Cleaning up session class.
340
    session->close_connection(ER_OUT_OF_RESOURCES, true);
1 by brian
clean slate
341
    statistic_increment(aborted_connects,&LOCK_status);
520.1.22 by Brian Aker
Second pass of thd cleanup
342
    thread_scheduler.end_thread(session, 0);
1 by brian
clean slate
343
    return 1;                                   // Error
344
  }
345
  return 0;
346
}
347
348
349
/*
350
  Autenticate user, with error reporting
351
352
  SYNOPSIS
353
   login_connection()
520.1.22 by Brian Aker
Second pass of thd cleanup
354
   session        Thread handler
1 by brian
clean slate
355
356
  NOTES
357
    Connection is not closed in case of errors
358
359
  RETURN
360
    0    ok
361
    1    error
362
*/
363
364
520.1.22 by Brian Aker
Second pass of thd cleanup
365
bool login_connection(Session *session)
1 by brian
clean slate
366
{
520.1.22 by Brian Aker
Second pass of thd cleanup
367
  NET *net= &session->net;
1 by brian
clean slate
368
  int error;
369
370
  /* Use "connect_timeout" value during connection phase */
840.1.17 by Monty Taylor
Renamed my_net_* to drizzleclient_net_* to help with namespace issues.
371
  drizzleclient_net_set_read_timeout(net, connect_timeout);
372
  drizzleclient_net_set_write_timeout(net, connect_timeout);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
373
520.1.22 by Brian Aker
Second pass of thd cleanup
374
  lex_start(session);
1 by brian
clean slate
375
520.1.22 by Brian Aker
Second pass of thd cleanup
376
  error= check_connection(session);
377
  net_end_statement(session);
1 by brian
clean slate
378
379
  if (error)
380
  {						// Wrong permissions
381
    statistic_increment(aborted_connects,&LOCK_status);
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
382
    return(1);
1 by brian
clean slate
383
  }
384
  /* Connect completed, set read/write timeouts back to default */
840.1.17 by Monty Taylor
Renamed my_net_* to drizzleclient_net_* to help with namespace issues.
385
  drizzleclient_net_set_read_timeout(net, session->variables.net_read_timeout);
386
  drizzleclient_net_set_write_timeout(net, session->variables.net_write_timeout);
51.1.50 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
387
  return(0);
1 by brian
clean slate
388
}
389
390
391
/*
392
  Close an established connection
393
394
  NOTES
395
    This mainly updates status variables
396
*/
397
520.1.22 by Brian Aker
Second pass of thd cleanup
398
void end_connection(Session *session)
1 by brian
clean slate
399
{
520.1.22 by Brian Aker
Second pass of thd cleanup
400
  NET *net= &session->net;
401
  plugin_sessionvar_cleanup(session);
1 by brian
clean slate
402
520.1.22 by Brian Aker
Second pass of thd cleanup
403
  if (session->killed || (net->error && net->vio != 0))
1 by brian
clean slate
404
  {
405
    statistic_increment(aborted_threads,&LOCK_status);
406
  }
407
408
  if (net->error && net->vio != 0)
409
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
410
    if (!session->killed && session->variables.log_warnings > 1)
1 by brian
clean slate
411
    {
694 by Brian Aker
Refactor out char* strdup for string class in user.
412
      Security_context *sctx= &session->security_ctx;
1 by brian
clean slate
413
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
414
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION),
520.1.22 by Brian Aker
Second pass of thd cleanup
415
                        session->thread_id,(session->db ? session->db : "unconnected"),
694 by Brian Aker
Refactor out char* strdup for string class in user.
416
                        sctx->user.empty() == false ? sctx->user.c_str() : "unauthenticated",
417
                        sctx->ip.c_str(),
520.1.22 by Brian Aker
Second pass of thd cleanup
418
                        (session->main_da.is_error() ? session->main_da.message() :
1 by brian
clean slate
419
                         ER(ER_UNKNOWN_ERROR)));
420
    }
421
  }
422
}
423
424
425
/*
520.1.21 by Brian Aker
THD -> Session rename
426
  Initialize Session to handle queries
1 by brian
clean slate
427
*/
428
520.1.22 by Brian Aker
Second pass of thd cleanup
429
void prepare_new_connection_state(Session* session)
1 by brian
clean slate
430
{
694 by Brian Aker
Refactor out char* strdup for string class in user.
431
  Security_context *sctx= &session->security_ctx;
1 by brian
clean slate
432
520.1.22 by Brian Aker
Second pass of thd cleanup
433
  if (session->variables.max_join_size == HA_POS_ERROR)
434
    session->options |= OPTION_BIG_SELECTS;
435
  if (session->client_capabilities & CLIENT_COMPRESS)
436
    session->net.compress=1;				// Use compression
1 by brian
clean slate
437
438
  /*
520.1.22 by Brian Aker
Second pass of thd cleanup
439
    Much of this is duplicated in create_embedded_session() for the
1 by brian
clean slate
440
    embedded server library.
441
    TODO: refactor this to avoid code duplication there
442
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
443
  session->version= refresh_version;
444
  session->set_proc_info(0);
445
  session->command= COM_SLEEP;
446
  session->set_time();
447
  session->init_for_queries();
1 by brian
clean slate
448
449
  /* In the past this would only run of the user did not have SUPER_ACL */
450
  if (sys_init_connect.value_length)
451
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
452
    execute_init_command(session, &sys_init_connect, &LOCK_sys_init_connect);
453
    if (session->is_error())
1 by brian
clean slate
454
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
455
      session->killed= Session::KILL_CONNECTION;
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
456
      errmsg_printf(ERRMSG_LVL_WARN, ER(ER_NEW_ABORTING_CONNECTION),
520.1.22 by Brian Aker
Second pass of thd cleanup
457
                        session->thread_id,(session->db ? session->db : "unconnected"),
694 by Brian Aker
Refactor out char* strdup for string class in user.
458
                        sctx->user.empty() == false ? sctx->user.c_str() : "unauthenticated",
459
                        sctx->ip.c_str(), "init_connect command failed");
755.2.1 by Mark Atwood
replace sql_print_error etc with errmsg_print
460
      errmsg_printf(ERRMSG_LVL_WARN, "%s", session->main_da.message());
1 by brian
clean slate
461
    }
520.1.22 by Brian Aker
Second pass of thd cleanup
462
    session->set_proc_info(0);
463
    session->set_time();
464
    session->init_for_queries();
1 by brian
clean slate
465
  }
466
}
467
468
469
/*
470
  Thread handler for a connection
471
472
  SYNOPSIS
473
    handle_one_connection()
520.1.21 by Brian Aker
THD -> Session rename
474
    arg		Connection object (Session)
1 by brian
clean slate
475
476
  IMPLEMENTATION
477
    This function (normally) does the following:
478
    - Initialize thread
520.1.21 by Brian Aker
THD -> Session rename
479
    - Initialize Session to be used with this thread
1 by brian
clean slate
480
    - Authenticate user
481
    - Execute all queries sent on the connection
482
    - Take connection down
483
    - End thread  / Handle next connection using thread from thread cache
484
*/
485
486
pthread_handler_t handle_one_connection(void *arg)
487
{
520.1.22 by Brian Aker
Second pass of thd cleanup
488
  Session *session= (Session*) arg;
489
  uint32_t launch_time= (uint32_t) ((session->thr_create_utime= my_micro_time()) -
490
                              session->connect_utime);
1 by brian
clean slate
491
492
  if (thread_scheduler.init_new_connection_thread())
493
  {
693 by Brian Aker
Cleaning up session class.
494
    session->close_connection(ER_OUT_OF_RESOURCES, true);
1 by brian
clean slate
495
    statistic_increment(aborted_connects,&LOCK_status);
520.1.22 by Brian Aker
Second pass of thd cleanup
496
    thread_scheduler.end_thread(session,0);
1 by brian
clean slate
497
    return 0;
498
  }
499
  if (launch_time >= slow_launch_time*1000000L)
500
    statistic_increment(slow_launch_threads,&LOCK_status);
501
502
  /*
503
    handle_one_connection() is normally the only way a thread would
504
    start and would always be on the very high end of the stack ,
505
    therefore, the thread stack always starts at the address of the
520.1.22 by Brian Aker
Second pass of thd cleanup
506
    first local variable of handle_one_connection, which is session. We
1 by brian
clean slate
507
    need to know the start of the stack so that we could check for
508
    stack overruns.
509
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
510
  session->thread_stack= (char*) &session;
511
  if (setup_connection_thread_globals(session))
1 by brian
clean slate
512
    return 0;
513
514
  for (;;)
515
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
516
    NET *net= &session->net;
1 by brian
clean slate
517
520.1.22 by Brian Aker
Second pass of thd cleanup
518
    if (login_connection(session))
1 by brian
clean slate
519
      goto end_thread;
520
520.1.22 by Brian Aker
Second pass of thd cleanup
521
    prepare_new_connection_state(session);
1 by brian
clean slate
522
523
    while (!net->error && net->vio != 0 &&
520.1.22 by Brian Aker
Second pass of thd cleanup
524
           !(session->killed == Session::KILL_CONNECTION))
1 by brian
clean slate
525
    {
520.1.22 by Brian Aker
Second pass of thd cleanup
526
      if (do_command(session))
1 by brian
clean slate
527
	break;
528
    }
520.1.22 by Brian Aker
Second pass of thd cleanup
529
    end_connection(session);
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
530
1 by brian
clean slate
531
end_thread:
813.4.1 by Stewart Smith
gcc 4.2.1 fixes
532
    session->close_connection(0, true);
693 by Brian Aker
Cleaning up session class.
533
    if (thread_scheduler.end_thread(session, 1))
1 by brian
clean slate
534
      return 0;                                 // Probably no-threads
535
536
    /*
537
      If end_thread() returns, we are either running with
538
      thread-handler=no-threads or this thread has been schedule to
539
      handle the next connection.
540
    */
520.1.22 by Brian Aker
Second pass of thd cleanup
541
    session= current_session;
542
    session->thread_stack= (char*) &session;
1 by brian
clean slate
543
  }
544
}