-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathevs_api.c
435 lines (399 loc) · 28.5 KB
/
evs_api.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
// ----------------------------------------------------------------------
// Protocol Analyzer for PostgreSQL -
// Purpose:
// Various API processing.
//
// Program:
// Takeshi Kaburagi/MyDNS.JP https://www.fvg-on.net/
//
// Usage:
// ./evs_pganalyzer [./evserver.ini]
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// ヘッダ部分
// ----------------------------------------------------------------------
// --------------------------------
// インクルード宣言
// --------------------------------
// autoconf用宣言
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "evs_main.h"
// --------------------------------
// 定数宣言
// --------------------------------
// --------------------------------
// 型宣言
// --------------------------------
// --------------------------------
// 変数宣言
// --------------------------------
// ----------------
// PosgreSQL関連
// ----------------
const char *PgSQL_message_front_str[] = { // PostgreSQLのメッセージ名称の文字列をテーブル化(フロントエンドからのメッセージ用)
"", // 0x00 : NUL
"", // 0x01 : SOH
"", // 0x02 : STX
"", // 0x03 : ETX
"", // 0x04 : EOT
"", // 0x05 : ENQ
"", // 0x06 : ACK
"", // 0x07 : BEL
"", // 0x08 : BS
"", // 0x09 : HT
"", // 0x0A : LF
"", // 0x0B : VT
"", // 0x0C : FF(NP)
"", // 0x0D : CR
"", // 0x0E : SO
"", // 0x0F : SI
"", // 0x10 : DLE
"", // 0x11 : DC1
"", // 0x12 : DC2
"", // 0x13 : DC3
"", // 0x14 : DC4
"", // 0x15 : NAK
"", // 0x16 : SYN
"", // 0x17 : ETB
"", // 0x18 : CAN
"", // 0x19 : EM
"", // 0x1A : SUB
"", // 0x1B : ESC
"", // 0x1C : FS
"", // 0x1D : GS
"", // 0x1E : RS
"", // 0x1F : US
"", // 0x20 : SP
"", // 0x21 : !
"", // 0x22 : A
"", // 0x23 : #
"", // 0x24 : $
"", // 0x25 : %
"", // 0x26 : &
"", // 0x27 : '
"", // 0x28 : (
"", // 0x29 : )
"", // 0x2A : *
"", // 0x2B : +
"", // 0x2C : ,
"", // 0x2D : -
"", // 0x2E : .
"", // 0x2F : /
"", // 0x30 : 0
"", // 0x31 : 1
"", // 0x32 : 2
" ", // 0x33 : 3
"", // 0x34 : 4
"", // 0x35 : 5
"", // 0x36 : 6
"", // 0x37 : 7
"", // 0x38 : 8
"", // 0x39 : 9
"", // 0x3A : *
"", // 0x3B : ;
"", // 0x3C : <
"", // 0x3D : =
"", // 0x3E : >
"", // 0x3F : ?
"", // 0x40 : @
"", // 0x41 : A
"Bind", // 0x42 : B ... Bindコマンド(F)
"Close", // 0x43 : C ... Closeコマンド(F)
"Describe", // 0x44 : D ... Describeコマンド(F)
"Execute", // 0x45 : E ... Executeコマンド(F)
"FunctionCall", // 0x46 : F ... 関数呼び出し(F)
"", // 0x47 : G
"Flush", // 0x48 : H ... Flushコマンド(F)
"", // 0x49 : I
"", // 0x4A : J
"", // 0x4B : K
"", // 0x4C : L
"", // 0x4D : M
"", // 0x4E : N
"", // 0x4F : O
"Parse", // 0x50 : P ... Parseコマンド(F)
"Query", // 0x51 : Q ... 簡易問い合わせ(F)
"", // 0x52 : R
"Sync", // 0x53 : S ... Syncコマンド(F)
"", // 0x54 : T
"", // 0x55 : U
"", // 0x56 : V
"", // 0x57 : W
"Terminate", // 0x58 : X ... 終了(F)
"", // 0x59 : Y
"", // 0x5A : Z
"", // 0x5B : [
"", // 0x5C : \
"", // 0x5D : ]
"", // 0x5E : ^
"", // 0x5F : _
"", // 0x60 : `
"", // 0x61 : a
"", // 0x62 : b
"CopyDone", // 0x63 : c ... COPY完了指示子(F&B)
"CopyData", // 0x64 : d ... データのCOPY(F&B)
"", // 0x65 : e
"CopyFail", // 0x66 : f ... COPY失敗指示子(F)
"", // 0x67 : g
"", // 0x68 : h
"", // 0x69 : i
"", // 0x6A : j
"", // 0x6B : k
"", // 0x6C : l
"", // 0x6D : m
"", // 0x6E : n
"", // 0x6F : o
"Response...", // 0x70 : p ... パスワード応答(F)/最初のSASL応答(F)/SASL応答(F)/GSSAPIまたはSSPI応答(F) ※厳密なメッセージ種別は、その状況から推論しろと…
"", // 0x71 : q
"", // 0x72 : r
"", // 0x73 : s
"", // 0x74 : t
"", // 0x75 : u
"", // 0x76 : v
"", // 0x77 : w
"", // 0x78 : x
"", // 0x79 : y
"", // 0x7A : z
"", // 0x7B : {
"", // 0x7C : |
"", // 0x7D : }
"", // 0x7E : ~
"", // 0x7F : DEL
};
const char *PgSQL_message_backend_str[] = { // PostgreSQLのメッセージ名称の文字列をテーブル化(バックエンドからのメッセージ用)
"", // 0x00 : NUL
"", // 0x01 : SOH
"", // 0x02 : STX
"", // 0x03 : ETX
"", // 0x04 : EOT
"", // 0x05 : ENQ
"", // 0x06 : ACK
"", // 0x07 : BEL
"", // 0x08 : BS
"", // 0x09 : HT
"", // 0x0A : LF
"", // 0x0B : VT
"", // 0x0C : FF(NP)
"", // 0x0D : CR
"", // 0x0E : SO
"", // 0x0F : SI
"", // 0x10 : DLE
"", // 0x11 : DC1
"", // 0x12 : DC2
"", // 0x13 : DC3
"", // 0x14 : DC4
"", // 0x15 : NAK
"", // 0x16 : SYN
"", // 0x17 : ETB
"", // 0x18 : CAN
"", // 0x19 : EM
"", // 0x1A : SUB
"", // 0x1B : ESC
"", // 0x1C : FS
"", // 0x1D : GS
"", // 0x1E : RS
"", // 0x1F : US
"", // 0x20 : SP
"", // 0x21 : !
"", // 0x22 : A
"", // 0x23 : #
"", // 0x24 : $
"", // 0x25 : %
"", // 0x26 : &
"", // 0x27 : '
"", // 0x28 : (
"", // 0x29 : )
"", // 0x2A : *
"", // 0x2B : +
"", // 0x2C : ,
"", // 0x2D : -
"", // 0x2E : .
"", // 0x2F : /
"", // 0x30 : 0
"ParseComplete", // 0x31 : 1 ... Parse完了指示子(B)
"BindComplete", // 0x32 : 2 ... Bind完了指示子(B)
"CloseComplete ", // 0x33 : 3 ... Close完了指示子(B)
"", // 0x34 : 4
"", // 0x35 : 5
"", // 0x36 : 6
"", // 0x37 : 7
"", // 0x38 : 8
"", // 0x39 : 9
"", // 0x3A : *
"", // 0x3B : ;
"", // 0x3C : <
"", // 0x3D : =
"", // 0x3E : >
"", // 0x3F : ?
"", // 0x40 : @
"NotificationResponse", // 0x41 : A ... 通知応答(B)
"", // 0x42 : B
"CommandComplete", // 0x43 : C ... コマンド完了(B)
"DataRow", // 0x44 : D ... データ行(B)
"ErrorResponse", // 0x45 : E ... エラー(B)
"FunctionCall", // 0x46 : F
"CopyInResponse", // 0x47 : G ... Start Copy Inの応答(B)
"CopyOutResponse", // 0x48 : H ... Start Copy Outの応答(B)
"EmptyQueryResponse", // 0x49 : I ... 空の問い合わせ文字列に対する応答(B)
"", // 0x4A : J
"BackendKeyData", // 0x4B : K ... 取り消しする際のキーデータ(B)
"", // 0x4C : L
"", // 0x4D : M
"NoticeResponse", // 0x4E : N ... 警報(B)
"", // 0x4F : O
"", // 0x50 : P
"", // 0x51 : Q
"Authentication", // 0x52 : R ... OKか、特定の認証が必要かはメッセージ内容による(B)
"ParameterStatus", // 0x53 : S ... 実行時パラメータ状態報告(B)
"RowDescription", // 0x54 : T ... 行の記述(B)
"", // 0x55 : U
"FunctionCallResponse", // 0x56 : V ... 関数呼び出しの結果(B)
"CopyBothResponse", // 0x57 : W ... Start Copy Bothの応答(B)
"", // 0x58 : X
"", // 0x59 : Y
"ReadyForQuery", // 0x5A : Z ... 新しい問い合わせサイクルの準備が整った
"", // 0x5B : [
"", // 0x5C : \
"", // 0x5D : ]
"", // 0x5E : ^
"", // 0x5F : _
"", // 0x60 : `
"", // 0x61 : a
"", // 0x62 : b
"CopyDone", // 0x63 : c ... COPY完了指示子(F&B)
"CopyData", // 0x64 : d ... データのCOPY(F&B)
"", // 0x65 : e
"", // 0x66 : f
"", // 0x67 : g
"", // 0x68 : h
"", // 0x69 : i
"", // 0x6A : j
"", // 0x6B : k
"", // 0x6C : l
"", // 0x6D : m
"NoData", // 0x6E : n ... データなしの指示子(B)
"", // 0x6F : o
"", // 0x70 : p
"", // 0x71 : q
"", // 0x72 : r
"PortalSuspended", // 0x73 : s ... ポータル中断指示子(B)
"ParameterDescription", // 0x74 : t ... パラメータ記述(B)
"", // 0x75 : u
"NegotiateProtocolVersion", // 0x76 : v ... プロトコルバージョン交渉(B)
"", // 0x77 : w
"", // 0x78 : x
"", // 0x79 : y
"", // 0x7A : z
"", // 0x7B : {
"", // 0x7C : |
"", // 0x7D : }
"", // 0x7E : ~
"", // 0x7F : DEL
};
const char *PgSQL_client_param_list[] = { // PostgreSQLの開始メッセージ中の各種設定値名(基本的には受けたメッセージをそのままPostgreSQLに転送するけどね)
"database", // 接続したいデータベース名
"user", // 接続してきたユーザー名
"client_encoding", // クライアントが指定してきた文字コード
};
const char *PgSQL_server_SASL_list[] = { // PostgreSQLのSASL認証で送られてくるパラメータ
"r=", // サーバー側が指定してきたナンス
"s=", // サーバー側が指定してきたBASE64エンコードされたソルトキー
"i=", // サーバー側が指定してきたイテレーション(反復回数)
"v=", // サーバー側が指定してきたベリファイデータ
};
// ----------------------------------------------------------------------
// コード部分
// ----------------------------------------------------------------------
// --------------------------------
// クライアント(psql)関連
// --------------------------------
// evs_api.c に各APIの処理を全部書くと長すぎるので、API毎にファイルを分離する。
// evs_api.c からincludeされることを想定しているので、evs_main.hなどのヘッダファイルはincludeしていない。
#include "evs_api_client.c"
// --------------------------------
// PostgreSQL関連
// --------------------------------
// evs_api.c に各APIの処理を全部書くと長すぎるので、API毎にファイルを分離する。
// evs_api.c からincludeされることを想定しているので、evs_main.hなどのヘッダファイルはincludeしていない。
#include "evs_api_pgsql.c"
// --------------------------------
// PostgreSQLクライアント側処理
// --------------------------------
int API_pgsql_client(struct EVS_ev_client_t *this_client)
{
int api_result = 0;
char log_str[MAX_LOG_LENGTH];
// とりあえず表示する
snprintf(log_str, MAX_LOG_LENGTH, "%s(fd=%d): START! client_status=%d\n", __func__, this_client->socket_fd, this_client->client_status);
logging(LOG_QUEUEING, LOGLEVEL_INFO, NULL, NULL, NULL, log_str, strlen(log_str));
// ------------------------------------
// クライアントからのメッセージ解析
// ------------------------------------
// クライアント毎の状態が、0:接続待ちなら
if (this_client->client_status == 0)
{
// クライアント開始メッセージ解析処理を呼び出し(クエリは来ないはず)
api_result = API_pgsql_client_start(this_client);
// 正常終了でないなら
if (api_result != 0)
{
// 戻る
return api_result;
}
}
// クライアント毎の状態が、1:開始メッセージ応答待ちなら
if (this_client->client_status == 1)
{
// ここには来ないはずだが…!?
}
// クライアント毎の状態が、2:クエリメッセージ待ちなら
if (this_client->client_status == 2)
{
// クライアントクエリメッセージ解析処理を呼び出し(クエリ以外の場合もあり)
api_result = API_pgsql_client_query(this_client);
// 正常終了でないなら
if (api_result != 0)
{
// 戻る
return api_result;
}
}
// クライアント毎の状態が、3:クエリデータ待ちなら
if (this_client->client_status == 3)
{
}
// 上記以外は
if (this_client->client_status < 0 ||
this_client->client_status > 3)
{
// エラー
snprintf(log_str, MAX_LOG_LENGTH, "%s(fd=%d): Illegal Client Status(=%d)!?\n", __func__, this_client->socket_fd, this_client->client_status);
logging(LOG_DIRECT, LOGLEVEL_ERROR, NULL, NULL, NULL, log_str, strlen(log_str));
// 戻る
return -1;
}
snprintf(log_str, MAX_LOG_LENGTH, "%s(): END!\n", __func__);
logging(LOG_QUEUEING, LOGLEVEL_DEBUG, NULL, NULL, NULL, log_str, strlen(log_str));
// 戻る
return api_result;
}
// --------------------------------
// API開始処理(クライアント別処理分岐、スレッド生成など)
// --------------------------------
int API_start(struct EVS_ev_client_t *this_client)
{
int api_result;
char log_str[MAX_LOG_LENGTH];
// とりあえず表示する
snprintf(log_str, MAX_LOG_LENGTH, "%s(fd=%d): START!\n", __func__, this_client->socket_fd);
logging(LOG_QUEUEING, LOGLEVEL_INFO, NULL, NULL, NULL, log_str, strlen(log_str));
// PostgreSQLクライアント側処理を通常呼出
api_result = API_pgsql_client(this_client);
// クライアント毎のリクエストで処理時間が変わるので、スレッド化して分散処理をしたほうがいいかと思ったけれど、スレッドを生成すると、クライアントからの接続をとりこぼす事象が発生した。
// これとは別にHTTP処理について作りこみをしたが、少なくともabでApache(Prefork)との処理速度比較をすると、変にスレッド生成しないのが一番速いという結果がでた。
// libevとpthreadの関係だと思うけど、深いところまでは追っていないので、調べて教えてくれると嬉しいです。
// 戻る
return api_result;
}