diff options
Diffstat (limited to 'src/qq_file_entry.c')
| -rw-r--r-- | src/qq_file_entry.c | 868 |
1 files changed, 868 insertions, 0 deletions
diff --git a/src/qq_file_entry.c b/src/qq_file_entry.c new file mode 100644 index 0000000..ad49b50 --- /dev/null +++ b/src/qq_file_entry.c @@ -0,0 +1,868 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <errno.h> +#include <assert.h> + +#include <MESA/stream.h> +#include <MESA/MESA_prof_load.h> +#include <MESA/MESA_handle_logger.h> +#include <MESA/field_stat.h> + +#include "qq_file_entry.h" +#include "qq_file_global.h" +#include "connector.h" + +qq_global_info_t g_qq_global_info; + +int data_hit_feature(const char *data, unsigned int datalen, unsigned int min_len, FEATURE_INDEX_T index) +{ + unsigned int i, j; + + if(datalen > min_len) + { + for(i=0; i<g_qq_global_info.fnum[index]; i++) + { + for(j=0; j<g_qq_global_info.rulenum[index][i]; j++) + { + //������ƥ�� + if(datalen <= (g_qq_global_info.ftoff[index][i][j] + g_qq_global_info.ftlen[index][i][j]) || \ + memcmp(data+g_qq_global_info.ftoff[index][i][j], g_qq_global_info.feature[index][i][j], g_qq_global_info.ftlen[index][i][j])) + { + break; + } + } + //һ�������ڵ����й���ƥ�䣬������ + if(j == g_qq_global_info.rulenum[index][i]) + { + return 1; + } + } + } + + return 0; +} + +QQ_PACKET_TYPE_t is_qq_protocol_tcp(const char *data, unsigned int datalen) +{ + if(data_hit_feature(data, datalen, 0, FINDEX_TCPFILE)) + return QQ_PACKET_TCPFILE; + if(data_hit_feature(data, datalen, PACKET_MIN_LEN_TCPNAME, FINDEX_TCPNAME)) + return QQ_PACKET_TCPFILENAME; + //�ŵ�FINDEX_TCPFILE��FINDEX_TCPNAME֮����Ϊ������Ҳ������FINDEX_TCPNUM���Ͷ��������ݣ�UDPһ�������� + if(data_hit_feature(data, datalen, PACKET_MIN_LEN_QQNUM, FINDEX_TCPNUM)) + return QQ_PACKET_QQNUM; + if(data_hit_feature(data, datalen, 0, FINDEX_TCPPROT)) + return QQ_PACKET_OTHER; + + return QQ_PACKET_NOT; +} + +QQ_PACKET_TYPE_t is_qq_protocol_udp(const char *data, unsigned int datalen) +{ + if(data_hit_feature(data, datalen, 0, FINDEX_UDPFILE)) + return QQ_PACKET_UDPFILE; + if(data_hit_feature(data, datalen, PACKET_MIN_LEN_UDPNAME, FINDEX_UDPNAME)) + return QQ_PACKET_UDPFILENAME; + if(data_hit_feature(data, datalen, 0, FINDEX_UDPFILE_END)) + return QQ_PACKET_UDPFILE_END; + if(data_hit_feature(data, datalen, PACKET_MIN_LEN_QQNUM, FINDEX_UDPNUM)) + return QQ_PACKET_QQNUM; + if(data_hit_feature(data, datalen, 0, FINDEX_UDPPROT)) + return QQ_PACKET_OTHER; + + return QQ_PACKET_NOT; +} + + +QQ_STATE_t assign_qq_state(QQ_PACKET_TYPE_t type) +{ + switch(type) + { + case QQ_PACKET_QQNUM: return QQ_STATE_QQNUM; + + case QQ_PACKET_TCPFILE: + case QQ_PACKET_UDPFILE: return QQ_STATE_FCONT_START; + + case QQ_PACKET_UDPFILE_END: return QQ_STATE_FCONT_END; + + case QQ_PACKET_TCPFILENAME: + case QQ_PACKET_UDPFILENAME: return QQ_STATE_FNAME; + + case QQ_PACKET_NOT: + case QQ_PACKET_OTHER: return QQ_STATE_INIT; + default: + assert(0); + return QQ_STATE_INIT; + } +} + +static int init_qq_pme_info(qq_proto_pme_t **pme, int thread_id, char tcp_flag) +{ + qq_proto_pme_t *qq_pme=NULL; + + qq_pme= (qq_proto_pme_t *)dictator_malloc(thread_id, sizeof(qq_proto_pme_t)); + memset(qq_pme, 0, sizeof(qq_proto_pme_t)); + qq_pme->thread_id = thread_id; + qq_pme->qq_state = QQ_STATE_INIT; + qq_pme->pending_flag = 1; + qq_pme->fileinfo.block_seq = -1; //UDP��ʼ�������-1������ʶ���ش������ + qq_pme->tcp_flag = tcp_flag; + + *pme = qq_pme; + + if(g_qq_global_info.stat_trig) + { + stat_field_operation(g_qq_global_info.stat_handle, g_qq_global_info.stat_id[STAT_ID_SESSION_NUM], FS_OP_TYPE_ADD, 1); + stat_field_operation(g_qq_global_info.stat_handle, g_qq_global_info.stat_id[STAT_ID_NEW_SESSION], FS_OP_TYPE_ADD, 1); + } + + return 0; +} + +static void clear_qq_pme_info(qq_proto_pme_t *qq_pme, struct streaminfo *a_udp, const void *raw_pkt) +{ + if(qq_pme->connector_hdl != NULL) + { + connector_finish(qq_pme->connector_hdl); + } + if(qq_pme->fileinfo.buf) + { + dictator_free(qq_pme->thread_id, qq_pme->fileinfo.buf); + } + + dictator_free(qq_pme->thread_id, qq_pme); + + if(g_qq_global_info.stat_trig) + { + stat_field_operation(g_qq_global_info.stat_handle, g_qq_global_info.stat_id[STAT_ID_SESSION_NUM], FS_OP_TYPE_ADD, -1); + stat_field_operation(g_qq_global_info.stat_handle, g_qq_global_info.stat_id[STAT_ID_DEL_SESSION], FS_OP_TYPE_ADD, 1); + } +} + +QQ_STATE_t analyse_udp_pdata_state(QQ_STATE_t state, const char *data, int datalen) +{ + if(state != QQ_STATE_INIT) + return state; + + return assign_qq_state(is_qq_protocol_udp(data, datalen)); +} + +QQ_STATE_t analyse_tcp_pdata_state(QQ_STATE_t state, const char *data, int datalen) +{ + if(state != QQ_STATE_INIT) + return state; + + return assign_qq_state(is_qq_protocol_tcp(data, datalen)); +} + +int process_udp_data_state(struct streaminfo *a_udp, qq_proto_pme_t *qq_pme, int thread_seq,const void *raw_pkt) +{ + char *data = (char *)a_udp->pudpdetail->pdata; + int datalen = a_udp->pudpdetail->datalen; + char filename[512]; + int tmp, i, j; + + switch(qq_pme->qq_state) + { + case QQ_STATE_QQNUM: + qq_pme->qq_state = QQ_STATE_INIT; + if(qq_pme->qqnum[a_udp->curdir-1] || qq_pme->qqnum_from) + break; + + if(*data == 0x03 && datalen==27) + { + qq_pme->qqnum[a_udp->curdir-1] = ntohl(*((unsigned int *)&data[23])); + } + else if(*data == 0x04) //TODO + { + qq_pme->qqnum_from = ntohl(*((unsigned int *)&data[9])); + } + break; + + case QQ_STATE_FNAME: + qq_pme->qq_state = QQ_STATE_INIT; + qq_pme->file_dir = a_udp->curdir - 1; + + if(*data == 0x05 && datalen < 800) //800---����д�� + { + qq_pme->total_file_len = ntohl(*((unsigned int *)&data[11])); + for (i = 23, j = 0; i < datalen - 1; i+=2, j+=2) + { + if ((data[i] == 0x00) && (data[i + 1] == 0x00)) + break; + filename[j] = data[i]; + filename[j+1] = data[i+1]; + } + tmp = j; + } + else if(*data == 0x04 && datalen < 800) + { + if(qq_pme->qqnum_from == 0) + { + qq_pme->qqnum_from = ntohl(*((unsigned int *)&data[9])); + } + qq_pme->total_file_len = ntohl(*((unsigned int *)&data[42])); + for (i = 54, j = 0; i < datalen - 1; i+=2, j+=2) + { + if ((data[i] == 0x00) && (data[i + 1] == 0x00)) + break; + filename[j] = data[i]; + filename[j+1] = data[i+1]; + } + tmp = j; + } + else + { + return APP_STATE_GIVEME; + } + return protocol_process(qq_pme, QQ_FILENAME, filename, tmp, a_udp, raw_pkt); + + case QQ_STATE_FCONT_START: + qq_pme->qq_state = QQ_STATE_INIT; //ÿ����ǰ�涼������ + if(*data == 0x05 && datalen>18) + { + tmp = ntohl(*((int *)&data[10])); //TODO��֪��int�ͻ���short + if(qq_pme->fileinfo.block_seq >= tmp) + return APP_STATE_GIVEME; + + qq_pme->fileinfo.block_seq = tmp; + qq_pme->compress_flag = data[17]; + return protocol_process(qq_pme, QQ_FILECONT, data+18, datalen-18, a_udp, raw_pkt); + } + else if(*data==0x04 && datalen>50) + { + tmp = ntohl(*((int *)&data[41])); //TODO��֪��int�ͻ���short + if(qq_pme->fileinfo.block_seq >= tmp) + return APP_STATE_GIVEME; + + qq_pme->fileinfo.block_seq = tmp; + qq_pme->compress_flag = data[48]; + return protocol_process(qq_pme, QQ_FILECONT, data+49, datalen-50, a_udp, raw_pkt); + } + break; + + case QQ_STATE_FCONT_END: + qq_pme->qq_state = QQ_STATE_INIT; + if(*data == 0x05 && datalen>18) + { + qq_pme->compress_flag = data[17]; + return protocol_process(qq_pme, QQ_FILECONT_END, data+18, datalen-18, a_udp, raw_pkt); + } + else if(*data == 0x04 && datalen>50) + { + qq_pme->compress_flag = data[48]; + return protocol_process(qq_pme, QQ_FILECONT_END, data+49, datalen-50, a_udp, raw_pkt); + } + break; + + case QQ_STATE_FCONT: + case QQ_STATE_INIT: + default: + break; + } + + return APP_STATE_GIVEME; +} + +extern "C" char QQ_PROT_UDP_ENTRY(struct streaminfo *a_udp, void **pme, int thread_seq,const void *raw_pkt) +{ + QQ_PACKET_TYPE_t type; + qq_proto_pme_t *qq_pme=(qq_proto_pme_t*)(*pme); + int rec = APP_STATE_GIVEME; + + switch(a_udp->opstate) + { + case OP_STATE_PENDING: + type = is_qq_protocol_udp((char *)a_udp->pudpdetail->pdata, a_udp->pudpdetail->datalen); + if(type) + { + if(init_qq_pme_info(&qq_pme, a_udp->threadnum, 0)) + return APP_STATE_DROPME; + qq_pme->qq_state = assign_qq_state(type); + *pme = qq_pme; + } + else + { + return APP_STATE_DROPME; + } + //no break here + + case OP_STATE_DATA: + qq_pme->qq_state = analyse_udp_pdata_state(qq_pme->qq_state, (char *)a_udp->pudpdetail->pdata, a_udp->pudpdetail->datalen); + + rec = process_udp_data_state(a_udp, qq_pme, thread_seq, raw_pkt); + break; + + case OP_STATE_CLOSE: + clear_qq_pme_info(qq_pme, a_udp, raw_pkt); + break; + + default: + return APP_STATE_DROPME; + } + + if(rec & APP_STATE_DROPME) + { + clear_qq_pme_info(qq_pme, a_udp, raw_pkt); + } + + return rec; +} + + +int process_tcp_data_state(struct streaminfo *a_tcp, qq_proto_pme_t *qq_pme, int thread_seq,const void *raw_pkt) +{ + char *data = (char *)a_tcp->pudpdetail->pdata; + int datalen = a_tcp->pudpdetail->datalen; + char filename[512]; + int cur_len=0, i, j, rec = APP_STATE_GIVEME, need_len; + + switch(qq_pme->qq_state) + { + case QQ_STATE_QQNUM: + qq_pme->qq_state = QQ_STATE_INIT; + if(qq_pme->qqnum_from) + break; + + if(*data == 0x04) //TODO + { + qq_pme->qqnum_from = ntohl(*((unsigned int *)&data[9])); + } + break; + + case QQ_STATE_FNAME: + qq_pme->qq_state = QQ_STATE_INIT; + qq_pme->file_dir = a_tcp->curdir - 1; + + //ȡ���ļ������ļ�����UNICODE����� + if(*data == TCPFILE_START_CHAR0c && datalen < 800) //800---����д�� + { + qq_pme->total_file_len = ntohl(*((unsigned int *)&data[27])); + for (i = 39, j = 0; i < datalen - 1; i+=2, j+=2) + { + if ((data[i] == 0x00) && (data[i + 1] == 0x00)) + break; + filename[j] = data[i]; + filename[j+1] = data[i+1]; + } + cur_len = j; + } + else if(*data == TCPFILE_START_CHAR04 && datalen < 800) + { + qq_pme->total_file_len = ntohl(*((unsigned int *)&data[90])); + for (i = 102, j = 0; i < datalen - 1; i+=2, j+=2) + { + if ((data[i] == 0x00) && (data[i + 1] == 0x00)) + break; + filename[j] = data[i]; + filename[j+1] = data[i+1]; + } + cur_len = j; + } + else + { + return APP_STATE_GIVEME; + } + return protocol_process(qq_pme, QQ_FILENAME, filename, cur_len, a_tcp, raw_pkt); + + case QQ_STATE_FCONT_START: + //��UDP��ͬ���ǣ�TCP����ͷ����һ���ǰ���ƥ����������ʽ���䣻 + if(a_tcp->curdir != qq_pme->file_dir+1) + break; + + if(a_tcp->ptcpdetail->lostlen) //����������Ѱ�Ұ���ͷ + { + qq_pme->fileinfo.len = 0; + qq_pme->qq_state = QQ_STATE_INIT; + break; + } + if(qq_pme->fileinfo.len > 0) + { + if(qq_pme->fileinfo.len < TCPFILE_HDR_LEN04+1) //�ж�������ʱ��Ҫ�����ݳ��ȴ���ͷ������ + { + need_len = TCPFILE_HDR_LEN04+1 - qq_pme->fileinfo.len; + if(datalen < need_len) + { + if(save_initial_tcp_data(&qq_pme->fileinfo, data, datalen, qq_pme->thread_id) < 0) + { + return APP_STATE_DROPME; + } + return APP_STATE_GIVEME; + } + memcpy(qq_pme->fileinfo.buf+qq_pme->fileinfo.len, data, need_len); + qq_pme->fileinfo.len += need_len; + data += need_len; + datalen -= need_len; + if(data_hit_feature(qq_pme->fileinfo.buf, qq_pme->fileinfo.len, 0, FINDEX_TCPFILE)) + { + qq_pme->fileinfo.prot_flag = QQ_FILECONT; + } + else if(data_hit_feature(qq_pme->fileinfo.buf, qq_pme->fileinfo.len, 0, FINDEX_TCPFILE_END)) + { + qq_pme->fileinfo.prot_flag = QQ_FILECONT_END; + } + else + { + return APP_STATE_DROPME; + } + if(*(qq_pme->fileinfo.buf) == TCPFILE_START_CHAR04) + { + qq_pme->fileinfo.block_len = ntohs(*((unsigned short *)&qq_pme->fileinfo.buf[3])); + qq_pme->compress_flag = qq_pme->fileinfo.buf[TCPFILE_HDR_LEN04-1]; + } + } + + //����һ��������ij��� + need_len = qq_pme->fileinfo.block_len - qq_pme->fileinfo.len; + if(need_len > datalen) + { + if(save_initial_tcp_data(&qq_pme->fileinfo, data, datalen, qq_pme->thread_id) < 0) + { + return APP_STATE_DROPME; + } + return APP_STATE_GIVEME; + } + if(save_initial_tcp_data(&qq_pme->fileinfo, data, need_len, qq_pme->thread_id) < 0) + { + return APP_STATE_DROPME; + } + qq_pme->fileinfo.len = 0; + data += need_len; + datalen -= need_len; + + if(*(qq_pme->fileinfo.buf) == TCPFILE_START_CHAR04 && qq_pme->fileinfo.block_len>TCPFILE_HDR_LEN04) + { + if(*(qq_pme->fileinfo.buf + qq_pme->fileinfo.block_len - 1) != TCPFILE_END_CHAR04) + return APP_STATE_DROPME; + rec = protocol_process(qq_pme, qq_pme->fileinfo.prot_flag, qq_pme->fileinfo.buf+TCPFILE_HDR_LEN04, qq_pme->fileinfo.block_len-TCPFILE_HDR_LEN04-1, a_tcp, raw_pkt); + } + if(rec & APP_STATE_DROPME) + { + return rec; + } + } + + while(datalen>0) + { + //ͷ���������Ȳ������������� + if(datalen < TCPFILE_HDR_LEN04+1) + { + if(save_initial_tcp_data(&qq_pme->fileinfo, data, datalen, qq_pme->thread_id) < 0) + { + return APP_STATE_DROPME; + } + return APP_STATE_GIVEME; + } + + if(data_hit_feature(data, datalen, 0, FINDEX_TCPFILE)) + { + qq_pme->fileinfo.prot_flag = QQ_FILECONT; + } + else if(data_hit_feature(data, datalen, 0, FINDEX_TCPFILE_END)) + { + qq_pme->fileinfo.prot_flag = QQ_FILECONT_END; + } + else + { + //�е�ʱ���м����С�飬�轫���߳� + unsigned short block_len = ntohs(*((unsigned short *)&data[3])); + if(*data == TCPFILE_START_CHAR04 && block_len < TCPFILE_HDR_LEN04) + { + data += block_len; + datalen -= block_len; + } + else + { + return APP_STATE_DROPME; + } + } + + //ͷ�����ȹ�����ͷ��ȡ���鳤�ȣ��鲻��Ҳ�������� + if(*data == TCPFILE_START_CHAR04 && datalen>TCPFILE_HDR_LEN04) + { + qq_pme->fileinfo.block_len = ntohs(*((unsigned short *)&data[3])); + qq_pme->compress_flag = data[TCPFILE_HDR_LEN04-1]; + if(datalen < qq_pme->fileinfo.block_len) + { + if(save_initial_tcp_data(&qq_pme->fileinfo, data, datalen, qq_pme->thread_id) < 0) + { + return APP_STATE_DROPME; + } + return APP_STATE_GIVEME; + } + + rec = protocol_process(qq_pme, qq_pme->fileinfo.prot_flag, data+TCPFILE_HDR_LEN04, qq_pme->fileinfo.block_len-TCPFILE_HDR_LEN04-1, a_tcp, raw_pkt); + if(rec & APP_STATE_DROPME) + { + return rec; + } + data += qq_pme->fileinfo.block_len; + datalen -= qq_pme->fileinfo.block_len; + } + } + break; + + case QQ_STATE_FCONT_END: + case QQ_STATE_FCONT: + case QQ_STATE_INIT: + default: + break; + } + + return APP_STATE_GIVEME; +} + +extern "C" char QQ_PROT_TCP_ENTRY(struct streaminfo *a_tcp, void **pme, int thread_seq,const void *raw_pkt) +{ + QQ_PACKET_TYPE_t type; + qq_proto_pme_t *qq_pme=(qq_proto_pme_t*)(*pme); + int rec = APP_STATE_GIVEME; + + switch(a_tcp->opstate) + { + case OP_STATE_PENDING: + type = is_qq_protocol_tcp((char *)a_tcp->ptcpdetail->pdata, a_tcp->ptcpdetail->datalen); + if(type) + { + if(init_qq_pme_info(&qq_pme, a_tcp->threadnum, 1)) + return APP_STATE_DROPME; + qq_pme->qq_state = assign_qq_state(type); + *pme = qq_pme; + } + else + { + return APP_STATE_DROPME; + } + //no break here + + case OP_STATE_DATA: + qq_pme->qq_state = analyse_tcp_pdata_state(qq_pme->qq_state, (char *)a_tcp->ptcpdetail->pdata, a_tcp->ptcpdetail->datalen); + + rec = process_tcp_data_state(a_tcp, qq_pme, thread_seq, raw_pkt); + break; + + case OP_STATE_CLOSE: + clear_qq_pme_info(qq_pme, a_tcp, raw_pkt); + break; + + default: + return APP_STATE_DROPME; + } + + if(rec & APP_STATE_DROPME) + { + clear_qq_pme_info(qq_pme, a_tcp, raw_pkt); + } + + return rec; +} + +int mkdir_according_path(const char * path) +{ + char buffer[256]; + const char *ps=path, *pc; + + if(*ps == '/') + ps += 1; + + while((pc = strchr(ps, '/')) != NULL) + { + while(*(pc+1) == '/') + pc++; + + memcpy(buffer, path, pc - path); + buffer[pc-path] = '\0'; + + if(access(buffer, F_OK)) + { + if(mkdir(buffer, 0777)) + { + return -1; + } + } + + ps = pc + 1; + } + if(access(path, F_OK)) + { + if(mkdir(path, 0777)) + { + return -1; + } + } + return 0; +} + +static int register_field_stat(const char *logpath) +{ + unsigned int stat_cycle; + int ret, i; + char stat_log[128]; + const char *region_name[STAT_ID_NUM]={"NEW_SESSION", "DEL_SESSION", "SESSION_NUM"}; + + snprintf(stat_log, 128, "%s/qq_stat.log", logpath); + + ret = MESA_load_profile_uint_def(CONF_FILENAME, "MODULE", "STAT_FIELD_CYCLE",&stat_cycle, 5); + if(ret < 0) + { + MESA_HANDLE_RUNTIME_LOG(g_qq_global_info.runtime_log, RLOG_LV_INFO, MODULE_NAME,"get [MODULE] STAT_FIELD_CYCLE failed, using default 5."); + } + ret = MESA_load_profile_int_def(CONF_FILENAME, "MODULE", "STAT_FIELD_TRIG",&g_qq_global_info.stat_trig, 0); + if(ret < 0) + { + MESA_HANDLE_RUNTIME_LOG(g_qq_global_info.runtime_log, RLOG_LV_INFO, MODULE_NAME,"get [MODULE] STAT_FIELD_TRIG failed, using default 0."); + } + + if(g_qq_global_info.stat_trig==0) + return 0; + + FILE* stat_fd = fopen(stat_log, "w"); + if(stat_fd == NULL) + { + MESA_HANDLE_RUNTIME_LOG(g_qq_global_info.runtime_log, RLOG_LV_INFO, MODULE_NAME,"fopen %s failed.", stat_log); + return -1; + } + + g_qq_global_info.stat_handle = init_screen_stat(stat_fd, stat_cycle, g_qq_global_info.stat_trig); + if(g_qq_global_info.stat_handle==NULL) + { + MESA_HANDLE_RUNTIME_LOG(g_qq_global_info.runtime_log, RLOG_LV_INFO, MODULE_NAME,"init_screen_stat failed."); + return -1; + } + + for(i=0;i<STAT_ID_NUM;i++) + { + g_qq_global_info.stat_id[i] = stat_field_register(g_qq_global_info.stat_handle, region_name[i]); + if(g_qq_global_info.stat_id[i] < 0) + { + MESA_HANDLE_RUNTIME_LOG(g_qq_global_info.runtime_log, RLOG_LV_INFO, MODULE_NAME,"stat_field_register %s failed.", region_name[i]); + return -1; + } + } + + return 0; +} + +/*������������ʽ(��ʾ��)�� + *FEATURE_QQ_TCPFILENAME=0:04&13:00,01,00,00,00,00,00&31:0c,00,00,00,00,2b;3:00,2b,52,00,00&34:00,2b,52,00,00 + *1.�Էֺŷָ�һ�����ã������ж�����ã������ǻ�Ĺ�ϵ�� + *2.��&�ָ�һ�������ڵĶ���������������Ĺ�ϵ�� + *3.ÿ�������ǰ��һ�����ֺ�ð�ű�ʾ��ʮ�����ƴ���һ�����ڵ�ƫ����(�ֽ�)��ÿ��ʮ����������ռ��λ���ö��ŷָ +*/ +int decode_feature_to_binary(char *feature, const char *feature_name, + char *feature_bin[MAX_QQ_FEATURE_NUM][MAX_AND_RULE], + unsigned int feature_len[MAX_QQ_FEATURE_NUM][MAX_AND_RULE], + unsigned int feature_off[MAX_QQ_FEATURE_NUM][MAX_AND_RULE], + unsigned int rulenum[MAX_QQ_FEATURE_NUM], + unsigned int *feature_num) +{ + char *ptmp0, *save_ptr0=NULL, *ptmp1, *save_ptr1=NULL, *ptmp2, *save_ptr2=NULL; + int fnum=0, rnum, i, val; + + for(ptmp0 = strtok_r(feature, ";", &save_ptr0); ptmp0 != NULL; ptmp0 = strtok_r(NULL, ";", &save_ptr0)) + { + rnum = 0; + for(ptmp1 = strtok_r(ptmp0, "&", &save_ptr1); ptmp1 != NULL; ptmp1 = strtok_r(NULL, "&", &save_ptr1)) + { + feature_bin[fnum][rnum] = (char *)calloc(1, strlen(ptmp1)/2+1); + i = 0; + if(sscanf(ptmp1, "%u:", &feature_off[fnum][rnum]) != 1) + { + MESA_HANDLE_RUNTIME_LOGV2(g_qq_global_info.runtime_log,RLOG_LV_FATAL, MODULE_NAME, "Decode [FEATURE] %s error, format invalid.", feature_name); + return -1; + } + while(*ptmp1 != ':') + ptmp1++; + for(ptmp2 = strtok_r(ptmp1+1, ",", &save_ptr2); ptmp2 != NULL; ptmp2 = strtok_r(NULL, ",", &save_ptr2)) + { + if(strlen(ptmp2)!=2 || sscanf(ptmp2, "%02x", &val)!=1) + { + MESA_HANDLE_RUNTIME_LOGV2(g_qq_global_info.runtime_log,RLOG_LV_FATAL, MODULE_NAME, "Decode [FEATURE] %s error, format invalid.", feature_name); + return -1; + } + feature_bin[fnum][rnum][i++] = val; + } + feature_len[fnum][rnum] = i; + rnum++; + } + rulenum[fnum] = rnum; + fnum++; + } + + *feature_num = fnum; + return 0; +} + +extern "C" int QQ_PROT_INIT(void) +{ + int log_level; + char tmp_buffer[512]={0}, tmp_buffer2[512]={0}; + + memset(&g_qq_global_info, 0, sizeof(qq_global_info_t)); + + MESA_load_profile_string_def(CONF_FILENAME, "MODULE", "RUN_LOG_DIR", tmp_buffer, sizeof(tmp_buffer), "./log/qq_file_trans"); + MESA_load_profile_int_def(CONF_FILENAME, "MODULE", "RUN_LOG_LEVEL", &log_level,10); + if(mkdir_according_path(tmp_buffer)) + { + printf("mkdir %s failed: %s\n", tmp_buffer, strerror(errno)); + assert(0); + return -1; + } + snprintf(tmp_buffer2, sizeof(tmp_buffer2), "%s/qq_file_trans.log", tmp_buffer); + g_qq_global_info.runtime_log = MESA_create_runtime_log_handle(tmp_buffer2, log_level); + if(g_qq_global_info.runtime_log==NULL) + { + assert(0); + return -1; + } + + if(register_field_stat(tmp_buffer) < 0) + { + assert(0); + return -1; + } + + memset(tmp_buffer, 0 , sizeof(tmp_buffer)); + if(MESA_load_profile_string_nodef(CONF_FILENAME, "FEATURE", "FEATURE_QQTCP_PROTOCOL", tmp_buffer, sizeof(tmp_buffer)) < 0) + { + MESA_HANDLE_RUNTIME_LOGV2(g_qq_global_info.runtime_log,RLOG_LV_FATAL, MODULE_NAME, "Get [FEATURE] FEATURE_QQTCP_PROTOCOL error."); + assert(0); + return -1; + } + if(decode_feature_to_binary(tmp_buffer, "FEATURE_QQTCP_PROTOCOL", g_qq_global_info.feature[FINDEX_TCPPROT], g_qq_global_info.ftlen[FINDEX_TCPPROT], g_qq_global_info.ftoff[FINDEX_TCPPROT], g_qq_global_info.rulenum[FINDEX_TCPPROT], &g_qq_global_info.fnum[FINDEX_TCPPROT])) + { + return -1; + } + memset(tmp_buffer, 0 , sizeof(tmp_buffer)); + if(MESA_load_profile_string_nodef(CONF_FILENAME, "FEATURE", "FEATURE_QQUDP_PROTOCOL", tmp_buffer, sizeof(tmp_buffer)) < 0) + { + MESA_HANDLE_RUNTIME_LOGV2(g_qq_global_info.runtime_log,RLOG_LV_FATAL, MODULE_NAME, "Get [FEATURE] FEATURE_QQUDP_PROTOCOL error."); + assert(0); + return -1; + } + if(decode_feature_to_binary(tmp_buffer, "FEATURE_QQUDP_PROTOCOL", g_qq_global_info.feature[FINDEX_UDPPROT], g_qq_global_info.ftlen[FINDEX_UDPPROT], g_qq_global_info.ftoff[FINDEX_UDPPROT], g_qq_global_info.rulenum[FINDEX_UDPPROT], &g_qq_global_info.fnum[FINDEX_UDPPROT])) + { + return -1; + } + memset(tmp_buffer, 0 , sizeof(tmp_buffer)); + if(MESA_load_profile_string_nodef(CONF_FILENAME, "FEATURE", "FEATURE_QQ_NUMBER_TCP", tmp_buffer, sizeof(tmp_buffer)) < 0) + { + MESA_HANDLE_RUNTIME_LOGV2(g_qq_global_info.runtime_log,RLOG_LV_FATAL, MODULE_NAME, "Get [FEATURE] FEATURE_QQ_NUMBER_TCP error."); + assert(0); + return -1; + } + if(decode_feature_to_binary(tmp_buffer, "FEATURE_QQ_NUMBER_TCP", g_qq_global_info.feature[FINDEX_TCPNUM], g_qq_global_info.ftlen[FINDEX_TCPNUM], g_qq_global_info.ftoff[FINDEX_TCPNUM], g_qq_global_info.rulenum[FINDEX_TCPNUM], &g_qq_global_info.fnum[FINDEX_TCPNUM])) + { + return -1; + } + memset(tmp_buffer, 0 , sizeof(tmp_buffer)); + if(MESA_load_profile_string_nodef(CONF_FILENAME, "FEATURE", "FEATURE_QQ_NUMBER_UDP", tmp_buffer, sizeof(tmp_buffer)) < 0) + { + MESA_HANDLE_RUNTIME_LOGV2(g_qq_global_info.runtime_log,RLOG_LV_FATAL, MODULE_NAME, "Get [FEATURE] FEATURE_QQ_NUMBER_UDP error."); + assert(0); + return -1; + } + if(decode_feature_to_binary(tmp_buffer, "FEATURE_QQ_NUMBER_UDP", g_qq_global_info.feature[FINDEX_UDPNUM], g_qq_global_info.ftlen[FINDEX_UDPNUM], g_qq_global_info.ftoff[FINDEX_UDPNUM], g_qq_global_info.rulenum[FINDEX_UDPNUM], &g_qq_global_info.fnum[FINDEX_UDPNUM])) + { + return -1; + } + memset(tmp_buffer, 0 , sizeof(tmp_buffer)); + if(MESA_load_profile_string_nodef(CONF_FILENAME, "FEATURE", "FEATURE_QQ_TCPFILE", tmp_buffer, sizeof(tmp_buffer)) < 0) + { + MESA_HANDLE_RUNTIME_LOGV2(g_qq_global_info.runtime_log,RLOG_LV_FATAL, MODULE_NAME, "Get [FEATURE] FEATURE_QQ_TCPFILE error."); + assert(0); + return -1; + } + if(decode_feature_to_binary(tmp_buffer, "FEATURE_QQ_TCPFILE", g_qq_global_info.feature[FINDEX_TCPFILE], g_qq_global_info.ftlen[FINDEX_TCPFILE], g_qq_global_info.ftoff[FINDEX_TCPFILE], g_qq_global_info.rulenum[FINDEX_TCPFILE], &g_qq_global_info.fnum[FINDEX_TCPFILE])) + { + return -1; + } + memset(tmp_buffer, 0 , sizeof(tmp_buffer)); + if(MESA_load_profile_string_nodef(CONF_FILENAME, "FEATURE", "FEATURE_QQ_TCPFILE_END", tmp_buffer, sizeof(tmp_buffer)) < 0) + { + MESA_HANDLE_RUNTIME_LOGV2(g_qq_global_info.runtime_log,RLOG_LV_FATAL, MODULE_NAME, "Get [FEATURE] FEATURE_QQ_TCPFILE_END error."); + assert(0); + return -1; + } + if(decode_feature_to_binary(tmp_buffer, "FEATURE_QQ_TCPFILE_END", g_qq_global_info.feature[FINDEX_TCPFILE_END], g_qq_global_info.ftlen[FINDEX_TCPFILE_END], g_qq_global_info.ftoff[FINDEX_TCPFILE_END], g_qq_global_info.rulenum[FINDEX_TCPFILE_END], &g_qq_global_info.fnum[FINDEX_TCPFILE_END])) + { + return -1; + } + memset(tmp_buffer, 0 , sizeof(tmp_buffer)); + if(MESA_load_profile_string_nodef(CONF_FILENAME, "FEATURE", "FEATURE_QQ_TCPFILENAME", tmp_buffer, sizeof(tmp_buffer)) < 0) + { + MESA_HANDLE_RUNTIME_LOGV2(g_qq_global_info.runtime_log,RLOG_LV_FATAL, MODULE_NAME, "Get [FEATURE] FEATURE_QQ_TCPFILENAME error."); + assert(0); + return -1; + } + if(decode_feature_to_binary(tmp_buffer, "FEATURE_QQ_TCPFILENAME", g_qq_global_info.feature[FINDEX_TCPNAME], g_qq_global_info.ftlen[FINDEX_TCPNAME], g_qq_global_info.ftoff[FINDEX_TCPNAME], g_qq_global_info.rulenum[FINDEX_TCPNAME], &g_qq_global_info.fnum[FINDEX_TCPNAME])) + { + return -1; + } + memset(tmp_buffer, 0 , sizeof(tmp_buffer)); + if(MESA_load_profile_string_nodef(CONF_FILENAME, "FEATURE", "FEATURE_QQ_UDPFILE_START", tmp_buffer, sizeof(tmp_buffer)) < 0) + { + MESA_HANDLE_RUNTIME_LOGV2(g_qq_global_info.runtime_log,RLOG_LV_FATAL, MODULE_NAME, "Get [FEATURE] FEATURE_QQ_UDPFILE_START error."); + assert(0); + return -1; + } + if(decode_feature_to_binary(tmp_buffer, "FEATURE_QQ_UDPFILE_START", g_qq_global_info.feature[FINDEX_UDPFILE], g_qq_global_info.ftlen[FINDEX_UDPFILE], g_qq_global_info.ftoff[FINDEX_UDPFILE], g_qq_global_info.rulenum[FINDEX_UDPFILE], &g_qq_global_info.fnum[FINDEX_UDPFILE])) + { + return -1; + } + memset(tmp_buffer, 0 , sizeof(tmp_buffer)); + if(MESA_load_profile_string_nodef(CONF_FILENAME, "FEATURE", "FEATURE_QQ_UDPFILE_END", tmp_buffer, sizeof(tmp_buffer)) < 0) + { + MESA_HANDLE_RUNTIME_LOGV2(g_qq_global_info.runtime_log,RLOG_LV_FATAL, MODULE_NAME, "Get [FEATURE] FEATURE_QQ_UDPFILE_END error."); + assert(0); + return -1; + } + if(decode_feature_to_binary(tmp_buffer, "FEATURE_QQ_UDPFILE_END", g_qq_global_info.feature[FINDEX_UDPFILE_END], g_qq_global_info.ftlen[FINDEX_UDPFILE_END], g_qq_global_info.ftoff[FINDEX_UDPFILE_END], g_qq_global_info.rulenum[FINDEX_UDPFILE_END], &g_qq_global_info.fnum[FINDEX_UDPFILE_END])) + { + return -1; + } + memset(tmp_buffer, 0 , sizeof(tmp_buffer)); + if(MESA_load_profile_string_nodef(CONF_FILENAME, "FEATURE", "FEATURE_QQ_UDPFILENAME", tmp_buffer, sizeof(tmp_buffer)) < 0) + { + MESA_HANDLE_RUNTIME_LOGV2(g_qq_global_info.runtime_log,RLOG_LV_FATAL, MODULE_NAME, "Get [FEATURE] FEATURE_QQ_UDPFILENAME error."); + assert(0); + return -1; + } + if(decode_feature_to_binary(tmp_buffer, "FEATURE_QQ_UDPFILENAME", g_qq_global_info.feature[FINDEX_UDPNAME], g_qq_global_info.ftlen[FINDEX_UDPNAME], g_qq_global_info.ftoff[FINDEX_UDPNAME], g_qq_global_info.rulenum[FINDEX_UDPNAME], &g_qq_global_info.fnum[FINDEX_UDPNAME])) + { + return -1; + } + g_qq_global_info.instanse = docanalyze_initialize(get_thread_count()); + if(g_qq_global_info.instanse==NULL) + { + MESA_HANDLE_RUNTIME_LOGV2(g_qq_global_info.runtime_log,RLOG_LV_FATAL, MODULE_NAME, "docanalyze_initialize() error."); + assert(0); + return -1; + } + + MESA_load_profile_int_def(CONF_FILENAME, "MODULE", "DEBUG_SWITCH", &g_qq_global_info.debug_sw, 0); + if(g_qq_global_info.debug_sw) + { + if(mkdir_according_path(QQ_DEBUG_FILEPATH)) + { + printf("mkdir %s failed: %s\n", tmp_buffer, strerror(errno)); + assert(0); + return -1; + } + } + + g_qq_global_info.project_id = project_customer_register("STREAMID", "long"); + assert(g_qq_global_info.project_id >= 0); + + srand(time(NULL)); + return 0; +} + +extern "C" void QQ_PROT_DESTROY(void) +{ +} + |
