#include #include #include "lib_acl.h" #include "service_main.h" typedef struct { ACL_ASTREAM *client; ACL_ASTREAM *server; } STREAM_PIPE; /* configure info */ /* TODO: you can add configure items here */ static int var_cfg_debug_mem; static int var_cfg_read_line; ACL_CONFIG_BOOL_TABLE service_conf_bool_tab[] = { /* TODO: you can add configure variables of int type here */ { "debug_mem", 0, &var_cfg_debug_mem }, { "read_line", 1, &var_cfg_read_line }, { 0, 0, 0 }, }; static int var_cfg_io_idle_limit; static int var_cfg_debug_mem; ACL_CONFIG_INT_TABLE service_conf_int_tab[] = { /* TODO: you can add configure variables of int type here */ { "io_idle_limit", 60, &var_cfg_io_idle_limit, 0, 0 }, { 0, 0, 0, 0, 0 }, }; static char *var_cfg_backend_addr; static char *var_cfg_request_file; static char *var_cfg_respond_file; ACL_CONFIG_STR_TABLE service_conf_str_tab[] = { /* TODO: you can add configure variables of (char *) type here */ /* example: { "mysql_dbaddr", "127.0.0.1:3306", &var_cfg_mysql_dbaddr }, */ { "backend_addr", "127.0.0.1:3306", &var_cfg_backend_addr }, { "request_file", "", &var_cfg_request_file }, { "respond_file", "", &var_cfg_respond_file }, { 0, 0, 0 }, }; static ACL_FILE *request_fp, *respond_fp; void service_init(void *init_ctx acl_unused) { const char *myname = "service_init"; if (var_cfg_request_file && *var_cfg_request_file) { request_fp = acl_fopen(var_cfg_request_file, "a+"); if (request_fp == NULL) acl_msg_error("%s(%d): open %s error(%s)", myname, __LINE__, var_cfg_request_file, acl_last_serror()); } if (var_cfg_respond_file && *var_cfg_respond_file) { respond_fp = acl_fopen(var_cfg_respond_file, "a+"); if (respond_fp == NULL) acl_msg_error("%s(%d): open %s error(%s)", myname, __LINE__, var_cfg_respond_file, acl_last_serror()); } } void service_exit(void *exist_ctx acl_unused) { if (request_fp) acl_fclose(request_fp); if (respond_fp) acl_fclose(respond_fp); } static int close_callback(ACL_ASTREAM *stream, void *ctx) { STREAM_PIPE *sp = (STREAM_PIPE*) ctx; if (sp->client == stream) { if (sp->server) acl_aio_iocp_close(sp->server); sp->client = NULL; } else if (sp->server == stream) { if (sp->client) acl_aio_iocp_close(sp->client); sp->server = NULL; } if (sp->client == NULL && sp->server == NULL) acl_myfree(sp); return (0); } static int read_callback(ACL_ASTREAM *stream, void *ctx, char *data, int dlen) { const char *myname = "read_callback"; STREAM_PIPE *sp = (STREAM_PIPE*) ctx; if (sp->client == stream) { if (request_fp) { if (var_cfg_read_line) { if (acl_fprintf(request_fp, ">>>%s", data) == EOF) { acl_msg_error("%s(%d): write to %s error(%s)", myname, __LINE__, var_cfg_request_file, acl_last_serror()); acl_fclose(request_fp); request_fp = NULL; } } else { if (acl_fwrite(data, dlen, 1, request_fp) == (size_t) EOF) { acl_msg_error("%s(%d): write to %s error(%s)", myname, __LINE__, var_cfg_request_file, acl_last_serror()); acl_fclose(request_fp); request_fp = NULL; } } } if (sp->server == NULL) return (-1); acl_aio_writen(sp->server, data, dlen); } else if (sp->server == stream) { if (respond_fp) { if (var_cfg_read_line) { if (acl_fprintf(respond_fp, "<<<%s", data) == EOF) { acl_msg_error("%s(%d): write to %s error(%s)", myname, __LINE__, var_cfg_respond_file, acl_last_serror()); acl_fclose(respond_fp); respond_fp = NULL; } } else { if (acl_fwrite(data, dlen, 1, respond_fp) == (size_t) EOF) { acl_msg_error("%s(%d): write to %s error(%s)", myname, __LINE__, var_cfg_respond_file, acl_last_serror()); acl_fclose(respond_fp); respond_fp = NULL; } } } if (sp->client == NULL) return (-1); acl_aio_writen(sp->client, data, dlen); } else return (-1); return (0); } static int connect_callback(ACL_ASTREAM *stream, void *ctx) { const char *myname = "connect_callback"; STREAM_PIPE *sp = (STREAM_PIPE*) ctx; if (sp->server != stream) acl_msg_fatal("%s(%d): sp->server != stream", myname, __LINE__); if (var_cfg_read_line) acl_aio_gets(sp->server); else acl_aio_read(sp->server); if (sp->client == NULL) return (-1); if (var_cfg_read_line) acl_aio_gets(sp->client); else acl_aio_read(sp->client); return (0); } void service_main(ACL_ASTREAM *astream, void *run_ctx acl_unused) { const char *myname = "service_main"; STREAM_PIPE *sp = (STREAM_PIPE*) acl_mycalloc(1, sizeof(STREAM_PIPE)); acl_msg_info("%s: begin connect %s, client: %s", myname, var_cfg_backend_addr, ACL_VSTREAM_PEER(acl_aio_vstream(astream))); sp->client = astream; sp->server = acl_aio_connect(acl_aio_handle(astream), var_cfg_backend_addr, 10); if (sp->server == NULL) { acl_msg_error("%s(%d): connect %s error(%s)", myname, __LINE__, var_cfg_backend_addr, acl_last_serror()); acl_aio_iocp_close(astream); acl_myfree(sp); return; } acl_aio_ctl(sp->server, ACL_AIO_CTL_CONNECT_HOOK_ADD, connect_callback, sp, ACL_AIO_CTL_CLOSE_HOOK_ADD, close_callback, sp, ACL_AIO_CTL_READ_HOOK_ADD, read_callback, sp, ACL_AIO_CTL_TIMEOUT, 300, ACL_AIO_CTL_END); acl_aio_ctl(sp->client, ACL_AIO_CTL_CLOSE_HOOK_ADD, close_callback, sp, ACL_AIO_CTL_READ_HOOK_ADD, read_callback, sp, ACL_AIO_CTL_TIMEOUT, 300, ACL_AIO_CTL_END); }