2014-11-19 00:06:40 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#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);
|
|
|
|
}
|