libdrizzle Developer Documentation

proxy.c
Go to the documentation of this file.
1/*
2 * Drizzle Client & Protocol Library
3 *
4 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5 * All rights reserved.
6 *
7 * Use and distribution licensed under the BSD license. See
8 * the COPYING file in this directory for full text.
9 */
10
11#include <errno.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <unistd.h>
15
18
19#define DRIZZLE_RETURN_CHECK(__ret, __function, __drizzle) \
20{ \
21 if ((__ret) != DRIZZLE_RETURN_OK) \
22 DRIZZLE_RETURN_ERROR(__function, __drizzle) \
23}
24
25#define DRIZZLE_RETURN_ERROR(__function, __drizzle) \
26{ \
27 printf(__function ":%s\n", drizzle_error(__drizzle)); \
28 return; \
29}
30
31static void proxy(drizzle_st *drizzle, drizzle_con_st *server,
32 drizzle_con_st *client, drizzle_result_st *server_result,
33 drizzle_result_st *client_result, drizzle_column_st *column);
34
35int main(int argc, char *argv[])
36{
37 int c;
38 uint32_t count= 0;
39 const char *server_host= NULL;
40 const char *client_host= NULL;
41 bool server_mysql= false;
42 bool client_mysql= false;
43 in_port_t server_port= 0;
44 in_port_t client_port= 0;
47 drizzle_st drizzle;
48 drizzle_con_st con_listen;
50 drizzle_con_st client;
51 drizzle_result_st server_result;
52 drizzle_result_st client_result;
53 drizzle_column_st column;
54
55 while((c = getopt(argc, argv, "c:h:H:mMp:P:v")) != -1)
56 {
57 switch(c)
58 {
59 case 'c':
60 count= (uint32_t)atoi(optarg);
61 break;
62
63 case 'h':
64 server_host= optarg;
65 break;
66
67 case 'H':
68 client_host= optarg;
69 break;
70
71 case 'm':
72 server_mysql= true;
73 break;
74
75 case 'M':
76 client_mysql= true;
77 break;
78
79 case 'p':
80 server_port= (in_port_t)atoi(optarg);
81 break;
82
83 case 'P':
84 client_port= (in_port_t)atoi(optarg);
85 break;
86
87 case 'v':
88 verbose++;
89 break;
90
91 default:
92 printf("\nusage: %s [-c <count>] [-h <host>] [-H <host>] [-m] [-M] "
93 "[-p <port>] [-p <port>] [-v]\n", argv[0]);
94 printf("\t-c <count> - Number of connections to accept before exiting\n");
95 printf("\t-h <host> - Host to listen on\n");
96 printf("\t-H <host> - Host to connect to\n");
97 printf("\t-m - Use MySQL protocol for incoming connections\n");
98 printf("\t-M - Use MySQL protocol for outgoing connectionsn\n");
99 printf("\t-p <port> - Port to listen on\n");
100 printf("\t-P <port> - Port to connect to\n");
101 printf("\t-v - Increase verbosity level\n");
102 return 1;
103 }
104 }
105
106 if (drizzle_create(&drizzle) == NULL)
107 {
108 printf("drizzle_create:NULL\n");
109 return 1;
110 }
111
113 drizzle_set_verbose(&drizzle, verbose);
114
115 if (drizzle_con_create(&drizzle, &con_listen) == NULL)
116 {
117 printf("drizzle_con_create:NULL\n");
118 return 1;
119 }
120
122 drizzle_con_set_tcp(&con_listen, server_host, server_port);
123
124 if (server_mysql)
126
127 if (drizzle_con_listen(&con_listen) != DRIZZLE_RETURN_OK)
128 {
129 printf("drizzle_con_listen:%s\n", drizzle_error(&drizzle));
130 return 1;
131 }
132
133 while (1)
134 {
135 (void)drizzle_con_accept(&drizzle, &server, &ret);
136 if (ret != DRIZZLE_RETURN_OK)
137 {
138 printf("drizzle_con_accept:%s\n", drizzle_error(&drizzle));
139 return 1;
140 }
141
142 if (drizzle_con_create(&drizzle, &client) == NULL)
143 {
144 printf("drizzle_con_create:NULL\n");
145 return 1;
146 }
147
150 if (client_mysql)
152 drizzle_con_set_tcp(&client, client_host, client_port);
153
154 ret= drizzle_con_connect(&client);
155 if (ret != DRIZZLE_RETURN_OK)
156 {
157 printf("drizzle_con_connect:%s\n", drizzle_error(&drizzle));
158 return 1;
159 }
160
161 proxy(&drizzle, &server, &client, &server_result, &client_result, &column);
162
163 drizzle_con_free(&client);
165
166 if (count > 0)
167 {
168 count--;
169
170 if (count == 0)
171 break;
172 }
173 }
174
175 drizzle_con_free(&con_listen);
176 drizzle_free(&drizzle);
177
178 return 0;
179}
180
181static void proxy(drizzle_st *drizzle, drizzle_con_st *server,
182 drizzle_con_st *client, drizzle_result_st *server_result,
183 drizzle_result_st *client_result, drizzle_column_st *column)
184{
186 drizzle_command_t command;
187 const uint8_t *data;
188 size_t offset;
189 size_t size;
190 size_t total;
191 uint64_t row;
192 bool row_break;
193 drizzle_field_t field;
194
195 /* Handshake packets. */
197 DRIZZLE_RETURN_CHECK(ret, "drizzle_handshake_server_read", drizzle)
198
200
202 DRIZZLE_RETURN_CHECK(ret, "drizzle_handshake_server_write", drizzle)
203
205 DRIZZLE_RETURN_CHECK(ret, "drizzle_handshake_client_read", drizzle)
206
208
210 DRIZZLE_RETURN_CHECK(ret, "drizzle_handshake_client_write", drizzle)
211
212 (void)drizzle_result_read(client, client_result, &ret);
213 DRIZZLE_RETURN_CHECK(ret, "drizzle_result_read", drizzle)
214
216
217 if (drizzle_result_clone(server, server_result, client_result) == NULL)
218 DRIZZLE_RETURN_ERROR("drizzle_result_clone", drizzle)
219
220 ret= drizzle_result_write(server, server_result, true);
221 DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
222
223 if (drizzle_result_error_code(client_result) != 0 ||
224 drizzle_result_eof(client_result))
225 {
226 /* There was a handshake or authentication error. */
227 return;
228 }
229
231
232 /* Command loop. */
233 while (1)
234 {
235 drizzle_result_free(server_result);
236 drizzle_result_free(client_result);
237
238 while (1)
239 {
240 data= drizzle_con_command_read(server, &command, &offset, &size, &total,
241 &ret);
243 return;
244
245 DRIZZLE_RETURN_CHECK(ret, "drizzle_con_command_read", drizzle)
246
247 (void)drizzle_con_command_write(client, NULL, command, data, size, total,
248 &ret);
249 DRIZZLE_RETURN_CHECK(ret, "drizzle_con_command_write", drizzle)
250
251 if ((offset + size) == total)
252 break;
253 }
254
255 if (command == DRIZZLE_COMMAND_QUIT)
256 return;
257 else if (command == DRIZZLE_COMMAND_FIELD_LIST)
258 {
259 if (drizzle_result_create(client, client_result) == NULL)
260 DRIZZLE_RETURN_ERROR("drizzle_result_create", drizzle)
261
262 if (drizzle_result_create(server, server_result) == NULL)
263 DRIZZLE_RETURN_ERROR("drizzle_result_create", drizzle)
264 }
265 else
266 {
267 (void)drizzle_result_read(client, client_result, &ret);
268 DRIZZLE_RETURN_CHECK(ret, "drizzle_result_read", drizzle)
269
271 if (drizzle_result_clone(server, server_result, client_result) == NULL)
272 DRIZZLE_RETURN_ERROR("drizzle_result_clone", drizzle)
273
274 if (drizzle_result_column_count(client_result) == 0)
275 {
276 /* Simple result with no column, row, or field data. */
277 ret= drizzle_result_write(server, server_result, true);
278 DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
279
280 continue;
281 }
282
283 ret= drizzle_result_write(server, server_result, false);
284 DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
285 }
286
287 /* Columns. */
288 while (1)
289 {
290 if (drizzle_column_read(client_result, column, &ret) == NULL)
291 {
292 DRIZZLE_RETURN_CHECK(ret, "drizzle_column_read", drizzle)
293 break;
294 }
295
296 DRIZZLE_RETURN_CHECK(ret, "drizzle_column_read", drizzle)
297
298 ret= drizzle_column_write(server_result, column);
299 DRIZZLE_RETURN_CHECK(ret, "drizzle_column_write", drizzle)
300
301 drizzle_column_free(column);
302 }
303
305 drizzle_result_set_eof(server_result, true);
306
307 if (command == DRIZZLE_COMMAND_FIELD_LIST)
308 {
309 ret= drizzle_result_write(server, server_result, true);
310 DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
311 continue;
312 }
313 else
314 {
315 ret= drizzle_result_write(server, server_result, false);
316 DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
317 }
318
319 /* Rows. */
320 while (1)
321 {
322 row= drizzle_row_read(client_result, &ret);
323 DRIZZLE_RETURN_CHECK(ret, "drizzle_row_read", drizzle)
324
325 if (row == 0)
326 break;
327
328 drizzle_result_set_row_size(server_result,
329 drizzle_result_row_size(client_result));
330
331 ret= drizzle_row_write(server_result);
332 DRIZZLE_RETURN_CHECK(ret, "drizzle_row_write", drizzle)
333
334 /* Fields. */
335 row_break= false;
336 while (row_break == false)
337 {
338 field= drizzle_field_read(client_result, &offset, &size, &total, &ret);
339 if (ret == DRIZZLE_RETURN_ROW_END)
340 break;
341 else if (ret == DRIZZLE_RETURN_ROW_BREAK)
342 {
343 if (size == 0)
344 break;
345
346 row_break= true;
347 }
348 else
349 DRIZZLE_RETURN_CHECK(ret, "drizzle_field_read", drizzle)
350
351 ret= drizzle_field_write(server_result, field, size, total);
352 DRIZZLE_RETURN_CHECK(ret, "drizzle_field_write", drizzle)
353 }
354 }
355
356 ret= drizzle_result_write(server, server_result, true);
357 DRIZZLE_RETURN_CHECK(ret, "drizzle_result_write", drizzle)
358 }
359}
drizzle_command_t
Definition constants.h:214
@ DRIZZLE_COMMAND_FIELD_LIST
Definition constants.h:219
@ DRIZZLE_COMMAND_QUIT
Definition constants.h:216
Drizzle Declarations for Clients.
Drizzle Declarations for Servers.
drizzle_column_st * drizzle_column_read(drizzle_result_st *result, drizzle_column_st *column, drizzle_return_t *ret_ptr)
Definition column.c:469
drizzle_return_t drizzle_column_write(drizzle_result_st *result, drizzle_column_st *column)
Definition column.c:562
void drizzle_column_free(drizzle_column_st *column)
Definition column.c:356
drizzle_return_t drizzle_con_connect(drizzle_con_st *con)
Definition conn.c:352
drizzle_result_st * drizzle_con_command_write(drizzle_con_st *con, drizzle_result_st *result, drizzle_command_t command, const void *data, size_t size, size_t total, drizzle_return_t *ret_ptr)
Definition conn.c:442
void drizzle_con_copy_handshake(drizzle_con_st *con, drizzle_con_st *from)
Definition conn.c:591
void drizzle_con_set_status(drizzle_con_st *con, drizzle_con_status_t status)
Definition conn.c:580
drizzle_return_t drizzle_con_listen(drizzle_con_st *con)
Definition conn.c:510
void * drizzle_con_command_read(drizzle_con_st *con, drizzle_command_t *command, size_t *offset, size_t *size, size_t *total, drizzle_return_t *ret_ptr)
Definition conn.c:606
void drizzle_con_set_tcp(drizzle_con_st *con, const char *host, in_port_t port)
Definition conn.c:209
drizzle_con_status_t drizzle_con_status(const drizzle_con_st *con)
Definition conn.c:338
void drizzle_con_add_options(drizzle_con_st *con, drizzle_con_options_t options)
Definition conn.c:164
@ DRIZZLE_CON_LISTEN
Definition constants.h:141
@ DRIZZLE_CON_MYSQL
Definition constants.h:135
@ DRIZZLE_CON_READY
Definition constants.h:138
@ DRIZZLE_CON_RAW_SCRAMBLE
Definition constants.h:137
@ DRIZZLE_CON_RAW_PACKET
Definition constants.h:136
drizzle_return_t
Definition constants.h:69
drizzle_verbose_t
Definition constants.h:102
@ DRIZZLE_RETURN_OK
Definition constants.h:70
@ DRIZZLE_RETURN_LOST_CONNECTION
Definition constants.h:90
@ DRIZZLE_RETURN_ROW_END
Definition constants.h:89
@ DRIZZLE_RETURN_ROW_BREAK
Definition constants.h:73
@ DRIZZLE_VERBOSE_NEVER
Definition constants.h:103
drizzle_field_t drizzle_field_read(drizzle_result_st *result, size_t *offset, size_t *size, size_t *total, drizzle_return_t *ret_ptr)
Definition field.c:22
drizzle_return_t drizzle_field_write(drizzle_result_st *result, const drizzle_field_t field, size_t size, size_t total)
Definition field.c:107
drizzle_return_t drizzle_handshake_server_read(drizzle_con_st *con)
Definition handshake.c:22
drizzle_return_t drizzle_handshake_client_write(drizzle_con_st *con)
Definition handshake.c:33
drizzle_return_t drizzle_handshake_client_read(drizzle_con_st *con)
Definition handshake.c:59
drizzle_return_t drizzle_handshake_server_write(drizzle_con_st *con)
Definition handshake.c:48
size_t drizzle_result_row_size(drizzle_result_st *result)
Definition result.c:261
drizzle_result_st * drizzle_result_read(drizzle_con_st *con, drizzle_result_st *result, drizzle_return_t *ret_ptr)
Definition result.c:172
void drizzle_result_set_eof(drizzle_result_st *result, bool eof)
Definition result.c:314
void drizzle_result_set_row_size(drizzle_result_st *result, size_t size)
Definition result.c:286
drizzle_return_t drizzle_result_write(drizzle_con_st *con, drizzle_result_st *result, bool flush)
Definition result.c:270
drizzle_result_st * drizzle_result_create(drizzle_con_st *con, drizzle_result_st *result)
Definition result.c:22
uint16_t drizzle_result_column_count(drizzle_result_st *result)
Definition result.c:158
bool drizzle_result_eof(drizzle_result_st *result)
Definition result.c:118
uint16_t drizzle_result_error_code(drizzle_result_st *result)
Definition result.c:133
void drizzle_result_free(drizzle_result_st *result)
Definition result.c:75
drizzle_result_st * drizzle_result_clone(drizzle_con_st *con, drizzle_result_st *result, drizzle_result_st *from)
Definition result.c:52
uint64_t drizzle_row_read(drizzle_result_st *result, drizzle_return_t *ret_ptr)
Definition row.c:22
drizzle_return_t drizzle_row_write(drizzle_result_st *result)
Definition row.c:146
drizzle_con_st * drizzle_con_accept(drizzle_st *drizzle, drizzle_con_st *con, drizzle_return_t *ret_ptr)
Definition drizzle.c:577
char * drizzle_field_t
Definition constants.h:412
drizzle_con_st * drizzle_con_create(drizzle_st *drizzle, drizzle_con_st *con)
Definition drizzle.c:237
const char * drizzle_error(const drizzle_st *drizzle)
Definition drizzle.c:146
void drizzle_set_verbose(drizzle_st *drizzle, drizzle_verbose_t verbose)
Definition drizzle.c:217
void drizzle_free(drizzle_st *drizzle)
Definition drizzle.c:123
void drizzle_add_options(drizzle_st *drizzle, drizzle_options_t options)
Definition drizzle.c:176
drizzle_st * drizzle_create(drizzle_st *drizzle)
Definition drizzle.c:61
void drizzle_con_free(drizzle_con_st *con)
Definition drizzle.c:343
@ DRIZZLE_FREE_OBJECTS
Definition constants.h:123
#define DRIZZLE_RETURN_CHECK(__ret, __function, __drizzle)
Definition proxy.c:19
int main(int argc, char *argv[])
Definition proxy.c:35
static void proxy(drizzle_st *drizzle, drizzle_con_st *server, drizzle_con_st *client, drizzle_result_st *server_result, drizzle_result_st *client_result, drizzle_column_st *column)
Definition proxy.c:181
#define DRIZZLE_RETURN_ERROR(__function, __drizzle)
Definition proxy.c:25
static void server(drizzle_st *drizzle, drizzle_con_st *con, drizzle_result_st *result, drizzle_column_st *column)
Definition server.c:142