645
|
1
|
|
2 /*
|
|
3 * Copyright (C) Igor Sysoev
|
|
4 */
|
|
5
|
|
6
|
|
7 #include <ngx_config.h>
|
|
8 #include <ngx_core.h>
|
|
9 #include <ngx_event.h>
|
|
10 #include <ngx_mysql.h>
|
|
11
|
|
12
|
|
13 /* the library supports the subset of the MySQL 4.1+ protocol (version 10) */
|
|
14
|
|
15
|
|
16 ngx_int_t
|
|
17 ngx_mysql_connect(ngx_mysql_t *m)
|
|
18 {
|
|
19 ngx_int_t rc;
|
|
20
|
|
21 #if 0
|
|
22 if (cached) {
|
|
23 return NGX_OK;
|
|
24 }
|
|
25 #endif
|
|
26
|
|
27 m->peer.log->action = "connecting to mysql server";
|
|
28
|
|
29 rc = ngx_event_connect_peer(&m->peer);
|
|
30
|
|
31 if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) {
|
|
32 return rc;
|
|
33 }
|
|
34
|
|
35 m->peer.connection->read->handler = ngx_mysql_read_server_greeting;
|
|
36 m->peer.connection->write->handler = ngx_mysql_emtpy_handler;
|
|
37
|
|
38 ngx_add_timer(m->peer.connection->read, /* STUB */ 5000);
|
|
39 ngx_add_timer(m->peer.connection->write, /* STUB */ 5000);
|
|
40
|
|
41 return NGX_OK;
|
|
42 }
|
|
43
|
|
44
|
|
45 static void
|
|
46 ngx_mysql_read_server_greeting(ngx_event_t *rev)
|
|
47 {
|
|
48 size_t len;
|
|
49 u_char *p, *t;
|
|
50 ngx_mysql_t *m;
|
|
51 ngx_connection_t *c;
|
|
52
|
|
53 c = rev->data;
|
|
54 m = c->data;
|
|
55
|
|
56 if (rev->timedout) {
|
|
57 ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT,
|
|
58 "mysql server %V timed out",
|
|
59 &ctx->peer.peers->peer[0].name);
|
|
60
|
|
61 ngx_mysql_close(m, NGX_ERROR);
|
|
62 return;
|
|
63 }
|
|
64
|
|
65 if (m->buf == NULL) {
|
|
66 m->peer.log->action = "reading to mysql server greeting";
|
|
67
|
|
68 m->buf = ngx_create_temp(m->pool, /* STUB */ 1024);
|
|
69 if (m->buf == NULL) {
|
|
70 ngx_mysql_close(m, NGX_ERROR);
|
|
71 return;
|
|
72 }
|
|
73 }
|
|
74
|
|
75 n = ngx_recv(m->peer.connection, m->buf->pos, /* STUB */ 1024);
|
|
76
|
|
77 if (n == NGX_AGAIN) {
|
|
78 return;
|
|
79 }
|
|
80
|
|
81 if (n < 5) {
|
|
82 ngx_mysql_close(m, NGX_ERROR);
|
|
83 return;
|
|
84 }
|
|
85
|
|
86 p = m->buf->pos;
|
|
87
|
|
88 if (ngx_m24toh(p) > n - 4) {
|
|
89 ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
|
90 "mysql server %V sent incomplete greeting packet",
|
|
91 &ctx->peer.peers->peer[0].name);
|
|
92
|
|
93 ngx_mysql_close(m, NGX_ERROR);
|
|
94 return;
|
|
95 }
|
|
96
|
|
97 if (p[4]) < 10) {
|
|
98 ngx_log_error(NGX_LOG_ERR, rev->log, 0,
|
|
99 "mysql server %V sent unsupported protocol version %ud",
|
|
100 &ctx->peer.peers->peer[0].name, p[4]);
|
|
101
|
|
102 ngx_mysql_close(m, NGX_ERROR);
|
|
103 return;
|
|
104 }
|
|
105
|
|
106 len = ngx_strlen(&p[5]);
|
|
107 t = p + 5 + len + 1;
|
|
108
|
|
109 capacity = ngx_m16toh((&t[4 + 9]));
|
|
110
|
|
111 ngx_log_debug8(NGX_LOG_DEBUG_MYSQL, rev->log, 0,
|
|
112 "mysql version: %ud, \"%s\", thread: %ud, salt: \"%s\", ",
|
|
113 "capacity: %Xd, charset: %ud, status: %ud, salt rest \"%s\"",
|
|
114 p[4], &p[5], ngx_m32toh(t), &t[4],
|
|
115 capacity, t[4 + 9 + 2],
|
|
116 ngx_m16toh((&t[4 + 9 + 2 + 1])),
|
|
117 t[4 + 9 + 2 + 1 + 2 + 13]);
|
|
118
|
|
119 capacity &= NGX_MYSQL_LONG_PASSWORD
|
|
120 | NGX_MYSQL_CONNECT_WITH_DB
|
|
121 | NGX_MYSQL_PROTOCOL_41;
|
|
122
|
|
123 }
|
|
124
|
|
125
|
|
126 static void
|
|
127 ngx_mysql_close(ngx_mysql_t *m, ngx_int_t rc)
|
|
128 {
|
|
129 if (rc == NGX_ERROR) {
|
|
130 ngx_close_connection(m->peer.connection);
|
|
131 }
|
|
132
|
|
133 m->state = rc;
|
|
134
|
|
135 m->handler(m);
|
|
136 }
|